403Webshell
Server IP : 127.0.0.1  /  Your IP : 216.73.216.109
Web Server : Apache/2.4.54 (Win64) OpenSSL/1.1.1q PHP/8.1.10
System : Windows NT DESKTOP-E5T4RUN 10.0 build 19045 (Windows 10) AMD64
User : SERVERWEB ( 0)
PHP Version : 8.1.10
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : OFF |  Perl : OFF |  Python : OFF |  Sudo : OFF |  Pkexec : OFF
Directory :  C:/Users/SERVERWEB/AppData/Local/Microsoft/Edge/User Data/Default/Cache/Cache_Data/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : C:/Users/SERVERWEB/AppData/Local/Microsoft/Edge/User Data/Default/Cache/Cache_Data/f_000096
(self["webpackChunkdeportes_gamq"] = self["webpackChunkdeportes_gamq"] || []).push([["vendor"],{

/***/ 9980:
/*!***********************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/augmentation.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */


/***/ }),

/***/ 66306:
/*!**************************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/contextwatchdog.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ ContextWatchdog)
/* harmony export */ });
/* harmony import */ var _watchdog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./watchdog */ 80523);
/* harmony import */ var _editorwatchdog__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./editorwatchdog */ 54974);
/* harmony import */ var _utils_areconnectedthroughproperties__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/areconnectedthroughproperties */ 89687);
/* harmony import */ var _utils_getsubnodes__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/getsubnodes */ 21543);
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */




const mainQueueId = Symbol('MainQueueId');
/**
 * A watchdog for the {@link module:core/context~Context} class.
 *
 * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and
 * how to use it.
 */
class ContextWatchdog extends _watchdog__WEBPACK_IMPORTED_MODULE_0__["default"] {
  /**
   * The context watchdog class constructor.
   *
   * ```ts
   * const watchdog = new ContextWatchdog( Context );
   *
   * await watchdog.create( contextConfiguration );
   *
   * await watchdog.add( item );
   * ```
   *
   * See the {@glink features/watchdog Watchdog feature guide} to learn more how to use this feature.
   *
   * @param Context The {@link module:core/context~Context} class.
   * @param watchdogConfig The watchdog configuration.
   */
  constructor(Context, watchdogConfig = {}) {
    super(watchdogConfig);
    /**
     * A map of internal watchdogs for added items.
     */
    this._watchdogs = new Map();
    /**
     * The current context instance.
     */
    this._context = null;
    /**
     * Context properties (nodes/references) that are gathered during the initial context creation
     * and are used to distinguish the origin of an error.
     */
    this._contextProps = new Set();
    /**
     * An action queue, which is used to handle async functions queuing.
     */
    this._actionQueues = new ActionQueues();
    this._watchdogConfig = watchdogConfig;
    // Default creator and destructor.
    this._creator = contextConfig => Context.create(contextConfig);
    this._destructor = context => context.destroy();
    this._actionQueues.onEmpty(() => {
      if (this.state === 'initializing') {
        this.state = 'ready';
        this._fire('stateChange');
      }
    });
  }
  /**
   * Sets the function that is responsible for the context creation.
   * It expects a function that should return a promise (or `undefined`).
   *
   * ```ts
   * watchdog.setCreator( config => Context.create( config ) );
   * ```
   */
  setCreator(creator) {
    this._creator = creator;
  }
  /**
   * Sets the function that is responsible for the context destruction.
   * Overrides the default destruction function, which destroys only the context instance.
   * It expects a function that should return a promise (or `undefined`).
   *
   * ```ts
   * watchdog.setDestructor( context => {
   * 	// Do something before the context is destroyed.
   *
   * 	return context
   * 		.destroy()
   * 		.then( () => {
   * 			// Do something after the context is destroyed.
   * 		} );
   * } );
   * ```
   */
  setDestructor(destructor) {
    this._destructor = destructor;
  }
  /**
   * The context instance. Keep in mind that this property might be changed when the context watchdog restarts,
   * so do not keep this instance internally. Always operate on the `ContextWatchdog#context` property.
   */
  get context() {
    return this._context;
  }
  /**
   * Initializes the context watchdog. Once it is created, the watchdog takes care about
   * recreating the context and the provided items, and starts the error handling mechanism.
   *
   * ```ts
   * await watchdog.create( {
   * 	plugins: []
   * } );
   * ```
   *
   * @param contextConfig The context configuration. See {@link module:core/context~Context}.
   */
  create(contextConfig = {}) {
    return this._actionQueues.enqueue(mainQueueId, () => {
      this._contextConfig = contextConfig;
      return this._create();
    });
  }
  /**
   * Returns an item instance with the given `itemId`.
   *
   * ```ts
   * const editor1 = watchdog.getItem( 'editor1' );
   * ```
   *
   * @param itemId The item ID.
   * @returns The item instance or `undefined` if an item with a given ID has not been found.
   */
  getItem(itemId) {
    const watchdog = this._getWatchdog(itemId);
    return watchdog._item;
  }
  /**
   * Gets the state of the given item. See {@link #state} for a list of available states.
   *
   * ```ts
   * const editor1State = watchdog.getItemState( 'editor1' );
   * ```
   *
   * @param itemId Item ID.
   * @returns The state of the item.
   */
  getItemState(itemId) {
    const watchdog = this._getWatchdog(itemId);
    return watchdog.state;
  }
  /**
   * Adds items to the watchdog. Once created, instances of these items will be available using the {@link #getItem} method.
   *
   * Items can be passed together as an array of objects:
   *
   * ```ts
   * await watchdog.add( [ {
   * 	id: 'editor1',
   * 	type: 'editor',
   * 	sourceElementOrData: document.querySelector( '#editor' ),
   * 	config: {
   * 		plugins: [ Essentials, Paragraph, Bold, Italic ],
   * 		toolbar: [ 'bold', 'italic', 'alignment' ]
   * 	},
   * 	creator: ( element, config ) => ClassicEditor.create( element, config )
   * } ] );
   * ```
   *
   * Or one by one as objects:
   *
   * ```ts
   * await watchdog.add( {
   * 	id: 'editor1',
   * 	type: 'editor',
   * 	sourceElementOrData: document.querySelector( '#editor' ),
   * 	config: {
   * 		plugins: [ Essentials, Paragraph, Bold, Italic ],
   * 		toolbar: [ 'bold', 'italic', 'alignment' ]
   * 	},
   * 	creator: ( element, config ) => ClassicEditor.create( element, config )
   * ] );
   * ```
   *
   * Then an instance can be retrieved using the {@link #getItem} method:
   *
   * ```ts
   * const editor1 = watchdog.getItem( 'editor1' );
   * ```
   *
   * Note that this method can be called multiple times, but for performance reasons it is better
   * to pass all items together.
   *
   * @param itemConfigurationOrItemConfigurations An item configuration object or an array of item configurations.
   */
  add(itemConfigurationOrItemConfigurations) {
    const itemConfigurations = toArray(itemConfigurationOrItemConfigurations);
    return Promise.all(itemConfigurations.map(item => {
      return this._actionQueues.enqueue(item.id, () => {
        if (this.state === 'destroyed') {
          throw new Error('Cannot add items to destroyed watchdog.');
        }
        if (!this._context) {
          throw new Error('Context was not created yet. You should call the `ContextWatchdog#create()` method first.');
        }
        let watchdog;
        if (this._watchdogs.has(item.id)) {
          throw new Error(`Item with the given id is already added: '${item.id}'.`);
        }
        if (item.type === 'editor') {
          watchdog = new _editorwatchdog__WEBPACK_IMPORTED_MODULE_1__["default"](null, this._watchdogConfig);
          watchdog.setCreator(item.creator);
          watchdog._setExcludedProperties(this._contextProps);
          if (item.destructor) {
            watchdog.setDestructor(item.destructor);
          }
          this._watchdogs.set(item.id, watchdog);
          // Enqueue the internal watchdog errors within the main queue.
          // And propagate the internal `error` events as `itemError` event.
          watchdog.on('error', (evt, {
            error,
            causesRestart
          }) => {
            this._fire('itemError', {
              itemId: item.id,
              error
            });
            // Do not enqueue the item restart action if the item will not restart.
            if (!causesRestart) {
              return;
            }
            this._actionQueues.enqueue(item.id, () => new Promise(res => {
              const rethrowRestartEventOnce = () => {
                watchdog.off('restart', rethrowRestartEventOnce);
                this._fire('itemRestart', {
                  itemId: item.id
                });
                res();
              };
              watchdog.on('restart', rethrowRestartEventOnce);
            }));
          });
          return watchdog.create(item.sourceElementOrData, item.config, this._context);
        } else {
          throw new Error(`Not supported item type: '${item.type}'.`);
        }
      });
    }));
  }
  /**
   * Removes and destroys item(s) with given ID(s).
   *
   * ```ts
   * await watchdog.remove( 'editor1' );
   * ```
   *
   * Or
   *
   * ```ts
   * await watchdog.remove( [ 'editor1', 'editor2' ] );
   * ```
   *
   * @param itemIdOrItemIds Item ID or an array of item IDs.
   */
  remove(itemIdOrItemIds) {
    const itemIds = toArray(itemIdOrItemIds);
    return Promise.all(itemIds.map(itemId => {
      return this._actionQueues.enqueue(itemId, () => {
        const watchdog = this._getWatchdog(itemId);
        this._watchdogs.delete(itemId);
        return watchdog.destroy();
      });
    }));
  }
  /**
   * Destroys the context watchdog and all added items.
   * Once the context watchdog is destroyed, new items cannot be added.
   *
   * ```ts
   * await watchdog.destroy();
   * ```
   */
  destroy() {
    return this._actionQueues.enqueue(mainQueueId, () => {
      this.state = 'destroyed';
      this._fire('stateChange');
      super.destroy();
      return this._destroy();
    });
  }
  /**
   * Restarts the context watchdog.
   */
  _restart() {
    return this._actionQueues.enqueue(mainQueueId, () => {
      this.state = 'initializing';
      this._fire('stateChange');
      return this._destroy().catch(err => {
        console.error('An error happened during destroying the context or items.', err);
      }).then(() => this._create()).then(() => this._fire('restart'));
    });
  }
  /**
   * Initializes the context watchdog.
   */
  _create() {
    return Promise.resolve().then(() => {
      this._startErrorHandling();
      return this._creator(this._contextConfig);
    }).then(context => {
      this._context = context;
      this._contextProps = (0,_utils_getsubnodes__WEBPACK_IMPORTED_MODULE_3__["default"])(this._context);
      return Promise.all(Array.from(this._watchdogs.values()).map(watchdog => {
        watchdog._setExcludedProperties(this._contextProps);
        return watchdog.create(undefined, undefined, this._context);
      }));
    });
  }
  /**
   * Destroys the context instance and all added items.
   */
  _destroy() {
    return Promise.resolve().then(() => {
      this._stopErrorHandling();
      const context = this._context;
      this._context = null;
      this._contextProps = new Set();
      return Promise.all(Array.from(this._watchdogs.values()).map(watchdog => watchdog.destroy()))
      // Context destructor destroys each editor.
      .then(() => this._destructor(context));
    });
  }
  /**
   * Returns the watchdog for a given item ID.
   *
   * @param itemId Item ID.
   */
  _getWatchdog(itemId) {
    const watchdog = this._watchdogs.get(itemId);
    if (!watchdog) {
      throw new Error(`Item with the given id was not registered: ${itemId}.`);
    }
    return watchdog;
  }
  /**
   * Checks whether an error comes from the context instance and not from the item instances.
   *
   * @internal
   */
  _isErrorComingFromThisItem(error) {
    for (const watchdog of this._watchdogs.values()) {
      if (watchdog._isErrorComingFromThisItem(error)) {
        return false;
      }
    }
    return (0,_utils_areconnectedthroughproperties__WEBPACK_IMPORTED_MODULE_2__["default"])(this._context, error.context);
  }
}
/**
 * Manager of action queues that allows queuing async functions.
 */
class ActionQueues {
  constructor() {
    this._onEmptyCallbacks = [];
    this._queues = new Map();
    this._activeActions = 0;
  }
  /**
   * Used to register callbacks that will be run when the queue becomes empty.
   *
   * @param onEmptyCallback A callback that will be run whenever the queue becomes empty.
   */
  onEmpty(onEmptyCallback) {
    this._onEmptyCallbacks.push(onEmptyCallback);
  }
  /**
   * It adds asynchronous actions (functions) to the proper queue and runs them one by one.
   *
   * @param queueId The action queue ID.
   * @param action A function that should be enqueued.
   */
  enqueue(queueId, action) {
    const isMainAction = queueId === mainQueueId;
    this._activeActions++;
    if (!this._queues.get(queueId)) {
      this._queues.set(queueId, Promise.resolve());
    }
    // List all sources of actions that the current action needs to await for.
    // For the main action wait for all other actions.
    // For the item action wait only for the item queue and the main queue.
    const awaitedActions = isMainAction ? Promise.all(this._queues.values()) : Promise.all([this._queues.get(mainQueueId), this._queues.get(queueId)]);
    const queueWithAction = awaitedActions.then(action);
    // Catch all errors in the main queue to stack promises even if an error occurred in the past.
    const nonErrorQueue = queueWithAction.catch(() => {});
    this._queues.set(queueId, nonErrorQueue);
    return queueWithAction.finally(() => {
      this._activeActions--;
      if (this._queues.get(queueId) === nonErrorQueue && this._activeActions === 0) {
        this._onEmptyCallbacks.forEach(cb => cb());
      }
    });
  }
}
/**
 * Transforms any value to an array. If the provided value is already an array, it is returned unchanged.
 *
 * @param elementOrArray The value to transform to an array.
 * @returns An array created from data.
 */
function toArray(elementOrArray) {
  return Array.isArray(elementOrArray) ? elementOrArray : [elementOrArray];
}

/***/ }),

/***/ 54974:
/*!*************************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/editorwatchdog.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ EditorWatchdog)
/* harmony export */ });
/* harmony import */ var _utils_areconnectedthroughproperties__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/areconnectedthroughproperties */ 89687);
/* harmony import */ var _watchdog__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./watchdog */ 80523);
/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lodash-es */ 57156);
/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lodash-es */ 4134);
/* harmony import */ var lodash_es__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! lodash-es */ 60105);
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */



/**
 * A watchdog for CKEditor 5 editors.
 *
 * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and
 * how to use it.
 */
class EditorWatchdog extends _watchdog__WEBPACK_IMPORTED_MODULE_1__["default"] {
  /**
   * @param Editor The editor class.
   * @param watchdogConfig The watchdog plugin configuration.
   */
  constructor(Editor, watchdogConfig = {}) {
    super(watchdogConfig);
    /**
     * The current editor instance.
     */
    this._editor = null;
    /**
     * Specifies whether the editor was initialized using document data (`true`) or HTML elements (`false`).
     */
    this._initUsingData = true;
    /**
     * The latest record of the editor editable elements. Used to restart the editor.
     */
    this._editables = {};
    // this._editorClass = Editor;
    this._throttledSave = (0,lodash_es__WEBPACK_IMPORTED_MODULE_2__["default"])(this._save.bind(this), typeof watchdogConfig.saveInterval === 'number' ? watchdogConfig.saveInterval : 5000);
    // Set default creator and destructor functions:
    if (Editor) {
      this._creator = (elementOrData, config) => Editor.create(elementOrData, config);
    }
    this._destructor = editor => editor.destroy();
  }
  /**
   * The current editor instance.
   */
  get editor() {
    return this._editor;
  }
  /**
   * @internal
   */
  get _item() {
    return this._editor;
  }
  /**
   * Sets the function that is responsible for the editor creation.
   * It expects a function that should return a promise.
   *
   * ```ts
   * watchdog.setCreator( ( element, config ) => ClassicEditor.create( element, config ) );
   * ```
   */
  setCreator(creator) {
    this._creator = creator;
  }
  /**
   * Sets the function that is responsible for the editor destruction.
   * Overrides the default destruction function, which destroys only the editor instance.
   * It expects a function that should return a promise or `undefined`.
   *
   * ```ts
   * watchdog.setDestructor( editor => {
   * 	// Do something before the editor is destroyed.
   *
   * 	return editor
   * 		.destroy()
   * 		.then( () => {
   * 			// Do something after the editor is destroyed.
   * 		} );
   * } );
   * ```
   */
  setDestructor(destructor) {
    this._destructor = destructor;
  }
  /**
   * Restarts the editor instance. This method is called whenever an editor error occurs. It fires the `restart` event and changes
   * the state to `initializing`.
   *
   * @fires restart
   */
  _restart() {
    return Promise.resolve().then(() => {
      this.state = 'initializing';
      this._fire('stateChange');
      return this._destroy();
    }).catch(err => {
      console.error('An error happened during the editor destroying.', err);
    }).then(() => {
      // Pre-process some data from the original editor config.
      // Our goal here is to make sure that the restarted editor will be reinitialized with correct set of roots.
      // We are not interested in any data set in config or in `.create()` first parameter. It will be replaced anyway.
      // But we need to set them correctly to make sure that proper roots are created.
      //
      // Since a different set of roots will be created, `lazyRoots` and `rootsAttributes` properties must be managed too.
      // Keys are root names, values are ''. Used when the editor was initialized by setting the first parameter to document data.
      const existingRoots = {};
      // Keeps lazy roots. They may be different when compared to initial config if some of the roots were loaded.
      const lazyRoots = [];
      // Roots attributes from the old config. Will be referred when setting new attributes.
      const oldRootsAttributes = this._config.rootsAttributes || {};
      // New attributes to be set. Is filled only for roots that still exist in the document.
      const rootsAttributes = {};
      // Traverse through the roots saved when the editor crashed and set up the discussed values.
      for (const [rootName, rootData] of Object.entries(this._data.roots)) {
        if (rootData.isLoaded) {
          existingRoots[rootName] = '';
          rootsAttributes[rootName] = oldRootsAttributes[rootName] || {};
        } else {
          lazyRoots.push(rootName);
        }
      }
      const updatedConfig = {
        ...this._config,
        extraPlugins: this._config.extraPlugins || [],
        lazyRoots,
        rootsAttributes,
        _watchdogInitialData: this._data
      };
      // Delete `initialData` as it is not needed. Data will be set by the watchdog based on `_watchdogInitialData`.
      // First parameter of the editor `.create()` will be used to set up initial roots.
      delete updatedConfig.initialData;
      updatedConfig.extraPlugins.push(EditorWatchdogInitPlugin);
      if (this._initUsingData) {
        return this.create(existingRoots, updatedConfig, updatedConfig.context);
      } else {
        // Set correct editables to make sure that proper roots are created and linked with DOM elements.
        // No need to set initial data, as it would be discarded anyway.
        //
        // If one element was initially set in `elementOrData`, then use that original element to restart the editor.
        // This is for compatibility purposes with single-root editor types.
        if ((0,lodash_es__WEBPACK_IMPORTED_MODULE_3__["default"])(this._elementOrData)) {
          return this.create(this._elementOrData, updatedConfig, updatedConfig.context);
        } else {
          return this.create(this._editables, updatedConfig, updatedConfig.context);
        }
      }
    }).then(() => {
      this._fire('restart');
    });
  }
  /**
   * Creates the editor instance and keeps it running, using the defined creator and destructor.
   *
   * @param elementOrData The editor source element or the editor data.
   * @param config The editor configuration.
   * @param context A context for the editor.
   */
  create(elementOrData = this._elementOrData, config = this._config, context) {
    return Promise.resolve().then(() => {
      super._startErrorHandling();
      this._elementOrData = elementOrData;
      // Use document data in the first parameter of the editor `.create()` call only if it was used like this originally.
      // Use document data if a string or object with strings was passed.
      this._initUsingData = typeof elementOrData == 'string' || Object.keys(elementOrData).length > 0 && typeof Object.values(elementOrData)[0] == 'string';
      // Clone configuration because it might be shared within multiple watchdog instances. Otherwise,
      // when an error occurs in one of these editors, the watchdog will restart all of them.
      this._config = this._cloneEditorConfiguration(config) || {};
      this._config.context = context;
      return this._creator(elementOrData, this._config);
    }).then(editor => {
      this._editor = editor;
      editor.model.document.on('change:data', this._throttledSave);
      this._lastDocumentVersion = editor.model.document.version;
      this._data = this._getData();
      if (!this._initUsingData) {
        this._editables = this._getEditables();
      }
      this.state = 'ready';
      this._fire('stateChange');
    });
  }
  /**
   * Destroys the watchdog and the current editor instance. It fires the callback
   * registered in {@link #setDestructor `setDestructor()`} and uses it to destroy the editor instance.
   * It also sets the state to `destroyed`.
   */
  destroy() {
    return Promise.resolve().then(() => {
      this.state = 'destroyed';
      this._fire('stateChange');
      super.destroy();
      return this._destroy();
    });
  }
  _destroy() {
    return Promise.resolve().then(() => {
      this._stopErrorHandling();
      this._throttledSave.cancel();
      const editor = this._editor;
      this._editor = null;
      // Remove the `change:data` listener before destroying the editor.
      // Incorrectly written plugins may trigger firing `change:data` events during the editor destruction phase
      // causing the watchdog to call `editor.getData()` when some parts of editor are already destroyed.
      editor.model.document.off('change:data', this._throttledSave);
      return this._destructor(editor);
    });
  }
  /**
   * Saves the editor data, so it can be restored after the crash even if the data cannot be fetched at
   * the moment of the crash.
   */
  _save() {
    const version = this._editor.model.document.version;
    try {
      this._data = this._getData();
      if (!this._initUsingData) {
        this._editables = this._getEditables();
      }
      this._lastDocumentVersion = version;
    } catch (err) {
      console.error(err, 'An error happened during restoring editor data. ' + 'Editor will be restored from the previously saved data.');
    }
  }
  /**
   * @internal
   */
  _setExcludedProperties(props) {
    this._excludedProps = props;
  }
  /**
   * Gets all data that is required to reinitialize editor instance.
   */
  _getData() {
    const editor = this._editor;
    const roots = editor.model.document.roots.filter(root => root.isAttached() && root.rootName != '$graveyard');
    const {
      plugins
    } = editor;
    // `as any` to avoid linking from external private repo.
    const commentsRepository = plugins.has('CommentsRepository') && plugins.get('CommentsRepository');
    const trackChanges = plugins.has('TrackChanges') && plugins.get('TrackChanges');
    const data = {
      roots: {},
      markers: {},
      commentThreads: JSON.stringify([]),
      suggestions: JSON.stringify([])
    };
    roots.forEach(root => {
      data.roots[root.rootName] = {
        content: JSON.stringify(Array.from(root.getChildren())),
        attributes: JSON.stringify(Array.from(root.getAttributes())),
        isLoaded: root._isLoaded
      };
    });
    for (const marker of editor.model.markers) {
      if (!marker._affectsData) {
        continue;
      }
      data.markers[marker.name] = {
        rangeJSON: marker.getRange().toJSON(),
        usingOperation: marker._managedUsingOperations,
        affectsData: marker._affectsData
      };
    }
    if (commentsRepository) {
      data.commentThreads = JSON.stringify(commentsRepository.getCommentThreads({
        toJSON: true,
        skipNotAttached: true
      }));
    }
    if (trackChanges) {
      data.suggestions = JSON.stringify(trackChanges.getSuggestions({
        toJSON: true,
        skipNotAttached: true
      }));
    }
    return data;
  }
  /**
   * For each attached model root, returns its HTML editable element (if available).
   */
  _getEditables() {
    const editables = {};
    for (const rootName of this.editor.model.document.getRootNames()) {
      const editable = this.editor.ui.getEditableElement(rootName);
      if (editable) {
        editables[rootName] = editable;
      }
    }
    return editables;
  }
  /**
   * Traverses the error context and the current editor to find out whether these structures are connected
   * to each other via properties.
   *
   * @internal
   */
  _isErrorComingFromThisItem(error) {
    return (0,_utils_areconnectedthroughproperties__WEBPACK_IMPORTED_MODULE_0__["default"])(this._editor, error.context, this._excludedProps);
  }
  /**
   * Clones the editor configuration.
   */
  _cloneEditorConfiguration(config) {
    return (0,lodash_es__WEBPACK_IMPORTED_MODULE_4__["default"])(config, (value, key) => {
      // Leave DOM references.
      if ((0,lodash_es__WEBPACK_IMPORTED_MODULE_3__["default"])(value)) {
        return value;
      }
      if (key === 'context') {
        return value;
      }
    });
  }
}
/**
 * Internal plugin that is used to stop the default editor initialization and restoring the editor state
 * based on the `editor.config._watchdogInitialData` data.
 */
class EditorWatchdogInitPlugin {
  constructor(editor) {
    this.editor = editor;
    this._data = editor.config.get('_watchdogInitialData');
  }
  /**
   * @inheritDoc
   */
  init() {
    // Stops the default editor initialization and use the saved data to restore the editor state.
    // Some of data could not be initialize as a config properties. It is important to keep the data
    // in the same form as it was before the restarting.
    this.editor.data.on('init', evt => {
      evt.stop();
      this.editor.model.enqueueChange({
        isUndoable: false
      }, writer => {
        this._restoreCollaborationData();
        this._restoreEditorData(writer);
      });
      this.editor.data.fire('ready');
      // Keep priority `'high' - 1` to be sure that RTC initialization will be first.
    }, {
      priority: 1000 - 1
    });
  }
  /**
   * Creates a model node (element or text) based on provided JSON.
   */
  _createNode(writer, jsonNode) {
    if ('name' in jsonNode) {
      // If child has name property, it is an Element.
      const element = writer.createElement(jsonNode.name, jsonNode.attributes);
      if (jsonNode.children) {
        for (const child of jsonNode.children) {
          element._appendChild(this._createNode(writer, child));
        }
      }
      return element;
    } else {
      // Otherwise, it is a Text node.
      return writer.createText(jsonNode.data, jsonNode.attributes);
    }
  }
  /**
   * Restores the editor by setting the document data, roots attributes and markers.
   */
  _restoreEditorData(writer) {
    const editor = this.editor;
    Object.entries(this._data.roots).forEach(([rootName, {
      content,
      attributes
    }]) => {
      const parsedNodes = JSON.parse(content);
      const parsedAttributes = JSON.parse(attributes);
      const rootElement = editor.model.document.getRoot(rootName);
      for (const [key, value] of parsedAttributes) {
        writer.setAttribute(key, value, rootElement);
      }
      for (const child of parsedNodes) {
        const node = this._createNode(writer, child);
        writer.insert(node, rootElement, 'end');
      }
    });
    Object.entries(this._data.markers).forEach(([markerName, markerOptions]) => {
      const {
        document
      } = editor.model;
      const {
        rangeJSON: {
          start,
          end
        },
        ...options
      } = markerOptions;
      const root = document.getRoot(start.root);
      const startPosition = writer.createPositionFromPath(root, start.path, start.stickiness);
      const endPosition = writer.createPositionFromPath(root, end.path, end.stickiness);
      const range = writer.createRange(startPosition, endPosition);
      writer.addMarker(markerName, {
        range,
        ...options
      });
    });
  }
  /**
   * Restores the editor collaboration data - comment threads and suggestions.
   */
  _restoreCollaborationData() {
    // `as any` to avoid linking from external private repo.
    const parsedCommentThreads = JSON.parse(this._data.commentThreads);
    const parsedSuggestions = JSON.parse(this._data.suggestions);
    parsedCommentThreads.forEach(commentThreadData => {
      const channelId = this.editor.config.get('collaboration.channelId');
      const commentsRepository = this.editor.plugins.get('CommentsRepository');
      if (commentsRepository.hasCommentThread(commentThreadData.threadId)) {
        const commentThread = commentsRepository.getCommentThread(commentThreadData.threadId);
        commentThread.remove();
      }
      commentsRepository.addCommentThread({
        channelId,
        ...commentThreadData
      });
    });
    parsedSuggestions.forEach(suggestionData => {
      const trackChangesEditing = this.editor.plugins.get('TrackChangesEditing');
      if (trackChangesEditing.hasSuggestion(suggestionData.id)) {
        const suggestion = trackChangesEditing.getSuggestion(suggestionData.id);
        suggestion.attributes = suggestionData.attributes;
      } else {
        trackChangesEditing.addSuggestionData(suggestionData);
      }
    });
  }
}

/***/ }),

/***/ 63118:
/*!****************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/index.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ContextWatchdog: () => (/* reexport safe */ _contextwatchdog__WEBPACK_IMPORTED_MODULE_0__["default"]),
/* harmony export */   EditorWatchdog: () => (/* reexport safe */ _editorwatchdog__WEBPACK_IMPORTED_MODULE_1__["default"]),
/* harmony export */   Watchdog: () => (/* reexport safe */ _watchdog__WEBPACK_IMPORTED_MODULE_2__["default"])
/* harmony export */ });
/* harmony import */ var _contextwatchdog__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./contextwatchdog */ 66306);
/* harmony import */ var _editorwatchdog__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./editorwatchdog */ 54974);
/* harmony import */ var _watchdog__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./watchdog */ 80523);
/* harmony import */ var _augmentation__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./augmentation */ 9980);
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module watchdog
 */





/***/ }),

/***/ 89687:
/*!**********************************************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/utils/areconnectedthroughproperties.js ***!
  \**********************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ areConnectedThroughProperties)
/* harmony export */ });
/* harmony import */ var _getsubnodes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getsubnodes */ 21543);
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module watchdog/utils/areconnectedthroughproperties
 */
/* globals console */

/**
 * Traverses both structures to find out whether there is a reference that is shared between both structures.
 */
function areConnectedThroughProperties(target1, target2, excludedNodes = new Set()) {
  if (target1 === target2 && isObject(target1)) {
    return true;
  }
  // @if CK_DEBUG_WATCHDOG // return checkConnectionBetweenProps( target1, target2, excludedNodes );
  const subNodes1 = (0,_getsubnodes__WEBPACK_IMPORTED_MODULE_0__["default"])(target1, excludedNodes);
  const subNodes2 = (0,_getsubnodes__WEBPACK_IMPORTED_MODULE_0__["default"])(target2, excludedNodes);
  for (const node of subNodes1) {
    if (subNodes2.has(node)) {
      return true;
    }
  }
  return false;
}
/* istanbul ignore next -- @preserve */
// eslint-disable-next-line
function checkConnectionBetweenProps(target1, target2, excludedNodes) {
  const {
    subNodes: subNodes1,
    prevNodeMap: prevNodeMap1
  } = (0,_getsubnodes__WEBPACK_IMPORTED_MODULE_0__["default"])(target1, excludedNodes.subNodes);
  const {
    subNodes: subNodes2,
    prevNodeMap: prevNodeMap2
  } = (0,_getsubnodes__WEBPACK_IMPORTED_MODULE_0__["default"])(target2, excludedNodes.subNodes);
  for (const sharedNode of subNodes1) {
    if (subNodes2.has(sharedNode)) {
      const connection = [];
      connection.push(sharedNode);
      let node = prevNodeMap1.get(sharedNode);
      while (node && node !== target1) {
        connection.push(node);
        node = prevNodeMap1.get(node);
      }
      node = prevNodeMap2.get(sharedNode);
      while (node && node !== target2) {
        connection.unshift(node);
        node = prevNodeMap2.get(node);
      }
      console.log('--------');
      console.log({
        target1
      });
      console.log({
        sharedNode
      });
      console.log({
        target2
      });
      console.log({
        connection
      });
      return true;
    }
  }
  return false;
}
function isObject(structure) {
  return typeof structure === 'object' && structure !== null;
}

/***/ }),

/***/ 21543:
/*!****************************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/utils/getsubnodes.js ***!
  \****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getSubNodes)
/* harmony export */ });
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * @module watchdog/utils/getsubnodes
 */
/* globals EventTarget, Event */
function getSubNodes(head, excludedProperties = new Set()) {
  const nodes = [head];
  // @if CK_DEBUG_WATCHDOG // const prevNodeMap = new Map();
  // Nodes are stored to prevent infinite looping.
  const subNodes = new Set();
  let nodeIndex = 0;
  while (nodes.length > nodeIndex) {
    // Incrementing the iterator is much faster than changing size of the array with Array.prototype.shift().
    const node = nodes[nodeIndex++];
    if (subNodes.has(node) || !shouldNodeBeIncluded(node) || excludedProperties.has(node)) {
      continue;
    }
    subNodes.add(node);
    // Handle arrays, maps, sets, custom collections that implements `[ Symbol.iterator ]()`, etc.
    if (Symbol.iterator in node) {
      // The custom editor iterators might cause some problems if the editor is crashed.
      try {
        for (const n of node) {
          nodes.push(n);
          // @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( n ) ) {
          // @if CK_DEBUG_WATCHDOG // 	prevNodeMap.set( n, node );
          // @if CK_DEBUG_WATCHDOG // }
        }
      } catch (err) {
        // Do not log errors for broken structures
        // since we are in the error handling process already.
        // eslint-disable-line no-empty
      }
    } else {
      for (const key in node) {
        // We share a reference via the protobuf library within the editors,
        // hence the shared value should be skipped. Although, it's not a perfect
        // solution since new places like that might occur in the future.
        if (key === 'defaultValue') {
          continue;
        }
        nodes.push(node[key]);
        // @if CK_DEBUG_WATCHDOG // if ( !prevNodeMap.has( node[ key ] ) ) {
        // @if CK_DEBUG_WATCHDOG // 	prevNodeMap.set( node[ key ], node );
        // @if CK_DEBUG_WATCHDOG // }
      }
    }
  }
  // @if CK_DEBUG_WATCHDOG // return { subNodes, prevNodeMap } as any;
  return subNodes;
}
function shouldNodeBeIncluded(node) {
  const type = Object.prototype.toString.call(node);
  const typeOfNode = typeof node;
  return !(typeOfNode === 'number' || typeOfNode === 'boolean' || typeOfNode === 'string' || typeOfNode === 'symbol' || typeOfNode === 'function' || type === '[object Date]' || type === '[object RegExp]' || type === '[object Module]' || node === undefined || node === null ||
  // This flag is meant to exclude singletons shared across editor instances. So when an error is thrown in one editor,
  // the other editors connected through the reference to the same singleton are not restarted. This is a temporary workaround
  // until a better solution is found.
  // More in https://github.com/ckeditor/ckeditor5/issues/12292.
  node._watchdogExcluded ||
  // Skip native DOM objects, e.g. Window, nodes, events, etc.
  node instanceof EventTarget || node instanceof Event);
}

/***/ }),

/***/ 80523:
/*!*******************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-watchdog/src/watchdog.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ Watchdog)
/* harmony export */ });
/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
 */
/**
 * An abstract watchdog class that handles most of the error handling process and the state of the underlying component.
 *
 * See the {@glink features/watchdog Watchdog feature guide} to learn the rationale behind it and how to use it.
 *
 * @internal
 */
class Watchdog {
  /**
   * @param {module:watchdog/watchdog~WatchdogConfig} config The watchdog plugin configuration.
   */
  constructor(config) {
    /**
     * An array of crashes saved as an object with the following properties:
     *
     * * `message`: `String`,
     * * `stack`: `String`,
     * * `date`: `Number`,
     * * `filename`: `String | undefined`,
     * * `lineno`: `Number | undefined`,
     * * `colno`: `Number | undefined`,
     */
    this.crashes = [];
    /**
     * Specifies the state of the item watched by the watchdog. The state can be one of the following values:
     *
     * * `initializing` – Before the first initialization, and after crashes, before the item is ready.
     * * `ready` – A state when the user can interact with the item.
     * * `crashed` – A state when an error occurs. It quickly changes to `initializing` or `crashedPermanently`
     * depending on how many and how frequent errors have been caught recently.
     * * `crashedPermanently` – A state when the watchdog stops reacting to errors and keeps the item it is watching crashed,
     * * `destroyed` – A state when the item is manually destroyed by the user after calling `watchdog.destroy()`.
     */
    this.state = 'initializing';
    /**
     * Returns the result of the `Date.now()` call. It can be overridden in tests to mock time as some popular
     * approaches like `sinon.useFakeTimers()` do not work well with error handling.
     */
    this._now = Date.now;
    this.crashes = [];
    this._crashNumberLimit = typeof config.crashNumberLimit === 'number' ? config.crashNumberLimit : 3;
    this._minimumNonErrorTimePeriod = typeof config.minimumNonErrorTimePeriod === 'number' ? config.minimumNonErrorTimePeriod : 5000;
    this._boundErrorHandler = evt => {
      // `evt.error` is exposed by EventError while `evt.reason` is available in PromiseRejectionEvent.
      const error = 'error' in evt ? evt.error : evt.reason;
      // Note that `evt.reason` might be everything that is in the promise rejection.
      // Similarly everything that is thrown lands in `evt.error`.
      if (error instanceof Error) {
        this._handleError(error, evt);
      }
    };
    this._listeners = {};
    if (!this._restart) {
      throw new Error('The Watchdog class was split into the abstract `Watchdog` class and the `EditorWatchdog` class. ' + 'Please, use `EditorWatchdog` if you have used the `Watchdog` class previously.');
    }
  }
  /**
   * Destroys the watchdog and releases the resources.
   */
  destroy() {
    this._stopErrorHandling();
    this._listeners = {};
  }
  /**
   * Starts listening to a specific event name by registering a callback that will be executed
   * whenever an event with a given name fires.
   *
   * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.
   *
   * @param eventName The event name.
   * @param callback A callback which will be added to event listeners.
   */
  on(eventName, callback) {
    if (!this._listeners[eventName]) {
      this._listeners[eventName] = [];
    }
    this._listeners[eventName].push(callback);
  }
  /**
   * Stops listening to the specified event name by removing the callback from event listeners.
   *
   * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.
   *
   * @param eventName The event name.
   * @param callback A callback which will be removed from event listeners.
   */
  off(eventName, callback) {
    this._listeners[eventName] = this._listeners[eventName].filter(cb => cb !== callback);
  }
  /**
   * Fires an event with a given event name and arguments.
   *
   * Note that this method differs from the CKEditor 5's default `EventEmitterMixin` implementation.
   */
  _fire(eventName, ...args) {
    const callbacks = this._listeners[eventName] || [];
    for (const callback of callbacks) {
      callback.apply(this, [null, ...args]);
    }
  }
  /**
   * Starts error handling by attaching global error handlers.
   */
  _startErrorHandling() {
    window.addEventListener('error', this._boundErrorHandler);
    window.addEventListener('unhandledrejection', this._boundErrorHandler);
  }
  /**
   * Stops error handling by detaching global error handlers.
   */
  _stopErrorHandling() {
    window.removeEventListener('error', this._boundErrorHandler);
    window.removeEventListener('unhandledrejection', this._boundErrorHandler);
  }
  /**
   * Checks if an error comes from the watched item and restarts it.
   * It reacts to {@link module:utils/ckeditorerror~CKEditorError `CKEditorError` errors} only.
   *
   * @fires error
   * @param error Error.
   * @param evt An error event.
   */
  _handleError(error, evt) {
    // @if CK_DEBUG // const err = error as CKEditorError;
    // @if CK_DEBUG // if ( err.is && err.is( 'CKEditorError' ) && err.context === undefined ) {
    // @if CK_DEBUG // console.warn( 'The error is missing its context and Watchdog cannot restart the proper item.' );
    // @if CK_DEBUG // }
    if (this._shouldReactToError(error)) {
      this.crashes.push({
        message: error.message,
        stack: error.stack,
        // `evt.filename`, `evt.lineno` and `evt.colno` are available only in ErrorEvent events
        filename: evt instanceof ErrorEvent ? evt.filename : undefined,
        lineno: evt instanceof ErrorEvent ? evt.lineno : undefined,
        colno: evt instanceof ErrorEvent ? evt.colno : undefined,
        date: this._now()
      });
      const causesRestart = this._shouldRestart();
      this.state = 'crashed';
      this._fire('stateChange');
      this._fire('error', {
        error,
        causesRestart
      });
      if (causesRestart) {
        this._restart();
      } else {
        this.state = 'crashedPermanently';
        this._fire('stateChange');
      }
    }
  }
  /**
   * Checks whether an error should be handled by the watchdog.
   *
   * @param error An error that was caught by the error handling process.
   */
  _shouldReactToError(error) {
    return error.is && error.is('CKEditorError') && error.context !== undefined &&
    // In some cases the watched item should not be restarted - e.g. during the item initialization.
    // That's why the `null` was introduced as a correct error context which does cause restarting.
    error.context !== null &&
    // Do not react to errors if the watchdog is in states other than `ready`.
    this.state === 'ready' && this._isErrorComingFromThisItem(error);
  }
  /**
   * Checks if the watchdog should restart the underlying item.
   */
  _shouldRestart() {
    if (this.crashes.length <= this._crashNumberLimit) {
      return true;
    }
    const lastErrorTime = this.crashes[this.crashes.length - 1].date;
    const firstMeaningfulErrorTime = this.crashes[this.crashes.length - 1 - this._crashNumberLimit].date;
    const averageNonErrorTimePeriod = (lastErrorTime - firstMeaningfulErrorTime) / this._crashNumberLimit;
    return averageNonErrorTimePeriod > this._minimumNonErrorTimePeriod;
  }
}

/***/ }),

/***/ 50692:
/*!*********************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/createPopper.js ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createPopper: () => (/* binding */ createPopper),
/* harmony export */   detectOverflow: () => (/* reexport safe */ _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_8__["default"]),
/* harmony export */   popperGenerator: () => (/* binding */ popperGenerator)
/* harmony export */ });
/* harmony import */ var _dom_utils_getCompositeRect_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./dom-utils/getCompositeRect.js */ 97226);
/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dom-utils/getLayoutRect.js */ 25375);
/* harmony import */ var _dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dom-utils/listScrollParents.js */ 25569);
/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./dom-utils/getOffsetParent.js */ 24884);
/* harmony import */ var _utils_orderModifiers_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/orderModifiers.js */ 96082);
/* harmony import */ var _utils_debounce_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils/debounce.js */ 17655);
/* harmony import */ var _utils_mergeByName_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/mergeByName.js */ 45800);
/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils/detectOverflow.js */ 87269);
/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./dom-utils/instanceOf.js */ 84265);









var DEFAULT_OPTIONS = {
  placement: 'bottom',
  modifiers: [],
  strategy: 'absolute'
};
function areValidElements() {
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
    args[_key] = arguments[_key];
  }
  return !args.some(function (element) {
    return !(element && typeof element.getBoundingClientRect === 'function');
  });
}
function popperGenerator(generatorOptions) {
  if (generatorOptions === void 0) {
    generatorOptions = {};
  }
  var _generatorOptions = generatorOptions,
    _generatorOptions$def = _generatorOptions.defaultModifiers,
    defaultModifiers = _generatorOptions$def === void 0 ? [] : _generatorOptions$def,
    _generatorOptions$def2 = _generatorOptions.defaultOptions,
    defaultOptions = _generatorOptions$def2 === void 0 ? DEFAULT_OPTIONS : _generatorOptions$def2;
  return function createPopper(reference, popper, options) {
    if (options === void 0) {
      options = defaultOptions;
    }
    var state = {
      placement: 'bottom',
      orderedModifiers: [],
      options: Object.assign({}, DEFAULT_OPTIONS, defaultOptions),
      modifiersData: {},
      elements: {
        reference: reference,
        popper: popper
      },
      attributes: {},
      styles: {}
    };
    var effectCleanupFns = [];
    var isDestroyed = false;
    var instance = {
      state: state,
      setOptions: function setOptions(setOptionsAction) {
        var options = typeof setOptionsAction === 'function' ? setOptionsAction(state.options) : setOptionsAction;
        cleanupModifierEffects();
        state.options = Object.assign({}, defaultOptions, state.options, options);
        state.scrollParents = {
          reference: (0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(reference) ? (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(reference) : reference.contextElement ? (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(reference.contextElement) : [],
          popper: (0,_dom_utils_listScrollParents_js__WEBPACK_IMPORTED_MODULE_1__["default"])(popper)
        }; // Orders the modifiers based on their dependencies and `phase`
        // properties

        var orderedModifiers = (0,_utils_orderModifiers_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_utils_mergeByName_js__WEBPACK_IMPORTED_MODULE_3__["default"])([].concat(defaultModifiers, state.options.modifiers))); // Strip out disabled modifiers

        state.orderedModifiers = orderedModifiers.filter(function (m) {
          return m.enabled;
        });
        runModifierEffects();
        return instance.update();
      },
      // Sync update – it will always be executed, even if not necessary. This
      // is useful for low frequency updates where sync behavior simplifies the
      // logic.
      // For high frequency updates (e.g. `resize` and `scroll` events), always
      // prefer the async Popper#update method
      forceUpdate: function forceUpdate() {
        if (isDestroyed) {
          return;
        }
        var _state$elements = state.elements,
          reference = _state$elements.reference,
          popper = _state$elements.popper; // Don't proceed if `reference` or `popper` are not valid elements
        // anymore

        if (!areValidElements(reference, popper)) {
          return;
        } // Store the reference and popper rects to be read by modifiers

        state.rects = {
          reference: (0,_dom_utils_getCompositeRect_js__WEBPACK_IMPORTED_MODULE_4__["default"])(reference, (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_5__["default"])(popper), state.options.strategy === 'fixed'),
          popper: (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__["default"])(popper)
        }; // Modifiers have the ability to reset the current update cycle. The
        // most common use case for this is the `flip` modifier changing the
        // placement, which then needs to re-run all the modifiers, because the
        // logic was previously ran for the previous placement and is therefore
        // stale/incorrect

        state.reset = false;
        state.placement = state.options.placement; // On each update cycle, the `modifiersData` property for each modifier
        // is filled with the initial data specified by the modifier. This means
        // it doesn't persist and is fresh on each update.
        // To ensure persistent data, use `${name}#persistent`

        state.orderedModifiers.forEach(function (modifier) {
          return state.modifiersData[modifier.name] = Object.assign({}, modifier.data);
        });
        for (var index = 0; index < state.orderedModifiers.length; index++) {
          if (state.reset === true) {
            state.reset = false;
            index = -1;
            continue;
          }
          var _state$orderedModifie = state.orderedModifiers[index],
            fn = _state$orderedModifie.fn,
            _state$orderedModifie2 = _state$orderedModifie.options,
            _options = _state$orderedModifie2 === void 0 ? {} : _state$orderedModifie2,
            name = _state$orderedModifie.name;
          if (typeof fn === 'function') {
            state = fn({
              state: state,
              options: _options,
              name: name,
              instance: instance
            }) || state;
          }
        }
      },
      // Async and optimistically optimized update – it will not be executed if
      // not necessary (debounced to run at most once-per-tick)
      update: (0,_utils_debounce_js__WEBPACK_IMPORTED_MODULE_7__["default"])(function () {
        return new Promise(function (resolve) {
          instance.forceUpdate();
          resolve(state);
        });
      }),
      destroy: function destroy() {
        cleanupModifierEffects();
        isDestroyed = true;
      }
    };
    if (!areValidElements(reference, popper)) {
      return instance;
    }
    instance.setOptions(options).then(function (state) {
      if (!isDestroyed && options.onFirstUpdate) {
        options.onFirstUpdate(state);
      }
    }); // Modifiers have the ability to execute arbitrary code before the first
    // update cycle runs. They will be executed in the same order as the update
    // cycle. This is useful when a modifier adds some persistent data that
    // other modifiers need to use, but the modifier is run after the dependent
    // one.

    function runModifierEffects() {
      state.orderedModifiers.forEach(function (_ref) {
        var name = _ref.name,
          _ref$options = _ref.options,
          options = _ref$options === void 0 ? {} : _ref$options,
          effect = _ref.effect;
        if (typeof effect === 'function') {
          var cleanupFn = effect({
            state: state,
            name: name,
            instance: instance,
            options: options
          });
          var noopFn = function noopFn() {};
          effectCleanupFns.push(cleanupFn || noopFn);
        }
      });
    }
    function cleanupModifierEffects() {
      effectCleanupFns.forEach(function (fn) {
        return fn();
      });
      effectCleanupFns = [];
    }
    return instance;
  };
}
var createPopper = /*#__PURE__*/popperGenerator(); // eslint-disable-next-line import/no-unused-modules



/***/ }),

/***/ 91234:
/*!***************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/contains.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ contains)
/* harmony export */ });
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ 84265);

function contains(parent, child) {
  var rootNode = child.getRootNode && child.getRootNode(); // First, attempt with faster native method

  if (parent.contains(child)) {
    return true;
  } // then fallback to custom implementation with Shadow DOM support
  else if (rootNode && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(rootNode)) {
    var next = child;
    do {
      if (next && parent.isSameNode(next)) {
        return true;
      } // $FlowFixMe[prop-missing]: need a better way to handle this...

      next = next.parentNode || next.host;
    } while (next);
  } // Give up, the result is false

  return false;
}

/***/ }),

/***/ 40814:
/*!****************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js ***!
  \****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getBoundingClientRect)
/* harmony export */ });
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ 84265);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/math.js */ 22310);
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindow.js */ 33735);
/* harmony import */ var _isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./isLayoutViewport.js */ 89887);




function getBoundingClientRect(element, includeScale, isFixedStrategy) {
  if (includeScale === void 0) {
    includeScale = false;
  }
  if (isFixedStrategy === void 0) {
    isFixedStrategy = false;
  }
  var clientRect = element.getBoundingClientRect();
  var scaleX = 1;
  var scaleY = 1;
  if (includeScale && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element)) {
    scaleX = element.offsetWidth > 0 ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_1__.round)(clientRect.width) / element.offsetWidth || 1 : 1;
    scaleY = element.offsetHeight > 0 ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_1__.round)(clientRect.height) / element.offsetHeight || 1 : 1;
  }
  var _ref = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(element) ? (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element) : window,
    visualViewport = _ref.visualViewport;
  var addVisualOffsets = !(0,_isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_3__["default"])() && isFixedStrategy;
  var x = (clientRect.left + (addVisualOffsets && visualViewport ? visualViewport.offsetLeft : 0)) / scaleX;
  var y = (clientRect.top + (addVisualOffsets && visualViewport ? visualViewport.offsetTop : 0)) / scaleY;
  var width = clientRect.width / scaleX;
  var height = clientRect.height / scaleY;
  return {
    width: width,
    height: height,
    top: y,
    right: x + width,
    bottom: y + height,
    left: x,
    x: x,
    y: y
  };
}

/***/ }),

/***/ 56455:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getClippingRect)
/* harmony export */ });
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _getViewportRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getViewportRect.js */ 39427);
/* harmony import */ var _getDocumentRect_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./getDocumentRect.js */ 65956);
/* harmony import */ var _listScrollParents_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./listScrollParents.js */ 25569);
/* harmony import */ var _getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./getOffsetParent.js */ 24884);
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./getComputedStyle.js */ 56539);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./instanceOf.js */ 84265);
/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ 40814);
/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./getParentNode.js */ 99351);
/* harmony import */ var _contains_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./contains.js */ 91234);
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./getNodeName.js */ 5752);
/* harmony import */ var _utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/rectToClientRect.js */ 91094);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../utils/math.js */ 22310);














function getInnerBoundingClientRect(element, strategy) {
  var rect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element, false, strategy === 'fixed');
  rect.top = rect.top + element.clientTop;
  rect.left = rect.left + element.clientLeft;
  rect.bottom = rect.top + element.clientHeight;
  rect.right = rect.left + element.clientWidth;
  rect.width = element.clientWidth;
  rect.height = element.clientHeight;
  rect.x = rect.left;
  rect.y = rect.top;
  return rect;
}
function getClientRectFromMixedType(element, clippingParent, strategy) {
  return clippingParent === _enums_js__WEBPACK_IMPORTED_MODULE_1__.viewport ? (0,_utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_getViewportRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element, strategy)) : (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clippingParent) ? getInnerBoundingClientRect(clippingParent, strategy) : (0,_utils_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_2__["default"])((0,_getDocumentRect_js__WEBPACK_IMPORTED_MODULE_5__["default"])((0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(element)));
} // A "clipping parent" is an overflowable container with the characteristic of
// clipping (or hiding) overflowing elements with a position different from
// `initial`

function getClippingParents(element) {
  var clippingParents = (0,_listScrollParents_js__WEBPACK_IMPORTED_MODULE_7__["default"])((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_8__["default"])(element));
  var canEscapeClipping = ['absolute', 'fixed'].indexOf((0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_9__["default"])(element).position) >= 0;
  var clipperElement = canEscapeClipping && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isHTMLElement)(element) ? (0,_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_10__["default"])(element) : element;
  if (!(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clipperElement)) {
    return [];
  } // $FlowFixMe[incompatible-return]: https://github.com/facebook/flow/issues/1414

  return clippingParents.filter(function (clippingParent) {
    return (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(clippingParent) && (0,_contains_js__WEBPACK_IMPORTED_MODULE_11__["default"])(clippingParent, clipperElement) && (0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_12__["default"])(clippingParent) !== 'body';
  });
} // Gets the maximum area that the element is visible in due to any number of
// clipping parents

function getClippingRect(element, boundary, rootBoundary, strategy) {
  var mainClippingParents = boundary === 'clippingParents' ? getClippingParents(element) : [].concat(boundary);
  var clippingParents = [].concat(mainClippingParents, [rootBoundary]);
  var firstClippingParent = clippingParents[0];
  var clippingRect = clippingParents.reduce(function (accRect, clippingParent) {
    var rect = getClientRectFromMixedType(element, clippingParent, strategy);
    accRect.top = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.max)(rect.top, accRect.top);
    accRect.right = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.min)(rect.right, accRect.right);
    accRect.bottom = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.min)(rect.bottom, accRect.bottom);
    accRect.left = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_13__.max)(rect.left, accRect.left);
    return accRect;
  }, getClientRectFromMixedType(element, firstClippingParent, strategy));
  clippingRect.width = clippingRect.right - clippingRect.left;
  clippingRect.height = clippingRect.bottom - clippingRect.top;
  clippingRect.x = clippingRect.left;
  clippingRect.y = clippingRect.top;
  return clippingRect;
}

/***/ }),

/***/ 97226:
/*!***********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getCompositeRect)
/* harmony export */ });
/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getBoundingClientRect.js */ 40814);
/* harmony import */ var _getNodeScroll_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./getNodeScroll.js */ 86826);
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getNodeName.js */ 5752);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ 84265);
/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ 34693);
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./isScrollParent.js */ 9586);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/math.js */ 22310);








function isElementScaled(element) {
  var rect = element.getBoundingClientRect();
  var scaleX = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(rect.width) / element.offsetWidth || 1;
  var scaleY = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(rect.height) / element.offsetHeight || 1;
  return scaleX !== 1 || scaleY !== 1;
} // Returns the composite rect of an element relative to its offsetParent.
// Composite means it takes into account transforms as well as layout.

function getCompositeRect(elementOrVirtualElement, offsetParent, isFixed) {
  if (isFixed === void 0) {
    isFixed = false;
  }
  var isOffsetParentAnElement = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent);
  var offsetParentIsScaled = (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent) && isElementScaled(offsetParent);
  var documentElement = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(offsetParent);
  var rect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(elementOrVirtualElement, offsetParentIsScaled, isFixed);
  var scroll = {
    scrollLeft: 0,
    scrollTop: 0
  };
  var offsets = {
    x: 0,
    y: 0
  };
  if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {
    if ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) !== 'body' ||
    // https://github.com/popperjs/popper-core/issues/1078
    (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_5__["default"])(documentElement)) {
      scroll = (0,_getNodeScroll_js__WEBPACK_IMPORTED_MODULE_6__["default"])(offsetParent);
    }
    if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(offsetParent)) {
      offsets = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])(offsetParent, true);
      offsets.x += offsetParent.clientLeft;
      offsets.y += offsetParent.clientTop;
    } else if (documentElement) {
      offsets.x = (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_7__["default"])(documentElement);
    }
  }
  return {
    x: rect.left + scroll.scrollLeft - offsets.x,
    y: rect.top + scroll.scrollTop - offsets.y,
    width: rect.width,
    height: rect.height
  };
}

/***/ }),

/***/ 56539:
/*!***********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getComputedStyle)
/* harmony export */ });
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ 33735);

function getComputedStyle(element) {
  return (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element).getComputedStyle(element);
}

/***/ }),

/***/ 63364:
/*!*************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getDocumentElement)
/* harmony export */ });
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ 84265);

function getDocumentElement(element) {
  // $FlowFixMe[incompatible-return]: assume body is always available
  return (((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isElement)(element) ? element.ownerDocument :
  // $FlowFixMe[prop-missing]
  element.document) || window.document).documentElement;
}

/***/ }),

/***/ 65956:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getDocumentRect)
/* harmony export */ });
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getComputedStyle.js */ 56539);
/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ 34693);
/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getWindowScroll.js */ 9354);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/math.js */ 22310);




 // Gets the entire size of the scrollable document area, even extending outside
// of the `<html>` and `<body>` rect bounds if horizontally scrollable

function getDocumentRect(element) {
  var _element$ownerDocumen;
  var html = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element);
  var winScroll = (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element);
  var body = (_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body;
  var width = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.scrollWidth, html.clientWidth, body ? body.scrollWidth : 0, body ? body.clientWidth : 0);
  var height = (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.scrollHeight, html.clientHeight, body ? body.scrollHeight : 0, body ? body.clientHeight : 0);
  var x = -winScroll.scrollLeft + (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element);
  var y = -winScroll.scrollTop;
  if ((0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_4__["default"])(body || html).direction === 'rtl') {
    x += (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_2__.max)(html.clientWidth, body ? body.clientWidth : 0) - width;
  }
  return {
    width: width,
    height: height,
    x: x,
    y: y
  };
}

/***/ }),

/***/ 49669:
/*!***************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js ***!
  \***************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getHTMLElementScroll)
/* harmony export */ });
function getHTMLElementScroll(element) {
  return {
    scrollLeft: element.scrollLeft,
    scrollTop: element.scrollTop
  };
}

/***/ }),

/***/ 25375:
/*!********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getLayoutRect)
/* harmony export */ });
/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ 40814);
 // Returns the layout rect of an element relative to its offsetParent. Layout
// means it doesn't take into account transforms.

function getLayoutRect(element) {
  var clientRect = (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element); // Use the clientRect sizes if it's not been transformed.
  // Fixes https://github.com/popperjs/popper-core/issues/1223

  var width = element.offsetWidth;
  var height = element.offsetHeight;
  if (Math.abs(clientRect.width - width) <= 1) {
    width = clientRect.width;
  }
  if (Math.abs(clientRect.height - height) <= 1) {
    height = clientRect.height;
  }
  return {
    x: element.offsetLeft,
    y: element.offsetTop,
    width: width,
    height: height
  };
}

/***/ }),

/***/ 5752:
/*!******************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getNodeName.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getNodeName)
/* harmony export */ });
function getNodeName(element) {
  return element ? (element.nodeName || '').toLowerCase() : null;
}

/***/ }),

/***/ 86826:
/*!********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getNodeScroll)
/* harmony export */ });
/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindowScroll.js */ 9354);
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ 33735);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ 84265);
/* harmony import */ var _getHTMLElementScroll_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getHTMLElementScroll.js */ 49669);




function getNodeScroll(node) {
  if (node === (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node) || !(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(node)) {
    return (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__["default"])(node);
  } else {
    return (0,_getHTMLElementScroll_js__WEBPACK_IMPORTED_MODULE_3__["default"])(node);
  }
}

/***/ }),

/***/ 24884:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getOffsetParent)
/* harmony export */ });
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./getWindow.js */ 33735);
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./getNodeName.js */ 5752);
/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getComputedStyle.js */ 56539);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./instanceOf.js */ 84265);
/* harmony import */ var _isTableElement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./isTableElement.js */ 9163);
/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ 99351);
/* harmony import */ var _utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/userAgent.js */ 42226);







function getTrueOffsetParent(element) {
  if (!(0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) ||
  // https://github.com/popperjs/popper-core/issues/837
  (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element).position === 'fixed') {
    return null;
  }
  return element.offsetParent;
} // `.offsetParent` reports `null` for fixed elements, while absolute elements
// return the containing block

function getContainingBlock(element) {
  var isFirefox = /firefox/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__["default"])());
  var isIE = /Trident/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_2__["default"])());
  if (isIE && (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element)) {
    // In IE 9, 10 and 11 fixed elements containing block is always established by the viewport
    var elementCss = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element);
    if (elementCss.position === 'fixed') {
      return null;
    }
  }
  var currentNode = (0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element);
  if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isShadowRoot)(currentNode)) {
    currentNode = currentNode.host;
  }
  while ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(currentNode) && ['html', 'body'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(currentNode)) < 0) {
    var css = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(currentNode); // This is non-exhaustive but covers the most common CSS properties that
    // create a containing block.
    // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block

    if (css.transform !== 'none' || css.perspective !== 'none' || css.contain === 'paint' || ['transform', 'perspective'].indexOf(css.willChange) !== -1 || isFirefox && css.willChange === 'filter' || isFirefox && css.filter && css.filter !== 'none') {
      return currentNode;
    } else {
      currentNode = currentNode.parentNode;
    }
  }
  return null;
} // Gets the closest ancestor positioned element. Handles some edge cases,
// such as table ancestors and cross browser bugs.

function getOffsetParent(element) {
  var window = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_5__["default"])(element);
  var offsetParent = getTrueOffsetParent(element);
  while (offsetParent && (0,_isTableElement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(offsetParent) && (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(offsetParent).position === 'static') {
    offsetParent = getTrueOffsetParent(offsetParent);
  }
  if (offsetParent && ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) === 'html' || (0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_4__["default"])(offsetParent) === 'body' && (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_1__["default"])(offsetParent).position === 'static')) {
    return window;
  }
  return offsetParent || getContainingBlock(element) || window;
}

/***/ }),

/***/ 99351:
/*!********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getParentNode.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getParentNode)
/* harmony export */ });
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ 5752);
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ 84265);



function getParentNode(element) {
  if ((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element) === 'html') {
    return element;
  }
  return (
    // this is a quicker (but less type safe) way to save quite some bytes from the bundle
    // $FlowFixMe[incompatible-return]
    // $FlowFixMe[prop-missing]
    element.assignedSlot ||
    // step into the shadow DOM of the parent of a slotted node
    element.parentNode || (
    // DOM Element detected
    (0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isShadowRoot)(element) ? element.host : null) ||
    // ShadowRoot detected
    // $FlowFixMe[incompatible-call]: HTMLElement is a Node
    (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element) // fallback
  );
}

/***/ }),

/***/ 92958:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getScrollParent)
/* harmony export */ });
/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ 99351);
/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isScrollParent.js */ 9586);
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ 5752);
/* harmony import */ var _instanceOf_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./instanceOf.js */ 84265);




function getScrollParent(node) {
  if (['html', 'body', '#document'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node)) >= 0) {
    // $FlowFixMe[incompatible-return]: assume body is always available
    return node.ownerDocument.body;
  }
  if ((0,_instanceOf_js__WEBPACK_IMPORTED_MODULE_1__.isHTMLElement)(node) && (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(node)) {
    return node;
  }
  return getScrollParent((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(node));
}

/***/ }),

/***/ 39427:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getViewportRect)
/* harmony export */ });
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ 33735);
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getWindowScrollBarX.js */ 34693);
/* harmony import */ var _isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isLayoutViewport.js */ 89887);




function getViewportRect(element, strategy) {
  var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element);
  var html = (0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element);
  var visualViewport = win.visualViewport;
  var width = html.clientWidth;
  var height = html.clientHeight;
  var x = 0;
  var y = 0;
  if (visualViewport) {
    width = visualViewport.width;
    height = visualViewport.height;
    var layoutViewport = (0,_isLayoutViewport_js__WEBPACK_IMPORTED_MODULE_2__["default"])();
    if (layoutViewport || !layoutViewport && strategy === 'fixed') {
      x = visualViewport.offsetLeft;
      y = visualViewport.offsetTop;
    }
  }
  return {
    width: width,
    height: height,
    x: x + (0,_getWindowScrollBarX_js__WEBPACK_IMPORTED_MODULE_3__["default"])(element),
    y: y
  };
}

/***/ }),

/***/ 33735:
/*!****************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getWindow.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getWindow)
/* harmony export */ });
function getWindow(node) {
  if (node == null) {
    return window;
  }
  if (node.toString() !== '[object Window]') {
    var ownerDocument = node.ownerDocument;
    return ownerDocument ? ownerDocument.defaultView || window : window;
  }
  return node;
}

/***/ }),

/***/ 9354:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getWindowScroll)
/* harmony export */ });
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ 33735);

function getWindowScroll(node) {
  var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node);
  var scrollLeft = win.pageXOffset;
  var scrollTop = win.pageYOffset;
  return {
    scrollLeft: scrollLeft,
    scrollTop: scrollTop
  };
}

/***/ }),

/***/ 34693:
/*!**************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getWindowScrollBarX)
/* harmony export */ });
/* harmony import */ var _getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBoundingClientRect.js */ 40814);
/* harmony import */ var _getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getDocumentElement.js */ 63364);
/* harmony import */ var _getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./getWindowScroll.js */ 9354);



function getWindowScrollBarX(element) {
  // If <html> has a CSS width greater than the viewport, then this will be
  // incorrect for RTL.
  // Popper 1 is broken in this case and never had a bug report so let's assume
  // it's not an issue. I don't think anyone ever specifies width on <html>
  // anyway.
  // Browsers where the left scrollbar doesn't cause an issue report `0` for
  // this (e.g. Edge 2019, IE11, Safari)
  return (0,_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_0__["default"])((0,_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)).left + (0,_getWindowScroll_js__WEBPACK_IMPORTED_MODULE_2__["default"])(element).scrollLeft;
}

/***/ }),

/***/ 84265:
/*!*****************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/instanceOf.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isElement: () => (/* binding */ isElement),
/* harmony export */   isHTMLElement: () => (/* binding */ isHTMLElement),
/* harmony export */   isShadowRoot: () => (/* binding */ isShadowRoot)
/* harmony export */ });
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getWindow.js */ 33735);

function isElement(node) {
  var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).Element;
  return node instanceof OwnElement || node instanceof Element;
}
function isHTMLElement(node) {
  var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).HTMLElement;
  return node instanceof OwnElement || node instanceof HTMLElement;
}
function isShadowRoot(node) {
  // IE 11 has no ShadowRoot
  if (typeof ShadowRoot === 'undefined') {
    return false;
  }
  var OwnElement = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(node).ShadowRoot;
  return node instanceof OwnElement || node instanceof ShadowRoot;
}


/***/ }),

/***/ 89887:
/*!***********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ isLayoutViewport)
/* harmony export */ });
/* harmony import */ var _utils_userAgent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/userAgent.js */ 42226);

function isLayoutViewport() {
  return !/^((?!chrome|android).)*safari/i.test((0,_utils_userAgent_js__WEBPACK_IMPORTED_MODULE_0__["default"])());
}

/***/ }),

/***/ 9586:
/*!*********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ isScrollParent)
/* harmony export */ });
/* harmony import */ var _getComputedStyle_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getComputedStyle.js */ 56539);

function isScrollParent(element) {
  // Firefox wants us to check `-x` and `-y` variations as well
  var _getComputedStyle = (0,_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element),
    overflow = _getComputedStyle.overflow,
    overflowX = _getComputedStyle.overflowX,
    overflowY = _getComputedStyle.overflowY;
  return /auto|scroll|overlay|hidden/.test(overflow + overflowY + overflowX);
}

/***/ }),

/***/ 9163:
/*!*********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/isTableElement.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ isTableElement)
/* harmony export */ });
/* harmony import */ var _getNodeName_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getNodeName.js */ 5752);

function isTableElement(element) {
  return ['table', 'td', 'th'].indexOf((0,_getNodeName_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element)) >= 0;
}

/***/ }),

/***/ 25569:
/*!************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ listScrollParents)
/* harmony export */ });
/* harmony import */ var _getScrollParent_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getScrollParent.js */ 92958);
/* harmony import */ var _getParentNode_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getParentNode.js */ 99351);
/* harmony import */ var _getWindow_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getWindow.js */ 33735);
/* harmony import */ var _isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isScrollParent.js */ 9586);




/*
given a DOM element, return the list of all scroll parents, up the list of ancesors
until we get to the top window object. This list is what we attach scroll listeners
to, because if any of these parent elements scroll, we'll need to re-calculate the
reference element's position.
*/

function listScrollParents(element, list) {
  var _element$ownerDocumen;
  if (list === void 0) {
    list = [];
  }
  var scrollParent = (0,_getScrollParent_js__WEBPACK_IMPORTED_MODULE_0__["default"])(element);
  var isBody = scrollParent === ((_element$ownerDocumen = element.ownerDocument) == null ? void 0 : _element$ownerDocumen.body);
  var win = (0,_getWindow_js__WEBPACK_IMPORTED_MODULE_1__["default"])(scrollParent);
  var target = isBody ? [win].concat(win.visualViewport || [], (0,_isScrollParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(scrollParent) ? scrollParent : []) : scrollParent;
  var updatedList = list.concat(target);
  return isBody ? updatedList :
  // $FlowFixMe[incompatible-call]: isBody tells us target will be an HTMLElement here
  updatedList.concat(listScrollParents((0,_getParentNode_js__WEBPACK_IMPORTED_MODULE_3__["default"])(target)));
}

/***/ }),

/***/ 39322:
/*!**************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/enums.js ***!
  \**************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   afterMain: () => (/* binding */ afterMain),
/* harmony export */   afterRead: () => (/* binding */ afterRead),
/* harmony export */   afterWrite: () => (/* binding */ afterWrite),
/* harmony export */   auto: () => (/* binding */ auto),
/* harmony export */   basePlacements: () => (/* binding */ basePlacements),
/* harmony export */   beforeMain: () => (/* binding */ beforeMain),
/* harmony export */   beforeRead: () => (/* binding */ beforeRead),
/* harmony export */   beforeWrite: () => (/* binding */ beforeWrite),
/* harmony export */   bottom: () => (/* binding */ bottom),
/* harmony export */   clippingParents: () => (/* binding */ clippingParents),
/* harmony export */   end: () => (/* binding */ end),
/* harmony export */   left: () => (/* binding */ left),
/* harmony export */   main: () => (/* binding */ main),
/* harmony export */   modifierPhases: () => (/* binding */ modifierPhases),
/* harmony export */   placements: () => (/* binding */ placements),
/* harmony export */   popper: () => (/* binding */ popper),
/* harmony export */   read: () => (/* binding */ read),
/* harmony export */   reference: () => (/* binding */ reference),
/* harmony export */   right: () => (/* binding */ right),
/* harmony export */   start: () => (/* binding */ start),
/* harmony export */   top: () => (/* binding */ top),
/* harmony export */   variationPlacements: () => (/* binding */ variationPlacements),
/* harmony export */   viewport: () => (/* binding */ viewport),
/* harmony export */   write: () => (/* binding */ write)
/* harmony export */ });
var top = 'top';
var bottom = 'bottom';
var right = 'right';
var left = 'left';
var auto = 'auto';
var basePlacements = [top, bottom, right, left];
var start = 'start';
var end = 'end';
var clippingParents = 'clippingParents';
var viewport = 'viewport';
var popper = 'popper';
var reference = 'reference';
var variationPlacements = /*#__PURE__*/basePlacements.reduce(function (acc, placement) {
  return acc.concat([placement + "-" + start, placement + "-" + end]);
}, []);
var placements = /*#__PURE__*/[].concat(basePlacements, [auto]).reduce(function (acc, placement) {
  return acc.concat([placement, placement + "-" + start, placement + "-" + end]);
}, []); // modifiers that need to read the DOM

var beforeRead = 'beforeRead';
var read = 'read';
var afterRead = 'afterRead'; // pure-logic modifiers

var beforeMain = 'beforeMain';
var main = 'main';
var afterMain = 'afterMain'; // modifier with the purpose to write to the DOM (or write into a framework state)

var beforeWrite = 'beforeWrite';
var write = 'write';
var afterWrite = 'afterWrite';
var modifierPhases = [beforeRead, read, afterRead, beforeMain, main, afterMain, beforeWrite, write, afterWrite];

/***/ }),

/***/ 26643:
/*!******************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/applyStyles.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../dom-utils/getNodeName.js */ 5752);
/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../dom-utils/instanceOf.js */ 84265);

 // This modifier takes the styles prepared by the `computeStyles` modifier
// and applies them to the HTMLElements such as popper and arrow

function applyStyles(_ref) {
  var state = _ref.state;
  Object.keys(state.elements).forEach(function (name) {
    var style = state.styles[name] || {};
    var attributes = state.attributes[name] || {};
    var element = state.elements[name]; // arrow is optional + virtual elements

    if (!(0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) || !(0,_dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)) {
      return;
    } // Flow doesn't support to extend this property, but it's the most
    // effective way to apply styles to an HTMLElement
    // $FlowFixMe[cannot-write]

    Object.assign(element.style, style);
    Object.keys(attributes).forEach(function (name) {
      var value = attributes[name];
      if (value === false) {
        element.removeAttribute(name);
      } else {
        element.setAttribute(name, value === true ? '' : value);
      }
    });
  });
}
function effect(_ref2) {
  var state = _ref2.state;
  var initialStyles = {
    popper: {
      position: state.options.strategy,
      left: '0',
      top: '0',
      margin: '0'
    },
    arrow: {
      position: 'absolute'
    },
    reference: {}
  };
  Object.assign(state.elements.popper.style, initialStyles.popper);
  state.styles = initialStyles;
  if (state.elements.arrow) {
    Object.assign(state.elements.arrow.style, initialStyles.arrow);
  }
  return function () {
    Object.keys(state.elements).forEach(function (name) {
      var element = state.elements[name];
      var attributes = state.attributes[name] || {};
      var styleProperties = Object.keys(state.styles.hasOwnProperty(name) ? state.styles[name] : initialStyles[name]); // Set all values to an empty string to unset them

      var style = styleProperties.reduce(function (style, property) {
        style[property] = '';
        return style;
      }, {}); // arrow is optional + virtual elements

      if (!(0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_0__.isHTMLElement)(element) || !(0,_dom_utils_getNodeName_js__WEBPACK_IMPORTED_MODULE_1__["default"])(element)) {
        return;
      }
      Object.assign(element.style, style);
      Object.keys(attributes).forEach(function (attribute) {
        element.removeAttribute(attribute);
      });
    });
  };
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'applyStyles',
  enabled: true,
  phase: 'write',
  fn: applyStyles,
  effect: effect,
  requires: ['computeStyles']
});

/***/ }),

/***/ 87348:
/*!************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/arrow.js ***!
  \************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ 98532);
/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getLayoutRect.js */ 25375);
/* harmony import */ var _dom_utils_contains_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../dom-utils/contains.js */ 91234);
/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ 24884);
/* harmony import */ var _utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/getMainAxisFromPlacement.js */ 69155);
/* harmony import */ var _utils_within_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/within.js */ 12268);
/* harmony import */ var _utils_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/mergePaddingObject.js */ 25714);
/* harmony import */ var _utils_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/expandToHashMap.js */ 74019);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../enums.js */ 39322);








 // eslint-disable-next-line import/no-unused-modules

var toPaddingObject = function toPaddingObject(padding, state) {
  padding = typeof padding === 'function' ? padding(Object.assign({}, state.rects, {
    placement: state.placement
  })) : padding;
  return (0,_utils_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(typeof padding !== 'number' ? padding : (0,_utils_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_1__["default"])(padding, _enums_js__WEBPACK_IMPORTED_MODULE_2__.basePlacements));
};
function arrow(_ref) {
  var _state$modifiersData$;
  var state = _ref.state,
    name = _ref.name,
    options = _ref.options;
  var arrowElement = state.elements.arrow;
  var popperOffsets = state.modifiersData.popperOffsets;
  var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(state.placement);
  var axis = (0,_utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(basePlacement);
  var isVertical = [_enums_js__WEBPACK_IMPORTED_MODULE_2__.left, _enums_js__WEBPACK_IMPORTED_MODULE_2__.right].indexOf(basePlacement) >= 0;
  var len = isVertical ? 'height' : 'width';
  if (!arrowElement || !popperOffsets) {
    return;
  }
  var paddingObject = toPaddingObject(options.padding, state);
  var arrowRect = (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_5__["default"])(arrowElement);
  var minProp = axis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_2__.top : _enums_js__WEBPACK_IMPORTED_MODULE_2__.left;
  var maxProp = axis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_2__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_2__.right;
  var endDiff = state.rects.reference[len] + state.rects.reference[axis] - popperOffsets[axis] - state.rects.popper[len];
  var startDiff = popperOffsets[axis] - state.rects.reference[axis];
  var arrowOffsetParent = (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_6__["default"])(arrowElement);
  var clientSize = arrowOffsetParent ? axis === 'y' ? arrowOffsetParent.clientHeight || 0 : arrowOffsetParent.clientWidth || 0 : 0;
  var centerToReference = endDiff / 2 - startDiff / 2; // Make sure the arrow doesn't overflow the popper if the center point is
  // outside of the popper bounds

  var min = paddingObject[minProp];
  var max = clientSize - arrowRect[len] - paddingObject[maxProp];
  var center = clientSize / 2 - arrowRect[len] / 2 + centerToReference;
  var offset = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_7__.within)(min, center, max); // Prevents breaking syntax highlighting...

  var axisProp = axis;
  state.modifiersData[name] = (_state$modifiersData$ = {}, _state$modifiersData$[axisProp] = offset, _state$modifiersData$.centerOffset = offset - center, _state$modifiersData$);
}
function effect(_ref2) {
  var state = _ref2.state,
    options = _ref2.options;
  var _options$element = options.element,
    arrowElement = _options$element === void 0 ? '[data-popper-arrow]' : _options$element;
  if (arrowElement == null) {
    return;
  } // CSS selector

  if (typeof arrowElement === 'string') {
    arrowElement = state.elements.popper.querySelector(arrowElement);
    if (!arrowElement) {
      return;
    }
  }
  if (!(0,_dom_utils_contains_js__WEBPACK_IMPORTED_MODULE_8__["default"])(state.elements.popper, arrowElement)) {
    return;
  }
  state.elements.arrow = arrowElement;
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'arrow',
  enabled: true,
  phase: 'main',
  fn: arrow,
  effect: effect,
  requires: ['popperOffsets'],
  requiresIfExists: ['preventOverflow']
});

/***/ }),

/***/ 5474:
/*!********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/computeStyles.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   mapToStyles: () => (/* binding */ mapToStyles)
/* harmony export */ });
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ 24884);
/* harmony import */ var _dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../dom-utils/getWindow.js */ 33735);
/* harmony import */ var _dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dom-utils/getDocumentElement.js */ 63364);
/* harmony import */ var _dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getComputedStyle.js */ 56539);
/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ 98532);
/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/getVariation.js */ 68089);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/math.js */ 22310);







 // eslint-disable-next-line import/no-unused-modules

var unsetSides = {
  top: 'auto',
  right: 'auto',
  bottom: 'auto',
  left: 'auto'
}; // Round the offsets to the nearest suitable subpixel based on the DPR.
// Zooming can change the DPR, but it seems to report a value that will
// cleanly divide the values into the appropriate subpixels.

function roundOffsetsByDPR(_ref, win) {
  var x = _ref.x,
    y = _ref.y;
  var dpr = win.devicePixelRatio || 1;
  return {
    x: (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(x * dpr) / dpr || 0,
    y: (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_0__.round)(y * dpr) / dpr || 0
  };
}
function mapToStyles(_ref2) {
  var _Object$assign2;
  var popper = _ref2.popper,
    popperRect = _ref2.popperRect,
    placement = _ref2.placement,
    variation = _ref2.variation,
    offsets = _ref2.offsets,
    position = _ref2.position,
    gpuAcceleration = _ref2.gpuAcceleration,
    adaptive = _ref2.adaptive,
    roundOffsets = _ref2.roundOffsets,
    isFixed = _ref2.isFixed;
  var _offsets$x = offsets.x,
    x = _offsets$x === void 0 ? 0 : _offsets$x,
    _offsets$y = offsets.y,
    y = _offsets$y === void 0 ? 0 : _offsets$y;
  var _ref3 = typeof roundOffsets === 'function' ? roundOffsets({
    x: x,
    y: y
  }) : {
    x: x,
    y: y
  };
  x = _ref3.x;
  y = _ref3.y;
  var hasX = offsets.hasOwnProperty('x');
  var hasY = offsets.hasOwnProperty('y');
  var sideX = _enums_js__WEBPACK_IMPORTED_MODULE_1__.left;
  var sideY = _enums_js__WEBPACK_IMPORTED_MODULE_1__.top;
  var win = window;
  if (adaptive) {
    var offsetParent = (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_2__["default"])(popper);
    var heightProp = 'clientHeight';
    var widthProp = 'clientWidth';
    if (offsetParent === (0,_dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_3__["default"])(popper)) {
      offsetParent = (0,_dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(popper);
      if ((0,_dom_utils_getComputedStyle_js__WEBPACK_IMPORTED_MODULE_5__["default"])(offsetParent).position !== 'static' && position === 'absolute') {
        heightProp = 'scrollHeight';
        widthProp = 'scrollWidth';
      }
    } // $FlowFixMe[incompatible-cast]: force type refinement, we compare offsetParent with window above, but Flow doesn't detect it

    offsetParent = offsetParent;
    if (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.top || (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.left || placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.right) && variation === _enums_js__WEBPACK_IMPORTED_MODULE_1__.end) {
      sideY = _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom;
      var offsetY = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.height :
      // $FlowFixMe[prop-missing]
      offsetParent[heightProp];
      y -= offsetY - popperRect.height;
      y *= gpuAcceleration ? 1 : -1;
    }
    if (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.left || (placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.top || placement === _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom) && variation === _enums_js__WEBPACK_IMPORTED_MODULE_1__.end) {
      sideX = _enums_js__WEBPACK_IMPORTED_MODULE_1__.right;
      var offsetX = isFixed && offsetParent === win && win.visualViewport ? win.visualViewport.width :
      // $FlowFixMe[prop-missing]
      offsetParent[widthProp];
      x -= offsetX - popperRect.width;
      x *= gpuAcceleration ? 1 : -1;
    }
  }
  var commonStyles = Object.assign({
    position: position
  }, adaptive && unsetSides);
  var _ref4 = roundOffsets === true ? roundOffsetsByDPR({
    x: x,
    y: y
  }, (0,_dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_3__["default"])(popper)) : {
    x: x,
    y: y
  };
  x = _ref4.x;
  y = _ref4.y;
  if (gpuAcceleration) {
    var _Object$assign;
    return Object.assign({}, commonStyles, (_Object$assign = {}, _Object$assign[sideY] = hasY ? '0' : '', _Object$assign[sideX] = hasX ? '0' : '', _Object$assign.transform = (win.devicePixelRatio || 1) <= 1 ? "translate(" + x + "px, " + y + "px)" : "translate3d(" + x + "px, " + y + "px, 0)", _Object$assign));
  }
  return Object.assign({}, commonStyles, (_Object$assign2 = {}, _Object$assign2[sideY] = hasY ? y + "px" : '', _Object$assign2[sideX] = hasX ? x + "px" : '', _Object$assign2.transform = '', _Object$assign2));
}
function computeStyles(_ref5) {
  var state = _ref5.state,
    options = _ref5.options;
  var _options$gpuAccelerat = options.gpuAcceleration,
    gpuAcceleration = _options$gpuAccelerat === void 0 ? true : _options$gpuAccelerat,
    _options$adaptive = options.adaptive,
    adaptive = _options$adaptive === void 0 ? true : _options$adaptive,
    _options$roundOffsets = options.roundOffsets,
    roundOffsets = _options$roundOffsets === void 0 ? true : _options$roundOffsets;
  var commonStyles = {
    placement: (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state.placement),
    variation: (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_7__["default"])(state.placement),
    popper: state.elements.popper,
    popperRect: state.rects.popper,
    gpuAcceleration: gpuAcceleration,
    isFixed: state.options.strategy === 'fixed'
  };
  if (state.modifiersData.popperOffsets != null) {
    state.styles.popper = Object.assign({}, state.styles.popper, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.popperOffsets,
      position: state.options.strategy,
      adaptive: adaptive,
      roundOffsets: roundOffsets
    })));
  }
  if (state.modifiersData.arrow != null) {
    state.styles.arrow = Object.assign({}, state.styles.arrow, mapToStyles(Object.assign({}, commonStyles, {
      offsets: state.modifiersData.arrow,
      position: 'absolute',
      adaptive: false,
      roundOffsets: roundOffsets
    })));
  }
  state.attributes.popper = Object.assign({}, state.attributes.popper, {
    'data-popper-placement': state.placement
  });
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'computeStyles',
  enabled: true,
  phase: 'beforeWrite',
  fn: computeStyles,
  data: {}
});

/***/ }),

/***/ 15496:
/*!*********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/eventListeners.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../dom-utils/getWindow.js */ 33735);
 // eslint-disable-next-line import/no-unused-modules

var passive = {
  passive: true
};
function effect(_ref) {
  var state = _ref.state,
    instance = _ref.instance,
    options = _ref.options;
  var _options$scroll = options.scroll,
    scroll = _options$scroll === void 0 ? true : _options$scroll,
    _options$resize = options.resize,
    resize = _options$resize === void 0 ? true : _options$resize;
  var window = (0,_dom_utils_getWindow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(state.elements.popper);
  var scrollParents = [].concat(state.scrollParents.reference, state.scrollParents.popper);
  if (scroll) {
    scrollParents.forEach(function (scrollParent) {
      scrollParent.addEventListener('scroll', instance.update, passive);
    });
  }
  if (resize) {
    window.addEventListener('resize', instance.update, passive);
  }
  return function () {
    if (scroll) {
      scrollParents.forEach(function (scrollParent) {
        scrollParent.removeEventListener('scroll', instance.update, passive);
      });
    }
    if (resize) {
      window.removeEventListener('resize', instance.update, passive);
    }
  };
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'eventListeners',
  enabled: true,
  phase: 'write',
  fn: function fn() {},
  effect: effect,
  data: {}
});

/***/ }),

/***/ 94970:
/*!***********************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/flip.js ***!
  \***********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/getOppositePlacement.js */ 55436);
/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ 98532);
/* harmony import */ var _utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getOppositeVariationPlacement.js */ 26207);
/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../utils/detectOverflow.js */ 87269);
/* harmony import */ var _utils_computeAutoPlacement_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/computeAutoPlacement.js */ 19861);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../utils/getVariation.js */ 68089);






 // eslint-disable-next-line import/no-unused-modules

function getExpandedFallbackPlacements(placement) {
  if ((0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.auto) {
    return [];
  }
  var oppositePlacement = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(placement);
  return [(0,_utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(placement), oppositePlacement, (0,_utils_getOppositeVariationPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(oppositePlacement)];
}
function flip(_ref) {
  var state = _ref.state,
    options = _ref.options,
    name = _ref.name;
  if (state.modifiersData[name]._skip) {
    return;
  }
  var _options$mainAxis = options.mainAxis,
    checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
    _options$altAxis = options.altAxis,
    checkAltAxis = _options$altAxis === void 0 ? true : _options$altAxis,
    specifiedFallbackPlacements = options.fallbackPlacements,
    padding = options.padding,
    boundary = options.boundary,
    rootBoundary = options.rootBoundary,
    altBoundary = options.altBoundary,
    _options$flipVariatio = options.flipVariations,
    flipVariations = _options$flipVariatio === void 0 ? true : _options$flipVariatio,
    allowedAutoPlacements = options.allowedAutoPlacements;
  var preferredPlacement = state.options.placement;
  var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(preferredPlacement);
  var isBasePlacement = basePlacement === preferredPlacement;
  var fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipVariations ? [(0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(preferredPlacement)] : getExpandedFallbackPlacements(preferredPlacement));
  var placements = [preferredPlacement].concat(fallbackPlacements).reduce(function (acc, placement) {
    return acc.concat((0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.auto ? (0,_utils_computeAutoPlacement_js__WEBPACK_IMPORTED_MODULE_4__["default"])(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      padding: padding,
      flipVariations: flipVariations,
      allowedAutoPlacements: allowedAutoPlacements
    }) : placement);
  }, []);
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var checksMap = new Map();
  var makeFallbackChecks = true;
  var firstFittingPlacement = placements[0];
  for (var i = 0; i < placements.length; i++) {
    var placement = placements[i];
    var _basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement);
    var isStartVariation = (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_5__["default"])(placement) === _enums_js__WEBPACK_IMPORTED_MODULE_1__.start;
    var isVertical = [_enums_js__WEBPACK_IMPORTED_MODULE_1__.top, _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom].indexOf(_basePlacement) >= 0;
    var len = isVertical ? 'width' : 'height';
    var overflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      altBoundary: altBoundary,
      padding: padding
    });
    var mainVariationSide = isVertical ? isStartVariation ? _enums_js__WEBPACK_IMPORTED_MODULE_1__.right : _enums_js__WEBPACK_IMPORTED_MODULE_1__.left : isStartVariation ? _enums_js__WEBPACK_IMPORTED_MODULE_1__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_1__.top;
    if (referenceRect[len] > popperRect[len]) {
      mainVariationSide = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(mainVariationSide);
    }
    var altVariationSide = (0,_utils_getOppositePlacement_js__WEBPACK_IMPORTED_MODULE_2__["default"])(mainVariationSide);
    var checks = [];
    if (checkMainAxis) {
      checks.push(overflow[_basePlacement] <= 0);
    }
    if (checkAltAxis) {
      checks.push(overflow[mainVariationSide] <= 0, overflow[altVariationSide] <= 0);
    }
    if (checks.every(function (check) {
      return check;
    })) {
      firstFittingPlacement = placement;
      makeFallbackChecks = false;
      break;
    }
    checksMap.set(placement, checks);
  }
  if (makeFallbackChecks) {
    // `2` may be desired in some cases – research later
    var numberOfChecks = flipVariations ? 3 : 1;
    var _loop = function _loop(_i) {
      var fittingPlacement = placements.find(function (placement) {
        var checks = checksMap.get(placement);
        if (checks) {
          return checks.slice(0, _i).every(function (check) {
            return check;
          });
        }
      });
      if (fittingPlacement) {
        firstFittingPlacement = fittingPlacement;
        return "break";
      }
    };
    for (var _i = numberOfChecks; _i > 0; _i--) {
      var _ret = _loop(_i);
      if (_ret === "break") break;
    }
  }
  if (state.placement !== firstFittingPlacement) {
    state.modifiersData[name]._skip = true;
    state.placement = firstFittingPlacement;
    state.reset = true;
  }
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'flip',
  enabled: true,
  phase: 'main',
  fn: flip,
  requiresIfExists: ['offset'],
  data: {
    _skip: false
  }
});

/***/ }),

/***/ 30142:
/*!*************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/offset.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   distanceAndSkiddingToXY: () => (/* binding */ distanceAndSkiddingToXY)
/* harmony export */ });
/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ 98532);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../enums.js */ 39322);

 // eslint-disable-next-line import/no-unused-modules

function distanceAndSkiddingToXY(placement, rects, offset) {
  var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement);
  var invertDistance = [_enums_js__WEBPACK_IMPORTED_MODULE_1__.left, _enums_js__WEBPACK_IMPORTED_MODULE_1__.top].indexOf(basePlacement) >= 0 ? -1 : 1;
  var _ref = typeof offset === 'function' ? offset(Object.assign({}, rects, {
      placement: placement
    })) : offset,
    skidding = _ref[0],
    distance = _ref[1];
  skidding = skidding || 0;
  distance = (distance || 0) * invertDistance;
  return [_enums_js__WEBPACK_IMPORTED_MODULE_1__.left, _enums_js__WEBPACK_IMPORTED_MODULE_1__.right].indexOf(basePlacement) >= 0 ? {
    x: distance,
    y: skidding
  } : {
    x: skidding,
    y: distance
  };
}
function offset(_ref2) {
  var state = _ref2.state,
    options = _ref2.options,
    name = _ref2.name;
  var _options$offset = options.offset,
    offset = _options$offset === void 0 ? [0, 0] : _options$offset;
  var data = _enums_js__WEBPACK_IMPORTED_MODULE_1__.placements.reduce(function (acc, placement) {
    acc[placement] = distanceAndSkiddingToXY(placement, state.rects, offset);
    return acc;
  }, {});
  var _data$state$placement = data[state.placement],
    x = _data$state$placement.x,
    y = _data$state$placement.y;
  if (state.modifiersData.popperOffsets != null) {
    state.modifiersData.popperOffsets.x += x;
    state.modifiersData.popperOffsets.y += y;
  }
  state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'offset',
  enabled: true,
  phase: 'main',
  requires: ['popperOffsets'],
  fn: offset
});

/***/ }),

/***/ 60943:
/*!********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/popperOffsets.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _utils_computeOffsets_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/computeOffsets.js */ 41795);

function popperOffsets(_ref) {
  var state = _ref.state,
    name = _ref.name;
  // Offsets are the actual position the popper needs to have to be
  // properly positioned near its reference element
  // This is the most basic placement, and will be adjusted by
  // the modifiers in the next step
  state.modifiersData[name] = (0,_utils_computeOffsets_js__WEBPACK_IMPORTED_MODULE_0__["default"])({
    reference: state.rects.reference,
    element: state.rects.popper,
    strategy: 'absolute',
    placement: state.placement
  });
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'popperOffsets',
  enabled: true,
  phase: 'read',
  fn: popperOffsets,
  data: {}
});

/***/ }),

/***/ 77437:
/*!**********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/modifiers/preventOverflow.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../utils/getBasePlacement.js */ 98532);
/* harmony import */ var _utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/getMainAxisFromPlacement.js */ 69155);
/* harmony import */ var _utils_getAltAxis_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../utils/getAltAxis.js */ 63886);
/* harmony import */ var _utils_within_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../utils/within.js */ 12268);
/* harmony import */ var _dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getLayoutRect.js */ 25375);
/* harmony import */ var _dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../dom-utils/getOffsetParent.js */ 24884);
/* harmony import */ var _utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/detectOverflow.js */ 87269);
/* harmony import */ var _utils_getVariation_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../utils/getVariation.js */ 68089);
/* harmony import */ var _utils_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../utils/getFreshSideObject.js */ 81280);
/* harmony import */ var _utils_math_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../utils/math.js */ 22310);











function preventOverflow(_ref) {
  var state = _ref.state,
    options = _ref.options,
    name = _ref.name;
  var _options$mainAxis = options.mainAxis,
    checkMainAxis = _options$mainAxis === void 0 ? true : _options$mainAxis,
    _options$altAxis = options.altAxis,
    checkAltAxis = _options$altAxis === void 0 ? false : _options$altAxis,
    boundary = options.boundary,
    rootBoundary = options.rootBoundary,
    altBoundary = options.altBoundary,
    padding = options.padding,
    _options$tether = options.tether,
    tether = _options$tether === void 0 ? true : _options$tether,
    _options$tetherOffset = options.tetherOffset,
    tetherOffset = _options$tetherOffset === void 0 ? 0 : _options$tetherOffset;
  var overflow = (0,_utils_detectOverflow_js__WEBPACK_IMPORTED_MODULE_0__["default"])(state, {
    boundary: boundary,
    rootBoundary: rootBoundary,
    padding: padding,
    altBoundary: altBoundary
  });
  var basePlacement = (0,_utils_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_1__["default"])(state.placement);
  var variation = (0,_utils_getVariation_js__WEBPACK_IMPORTED_MODULE_2__["default"])(state.placement);
  var isBasePlacement = !variation;
  var mainAxis = (0,_utils_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(basePlacement);
  var altAxis = (0,_utils_getAltAxis_js__WEBPACK_IMPORTED_MODULE_4__["default"])(mainAxis);
  var popperOffsets = state.modifiersData.popperOffsets;
  var referenceRect = state.rects.reference;
  var popperRect = state.rects.popper;
  var tetherOffsetValue = typeof tetherOffset === 'function' ? tetherOffset(Object.assign({}, state.rects, {
    placement: state.placement
  })) : tetherOffset;
  var normalizedTetherOffsetValue = typeof tetherOffsetValue === 'number' ? {
    mainAxis: tetherOffsetValue,
    altAxis: tetherOffsetValue
  } : Object.assign({
    mainAxis: 0,
    altAxis: 0
  }, tetherOffsetValue);
  var offsetModifierState = state.modifiersData.offset ? state.modifiersData.offset[state.placement] : null;
  var data = {
    x: 0,
    y: 0
  };
  if (!popperOffsets) {
    return;
  }
  if (checkMainAxis) {
    var _offsetModifierState$;
    var mainSide = mainAxis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.top : _enums_js__WEBPACK_IMPORTED_MODULE_5__.left;
    var altSide = mainAxis === 'y' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_5__.right;
    var len = mainAxis === 'y' ? 'height' : 'width';
    var offset = popperOffsets[mainAxis];
    var min = offset + overflow[mainSide];
    var max = offset - overflow[altSide];
    var additive = tether ? -popperRect[len] / 2 : 0;
    var minLen = variation === _enums_js__WEBPACK_IMPORTED_MODULE_5__.start ? referenceRect[len] : popperRect[len];
    var maxLen = variation === _enums_js__WEBPACK_IMPORTED_MODULE_5__.start ? -popperRect[len] : -referenceRect[len]; // We need to include the arrow in the calculation so the arrow doesn't go
    // outside the reference bounds

    var arrowElement = state.elements.arrow;
    var arrowRect = tether && arrowElement ? (0,_dom_utils_getLayoutRect_js__WEBPACK_IMPORTED_MODULE_6__["default"])(arrowElement) : {
      width: 0,
      height: 0
    };
    var arrowPaddingObject = state.modifiersData['arrow#persistent'] ? state.modifiersData['arrow#persistent'].padding : (0,_utils_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_7__["default"])();
    var arrowPaddingMin = arrowPaddingObject[mainSide];
    var arrowPaddingMax = arrowPaddingObject[altSide]; // If the reference length is smaller than the arrow length, we don't want
    // to include its full size in the calculation. If the reference is small
    // and near the edge of a boundary, the popper can overflow even if the
    // reference is not overflowing as well (e.g. virtual elements with no
    // width or height)

    var arrowLen = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(0, referenceRect[len], arrowRect[len]);
    var minOffset = isBasePlacement ? referenceRect[len] / 2 - additive - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis : minLen - arrowLen - arrowPaddingMin - normalizedTetherOffsetValue.mainAxis;
    var maxOffset = isBasePlacement ? -referenceRect[len] / 2 + additive + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis : maxLen + arrowLen + arrowPaddingMax + normalizedTetherOffsetValue.mainAxis;
    var arrowOffsetParent = state.elements.arrow && (0,_dom_utils_getOffsetParent_js__WEBPACK_IMPORTED_MODULE_9__["default"])(state.elements.arrow);
    var clientOffset = arrowOffsetParent ? mainAxis === 'y' ? arrowOffsetParent.clientTop || 0 : arrowOffsetParent.clientLeft || 0 : 0;
    var offsetModifierValue = (_offsetModifierState$ = offsetModifierState == null ? void 0 : offsetModifierState[mainAxis]) != null ? _offsetModifierState$ : 0;
    var tetherMin = offset + minOffset - offsetModifierValue - clientOffset;
    var tetherMax = offset + maxOffset - offsetModifierValue;
    var preventedOffset = (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(tether ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_10__.min)(min, tetherMin) : min, offset, tether ? (0,_utils_math_js__WEBPACK_IMPORTED_MODULE_10__.max)(max, tetherMax) : max);
    popperOffsets[mainAxis] = preventedOffset;
    data[mainAxis] = preventedOffset - offset;
  }
  if (checkAltAxis) {
    var _offsetModifierState$2;
    var _mainSide = mainAxis === 'x' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.top : _enums_js__WEBPACK_IMPORTED_MODULE_5__.left;
    var _altSide = mainAxis === 'x' ? _enums_js__WEBPACK_IMPORTED_MODULE_5__.bottom : _enums_js__WEBPACK_IMPORTED_MODULE_5__.right;
    var _offset = popperOffsets[altAxis];
    var _len = altAxis === 'y' ? 'height' : 'width';
    var _min = _offset + overflow[_mainSide];
    var _max = _offset - overflow[_altSide];
    var isOriginSide = [_enums_js__WEBPACK_IMPORTED_MODULE_5__.top, _enums_js__WEBPACK_IMPORTED_MODULE_5__.left].indexOf(basePlacement) !== -1;
    var _offsetModifierValue = (_offsetModifierState$2 = offsetModifierState == null ? void 0 : offsetModifierState[altAxis]) != null ? _offsetModifierState$2 : 0;
    var _tetherMin = isOriginSide ? _min : _offset - referenceRect[_len] - popperRect[_len] - _offsetModifierValue + normalizedTetherOffsetValue.altAxis;
    var _tetherMax = isOriginSide ? _offset + referenceRect[_len] + popperRect[_len] - _offsetModifierValue - normalizedTetherOffsetValue.altAxis : _max;
    var _preventedOffset = tether && isOriginSide ? (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.withinMaxClamp)(_tetherMin, _offset, _tetherMax) : (0,_utils_within_js__WEBPACK_IMPORTED_MODULE_8__.within)(tether ? _tetherMin : _min, _offset, tether ? _tetherMax : _max);
    popperOffsets[altAxis] = _preventedOffset;
    data[altAxis] = _preventedOffset - _offset;
  }
  state.modifiersData[name] = data;
} // eslint-disable-next-line import/no-unused-modules

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  name: 'preventOverflow',
  enabled: true,
  phase: 'main',
  fn: preventOverflow,
  requiresIfExists: ['offset']
});

/***/ }),

/***/ 65125:
/*!********************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/popper-lite.js ***!
  \********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createPopper: () => (/* binding */ createPopper),
/* harmony export */   defaultModifiers: () => (/* binding */ defaultModifiers),
/* harmony export */   detectOverflow: () => (/* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_5__["default"]),
/* harmony export */   popperGenerator: () => (/* reexport safe */ _createPopper_js__WEBPACK_IMPORTED_MODULE_4__.popperGenerator)
/* harmony export */ });
/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./createPopper.js */ 50692);
/* harmony import */ var _createPopper_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./createPopper.js */ 87269);
/* harmony import */ var _modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modifiers/eventListeners.js */ 15496);
/* harmony import */ var _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./modifiers/popperOffsets.js */ 60943);
/* harmony import */ var _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./modifiers/computeStyles.js */ 5474);
/* harmony import */ var _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./modifiers/applyStyles.js */ 26643);





var defaultModifiers = [_modifiers_eventListeners_js__WEBPACK_IMPORTED_MODULE_0__["default"], _modifiers_popperOffsets_js__WEBPACK_IMPORTED_MODULE_1__["default"], _modifiers_computeStyles_js__WEBPACK_IMPORTED_MODULE_2__["default"], _modifiers_applyStyles_js__WEBPACK_IMPORTED_MODULE_3__["default"]];
var createPopper = /*#__PURE__*/(0,_createPopper_js__WEBPACK_IMPORTED_MODULE_4__.popperGenerator)({
  defaultModifiers: defaultModifiers
}); // eslint-disable-next-line import/no-unused-modules



/***/ }),

/***/ 19861:
/*!***********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ computeAutoPlacement)
/* harmony export */ });
/* harmony import */ var _getVariation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getVariation.js */ 68089);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _detectOverflow_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./detectOverflow.js */ 87269);
/* harmony import */ var _getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getBasePlacement.js */ 98532);




function computeAutoPlacement(state, options) {
  if (options === void 0) {
    options = {};
  }
  var _options = options,
    placement = _options.placement,
    boundary = _options.boundary,
    rootBoundary = _options.rootBoundary,
    padding = _options.padding,
    flipVariations = _options.flipVariations,
    _options$allowedAutoP = _options.allowedAutoPlacements,
    allowedAutoPlacements = _options$allowedAutoP === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.placements : _options$allowedAutoP;
  var variation = (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement);
  var placements = variation ? flipVariations ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.variationPlacements : _enums_js__WEBPACK_IMPORTED_MODULE_0__.variationPlacements.filter(function (placement) {
    return (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement) === variation;
  }) : _enums_js__WEBPACK_IMPORTED_MODULE_0__.basePlacements;
  var allowedPlacements = placements.filter(function (placement) {
    return allowedAutoPlacements.indexOf(placement) >= 0;
  });
  if (allowedPlacements.length === 0) {
    allowedPlacements = placements;
  } // $FlowFixMe[incompatible-type]: Flow seems to have problems with two array unions...

  var overflows = allowedPlacements.reduce(function (acc, placement) {
    acc[placement] = (0,_detectOverflow_js__WEBPACK_IMPORTED_MODULE_2__["default"])(state, {
      placement: placement,
      boundary: boundary,
      rootBoundary: rootBoundary,
      padding: padding
    })[(0,_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(placement)];
    return acc;
  }, {});
  return Object.keys(overflows).sort(function (a, b) {
    return overflows[a] - overflows[b];
  });
}

/***/ }),

/***/ 41795:
/*!*****************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/computeOffsets.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ computeOffsets)
/* harmony export */ });
/* harmony import */ var _getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getBasePlacement.js */ 98532);
/* harmony import */ var _getVariation_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getVariation.js */ 68089);
/* harmony import */ var _getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./getMainAxisFromPlacement.js */ 69155);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../enums.js */ 39322);




function computeOffsets(_ref) {
  var reference = _ref.reference,
    element = _ref.element,
    placement = _ref.placement;
  var basePlacement = placement ? (0,_getBasePlacement_js__WEBPACK_IMPORTED_MODULE_0__["default"])(placement) : null;
  var variation = placement ? (0,_getVariation_js__WEBPACK_IMPORTED_MODULE_1__["default"])(placement) : null;
  var commonX = reference.x + reference.width / 2 - element.width / 2;
  var commonY = reference.y + reference.height / 2 - element.height / 2;
  var offsets;
  switch (basePlacement) {
    case _enums_js__WEBPACK_IMPORTED_MODULE_2__.top:
      offsets = {
        x: commonX,
        y: reference.y - element.height
      };
      break;
    case _enums_js__WEBPACK_IMPORTED_MODULE_2__.bottom:
      offsets = {
        x: commonX,
        y: reference.y + reference.height
      };
      break;
    case _enums_js__WEBPACK_IMPORTED_MODULE_2__.right:
      offsets = {
        x: reference.x + reference.width,
        y: commonY
      };
      break;
    case _enums_js__WEBPACK_IMPORTED_MODULE_2__.left:
      offsets = {
        x: reference.x - element.width,
        y: commonY
      };
      break;
    default:
      offsets = {
        x: reference.x,
        y: reference.y
      };
  }
  var mainAxis = basePlacement ? (0,_getMainAxisFromPlacement_js__WEBPACK_IMPORTED_MODULE_3__["default"])(basePlacement) : null;
  if (mainAxis != null) {
    var len = mainAxis === 'y' ? 'height' : 'width';
    switch (variation) {
      case _enums_js__WEBPACK_IMPORTED_MODULE_2__.start:
        offsets[mainAxis] = offsets[mainAxis] - (reference[len] / 2 - element[len] / 2);
        break;
      case _enums_js__WEBPACK_IMPORTED_MODULE_2__.end:
        offsets[mainAxis] = offsets[mainAxis] + (reference[len] / 2 - element[len] / 2);
        break;
      default:
    }
  }
  return offsets;
}

/***/ }),

/***/ 17655:
/*!***********************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/debounce.js ***!
  \***********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ debounce)
/* harmony export */ });
function debounce(fn) {
  var pending;
  return function () {
    if (!pending) {
      pending = new Promise(function (resolve) {
        Promise.resolve().then(function () {
          pending = undefined;
          resolve(fn());
        });
      });
    }
    return pending;
  };
}

/***/ }),

/***/ 87269:
/*!*****************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/detectOverflow.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ detectOverflow)
/* harmony export */ });
/* harmony import */ var _dom_utils_getClippingRect_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../dom-utils/getClippingRect.js */ 56455);
/* harmony import */ var _dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../dom-utils/getDocumentElement.js */ 63364);
/* harmony import */ var _dom_utils_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../dom-utils/getBoundingClientRect.js */ 40814);
/* harmony import */ var _computeOffsets_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./computeOffsets.js */ 41795);
/* harmony import */ var _rectToClientRect_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./rectToClientRect.js */ 91094);
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ 39322);
/* harmony import */ var _dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../dom-utils/instanceOf.js */ 84265);
/* harmony import */ var _mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mergePaddingObject.js */ 25714);
/* harmony import */ var _expandToHashMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./expandToHashMap.js */ 74019);








 // eslint-disable-next-line import/no-unused-modules

function detectOverflow(state, options) {
  if (options === void 0) {
    options = {};
  }
  var _options = options,
    _options$placement = _options.placement,
    placement = _options$placement === void 0 ? state.placement : _options$placement,
    _options$strategy = _options.strategy,
    strategy = _options$strategy === void 0 ? state.strategy : _options$strategy,
    _options$boundary = _options.boundary,
    boundary = _options$boundary === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.clippingParents : _options$boundary,
    _options$rootBoundary = _options.rootBoundary,
    rootBoundary = _options$rootBoundary === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.viewport : _options$rootBoundary,
    _options$elementConte = _options.elementContext,
    elementContext = _options$elementConte === void 0 ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper : _options$elementConte,
    _options$altBoundary = _options.altBoundary,
    altBoundary = _options$altBoundary === void 0 ? false : _options$altBoundary,
    _options$padding = _options.padding,
    padding = _options$padding === void 0 ? 0 : _options$padding;
  var paddingObject = (0,_mergePaddingObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(typeof padding !== 'number' ? padding : (0,_expandToHashMap_js__WEBPACK_IMPORTED_MODULE_2__["default"])(padding, _enums_js__WEBPACK_IMPORTED_MODULE_0__.basePlacements));
  var altContext = elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper ? _enums_js__WEBPACK_IMPORTED_MODULE_0__.reference : _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper;
  var popperRect = state.rects.popper;
  var element = state.elements[altBoundary ? altContext : elementContext];
  var clippingClientRect = (0,_dom_utils_getClippingRect_js__WEBPACK_IMPORTED_MODULE_3__["default"])((0,_dom_utils_instanceOf_js__WEBPACK_IMPORTED_MODULE_4__.isElement)(element) ? element : element.contextElement || (0,_dom_utils_getDocumentElement_js__WEBPACK_IMPORTED_MODULE_5__["default"])(state.elements.popper), boundary, rootBoundary, strategy);
  var referenceClientRect = (0,_dom_utils_getBoundingClientRect_js__WEBPACK_IMPORTED_MODULE_6__["default"])(state.elements.reference);
  var popperOffsets = (0,_computeOffsets_js__WEBPACK_IMPORTED_MODULE_7__["default"])({
    reference: referenceClientRect,
    element: popperRect,
    strategy: 'absolute',
    placement: placement
  });
  var popperClientRect = (0,_rectToClientRect_js__WEBPACK_IMPORTED_MODULE_8__["default"])(Object.assign({}, popperRect, popperOffsets));
  var elementClientRect = elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper ? popperClientRect : referenceClientRect; // positive = overflowing the clipping rect
  // 0 or negative = within the clipping rect

  var overflowOffsets = {
    top: clippingClientRect.top - elementClientRect.top + paddingObject.top,
    bottom: elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom,
    left: clippingClientRect.left - elementClientRect.left + paddingObject.left,
    right: elementClientRect.right - clippingClientRect.right + paddingObject.right
  };
  var offsetData = state.modifiersData.offset; // Offsets can be applied only to the popper element

  if (elementContext === _enums_js__WEBPACK_IMPORTED_MODULE_0__.popper && offsetData) {
    var offset = offsetData[placement];
    Object.keys(overflowOffsets).forEach(function (key) {
      var multiply = [_enums_js__WEBPACK_IMPORTED_MODULE_0__.right, _enums_js__WEBPACK_IMPORTED_MODULE_0__.bottom].indexOf(key) >= 0 ? 1 : -1;
      var axis = [_enums_js__WEBPACK_IMPORTED_MODULE_0__.top, _enums_js__WEBPACK_IMPORTED_MODULE_0__.bottom].indexOf(key) >= 0 ? 'y' : 'x';
      overflowOffsets[key] += offset[axis] * multiply;
    });
  }
  return overflowOffsets;
}

/***/ }),

/***/ 74019:
/*!******************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/expandToHashMap.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ expandToHashMap)
/* harmony export */ });
function expandToHashMap(value, keys) {
  return keys.reduce(function (hashMap, key) {
    hashMap[key] = value;
    return hashMap;
  }, {});
}

/***/ }),

/***/ 63886:
/*!*************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getAltAxis.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getAltAxis)
/* harmony export */ });
function getAltAxis(axis) {
  return axis === 'x' ? 'y' : 'x';
}

/***/ }),

/***/ 98532:
/*!*******************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getBasePlacement.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getBasePlacement)
/* harmony export */ });

function getBasePlacement(placement) {
  return placement.split('-')[0];
}

/***/ }),

/***/ 81280:
/*!*********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getFreshSideObject.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getFreshSideObject)
/* harmony export */ });
function getFreshSideObject() {
  return {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  };
}

/***/ }),

/***/ 69155:
/*!***************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js ***!
  \***************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getMainAxisFromPlacement)
/* harmony export */ });
function getMainAxisFromPlacement(placement) {
  return ['top', 'bottom'].indexOf(placement) >= 0 ? 'x' : 'y';
}

/***/ }),

/***/ 55436:
/*!***********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getOppositePlacement.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getOppositePlacement)
/* harmony export */ });
var hash = {
  left: 'right',
  right: 'left',
  bottom: 'top',
  top: 'bottom'
};
function getOppositePlacement(placement) {
  return placement.replace(/left|right|bottom|top/g, function (matched) {
    return hash[matched];
  });
}

/***/ }),

/***/ 26207:
/*!********************************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js ***!
  \********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getOppositeVariationPlacement)
/* harmony export */ });
var hash = {
  start: 'end',
  end: 'start'
};
function getOppositeVariationPlacement(placement) {
  return placement.replace(/start|end/g, function (matched) {
    return hash[matched];
  });
}

/***/ }),

/***/ 68089:
/*!***************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/getVariation.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getVariation)
/* harmony export */ });
function getVariation(placement) {
  return placement.split('-')[1];
}

/***/ }),

/***/ 22310:
/*!*******************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/math.js ***!
  \*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   max: () => (/* binding */ max),
/* harmony export */   min: () => (/* binding */ min),
/* harmony export */   round: () => (/* binding */ round)
/* harmony export */ });
var max = Math.max;
var min = Math.min;
var round = Math.round;

/***/ }),

/***/ 45800:
/*!**************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/mergeByName.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ mergeByName)
/* harmony export */ });
function mergeByName(modifiers) {
  var merged = modifiers.reduce(function (merged, current) {
    var existing = merged[current.name];
    merged[current.name] = existing ? Object.assign({}, existing, current, {
      options: Object.assign({}, existing.options, current.options),
      data: Object.assign({}, existing.data, current.data)
    }) : current;
    return merged;
  }, {}); // IE11 does not support Object.values

  return Object.keys(merged).map(function (key) {
    return merged[key];
  });
}

/***/ }),

/***/ 25714:
/*!*********************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/mergePaddingObject.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ mergePaddingObject)
/* harmony export */ });
/* harmony import */ var _getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getFreshSideObject.js */ 81280);

function mergePaddingObject(paddingObject) {
  return Object.assign({}, (0,_getFreshSideObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(), paddingObject);
}

/***/ }),

/***/ 96082:
/*!*****************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/orderModifiers.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ orderModifiers)
/* harmony export */ });
/* harmony import */ var _enums_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../enums.js */ 39322);
 // source: https://stackoverflow.com/questions/49875255

function order(modifiers) {
  var map = new Map();
  var visited = new Set();
  var result = [];
  modifiers.forEach(function (modifier) {
    map.set(modifier.name, modifier);
  }); // On visiting object, check for its dependencies and visit them recursively

  function sort(modifier) {
    visited.add(modifier.name);
    var requires = [].concat(modifier.requires || [], modifier.requiresIfExists || []);
    requires.forEach(function (dep) {
      if (!visited.has(dep)) {
        var depModifier = map.get(dep);
        if (depModifier) {
          sort(depModifier);
        }
      }
    });
    result.push(modifier);
  }
  modifiers.forEach(function (modifier) {
    if (!visited.has(modifier.name)) {
      // check for visited object
      sort(modifier);
    }
  });
  return result;
}
function orderModifiers(modifiers) {
  // order based on dependencies
  var orderedModifiers = order(modifiers); // order based on phase

  return _enums_js__WEBPACK_IMPORTED_MODULE_0__.modifierPhases.reduce(function (acc, phase) {
    return acc.concat(orderedModifiers.filter(function (modifier) {
      return modifier.phase === phase;
    }));
  }, []);
}

/***/ }),

/***/ 91094:
/*!*******************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/rectToClientRect.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ rectToClientRect)
/* harmony export */ });
function rectToClientRect(rect) {
  return Object.assign({}, rect, {
    left: rect.x,
    top: rect.y,
    right: rect.x + rect.width,
    bottom: rect.y + rect.height
  });
}

/***/ }),

/***/ 42226:
/*!************************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/userAgent.js ***!
  \************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ getUAString)
/* harmony export */ });
function getUAString() {
  var uaData = navigator.userAgentData;
  if (uaData != null && uaData.brands && Array.isArray(uaData.brands)) {
    return uaData.brands.map(function (item) {
      return item.brand + "/" + item.version;
    }).join(' ');
  }
  return navigator.userAgent;
}

/***/ }),

/***/ 12268:
/*!*********************************************************!*\
  !*** ./node_modules/@popperjs/core/lib/utils/within.js ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   within: () => (/* binding */ within),
/* harmony export */   withinMaxClamp: () => (/* binding */ withinMaxClamp)
/* harmony export */ });
/* harmony import */ var _math_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./math.js */ 22310);

function within(min, value, max) {
  return (0,_math_js__WEBPACK_IMPORTED_MODULE_0__.max)(min, (0,_math_js__WEBPACK_IMPORTED_MODULE_0__.min)(value, max));
}
function withinMaxClamp(min, value, max) {
  var v = within(min, value, max);
  return v > max ? max : v;
}

/***/ }),

/***/ 51474:
/*!************************************************************************!*\
  !*** ./node_modules/angular-feather/fesm2015/angular-feather-icons.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Activity: () => (/* binding */ Activity),
/* harmony export */   Airplay: () => (/* binding */ Airplay),
/* harmony export */   AlertCircle: () => (/* binding */ AlertCircle),
/* harmony export */   AlertOctagon: () => (/* binding */ AlertOctagon),
/* harmony export */   AlertTriangle: () => (/* binding */ AlertTriangle),
/* harmony export */   AlignCenter: () => (/* binding */ AlignCenter),
/* harmony export */   AlignJustify: () => (/* binding */ AlignJustify),
/* harmony export */   AlignLeft: () => (/* binding */ AlignLeft),
/* harmony export */   AlignRight: () => (/* binding */ AlignRight),
/* harmony export */   Anchor: () => (/* binding */ Anchor),
/* harmony export */   Aperture: () => (/* binding */ Aperture),
/* harmony export */   Archive: () => (/* binding */ Archive),
/* harmony export */   ArrowDown: () => (/* binding */ ArrowDown),
/* harmony export */   ArrowDownCircle: () => (/* binding */ ArrowDownCircle),
/* harmony export */   ArrowDownLeft: () => (/* binding */ ArrowDownLeft),
/* harmony export */   ArrowDownRight: () => (/* binding */ ArrowDownRight),
/* harmony export */   ArrowLeft: () => (/* binding */ ArrowLeft),
/* harmony export */   ArrowLeftCircle: () => (/* binding */ ArrowLeftCircle),
/* harmony export */   ArrowRight: () => (/* binding */ ArrowRight),
/* harmony export */   ArrowRightCircle: () => (/* binding */ ArrowRightCircle),
/* harmony export */   ArrowUp: () => (/* binding */ ArrowUp),
/* harmony export */   ArrowUpCircle: () => (/* binding */ ArrowUpCircle),
/* harmony export */   ArrowUpLeft: () => (/* binding */ ArrowUpLeft),
/* harmony export */   ArrowUpRight: () => (/* binding */ ArrowUpRight),
/* harmony export */   AtSign: () => (/* binding */ AtSign),
/* harmony export */   Award: () => (/* binding */ Award),
/* harmony export */   BarChart: () => (/* binding */ BarChart),
/* harmony export */   BarChart2: () => (/* binding */ BarChart2),
/* harmony export */   Battery: () => (/* binding */ Battery),
/* harmony export */   BatteryCharging: () => (/* binding */ BatteryCharging),
/* harmony export */   Bell: () => (/* binding */ Bell),
/* harmony export */   BellOff: () => (/* binding */ BellOff),
/* harmony export */   Bluetooth: () => (/* binding */ Bluetooth),
/* harmony export */   Bold: () => (/* binding */ Bold),
/* harmony export */   Book: () => (/* binding */ Book),
/* harmony export */   BookOpen: () => (/* binding */ BookOpen),
/* harmony export */   Bookmark: () => (/* binding */ Bookmark),
/* harmony export */   Box: () => (/* binding */ Box),
/* harmony export */   Briefcase: () => (/* binding */ Briefcase),
/* harmony export */   Calendar: () => (/* binding */ Calendar),
/* harmony export */   Camera: () => (/* binding */ Camera),
/* harmony export */   CameraOff: () => (/* binding */ CameraOff),
/* harmony export */   Cast: () => (/* binding */ Cast),
/* harmony export */   Check: () => (/* binding */ Check),
/* harmony export */   CheckCircle: () => (/* binding */ CheckCircle),
/* harmony export */   CheckSquare: () => (/* binding */ CheckSquare),
/* harmony export */   ChevronDown: () => (/* binding */ ChevronDown),
/* harmony export */   ChevronLeft: () => (/* binding */ ChevronLeft),
/* harmony export */   ChevronRight: () => (/* binding */ ChevronRight),
/* harmony export */   ChevronUp: () => (/* binding */ ChevronUp),
/* harmony export */   ChevronsDown: () => (/* binding */ ChevronsDown),
/* harmony export */   ChevronsLeft: () => (/* binding */ ChevronsLeft),
/* harmony export */   ChevronsRight: () => (/* binding */ ChevronsRight),
/* harmony export */   ChevronsUp: () => (/* binding */ ChevronsUp),
/* harmony export */   Chrome: () => (/* binding */ Chrome),
/* harmony export */   Circle: () => (/* binding */ Circle),
/* harmony export */   Clipboard: () => (/* binding */ Clipboard),
/* harmony export */   Clock: () => (/* binding */ Clock),
/* harmony export */   Cloud: () => (/* binding */ Cloud),
/* harmony export */   CloudDrizzle: () => (/* binding */ CloudDrizzle),
/* harmony export */   CloudLightning: () => (/* binding */ CloudLightning),
/* harmony export */   CloudOff: () => (/* binding */ CloudOff),
/* harmony export */   CloudRain: () => (/* binding */ CloudRain),
/* harmony export */   CloudSnow: () => (/* binding */ CloudSnow),
/* harmony export */   Code: () => (/* binding */ Code),
/* harmony export */   Codepen: () => (/* binding */ Codepen),
/* harmony export */   Codesandbox: () => (/* binding */ Codesandbox),
/* harmony export */   Coffee: () => (/* binding */ Coffee),
/* harmony export */   Columns: () => (/* binding */ Columns),
/* harmony export */   Command: () => (/* binding */ Command),
/* harmony export */   Compass: () => (/* binding */ Compass),
/* harmony export */   Copy: () => (/* binding */ Copy),
/* harmony export */   CornerDownLeft: () => (/* binding */ CornerDownLeft),
/* harmony export */   CornerDownRight: () => (/* binding */ CornerDownRight),
/* harmony export */   CornerLeftDown: () => (/* binding */ CornerLeftDown),
/* harmony export */   CornerLeftUp: () => (/* binding */ CornerLeftUp),
/* harmony export */   CornerRightDown: () => (/* binding */ CornerRightDown),
/* harmony export */   CornerRightUp: () => (/* binding */ CornerRightUp),
/* harmony export */   CornerUpLeft: () => (/* binding */ CornerUpLeft),
/* harmony export */   CornerUpRight: () => (/* binding */ CornerUpRight),
/* harmony export */   Cpu: () => (/* binding */ Cpu),
/* harmony export */   CreditCard: () => (/* binding */ CreditCard),
/* harmony export */   Crop: () => (/* binding */ Crop),
/* harmony export */   Crosshair: () => (/* binding */ Crosshair),
/* harmony export */   Database: () => (/* binding */ Database),
/* harmony export */   Delete: () => (/* binding */ Delete),
/* harmony export */   Disc: () => (/* binding */ Disc),
/* harmony export */   Divide: () => (/* binding */ Divide),
/* harmony export */   DivideCircle: () => (/* binding */ DivideCircle),
/* harmony export */   DivideSquare: () => (/* binding */ DivideSquare),
/* harmony export */   DollarSign: () => (/* binding */ DollarSign),
/* harmony export */   Download: () => (/* binding */ Download),
/* harmony export */   DownloadCloud: () => (/* binding */ DownloadCloud),
/* harmony export */   Dribbble: () => (/* binding */ Dribbble),
/* harmony export */   Droplet: () => (/* binding */ Droplet),
/* harmony export */   Edit: () => (/* binding */ Edit),
/* harmony export */   Edit2: () => (/* binding */ Edit2),
/* harmony export */   Edit3: () => (/* binding */ Edit3),
/* harmony export */   ExternalLink: () => (/* binding */ ExternalLink),
/* harmony export */   Eye: () => (/* binding */ Eye),
/* harmony export */   EyeOff: () => (/* binding */ EyeOff),
/* harmony export */   Facebook: () => (/* binding */ Facebook),
/* harmony export */   FastForward: () => (/* binding */ FastForward),
/* harmony export */   Feather: () => (/* binding */ Feather),
/* harmony export */   Figma: () => (/* binding */ Figma),
/* harmony export */   File: () => (/* binding */ File),
/* harmony export */   FileMinus: () => (/* binding */ FileMinus),
/* harmony export */   FilePlus: () => (/* binding */ FilePlus),
/* harmony export */   FileText: () => (/* binding */ FileText),
/* harmony export */   Film: () => (/* binding */ Film),
/* harmony export */   Filter: () => (/* binding */ Filter),
/* harmony export */   Flag: () => (/* binding */ Flag),
/* harmony export */   Folder: () => (/* binding */ Folder),
/* harmony export */   FolderMinus: () => (/* binding */ FolderMinus),
/* harmony export */   FolderPlus: () => (/* binding */ FolderPlus),
/* harmony export */   Framer: () => (/* binding */ Framer),
/* harmony export */   Frown: () => (/* binding */ Frown),
/* harmony export */   Gift: () => (/* binding */ Gift),
/* harmony export */   GitBranch: () => (/* binding */ GitBranch),
/* harmony export */   GitCommit: () => (/* binding */ GitCommit),
/* harmony export */   GitMerge: () => (/* binding */ GitMerge),
/* harmony export */   GitPullRequest: () => (/* binding */ GitPullRequest),
/* harmony export */   Github: () => (/* binding */ Github),
/* harmony export */   Gitlab: () => (/* binding */ Gitlab),
/* harmony export */   Globe: () => (/* binding */ Globe),
/* harmony export */   Grid: () => (/* binding */ Grid),
/* harmony export */   HardDrive: () => (/* binding */ HardDrive),
/* harmony export */   Hash: () => (/* binding */ Hash),
/* harmony export */   Headphones: () => (/* binding */ Headphones),
/* harmony export */   Heart: () => (/* binding */ Heart),
/* harmony export */   HelpCircle: () => (/* binding */ HelpCircle),
/* harmony export */   Hexagon: () => (/* binding */ Hexagon),
/* harmony export */   Home: () => (/* binding */ Home),
/* harmony export */   Image: () => (/* binding */ Image),
/* harmony export */   Inbox: () => (/* binding */ Inbox),
/* harmony export */   Info: () => (/* binding */ Info),
/* harmony export */   Instagram: () => (/* binding */ Instagram),
/* harmony export */   Italic: () => (/* binding */ Italic),
/* harmony export */   Key: () => (/* binding */ Key),
/* harmony export */   Layers: () => (/* binding */ Layers),
/* harmony export */   Layout: () => (/* binding */ Layout),
/* harmony export */   LifeBuoy: () => (/* binding */ LifeBuoy),
/* harmony export */   Link: () => (/* binding */ Link),
/* harmony export */   Link2: () => (/* binding */ Link2),
/* harmony export */   Linkedin: () => (/* binding */ Linkedin),
/* harmony export */   List: () => (/* binding */ List),
/* harmony export */   Loader: () => (/* binding */ Loader),
/* harmony export */   Lock: () => (/* binding */ Lock),
/* harmony export */   LogIn: () => (/* binding */ LogIn),
/* harmony export */   LogOut: () => (/* binding */ LogOut),
/* harmony export */   Mail: () => (/* binding */ Mail),
/* harmony export */   Map: () => (/* binding */ Map),
/* harmony export */   MapPin: () => (/* binding */ MapPin),
/* harmony export */   Maximize: () => (/* binding */ Maximize),
/* harmony export */   Maximize2: () => (/* binding */ Maximize2),
/* harmony export */   Meh: () => (/* binding */ Meh),
/* harmony export */   Menu: () => (/* binding */ Menu),
/* harmony export */   MessageCircle: () => (/* binding */ MessageCircle),
/* harmony export */   MessageSquare: () => (/* binding */ MessageSquare),
/* harmony export */   Mic: () => (/* binding */ Mic),
/* harmony export */   MicOff: () => (/* binding */ MicOff),
/* harmony export */   Minimize: () => (/* binding */ Minimize),
/* harmony export */   Minimize2: () => (/* binding */ Minimize2),
/* harmony export */   Minus: () => (/* binding */ Minus),
/* harmony export */   MinusCircle: () => (/* binding */ MinusCircle),
/* harmony export */   MinusSquare: () => (/* binding */ MinusSquare),
/* harmony export */   Monitor: () => (/* binding */ Monitor),
/* harmony export */   Moon: () => (/* binding */ Moon),
/* harmony export */   MoreHorizontal: () => (/* binding */ MoreHorizontal),
/* harmony export */   MoreVertical: () => (/* binding */ MoreVertical),
/* harmony export */   MousePointer: () => (/* binding */ MousePointer),
/* harmony export */   Move: () => (/* binding */ Move),
/* harmony export */   Music: () => (/* binding */ Music),
/* harmony export */   Navigation: () => (/* binding */ Navigation),
/* harmony export */   Navigation2: () => (/* binding */ Navigation2),
/* harmony export */   Octagon: () => (/* binding */ Octagon),
/* harmony export */   Package: () => (/* binding */ Package),
/* harmony export */   Paperclip: () => (/* binding */ Paperclip),
/* harmony export */   Pause: () => (/* binding */ Pause),
/* harmony export */   PauseCircle: () => (/* binding */ PauseCircle),
/* harmony export */   PenTool: () => (/* binding */ PenTool),
/* harmony export */   Percent: () => (/* binding */ Percent),
/* harmony export */   Phone: () => (/* binding */ Phone),
/* harmony export */   PhoneCall: () => (/* binding */ PhoneCall),
/* harmony export */   PhoneForwarded: () => (/* binding */ PhoneForwarded),
/* harmony export */   PhoneIncoming: () => (/* binding */ PhoneIncoming),
/* harmony export */   PhoneMissed: () => (/* binding */ PhoneMissed),
/* harmony export */   PhoneOff: () => (/* binding */ PhoneOff),
/* harmony export */   PhoneOutgoing: () => (/* binding */ PhoneOutgoing),
/* harmony export */   PieChart: () => (/* binding */ PieChart),
/* harmony export */   Play: () => (/* binding */ Play),
/* harmony export */   PlayCircle: () => (/* binding */ PlayCircle),
/* harmony export */   Plus: () => (/* binding */ Plus),
/* harmony export */   PlusCircle: () => (/* binding */ PlusCircle),
/* harmony export */   PlusSquare: () => (/* binding */ PlusSquare),
/* harmony export */   Pocket: () => (/* binding */ Pocket),
/* harmony export */   Power: () => (/* binding */ Power),
/* harmony export */   Printer: () => (/* binding */ Printer),
/* harmony export */   Radio: () => (/* binding */ Radio),
/* harmony export */   RefreshCcw: () => (/* binding */ RefreshCcw),
/* harmony export */   RefreshCw: () => (/* binding */ RefreshCw),
/* harmony export */   Repeat: () => (/* binding */ Repeat),
/* harmony export */   Rewind: () => (/* binding */ Rewind),
/* harmony export */   RotateCcw: () => (/* binding */ RotateCcw),
/* harmony export */   RotateCw: () => (/* binding */ RotateCw),
/* harmony export */   Rss: () => (/* binding */ Rss),
/* harmony export */   Save: () => (/* binding */ Save),
/* harmony export */   Scissors: () => (/* binding */ Scissors),
/* harmony export */   Search: () => (/* binding */ Search),
/* harmony export */   Send: () => (/* binding */ Send),
/* harmony export */   Server: () => (/* binding */ Server),
/* harmony export */   Settings: () => (/* binding */ Settings),
/* harmony export */   Share: () => (/* binding */ Share),
/* harmony export */   Share2: () => (/* binding */ Share2),
/* harmony export */   Shield: () => (/* binding */ Shield),
/* harmony export */   ShieldOff: () => (/* binding */ ShieldOff),
/* harmony export */   ShoppingBag: () => (/* binding */ ShoppingBag),
/* harmony export */   ShoppingCart: () => (/* binding */ ShoppingCart),
/* harmony export */   Shuffle: () => (/* binding */ Shuffle),
/* harmony export */   Sidebar: () => (/* binding */ Sidebar),
/* harmony export */   SkipBack: () => (/* binding */ SkipBack),
/* harmony export */   SkipForward: () => (/* binding */ SkipForward),
/* harmony export */   Slack: () => (/* binding */ Slack),
/* harmony export */   Slash: () => (/* binding */ Slash),
/* harmony export */   Sliders: () => (/* binding */ Sliders),
/* harmony export */   Smartphone: () => (/* binding */ Smartphone),
/* harmony export */   Smile: () => (/* binding */ Smile),
/* harmony export */   Speaker: () => (/* binding */ Speaker),
/* harmony export */   Square: () => (/* binding */ Square),
/* harmony export */   Star: () => (/* binding */ Star),
/* harmony export */   StopCircle: () => (/* binding */ StopCircle),
/* harmony export */   Sun: () => (/* binding */ Sun),
/* harmony export */   Sunrise: () => (/* binding */ Sunrise),
/* harmony export */   Sunset: () => (/* binding */ Sunset),
/* harmony export */   Table: () => (/* binding */ Table),
/* harmony export */   Tablet: () => (/* binding */ Tablet),
/* harmony export */   Tag: () => (/* binding */ Tag),
/* harmony export */   Target: () => (/* binding */ Target),
/* harmony export */   Terminal: () => (/* binding */ Terminal),
/* harmony export */   Thermometer: () => (/* binding */ Thermometer),
/* harmony export */   ThumbsDown: () => (/* binding */ ThumbsDown),
/* harmony export */   ThumbsUp: () => (/* binding */ ThumbsUp),
/* harmony export */   ToggleLeft: () => (/* binding */ ToggleLeft),
/* harmony export */   ToggleRight: () => (/* binding */ ToggleRight),
/* harmony export */   Tool: () => (/* binding */ Tool),
/* harmony export */   Trash: () => (/* binding */ Trash),
/* harmony export */   Trash2: () => (/* binding */ Trash2),
/* harmony export */   Trello: () => (/* binding */ Trello),
/* harmony export */   TrendingDown: () => (/* binding */ TrendingDown),
/* harmony export */   TrendingUp: () => (/* binding */ TrendingUp),
/* harmony export */   Triangle: () => (/* binding */ Triangle),
/* harmony export */   Truck: () => (/* binding */ Truck),
/* harmony export */   Tv: () => (/* binding */ Tv),
/* harmony export */   Twitch: () => (/* binding */ Twitch),
/* harmony export */   Twitter: () => (/* binding */ Twitter),
/* harmony export */   Type: () => (/* binding */ Type),
/* harmony export */   Umbrella: () => (/* binding */ Umbrella),
/* harmony export */   Underline: () => (/* binding */ Underline),
/* harmony export */   Unlock: () => (/* binding */ Unlock),
/* harmony export */   Upload: () => (/* binding */ Upload),
/* harmony export */   UploadCloud: () => (/* binding */ UploadCloud),
/* harmony export */   User: () => (/* binding */ User),
/* harmony export */   UserCheck: () => (/* binding */ UserCheck),
/* harmony export */   UserMinus: () => (/* binding */ UserMinus),
/* harmony export */   UserPlus: () => (/* binding */ UserPlus),
/* harmony export */   UserX: () => (/* binding */ UserX),
/* harmony export */   Users: () => (/* binding */ Users),
/* harmony export */   Video: () => (/* binding */ Video),
/* harmony export */   VideoOff: () => (/* binding */ VideoOff),
/* harmony export */   Voicemail: () => (/* binding */ Voicemail),
/* harmony export */   Volume: () => (/* binding */ Volume),
/* harmony export */   Volume1: () => (/* binding */ Volume1),
/* harmony export */   Volume2: () => (/* binding */ Volume2),
/* harmony export */   VolumeX: () => (/* binding */ VolumeX),
/* harmony export */   Watch: () => (/* binding */ Watch),
/* harmony export */   Wifi: () => (/* binding */ Wifi),
/* harmony export */   WifiOff: () => (/* binding */ WifiOff),
/* harmony export */   Wind: () => (/* binding */ Wind),
/* harmony export */   X: () => (/* binding */ X),
/* harmony export */   XCircle: () => (/* binding */ XCircle),
/* harmony export */   XOctagon: () => (/* binding */ XOctagon),
/* harmony export */   XSquare: () => (/* binding */ XSquare),
/* harmony export */   Youtube: () => (/* binding */ Youtube),
/* harmony export */   Zap: () => (/* binding */ Zap),
/* harmony export */   ZapOff: () => (/* binding */ ZapOff),
/* harmony export */   ZoomIn: () => (/* binding */ ZoomIn),
/* harmony export */   ZoomOut: () => (/* binding */ ZoomOut),
/* harmony export */   allIcons: () => (/* binding */ allIcons)
/* harmony export */ });
const Activity = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-activity">
    <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"></polyline>
</svg>`;
const Airplay = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-airplay">
    <path d="M5 17H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-1"></path><polygon points="12 15 17 21 7 21 12 15"></polygon>
</svg>`;
const AlertCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-alert-circle">
    <circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>`;
const AlertOctagon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-alert-octagon">
    <polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line>
</svg>`;
const AlertTriangle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-alert-triangle">
    <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line>
</svg>`;
const AlignCenter = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-align-center">
    <line x1="18" y1="10" x2="6" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="18" y1="18" x2="6" y2="18"></line>
</svg>`;
const AlignJustify = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-align-justify">
    <line x1="21" y1="10" x2="3" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="3" y2="18"></line>
</svg>`;
const AlignLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-align-left">
    <line x1="17" y1="10" x2="3" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="17" y1="18" x2="3" y2="18"></line>
</svg>`;
const AlignRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-align-right">
    <line x1="21" y1="10" x2="7" y2="10"></line><line x1="21" y1="6" x2="3" y2="6"></line><line x1="21" y1="14" x2="3" y2="14"></line><line x1="21" y1="18" x2="7" y2="18"></line>
</svg>`;
const Anchor = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-anchor">
    <circle cx="12" cy="5" r="3"></circle><line x1="12" y1="22" x2="12" y2="8"></line><path d="M5 12H2a10 10 0 0 0 20 0h-3"></path>
</svg>`;
const Aperture = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-aperture">
    <circle cx="12" cy="12" r="10"></circle><line x1="14.31" y1="8" x2="20.05" y2="17.94"></line><line x1="9.69" y1="8" x2="21.17" y2="8"></line><line x1="7.38" y1="12" x2="13.12" y2="2.06"></line><line x1="9.69" y1="16" x2="3.95" y2="6.06"></line><line x1="14.31" y1="16" x2="2.83" y2="16"></line><line x1="16.62" y1="12" x2="10.88" y2="21.94"></line>
</svg>`;
const Archive = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-archive">
    <polyline points="21 8 21 21 3 21 3 8"></polyline><rect x="1" y="3" width="22" height="5"></rect><line x1="10" y1="12" x2="14" y2="12"></line>
</svg>`;
const ArrowDownCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-down-circle">
    <circle cx="12" cy="12" r="10"></circle><polyline points="8 12 12 16 16 12"></polyline><line x1="12" y1="8" x2="12" y2="16"></line>
</svg>`;
const ArrowDownLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-down-left">
    <line x1="17" y1="7" x2="7" y2="17"></line><polyline points="17 17 7 17 7 7"></polyline>
</svg>`;
const ArrowDownRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-down-right">
    <line x1="7" y1="7" x2="17" y2="17"></line><polyline points="17 7 17 17 7 17"></polyline>
</svg>`;
const ArrowDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-down">
    <line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline>
</svg>`;
const ArrowLeftCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-left-circle">
    <circle cx="12" cy="12" r="10"></circle><polyline points="12 8 8 12 12 16"></polyline><line x1="16" y1="12" x2="8" y2="12"></line>
</svg>`;
const ArrowLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-left">
    <line x1="19" y1="12" x2="5" y2="12"></line><polyline points="12 19 5 12 12 5"></polyline>
</svg>`;
const ArrowRightCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-right-circle">
    <circle cx="12" cy="12" r="10"></circle><polyline points="12 16 16 12 12 8"></polyline><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const ArrowRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-right">
    <line x1="5" y1="12" x2="19" y2="12"></line><polyline points="12 5 19 12 12 19"></polyline>
</svg>`;
const ArrowUpCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-up-circle">
    <circle cx="12" cy="12" r="10"></circle><polyline points="16 12 12 8 8 12"></polyline><line x1="12" y1="16" x2="12" y2="8"></line>
</svg>`;
const ArrowUpLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-up-left">
    <line x1="17" y1="17" x2="7" y2="7"></line><polyline points="7 17 7 7 17 7"></polyline>
</svg>`;
const ArrowUpRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-up-right">
    <line x1="7" y1="17" x2="17" y2="7"></line><polyline points="7 7 17 7 17 17"></polyline>
</svg>`;
const ArrowUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-arrow-up">
    <line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline>
</svg>`;
const AtSign = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-at-sign">
    <circle cx="12" cy="12" r="4"></circle><path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-3.92 7.94"></path>
</svg>`;
const Award = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-award">
    <circle cx="12" cy="8" r="7"></circle><polyline points="8.21 13.89 7 23 12 20 17 23 15.79 13.88"></polyline>
</svg>`;
const BarChart2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bar-chart-2">
    <line x1="18" y1="20" x2="18" y2="10"></line><line x1="12" y1="20" x2="12" y2="4"></line><line x1="6" y1="20" x2="6" y2="14"></line>
</svg>`;
const BarChart = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bar-chart">
    <line x1="12" y1="20" x2="12" y2="10"></line><line x1="18" y1="20" x2="18" y2="4"></line><line x1="6" y1="20" x2="6" y2="16"></line>
</svg>`;
const BatteryCharging = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-battery-charging">
    <path d="M5 18H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3.19M15 6h2a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-3.19"></path><line x1="23" y1="13" x2="23" y2="11"></line><polyline points="11 6 7 12 13 12 9 18"></polyline>
</svg>`;
const Battery = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-battery">
    <rect x="1" y="6" width="18" height="12" rx="2" ry="2"></rect><line x1="23" y1="13" x2="23" y2="11"></line>
</svg>`;
const BellOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bell-off">
    <path d="M13.73 21a2 2 0 0 1-3.46 0"></path><path d="M18.63 13A17.89 17.89 0 0 1 18 8"></path><path d="M6.26 6.26A5.86 5.86 0 0 0 6 8c0 7-3 9-3 9h14"></path><path d="M18 8a6 6 0 0 0-9.33-5"></path><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const Bell = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bell">
    <path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"></path><path d="M13.73 21a2 2 0 0 1-3.46 0"></path>
</svg>`;
const Bluetooth = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bluetooth">
    <polyline points="6.5 6.5 17.5 17.5 12 23 12 1 17.5 6.5 6.5 17.5"></polyline>
</svg>`;
const Bold = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bold">
    <path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path><path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z"></path>
</svg>`;
const BookOpen = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-book-open">
    <path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"></path><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"></path>
</svg>`;
const Book = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-book">
    <path d="M4 19.5A2.5 2.5 0 0 1 6.5 17H20"></path><path d="M6.5 2H20v20H6.5A2.5 2.5 0 0 1 4 19.5v-15A2.5 2.5 0 0 1 6.5 2z"></path>
</svg>`;
const Bookmark = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-bookmark">
    <path d="M19 21l-7-5-7 5V5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"></path>
</svg>`;
const Box = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-box">
    <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line>
</svg>`;
const Briefcase = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-briefcase">
    <rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path>
</svg>`;
const Calendar = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-calendar">
    <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line>
</svg>`;
const CameraOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-camera-off">
    <line x1="1" y1="1" x2="23" y2="23"></line><path d="M21 21H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h3m3-3h6l2 3h4a2 2 0 0 1 2 2v9.34m-7.72-2.06a4 4 0 1 1-5.56-5.56"></path>
</svg>`;
const Camera = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-camera">
    <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"></path><circle cx="12" cy="13" r="4"></circle>
</svg>`;
const Cast = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cast">
    <path d="M2 16.1A5 5 0 0 1 5.9 20M2 12.05A9 9 0 0 1 9.95 20M2 8V6a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2h-6"></path><line x1="2" y1="20" x2="2.01" y2="20"></line>
</svg>`;
const CheckCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-check-circle">
    <path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path><polyline points="22 4 12 14.01 9 11.01"></polyline>
</svg>`;
const CheckSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-check-square">
    <polyline points="9 11 12 14 22 4"></polyline><path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11"></path>
</svg>`;
const Check = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-check">
    <polyline points="20 6 9 17 4 12"></polyline>
</svg>`;
const ChevronDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevron-down">
    <polyline points="6 9 12 15 18 9"></polyline>
</svg>`;
const ChevronLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevron-left">
    <polyline points="15 18 9 12 15 6"></polyline>
</svg>`;
const ChevronRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevron-right">
    <polyline points="9 18 15 12 9 6"></polyline>
</svg>`;
const ChevronUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevron-up">
    <polyline points="18 15 12 9 6 15"></polyline>
</svg>`;
const ChevronsDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevrons-down">
    <polyline points="7 13 12 18 17 13"></polyline><polyline points="7 6 12 11 17 6"></polyline>
</svg>`;
const ChevronsLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevrons-left">
    <polyline points="11 17 6 12 11 7"></polyline><polyline points="18 17 13 12 18 7"></polyline>
</svg>`;
const ChevronsRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevrons-right">
    <polyline points="13 17 18 12 13 7"></polyline><polyline points="6 17 11 12 6 7"></polyline>
</svg>`;
const ChevronsUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chevrons-up">
    <polyline points="17 11 12 6 7 11"></polyline><polyline points="17 18 12 13 7 18"></polyline>
</svg>`;
const Chrome = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-chrome">
    <circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle><line x1="21.17" y1="8" x2="12" y2="8"></line><line x1="3.95" y1="6.06" x2="8.54" y2="14"></line><line x1="10.88" y1="21.94" x2="15.46" y2="14"></line>
</svg>`;
const Circle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-circle">
    <circle cx="12" cy="12" r="10"></circle>
</svg>`;
const Clipboard = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-clipboard">
    <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"></path><rect x="8" y="2" width="8" height="4" rx="1" ry="1"></rect>
</svg>`;
const Clock = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-clock">
    <circle cx="12" cy="12" r="10"></circle><polyline points="12 6 12 12 16 14"></polyline>
</svg>`;
const CloudDrizzle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud-drizzle">
    <line x1="8" y1="19" x2="8" y2="21"></line><line x1="8" y1="13" x2="8" y2="15"></line><line x1="16" y1="19" x2="16" y2="21"></line><line x1="16" y1="13" x2="16" y2="15"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="12" y1="15" x2="12" y2="17"></line><path d="M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25"></path>
</svg>`;
const CloudLightning = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud-lightning">
    <path d="M19 16.9A5 5 0 0 0 18 7h-1.26a8 8 0 1 0-11.62 9"></path><polyline points="13 11 9 17 15 17 11 23"></polyline>
</svg>`;
const CloudOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud-off">
    <path d="M22.61 16.95A5 5 0 0 0 18 10h-1.26a8 8 0 0 0-7.05-6M5 5a8 8 0 0 0 4 15h9a5 5 0 0 0 1.7-.3"></path><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const CloudRain = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud-rain">
    <line x1="16" y1="13" x2="16" y2="21"></line><line x1="8" y1="13" x2="8" y2="21"></line><line x1="12" y1="15" x2="12" y2="23"></line><path d="M20 16.58A5 5 0 0 0 18 7h-1.26A8 8 0 1 0 4 15.25"></path>
</svg>`;
const CloudSnow = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud-snow">
    <path d="M20 17.58A5 5 0 0 0 18 8h-1.26A8 8 0 1 0 4 16.25"></path><line x1="8" y1="16" x2="8.01" y2="16"></line><line x1="8" y1="20" x2="8.01" y2="20"></line><line x1="12" y1="18" x2="12.01" y2="18"></line><line x1="12" y1="22" x2="12.01" y2="22"></line><line x1="16" y1="16" x2="16.01" y2="16"></line><line x1="16" y1="20" x2="16.01" y2="20"></line>
</svg>`;
const Cloud = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cloud">
    <path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z"></path>
</svg>`;
const Code = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-code">
    <polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline>
</svg>`;
const Codepen = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-codepen">
    <polygon points="12 2 22 8.5 22 15.5 12 22 2 15.5 2 8.5 12 2"></polygon><line x1="12" y1="22" x2="12" y2="15.5"></line><polyline points="22 8.5 12 15.5 2 8.5"></polyline><polyline points="2 15.5 12 8.5 22 15.5"></polyline><line x1="12" y1="2" x2="12" y2="8.5"></line>
</svg>`;
const Codesandbox = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-codesandbox">
    <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="7.5 4.21 12 6.81 16.5 4.21"></polyline><polyline points="7.5 19.79 7.5 14.6 3 12"></polyline><polyline points="21 12 16.5 14.6 16.5 19.79"></polyline><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line>
</svg>`;
const Coffee = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-coffee">
    <path d="M18 8h1a4 4 0 0 1 0 8h-1"></path><path d="M2 8h16v9a4 4 0 0 1-4 4H6a4 4 0 0 1-4-4V8z"></path><line x1="6" y1="1" x2="6" y2="4"></line><line x1="10" y1="1" x2="10" y2="4"></line><line x1="14" y1="1" x2="14" y2="4"></line>
</svg>`;
const Columns = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-columns">
    <path d="M12 3h7a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-7m0-18H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h7m0-18v18"></path>
</svg>`;
const Command = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-command">
    <path d="M18 3a3 3 0 0 0-3 3v12a3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3H6a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3V6a3 3 0 0 0-3-3 3 3 0 0 0-3 3 3 3 0 0 0 3 3h12a3 3 0 0 0 3-3 3 3 0 0 0-3-3z"></path>
</svg>`;
const Compass = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-compass">
    <circle cx="12" cy="12" r="10"></circle><polygon points="16.24 7.76 14.12 14.12 7.76 16.24 9.88 9.88 16.24 7.76"></polygon>
</svg>`;
const Copy = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-copy">
    <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>`;
const CornerDownLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-down-left">
    <polyline points="9 10 4 15 9 20"></polyline><path d="M20 4v7a4 4 0 0 1-4 4H4"></path>
</svg>`;
const CornerDownRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-down-right">
    <polyline points="15 10 20 15 15 20"></polyline><path d="M4 4v7a4 4 0 0 0 4 4h12"></path>
</svg>`;
const CornerLeftDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-left-down">
    <polyline points="14 15 9 20 4 15"></polyline><path d="M20 4h-7a4 4 0 0 0-4 4v12"></path>
</svg>`;
const CornerLeftUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-left-up">
    <polyline points="14 9 9 4 4 9"></polyline><path d="M20 20h-7a4 4 0 0 1-4-4V4"></path>
</svg>`;
const CornerRightDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-right-down">
    <polyline points="10 15 15 20 20 15"></polyline><path d="M4 4h7a4 4 0 0 1 4 4v12"></path>
</svg>`;
const CornerRightUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-right-up">
    <polyline points="10 9 15 4 20 9"></polyline><path d="M4 20h7a4 4 0 0 0 4-4V4"></path>
</svg>`;
const CornerUpLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-up-left">
    <polyline points="9 14 4 9 9 4"></polyline><path d="M20 20v-7a4 4 0 0 0-4-4H4"></path>
</svg>`;
const CornerUpRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-corner-up-right">
    <polyline points="15 14 20 9 15 4"></polyline><path d="M4 20v-7a4 4 0 0 1 4-4h12"></path>
</svg>`;
const Cpu = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-cpu">
    <rect x="4" y="4" width="16" height="16" rx="2" ry="2"></rect><rect x="9" y="9" width="6" height="6"></rect><line x1="9" y1="1" x2="9" y2="4"></line><line x1="15" y1="1" x2="15" y2="4"></line><line x1="9" y1="20" x2="9" y2="23"></line><line x1="15" y1="20" x2="15" y2="23"></line><line x1="20" y1="9" x2="23" y2="9"></line><line x1="20" y1="14" x2="23" y2="14"></line><line x1="1" y1="9" x2="4" y2="9"></line><line x1="1" y1="14" x2="4" y2="14"></line>
</svg>`;
const CreditCard = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-credit-card">
    <rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect><line x1="1" y1="10" x2="23" y2="10"></line>
</svg>`;
const Crop = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-crop">
    <path d="M6.13 1L6 16a2 2 0 0 0 2 2h15"></path><path d="M1 6.13L16 6a2 2 0 0 1 2 2v15"></path>
</svg>`;
const Crosshair = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-crosshair">
    <circle cx="12" cy="12" r="10"></circle><line x1="22" y1="12" x2="18" y2="12"></line><line x1="6" y1="12" x2="2" y2="12"></line><line x1="12" y1="6" x2="12" y2="2"></line><line x1="12" y1="22" x2="12" y2="18"></line>
</svg>`;
const Database = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-database">
    <ellipse cx="12" cy="5" rx="9" ry="3"></ellipse><path d="M21 12c0 1.66-4 3-9 3s-9-1.34-9-3"></path><path d="M3 5v14c0 1.66 4 3 9 3s9-1.34 9-3V5"></path>
</svg>`;
const Delete = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-delete">
    <path d="M21 4H8l-7 8 7 8h13a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2z"></path><line x1="18" y1="9" x2="12" y2="15"></line><line x1="12" y1="9" x2="18" y2="15"></line>
</svg>`;
const Disc = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-disc">
    <circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="3"></circle>
</svg>`;
const DivideCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-divide-circle">
    <line x1="8" y1="12" x2="16" y2="12"></line><line x1="12" y1="16" x2="12" y2="16"></line><line x1="12" y1="8" x2="12" y2="8"></line><circle cx="12" cy="12" r="10"></circle>
</svg>`;
const DivideSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-divide-square">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line><line x1="12" y1="16" x2="12" y2="16"></line><line x1="12" y1="8" x2="12" y2="8"></line>
</svg>`;
const Divide = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-divide">
    <circle cx="12" cy="6" r="2"></circle><line x1="5" y1="12" x2="19" y2="12"></line><circle cx="12" cy="18" r="2"></circle>
</svg>`;
const DollarSign = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-dollar-sign">
    <line x1="12" y1="1" x2="12" y2="23"></line><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"></path>
</svg>`;
const DownloadCloud = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-download-cloud">
    <polyline points="8 17 12 21 16 17"></polyline><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.88 18.09A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.29"></path>
</svg>`;
const Download = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-download">
    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line>
</svg>`;
const Dribbble = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-dribbble">
    <circle cx="12" cy="12" r="10"></circle><path d="M8.56 2.75c4.37 6.03 6.02 9.42 8.03 17.72m2.54-15.38c-3.72 4.35-8.94 5.66-16.88 5.85m19.5 1.9c-3.5-.93-6.63-.82-8.94 0-2.58.92-5.01 2.86-7.44 6.32"></path>
</svg>`;
const Droplet = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-droplet">
    <path d="M12 2.69l5.66 5.66a8 8 0 1 1-11.31 0z"></path>
</svg>`;
const Edit2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-edit-2">
    <path d="M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z"></path>
</svg>`;
const Edit3 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-edit-3">
    <path d="M12 20h9"></path><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"></path>
</svg>`;
const Edit = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-edit">
    <path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
</svg>`;
const ExternalLink = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-external-link">
    <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line>
</svg>`;
const EyeOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-eye-off">
    <path d="M17.94 17.94A10.07 10.07 0 0 1 12 20c-7 0-11-8-11-8a18.45 18.45 0 0 1 5.06-5.94M9.9 4.24A9.12 9.12 0 0 1 12 4c7 0 11 8 11 8a18.5 18.5 0 0 1-2.16 3.19m-6.72-1.07a3 3 0 1 1-4.24-4.24"></path><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const Eye = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-eye">
    <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path><circle cx="12" cy="12" r="3"></circle>
</svg>`;
const Facebook = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-facebook">
    <path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path>
</svg>`;
const FastForward = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-fast-forward">
    <polygon points="13 19 22 12 13 5 13 19"></polygon><polygon points="2 19 11 12 2 5 2 19"></polygon>
</svg>`;
const Feather = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-feather">
    <path d="M20.24 12.24a6 6 0 0 0-8.49-8.49L5 10.5V19h8.5z"></path><line x1="16" y1="8" x2="2" y2="22"></line><line x1="17.5" y1="15" x2="9" y2="15"></line>
</svg>`;
const Figma = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-figma">
    <path d="M5 5.5A3.5 3.5 0 0 1 8.5 2H12v7H8.5A3.5 3.5 0 0 1 5 5.5z"></path><path d="M12 2h3.5a3.5 3.5 0 1 1 0 7H12V2z"></path><path d="M12 12.5a3.5 3.5 0 1 1 7 0 3.5 3.5 0 1 1-7 0z"></path><path d="M5 19.5A3.5 3.5 0 0 1 8.5 16H12v3.5a3.5 3.5 0 1 1-7 0z"></path><path d="M5 12.5A3.5 3.5 0 0 1 8.5 9H12v7H8.5A3.5 3.5 0 0 1 5 12.5z"></path>
</svg>`;
const FileMinus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-file-minus">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="9" y1="15" x2="15" y2="15"></line>
</svg>`;
const FilePlus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-file-plus">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="12" y1="18" x2="12" y2="12"></line><line x1="9" y1="15" x2="15" y2="15"></line>
</svg>`;
const FileText = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-file-text">
    <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path><polyline points="14 2 14 8 20 8"></polyline><line x1="16" y1="13" x2="8" y2="13"></line><line x1="16" y1="17" x2="8" y2="17"></line><polyline points="10 9 9 9 8 9"></polyline>
</svg>`;
const File = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-file">
    <path d="M13 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9z"></path><polyline points="13 2 13 9 20 9"></polyline>
</svg>`;
const Film = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-film">
    <rect x="2" y="2" width="20" height="20" rx="2.18" ry="2.18"></rect><line x1="7" y1="2" x2="7" y2="22"></line><line x1="17" y1="2" x2="17" y2="22"></line><line x1="2" y1="12" x2="22" y2="12"></line><line x1="2" y1="7" x2="7" y2="7"></line><line x1="2" y1="17" x2="7" y2="17"></line><line x1="17" y1="17" x2="22" y2="17"></line><line x1="17" y1="7" x2="22" y2="7"></line>
</svg>`;
const Filter = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-filter">
    <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon>
</svg>`;
const Flag = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-flag">
    <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"></path><line x1="4" y1="22" x2="4" y2="15"></line>
</svg>`;
const FolderMinus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-folder-minus">
    <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path><line x1="9" y1="14" x2="15" y2="14"></line>
</svg>`;
const FolderPlus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-folder-plus">
    <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path><line x1="12" y1="11" x2="12" y2="17"></line><line x1="9" y1="14" x2="15" y2="14"></line>
</svg>`;
const Folder = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-folder">
    <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
</svg>`;
const Framer = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-framer">
    <path d="M5 16V9h14V2H5l14 14h-7m-7 0l7 7v-7m-7 0h7"></path>
</svg>`;
const Frown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-frown">
    <circle cx="12" cy="12" r="10"></circle><path d="M16 16s-1.5-2-4-2-4 2-4 2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line>
</svg>`;
const Gift = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-gift">
    <polyline points="20 12 20 22 4 22 4 12"></polyline><rect x="2" y="7" width="20" height="5"></rect><line x1="12" y1="22" x2="12" y2="7"></line><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"></path><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"></path>
</svg>`;
const GitBranch = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-git-branch">
    <line x1="6" y1="3" x2="6" y2="15"></line><circle cx="18" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><path d="M18 9a9 9 0 0 1-9 9"></path>
</svg>`;
const GitCommit = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-git-commit">
    <circle cx="12" cy="12" r="4"></circle><line x1="1.05" y1="12" x2="7" y2="12"></line><line x1="17.01" y1="12" x2="22.96" y2="12"></line>
</svg>`;
const GitMerge = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-git-merge">
    <circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M6 21V9a9 9 0 0 0 9 9"></path>
</svg>`;
const GitPullRequest = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-git-pull-request">
    <circle cx="18" cy="18" r="3"></circle><circle cx="6" cy="6" r="3"></circle><path d="M13 6h3a2 2 0 0 1 2 2v7"></path><line x1="6" y1="9" x2="6" y2="21"></line>
</svg>`;
const Github = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-github">
    <path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path>
</svg>`;
const Gitlab = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-gitlab">
    <path d="M22.65 14.39L12 22.13 1.35 14.39a.84.84 0 0 1-.3-.94l1.22-3.78 2.44-7.51A.42.42 0 0 1 4.82 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.49h8.1l2.44-7.51A.42.42 0 0 1 18.6 2a.43.43 0 0 1 .58 0 .42.42 0 0 1 .11.18l2.44 7.51L23 13.45a.84.84 0 0 1-.35.94z"></path>
</svg>`;
const Globe = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-globe">
    <circle cx="12" cy="12" r="10"></circle><line x1="2" y1="12" x2="22" y2="12"></line><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"></path>
</svg>`;
const Grid = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-grid">
    <rect x="3" y="3" width="7" height="7"></rect><rect x="14" y="3" width="7" height="7"></rect><rect x="14" y="14" width="7" height="7"></rect><rect x="3" y="14" width="7" height="7"></rect>
</svg>`;
const HardDrive = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-hard-drive">
    <line x1="22" y1="12" x2="2" y2="12"></line><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path><line x1="6" y1="16" x2="6.01" y2="16"></line><line x1="10" y1="16" x2="10.01" y2="16"></line>
</svg>`;
const Hash = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-hash">
    <line x1="4" y1="9" x2="20" y2="9"></line><line x1="4" y1="15" x2="20" y2="15"></line><line x1="10" y1="3" x2="8" y2="21"></line><line x1="16" y1="3" x2="14" y2="21"></line>
</svg>`;
const Headphones = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-headphones">
    <path d="M3 18v-6a9 9 0 0 1 18 0v6"></path><path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3zM3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3z"></path>
</svg>`;
const Heart = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-heart">
    <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path>
</svg>`;
const HelpCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-help-circle">
    <circle cx="12" cy="12" r="10"></circle><path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"></path><line x1="12" y1="17" x2="12.01" y2="17"></line>
</svg>`;
const Hexagon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-hexagon">
    <path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path>
</svg>`;
const Home = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-home">
    <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline>
</svg>`;
const Image = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-image">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><circle cx="8.5" cy="8.5" r="1.5"></circle><polyline points="21 15 16 10 5 21"></polyline>
</svg>`;
const Inbox = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-inbox">
    <polyline points="22 12 16 12 14 15 10 15 8 12 2 12"></polyline><path d="M5.45 5.11L2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"></path>
</svg>`;
const Info = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-info">
    <circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line>
</svg>`;
const Instagram = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-instagram">
    <rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line>
</svg>`;
const Italic = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-italic">
    <line x1="19" y1="4" x2="10" y2="4"></line><line x1="14" y1="20" x2="5" y2="20"></line><line x1="15" y1="4" x2="9" y2="20"></line>
</svg>`;
const Key = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-key">
    <path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"></path>
</svg>`;
const Layers = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-layers">
    <polygon points="12 2 2 7 12 12 22 7 12 2"></polygon><polyline points="2 17 12 22 22 17"></polyline><polyline points="2 12 12 17 22 12"></polyline>
</svg>`;
const Layout = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-layout">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line>
</svg>`;
const LifeBuoy = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-life-buoy">
    <circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="4"></circle><line x1="4.93" y1="4.93" x2="9.17" y2="9.17"></line><line x1="14.83" y1="14.83" x2="19.07" y2="19.07"></line><line x1="14.83" y1="9.17" x2="19.07" y2="4.93"></line><line x1="14.83" y1="9.17" x2="18.36" y2="5.64"></line><line x1="4.93" y1="19.07" x2="9.17" y2="14.83"></line>
</svg>`;
const Link2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-link-2">
    <path d="M15 7h3a5 5 0 0 1 5 5 5 5 0 0 1-5 5h-3m-6 0H6a5 5 0 0 1-5-5 5 5 0 0 1 5-5h3"></path><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const Link = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-link">
    <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
</svg>`;
const Linkedin = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-linkedin">
    <path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle>
</svg>`;
const List = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-list">
    <line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line>
</svg>`;
const Loader = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-loader">
    <line x1="12" y1="2" x2="12" y2="6"></line><line x1="12" y1="18" x2="12" y2="22"></line><line x1="4.93" y1="4.93" x2="7.76" y2="7.76"></line><line x1="16.24" y1="16.24" x2="19.07" y2="19.07"></line><line x1="2" y1="12" x2="6" y2="12"></line><line x1="18" y1="12" x2="22" y2="12"></line><line x1="4.93" y1="19.07" x2="7.76" y2="16.24"></line><line x1="16.24" y1="7.76" x2="19.07" y2="4.93"></line>
</svg>`;
const Lock = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-lock">
    <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>`;
const LogIn = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-log-in">
    <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line>
</svg>`;
const LogOut = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-log-out">
    <path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"></path><polyline points="16 17 21 12 16 7"></polyline><line x1="21" y1="12" x2="9" y2="12"></line>
</svg>`;
const Mail = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-mail">
    <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline>
</svg>`;
const MapPin = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-map-pin">
    <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path><circle cx="12" cy="10" r="3"></circle>
</svg>`;
const Map = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-map">
    <polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6"></polygon><line x1="8" y1="2" x2="8" y2="18"></line><line x1="16" y1="6" x2="16" y2="22"></line>
</svg>`;
const Maximize2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-maximize-2">
    <polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" y1="3" x2="14" y2="10"></line><line x1="3" y1="21" x2="10" y2="14"></line>
</svg>`;
const Maximize = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-maximize">
    <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"></path>
</svg>`;
const Meh = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-meh">
    <circle cx="12" cy="12" r="10"></circle><line x1="8" y1="15" x2="16" y2="15"></line><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line>
</svg>`;
const Menu = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-menu">
    <line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line>
</svg>`;
const MessageCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-message-circle">
    <path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"></path>
</svg>`;
const MessageSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-message-square">
    <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"></path>
</svg>`;
const MicOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-mic-off">
    <line x1="1" y1="1" x2="23" y2="23"></line><path d="M9 9v3a3 3 0 0 0 5.12 2.12M15 9.34V4a3 3 0 0 0-5.94-.6"></path><path d="M17 16.95A7 7 0 0 1 5 12v-2m14 0v2a7 7 0 0 1-.11 1.23"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line>
</svg>`;
const Mic = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-mic">
    <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"></path><path d="M19 10v2a7 7 0 0 1-14 0v-2"></path><line x1="12" y1="19" x2="12" y2="23"></line><line x1="8" y1="23" x2="16" y2="23"></line>
</svg>`;
const Minimize2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-minimize-2">
    <polyline points="4 14 10 14 10 20"></polyline><polyline points="20 10 14 10 14 4"></polyline><line x1="14" y1="10" x2="21" y2="3"></line><line x1="3" y1="21" x2="10" y2="14"></line>
</svg>`;
const Minimize = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-minimize">
    <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"></path>
</svg>`;
const MinusCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-minus-circle">
    <circle cx="12" cy="12" r="10"></circle><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const MinusSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-minus-square">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const Minus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-minus">
    <line x1="5" y1="12" x2="19" y2="12"></line>
</svg>`;
const Monitor = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-monitor">
    <rect x="2" y="3" width="20" height="14" rx="2" ry="2"></rect><line x1="8" y1="21" x2="16" y2="21"></line><line x1="12" y1="17" x2="12" y2="21"></line>
</svg>`;
const Moon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-moon">
    <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>`;
const MoreHorizontal = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-more-horizontal">
    <circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle><circle cx="5" cy="12" r="1"></circle>
</svg>`;
const MoreVertical = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-more-vertical">
    <circle cx="12" cy="12" r="1"></circle><circle cx="12" cy="5" r="1"></circle><circle cx="12" cy="19" r="1"></circle>
</svg>`;
const MousePointer = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-mouse-pointer">
    <path d="M3 3l7.07 16.97 2.51-7.39 7.39-2.51L3 3z"></path><path d="M13 13l6 6"></path>
</svg>`;
const Move = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-move">
    <polyline points="5 9 2 12 5 15"></polyline><polyline points="9 5 12 2 15 5"></polyline><polyline points="15 19 12 22 9 19"></polyline><polyline points="19 9 22 12 19 15"></polyline><line x1="2" y1="12" x2="22" y2="12"></line><line x1="12" y1="2" x2="12" y2="22"></line>
</svg>`;
const Music = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-music">
    <path d="M9 18V5l12-2v13"></path><circle cx="6" cy="18" r="3"></circle><circle cx="18" cy="16" r="3"></circle>
</svg>`;
const Navigation2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-navigation-2">
    <polygon points="12 2 19 21 12 17 5 21 12 2"></polygon>
</svg>`;
const Navigation = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-navigation">
    <polygon points="3 11 22 2 13 21 11 13 3 11"></polygon>
</svg>`;
const Octagon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-octagon">
    <polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon>
</svg>`;
const Package = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-package">
    <line x1="16.5" y1="9.4" x2="7.5" y2="4.21"></line><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"></path><polyline points="3.27 6.96 12 12.01 20.73 6.96"></polyline><line x1="12" y1="22.08" x2="12" y2="12"></line>
</svg>`;
const Paperclip = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-paperclip">
    <path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"></path>
</svg>`;
const PauseCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-pause-circle">
    <circle cx="12" cy="12" r="10"></circle><line x1="10" y1="15" x2="10" y2="9"></line><line x1="14" y1="15" x2="14" y2="9"></line>
</svg>`;
const Pause = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-pause">
    <rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect>
</svg>`;
const PenTool = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-pen-tool">
    <path d="M12 19l7-7 3 3-7 7-3-3z"></path><path d="M18 13l-1.5-7.5L2 2l3.5 14.5L13 18l5-5z"></path><path d="M2 2l7.586 7.586"></path><circle cx="11" cy="11" r="2"></circle>
</svg>`;
const Percent = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-percent">
    <line x1="19" y1="5" x2="5" y2="19"></line><circle cx="6.5" cy="6.5" r="2.5"></circle><circle cx="17.5" cy="17.5" r="2.5"></circle>
</svg>`;
const PhoneCall = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-call">
    <path d="M15.05 5A5 5 0 0 1 19 8.95M15.05 1A9 9 0 0 1 23 8.94m-1 7.98v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const PhoneForwarded = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-forwarded">
    <polyline points="19 1 23 5 19 9"></polyline><line x1="15" y1="5" x2="23" y2="5"></line><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const PhoneIncoming = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-incoming">
    <polyline points="16 2 16 8 22 8"></polyline><line x1="23" y1="1" x2="16" y2="8"></line><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const PhoneMissed = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-missed">
    <line x1="23" y1="1" x2="17" y2="7"></line><line x1="17" y1="1" x2="23" y2="7"></line><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const PhoneOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-off">
    <path d="M10.68 13.31a16 16 0 0 0 3.41 2.6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7 2 2 0 0 1 1.72 2v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.42 19.42 0 0 1-3.33-2.67m-2.67-3.34a19.79 19.79 0 0 1-3.07-8.63A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91"></path><line x1="23" y1="1" x2="1" y2="23"></line>
</svg>`;
const PhoneOutgoing = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone-outgoing">
    <polyline points="23 7 23 1 17 1"></polyline><line x1="16" y1="8" x2="23" y2="1"></line><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const Phone = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-phone">
    <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
</svg>`;
const PieChart = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-pie-chart">
    <path d="M21.21 15.89A10 10 0 1 1 8 2.83"></path><path d="M22 12A10 10 0 0 0 12 2v10z"></path>
</svg>`;
const PlayCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-play-circle">
    <circle cx="12" cy="12" r="10"></circle><polygon points="10 8 16 12 10 16 10 8"></polygon>
</svg>`;
const Play = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-play">
    <polygon points="5 3 19 12 5 21 5 3"></polygon>
</svg>`;
const PlusCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-plus-circle">
    <circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const PlusSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-plus-square">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="12" y1="8" x2="12" y2="16"></line><line x1="8" y1="12" x2="16" y2="12"></line>
</svg>`;
const Plus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-plus">
    <line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line>
</svg>`;
const Pocket = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-pocket">
    <path d="M4 3h16a2 2 0 0 1 2 2v6a10 10 0 0 1-10 10A10 10 0 0 1 2 11V5a2 2 0 0 1 2-2z"></path><polyline points="8 10 12 14 16 10"></polyline>
</svg>`;
const Power = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-power">
    <path d="M18.36 6.64a9 9 0 1 1-12.73 0"></path><line x1="12" y1="2" x2="12" y2="12"></line>
</svg>`;
const Printer = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-printer">
    <polyline points="6 9 6 2 18 2 18 9"></polyline><path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path><rect x="6" y="14" width="12" height="8"></rect>
</svg>`;
const Radio = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-radio">
    <circle cx="12" cy="12" r="2"></circle><path d="M16.24 7.76a6 6 0 0 1 0 8.49m-8.48-.01a6 6 0 0 1 0-8.49m11.31-2.82a10 10 0 0 1 0 14.14m-14.14 0a10 10 0 0 1 0-14.14"></path>
</svg>`;
const RefreshCcw = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-refresh-ccw">
    <polyline points="1 4 1 10 7 10"></polyline><polyline points="23 20 23 14 17 14"></polyline><path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"></path>
</svg>`;
const RefreshCw = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-refresh-cw">
    <polyline points="23 4 23 10 17 10"></polyline><polyline points="1 20 1 14 7 14"></polyline><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"></path>
</svg>`;
const Repeat = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-repeat">
    <polyline points="17 1 21 5 17 9"></polyline><path d="M3 11V9a4 4 0 0 1 4-4h14"></path><polyline points="7 23 3 19 7 15"></polyline><path d="M21 13v2a4 4 0 0 1-4 4H3"></path>
</svg>`;
const Rewind = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-rewind">
    <polygon points="11 19 2 12 11 5 11 19"></polygon><polygon points="22 19 13 12 22 5 22 19"></polygon>
</svg>`;
const RotateCcw = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-rotate-ccw">
    <polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path>
</svg>`;
const RotateCw = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-rotate-cw">
    <polyline points="23 4 23 10 17 10"></polyline><path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>
</svg>`;
const Rss = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-rss">
    <path d="M4 11a9 9 0 0 1 9 9"></path><path d="M4 4a16 16 0 0 1 16 16"></path><circle cx="5" cy="19" r="1"></circle>
</svg>`;
const Save = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-save">
    <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"></path><polyline points="17 21 17 13 7 13 7 21"></polyline><polyline points="7 3 7 8 15 8"></polyline>
</svg>`;
const Scissors = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-scissors">
    <circle cx="6" cy="6" r="3"></circle><circle cx="6" cy="18" r="3"></circle><line x1="20" y1="4" x2="8.12" y2="15.88"></line><line x1="14.47" y1="14.48" x2="20" y2="20"></line><line x1="8.12" y1="8.12" x2="12" y2="12"></line>
</svg>`;
const Search = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-search">
    <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line>
</svg>`;
const Send = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-send">
    <line x1="22" y1="2" x2="11" y2="13"></line><polygon points="22 2 15 22 11 13 2 9 22 2"></polygon>
</svg>`;
const Server = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-server">
    <rect x="2" y="2" width="20" height="8" rx="2" ry="2"></rect><rect x="2" y="14" width="20" height="8" rx="2" ry="2"></rect><line x1="6" y1="6" x2="6.01" y2="6"></line><line x1="6" y1="18" x2="6.01" y2="18"></line>
</svg>`;
const Settings = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-settings">
    <circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path>
</svg>`;
const Share2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-share-2">
    <circle cx="18" cy="5" r="3"></circle><circle cx="6" cy="12" r="3"></circle><circle cx="18" cy="19" r="3"></circle><line x1="8.59" y1="13.51" x2="15.42" y2="17.49"></line><line x1="15.41" y1="6.51" x2="8.59" y2="10.49"></line>
</svg>`;
const Share = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-share">
    <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"></path><polyline points="16 6 12 2 8 6"></polyline><line x1="12" y1="2" x2="12" y2="15"></line>
</svg>`;
const ShieldOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-shield-off">
    <path d="M19.69 14a6.9 6.9 0 0 0 .31-2V5l-8-3-3.16 1.18"></path><path d="M4.73 4.73L4 5v7c0 6 8 10 8 10a20.29 20.29 0 0 0 5.62-4.38"></path><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const Shield = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-shield">
    <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"></path>
</svg>`;
const ShoppingBag = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-shopping-bag">
    <path d="M6 2L3 6v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V6l-3-4z"></path><line x1="3" y1="6" x2="21" y2="6"></line><path d="M16 10a4 4 0 0 1-8 0"></path>
</svg>`;
const ShoppingCart = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-shopping-cart">
    <circle cx="9" cy="21" r="1"></circle><circle cx="20" cy="21" r="1"></circle><path d="M1 1h4l2.68 13.39a2 2 0 0 0 2 1.61h9.72a2 2 0 0 0 2-1.61L23 6H6"></path>
</svg>`;
const Shuffle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-shuffle">
    <polyline points="16 3 21 3 21 8"></polyline><line x1="4" y1="20" x2="21" y2="3"></line><polyline points="21 16 21 21 16 21"></polyline><line x1="15" y1="15" x2="21" y2="21"></line><line x1="4" y1="4" x2="9" y2="9"></line>
</svg>`;
const Sidebar = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-sidebar">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="3" x2="9" y2="21"></line>
</svg>`;
const SkipBack = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-skip-back">
    <polygon points="19 20 9 12 19 4 19 20"></polygon><line x1="5" y1="19" x2="5" y2="5"></line>
</svg>`;
const SkipForward = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-skip-forward">
    <polygon points="5 4 15 12 5 20 5 4"></polygon><line x1="19" y1="5" x2="19" y2="19"></line>
</svg>`;
const Slack = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-slack">
    <path d="M14.5 10c-.83 0-1.5-.67-1.5-1.5v-5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5z"></path><path d="M20.5 10H19V8.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5-.67 1.5-1.5 1.5z"></path><path d="M9.5 14c.83 0 1.5.67 1.5 1.5v5c0 .83-.67 1.5-1.5 1.5S8 21.33 8 20.5v-5c0-.83.67-1.5 1.5-1.5z"></path><path d="M3.5 14H5v1.5c0 .83-.67 1.5-1.5 1.5S2 16.33 2 15.5 2.67 14 3.5 14z"></path><path d="M14 14.5c0-.83.67-1.5 1.5-1.5h5c.83 0 1.5.67 1.5 1.5s-.67 1.5-1.5 1.5h-5c-.83 0-1.5-.67-1.5-1.5z"></path><path d="M15.5 19H14v1.5c0 .83.67 1.5 1.5 1.5s1.5-.67 1.5-1.5-.67-1.5-1.5-1.5z"></path><path d="M10 9.5C10 8.67 9.33 8 8.5 8h-5C2.67 8 2 8.67 2 9.5S2.67 11 3.5 11h5c.83 0 1.5-.67 1.5-1.5z"></path><path d="M8.5 5H10V3.5C10 2.67 9.33 2 8.5 2S7 2.67 7 3.5 7.67 5 8.5 5z"></path>
</svg>`;
const Slash = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-slash">
    <circle cx="12" cy="12" r="10"></circle><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line>
</svg>`;
const Sliders = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-sliders">
    <line x1="4" y1="21" x2="4" y2="14"></line><line x1="4" y1="10" x2="4" y2="3"></line><line x1="12" y1="21" x2="12" y2="12"></line><line x1="12" y1="8" x2="12" y2="3"></line><line x1="20" y1="21" x2="20" y2="16"></line><line x1="20" y1="12" x2="20" y2="3"></line><line x1="1" y1="14" x2="7" y2="14"></line><line x1="9" y1="8" x2="15" y2="8"></line><line x1="17" y1="16" x2="23" y2="16"></line>
</svg>`;
const Smartphone = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-smartphone">
    <rect x="5" y="2" width="14" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line>
</svg>`;
const Smile = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-smile">
    <circle cx="12" cy="12" r="10"></circle><path d="M8 14s1.5 2 4 2 4-2 4-2"></path><line x1="9" y1="9" x2="9.01" y2="9"></line><line x1="15" y1="9" x2="15.01" y2="9"></line>
</svg>`;
const Speaker = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-speaker">
    <rect x="4" y="2" width="16" height="20" rx="2" ry="2"></rect><circle cx="12" cy="14" r="4"></circle><line x1="12" y1="6" x2="12.01" y2="6"></line>
</svg>`;
const Square = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-square">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
</svg>`;
const Star = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-star">
    <polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"></polygon>
</svg>`;
const StopCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-stop-circle">
    <circle cx="12" cy="12" r="10"></circle><rect x="9" y="9" width="6" height="6"></rect>
</svg>`;
const Sun = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-sun">
    <circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>`;
const Sunrise = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-sunrise">
    <path d="M17 18a5 5 0 0 0-10 0"></path><line x1="12" y1="2" x2="12" y2="9"></line><line x1="4.22" y1="10.22" x2="5.64" y2="11.64"></line><line x1="1" y1="18" x2="3" y2="18"></line><line x1="21" y1="18" x2="23" y2="18"></line><line x1="18.36" y1="11.64" x2="19.78" y2="10.22"></line><line x1="23" y1="22" x2="1" y2="22"></line><polyline points="8 6 12 2 16 6"></polyline>
</svg>`;
const Sunset = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-sunset">
    <path d="M17 18a5 5 0 0 0-10 0"></path><line x1="12" y1="9" x2="12" y2="2"></line><line x1="4.22" y1="10.22" x2="5.64" y2="11.64"></line><line x1="1" y1="18" x2="3" y2="18"></line><line x1="21" y1="18" x2="23" y2="18"></line><line x1="18.36" y1="11.64" x2="19.78" y2="10.22"></line><line x1="23" y1="22" x2="1" y2="22"></line><polyline points="16 5 12 9 8 5"></polyline>
</svg>`;
const Table = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-table">
    <path d="M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18"></path>
</svg>`;
const Tablet = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-tablet">
    <rect x="4" y="2" width="16" height="20" rx="2" ry="2"></rect><line x1="12" y1="18" x2="12.01" y2="18"></line>
</svg>`;
const Tag = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-tag">
    <path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line>
</svg>`;
const Target = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-target">
    <circle cx="12" cy="12" r="10"></circle><circle cx="12" cy="12" r="6"></circle><circle cx="12" cy="12" r="2"></circle>
</svg>`;
const Terminal = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-terminal">
    <polyline points="4 17 10 11 4 5"></polyline><line x1="12" y1="19" x2="20" y2="19"></line>
</svg>`;
const Thermometer = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-thermometer">
    <path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z"></path>
</svg>`;
const ThumbsDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-thumbs-down">
    <path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17"></path>
</svg>`;
const ThumbsUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-thumbs-up">
    <path d="M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3"></path>
</svg>`;
const ToggleLeft = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-toggle-left">
    <rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="8" cy="12" r="3"></circle>
</svg>`;
const ToggleRight = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-toggle-right">
    <rect x="1" y="5" width="22" height="14" rx="7" ry="7"></rect><circle cx="16" cy="12" r="3"></circle>
</svg>`;
const Tool = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-tool">
    <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path>
</svg>`;
const Trash2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-trash-2">
    <polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line>
</svg>`;
const Trash = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-trash">
    <polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
</svg>`;
const Trello = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-trello">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><rect x="7" y="7" width="3" height="9"></rect><rect x="14" y="7" width="3" height="5"></rect>
</svg>`;
const TrendingDown = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-trending-down">
    <polyline points="23 18 13.5 8.5 8.5 13.5 1 6"></polyline><polyline points="17 18 23 18 23 12"></polyline>
</svg>`;
const TrendingUp = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-trending-up">
    <polyline points="23 6 13.5 15.5 8.5 10.5 1 18"></polyline><polyline points="17 6 23 6 23 12"></polyline>
</svg>`;
const Triangle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-triangle">
    <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>
</svg>`;
const Truck = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-truck">
    <rect x="1" y="3" width="15" height="13"></rect><polygon points="16 8 20 8 23 11 23 16 16 16 16 8"></polygon><circle cx="5.5" cy="18.5" r="2.5"></circle><circle cx="18.5" cy="18.5" r="2.5"></circle>
</svg>`;
const Tv = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-tv">
    <rect x="2" y="7" width="20" height="15" rx="2" ry="2"></rect><polyline points="17 2 12 7 7 2"></polyline>
</svg>`;
const Twitch = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-twitch">
    <path d="M21 2H3v16h5v4l4-4h5l4-4V2zm-10 9V7m5 4V7"></path>
</svg>`;
const Twitter = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-twitter">
    <path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path>
</svg>`;
const Type = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-type">
    <polyline points="4 7 4 4 20 4 20 7"></polyline><line x1="9" y1="20" x2="15" y2="20"></line><line x1="12" y1="4" x2="12" y2="20"></line>
</svg>`;
const Umbrella = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-umbrella">
    <path d="M23 12a11.05 11.05 0 0 0-22 0zm-5 7a3 3 0 0 1-6 0v-7"></path>
</svg>`;
const Underline = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-underline">
    <path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3"></path><line x1="4" y1="21" x2="20" y2="21"></line>
</svg>`;
const Unlock = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-unlock">
    <rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path>
</svg>`;
const UploadCloud = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-upload-cloud">
    <polyline points="16 16 12 12 8 16"></polyline><line x1="12" y1="12" x2="12" y2="21"></line><path d="M20.39 18.39A5 5 0 0 0 18 9h-1.26A8 8 0 1 0 3 16.3"></path><polyline points="16 16 12 12 8 16"></polyline>
</svg>`;
const Upload = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-upload">
    <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line>
</svg>`;
const UserCheck = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-user-check">
    <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><polyline points="17 11 19 13 23 9"></polyline>
</svg>`;
const UserMinus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-user-minus">
    <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="23" y1="11" x2="17" y2="11"></line>
</svg>`;
const UserPlus = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-user-plus">
    <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="20" y1="8" x2="20" y2="14"></line><line x1="23" y1="11" x2="17" y2="11"></line>
</svg>`;
const UserX = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-user-x">
    <path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="18" y1="8" x2="23" y2="13"></line><line x1="23" y1="8" x2="18" y2="13"></line>
</svg>`;
const User = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-user">
    <path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle>
</svg>`;
const Users = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-users">
    <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="9" cy="7" r="4"></circle><path d="M23 21v-2a4 4 0 0 0-3-3.87"></path><path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
</svg>`;
const VideoOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-video-off">
    <path d="M16 16v1a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2h2m5.66 0H14a2 2 0 0 1 2 2v3.34l1 1L23 7v10"></path><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const Video = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-video">
    <polygon points="23 7 16 12 23 17 23 7"></polygon><rect x="1" y="5" width="15" height="14" rx="2" ry="2"></rect>
</svg>`;
const Voicemail = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-voicemail">
    <circle cx="5.5" cy="11.5" r="4.5"></circle><circle cx="18.5" cy="11.5" r="4.5"></circle><line x1="5.5" y1="16" x2="18.5" y2="16"></line>
</svg>`;
const Volume1 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-volume-1">
    <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M15.54 8.46a5 5 0 0 1 0 7.07"></path>
</svg>`;
const Volume2 = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-volume-2">
    <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path>
</svg>`;
const VolumeX = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-volume-x">
    <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><line x1="23" y1="9" x2="17" y2="15"></line><line x1="17" y1="9" x2="23" y2="15"></line>
</svg>`;
const Volume = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-volume">
    <polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon>
</svg>`;
const Watch = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-watch">
    <circle cx="12" cy="12" r="7"></circle><polyline points="12 9 12 12 13.5 13.5"></polyline><path d="M16.51 17.35l-.35 3.83a2 2 0 0 1-2 1.82H9.83a2 2 0 0 1-2-1.82l-.35-3.83m.01-10.7l.35-3.83A2 2 0 0 1 9.83 1h4.35a2 2 0 0 1 2 1.82l.35 3.83"></path>
</svg>`;
const WifiOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-wifi-off">
    <line x1="1" y1="1" x2="23" y2="23"></line><path d="M16.72 11.06A10.94 10.94 0 0 1 19 12.55"></path><path d="M5 12.55a10.94 10.94 0 0 1 5.17-2.39"></path><path d="M10.71 5.05A16 16 0 0 1 22.58 9"></path><path d="M1.42 9a15.91 15.91 0 0 1 4.7-2.88"></path><path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path><line x1="12" y1="20" x2="12.01" y2="20"></line>
</svg>`;
const Wifi = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-wifi">
    <path d="M5 12.55a11 11 0 0 1 14.08 0"></path><path d="M1.42 9a16 16 0 0 1 21.16 0"></path><path d="M8.53 16.11a6 6 0 0 1 6.95 0"></path><line x1="12" y1="20" x2="12.01" y2="20"></line>
</svg>`;
const Wind = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-wind">
    <path d="M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2"></path>
</svg>`;
const XCircle = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-x-circle">
    <circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>
</svg>`;
const XOctagon = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-x-octagon">
    <polygon points="7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"></polygon><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line>
</svg>`;
const XSquare = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-x-square">
    <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="9" y1="9" x2="15" y2="15"></line><line x1="15" y1="9" x2="9" y2="15"></line>
</svg>`;
const X = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-x">
    <line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line>
</svg>`;
const Youtube = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-youtube">
    <path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon>
</svg>`;
const ZapOff = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-zap-off">
    <polyline points="12.41 6.75 13 2 10.57 4.92"></polyline><polyline points="18.57 12.91 21 10 15.66 10"></polyline><polyline points="8 8 3 14 12 14 11 22 16 16"></polyline><line x1="1" y1="1" x2="23" y2="23"></line>
</svg>`;
const Zap = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-zap">
    <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"></polygon>
</svg>`;
const ZoomIn = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-zoom-in">
    <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="11" y1="8" x2="11" y2="14"></line><line x1="8" y1="11" x2="14" y2="11"></line>
</svg>`;
const ZoomOut = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" class="feather feather-zoom-out">
    <circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line><line x1="8" y1="11" x2="14" y2="11"></line>
</svg>`;
const allIcons = {
  Activity,
  Airplay,
  AlertCircle,
  AlertOctagon,
  AlertTriangle,
  AlignCenter,
  AlignJustify,
  AlignLeft,
  AlignRight,
  Anchor,
  Aperture,
  Archive,
  ArrowDownCircle,
  ArrowDownLeft,
  ArrowDownRight,
  ArrowDown,
  ArrowLeftCircle,
  ArrowLeft,
  ArrowRightCircle,
  ArrowRight,
  ArrowUpCircle,
  ArrowUpLeft,
  ArrowUpRight,
  ArrowUp,
  AtSign,
  Award,
  BarChart2,
  BarChart,
  BatteryCharging,
  Battery,
  BellOff,
  Bell,
  Bluetooth,
  Bold,
  BookOpen,
  Book,
  Bookmark,
  Box,
  Briefcase,
  Calendar,
  CameraOff,
  Camera,
  Cast,
  CheckCircle,
  CheckSquare,
  Check,
  ChevronDown,
  ChevronLeft,
  ChevronRight,
  ChevronUp,
  ChevronsDown,
  ChevronsLeft,
  ChevronsRight,
  ChevronsUp,
  Chrome,
  Circle,
  Clipboard,
  Clock,
  CloudDrizzle,
  CloudLightning,
  CloudOff,
  CloudRain,
  CloudSnow,
  Cloud,
  Code,
  Codepen,
  Codesandbox,
  Coffee,
  Columns,
  Command,
  Compass,
  Copy,
  CornerDownLeft,
  CornerDownRight,
  CornerLeftDown,
  CornerLeftUp,
  CornerRightDown,
  CornerRightUp,
  CornerUpLeft,
  CornerUpRight,
  Cpu,
  CreditCard,
  Crop,
  Crosshair,
  Database,
  Delete,
  Disc,
  DivideCircle,
  DivideSquare,
  Divide,
  DollarSign,
  DownloadCloud,
  Download,
  Dribbble,
  Droplet,
  Edit2,
  Edit3,
  Edit,
  ExternalLink,
  EyeOff,
  Eye,
  Facebook,
  FastForward,
  Feather,
  Figma,
  FileMinus,
  FilePlus,
  FileText,
  File,
  Film,
  Filter,
  Flag,
  FolderMinus,
  FolderPlus,
  Folder,
  Framer,
  Frown,
  Gift,
  GitBranch,
  GitCommit,
  GitMerge,
  GitPullRequest,
  Github,
  Gitlab,
  Globe,
  Grid,
  HardDrive,
  Hash,
  Headphones,
  Heart,
  HelpCircle,
  Hexagon,
  Home,
  Image,
  Inbox,
  Info,
  Instagram,
  Italic,
  Key,
  Layers,
  Layout,
  LifeBuoy,
  Link2,
  Link,
  Linkedin,
  List,
  Loader,
  Lock,
  LogIn,
  LogOut,
  Mail,
  MapPin,
  Map,
  Maximize2,
  Maximize,
  Meh,
  Menu,
  MessageCircle,
  MessageSquare,
  MicOff,
  Mic,
  Minimize2,
  Minimize,
  MinusCircle,
  MinusSquare,
  Minus,
  Monitor,
  Moon,
  MoreHorizontal,
  MoreVertical,
  MousePointer,
  Move,
  Music,
  Navigation2,
  Navigation,
  Octagon,
  Package,
  Paperclip,
  PauseCircle,
  Pause,
  PenTool,
  Percent,
  PhoneCall,
  PhoneForwarded,
  PhoneIncoming,
  PhoneMissed,
  PhoneOff,
  PhoneOutgoing,
  Phone,
  PieChart,
  PlayCircle,
  Play,
  PlusCircle,
  PlusSquare,
  Plus,
  Pocket,
  Power,
  Printer,
  Radio,
  RefreshCcw,
  RefreshCw,
  Repeat,
  Rewind,
  RotateCcw,
  RotateCw,
  Rss,
  Save,
  Scissors,
  Search,
  Send,
  Server,
  Settings,
  Share2,
  Share,
  ShieldOff,
  Shield,
  ShoppingBag,
  ShoppingCart,
  Shuffle,
  Sidebar,
  SkipBack,
  SkipForward,
  Slack,
  Slash,
  Sliders,
  Smartphone,
  Smile,
  Speaker,
  Square,
  Star,
  StopCircle,
  Sun,
  Sunrise,
  Sunset,
  Table,
  Tablet,
  Tag,
  Target,
  Terminal,
  Thermometer,
  ThumbsDown,
  ThumbsUp,
  ToggleLeft,
  ToggleRight,
  Tool,
  Trash2,
  Trash,
  Trello,
  TrendingDown,
  TrendingUp,
  Triangle,
  Truck,
  Tv,
  Twitch,
  Twitter,
  Type,
  Umbrella,
  Underline,
  Unlock,
  UploadCloud,
  Upload,
  UserCheck,
  UserMinus,
  UserPlus,
  UserX,
  User,
  Users,
  VideoOff,
  Video,
  Voicemail,
  Volume1,
  Volume2,
  VolumeX,
  Volume,
  Watch,
  WifiOff,
  Wifi,
  Wind,
  XCircle,
  XOctagon,
  XSquare,
  X,
  Youtube,
  ZapOff,
  Zap,
  ZoomIn,
  ZoomOut
};

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 54341:
/*!******************************************************************!*\
  !*** ./node_modules/angular-feather/fesm2015/angular-feather.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   FeatherComponent: () => (/* binding */ FeatherComponent),
/* harmony export */   FeatherModule: () => (/* binding */ FeatherModule)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/platform-browser */ 80436);




const _c0 = ["*"];
class Icons {
  constructor(icons) {
    this.icons = icons;
  }
}
function uppercamelcase(str) {
  return str.toLowerCase().replace(/(?:^\w|[A-Z]|\b\w)/g, firstLetter => {
    return firstLetter.toUpperCase();
  }).replace(/[-_]/g, '');
}
class FeatherComponent {
  constructor(elem, changeDetector, icons, sanitizer) {
    this.elem = elem;
    this.changeDetector = changeDetector;
    this.icons = icons;
    this.sanitizer = sanitizer;
  }
  ngOnChanges(changes) {
    // icons are provided as an array of objects because of "multi: true"
    const icons = Object.assign({}, ...this.icons);
    const svg = icons[uppercamelcase(changes.name.currentValue)] || '';
    if (!svg) {
      console.warn(`Icon not found: ${changes.name.currentValue}\n` + `Refer to documentation on https://github.com/michaelbazos/angular-feather`);
    }
    // Since the icons are precompiled we can trust them as safe html.
    this.elem.nativeElement.innerHTML = this.sanitizer.sanitize(_angular_core__WEBPACK_IMPORTED_MODULE_0__.SecurityContext.HTML, this.sanitizer.bypassSecurityTrustHtml(svg));
    this.changeDetector.markForCheck();
  }
}
FeatherComponent.ɵfac = function FeatherComponent_Factory(t) {
  return new (t || FeatherComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](Icons), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_platform_browser__WEBPACK_IMPORTED_MODULE_1__.DomSanitizer));
};
FeatherComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
  type: FeatherComponent,
  selectors: [["i-feather"], ["feather-icon"]],
  inputs: {
    name: "name"
  },
  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
  ngContentSelectors: _c0,
  decls: 1,
  vars: 0,
  template: function FeatherComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
    }
  },
  styles: ["[_nghost-%COMP%]{display:inline-block;width:24px;height:24px;fill:none;stroke:currentColor;stroke-width:2px;stroke-linecap:round;stroke-linejoin:round}"]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FeatherComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'i-feather, feather-icon',
      templateUrl: './feather.component.html',
      styleUrls: ['./feather.component.scss']
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef]
      }]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef]
      }]
    }, {
      type: Icons,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [Icons]
      }]
    }, {
      type: _angular_platform_browser__WEBPACK_IMPORTED_MODULE_1__.DomSanitizer,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_1__.DomSanitizer]
      }]
    }];
  }, {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class FeatherModule {
  constructor(icons) {
    this.icons = icons;
    if (!this.icons) {
      throw new Error(`No icon provided. Make sure to use 'FeatherModule.pick({ ... })' when importing the module\n` + `Refer to documentation on https://github.com/michaelbazos/angular-feather`);
    }
  }
  static pick(icons) {
    return {
      ngModule: FeatherModule,
      providers: [{
        provide: Icons,
        multi: true,
        useValue: icons
      }]
    };
  }
}
FeatherModule.ɵfac = function FeatherModule_Factory(t) {
  return new (t || FeatherModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](Icons, 8));
};
FeatherModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: FeatherModule
});
FeatherModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FeatherModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: [FeatherComponent],
      exports: [FeatherComponent]
    }]
  }], function () {
    return [{
      type: Icons,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
      }]
    }];
  }, null);
})();

/*
 * Public API Surface of angular-feather
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 46972:
/*!***************************************************!*\
  !*** ./node_modules/ansi-html-community/index.js ***!
  \***************************************************/
/***/ ((module) => {

"use strict";


module.exports = ansiHTML;

// Reference to https://github.com/sindresorhus/ansi-regex
var _regANSI = /(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/;
var _defColors = {
  reset: ['fff', '000'],
  // [FOREGROUD_COLOR, BACKGROUND_COLOR]
  black: '000',
  red: 'ff0000',
  green: '209805',
  yellow: 'e8bf03',
  blue: '0000ff',
  magenta: 'ff00ff',
  cyan: '00ffee',
  lightgrey: 'f0f0f0',
  darkgrey: '888'
};
var _styles = {
  30: 'black',
  31: 'red',
  32: 'green',
  33: 'yellow',
  34: 'blue',
  35: 'magenta',
  36: 'cyan',
  37: 'lightgrey'
};
var _openTags = {
  '1': 'font-weight:bold',
  // bold
  '2': 'opacity:0.5',
  // dim
  '3': '<i>',
  // italic
  '4': '<u>',
  // underscore
  '8': 'display:none',
  // hidden
  '9': '<del>' // delete
};
var _closeTags = {
  '23': '</i>',
  // reset italic
  '24': '</u>',
  // reset underscore
  '29': '</del>' // reset delete
};
[0, 21, 22, 27, 28, 39, 49].forEach(function (n) {
  _closeTags[n] = '</span>';
});

/**
 * Converts text with ANSI color codes to HTML markup.
 * @param {String} text
 * @returns {*}
 */
function ansiHTML(text) {
  // Returns the text if the string has no ANSI escape code.
  if (!_regANSI.test(text)) {
    return text;
  }

  // Cache opened sequence.
  var ansiCodes = [];
  // Replace with markup.
  var ret = text.replace(/\033\[(\d+)m/g, function (match, seq) {
    var ot = _openTags[seq];
    if (ot) {
      // If current sequence has been opened, close it.
      if (!!~ansiCodes.indexOf(seq)) {
        // eslint-disable-line no-extra-boolean-cast
        ansiCodes.pop();
        return '</span>';
      }
      // Open tag.
      ansiCodes.push(seq);
      return ot[0] === '<' ? ot : '<span style="' + ot + ';">';
    }
    var ct = _closeTags[seq];
    if (ct) {
      // Pop sequence
      ansiCodes.pop();
      return ct;
    }
    return '';
  });

  // Make sure tags are closed.
  var l = ansiCodes.length;
  l > 0 && (ret += Array(l + 1).join('</span>'));
  return ret;
}

/**
 * Customize colors.
 * @param {Object} colors reference to _defColors
 */
ansiHTML.setColors = function (colors) {
  if (typeof colors !== 'object') {
    throw new Error('`colors` parameter must be an Object.');
  }
  var _finalColors = {};
  for (var key in _defColors) {
    var hex = colors.hasOwnProperty(key) ? colors[key] : null;
    if (!hex) {
      _finalColors[key] = _defColors[key];
      continue;
    }
    if ('reset' === key) {
      if (typeof hex === 'string') {
        hex = [hex];
      }
      if (!Array.isArray(hex) || hex.length === 0 || hex.some(function (h) {
        return typeof h !== 'string';
      })) {
        throw new Error('The value of `' + key + '` property must be an Array and each item could only be a hex string, e.g.: FF0000');
      }
      var defHexColor = _defColors[key];
      if (!hex[0]) {
        hex[0] = defHexColor[0];
      }
      if (hex.length === 1 || !hex[1]) {
        hex = [hex[0]];
        hex.push(defHexColor[1]);
      }
      hex = hex.slice(0, 2);
    } else if (typeof hex !== 'string') {
      throw new Error('The value of `' + key + '` property must be a hex string, e.g.: FF0000');
    }
    _finalColors[key] = hex;
  }
  _setTags(_finalColors);
};

/**
 * Reset colors.
 */
ansiHTML.reset = function () {
  _setTags(_defColors);
};

/**
 * Expose tags, including open and close.
 * @type {Object}
 */
ansiHTML.tags = {};
if (Object.defineProperty) {
  Object.defineProperty(ansiHTML.tags, 'open', {
    get: function () {
      return _openTags;
    }
  });
  Object.defineProperty(ansiHTML.tags, 'close', {
    get: function () {
      return _closeTags;
    }
  });
} else {
  ansiHTML.tags.open = _openTags;
  ansiHTML.tags.close = _closeTags;
}
function _setTags(colors) {
  // reset all
  _openTags['0'] = 'font-weight:normal;opacity:1;color:#' + colors.reset[0] + ';background:#' + colors.reset[1];
  // inverse
  _openTags['7'] = 'color:#' + colors.reset[1] + ';background:#' + colors.reset[0];
  // dark grey
  _openTags['90'] = 'color:#' + colors.darkgrey;
  for (var code in _styles) {
    var color = _styles[code];
    var oriColor = colors[color] || '000';
    _openTags[code] = 'color:#' + oriColor;
    code = parseInt(code);
    _openTags[(code + 10).toString()] = 'background:#' + oriColor;
  }
}
ansiHTML.reset();

/***/ }),

/***/ 37627:
/*!*****************************************************!*\
  !*** ./node_modules/countup.js/dist/countUp.min.js ***!
  \*****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CountUp: () => (/* binding */ i)
/* harmony export */ });
var t = function () {
    return t = Object.assign || function (t) {
      for (var i, n = 1, s = arguments.length; n < s; n++) for (var a in i = arguments[n]) Object.prototype.hasOwnProperty.call(i, a) && (t[a] = i[a]);
      return t;
    }, t.apply(this, arguments);
  },
  i = function () {
    function i(i, n, s) {
      var a = this;
      this.endVal = n, this.options = s, this.version = "2.9.0", this.defaults = {
        startVal: 0,
        decimalPlaces: 0,
        duration: 2,
        useEasing: !0,
        useGrouping: !0,
        useIndianSeparators: !1,
        smartEasingThreshold: 999,
        smartEasingAmount: 333,
        separator: ",",
        decimal: ".",
        prefix: "",
        suffix: "",
        enableScrollSpy: !1,
        scrollSpyDelay: 200,
        scrollSpyOnce: !1
      }, this.finalEndVal = null, this.useEasing = !0, this.countDown = !1, this.error = "", this.startVal = 0, this.paused = !0, this.once = !1, this.count = function (t) {
        a.startTime || (a.startTime = t);
        var i = t - a.startTime;
        a.remaining = a.duration - i, a.useEasing ? a.countDown ? a.frameVal = a.startVal - a.easingFn(i, 0, a.startVal - a.endVal, a.duration) : a.frameVal = a.easingFn(i, a.startVal, a.endVal - a.startVal, a.duration) : a.frameVal = a.startVal + (a.endVal - a.startVal) * (i / a.duration);
        var n = a.countDown ? a.frameVal < a.endVal : a.frameVal > a.endVal;
        a.frameVal = n ? a.endVal : a.frameVal, a.frameVal = Number(a.frameVal.toFixed(a.options.decimalPlaces)), a.printValue(a.frameVal), i < a.duration ? a.rAF = requestAnimationFrame(a.count) : null !== a.finalEndVal ? a.update(a.finalEndVal) : a.options.onCompleteCallback && a.options.onCompleteCallback();
      }, this.formatNumber = function (t) {
        var i,
          n,
          s,
          e,
          o = t < 0 ? "-" : "";
        i = Math.abs(t).toFixed(a.options.decimalPlaces);
        var r = (i += "").split(".");
        if (n = r[0], s = r.length > 1 ? a.options.decimal + r[1] : "", a.options.useGrouping) {
          e = "";
          for (var l = 3, h = 0, u = 0, p = n.length; u < p; ++u) a.options.useIndianSeparators && 4 === u && (l = 2, h = 1), 0 !== u && h % l == 0 && (e = a.options.separator + e), h++, e = n[p - u - 1] + e;
          n = e;
        }
        return a.options.numerals && a.options.numerals.length && (n = n.replace(/[0-9]/g, function (t) {
          return a.options.numerals[+t];
        }), s = s.replace(/[0-9]/g, function (t) {
          return a.options.numerals[+t];
        })), o + a.options.prefix + n + s + a.options.suffix;
      }, this.easeOutExpo = function (t, i, n, s) {
        return n * (1 - Math.pow(2, -10 * t / s)) * 1024 / 1023 + i;
      }, this.options = t(t({}, this.defaults), s), this.formattingFn = this.options.formattingFn ? this.options.formattingFn : this.formatNumber, this.easingFn = this.options.easingFn ? this.options.easingFn : this.easeOutExpo, this.el = "string" == typeof i ? document.getElementById(i) : i, n = null == n ? this.parse(this.el.innerHTML) : n, this.startVal = this.validateValue(this.options.startVal), this.frameVal = this.startVal, this.endVal = this.validateValue(n), this.options.decimalPlaces = Math.max(this.options.decimalPlaces), this.resetDuration(), this.options.separator = String(this.options.separator), this.useEasing = this.options.useEasing, "" === this.options.separator && (this.options.useGrouping = !1), this.el ? this.printValue(this.startVal) : this.error = "[CountUp] target is null or undefined", "undefined" != typeof window && this.options.enableScrollSpy && (this.error ? console.error(this.error, i) : (window.onScrollFns = window.onScrollFns || [], window.onScrollFns.push(function () {
        return a.handleScroll(a);
      }), window.onscroll = function () {
        window.onScrollFns.forEach(function (t) {
          return t();
        });
      }, this.handleScroll(this)));
    }
    return i.prototype.handleScroll = function (t) {
      if (t && window && !t.once) {
        var i = window.innerHeight + window.scrollY,
          n = t.el.getBoundingClientRect(),
          s = n.top + window.pageYOffset,
          a = n.top + n.height + window.pageYOffset;
        a < i && a > window.scrollY && t.paused ? (t.paused = !1, setTimeout(function () {
          return t.start();
        }, t.options.scrollSpyDelay), t.options.scrollSpyOnce && (t.once = !0)) : (window.scrollY > a || s > i) && !t.paused && t.reset();
      }
    }, i.prototype.determineDirectionAndSmartEasing = function () {
      var t = this.finalEndVal ? this.finalEndVal : this.endVal;
      this.countDown = this.startVal > t;
      var i = t - this.startVal;
      if (Math.abs(i) > this.options.smartEasingThreshold && this.options.useEasing) {
        this.finalEndVal = t;
        var n = this.countDown ? 1 : -1;
        this.endVal = t + n * this.options.smartEasingAmount, this.duration = this.duration / 2;
      } else this.endVal = t, this.finalEndVal = null;
      null !== this.finalEndVal ? this.useEasing = !1 : this.useEasing = this.options.useEasing;
    }, i.prototype.start = function (t) {
      this.error || (this.options.onStartCallback && this.options.onStartCallback(), t && (this.options.onCompleteCallback = t), this.duration > 0 ? (this.determineDirectionAndSmartEasing(), this.paused = !1, this.rAF = requestAnimationFrame(this.count)) : this.printValue(this.endVal));
    }, i.prototype.pauseResume = function () {
      this.paused ? (this.startTime = null, this.duration = this.remaining, this.startVal = this.frameVal, this.determineDirectionAndSmartEasing(), this.rAF = requestAnimationFrame(this.count)) : cancelAnimationFrame(this.rAF), this.paused = !this.paused;
    }, i.prototype.reset = function () {
      cancelAnimationFrame(this.rAF), this.paused = !0, this.resetDuration(), this.startVal = this.validateValue(this.options.startVal), this.frameVal = this.startVal, this.printValue(this.startVal);
    }, i.prototype.update = function (t) {
      cancelAnimationFrame(this.rAF), this.startTime = null, this.endVal = this.validateValue(t), this.endVal !== this.frameVal && (this.startVal = this.frameVal, null == this.finalEndVal && this.resetDuration(), this.finalEndVal = null, this.determineDirectionAndSmartEasing(), this.rAF = requestAnimationFrame(this.count));
    }, i.prototype.printValue = function (t) {
      var i;
      if (this.el) {
        var n = this.formattingFn(t);
        if (null === (i = this.options.plugin) || void 0 === i ? void 0 : i.render) this.options.plugin.render(this.el, n);else if ("INPUT" === this.el.tagName) this.el.value = n;else "text" === this.el.tagName || "tspan" === this.el.tagName ? this.el.textContent = n : this.el.innerHTML = n;
      }
    }, i.prototype.ensureNumber = function (t) {
      return "number" == typeof t && !isNaN(t);
    }, i.prototype.validateValue = function (t) {
      var i = Number(t);
      return this.ensureNumber(i) ? i : (this.error = "[CountUp] invalid start or end value: ".concat(t), null);
    }, i.prototype.resetDuration = function () {
      this.startTime = null, this.duration = 1e3 * Number(this.options.duration), this.remaining = this.duration;
    }, i.prototype.parse = function (t) {
      var i = function (t) {
          return t.replace(/([.,'  ])/g, "\\$1");
        },
        n = i(this.options.separator),
        s = i(this.options.decimal),
        a = t.replace(new RegExp(n, "g"), "").replace(new RegExp(s, "g"), ".");
      return parseFloat(a);
    }, i;
  }();


/***/ }),

/***/ 27264:
/*!*****************************************************!*\
  !*** ./node_modules/emailjs-com/es/api/sendPost.js ***!
  \*****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   sendPost: () => (/* binding */ sendPost)
/* harmony export */ });
/* harmony import */ var _models_EmailJSResponseStatus__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../models/EmailJSResponseStatus */ 13262);
/* harmony import */ var _store_store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../store/store */ 33690);


const sendPost = (url, data, headers = {}) => {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.addEventListener('load', ({
      target
    }) => {
      const responseStatus = new _models_EmailJSResponseStatus__WEBPACK_IMPORTED_MODULE_0__.EmailJSResponseStatus(target);
      if (responseStatus.status === 200 || responseStatus.text === 'OK') {
        resolve(responseStatus);
      } else {
        reject(responseStatus);
      }
    });
    xhr.addEventListener('error', ({
      target
    }) => {
      reject(new _models_EmailJSResponseStatus__WEBPACK_IMPORTED_MODULE_0__.EmailJSResponseStatus(target));
    });
    xhr.open('POST', _store_store__WEBPACK_IMPORTED_MODULE_1__.store._origin + url, true);
    Object.keys(headers).forEach(key => {
      xhr.setRequestHeader(key, headers[key]);
    });
    xhr.send(data);
  });
};

/***/ }),

/***/ 4133:
/*!**********************************************!*\
  !*** ./node_modules/emailjs-com/es/index.js ***!
  \**********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   init: () => (/* reexport safe */ _methods_init_init__WEBPACK_IMPORTED_MODULE_0__.init),
/* harmony export */   send: () => (/* reexport safe */ _methods_send_send__WEBPACK_IMPORTED_MODULE_1__.send),
/* harmony export */   sendForm: () => (/* reexport safe */ _methods_sendForm_sendForm__WEBPACK_IMPORTED_MODULE_2__.sendForm)
/* harmony export */ });
/* harmony import */ var _methods_init_init__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./methods/init/init */ 84137);
/* harmony import */ var _methods_send_send__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./methods/send/send */ 17601);
/* harmony import */ var _methods_sendForm_sendForm__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./methods/sendForm/sendForm */ 31853);




/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  init: _methods_init_init__WEBPACK_IMPORTED_MODULE_0__.init,
  send: _methods_send_send__WEBPACK_IMPORTED_MODULE_1__.send,
  sendForm: _methods_sendForm_sendForm__WEBPACK_IMPORTED_MODULE_2__.sendForm
});

/***/ }),

/***/ 84137:
/*!**********************************************************!*\
  !*** ./node_modules/emailjs-com/es/methods/init/init.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   init: () => (/* binding */ init)
/* harmony export */ });
/* harmony import */ var _store_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../store/store */ 33690);

/**
 * Initiation
 * @param {string} userID - set the EmailJS user ID
 * @param {string} origin - set the EmailJS origin
 */
const init = (userID, origin = 'https://api.emailjs.com') => {
  _store_store__WEBPACK_IMPORTED_MODULE_0__.store._userID = userID;
  _store_store__WEBPACK_IMPORTED_MODULE_0__.store._origin = origin;
};

/***/ }),

/***/ 31853:
/*!******************************************************************!*\
  !*** ./node_modules/emailjs-com/es/methods/sendForm/sendForm.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   sendForm: () => (/* binding */ sendForm)
/* harmony export */ });
/* harmony import */ var _store_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../store/store */ 33690);
/* harmony import */ var _utils_validateParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/validateParams */ 39959);
/* harmony import */ var _api_sendPost__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../api/sendPost */ 27264);



const findHTMLForm = form => {
  let currentForm;
  if (typeof form === 'string') {
    currentForm = document.querySelector(form);
  } else {
    currentForm = form;
  }
  if (!currentForm || currentForm.nodeName !== 'FORM') {
    throw 'The 3rd parameter is expected to be the HTML form element or the style selector of form';
  }
  return currentForm;
};
/**
 * Send a form the specific EmailJS service
 * @param {string} serviceID - the EmailJS service ID
 * @param {string} templateID - the EmailJS template ID
 * @param {string | HTMLFormElement} form - the form element or selector
 * @param {string} userID - the EmailJS user ID
 * @returns {Promise<EmailJSResponseStatus>}
 */
const sendForm = (serviceID, templateID, form, userID) => {
  const uID = userID || _store_store__WEBPACK_IMPORTED_MODULE_0__.store._userID;
  const currentForm = findHTMLForm(form);
  (0,_utils_validateParams__WEBPACK_IMPORTED_MODULE_1__.validateParams)(uID, serviceID, templateID);
  const formData = new FormData(currentForm);
  formData.append('lib_version', '3.2.0');
  formData.append('service_id', serviceID);
  formData.append('template_id', templateID);
  formData.append('user_id', uID);
  return (0,_api_sendPost__WEBPACK_IMPORTED_MODULE_2__.sendPost)('/api/v1.0/email/send-form', formData);
};

/***/ }),

/***/ 17601:
/*!**********************************************************!*\
  !*** ./node_modules/emailjs-com/es/methods/send/send.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   send: () => (/* binding */ send)
/* harmony export */ });
/* harmony import */ var _store_store__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../store/store */ 33690);
/* harmony import */ var _utils_validateParams__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../utils/validateParams */ 39959);
/* harmony import */ var _api_sendPost__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../api/sendPost */ 27264);



/**
 * Send a template to the specific EmailJS service
 * @param {string} serviceID - the EmailJS service ID
 * @param {string} templateID - the EmailJS template ID
 * @param {object} templatePrams - the template params, what will be set to the EmailJS template
 * @param {string} userID - the EmailJS user ID
 * @returns {Promise<EmailJSResponseStatus>}
 */
const send = (serviceID, templateID, templatePrams, userID) => {
  const uID = userID || _store_store__WEBPACK_IMPORTED_MODULE_0__.store._userID;
  (0,_utils_validateParams__WEBPACK_IMPORTED_MODULE_1__.validateParams)(uID, serviceID, templateID);
  const params = {
    lib_version: '3.2.0',
    user_id: uID,
    service_id: serviceID,
    template_id: templateID,
    template_params: templatePrams
  };
  return (0,_api_sendPost__WEBPACK_IMPORTED_MODULE_2__.sendPost)('/api/v1.0/email/send', JSON.stringify(params), {
    'Content-type': 'application/json'
  });
};

/***/ }),

/***/ 13262:
/*!*********************************************************************!*\
  !*** ./node_modules/emailjs-com/es/models/EmailJSResponseStatus.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   EmailJSResponseStatus: () => (/* binding */ EmailJSResponseStatus)
/* harmony export */ });
class EmailJSResponseStatus {
  constructor(httpResponse) {
    this.status = httpResponse.status;
    this.text = httpResponse.responseText;
  }
}

/***/ }),

/***/ 33690:
/*!****************************************************!*\
  !*** ./node_modules/emailjs-com/es/store/store.js ***!
  \****************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   store: () => (/* binding */ store)
/* harmony export */ });
const store = {
  _origin: 'https://api.emailjs.com'
};

/***/ }),

/***/ 39959:
/*!*************************************************************!*\
  !*** ./node_modules/emailjs-com/es/utils/validateParams.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   validateParams: () => (/* binding */ validateParams)
/* harmony export */ });
const validateParams = (userID, serviceID, templateID) => {
  if (!userID) {
    throw 'The user ID is required. Visit https://dashboard.emailjs.com/admin/integration';
  }
  if (!serviceID) {
    throw 'The service ID is required. Visit https://dashboard.emailjs.com/admin';
  }
  if (!templateID) {
    throw 'The template ID is required. Visit https://dashboard.emailjs.com/admin/templates';
  }
  return true;
};

/***/ }),

/***/ 44339:
/*!***************************************!*\
  !*** ./node_modules/events/events.js ***!
  \***************************************/
/***/ ((module) => {

"use strict";
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.



var R = typeof Reflect === 'object' ? Reflect : null;
var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
  return Function.prototype.apply.call(target, receiver, args);
};
var ReflectOwnKeys;
if (R && typeof R.ownKeys === 'function') {
  ReflectOwnKeys = R.ownKeys;
} else if (Object.getOwnPropertySymbols) {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
  };
} else {
  ReflectOwnKeys = function ReflectOwnKeys(target) {
    return Object.getOwnPropertyNames(target);
  };
}
function ProcessEmitWarning(warning) {
  if (console && console.warn) console.warn(warning);
}
var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
  return value !== value;
};
function EventEmitter() {
  EventEmitter.init.call(this);
}
module.exports = EventEmitter;
module.exports.once = once;

// Backwards-compat with node 0.10.x
EventEmitter.EventEmitter = EventEmitter;
EventEmitter.prototype._events = undefined;
EventEmitter.prototype._eventsCount = 0;
EventEmitter.prototype._maxListeners = undefined;

// By default EventEmitters will print a warning if more than 10 listeners are
// added to it. This is a useful default which helps finding memory leaks.
var defaultMaxListeners = 10;
function checkListener(listener) {
  if (typeof listener !== 'function') {
    throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
  }
}
Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
  enumerable: true,
  get: function () {
    return defaultMaxListeners;
  },
  set: function (arg) {
    if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
      throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
    }
    defaultMaxListeners = arg;
  }
});
EventEmitter.init = function () {
  if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
    this._events = Object.create(null);
    this._eventsCount = 0;
  }
  this._maxListeners = this._maxListeners || undefined;
};

// Obviously not all Emitters should be limited to 10. This function allows
// that to be increased. Set to zero for unlimited.
EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
  if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
    throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
  }
  this._maxListeners = n;
  return this;
};
function _getMaxListeners(that) {
  if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
  return that._maxListeners;
}
EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
  return _getMaxListeners(this);
};
EventEmitter.prototype.emit = function emit(type) {
  var args = [];
  for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
  var doError = type === 'error';
  var events = this._events;
  if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;

  // If there is no 'error' event listener then throw.
  if (doError) {
    var er;
    if (args.length > 0) er = args[0];
    if (er instanceof Error) {
      // Note: The comments on the `throw` lines are intentional, they show
      // up in Node's output if this results in an unhandled exception.
      throw er; // Unhandled 'error' event
    }
    // At least give some kind of context to the user
    var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
    err.context = er;
    throw err; // Unhandled 'error' event
  }
  var handler = events[type];
  if (handler === undefined) return false;
  if (typeof handler === 'function') {
    ReflectApply(handler, this, args);
  } else {
    var len = handler.length;
    var listeners = arrayClone(handler, len);
    for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
  }
  return true;
};
function _addListener(target, type, listener, prepend) {
  var m;
  var events;
  var existing;
  checkListener(listener);
  events = target._events;
  if (events === undefined) {
    events = target._events = Object.create(null);
    target._eventsCount = 0;
  } else {
    // To avoid recursion in the case that type === "newListener"! Before
    // adding it to the listeners, first emit "newListener".
    if (events.newListener !== undefined) {
      target.emit('newListener', type, listener.listener ? listener.listener : listener);

      // Re-assign `events` because a newListener handler could have caused the
      // this._events to be assigned to a new object
      events = target._events;
    }
    existing = events[type];
  }
  if (existing === undefined) {
    // Optimize the case of one listener. Don't need the extra array object.
    existing = events[type] = listener;
    ++target._eventsCount;
  } else {
    if (typeof existing === 'function') {
      // Adding the second element, need to change to array.
      existing = events[type] = prepend ? [listener, existing] : [existing, listener];
      // If we've already got an array, just append.
    } else if (prepend) {
      existing.unshift(listener);
    } else {
      existing.push(listener);
    }

    // Check for listener leak
    m = _getMaxListeners(target);
    if (m > 0 && existing.length > m && !existing.warned) {
      existing.warned = true;
      // No error code for this since it is a Warning
      // eslint-disable-next-line no-restricted-syntax
      var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
      w.name = 'MaxListenersExceededWarning';
      w.emitter = target;
      w.type = type;
      w.count = existing.length;
      ProcessEmitWarning(w);
    }
  }
  return target;
}
EventEmitter.prototype.addListener = function addListener(type, listener) {
  return _addListener(this, type, listener, false);
};
EventEmitter.prototype.on = EventEmitter.prototype.addListener;
EventEmitter.prototype.prependListener = function prependListener(type, listener) {
  return _addListener(this, type, listener, true);
};
function onceWrapper() {
  if (!this.fired) {
    this.target.removeListener(this.type, this.wrapFn);
    this.fired = true;
    if (arguments.length === 0) return this.listener.call(this.target);
    return this.listener.apply(this.target, arguments);
  }
}
function _onceWrap(target, type, listener) {
  var state = {
    fired: false,
    wrapFn: undefined,
    target: target,
    type: type,
    listener: listener
  };
  var wrapped = onceWrapper.bind(state);
  wrapped.listener = listener;
  state.wrapFn = wrapped;
  return wrapped;
}
EventEmitter.prototype.once = function once(type, listener) {
  checkListener(listener);
  this.on(type, _onceWrap(this, type, listener));
  return this;
};
EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
  checkListener(listener);
  this.prependListener(type, _onceWrap(this, type, listener));
  return this;
};

// Emits a 'removeListener' event if and only if the listener was removed.
EventEmitter.prototype.removeListener = function removeListener(type, listener) {
  var list, events, position, i, originalListener;
  checkListener(listener);
  events = this._events;
  if (events === undefined) return this;
  list = events[type];
  if (list === undefined) return this;
  if (list === listener || list.listener === listener) {
    if (--this._eventsCount === 0) this._events = Object.create(null);else {
      delete events[type];
      if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
    }
  } else if (typeof list !== 'function') {
    position = -1;
    for (i = list.length - 1; i >= 0; i--) {
      if (list[i] === listener || list[i].listener === listener) {
        originalListener = list[i].listener;
        position = i;
        break;
      }
    }
    if (position < 0) return this;
    if (position === 0) list.shift();else {
      spliceOne(list, position);
    }
    if (list.length === 1) events[type] = list[0];
    if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
  }
  return this;
};
EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
  var listeners, events, i;
  events = this._events;
  if (events === undefined) return this;

  // not listening for removeListener, no need to emit
  if (events.removeListener === undefined) {
    if (arguments.length === 0) {
      this._events = Object.create(null);
      this._eventsCount = 0;
    } else if (events[type] !== undefined) {
      if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
    }
    return this;
  }

  // emit removeListener for all listeners on all events
  if (arguments.length === 0) {
    var keys = Object.keys(events);
    var key;
    for (i = 0; i < keys.length; ++i) {
      key = keys[i];
      if (key === 'removeListener') continue;
      this.removeAllListeners(key);
    }
    this.removeAllListeners('removeListener');
    this._events = Object.create(null);
    this._eventsCount = 0;
    return this;
  }
  listeners = events[type];
  if (typeof listeners === 'function') {
    this.removeListener(type, listeners);
  } else if (listeners !== undefined) {
    // LIFO order
    for (i = listeners.length - 1; i >= 0; i--) {
      this.removeListener(type, listeners[i]);
    }
  }
  return this;
};
function _listeners(target, type, unwrap) {
  var events = target._events;
  if (events === undefined) return [];
  var evlistener = events[type];
  if (evlistener === undefined) return [];
  if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
  return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
}
EventEmitter.prototype.listeners = function listeners(type) {
  return _listeners(this, type, true);
};
EventEmitter.prototype.rawListeners = function rawListeners(type) {
  return _listeners(this, type, false);
};
EventEmitter.listenerCount = function (emitter, type) {
  if (typeof emitter.listenerCount === 'function') {
    return emitter.listenerCount(type);
  } else {
    return listenerCount.call(emitter, type);
  }
};
EventEmitter.prototype.listenerCount = listenerCount;
function listenerCount(type) {
  var events = this._events;
  if (events !== undefined) {
    var evlistener = events[type];
    if (typeof evlistener === 'function') {
      return 1;
    } else if (evlistener !== undefined) {
      return evlistener.length;
    }
  }
  return 0;
}
EventEmitter.prototype.eventNames = function eventNames() {
  return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
};
function arrayClone(arr, n) {
  var copy = new Array(n);
  for (var i = 0; i < n; ++i) copy[i] = arr[i];
  return copy;
}
function spliceOne(list, index) {
  for (; index + 1 < list.length; index++) list[index] = list[index + 1];
  list.pop();
}
function unwrapListeners(arr) {
  var ret = new Array(arr.length);
  for (var i = 0; i < ret.length; ++i) {
    ret[i] = arr[i].listener || arr[i];
  }
  return ret;
}
function once(emitter, name) {
  return new Promise(function (resolve, reject) {
    function errorListener(err) {
      emitter.removeListener(name, resolver);
      reject(err);
    }
    function resolver() {
      if (typeof emitter.removeListener === 'function') {
        emitter.removeListener('error', errorListener);
      }
      resolve([].slice.call(arguments));
    }
    ;
    eventTargetAgnosticAddListener(emitter, name, resolver, {
      once: true
    });
    if (name !== 'error') {
      addErrorHandlerIfEventEmitter(emitter, errorListener, {
        once: true
      });
    }
  });
}
function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
  if (typeof emitter.on === 'function') {
    eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
  }
}
function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
  if (typeof emitter.on === 'function') {
    if (flags.once) {
      emitter.once(name, listener);
    } else {
      emitter.on(name, listener);
    }
  } else if (typeof emitter.addEventListener === 'function') {
    // EventTarget does not have `error` event semantics like Node
    // EventEmitters, we do not listen for `error` events here.
    emitter.addEventListener(name, function wrapListener(arg) {
      // IE does not have builtin `{ once: true }` support so we
      // have to do it manually.
      if (flags.once) {
        emitter.removeEventListener(name, wrapListener);
      }
      listener(arg);
    });
  } else {
    throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
  }
}

/***/ }),

/***/ 85841:
/*!*******************************************************!*\
  !*** ./node_modules/file-saver/dist/FileSaver.min.js ***!
  \*******************************************************/
/***/ (function(module, exports) {

var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (a, b) {
  if (true) !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (b),
		__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?
		(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));else {}
})(this, function () {
  "use strict";

  function b(a, b) {
    return "undefined" == typeof b ? b = {
      autoBom: !1
    } : "object" != typeof b && (console.warn("Deprecated: Expected third argument to be a object"), b = {
      autoBom: !b
    }), b.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(a.type) ? new Blob(["\uFEFF", a], {
      type: a.type
    }) : a;
  }
  function c(a, b, c) {
    var d = new XMLHttpRequest();
    d.open("GET", a), d.responseType = "blob", d.onload = function () {
      g(d.response, b, c);
    }, d.onerror = function () {
      console.error("could not download file");
    }, d.send();
  }
  function d(a) {
    var b = new XMLHttpRequest();
    b.open("HEAD", a, !1);
    try {
      b.send();
    } catch (a) {}
    return 200 <= b.status && 299 >= b.status;
  }
  function e(a) {
    try {
      a.dispatchEvent(new MouseEvent("click"));
    } catch (c) {
      var b = document.createEvent("MouseEvents");
      b.initMouseEvent("click", !0, !0, window, 0, 0, 0, 80, 20, !1, !1, !1, !1, 0, null), a.dispatchEvent(b);
    }
  }
  var f = "object" == typeof window && window.window === window ? window : "object" == typeof self && self.self === self ? self : "object" == typeof global && global.global === global ? global : void 0,
    a = f.navigator && /Macintosh/.test(navigator.userAgent) && /AppleWebKit/.test(navigator.userAgent) && !/Safari/.test(navigator.userAgent),
    g = f.saveAs || ("object" != typeof window || window !== f ? function () {} : "download" in HTMLAnchorElement.prototype && !a ? function (b, g, h) {
      var i = f.URL || f.webkitURL,
        j = document.createElement("a");
      g = g || b.name || "download", j.download = g, j.rel = "noopener", "string" == typeof b ? (j.href = b, j.origin === location.origin ? e(j) : d(j.href) ? c(b, g, h) : e(j, j.target = "_blank")) : (j.href = i.createObjectURL(b), setTimeout(function () {
        i.revokeObjectURL(j.href);
      }, 4E4), setTimeout(function () {
        e(j);
      }, 0));
    } : "msSaveOrOpenBlob" in navigator ? function (f, g, h) {
      if (g = g || f.name || "download", "string" != typeof f) navigator.msSaveOrOpenBlob(b(f, h), g);else if (d(f)) c(f, g, h);else {
        var i = document.createElement("a");
        i.href = f, i.target = "_blank", setTimeout(function () {
          e(i);
        });
      }
    } : function (b, d, e, g) {
      if (g = g || open("", "_blank"), g && (g.document.title = g.document.body.innerText = "downloading..."), "string" == typeof b) return c(b, d, e);
      var h = "application/octet-stream" === b.type,
        i = /constructor/i.test(f.HTMLElement) || f.safari,
        j = /CriOS\/[\d]+/.test(navigator.userAgent);
      if ((j || h && i || a) && "undefined" != typeof FileReader) {
        var k = new FileReader();
        k.onloadend = function () {
          var a = k.result;
          a = j ? a : a.replace(/^data:[^;]*;/, "data:attachment/file;"), g ? g.location.href = a : location = a, g = null;
        }, k.readAsDataURL(b);
      } else {
        var l = f.URL || f.webkitURL,
          m = l.createObjectURL(b);
        g ? g.location = m : location.href = m, g = null, setTimeout(function () {
          l.revokeObjectURL(m);
        }, 4E4);
      }
    });
  f.saveAs = g.saveAs = g,  true && (module.exports = g);
});

/***/ }),

/***/ 61788:
/*!**************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/index.js ***!
  \**************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _types_options__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./types/options */ 50460);
/* harmony import */ var _l10n_default__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./l10n/default */ 70521);
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils */ 90238);
/* harmony import */ var _utils_dom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/dom */ 52750);
/* harmony import */ var _utils_dates__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utils/dates */ 41695);
/* harmony import */ var _utils_formatting__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/formatting */ 17563);
/* harmony import */ var _utils_polyfills__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/polyfills */ 19522);
/* harmony import */ var _utils_polyfills__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(_utils_polyfills__WEBPACK_IMPORTED_MODULE_6__);
var __assign = undefined && undefined.__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];
      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    }
    return t;
  };
  return __assign.apply(this, arguments);
};
var __spreadArrays = undefined && undefined.__spreadArrays || function () {
  for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j];
  return r;
};







var DEBOUNCED_CHANGE_MS = 300;
function FlatpickrInstance(element, instanceConfig) {
  var self = {
    config: __assign(__assign({}, _types_options__WEBPACK_IMPORTED_MODULE_0__.defaults), flatpickr.defaultConfig),
    l10n: _l10n_default__WEBPACK_IMPORTED_MODULE_1__["default"]
  };
  self.parseDate = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.createDateParser)({
    config: self.config,
    l10n: self.l10n
  });
  self._handlers = [];
  self.pluginElements = [];
  self.loadedPlugins = [];
  self._bind = bind;
  self._setHoursFromDate = setHoursFromDate;
  self._positionCalendar = positionCalendar;
  self.changeMonth = changeMonth;
  self.changeYear = changeYear;
  self.clear = clear;
  self.close = close;
  self.onMouseOver = onMouseOver;
  self._createElement = _utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement;
  self.createDay = createDay;
  self.destroy = destroy;
  self.isEnabled = isEnabled;
  self.jumpToDate = jumpToDate;
  self.updateValue = updateValue;
  self.open = open;
  self.redraw = redraw;
  self.set = set;
  self.setDate = setDate;
  self.toggle = toggle;
  function setupHelperFunctions() {
    self.utils = {
      getDaysInMonth: function (month, yr) {
        if (month === void 0) {
          month = self.currentMonth;
        }
        if (yr === void 0) {
          yr = self.currentYear;
        }
        if (month === 1 && (yr % 4 === 0 && yr % 100 !== 0 || yr % 400 === 0)) return 29;
        return self.l10n.daysInMonth[month];
      }
    };
  }
  function init() {
    self.element = self.input = element;
    self.isOpen = false;
    parseConfig();
    setupLocale();
    setupInputs();
    setupDates();
    setupHelperFunctions();
    if (!self.isMobile) build();
    bindEvents();
    if (self.selectedDates.length || self.config.noCalendar) {
      if (self.config.enableTime) {
        setHoursFromDate(self.config.noCalendar ? self.latestSelectedDateObj : undefined);
      }
      updateValue(false);
    }
    setCalendarWidth();
    var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
    if (!self.isMobile && isSafari) {
      positionCalendar();
    }
    triggerEvent("onReady");
  }
  function getClosestActiveElement() {
    var _a;
    return ((_a = self.calendarContainer) === null || _a === void 0 ? void 0 : _a.getRootNode()).activeElement || document.activeElement;
  }
  function bindToInstance(fn) {
    return fn.bind(self);
  }
  function setCalendarWidth() {
    var config = self.config;
    if (config.weekNumbers === false && config.showMonths === 1) {
      return;
    } else if (config.noCalendar !== true) {
      window.requestAnimationFrame(function () {
        if (self.calendarContainer !== undefined) {
          self.calendarContainer.style.visibility = "hidden";
          self.calendarContainer.style.display = "block";
        }
        if (self.daysContainer !== undefined) {
          var daysWidth = (self.days.offsetWidth + 1) * config.showMonths;
          self.daysContainer.style.width = daysWidth + "px";
          self.calendarContainer.style.width = daysWidth + (self.weekWrapper !== undefined ? self.weekWrapper.offsetWidth : 0) + "px";
          self.calendarContainer.style.removeProperty("visibility");
          self.calendarContainer.style.removeProperty("display");
        }
      });
    }
  }
  function updateTime(e) {
    if (self.selectedDates.length === 0) {
      var defaultDate = self.config.minDate === undefined || (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(new Date(), self.config.minDate) >= 0 ? new Date() : new Date(self.config.minDate.getTime());
      var defaults = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.getDefaultHours)(self.config);
      defaultDate.setHours(defaults.hours, defaults.minutes, defaults.seconds, defaultDate.getMilliseconds());
      self.selectedDates = [defaultDate];
      self.latestSelectedDateObj = defaultDate;
    }
    if (e !== undefined && e.type !== "blur") {
      timeWrapper(e);
    }
    var prevValue = self._input.value;
    setHoursFromInputs();
    updateValue();
    if (self._input.value !== prevValue) {
      self._debouncedChange();
    }
  }
  function ampm2military(hour, amPM) {
    return hour % 12 + 12 * (0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(amPM === self.l10n.amPM[1]);
  }
  function military2ampm(hour) {
    switch (hour % 24) {
      case 0:
      case 12:
        return 12;
      default:
        return hour % 12;
    }
  }
  function setHoursFromInputs() {
    if (self.hourElement === undefined || self.minuteElement === undefined) return;
    var hours = (parseInt(self.hourElement.value.slice(-2), 10) || 0) % 24,
      minutes = (parseInt(self.minuteElement.value, 10) || 0) % 60,
      seconds = self.secondElement !== undefined ? (parseInt(self.secondElement.value, 10) || 0) % 60 : 0;
    if (self.amPM !== undefined) {
      hours = ampm2military(hours, self.amPM.textContent);
    }
    var limitMinHours = self.config.minTime !== undefined || self.config.minDate && self.minDateHasTime && self.latestSelectedDateObj && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(self.latestSelectedDateObj, self.config.minDate, true) === 0;
    var limitMaxHours = self.config.maxTime !== undefined || self.config.maxDate && self.maxDateHasTime && self.latestSelectedDateObj && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(self.latestSelectedDateObj, self.config.maxDate, true) === 0;
    if (self.config.maxTime !== undefined && self.config.minTime !== undefined && self.config.minTime > self.config.maxTime) {
      var minBound = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.calculateSecondsSinceMidnight)(self.config.minTime.getHours(), self.config.minTime.getMinutes(), self.config.minTime.getSeconds());
      var maxBound = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.calculateSecondsSinceMidnight)(self.config.maxTime.getHours(), self.config.maxTime.getMinutes(), self.config.maxTime.getSeconds());
      var currentTime = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.calculateSecondsSinceMidnight)(hours, minutes, seconds);
      if (currentTime > maxBound && currentTime < minBound) {
        var result = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.parseSeconds)(minBound);
        hours = result[0];
        minutes = result[1];
        seconds = result[2];
      }
    } else {
      if (limitMaxHours) {
        var maxTime = self.config.maxTime !== undefined ? self.config.maxTime : self.config.maxDate;
        hours = Math.min(hours, maxTime.getHours());
        if (hours === maxTime.getHours()) minutes = Math.min(minutes, maxTime.getMinutes());
        if (minutes === maxTime.getMinutes()) seconds = Math.min(seconds, maxTime.getSeconds());
      }
      if (limitMinHours) {
        var minTime = self.config.minTime !== undefined ? self.config.minTime : self.config.minDate;
        hours = Math.max(hours, minTime.getHours());
        if (hours === minTime.getHours() && minutes < minTime.getMinutes()) minutes = minTime.getMinutes();
        if (minutes === minTime.getMinutes()) seconds = Math.max(seconds, minTime.getSeconds());
      }
    }
    setHours(hours, minutes, seconds);
  }
  function setHoursFromDate(dateObj) {
    var date = dateObj || self.latestSelectedDateObj;
    if (date && date instanceof Date) {
      setHours(date.getHours(), date.getMinutes(), date.getSeconds());
    }
  }
  function setHours(hours, minutes, seconds) {
    if (self.latestSelectedDateObj !== undefined) {
      self.latestSelectedDateObj.setHours(hours % 24, minutes, seconds || 0, 0);
    }
    if (!self.hourElement || !self.minuteElement || self.isMobile) return;
    self.hourElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(!self.config.time_24hr ? (12 + hours) % 12 + 12 * (0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(hours % 12 === 0) : hours);
    self.minuteElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(minutes);
    if (self.amPM !== undefined) self.amPM.textContent = self.l10n.amPM[(0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(hours >= 12)];
    if (self.secondElement !== undefined) self.secondElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(seconds);
  }
  function onYearInput(event) {
    var eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(event);
    var year = parseInt(eventTarget.value) + (event.delta || 0);
    if (year / 1000 > 1 || event.key === "Enter" && !/[^\d]/.test(year.toString())) {
      changeYear(year);
    }
  }
  function bind(element, event, handler, options) {
    if (event instanceof Array) return event.forEach(function (ev) {
      return bind(element, ev, handler, options);
    });
    if (element instanceof Array) return element.forEach(function (el) {
      return bind(el, event, handler, options);
    });
    element.addEventListener(event, handler, options);
    self._handlers.push({
      remove: function () {
        return element.removeEventListener(event, handler, options);
      }
    });
  }
  function triggerChange() {
    triggerEvent("onChange");
  }
  function bindEvents() {
    if (self.config.wrap) {
      ["open", "close", "toggle", "clear"].forEach(function (evt) {
        Array.prototype.forEach.call(self.element.querySelectorAll("[data-" + evt + "]"), function (el) {
          return bind(el, "click", self[evt]);
        });
      });
    }
    if (self.isMobile) {
      setupMobile();
      return;
    }
    var debouncedResize = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.debounce)(onResize, 50);
    self._debouncedChange = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.debounce)(triggerChange, DEBOUNCED_CHANGE_MS);
    if (self.daysContainer && !/iPhone|iPad|iPod/i.test(navigator.userAgent)) bind(self.daysContainer, "mouseover", function (e) {
      if (self.config.mode === "range") onMouseOver((0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e));
    });
    bind(self._input, "keydown", onKeyDown);
    if (self.calendarContainer !== undefined) {
      bind(self.calendarContainer, "keydown", onKeyDown);
    }
    if (!self.config.inline && !self.config.static) bind(window, "resize", debouncedResize);
    if (window.ontouchstart !== undefined) bind(window.document, "touchstart", documentClick);else bind(window.document, "mousedown", documentClick);
    bind(window.document, "focus", documentClick, {
      capture: true
    });
    if (self.config.clickOpens === true) {
      bind(self._input, "focus", self.open);
      bind(self._input, "click", self.open);
    }
    if (self.daysContainer !== undefined) {
      bind(self.monthNav, "click", onMonthNavClick);
      bind(self.monthNav, ["keyup", "increment"], onYearInput);
      bind(self.daysContainer, "click", selectDate);
    }
    if (self.timeContainer !== undefined && self.minuteElement !== undefined && self.hourElement !== undefined) {
      var selText = function (e) {
        return (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e).select();
      };
      bind(self.timeContainer, ["increment"], updateTime);
      bind(self.timeContainer, "blur", updateTime, {
        capture: true
      });
      bind(self.timeContainer, "click", timeIncrement);
      bind([self.hourElement, self.minuteElement], ["focus", "click"], selText);
      if (self.secondElement !== undefined) bind(self.secondElement, "focus", function () {
        return self.secondElement && self.secondElement.select();
      });
      if (self.amPM !== undefined) {
        bind(self.amPM, "click", function (e) {
          updateTime(e);
        });
      }
    }
    if (self.config.allowInput) {
      bind(self._input, "blur", onBlur);
    }
  }
  function jumpToDate(jumpDate, triggerChange) {
    var jumpTo = jumpDate !== undefined ? self.parseDate(jumpDate) : self.latestSelectedDateObj || (self.config.minDate && self.config.minDate > self.now ? self.config.minDate : self.config.maxDate && self.config.maxDate < self.now ? self.config.maxDate : self.now);
    var oldYear = self.currentYear;
    var oldMonth = self.currentMonth;
    try {
      if (jumpTo !== undefined) {
        self.currentYear = jumpTo.getFullYear();
        self.currentMonth = jumpTo.getMonth();
      }
    } catch (e) {
      e.message = "Invalid date supplied: " + jumpTo;
      self.config.errorHandler(e);
    }
    if (triggerChange && self.currentYear !== oldYear) {
      triggerEvent("onYearChange");
      buildMonthSwitch();
    }
    if (triggerChange && (self.currentYear !== oldYear || self.currentMonth !== oldMonth)) {
      triggerEvent("onMonthChange");
    }
    self.redraw();
  }
  function timeIncrement(e) {
    var eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
    if (~eventTarget.className.indexOf("arrow")) incrementNumInput(e, eventTarget.classList.contains("arrowUp") ? 1 : -1);
  }
  function incrementNumInput(e, delta, inputElem) {
    var target = e && (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
    var input = inputElem || target && target.parentNode && target.parentNode.firstChild;
    var event = createEvent("increment");
    event.delta = delta;
    input && input.dispatchEvent(event);
  }
  function build() {
    var fragment = window.document.createDocumentFragment();
    self.calendarContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-calendar");
    self.calendarContainer.tabIndex = -1;
    if (!self.config.noCalendar) {
      fragment.appendChild(buildMonthNav());
      self.innerContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-innerContainer");
      if (self.config.weekNumbers) {
        var _a = buildWeeks(),
          weekWrapper = _a.weekWrapper,
          weekNumbers = _a.weekNumbers;
        self.innerContainer.appendChild(weekWrapper);
        self.weekNumbers = weekNumbers;
        self.weekWrapper = weekWrapper;
      }
      self.rContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-rContainer");
      self.rContainer.appendChild(buildWeekdays());
      if (!self.daysContainer) {
        self.daysContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-days");
        self.daysContainer.tabIndex = -1;
      }
      buildDays();
      self.rContainer.appendChild(self.daysContainer);
      self.innerContainer.appendChild(self.rContainer);
      fragment.appendChild(self.innerContainer);
    }
    if (self.config.enableTime) {
      fragment.appendChild(buildTime());
    }
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "rangeMode", self.config.mode === "range");
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "animate", self.config.animate === true);
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "multiMonth", self.config.showMonths > 1);
    self.calendarContainer.appendChild(fragment);
    var customAppend = self.config.appendTo !== undefined && self.config.appendTo.nodeType !== undefined;
    if (self.config.inline || self.config.static) {
      self.calendarContainer.classList.add(self.config.inline ? "inline" : "static");
      if (self.config.inline) {
        if (!customAppend && self.element.parentNode) self.element.parentNode.insertBefore(self.calendarContainer, self._input.nextSibling);else if (self.config.appendTo !== undefined) self.config.appendTo.appendChild(self.calendarContainer);
      }
      if (self.config.static) {
        var wrapper = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-wrapper");
        if (self.element.parentNode) self.element.parentNode.insertBefore(wrapper, self.element);
        wrapper.appendChild(self.element);
        if (self.altInput) wrapper.appendChild(self.altInput);
        wrapper.appendChild(self.calendarContainer);
      }
    }
    if (!self.config.static && !self.config.inline) (self.config.appendTo !== undefined ? self.config.appendTo : window.document.body).appendChild(self.calendarContainer);
  }
  function createDay(className, date, _dayNumber, i) {
    var dateIsEnabled = isEnabled(date, true),
      dayElement = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", className, date.getDate().toString());
    dayElement.dateObj = date;
    dayElement.$i = i;
    dayElement.setAttribute("aria-label", self.formatDate(date, self.config.ariaDateFormat));
    if (className.indexOf("hidden") === -1 && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(date, self.now) === 0) {
      self.todayDateElem = dayElement;
      dayElement.classList.add("today");
      dayElement.setAttribute("aria-current", "date");
    }
    if (dateIsEnabled) {
      dayElement.tabIndex = -1;
      if (isDateSelected(date)) {
        dayElement.classList.add("selected");
        self.selectedDateElem = dayElement;
        if (self.config.mode === "range") {
          (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(dayElement, "startRange", self.selectedDates[0] && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(date, self.selectedDates[0], true) === 0);
          (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(dayElement, "endRange", self.selectedDates[1] && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(date, self.selectedDates[1], true) === 0);
          if (className === "nextMonthDay") dayElement.classList.add("inRange");
        }
      }
    } else {
      dayElement.classList.add("flatpickr-disabled");
    }
    if (self.config.mode === "range") {
      if (isDateInRange(date) && !isDateSelected(date)) dayElement.classList.add("inRange");
    }
    if (self.weekNumbers && self.config.showMonths === 1 && className !== "prevMonthDay" && i % 7 === 6) {
      self.weekNumbers.insertAdjacentHTML("beforeend", "<span class='flatpickr-day'>" + self.config.getWeek(date) + "</span>");
    }
    triggerEvent("onDayCreate", dayElement);
    return dayElement;
  }
  function focusOnDayElem(targetNode) {
    targetNode.focus();
    if (self.config.mode === "range") onMouseOver(targetNode);
  }
  function getFirstAvailableDay(delta) {
    var startMonth = delta > 0 ? 0 : self.config.showMonths - 1;
    var endMonth = delta > 0 ? self.config.showMonths : -1;
    for (var m = startMonth; m != endMonth; m += delta) {
      var month = self.daysContainer.children[m];
      var startIndex = delta > 0 ? 0 : month.children.length - 1;
      var endIndex = delta > 0 ? month.children.length : -1;
      for (var i = startIndex; i != endIndex; i += delta) {
        var c = month.children[i];
        if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj)) return c;
      }
    }
    return undefined;
  }
  function getNextAvailableDay(current, delta) {
    var givenMonth = current.className.indexOf("Month") === -1 ? current.dateObj.getMonth() : self.currentMonth;
    var endMonth = delta > 0 ? self.config.showMonths : -1;
    var loopDelta = delta > 0 ? 1 : -1;
    for (var m = givenMonth - self.currentMonth; m != endMonth; m += loopDelta) {
      var month = self.daysContainer.children[m];
      var startIndex = givenMonth - self.currentMonth === m ? current.$i + delta : delta < 0 ? month.children.length - 1 : 0;
      var numMonthDays = month.children.length;
      for (var i = startIndex; i >= 0 && i < numMonthDays && i != (delta > 0 ? numMonthDays : -1); i += loopDelta) {
        var c = month.children[i];
        if (c.className.indexOf("hidden") === -1 && isEnabled(c.dateObj) && Math.abs(current.$i - i) >= Math.abs(delta)) return focusOnDayElem(c);
      }
    }
    self.changeMonth(loopDelta);
    focusOnDay(getFirstAvailableDay(loopDelta), 0);
    return undefined;
  }
  function focusOnDay(current, offset) {
    var activeElement = getClosestActiveElement();
    var dayFocused = isInView(activeElement || document.body);
    var startElem = current !== undefined ? current : dayFocused ? activeElement : self.selectedDateElem !== undefined && isInView(self.selectedDateElem) ? self.selectedDateElem : self.todayDateElem !== undefined && isInView(self.todayDateElem) ? self.todayDateElem : getFirstAvailableDay(offset > 0 ? 1 : -1);
    if (startElem === undefined) {
      self._input.focus();
    } else if (!dayFocused) {
      focusOnDayElem(startElem);
    } else {
      getNextAvailableDay(startElem, offset);
    }
  }
  function buildMonthDays(year, month) {
    var firstOfMonth = (new Date(year, month, 1).getDay() - self.l10n.firstDayOfWeek + 7) % 7;
    var prevMonthDays = self.utils.getDaysInMonth((month - 1 + 12) % 12, year);
    var daysInMonth = self.utils.getDaysInMonth(month, year),
      days = window.document.createDocumentFragment(),
      isMultiMonth = self.config.showMonths > 1,
      prevMonthDayClass = isMultiMonth ? "prevMonthDay hidden" : "prevMonthDay",
      nextMonthDayClass = isMultiMonth ? "nextMonthDay hidden" : "nextMonthDay";
    var dayNumber = prevMonthDays + 1 - firstOfMonth,
      dayIndex = 0;
    for (; dayNumber <= prevMonthDays; dayNumber++, dayIndex++) {
      days.appendChild(createDay("flatpickr-day " + prevMonthDayClass, new Date(year, month - 1, dayNumber), dayNumber, dayIndex));
    }
    for (dayNumber = 1; dayNumber <= daysInMonth; dayNumber++, dayIndex++) {
      days.appendChild(createDay("flatpickr-day", new Date(year, month, dayNumber), dayNumber, dayIndex));
    }
    for (var dayNum = daysInMonth + 1; dayNum <= 42 - firstOfMonth && (self.config.showMonths === 1 || dayIndex % 7 !== 0); dayNum++, dayIndex++) {
      days.appendChild(createDay("flatpickr-day " + nextMonthDayClass, new Date(year, month + 1, dayNum % daysInMonth), dayNum, dayIndex));
    }
    var dayContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "dayContainer");
    dayContainer.appendChild(days);
    return dayContainer;
  }
  function buildDays() {
    if (self.daysContainer === undefined) {
      return;
    }
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.clearNode)(self.daysContainer);
    if (self.weekNumbers) (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.clearNode)(self.weekNumbers);
    var frag = document.createDocumentFragment();
    for (var i = 0; i < self.config.showMonths; i++) {
      var d = new Date(self.currentYear, self.currentMonth, 1);
      d.setMonth(self.currentMonth + i);
      frag.appendChild(buildMonthDays(d.getFullYear(), d.getMonth()));
    }
    self.daysContainer.appendChild(frag);
    self.days = self.daysContainer.firstChild;
    if (self.config.mode === "range" && self.selectedDates.length === 1) {
      onMouseOver();
    }
  }
  function buildMonthSwitch() {
    if (self.config.showMonths > 1 || self.config.monthSelectorType !== "dropdown") return;
    var shouldBuildMonth = function (month) {
      if (self.config.minDate !== undefined && self.currentYear === self.config.minDate.getFullYear() && month < self.config.minDate.getMonth()) {
        return false;
      }
      return !(self.config.maxDate !== undefined && self.currentYear === self.config.maxDate.getFullYear() && month > self.config.maxDate.getMonth());
    };
    self.monthsDropdownContainer.tabIndex = -1;
    self.monthsDropdownContainer.innerHTML = "";
    for (var i = 0; i < 12; i++) {
      if (!shouldBuildMonth(i)) continue;
      var month = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("option", "flatpickr-monthDropdown-month");
      month.value = new Date(self.currentYear, i).getMonth().toString();
      month.textContent = (0,_utils_formatting__WEBPACK_IMPORTED_MODULE_5__.monthToStr)(i, self.config.shorthandCurrentMonth, self.l10n);
      month.tabIndex = -1;
      if (self.currentMonth === i) {
        month.selected = true;
      }
      self.monthsDropdownContainer.appendChild(month);
    }
  }
  function buildMonth() {
    var container = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-month");
    var monthNavFragment = window.document.createDocumentFragment();
    var monthElement;
    if (self.config.showMonths > 1 || self.config.monthSelectorType === "static") {
      monthElement = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "cur-month");
    } else {
      self.monthsDropdownContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("select", "flatpickr-monthDropdown-months");
      self.monthsDropdownContainer.setAttribute("aria-label", self.l10n.monthAriaLabel);
      bind(self.monthsDropdownContainer, "change", function (e) {
        var target = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
        var selectedMonth = parseInt(target.value, 10);
        self.changeMonth(selectedMonth - self.currentMonth);
        triggerEvent("onMonthChange");
      });
      buildMonthSwitch();
      monthElement = self.monthsDropdownContainer;
    }
    var yearInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createNumberInput)("cur-year", {
      tabindex: "-1"
    });
    var yearElement = yearInput.getElementsByTagName("input")[0];
    yearElement.setAttribute("aria-label", self.l10n.yearAriaLabel);
    if (self.config.minDate) {
      yearElement.setAttribute("min", self.config.minDate.getFullYear().toString());
    }
    if (self.config.maxDate) {
      yearElement.setAttribute("max", self.config.maxDate.getFullYear().toString());
      yearElement.disabled = !!self.config.minDate && self.config.minDate.getFullYear() === self.config.maxDate.getFullYear();
    }
    var currentMonth = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-current-month");
    currentMonth.appendChild(monthElement);
    currentMonth.appendChild(yearInput);
    monthNavFragment.appendChild(currentMonth);
    container.appendChild(monthNavFragment);
    return {
      container: container,
      yearElement: yearElement,
      monthElement: monthElement
    };
  }
  function buildMonths() {
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.clearNode)(self.monthNav);
    self.monthNav.appendChild(self.prevMonthNav);
    if (self.config.showMonths) {
      self.yearElements = [];
      self.monthElements = [];
    }
    for (var m = self.config.showMonths; m--;) {
      var month = buildMonth();
      self.yearElements.push(month.yearElement);
      self.monthElements.push(month.monthElement);
      self.monthNav.appendChild(month.container);
    }
    self.monthNav.appendChild(self.nextMonthNav);
  }
  function buildMonthNav() {
    self.monthNav = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-months");
    self.yearElements = [];
    self.monthElements = [];
    self.prevMonthNav = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-prev-month");
    self.prevMonthNav.innerHTML = self.config.prevArrow;
    self.nextMonthNav = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-next-month");
    self.nextMonthNav.innerHTML = self.config.nextArrow;
    buildMonths();
    Object.defineProperty(self, "_hidePrevMonthArrow", {
      get: function () {
        return self.__hidePrevMonthArrow;
      },
      set: function (bool) {
        if (self.__hidePrevMonthArrow !== bool) {
          (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.prevMonthNav, "flatpickr-disabled", bool);
          self.__hidePrevMonthArrow = bool;
        }
      }
    });
    Object.defineProperty(self, "_hideNextMonthArrow", {
      get: function () {
        return self.__hideNextMonthArrow;
      },
      set: function (bool) {
        if (self.__hideNextMonthArrow !== bool) {
          (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.nextMonthNav, "flatpickr-disabled", bool);
          self.__hideNextMonthArrow = bool;
        }
      }
    });
    self.currentYearElement = self.yearElements[0];
    updateNavigationCurrentMonth();
    return self.monthNav;
  }
  function buildTime() {
    self.calendarContainer.classList.add("hasTime");
    if (self.config.noCalendar) self.calendarContainer.classList.add("noCalendar");
    var defaults = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.getDefaultHours)(self.config);
    self.timeContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-time");
    self.timeContainer.tabIndex = -1;
    var separator = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-time-separator", ":");
    var hourInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createNumberInput)("flatpickr-hour", {
      "aria-label": self.l10n.hourAriaLabel
    });
    self.hourElement = hourInput.getElementsByTagName("input")[0];
    var minuteInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createNumberInput)("flatpickr-minute", {
      "aria-label": self.l10n.minuteAriaLabel
    });
    self.minuteElement = minuteInput.getElementsByTagName("input")[0];
    self.hourElement.tabIndex = self.minuteElement.tabIndex = -1;
    self.hourElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(self.latestSelectedDateObj ? self.latestSelectedDateObj.getHours() : self.config.time_24hr ? defaults.hours : military2ampm(defaults.hours));
    self.minuteElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(self.latestSelectedDateObj ? self.latestSelectedDateObj.getMinutes() : defaults.minutes);
    self.hourElement.setAttribute("step", self.config.hourIncrement.toString());
    self.minuteElement.setAttribute("step", self.config.minuteIncrement.toString());
    self.hourElement.setAttribute("min", self.config.time_24hr ? "0" : "1");
    self.hourElement.setAttribute("max", self.config.time_24hr ? "23" : "12");
    self.hourElement.setAttribute("maxlength", "2");
    self.minuteElement.setAttribute("min", "0");
    self.minuteElement.setAttribute("max", "59");
    self.minuteElement.setAttribute("maxlength", "2");
    self.timeContainer.appendChild(hourInput);
    self.timeContainer.appendChild(separator);
    self.timeContainer.appendChild(minuteInput);
    if (self.config.time_24hr) self.timeContainer.classList.add("time24hr");
    if (self.config.enableSeconds) {
      self.timeContainer.classList.add("hasSeconds");
      var secondInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createNumberInput)("flatpickr-second");
      self.secondElement = secondInput.getElementsByTagName("input")[0];
      self.secondElement.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(self.latestSelectedDateObj ? self.latestSelectedDateObj.getSeconds() : defaults.seconds);
      self.secondElement.setAttribute("step", self.minuteElement.getAttribute("step"));
      self.secondElement.setAttribute("min", "0");
      self.secondElement.setAttribute("max", "59");
      self.secondElement.setAttribute("maxlength", "2");
      self.timeContainer.appendChild((0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-time-separator", ":"));
      self.timeContainer.appendChild(secondInput);
    }
    if (!self.config.time_24hr) {
      self.amPM = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-am-pm", self.l10n.amPM[(0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)((self.latestSelectedDateObj ? self.hourElement.value : self.config.defaultHour) > 11)]);
      self.amPM.title = self.l10n.toggleTitle;
      self.amPM.tabIndex = -1;
      self.timeContainer.appendChild(self.amPM);
    }
    return self.timeContainer;
  }
  function buildWeekdays() {
    if (!self.weekdayContainer) self.weekdayContainer = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-weekdays");else (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.clearNode)(self.weekdayContainer);
    for (var i = self.config.showMonths; i--;) {
      var container = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-weekdaycontainer");
      self.weekdayContainer.appendChild(container);
    }
    updateWeekdays();
    return self.weekdayContainer;
  }
  function updateWeekdays() {
    if (!self.weekdayContainer) {
      return;
    }
    var firstDayOfWeek = self.l10n.firstDayOfWeek;
    var weekdays = __spreadArrays(self.l10n.weekdays.shorthand);
    if (firstDayOfWeek > 0 && firstDayOfWeek < weekdays.length) {
      weekdays = __spreadArrays(weekdays.splice(firstDayOfWeek, weekdays.length), weekdays.splice(0, firstDayOfWeek));
    }
    for (var i = self.config.showMonths; i--;) {
      self.weekdayContainer.children[i].innerHTML = "\n      <span class='flatpickr-weekday'>\n        " + weekdays.join("</span><span class='flatpickr-weekday'>") + "\n      </span>\n      ";
    }
  }
  function buildWeeks() {
    self.calendarContainer.classList.add("hasWeeks");
    var weekWrapper = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-weekwrapper");
    weekWrapper.appendChild((0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("span", "flatpickr-weekday", self.l10n.weekAbbreviation));
    var weekNumbers = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("div", "flatpickr-weeks");
    weekWrapper.appendChild(weekNumbers);
    return {
      weekWrapper: weekWrapper,
      weekNumbers: weekNumbers
    };
  }
  function changeMonth(value, isOffset) {
    if (isOffset === void 0) {
      isOffset = true;
    }
    var delta = isOffset ? value : value - self.currentMonth;
    if (delta < 0 && self._hidePrevMonthArrow === true || delta > 0 && self._hideNextMonthArrow === true) return;
    self.currentMonth += delta;
    if (self.currentMonth < 0 || self.currentMonth > 11) {
      self.currentYear += self.currentMonth > 11 ? 1 : -1;
      self.currentMonth = (self.currentMonth + 12) % 12;
      triggerEvent("onYearChange");
      buildMonthSwitch();
    }
    buildDays();
    triggerEvent("onMonthChange");
    updateNavigationCurrentMonth();
  }
  function clear(triggerChangeEvent, toInitial) {
    if (triggerChangeEvent === void 0) {
      triggerChangeEvent = true;
    }
    if (toInitial === void 0) {
      toInitial = true;
    }
    self.input.value = "";
    if (self.altInput !== undefined) self.altInput.value = "";
    if (self.mobileInput !== undefined) self.mobileInput.value = "";
    self.selectedDates = [];
    self.latestSelectedDateObj = undefined;
    if (toInitial === true) {
      self.currentYear = self._initialDate.getFullYear();
      self.currentMonth = self._initialDate.getMonth();
    }
    if (self.config.enableTime === true) {
      var _a = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.getDefaultHours)(self.config),
        hours = _a.hours,
        minutes = _a.minutes,
        seconds = _a.seconds;
      setHours(hours, minutes, seconds);
    }
    self.redraw();
    if (triggerChangeEvent) triggerEvent("onChange");
  }
  function close() {
    self.isOpen = false;
    if (!self.isMobile) {
      if (self.calendarContainer !== undefined) {
        self.calendarContainer.classList.remove("open");
      }
      if (self._input !== undefined) {
        self._input.classList.remove("active");
      }
    }
    triggerEvent("onClose");
  }
  function destroy() {
    if (self.config !== undefined) triggerEvent("onDestroy");
    for (var i = self._handlers.length; i--;) {
      self._handlers[i].remove();
    }
    self._handlers = [];
    if (self.mobileInput) {
      if (self.mobileInput.parentNode) self.mobileInput.parentNode.removeChild(self.mobileInput);
      self.mobileInput = undefined;
    } else if (self.calendarContainer && self.calendarContainer.parentNode) {
      if (self.config.static && self.calendarContainer.parentNode) {
        var wrapper = self.calendarContainer.parentNode;
        wrapper.lastChild && wrapper.removeChild(wrapper.lastChild);
        if (wrapper.parentNode) {
          while (wrapper.firstChild) wrapper.parentNode.insertBefore(wrapper.firstChild, wrapper);
          wrapper.parentNode.removeChild(wrapper);
        }
      } else self.calendarContainer.parentNode.removeChild(self.calendarContainer);
    }
    if (self.altInput) {
      self.input.type = "text";
      if (self.altInput.parentNode) self.altInput.parentNode.removeChild(self.altInput);
      delete self.altInput;
    }
    if (self.input) {
      self.input.type = self.input._type;
      self.input.classList.remove("flatpickr-input");
      self.input.removeAttribute("readonly");
    }
    ["_showTimeInput", "latestSelectedDateObj", "_hideNextMonthArrow", "_hidePrevMonthArrow", "__hideNextMonthArrow", "__hidePrevMonthArrow", "isMobile", "isOpen", "selectedDateElem", "minDateHasTime", "maxDateHasTime", "days", "daysContainer", "_input", "_positionElement", "innerContainer", "rContainer", "monthNav", "todayDateElem", "calendarContainer", "weekdayContainer", "prevMonthNav", "nextMonthNav", "monthsDropdownContainer", "currentMonthElement", "currentYearElement", "navigationCurrentMonth", "selectedDateElem", "config"].forEach(function (k) {
      try {
        delete self[k];
      } catch (_) {}
    });
  }
  function isCalendarElem(elem) {
    return self.calendarContainer.contains(elem);
  }
  function documentClick(e) {
    if (self.isOpen && !self.config.inline) {
      var eventTarget_1 = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
      var isCalendarElement = isCalendarElem(eventTarget_1);
      var isInput = eventTarget_1 === self.input || eventTarget_1 === self.altInput || self.element.contains(eventTarget_1) || e.path && e.path.indexOf && (~e.path.indexOf(self.input) || ~e.path.indexOf(self.altInput));
      var lostFocus = !isInput && !isCalendarElement && !isCalendarElem(e.relatedTarget);
      var isIgnored = !self.config.ignoredFocusElements.some(function (elem) {
        return elem.contains(eventTarget_1);
      });
      if (lostFocus && isIgnored) {
        if (self.config.allowInput) {
          self.setDate(self._input.value, false, self.config.altInput ? self.config.altFormat : self.config.dateFormat);
        }
        if (self.timeContainer !== undefined && self.minuteElement !== undefined && self.hourElement !== undefined && self.input.value !== "" && self.input.value !== undefined) {
          updateTime();
        }
        self.close();
        if (self.config && self.config.mode === "range" && self.selectedDates.length === 1) self.clear(false);
      }
    }
  }
  function changeYear(newYear) {
    if (!newYear || self.config.minDate && newYear < self.config.minDate.getFullYear() || self.config.maxDate && newYear > self.config.maxDate.getFullYear()) return;
    var newYearNum = newYear,
      isNewYear = self.currentYear !== newYearNum;
    self.currentYear = newYearNum || self.currentYear;
    if (self.config.maxDate && self.currentYear === self.config.maxDate.getFullYear()) {
      self.currentMonth = Math.min(self.config.maxDate.getMonth(), self.currentMonth);
    } else if (self.config.minDate && self.currentYear === self.config.minDate.getFullYear()) {
      self.currentMonth = Math.max(self.config.minDate.getMonth(), self.currentMonth);
    }
    if (isNewYear) {
      self.redraw();
      triggerEvent("onYearChange");
      buildMonthSwitch();
    }
  }
  function isEnabled(date, timeless) {
    var _a;
    if (timeless === void 0) {
      timeless = true;
    }
    var dateToCheck = self.parseDate(date, undefined, timeless);
    if (self.config.minDate && dateToCheck && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(dateToCheck, self.config.minDate, timeless !== undefined ? timeless : !self.minDateHasTime) < 0 || self.config.maxDate && dateToCheck && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(dateToCheck, self.config.maxDate, timeless !== undefined ? timeless : !self.maxDateHasTime) > 0) return false;
    if (!self.config.enable && self.config.disable.length === 0) return true;
    if (dateToCheck === undefined) return false;
    var bool = !!self.config.enable,
      array = (_a = self.config.enable) !== null && _a !== void 0 ? _a : self.config.disable;
    for (var i = 0, d = void 0; i < array.length; i++) {
      d = array[i];
      if (typeof d === "function" && d(dateToCheck)) return bool;else if (d instanceof Date && dateToCheck !== undefined && d.getTime() === dateToCheck.getTime()) return bool;else if (typeof d === "string") {
        var parsed = self.parseDate(d, undefined, true);
        return parsed && parsed.getTime() === dateToCheck.getTime() ? bool : !bool;
      } else if (typeof d === "object" && dateToCheck !== undefined && d.from && d.to && dateToCheck.getTime() >= d.from.getTime() && dateToCheck.getTime() <= d.to.getTime()) return bool;
    }
    return !bool;
  }
  function isInView(elem) {
    if (self.daysContainer !== undefined) return elem.className.indexOf("hidden") === -1 && elem.className.indexOf("flatpickr-disabled") === -1 && self.daysContainer.contains(elem);
    return false;
  }
  function onBlur(e) {
    var isInput = e.target === self._input;
    var valueChanged = self._input.value.trimEnd() !== getDateStr();
    if (isInput && valueChanged && !(e.relatedTarget && isCalendarElem(e.relatedTarget))) {
      self.setDate(self._input.value, true, e.target === self.altInput ? self.config.altFormat : self.config.dateFormat);
    }
  }
  function onKeyDown(e) {
    var eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
    var isInput = self.config.wrap ? element.contains(eventTarget) : eventTarget === self._input;
    var allowInput = self.config.allowInput;
    var allowKeydown = self.isOpen && (!allowInput || !isInput);
    var allowInlineKeydown = self.config.inline && isInput && !allowInput;
    if (e.keyCode === 13 && isInput) {
      if (allowInput) {
        self.setDate(self._input.value, true, eventTarget === self.altInput ? self.config.altFormat : self.config.dateFormat);
        self.close();
        return eventTarget.blur();
      } else {
        self.open();
      }
    } else if (isCalendarElem(eventTarget) || allowKeydown || allowInlineKeydown) {
      var isTimeObj = !!self.timeContainer && self.timeContainer.contains(eventTarget);
      switch (e.keyCode) {
        case 13:
          if (isTimeObj) {
            e.preventDefault();
            updateTime();
            focusAndClose();
          } else selectDate(e);
          break;
        case 27:
          e.preventDefault();
          focusAndClose();
          break;
        case 8:
        case 46:
          if (isInput && !self.config.allowInput) {
            e.preventDefault();
            self.clear();
          }
          break;
        case 37:
        case 39:
          if (!isTimeObj && !isInput) {
            e.preventDefault();
            var activeElement = getClosestActiveElement();
            if (self.daysContainer !== undefined && (allowInput === false || activeElement && isInView(activeElement))) {
              var delta_1 = e.keyCode === 39 ? 1 : -1;
              if (!e.ctrlKey) focusOnDay(undefined, delta_1);else {
                e.stopPropagation();
                changeMonth(delta_1);
                focusOnDay(getFirstAvailableDay(1), 0);
              }
            }
          } else if (self.hourElement) self.hourElement.focus();
          break;
        case 38:
        case 40:
          e.preventDefault();
          var delta = e.keyCode === 40 ? 1 : -1;
          if (self.daysContainer && eventTarget.$i !== undefined || eventTarget === self.input || eventTarget === self.altInput) {
            if (e.ctrlKey) {
              e.stopPropagation();
              changeYear(self.currentYear - delta);
              focusOnDay(getFirstAvailableDay(1), 0);
            } else if (!isTimeObj) focusOnDay(undefined, delta * 7);
          } else if (eventTarget === self.currentYearElement) {
            changeYear(self.currentYear - delta);
          } else if (self.config.enableTime) {
            if (!isTimeObj && self.hourElement) self.hourElement.focus();
            updateTime(e);
            self._debouncedChange();
          }
          break;
        case 9:
          if (isTimeObj) {
            var elems = [self.hourElement, self.minuteElement, self.secondElement, self.amPM].concat(self.pluginElements).filter(function (x) {
              return x;
            });
            var i = elems.indexOf(eventTarget);
            if (i !== -1) {
              var target = elems[i + (e.shiftKey ? -1 : 1)];
              e.preventDefault();
              (target || self._input).focus();
            }
          } else if (!self.config.noCalendar && self.daysContainer && self.daysContainer.contains(eventTarget) && e.shiftKey) {
            e.preventDefault();
            self._input.focus();
          }
          break;
        default:
          break;
      }
    }
    if (self.amPM !== undefined && eventTarget === self.amPM) {
      switch (e.key) {
        case self.l10n.amPM[0].charAt(0):
        case self.l10n.amPM[0].charAt(0).toLowerCase():
          self.amPM.textContent = self.l10n.amPM[0];
          setHoursFromInputs();
          updateValue();
          break;
        case self.l10n.amPM[1].charAt(0):
        case self.l10n.amPM[1].charAt(0).toLowerCase():
          self.amPM.textContent = self.l10n.amPM[1];
          setHoursFromInputs();
          updateValue();
          break;
      }
    }
    if (isInput || isCalendarElem(eventTarget)) {
      triggerEvent("onKeyDown", e);
    }
  }
  function onMouseOver(elem, cellClass) {
    if (cellClass === void 0) {
      cellClass = "flatpickr-day";
    }
    if (self.selectedDates.length !== 1 || elem && (!elem.classList.contains(cellClass) || elem.classList.contains("flatpickr-disabled"))) return;
    var hoverDate = elem ? elem.dateObj.getTime() : self.days.firstElementChild.dateObj.getTime(),
      initialDate = self.parseDate(self.selectedDates[0], undefined, true).getTime(),
      rangeStartDate = Math.min(hoverDate, self.selectedDates[0].getTime()),
      rangeEndDate = Math.max(hoverDate, self.selectedDates[0].getTime());
    var containsDisabled = false;
    var minRange = 0,
      maxRange = 0;
    for (var t = rangeStartDate; t < rangeEndDate; t += _utils_dates__WEBPACK_IMPORTED_MODULE_4__.duration.DAY) {
      if (!isEnabled(new Date(t), true)) {
        containsDisabled = containsDisabled || t > rangeStartDate && t < rangeEndDate;
        if (t < initialDate && (!minRange || t > minRange)) minRange = t;else if (t > initialDate && (!maxRange || t < maxRange)) maxRange = t;
      }
    }
    var hoverableCells = Array.from(self.rContainer.querySelectorAll("*:nth-child(-n+" + self.config.showMonths + ") > ." + cellClass));
    hoverableCells.forEach(function (dayElem) {
      var date = dayElem.dateObj;
      var timestamp = date.getTime();
      var outOfRange = minRange > 0 && timestamp < minRange || maxRange > 0 && timestamp > maxRange;
      if (outOfRange) {
        dayElem.classList.add("notAllowed");
        ["inRange", "startRange", "endRange"].forEach(function (c) {
          dayElem.classList.remove(c);
        });
        return;
      } else if (containsDisabled && !outOfRange) return;
      ["startRange", "inRange", "endRange", "notAllowed"].forEach(function (c) {
        dayElem.classList.remove(c);
      });
      if (elem !== undefined) {
        elem.classList.add(hoverDate <= self.selectedDates[0].getTime() ? "startRange" : "endRange");
        if (initialDate < hoverDate && timestamp === initialDate) dayElem.classList.add("startRange");else if (initialDate > hoverDate && timestamp === initialDate) dayElem.classList.add("endRange");
        if (timestamp >= minRange && (maxRange === 0 || timestamp <= maxRange) && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.isBetween)(timestamp, initialDate, hoverDate)) dayElem.classList.add("inRange");
      }
    });
  }
  function onResize() {
    if (self.isOpen && !self.config.static && !self.config.inline) positionCalendar();
  }
  function open(e, positionElement) {
    if (positionElement === void 0) {
      positionElement = self._positionElement;
    }
    if (self.isMobile === true) {
      if (e) {
        e.preventDefault();
        var eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
        if (eventTarget) {
          eventTarget.blur();
        }
      }
      if (self.mobileInput !== undefined) {
        self.mobileInput.focus();
        self.mobileInput.click();
      }
      triggerEvent("onOpen");
      return;
    } else if (self._input.disabled || self.config.inline) {
      return;
    }
    var wasOpen = self.isOpen;
    self.isOpen = true;
    if (!wasOpen) {
      self.calendarContainer.classList.add("open");
      self._input.classList.add("active");
      triggerEvent("onOpen");
      positionCalendar(positionElement);
    }
    if (self.config.enableTime === true && self.config.noCalendar === true) {
      if (self.config.allowInput === false && (e === undefined || !self.timeContainer.contains(e.relatedTarget))) {
        setTimeout(function () {
          return self.hourElement.select();
        }, 50);
      }
    }
  }
  function minMaxDateSetter(type) {
    return function (date) {
      var dateObj = self.config["_" + type + "Date"] = self.parseDate(date, self.config.dateFormat);
      var inverseDateObj = self.config["_" + (type === "min" ? "max" : "min") + "Date"];
      if (dateObj !== undefined) {
        self[type === "min" ? "minDateHasTime" : "maxDateHasTime"] = dateObj.getHours() > 0 || dateObj.getMinutes() > 0 || dateObj.getSeconds() > 0;
      }
      if (self.selectedDates) {
        self.selectedDates = self.selectedDates.filter(function (d) {
          return isEnabled(d);
        });
        if (!self.selectedDates.length && type === "min") setHoursFromDate(dateObj);
        updateValue();
      }
      if (self.daysContainer) {
        redraw();
        if (dateObj !== undefined) self.currentYearElement[type] = dateObj.getFullYear().toString();else self.currentYearElement.removeAttribute(type);
        self.currentYearElement.disabled = !!inverseDateObj && dateObj !== undefined && inverseDateObj.getFullYear() === dateObj.getFullYear();
      }
    };
  }
  function parseConfig() {
    var boolOpts = ["wrap", "weekNumbers", "allowInput", "allowInvalidPreload", "clickOpens", "time_24hr", "enableTime", "noCalendar", "altInput", "shorthandCurrentMonth", "inline", "static", "enableSeconds", "disableMobile"];
    var userConfig = __assign(__assign({}, JSON.parse(JSON.stringify(element.dataset || {}))), instanceConfig);
    var formats = {};
    self.config.parseDate = userConfig.parseDate;
    self.config.formatDate = userConfig.formatDate;
    Object.defineProperty(self.config, "enable", {
      get: function () {
        return self.config._enable;
      },
      set: function (dates) {
        self.config._enable = parseDateRules(dates);
      }
    });
    Object.defineProperty(self.config, "disable", {
      get: function () {
        return self.config._disable;
      },
      set: function (dates) {
        self.config._disable = parseDateRules(dates);
      }
    });
    var timeMode = userConfig.mode === "time";
    if (!userConfig.dateFormat && (userConfig.enableTime || timeMode)) {
      var defaultDateFormat = flatpickr.defaultConfig.dateFormat || _types_options__WEBPACK_IMPORTED_MODULE_0__.defaults.dateFormat;
      formats.dateFormat = userConfig.noCalendar || timeMode ? "H:i" + (userConfig.enableSeconds ? ":S" : "") : defaultDateFormat + " H:i" + (userConfig.enableSeconds ? ":S" : "");
    }
    if (userConfig.altInput && (userConfig.enableTime || timeMode) && !userConfig.altFormat) {
      var defaultAltFormat = flatpickr.defaultConfig.altFormat || _types_options__WEBPACK_IMPORTED_MODULE_0__.defaults.altFormat;
      formats.altFormat = userConfig.noCalendar || timeMode ? "h:i" + (userConfig.enableSeconds ? ":S K" : " K") : defaultAltFormat + (" h:i" + (userConfig.enableSeconds ? ":S" : "") + " K");
    }
    Object.defineProperty(self.config, "minDate", {
      get: function () {
        return self.config._minDate;
      },
      set: minMaxDateSetter("min")
    });
    Object.defineProperty(self.config, "maxDate", {
      get: function () {
        return self.config._maxDate;
      },
      set: minMaxDateSetter("max")
    });
    var minMaxTimeSetter = function (type) {
      return function (val) {
        self.config[type === "min" ? "_minTime" : "_maxTime"] = self.parseDate(val, "H:i:S");
      };
    };
    Object.defineProperty(self.config, "minTime", {
      get: function () {
        return self.config._minTime;
      },
      set: minMaxTimeSetter("min")
    });
    Object.defineProperty(self.config, "maxTime", {
      get: function () {
        return self.config._maxTime;
      },
      set: minMaxTimeSetter("max")
    });
    if (userConfig.mode === "time") {
      self.config.noCalendar = true;
      self.config.enableTime = true;
    }
    Object.assign(self.config, formats, userConfig);
    for (var i = 0; i < boolOpts.length; i++) self.config[boolOpts[i]] = self.config[boolOpts[i]] === true || self.config[boolOpts[i]] === "true";
    _types_options__WEBPACK_IMPORTED_MODULE_0__.HOOKS.filter(function (hook) {
      return self.config[hook] !== undefined;
    }).forEach(function (hook) {
      self.config[hook] = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.arrayify)(self.config[hook] || []).map(bindToInstance);
    });
    self.isMobile = !self.config.disableMobile && !self.config.inline && self.config.mode === "single" && !self.config.disable.length && !self.config.enable && !self.config.weekNumbers && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
    for (var i = 0; i < self.config.plugins.length; i++) {
      var pluginConf = self.config.plugins[i](self) || {};
      for (var key in pluginConf) {
        if (_types_options__WEBPACK_IMPORTED_MODULE_0__.HOOKS.indexOf(key) > -1) {
          self.config[key] = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.arrayify)(pluginConf[key]).map(bindToInstance).concat(self.config[key]);
        } else if (typeof userConfig[key] === "undefined") self.config[key] = pluginConf[key];
      }
    }
    if (!userConfig.altInputClass) {
      self.config.altInputClass = getInputElem().className + " " + self.config.altInputClass;
    }
    triggerEvent("onParseConfig");
  }
  function getInputElem() {
    return self.config.wrap ? element.querySelector("[data-input]") : element;
  }
  function setupLocale() {
    if (typeof self.config.locale !== "object" && typeof flatpickr.l10ns[self.config.locale] === "undefined") self.config.errorHandler(new Error("flatpickr: invalid locale " + self.config.locale));
    self.l10n = __assign(__assign({}, flatpickr.l10ns.default), typeof self.config.locale === "object" ? self.config.locale : self.config.locale !== "default" ? flatpickr.l10ns[self.config.locale] : undefined);
    _utils_formatting__WEBPACK_IMPORTED_MODULE_5__.tokenRegex.D = "(" + self.l10n.weekdays.shorthand.join("|") + ")";
    _utils_formatting__WEBPACK_IMPORTED_MODULE_5__.tokenRegex.l = "(" + self.l10n.weekdays.longhand.join("|") + ")";
    _utils_formatting__WEBPACK_IMPORTED_MODULE_5__.tokenRegex.M = "(" + self.l10n.months.shorthand.join("|") + ")";
    _utils_formatting__WEBPACK_IMPORTED_MODULE_5__.tokenRegex.F = "(" + self.l10n.months.longhand.join("|") + ")";
    _utils_formatting__WEBPACK_IMPORTED_MODULE_5__.tokenRegex.K = "(" + self.l10n.amPM[0] + "|" + self.l10n.amPM[1] + "|" + self.l10n.amPM[0].toLowerCase() + "|" + self.l10n.amPM[1].toLowerCase() + ")";
    var userConfig = __assign(__assign({}, instanceConfig), JSON.parse(JSON.stringify(element.dataset || {})));
    if (userConfig.time_24hr === undefined && flatpickr.defaultConfig.time_24hr === undefined) {
      self.config.time_24hr = self.l10n.time_24hr;
    }
    self.formatDate = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.createDateFormatter)(self);
    self.parseDate = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.createDateParser)({
      config: self.config,
      l10n: self.l10n
    });
  }
  function positionCalendar(customPositionElement) {
    if (typeof self.config.position === "function") {
      return void self.config.position(self, customPositionElement);
    }
    if (self.calendarContainer === undefined) return;
    triggerEvent("onPreCalendarPosition");
    var positionElement = customPositionElement || self._positionElement;
    var calendarHeight = Array.prototype.reduce.call(self.calendarContainer.children, function (acc, child) {
        return acc + child.offsetHeight;
      }, 0),
      calendarWidth = self.calendarContainer.offsetWidth,
      configPos = self.config.position.split(" "),
      configPosVertical = configPos[0],
      configPosHorizontal = configPos.length > 1 ? configPos[1] : null,
      inputBounds = positionElement.getBoundingClientRect(),
      distanceFromBottom = window.innerHeight - inputBounds.bottom,
      showOnTop = configPosVertical === "above" || configPosVertical !== "below" && distanceFromBottom < calendarHeight && inputBounds.top > calendarHeight;
    var top = window.pageYOffset + inputBounds.top + (!showOnTop ? positionElement.offsetHeight + 2 : -calendarHeight - 2);
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "arrowTop", !showOnTop);
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "arrowBottom", showOnTop);
    if (self.config.inline) return;
    var left = window.pageXOffset + inputBounds.left;
    var isCenter = false;
    var isRight = false;
    if (configPosHorizontal === "center") {
      left -= (calendarWidth - inputBounds.width) / 2;
      isCenter = true;
    } else if (configPosHorizontal === "right") {
      left -= calendarWidth - inputBounds.width;
      isRight = true;
    }
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "arrowLeft", !isCenter && !isRight);
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "arrowCenter", isCenter);
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "arrowRight", isRight);
    var right = window.document.body.offsetWidth - (window.pageXOffset + inputBounds.right);
    var rightMost = left + calendarWidth > window.document.body.offsetWidth;
    var centerMost = right + calendarWidth > window.document.body.offsetWidth;
    (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "rightMost", rightMost);
    if (self.config.static) return;
    self.calendarContainer.style.top = top + "px";
    if (!rightMost) {
      self.calendarContainer.style.left = left + "px";
      self.calendarContainer.style.right = "auto";
    } else if (!centerMost) {
      self.calendarContainer.style.left = "auto";
      self.calendarContainer.style.right = right + "px";
    } else {
      var doc = getDocumentStyleSheet();
      if (doc === undefined) return;
      var bodyWidth = window.document.body.offsetWidth;
      var centerLeft = Math.max(0, bodyWidth / 2 - calendarWidth / 2);
      var centerBefore = ".flatpickr-calendar.centerMost:before";
      var centerAfter = ".flatpickr-calendar.centerMost:after";
      var centerIndex = doc.cssRules.length;
      var centerStyle = "{left:" + inputBounds.left + "px;right:auto;}";
      (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "rightMost", false);
      (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.toggleClass)(self.calendarContainer, "centerMost", true);
      doc.insertRule(centerBefore + "," + centerAfter + centerStyle, centerIndex);
      self.calendarContainer.style.left = centerLeft + "px";
      self.calendarContainer.style.right = "auto";
    }
  }
  function getDocumentStyleSheet() {
    var editableSheet = null;
    for (var i = 0; i < document.styleSheets.length; i++) {
      var sheet = document.styleSheets[i];
      if (!sheet.cssRules) continue;
      try {
        sheet.cssRules;
      } catch (err) {
        continue;
      }
      editableSheet = sheet;
      break;
    }
    return editableSheet != null ? editableSheet : createStyleSheet();
  }
  function createStyleSheet() {
    var style = document.createElement("style");
    document.head.appendChild(style);
    return style.sheet;
  }
  function redraw() {
    if (self.config.noCalendar || self.isMobile) return;
    buildMonthSwitch();
    updateNavigationCurrentMonth();
    buildDays();
  }
  function focusAndClose() {
    self._input.focus();
    if (window.navigator.userAgent.indexOf("MSIE") !== -1 || navigator.msMaxTouchPoints !== undefined) {
      setTimeout(self.close, 0);
    } else {
      self.close();
    }
  }
  function selectDate(e) {
    e.preventDefault();
    e.stopPropagation();
    var isSelectable = function (day) {
      return day.classList && day.classList.contains("flatpickr-day") && !day.classList.contains("flatpickr-disabled") && !day.classList.contains("notAllowed");
    };
    var t = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.findParent)((0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e), isSelectable);
    if (t === undefined) return;
    var target = t;
    var selectedDate = self.latestSelectedDateObj = new Date(target.dateObj.getTime());
    var shouldChangeMonth = (selectedDate.getMonth() < self.currentMonth || selectedDate.getMonth() > self.currentMonth + self.config.showMonths - 1) && self.config.mode !== "range";
    self.selectedDateElem = target;
    if (self.config.mode === "single") self.selectedDates = [selectedDate];else if (self.config.mode === "multiple") {
      var selectedIndex = isDateSelected(selectedDate);
      if (selectedIndex) self.selectedDates.splice(parseInt(selectedIndex), 1);else self.selectedDates.push(selectedDate);
    } else if (self.config.mode === "range") {
      if (self.selectedDates.length === 2) {
        self.clear(false, false);
      }
      self.latestSelectedDateObj = selectedDate;
      self.selectedDates.push(selectedDate);
      if ((0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(selectedDate, self.selectedDates[0], true) !== 0) self.selectedDates.sort(function (a, b) {
        return a.getTime() - b.getTime();
      });
    }
    setHoursFromInputs();
    if (shouldChangeMonth) {
      var isNewYear = self.currentYear !== selectedDate.getFullYear();
      self.currentYear = selectedDate.getFullYear();
      self.currentMonth = selectedDate.getMonth();
      if (isNewYear) {
        triggerEvent("onYearChange");
        buildMonthSwitch();
      }
      triggerEvent("onMonthChange");
    }
    updateNavigationCurrentMonth();
    buildDays();
    updateValue();
    if (!shouldChangeMonth && self.config.mode !== "range" && self.config.showMonths === 1) focusOnDayElem(target);else if (self.selectedDateElem !== undefined && self.hourElement === undefined) {
      self.selectedDateElem && self.selectedDateElem.focus();
    }
    if (self.hourElement !== undefined) self.hourElement !== undefined && self.hourElement.focus();
    if (self.config.closeOnSelect) {
      var single = self.config.mode === "single" && !self.config.enableTime;
      var range = self.config.mode === "range" && self.selectedDates.length === 2 && !self.config.enableTime;
      if (single || range) {
        focusAndClose();
      }
    }
    triggerChange();
  }
  var CALLBACKS = {
    locale: [setupLocale, updateWeekdays],
    showMonths: [buildMonths, setCalendarWidth, buildWeekdays],
    minDate: [jumpToDate],
    maxDate: [jumpToDate],
    positionElement: [updatePositionElement],
    clickOpens: [function () {
      if (self.config.clickOpens === true) {
        bind(self._input, "focus", self.open);
        bind(self._input, "click", self.open);
      } else {
        self._input.removeEventListener("focus", self.open);
        self._input.removeEventListener("click", self.open);
      }
    }]
  };
  function set(option, value) {
    if (option !== null && typeof option === "object") {
      Object.assign(self.config, option);
      for (var key in option) {
        if (CALLBACKS[key] !== undefined) CALLBACKS[key].forEach(function (x) {
          return x();
        });
      }
    } else {
      self.config[option] = value;
      if (CALLBACKS[option] !== undefined) CALLBACKS[option].forEach(function (x) {
        return x();
      });else if (_types_options__WEBPACK_IMPORTED_MODULE_0__.HOOKS.indexOf(option) > -1) self.config[option] = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.arrayify)(value);
    }
    self.redraw();
    updateValue(true);
  }
  function setSelectedDate(inputDate, format) {
    var dates = [];
    if (inputDate instanceof Array) dates = inputDate.map(function (d) {
      return self.parseDate(d, format);
    });else if (inputDate instanceof Date || typeof inputDate === "number") dates = [self.parseDate(inputDate, format)];else if (typeof inputDate === "string") {
      switch (self.config.mode) {
        case "single":
        case "time":
          dates = [self.parseDate(inputDate, format)];
          break;
        case "multiple":
          dates = inputDate.split(self.config.conjunction).map(function (date) {
            return self.parseDate(date, format);
          });
          break;
        case "range":
          dates = inputDate.split(self.l10n.rangeSeparator).map(function (date) {
            return self.parseDate(date, format);
          });
          break;
        default:
          break;
      }
    } else self.config.errorHandler(new Error("Invalid date supplied: " + JSON.stringify(inputDate)));
    self.selectedDates = self.config.allowInvalidPreload ? dates : dates.filter(function (d) {
      return d instanceof Date && isEnabled(d, false);
    });
    if (self.config.mode === "range") self.selectedDates.sort(function (a, b) {
      return a.getTime() - b.getTime();
    });
  }
  function setDate(date, triggerChange, format) {
    if (triggerChange === void 0) {
      triggerChange = false;
    }
    if (format === void 0) {
      format = self.config.dateFormat;
    }
    if (date !== 0 && !date || date instanceof Array && date.length === 0) return self.clear(triggerChange);
    setSelectedDate(date, format);
    self.latestSelectedDateObj = self.selectedDates[self.selectedDates.length - 1];
    self.redraw();
    jumpToDate(undefined, triggerChange);
    setHoursFromDate();
    if (self.selectedDates.length === 0) {
      self.clear(false);
    }
    updateValue(triggerChange);
    if (triggerChange) triggerEvent("onChange");
  }
  function parseDateRules(arr) {
    return arr.slice().map(function (rule) {
      if (typeof rule === "string" || typeof rule === "number" || rule instanceof Date) {
        return self.parseDate(rule, undefined, true);
      } else if (rule && typeof rule === "object" && rule.from && rule.to) return {
        from: self.parseDate(rule.from, undefined),
        to: self.parseDate(rule.to, undefined)
      };
      return rule;
    }).filter(function (x) {
      return x;
    });
  }
  function setupDates() {
    self.selectedDates = [];
    self.now = self.parseDate(self.config.now) || new Date();
    var preloadedDate = self.config.defaultDate || ((self.input.nodeName === "INPUT" || self.input.nodeName === "TEXTAREA") && self.input.placeholder && self.input.value === self.input.placeholder ? null : self.input.value);
    if (preloadedDate) setSelectedDate(preloadedDate, self.config.dateFormat);
    self._initialDate = self.selectedDates.length > 0 ? self.selectedDates[0] : self.config.minDate && self.config.minDate.getTime() > self.now.getTime() ? self.config.minDate : self.config.maxDate && self.config.maxDate.getTime() < self.now.getTime() ? self.config.maxDate : self.now;
    self.currentYear = self._initialDate.getFullYear();
    self.currentMonth = self._initialDate.getMonth();
    if (self.selectedDates.length > 0) self.latestSelectedDateObj = self.selectedDates[0];
    if (self.config.minTime !== undefined) self.config.minTime = self.parseDate(self.config.minTime, "H:i");
    if (self.config.maxTime !== undefined) self.config.maxTime = self.parseDate(self.config.maxTime, "H:i");
    self.minDateHasTime = !!self.config.minDate && (self.config.minDate.getHours() > 0 || self.config.minDate.getMinutes() > 0 || self.config.minDate.getSeconds() > 0);
    self.maxDateHasTime = !!self.config.maxDate && (self.config.maxDate.getHours() > 0 || self.config.maxDate.getMinutes() > 0 || self.config.maxDate.getSeconds() > 0);
  }
  function setupInputs() {
    self.input = getInputElem();
    if (!self.input) {
      self.config.errorHandler(new Error("Invalid input element specified"));
      return;
    }
    self.input._type = self.input.type;
    self.input.type = "text";
    self.input.classList.add("flatpickr-input");
    self._input = self.input;
    if (self.config.altInput) {
      self.altInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)(self.input.nodeName, self.config.altInputClass);
      self._input = self.altInput;
      self.altInput.placeholder = self.input.placeholder;
      self.altInput.disabled = self.input.disabled;
      self.altInput.required = self.input.required;
      self.altInput.tabIndex = self.input.tabIndex;
      self.altInput.type = "text";
      self.input.setAttribute("type", "hidden");
      if (!self.config.static && self.input.parentNode) self.input.parentNode.insertBefore(self.altInput, self.input.nextSibling);
    }
    if (!self.config.allowInput) self._input.setAttribute("readonly", "readonly");
    updatePositionElement();
  }
  function updatePositionElement() {
    self._positionElement = self.config.positionElement || self._input;
  }
  function setupMobile() {
    var inputType = self.config.enableTime ? self.config.noCalendar ? "time" : "datetime-local" : "date";
    self.mobileInput = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.createElement)("input", self.input.className + " flatpickr-mobile");
    self.mobileInput.tabIndex = 1;
    self.mobileInput.type = inputType;
    self.mobileInput.disabled = self.input.disabled;
    self.mobileInput.required = self.input.required;
    self.mobileInput.placeholder = self.input.placeholder;
    self.mobileFormatStr = inputType === "datetime-local" ? "Y-m-d\\TH:i:S" : inputType === "date" ? "Y-m-d" : "H:i:S";
    if (self.selectedDates.length > 0) {
      self.mobileInput.defaultValue = self.mobileInput.value = self.formatDate(self.selectedDates[0], self.mobileFormatStr);
    }
    if (self.config.minDate) self.mobileInput.min = self.formatDate(self.config.minDate, "Y-m-d");
    if (self.config.maxDate) self.mobileInput.max = self.formatDate(self.config.maxDate, "Y-m-d");
    if (self.input.getAttribute("step")) self.mobileInput.step = String(self.input.getAttribute("step"));
    self.input.type = "hidden";
    if (self.altInput !== undefined) self.altInput.type = "hidden";
    try {
      if (self.input.parentNode) self.input.parentNode.insertBefore(self.mobileInput, self.input.nextSibling);
    } catch (_a) {}
    bind(self.mobileInput, "change", function (e) {
      self.setDate((0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e).value, false, self.mobileFormatStr);
      triggerEvent("onChange");
      triggerEvent("onClose");
    });
  }
  function toggle(e) {
    if (self.isOpen === true) return self.close();
    self.open(e);
  }
  function triggerEvent(event, data) {
    if (self.config === undefined) return;
    var hooks = self.config[event];
    if (hooks !== undefined && hooks.length > 0) {
      for (var i = 0; hooks[i] && i < hooks.length; i++) hooks[i](self.selectedDates, self.input.value, self, data);
    }
    if (event === "onChange") {
      self.input.dispatchEvent(createEvent("change"));
      self.input.dispatchEvent(createEvent("input"));
    }
  }
  function createEvent(name) {
    var e = document.createEvent("Event");
    e.initEvent(name, true, true);
    return e;
  }
  function isDateSelected(date) {
    for (var i = 0; i < self.selectedDates.length; i++) {
      var selectedDate = self.selectedDates[i];
      if (selectedDate instanceof Date && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(selectedDate, date) === 0) return "" + i;
    }
    return false;
  }
  function isDateInRange(date) {
    if (self.config.mode !== "range" || self.selectedDates.length < 2) return false;
    return (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(date, self.selectedDates[0]) >= 0 && (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates)(date, self.selectedDates[1]) <= 0;
  }
  function updateNavigationCurrentMonth() {
    if (self.config.noCalendar || self.isMobile || !self.monthNav) return;
    self.yearElements.forEach(function (yearElement, i) {
      var d = new Date(self.currentYear, self.currentMonth, 1);
      d.setMonth(self.currentMonth + i);
      if (self.config.showMonths > 1 || self.config.monthSelectorType === "static") {
        self.monthElements[i].textContent = (0,_utils_formatting__WEBPACK_IMPORTED_MODULE_5__.monthToStr)(d.getMonth(), self.config.shorthandCurrentMonth, self.l10n) + " ";
      } else {
        self.monthsDropdownContainer.value = d.getMonth().toString();
      }
      yearElement.value = d.getFullYear().toString();
    });
    self._hidePrevMonthArrow = self.config.minDate !== undefined && (self.currentYear === self.config.minDate.getFullYear() ? self.currentMonth <= self.config.minDate.getMonth() : self.currentYear < self.config.minDate.getFullYear());
    self._hideNextMonthArrow = self.config.maxDate !== undefined && (self.currentYear === self.config.maxDate.getFullYear() ? self.currentMonth + 1 > self.config.maxDate.getMonth() : self.currentYear > self.config.maxDate.getFullYear());
  }
  function getDateStr(specificFormat) {
    var format = specificFormat || (self.config.altInput ? self.config.altFormat : self.config.dateFormat);
    return self.selectedDates.map(function (dObj) {
      return self.formatDate(dObj, format);
    }).filter(function (d, i, arr) {
      return self.config.mode !== "range" || self.config.enableTime || arr.indexOf(d) === i;
    }).join(self.config.mode !== "range" ? self.config.conjunction : self.l10n.rangeSeparator);
  }
  function updateValue(triggerChange) {
    if (triggerChange === void 0) {
      triggerChange = true;
    }
    if (self.mobileInput !== undefined && self.mobileFormatStr) {
      self.mobileInput.value = self.latestSelectedDateObj !== undefined ? self.formatDate(self.latestSelectedDateObj, self.mobileFormatStr) : "";
    }
    self.input.value = getDateStr(self.config.dateFormat);
    if (self.altInput !== undefined) {
      self.altInput.value = getDateStr(self.config.altFormat);
    }
    if (triggerChange !== false) triggerEvent("onValueUpdate");
  }
  function onMonthNavClick(e) {
    var eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e);
    var isPrevMonth = self.prevMonthNav.contains(eventTarget);
    var isNextMonth = self.nextMonthNav.contains(eventTarget);
    if (isPrevMonth || isNextMonth) {
      changeMonth(isPrevMonth ? -1 : 1);
    } else if (self.yearElements.indexOf(eventTarget) >= 0) {
      eventTarget.select();
    } else if (eventTarget.classList.contains("arrowUp")) {
      self.changeYear(self.currentYear + 1);
    } else if (eventTarget.classList.contains("arrowDown")) {
      self.changeYear(self.currentYear - 1);
    }
  }
  function timeWrapper(e) {
    e.preventDefault();
    var isKeyDown = e.type === "keydown",
      eventTarget = (0,_utils_dom__WEBPACK_IMPORTED_MODULE_3__.getEventTarget)(e),
      input = eventTarget;
    if (self.amPM !== undefined && eventTarget === self.amPM) {
      self.amPM.textContent = self.l10n.amPM[(0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(self.amPM.textContent === self.l10n.amPM[0])];
    }
    var min = parseFloat(input.getAttribute("min")),
      max = parseFloat(input.getAttribute("max")),
      step = parseFloat(input.getAttribute("step")),
      curValue = parseInt(input.value, 10),
      delta = e.delta || (isKeyDown ? e.which === 38 ? 1 : -1 : 0);
    var newValue = curValue + step * delta;
    if (typeof input.value !== "undefined" && input.value.length === 2) {
      var isHourElem = input === self.hourElement,
        isMinuteElem = input === self.minuteElement;
      if (newValue < min) {
        newValue = max + newValue + (0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(!isHourElem) + ((0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(isHourElem) && (0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(!self.amPM));
        if (isMinuteElem) incrementNumInput(undefined, -1, self.hourElement);
      } else if (newValue > max) {
        newValue = input === self.hourElement ? newValue - max - (0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(!self.amPM) : min;
        if (isMinuteElem) incrementNumInput(undefined, 1, self.hourElement);
      }
      if (self.amPM && isHourElem && (step === 1 ? newValue + curValue === 23 : Math.abs(newValue - curValue) > step)) {
        self.amPM.textContent = self.l10n.amPM[(0,_utils__WEBPACK_IMPORTED_MODULE_2__.int)(self.amPM.textContent === self.l10n.amPM[0])];
      }
      input.value = (0,_utils__WEBPACK_IMPORTED_MODULE_2__.pad)(newValue);
    }
  }
  init();
  return self;
}
function _flatpickr(nodeList, config) {
  var nodes = Array.prototype.slice.call(nodeList).filter(function (x) {
    return x instanceof HTMLElement;
  });
  var instances = [];
  for (var i = 0; i < nodes.length; i++) {
    var node = nodes[i];
    try {
      if (node.getAttribute("data-fp-omit") !== null) continue;
      if (node._flatpickr !== undefined) {
        node._flatpickr.destroy();
        node._flatpickr = undefined;
      }
      node._flatpickr = FlatpickrInstance(node, config || {});
      instances.push(node._flatpickr);
    } catch (e) {
      console.error(e);
    }
  }
  return instances.length === 1 ? instances[0] : instances;
}
if (typeof HTMLElement !== "undefined" && typeof HTMLCollection !== "undefined" && typeof NodeList !== "undefined") {
  HTMLCollection.prototype.flatpickr = NodeList.prototype.flatpickr = function (config) {
    return _flatpickr(this, config);
  };
  HTMLElement.prototype.flatpickr = function (config) {
    return _flatpickr([this], config);
  };
}
var flatpickr = function (selector, config) {
  if (typeof selector === "string") {
    return _flatpickr(window.document.querySelectorAll(selector), config);
  } else if (selector instanceof Node) {
    return _flatpickr([selector], config);
  } else {
    return _flatpickr(selector, config);
  }
};
flatpickr.defaultConfig = {};
flatpickr.l10ns = {
  en: __assign({}, _l10n_default__WEBPACK_IMPORTED_MODULE_1__["default"]),
  default: __assign({}, _l10n_default__WEBPACK_IMPORTED_MODULE_1__["default"])
};
flatpickr.localize = function (l10n) {
  flatpickr.l10ns.default = __assign(__assign({}, flatpickr.l10ns.default), l10n);
};
flatpickr.setDefaults = function (config) {
  flatpickr.defaultConfig = __assign(__assign({}, flatpickr.defaultConfig), config);
};
flatpickr.parseDate = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.createDateParser)({});
flatpickr.formatDate = (0,_utils_dates__WEBPACK_IMPORTED_MODULE_4__.createDateFormatter)({});
flatpickr.compareDates = _utils_dates__WEBPACK_IMPORTED_MODULE_4__.compareDates;
if (typeof jQuery !== "undefined" && typeof jQuery.fn !== "undefined") {
  jQuery.fn.flatpickr = function (config) {
    return _flatpickr(this, config);
  };
}
Date.prototype.fp_incr = function (days) {
  return new Date(this.getFullYear(), this.getMonth(), this.getDate() + (typeof days === "string" ? parseInt(days, 10) : days));
};
if (typeof window !== "undefined") {
  window.flatpickr = flatpickr;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (flatpickr);

/***/ }),

/***/ 70521:
/*!*********************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/l10n/default.js ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   english: () => (/* binding */ english)
/* harmony export */ });
var english = {
  weekdays: {
    shorthand: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
    longhand: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
  },
  months: {
    shorthand: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
    longhand: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
  },
  daysInMonth: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
  firstDayOfWeek: 0,
  ordinal: function (nth) {
    var s = nth % 100;
    if (s > 3 && s < 21) return "th";
    switch (s % 10) {
      case 1:
        return "st";
      case 2:
        return "nd";
      case 3:
        return "rd";
      default:
        return "th";
    }
  },
  rangeSeparator: " to ",
  weekAbbreviation: "Wk",
  scrollTitle: "Scroll to increment",
  toggleTitle: "Click to toggle",
  amPM: ["AM", "PM"],
  yearAriaLabel: "Year",
  monthAriaLabel: "Month",
  hourAriaLabel: "Hour",
  minuteAriaLabel: "Minute",
  time_24hr: false
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (english);

/***/ }),

/***/ 50460:
/*!**********************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/types/options.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   HOOKS: () => (/* binding */ HOOKS),
/* harmony export */   defaults: () => (/* binding */ defaults)
/* harmony export */ });
var HOOKS = ["onChange", "onClose", "onDayCreate", "onDestroy", "onKeyDown", "onMonthChange", "onOpen", "onParseConfig", "onReady", "onValueUpdate", "onYearChange", "onPreCalendarPosition"];
var defaults = {
  _disable: [],
  allowInput: false,
  allowInvalidPreload: false,
  altFormat: "F j, Y",
  altInput: false,
  altInputClass: "form-control input",
  animate: typeof window === "object" && window.navigator.userAgent.indexOf("MSIE") === -1,
  ariaDateFormat: "F j, Y",
  autoFillDefaultTime: true,
  clickOpens: true,
  closeOnSelect: true,
  conjunction: ", ",
  dateFormat: "Y-m-d",
  defaultHour: 12,
  defaultMinute: 0,
  defaultSeconds: 0,
  disable: [],
  disableMobile: false,
  enableSeconds: false,
  enableTime: false,
  errorHandler: function (err) {
    return typeof console !== "undefined" && console.warn(err);
  },
  getWeek: function (givenDate) {
    var date = new Date(givenDate.getTime());
    date.setHours(0, 0, 0, 0);
    date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
    var week1 = new Date(date.getFullYear(), 0, 4);
    return 1 + Math.round(((date.getTime() - week1.getTime()) / 86400000 - 3 + (week1.getDay() + 6) % 7) / 7);
  },
  hourIncrement: 1,
  ignoredFocusElements: [],
  inline: false,
  locale: "default",
  minuteIncrement: 5,
  mode: "single",
  monthSelectorType: "dropdown",
  nextArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M13.207 8.472l-7.854 7.854-0.707-0.707 7.146-7.146-7.146-7.148 0.707-0.707 7.854 7.854z' /></svg>",
  noCalendar: false,
  now: new Date(),
  onChange: [],
  onClose: [],
  onDayCreate: [],
  onDestroy: [],
  onKeyDown: [],
  onMonthChange: [],
  onOpen: [],
  onParseConfig: [],
  onReady: [],
  onValueUpdate: [],
  onYearChange: [],
  onPreCalendarPosition: [],
  plugins: [],
  position: "auto",
  positionElement: undefined,
  prevArrow: "<svg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' viewBox='0 0 17 17'><g></g><path d='M5.207 8.471l7.146 7.147-0.707 0.707-7.853-7.854 7.854-7.853 0.707 0.707-7.147 7.146z' /></svg>",
  shorthandCurrentMonth: false,
  showMonths: 1,
  static: false,
  time_24hr: false,
  weekNumbers: false,
  wrap: false
};

/***/ }),

/***/ 41695:
/*!********************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/utils/dates.js ***!
  \********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   calculateSecondsSinceMidnight: () => (/* binding */ calculateSecondsSinceMidnight),
/* harmony export */   compareDates: () => (/* binding */ compareDates),
/* harmony export */   compareTimes: () => (/* binding */ compareTimes),
/* harmony export */   createDateFormatter: () => (/* binding */ createDateFormatter),
/* harmony export */   createDateParser: () => (/* binding */ createDateParser),
/* harmony export */   duration: () => (/* binding */ duration),
/* harmony export */   getDefaultHours: () => (/* binding */ getDefaultHours),
/* harmony export */   isBetween: () => (/* binding */ isBetween),
/* harmony export */   parseSeconds: () => (/* binding */ parseSeconds)
/* harmony export */ });
/* harmony import */ var _formatting__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./formatting */ 17563);
/* harmony import */ var _types_options__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../types/options */ 50460);
/* harmony import */ var _l10n_default__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../l10n/default */ 70521);



var createDateFormatter = function (_a) {
  var _b = _a.config,
    config = _b === void 0 ? _types_options__WEBPACK_IMPORTED_MODULE_1__.defaults : _b,
    _c = _a.l10n,
    l10n = _c === void 0 ? _l10n_default__WEBPACK_IMPORTED_MODULE_2__.english : _c,
    _d = _a.isMobile,
    isMobile = _d === void 0 ? false : _d;
  return function (dateObj, frmt, overrideLocale) {
    var locale = overrideLocale || l10n;
    if (config.formatDate !== undefined && !isMobile) {
      return config.formatDate(dateObj, frmt, locale);
    }
    return frmt.split("").map(function (c, i, arr) {
      return _formatting__WEBPACK_IMPORTED_MODULE_0__.formats[c] && arr[i - 1] !== "\\" ? _formatting__WEBPACK_IMPORTED_MODULE_0__.formats[c](dateObj, locale, config) : c !== "\\" ? c : "";
    }).join("");
  };
};
var createDateParser = function (_a) {
  var _b = _a.config,
    config = _b === void 0 ? _types_options__WEBPACK_IMPORTED_MODULE_1__.defaults : _b,
    _c = _a.l10n,
    l10n = _c === void 0 ? _l10n_default__WEBPACK_IMPORTED_MODULE_2__.english : _c;
  return function (date, givenFormat, timeless, customLocale) {
    if (date !== 0 && !date) return undefined;
    var locale = customLocale || l10n;
    var parsedDate;
    var dateOrig = date;
    if (date instanceof Date) parsedDate = new Date(date.getTime());else if (typeof date !== "string" && date.toFixed !== undefined) parsedDate = new Date(date);else if (typeof date === "string") {
      var format = givenFormat || (config || _types_options__WEBPACK_IMPORTED_MODULE_1__.defaults).dateFormat;
      var datestr = String(date).trim();
      if (datestr === "today") {
        parsedDate = new Date();
        timeless = true;
      } else if (config && config.parseDate) {
        parsedDate = config.parseDate(date, format);
      } else if (/Z$/.test(datestr) || /GMT$/.test(datestr)) {
        parsedDate = new Date(date);
      } else {
        var matched = void 0,
          ops = [];
        for (var i = 0, matchIndex = 0, regexStr = ""; i < format.length; i++) {
          var token = format[i];
          var isBackSlash = token === "\\";
          var escaped = format[i - 1] === "\\" || isBackSlash;
          if (_formatting__WEBPACK_IMPORTED_MODULE_0__.tokenRegex[token] && !escaped) {
            regexStr += _formatting__WEBPACK_IMPORTED_MODULE_0__.tokenRegex[token];
            var match = new RegExp(regexStr).exec(date);
            if (match && (matched = true)) {
              ops[token !== "Y" ? "push" : "unshift"]({
                fn: _formatting__WEBPACK_IMPORTED_MODULE_0__.revFormat[token],
                val: match[++matchIndex]
              });
            }
          } else if (!isBackSlash) regexStr += ".";
        }
        parsedDate = !config || !config.noCalendar ? new Date(new Date().getFullYear(), 0, 1, 0, 0, 0, 0) : new Date(new Date().setHours(0, 0, 0, 0));
        ops.forEach(function (_a) {
          var fn = _a.fn,
            val = _a.val;
          return parsedDate = fn(parsedDate, val, locale) || parsedDate;
        });
        parsedDate = matched ? parsedDate : undefined;
      }
    }
    if (!(parsedDate instanceof Date && !isNaN(parsedDate.getTime()))) {
      config.errorHandler(new Error("Invalid date provided: " + dateOrig));
      return undefined;
    }
    if (timeless === true) parsedDate.setHours(0, 0, 0, 0);
    return parsedDate;
  };
};
function compareDates(date1, date2, timeless) {
  if (timeless === void 0) {
    timeless = true;
  }
  if (timeless !== false) {
    return new Date(date1.getTime()).setHours(0, 0, 0, 0) - new Date(date2.getTime()).setHours(0, 0, 0, 0);
  }
  return date1.getTime() - date2.getTime();
}
function compareTimes(date1, date2) {
  return 3600 * (date1.getHours() - date2.getHours()) + 60 * (date1.getMinutes() - date2.getMinutes()) + date1.getSeconds() - date2.getSeconds();
}
var isBetween = function (ts, ts1, ts2) {
  return ts > Math.min(ts1, ts2) && ts < Math.max(ts1, ts2);
};
var calculateSecondsSinceMidnight = function (hours, minutes, seconds) {
  return hours * 3600 + minutes * 60 + seconds;
};
var parseSeconds = function (secondsSinceMidnight) {
  var hours = Math.floor(secondsSinceMidnight / 3600),
    minutes = (secondsSinceMidnight - hours * 3600) / 60;
  return [hours, minutes, secondsSinceMidnight - hours * 3600 - minutes * 60];
};
var duration = {
  DAY: 86400000
};
function getDefaultHours(config) {
  var hours = config.defaultHour;
  var minutes = config.defaultMinute;
  var seconds = config.defaultSeconds;
  if (config.minDate !== undefined) {
    var minHour = config.minDate.getHours();
    var minMinutes = config.minDate.getMinutes();
    var minSeconds = config.minDate.getSeconds();
    if (hours < minHour) {
      hours = minHour;
    }
    if (hours === minHour && minutes < minMinutes) {
      minutes = minMinutes;
    }
    if (hours === minHour && minutes === minMinutes && seconds < minSeconds) seconds = config.minDate.getSeconds();
  }
  if (config.maxDate !== undefined) {
    var maxHr = config.maxDate.getHours();
    var maxMinutes = config.maxDate.getMinutes();
    hours = Math.min(hours, maxHr);
    if (hours === maxHr) minutes = Math.min(maxMinutes, minutes);
    if (hours === maxHr && minutes === maxMinutes) seconds = config.maxDate.getSeconds();
  }
  return {
    hours: hours,
    minutes: minutes,
    seconds: seconds
  };
}

/***/ }),

/***/ 52750:
/*!******************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/utils/dom.js ***!
  \******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   clearNode: () => (/* binding */ clearNode),
/* harmony export */   createElement: () => (/* binding */ createElement),
/* harmony export */   createNumberInput: () => (/* binding */ createNumberInput),
/* harmony export */   findParent: () => (/* binding */ findParent),
/* harmony export */   getEventTarget: () => (/* binding */ getEventTarget),
/* harmony export */   toggleClass: () => (/* binding */ toggleClass)
/* harmony export */ });
function toggleClass(elem, className, bool) {
  if (bool === true) return elem.classList.add(className);
  elem.classList.remove(className);
}
function createElement(tag, className, content) {
  var e = window.document.createElement(tag);
  className = className || "";
  content = content || "";
  e.className = className;
  if (content !== undefined) e.textContent = content;
  return e;
}
function clearNode(node) {
  while (node.firstChild) node.removeChild(node.firstChild);
}
function findParent(node, condition) {
  if (condition(node)) return node;else if (node.parentNode) return findParent(node.parentNode, condition);
  return undefined;
}
function createNumberInput(inputClassName, opts) {
  var wrapper = createElement("div", "numInputWrapper"),
    numInput = createElement("input", "numInput " + inputClassName),
    arrowUp = createElement("span", "arrowUp"),
    arrowDown = createElement("span", "arrowDown");
  if (navigator.userAgent.indexOf("MSIE 9.0") === -1) {
    numInput.type = "number";
  } else {
    numInput.type = "text";
    numInput.pattern = "\\d*";
  }
  if (opts !== undefined) for (var key in opts) numInput.setAttribute(key, opts[key]);
  wrapper.appendChild(numInput);
  wrapper.appendChild(arrowUp);
  wrapper.appendChild(arrowDown);
  return wrapper;
}
function getEventTarget(event) {
  try {
    if (typeof event.composedPath === "function") {
      var path = event.composedPath();
      return path[0];
    }
    return event.target;
  } catch (error) {
    return event.target;
  }
}

/***/ }),

/***/ 17563:
/*!*************************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/utils/formatting.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formats: () => (/* binding */ formats),
/* harmony export */   monthToStr: () => (/* binding */ monthToStr),
/* harmony export */   revFormat: () => (/* binding */ revFormat),
/* harmony export */   tokenRegex: () => (/* binding */ tokenRegex)
/* harmony export */ });
/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils */ 90238);

var doNothing = function () {
  return undefined;
};
var monthToStr = function (monthNumber, shorthand, locale) {
  return locale.months[shorthand ? "shorthand" : "longhand"][monthNumber];
};
var revFormat = {
  D: doNothing,
  F: function (dateObj, monthName, locale) {
    dateObj.setMonth(locale.months.longhand.indexOf(monthName));
  },
  G: function (dateObj, hour) {
    dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));
  },
  H: function (dateObj, hour) {
    dateObj.setHours(parseFloat(hour));
  },
  J: function (dateObj, day) {
    dateObj.setDate(parseFloat(day));
  },
  K: function (dateObj, amPM, locale) {
    dateObj.setHours(dateObj.getHours() % 12 + 12 * (0,_utils__WEBPACK_IMPORTED_MODULE_0__.int)(new RegExp(locale.amPM[1], "i").test(amPM)));
  },
  M: function (dateObj, shortMonth, locale) {
    dateObj.setMonth(locale.months.shorthand.indexOf(shortMonth));
  },
  S: function (dateObj, seconds) {
    dateObj.setSeconds(parseFloat(seconds));
  },
  U: function (_, unixSeconds) {
    return new Date(parseFloat(unixSeconds) * 1000);
  },
  W: function (dateObj, weekNum, locale) {
    var weekNumber = parseInt(weekNum);
    var date = new Date(dateObj.getFullYear(), 0, 2 + (weekNumber - 1) * 7, 0, 0, 0, 0);
    date.setDate(date.getDate() - date.getDay() + locale.firstDayOfWeek);
    return date;
  },
  Y: function (dateObj, year) {
    dateObj.setFullYear(parseFloat(year));
  },
  Z: function (_, ISODate) {
    return new Date(ISODate);
  },
  d: function (dateObj, day) {
    dateObj.setDate(parseFloat(day));
  },
  h: function (dateObj, hour) {
    dateObj.setHours((dateObj.getHours() >= 12 ? 12 : 0) + parseFloat(hour));
  },
  i: function (dateObj, minutes) {
    dateObj.setMinutes(parseFloat(minutes));
  },
  j: function (dateObj, day) {
    dateObj.setDate(parseFloat(day));
  },
  l: doNothing,
  m: function (dateObj, month) {
    dateObj.setMonth(parseFloat(month) - 1);
  },
  n: function (dateObj, month) {
    dateObj.setMonth(parseFloat(month) - 1);
  },
  s: function (dateObj, seconds) {
    dateObj.setSeconds(parseFloat(seconds));
  },
  u: function (_, unixMillSeconds) {
    return new Date(parseFloat(unixMillSeconds));
  },
  w: doNothing,
  y: function (dateObj, year) {
    dateObj.setFullYear(2000 + parseFloat(year));
  }
};
var tokenRegex = {
  D: "",
  F: "",
  G: "(\\d\\d|\\d)",
  H: "(\\d\\d|\\d)",
  J: "(\\d\\d|\\d)\\w+",
  K: "",
  M: "",
  S: "(\\d\\d|\\d)",
  U: "(.+)",
  W: "(\\d\\d|\\d)",
  Y: "(\\d{4})",
  Z: "(.+)",
  d: "(\\d\\d|\\d)",
  h: "(\\d\\d|\\d)",
  i: "(\\d\\d|\\d)",
  j: "(\\d\\d|\\d)",
  l: "",
  m: "(\\d\\d|\\d)",
  n: "(\\d\\d|\\d)",
  s: "(\\d\\d|\\d)",
  u: "(.+)",
  w: "(\\d\\d|\\d)",
  y: "(\\d{2})"
};
var formats = {
  Z: function (date) {
    return date.toISOString();
  },
  D: function (date, locale, options) {
    return locale.weekdays.shorthand[formats.w(date, locale, options)];
  },
  F: function (date, locale, options) {
    return monthToStr(formats.n(date, locale, options) - 1, false, locale);
  },
  G: function (date, locale, options) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(formats.h(date, locale, options));
  },
  H: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getHours());
  },
  J: function (date, locale) {
    return locale.ordinal !== undefined ? date.getDate() + locale.ordinal(date.getDate()) : date.getDate();
  },
  K: function (date, locale) {
    return locale.amPM[(0,_utils__WEBPACK_IMPORTED_MODULE_0__.int)(date.getHours() > 11)];
  },
  M: function (date, locale) {
    return monthToStr(date.getMonth(), true, locale);
  },
  S: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getSeconds());
  },
  U: function (date) {
    return date.getTime() / 1000;
  },
  W: function (date, _, options) {
    return options.getWeek(date);
  },
  Y: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getFullYear(), 4);
  },
  d: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getDate());
  },
  h: function (date) {
    return date.getHours() % 12 ? date.getHours() % 12 : 12;
  },
  i: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getMinutes());
  },
  j: function (date) {
    return date.getDate();
  },
  l: function (date, locale) {
    return locale.weekdays.longhand[date.getDay()];
  },
  m: function (date) {
    return (0,_utils__WEBPACK_IMPORTED_MODULE_0__.pad)(date.getMonth() + 1);
  },
  n: function (date) {
    return date.getMonth() + 1;
  },
  s: function (date) {
    return date.getSeconds();
  },
  u: function (date) {
    return date.getTime();
  },
  w: function (date) {
    return date.getDay();
  },
  y: function (date) {
    return String(date.getFullYear()).substring(2);
  }
};

/***/ }),

/***/ 90238:
/*!********************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/utils/index.js ***!
  \********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   arrayify: () => (/* binding */ arrayify),
/* harmony export */   debounce: () => (/* binding */ debounce),
/* harmony export */   int: () => (/* binding */ int),
/* harmony export */   pad: () => (/* binding */ pad)
/* harmony export */ });
var pad = function (number, length) {
  if (length === void 0) {
    length = 2;
  }
  return ("000" + number).slice(length * -1);
};
var int = function (bool) {
  return bool === true ? 1 : 0;
};
function debounce(fn, wait) {
  var t;
  return function () {
    var _this = this;
    var args = arguments;
    clearTimeout(t);
    t = setTimeout(function () {
      return fn.apply(_this, args);
    }, wait);
  };
}
var arrayify = function (obj) {
  return obj instanceof Array ? obj : [obj];
};

/***/ }),

/***/ 19522:
/*!************************************************************!*\
  !*** ./node_modules/flatpickr/dist/esm/utils/polyfills.js ***!
  \************************************************************/
/***/ (() => {

"use strict";


if (typeof Object.assign !== "function") {
  Object.assign = function (target) {
    var args = [];
    for (var _i = 1; _i < arguments.length; _i++) {
      args[_i - 1] = arguments[_i];
    }
    if (!target) {
      throw TypeError("Cannot convert undefined or null to object");
    }
    var _loop_1 = function (source) {
      if (source) {
        Object.keys(source).forEach(function (key) {
          return target[key] = source[key];
        });
      }
    };
    for (var _a = 0, args_1 = args; _a < args_1.length; _a++) {
      var source = args_1[_a];
      _loop_1(source);
    }
    return target;
  };
}

/***/ }),

/***/ 94434:
/*!*****************************************************************!*\
  !*** ./node_modules/leaflet-geosearch/dist/geosearch.module.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AlgoliaProvider: () => (/* binding */ L),
/* harmony export */   BingProvider: () => (/* binding */ k),
/* harmony export */   CivilDefenseMapProvider: () => (/* binding */ q),
/* harmony export */   EsriProvider: () => (/* binding */ U),
/* harmony export */   GeoApiFrProvider: () => (/* binding */ D),
/* harmony export */   GeoSearchControl: () => (/* binding */ w),
/* harmony export */   GeoapifyProvider: () => (/* binding */ T),
/* harmony export */   GeocodeEarthProvider: () => (/* binding */ C),
/* harmony export */   GoogleProvider: () => (/* binding */ A),
/* harmony export */   HereProvider: () => (/* binding */ O),
/* harmony export */   JsonProvider: () => (/* binding */ x),
/* harmony export */   LegacyGoogleProvider: () => (/* binding */ N),
/* harmony export */   LocationIQProvider: () => (/* binding */ _),
/* harmony export */   MapBoxProvider: () => (/* binding */ B),
/* harmony export */   OpenCageProvider: () => (/* binding */ M),
/* harmony export */   OpenStreetMapProvider: () => (/* binding */ F),
/* harmony export */   PeliasProvider: () => (/* binding */ S),
/* harmony export */   SearchControl: () => (/* binding */ w),
/* harmony export */   SearchElement: () => (/* binding */ m)
/* harmony export */ });
/* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! leaflet */ 67381);
/* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(leaflet__WEBPACK_IMPORTED_MODULE_0__);

function e() {
  return e = Object.assign ? Object.assign.bind() : function (t) {
    for (var e = 1; e < arguments.length; e++) {
      var r = arguments[e];
      for (var n in r) Object.prototype.hasOwnProperty.call(r, n) && (t[n] = r[n]);
    }
    return t;
  }, e.apply(this, arguments);
}
function r(t, e) {
  t.prototype = Object.create(e.prototype), t.prototype.constructor = t, n(t, e);
}
function n(t, e) {
  return n = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function (t, e) {
    return t.__proto__ = e, t;
  }, n(t, e);
}
function o() {
  if ("undefined" == typeof Reflect || !Reflect.construct) return !1;
  if (Reflect.construct.sham) return !1;
  if ("function" == typeof Proxy) return !0;
  try {
    return Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})), !0;
  } catch (t) {
    return !1;
  }
}
function i(t, e, r) {
  return i = o() ? Reflect.construct.bind() : function (t, e, r) {
    var o = [null];
    o.push.apply(o, e);
    var i = new (Function.bind.apply(t, o))();
    return r && n(i, r.prototype), i;
  }, i.apply(null, arguments);
}
function s(t, e, r, n) {
  void 0 === e && (e = ""), void 0 === n && (n = {});
  var o = document.createElement(t);
  return e && (o.className = e), Object.keys(n).forEach(function (t) {
    if ("function" == typeof n[t]) {
      var e = 0 === t.indexOf("on") ? t.substr(2).toLowerCase() : t;
      o.addEventListener(e, n[t]);
    } else "html" === t ? o.innerHTML = n[t] : "text" === t ? o.innerText = n[t] : o.setAttribute(t, n[t]);
  }), r && r.appendChild(o), o;
}
function a(t) {
  t.preventDefault(), t.stopPropagation();
}
var l = function () {
  return [].slice.call(arguments).filter(Boolean).join(" ").trim();
};
function c(t, e) {
  t && t.classList && (Array.isArray(e) ? e : [e]).forEach(function (e) {
    t.classList.contains(e) || t.classList.add(e);
  });
}
function u(t, e) {
  t && t.classList && (Array.isArray(e) ? e : [e]).forEach(function (e) {
    t.classList.contains(e) && t.classList.remove(e);
  });
}
var h,
  p = 13,
  d = 40,
  f = 38,
  v = [p, 27, d, f, 37, 39],
  m = /*#__PURE__*/function () {
    function t(t) {
      var e = this,
        r = t.handleSubmit,
        n = t.searchLabel,
        o = t.classNames,
        i = void 0 === o ? {} : o;
      this.container = void 0, this.form = void 0, this.input = void 0, this.handleSubmit = void 0, this.hasError = !1, this.container = s("div", l("geosearch", i.container)), this.form = s("form", ["", i.form].join(" "), this.container, {
        autocomplete: "none",
        onClick: a,
        onDblClick: a,
        touchStart: a,
        touchEnd: a
      }), this.input = s("input", ["glass", i.input].join(" "), this.form, {
        type: "text",
        placeholder: n || "search",
        onInput: this.onInput,
        onKeyUp: function (t) {
          return e.onKeyUp(t);
        },
        onKeyPress: function (t) {
          return e.onKeyPress(t);
        },
        onFocus: this.onFocus,
        onBlur: this.onBlur,
        onClick: function () {
          e.input.focus(), e.input.dispatchEvent(new Event("focus"));
        }
      }), this.handleSubmit = r;
    }
    var e = t.prototype;
    return e.onFocus = function () {
      c(this.form, "active");
    }, e.onBlur = function () {
      u(this.form, "active");
    }, e.onSubmit = function (t) {
      try {
        var e = this;
        return a(t), u(r = e.container, "error"), c(r, "pending"), Promise.resolve(e.handleSubmit({
          query: e.input.value
        })).then(function () {
          u(e.container, "pending");
        });
      } catch (t) {
        return Promise.reject(t);
      }
      var r;
    }, e.onInput = function () {
      this.hasError && (u(this.container, "error"), this.hasError = !1);
    }, e.onKeyUp = function (t) {
      27 === t.keyCode && (u(this.container, ["pending", "active"]), this.input.value = "", document.body.focus(), document.body.blur());
    }, e.onKeyPress = function (t) {
      t.keyCode === p && this.onSubmit(t);
    }, e.setQuery = function (t) {
      this.input.value = t;
    }, t;
  }(),
  g = /*#__PURE__*/function () {
    function t(t) {
      var e = this,
        r = t.handleClick,
        n = t.classNames,
        o = void 0 === n ? {} : n,
        i = t.notFoundMessage;
      this.handleClick = void 0, this.selected = -1, this.results = [], this.container = void 0, this.resultItem = void 0, this.notFoundMessage = void 0, this.onClick = function (t) {
        if ("function" == typeof e.handleClick) {
          var r = t.target;
          if (r && e.container.contains(r) && r.hasAttribute("data-key")) {
            var n = Number(r.getAttribute("data-key"));
            e.handleClick({
              result: e.results[n]
            });
          }
        }
      }, this.handleClick = r, this.notFoundMessage = i ? s("div", l(o.notfound), void 0, {
        html: i
      }) : void 0, this.container = s("div", l("results", o.resultlist)), this.container.addEventListener("click", this.onClick, !0), this.resultItem = s("div", l(o.item));
    }
    var e = t.prototype;
    return e.render = function (t, e) {
      var r = this;
      void 0 === t && (t = []), this.clear(), t.forEach(function (t, n) {
        var o = r.resultItem.cloneNode(!0);
        o.setAttribute("data-key", "" + n), o.innerHTML = e({
          result: t
        }), r.container.appendChild(o);
      }), t.length > 0 ? (c(this.container.parentElement, "open"), c(this.container, "active")) : this.notFoundMessage && (this.container.appendChild(this.notFoundMessage), c(this.container.parentElement, "open")), this.results = t;
    }, e.select = function (t) {
      return Array.from(this.container.children).forEach(function (e, r) {
        return r === t ? c(e, "active") : u(e, "active");
      }), this.selected = t, this.results[t];
    }, e.count = function () {
      return this.results ? this.results.length : 0;
    }, e.clear = function () {
      for (this.selected = -1; this.container.lastChild;) this.container.removeChild(this.container.lastChild);
      u(this.container.parentElement, "open"), u(this.container, "active");
    }, t;
  }(),
  y = {
    position: "topleft",
    style: "button",
    showMarker: !0,
    showPopup: !1,
    popupFormat: function (t) {
      return "" + t.result.label;
    },
    resultFormat: function (t) {
      return "" + t.result.label;
    },
    marker: {
      icon: leaflet__WEBPACK_IMPORTED_MODULE_0__ && leaflet__WEBPACK_IMPORTED_MODULE_0__.Icon ? new leaflet__WEBPACK_IMPORTED_MODULE_0__.Icon.Default() : void 0,
      draggable: !1
    },
    maxMarkers: 1,
    maxSuggestions: 5,
    retainZoomLevel: !1,
    animateZoom: !0,
    searchLabel: "Enter address",
    clearSearchLabel: "Clear search",
    notFoundMessage: "",
    messageHideDelay: 3e3,
    zoomLevel: 18,
    classNames: {
      container: "leaflet-bar leaflet-control leaflet-control-geosearch",
      button: "leaflet-bar-part leaflet-bar-part-single",
      resetButton: "reset",
      msgbox: "leaflet-bar message",
      form: "",
      input: "",
      resultlist: "",
      item: "",
      notfound: "leaflet-bar-notfound"
    },
    autoComplete: !0,
    autoCompleteDelay: 250,
    autoClose: !1,
    keepResult: !1,
    updateMap: !0
  },
  b = "Leaflet must be loaded before instantiating the GeoSearch control",
  E = {
    options: e({}, y),
    classNames: e({}, y.classNames),
    initialize: function (r) {
      var n,
        o,
        i,
        a,
        l = this;
      if (!leaflet__WEBPACK_IMPORTED_MODULE_0__) throw new Error(b);
      if (!r.provider) throw new Error("Provider is missing from options");
      this.options = e({}, y, r), this.classNames = e({}, this.classNames, r.classNames), this.markers = new leaflet__WEBPACK_IMPORTED_MODULE_0__.FeatureGroup(), this.classNames.container += " leaflet-geosearch-" + this.options.style, this.searchElement = new m({
        searchLabel: this.options.searchLabel,
        classNames: {
          container: this.classNames.container,
          form: this.classNames.form,
          input: this.classNames.input
        },
        handleSubmit: function (t) {
          return l.onSubmit(t);
        }
      }), this.button = s("a", this.classNames.button, this.searchElement.container, {
        title: this.options.searchLabel,
        href: "#",
        onClick: function (t) {
          return l.onClick(t);
        }
      }), leaflet__WEBPACK_IMPORTED_MODULE_0__.DomEvent.disableClickPropagation(this.button), this.resetButton = s("button", this.classNames.resetButton, this.searchElement.form, {
        text: "×",
        "aria-label": this.options.clearSearchLabel,
        onClick: function () {
          "" === l.searchElement.input.value ? l.close() : l.clearResults(null, !0);
        }
      }), leaflet__WEBPACK_IMPORTED_MODULE_0__.DomEvent.disableClickPropagation(this.resetButton), this.options.autoComplete && (this.resultList = new g({
        handleClick: function (t) {
          var e = t.result;
          l.searchElement.input.value = e.label, l.onSubmit({
            query: e.label,
            data: e
          });
        },
        classNames: {
          resultlist: this.classNames.resultlist,
          item: this.classNames.item,
          notfound: this.classNames.notfound
        },
        notFoundMessage: this.options.notFoundMessage
      }), this.searchElement.form.appendChild(this.resultList.container), this.searchElement.input.addEventListener("keyup", (n = function (t) {
        return l.autoSearch(t);
      }, void 0 === (o = this.options.autoCompleteDelay) && (o = 250), void 0 === i && (i = !1), function () {
        var t = [].slice.call(arguments);
        a && clearTimeout(a), a = setTimeout(function () {
          a = null, i || n.apply(void 0, t);
        }, o), i && !a && n.apply(void 0, t);
      }), !0), this.searchElement.input.addEventListener("keydown", function (t) {
        return l.selectResult(t);
      }, !0), this.searchElement.input.addEventListener("keydown", function (t) {
        return l.clearResults(t, !0);
      }, !0)), this.searchElement.form.addEventListener("click", function (t) {
        t.preventDefault();
      }, !1);
    },
    onAdd: function (e) {
      var r = this.options,
        n = r.showMarker,
        o = r.style;
      if (this.map = e, n && this.markers.addTo(e), "bar" === o) {
        var i = e.getContainer().querySelector(".leaflet-control-container");
        this.container = s("div", "leaflet-control-geosearch leaflet-geosearch-bar"), this.container.appendChild(this.searchElement.form), i.appendChild(this.container);
      }
      return leaflet__WEBPACK_IMPORTED_MODULE_0__.DomEvent.disableClickPropagation(this.searchElement.form), this.searchElement.container;
    },
    onRemove: function () {
      var t;
      return null == (t = this.container) || t.remove(), this;
    },
    open: function () {
      var t = this.searchElement,
        e = t.input;
      c(t.container, "active"), e.focus();
    },
    close: function () {
      u(this.searchElement.container, "active"), this.clearResults();
    },
    onClick: function (t) {
      t.preventDefault(), t.stopPropagation(), this.searchElement.container.classList.contains("active") ? this.close() : this.open();
    },
    selectResult: function (t) {
      if (-1 !== [p, d, f].indexOf(t.keyCode)) if (t.preventDefault(), t.keyCode !== p) {
        var e = this.resultList.count() - 1;
        if (!(e < 0)) {
          var r = this.resultList.selected,
            n = t.keyCode === d ? r + 1 : r - 1,
            o = this.resultList.select(n < 0 ? e : n > e ? 0 : n);
          this.searchElement.input.value = o.label;
        }
      } else {
        var i = this.resultList.select(this.resultList.selected);
        this.onSubmit({
          query: this.searchElement.input.value,
          data: i
        });
      }
    },
    clearResults: function (t, e) {
      if (void 0 === e && (e = !1), !t || 27 === t.keyCode) {
        var r = this.options,
          n = r.autoComplete;
        !e && r.keepResult || (this.searchElement.input.value = "", this.markers.clearLayers()), n && this.resultList.clear();
      }
    },
    autoSearch: function (t) {
      try {
        var e = this;
        if (v.indexOf(t.keyCode) > -1) return Promise.resolve();
        var r = t.target.value,
          n = e.options.provider,
          o = function () {
            if (r.length) return Promise.resolve(n.search({
              query: r
            })).then(function (t) {
              t = t.slice(0, e.options.maxSuggestions), e.resultList.render(t, e.options.resultFormat);
            });
            e.resultList.clear();
          }();
        return Promise.resolve(o && o.then ? o.then(function () {}) : void 0);
      } catch (t) {
        return Promise.reject(t);
      }
    },
    onSubmit: function (t) {
      try {
        var e = this;
        return e.resultList.clear(), Promise.resolve(e.options.provider.search(t)).then(function (r) {
          r && r.length > 0 && e.showResult(r[0], t);
        });
      } catch (t) {
        return Promise.reject(t);
      }
    },
    showResult: function (t, e) {
      var r = this.options,
        n = r.autoClose,
        o = r.updateMap,
        i = this.markers.getLayers();
      i.length >= this.options.maxMarkers && this.markers.removeLayer(i[0]);
      var s = this.addMarker(t, e);
      o && this.centerMap(t), this.map.fireEvent("geosearch/showlocation", {
        location: t,
        marker: s
      }), n && this.closeResults();
    },
    closeResults: function () {
      var t = this.searchElement.container;
      t.classList.contains("active") && u(t, "active"), this.clearResults();
    },
    addMarker: function (e, r) {
      var n = this,
        o = this.options,
        i = o.marker,
        s = o.showPopup,
        a = o.popupFormat,
        l = new leaflet__WEBPACK_IMPORTED_MODULE_0__.Marker([e.y, e.x], i),
        c = e.label;
      return "function" == typeof a && (c = a({
        query: r,
        result: e
      })), l.bindPopup(c), this.markers.addLayer(l), s && l.openPopup(), i.draggable && l.on("dragend", function (t) {
        n.map.fireEvent("geosearch/marker/dragend", {
          location: l.getLatLng(),
          event: t
        });
      }), l;
    },
    centerMap: function (e) {
      var r = this.options,
        n = r.retainZoomLevel,
        o = r.animateZoom,
        i = e.bounds ? new leaflet__WEBPACK_IMPORTED_MODULE_0__.LatLngBounds(e.bounds) : new leaflet__WEBPACK_IMPORTED_MODULE_0__.LatLng(e.y, e.x).toBounds(10),
        s = i.isValid() ? i : this.markers.getBounds();
      !n && i.isValid() && !e.bounds || n || !i.isValid() ? this.map.setView(s.getCenter(), this.getZoom(), {
        animate: o
      }) : this.map.fitBounds(s, {
        animate: o
      });
    },
    getZoom: function () {
      var t = this.options,
        e = t.zoomLevel;
      return t.retainZoomLevel ? this.map.getZoom() : e;
    }
  };
function w() {
  if (!leaflet__WEBPACK_IMPORTED_MODULE_0__) throw new Error(b);
  var e = leaflet__WEBPACK_IMPORTED_MODULE_0__.Control.extend(E);
  return i(e, [].slice.call(arguments));
}
!function (t) {
  t[t.SEARCH = 0] = "SEARCH", t[t.REVERSE = 1] = "REVERSE";
}(h || (h = {}));
var x = /*#__PURE__*/function () {
    function t(t) {
      void 0 === t && (t = {}), this.options = void 0, this.options = t;
    }
    var r = t.prototype;
    return r.getParamString = function (t) {
      void 0 === t && (t = {});
      var r = e({}, this.options.params, t);
      return Object.keys(r).map(function (t) {
        return encodeURIComponent(t) + "=" + encodeURIComponent(r[t]);
      }).join("&");
    }, r.getUrl = function (t, e) {
      return t + "?" + this.getParamString(e);
    }, r.search = function (t) {
      try {
        var e = this,
          r = e.endpoint({
            query: t.query,
            type: h.SEARCH
          });
        return Promise.resolve(fetch(r)).then(function (t) {
          return Promise.resolve(t.json()).then(function (t) {
            return e.parse({
              data: t
            });
          });
        });
      } catch (t) {
        return Promise.reject(t);
      }
    }, t;
  }(),
  L = /*#__PURE__*/function (t) {
    function n() {
      return t.apply(this, arguments) || this;
    }
    r(n, t);
    var o = n.prototype;
    return o.endpoint = function () {
      return "https://places-dsn.algolia.net/1/places/query";
    }, o.findBestMatchLevelIndex = function (t) {
      var e = t.find(function (t) {
        return "full" === t.matchLevel;
      }) || t.find(function (t) {
        return "partial" === t.matchLevel;
      });
      return e ? t.indexOf(e) : 0;
    }, o.getLabel = function (t) {
      var e, r, n, o;
      return [null == (e = t.locale_names) ? void 0 : e.default[this.findBestMatchLevelIndex(t._highlightResult.locale_names.default)], null == (r = t.city) ? void 0 : r.default[this.findBestMatchLevelIndex(t._highlightResult.city.default)], t.administrative[this.findBestMatchLevelIndex(t._highlightResult.administrative)], null == (n = t.postcode) ? void 0 : n[this.findBestMatchLevelIndex(t._highlightResult.postcode)], null == (o = t.country) ? void 0 : o.default].filter(Boolean).join(", ");
    }, o.parse = function (t) {
      var e = this;
      return t.data.hits.map(function (t) {
        return {
          x: t._geoloc.lng,
          y: t._geoloc.lat,
          label: e.getLabel(t),
          bounds: null,
          raw: t
        };
      });
    }, o.search = function (t) {
      var r = t.query;
      try {
        var n = this,
          o = "string" == typeof r ? {
            query: r
          } : r;
        return Promise.resolve(fetch(n.endpoint(), {
          method: "POST",
          body: JSON.stringify(e({}, n.options.params, o))
        })).then(function (t) {
          return Promise.resolve(t.json()).then(function (t) {
            return n.parse({
              data: t
            });
          });
        });
      } catch (t) {
        return Promise.reject(t);
      }
    }, n;
  }(x),
  k = /*#__PURE__*/function (t) {
    function e() {
      for (var e, r = arguments.length, n = new Array(r), o = 0; o < r; o++) n[o] = arguments[o];
      return (e = t.call.apply(t, [this].concat(n)) || this).searchUrl = "https://dev.virtualearth.net/REST/v1/Locations", e;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = "string" == typeof e ? {
          q: e
        } : e;
      return r.jsonp = t.jsonp, this.getUrl(this.searchUrl, r);
    }, n.parse = function (t) {
      return 0 === t.data.resourceSets.length ? [] : t.data.resourceSets[0].resources.map(function (t) {
        return {
          x: t.point.coordinates[1],
          y: t.point.coordinates[0],
          label: t.address.formattedAddress,
          bounds: [[t.bbox[0], t.bbox[1]], [t.bbox[2], t.bbox[3]]],
          raw: t
        };
      });
    }, n.search = function (t) {
      var e,
        r,
        n,
        o = t.query;
      try {
        var i = this,
          a = "BING_JSONP_CB_" + Date.now();
        return Promise.resolve((e = i.endpoint({
          query: o,
          jsonp: a
        }), r = a, n = s("script", null, document.body), n.setAttribute("type", "text/javascript"), new Promise(function (t) {
          window[r] = function (e) {
            n.remove(), delete window[r], t(e);
          }, n.setAttribute("src", e);
        }))).then(function (t) {
          return i.parse({
            data: t
          });
        });
      } catch (t) {
        return Promise.reject(t);
      }
    }, e;
  }(x),
  U = /*#__PURE__*/function (t) {
    function e() {
      for (var e, r = arguments.length, n = new Array(r), o = 0; o < r; o++) n[o] = arguments[o];
      return (e = t.call.apply(t, [this].concat(n)) || this).searchUrl = "https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer/find", e;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = "string" == typeof e ? {
          text: e
        } : e;
      return r.f = "json", this.getUrl(this.searchUrl, r);
    }, n.parse = function (t) {
      return t.data.locations.map(function (t) {
        return {
          x: t.feature.geometry.x,
          y: t.feature.geometry.y,
          label: t.name,
          bounds: [[t.extent.ymin, t.extent.xmin], [t.extent.ymax, t.extent.xmax]],
          raw: t
        };
      });
    }, e;
  }(x),
  S = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      return void 0 === e && (e = {}), (r = t.call(this, e) || this).host = void 0, r.host = e.host || "http://localhost:4000", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query;
      return t.type === h.REVERSE ? this.getUrl(this.host + "/v1/reverse", "string" == typeof e ? {} : e) : this.getUrl(this.host + "/v1/autocomplete", "string" == typeof e ? {
        text: e
      } : e);
    }, n.parse = function (t) {
      return t.data.features.map(function (t) {
        var e = {
          x: t.geometry.coordinates[0],
          y: t.geometry.coordinates[1],
          label: t.properties.label,
          bounds: null,
          raw: t
        };
        return Array.isArray(t.bbox) && 4 === t.bbox.length && (e.bounds = [[t.bbox[1], t.bbox[0]], [t.bbox[3], t.bbox[2]]]), e;
      });
    }, e;
  }(x),
  C = /*#__PURE__*/function (t) {
    function e(e) {
      return void 0 === e && (e = {}), e.host = "https://api.geocode.earth", t.call(this, e) || this;
    }
    return r(e, t), e;
  }(S);
function P(t) {
  return t && t.__esModule && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t;
}
"function" == typeof SuppressedError && SuppressedError;
var R,
  I = /*@__PURE__*/P(function t(e, r) {
    if (e === r) return !0;
    if (e && r && "object" == typeof e && "object" == typeof r) {
      if (e.constructor !== r.constructor) return !1;
      var n, o, i;
      if (Array.isArray(e)) {
        if ((n = e.length) != r.length) return !1;
        for (o = n; 0 != o--;) if (!t(e[o], r[o])) return !1;
        return !0;
      }
      if (e.constructor === RegExp) return e.source === r.source && e.flags === r.flags;
      if (e.valueOf !== Object.prototype.valueOf) return e.valueOf() === r.valueOf();
      if (e.toString !== Object.prototype.toString) return e.toString() === r.toString();
      if ((n = (i = Object.keys(e)).length) !== Object.keys(r).length) return !1;
      for (o = n; 0 != o--;) if (!Object.prototype.hasOwnProperty.call(r, i[o])) return !1;
      for (o = n; 0 != o--;) {
        var s = i[o];
        if (!t(e[s], r[s])) return !1;
      }
      return !0;
    }
    return e != e && r != r;
  });
!function (t) {
  t[t.INITIALIZED = 0] = "INITIALIZED", t[t.LOADING = 1] = "LOADING", t[t.SUCCESS = 2] = "SUCCESS", t[t.FAILURE = 3] = "FAILURE";
}(R || (R = {}));
class j {
  constructor({
    apiKey: t,
    authReferrerPolicy: e,
    channel: r,
    client: n,
    id: o = "__googleMapsScriptId",
    language: i,
    libraries: s = [],
    mapIds: a,
    nonce: l,
    region: c,
    retries: u = 3,
    url: h = "https://maps.googleapis.com/maps/api/js",
    version: p
  }) {
    if (this.callbacks = [], this.done = !1, this.loading = !1, this.errors = [], this.apiKey = t, this.authReferrerPolicy = e, this.channel = r, this.client = n, this.id = o || "__googleMapsScriptId", this.language = i, this.libraries = s, this.mapIds = a, this.nonce = l, this.region = c, this.retries = u, this.url = h, this.version = p, j.instance) {
      if (!I(this.options, j.instance.options)) throw new Error(`Loader must not be called again with different options. ${JSON.stringify(this.options)} !== ${JSON.stringify(j.instance.options)}`);
      return j.instance;
    }
    j.instance = this;
  }
  get options() {
    return {
      version: this.version,
      apiKey: this.apiKey,
      channel: this.channel,
      client: this.client,
      id: this.id,
      libraries: this.libraries,
      language: this.language,
      region: this.region,
      mapIds: this.mapIds,
      nonce: this.nonce,
      url: this.url,
      authReferrerPolicy: this.authReferrerPolicy
    };
  }
  get status() {
    return this.errors.length ? R.FAILURE : this.done ? R.SUCCESS : this.loading ? R.LOADING : R.INITIALIZED;
  }
  get failed() {
    return this.done && !this.loading && this.errors.length >= this.retries + 1;
  }
  createUrl() {
    let t = this.url;
    return t += "?callback=__googleMapsCallback&loading=async", this.apiKey && (t += `&key=${this.apiKey}`), this.channel && (t += `&channel=${this.channel}`), this.client && (t += `&client=${this.client}`), this.libraries.length > 0 && (t += `&libraries=${this.libraries.join(",")}`), this.language && (t += `&language=${this.language}`), this.region && (t += `&region=${this.region}`), this.version && (t += `&v=${this.version}`), this.mapIds && (t += `&map_ids=${this.mapIds.join(",")}`), this.authReferrerPolicy && (t += `&auth_referrer_policy=${this.authReferrerPolicy}`), t;
  }
  deleteScript() {
    const t = document.getElementById(this.id);
    t && t.remove();
  }
  load() {
    return this.loadPromise();
  }
  loadPromise() {
    return new Promise((t, e) => {
      this.loadCallback(r => {
        r ? e(r.error) : t(window.google);
      });
    });
  }
  importLibrary(t) {
    return this.execute(), google.maps.importLibrary(t);
  }
  loadCallback(t) {
    this.callbacks.push(t), this.execute();
  }
  setScript() {
    var t, e;
    if (document.getElementById(this.id)) return void this.callback();
    const r = {
      key: this.apiKey,
      channel: this.channel,
      client: this.client,
      libraries: this.libraries.length && this.libraries,
      v: this.version,
      mapIds: this.mapIds,
      language: this.language,
      region: this.region,
      authReferrerPolicy: this.authReferrerPolicy
    };
    Object.keys(r).forEach(t => !r[t] && delete r[t]), (null === (e = null === (t = null === window || void 0 === window ? void 0 : window.google) || void 0 === t ? void 0 : t.maps) || void 0 === e ? void 0 : e.importLibrary) || (t => {
      let e,
        r,
        n,
        o = "The Google Maps JavaScript API",
        i = "google",
        s = "importLibrary",
        a = "__ib__",
        l = document,
        c = window;
      c = c[i] || (c[i] = {});
      const u = c.maps || (c.maps = {}),
        h = new Set(),
        p = new URLSearchParams(),
        d = () => e || (e = new Promise((s, c) => {
          return d = this, v = function* () {
            var d;
            for (n in yield r = l.createElement("script"), r.id = this.id, p.set("libraries", [...h] + ""), t) p.set(n.replace(/[A-Z]/g, t => "_" + t[0].toLowerCase()), t[n]);
            p.set("callback", i + ".maps." + a), r.src = this.url + "?" + p, u[a] = s, r.onerror = () => e = c(Error(o + " could not load.")), r.nonce = this.nonce || (null === (d = l.querySelector("script[nonce]")) || void 0 === d ? void 0 : d.nonce) || "", l.head.append(r);
          }, new ((f = void 0) || (f = Promise))(function (t, e) {
            function r(t) {
              try {
                o(v.next(t));
              } catch (t) {
                e(t);
              }
            }
            function n(t) {
              try {
                o(v.throw(t));
              } catch (t) {
                e(t);
              }
            }
            function o(e) {
              var o;
              e.done ? t(e.value) : (o = e.value, o instanceof f ? o : new f(function (t) {
                t(o);
              })).then(r, n);
            }
            o((v = v.apply(d, [])).next());
          });
          var d, f, v;
        }));
      u[s] ? console.warn(o + " only loads once. Ignoring:", t) : u[s] = (t, ...e) => h.add(t) && d().then(() => u[s](t, ...e));
    })(r);
    const n = this.libraries.map(t => this.importLibrary(t));
    n.length || n.push(this.importLibrary("core")), Promise.all(n).then(() => this.callback(), t => {
      const e = new ErrorEvent("error", {
        error: t
      });
      this.loadErrorCallback(e);
    });
  }
  reset() {
    this.deleteScript(), this.done = !1, this.loading = !1, this.errors = [], this.onerrorEvent = null;
  }
  resetIfRetryingFailed() {
    this.failed && this.reset();
  }
  loadErrorCallback(t) {
    if (this.errors.push(t), this.errors.length <= this.retries) {
      const t = this.errors.length * Math.pow(2, this.errors.length);
      console.error(`Failed to load Google Maps script, retrying in ${t} ms.`), setTimeout(() => {
        this.deleteScript(), this.setScript();
      }, t);
    } else this.onerrorEvent = t, this.callback();
  }
  callback() {
    this.done = !0, this.loading = !1, this.callbacks.forEach(t => {
      t(this.onerrorEvent);
    }), this.callbacks = [];
  }
  execute() {
    if (this.resetIfRetryingFailed(), this.done) this.callback();else {
      if (window.google && window.google.maps && window.google.maps.version) return console.warn("Google Maps already loaded outside @googlemaps/js-api-loader.This may result in undesirable behavior as options and script parameters may not match."), void this.callback();
      this.loading || (this.loading = !0, this.setScript());
    }
  }
}
var A = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      return (r = t.call(this, e) || this).loader = null, r.geocoder = null, "undefined" != typeof window && (r.loader = new j(e).load().then(function (t) {
        var e = new t.maps.Geocoder();
        return r.geocoder = e, e;
      })), r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      throw new Error("Method not implemented.");
    }, n.parse = function (t) {
      return t.data.results.map(function (t) {
        var e = t.geometry.location.toJSON(),
          r = e.lat,
          n = e.lng,
          o = t.geometry.viewport.toJSON();
        return {
          x: n,
          y: r,
          label: t.formatted_address,
          bounds: [[o.south, o.west], [o.north, o.east]],
          raw: t
        };
      });
    }, n.search = function (t) {
      try {
        var e = function (e) {
            if (!e) throw new Error("GoogleMaps GeoCoder is not loaded. Are you trying to run this server side?");
            return Promise.resolve(e.geocode({
              address: t.query
            }, function (t) {
              return {
                results: t
              };
            }).catch(function (t) {
              return "ZERO_RESULTS" !== t.code && console.error(t.code + ": " + t.message), {
                results: []
              };
            })).then(function (t) {
              return r.parse({
                data: t
              });
            });
          },
          r = this,
          n = r.geocoder;
        return Promise.resolve(n ? e(n) : Promise.resolve(r.loader).then(e));
      } catch (t) {
        return Promise.reject(t);
      }
    }, e;
  }(x),
  N = /*#__PURE__*/function (t) {
    function e() {
      for (var e, r = arguments.length, n = new Array(r), o = 0; o < r; o++) n[o] = arguments[o];
      return (e = t.call.apply(t, [this].concat(n)) || this).searchUrl = "https://maps.googleapis.com/maps/api/geocode/json", e;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query;
      return this.getUrl(this.searchUrl, "string" == typeof e ? {
        address: e
      } : e);
    }, n.parse = function (t) {
      return t.data.results.map(function (t) {
        return {
          x: t.geometry.location.lng,
          y: t.geometry.location.lat,
          label: t.formatted_address,
          bounds: [[t.geometry.viewport.southwest.lat, t.geometry.viewport.southwest.lng], [t.geometry.viewport.northeast.lat, t.geometry.viewport.northeast.lng]],
          raw: t
        };
      });
    }, e;
  }(x),
  O = /*#__PURE__*/function (t) {
    function e() {
      for (var e, r = arguments.length, n = new Array(r), o = 0; o < r; o++) n[o] = arguments[o];
      return (e = t.call.apply(t, [this].concat(n)) || this).searchUrl = "https://geocode.search.hereapi.com/v1/autosuggest", e;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query;
      return this.getUrl(this.searchUrl, "string" == typeof e ? {
        q: e
      } : e);
    }, n.parse = function (t) {
      return t.data.items.filter(function (t) {
        return void 0 !== t.position;
      }).map(function (t) {
        return {
          x: t.position.lng,
          y: t.position.lat,
          label: t.address.label,
          bounds: null,
          raw: t
        };
      });
    }, e;
  }(x),
  F = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      void 0 === e && (e = {}), (r = t.call(this, e) || this).searchUrl = void 0, r.reverseUrl = void 0;
      var n = "https://nominatim.openstreetmap.org";
      return r.searchUrl = e.searchUrl || n + "/search", r.reverseUrl = e.reverseUrl || n + "/reverse", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = t.type,
        n = "string" == typeof e ? {
          q: e
        } : e;
      return n.format = "json", this.getUrl(r === h.REVERSE ? this.reverseUrl : this.searchUrl, n);
    }, n.parse = function (t) {
      return (Array.isArray(t.data) ? t.data : [t.data]).map(function (t) {
        return {
          x: Number(t.lon),
          y: Number(t.lat),
          label: t.display_name,
          bounds: [[parseFloat(t.boundingbox[0]), parseFloat(t.boundingbox[2])], [parseFloat(t.boundingbox[1]), parseFloat(t.boundingbox[3])]],
          raw: t
        };
      });
    }, e;
  }(x),
  _ = /*#__PURE__*/function (t) {
    function n(r) {
      return t.call(this, e({}, r, {
        searchUrl: "https://locationiq.org/v1/search.php",
        reverseUrl: "https://locationiq.org/v1/reverse.php"
      })) || this;
    }
    return r(n, t), n.prototype.parse = function (e) {
      return e.data.error ? [] : t.prototype.parse.call(this, e);
    }, n;
  }(F),
  M = /*#__PURE__*/function (t) {
    function e() {
      for (var e, r = arguments.length, n = new Array(r), o = 0; o < r; o++) n[o] = arguments[o];
      return (e = t.call.apply(t, [this].concat(n)) || this).searchUrl = "https://api.opencagedata.com/geocode/v1/json", e;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = "string" == typeof e ? {
          q: e
        } : e;
      return r.format = "json", this.getUrl(this.searchUrl, r);
    }, n.parse = function (t) {
      return t.data.results.map(function (t) {
        return {
          x: t.geometry.lng,
          y: t.geometry.lat,
          label: t.formatted,
          bounds: [[t.bounds.southwest.lat, t.bounds.southwest.lng], [t.bounds.northeast.lat, t.bounds.northeast.lng]],
          raw: t
        };
      });
    }, n.search = function (e) {
      try {
        return Promise.resolve(e.query.length < 2 ? [] : t.prototype.search.call(this, e));
      } catch (t) {
        return Promise.reject(t);
      }
    }, e;
  }(x),
  q = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      void 0 === e && (e = {}), (r = t.call(this, e) || this).searchUrl = void 0, r.reverseUrl = void 0;
      var n = "https://civildefense.fit.vutbr.cz";
      return r.searchUrl = e.searchUrl || n + "/search", r.reverseUrl = e.reverseUrl || n + "/reverse", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = t.type,
        n = "string" == typeof e ? {
          q: e
        } : e;
      return n.format = "json", this.getUrl(r === h.REVERSE ? this.reverseUrl : this.searchUrl, n);
    }, n.parse = function (t) {
      return (Array.isArray(t.data) ? t.data : [t.data]).map(function (t) {
        return {
          x: Number(t.lon),
          y: Number(t.lat),
          label: t.display_name,
          bounds: [[parseFloat(t.boundingbox[0]), parseFloat(t.boundingbox[2])], [parseFloat(t.boundingbox[1]), parseFloat(t.boundingbox[3])]],
          raw: t
        };
      });
    }, e;
  }(x),
  B = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      return void 0 === e && (e = {}), (r = t.call(this, e) || this).searchUrl = void 0, r.searchUrl = e.searchUrl || "https://a.tiles.mapbox.com/v4/geocode/mapbox.places/", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      return this.getUrl("" + this.searchUrl + t.query + ".json");
    }, n.parse = function (t) {
      return (Array.isArray(t.data.features) ? t.data.features : []).map(function (t) {
        var e = null;
        return t.bbox && (e = [[parseFloat(t.bbox[1]), parseFloat(t.bbox[0])], [parseFloat(t.bbox[3]), parseFloat(t.bbox[2])]]), {
          x: Number(t.center[0]),
          y: Number(t.center[1]),
          label: t.place_name ? t.place_name : t.text,
          bounds: e,
          raw: t
        };
      });
    }, e;
  }(x),
  D = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      void 0 === e && (e = {}), (r = t.call(this, e) || this).searchUrl = void 0, r.reverseUrl = void 0;
      var n = "https://api-adresse.data.gouv.fr";
      return r.searchUrl = e.searchUrl || n + "/search", r.reverseUrl = e.reverseUrl || n + "/reverse", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query;
      return this.getUrl(t.type === h.REVERSE ? this.reverseUrl : this.searchUrl, "string" == typeof e ? {
        q: e
      } : e);
    }, n.parse = function (t) {
      return t.data.features.map(function (t) {
        return {
          x: t.geometry.coordinates[0],
          y: t.geometry.coordinates[1],
          label: t.properties.label,
          bounds: null,
          raw: t
        };
      });
    }, e;
  }(x),
  T = /*#__PURE__*/function (t) {
    function e(e) {
      var r;
      void 0 === e && (e = {}), (r = t.call(this, e) || this).searchUrl = void 0, r.reverseUrl = void 0;
      var n = "https://api.geoapify.com/v1/geocode";
      return r.searchUrl = e.searchUrl || n + "/search", r.reverseUrl = e.reverseUrl || n + "/reverse", r;
    }
    r(e, t);
    var n = e.prototype;
    return n.endpoint = function (t) {
      var e = t.query,
        r = t.type,
        n = "string" == typeof e ? {
          text: e
        } : e;
      return n.format = "json", this.getUrl(r === h.REVERSE ? this.reverseUrl : this.searchUrl, n);
    }, n.parse = function (t) {
      return (Array.isArray(t.data.results) ? t.data.results : [t.data.results]).map(function (t) {
        return {
          x: Number(t.lon),
          y: Number(t.lat),
          label: t.formatted,
          bounds: [[parseFloat(t.bbox.lat1), parseFloat(t.bbox.lon1)], [parseFloat(t.bbox.lat2), parseFloat(t.bbox.lon2)]],
          raw: t
        };
      });
    }, e;
  }(x);


/***/ }),

/***/ 35449:
/*!******************************************************************************!*\
  !*** ./node_modules/leaflet.markercluster/dist/leaflet.markercluster-src.js ***!
  \******************************************************************************/
/***/ (function(__unused_webpack_module, exports) {

/*
 * Leaflet.markercluster 1.5.3+master.e5124b2,
 * Provides Beautiful Animated Marker Clustering functionality for Leaflet, a JS library for interactive maps.
 * https://github.com/Leaflet/Leaflet.markercluster
 * (c) 2012-2017, Dave Leaver, smartrak
 */
(function (global, factory) {
   true ? factory(exports) : 0;
})(this, function (exports) {
  'use strict';

  /*
   * L.MarkerClusterGroup extends L.FeatureGroup by clustering the markers contained within
   */
  var MarkerClusterGroup = L.MarkerClusterGroup = L.FeatureGroup.extend({
    options: {
      maxClusterRadius: 80,
      //A cluster will cover at most this many pixels from its center
      iconCreateFunction: null,
      clusterPane: L.Marker.prototype.options.pane,
      spiderfyOnEveryZoom: false,
      spiderfyOnMaxZoom: true,
      showCoverageOnHover: true,
      zoomToBoundsOnClick: true,
      singleMarkerMode: false,
      disableClusteringAtZoom: null,
      // Setting this to false prevents the removal of any clusters outside of the viewpoint, which
      // is the default behaviour for performance reasons.
      removeOutsideVisibleBounds: true,
      // Set to false to disable all animations (zoom and spiderfy).
      // If false, option animateAddingMarkers below has no effect.
      // If L.DomUtil.TRANSITION is falsy, this option has no effect.
      animate: true,
      //Whether to animate adding markers after adding the MarkerClusterGroup to the map
      // If you are adding individual markers set to true, if adding bulk markers leave false for massive performance gains.
      animateAddingMarkers: false,
      // Make it possible to provide custom function to calculate spiderfy shape positions
      spiderfyShapePositions: null,
      //Increase to increase the distance away that spiderfied markers appear from the center
      spiderfyDistanceMultiplier: 1,
      // Make it possible to specify a polyline options on a spider leg
      spiderLegPolylineOptions: {
        weight: 1.5,
        color: '#222',
        opacity: 0.5
      },
      // When bulk adding layers, adds markers in chunks. Means addLayers may not add all the layers in the call, others will be loaded during setTimeouts
      chunkedLoading: false,
      chunkInterval: 200,
      // process markers for a maximum of ~ n milliseconds (then trigger the chunkProgress callback)
      chunkDelay: 50,
      // at the end of each interval, give n milliseconds back to system/browser
      chunkProgress: null,
      // progress callback: function(processed, total, elapsed) (e.g. for a progress indicator)

      //Options to pass to the L.Polygon constructor
      polygonOptions: {}
    },
    initialize: function (options) {
      L.Util.setOptions(this, options);
      if (!this.options.iconCreateFunction) {
        this.options.iconCreateFunction = this._defaultIconCreateFunction;
      }
      this._featureGroup = L.featureGroup();
      this._featureGroup.addEventParent(this);
      this._nonPointGroup = L.featureGroup();
      this._nonPointGroup.addEventParent(this);
      this._inZoomAnimation = 0;
      this._needsClustering = [];
      this._needsRemoving = []; //Markers removed while we aren't on the map need to be kept track of
      //The bounds of the currently shown area (from _getExpandedVisibleBounds) Updated on zoom/move
      this._currentShownBounds = null;
      this._queue = [];
      this._childMarkerEventHandlers = {
        'dragstart': this._childMarkerDragStart,
        'move': this._childMarkerMoved,
        'dragend': this._childMarkerDragEnd
      };

      // Hook the appropriate animation methods.
      var animate = L.DomUtil.TRANSITION && this.options.animate;
      L.extend(this, animate ? this._withAnimation : this._noAnimation);
      // Remember which MarkerCluster class to instantiate (animated or not).
      this._markerCluster = animate ? L.MarkerCluster : L.MarkerClusterNonAnimated;
    },
    addLayer: function (layer) {
      if (layer instanceof L.LayerGroup) {
        return this.addLayers([layer]);
      }

      //Don't cluster non point data
      if (!layer.getLatLng) {
        this._nonPointGroup.addLayer(layer);
        this.fire('layeradd', {
          layer: layer
        });
        return this;
      }
      if (!this._map) {
        this._needsClustering.push(layer);
        this.fire('layeradd', {
          layer: layer
        });
        return this;
      }
      if (this.hasLayer(layer)) {
        return this;
      }

      //If we have already clustered we'll need to add this one to a cluster

      if (this._unspiderfy) {
        this._unspiderfy();
      }
      this._addLayer(layer, this._maxZoom);
      this.fire('layeradd', {
        layer: layer
      });

      // Refresh bounds and weighted positions.
      this._topClusterLevel._recalculateBounds();
      this._refreshClustersIcons();

      //Work out what is visible
      var visibleLayer = layer,
        currentZoom = this._zoom;
      if (layer.__parent) {
        while (visibleLayer.__parent._zoom >= currentZoom) {
          visibleLayer = visibleLayer.__parent;
        }
      }
      if (this._currentShownBounds.contains(visibleLayer.getLatLng())) {
        if (this.options.animateAddingMarkers) {
          this._animationAddLayer(layer, visibleLayer);
        } else {
          this._animationAddLayerNonAnimated(layer, visibleLayer);
        }
      }
      return this;
    },
    removeLayer: function (layer) {
      if (layer instanceof L.LayerGroup) {
        return this.removeLayers([layer]);
      }

      //Non point layers
      if (!layer.getLatLng) {
        this._nonPointGroup.removeLayer(layer);
        this.fire('layerremove', {
          layer: layer
        });
        return this;
      }
      if (!this._map) {
        if (!this._arraySplice(this._needsClustering, layer) && this.hasLayer(layer)) {
          this._needsRemoving.push({
            layer: layer,
            latlng: layer._latlng
          });
        }
        this.fire('layerremove', {
          layer: layer
        });
        return this;
      }
      if (!layer.__parent) {
        return this;
      }
      if (this._unspiderfy) {
        this._unspiderfy();
        this._unspiderfyLayer(layer);
      }

      //Remove the marker from clusters
      this._removeLayer(layer, true);
      this.fire('layerremove', {
        layer: layer
      });

      // Refresh bounds and weighted positions.
      this._topClusterLevel._recalculateBounds();
      this._refreshClustersIcons();
      layer.off(this._childMarkerEventHandlers, this);
      if (this._featureGroup.hasLayer(layer)) {
        this._featureGroup.removeLayer(layer);
        if (layer.clusterShow) {
          layer.clusterShow();
        }
      }
      return this;
    },
    //Takes an array of markers and adds them in bulk
    addLayers: function (layersArray, skipLayerAddEvent) {
      if (!L.Util.isArray(layersArray)) {
        return this.addLayer(layersArray);
      }
      var fg = this._featureGroup,
        npg = this._nonPointGroup,
        chunked = this.options.chunkedLoading,
        chunkInterval = this.options.chunkInterval,
        chunkProgress = this.options.chunkProgress,
        l = layersArray.length,
        offset = 0,
        originalArray = true,
        m;
      if (this._map) {
        var started = new Date().getTime();
        var process = L.bind(function () {
          var start = new Date().getTime();

          // Make sure to unspiderfy before starting to add some layers
          if (this._map && this._unspiderfy) {
            this._unspiderfy();
          }
          for (; offset < l; offset++) {
            if (chunked && offset % 200 === 0) {
              // every couple hundred markers, instrument the time elapsed since processing started:
              var elapsed = new Date().getTime() - start;
              if (elapsed > chunkInterval) {
                break; // been working too hard, time to take a break :-)
              }
            }
            m = layersArray[offset];

            // Group of layers, append children to layersArray and skip.
            // Side effects:
            // - Total increases, so chunkProgress ratio jumps backward.
            // - Groups are not included in this group, only their non-group child layers (hasLayer).
            // Changing array length while looping does not affect performance in current browsers:
            // http://jsperf.com/for-loop-changing-length/6
            if (m instanceof L.LayerGroup) {
              if (originalArray) {
                layersArray = layersArray.slice();
                originalArray = false;
              }
              this._extractNonGroupLayers(m, layersArray);
              l = layersArray.length;
              continue;
            }

            //Not point data, can't be clustered
            if (!m.getLatLng) {
              npg.addLayer(m);
              if (!skipLayerAddEvent) {
                this.fire('layeradd', {
                  layer: m
                });
              }
              continue;
            }
            if (this.hasLayer(m)) {
              continue;
            }
            this._addLayer(m, this._maxZoom);
            if (!skipLayerAddEvent) {
              this.fire('layeradd', {
                layer: m
              });
            }

            //If we just made a cluster of size 2 then we need to remove the other marker from the map (if it is) or we never will
            if (m.__parent) {
              if (m.__parent.getChildCount() === 2) {
                var markers = m.__parent.getAllChildMarkers(),
                  otherMarker = markers[0] === m ? markers[1] : markers[0];
                fg.removeLayer(otherMarker);
              }
            }
          }
          if (chunkProgress) {
            // report progress and time elapsed:
            chunkProgress(offset, l, new Date().getTime() - started);
          }

          // Completed processing all markers.
          if (offset === l) {
            // Refresh bounds and weighted positions.
            this._topClusterLevel._recalculateBounds();
            this._refreshClustersIcons();
            this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
          } else {
            setTimeout(process, this.options.chunkDelay);
          }
        }, this);
        process();
      } else {
        var needsClustering = this._needsClustering;
        for (; offset < l; offset++) {
          m = layersArray[offset];

          // Group of layers, append children to layersArray and skip.
          if (m instanceof L.LayerGroup) {
            if (originalArray) {
              layersArray = layersArray.slice();
              originalArray = false;
            }
            this._extractNonGroupLayers(m, layersArray);
            l = layersArray.length;
            continue;
          }

          //Not point data, can't be clustered
          if (!m.getLatLng) {
            npg.addLayer(m);
            continue;
          }
          if (this.hasLayer(m)) {
            continue;
          }
          needsClustering.push(m);
        }
      }
      return this;
    },
    //Takes an array of markers and removes them in bulk
    removeLayers: function (layersArray) {
      var i,
        m,
        l = layersArray.length,
        fg = this._featureGroup,
        npg = this._nonPointGroup,
        originalArray = true;
      if (!this._map) {
        for (i = 0; i < l; i++) {
          m = layersArray[i];

          // Group of layers, append children to layersArray and skip.
          if (m instanceof L.LayerGroup) {
            if (originalArray) {
              layersArray = layersArray.slice();
              originalArray = false;
            }
            this._extractNonGroupLayers(m, layersArray);
            l = layersArray.length;
            continue;
          }
          this._arraySplice(this._needsClustering, m);
          npg.removeLayer(m);
          if (this.hasLayer(m)) {
            this._needsRemoving.push({
              layer: m,
              latlng: m._latlng
            });
          }
          this.fire('layerremove', {
            layer: m
          });
        }
        return this;
      }
      if (this._unspiderfy) {
        this._unspiderfy();

        // Work on a copy of the array, so that next loop is not affected.
        var layersArray2 = layersArray.slice(),
          l2 = l;
        for (i = 0; i < l2; i++) {
          m = layersArray2[i];

          // Group of layers, append children to layersArray and skip.
          if (m instanceof L.LayerGroup) {
            this._extractNonGroupLayers(m, layersArray2);
            l2 = layersArray2.length;
            continue;
          }
          this._unspiderfyLayer(m);
        }
      }
      for (i = 0; i < l; i++) {
        m = layersArray[i];

        // Group of layers, append children to layersArray and skip.
        if (m instanceof L.LayerGroup) {
          if (originalArray) {
            layersArray = layersArray.slice();
            originalArray = false;
          }
          this._extractNonGroupLayers(m, layersArray);
          l = layersArray.length;
          continue;
        }
        if (!m.__parent) {
          npg.removeLayer(m);
          this.fire('layerremove', {
            layer: m
          });
          continue;
        }
        this._removeLayer(m, true, true);
        this.fire('layerremove', {
          layer: m
        });
        if (fg.hasLayer(m)) {
          fg.removeLayer(m);
          if (m.clusterShow) {
            m.clusterShow();
          }
        }
      }

      // Refresh bounds and weighted positions.
      this._topClusterLevel._recalculateBounds();
      this._refreshClustersIcons();

      //Fix up the clusters and markers on the map
      this._topClusterLevel._recursivelyAddChildrenToMap(null, this._zoom, this._currentShownBounds);
      return this;
    },
    //Removes all layers from the MarkerClusterGroup
    clearLayers: function () {
      //Need our own special implementation as the LayerGroup one doesn't work for us

      //If we aren't on the map (yet), blow away the markers we know of
      if (!this._map) {
        this._needsClustering = [];
        this._needsRemoving = [];
        delete this._gridClusters;
        delete this._gridUnclustered;
      }
      if (this._noanimationUnspiderfy) {
        this._noanimationUnspiderfy();
      }

      //Remove all the visible layers
      this._featureGroup.clearLayers();
      this._nonPointGroup.clearLayers();
      this.eachLayer(function (marker) {
        marker.off(this._childMarkerEventHandlers, this);
        delete marker.__parent;
      }, this);
      if (this._map) {
        //Reset _topClusterLevel and the DistanceGrids
        this._generateInitialClusters();
      }
      return this;
    },
    //Override FeatureGroup.getBounds as it doesn't work
    getBounds: function () {
      var bounds = new L.LatLngBounds();
      if (this._topClusterLevel) {
        bounds.extend(this._topClusterLevel._bounds);
      }
      for (var i = this._needsClustering.length - 1; i >= 0; i--) {
        bounds.extend(this._needsClustering[i].getLatLng());
      }
      bounds.extend(this._nonPointGroup.getBounds());
      return bounds;
    },
    //Overrides LayerGroup.eachLayer
    eachLayer: function (method, context) {
      var markers = this._needsClustering.slice(),
        needsRemoving = this._needsRemoving,
        thisNeedsRemoving,
        i,
        j;
      if (this._topClusterLevel) {
        this._topClusterLevel.getAllChildMarkers(markers);
      }
      for (i = markers.length - 1; i >= 0; i--) {
        thisNeedsRemoving = true;
        for (j = needsRemoving.length - 1; j >= 0; j--) {
          if (needsRemoving[j].layer === markers[i]) {
            thisNeedsRemoving = false;
            break;
          }
        }
        if (thisNeedsRemoving) {
          method.call(context, markers[i]);
        }
      }
      this._nonPointGroup.eachLayer(method, context);
    },
    //Overrides LayerGroup.getLayers
    getLayers: function () {
      var layers = [];
      this.eachLayer(function (l) {
        layers.push(l);
      });
      return layers;
    },
    //Overrides LayerGroup.getLayer, WARNING: Really bad performance
    getLayer: function (id) {
      var result = null;
      id = parseInt(id, 10);
      this.eachLayer(function (l) {
        if (L.stamp(l) === id) {
          result = l;
        }
      });
      return result;
    },
    //Returns true if the given layer is in this MarkerClusterGroup
    hasLayer: function (layer) {
      if (!layer) {
        return false;
      }
      var i,
        anArray = this._needsClustering;
      for (i = anArray.length - 1; i >= 0; i--) {
        if (anArray[i] === layer) {
          return true;
        }
      }
      anArray = this._needsRemoving;
      for (i = anArray.length - 1; i >= 0; i--) {
        if (anArray[i].layer === layer) {
          return false;
        }
      }
      return !!(layer.__parent && layer.__parent._group === this) || this._nonPointGroup.hasLayer(layer);
    },
    //Zoom down to show the given layer (spiderfying if necessary) then calls the callback
    zoomToShowLayer: function (layer, callback) {
      var map = this._map;
      if (typeof callback !== 'function') {
        callback = function () {};
      }
      var showMarker = function () {
        // Assumes that map.hasLayer checks for direct appearance on map, not recursively calling
        // hasLayer on Layer Groups that are on map (typically not calling this MarkerClusterGroup.hasLayer, which would always return true)
        if ((map.hasLayer(layer) || map.hasLayer(layer.__parent)) && !this._inZoomAnimation) {
          this._map.off('moveend', showMarker, this);
          this.off('animationend', showMarker, this);
          if (map.hasLayer(layer)) {
            callback();
          } else if (layer.__parent._icon) {
            this.once('spiderfied', callback, this);
            layer.__parent.spiderfy();
          }
        }
      };
      if (layer._icon && this._map.getBounds().contains(layer.getLatLng())) {
        //Layer is visible ond on screen, immediate return
        callback();
      } else if (layer.__parent._zoom < Math.round(this._map._zoom)) {
        //Layer should be visible at this zoom level. It must not be on screen so just pan over to it
        this._map.on('moveend', showMarker, this);
        this._map.panTo(layer.getLatLng());
      } else {
        this._map.on('moveend', showMarker, this);
        this.on('animationend', showMarker, this);
        layer.__parent.zoomToBounds();
      }
    },
    //Overrides FeatureGroup.onAdd
    onAdd: function (map) {
      this._map = map;
      var i, l, layer;
      if (!isFinite(this._map.getMaxZoom())) {
        throw "Map has no maxZoom specified";
      }
      this._featureGroup.addTo(map);
      this._nonPointGroup.addTo(map);
      if (!this._gridClusters) {
        this._generateInitialClusters();
      }
      this._maxLat = map.options.crs.projection.MAX_LATITUDE;

      //Restore all the positions as they are in the MCG before removing them
      for (i = 0, l = this._needsRemoving.length; i < l; i++) {
        layer = this._needsRemoving[i];
        layer.newlatlng = layer.layer._latlng;
        layer.layer._latlng = layer.latlng;
      }
      //Remove them, then restore their new positions
      for (i = 0, l = this._needsRemoving.length; i < l; i++) {
        layer = this._needsRemoving[i];
        this._removeLayer(layer.layer, true);
        layer.layer._latlng = layer.newlatlng;
      }
      this._needsRemoving = [];

      //Remember the current zoom level and bounds
      this._zoom = Math.round(this._map._zoom);
      this._currentShownBounds = this._getExpandedVisibleBounds();
      this._map.on('zoomend', this._zoomEnd, this);
      this._map.on('moveend', this._moveEnd, this);
      if (this._spiderfierOnAdd) {
        //TODO FIXME: Not sure how to have spiderfier add something on here nicely
        this._spiderfierOnAdd();
      }
      this._bindEvents();

      //Actually add our markers to the map:
      l = this._needsClustering;
      this._needsClustering = [];
      this.addLayers(l, true);
    },
    //Overrides FeatureGroup.onRemove
    onRemove: function (map) {
      map.off('zoomend', this._zoomEnd, this);
      map.off('moveend', this._moveEnd, this);
      this._unbindEvents();

      //In case we are in a cluster animation
      this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
      if (this._spiderfierOnRemove) {
        //TODO FIXME: Not sure how to have spiderfier add something on here nicely
        this._spiderfierOnRemove();
      }
      delete this._maxLat;

      //Clean up all the layers we added to the map
      this._hideCoverage();
      this._featureGroup.remove();
      this._nonPointGroup.remove();
      this._featureGroup.clearLayers();
      this._map = null;
    },
    getVisibleParent: function (marker) {
      var vMarker = marker;
      while (vMarker && !vMarker._icon) {
        vMarker = vMarker.__parent;
      }
      return vMarker || null;
    },
    //Remove the given object from the given array
    _arraySplice: function (anArray, obj) {
      for (var i = anArray.length - 1; i >= 0; i--) {
        if (anArray[i] === obj) {
          anArray.splice(i, 1);
          return true;
        }
      }
    },
    /**
     * Removes a marker from all _gridUnclustered zoom levels, starting at the supplied zoom.
     * @param marker to be removed from _gridUnclustered.
     * @param z integer bottom start zoom level (included)
     * @private
     */
    _removeFromGridUnclustered: function (marker, z) {
      var map = this._map,
        gridUnclustered = this._gridUnclustered,
        minZoom = Math.floor(this._map.getMinZoom());
      for (; z >= minZoom; z--) {
        if (!gridUnclustered[z].removeObject(marker, map.project(marker.getLatLng(), z))) {
          break;
        }
      }
    },
    _childMarkerDragStart: function (e) {
      e.target.__dragStart = e.target._latlng;
    },
    _childMarkerMoved: function (e) {
      if (!this._ignoreMove && !e.target.__dragStart) {
        var isPopupOpen = e.target._popup && e.target._popup.isOpen();
        this._moveChild(e.target, e.oldLatLng, e.latlng);
        if (isPopupOpen) {
          e.target.openPopup();
        }
      }
    },
    _moveChild: function (layer, from, to) {
      layer._latlng = from;
      this.removeLayer(layer);
      layer._latlng = to;
      this.addLayer(layer);
    },
    _childMarkerDragEnd: function (e) {
      var dragStart = e.target.__dragStart;
      delete e.target.__dragStart;
      if (dragStart) {
        this._moveChild(e.target, dragStart, e.target._latlng);
      }
    },
    //Internal function for removing a marker from everything.
    //dontUpdateMap: set to true if you will handle updating the map manually (for bulk functions)
    _removeLayer: function (marker, removeFromDistanceGrid, dontUpdateMap) {
      var gridClusters = this._gridClusters,
        gridUnclustered = this._gridUnclustered,
        fg = this._featureGroup,
        map = this._map,
        minZoom = Math.floor(this._map.getMinZoom());

      //Remove the marker from distance clusters it might be in
      if (removeFromDistanceGrid) {
        this._removeFromGridUnclustered(marker, this._maxZoom);
      }

      //Work our way up the clusters removing them as we go if required
      var cluster = marker.__parent,
        markers = cluster._markers,
        otherMarker;

      //Remove the marker from the immediate parents marker list
      this._arraySplice(markers, marker);
      while (cluster) {
        cluster._childCount--;
        cluster._boundsNeedUpdate = true;
        if (cluster._zoom < minZoom) {
          //Top level, do nothing
          break;
        } else if (removeFromDistanceGrid && cluster._childCount <= 1) {
          //Cluster no longer required
          //We need to push the other marker up to the parent
          otherMarker = cluster._markers[0] === marker ? cluster._markers[1] : cluster._markers[0];

          //Update distance grid
          gridClusters[cluster._zoom].removeObject(cluster, map.project(cluster._cLatLng, cluster._zoom));
          gridUnclustered[cluster._zoom].addObject(otherMarker, map.project(otherMarker.getLatLng(), cluster._zoom));

          //Move otherMarker up to parent
          this._arraySplice(cluster.__parent._childClusters, cluster);
          cluster.__parent._markers.push(otherMarker);
          otherMarker.__parent = cluster.__parent;
          if (cluster._icon) {
            //Cluster is currently on the map, need to put the marker on the map instead
            fg.removeLayer(cluster);
            if (!dontUpdateMap) {
              fg.addLayer(otherMarker);
            }
          }
        } else {
          cluster._iconNeedsUpdate = true;
        }
        cluster = cluster.__parent;
      }
      delete marker.__parent;
    },
    _isOrIsParent: function (el, oel) {
      while (oel) {
        if (el === oel) {
          return true;
        }
        oel = oel.parentNode;
      }
      return false;
    },
    //Override L.Evented.fire
    fire: function (type, data, propagate) {
      if (data && data.layer instanceof L.MarkerCluster) {
        //Prevent multiple clustermouseover/off events if the icon is made up of stacked divs (Doesn't work in ie <= 8, no relatedTarget)
        if (data.originalEvent && this._isOrIsParent(data.layer._icon, data.originalEvent.relatedTarget)) {
          return;
        }
        type = 'cluster' + type;
      }
      L.FeatureGroup.prototype.fire.call(this, type, data, propagate);
    },
    //Override L.Evented.listens
    listens: function (type, propagate) {
      return L.FeatureGroup.prototype.listens.call(this, type, propagate) || L.FeatureGroup.prototype.listens.call(this, 'cluster' + type, propagate);
    },
    //Default functionality
    _defaultIconCreateFunction: function (cluster) {
      var childCount = cluster.getChildCount();
      var c = ' marker-cluster-';
      if (childCount < 10) {
        c += 'small';
      } else if (childCount < 100) {
        c += 'medium';
      } else {
        c += 'large';
      }
      return new L.DivIcon({
        html: '<div><span>' + childCount + '</span></div>',
        className: 'marker-cluster' + c,
        iconSize: new L.Point(40, 40)
      });
    },
    _bindEvents: function () {
      var map = this._map,
        spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
        showCoverageOnHover = this.options.showCoverageOnHover,
        zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
        spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom;

      //Zoom on cluster click or spiderfy if we are at the lowest level
      if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {
        this.on('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);
      }

      //Show convex hull (boundary) polygon on mouse over
      if (showCoverageOnHover) {
        this.on('clustermouseover', this._showCoverage, this);
        this.on('clustermouseout', this._hideCoverage, this);
        map.on('zoomend', this._hideCoverage, this);
      }
    },
    _zoomOrSpiderfy: function (e) {
      var cluster = e.layer,
        bottomCluster = cluster;
      if (e.type === 'clusterkeypress' && e.originalEvent && e.originalEvent.keyCode !== 13) {
        return;
      }
      while (bottomCluster._childClusters.length === 1) {
        bottomCluster = bottomCluster._childClusters[0];
      }
      if (bottomCluster._zoom === this._maxZoom && bottomCluster._childCount === cluster._childCount && this.options.spiderfyOnMaxZoom) {
        // All child markers are contained in a single cluster from this._maxZoom to this cluster.
        cluster.spiderfy();
      } else if (this.options.zoomToBoundsOnClick) {
        cluster.zoomToBounds();
      }
      if (this.options.spiderfyOnEveryZoom) {
        cluster.spiderfy();
      }

      // Focus the map again for keyboard users.
      if (e.originalEvent && e.originalEvent.keyCode === 13) {
        this._map._container.focus();
      }
    },
    _showCoverage: function (e) {
      var map = this._map;
      if (this._inZoomAnimation) {
        return;
      }
      if (this._shownPolygon) {
        map.removeLayer(this._shownPolygon);
      }
      if (e.layer.getChildCount() > 2 && e.layer !== this._spiderfied) {
        this._shownPolygon = new L.Polygon(e.layer.getConvexHull(), this.options.polygonOptions);
        map.addLayer(this._shownPolygon);
      }
    },
    _hideCoverage: function () {
      if (this._shownPolygon) {
        this._map.removeLayer(this._shownPolygon);
        this._shownPolygon = null;
      }
    },
    _unbindEvents: function () {
      var spiderfyOnMaxZoom = this.options.spiderfyOnMaxZoom,
        showCoverageOnHover = this.options.showCoverageOnHover,
        zoomToBoundsOnClick = this.options.zoomToBoundsOnClick,
        spiderfyOnEveryZoom = this.options.spiderfyOnEveryZoom,
        map = this._map;
      if (spiderfyOnMaxZoom || zoomToBoundsOnClick || spiderfyOnEveryZoom) {
        this.off('clusterclick clusterkeypress', this._zoomOrSpiderfy, this);
      }
      if (showCoverageOnHover) {
        this.off('clustermouseover', this._showCoverage, this);
        this.off('clustermouseout', this._hideCoverage, this);
        map.off('zoomend', this._hideCoverage, this);
      }
    },
    _zoomEnd: function () {
      if (!this._map) {
        //May have been removed from the map by a zoomEnd handler
        return;
      }
      this._mergeSplitClusters();
      this._zoom = Math.round(this._map._zoom);
      this._currentShownBounds = this._getExpandedVisibleBounds();
    },
    _moveEnd: function () {
      if (this._inZoomAnimation) {
        return;
      }
      var newBounds = this._getExpandedVisibleBounds();
      this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, newBounds);
      this._topClusterLevel._recursivelyAddChildrenToMap(null, Math.round(this._map._zoom), newBounds);
      this._currentShownBounds = newBounds;
      return;
    },
    _generateInitialClusters: function () {
      var maxZoom = Math.ceil(this._map.getMaxZoom()),
        minZoom = Math.floor(this._map.getMinZoom()),
        radius = this.options.maxClusterRadius,
        radiusFn = radius;

      //If we just set maxClusterRadius to a single number, we need to create
      //a simple function to return that number. Otherwise, we just have to
      //use the function we've passed in.
      if (typeof radius !== "function") {
        radiusFn = function () {
          return radius;
        };
      }
      if (this.options.disableClusteringAtZoom !== null) {
        maxZoom = this.options.disableClusteringAtZoom - 1;
      }
      this._maxZoom = maxZoom;
      this._gridClusters = {};
      this._gridUnclustered = {};

      //Set up DistanceGrids for each zoom
      for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
        this._gridClusters[zoom] = new L.DistanceGrid(radiusFn(zoom));
        this._gridUnclustered[zoom] = new L.DistanceGrid(radiusFn(zoom));
      }

      // Instantiate the appropriate L.MarkerCluster class (animated or not).
      this._topClusterLevel = new this._markerCluster(this, minZoom - 1);
    },
    //Zoom: Zoom to start adding at (Pass this._maxZoom to start at the bottom)
    _addLayer: function (layer, zoom) {
      var gridClusters = this._gridClusters,
        gridUnclustered = this._gridUnclustered,
        minZoom = Math.floor(this._map.getMinZoom()),
        markerPoint,
        z;
      if (this.options.singleMarkerMode) {
        this._overrideMarkerIcon(layer);
      }
      layer.on(this._childMarkerEventHandlers, this);

      //Find the lowest zoom level to slot this one in
      for (; zoom >= minZoom; zoom--) {
        markerPoint = this._map.project(layer.getLatLng(), zoom); // calculate pixel position

        //Try find a cluster close by
        var closest = gridClusters[zoom].getNearObject(markerPoint);
        if (closest) {
          closest._addChild(layer);
          layer.__parent = closest;
          return;
        }

        //Try find a marker close by to form a new cluster with
        closest = gridUnclustered[zoom].getNearObject(markerPoint);
        if (closest) {
          var parent = closest.__parent;
          if (parent) {
            this._removeLayer(closest, false);
          }

          //Create new cluster with these 2 in it

          var newCluster = new this._markerCluster(this, zoom, closest, layer);
          gridClusters[zoom].addObject(newCluster, this._map.project(newCluster._cLatLng, zoom));
          closest.__parent = newCluster;
          layer.__parent = newCluster;

          //First create any new intermediate parent clusters that don't exist
          var lastParent = newCluster;
          for (z = zoom - 1; z > parent._zoom; z--) {
            lastParent = new this._markerCluster(this, z, lastParent);
            gridClusters[z].addObject(lastParent, this._map.project(closest.getLatLng(), z));
          }
          parent._addChild(lastParent);

          //Remove closest from this zoom level and any above that it is in, replace with newCluster
          this._removeFromGridUnclustered(closest, zoom);
          return;
        }

        //Didn't manage to cluster in at this zoom, record us as a marker here and continue upwards
        gridUnclustered[zoom].addObject(layer, markerPoint);
      }

      //Didn't get in anything, add us to the top
      this._topClusterLevel._addChild(layer);
      layer.__parent = this._topClusterLevel;
      return;
    },
    /**
     * Refreshes the icon of all "dirty" visible clusters.
     * Non-visible "dirty" clusters will be updated when they are added to the map.
     * @private
     */
    _refreshClustersIcons: function () {
      this._featureGroup.eachLayer(function (c) {
        if (c instanceof L.MarkerCluster && c._iconNeedsUpdate) {
          c._updateIcon();
        }
      });
    },
    //Enqueue code to fire after the marker expand/contract has happened
    _enqueue: function (fn) {
      this._queue.push(fn);
      if (!this._queueTimeout) {
        this._queueTimeout = setTimeout(L.bind(this._processQueue, this), 300);
      }
    },
    _processQueue: function () {
      for (var i = 0; i < this._queue.length; i++) {
        this._queue[i].call(this);
      }
      this._queue.length = 0;
      clearTimeout(this._queueTimeout);
      this._queueTimeout = null;
    },
    //Merge and split any existing clusters that are too big or small
    _mergeSplitClusters: function () {
      var mapZoom = Math.round(this._map._zoom);

      //In case we are starting to split before the animation finished
      this._processQueue();
      if (this._zoom < mapZoom && this._currentShownBounds.intersects(this._getExpandedVisibleBounds())) {
        //Zoom in, split
        this._animationStart();
        //Remove clusters now off screen
        this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), this._zoom, this._getExpandedVisibleBounds());
        this._animationZoomIn(this._zoom, mapZoom);
      } else if (this._zoom > mapZoom) {
        //Zoom out, merge
        this._animationStart();
        this._animationZoomOut(this._zoom, mapZoom);
      } else {
        this._moveEnd();
      }
    },
    //Gets the maps visible bounds expanded in each direction by the size of the screen (so the user cannot see an area we do not cover in one pan)
    _getExpandedVisibleBounds: function () {
      if (!this.options.removeOutsideVisibleBounds) {
        return this._mapBoundsInfinite;
      } else if (L.Browser.mobile) {
        return this._checkBoundsMaxLat(this._map.getBounds());
      }
      return this._checkBoundsMaxLat(this._map.getBounds().pad(1)); // Padding expands the bounds by its own dimensions but scaled with the given factor.
    },
    /**
     * Expands the latitude to Infinity (or -Infinity) if the input bounds reach the map projection maximum defined latitude
     * (in the case of Web/Spherical Mercator, it is 85.0511287798 / see https://en.wikipedia.org/wiki/Web_Mercator#Formulas).
     * Otherwise, the removeOutsideVisibleBounds option will remove markers beyond that limit, whereas the same markers without
     * this option (or outside MCG) will have their position floored (ceiled) by the projection and rendered at that limit,
     * making the user think that MCG "eats" them and never displays them again.
     * @param bounds L.LatLngBounds
     * @returns {L.LatLngBounds}
     * @private
     */
    _checkBoundsMaxLat: function (bounds) {
      var maxLat = this._maxLat;
      if (maxLat !== undefined) {
        if (bounds.getNorth() >= maxLat) {
          bounds._northEast.lat = Infinity;
        }
        if (bounds.getSouth() <= -maxLat) {
          bounds._southWest.lat = -Infinity;
        }
      }
      return bounds;
    },
    //Shared animation code
    _animationAddLayerNonAnimated: function (layer, newCluster) {
      if (newCluster === layer) {
        this._featureGroup.addLayer(layer);
      } else if (newCluster._childCount === 2) {
        newCluster._addToMap();
        var markers = newCluster.getAllChildMarkers();
        this._featureGroup.removeLayer(markers[0]);
        this._featureGroup.removeLayer(markers[1]);
      } else {
        newCluster._updateIcon();
      }
    },
    /**
     * Extracts individual (i.e. non-group) layers from a Layer Group.
     * @param group to extract layers from.
     * @param output {Array} in which to store the extracted layers.
     * @returns {*|Array}
     * @private
     */
    _extractNonGroupLayers: function (group, output) {
      var layers = group.getLayers(),
        i = 0,
        layer;
      output = output || [];
      for (; i < layers.length; i++) {
        layer = layers[i];
        if (layer instanceof L.LayerGroup) {
          this._extractNonGroupLayers(layer, output);
          continue;
        }
        output.push(layer);
      }
      return output;
    },
    /**
     * Implements the singleMarkerMode option.
     * @param layer Marker to re-style using the Clusters iconCreateFunction.
     * @returns {L.Icon} The newly created icon.
     * @private
     */
    _overrideMarkerIcon: function (layer) {
      var icon = layer.options.icon = this.options.iconCreateFunction({
        getChildCount: function () {
          return 1;
        },
        getAllChildMarkers: function () {
          return [layer];
        }
      });
      return icon;
    }
  });

  // Constant bounds used in case option "removeOutsideVisibleBounds" is set to false.
  L.MarkerClusterGroup.include({
    _mapBoundsInfinite: new L.LatLngBounds(new L.LatLng(-Infinity, -Infinity), new L.LatLng(Infinity, Infinity))
  });
  L.MarkerClusterGroup.include({
    _noAnimation: {
      //Non Animated versions of everything
      _animationStart: function () {
        //Do nothing...
      },
      _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
        this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel);
        this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());

        //We didn't actually animate, but we use this event to mean "clustering animations have finished"
        this.fire('animationend');
      },
      _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
        this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel);
        this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());

        //We didn't actually animate, but we use this event to mean "clustering animations have finished"
        this.fire('animationend');
      },
      _animationAddLayer: function (layer, newCluster) {
        this._animationAddLayerNonAnimated(layer, newCluster);
      }
    },
    _withAnimation: {
      //Animated versions here
      _animationStart: function () {
        this._map._mapPane.className += ' leaflet-cluster-anim';
        this._inZoomAnimation++;
      },
      _animationZoomIn: function (previousZoomLevel, newZoomLevel) {
        var bounds = this._getExpandedVisibleBounds(),
          fg = this._featureGroup,
          minZoom = Math.floor(this._map.getMinZoom()),
          i;
        this._ignoreMove = true;

        //Add all children of current clusters to map and remove those clusters from map
        this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {
          var startPos = c._latlng,
            markers = c._markers,
            m;
          if (!bounds.contains(startPos)) {
            startPos = null;
          }
          if (c._isSingleParent() && previousZoomLevel + 1 === newZoomLevel) {
            //Immediately add the new child and remove us
            fg.removeLayer(c);
            c._recursivelyAddChildrenToMap(null, newZoomLevel, bounds);
          } else {
            //Fade out old cluster
            c.clusterHide();
            c._recursivelyAddChildrenToMap(startPos, newZoomLevel, bounds);
          }

          //Remove all markers that aren't visible any more
          //TODO: Do we actually need to do this on the higher levels too?
          for (i = markers.length - 1; i >= 0; i--) {
            m = markers[i];
            if (!bounds.contains(m._latlng)) {
              fg.removeLayer(m);
            }
          }
        });
        this._forceLayout();

        //Update opacities
        this._topClusterLevel._recursivelyBecomeVisible(bounds, newZoomLevel);
        //TODO Maybe? Update markers in _recursivelyBecomeVisible
        fg.eachLayer(function (n) {
          if (!(n instanceof L.MarkerCluster) && n._icon) {
            n.clusterShow();
          }
        });

        //update the positions of the just added clusters/markers
        this._topClusterLevel._recursively(bounds, previousZoomLevel, newZoomLevel, function (c) {
          c._recursivelyRestoreChildPositions(newZoomLevel);
        });
        this._ignoreMove = false;

        //Remove the old clusters and close the zoom animation
        this._enqueue(function () {
          //update the positions of the just added clusters/markers
          this._topClusterLevel._recursively(bounds, previousZoomLevel, minZoom, function (c) {
            fg.removeLayer(c);
            c.clusterShow();
          });
          this._animationEnd();
        });
      },
      _animationZoomOut: function (previousZoomLevel, newZoomLevel) {
        this._animationZoomOutSingle(this._topClusterLevel, previousZoomLevel - 1, newZoomLevel);

        //Need to add markers for those that weren't on the map before but are now
        this._topClusterLevel._recursivelyAddChildrenToMap(null, newZoomLevel, this._getExpandedVisibleBounds());
        //Remove markers that were on the map before but won't be now
        this._topClusterLevel._recursivelyRemoveChildrenFromMap(this._currentShownBounds, Math.floor(this._map.getMinZoom()), previousZoomLevel, this._getExpandedVisibleBounds());
      },
      _animationAddLayer: function (layer, newCluster) {
        var me = this,
          fg = this._featureGroup;
        fg.addLayer(layer);
        if (newCluster !== layer) {
          if (newCluster._childCount > 2) {
            //Was already a cluster

            newCluster._updateIcon();
            this._forceLayout();
            this._animationStart();
            layer._setPos(this._map.latLngToLayerPoint(newCluster.getLatLng()));
            layer.clusterHide();
            this._enqueue(function () {
              fg.removeLayer(layer);
              layer.clusterShow();
              me._animationEnd();
            });
          } else {
            //Just became a cluster
            this._forceLayout();
            me._animationStart();
            me._animationZoomOutSingle(newCluster, this._map.getMaxZoom(), this._zoom);
          }
        }
      }
    },
    // Private methods for animated versions.
    _animationZoomOutSingle: function (cluster, previousZoomLevel, newZoomLevel) {
      var bounds = this._getExpandedVisibleBounds(),
        minZoom = Math.floor(this._map.getMinZoom());

      //Animate all of the markers in the clusters to move to their cluster center point
      cluster._recursivelyAnimateChildrenInAndAddSelfToMap(bounds, minZoom, previousZoomLevel + 1, newZoomLevel);
      var me = this;

      //Update the opacity (If we immediately set it they won't animate)
      this._forceLayout();
      cluster._recursivelyBecomeVisible(bounds, newZoomLevel);

      //TODO: Maybe use the transition timing stuff to make this more reliable
      //When the animations are done, tidy up
      this._enqueue(function () {
        //This cluster stopped being a cluster before the timeout fired
        if (cluster._childCount === 1) {
          var m = cluster._markers[0];
          //If we were in a cluster animation at the time then the opacity and position of our child could be wrong now, so fix it
          this._ignoreMove = true;
          m.setLatLng(m.getLatLng());
          this._ignoreMove = false;
          if (m.clusterShow) {
            m.clusterShow();
          }
        } else {
          cluster._recursively(bounds, newZoomLevel, minZoom, function (c) {
            c._recursivelyRemoveChildrenFromMap(bounds, minZoom, previousZoomLevel + 1);
          });
        }
        me._animationEnd();
      });
    },
    _animationEnd: function () {
      if (this._map) {
        this._map._mapPane.className = this._map._mapPane.className.replace(' leaflet-cluster-anim', '');
      }
      this._inZoomAnimation--;
      this.fire('animationend');
    },
    //Force a browser layout of stuff in the map
    // Should apply the current opacity and location to all elements so we can update them again for an animation
    _forceLayout: function () {
      //In my testing this works, infact offsetWidth of any element seems to work.
      //Could loop all this._layers and do this for each _icon if it stops working

      L.Util.falseFn(document.body.offsetWidth);
    }
  });
  L.markerClusterGroup = function (options) {
    return new L.MarkerClusterGroup(options);
  };
  var MarkerCluster = L.MarkerCluster = L.Marker.extend({
    options: L.Icon.prototype.options,
    initialize: function (group, zoom, a, b) {
      L.Marker.prototype.initialize.call(this, a ? a._cLatLng || a.getLatLng() : new L.LatLng(0, 0), {
        icon: this,
        pane: group.options.clusterPane
      });
      this._group = group;
      this._zoom = zoom;
      this._markers = [];
      this._childClusters = [];
      this._childCount = 0;
      this._iconNeedsUpdate = true;
      this._boundsNeedUpdate = true;
      this._bounds = new L.LatLngBounds();
      if (a) {
        this._addChild(a);
      }
      if (b) {
        this._addChild(b);
      }
    },
    //Recursively retrieve all child markers of this cluster
    getAllChildMarkers: function (storageArray, ignoreDraggedMarker) {
      storageArray = storageArray || [];
      for (var i = this._childClusters.length - 1; i >= 0; i--) {
        this._childClusters[i].getAllChildMarkers(storageArray, ignoreDraggedMarker);
      }
      for (var j = this._markers.length - 1; j >= 0; j--) {
        if (ignoreDraggedMarker && this._markers[j].__dragStart) {
          continue;
        }
        storageArray.push(this._markers[j]);
      }
      return storageArray;
    },
    //Returns the count of how many child markers we have
    getChildCount: function () {
      return this._childCount;
    },
    //Zoom to the minimum of showing all of the child markers, or the extents of this cluster
    zoomToBounds: function (fitBoundsOptions) {
      var childClusters = this._childClusters.slice(),
        map = this._group._map,
        boundsZoom = map.getBoundsZoom(this._bounds),
        zoom = this._zoom + 1,
        mapZoom = map.getZoom(),
        i;

      //calculate how far we need to zoom down to see all of the markers
      while (childClusters.length > 0 && boundsZoom > zoom) {
        zoom++;
        var newClusters = [];
        for (i = 0; i < childClusters.length; i++) {
          newClusters = newClusters.concat(childClusters[i]._childClusters);
        }
        childClusters = newClusters;
      }
      if (boundsZoom > zoom) {
        this._group._map.setView(this._latlng, zoom);
      } else if (boundsZoom <= mapZoom) {
        //If fitBounds wouldn't zoom us down, zoom us down instead
        this._group._map.setView(this._latlng, mapZoom + 1);
      } else {
        this._group._map.fitBounds(this._bounds, fitBoundsOptions);
      }
    },
    getBounds: function () {
      var bounds = new L.LatLngBounds();
      bounds.extend(this._bounds);
      return bounds;
    },
    _updateIcon: function () {
      this._iconNeedsUpdate = true;
      if (this._icon) {
        this.setIcon(this);
      }
    },
    //Cludge for Icon, we pretend to be an icon for performance
    createIcon: function () {
      if (this._iconNeedsUpdate) {
        this._iconObj = this._group.options.iconCreateFunction(this);
        this._iconNeedsUpdate = false;
      }
      return this._iconObj.createIcon();
    },
    createShadow: function () {
      return this._iconObj.createShadow();
    },
    _addChild: function (new1, isNotificationFromChild) {
      this._iconNeedsUpdate = true;
      this._boundsNeedUpdate = true;
      this._setClusterCenter(new1);
      if (new1 instanceof L.MarkerCluster) {
        if (!isNotificationFromChild) {
          this._childClusters.push(new1);
          new1.__parent = this;
        }
        this._childCount += new1._childCount;
      } else {
        if (!isNotificationFromChild) {
          this._markers.push(new1);
        }
        this._childCount++;
      }
      if (this.__parent) {
        this.__parent._addChild(new1, true);
      }
    },
    /**
     * Makes sure the cluster center is set. If not, uses the child center if it is a cluster, or the marker position.
     * @param child L.MarkerCluster|L.Marker that will be used as cluster center if not defined yet.
     * @private
     */
    _setClusterCenter: function (child) {
      if (!this._cLatLng) {
        // when clustering, take position of the first point as the cluster center
        this._cLatLng = child._cLatLng || child._latlng;
      }
    },
    /**
     * Assigns impossible bounding values so that the next extend entirely determines the new bounds.
     * This method avoids having to trash the previous L.LatLngBounds object and to create a new one, which is much slower for this class.
     * As long as the bounds are not extended, most other methods would probably fail, as they would with bounds initialized but not extended.
     * @private
     */
    _resetBounds: function () {
      var bounds = this._bounds;
      if (bounds._southWest) {
        bounds._southWest.lat = Infinity;
        bounds._southWest.lng = Infinity;
      }
      if (bounds._northEast) {
        bounds._northEast.lat = -Infinity;
        bounds._northEast.lng = -Infinity;
      }
    },
    _recalculateBounds: function () {
      var markers = this._markers,
        childClusters = this._childClusters,
        latSum = 0,
        lngSum = 0,
        totalCount = this._childCount,
        i,
        child,
        childLatLng,
        childCount;

      // Case where all markers are removed from the map and we are left with just an empty _topClusterLevel.
      if (totalCount === 0) {
        return;
      }

      // Reset rather than creating a new object, for performance.
      this._resetBounds();

      // Child markers.
      for (i = 0; i < markers.length; i++) {
        childLatLng = markers[i]._latlng;
        this._bounds.extend(childLatLng);
        latSum += childLatLng.lat;
        lngSum += childLatLng.lng;
      }

      // Child clusters.
      for (i = 0; i < childClusters.length; i++) {
        child = childClusters[i];

        // Re-compute child bounds and weighted position first if necessary.
        if (child._boundsNeedUpdate) {
          child._recalculateBounds();
        }
        this._bounds.extend(child._bounds);
        childLatLng = child._wLatLng;
        childCount = child._childCount;
        latSum += childLatLng.lat * childCount;
        lngSum += childLatLng.lng * childCount;
      }
      this._latlng = this._wLatLng = new L.LatLng(latSum / totalCount, lngSum / totalCount);

      // Reset dirty flag.
      this._boundsNeedUpdate = false;
    },
    //Set our markers position as given and add it to the map
    _addToMap: function (startPos) {
      if (startPos) {
        this._backupLatlng = this._latlng;
        this.setLatLng(startPos);
      }
      this._group._featureGroup.addLayer(this);
    },
    _recursivelyAnimateChildrenIn: function (bounds, center, maxZoom) {
      this._recursively(bounds, this._group._map.getMinZoom(), maxZoom - 1, function (c) {
        var markers = c._markers,
          i,
          m;
        for (i = markers.length - 1; i >= 0; i--) {
          m = markers[i];

          //Only do it if the icon is still on the map
          if (m._icon) {
            m._setPos(center);
            m.clusterHide();
          }
        }
      }, function (c) {
        var childClusters = c._childClusters,
          j,
          cm;
        for (j = childClusters.length - 1; j >= 0; j--) {
          cm = childClusters[j];
          if (cm._icon) {
            cm._setPos(center);
            cm.clusterHide();
          }
        }
      });
    },
    _recursivelyAnimateChildrenInAndAddSelfToMap: function (bounds, mapMinZoom, previousZoomLevel, newZoomLevel) {
      this._recursively(bounds, newZoomLevel, mapMinZoom, function (c) {
        c._recursivelyAnimateChildrenIn(bounds, c._group._map.latLngToLayerPoint(c.getLatLng()).round(), previousZoomLevel);

        //TODO: depthToAnimateIn affects _isSingleParent, if there is a multizoom we may/may not be.
        //As a hack we only do a animation free zoom on a single level zoom, if someone does multiple levels then we always animate
        if (c._isSingleParent() && previousZoomLevel - 1 === newZoomLevel) {
          c.clusterShow();
          c._recursivelyRemoveChildrenFromMap(bounds, mapMinZoom, previousZoomLevel); //Immediately remove our children as we are replacing them. TODO previousBounds not bounds
        } else {
          c.clusterHide();
        }
        c._addToMap();
      });
    },
    _recursivelyBecomeVisible: function (bounds, zoomLevel) {
      this._recursively(bounds, this._group._map.getMinZoom(), zoomLevel, null, function (c) {
        c.clusterShow();
      });
    },
    _recursivelyAddChildrenToMap: function (startPos, zoomLevel, bounds) {
      this._recursively(bounds, this._group._map.getMinZoom() - 1, zoomLevel, function (c) {
        if (zoomLevel === c._zoom) {
          return;
        }

        //Add our child markers at startPos (so they can be animated out)
        for (var i = c._markers.length - 1; i >= 0; i--) {
          var nm = c._markers[i];
          if (!bounds.contains(nm._latlng)) {
            continue;
          }
          if (startPos) {
            nm._backupLatlng = nm.getLatLng();
            nm.setLatLng(startPos);
            if (nm.clusterHide) {
              nm.clusterHide();
            }
          }
          c._group._featureGroup.addLayer(nm);
        }
      }, function (c) {
        c._addToMap(startPos);
      });
    },
    _recursivelyRestoreChildPositions: function (zoomLevel) {
      //Fix positions of child markers
      for (var i = this._markers.length - 1; i >= 0; i--) {
        var nm = this._markers[i];
        if (nm._backupLatlng) {
          nm.setLatLng(nm._backupLatlng);
          delete nm._backupLatlng;
        }
      }
      if (zoomLevel - 1 === this._zoom) {
        //Reposition child clusters
        for (var j = this._childClusters.length - 1; j >= 0; j--) {
          this._childClusters[j]._restorePosition();
        }
      } else {
        for (var k = this._childClusters.length - 1; k >= 0; k--) {
          this._childClusters[k]._recursivelyRestoreChildPositions(zoomLevel);
        }
      }
    },
    _restorePosition: function () {
      if (this._backupLatlng) {
        this.setLatLng(this._backupLatlng);
        delete this._backupLatlng;
      }
    },
    //exceptBounds: If set, don't remove any markers/clusters in it
    _recursivelyRemoveChildrenFromMap: function (previousBounds, mapMinZoom, zoomLevel, exceptBounds) {
      var m, i;
      this._recursively(previousBounds, mapMinZoom - 1, zoomLevel - 1, function (c) {
        //Remove markers at every level
        for (i = c._markers.length - 1; i >= 0; i--) {
          m = c._markers[i];
          if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
            c._group._featureGroup.removeLayer(m);
            if (m.clusterShow) {
              m.clusterShow();
            }
          }
        }
      }, function (c) {
        //Remove child clusters at just the bottom level
        for (i = c._childClusters.length - 1; i >= 0; i--) {
          m = c._childClusters[i];
          if (!exceptBounds || !exceptBounds.contains(m._latlng)) {
            c._group._featureGroup.removeLayer(m);
            if (m.clusterShow) {
              m.clusterShow();
            }
          }
        }
      });
    },
    //Run the given functions recursively to this and child clusters
    // boundsToApplyTo: a L.LatLngBounds representing the bounds of what clusters to recurse in to
    // zoomLevelToStart: zoom level to start running functions (inclusive)
    // zoomLevelToStop: zoom level to stop running functions (inclusive)
    // runAtEveryLevel: function that takes an L.MarkerCluster as an argument that should be applied on every level
    // runAtBottomLevel: function that takes an L.MarkerCluster as an argument that should be applied at only the bottom level
    _recursively: function (boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel) {
      var childClusters = this._childClusters,
        zoom = this._zoom,
        i,
        c;
      if (zoomLevelToStart <= zoom) {
        if (runAtEveryLevel) {
          runAtEveryLevel(this);
        }
        if (runAtBottomLevel && zoom === zoomLevelToStop) {
          runAtBottomLevel(this);
        }
      }
      if (zoom < zoomLevelToStart || zoom < zoomLevelToStop) {
        for (i = childClusters.length - 1; i >= 0; i--) {
          c = childClusters[i];
          if (c._boundsNeedUpdate) {
            c._recalculateBounds();
          }
          if (boundsToApplyTo.intersects(c._bounds)) {
            c._recursively(boundsToApplyTo, zoomLevelToStart, zoomLevelToStop, runAtEveryLevel, runAtBottomLevel);
          }
        }
      }
    },
    //Returns true if we are the parent of only one cluster and that cluster is the same as us
    _isSingleParent: function () {
      //Don't need to check this._markers as the rest won't work if there are any
      return this._childClusters.length > 0 && this._childClusters[0]._childCount === this._childCount;
    }
  });

  /*
  * Extends L.Marker to include two extra methods: clusterHide and clusterShow.
  * 
  * They work as setOpacity(0) and setOpacity(1) respectively, but
  * don't overwrite the options.opacity
  * 
  */

  L.Marker.include({
    clusterHide: function () {
      var backup = this.options.opacity;
      this.setOpacity(0);
      this.options.opacity = backup;
      return this;
    },
    clusterShow: function () {
      return this.setOpacity(this.options.opacity);
    }
  });
  L.DistanceGrid = function (cellSize) {
    this._cellSize = cellSize;
    this._sqCellSize = cellSize * cellSize;
    this._grid = {};
    this._objectPoint = {};
  };
  L.DistanceGrid.prototype = {
    addObject: function (obj, point) {
      var x = this._getCoord(point.x),
        y = this._getCoord(point.y),
        grid = this._grid,
        row = grid[y] = grid[y] || {},
        cell = row[x] = row[x] || [],
        stamp = L.Util.stamp(obj);
      this._objectPoint[stamp] = point;
      cell.push(obj);
    },
    updateObject: function (obj, point) {
      this.removeObject(obj);
      this.addObject(obj, point);
    },
    //Returns true if the object was found
    removeObject: function (obj, point) {
      var x = this._getCoord(point.x),
        y = this._getCoord(point.y),
        grid = this._grid,
        row = grid[y] = grid[y] || {},
        cell = row[x] = row[x] || [],
        i,
        len;
      delete this._objectPoint[L.Util.stamp(obj)];
      for (i = 0, len = cell.length; i < len; i++) {
        if (cell[i] === obj) {
          cell.splice(i, 1);
          if (len === 1) {
            delete row[x];
          }
          return true;
        }
      }
    },
    eachObject: function (fn, context) {
      var i,
        j,
        k,
        len,
        row,
        cell,
        removed,
        grid = this._grid;
      for (i in grid) {
        row = grid[i];
        for (j in row) {
          cell = row[j];
          for (k = 0, len = cell.length; k < len; k++) {
            removed = fn.call(context, cell[k]);
            if (removed) {
              k--;
              len--;
            }
          }
        }
      }
    },
    getNearObject: function (point) {
      var x = this._getCoord(point.x),
        y = this._getCoord(point.y),
        i,
        j,
        k,
        row,
        cell,
        len,
        obj,
        dist,
        objectPoint = this._objectPoint,
        closestDistSq = this._sqCellSize,
        closest = null;
      for (i = y - 1; i <= y + 1; i++) {
        row = this._grid[i];
        if (row) {
          for (j = x - 1; j <= x + 1; j++) {
            cell = row[j];
            if (cell) {
              for (k = 0, len = cell.length; k < len; k++) {
                obj = cell[k];
                dist = this._sqDist(objectPoint[L.Util.stamp(obj)], point);
                if (dist < closestDistSq || dist <= closestDistSq && closest === null) {
                  closestDistSq = dist;
                  closest = obj;
                }
              }
            }
          }
        }
      }
      return closest;
    },
    _getCoord: function (x) {
      var coord = Math.floor(x / this._cellSize);
      return isFinite(coord) ? coord : x;
    },
    _sqDist: function (p, p2) {
      var dx = p2.x - p.x,
        dy = p2.y - p.y;
      return dx * dx + dy * dy;
    }
  };

  /* Copyright (c) 2012 the authors listed at the following URL, and/or
  the authors of referenced articles or incorporated external code:
  http://en.literateprograms.org/Quickhull_(Javascript)?action=history&offset=20120410175256
  	Permission is hereby granted, free of charge, to any person obtaining
  a copy of this software and associated documentation files (the
  "Software"), to deal in the Software without restriction, including
  without limitation the rights to use, copy, modify, merge, publish,
  distribute, sublicense, and/or sell copies of the Software, and to
  permit persons to whom the Software is furnished to do so, subject to
  the following conditions:
  	The above copyright notice and this permission notice shall be
  included in all copies or substantial portions of the Software.
  	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  	Retrieved from: http://en.literateprograms.org/Quickhull_(Javascript)?oldid=18434
  */

  (function () {
    L.QuickHull = {
      /*
       * @param {Object} cpt a point to be measured from the baseline
       * @param {Array} bl the baseline, as represented by a two-element
       *   array of latlng objects.
       * @returns {Number} an approximate distance measure
       */
      getDistant: function (cpt, bl) {
        var vY = bl[1].lat - bl[0].lat,
          vX = bl[0].lng - bl[1].lng;
        return vX * (cpt.lat - bl[0].lat) + vY * (cpt.lng - bl[0].lng);
      },
      /*
       * @param {Array} baseLine a two-element array of latlng objects
       *   representing the baseline to project from
       * @param {Array} latLngs an array of latlng objects
       * @returns {Object} the maximum point and all new points to stay
       *   in consideration for the hull.
       */
      findMostDistantPointFromBaseLine: function (baseLine, latLngs) {
        var maxD = 0,
          maxPt = null,
          newPoints = [],
          i,
          pt,
          d;
        for (i = latLngs.length - 1; i >= 0; i--) {
          pt = latLngs[i];
          d = this.getDistant(pt, baseLine);
          if (d > 0) {
            newPoints.push(pt);
          } else {
            continue;
          }
          if (d > maxD) {
            maxD = d;
            maxPt = pt;
          }
        }
        return {
          maxPoint: maxPt,
          newPoints: newPoints
        };
      },
      /*
       * Given a baseline, compute the convex hull of latLngs as an array
       * of latLngs.
       *
       * @param {Array} latLngs
       * @returns {Array}
       */
      buildConvexHull: function (baseLine, latLngs) {
        var convexHullBaseLines = [],
          t = this.findMostDistantPointFromBaseLine(baseLine, latLngs);
        if (t.maxPoint) {
          // if there is still a point "outside" the base line
          convexHullBaseLines = convexHullBaseLines.concat(this.buildConvexHull([baseLine[0], t.maxPoint], t.newPoints));
          convexHullBaseLines = convexHullBaseLines.concat(this.buildConvexHull([t.maxPoint, baseLine[1]], t.newPoints));
          return convexHullBaseLines;
        } else {
          // if there is no more point "outside" the base line, the current base line is part of the convex hull
          return [baseLine[0]];
        }
      },
      /*
       * Given an array of latlngs, compute a convex hull as an array
       * of latlngs
       *
       * @param {Array} latLngs
       * @returns {Array}
       */
      getConvexHull: function (latLngs) {
        // find first baseline
        var maxLat = false,
          minLat = false,
          maxLng = false,
          minLng = false,
          maxLatPt = null,
          minLatPt = null,
          maxLngPt = null,
          minLngPt = null,
          maxPt = null,
          minPt = null,
          i;
        for (i = latLngs.length - 1; i >= 0; i--) {
          var pt = latLngs[i];
          if (maxLat === false || pt.lat > maxLat) {
            maxLatPt = pt;
            maxLat = pt.lat;
          }
          if (minLat === false || pt.lat < minLat) {
            minLatPt = pt;
            minLat = pt.lat;
          }
          if (maxLng === false || pt.lng > maxLng) {
            maxLngPt = pt;
            maxLng = pt.lng;
          }
          if (minLng === false || pt.lng < minLng) {
            minLngPt = pt;
            minLng = pt.lng;
          }
        }
        if (minLat !== maxLat) {
          minPt = minLatPt;
          maxPt = maxLatPt;
        } else {
          minPt = minLngPt;
          maxPt = maxLngPt;
        }
        var ch = [].concat(this.buildConvexHull([minPt, maxPt], latLngs), this.buildConvexHull([maxPt, minPt], latLngs));
        return ch;
      }
    };
  })();
  L.MarkerCluster.include({
    getConvexHull: function () {
      var childMarkers = this.getAllChildMarkers(),
        points = [],
        p,
        i;
      for (i = childMarkers.length - 1; i >= 0; i--) {
        p = childMarkers[i].getLatLng();
        points.push(p);
      }
      return L.QuickHull.getConvexHull(points);
    }
  });

  //This code is 100% based on https://github.com/jawj/OverlappingMarkerSpiderfier-Leaflet
  //Huge thanks to jawj for implementing it first to make my job easy :-)

  L.MarkerCluster.include({
    _2PI: Math.PI * 2,
    _circleFootSeparation: 25,
    //related to circumference of circle
    _circleStartAngle: 0,
    _spiralFootSeparation: 28,
    //related to size of spiral (experiment!)
    _spiralLengthStart: 11,
    _spiralLengthFactor: 5,
    _circleSpiralSwitchover: 9,
    //show spiral instead of circle from this marker count upwards.
    // 0 -> always spiral; Infinity -> always circle

    spiderfy: function () {
      if (this._group._spiderfied === this || this._group._inZoomAnimation) {
        return;
      }
      var childMarkers = this.getAllChildMarkers(null, true),
        group = this._group,
        map = group._map,
        center = map.latLngToLayerPoint(this._latlng),
        positions;
      this._group._unspiderfy();
      this._group._spiderfied = this;

      //TODO Maybe: childMarkers order by distance to center

      if (this._group.options.spiderfyShapePositions) {
        positions = this._group.options.spiderfyShapePositions(childMarkers.length, center);
      } else if (childMarkers.length >= this._circleSpiralSwitchover) {
        positions = this._generatePointsSpiral(childMarkers.length, center);
      } else {
        center.y += 10; // Otherwise circles look wrong => hack for standard blue icon, renders differently for other icons.
        positions = this._generatePointsCircle(childMarkers.length, center);
      }
      this._animationSpiderfy(childMarkers, positions);
    },
    unspiderfy: function (zoomDetails) {
      /// <param Name="zoomDetails">Argument from zoomanim if being called in a zoom animation or null otherwise</param>
      if (this._group._inZoomAnimation) {
        return;
      }
      this._animationUnspiderfy(zoomDetails);
      this._group._spiderfied = null;
    },
    _generatePointsCircle: function (count, centerPt) {
      var circumference = this._group.options.spiderfyDistanceMultiplier * this._circleFootSeparation * (2 + count),
        legLength = circumference / this._2PI,
        //radius from circumference
        angleStep = this._2PI / count,
        res = [],
        i,
        angle;
      legLength = Math.max(legLength, 35); // Minimum distance to get outside the cluster icon.

      res.length = count;
      for (i = 0; i < count; i++) {
        // Clockwise, like spiral.
        angle = this._circleStartAngle + i * angleStep;
        res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
      }
      return res;
    },
    _generatePointsSpiral: function (count, centerPt) {
      var spiderfyDistanceMultiplier = this._group.options.spiderfyDistanceMultiplier,
        legLength = spiderfyDistanceMultiplier * this._spiralLengthStart,
        separation = spiderfyDistanceMultiplier * this._spiralFootSeparation,
        lengthFactor = spiderfyDistanceMultiplier * this._spiralLengthFactor * this._2PI,
        angle = 0,
        res = [],
        i;
      res.length = count;

      // Higher index, closer position to cluster center.
      for (i = count; i >= 0; i--) {
        // Skip the first position, so that we are already farther from center and we avoid
        // being under the default cluster icon (especially important for Circle Markers).
        if (i < count) {
          res[i] = new L.Point(centerPt.x + legLength * Math.cos(angle), centerPt.y + legLength * Math.sin(angle))._round();
        }
        angle += separation / legLength + i * 0.0005;
        legLength += lengthFactor / angle;
      }
      return res;
    },
    _noanimationUnspiderfy: function () {
      var group = this._group,
        map = group._map,
        fg = group._featureGroup,
        childMarkers = this.getAllChildMarkers(null, true),
        m,
        i;
      group._ignoreMove = true;
      this.setOpacity(1);
      for (i = childMarkers.length - 1; i >= 0; i--) {
        m = childMarkers[i];
        fg.removeLayer(m);
        if (m._preSpiderfyLatlng) {
          m.setLatLng(m._preSpiderfyLatlng);
          delete m._preSpiderfyLatlng;
        }
        if (m.setZIndexOffset) {
          m.setZIndexOffset(0);
        }
        if (m._spiderLeg) {
          map.removeLayer(m._spiderLeg);
          delete m._spiderLeg;
        }
      }
      group.fire('unspiderfied', {
        cluster: this,
        markers: childMarkers
      });
      group._ignoreMove = false;
      group._spiderfied = null;
    }
  });

  //Non Animated versions of everything
  L.MarkerClusterNonAnimated = L.MarkerCluster.extend({
    _animationSpiderfy: function (childMarkers, positions) {
      var group = this._group,
        map = group._map,
        fg = group._featureGroup,
        legOptions = this._group.options.spiderLegPolylineOptions,
        i,
        m,
        leg,
        newPos;
      group._ignoreMove = true;

      // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
      // The reverse order trick no longer improves performance on modern browsers.
      for (i = 0; i < childMarkers.length; i++) {
        newPos = map.layerPointToLatLng(positions[i]);
        m = childMarkers[i];

        // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
        leg = new L.Polyline([this._latlng, newPos], legOptions);
        map.addLayer(leg);
        m._spiderLeg = leg;

        // Now add the marker.
        m._preSpiderfyLatlng = m._latlng;
        m.setLatLng(newPos);
        if (m.setZIndexOffset) {
          m.setZIndexOffset(1000000); //Make these appear on top of EVERYTHING
        }
        fg.addLayer(m);
      }
      this.setOpacity(0.3);
      group._ignoreMove = false;
      group.fire('spiderfied', {
        cluster: this,
        markers: childMarkers
      });
    },
    _animationUnspiderfy: function () {
      this._noanimationUnspiderfy();
    }
  });

  //Animated versions here
  L.MarkerCluster.include({
    _animationSpiderfy: function (childMarkers, positions) {
      var me = this,
        group = this._group,
        map = group._map,
        fg = group._featureGroup,
        thisLayerLatLng = this._latlng,
        thisLayerPos = map.latLngToLayerPoint(thisLayerLatLng),
        svg = L.Path.SVG,
        legOptions = L.extend({}, this._group.options.spiderLegPolylineOptions),
        // Copy the options so that we can modify them for animation.
        finalLegOpacity = legOptions.opacity,
        i,
        m,
        leg,
        legPath,
        legLength,
        newPos;
      if (finalLegOpacity === undefined) {
        finalLegOpacity = L.MarkerClusterGroup.prototype.options.spiderLegPolylineOptions.opacity;
      }
      if (svg) {
        // If the initial opacity of the spider leg is not 0 then it appears before the animation starts.
        legOptions.opacity = 0;

        // Add the class for CSS transitions.
        legOptions.className = (legOptions.className || '') + ' leaflet-cluster-spider-leg';
      } else {
        // Make sure we have a defined opacity.
        legOptions.opacity = finalLegOpacity;
      }
      group._ignoreMove = true;

      // Add markers and spider legs to map, hidden at our center point.
      // Traverse in ascending order to make sure that inner circleMarkers are on top of further legs. Normal markers are re-ordered by newPosition.
      // The reverse order trick no longer improves performance on modern browsers.
      for (i = 0; i < childMarkers.length; i++) {
        m = childMarkers[i];
        newPos = map.layerPointToLatLng(positions[i]);

        // Add the leg before the marker, so that in case the latter is a circleMarker, the leg is behind it.
        leg = new L.Polyline([thisLayerLatLng, newPos], legOptions);
        map.addLayer(leg);
        m._spiderLeg = leg;

        // Explanations: https://jakearchibald.com/2013/animated-line-drawing-svg/
        // In our case the transition property is declared in the CSS file.
        if (svg) {
          legPath = leg._path;
          legLength = legPath.getTotalLength() + 0.1; // Need a small extra length to avoid remaining dot in Firefox.
          legPath.style.strokeDasharray = legLength; // Just 1 length is enough, it will be duplicated.
          legPath.style.strokeDashoffset = legLength;
        }

        // If it is a marker, add it now and we'll animate it out
        if (m.setZIndexOffset) {
          m.setZIndexOffset(1000000); // Make normal markers appear on top of EVERYTHING
        }
        if (m.clusterHide) {
          m.clusterHide();
        }

        // Vectors just get immediately added
        fg.addLayer(m);
        if (m._setPos) {
          m._setPos(thisLayerPos);
        }
      }
      group._forceLayout();
      group._animationStart();

      // Reveal markers and spider legs.
      for (i = childMarkers.length - 1; i >= 0; i--) {
        newPos = map.layerPointToLatLng(positions[i]);
        m = childMarkers[i];

        //Move marker to new position
        m._preSpiderfyLatlng = m._latlng;
        m.setLatLng(newPos);
        if (m.clusterShow) {
          m.clusterShow();
        }

        // Animate leg (animation is actually delegated to CSS transition).
        if (svg) {
          leg = m._spiderLeg;
          legPath = leg._path;
          legPath.style.strokeDashoffset = 0;
          //legPath.style.strokeOpacity = finalLegOpacity;
          leg.setStyle({
            opacity: finalLegOpacity
          });
        }
      }
      this.setOpacity(0.3);
      group._ignoreMove = false;
      setTimeout(function () {
        group._animationEnd();
        group.fire('spiderfied', {
          cluster: me,
          markers: childMarkers
        });
      }, 200);
    },
    _animationUnspiderfy: function (zoomDetails) {
      var me = this,
        group = this._group,
        map = group._map,
        fg = group._featureGroup,
        thisLayerPos = zoomDetails ? map._latLngToNewLayerPoint(this._latlng, zoomDetails.zoom, zoomDetails.center) : map.latLngToLayerPoint(this._latlng),
        childMarkers = this.getAllChildMarkers(null, true),
        svg = L.Path.SVG,
        m,
        i,
        leg,
        legPath,
        legLength,
        nonAnimatable;
      group._ignoreMove = true;
      group._animationStart();

      //Make us visible and bring the child markers back in
      this.setOpacity(1);
      for (i = childMarkers.length - 1; i >= 0; i--) {
        m = childMarkers[i];

        //Marker was added to us after we were spiderfied
        if (!m._preSpiderfyLatlng) {
          continue;
        }

        //Close any popup on the marker first, otherwise setting the location of the marker will make the map scroll
        m.closePopup();

        //Fix up the location to the real one
        m.setLatLng(m._preSpiderfyLatlng);
        delete m._preSpiderfyLatlng;

        //Hack override the location to be our center
        nonAnimatable = true;
        if (m._setPos) {
          m._setPos(thisLayerPos);
          nonAnimatable = false;
        }
        if (m.clusterHide) {
          m.clusterHide();
          nonAnimatable = false;
        }
        if (nonAnimatable) {
          fg.removeLayer(m);
        }

        // Animate the spider leg back in (animation is actually delegated to CSS transition).
        if (svg) {
          leg = m._spiderLeg;
          legPath = leg._path;
          legLength = legPath.getTotalLength() + 0.1;
          legPath.style.strokeDashoffset = legLength;
          leg.setStyle({
            opacity: 0
          });
        }
      }
      group._ignoreMove = false;
      setTimeout(function () {
        //If we have only <= one child left then that marker will be shown on the map so don't remove it!
        var stillThereChildCount = 0;
        for (i = childMarkers.length - 1; i >= 0; i--) {
          m = childMarkers[i];
          if (m._spiderLeg) {
            stillThereChildCount++;
          }
        }
        for (i = childMarkers.length - 1; i >= 0; i--) {
          m = childMarkers[i];
          if (!m._spiderLeg) {
            //Has already been unspiderfied
            continue;
          }
          if (m.clusterShow) {
            m.clusterShow();
          }
          if (m.setZIndexOffset) {
            m.setZIndexOffset(0);
          }
          if (stillThereChildCount > 1) {
            fg.removeLayer(m);
          }
          map.removeLayer(m._spiderLeg);
          delete m._spiderLeg;
        }
        group._animationEnd();
        group.fire('unspiderfied', {
          cluster: me,
          markers: childMarkers
        });
      }, 200);
    }
  });
  L.MarkerClusterGroup.include({
    //The MarkerCluster currently spiderfied (if any)
    _spiderfied: null,
    unspiderfy: function () {
      this._unspiderfy.apply(this, arguments);
    },
    _spiderfierOnAdd: function () {
      this._map.on('click', this._unspiderfyWrapper, this);
      if (this._map.options.zoomAnimation) {
        this._map.on('zoomstart', this._unspiderfyZoomStart, this);
      }
      //Browsers without zoomAnimation or a big zoom don't fire zoomstart
      this._map.on('zoomend', this._noanimationUnspiderfy, this);
      if (!L.Browser.touch) {
        this._map.getRenderer(this);
        //Needs to happen in the pageload, not after, or animations don't work in webkit
        //  http://stackoverflow.com/questions/8455200/svg-animate-with-dynamically-added-elements
        //Disable on touch browsers as the animation messes up on a touch zoom and isn't very noticable
      }
    },
    _spiderfierOnRemove: function () {
      this._map.off('click', this._unspiderfyWrapper, this);
      this._map.off('zoomstart', this._unspiderfyZoomStart, this);
      this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
      this._map.off('zoomend', this._noanimationUnspiderfy, this);

      //Ensure that markers are back where they should be
      // Use no animation to avoid a sticky leaflet-cluster-anim class on mapPane
      this._noanimationUnspiderfy();
    },
    //On zoom start we add a zoomanim handler so that we are guaranteed to be last (after markers are animated)
    //This means we can define the animation they do rather than Markers doing an animation to their actual location
    _unspiderfyZoomStart: function () {
      if (!this._map) {
        //May have been removed from the map by a zoomEnd handler
        return;
      }
      this._map.on('zoomanim', this._unspiderfyZoomAnim, this);
    },
    _unspiderfyZoomAnim: function (zoomDetails) {
      //Wait until the first zoomanim after the user has finished touch-zooming before running the animation
      if (L.DomUtil.hasClass(this._map._mapPane, 'leaflet-touching')) {
        return;
      }
      this._map.off('zoomanim', this._unspiderfyZoomAnim, this);
      this._unspiderfy(zoomDetails);
    },
    _unspiderfyWrapper: function () {
      /// <summary>_unspiderfy but passes no arguments</summary>
      this._unspiderfy();
    },
    _unspiderfy: function (zoomDetails) {
      if (this._spiderfied) {
        this._spiderfied.unspiderfy(zoomDetails);
      }
    },
    _noanimationUnspiderfy: function () {
      if (this._spiderfied) {
        this._spiderfied._noanimationUnspiderfy();
      }
    },
    //If the given layer is currently being spiderfied then we unspiderfy it so it isn't on the map anymore etc
    _unspiderfyLayer: function (layer) {
      if (layer._spiderLeg) {
        this._featureGroup.removeLayer(layer);
        if (layer.clusterShow) {
          layer.clusterShow();
        }
        //Position will be fixed up immediately in _animationUnspiderfy
        if (layer.setZIndexOffset) {
          layer.setZIndexOffset(0);
        }
        this._map.removeLayer(layer._spiderLeg);
        delete layer._spiderLeg;
      }
    }
  });

  /**
   * Adds 1 public method to MCG and 1 to L.Marker to facilitate changing
   * markers' icon options and refreshing their icon and their parent clusters
   * accordingly (case where their iconCreateFunction uses data of childMarkers
   * to make up the cluster icon).
   */

  L.MarkerClusterGroup.include({
    /**
     * Updates the icon of all clusters which are parents of the given marker(s).
     * In singleMarkerMode, also updates the given marker(s) icon.
     * @param layers L.MarkerClusterGroup|L.LayerGroup|Array(L.Marker)|Map(L.Marker)|
     * L.MarkerCluster|L.Marker (optional) list of markers (or single marker) whose parent
     * clusters need to be updated. If not provided, retrieves all child markers of this.
     * @returns {L.MarkerClusterGroup}
     */
    refreshClusters: function (layers) {
      if (!layers) {
        layers = this._topClusterLevel.getAllChildMarkers();
      } else if (layers instanceof L.MarkerClusterGroup) {
        layers = layers._topClusterLevel.getAllChildMarkers();
      } else if (layers instanceof L.LayerGroup) {
        layers = layers._layers;
      } else if (layers instanceof L.MarkerCluster) {
        layers = layers.getAllChildMarkers();
      } else if (layers instanceof L.Marker) {
        layers = [layers];
      } // else: must be an Array(L.Marker)|Map(L.Marker)
      this._flagParentsIconsNeedUpdate(layers);
      this._refreshClustersIcons();

      // In case of singleMarkerMode, also re-draw the markers.
      if (this.options.singleMarkerMode) {
        this._refreshSingleMarkerModeMarkers(layers);
      }
      return this;
    },
    /**
     * Simply flags all parent clusters of the given markers as having a "dirty" icon.
     * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
     * @private
     */
    _flagParentsIconsNeedUpdate: function (layers) {
      var id, parent;

      // Assumes layers is an Array or an Object whose prototype is non-enumerable.
      for (id in layers) {
        // Flag parent clusters' icon as "dirty", all the way up.
        // Dumb process that flags multiple times upper parents, but still
        // much more efficient than trying to be smart and make short lists,
        // at least in the case of a hierarchy following a power law:
        // http://jsperf.com/flag-nodes-in-power-hierarchy/2
        parent = layers[id].__parent;
        while (parent) {
          parent._iconNeedsUpdate = true;
          parent = parent.__parent;
        }
      }
    },
    /**
     * Re-draws the icon of the supplied markers.
     * To be used in singleMarkerMode only.
     * @param layers Array(L.Marker)|Map(L.Marker) list of markers.
     * @private
     */
    _refreshSingleMarkerModeMarkers: function (layers) {
      var id, layer;
      for (id in layers) {
        layer = layers[id];

        // Make sure we do not override markers that do not belong to THIS group.
        if (this.hasLayer(layer)) {
          // Need to re-create the icon first, then re-draw the marker.
          layer.setIcon(this._overrideMarkerIcon(layer));
        }
      }
    }
  });
  L.Marker.include({
    /**
     * Updates the given options in the marker's icon and refreshes the marker.
     * @param options map object of icon options.
     * @param directlyRefreshClusters boolean (optional) true to trigger
     * MCG.refreshClustersOf() right away with this single marker.
     * @returns {L.Marker}
     */
    refreshIconOptions: function (options, directlyRefreshClusters) {
      var icon = this.options.icon;
      L.setOptions(icon, options);
      this.setIcon(icon);

      // Shortcut to refresh the associated MCG clusters right away.
      // To be used when refreshing a single marker.
      // Otherwise, better use MCG.refreshClusters() once at the end with
      // the list of modified markers.
      if (directlyRefreshClusters && this.__parent) {
        this.__parent._group.refreshClusters(this);
      }
      return this;
    }
  });
  exports.MarkerClusterGroup = MarkerClusterGroup;
  exports.MarkerCluster = MarkerCluster;
  Object.defineProperty(exports, '__esModule', {
    value: true
  });
});

/***/ }),

/***/ 67381:
/*!**************************************************!*\
  !*** ./node_modules/leaflet/dist/leaflet-src.js ***!
  \**************************************************/
/***/ (function(__unused_webpack_module, exports) {

/* @preserve
 * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com
 * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade
 */

(function (global, factory) {
   true ? factory(exports) : 0;
})(this, function (exports) {
  'use strict';

  var version = "1.9.4";

  /*
   * @namespace Util
   *
   * Various utility functions, used by Leaflet internally.
   */

  // @function extend(dest: Object, src?: Object): Object
  // Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.
  function extend(dest) {
    var i, j, len, src;
    for (j = 1, len = arguments.length; j < len; j++) {
      src = arguments[j];
      for (i in src) {
        dest[i] = src[i];
      }
    }
    return dest;
  }

  // @function create(proto: Object, properties?: Object): Object
  // Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
  var create$2 = Object.create || function () {
    function F() {}
    return function (proto) {
      F.prototype = proto;
      return new F();
    };
  }();

  // @function bind(fn: Function, …): Function
  // Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
  // Has a `L.bind()` shortcut.
  function bind(fn, obj) {
    var slice = Array.prototype.slice;
    if (fn.bind) {
      return fn.bind.apply(fn, slice.call(arguments, 1));
    }
    var args = slice.call(arguments, 2);
    return function () {
      return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);
    };
  }

  // @property lastId: Number
  // Last unique ID used by [`stamp()`](#util-stamp)
  var lastId = 0;

  // @function stamp(obj: Object): Number
  // Returns the unique ID of an object, assigning it one if it doesn't have it.
  function stamp(obj) {
    if (!('_leaflet_id' in obj)) {
      obj['_leaflet_id'] = ++lastId;
    }
    return obj._leaflet_id;
  }

  // @function throttle(fn: Function, time: Number, context: Object): Function
  // Returns a function which executes function `fn` with the given scope `context`
  // (so that the `this` keyword refers to `context` inside `fn`'s code). The function
  // `fn` will be called no more than one time per given amount of `time`. The arguments
  // received by the bound function will be any arguments passed when binding the
  // function, followed by any arguments passed when invoking the bound function.
  // Has an `L.throttle` shortcut.
  function throttle(fn, time, context) {
    var lock, args, wrapperFn, later;
    later = function () {
      // reset lock and call if queued
      lock = false;
      if (args) {
        wrapperFn.apply(context, args);
        args = false;
      }
    };
    wrapperFn = function () {
      if (lock) {
        // called too soon, queue to call later
        args = arguments;
      } else {
        // call and lock until later
        fn.apply(context, arguments);
        setTimeout(later, time);
        lock = true;
      }
    };
    return wrapperFn;
  }

  // @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number
  // Returns the number `num` modulo `range` in such a way so it lies within
  // `range[0]` and `range[1]`. The returned value will be always smaller than
  // `range[1]` unless `includeMax` is set to `true`.
  function wrapNum(x, range, includeMax) {
    var max = range[1],
      min = range[0],
      d = max - min;
    return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
  }

  // @function falseFn(): Function
  // Returns a function which always returns `false`.
  function falseFn() {
    return false;
  }

  // @function formatNum(num: Number, precision?: Number|false): Number
  // Returns the number `num` rounded with specified `precision`.
  // The default `precision` value is 6 decimal places.
  // `false` can be passed to skip any processing (can be useful to avoid round-off errors).
  function formatNum(num, precision) {
    if (precision === false) {
      return num;
    }
    var pow = Math.pow(10, precision === undefined ? 6 : precision);
    return Math.round(num * pow) / pow;
  }

  // @function trim(str: String): String
  // Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
  function trim(str) {
    return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
  }

  // @function splitWords(str: String): String[]
  // Trims and splits the string on whitespace and returns the array of parts.
  function splitWords(str) {
    return trim(str).split(/\s+/);
  }

  // @function setOptions(obj: Object, options: Object): Object
  // Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.
  function setOptions(obj, options) {
    if (!Object.prototype.hasOwnProperty.call(obj, 'options')) {
      obj.options = obj.options ? create$2(obj.options) : {};
    }
    for (var i in options) {
      obj.options[i] = options[i];
    }
    return obj.options;
  }

  // @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String
  // Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}`
  // translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will
  // be appended at the end. If `uppercase` is `true`, the parameter names will
  // be uppercased (e.g. `'?A=foo&B=bar'`)
  function getParamString(obj, existingUrl, uppercase) {
    var params = [];
    for (var i in obj) {
      params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
    }
    return (!existingUrl || existingUrl.indexOf('?') === -1 ? '?' : '&') + params.join('&');
  }
  var templateRe = /\{ *([\w_ -]+) *\}/g;

  // @function template(str: String, data: Object): String
  // Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`
  // and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string
  // `('Hello foo, bar')`. You can also specify functions instead of strings for
  // data values — they will be evaluated passing `data` as an argument.
  function template(str, data) {
    return str.replace(templateRe, function (str, key) {
      var value = data[key];
      if (value === undefined) {
        throw new Error('No value provided for variable ' + str);
      } else if (typeof value === 'function') {
        value = value(data);
      }
      return value;
    });
  }

  // @function isArray(obj): Boolean
  // Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)
  var isArray = Array.isArray || function (obj) {
    return Object.prototype.toString.call(obj) === '[object Array]';
  };

  // @function indexOf(array: Array, el: Object): Number
  // Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
  function indexOf(array, el) {
    for (var i = 0; i < array.length; i++) {
      if (array[i] === el) {
        return i;
      }
    }
    return -1;
  }

  // @property emptyImageUrl: String
  // Data URI string containing a base64-encoded empty GIF image.
  // Used as a hack to free memory from unused images on WebKit-powered
  // mobile devices (by setting image `src` to this string).
  var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';

  // inspired by https://paulirish.com/2011/requestanimationframe-for-smart-animating/

  function getPrefixed(name) {
    return window['webkit' + name] || window['moz' + name] || window['ms' + name];
  }
  var lastTime = 0;

  // fallback for IE 7-8
  function timeoutDefer(fn) {
    var time = +new Date(),
      timeToCall = Math.max(0, 16 - (time - lastTime));
    lastTime = time + timeToCall;
    return window.setTimeout(fn, timeToCall);
  }
  var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;
  var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') || getPrefixed('CancelRequestAnimationFrame') || function (id) {
    window.clearTimeout(id);
  };

  // @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number
  // Schedules `fn` to be executed when the browser repaints. `fn` is bound to
  // `context` if given. When `immediate` is set, `fn` is called immediately if
  // the browser doesn't have native support for
  // [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),
  // otherwise it's delayed. Returns a request ID that can be used to cancel the request.
  function requestAnimFrame(fn, context, immediate) {
    if (immediate && requestFn === timeoutDefer) {
      fn.call(context);
    } else {
      return requestFn.call(window, bind(fn, context));
    }
  }

  // @function cancelAnimFrame(id: Number): undefined
  // Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).
  function cancelAnimFrame(id) {
    if (id) {
      cancelFn.call(window, id);
    }
  }
  var Util = {
    __proto__: null,
    extend: extend,
    create: create$2,
    bind: bind,
    get lastId() {
      return lastId;
    },
    stamp: stamp,
    throttle: throttle,
    wrapNum: wrapNum,
    falseFn: falseFn,
    formatNum: formatNum,
    trim: trim,
    splitWords: splitWords,
    setOptions: setOptions,
    getParamString: getParamString,
    template: template,
    isArray: isArray,
    indexOf: indexOf,
    emptyImageUrl: emptyImageUrl,
    requestFn: requestFn,
    cancelFn: cancelFn,
    requestAnimFrame: requestAnimFrame,
    cancelAnimFrame: cancelAnimFrame
  };

  // @class Class
  // @aka L.Class

  // @section
  // @uninheritable

  // Thanks to John Resig and Dean Edwards for inspiration!

  function Class() {}
  Class.extend = function (props) {
    // @function extend(props: Object): Function
    // [Extends the current class](#class-inheritance) given the properties to be included.
    // Returns a Javascript function that is a class constructor (to be called with `new`).
    var NewClass = function () {
      setOptions(this);

      // call the constructor
      if (this.initialize) {
        this.initialize.apply(this, arguments);
      }

      // call all constructor hooks
      this.callInitHooks();
    };
    var parentProto = NewClass.__super__ = this.prototype;
    var proto = create$2(parentProto);
    proto.constructor = NewClass;
    NewClass.prototype = proto;

    // inherit parent's statics
    for (var i in this) {
      if (Object.prototype.hasOwnProperty.call(this, i) && i !== 'prototype' && i !== '__super__') {
        NewClass[i] = this[i];
      }
    }

    // mix static properties into the class
    if (props.statics) {
      extend(NewClass, props.statics);
    }

    // mix includes into the prototype
    if (props.includes) {
      checkDeprecatedMixinEvents(props.includes);
      extend.apply(null, [proto].concat(props.includes));
    }

    // mix given properties into the prototype
    extend(proto, props);
    delete proto.statics;
    delete proto.includes;

    // merge options
    if (proto.options) {
      proto.options = parentProto.options ? create$2(parentProto.options) : {};
      extend(proto.options, props.options);
    }
    proto._initHooks = [];

    // add method for calling all hooks
    proto.callInitHooks = function () {
      if (this._initHooksCalled) {
        return;
      }
      if (parentProto.callInitHooks) {
        parentProto.callInitHooks.call(this);
      }
      this._initHooksCalled = true;
      for (var i = 0, len = proto._initHooks.length; i < len; i++) {
        proto._initHooks[i].call(this);
      }
    };
    return NewClass;
  };

  // @function include(properties: Object): this
  // [Includes a mixin](#class-includes) into the current class.
  Class.include = function (props) {
    var parentOptions = this.prototype.options;
    extend(this.prototype, props);
    if (props.options) {
      this.prototype.options = parentOptions;
      this.mergeOptions(props.options);
    }
    return this;
  };

  // @function mergeOptions(options: Object): this
  // [Merges `options`](#class-options) into the defaults of the class.
  Class.mergeOptions = function (options) {
    extend(this.prototype.options, options);
    return this;
  };

  // @function addInitHook(fn: Function): this
  // Adds a [constructor hook](#class-constructor-hooks) to the class.
  Class.addInitHook = function (fn) {
    // (Function) || (String, args...)
    var args = Array.prototype.slice.call(arguments, 1);
    var init = typeof fn === 'function' ? fn : function () {
      this[fn].apply(this, args);
    };
    this.prototype._initHooks = this.prototype._initHooks || [];
    this.prototype._initHooks.push(init);
    return this;
  };
  function checkDeprecatedMixinEvents(includes) {
    /* global L: true */
    if (typeof L === 'undefined' || !L || !L.Mixin) {
      return;
    }
    includes = isArray(includes) ? includes : [includes];
    for (var i = 0; i < includes.length; i++) {
      if (includes[i] === L.Mixin.Events) {
        console.warn('Deprecated include of L.Mixin.Events: ' + 'this property will be removed in future releases, ' + 'please inherit from L.Evented instead.', new Error().stack);
      }
    }
  }

  /*
   * @class Evented
   * @aka L.Evented
   * @inherits Class
   *
   * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).
   *
   * @example
   *
   * ```js
   * map.on('click', function(e) {
   * 	alert(e.latlng);
   * } );
   * ```
   *
   * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:
   *
   * ```js
   * function onClick(e) { ... }
   *
   * map.on('click', onClick);
   * map.off('click', onClick);
   * ```
   */

  var Events = {
    /* @method on(type: String, fn: Function, context?: Object): this
     * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).
     *
     * @alternative
     * @method on(eventMap: Object): this
     * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
     */
    on: function (types, fn, context) {
      // types can be a map of types/handlers
      if (typeof types === 'object') {
        for (var type in types) {
          // we don't process space-separated events here for performance;
          // it's a hot path since Layer uses the on(obj) syntax
          this._on(type, types[type], fn);
        }
      } else {
        // types can be a string of space-separated words
        types = splitWords(types);
        for (var i = 0, len = types.length; i < len; i++) {
          this._on(types[i], fn, context);
        }
      }
      return this;
    },
    /* @method off(type: String, fn?: Function, context?: Object): this
     * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.
     *
     * @alternative
     * @method off(eventMap: Object): this
     * Removes a set of type/listener pairs.
     *
     * @alternative
     * @method off: this
     * Removes all listeners to all events on the object. This includes implicitly attached events.
     */
    off: function (types, fn, context) {
      if (!arguments.length) {
        // clear all listeners if called without arguments
        delete this._events;
      } else if (typeof types === 'object') {
        for (var type in types) {
          this._off(type, types[type], fn);
        }
      } else {
        types = splitWords(types);
        var removeAll = arguments.length === 1;
        for (var i = 0, len = types.length; i < len; i++) {
          if (removeAll) {
            this._off(types[i]);
          } else {
            this._off(types[i], fn, context);
          }
        }
      }
      return this;
    },
    // attach listener (without syntactic sugar now)
    _on: function (type, fn, context, _once) {
      if (typeof fn !== 'function') {
        console.warn('wrong listener type: ' + typeof fn);
        return;
      }

      // check if fn already there
      if (this._listens(type, fn, context) !== false) {
        return;
      }
      if (context === this) {
        // Less memory footprint.
        context = undefined;
      }
      var newListener = {
        fn: fn,
        ctx: context
      };
      if (_once) {
        newListener.once = true;
      }
      this._events = this._events || {};
      this._events[type] = this._events[type] || [];
      this._events[type].push(newListener);
    },
    _off: function (type, fn, context) {
      var listeners, i, len;
      if (!this._events) {
        return;
      }
      listeners = this._events[type];
      if (!listeners) {
        return;
      }
      if (arguments.length === 1) {
        // remove all
        if (this._firingCount) {
          // Set all removed listeners to noop
          // so they are not called if remove happens in fire
          for (i = 0, len = listeners.length; i < len; i++) {
            listeners[i].fn = falseFn;
          }
        }
        // clear all listeners for a type if function isn't specified
        delete this._events[type];
        return;
      }
      if (typeof fn !== 'function') {
        console.warn('wrong listener type: ' + typeof fn);
        return;
      }

      // find fn and remove it
      var index = this._listens(type, fn, context);
      if (index !== false) {
        var listener = listeners[index];
        if (this._firingCount) {
          // set the removed listener to noop so that's not called if remove happens in fire
          listener.fn = falseFn;

          /* copy array in case events are being fired */
          this._events[type] = listeners = listeners.slice();
        }
        listeners.splice(index, 1);
      }
    },
    // @method fire(type: String, data?: Object, propagate?: Boolean): this
    // Fires an event of the specified type. You can optionally provide a data
    // object — the first argument of the listener function will contain its
    // properties. The event can optionally be propagated to event parents.
    fire: function (type, data, propagate) {
      if (!this.listens(type, propagate)) {
        return this;
      }
      var event = extend({}, data, {
        type: type,
        target: this,
        sourceTarget: data && data.sourceTarget || this
      });
      if (this._events) {
        var listeners = this._events[type];
        if (listeners) {
          this._firingCount = this._firingCount + 1 || 1;
          for (var i = 0, len = listeners.length; i < len; i++) {
            var l = listeners[i];
            // off overwrites l.fn, so we need to copy fn to a var
            var fn = l.fn;
            if (l.once) {
              this.off(type, fn, l.ctx);
            }
            fn.call(l.ctx || this, event);
          }
          this._firingCount--;
        }
      }
      if (propagate) {
        // propagate the event to parents (set with addEventParent)
        this._propagateEvent(event);
      }
      return this;
    },
    // @method listens(type: String, propagate?: Boolean): Boolean
    // @method listens(type: String, fn: Function, context?: Object, propagate?: Boolean): Boolean
    // Returns `true` if a particular event type has any listeners attached to it.
    // The verification can optionally be propagated, it will return `true` if parents have the listener attached to it.
    listens: function (type, fn, context, propagate) {
      if (typeof type !== 'string') {
        console.warn('"string" type argument expected');
      }

      // we don't overwrite the input `fn` value, because we need to use it for propagation
      var _fn = fn;
      if (typeof fn !== 'function') {
        propagate = !!fn;
        _fn = undefined;
        context = undefined;
      }
      var listeners = this._events && this._events[type];
      if (listeners && listeners.length) {
        if (this._listens(type, _fn, context) !== false) {
          return true;
        }
      }
      if (propagate) {
        // also check parents for listeners if event propagates
        for (var id in this._eventParents) {
          if (this._eventParents[id].listens(type, fn, context, propagate)) {
            return true;
          }
        }
      }
      return false;
    },
    // returns the index (number) or false
    _listens: function (type, fn, context) {
      if (!this._events) {
        return false;
      }
      var listeners = this._events[type] || [];
      if (!fn) {
        return !!listeners.length;
      }
      if (context === this) {
        // Less memory footprint.
        context = undefined;
      }
      for (var i = 0, len = listeners.length; i < len; i++) {
        if (listeners[i].fn === fn && listeners[i].ctx === context) {
          return i;
        }
      }
      return false;
    },
    // @method once(…): this
    // Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.
    once: function (types, fn, context) {
      // types can be a map of types/handlers
      if (typeof types === 'object') {
        for (var type in types) {
          // we don't process space-separated events here for performance;
          // it's a hot path since Layer uses the on(obj) syntax
          this._on(type, types[type], fn, true);
        }
      } else {
        // types can be a string of space-separated words
        types = splitWords(types);
        for (var i = 0, len = types.length; i < len; i++) {
          this._on(types[i], fn, context, true);
        }
      }
      return this;
    },
    // @method addEventParent(obj: Evented): this
    // Adds an event parent - an `Evented` that will receive propagated events
    addEventParent: function (obj) {
      this._eventParents = this._eventParents || {};
      this._eventParents[stamp(obj)] = obj;
      return this;
    },
    // @method removeEventParent(obj: Evented): this
    // Removes an event parent, so it will stop receiving propagated events
    removeEventParent: function (obj) {
      if (this._eventParents) {
        delete this._eventParents[stamp(obj)];
      }
      return this;
    },
    _propagateEvent: function (e) {
      for (var id in this._eventParents) {
        this._eventParents[id].fire(e.type, extend({
          layer: e.target,
          propagatedFrom: e.target
        }, e), true);
      }
    }
  };

  // aliases; we should ditch those eventually

  // @method addEventListener(…): this
  // Alias to [`on(…)`](#evented-on)
  Events.addEventListener = Events.on;

  // @method removeEventListener(…): this
  // Alias to [`off(…)`](#evented-off)

  // @method clearAllEventListeners(…): this
  // Alias to [`off()`](#evented-off)
  Events.removeEventListener = Events.clearAllEventListeners = Events.off;

  // @method addOneTimeEventListener(…): this
  // Alias to [`once(…)`](#evented-once)
  Events.addOneTimeEventListener = Events.once;

  // @method fireEvent(…): this
  // Alias to [`fire(…)`](#evented-fire)
  Events.fireEvent = Events.fire;

  // @method hasEventListeners(…): Boolean
  // Alias to [`listens(…)`](#evented-listens)
  Events.hasEventListeners = Events.listens;
  var Evented = Class.extend(Events);

  /*
   * @class Point
   * @aka L.Point
   *
   * Represents a point with `x` and `y` coordinates in pixels.
   *
   * @example
   *
   * ```js
   * var point = L.point(200, 300);
   * ```
   *
   * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:
   *
   * ```js
   * map.panBy([200, 300]);
   * map.panBy(L.point(200, 300));
   * ```
   *
   * Note that `Point` does not inherit from Leaflet's `Class` object,
   * which means new classes can't inherit from it, and new methods
   * can't be added to it with the `include` function.
   */

  function Point(x, y, round) {
    // @property x: Number; The `x` coordinate of the point
    this.x = round ? Math.round(x) : x;
    // @property y: Number; The `y` coordinate of the point
    this.y = round ? Math.round(y) : y;
  }
  var trunc = Math.trunc || function (v) {
    return v > 0 ? Math.floor(v) : Math.ceil(v);
  };
  Point.prototype = {
    // @method clone(): Point
    // Returns a copy of the current point.
    clone: function () {
      return new Point(this.x, this.y);
    },
    // @method add(otherPoint: Point): Point
    // Returns the result of addition of the current and the given points.
    add: function (point) {
      // non-destructive, returns a new point
      return this.clone()._add(toPoint(point));
    },
    _add: function (point) {
      // destructive, used directly for performance in situations where it's safe to modify existing point
      this.x += point.x;
      this.y += point.y;
      return this;
    },
    // @method subtract(otherPoint: Point): Point
    // Returns the result of subtraction of the given point from the current.
    subtract: function (point) {
      return this.clone()._subtract(toPoint(point));
    },
    _subtract: function (point) {
      this.x -= point.x;
      this.y -= point.y;
      return this;
    },
    // @method divideBy(num: Number): Point
    // Returns the result of division of the current point by the given number.
    divideBy: function (num) {
      return this.clone()._divideBy(num);
    },
    _divideBy: function (num) {
      this.x /= num;
      this.y /= num;
      return this;
    },
    // @method multiplyBy(num: Number): Point
    // Returns the result of multiplication of the current point by the given number.
    multiplyBy: function (num) {
      return this.clone()._multiplyBy(num);
    },
    _multiplyBy: function (num) {
      this.x *= num;
      this.y *= num;
      return this;
    },
    // @method scaleBy(scale: Point): Point
    // Multiply each coordinate of the current point by each coordinate of
    // `scale`. In linear algebra terms, multiply the point by the
    // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)
    // defined by `scale`.
    scaleBy: function (point) {
      return new Point(this.x * point.x, this.y * point.y);
    },
    // @method unscaleBy(scale: Point): Point
    // Inverse of `scaleBy`. Divide each coordinate of the current point by
    // each coordinate of `scale`.
    unscaleBy: function (point) {
      return new Point(this.x / point.x, this.y / point.y);
    },
    // @method round(): Point
    // Returns a copy of the current point with rounded coordinates.
    round: function () {
      return this.clone()._round();
    },
    _round: function () {
      this.x = Math.round(this.x);
      this.y = Math.round(this.y);
      return this;
    },
    // @method floor(): Point
    // Returns a copy of the current point with floored coordinates (rounded down).
    floor: function () {
      return this.clone()._floor();
    },
    _floor: function () {
      this.x = Math.floor(this.x);
      this.y = Math.floor(this.y);
      return this;
    },
    // @method ceil(): Point
    // Returns a copy of the current point with ceiled coordinates (rounded up).
    ceil: function () {
      return this.clone()._ceil();
    },
    _ceil: function () {
      this.x = Math.ceil(this.x);
      this.y = Math.ceil(this.y);
      return this;
    },
    // @method trunc(): Point
    // Returns a copy of the current point with truncated coordinates (rounded towards zero).
    trunc: function () {
      return this.clone()._trunc();
    },
    _trunc: function () {
      this.x = trunc(this.x);
      this.y = trunc(this.y);
      return this;
    },
    // @method distanceTo(otherPoint: Point): Number
    // Returns the cartesian distance between the current and the given points.
    distanceTo: function (point) {
      point = toPoint(point);
      var x = point.x - this.x,
        y = point.y - this.y;
      return Math.sqrt(x * x + y * y);
    },
    // @method equals(otherPoint: Point): Boolean
    // Returns `true` if the given point has the same coordinates.
    equals: function (point) {
      point = toPoint(point);
      return point.x === this.x && point.y === this.y;
    },
    // @method contains(otherPoint: Point): Boolean
    // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).
    contains: function (point) {
      point = toPoint(point);
      return Math.abs(point.x) <= Math.abs(this.x) && Math.abs(point.y) <= Math.abs(this.y);
    },
    // @method toString(): String
    // Returns a string representation of the point for debugging purposes.
    toString: function () {
      return 'Point(' + formatNum(this.x) + ', ' + formatNum(this.y) + ')';
    }
  };

  // @factory L.point(x: Number, y: Number, round?: Boolean)
  // Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.

  // @alternative
  // @factory L.point(coords: Number[])
  // Expects an array of the form `[x, y]` instead.

  // @alternative
  // @factory L.point(coords: Object)
  // Expects a plain object of the form `{x: Number, y: Number}` instead.
  function toPoint(x, y, round) {
    if (x instanceof Point) {
      return x;
    }
    if (isArray(x)) {
      return new Point(x[0], x[1]);
    }
    if (x === undefined || x === null) {
      return x;
    }
    if (typeof x === 'object' && 'x' in x && 'y' in x) {
      return new Point(x.x, x.y);
    }
    return new Point(x, y, round);
  }

  /*
   * @class Bounds
   * @aka L.Bounds
   *
   * Represents a rectangular area in pixel coordinates.
   *
   * @example
   *
   * ```js
   * var p1 = L.point(10, 10),
   * p2 = L.point(40, 60),
   * bounds = L.bounds(p1, p2);
   * ```
   *
   * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
   *
   * ```js
   * otherBounds.intersects([[10, 10], [40, 60]]);
   * ```
   *
   * Note that `Bounds` does not inherit from Leaflet's `Class` object,
   * which means new classes can't inherit from it, and new methods
   * can't be added to it with the `include` function.
   */

  function Bounds(a, b) {
    if (!a) {
      return;
    }
    var points = b ? [a, b] : a;
    for (var i = 0, len = points.length; i < len; i++) {
      this.extend(points[i]);
    }
  }
  Bounds.prototype = {
    // @method extend(point: Point): this
    // Extends the bounds to contain the given point.

    // @alternative
    // @method extend(otherBounds: Bounds): this
    // Extend the bounds to contain the given bounds
    extend: function (obj) {
      var min2, max2;
      if (!obj) {
        return this;
      }
      if (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) {
        min2 = max2 = toPoint(obj);
      } else {
        obj = toBounds(obj);
        min2 = obj.min;
        max2 = obj.max;
        if (!min2 || !max2) {
          return this;
        }
      }

      // @property min: Point
      // The top left corner of the rectangle.
      // @property max: Point
      // The bottom right corner of the rectangle.
      if (!this.min && !this.max) {
        this.min = min2.clone();
        this.max = max2.clone();
      } else {
        this.min.x = Math.min(min2.x, this.min.x);
        this.max.x = Math.max(max2.x, this.max.x);
        this.min.y = Math.min(min2.y, this.min.y);
        this.max.y = Math.max(max2.y, this.max.y);
      }
      return this;
    },
    // @method getCenter(round?: Boolean): Point
    // Returns the center point of the bounds.
    getCenter: function (round) {
      return toPoint((this.min.x + this.max.x) / 2, (this.min.y + this.max.y) / 2, round);
    },
    // @method getBottomLeft(): Point
    // Returns the bottom-left point of the bounds.
    getBottomLeft: function () {
      return toPoint(this.min.x, this.max.y);
    },
    // @method getTopRight(): Point
    // Returns the top-right point of the bounds.
    getTopRight: function () {
      // -> Point
      return toPoint(this.max.x, this.min.y);
    },
    // @method getTopLeft(): Point
    // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).
    getTopLeft: function () {
      return this.min; // left, top
    },
    // @method getBottomRight(): Point
    // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).
    getBottomRight: function () {
      return this.max; // right, bottom
    },
    // @method getSize(): Point
    // Returns the size of the given bounds
    getSize: function () {
      return this.max.subtract(this.min);
    },
    // @method contains(otherBounds: Bounds): Boolean
    // Returns `true` if the rectangle contains the given one.
    // @alternative
    // @method contains(point: Point): Boolean
    // Returns `true` if the rectangle contains the given point.
    contains: function (obj) {
      var min, max;
      if (typeof obj[0] === 'number' || obj instanceof Point) {
        obj = toPoint(obj);
      } else {
        obj = toBounds(obj);
      }
      if (obj instanceof Bounds) {
        min = obj.min;
        max = obj.max;
      } else {
        min = max = obj;
      }
      return min.x >= this.min.x && max.x <= this.max.x && min.y >= this.min.y && max.y <= this.max.y;
    },
    // @method intersects(otherBounds: Bounds): Boolean
    // Returns `true` if the rectangle intersects the given bounds. Two bounds
    // intersect if they have at least one point in common.
    intersects: function (bounds) {
      // (Bounds) -> Boolean
      bounds = toBounds(bounds);
      var min = this.min,
        max = this.max,
        min2 = bounds.min,
        max2 = bounds.max,
        xIntersects = max2.x >= min.x && min2.x <= max.x,
        yIntersects = max2.y >= min.y && min2.y <= max.y;
      return xIntersects && yIntersects;
    },
    // @method overlaps(otherBounds: Bounds): Boolean
    // Returns `true` if the rectangle overlaps the given bounds. Two bounds
    // overlap if their intersection is an area.
    overlaps: function (bounds) {
      // (Bounds) -> Boolean
      bounds = toBounds(bounds);
      var min = this.min,
        max = this.max,
        min2 = bounds.min,
        max2 = bounds.max,
        xOverlaps = max2.x > min.x && min2.x < max.x,
        yOverlaps = max2.y > min.y && min2.y < max.y;
      return xOverlaps && yOverlaps;
    },
    // @method isValid(): Boolean
    // Returns `true` if the bounds are properly initialized.
    isValid: function () {
      return !!(this.min && this.max);
    },
    // @method pad(bufferRatio: Number): Bounds
    // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
    // For example, a ratio of 0.5 extends the bounds by 50% in each direction.
    // Negative values will retract the bounds.
    pad: function (bufferRatio) {
      var min = this.min,
        max = this.max,
        heightBuffer = Math.abs(min.x - max.x) * bufferRatio,
        widthBuffer = Math.abs(min.y - max.y) * bufferRatio;
      return toBounds(toPoint(min.x - heightBuffer, min.y - widthBuffer), toPoint(max.x + heightBuffer, max.y + widthBuffer));
    },
    // @method equals(otherBounds: Bounds): Boolean
    // Returns `true` if the rectangle is equivalent to the given bounds.
    equals: function (bounds) {
      if (!bounds) {
        return false;
      }
      bounds = toBounds(bounds);
      return this.min.equals(bounds.getTopLeft()) && this.max.equals(bounds.getBottomRight());
    }
  };

  // @factory L.bounds(corner1: Point, corner2: Point)
  // Creates a Bounds object from two corners coordinate pairs.
  // @alternative
  // @factory L.bounds(points: Point[])
  // Creates a Bounds object from the given array of points.
  function toBounds(a, b) {
    if (!a || a instanceof Bounds) {
      return a;
    }
    return new Bounds(a, b);
  }

  /*
   * @class LatLngBounds
   * @aka L.LatLngBounds
   *
   * Represents a rectangular geographical area on a map.
   *
   * @example
   *
   * ```js
   * var corner1 = L.latLng(40.712, -74.227),
   * corner2 = L.latLng(40.774, -74.125),
   * bounds = L.latLngBounds(corner1, corner2);
   * ```
   *
   * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
   *
   * ```js
   * map.fitBounds([
   * 	[40.712, -74.227],
   * 	[40.774, -74.125]
   * ]);
   * ```
   *
   * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.
   *
   * Note that `LatLngBounds` does not inherit from Leaflet's `Class` object,
   * which means new classes can't inherit from it, and new methods
   * can't be added to it with the `include` function.
   */

  function LatLngBounds(corner1, corner2) {
    // (LatLng, LatLng) or (LatLng[])
    if (!corner1) {
      return;
    }
    var latlngs = corner2 ? [corner1, corner2] : corner1;
    for (var i = 0, len = latlngs.length; i < len; i++) {
      this.extend(latlngs[i]);
    }
  }
  LatLngBounds.prototype = {
    // @method extend(latlng: LatLng): this
    // Extend the bounds to contain the given point

    // @alternative
    // @method extend(otherBounds: LatLngBounds): this
    // Extend the bounds to contain the given bounds
    extend: function (obj) {
      var sw = this._southWest,
        ne = this._northEast,
        sw2,
        ne2;
      if (obj instanceof LatLng) {
        sw2 = obj;
        ne2 = obj;
      } else if (obj instanceof LatLngBounds) {
        sw2 = obj._southWest;
        ne2 = obj._northEast;
        if (!sw2 || !ne2) {
          return this;
        }
      } else {
        return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;
      }
      if (!sw && !ne) {
        this._southWest = new LatLng(sw2.lat, sw2.lng);
        this._northEast = new LatLng(ne2.lat, ne2.lng);
      } else {
        sw.lat = Math.min(sw2.lat, sw.lat);
        sw.lng = Math.min(sw2.lng, sw.lng);
        ne.lat = Math.max(ne2.lat, ne.lat);
        ne.lng = Math.max(ne2.lng, ne.lng);
      }
      return this;
    },
    // @method pad(bufferRatio: Number): LatLngBounds
    // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
    // For example, a ratio of 0.5 extends the bounds by 50% in each direction.
    // Negative values will retract the bounds.
    pad: function (bufferRatio) {
      var sw = this._southWest,
        ne = this._northEast,
        heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
        widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
      return new LatLngBounds(new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));
    },
    // @method getCenter(): LatLng
    // Returns the center point of the bounds.
    getCenter: function () {
      return new LatLng((this._southWest.lat + this._northEast.lat) / 2, (this._southWest.lng + this._northEast.lng) / 2);
    },
    // @method getSouthWest(): LatLng
    // Returns the south-west point of the bounds.
    getSouthWest: function () {
      return this._southWest;
    },
    // @method getNorthEast(): LatLng
    // Returns the north-east point of the bounds.
    getNorthEast: function () {
      return this._northEast;
    },
    // @method getNorthWest(): LatLng
    // Returns the north-west point of the bounds.
    getNorthWest: function () {
      return new LatLng(this.getNorth(), this.getWest());
    },
    // @method getSouthEast(): LatLng
    // Returns the south-east point of the bounds.
    getSouthEast: function () {
      return new LatLng(this.getSouth(), this.getEast());
    },
    // @method getWest(): Number
    // Returns the west longitude of the bounds
    getWest: function () {
      return this._southWest.lng;
    },
    // @method getSouth(): Number
    // Returns the south latitude of the bounds
    getSouth: function () {
      return this._southWest.lat;
    },
    // @method getEast(): Number
    // Returns the east longitude of the bounds
    getEast: function () {
      return this._northEast.lng;
    },
    // @method getNorth(): Number
    // Returns the north latitude of the bounds
    getNorth: function () {
      return this._northEast.lat;
    },
    // @method contains(otherBounds: LatLngBounds): Boolean
    // Returns `true` if the rectangle contains the given one.

    // @alternative
    // @method contains (latlng: LatLng): Boolean
    // Returns `true` if the rectangle contains the given point.
    contains: function (obj) {
      // (LatLngBounds) or (LatLng) -> Boolean
      if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {
        obj = toLatLng(obj);
      } else {
        obj = toLatLngBounds(obj);
      }
      var sw = this._southWest,
        ne = this._northEast,
        sw2,
        ne2;
      if (obj instanceof LatLngBounds) {
        sw2 = obj.getSouthWest();
        ne2 = obj.getNorthEast();
      } else {
        sw2 = ne2 = obj;
      }
      return sw2.lat >= sw.lat && ne2.lat <= ne.lat && sw2.lng >= sw.lng && ne2.lng <= ne.lng;
    },
    // @method intersects(otherBounds: LatLngBounds): Boolean
    // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.
    intersects: function (bounds) {
      bounds = toLatLngBounds(bounds);
      var sw = this._southWest,
        ne = this._northEast,
        sw2 = bounds.getSouthWest(),
        ne2 = bounds.getNorthEast(),
        latIntersects = ne2.lat >= sw.lat && sw2.lat <= ne.lat,
        lngIntersects = ne2.lng >= sw.lng && sw2.lng <= ne.lng;
      return latIntersects && lngIntersects;
    },
    // @method overlaps(otherBounds: LatLngBounds): Boolean
    // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.
    overlaps: function (bounds) {
      bounds = toLatLngBounds(bounds);
      var sw = this._southWest,
        ne = this._northEast,
        sw2 = bounds.getSouthWest(),
        ne2 = bounds.getNorthEast(),
        latOverlaps = ne2.lat > sw.lat && sw2.lat < ne.lat,
        lngOverlaps = ne2.lng > sw.lng && sw2.lng < ne.lng;
      return latOverlaps && lngOverlaps;
    },
    // @method toBBoxString(): String
    // Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.
    toBBoxString: function () {
      return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');
    },
    // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean
    // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.
    equals: function (bounds, maxMargin) {
      if (!bounds) {
        return false;
      }
      bounds = toLatLngBounds(bounds);
      return this._southWest.equals(bounds.getSouthWest(), maxMargin) && this._northEast.equals(bounds.getNorthEast(), maxMargin);
    },
    // @method isValid(): Boolean
    // Returns `true` if the bounds are properly initialized.
    isValid: function () {
      return !!(this._southWest && this._northEast);
    }
  };

  // TODO International date line?

  // @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)
  // Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.

  // @alternative
  // @factory L.latLngBounds(latlngs: LatLng[])
  // Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).
  function toLatLngBounds(a, b) {
    if (a instanceof LatLngBounds) {
      return a;
    }
    return new LatLngBounds(a, b);
  }

  /* @class LatLng
   * @aka L.LatLng
   *
   * Represents a geographical point with a certain latitude and longitude.
   *
   * @example
   *
   * ```
   * var latlng = L.latLng(50.5, 30.5);
   * ```
   *
   * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:
   *
   * ```
   * map.panTo([50, 30]);
   * map.panTo({lon: 30, lat: 50});
   * map.panTo({lat: 50, lng: 30});
   * map.panTo(L.latLng(50, 30));
   * ```
   *
   * Note that `LatLng` does not inherit from Leaflet's `Class` object,
   * which means new classes can't inherit from it, and new methods
   * can't be added to it with the `include` function.
   */

  function LatLng(lat, lng, alt) {
    if (isNaN(lat) || isNaN(lng)) {
      throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');
    }

    // @property lat: Number
    // Latitude in degrees
    this.lat = +lat;

    // @property lng: Number
    // Longitude in degrees
    this.lng = +lng;

    // @property alt: Number
    // Altitude in meters (optional)
    if (alt !== undefined) {
      this.alt = +alt;
    }
  }
  LatLng.prototype = {
    // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean
    // Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.
    equals: function (obj, maxMargin) {
      if (!obj) {
        return false;
      }
      obj = toLatLng(obj);
      var margin = Math.max(Math.abs(this.lat - obj.lat), Math.abs(this.lng - obj.lng));
      return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);
    },
    // @method toString(): String
    // Returns a string representation of the point (for debugging purposes).
    toString: function (precision) {
      return 'LatLng(' + formatNum(this.lat, precision) + ', ' + formatNum(this.lng, precision) + ')';
    },
    // @method distanceTo(otherLatLng: LatLng): Number
    // Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).
    distanceTo: function (other) {
      return Earth.distance(this, toLatLng(other));
    },
    // @method wrap(): LatLng
    // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.
    wrap: function () {
      return Earth.wrapLatLng(this);
    },
    // @method toBounds(sizeInMeters: Number): LatLngBounds
    // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.
    toBounds: function (sizeInMeters) {
      var latAccuracy = 180 * sizeInMeters / 40075017,
        lngAccuracy = latAccuracy / Math.cos(Math.PI / 180 * this.lat);
      return toLatLngBounds([this.lat - latAccuracy, this.lng - lngAccuracy], [this.lat + latAccuracy, this.lng + lngAccuracy]);
    },
    clone: function () {
      return new LatLng(this.lat, this.lng, this.alt);
    }
  };

  // @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng
  // Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).

  // @alternative
  // @factory L.latLng(coords: Array): LatLng
  // Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.

  // @alternative
  // @factory L.latLng(coords: Object): LatLng
  // Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.

  function toLatLng(a, b, c) {
    if (a instanceof LatLng) {
      return a;
    }
    if (isArray(a) && typeof a[0] !== 'object') {
      if (a.length === 3) {
        return new LatLng(a[0], a[1], a[2]);
      }
      if (a.length === 2) {
        return new LatLng(a[0], a[1]);
      }
      return null;
    }
    if (a === undefined || a === null) {
      return a;
    }
    if (typeof a === 'object' && 'lat' in a) {
      return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);
    }
    if (b === undefined) {
      return null;
    }
    return new LatLng(a, b, c);
  }

  /*
   * @namespace CRS
   * @crs L.CRS.Base
   * Object that defines coordinate reference systems for projecting
   * geographical points into pixel (screen) coordinates and back (and to
   * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See
   * [spatial reference system](https://en.wikipedia.org/wiki/Spatial_reference_system).
   *
   * Leaflet defines the most usual CRSs by default. If you want to use a
   * CRS not defined by default, take a look at the
   * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.
   *
   * Note that the CRS instances do not inherit from Leaflet's `Class` object,
   * and can't be instantiated. Also, new classes can't inherit from them,
   * and methods can't be added to them with the `include` function.
   */

  var CRS = {
    // @method latLngToPoint(latlng: LatLng, zoom: Number): Point
    // Projects geographical coordinates into pixel coordinates for a given zoom.
    latLngToPoint: function (latlng, zoom) {
      var projectedPoint = this.projection.project(latlng),
        scale = this.scale(zoom);
      return this.transformation._transform(projectedPoint, scale);
    },
    // @method pointToLatLng(point: Point, zoom: Number): LatLng
    // The inverse of `latLngToPoint`. Projects pixel coordinates on a given
    // zoom into geographical coordinates.
    pointToLatLng: function (point, zoom) {
      var scale = this.scale(zoom),
        untransformedPoint = this.transformation.untransform(point, scale);
      return this.projection.unproject(untransformedPoint);
    },
    // @method project(latlng: LatLng): Point
    // Projects geographical coordinates into coordinates in units accepted for
    // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).
    project: function (latlng) {
      return this.projection.project(latlng);
    },
    // @method unproject(point: Point): LatLng
    // Given a projected coordinate returns the corresponding LatLng.
    // The inverse of `project`.
    unproject: function (point) {
      return this.projection.unproject(point);
    },
    // @method scale(zoom: Number): Number
    // Returns the scale used when transforming projected coordinates into
    // pixel coordinates for a particular zoom. For example, it returns
    // `256 * 2^zoom` for Mercator-based CRS.
    scale: function (zoom) {
      return 256 * Math.pow(2, zoom);
    },
    // @method zoom(scale: Number): Number
    // Inverse of `scale()`, returns the zoom level corresponding to a scale
    // factor of `scale`.
    zoom: function (scale) {
      return Math.log(scale / 256) / Math.LN2;
    },
    // @method getProjectedBounds(zoom: Number): Bounds
    // Returns the projection's bounds scaled and transformed for the provided `zoom`.
    getProjectedBounds: function (zoom) {
      if (this.infinite) {
        return null;
      }
      var b = this.projection.bounds,
        s = this.scale(zoom),
        min = this.transformation.transform(b.min, s),
        max = this.transformation.transform(b.max, s);
      return new Bounds(min, max);
    },
    // @method distance(latlng1: LatLng, latlng2: LatLng): Number
    // Returns the distance between two geographical coordinates.

    // @property code: String
    // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)
    //
    // @property wrapLng: Number[]
    // An array of two numbers defining whether the longitude (horizontal) coordinate
    // axis wraps around a given range and how. Defaults to `[-180, 180]` in most
    // geographical CRSs. If `undefined`, the longitude axis does not wrap around.
    //
    // @property wrapLat: Number[]
    // Like `wrapLng`, but for the latitude (vertical) axis.

    // wrapLng: [min, max],
    // wrapLat: [min, max],

    // @property infinite: Boolean
    // If true, the coordinate space will be unbounded (infinite in both axes)
    infinite: false,
    // @method wrapLatLng(latlng: LatLng): LatLng
    // Returns a `LatLng` where lat and lng has been wrapped according to the
    // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.
    wrapLatLng: function (latlng) {
      var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,
        lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,
        alt = latlng.alt;
      return new LatLng(lat, lng, alt);
    },
    // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
    // Returns a `LatLngBounds` with the same size as the given one, ensuring
    // that its center is within the CRS's bounds.
    // Only accepts actual `L.LatLngBounds` instances, not arrays.
    wrapLatLngBounds: function (bounds) {
      var center = bounds.getCenter(),
        newCenter = this.wrapLatLng(center),
        latShift = center.lat - newCenter.lat,
        lngShift = center.lng - newCenter.lng;
      if (latShift === 0 && lngShift === 0) {
        return bounds;
      }
      var sw = bounds.getSouthWest(),
        ne = bounds.getNorthEast(),
        newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),
        newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);
      return new LatLngBounds(newSw, newNe);
    }
  };

  /*
   * @namespace CRS
   * @crs L.CRS.Earth
   *
   * Serves as the base for CRS that are global such that they cover the earth.
   * Can only be used as the base for other CRS and cannot be used directly,
   * since it does not have a `code`, `projection` or `transformation`. `distance()` returns
   * meters.
   */

  var Earth = extend({}, CRS, {
    wrapLng: [-180, 180],
    // Mean Earth Radius, as recommended for use by
    // the International Union of Geodesy and Geophysics,
    // see https://rosettacode.org/wiki/Haversine_formula
    R: 6371000,
    // distance between two geographical points using spherical law of cosines approximation
    distance: function (latlng1, latlng2) {
      var rad = Math.PI / 180,
        lat1 = latlng1.lat * rad,
        lat2 = latlng2.lat * rad,
        sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),
        sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),
        a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,
        c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
      return this.R * c;
    }
  });

  /*
   * @namespace Projection
   * @projection L.Projection.SphericalMercator
   *
   * Spherical Mercator projection — the most common projection for online maps,
   * used by almost all free and commercial tile providers. Assumes that Earth is
   * a sphere. Used by the `EPSG:3857` CRS.
   */

  var earthRadius = 6378137;
  var SphericalMercator = {
    R: earthRadius,
    MAX_LATITUDE: 85.0511287798,
    project: function (latlng) {
      var d = Math.PI / 180,
        max = this.MAX_LATITUDE,
        lat = Math.max(Math.min(max, latlng.lat), -max),
        sin = Math.sin(lat * d);
      return new Point(this.R * latlng.lng * d, this.R * Math.log((1 + sin) / (1 - sin)) / 2);
    },
    unproject: function (point) {
      var d = 180 / Math.PI;
      return new LatLng((2 * Math.atan(Math.exp(point.y / this.R)) - Math.PI / 2) * d, point.x * d / this.R);
    },
    bounds: function () {
      var d = earthRadius * Math.PI;
      return new Bounds([-d, -d], [d, d]);
    }()
  };

  /*
   * @class Transformation
   * @aka L.Transformation
   *
   * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`
   * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing
   * the reverse. Used by Leaflet in its projections code.
   *
   * @example
   *
   * ```js
   * var transformation = L.transformation(2, 5, -1, 10),
   * 	p = L.point(1, 2),
   * 	p2 = transformation.transform(p), //  L.point(7, 8)
   * 	p3 = transformation.untransform(p2); //  L.point(1, 2)
   * ```
   */

  // factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)
  // Creates a `Transformation` object with the given coefficients.
  function Transformation(a, b, c, d) {
    if (isArray(a)) {
      // use array properties
      this._a = a[0];
      this._b = a[1];
      this._c = a[2];
      this._d = a[3];
      return;
    }
    this._a = a;
    this._b = b;
    this._c = c;
    this._d = d;
  }
  Transformation.prototype = {
    // @method transform(point: Point, scale?: Number): Point
    // Returns a transformed point, optionally multiplied by the given scale.
    // Only accepts actual `L.Point` instances, not arrays.
    transform: function (point, scale) {
      // (Point, Number) -> Point
      return this._transform(point.clone(), scale);
    },
    // destructive transform (faster)
    _transform: function (point, scale) {
      scale = scale || 1;
      point.x = scale * (this._a * point.x + this._b);
      point.y = scale * (this._c * point.y + this._d);
      return point;
    },
    // @method untransform(point: Point, scale?: Number): Point
    // Returns the reverse transformation of the given point, optionally divided
    // by the given scale. Only accepts actual `L.Point` instances, not arrays.
    untransform: function (point, scale) {
      scale = scale || 1;
      return new Point((point.x / scale - this._b) / this._a, (point.y / scale - this._d) / this._c);
    }
  };

  // factory L.transformation(a: Number, b: Number, c: Number, d: Number)

  // @factory L.transformation(a: Number, b: Number, c: Number, d: Number)
  // Instantiates a Transformation object with the given coefficients.

  // @alternative
  // @factory L.transformation(coefficients: Array): Transformation
  // Expects an coefficients array of the form
  // `[a: Number, b: Number, c: Number, d: Number]`.

  function toTransformation(a, b, c, d) {
    return new Transformation(a, b, c, d);
  }

  /*
   * @namespace CRS
   * @crs L.CRS.EPSG3857
   *
   * The most common CRS for online maps, used by almost all free and commercial
   * tile providers. Uses Spherical Mercator projection. Set in by default in
   * Map's `crs` option.
   */

  var EPSG3857 = extend({}, Earth, {
    code: 'EPSG:3857',
    projection: SphericalMercator,
    transformation: function () {
      var scale = 0.5 / (Math.PI * SphericalMercator.R);
      return toTransformation(scale, 0.5, -scale, 0.5);
    }()
  });
  var EPSG900913 = extend({}, EPSG3857, {
    code: 'EPSG:900913'
  });

  // @namespace SVG; @section
  // There are several static functions which can be called without instantiating L.SVG:

  // @function create(name: String): SVGElement
  // Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),
  // corresponding to the class name passed. For example, using 'line' will return
  // an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).
  function svgCreate(name) {
    return document.createElementNS('http://www.w3.org/2000/svg', name);
  }

  // @function pointsToPath(rings: Point[], closed: Boolean): String
  // Generates a SVG path string for multiple rings, with each ring turning
  // into "M..L..L.." instructions
  function pointsToPath(rings, closed) {
    var str = '',
      i,
      j,
      len,
      len2,
      points,
      p;
    for (i = 0, len = rings.length; i < len; i++) {
      points = rings[i];
      for (j = 0, len2 = points.length; j < len2; j++) {
        p = points[j];
        str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
      }

      // closes the ring for polygons; "x" is VML syntax
      str += closed ? Browser.svg ? 'z' : 'x' : '';
    }

    // SVG complains about empty path strings
    return str || 'M0 0';
  }

  /*
   * @namespace Browser
   * @aka L.Browser
   *
   * A namespace with static properties for browser/feature detection used by Leaflet internally.
   *
   * @example
   *
   * ```js
   * if (L.Browser.ielt9) {
   *   alert('Upgrade your browser, dude!');
   * }
   * ```
   */

  var style = document.documentElement.style;

  // @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).
  var ie = 'ActiveXObject' in window;

  // @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.
  var ielt9 = ie && !document.addEventListener;

  // @property edge: Boolean; `true` for the Edge web browser.
  var edge = 'msLaunchUri' in navigator && !('documentMode' in document);

  // @property webkit: Boolean;
  // `true` for webkit-based browsers like Chrome and Safari (including mobile versions).
  var webkit = userAgentContains('webkit');

  // @property android: Boolean
  // **Deprecated.** `true` for any browser running on an Android platform.
  var android = userAgentContains('android');

  // @property android23: Boolean; **Deprecated.** `true` for browsers running on Android 2 or Android 3.
  var android23 = userAgentContains('android 2') || userAgentContains('android 3');

  /* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */
  var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit
  // @property androidStock: Boolean; **Deprecated.** `true` for the Android stock browser (i.e. not Chrome)
  var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);

  // @property opera: Boolean; `true` for the Opera browser
  var opera = !!window.opera;

  // @property chrome: Boolean; `true` for the Chrome browser.
  var chrome = !edge && userAgentContains('chrome');

  // @property gecko: Boolean; `true` for gecko-based browsers like Firefox.
  var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;

  // @property safari: Boolean; `true` for the Safari browser.
  var safari = !chrome && userAgentContains('safari');
  var phantom = userAgentContains('phantom');

  // @property opera12: Boolean
  // `true` for the Opera browser supporting CSS transforms (version 12 or later).
  var opera12 = 'OTransition' in style;

  // @property win: Boolean; `true` when the browser is running in a Windows platform
  var win = navigator.platform.indexOf('Win') === 0;

  // @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.
  var ie3d = ie && 'transition' in style;

  // @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.
  var webkit3d = 'WebKitCSSMatrix' in window && 'm11' in new window.WebKitCSSMatrix() && !android23;

  // @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.
  var gecko3d = 'MozPerspective' in style;

  // @property any3d: Boolean
  // `true` for all browsers supporting CSS transforms.
  var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;

  // @property mobile: Boolean; `true` for all browsers running in a mobile device.
  var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');

  // @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.
  var mobileWebkit = mobile && webkit;

  // @property mobileWebkit3d: Boolean
  // `true` for all webkit-based browsers in a mobile device supporting CSS transforms.
  var mobileWebkit3d = mobile && webkit3d;

  // @property msPointer: Boolean
  // `true` for browsers implementing the Microsoft touch events model (notably IE10).
  var msPointer = !window.PointerEvent && window.MSPointerEvent;

  // @property pointer: Boolean
  // `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).
  var pointer = !!(window.PointerEvent || msPointer);

  // @property touchNative: Boolean
  // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
  // **This does not necessarily mean** that the browser is running in a computer with
  // a touchscreen, it only means that the browser is capable of understanding
  // touch events.
  var touchNative = 'ontouchstart' in window || !!window.TouchEvent;

  // @property touch: Boolean
  // `true` for all browsers supporting either [touch](#browser-touch) or [pointer](#browser-pointer) events.
  // Note: pointer events will be preferred (if available), and processed for all `touch*` listeners.
  var touch = !window.L_NO_TOUCH && (touchNative || pointer);

  // @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.
  var mobileOpera = mobile && opera;

  // @property mobileGecko: Boolean
  // `true` for gecko-based browsers running in a mobile device.
  var mobileGecko = mobile && gecko;

  // @property retina: Boolean
  // `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%.
  var retina = (window.devicePixelRatio || window.screen.deviceXDPI / window.screen.logicalXDPI) > 1;

  // @property passiveEvents: Boolean
  // `true` for browsers that support passive events.
  var passiveEvents = function () {
    var supportsPassiveOption = false;
    try {
      var opts = Object.defineProperty({}, 'passive', {
        get: function () {
          // eslint-disable-line getter-return
          supportsPassiveOption = true;
        }
      });
      window.addEventListener('testPassiveEventSupport', falseFn, opts);
      window.removeEventListener('testPassiveEventSupport', falseFn, opts);
    } catch (e) {
      // Errors can safely be ignored since this is only a browser support test.
    }
    return supportsPassiveOption;
  }();

  // @property canvas: Boolean
  // `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
  var canvas$1 = function () {
    return !!document.createElement('canvas').getContext;
  }();

  // @property svg: Boolean
  // `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).
  var svg$1 = !!(document.createElementNS && svgCreate('svg').createSVGRect);
  var inlineSvg = !!svg$1 && function () {
    var div = document.createElement('div');
    div.innerHTML = '<svg/>';
    return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg';
  }();

  // @property vml: Boolean
  // `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).
  var vml = !svg$1 && function () {
    try {
      var div = document.createElement('div');
      div.innerHTML = '<v:shape adj="1"/>';
      var shape = div.firstChild;
      shape.style.behavior = 'url(#default#VML)';
      return shape && typeof shape.adj === 'object';
    } catch (e) {
      return false;
    }
  }();

  // @property mac: Boolean; `true` when the browser is running in a Mac platform
  var mac = navigator.platform.indexOf('Mac') === 0;

  // @property mac: Boolean; `true` when the browser is running in a Linux platform
  var linux = navigator.platform.indexOf('Linux') === 0;
  function userAgentContains(str) {
    return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
  }
  var Browser = {
    ie: ie,
    ielt9: ielt9,
    edge: edge,
    webkit: webkit,
    android: android,
    android23: android23,
    androidStock: androidStock,
    opera: opera,
    chrome: chrome,
    gecko: gecko,
    safari: safari,
    phantom: phantom,
    opera12: opera12,
    win: win,
    ie3d: ie3d,
    webkit3d: webkit3d,
    gecko3d: gecko3d,
    any3d: any3d,
    mobile: mobile,
    mobileWebkit: mobileWebkit,
    mobileWebkit3d: mobileWebkit3d,
    msPointer: msPointer,
    pointer: pointer,
    touch: touch,
    touchNative: touchNative,
    mobileOpera: mobileOpera,
    mobileGecko: mobileGecko,
    retina: retina,
    passiveEvents: passiveEvents,
    canvas: canvas$1,
    svg: svg$1,
    vml: vml,
    inlineSvg: inlineSvg,
    mac: mac,
    linux: linux
  };

  /*
   * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
   */

  var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown';
  var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove';
  var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup';
  var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel';
  var pEvent = {
    touchstart: POINTER_DOWN,
    touchmove: POINTER_MOVE,
    touchend: POINTER_UP,
    touchcancel: POINTER_CANCEL
  };
  var handle = {
    touchstart: _onPointerStart,
    touchmove: _handlePointer,
    touchend: _handlePointer,
    touchcancel: _handlePointer
  };
  var _pointers = {};
  var _pointerDocListener = false;

  // Provides a touch events wrapper for (ms)pointer events.
  // ref https://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890

  function addPointerListener(obj, type, handler) {
    if (type === 'touchstart') {
      _addPointerDocListener();
    }
    if (!handle[type]) {
      console.warn('wrong event specified:', type);
      return falseFn;
    }
    handler = handle[type].bind(this, handler);
    obj.addEventListener(pEvent[type], handler, false);
    return handler;
  }
  function removePointerListener(obj, type, handler) {
    if (!pEvent[type]) {
      console.warn('wrong event specified:', type);
      return;
    }
    obj.removeEventListener(pEvent[type], handler, false);
  }
  function _globalPointerDown(e) {
    _pointers[e.pointerId] = e;
  }
  function _globalPointerMove(e) {
    if (_pointers[e.pointerId]) {
      _pointers[e.pointerId] = e;
    }
  }
  function _globalPointerUp(e) {
    delete _pointers[e.pointerId];
  }
  function _addPointerDocListener() {
    // need to keep track of what pointers and how many are active to provide e.touches emulation
    if (!_pointerDocListener) {
      // we listen document as any drags that end by moving the touch off the screen get fired there
      document.addEventListener(POINTER_DOWN, _globalPointerDown, true);
      document.addEventListener(POINTER_MOVE, _globalPointerMove, true);
      document.addEventListener(POINTER_UP, _globalPointerUp, true);
      document.addEventListener(POINTER_CANCEL, _globalPointerUp, true);
      _pointerDocListener = true;
    }
  }
  function _handlePointer(handler, e) {
    if (e.pointerType === (e.MSPOINTER_TYPE_MOUSE || 'mouse')) {
      return;
    }
    e.touches = [];
    for (var i in _pointers) {
      e.touches.push(_pointers[i]);
    }
    e.changedTouches = [e];
    handler(e);
  }
  function _onPointerStart(handler, e) {
    // IE10 specific: MsTouch needs preventDefault. See #2000
    if (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) {
      preventDefault(e);
    }
    _handlePointer(handler, e);
  }

  /*
   * Extends the event handling code with double tap support for mobile browsers.
   *
   * Note: currently most browsers fire native dblclick, with only a few exceptions
   * (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386)
   */

  function makeDblclick(event) {
    // in modern browsers `type` cannot be just overridden:
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only
    var newEvent = {},
      prop,
      i;
    for (i in event) {
      prop = event[i];
      newEvent[i] = prop && prop.bind ? prop.bind(event) : prop;
    }
    event = newEvent;
    newEvent.type = 'dblclick';
    newEvent.detail = 2;
    newEvent.isTrusted = false;
    newEvent._simulated = true; // for debug purposes
    return newEvent;
  }
  var delay = 200;
  function addDoubleTapListener(obj, handler) {
    // Most browsers handle double tap natively
    obj.addEventListener('dblclick', handler);

    // On some platforms the browser doesn't fire native dblclicks for touch events.
    // It seems that in all such cases `detail` property of `click` event is always `1`.
    // So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed.
    var last = 0,
      detail;
    function simDblclick(e) {
      if (e.detail !== 1) {
        detail = e.detail; // keep in sync to avoid false dblclick in some cases
        return;
      }
      if (e.pointerType === 'mouse' || e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents) {
        return;
      }

      // When clicking on an <input>, the browser generates a click on its
      // <label> (and vice versa) triggering two clicks in quick succession.
      // This ignores clicks on elements which are a label with a 'for'
      // attribute (or children of such a label), but not children of
      // a <input>.
      var path = getPropagationPath(e);
      if (path.some(function (el) {
        return el instanceof HTMLLabelElement && el.attributes.for;
      }) && !path.some(function (el) {
        return el instanceof HTMLInputElement || el instanceof HTMLSelectElement;
      })) {
        return;
      }
      var now = Date.now();
      if (now - last <= delay) {
        detail++;
        if (detail === 2) {
          handler(makeDblclick(e));
        }
      } else {
        detail = 1;
      }
      last = now;
    }
    obj.addEventListener('click', simDblclick);
    return {
      dblclick: handler,
      simDblclick: simDblclick
    };
  }
  function removeDoubleTapListener(obj, handlers) {
    obj.removeEventListener('dblclick', handlers.dblclick);
    obj.removeEventListener('click', handlers.simDblclick);
  }

  /*
   * @namespace DomUtil
   *
   * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)
   * tree, used by Leaflet internally.
   *
   * Most functions expecting or returning a `HTMLElement` also work for
   * SVG elements. The only difference is that classes refer to CSS classes
   * in HTML and SVG classes in SVG.
   */

  // @property TRANSFORM: String
  // Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit).
  var TRANSFORM = testProp(['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);

  // webkitTransition comes first because some browser versions that drop vendor prefix don't do
  // the same for the transitionend event, in particular the Android 4.1 stock browser

  // @property TRANSITION: String
  // Vendor-prefixed transition style name.
  var TRANSITION = testProp(['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);

  // @property TRANSITION_END: String
  // Vendor-prefixed transitionend event name.
  var TRANSITION_END = TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend';

  // @function get(id: String|HTMLElement): HTMLElement
  // Returns an element given its DOM id, or returns the element itself
  // if it was passed directly.
  function get(id) {
    return typeof id === 'string' ? document.getElementById(id) : id;
  }

  // @function getStyle(el: HTMLElement, styleAttrib: String): String
  // Returns the value for a certain style attribute on an element,
  // including computed values or values set through CSS.
  function getStyle(el, style) {
    var value = el.style[style] || el.currentStyle && el.currentStyle[style];
    if ((!value || value === 'auto') && document.defaultView) {
      var css = document.defaultView.getComputedStyle(el, null);
      value = css ? css[style] : null;
    }
    return value === 'auto' ? null : value;
  }

  // @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement
  // Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element.
  function create$1(tagName, className, container) {
    var el = document.createElement(tagName);
    el.className = className || '';
    if (container) {
      container.appendChild(el);
    }
    return el;
  }

  // @function remove(el: HTMLElement)
  // Removes `el` from its parent element
  function remove(el) {
    var parent = el.parentNode;
    if (parent) {
      parent.removeChild(el);
    }
  }

  // @function empty(el: HTMLElement)
  // Removes all of `el`'s children elements from `el`
  function empty(el) {
    while (el.firstChild) {
      el.removeChild(el.firstChild);
    }
  }

  // @function toFront(el: HTMLElement)
  // Makes `el` the last child of its parent, so it renders in front of the other children.
  function toFront(el) {
    var parent = el.parentNode;
    if (parent && parent.lastChild !== el) {
      parent.appendChild(el);
    }
  }

  // @function toBack(el: HTMLElement)
  // Makes `el` the first child of its parent, so it renders behind the other children.
  function toBack(el) {
    var parent = el.parentNode;
    if (parent && parent.firstChild !== el) {
      parent.insertBefore(el, parent.firstChild);
    }
  }

  // @function hasClass(el: HTMLElement, name: String): Boolean
  // Returns `true` if the element's class attribute contains `name`.
  function hasClass(el, name) {
    if (el.classList !== undefined) {
      return el.classList.contains(name);
    }
    var className = getClass(el);
    return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
  }

  // @function addClass(el: HTMLElement, name: String)
  // Adds `name` to the element's class attribute.
  function addClass(el, name) {
    if (el.classList !== undefined) {
      var classes = splitWords(name);
      for (var i = 0, len = classes.length; i < len; i++) {
        el.classList.add(classes[i]);
      }
    } else if (!hasClass(el, name)) {
      var className = getClass(el);
      setClass(el, (className ? className + ' ' : '') + name);
    }
  }

  // @function removeClass(el: HTMLElement, name: String)
  // Removes `name` from the element's class attribute.
  function removeClass(el, name) {
    if (el.classList !== undefined) {
      el.classList.remove(name);
    } else {
      setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
    }
  }

  // @function setClass(el: HTMLElement, name: String)
  // Sets the element's class.
  function setClass(el, name) {
    if (el.className.baseVal === undefined) {
      el.className = name;
    } else {
      // in case of SVG element
      el.className.baseVal = name;
    }
  }

  // @function getClass(el: HTMLElement): String
  // Returns the element's class.
  function getClass(el) {
    // Check if the element is an SVGElementInstance and use the correspondingElement instead
    // (Required for linked SVG elements in IE11.)
    if (el.correspondingElement) {
      el = el.correspondingElement;
    }
    return el.className.baseVal === undefined ? el.className : el.className.baseVal;
  }

  // @function setOpacity(el: HTMLElement, opacity: Number)
  // Set the opacity of an element (including old IE support).
  // `opacity` must be a number from `0` to `1`.
  function setOpacity(el, value) {
    if ('opacity' in el.style) {
      el.style.opacity = value;
    } else if ('filter' in el.style) {
      _setOpacityIE(el, value);
    }
  }
  function _setOpacityIE(el, value) {
    var filter = false,
      filterName = 'DXImageTransform.Microsoft.Alpha';

    // filters collection throws an error if we try to retrieve a filter that doesn't exist
    try {
      filter = el.filters.item(filterName);
    } catch (e) {
      // don't set opacity to 1 if we haven't already set an opacity,
      // it isn't needed and breaks transparent pngs.
      if (value === 1) {
        return;
      }
    }
    value = Math.round(value * 100);
    if (filter) {
      filter.Enabled = value !== 100;
      filter.Opacity = value;
    } else {
      el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
    }
  }

  // @function testProp(props: String[]): String|false
  // Goes through the array of style names and returns the first name
  // that is a valid style name for an element. If no such name is found,
  // it returns false. Useful for vendor-prefixed styles like `transform`.
  function testProp(props) {
    var style = document.documentElement.style;
    for (var i = 0; i < props.length; i++) {
      if (props[i] in style) {
        return props[i];
      }
    }
    return false;
  }

  // @function setTransform(el: HTMLElement, offset: Point, scale?: Number)
  // Resets the 3D CSS transform of `el` so it is translated by `offset` pixels
  // and optionally scaled by `scale`. Does not have an effect if the
  // browser doesn't support 3D CSS transforms.
  function setTransform(el, offset, scale) {
    var pos = offset || new Point(0, 0);
    el.style[TRANSFORM] = (Browser.ie3d ? 'translate(' + pos.x + 'px,' + pos.y + 'px)' : 'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') + (scale ? ' scale(' + scale + ')' : '');
  }

  // @function setPosition(el: HTMLElement, position: Point)
  // Sets the position of `el` to coordinates specified by `position`,
  // using CSS translate or top/left positioning depending on the browser
  // (used by Leaflet internally to position its layers).
  function setPosition(el, point) {
    /*eslint-disable */
    el._leaflet_pos = point;
    /* eslint-enable */

    if (Browser.any3d) {
      setTransform(el, point);
    } else {
      el.style.left = point.x + 'px';
      el.style.top = point.y + 'px';
    }
  }

  // @function getPosition(el: HTMLElement): Point
  // Returns the coordinates of an element previously positioned with setPosition.
  function getPosition(el) {
    // this method is only used for elements previously positioned using setPosition,
    // so it's safe to cache the position for performance

    return el._leaflet_pos || new Point(0, 0);
  }

  // @function disableTextSelection()
  // Prevents the user from generating `selectstart` DOM events, usually generated
  // when the user drags the mouse through a page with text. Used internally
  // by Leaflet to override the behaviour of any click-and-drag interaction on
  // the map. Affects drag interactions on the whole document.

  // @function enableTextSelection()
  // Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection).
  var disableTextSelection;
  var enableTextSelection;
  var _userSelect;
  if ('onselectstart' in document) {
    disableTextSelection = function () {
      on(window, 'selectstart', preventDefault);
    };
    enableTextSelection = function () {
      off(window, 'selectstart', preventDefault);
    };
  } else {
    var userSelectProperty = testProp(['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
    disableTextSelection = function () {
      if (userSelectProperty) {
        var style = document.documentElement.style;
        _userSelect = style[userSelectProperty];
        style[userSelectProperty] = 'none';
      }
    };
    enableTextSelection = function () {
      if (userSelectProperty) {
        document.documentElement.style[userSelectProperty] = _userSelect;
        _userSelect = undefined;
      }
    };
  }

  // @function disableImageDrag()
  // As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but
  // for `dragstart` DOM events, usually generated when the user drags an image.
  function disableImageDrag() {
    on(window, 'dragstart', preventDefault);
  }

  // @function enableImageDrag()
  // Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection).
  function enableImageDrag() {
    off(window, 'dragstart', preventDefault);
  }
  var _outlineElement, _outlineStyle;
  // @function preventOutline(el: HTMLElement)
  // Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline)
  // of the element `el` invisible. Used internally by Leaflet to prevent
  // focusable elements from displaying an outline when the user performs a
  // drag interaction on them.
  function preventOutline(element) {
    while (element.tabIndex === -1) {
      element = element.parentNode;
    }
    if (!element.style) {
      return;
    }
    restoreOutline();
    _outlineElement = element;
    _outlineStyle = element.style.outlineStyle;
    element.style.outlineStyle = 'none';
    on(window, 'keydown', restoreOutline);
  }

  // @function restoreOutline()
  // Cancels the effects of a previous [`L.DomUtil.preventOutline`]().
  function restoreOutline() {
    if (!_outlineElement) {
      return;
    }
    _outlineElement.style.outlineStyle = _outlineStyle;
    _outlineElement = undefined;
    _outlineStyle = undefined;
    off(window, 'keydown', restoreOutline);
  }

  // @function getSizedParentNode(el: HTMLElement): HTMLElement
  // Finds the closest parent node which size (width and height) is not null.
  function getSizedParentNode(element) {
    do {
      element = element.parentNode;
    } while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body);
    return element;
  }

  // @function getScale(el: HTMLElement): Object
  // Computes the CSS scale currently applied on the element.
  // Returns an object with `x` and `y` members as horizontal and vertical scales respectively,
  // and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
  function getScale(element) {
    var rect = element.getBoundingClientRect(); // Read-only in old browsers.

    return {
      x: rect.width / element.offsetWidth || 1,
      y: rect.height / element.offsetHeight || 1,
      boundingClientRect: rect
    };
  }
  var DomUtil = {
    __proto__: null,
    TRANSFORM: TRANSFORM,
    TRANSITION: TRANSITION,
    TRANSITION_END: TRANSITION_END,
    get: get,
    getStyle: getStyle,
    create: create$1,
    remove: remove,
    empty: empty,
    toFront: toFront,
    toBack: toBack,
    hasClass: hasClass,
    addClass: addClass,
    removeClass: removeClass,
    setClass: setClass,
    getClass: getClass,
    setOpacity: setOpacity,
    testProp: testProp,
    setTransform: setTransform,
    setPosition: setPosition,
    getPosition: getPosition,
    get disableTextSelection() {
      return disableTextSelection;
    },
    get enableTextSelection() {
      return enableTextSelection;
    },
    disableImageDrag: disableImageDrag,
    enableImageDrag: enableImageDrag,
    preventOutline: preventOutline,
    restoreOutline: restoreOutline,
    getSizedParentNode: getSizedParentNode,
    getScale: getScale
  };

  /*
   * @namespace DomEvent
   * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally.
   */

  // Inspired by John Resig, Dean Edwards and YUI addEvent implementations.

  // @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this
  // Adds a listener function (`fn`) to a particular DOM event type of the
  // element `el`. You can optionally specify the context of the listener
  // (object the `this` keyword will point to). You can also pass several
  // space-separated types (e.g. `'click dblclick'`).

  // @alternative
  // @function on(el: HTMLElement, eventMap: Object, context?: Object): this
  // Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
  function on(obj, types, fn, context) {
    if (types && typeof types === 'object') {
      for (var type in types) {
        addOne(obj, type, types[type], fn);
      }
    } else {
      types = splitWords(types);
      for (var i = 0, len = types.length; i < len; i++) {
        addOne(obj, types[i], fn, context);
      }
    }
    return this;
  }
  var eventsKey = '_leaflet_events';

  // @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this
  // Removes a previously added listener function.
  // Note that if you passed a custom context to on, you must pass the same
  // context to `off` in order to remove the listener.

  // @alternative
  // @function off(el: HTMLElement, eventMap: Object, context?: Object): this
  // Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`

  // @alternative
  // @function off(el: HTMLElement, types: String): this
  // Removes all previously added listeners of given types.

  // @alternative
  // @function off(el: HTMLElement): this
  // Removes all previously added listeners from given HTMLElement
  function off(obj, types, fn, context) {
    if (arguments.length === 1) {
      batchRemove(obj);
      delete obj[eventsKey];
    } else if (types && typeof types === 'object') {
      for (var type in types) {
        removeOne(obj, type, types[type], fn);
      }
    } else {
      types = splitWords(types);
      if (arguments.length === 2) {
        batchRemove(obj, function (type) {
          return indexOf(types, type) !== -1;
        });
      } else {
        for (var i = 0, len = types.length; i < len; i++) {
          removeOne(obj, types[i], fn, context);
        }
      }
    }
    return this;
  }
  function batchRemove(obj, filterFn) {
    for (var id in obj[eventsKey]) {
      var type = id.split(/\d/)[0];
      if (!filterFn || filterFn(type)) {
        removeOne(obj, type, null, null, id);
      }
    }
  }
  var mouseSubst = {
    mouseenter: 'mouseover',
    mouseleave: 'mouseout',
    wheel: !('onwheel' in window) && 'mousewheel'
  };
  function addOne(obj, type, fn, context) {
    var id = type + stamp(fn) + (context ? '_' + stamp(context) : '');
    if (obj[eventsKey] && obj[eventsKey][id]) {
      return this;
    }
    var handler = function (e) {
      return fn.call(context || obj, e || window.event);
    };
    var originalHandler = handler;
    if (!Browser.touchNative && Browser.pointer && type.indexOf('touch') === 0) {
      // Needs DomEvent.Pointer.js
      handler = addPointerListener(obj, type, handler);
    } else if (Browser.touch && type === 'dblclick') {
      handler = addDoubleTapListener(obj, handler);
    } else if ('addEventListener' in obj) {
      if (type === 'touchstart' || type === 'touchmove' || type === 'wheel' || type === 'mousewheel') {
        obj.addEventListener(mouseSubst[type] || type, handler, Browser.passiveEvents ? {
          passive: false
        } : false);
      } else if (type === 'mouseenter' || type === 'mouseleave') {
        handler = function (e) {
          e = e || window.event;
          if (isExternalTarget(obj, e)) {
            originalHandler(e);
          }
        };
        obj.addEventListener(mouseSubst[type], handler, false);
      } else {
        obj.addEventListener(type, originalHandler, false);
      }
    } else {
      obj.attachEvent('on' + type, handler);
    }
    obj[eventsKey] = obj[eventsKey] || {};
    obj[eventsKey][id] = handler;
  }
  function removeOne(obj, type, fn, context, id) {
    id = id || type + stamp(fn) + (context ? '_' + stamp(context) : '');
    var handler = obj[eventsKey] && obj[eventsKey][id];
    if (!handler) {
      return this;
    }
    if (!Browser.touchNative && Browser.pointer && type.indexOf('touch') === 0) {
      removePointerListener(obj, type, handler);
    } else if (Browser.touch && type === 'dblclick') {
      removeDoubleTapListener(obj, handler);
    } else if ('removeEventListener' in obj) {
      obj.removeEventListener(mouseSubst[type] || type, handler, false);
    } else {
      obj.detachEvent('on' + type, handler);
    }
    obj[eventsKey][id] = null;
  }

  // @function stopPropagation(ev: DOMEvent): this
  // Stop the given event from propagation to parent elements. Used inside the listener functions:
  // ```js
  // L.DomEvent.on(div, 'click', function (ev) {
  // 	L.DomEvent.stopPropagation(ev);
  // });
  // ```
  function stopPropagation(e) {
    if (e.stopPropagation) {
      e.stopPropagation();
    } else if (e.originalEvent) {
      // In case of Leaflet event.
      e.originalEvent._stopped = true;
    } else {
      e.cancelBubble = true;
    }
    return this;
  }

  // @function disableScrollPropagation(el: HTMLElement): this
  // Adds `stopPropagation` to the element's `'wheel'` events (plus browser variants).
  function disableScrollPropagation(el) {
    addOne(el, 'wheel', stopPropagation);
    return this;
  }

  // @function disableClickPropagation(el: HTMLElement): this
  // Adds `stopPropagation` to the element's `'click'`, `'dblclick'`, `'contextmenu'`,
  // `'mousedown'` and `'touchstart'` events (plus browser variants).
  function disableClickPropagation(el) {
    on(el, 'mousedown touchstart dblclick contextmenu', stopPropagation);
    el['_leaflet_disable_click'] = true;
    return this;
  }

  // @function preventDefault(ev: DOMEvent): this
  // Prevents the default action of the DOM Event `ev` from happening (such as
  // following a link in the href of the a element, or doing a POST request
  // with page reload when a `<form>` is submitted).
  // Use it inside listener functions.
  function preventDefault(e) {
    if (e.preventDefault) {
      e.preventDefault();
    } else {
      e.returnValue = false;
    }
    return this;
  }

  // @function stop(ev: DOMEvent): this
  // Does `stopPropagation` and `preventDefault` at the same time.
  function stop(e) {
    preventDefault(e);
    stopPropagation(e);
    return this;
  }

  // @function getPropagationPath(ev: DOMEvent): Array
  // Compatibility polyfill for [`Event.composedPath()`](https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath).
  // Returns an array containing the `HTMLElement`s that the given DOM event
  // should propagate to (if not stopped).
  function getPropagationPath(ev) {
    if (ev.composedPath) {
      return ev.composedPath();
    }
    var path = [];
    var el = ev.target;
    while (el) {
      path.push(el);
      el = el.parentNode;
    }
    return path;
  }

  // @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point
  // Gets normalized mouse position from a DOM event relative to the
  // `container` (border excluded) or to the whole page if not specified.
  function getMousePosition(e, container) {
    if (!container) {
      return new Point(e.clientX, e.clientY);
    }
    var scale = getScale(container),
      offset = scale.boundingClientRect; // left and top  values are in page scale (like the event clientX/Y)

    return new Point(
    // offset.left/top values are in page scale (like clientX/Y),
    // whereas clientLeft/Top (border width) values are the original values (before CSS scale applies).
    (e.clientX - offset.left) / scale.x - container.clientLeft, (e.clientY - offset.top) / scale.y - container.clientTop);
  }

  //  except , Safari and
  // We need double the scroll pixels (see #7403 and #4538) for all Browsers
  // except OSX (Mac) -> 3x, Chrome running on Linux 1x

  var wheelPxFactor = Browser.linux && Browser.chrome ? window.devicePixelRatio : Browser.mac ? window.devicePixelRatio * 3 : window.devicePixelRatio > 0 ? 2 * window.devicePixelRatio : 1;
  // @function getWheelDelta(ev: DOMEvent): Number
  // Gets normalized wheel delta from a wheel DOM event, in vertical
  // pixels scrolled (negative if scrolling down).
  // Events from pointing devices without precise scrolling are mapped to
  // a best guess of 60 pixels.
  function getWheelDelta(e) {
    return Browser.edge ? e.wheelDeltaY / 2 :
    // Don't trust window-geometry-based delta
    e.deltaY && e.deltaMode === 0 ? -e.deltaY / wheelPxFactor :
    // Pixels
    e.deltaY && e.deltaMode === 1 ? -e.deltaY * 20 :
    // Lines
    e.deltaY && e.deltaMode === 2 ? -e.deltaY * 60 :
    // Pages
    e.deltaX || e.deltaZ ? 0 :
    // Skip horizontal/depth wheel events
    e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 :
    // Legacy IE pixels
    e.detail && Math.abs(e.detail) < 32765 ? -e.detail * 20 :
    // Legacy Moz lines
    e.detail ? e.detail / -32765 * 60 :
    // Legacy Moz pages
    0;
  }

  // check if element really left/entered the event target (for mouseenter/mouseleave)
  function isExternalTarget(el, e) {
    var related = e.relatedTarget;
    if (!related) {
      return true;
    }
    try {
      while (related && related !== el) {
        related = related.parentNode;
      }
    } catch (err) {
      return false;
    }
    return related !== el;
  }
  var DomEvent = {
    __proto__: null,
    on: on,
    off: off,
    stopPropagation: stopPropagation,
    disableScrollPropagation: disableScrollPropagation,
    disableClickPropagation: disableClickPropagation,
    preventDefault: preventDefault,
    stop: stop,
    getPropagationPath: getPropagationPath,
    getMousePosition: getMousePosition,
    getWheelDelta: getWheelDelta,
    isExternalTarget: isExternalTarget,
    addListener: on,
    removeListener: off
  };

  /*
   * @class PosAnimation
   * @aka L.PosAnimation
   * @inherits Evented
   * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9.
   *
   * @example
   * ```js
   * var myPositionMarker = L.marker([48.864716, 2.294694]).addTo(map);
   *
   * myPositionMarker.on("click", function() {
   * 	var pos = map.latLngToLayerPoint(myPositionMarker.getLatLng());
   * 	pos.y -= 25;
   * 	var fx = new L.PosAnimation();
   *
   * 	fx.once('end',function() {
   * 		pos.y += 25;
   * 		fx.run(myPositionMarker._icon, pos, 0.8);
   * 	});
   *
   * 	fx.run(myPositionMarker._icon, pos, 0.3);
   * });
   *
   * ```
   *
   * @constructor L.PosAnimation()
   * Creates a `PosAnimation` object.
   *
   */

  var PosAnimation = Evented.extend({
    // @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number)
    // Run an animation of a given element to a new position, optionally setting
    // duration in seconds (`0.25` by default) and easing linearity factor (3rd
    // argument of the [cubic bezier curve](https://cubic-bezier.com/#0,0,.5,1),
    // `0.5` by default).
    run: function (el, newPos, duration, easeLinearity) {
      this.stop();
      this._el = el;
      this._inProgress = true;
      this._duration = duration || 0.25;
      this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
      this._startPos = getPosition(el);
      this._offset = newPos.subtract(this._startPos);
      this._startTime = +new Date();

      // @event start: Event
      // Fired when the animation starts
      this.fire('start');
      this._animate();
    },
    // @method stop()
    // Stops the animation (if currently running).
    stop: function () {
      if (!this._inProgress) {
        return;
      }
      this._step(true);
      this._complete();
    },
    _animate: function () {
      // animation loop
      this._animId = requestAnimFrame(this._animate, this);
      this._step();
    },
    _step: function (round) {
      var elapsed = +new Date() - this._startTime,
        duration = this._duration * 1000;
      if (elapsed < duration) {
        this._runFrame(this._easeOut(elapsed / duration), round);
      } else {
        this._runFrame(1);
        this._complete();
      }
    },
    _runFrame: function (progress, round) {
      var pos = this._startPos.add(this._offset.multiplyBy(progress));
      if (round) {
        pos._round();
      }
      setPosition(this._el, pos);

      // @event step: Event
      // Fired continuously during the animation.
      this.fire('step');
    },
    _complete: function () {
      cancelAnimFrame(this._animId);
      this._inProgress = false;
      // @event end: Event
      // Fired when the animation ends.
      this.fire('end');
    },
    _easeOut: function (t) {
      return 1 - Math.pow(1 - t, this._easeOutPower);
    }
  });

  /*
   * @class Map
   * @aka L.Map
   * @inherits Evented
   *
   * The central class of the API — it is used to create a map on a page and manipulate it.
   *
   * @example
   *
   * ```js
   * // initialize the map on the "map" div with a given center and zoom
   * var map = L.map('map', {
   * 	center: [51.505, -0.09],
   * 	zoom: 13
   * });
   * ```
   *
   */

  var Map = Evented.extend({
    options: {
      // @section Map State Options
      // @option crs: CRS = L.CRS.EPSG3857
      // The [Coordinate Reference System](#crs) to use. Don't change this if you're not
      // sure what it means.
      crs: EPSG3857,
      // @option center: LatLng = undefined
      // Initial geographic center of the map
      center: undefined,
      // @option zoom: Number = undefined
      // Initial map zoom level
      zoom: undefined,
      // @option minZoom: Number = *
      // Minimum zoom level of the map.
      // If not specified and at least one `GridLayer` or `TileLayer` is in the map,
      // the lowest of their `minZoom` options will be used instead.
      minZoom: undefined,
      // @option maxZoom: Number = *
      // Maximum zoom level of the map.
      // If not specified and at least one `GridLayer` or `TileLayer` is in the map,
      // the highest of their `maxZoom` options will be used instead.
      maxZoom: undefined,
      // @option layers: Layer[] = []
      // Array of layers that will be added to the map initially
      layers: [],
      // @option maxBounds: LatLngBounds = null
      // When this option is set, the map restricts the view to the given
      // geographical bounds, bouncing the user back if the user tries to pan
      // outside the view. To set the restriction dynamically, use
      // [`setMaxBounds`](#map-setmaxbounds) method.
      maxBounds: undefined,
      // @option renderer: Renderer = *
      // The default method for drawing vector layers on the map. `L.SVG`
      // or `L.Canvas` by default depending on browser support.
      renderer: undefined,
      // @section Animation Options
      // @option zoomAnimation: Boolean = true
      // Whether the map zoom animation is enabled. By default it's enabled
      // in all browsers that support CSS3 Transitions except Android.
      zoomAnimation: true,
      // @option zoomAnimationThreshold: Number = 4
      // Won't animate zoom if the zoom difference exceeds this value.
      zoomAnimationThreshold: 4,
      // @option fadeAnimation: Boolean = true
      // Whether the tile fade animation is enabled. By default it's enabled
      // in all browsers that support CSS3 Transitions except Android.
      fadeAnimation: true,
      // @option markerZoomAnimation: Boolean = true
      // Whether markers animate their zoom with the zoom animation, if disabled
      // they will disappear for the length of the animation. By default it's
      // enabled in all browsers that support CSS3 Transitions except Android.
      markerZoomAnimation: true,
      // @option transform3DLimit: Number = 2^23
      // Defines the maximum size of a CSS translation transform. The default
      // value should not be changed unless a web browser positions layers in
      // the wrong place after doing a large `panBy`.
      transform3DLimit: 8388608,
      // Precision limit of a 32-bit float

      // @section Interaction Options
      // @option zoomSnap: Number = 1
      // Forces the map's zoom level to always be a multiple of this, particularly
      // right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom.
      // By default, the zoom level snaps to the nearest integer; lower values
      // (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0`
      // means the zoom level will not be snapped after `fitBounds` or a pinch-zoom.
      zoomSnap: 1,
      // @option zoomDelta: Number = 1
      // Controls how much the map's zoom level will change after a
      // [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+`
      // or `-` on the keyboard, or using the [zoom controls](#control-zoom).
      // Values smaller than `1` (e.g. `0.5`) allow for greater granularity.
      zoomDelta: 1,
      // @option trackResize: Boolean = true
      // Whether the map automatically handles browser window resize to update itself.
      trackResize: true
    },
    initialize: function (id, options) {
      // (HTMLElement or String, Object)
      options = setOptions(this, options);

      // Make sure to assign internal flags at the beginning,
      // to avoid inconsistent state in some edge cases.
      this._handlers = [];
      this._layers = {};
      this._zoomBoundLayers = {};
      this._sizeChanged = true;
      this._initContainer(id);
      this._initLayout();

      // hack for https://github.com/Leaflet/Leaflet/issues/1980
      this._onResize = bind(this._onResize, this);
      this._initEvents();
      if (options.maxBounds) {
        this.setMaxBounds(options.maxBounds);
      }
      if (options.zoom !== undefined) {
        this._zoom = this._limitZoom(options.zoom);
      }
      if (options.center && options.zoom !== undefined) {
        this.setView(toLatLng(options.center), options.zoom, {
          reset: true
        });
      }
      this.callInitHooks();

      // don't animate on browsers without hardware-accelerated transitions or old Android/Opera
      this._zoomAnimated = TRANSITION && Browser.any3d && !Browser.mobileOpera && this.options.zoomAnimation;

      // zoom transitions run with the same duration for all layers, so if one of transitionend events
      // happens after starting zoom animation (propagating to the map pane), we know that it ended globally
      if (this._zoomAnimated) {
        this._createAnimProxy();
        on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this);
      }
      this._addLayers(this.options.layers);
    },
    // @section Methods for modifying map state

    // @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this
    // Sets the view of the map (geographical center and zoom) with the given
    // animation options.
    setView: function (center, zoom, options) {
      zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);
      center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds);
      options = options || {};
      this._stop();
      if (this._loaded && !options.reset && options !== true) {
        if (options.animate !== undefined) {
          options.zoom = extend({
            animate: options.animate
          }, options.zoom);
          options.pan = extend({
            animate: options.animate,
            duration: options.duration
          }, options.pan);
        }

        // try animating pan or zoom
        var moved = this._zoom !== zoom ? this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) : this._tryAnimatedPan(center, options.pan);
        if (moved) {
          // prevent resize handler call, the view will refresh after animation anyway
          clearTimeout(this._sizeTimer);
          return this;
        }
      }

      // animation didn't start, just reset the map view
      this._resetView(center, zoom, options.pan && options.pan.noMoveStart);
      return this;
    },
    // @method setZoom(zoom: Number, options?: Zoom/pan options): this
    // Sets the zoom of the map.
    setZoom: function (zoom, options) {
      if (!this._loaded) {
        this._zoom = zoom;
        return this;
      }
      return this.setView(this.getCenter(), zoom, {
        zoom: options
      });
    },
    // @method zoomIn(delta?: Number, options?: Zoom options): this
    // Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
    zoomIn: function (delta, options) {
      delta = delta || (Browser.any3d ? this.options.zoomDelta : 1);
      return this.setZoom(this._zoom + delta, options);
    },
    // @method zoomOut(delta?: Number, options?: Zoom options): this
    // Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
    zoomOut: function (delta, options) {
      delta = delta || (Browser.any3d ? this.options.zoomDelta : 1);
      return this.setZoom(this._zoom - delta, options);
    },
    // @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this
    // Zooms the map while keeping a specified geographical point on the map
    // stationary (e.g. used internally for scroll zoom and double-click zoom).
    // @alternative
    // @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this
    // Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary.
    setZoomAround: function (latlng, zoom, options) {
      var scale = this.getZoomScale(zoom),
        viewHalf = this.getSize().divideBy(2),
        containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng),
        centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),
        newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));
      return this.setView(newCenter, zoom, {
        zoom: options
      });
    },
    _getBoundsCenterZoom: function (bounds, options) {
      options = options || {};
      bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds);
      var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),
        paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),
        zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
      zoom = typeof options.maxZoom === 'number' ? Math.min(options.maxZoom, zoom) : zoom;
      if (zoom === Infinity) {
        return {
          center: bounds.getCenter(),
          zoom: zoom
        };
      }
      var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),
        swPoint = this.project(bounds.getSouthWest(), zoom),
        nePoint = this.project(bounds.getNorthEast(), zoom),
        center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
      return {
        center: center,
        zoom: zoom
      };
    },
    // @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this
    // Sets a map view that contains the given geographical bounds with the
    // maximum zoom level possible.
    fitBounds: function (bounds, options) {
      bounds = toLatLngBounds(bounds);
      if (!bounds.isValid()) {
        throw new Error('Bounds are not valid.');
      }
      var target = this._getBoundsCenterZoom(bounds, options);
      return this.setView(target.center, target.zoom, options);
    },
    // @method fitWorld(options?: fitBounds options): this
    // Sets a map view that mostly contains the whole world with the maximum
    // zoom level possible.
    fitWorld: function (options) {
      return this.fitBounds([[-90, -180], [90, 180]], options);
    },
    // @method panTo(latlng: LatLng, options?: Pan options): this
    // Pans the map to a given center.
    panTo: function (center, options) {
      // (LatLng)
      return this.setView(center, this._zoom, {
        pan: options
      });
    },
    // @method panBy(offset: Point, options?: Pan options): this
    // Pans the map by a given number of pixels (animated).
    panBy: function (offset, options) {
      offset = toPoint(offset).round();
      options = options || {};
      if (!offset.x && !offset.y) {
        return this.fire('moveend');
      }
      // If we pan too far, Chrome gets issues with tiles
      // and makes them disappear or appear in the wrong place (slightly offset) #2602
      if (options.animate !== true && !this.getSize().contains(offset)) {
        this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom());
        return this;
      }
      if (!this._panAnim) {
        this._panAnim = new PosAnimation();
        this._panAnim.on({
          'step': this._onPanTransitionStep,
          'end': this._onPanTransitionEnd
        }, this);
      }

      // don't fire movestart if animating inertia
      if (!options.noMoveStart) {
        this.fire('movestart');
      }

      // animate pan unless animate: false specified
      if (options.animate !== false) {
        addClass(this._mapPane, 'leaflet-pan-anim');
        var newPos = this._getMapPanePos().subtract(offset).round();
        this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity);
      } else {
        this._rawPanBy(offset);
        this.fire('move').fire('moveend');
      }
      return this;
    },
    // @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this
    // Sets the view of the map (geographical center and zoom) performing a smooth
    // pan-zoom animation.
    flyTo: function (targetCenter, targetZoom, options) {
      options = options || {};
      if (options.animate === false || !Browser.any3d) {
        return this.setView(targetCenter, targetZoom, options);
      }
      this._stop();
      var from = this.project(this.getCenter()),
        to = this.project(targetCenter),
        size = this.getSize(),
        startZoom = this._zoom;
      targetCenter = toLatLng(targetCenter);
      targetZoom = targetZoom === undefined ? startZoom : targetZoom;
      var w0 = Math.max(size.x, size.y),
        w1 = w0 * this.getZoomScale(startZoom, targetZoom),
        u1 = to.distanceTo(from) || 1,
        rho = 1.42,
        rho2 = rho * rho;
      function r(i) {
        var s1 = i ? -1 : 1,
          s2 = i ? w1 : w0,
          t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1,
          b1 = 2 * s2 * rho2 * u1,
          b = t1 / b1,
          sq = Math.sqrt(b * b + 1) - b;

        // workaround for floating point precision bug when sq = 0, log = -Infinite,
        // thus triggering an infinite loop in flyTo
        var log = sq < 0.000000001 ? -18 : Math.log(sq);
        return log;
      }
      function sinh(n) {
        return (Math.exp(n) - Math.exp(-n)) / 2;
      }
      function cosh(n) {
        return (Math.exp(n) + Math.exp(-n)) / 2;
      }
      function tanh(n) {
        return sinh(n) / cosh(n);
      }
      var r0 = r(0);
      function w(s) {
        return w0 * (cosh(r0) / cosh(r0 + rho * s));
      }
      function u(s) {
        return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2;
      }
      function easeOut(t) {
        return 1 - Math.pow(1 - t, 1.5);
      }
      var start = Date.now(),
        S = (r(1) - r0) / rho,
        duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8;
      function frame() {
        var t = (Date.now() - start) / duration,
          s = easeOut(t) * S;
        if (t <= 1) {
          this._flyToFrame = requestAnimFrame(frame, this);
          this._move(this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom), this.getScaleZoom(w0 / w(s), startZoom), {
            flyTo: true
          });
        } else {
          this._move(targetCenter, targetZoom)._moveEnd(true);
        }
      }
      this._moveStart(true, options.noMoveStart);
      frame.call(this);
      return this;
    },
    // @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this
    // Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto),
    // but takes a bounds parameter like [`fitBounds`](#map-fitbounds).
    flyToBounds: function (bounds, options) {
      var target = this._getBoundsCenterZoom(bounds, options);
      return this.flyTo(target.center, target.zoom, options);
    },
    // @method setMaxBounds(bounds: LatLngBounds): this
    // Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option).
    setMaxBounds: function (bounds) {
      bounds = toLatLngBounds(bounds);
      if (this.listens('moveend', this._panInsideMaxBounds)) {
        this.off('moveend', this._panInsideMaxBounds);
      }
      if (!bounds.isValid()) {
        this.options.maxBounds = null;
        return this;
      }
      this.options.maxBounds = bounds;
      if (this._loaded) {
        this._panInsideMaxBounds();
      }
      return this.on('moveend', this._panInsideMaxBounds);
    },
    // @method setMinZoom(zoom: Number): this
    // Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option).
    setMinZoom: function (zoom) {
      var oldZoom = this.options.minZoom;
      this.options.minZoom = zoom;
      if (this._loaded && oldZoom !== zoom) {
        this.fire('zoomlevelschange');
        if (this.getZoom() < this.options.minZoom) {
          return this.setZoom(zoom);
        }
      }
      return this;
    },
    // @method setMaxZoom(zoom: Number): this
    // Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option).
    setMaxZoom: function (zoom) {
      var oldZoom = this.options.maxZoom;
      this.options.maxZoom = zoom;
      if (this._loaded && oldZoom !== zoom) {
        this.fire('zoomlevelschange');
        if (this.getZoom() > this.options.maxZoom) {
          return this.setZoom(zoom);
        }
      }
      return this;
    },
    // @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this
    // Pans the map to the closest view that would lie inside the given bounds (if it's not already), controlling the animation using the options specific, if any.
    panInsideBounds: function (bounds, options) {
      this._enforcingBounds = true;
      var center = this.getCenter(),
        newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds));
      if (!center.equals(newCenter)) {
        this.panTo(newCenter, options);
      }
      this._enforcingBounds = false;
      return this;
    },
    // @method panInside(latlng: LatLng, options?: padding options): this
    // Pans the map the minimum amount to make the `latlng` visible. Use
    // padding options to fit the display to more restricted bounds.
    // If `latlng` is already within the (optionally padded) display bounds,
    // the map will not be panned.
    panInside: function (latlng, options) {
      options = options || {};
      var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),
        paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),
        pixelCenter = this.project(this.getCenter()),
        pixelPoint = this.project(latlng),
        pixelBounds = this.getPixelBounds(),
        paddedBounds = toBounds([pixelBounds.min.add(paddingTL), pixelBounds.max.subtract(paddingBR)]),
        paddedSize = paddedBounds.getSize();
      if (!paddedBounds.contains(pixelPoint)) {
        this._enforcingBounds = true;
        var centerOffset = pixelPoint.subtract(paddedBounds.getCenter());
        var offset = paddedBounds.extend(pixelPoint).getSize().subtract(paddedSize);
        pixelCenter.x += centerOffset.x < 0 ? -offset.x : offset.x;
        pixelCenter.y += centerOffset.y < 0 ? -offset.y : offset.y;
        this.panTo(this.unproject(pixelCenter), options);
        this._enforcingBounds = false;
      }
      return this;
    },
    // @method invalidateSize(options: Zoom/pan options): this
    // Checks if the map container size changed and updates the map if so —
    // call it after you've changed the map size dynamically, also animating
    // pan by default. If `options.pan` is `false`, panning will not occur.
    // If `options.debounceMoveend` is `true`, it will delay `moveend` event so
    // that it doesn't happen often even if the method is called many
    // times in a row.

    // @alternative
    // @method invalidateSize(animate: Boolean): this
    // Checks if the map container size changed and updates the map if so —
    // call it after you've changed the map size dynamically, also animating
    // pan by default.
    invalidateSize: function (options) {
      if (!this._loaded) {
        return this;
      }
      options = extend({
        animate: false,
        pan: true
      }, options === true ? {
        animate: true
      } : options);
      var oldSize = this.getSize();
      this._sizeChanged = true;
      this._lastCenter = null;
      var newSize = this.getSize(),
        oldCenter = oldSize.divideBy(2).round(),
        newCenter = newSize.divideBy(2).round(),
        offset = oldCenter.subtract(newCenter);
      if (!offset.x && !offset.y) {
        return this;
      }
      if (options.animate && options.pan) {
        this.panBy(offset);
      } else {
        if (options.pan) {
          this._rawPanBy(offset);
        }
        this.fire('move');
        if (options.debounceMoveend) {
          clearTimeout(this._sizeTimer);
          this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200);
        } else {
          this.fire('moveend');
        }
      }

      // @section Map state change events
      // @event resize: ResizeEvent
      // Fired when the map is resized.
      return this.fire('resize', {
        oldSize: oldSize,
        newSize: newSize
      });
    },
    // @section Methods for modifying map state
    // @method stop(): this
    // Stops the currently running `panTo` or `flyTo` animation, if any.
    stop: function () {
      this.setZoom(this._limitZoom(this._zoom));
      if (!this.options.zoomSnap) {
        this.fire('viewreset');
      }
      return this._stop();
    },
    // @section Geolocation methods
    // @method locate(options?: Locate options): this
    // Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)
    // event with location data on success or a [`locationerror`](#map-locationerror) event on failure,
    // and optionally sets the map view to the user's location with respect to
    // detection accuracy (or to the world view if geolocation failed).
    // Note that, if your page doesn't use HTTPS, this method will fail in
    // modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))
    // See `Locate options` for more details.
    locate: function (options) {
      options = this._locateOptions = extend({
        timeout: 10000,
        watch: false
        // setView: false
        // maxZoom: <Number>
        // maximumAge: 0
        // enableHighAccuracy: false
      }, options);
      if (!('geolocation' in navigator)) {
        this._handleGeolocationError({
          code: 0,
          message: 'Geolocation not supported.'
        });
        return this;
      }
      var onResponse = bind(this._handleGeolocationResponse, this),
        onError = bind(this._handleGeolocationError, this);
      if (options.watch) {
        this._locationWatchId = navigator.geolocation.watchPosition(onResponse, onError, options);
      } else {
        navigator.geolocation.getCurrentPosition(onResponse, onError, options);
      }
      return this;
    },
    // @method stopLocate(): this
    // Stops watching location previously initiated by `map.locate({watch: true})`
    // and aborts resetting the map view if map.locate was called with
    // `{setView: true}`.
    stopLocate: function () {
      if (navigator.geolocation && navigator.geolocation.clearWatch) {
        navigator.geolocation.clearWatch(this._locationWatchId);
      }
      if (this._locateOptions) {
        this._locateOptions.setView = false;
      }
      return this;
    },
    _handleGeolocationError: function (error) {
      if (!this._container._leaflet_id) {
        return;
      }
      var c = error.code,
        message = error.message || (c === 1 ? 'permission denied' : c === 2 ? 'position unavailable' : 'timeout');
      if (this._locateOptions.setView && !this._loaded) {
        this.fitWorld();
      }

      // @section Location events
      // @event locationerror: ErrorEvent
      // Fired when geolocation (using the [`locate`](#map-locate) method) failed.
      this.fire('locationerror', {
        code: c,
        message: 'Geolocation error: ' + message + '.'
      });
    },
    _handleGeolocationResponse: function (pos) {
      if (!this._container._leaflet_id) {
        return;
      }
      var lat = pos.coords.latitude,
        lng = pos.coords.longitude,
        latlng = new LatLng(lat, lng),
        bounds = latlng.toBounds(pos.coords.accuracy * 2),
        options = this._locateOptions;
      if (options.setView) {
        var zoom = this.getBoundsZoom(bounds);
        this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
      }
      var data = {
        latlng: latlng,
        bounds: bounds,
        timestamp: pos.timestamp
      };
      for (var i in pos.coords) {
        if (typeof pos.coords[i] === 'number') {
          data[i] = pos.coords[i];
        }
      }

      // @event locationfound: LocationEvent
      // Fired when geolocation (using the [`locate`](#map-locate) method)
      // went successfully.
      this.fire('locationfound', data);
    },
    // TODO Appropriate docs section?
    // @section Other Methods
    // @method addHandler(name: String, HandlerClass: Function): this
    // Adds a new `Handler` to the map, given its name and constructor function.
    addHandler: function (name, HandlerClass) {
      if (!HandlerClass) {
        return this;
      }
      var handler = this[name] = new HandlerClass(this);
      this._handlers.push(handler);
      if (this.options[name]) {
        handler.enable();
      }
      return this;
    },
    // @method remove(): this
    // Destroys the map and clears all related event listeners.
    remove: function () {
      this._initEvents(true);
      if (this.options.maxBounds) {
        this.off('moveend', this._panInsideMaxBounds);
      }
      if (this._containerId !== this._container._leaflet_id) {
        throw new Error('Map container is being reused by another instance');
      }
      try {
        // throws error in IE6-8
        delete this._container._leaflet_id;
        delete this._containerId;
      } catch (e) {
        /*eslint-disable */
        this._container._leaflet_id = undefined;
        /* eslint-enable */
        this._containerId = undefined;
      }
      if (this._locationWatchId !== undefined) {
        this.stopLocate();
      }
      this._stop();
      remove(this._mapPane);
      if (this._clearControlPos) {
        this._clearControlPos();
      }
      if (this._resizeRequest) {
        cancelAnimFrame(this._resizeRequest);
        this._resizeRequest = null;
      }
      this._clearHandlers();
      if (this._loaded) {
        // @section Map state change events
        // @event unload: Event
        // Fired when the map is destroyed with [remove](#map-remove) method.
        this.fire('unload');
      }
      var i;
      for (i in this._layers) {
        this._layers[i].remove();
      }
      for (i in this._panes) {
        remove(this._panes[i]);
      }
      this._layers = [];
      this._panes = [];
      delete this._mapPane;
      delete this._renderer;
      return this;
    },
    // @section Other Methods
    // @method createPane(name: String, container?: HTMLElement): HTMLElement
    // Creates a new [map pane](#map-pane) with the given name if it doesn't exist already,
    // then returns it. The pane is created as a child of `container`, or
    // as a child of the main map pane if not set.
    createPane: function (name, container) {
      var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''),
        pane = create$1('div', className, container || this._mapPane);
      if (name) {
        this._panes[name] = pane;
      }
      return pane;
    },
    // @section Methods for Getting Map State

    // @method getCenter(): LatLng
    // Returns the geographical center of the map view
    getCenter: function () {
      this._checkIfLoaded();
      if (this._lastCenter && !this._moved()) {
        return this._lastCenter.clone();
      }
      return this.layerPointToLatLng(this._getCenterLayerPoint());
    },
    // @method getZoom(): Number
    // Returns the current zoom level of the map view
    getZoom: function () {
      return this._zoom;
    },
    // @method getBounds(): LatLngBounds
    // Returns the geographical bounds visible in the current map view
    getBounds: function () {
      var bounds = this.getPixelBounds(),
        sw = this.unproject(bounds.getBottomLeft()),
        ne = this.unproject(bounds.getTopRight());
      return new LatLngBounds(sw, ne);
    },
    // @method getMinZoom(): Number
    // Returns the minimum zoom level of the map (if set in the `minZoom` option of the map or of any layers), or `0` by default.
    getMinZoom: function () {
      return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom;
    },
    // @method getMaxZoom(): Number
    // Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers).
    getMaxZoom: function () {
      return this.options.maxZoom === undefined ? this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom : this.options.maxZoom;
    },
    // @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number
    // Returns the maximum zoom level on which the given bounds fit to the map
    // view in its entirety. If `inside` (optional) is set to `true`, the method
    // instead returns the minimum zoom level on which the map view fits into
    // the given bounds in its entirety.
    getBoundsZoom: function (bounds, inside, padding) {
      // (LatLngBounds[, Boolean, Point]) -> Number
      bounds = toLatLngBounds(bounds);
      padding = toPoint(padding || [0, 0]);
      var zoom = this.getZoom() || 0,
        min = this.getMinZoom(),
        max = this.getMaxZoom(),
        nw = bounds.getNorthWest(),
        se = bounds.getSouthEast(),
        size = this.getSize().subtract(padding),
        boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),
        snap = Browser.any3d ? this.options.zoomSnap : 1,
        scalex = size.x / boundsSize.x,
        scaley = size.y / boundsSize.y,
        scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley);
      zoom = this.getScaleZoom(scale, zoom);
      if (snap) {
        zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
        zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
      }
      return Math.max(min, Math.min(max, zoom));
    },
    // @method getSize(): Point
    // Returns the current size of the map container (in pixels).
    getSize: function () {
      if (!this._size || this._sizeChanged) {
        this._size = new Point(this._container.clientWidth || 0, this._container.clientHeight || 0);
        this._sizeChanged = false;
      }
      return this._size.clone();
    },
    // @method getPixelBounds(): Bounds
    // Returns the bounds of the current map view in projected pixel
    // coordinates (sometimes useful in layer and overlay implementations).
    getPixelBounds: function (center, zoom) {
      var topLeftPoint = this._getTopLeftPoint(center, zoom);
      return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
    },
    // TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to
    // the map pane? "left point of the map layer" can be confusing, specially
    // since there can be negative offsets.
    // @method getPixelOrigin(): Point
    // Returns the projected pixel coordinates of the top left point of
    // the map layer (useful in custom layer and overlay implementations).
    getPixelOrigin: function () {
      this._checkIfLoaded();
      return this._pixelOrigin;
    },
    // @method getPixelWorldBounds(zoom?: Number): Bounds
    // Returns the world's bounds in pixel coordinates for zoom level `zoom`.
    // If `zoom` is omitted, the map's current zoom level is used.
    getPixelWorldBounds: function (zoom) {
      return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom);
    },
    // @section Other Methods

    // @method getPane(pane: String|HTMLElement): HTMLElement
    // Returns a [map pane](#map-pane), given its name or its HTML element (its identity).
    getPane: function (pane) {
      return typeof pane === 'string' ? this._panes[pane] : pane;
    },
    // @method getPanes(): Object
    // Returns a plain object containing the names of all [panes](#map-pane) as keys and
    // the panes as values.
    getPanes: function () {
      return this._panes;
    },
    // @method getContainer: HTMLElement
    // Returns the HTML element that contains the map.
    getContainer: function () {
      return this._container;
    },
    // @section Conversion Methods

    // @method getZoomScale(toZoom: Number, fromZoom: Number): Number
    // Returns the scale factor to be applied to a map transition from zoom level
    // `fromZoom` to `toZoom`. Used internally to help with zoom animations.
    getZoomScale: function (toZoom, fromZoom) {
      // TODO replace with universal implementation after refactoring projections
      var crs = this.options.crs;
      fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
      return crs.scale(toZoom) / crs.scale(fromZoom);
    },
    // @method getScaleZoom(scale: Number, fromZoom: Number): Number
    // Returns the zoom level that the map would end up at, if it is at `fromZoom`
    // level and everything is scaled by a factor of `scale`. Inverse of
    // [`getZoomScale`](#map-getZoomScale).
    getScaleZoom: function (scale, fromZoom) {
      var crs = this.options.crs;
      fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
      var zoom = crs.zoom(scale * crs.scale(fromZoom));
      return isNaN(zoom) ? Infinity : zoom;
    },
    // @method project(latlng: LatLng, zoom: Number): Point
    // Projects a geographical coordinate `LatLng` according to the projection
    // of the map's CRS, then scales it according to `zoom` and the CRS's
    // `Transformation`. The result is pixel coordinate relative to
    // the CRS origin.
    project: function (latlng, zoom) {
      zoom = zoom === undefined ? this._zoom : zoom;
      return this.options.crs.latLngToPoint(toLatLng(latlng), zoom);
    },
    // @method unproject(point: Point, zoom: Number): LatLng
    // Inverse of [`project`](#map-project).
    unproject: function (point, zoom) {
      zoom = zoom === undefined ? this._zoom : zoom;
      return this.options.crs.pointToLatLng(toPoint(point), zoom);
    },
    // @method layerPointToLatLng(point: Point): LatLng
    // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
    // returns the corresponding geographical coordinate (for the current zoom level).
    layerPointToLatLng: function (point) {
      var projectedPoint = toPoint(point).add(this.getPixelOrigin());
      return this.unproject(projectedPoint);
    },
    // @method latLngToLayerPoint(latlng: LatLng): Point
    // Given a geographical coordinate, returns the corresponding pixel coordinate
    // relative to the [origin pixel](#map-getpixelorigin).
    latLngToLayerPoint: function (latlng) {
      var projectedPoint = this.project(toLatLng(latlng))._round();
      return projectedPoint._subtract(this.getPixelOrigin());
    },
    // @method wrapLatLng(latlng: LatLng): LatLng
    // Returns a `LatLng` where `lat` and `lng` has been wrapped according to the
    // map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the
    // CRS's bounds.
    // By default this means longitude is wrapped around the dateline so its
    // value is between -180 and +180 degrees.
    wrapLatLng: function (latlng) {
      return this.options.crs.wrapLatLng(toLatLng(latlng));
    },
    // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
    // Returns a `LatLngBounds` with the same size as the given one, ensuring that
    // its center is within the CRS's bounds.
    // By default this means the center longitude is wrapped around the dateline so its
    // value is between -180 and +180 degrees, and the majority of the bounds
    // overlaps the CRS's bounds.
    wrapLatLngBounds: function (latlng) {
      return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng));
    },
    // @method distance(latlng1: LatLng, latlng2: LatLng): Number
    // Returns the distance between two geographical coordinates according to
    // the map's CRS. By default this measures distance in meters.
    distance: function (latlng1, latlng2) {
      return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2));
    },
    // @method containerPointToLayerPoint(point: Point): Point
    // Given a pixel coordinate relative to the map container, returns the corresponding
    // pixel coordinate relative to the [origin pixel](#map-getpixelorigin).
    containerPointToLayerPoint: function (point) {
      // (Point)
      return toPoint(point).subtract(this._getMapPanePos());
    },
    // @method layerPointToContainerPoint(point: Point): Point
    // Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
    // returns the corresponding pixel coordinate relative to the map container.
    layerPointToContainerPoint: function (point) {
      // (Point)
      return toPoint(point).add(this._getMapPanePos());
    },
    // @method containerPointToLatLng(point: Point): LatLng
    // Given a pixel coordinate relative to the map container, returns
    // the corresponding geographical coordinate (for the current zoom level).
    containerPointToLatLng: function (point) {
      var layerPoint = this.containerPointToLayerPoint(toPoint(point));
      return this.layerPointToLatLng(layerPoint);
    },
    // @method latLngToContainerPoint(latlng: LatLng): Point
    // Given a geographical coordinate, returns the corresponding pixel coordinate
    // relative to the map container.
    latLngToContainerPoint: function (latlng) {
      return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));
    },
    // @method mouseEventToContainerPoint(ev: MouseEvent): Point
    // Given a MouseEvent object, returns the pixel coordinate relative to the
    // map container where the event took place.
    mouseEventToContainerPoint: function (e) {
      return getMousePosition(e, this._container);
    },
    // @method mouseEventToLayerPoint(ev: MouseEvent): Point
    // Given a MouseEvent object, returns the pixel coordinate relative to
    // the [origin pixel](#map-getpixelorigin) where the event took place.
    mouseEventToLayerPoint: function (e) {
      return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));
    },
    // @method mouseEventToLatLng(ev: MouseEvent): LatLng
    // Given a MouseEvent object, returns geographical coordinate where the
    // event took place.
    mouseEventToLatLng: function (e) {
      // (MouseEvent)
      return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));
    },
    // map initialization methods

    _initContainer: function (id) {
      var container = this._container = get(id);
      if (!container) {
        throw new Error('Map container not found.');
      } else if (container._leaflet_id) {
        throw new Error('Map container is already initialized.');
      }
      on(container, 'scroll', this._onScroll, this);
      this._containerId = stamp(container);
    },
    _initLayout: function () {
      var container = this._container;
      this._fadeAnimated = this.options.fadeAnimation && Browser.any3d;
      addClass(container, 'leaflet-container' + (Browser.touch ? ' leaflet-touch' : '') + (Browser.retina ? ' leaflet-retina' : '') + (Browser.ielt9 ? ' leaflet-oldie' : '') + (Browser.safari ? ' leaflet-safari' : '') + (this._fadeAnimated ? ' leaflet-fade-anim' : ''));
      var position = getStyle(container, 'position');
      if (position !== 'absolute' && position !== 'relative' && position !== 'fixed' && position !== 'sticky') {
        container.style.position = 'relative';
      }
      this._initPanes();
      if (this._initControlPos) {
        this._initControlPos();
      }
    },
    _initPanes: function () {
      var panes = this._panes = {};
      this._paneRenderers = {};

      // @section
      //
      // Panes are DOM elements used to control the ordering of layers on the map. You
      // can access panes with [`map.getPane`](#map-getpane) or
      // [`map.getPanes`](#map-getpanes) methods. New panes can be created with the
      // [`map.createPane`](#map-createpane) method.
      //
      // Every map has the following default panes that differ only in zIndex.
      //
      // @pane mapPane: HTMLElement = 'auto'
      // Pane that contains all other map panes

      this._mapPane = this.createPane('mapPane', this._container);
      setPosition(this._mapPane, new Point(0, 0));

      // @pane tilePane: HTMLElement = 200
      // Pane for `GridLayer`s and `TileLayer`s
      this.createPane('tilePane');
      // @pane overlayPane: HTMLElement = 400
      // Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s
      this.createPane('overlayPane');
      // @pane shadowPane: HTMLElement = 500
      // Pane for overlay shadows (e.g. `Marker` shadows)
      this.createPane('shadowPane');
      // @pane markerPane: HTMLElement = 600
      // Pane for `Icon`s of `Marker`s
      this.createPane('markerPane');
      // @pane tooltipPane: HTMLElement = 650
      // Pane for `Tooltip`s.
      this.createPane('tooltipPane');
      // @pane popupPane: HTMLElement = 700
      // Pane for `Popup`s.
      this.createPane('popupPane');
      if (!this.options.markerZoomAnimation) {
        addClass(panes.markerPane, 'leaflet-zoom-hide');
        addClass(panes.shadowPane, 'leaflet-zoom-hide');
      }
    },
    // private methods that modify map state

    // @section Map state change events
    _resetView: function (center, zoom, noMoveStart) {
      setPosition(this._mapPane, new Point(0, 0));
      var loading = !this._loaded;
      this._loaded = true;
      zoom = this._limitZoom(zoom);
      this.fire('viewprereset');
      var zoomChanged = this._zoom !== zoom;
      this._moveStart(zoomChanged, noMoveStart)._move(center, zoom)._moveEnd(zoomChanged);

      // @event viewreset: Event
      // Fired when the map needs to redraw its content (this usually happens
      // on map zoom or load). Very useful for creating custom overlays.
      this.fire('viewreset');

      // @event load: Event
      // Fired when the map is initialized (when its center and zoom are set
      // for the first time).
      if (loading) {
        this.fire('load');
      }
    },
    _moveStart: function (zoomChanged, noMoveStart) {
      // @event zoomstart: Event
      // Fired when the map zoom is about to change (e.g. before zoom animation).
      // @event movestart: Event
      // Fired when the view of the map starts changing (e.g. user starts dragging the map).
      if (zoomChanged) {
        this.fire('zoomstart');
      }
      if (!noMoveStart) {
        this.fire('movestart');
      }
      return this;
    },
    _move: function (center, zoom, data, supressEvent) {
      if (zoom === undefined) {
        zoom = this._zoom;
      }
      var zoomChanged = this._zoom !== zoom;
      this._zoom = zoom;
      this._lastCenter = center;
      this._pixelOrigin = this._getNewPixelOrigin(center);
      if (!supressEvent) {
        // @event zoom: Event
        // Fired repeatedly during any change in zoom level,
        // including zoom and fly animations.
        if (zoomChanged || data && data.pinch) {
          // Always fire 'zoom' if pinching because #3530
          this.fire('zoom', data);
        }

        // @event move: Event
        // Fired repeatedly during any movement of the map,
        // including pan and fly animations.
        this.fire('move', data);
      } else if (data && data.pinch) {
        // Always fire 'zoom' if pinching because #3530
        this.fire('zoom', data);
      }
      return this;
    },
    _moveEnd: function (zoomChanged) {
      // @event zoomend: Event
      // Fired when the map zoom changed, after any animations.
      if (zoomChanged) {
        this.fire('zoomend');
      }

      // @event moveend: Event
      // Fired when the center of the map stops changing
      // (e.g. user stopped dragging the map or after non-centered zoom).
      return this.fire('moveend');
    },
    _stop: function () {
      cancelAnimFrame(this._flyToFrame);
      if (this._panAnim) {
        this._panAnim.stop();
      }
      return this;
    },
    _rawPanBy: function (offset) {
      setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
    },
    _getZoomSpan: function () {
      return this.getMaxZoom() - this.getMinZoom();
    },
    _panInsideMaxBounds: function () {
      if (!this._enforcingBounds) {
        this.panInsideBounds(this.options.maxBounds);
      }
    },
    _checkIfLoaded: function () {
      if (!this._loaded) {
        throw new Error('Set map center and zoom first.');
      }
    },
    // DOM event handling

    // @section Interaction events
    _initEvents: function (remove) {
      this._targets = {};
      this._targets[stamp(this._container)] = this;
      var onOff = remove ? off : on;

      // @event click: MouseEvent
      // Fired when the user clicks (or taps) the map.
      // @event dblclick: MouseEvent
      // Fired when the user double-clicks (or double-taps) the map.
      // @event mousedown: MouseEvent
      // Fired when the user pushes the mouse button on the map.
      // @event mouseup: MouseEvent
      // Fired when the user releases the mouse button on the map.
      // @event mouseover: MouseEvent
      // Fired when the mouse enters the map.
      // @event mouseout: MouseEvent
      // Fired when the mouse leaves the map.
      // @event mousemove: MouseEvent
      // Fired while the mouse moves over the map.
      // @event contextmenu: MouseEvent
      // Fired when the user pushes the right mouse button on the map, prevents
      // default browser context menu from showing if there are listeners on
      // this event. Also fired on mobile when the user holds a single touch
      // for a second (also called long press).
      // @event keypress: KeyboardEvent
      // Fired when the user presses a key from the keyboard that produces a character value while the map is focused.
      // @event keydown: KeyboardEvent
      // Fired when the user presses a key from the keyboard while the map is focused. Unlike the `keypress` event,
      // the `keydown` event is fired for keys that produce a character value and for keys
      // that do not produce a character value.
      // @event keyup: KeyboardEvent
      // Fired when the user releases a key from the keyboard while the map is focused.
      onOff(this._container, 'click dblclick mousedown mouseup ' + 'mouseover mouseout mousemove contextmenu keypress keydown keyup', this._handleDOMEvent, this);
      if (this.options.trackResize) {
        onOff(window, 'resize', this._onResize, this);
      }
      if (Browser.any3d && this.options.transform3DLimit) {
        (remove ? this.off : this.on).call(this, 'moveend', this._onMoveEnd);
      }
    },
    _onResize: function () {
      cancelAnimFrame(this._resizeRequest);
      this._resizeRequest = requestAnimFrame(function () {
        this.invalidateSize({
          debounceMoveend: true
        });
      }, this);
    },
    _onScroll: function () {
      this._container.scrollTop = 0;
      this._container.scrollLeft = 0;
    },
    _onMoveEnd: function () {
      var pos = this._getMapPanePos();
      if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) {
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have
        // a pixel offset on very high values, see: https://jsfiddle.net/dg6r5hhb/
        this._resetView(this.getCenter(), this.getZoom());
      }
    },
    _findEventTargets: function (e, type) {
      var targets = [],
        target,
        isHover = type === 'mouseout' || type === 'mouseover',
        src = e.target || e.srcElement,
        dragging = false;
      while (src) {
        target = this._targets[stamp(src)];
        if (target && (type === 'click' || type === 'preclick') && this._draggableMoved(target)) {
          // Prevent firing click after you just dragged an object.
          dragging = true;
          break;
        }
        if (target && target.listens(type, true)) {
          if (isHover && !isExternalTarget(src, e)) {
            break;
          }
          targets.push(target);
          if (isHover) {
            break;
          }
        }
        if (src === this._container) {
          break;
        }
        src = src.parentNode;
      }
      if (!targets.length && !dragging && !isHover && this.listens(type, true)) {
        targets = [this];
      }
      return targets;
    },
    _isClickDisabled: function (el) {
      while (el && el !== this._container) {
        if (el['_leaflet_disable_click']) {
          return true;
        }
        el = el.parentNode;
      }
    },
    _handleDOMEvent: function (e) {
      var el = e.target || e.srcElement;
      if (!this._loaded || el['_leaflet_disable_events'] || e.type === 'click' && this._isClickDisabled(el)) {
        return;
      }
      var type = e.type;
      if (type === 'mousedown') {
        // prevents outline when clicking on keyboard-focusable element
        preventOutline(el);
      }
      this._fireDOMEvent(e, type);
    },
    _mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'],
    _fireDOMEvent: function (e, type, canvasTargets) {
      if (e.type === 'click') {
        // Fire a synthetic 'preclick' event which propagates up (mainly for closing popups).
        // @event preclick: MouseEvent
        // Fired before mouse click on the map (sometimes useful when you
        // want something to happen on click before any existing click
        // handlers start running).
        var synth = extend({}, e);
        synth.type = 'preclick';
        this._fireDOMEvent(synth, synth.type, canvasTargets);
      }

      // Find the layer the event is propagating from and its parents.
      var targets = this._findEventTargets(e, type);
      if (canvasTargets) {
        var filtered = []; // pick only targets with listeners
        for (var i = 0; i < canvasTargets.length; i++) {
          if (canvasTargets[i].listens(type, true)) {
            filtered.push(canvasTargets[i]);
          }
        }
        targets = filtered.concat(targets);
      }
      if (!targets.length) {
        return;
      }
      if (type === 'contextmenu') {
        preventDefault(e);
      }
      var target = targets[0];
      var data = {
        originalEvent: e
      };
      if (e.type !== 'keypress' && e.type !== 'keydown' && e.type !== 'keyup') {
        var isMarker = target.getLatLng && (!target._radius || target._radius <= 10);
        data.containerPoint = isMarker ? this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);
        data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);
        data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint);
      }
      for (i = 0; i < targets.length; i++) {
        targets[i].fire(type, data, true);
        if (data.originalEvent._stopped || targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1) {
          return;
        }
      }
    },
    _draggableMoved: function (obj) {
      obj = obj.dragging && obj.dragging.enabled() ? obj : this;
      return obj.dragging && obj.dragging.moved() || this.boxZoom && this.boxZoom.moved();
    },
    _clearHandlers: function () {
      for (var i = 0, len = this._handlers.length; i < len; i++) {
        this._handlers[i].disable();
      }
    },
    // @section Other Methods

    // @method whenReady(fn: Function, context?: Object): this
    // Runs the given function `fn` when the map gets initialized with
    // a view (center and zoom) and at least one layer, or immediately
    // if it's already initialized, optionally passing a function context.
    whenReady: function (callback, context) {
      if (this._loaded) {
        callback.call(context || this, {
          target: this
        });
      } else {
        this.on('load', callback, context);
      }
      return this;
    },
    // private methods for getting map state

    _getMapPanePos: function () {
      return getPosition(this._mapPane) || new Point(0, 0);
    },
    _moved: function () {
      var pos = this._getMapPanePos();
      return pos && !pos.equals([0, 0]);
    },
    _getTopLeftPoint: function (center, zoom) {
      var pixelOrigin = center && zoom !== undefined ? this._getNewPixelOrigin(center, zoom) : this.getPixelOrigin();
      return pixelOrigin.subtract(this._getMapPanePos());
    },
    _getNewPixelOrigin: function (center, zoom) {
      var viewHalf = this.getSize()._divideBy(2);
      return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round();
    },
    _latLngToNewLayerPoint: function (latlng, zoom, center) {
      var topLeft = this._getNewPixelOrigin(center, zoom);
      return this.project(latlng, zoom)._subtract(topLeft);
    },
    _latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) {
      var topLeft = this._getNewPixelOrigin(center, zoom);
      return toBounds([this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft), this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft), this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft), this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft)]);
    },
    // layer point of the current center
    _getCenterLayerPoint: function () {
      return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
    },
    // offset of the specified place to the current center in pixels
    _getCenterOffset: function (latlng) {
      return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
    },
    // adjust center for view to get inside bounds
    _limitCenter: function (center, zoom, bounds) {
      if (!bounds) {
        return center;
      }
      var centerPoint = this.project(center, zoom),
        viewHalf = this.getSize().divideBy(2),
        viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
        offset = this._getBoundsOffset(viewBounds, bounds, zoom);

      // If offset is less than a pixel, ignore.
      // This prevents unstable projections from getting into
      // an infinite loop of tiny offsets.
      if (Math.abs(offset.x) <= 1 && Math.abs(offset.y) <= 1) {
        return center;
      }
      return this.unproject(centerPoint.add(offset), zoom);
    },
    // adjust offset for view to get inside bounds
    _limitOffset: function (offset, bounds) {
      if (!bounds) {
        return offset;
      }
      var viewBounds = this.getPixelBounds(),
        newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));
      return offset.add(this._getBoundsOffset(newBounds, bounds));
    },
    // returns offset needed for pxBounds to get inside maxBounds at a specified zoom
    _getBoundsOffset: function (pxBounds, maxBounds, zoom) {
      var projectedMaxBounds = toBounds(this.project(maxBounds.getNorthEast(), zoom), this.project(maxBounds.getSouthWest(), zoom)),
        minOffset = projectedMaxBounds.min.subtract(pxBounds.min),
        maxOffset = projectedMaxBounds.max.subtract(pxBounds.max),
        dx = this._rebound(minOffset.x, -maxOffset.x),
        dy = this._rebound(minOffset.y, -maxOffset.y);
      return new Point(dx, dy);
    },
    _rebound: function (left, right) {
      return left + right > 0 ? Math.round(left - right) / 2 : Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right));
    },
    _limitZoom: function (zoom) {
      var min = this.getMinZoom(),
        max = this.getMaxZoom(),
        snap = Browser.any3d ? this.options.zoomSnap : 1;
      if (snap) {
        zoom = Math.round(zoom / snap) * snap;
      }
      return Math.max(min, Math.min(max, zoom));
    },
    _onPanTransitionStep: function () {
      this.fire('move');
    },
    _onPanTransitionEnd: function () {
      removeClass(this._mapPane, 'leaflet-pan-anim');
      this.fire('moveend');
    },
    _tryAnimatedPan: function (center, options) {
      // difference between the new and current centers in pixels
      var offset = this._getCenterOffset(center)._trunc();

      // don't animate too far unless animate: true specified in options
      if ((options && options.animate) !== true && !this.getSize().contains(offset)) {
        return false;
      }
      this.panBy(offset, options);
      return true;
    },
    _createAnimProxy: function () {
      var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated');
      this._panes.mapPane.appendChild(proxy);
      this.on('zoomanim', function (e) {
        var prop = TRANSFORM,
          transform = this._proxy.style[prop];
        setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));

        // workaround for case when transform is the same and so transitionend event is not fired
        if (transform === this._proxy.style[prop] && this._animatingZoom) {
          this._onZoomTransitionEnd();
        }
      }, this);
      this.on('load moveend', this._animMoveEnd, this);
      this._on('unload', this._destroyAnimProxy, this);
    },
    _destroyAnimProxy: function () {
      remove(this._proxy);
      this.off('load moveend', this._animMoveEnd, this);
      delete this._proxy;
    },
    _animMoveEnd: function () {
      var c = this.getCenter(),
        z = this.getZoom();
      setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1));
    },
    _catchTransitionEnd: function (e) {
      if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
        this._onZoomTransitionEnd();
      }
    },
    _nothingToAnimate: function () {
      return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
    },
    _tryAnimatedZoom: function (center, zoom, options) {
      if (this._animatingZoom) {
        return true;
      }
      options = options || {};

      // don't animate if disabled, not supported or zoom difference is too large
      if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() || Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) {
        return false;
      }

      // offset is the pixel coords of the zoom origin relative to the current center
      var scale = this.getZoomScale(zoom),
        offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);

      // don't animate if the zoom origin isn't within one screen from the current center, unless forced
      if (options.animate !== true && !this.getSize().contains(offset)) {
        return false;
      }
      requestAnimFrame(function () {
        this._moveStart(true, options.noMoveStart || false)._animateZoom(center, zoom, true);
      }, this);
      return true;
    },
    _animateZoom: function (center, zoom, startAnim, noUpdate) {
      if (!this._mapPane) {
        return;
      }
      if (startAnim) {
        this._animatingZoom = true;

        // remember what center/zoom to set after animation
        this._animateToCenter = center;
        this._animateToZoom = zoom;
        addClass(this._mapPane, 'leaflet-zoom-anim');
      }

      // @section Other Events
      // @event zoomanim: ZoomAnimEvent
      // Fired at least once per zoom animation. For continuous zoom, like pinch zooming, fired once per frame during zoom.
      this.fire('zoomanim', {
        center: center,
        zoom: zoom,
        noUpdate: noUpdate
      });
      if (!this._tempFireZoomEvent) {
        this._tempFireZoomEvent = this._zoom !== this._animateToZoom;
      }
      this._move(this._animateToCenter, this._animateToZoom, undefined, true);

      // Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693
      setTimeout(bind(this._onZoomTransitionEnd, this), 250);
    },
    _onZoomTransitionEnd: function () {
      if (!this._animatingZoom) {
        return;
      }
      if (this._mapPane) {
        removeClass(this._mapPane, 'leaflet-zoom-anim');
      }
      this._animatingZoom = false;
      this._move(this._animateToCenter, this._animateToZoom, undefined, true);
      if (this._tempFireZoomEvent) {
        this.fire('zoom');
      }
      delete this._tempFireZoomEvent;
      this.fire('move');
      this._moveEnd(true);
    }
  });

  // @section

  // @factory L.map(id: String, options?: Map options)
  // Instantiates a map object given the DOM ID of a `<div>` element
  // and optionally an object literal with `Map options`.
  //
  // @alternative
  // @factory L.map(el: HTMLElement, options?: Map options)
  // Instantiates a map object given an instance of a `<div>` HTML element
  // and optionally an object literal with `Map options`.
  function createMap(id, options) {
    return new Map(id, options);
  }

  /*
   * @class Control
   * @aka L.Control
   * @inherits Class
   *
   * L.Control is a base class for implementing map controls. Handles positioning.
   * All other controls extend from this class.
   */

  var Control = Class.extend({
    // @section
    // @aka Control Options
    options: {
      // @option position: String = 'topright'
      // The position of the control (one of the map corners). Possible values are `'topleft'`,
      // `'topright'`, `'bottomleft'` or `'bottomright'`
      position: 'topright'
    },
    initialize: function (options) {
      setOptions(this, options);
    },
    /* @section
     * Classes extending L.Control will inherit the following methods:
     *
     * @method getPosition: string
     * Returns the position of the control.
     */
    getPosition: function () {
      return this.options.position;
    },
    // @method setPosition(position: string): this
    // Sets the position of the control.
    setPosition: function (position) {
      var map = this._map;
      if (map) {
        map.removeControl(this);
      }
      this.options.position = position;
      if (map) {
        map.addControl(this);
      }
      return this;
    },
    // @method getContainer: HTMLElement
    // Returns the HTMLElement that contains the control.
    getContainer: function () {
      return this._container;
    },
    // @method addTo(map: Map): this
    // Adds the control to the given map.
    addTo: function (map) {
      this.remove();
      this._map = map;
      var container = this._container = this.onAdd(map),
        pos = this.getPosition(),
        corner = map._controlCorners[pos];
      addClass(container, 'leaflet-control');
      if (pos.indexOf('bottom') !== -1) {
        corner.insertBefore(container, corner.firstChild);
      } else {
        corner.appendChild(container);
      }
      this._map.on('unload', this.remove, this);
      return this;
    },
    // @method remove: this
    // Removes the control from the map it is currently active on.
    remove: function () {
      if (!this._map) {
        return this;
      }
      remove(this._container);
      if (this.onRemove) {
        this.onRemove(this._map);
      }
      this._map.off('unload', this.remove, this);
      this._map = null;
      return this;
    },
    _refocusOnMap: function (e) {
      // if map exists and event is not a keyboard event
      if (this._map && e && e.screenX > 0 && e.screenY > 0) {
        this._map.getContainer().focus();
      }
    }
  });
  var control = function (options) {
    return new Control(options);
  };

  /* @section Extension methods
   * @uninheritable
   *
   * Every control should extend from `L.Control` and (re-)implement the following methods.
   *
   * @method onAdd(map: Map): HTMLElement
   * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo).
   *
   * @method onRemove(map: Map)
   * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove).
   */

  /* @namespace Map
   * @section Methods for Layers and Controls
   */
  Map.include({
    // @method addControl(control: Control): this
    // Adds the given control to the map
    addControl: function (control) {
      control.addTo(this);
      return this;
    },
    // @method removeControl(control: Control): this
    // Removes the given control from the map
    removeControl: function (control) {
      control.remove();
      return this;
    },
    _initControlPos: function () {
      var corners = this._controlCorners = {},
        l = 'leaflet-',
        container = this._controlContainer = create$1('div', l + 'control-container', this._container);
      function createCorner(vSide, hSide) {
        var className = l + vSide + ' ' + l + hSide;
        corners[vSide + hSide] = create$1('div', className, container);
      }
      createCorner('top', 'left');
      createCorner('top', 'right');
      createCorner('bottom', 'left');
      createCorner('bottom', 'right');
    },
    _clearControlPos: function () {
      for (var i in this._controlCorners) {
        remove(this._controlCorners[i]);
      }
      remove(this._controlContainer);
      delete this._controlCorners;
      delete this._controlContainer;
    }
  });

  /*
   * @class Control.Layers
   * @aka L.Control.Layers
   * @inherits Control
   *
   * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](https://leafletjs.com/examples/layers-control/)). Extends `Control`.
   *
   * @example
   *
   * ```js
   * var baseLayers = {
   * 	"Mapbox": mapbox,
   * 	"OpenStreetMap": osm
   * };
   *
   * var overlays = {
   * 	"Marker": marker,
   * 	"Roads": roadsLayer
   * };
   *
   * L.control.layers(baseLayers, overlays).addTo(map);
   * ```
   *
   * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values:
   *
   * ```js
   * {
   *     "<someName1>": layer1,
   *     "<someName2>": layer2
   * }
   * ```
   *
   * The layer names can contain HTML, which allows you to add additional styling to the items:
   *
   * ```js
   * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer}
   * ```
   */

  var Layers = Control.extend({
    // @section
    // @aka Control.Layers options
    options: {
      // @option collapsed: Boolean = true
      // If `true`, the control will be collapsed into an icon and expanded on mouse hover, touch, or keyboard activation.
      collapsed: true,
      position: 'topright',
      // @option autoZIndex: Boolean = true
      // If `true`, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off.
      autoZIndex: true,
      // @option hideSingleBase: Boolean = false
      // If `true`, the base layers in the control will be hidden when there is only one.
      hideSingleBase: false,
      // @option sortLayers: Boolean = false
      // Whether to sort the layers. When `false`, layers will keep the order
      // in which they were added to the control.
      sortLayers: false,
      // @option sortFunction: Function = *
      // A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
      // that will be used for sorting the layers, when `sortLayers` is `true`.
      // The function receives both the `L.Layer` instances and their names, as in
      // `sortFunction(layerA, layerB, nameA, nameB)`.
      // By default, it sorts layers alphabetically by their name.
      sortFunction: function (layerA, layerB, nameA, nameB) {
        return nameA < nameB ? -1 : nameB < nameA ? 1 : 0;
      }
    },
    initialize: function (baseLayers, overlays, options) {
      setOptions(this, options);
      this._layerControlInputs = [];
      this._layers = [];
      this._lastZIndex = 0;
      this._handlingClick = false;
      this._preventClick = false;
      for (var i in baseLayers) {
        this._addLayer(baseLayers[i], i);
      }
      for (i in overlays) {
        this._addLayer(overlays[i], i, true);
      }
    },
    onAdd: function (map) {
      this._initLayout();
      this._update();
      this._map = map;
      map.on('zoomend', this._checkDisabledLayers, this);
      for (var i = 0; i < this._layers.length; i++) {
        this._layers[i].layer.on('add remove', this._onLayerChange, this);
      }
      return this._container;
    },
    addTo: function (map) {
      Control.prototype.addTo.call(this, map);
      // Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height.
      return this._expandIfNotCollapsed();
    },
    onRemove: function () {
      this._map.off('zoomend', this._checkDisabledLayers, this);
      for (var i = 0; i < this._layers.length; i++) {
        this._layers[i].layer.off('add remove', this._onLayerChange, this);
      }
    },
    // @method addBaseLayer(layer: Layer, name: String): this
    // Adds a base layer (radio button entry) with the given name to the control.
    addBaseLayer: function (layer, name) {
      this._addLayer(layer, name);
      return this._map ? this._update() : this;
    },
    // @method addOverlay(layer: Layer, name: String): this
    // Adds an overlay (checkbox entry) with the given name to the control.
    addOverlay: function (layer, name) {
      this._addLayer(layer, name, true);
      return this._map ? this._update() : this;
    },
    // @method removeLayer(layer: Layer): this
    // Remove the given layer from the control.
    removeLayer: function (layer) {
      layer.off('add remove', this._onLayerChange, this);
      var obj = this._getLayer(stamp(layer));
      if (obj) {
        this._layers.splice(this._layers.indexOf(obj), 1);
      }
      return this._map ? this._update() : this;
    },
    // @method expand(): this
    // Expand the control container if collapsed.
    expand: function () {
      addClass(this._container, 'leaflet-control-layers-expanded');
      this._section.style.height = null;
      var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50);
      if (acceptableHeight < this._section.clientHeight) {
        addClass(this._section, 'leaflet-control-layers-scrollbar');
        this._section.style.height = acceptableHeight + 'px';
      } else {
        removeClass(this._section, 'leaflet-control-layers-scrollbar');
      }
      this._checkDisabledLayers();
      return this;
    },
    // @method collapse(): this
    // Collapse the control container if expanded.
    collapse: function () {
      removeClass(this._container, 'leaflet-control-layers-expanded');
      return this;
    },
    _initLayout: function () {
      var className = 'leaflet-control-layers',
        container = this._container = create$1('div', className),
        collapsed = this.options.collapsed;

      // makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released
      container.setAttribute('aria-haspopup', true);
      disableClickPropagation(container);
      disableScrollPropagation(container);
      var section = this._section = create$1('section', className + '-list');
      if (collapsed) {
        this._map.on('click', this.collapse, this);
        on(container, {
          mouseenter: this._expandSafely,
          mouseleave: this.collapse
        }, this);
      }
      var link = this._layersLink = create$1('a', className + '-toggle', container);
      link.href = '#';
      link.title = 'Layers';
      link.setAttribute('role', 'button');
      on(link, {
        keydown: function (e) {
          if (e.keyCode === 13) {
            this._expandSafely();
          }
        },
        // Certain screen readers intercept the key event and instead send a click event
        click: function (e) {
          preventDefault(e);
          this._expandSafely();
        }
      }, this);
      if (!collapsed) {
        this.expand();
      }
      this._baseLayersList = create$1('div', className + '-base', section);
      this._separator = create$1('div', className + '-separator', section);
      this._overlaysList = create$1('div', className + '-overlays', section);
      container.appendChild(section);
    },
    _getLayer: function (id) {
      for (var i = 0; i < this._layers.length; i++) {
        if (this._layers[i] && stamp(this._layers[i].layer) === id) {
          return this._layers[i];
        }
      }
    },
    _addLayer: function (layer, name, overlay) {
      if (this._map) {
        layer.on('add remove', this._onLayerChange, this);
      }
      this._layers.push({
        layer: layer,
        name: name,
        overlay: overlay
      });
      if (this.options.sortLayers) {
        this._layers.sort(bind(function (a, b) {
          return this.options.sortFunction(a.layer, b.layer, a.name, b.name);
        }, this));
      }
      if (this.options.autoZIndex && layer.setZIndex) {
        this._lastZIndex++;
        layer.setZIndex(this._lastZIndex);
      }
      this._expandIfNotCollapsed();
    },
    _update: function () {
      if (!this._container) {
        return this;
      }
      empty(this._baseLayersList);
      empty(this._overlaysList);
      this._layerControlInputs = [];
      var baseLayersPresent,
        overlaysPresent,
        i,
        obj,
        baseLayersCount = 0;
      for (i = 0; i < this._layers.length; i++) {
        obj = this._layers[i];
        this._addItem(obj);
        overlaysPresent = overlaysPresent || obj.overlay;
        baseLayersPresent = baseLayersPresent || !obj.overlay;
        baseLayersCount += !obj.overlay ? 1 : 0;
      }

      // Hide base layers section if there's only one layer.
      if (this.options.hideSingleBase) {
        baseLayersPresent = baseLayersPresent && baseLayersCount > 1;
        this._baseLayersList.style.display = baseLayersPresent ? '' : 'none';
      }
      this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none';
      return this;
    },
    _onLayerChange: function (e) {
      if (!this._handlingClick) {
        this._update();
      }
      var obj = this._getLayer(stamp(e.target));

      // @namespace Map
      // @section Layer events
      // @event baselayerchange: LayersControlEvent
      // Fired when the base layer is changed through the [layers control](#control-layers).
      // @event overlayadd: LayersControlEvent
      // Fired when an overlay is selected through the [layers control](#control-layers).
      // @event overlayremove: LayersControlEvent
      // Fired when an overlay is deselected through the [layers control](#control-layers).
      // @namespace Control.Layers
      var type = obj.overlay ? e.type === 'add' ? 'overlayadd' : 'overlayremove' : e.type === 'add' ? 'baselayerchange' : null;
      if (type) {
        this._map.fire(type, obj);
      }
    },
    // IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see https://stackoverflow.com/a/119079)
    _createRadioElement: function (name, checked) {
      var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"' + (checked ? ' checked="checked"' : '') + '/>';
      var radioFragment = document.createElement('div');
      radioFragment.innerHTML = radioHtml;
      return radioFragment.firstChild;
    },
    _addItem: function (obj) {
      var label = document.createElement('label'),
        checked = this._map.hasLayer(obj.layer),
        input;
      if (obj.overlay) {
        input = document.createElement('input');
        input.type = 'checkbox';
        input.className = 'leaflet-control-layers-selector';
        input.defaultChecked = checked;
      } else {
        input = this._createRadioElement('leaflet-base-layers_' + stamp(this), checked);
      }
      this._layerControlInputs.push(input);
      input.layerId = stamp(obj.layer);
      on(input, 'click', this._onInputClick, this);
      var name = document.createElement('span');
      name.innerHTML = ' ' + obj.name;

      // Helps from preventing layer control flicker when checkboxes are disabled
      // https://github.com/Leaflet/Leaflet/issues/2771
      var holder = document.createElement('span');
      label.appendChild(holder);
      holder.appendChild(input);
      holder.appendChild(name);
      var container = obj.overlay ? this._overlaysList : this._baseLayersList;
      container.appendChild(label);
      this._checkDisabledLayers();
      return label;
    },
    _onInputClick: function () {
      // expanding the control on mobile with a click can cause adding a layer - we don't want this
      if (this._preventClick) {
        return;
      }
      var inputs = this._layerControlInputs,
        input,
        layer;
      var addedLayers = [],
        removedLayers = [];
      this._handlingClick = true;
      for (var i = inputs.length - 1; i >= 0; i--) {
        input = inputs[i];
        layer = this._getLayer(input.layerId).layer;
        if (input.checked) {
          addedLayers.push(layer);
        } else if (!input.checked) {
          removedLayers.push(layer);
        }
      }

      // Bugfix issue 2318: Should remove all old layers before readding new ones
      for (i = 0; i < removedLayers.length; i++) {
        if (this._map.hasLayer(removedLayers[i])) {
          this._map.removeLayer(removedLayers[i]);
        }
      }
      for (i = 0; i < addedLayers.length; i++) {
        if (!this._map.hasLayer(addedLayers[i])) {
          this._map.addLayer(addedLayers[i]);
        }
      }
      this._handlingClick = false;
      this._refocusOnMap();
    },
    _checkDisabledLayers: function () {
      var inputs = this._layerControlInputs,
        input,
        layer,
        zoom = this._map.getZoom();
      for (var i = inputs.length - 1; i >= 0; i--) {
        input = inputs[i];
        layer = this._getLayer(input.layerId).layer;
        input.disabled = layer.options.minZoom !== undefined && zoom < layer.options.minZoom || layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom;
      }
    },
    _expandIfNotCollapsed: function () {
      if (this._map && !this.options.collapsed) {
        this.expand();
      }
      return this;
    },
    _expandSafely: function () {
      var section = this._section;
      this._preventClick = true;
      on(section, 'click', preventDefault);
      this.expand();
      var that = this;
      setTimeout(function () {
        off(section, 'click', preventDefault);
        that._preventClick = false;
      });
    }
  });

  // @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options)
  // Creates a layers control with the given layers. Base layers will be switched with radio buttons, while overlays will be switched with checkboxes. Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation.
  var layers = function (baseLayers, overlays, options) {
    return new Layers(baseLayers, overlays, options);
  };

  /*
   * @class Control.Zoom
   * @aka L.Control.Zoom
   * @inherits Control
   *
   * A basic zoom control with two buttons (zoom in and zoom out). It is put on the map by default unless you set its [`zoomControl` option](#map-zoomcontrol) to `false`. Extends `Control`.
   */

  var Zoom = Control.extend({
    // @section
    // @aka Control.Zoom options
    options: {
      position: 'topleft',
      // @option zoomInText: String = '<span aria-hidden="true">+</span>'
      // The text set on the 'zoom in' button.
      zoomInText: '<span aria-hidden="true">+</span>',
      // @option zoomInTitle: String = 'Zoom in'
      // The title set on the 'zoom in' button.
      zoomInTitle: 'Zoom in',
      // @option zoomOutText: String = '<span aria-hidden="true">&#x2212;</span>'
      // The text set on the 'zoom out' button.
      zoomOutText: '<span aria-hidden="true">&#x2212;</span>',
      // @option zoomOutTitle: String = 'Zoom out'
      // The title set on the 'zoom out' button.
      zoomOutTitle: 'Zoom out'
    },
    onAdd: function (map) {
      var zoomName = 'leaflet-control-zoom',
        container = create$1('div', zoomName + ' leaflet-bar'),
        options = this.options;
      this._zoomInButton = this._createButton(options.zoomInText, options.zoomInTitle, zoomName + '-in', container, this._zoomIn);
      this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle, zoomName + '-out', container, this._zoomOut);
      this._updateDisabled();
      map.on('zoomend zoomlevelschange', this._updateDisabled, this);
      return container;
    },
    onRemove: function (map) {
      map.off('zoomend zoomlevelschange', this._updateDisabled, this);
    },
    disable: function () {
      this._disabled = true;
      this._updateDisabled();
      return this;
    },
    enable: function () {
      this._disabled = false;
      this._updateDisabled();
      return this;
    },
    _zoomIn: function (e) {
      if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) {
        this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
      }
    },
    _zoomOut: function (e) {
      if (!this._disabled && this._map._zoom > this._map.getMinZoom()) {
        this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
      }
    },
    _createButton: function (html, title, className, container, fn) {
      var link = create$1('a', className, container);
      link.innerHTML = html;
      link.href = '#';
      link.title = title;

      /*
       * Will force screen readers like VoiceOver to read this as "Zoom in - button"
       */
      link.setAttribute('role', 'button');
      link.setAttribute('aria-label', title);
      disableClickPropagation(link);
      on(link, 'click', stop);
      on(link, 'click', fn, this);
      on(link, 'click', this._refocusOnMap, this);
      return link;
    },
    _updateDisabled: function () {
      var map = this._map,
        className = 'leaflet-disabled';
      removeClass(this._zoomInButton, className);
      removeClass(this._zoomOutButton, className);
      this._zoomInButton.setAttribute('aria-disabled', 'false');
      this._zoomOutButton.setAttribute('aria-disabled', 'false');
      if (this._disabled || map._zoom === map.getMinZoom()) {
        addClass(this._zoomOutButton, className);
        this._zoomOutButton.setAttribute('aria-disabled', 'true');
      }
      if (this._disabled || map._zoom === map.getMaxZoom()) {
        addClass(this._zoomInButton, className);
        this._zoomInButton.setAttribute('aria-disabled', 'true');
      }
    }
  });

  // @namespace Map
  // @section Control options
  // @option zoomControl: Boolean = true
  // Whether a [zoom control](#control-zoom) is added to the map by default.
  Map.mergeOptions({
    zoomControl: true
  });
  Map.addInitHook(function () {
    if (this.options.zoomControl) {
      // @section Controls
      // @property zoomControl: Control.Zoom
      // The default zoom control (only available if the
      // [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map).
      this.zoomControl = new Zoom();
      this.addControl(this.zoomControl);
    }
  });

  // @namespace Control.Zoom
  // @factory L.control.zoom(options: Control.Zoom options)
  // Creates a zoom control
  var zoom = function (options) {
    return new Zoom(options);
  };

  /*
   * @class Control.Scale
   * @aka L.Control.Scale
   * @inherits Control
   *
   * A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) systems. Extends `Control`.
   *
   * @example
   *
   * ```js
   * L.control.scale().addTo(map);
   * ```
   */

  var Scale = Control.extend({
    // @section
    // @aka Control.Scale options
    options: {
      position: 'bottomleft',
      // @option maxWidth: Number = 100
      // Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500).
      maxWidth: 100,
      // @option metric: Boolean = True
      // Whether to show the metric scale line (m/km).
      metric: true,
      // @option imperial: Boolean = True
      // Whether to show the imperial scale line (mi/ft).
      imperial: true

      // @option updateWhenIdle: Boolean = false
      // If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)).
    },
    onAdd: function (map) {
      var className = 'leaflet-control-scale',
        container = create$1('div', className),
        options = this.options;
      this._addScales(options, className + '-line', container);
      map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
      map.whenReady(this._update, this);
      return container;
    },
    onRemove: function (map) {
      map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
    },
    _addScales: function (options, className, container) {
      if (options.metric) {
        this._mScale = create$1('div', className, container);
      }
      if (options.imperial) {
        this._iScale = create$1('div', className, container);
      }
    },
    _update: function () {
      var map = this._map,
        y = map.getSize().y / 2;
      var maxMeters = map.distance(map.containerPointToLatLng([0, y]), map.containerPointToLatLng([this.options.maxWidth, y]));
      this._updateScales(maxMeters);
    },
    _updateScales: function (maxMeters) {
      if (this.options.metric && maxMeters) {
        this._updateMetric(maxMeters);
      }
      if (this.options.imperial && maxMeters) {
        this._updateImperial(maxMeters);
      }
    },
    _updateMetric: function (maxMeters) {
      var meters = this._getRoundNum(maxMeters),
        label = meters < 1000 ? meters + ' m' : meters / 1000 + ' km';
      this._updateScale(this._mScale, label, meters / maxMeters);
    },
    _updateImperial: function (maxMeters) {
      var maxFeet = maxMeters * 3.2808399,
        maxMiles,
        miles,
        feet;
      if (maxFeet > 5280) {
        maxMiles = maxFeet / 5280;
        miles = this._getRoundNum(maxMiles);
        this._updateScale(this._iScale, miles + ' mi', miles / maxMiles);
      } else {
        feet = this._getRoundNum(maxFeet);
        this._updateScale(this._iScale, feet + ' ft', feet / maxFeet);
      }
    },
    _updateScale: function (scale, text, ratio) {
      scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px';
      scale.innerHTML = text;
    },
    _getRoundNum: function (num) {
      var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
        d = num / pow10;
      d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1;
      return pow10 * d;
    }
  });

  // @factory L.control.scale(options?: Control.Scale options)
  // Creates an scale control with the given options.
  var scale = function (options) {
    return new Scale(options);
  };
  var ukrainianFlag = '<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" width="12" height="8" viewBox="0 0 12 8" class="leaflet-attribution-flag"><path fill="#4C7BE1" d="M0 0h12v4H0z"/><path fill="#FFD500" d="M0 4h12v3H0z"/><path fill="#E0BC00" d="M0 7h12v1H0z"/></svg>';

  /*
   * @class Control.Attribution
   * @aka L.Control.Attribution
   * @inherits Control
   *
   * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control.
   */

  var Attribution = Control.extend({
    // @section
    // @aka Control.Attribution options
    options: {
      position: 'bottomright',
      // @option prefix: String|false = 'Leaflet'
      // The HTML text shown before the attributions. Pass `false` to disable.
      prefix: '<a href="https://leafletjs.com" title="A JavaScript library for interactive maps">' + (Browser.inlineSvg ? ukrainianFlag + ' ' : '') + 'Leaflet</a>'
    },
    initialize: function (options) {
      setOptions(this, options);
      this._attributions = {};
    },
    onAdd: function (map) {
      map.attributionControl = this;
      this._container = create$1('div', 'leaflet-control-attribution');
      disableClickPropagation(this._container);

      // TODO ugly, refactor
      for (var i in map._layers) {
        if (map._layers[i].getAttribution) {
          this.addAttribution(map._layers[i].getAttribution());
        }
      }
      this._update();
      map.on('layeradd', this._addAttribution, this);
      return this._container;
    },
    onRemove: function (map) {
      map.off('layeradd', this._addAttribution, this);
    },
    _addAttribution: function (ev) {
      if (ev.layer.getAttribution) {
        this.addAttribution(ev.layer.getAttribution());
        ev.layer.once('remove', function () {
          this.removeAttribution(ev.layer.getAttribution());
        }, this);
      }
    },
    // @method setPrefix(prefix: String|false): this
    // The HTML text shown before the attributions. Pass `false` to disable.
    setPrefix: function (prefix) {
      this.options.prefix = prefix;
      this._update();
      return this;
    },
    // @method addAttribution(text: String): this
    // Adds an attribution text (e.g. `'&copy; OpenStreetMap contributors'`).
    addAttribution: function (text) {
      if (!text) {
        return this;
      }
      if (!this._attributions[text]) {
        this._attributions[text] = 0;
      }
      this._attributions[text]++;
      this._update();
      return this;
    },
    // @method removeAttribution(text: String): this
    // Removes an attribution text.
    removeAttribution: function (text) {
      if (!text) {
        return this;
      }
      if (this._attributions[text]) {
        this._attributions[text]--;
        this._update();
      }
      return this;
    },
    _update: function () {
      if (!this._map) {
        return;
      }
      var attribs = [];
      for (var i in this._attributions) {
        if (this._attributions[i]) {
          attribs.push(i);
        }
      }
      var prefixAndAttribs = [];
      if (this.options.prefix) {
        prefixAndAttribs.push(this.options.prefix);
      }
      if (attribs.length) {
        prefixAndAttribs.push(attribs.join(', '));
      }
      this._container.innerHTML = prefixAndAttribs.join(' <span aria-hidden="true">|</span> ');
    }
  });

  // @namespace Map
  // @section Control options
  // @option attributionControl: Boolean = true
  // Whether a [attribution control](#control-attribution) is added to the map by default.
  Map.mergeOptions({
    attributionControl: true
  });
  Map.addInitHook(function () {
    if (this.options.attributionControl) {
      new Attribution().addTo(this);
    }
  });

  // @namespace Control.Attribution
  // @factory L.control.attribution(options: Control.Attribution options)
  // Creates an attribution control.
  var attribution = function (options) {
    return new Attribution(options);
  };
  Control.Layers = Layers;
  Control.Zoom = Zoom;
  Control.Scale = Scale;
  Control.Attribution = Attribution;
  control.layers = layers;
  control.zoom = zoom;
  control.scale = scale;
  control.attribution = attribution;

  /*
  	L.Handler is a base class for handler classes that are used internally to inject
  	interaction features like dragging to classes like Map and Marker.
  */

  // @class Handler
  // @aka L.Handler
  // Abstract class for map interaction handlers

  var Handler = Class.extend({
    initialize: function (map) {
      this._map = map;
    },
    // @method enable(): this
    // Enables the handler
    enable: function () {
      if (this._enabled) {
        return this;
      }
      this._enabled = true;
      this.addHooks();
      return this;
    },
    // @method disable(): this
    // Disables the handler
    disable: function () {
      if (!this._enabled) {
        return this;
      }
      this._enabled = false;
      this.removeHooks();
      return this;
    },
    // @method enabled(): Boolean
    // Returns `true` if the handler is enabled
    enabled: function () {
      return !!this._enabled;
    }

    // @section Extension methods
    // Classes inheriting from `Handler` must implement the two following methods:
    // @method addHooks()
    // Called when the handler is enabled, should add event hooks.
    // @method removeHooks()
    // Called when the handler is disabled, should remove the event hooks added previously.
  });

  // @section There is static function which can be called without instantiating L.Handler:
  // @function addTo(map: Map, name: String): this
  // Adds a new Handler to the given map with the given name.
  Handler.addTo = function (map, name) {
    map.addHandler(name, this);
    return this;
  };
  var Mixin = {
    Events: Events
  };

  /*
   * @class Draggable
   * @aka L.Draggable
   * @inherits Evented
   *
   * A class for making DOM elements draggable (including touch support).
   * Used internally for map and marker dragging. Only works for elements
   * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
   *
   * @example
   * ```js
   * var draggable = new L.Draggable(elementToDrag);
   * draggable.enable();
   * ```
   */

  var START = Browser.touch ? 'touchstart mousedown' : 'mousedown';
  var Draggable = Evented.extend({
    options: {
      // @section
      // @aka Draggable options
      // @option clickTolerance: Number = 3
      // The max number of pixels a user can shift the mouse pointer during a click
      // for it to be considered a valid click (as opposed to a mouse drag).
      clickTolerance: 3
    },
    // @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options)
    // Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default).
    initialize: function (element, dragStartTarget, preventOutline, options) {
      setOptions(this, options);
      this._element = element;
      this._dragStartTarget = dragStartTarget || element;
      this._preventOutline = preventOutline;
    },
    // @method enable()
    // Enables the dragging ability
    enable: function () {
      if (this._enabled) {
        return;
      }
      on(this._dragStartTarget, START, this._onDown, this);
      this._enabled = true;
    },
    // @method disable()
    // Disables the dragging ability
    disable: function () {
      if (!this._enabled) {
        return;
      }

      // If we're currently dragging this draggable,
      // disabling it counts as first ending the drag.
      if (Draggable._dragging === this) {
        this.finishDrag(true);
      }
      off(this._dragStartTarget, START, this._onDown, this);
      this._enabled = false;
      this._moved = false;
    },
    _onDown: function (e) {
      // Ignore the event if disabled; this happens in IE11
      // under some circumstances, see #3666.
      if (!this._enabled) {
        return;
      }
      this._moved = false;
      if (hasClass(this._element, 'leaflet-zoom-anim')) {
        return;
      }
      if (e.touches && e.touches.length !== 1) {
        // Finish dragging to avoid conflict with touchZoom
        if (Draggable._dragging === this) {
          this.finishDrag();
        }
        return;
      }
      if (Draggable._dragging || e.shiftKey || e.which !== 1 && e.button !== 1 && !e.touches) {
        return;
      }
      Draggable._dragging = this; // Prevent dragging multiple objects at once.

      if (this._preventOutline) {
        preventOutline(this._element);
      }
      disableImageDrag();
      disableTextSelection();
      if (this._moving) {
        return;
      }

      // @event down: Event
      // Fired when a drag is about to start.
      this.fire('down');
      var first = e.touches ? e.touches[0] : e,
        sizedParent = getSizedParentNode(this._element);
      this._startPoint = new Point(first.clientX, first.clientY);
      this._startPos = getPosition(this._element);

      // Cache the scale, so that we can continuously compensate for it during drag (_onMove).
      this._parentScale = getScale(sizedParent);
      var mouseevent = e.type === 'mousedown';
      on(document, mouseevent ? 'mousemove' : 'touchmove', this._onMove, this);
      on(document, mouseevent ? 'mouseup' : 'touchend touchcancel', this._onUp, this);
    },
    _onMove: function (e) {
      // Ignore the event if disabled; this happens in IE11
      // under some circumstances, see #3666.
      if (!this._enabled) {
        return;
      }
      if (e.touches && e.touches.length > 1) {
        this._moved = true;
        return;
      }
      var first = e.touches && e.touches.length === 1 ? e.touches[0] : e,
        offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint);
      if (!offset.x && !offset.y) {
        return;
      }
      if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) {
        return;
      }

      // We assume that the parent container's position, border and scale do not change for the duration of the drag.
      // Therefore there is no need to account for the position and border (they are eliminated by the subtraction)
      // and we can use the cached value for the scale.
      offset.x /= this._parentScale.x;
      offset.y /= this._parentScale.y;
      preventDefault(e);
      if (!this._moved) {
        // @event dragstart: Event
        // Fired when a drag starts
        this.fire('dragstart');
        this._moved = true;
        addClass(document.body, 'leaflet-dragging');
        this._lastTarget = e.target || e.srcElement;
        // IE and Edge do not give the <use> element, so fetch it
        // if necessary
        if (window.SVGElementInstance && this._lastTarget instanceof window.SVGElementInstance) {
          this._lastTarget = this._lastTarget.correspondingUseElement;
        }
        addClass(this._lastTarget, 'leaflet-drag-target');
      }
      this._newPos = this._startPos.add(offset);
      this._moving = true;
      this._lastEvent = e;
      this._updatePosition();
    },
    _updatePosition: function () {
      var e = {
        originalEvent: this._lastEvent
      };

      // @event predrag: Event
      // Fired continuously during dragging *before* each corresponding
      // update of the element's position.
      this.fire('predrag', e);
      setPosition(this._element, this._newPos);

      // @event drag: Event
      // Fired continuously during dragging.
      this.fire('drag', e);
    },
    _onUp: function () {
      // Ignore the event if disabled; this happens in IE11
      // under some circumstances, see #3666.
      if (!this._enabled) {
        return;
      }
      this.finishDrag();
    },
    finishDrag: function (noInertia) {
      removeClass(document.body, 'leaflet-dragging');
      if (this._lastTarget) {
        removeClass(this._lastTarget, 'leaflet-drag-target');
        this._lastTarget = null;
      }
      off(document, 'mousemove touchmove', this._onMove, this);
      off(document, 'mouseup touchend touchcancel', this._onUp, this);
      enableImageDrag();
      enableTextSelection();
      var fireDragend = this._moved && this._moving;
      this._moving = false;
      Draggable._dragging = false;
      if (fireDragend) {
        // @event dragend: DragEndEvent
        // Fired when the drag ends.
        this.fire('dragend', {
          noInertia: noInertia,
          distance: this._newPos.distanceTo(this._startPos)
        });
      }
    }
  });

  /*
   * @namespace PolyUtil
   * Various utility functions for polygon geometries.
   */

  /* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]
   * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).
   * Used by Leaflet to only show polygon points that are on the screen or near, increasing
   * performance. Note that polygon points needs different algorithm for clipping
   * than polyline, so there's a separate method for it.
   */
  function clipPolygon(points, bounds, round) {
    var clippedPoints,
      edges = [1, 4, 2, 8],
      i,
      j,
      k,
      a,
      b,
      len,
      edge,
      p;
    for (i = 0, len = points.length; i < len; i++) {
      points[i]._code = _getBitCode(points[i], bounds);
    }

    // for each edge (left, bottom, right, top)
    for (k = 0; k < 4; k++) {
      edge = edges[k];
      clippedPoints = [];
      for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
        a = points[i];
        b = points[j];

        // if a is inside the clip window
        if (!(a._code & edge)) {
          // if b is outside the clip window (a->b goes out of screen)
          if (b._code & edge) {
            p = _getEdgeIntersection(b, a, edge, bounds, round);
            p._code = _getBitCode(p, bounds);
            clippedPoints.push(p);
          }
          clippedPoints.push(a);

          // else if b is inside the clip window (a->b enters the screen)
        } else if (!(b._code & edge)) {
          p = _getEdgeIntersection(b, a, edge, bounds, round);
          p._code = _getBitCode(p, bounds);
          clippedPoints.push(p);
        }
      }
      points = clippedPoints;
    }
    return points;
  }

  /* @function polygonCenter(latlngs: LatLng[], crs: CRS): LatLng
   * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polygon.
   */
  function polygonCenter(latlngs, crs) {
    var i, j, p1, p2, f, area, x, y, center;
    if (!latlngs || latlngs.length === 0) {
      throw new Error('latlngs not passed');
    }
    if (!isFlat(latlngs)) {
      console.warn('latlngs are not flat! Only the first ring will be used');
      latlngs = latlngs[0];
    }
    var centroidLatLng = toLatLng([0, 0]);
    var bounds = toLatLngBounds(latlngs);
    var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest());
    // tests showed that below 1700 rounding errors are happening
    if (areaBounds < 1700) {
      // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors
      centroidLatLng = centroid(latlngs);
    }
    var len = latlngs.length;
    var points = [];
    for (i = 0; i < len; i++) {
      var latlng = toLatLng(latlngs[i]);
      points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng])));
    }
    area = x = y = 0;

    // polygon centroid algorithm;
    for (i = 0, j = len - 1; i < len; j = i++) {
      p1 = points[i];
      p2 = points[j];
      f = p1.y * p2.x - p2.y * p1.x;
      x += (p1.x + p2.x) * f;
      y += (p1.y + p2.y) * f;
      area += f * 3;
    }
    if (area === 0) {
      // Polygon is so small that all points are on same pixel.
      center = points[0];
    } else {
      center = [x / area, y / area];
    }
    var latlngCenter = crs.unproject(toPoint(center));
    return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]);
  }

  /* @function centroid(latlngs: LatLng[]): LatLng
   * Returns the 'center of mass' of the passed LatLngs.
   */
  function centroid(coords) {
    var latSum = 0;
    var lngSum = 0;
    var len = 0;
    for (var i = 0; i < coords.length; i++) {
      var latlng = toLatLng(coords[i]);
      latSum += latlng.lat;
      lngSum += latlng.lng;
      len++;
    }
    return toLatLng([latSum / len, lngSum / len]);
  }
  var PolyUtil = {
    __proto__: null,
    clipPolygon: clipPolygon,
    polygonCenter: polygonCenter,
    centroid: centroid
  };

  /*
   * @namespace LineUtil
   *
   * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast.
   */

  // Simplify polyline with vertex reduction and Douglas-Peucker simplification.
  // Improves rendering performance dramatically by lessening the number of points to draw.

  // @function simplify(points: Point[], tolerance: Number): Point[]
  // Dramatically reduces the number of points in a polyline while retaining
  // its shape and returns a new array of simplified points, using the
  // [Ramer-Douglas-Peucker algorithm](https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm).
  // Used for a huge performance boost when processing/displaying Leaflet polylines for
  // each zoom level and also reducing visual noise. tolerance affects the amount of
  // simplification (lesser value means higher quality but slower and with more points).
  // Also released as a separated micro-library [Simplify.js](https://mourner.github.io/simplify-js/).
  function simplify(points, tolerance) {
    if (!tolerance || !points.length) {
      return points.slice();
    }
    var sqTolerance = tolerance * tolerance;

    // stage 1: vertex reduction
    points = _reducePoints(points, sqTolerance);

    // stage 2: Douglas-Peucker simplification
    points = _simplifyDP(points, sqTolerance);
    return points;
  }

  // @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number
  // Returns the distance between point `p` and segment `p1` to `p2`.
  function pointToSegmentDistance(p, p1, p2) {
    return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true));
  }

  // @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number
  // Returns the closest point from a point `p` on a segment `p1` to `p2`.
  function closestPointOnSegment(p, p1, p2) {
    return _sqClosestPointOnSegment(p, p1, p2);
  }

  // Ramer-Douglas-Peucker simplification, see https://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm
  function _simplifyDP(points, sqTolerance) {
    var len = points.length,
      ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array,
      markers = new ArrayConstructor(len);
    markers[0] = markers[len - 1] = 1;
    _simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
    var i,
      newPoints = [];
    for (i = 0; i < len; i++) {
      if (markers[i]) {
        newPoints.push(points[i]);
      }
    }
    return newPoints;
  }
  function _simplifyDPStep(points, markers, sqTolerance, first, last) {
    var maxSqDist = 0,
      index,
      i,
      sqDist;
    for (i = first + 1; i <= last - 1; i++) {
      sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true);
      if (sqDist > maxSqDist) {
        index = i;
        maxSqDist = sqDist;
      }
    }
    if (maxSqDist > sqTolerance) {
      markers[index] = 1;
      _simplifyDPStep(points, markers, sqTolerance, first, index);
      _simplifyDPStep(points, markers, sqTolerance, index, last);
    }
  }

  // reduce points that are too close to each other to a single point
  function _reducePoints(points, sqTolerance) {
    var reducedPoints = [points[0]];
    for (var i = 1, prev = 0, len = points.length; i < len; i++) {
      if (_sqDist(points[i], points[prev]) > sqTolerance) {
        reducedPoints.push(points[i]);
        prev = i;
      }
    }
    if (prev < len - 1) {
      reducedPoints.push(points[len - 1]);
    }
    return reducedPoints;
  }
  var _lastCode;

  // @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean
  // Clips the segment a to b by rectangular bounds with the
  // [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm)
  // (modifying the segment points directly!). Used by Leaflet to only show polyline
  // points that are on the screen or near, increasing performance.
  function clipSegment(a, b, bounds, useLastCode, round) {
    var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds),
      codeB = _getBitCode(b, bounds),
      codeOut,
      p,
      newCode;

    // save 2nd code to avoid calculating it on the next segment
    _lastCode = codeB;
    while (true) {
      // if a,b is inside the clip window (trivial accept)
      if (!(codeA | codeB)) {
        return [a, b];
      }

      // if a,b is outside the clip window (trivial reject)
      if (codeA & codeB) {
        return false;
      }

      // other cases
      codeOut = codeA || codeB;
      p = _getEdgeIntersection(a, b, codeOut, bounds, round);
      newCode = _getBitCode(p, bounds);
      if (codeOut === codeA) {
        a = p;
        codeA = newCode;
      } else {
        b = p;
        codeB = newCode;
      }
    }
  }
  function _getEdgeIntersection(a, b, code, bounds, round) {
    var dx = b.x - a.x,
      dy = b.y - a.y,
      min = bounds.min,
      max = bounds.max,
      x,
      y;
    if (code & 8) {
      // top
      x = a.x + dx * (max.y - a.y) / dy;
      y = max.y;
    } else if (code & 4) {
      // bottom
      x = a.x + dx * (min.y - a.y) / dy;
      y = min.y;
    } else if (code & 2) {
      // right
      x = max.x;
      y = a.y + dy * (max.x - a.x) / dx;
    } else if (code & 1) {
      // left
      x = min.x;
      y = a.y + dy * (min.x - a.x) / dx;
    }
    return new Point(x, y, round);
  }
  function _getBitCode(p, bounds) {
    var code = 0;
    if (p.x < bounds.min.x) {
      // left
      code |= 1;
    } else if (p.x > bounds.max.x) {
      // right
      code |= 2;
    }
    if (p.y < bounds.min.y) {
      // bottom
      code |= 4;
    } else if (p.y > bounds.max.y) {
      // top
      code |= 8;
    }
    return code;
  }

  // square distance (to avoid unnecessary Math.sqrt calls)
  function _sqDist(p1, p2) {
    var dx = p2.x - p1.x,
      dy = p2.y - p1.y;
    return dx * dx + dy * dy;
  }

  // return closest point on segment or distance to that point
  function _sqClosestPointOnSegment(p, p1, p2, sqDist) {
    var x = p1.x,
      y = p1.y,
      dx = p2.x - x,
      dy = p2.y - y,
      dot = dx * dx + dy * dy,
      t;
    if (dot > 0) {
      t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
      if (t > 1) {
        x = p2.x;
        y = p2.y;
      } else if (t > 0) {
        x += dx * t;
        y += dy * t;
      }
    }
    dx = p.x - x;
    dy = p.y - y;
    return sqDist ? dx * dx + dy * dy : new Point(x, y);
  }

  // @function isFlat(latlngs: LatLng[]): Boolean
  // Returns true if `latlngs` is a flat array, false is nested.
  function isFlat(latlngs) {
    return !isArray(latlngs[0]) || typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined';
  }
  function _flat(latlngs) {
    console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.');
    return isFlat(latlngs);
  }

  /* @function polylineCenter(latlngs: LatLng[], crs: CRS): LatLng
   * Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the passed LatLngs (first ring) from a polyline.
   */
  function polylineCenter(latlngs, crs) {
    var i, halfDist, segDist, dist, p1, p2, ratio, center;
    if (!latlngs || latlngs.length === 0) {
      throw new Error('latlngs not passed');
    }
    if (!isFlat(latlngs)) {
      console.warn('latlngs are not flat! Only the first ring will be used');
      latlngs = latlngs[0];
    }
    var centroidLatLng = toLatLng([0, 0]);
    var bounds = toLatLngBounds(latlngs);
    var areaBounds = bounds.getNorthWest().distanceTo(bounds.getSouthWest()) * bounds.getNorthEast().distanceTo(bounds.getNorthWest());
    // tests showed that below 1700 rounding errors are happening
    if (areaBounds < 1700) {
      // getting a inexact center, to move the latlngs near to [0, 0] to prevent rounding errors
      centroidLatLng = centroid(latlngs);
    }
    var len = latlngs.length;
    var points = [];
    for (i = 0; i < len; i++) {
      var latlng = toLatLng(latlngs[i]);
      points.push(crs.project(toLatLng([latlng.lat - centroidLatLng.lat, latlng.lng - centroidLatLng.lng])));
    }
    for (i = 0, halfDist = 0; i < len - 1; i++) {
      halfDist += points[i].distanceTo(points[i + 1]) / 2;
    }

    // The line is so small in the current view that all points are on the same pixel.
    if (halfDist === 0) {
      center = points[0];
    } else {
      for (i = 0, dist = 0; i < len - 1; i++) {
        p1 = points[i];
        p2 = points[i + 1];
        segDist = p1.distanceTo(p2);
        dist += segDist;
        if (dist > halfDist) {
          ratio = (dist - halfDist) / segDist;
          center = [p2.x - ratio * (p2.x - p1.x), p2.y - ratio * (p2.y - p1.y)];
          break;
        }
      }
    }
    var latlngCenter = crs.unproject(toPoint(center));
    return toLatLng([latlngCenter.lat + centroidLatLng.lat, latlngCenter.lng + centroidLatLng.lng]);
  }
  var LineUtil = {
    __proto__: null,
    simplify: simplify,
    pointToSegmentDistance: pointToSegmentDistance,
    closestPointOnSegment: closestPointOnSegment,
    clipSegment: clipSegment,
    _getEdgeIntersection: _getEdgeIntersection,
    _getBitCode: _getBitCode,
    _sqClosestPointOnSegment: _sqClosestPointOnSegment,
    isFlat: isFlat,
    _flat: _flat,
    polylineCenter: polylineCenter
  };

  /*
   * @namespace Projection
   * @section
   * Leaflet comes with a set of already defined Projections out of the box:
   *
   * @projection L.Projection.LonLat
   *
   * Equirectangular, or Plate Carree projection — the most simple projection,
   * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as
   * latitude. Also suitable for flat worlds, e.g. game maps. Used by the
   * `EPSG:4326` and `Simple` CRS.
   */

  var LonLat = {
    project: function (latlng) {
      return new Point(latlng.lng, latlng.lat);
    },
    unproject: function (point) {
      return new LatLng(point.y, point.x);
    },
    bounds: new Bounds([-180, -90], [180, 90])
  };

  /*
   * @namespace Projection
   * @projection L.Projection.Mercator
   *
   * Elliptical Mercator projection — more complex than Spherical Mercator. Assumes that Earth is an ellipsoid. Used by the EPSG:3395 CRS.
   */

  var Mercator = {
    R: 6378137,
    R_MINOR: 6356752.314245179,
    bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]),
    project: function (latlng) {
      var d = Math.PI / 180,
        r = this.R,
        y = latlng.lat * d,
        tmp = this.R_MINOR / r,
        e = Math.sqrt(1 - tmp * tmp),
        con = e * Math.sin(y);
      var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
      y = -r * Math.log(Math.max(ts, 1E-10));
      return new Point(latlng.lng * d * r, y);
    },
    unproject: function (point) {
      var d = 180 / Math.PI,
        r = this.R,
        tmp = this.R_MINOR / r,
        e = Math.sqrt(1 - tmp * tmp),
        ts = Math.exp(-point.y / r),
        phi = Math.PI / 2 - 2 * Math.atan(ts);
      for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
        con = e * Math.sin(phi);
        con = Math.pow((1 - con) / (1 + con), e / 2);
        dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;
        phi += dphi;
      }
      return new LatLng(phi * d, point.x * d / r);
    }
  };

  /*
   * @class Projection
    * An object with methods for projecting geographical coordinates of the world onto
   * a flat surface (and back). See [Map projection](https://en.wikipedia.org/wiki/Map_projection).
    * @property bounds: Bounds
   * The bounds (specified in CRS units) where the projection is valid
    * @method project(latlng: LatLng): Point
   * Projects geographical coordinates into a 2D point.
   * Only accepts actual `L.LatLng` instances, not arrays.
    * @method unproject(point: Point): LatLng
   * The inverse of `project`. Projects a 2D point into a geographical location.
   * Only accepts actual `L.Point` instances, not arrays.
    * Note that the projection instances do not inherit from Leaflet's `Class` object,
   * and can't be instantiated. Also, new classes can't inherit from them,
   * and methods can't be added to them with the `include` function.
    */

  var index = {
    __proto__: null,
    LonLat: LonLat,
    Mercator: Mercator,
    SphericalMercator: SphericalMercator
  };

  /*
   * @namespace CRS
   * @crs L.CRS.EPSG3395
   *
   * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection.
   */
  var EPSG3395 = extend({}, Earth, {
    code: 'EPSG:3395',
    projection: Mercator,
    transformation: function () {
      var scale = 0.5 / (Math.PI * Mercator.R);
      return toTransformation(scale, 0.5, -scale, 0.5);
    }()
  });

  /*
   * @namespace CRS
   * @crs L.CRS.EPSG4326
   *
   * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection.
   *
   * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic),
   * which is a breaking change from 0.7.x behaviour.  If you are using a `TileLayer`
   * with this CRS, ensure that there are two 256x256 pixel tiles covering the
   * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90),
   * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set.
   */

  var EPSG4326 = extend({}, Earth, {
    code: 'EPSG:4326',
    projection: LonLat,
    transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5)
  });

  /*
   * @namespace CRS
   * @crs L.CRS.Simple
   *
   * A simple CRS that maps longitude and latitude into `x` and `y` directly.
   * May be used for maps of flat surfaces (e.g. game maps). Note that the `y`
   * axis should still be inverted (going from bottom to top). `distance()` returns
   * simple euclidean distance.
   */

  var Simple = extend({}, CRS, {
    projection: LonLat,
    transformation: toTransformation(1, 0, -1, 0),
    scale: function (zoom) {
      return Math.pow(2, zoom);
    },
    zoom: function (scale) {
      return Math.log(scale) / Math.LN2;
    },
    distance: function (latlng1, latlng2) {
      var dx = latlng2.lng - latlng1.lng,
        dy = latlng2.lat - latlng1.lat;
      return Math.sqrt(dx * dx + dy * dy);
    },
    infinite: true
  });
  CRS.Earth = Earth;
  CRS.EPSG3395 = EPSG3395;
  CRS.EPSG3857 = EPSG3857;
  CRS.EPSG900913 = EPSG900913;
  CRS.EPSG4326 = EPSG4326;
  CRS.Simple = Simple;

  /*
   * @class Layer
   * @inherits Evented
   * @aka L.Layer
   * @aka ILayer
   *
   * A set of methods from the Layer base class that all Leaflet layers use.
   * Inherits all methods, options and events from `L.Evented`.
   *
   * @example
   *
   * ```js
   * var layer = L.marker(latlng).addTo(map);
   * layer.addTo(map);
   * layer.remove();
   * ```
   *
   * @event add: Event
   * Fired after the layer is added to a map
   *
   * @event remove: Event
   * Fired after the layer is removed from a map
   */

  var Layer = Evented.extend({
    // Classes extending `L.Layer` will inherit the following options:
    options: {
      // @option pane: String = 'overlayPane'
      // By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
      pane: 'overlayPane',
      // @option attribution: String = null
      // String to be shown in the attribution control, e.g. "© OpenStreetMap contributors". It describes the layer data and is often a legal obligation towards copyright holders and tile providers.
      attribution: null,
      bubblingMouseEvents: true
    },
    /* @section
     * Classes extending `L.Layer` will inherit the following methods:
     *
     * @method addTo(map: Map|LayerGroup): this
     * Adds the layer to the given map or layer group.
     */
    addTo: function (map) {
      map.addLayer(this);
      return this;
    },
    // @method remove: this
    // Removes the layer from the map it is currently active on.
    remove: function () {
      return this.removeFrom(this._map || this._mapToAdd);
    },
    // @method removeFrom(map: Map): this
    // Removes the layer from the given map
    //
    // @alternative
    // @method removeFrom(group: LayerGroup): this
    // Removes the layer from the given `LayerGroup`
    removeFrom: function (obj) {
      if (obj) {
        obj.removeLayer(this);
      }
      return this;
    },
    // @method getPane(name? : String): HTMLElement
    // Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
    getPane: function (name) {
      return this._map.getPane(name ? this.options[name] || name : this.options.pane);
    },
    addInteractiveTarget: function (targetEl) {
      this._map._targets[stamp(targetEl)] = this;
      return this;
    },
    removeInteractiveTarget: function (targetEl) {
      delete this._map._targets[stamp(targetEl)];
      return this;
    },
    // @method getAttribution: String
    // Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
    getAttribution: function () {
      return this.options.attribution;
    },
    _layerAdd: function (e) {
      var map = e.target;

      // check in case layer gets added and then removed before the map is ready
      if (!map.hasLayer(this)) {
        return;
      }
      this._map = map;
      this._zoomAnimated = map._zoomAnimated;
      if (this.getEvents) {
        var events = this.getEvents();
        map.on(events, this);
        this.once('remove', function () {
          map.off(events, this);
        }, this);
      }
      this.onAdd(map);
      this.fire('add');
      map.fire('layeradd', {
        layer: this
      });
    }
  });

  /* @section Extension methods
   * @uninheritable
   *
   * Every layer should extend from `L.Layer` and (re-)implement the following methods.
   *
   * @method onAdd(map: Map): this
   * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
   *
   * @method onRemove(map: Map): this
   * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
   *
   * @method getEvents(): Object
   * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
   *
   * @method getAttribution(): String
   * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
   *
   * @method beforeAdd(map: Map): this
   * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
   */

  /* @namespace Map
   * @section Layer events
   *
   * @event layeradd: LayerEvent
   * Fired when a new layer is added to the map.
   *
   * @event layerremove: LayerEvent
   * Fired when some layer is removed from the map
   *
   * @section Methods for Layers and Controls
   */
  Map.include({
    // @method addLayer(layer: Layer): this
    // Adds the given layer to the map
    addLayer: function (layer) {
      if (!layer._layerAdd) {
        throw new Error('The provided object is not a Layer.');
      }
      var id = stamp(layer);
      if (this._layers[id]) {
        return this;
      }
      this._layers[id] = layer;
      layer._mapToAdd = this;
      if (layer.beforeAdd) {
        layer.beforeAdd(this);
      }
      this.whenReady(layer._layerAdd, layer);
      return this;
    },
    // @method removeLayer(layer: Layer): this
    // Removes the given layer from the map.
    removeLayer: function (layer) {
      var id = stamp(layer);
      if (!this._layers[id]) {
        return this;
      }
      if (this._loaded) {
        layer.onRemove(this);
      }
      delete this._layers[id];
      if (this._loaded) {
        this.fire('layerremove', {
          layer: layer
        });
        layer.fire('remove');
      }
      layer._map = layer._mapToAdd = null;
      return this;
    },
    // @method hasLayer(layer: Layer): Boolean
    // Returns `true` if the given layer is currently added to the map
    hasLayer: function (layer) {
      return stamp(layer) in this._layers;
    },
    /* @method eachLayer(fn: Function, context?: Object): this
     * Iterates over the layers of the map, optionally specifying context of the iterator function.
     * ```
     * map.eachLayer(function(layer){
     *     layer.bindPopup('Hello');
     * });
     * ```
     */
    eachLayer: function (method, context) {
      for (var i in this._layers) {
        method.call(context, this._layers[i]);
      }
      return this;
    },
    _addLayers: function (layers) {
      layers = layers ? isArray(layers) ? layers : [layers] : [];
      for (var i = 0, len = layers.length; i < len; i++) {
        this.addLayer(layers[i]);
      }
    },
    _addZoomLimit: function (layer) {
      if (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
        this._zoomBoundLayers[stamp(layer)] = layer;
        this._updateZoomLevels();
      }
    },
    _removeZoomLimit: function (layer) {
      var id = stamp(layer);
      if (this._zoomBoundLayers[id]) {
        delete this._zoomBoundLayers[id];
        this._updateZoomLevels();
      }
    },
    _updateZoomLevels: function () {
      var minZoom = Infinity,
        maxZoom = -Infinity,
        oldZoomSpan = this._getZoomSpan();
      for (var i in this._zoomBoundLayers) {
        var options = this._zoomBoundLayers[i].options;
        minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
        maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
      }
      this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
      this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;

      // @section Map state change events
      // @event zoomlevelschange: Event
      // Fired when the number of zoomlevels on the map is changed due
      // to adding or removing a layer.
      if (oldZoomSpan !== this._getZoomSpan()) {
        this.fire('zoomlevelschange');
      }
      if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
        this.setZoom(this._layersMaxZoom);
      }
      if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
        this.setZoom(this._layersMinZoom);
      }
    }
  });

  /*
   * @class LayerGroup
   * @aka L.LayerGroup
   * @inherits Interactive layer
   *
   * Used to group several layers and handle them as one. If you add it to the map,
   * any layers added or removed from the group will be added/removed on the map as
   * well. Extends `Layer`.
   *
   * @example
   *
   * ```js
   * L.layerGroup([marker1, marker2])
   * 	.addLayer(polyline)
   * 	.addTo(map);
   * ```
   */

  var LayerGroup = Layer.extend({
    initialize: function (layers, options) {
      setOptions(this, options);
      this._layers = {};
      var i, len;
      if (layers) {
        for (i = 0, len = layers.length; i < len; i++) {
          this.addLayer(layers[i]);
        }
      }
    },
    // @method addLayer(layer: Layer): this
    // Adds the given layer to the group.
    addLayer: function (layer) {
      var id = this.getLayerId(layer);
      this._layers[id] = layer;
      if (this._map) {
        this._map.addLayer(layer);
      }
      return this;
    },
    // @method removeLayer(layer: Layer): this
    // Removes the given layer from the group.
    // @alternative
    // @method removeLayer(id: Number): this
    // Removes the layer with the given internal ID from the group.
    removeLayer: function (layer) {
      var id = layer in this._layers ? layer : this.getLayerId(layer);
      if (this._map && this._layers[id]) {
        this._map.removeLayer(this._layers[id]);
      }
      delete this._layers[id];
      return this;
    },
    // @method hasLayer(layer: Layer): Boolean
    // Returns `true` if the given layer is currently added to the group.
    // @alternative
    // @method hasLayer(id: Number): Boolean
    // Returns `true` if the given internal ID is currently added to the group.
    hasLayer: function (layer) {
      var layerId = typeof layer === 'number' ? layer : this.getLayerId(layer);
      return layerId in this._layers;
    },
    // @method clearLayers(): this
    // Removes all the layers from the group.
    clearLayers: function () {
      return this.eachLayer(this.removeLayer, this);
    },
    // @method invoke(methodName: String, …): this
    // Calls `methodName` on every layer contained in this group, passing any
    // additional parameters. Has no effect if the layers contained do not
    // implement `methodName`.
    invoke: function (methodName) {
      var args = Array.prototype.slice.call(arguments, 1),
        i,
        layer;
      for (i in this._layers) {
        layer = this._layers[i];
        if (layer[methodName]) {
          layer[methodName].apply(layer, args);
        }
      }
      return this;
    },
    onAdd: function (map) {
      this.eachLayer(map.addLayer, map);
    },
    onRemove: function (map) {
      this.eachLayer(map.removeLayer, map);
    },
    // @method eachLayer(fn: Function, context?: Object): this
    // Iterates over the layers of the group, optionally specifying context of the iterator function.
    // ```js
    // group.eachLayer(function (layer) {
    // 	layer.bindPopup('Hello');
    // });
    // ```
    eachLayer: function (method, context) {
      for (var i in this._layers) {
        method.call(context, this._layers[i]);
      }
      return this;
    },
    // @method getLayer(id: Number): Layer
    // Returns the layer with the given internal ID.
    getLayer: function (id) {
      return this._layers[id];
    },
    // @method getLayers(): Layer[]
    // Returns an array of all the layers added to the group.
    getLayers: function () {
      var layers = [];
      this.eachLayer(layers.push, layers);
      return layers;
    },
    // @method setZIndex(zIndex: Number): this
    // Calls `setZIndex` on every layer contained in this group, passing the z-index.
    setZIndex: function (zIndex) {
      return this.invoke('setZIndex', zIndex);
    },
    // @method getLayerId(layer: Layer): Number
    // Returns the internal ID for a layer
    getLayerId: function (layer) {
      return stamp(layer);
    }
  });

  // @factory L.layerGroup(layers?: Layer[], options?: Object)
  // Create a layer group, optionally given an initial set of layers and an `options` object.
  var layerGroup = function (layers, options) {
    return new LayerGroup(layers, options);
  };

  /*
   * @class FeatureGroup
   * @aka L.FeatureGroup
   * @inherits LayerGroup
   *
   * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers:
   *  * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip))
   *  * Events are propagated to the `FeatureGroup`, so if the group has an event
   * handler, it will handle events from any of the layers. This includes mouse events
   * and custom events.
   *  * Has `layeradd` and `layerremove` events
   *
   * @example
   *
   * ```js
   * L.featureGroup([marker1, marker2, polyline])
   * 	.bindPopup('Hello world!')
   * 	.on('click', function() { alert('Clicked on a member of the group!'); })
   * 	.addTo(map);
   * ```
   */

  var FeatureGroup = LayerGroup.extend({
    addLayer: function (layer) {
      if (this.hasLayer(layer)) {
        return this;
      }
      layer.addEventParent(this);
      LayerGroup.prototype.addLayer.call(this, layer);

      // @event layeradd: LayerEvent
      // Fired when a layer is added to this `FeatureGroup`
      return this.fire('layeradd', {
        layer: layer
      });
    },
    removeLayer: function (layer) {
      if (!this.hasLayer(layer)) {
        return this;
      }
      if (layer in this._layers) {
        layer = this._layers[layer];
      }
      layer.removeEventParent(this);
      LayerGroup.prototype.removeLayer.call(this, layer);

      // @event layerremove: LayerEvent
      // Fired when a layer is removed from this `FeatureGroup`
      return this.fire('layerremove', {
        layer: layer
      });
    },
    // @method setStyle(style: Path options): this
    // Sets the given path options to each layer of the group that has a `setStyle` method.
    setStyle: function (style) {
      return this.invoke('setStyle', style);
    },
    // @method bringToFront(): this
    // Brings the layer group to the top of all other layers
    bringToFront: function () {
      return this.invoke('bringToFront');
    },
    // @method bringToBack(): this
    // Brings the layer group to the back of all other layers
    bringToBack: function () {
      return this.invoke('bringToBack');
    },
    // @method getBounds(): LatLngBounds
    // Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children).
    getBounds: function () {
      var bounds = new LatLngBounds();
      for (var id in this._layers) {
        var layer = this._layers[id];
        bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng());
      }
      return bounds;
    }
  });

  // @factory L.featureGroup(layers?: Layer[], options?: Object)
  // Create a feature group, optionally given an initial set of layers and an `options` object.
  var featureGroup = function (layers, options) {
    return new FeatureGroup(layers, options);
  };

  /*
   * @class Icon
   * @aka L.Icon
   *
   * Represents an icon to provide when creating a marker.
   *
   * @example
   *
   * ```js
   * var myIcon = L.icon({
   *     iconUrl: 'my-icon.png',
   *     iconRetinaUrl: 'my-icon@2x.png',
   *     iconSize: [38, 95],
   *     iconAnchor: [22, 94],
   *     popupAnchor: [-3, -76],
   *     shadowUrl: 'my-icon-shadow.png',
   *     shadowRetinaUrl: 'my-icon-shadow@2x.png',
   *     shadowSize: [68, 95],
   *     shadowAnchor: [22, 94]
   * });
   *
   * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
   * ```
   *
   * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default.
   *
   */

  var Icon = Class.extend({
    /* @section
     * @aka Icon options
     *
     * @option iconUrl: String = null
     * **(required)** The URL to the icon image (absolute or relative to your script path).
     *
     * @option iconRetinaUrl: String = null
     * The URL to a retina sized version of the icon image (absolute or relative to your
     * script path). Used for Retina screen devices.
     *
     * @option iconSize: Point = null
     * Size of the icon image in pixels.
     *
     * @option iconAnchor: Point = null
     * The coordinates of the "tip" of the icon (relative to its top left corner). The icon
     * will be aligned so that this point is at the marker's geographical location. Centered
     * by default if size is specified, also can be set in CSS with negative margins.
     *
     * @option popupAnchor: Point = [0, 0]
     * The coordinates of the point from which popups will "open", relative to the icon anchor.
     *
     * @option tooltipAnchor: Point = [0, 0]
     * The coordinates of the point from which tooltips will "open", relative to the icon anchor.
     *
     * @option shadowUrl: String = null
     * The URL to the icon shadow image. If not specified, no shadow image will be created.
     *
     * @option shadowRetinaUrl: String = null
     *
     * @option shadowSize: Point = null
     * Size of the shadow image in pixels.
     *
     * @option shadowAnchor: Point = null
     * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same
     * as iconAnchor if not specified).
     *
     * @option className: String = ''
     * A custom class name to assign to both icon and shadow images. Empty by default.
     */

    options: {
      popupAnchor: [0, 0],
      tooltipAnchor: [0, 0],
      // @option crossOrigin: Boolean|String = false
      // Whether the crossOrigin attribute will be added to the tiles.
      // If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data.
      // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.
      crossOrigin: false
    },
    initialize: function (options) {
      setOptions(this, options);
    },
    // @method createIcon(oldIcon?: HTMLElement): HTMLElement
    // Called internally when the icon has to be shown, returns a `<img>` HTML element
    // styled according to the options.
    createIcon: function (oldIcon) {
      return this._createIcon('icon', oldIcon);
    },
    // @method createShadow(oldIcon?: HTMLElement): HTMLElement
    // As `createIcon`, but for the shadow beneath it.
    createShadow: function (oldIcon) {
      return this._createIcon('shadow', oldIcon);
    },
    _createIcon: function (name, oldIcon) {
      var src = this._getIconUrl(name);
      if (!src) {
        if (name === 'icon') {
          throw new Error('iconUrl not set in Icon options (see the docs).');
        }
        return null;
      }
      var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null);
      this._setIconStyles(img, name);
      if (this.options.crossOrigin || this.options.crossOrigin === '') {
        img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
      }
      return img;
    },
    _setIconStyles: function (img, name) {
      var options = this.options;
      var sizeOption = options[name + 'Size'];
      if (typeof sizeOption === 'number') {
        sizeOption = [sizeOption, sizeOption];
      }
      var size = toPoint(sizeOption),
        anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor || size && size.divideBy(2, true));
      img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');
      if (anchor) {
        img.style.marginLeft = -anchor.x + 'px';
        img.style.marginTop = -anchor.y + 'px';
      }
      if (size) {
        img.style.width = size.x + 'px';
        img.style.height = size.y + 'px';
      }
    },
    _createImg: function (src, el) {
      el = el || document.createElement('img');
      el.src = src;
      return el;
    },
    _getIconUrl: function (name) {
      return Browser.retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url'];
    }
  });

  // @factory L.icon(options: Icon options)
  // Creates an icon instance with the given options.
  function icon(options) {
    return new Icon(options);
  }

  /*
   * @miniclass Icon.Default (Icon)
   * @aka L.Icon.Default
   * @section
   *
   * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when
   * no icon is specified. Points to the blue marker image distributed with Leaflet
   * releases.
   *
   * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options`
   * (which is a set of `Icon options`).
   *
   * If you want to _completely_ replace the default icon, override the
   * `L.Marker.prototype.options.icon` with your own icon instead.
   */

  var IconDefault = Icon.extend({
    options: {
      iconUrl: 'marker-icon.png',
      iconRetinaUrl: 'marker-icon-2x.png',
      shadowUrl: 'marker-shadow.png',
      iconSize: [25, 41],
      iconAnchor: [12, 41],
      popupAnchor: [1, -34],
      tooltipAnchor: [16, -28],
      shadowSize: [41, 41]
    },
    _getIconUrl: function (name) {
      if (typeof IconDefault.imagePath !== 'string') {
        // Deprecated, backwards-compatibility only
        IconDefault.imagePath = this._detectIconPath();
      }

      // @option imagePath: String
      // `Icon.Default` will try to auto-detect the location of the
      // blue icon images. If you are placing these images in a non-standard
      // way, set this option to point to the right path.
      return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name);
    },
    _stripUrl: function (path) {
      // separate function to use in tests
      var strip = function (str, re, idx) {
        var match = re.exec(str);
        return match && match[idx];
      };
      path = strip(path, /^url\((['"])?(.+)\1\)$/, 2);
      return path && strip(path, /^(.*)marker-icon\.png$/, 1);
    },
    _detectIconPath: function () {
      var el = create$1('div', 'leaflet-default-icon-path', document.body);
      var path = getStyle(el, 'background-image') || getStyle(el, 'backgroundImage'); // IE8

      document.body.removeChild(el);
      path = this._stripUrl(path);
      if (path) {
        return path;
      }
      var link = document.querySelector('link[href$="leaflet.css"]');
      if (!link) {
        return '';
      }
      return link.href.substring(0, link.href.length - 'leaflet.css'.length - 1);
    }
  });

  /*
   * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
   */

  /* @namespace Marker
   * @section Interaction handlers
   *
   * Interaction handlers are properties of a marker instance that allow you to control interaction behavior in runtime, enabling or disabling certain features such as dragging (see `Handler` methods). Example:
   *
   * ```js
   * marker.dragging.disable();
   * ```
   *
   * @property dragging: Handler
   * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)).
   */

  var MarkerDrag = Handler.extend({
    initialize: function (marker) {
      this._marker = marker;
    },
    addHooks: function () {
      var icon = this._marker._icon;
      if (!this._draggable) {
        this._draggable = new Draggable(icon, icon, true);
      }
      this._draggable.on({
        dragstart: this._onDragStart,
        predrag: this._onPreDrag,
        drag: this._onDrag,
        dragend: this._onDragEnd
      }, this).enable();
      addClass(icon, 'leaflet-marker-draggable');
    },
    removeHooks: function () {
      this._draggable.off({
        dragstart: this._onDragStart,
        predrag: this._onPreDrag,
        drag: this._onDrag,
        dragend: this._onDragEnd
      }, this).disable();
      if (this._marker._icon) {
        removeClass(this._marker._icon, 'leaflet-marker-draggable');
      }
    },
    moved: function () {
      return this._draggable && this._draggable._moved;
    },
    _adjustPan: function (e) {
      var marker = this._marker,
        map = marker._map,
        speed = this._marker.options.autoPanSpeed,
        padding = this._marker.options.autoPanPadding,
        iconPos = getPosition(marker._icon),
        bounds = map.getPixelBounds(),
        origin = map.getPixelOrigin();
      var panBounds = toBounds(bounds.min._subtract(origin).add(padding), bounds.max._subtract(origin).subtract(padding));
      if (!panBounds.contains(iconPos)) {
        // Compute incremental movement
        var movement = toPoint((Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) - (Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x), (Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) - (Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)).multiplyBy(speed);
        map.panBy(movement, {
          animate: false
        });
        this._draggable._newPos._add(movement);
        this._draggable._startPos._add(movement);
        setPosition(marker._icon, this._draggable._newPos);
        this._onDrag(e);
        this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
      }
    },
    _onDragStart: function () {
      // @section Dragging events
      // @event dragstart: Event
      // Fired when the user starts dragging the marker.

      // @event movestart: Event
      // Fired when the marker starts moving (because of dragging).

      this._oldLatLng = this._marker.getLatLng();

      // When using ES6 imports it could not be set when `Popup` was not imported as well
      this._marker.closePopup && this._marker.closePopup();
      this._marker.fire('movestart').fire('dragstart');
    },
    _onPreDrag: function (e) {
      if (this._marker.options.autoPan) {
        cancelAnimFrame(this._panRequest);
        this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
      }
    },
    _onDrag: function (e) {
      var marker = this._marker,
        shadow = marker._shadow,
        iconPos = getPosition(marker._icon),
        latlng = marker._map.layerPointToLatLng(iconPos);

      // update shadow position
      if (shadow) {
        setPosition(shadow, iconPos);
      }
      marker._latlng = latlng;
      e.latlng = latlng;
      e.oldLatLng = this._oldLatLng;

      // @event drag: Event
      // Fired repeatedly while the user drags the marker.
      marker.fire('move', e).fire('drag', e);
    },
    _onDragEnd: function (e) {
      // @event dragend: DragEndEvent
      // Fired when the user stops dragging the marker.

      cancelAnimFrame(this._panRequest);

      // @event moveend: Event
      // Fired when the marker stops moving (because of dragging).
      delete this._oldLatLng;
      this._marker.fire('moveend').fire('dragend', e);
    }
  });

  /*
   * @class Marker
   * @inherits Interactive layer
   * @aka L.Marker
   * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.
   *
   * @example
   *
   * ```js
   * L.marker([50.5, 30.5]).addTo(map);
   * ```
   */

  var Marker = Layer.extend({
    // @section
    // @aka Marker options
    options: {
      // @option icon: Icon = *
      // Icon instance to use for rendering the marker.
      // See [Icon documentation](#L.Icon) for details on how to customize the marker icon.
      // If not specified, a common instance of `L.Icon.Default` is used.
      icon: new IconDefault(),
      // Option inherited from "Interactive layer" abstract class
      interactive: true,
      // @option keyboard: Boolean = true
      // Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
      keyboard: true,
      // @option title: String = ''
      // Text for the browser tooltip that appear on marker hover (no tooltip by default).
      // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled).
      title: '',
      // @option alt: String = 'Marker'
      // Text for the `alt` attribute of the icon image.
      // [Useful for accessibility](https://leafletjs.com/examples/accessibility/#markers-must-be-labelled).
      alt: 'Marker',
      // @option zIndexOffset: Number = 0
      // By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).
      zIndexOffset: 0,
      // @option opacity: Number = 1.0
      // The opacity of the marker.
      opacity: 1,
      // @option riseOnHover: Boolean = false
      // If `true`, the marker will get on top of others when you hover the mouse over it.
      riseOnHover: false,
      // @option riseOffset: Number = 250
      // The z-index offset used for the `riseOnHover` feature.
      riseOffset: 250,
      // @option pane: String = 'markerPane'
      // `Map pane` where the markers icon will be added.
      pane: 'markerPane',
      // @option shadowPane: String = 'shadowPane'
      // `Map pane` where the markers shadow will be added.
      shadowPane: 'shadowPane',
      // @option bubblingMouseEvents: Boolean = false
      // When `true`, a mouse event on this marker will trigger the same event on the map
      // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
      bubblingMouseEvents: false,
      // @option autoPanOnFocus: Boolean = true
      // When `true`, the map will pan whenever the marker is focused (via
      // e.g. pressing `tab` on the keyboard) to ensure the marker is
      // visible within the map's bounds
      autoPanOnFocus: true,
      // @section Draggable marker options
      // @option draggable: Boolean = false
      // Whether the marker is draggable with mouse/touch or not.
      draggable: false,
      // @option autoPan: Boolean = false
      // Whether to pan the map when dragging this marker near its edge or not.
      autoPan: false,
      // @option autoPanPadding: Point = Point(50, 50)
      // Distance (in pixels to the left/right and to the top/bottom) of the
      // map edge to start panning the map.
      autoPanPadding: [50, 50],
      // @option autoPanSpeed: Number = 10
      // Number of pixels the map should pan by.
      autoPanSpeed: 10
    },
    /* @section
     *
     * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:
     */

    initialize: function (latlng, options) {
      setOptions(this, options);
      this._latlng = toLatLng(latlng);
    },
    onAdd: function (map) {
      this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;
      if (this._zoomAnimated) {
        map.on('zoomanim', this._animateZoom, this);
      }
      this._initIcon();
      this.update();
    },
    onRemove: function (map) {
      if (this.dragging && this.dragging.enabled()) {
        this.options.draggable = true;
        this.dragging.removeHooks();
      }
      delete this.dragging;
      if (this._zoomAnimated) {
        map.off('zoomanim', this._animateZoom, this);
      }
      this._removeIcon();
      this._removeShadow();
    },
    getEvents: function () {
      return {
        zoom: this.update,
        viewreset: this.update
      };
    },
    // @method getLatLng: LatLng
    // Returns the current geographical position of the marker.
    getLatLng: function () {
      return this._latlng;
    },
    // @method setLatLng(latlng: LatLng): this
    // Changes the marker position to the given point.
    setLatLng: function (latlng) {
      var oldLatLng = this._latlng;
      this._latlng = toLatLng(latlng);
      this.update();

      // @event move: Event
      // Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
      return this.fire('move', {
        oldLatLng: oldLatLng,
        latlng: this._latlng
      });
    },
    // @method setZIndexOffset(offset: Number): this
    // Changes the [zIndex offset](#marker-zindexoffset) of the marker.
    setZIndexOffset: function (offset) {
      this.options.zIndexOffset = offset;
      return this.update();
    },
    // @method getIcon: Icon
    // Returns the current icon used by the marker
    getIcon: function () {
      return this.options.icon;
    },
    // @method setIcon(icon: Icon): this
    // Changes the marker icon.
    setIcon: function (icon) {
      this.options.icon = icon;
      if (this._map) {
        this._initIcon();
        this.update();
      }
      if (this._popup) {
        this.bindPopup(this._popup, this._popup.options);
      }
      return this;
    },
    getElement: function () {
      return this._icon;
    },
    update: function () {
      if (this._icon && this._map) {
        var pos = this._map.latLngToLayerPoint(this._latlng).round();
        this._setPos(pos);
      }
      return this;
    },
    _initIcon: function () {
      var options = this.options,
        classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
      var icon = options.icon.createIcon(this._icon),
        addIcon = false;

      // if we're not reusing the icon, remove the old one and init new one
      if (icon !== this._icon) {
        if (this._icon) {
          this._removeIcon();
        }
        addIcon = true;
        if (options.title) {
          icon.title = options.title;
        }
        if (icon.tagName === 'IMG') {
          icon.alt = options.alt || '';
        }
      }
      addClass(icon, classToAdd);
      if (options.keyboard) {
        icon.tabIndex = '0';
        icon.setAttribute('role', 'button');
      }
      this._icon = icon;
      if (options.riseOnHover) {
        this.on({
          mouseover: this._bringToFront,
          mouseout: this._resetZIndex
        });
      }
      if (this.options.autoPanOnFocus) {
        on(icon, 'focus', this._panOnFocus, this);
      }
      var newShadow = options.icon.createShadow(this._shadow),
        addShadow = false;
      if (newShadow !== this._shadow) {
        this._removeShadow();
        addShadow = true;
      }
      if (newShadow) {
        addClass(newShadow, classToAdd);
        newShadow.alt = '';
      }
      this._shadow = newShadow;
      if (options.opacity < 1) {
        this._updateOpacity();
      }
      if (addIcon) {
        this.getPane().appendChild(this._icon);
      }
      this._initInteraction();
      if (newShadow && addShadow) {
        this.getPane(options.shadowPane).appendChild(this._shadow);
      }
    },
    _removeIcon: function () {
      if (this.options.riseOnHover) {
        this.off({
          mouseover: this._bringToFront,
          mouseout: this._resetZIndex
        });
      }
      if (this.options.autoPanOnFocus) {
        off(this._icon, 'focus', this._panOnFocus, this);
      }
      remove(this._icon);
      this.removeInteractiveTarget(this._icon);
      this._icon = null;
    },
    _removeShadow: function () {
      if (this._shadow) {
        remove(this._shadow);
      }
      this._shadow = null;
    },
    _setPos: function (pos) {
      if (this._icon) {
        setPosition(this._icon, pos);
      }
      if (this._shadow) {
        setPosition(this._shadow, pos);
      }
      this._zIndex = pos.y + this.options.zIndexOffset;
      this._resetZIndex();
    },
    _updateZIndex: function (offset) {
      if (this._icon) {
        this._icon.style.zIndex = this._zIndex + offset;
      }
    },
    _animateZoom: function (opt) {
      var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
      this._setPos(pos);
    },
    _initInteraction: function () {
      if (!this.options.interactive) {
        return;
      }
      addClass(this._icon, 'leaflet-interactive');
      this.addInteractiveTarget(this._icon);
      if (MarkerDrag) {
        var draggable = this.options.draggable;
        if (this.dragging) {
          draggable = this.dragging.enabled();
          this.dragging.disable();
        }
        this.dragging = new MarkerDrag(this);
        if (draggable) {
          this.dragging.enable();
        }
      }
    },
    // @method setOpacity(opacity: Number): this
    // Changes the opacity of the marker.
    setOpacity: function (opacity) {
      this.options.opacity = opacity;
      if (this._map) {
        this._updateOpacity();
      }
      return this;
    },
    _updateOpacity: function () {
      var opacity = this.options.opacity;
      if (this._icon) {
        setOpacity(this._icon, opacity);
      }
      if (this._shadow) {
        setOpacity(this._shadow, opacity);
      }
    },
    _bringToFront: function () {
      this._updateZIndex(this.options.riseOffset);
    },
    _resetZIndex: function () {
      this._updateZIndex(0);
    },
    _panOnFocus: function () {
      var map = this._map;
      if (!map) {
        return;
      }
      var iconOpts = this.options.icon.options;
      var size = iconOpts.iconSize ? toPoint(iconOpts.iconSize) : toPoint(0, 0);
      var anchor = iconOpts.iconAnchor ? toPoint(iconOpts.iconAnchor) : toPoint(0, 0);
      map.panInside(this._latlng, {
        paddingTopLeft: anchor,
        paddingBottomRight: size.subtract(anchor)
      });
    },
    _getPopupAnchor: function () {
      return this.options.icon.options.popupAnchor;
    },
    _getTooltipAnchor: function () {
      return this.options.icon.options.tooltipAnchor;
    }
  });

  // factory L.marker(latlng: LatLng, options? : Marker options)

  // @factory L.marker(latlng: LatLng, options? : Marker options)
  // Instantiates a Marker object given a geographical point and optionally an options object.
  function marker(latlng, options) {
    return new Marker(latlng, options);
  }

  /*
   * @class Path
   * @aka L.Path
   * @inherits Interactive layer
   *
   * An abstract class that contains options and constants shared between vector
   * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`.
   */

  var Path = Layer.extend({
    // @section
    // @aka Path options
    options: {
      // @option stroke: Boolean = true
      // Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles.
      stroke: true,
      // @option color: String = '#3388ff'
      // Stroke color
      color: '#3388ff',
      // @option weight: Number = 3
      // Stroke width in pixels
      weight: 3,
      // @option opacity: Number = 1.0
      // Stroke opacity
      opacity: 1,
      // @option lineCap: String= 'round'
      // A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke.
      lineCap: 'round',
      // @option lineJoin: String = 'round'
      // A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke.
      lineJoin: 'round',
      // @option dashArray: String = null
      // A string that defines the stroke [dash pattern](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dasharray). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
      dashArray: null,
      // @option dashOffset: String = null
      // A string that defines the [distance into the dash pattern to start the dash](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dashoffset). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
      dashOffset: null,
      // @option fill: Boolean = depends
      // Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles.
      fill: false,
      // @option fillColor: String = *
      // Fill color. Defaults to the value of the [`color`](#path-color) option
      fillColor: null,
      // @option fillOpacity: Number = 0.2
      // Fill opacity.
      fillOpacity: 0.2,
      // @option fillRule: String = 'evenodd'
      // A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined.
      fillRule: 'evenodd',
      // className: '',

      // Option inherited from "Interactive layer" abstract class
      interactive: true,
      // @option bubblingMouseEvents: Boolean = true
      // When `true`, a mouse event on this path will trigger the same event on the map
      // (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
      bubblingMouseEvents: true
    },
    beforeAdd: function (map) {
      // Renderer is set here because we need to call renderer.getEvents
      // before this.getEvents.
      this._renderer = map.getRenderer(this);
    },
    onAdd: function () {
      this._renderer._initPath(this);
      this._reset();
      this._renderer._addPath(this);
    },
    onRemove: function () {
      this._renderer._removePath(this);
    },
    // @method redraw(): this
    // Redraws the layer. Sometimes useful after you changed the coordinates that the path uses.
    redraw: function () {
      if (this._map) {
        this._renderer._updatePath(this);
      }
      return this;
    },
    // @method setStyle(style: Path options): this
    // Changes the appearance of a Path based on the options in the `Path options` object.
    setStyle: function (style) {
      setOptions(this, style);
      if (this._renderer) {
        this._renderer._updateStyle(this);
        if (this.options.stroke && style && Object.prototype.hasOwnProperty.call(style, 'weight')) {
          this._updateBounds();
        }
      }
      return this;
    },
    // @method bringToFront(): this
    // Brings the layer to the top of all path layers.
    bringToFront: function () {
      if (this._renderer) {
        this._renderer._bringToFront(this);
      }
      return this;
    },
    // @method bringToBack(): this
    // Brings the layer to the bottom of all path layers.
    bringToBack: function () {
      if (this._renderer) {
        this._renderer._bringToBack(this);
      }
      return this;
    },
    getElement: function () {
      return this._path;
    },
    _reset: function () {
      // defined in child classes
      this._project();
      this._update();
    },
    _clickTolerance: function () {
      // used when doing hit detection for Canvas layers
      return (this.options.stroke ? this.options.weight / 2 : 0) + (this._renderer.options.tolerance || 0);
    }
  });

  /*
   * @class CircleMarker
   * @aka L.CircleMarker
   * @inherits Path
   *
   * A circle of a fixed size with radius specified in pixels. Extends `Path`.
   */

  var CircleMarker = Path.extend({
    // @section
    // @aka CircleMarker options
    options: {
      fill: true,
      // @option radius: Number = 10
      // Radius of the circle marker, in pixels
      radius: 10
    },
    initialize: function (latlng, options) {
      setOptions(this, options);
      this._latlng = toLatLng(latlng);
      this._radius = this.options.radius;
    },
    // @method setLatLng(latLng: LatLng): this
    // Sets the position of a circle marker to a new location.
    setLatLng: function (latlng) {
      var oldLatLng = this._latlng;
      this._latlng = toLatLng(latlng);
      this.redraw();

      // @event move: Event
      // Fired when the marker is moved via [`setLatLng`](#circlemarker-setlatlng). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
      return this.fire('move', {
        oldLatLng: oldLatLng,
        latlng: this._latlng
      });
    },
    // @method getLatLng(): LatLng
    // Returns the current geographical position of the circle marker
    getLatLng: function () {
      return this._latlng;
    },
    // @method setRadius(radius: Number): this
    // Sets the radius of a circle marker. Units are in pixels.
    setRadius: function (radius) {
      this.options.radius = this._radius = radius;
      return this.redraw();
    },
    // @method getRadius(): Number
    // Returns the current radius of the circle
    getRadius: function () {
      return this._radius;
    },
    setStyle: function (options) {
      var radius = options && options.radius || this._radius;
      Path.prototype.setStyle.call(this, options);
      this.setRadius(radius);
      return this;
    },
    _project: function () {
      this._point = this._map.latLngToLayerPoint(this._latlng);
      this._updateBounds();
    },
    _updateBounds: function () {
      var r = this._radius,
        r2 = this._radiusY || r,
        w = this._clickTolerance(),
        p = [r + w, r2 + w];
      this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p));
    },
    _update: function () {
      if (this._map) {
        this._updatePath();
      }
    },
    _updatePath: function () {
      this._renderer._updateCircle(this);
    },
    _empty: function () {
      return this._radius && !this._renderer._bounds.intersects(this._pxBounds);
    },
    // Needed by the `Canvas` renderer for interactivity
    _containsPoint: function (p) {
      return p.distanceTo(this._point) <= this._radius + this._clickTolerance();
    }
  });

  // @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options)
  // Instantiates a circle marker object given a geographical point, and an optional options object.
  function circleMarker(latlng, options) {
    return new CircleMarker(latlng, options);
  }

  /*
   * @class Circle
   * @aka L.Circle
   * @inherits CircleMarker
   *
   * A class for drawing circle overlays on a map. Extends `CircleMarker`.
   *
   * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
   *
   * @example
   *
   * ```js
   * L.circle([50.5, 30.5], {radius: 200}).addTo(map);
   * ```
   */

  var Circle = CircleMarker.extend({
    initialize: function (latlng, options, legacyOptions) {
      if (typeof options === 'number') {
        // Backwards compatibility with 0.7.x factory (latlng, radius, options?)
        options = extend({}, legacyOptions, {
          radius: options
        });
      }
      setOptions(this, options);
      this._latlng = toLatLng(latlng);
      if (isNaN(this.options.radius)) {
        throw new Error('Circle radius cannot be NaN');
      }

      // @section
      // @aka Circle options
      // @option radius: Number; Radius of the circle, in meters.
      this._mRadius = this.options.radius;
    },
    // @method setRadius(radius: Number): this
    // Sets the radius of a circle. Units are in meters.
    setRadius: function (radius) {
      this._mRadius = radius;
      return this.redraw();
    },
    // @method getRadius(): Number
    // Returns the current radius of a circle. Units are in meters.
    getRadius: function () {
      return this._mRadius;
    },
    // @method getBounds(): LatLngBounds
    // Returns the `LatLngBounds` of the path.
    getBounds: function () {
      var half = [this._radius, this._radiusY || this._radius];
      return new LatLngBounds(this._map.layerPointToLatLng(this._point.subtract(half)), this._map.layerPointToLatLng(this._point.add(half)));
    },
    setStyle: Path.prototype.setStyle,
    _project: function () {
      var lng = this._latlng.lng,
        lat = this._latlng.lat,
        map = this._map,
        crs = map.options.crs;
      if (crs.distance === Earth.distance) {
        var d = Math.PI / 180,
          latR = this._mRadius / Earth.R / d,
          top = map.project([lat + latR, lng]),
          bottom = map.project([lat - latR, lng]),
          p = top.add(bottom).divideBy(2),
          lat2 = map.unproject(p).lat,
          lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) / (Math.cos(lat * d) * Math.cos(lat2 * d))) / d;
        if (isNaN(lngR) || lngR === 0) {
          lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425
        }
        this._point = p.subtract(map.getPixelOrigin());
        this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x;
        this._radiusY = p.y - top.y;
      } else {
        var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0]));
        this._point = map.latLngToLayerPoint(this._latlng);
        this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x;
      }
      this._updateBounds();
    }
  });

  // @factory L.circle(latlng: LatLng, options?: Circle options)
  // Instantiates a circle object given a geographical point, and an options object
  // which contains the circle radius.
  // @alternative
  // @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options)
  // Obsolete way of instantiating a circle, for compatibility with 0.7.x code.
  // Do not use in new applications or plugins.
  function circle(latlng, options, legacyOptions) {
    return new Circle(latlng, options, legacyOptions);
  }

  /*
   * @class Polyline
   * @aka L.Polyline
   * @inherits Path
   *
   * A class for drawing polyline overlays on a map. Extends `Path`.
   *
   * @example
   *
   * ```js
   * // create a red polyline from an array of LatLng points
   * var latlngs = [
   * 	[45.51, -122.68],
   * 	[37.77, -122.43],
   * 	[34.04, -118.2]
   * ];
   *
   * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map);
   *
   * // zoom the map to the polyline
   * map.fitBounds(polyline.getBounds());
   * ```
   *
   * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape:
   *
   * ```js
   * // create a red polyline from an array of arrays of LatLng points
   * var latlngs = [
   * 	[[45.51, -122.68],
   * 	 [37.77, -122.43],
   * 	 [34.04, -118.2]],
   * 	[[40.78, -73.91],
   * 	 [41.83, -87.62],
   * 	 [32.76, -96.72]]
   * ];
   * ```
   */

  var Polyline = Path.extend({
    // @section
    // @aka Polyline options
    options: {
      // @option smoothFactor: Number = 1.0
      // How much to simplify the polyline on each zoom level. More means
      // better performance and smoother look, and less means more accurate representation.
      smoothFactor: 1.0,
      // @option noClip: Boolean = false
      // Disable polyline clipping.
      noClip: false
    },
    initialize: function (latlngs, options) {
      setOptions(this, options);
      this._setLatLngs(latlngs);
    },
    // @method getLatLngs(): LatLng[]
    // Returns an array of the points in the path, or nested arrays of points in case of multi-polyline.
    getLatLngs: function () {
      return this._latlngs;
    },
    // @method setLatLngs(latlngs: LatLng[]): this
    // Replaces all the points in the polyline with the given array of geographical points.
    setLatLngs: function (latlngs) {
      this._setLatLngs(latlngs);
      return this.redraw();
    },
    // @method isEmpty(): Boolean
    // Returns `true` if the Polyline has no LatLngs.
    isEmpty: function () {
      return !this._latlngs.length;
    },
    // @method closestLayerPoint(p: Point): Point
    // Returns the point closest to `p` on the Polyline.
    closestLayerPoint: function (p) {
      var minDistance = Infinity,
        minPoint = null,
        closest = _sqClosestPointOnSegment,
        p1,
        p2;
      for (var j = 0, jLen = this._parts.length; j < jLen; j++) {
        var points = this._parts[j];
        for (var i = 1, len = points.length; i < len; i++) {
          p1 = points[i - 1];
          p2 = points[i];
          var sqDist = closest(p, p1, p2, true);
          if (sqDist < minDistance) {
            minDistance = sqDist;
            minPoint = closest(p, p1, p2);
          }
        }
      }
      if (minPoint) {
        minPoint.distance = Math.sqrt(minDistance);
      }
      return minPoint;
    },
    // @method getCenter(): LatLng
    // Returns the center ([centroid](https://en.wikipedia.org/wiki/Centroid)) of the polyline.
    getCenter: function () {
      // throws error when not yet added to map as this center calculation requires projected coordinates
      if (!this._map) {
        throw new Error('Must add layer to map before using getCenter()');
      }
      return polylineCenter(this._defaultShape(), this._map.options.crs);
    },
    // @method getBounds(): LatLngBounds
    // Returns the `LatLngBounds` of the path.
    getBounds: function () {
      return this._bounds;
    },
    // @method addLatLng(latlng: LatLng, latlngs?: LatLng[]): this
    // Adds a given point to the polyline. By default, adds to the first ring of
    // the polyline in case of a multi-polyline, but can be overridden by passing
    // a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)).
    addLatLng: function (latlng, latlngs) {
      latlngs = latlngs || this._defaultShape();
      latlng = toLatLng(latlng);
      latlngs.push(latlng);
      this._bounds.extend(latlng);
      return this.redraw();
    },
    _setLatLngs: function (latlngs) {
      this._bounds = new LatLngBounds();
      this._latlngs = this._convertLatLngs(latlngs);
    },
    _defaultShape: function () {
      return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0];
    },
    // recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
    _convertLatLngs: function (latlngs) {
      var result = [],
        flat = isFlat(latlngs);
      for (var i = 0, len = latlngs.length; i < len; i++) {
        if (flat) {
          result[i] = toLatLng(latlngs[i]);
          this._bounds.extend(result[i]);
        } else {
          result[i] = this._convertLatLngs(latlngs[i]);
        }
      }
      return result;
    },
    _project: function () {
      var pxBounds = new Bounds();
      this._rings = [];
      this._projectLatlngs(this._latlngs, this._rings, pxBounds);
      if (this._bounds.isValid() && pxBounds.isValid()) {
        this._rawPxBounds = pxBounds;
        this._updateBounds();
      }
    },
    _updateBounds: function () {
      var w = this._clickTolerance(),
        p = new Point(w, w);
      if (!this._rawPxBounds) {
        return;
      }
      this._pxBounds = new Bounds([this._rawPxBounds.min.subtract(p), this._rawPxBounds.max.add(p)]);
    },
    // recursively turns latlngs into a set of rings with projected coordinates
    _projectLatlngs: function (latlngs, result, projectedBounds) {
      var flat = latlngs[0] instanceof LatLng,
        len = latlngs.length,
        i,
        ring;
      if (flat) {
        ring = [];
        for (i = 0; i < len; i++) {
          ring[i] = this._map.latLngToLayerPoint(latlngs[i]);
          projectedBounds.extend(ring[i]);
        }
        result.push(ring);
      } else {
        for (i = 0; i < len; i++) {
          this._projectLatlngs(latlngs[i], result, projectedBounds);
        }
      }
    },
    // clip polyline by renderer bounds so that we have less to render for performance
    _clipPoints: function () {
      var bounds = this._renderer._bounds;
      this._parts = [];
      if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
        return;
      }
      if (this.options.noClip) {
        this._parts = this._rings;
        return;
      }
      var parts = this._parts,
        i,
        j,
        k,
        len,
        len2,
        segment,
        points;
      for (i = 0, k = 0, len = this._rings.length; i < len; i++) {
        points = this._rings[i];
        for (j = 0, len2 = points.length; j < len2 - 1; j++) {
          segment = clipSegment(points[j], points[j + 1], bounds, j, true);
          if (!segment) {
            continue;
          }
          parts[k] = parts[k] || [];
          parts[k].push(segment[0]);

          // if segment goes out of screen, or it's the last one, it's the end of the line part
          if (segment[1] !== points[j + 1] || j === len2 - 2) {
            parts[k].push(segment[1]);
            k++;
          }
        }
      }
    },
    // simplify each clipped part of the polyline for performance
    _simplifyPoints: function () {
      var parts = this._parts,
        tolerance = this.options.smoothFactor;
      for (var i = 0, len = parts.length; i < len; i++) {
        parts[i] = simplify(parts[i], tolerance);
      }
    },
    _update: function () {
      if (!this._map) {
        return;
      }
      this._clipPoints();
      this._simplifyPoints();
      this._updatePath();
    },
    _updatePath: function () {
      this._renderer._updatePoly(this);
    },
    // Needed by the `Canvas` renderer for interactivity
    _containsPoint: function (p, closed) {
      var i,
        j,
        k,
        len,
        len2,
        part,
        w = this._clickTolerance();
      if (!this._pxBounds || !this._pxBounds.contains(p)) {
        return false;
      }

      // hit detection for polylines
      for (i = 0, len = this._parts.length; i < len; i++) {
        part = this._parts[i];
        for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
          if (!closed && j === 0) {
            continue;
          }
          if (pointToSegmentDistance(p, part[k], part[j]) <= w) {
            return true;
          }
        }
      }
      return false;
    }
  });

  // @factory L.polyline(latlngs: LatLng[], options?: Polyline options)
  // Instantiates a polyline object given an array of geographical points and
  // optionally an options object. You can create a `Polyline` object with
  // multiple separate lines (`MultiPolyline`) by passing an array of arrays
  // of geographic points.
  function polyline(latlngs, options) {
    return new Polyline(latlngs, options);
  }

  // Retrocompat. Allow plugins to support Leaflet versions before and after 1.1.
  Polyline._flat = _flat;

  /*
   * @class Polygon
   * @aka L.Polygon
   * @inherits Polyline
   *
   * A class for drawing polygon overlays on a map. Extends `Polyline`.
   *
   * Note that points you pass when creating a polygon shouldn't have an additional last point equal to the first one — it's better to filter out such points.
   *
   *
   * @example
   *
   * ```js
   * // create a red polygon from an array of LatLng points
   * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
   *
   * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map);
   *
   * // zoom the map to the polygon
   * map.fitBounds(polygon.getBounds());
   * ```
   *
   * You can also pass an array of arrays of latlngs, with the first array representing the outer shape and the other arrays representing holes in the outer shape:
   *
   * ```js
   * var latlngs = [
   *   [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
   *   [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
   * ];
   * ```
   *
   * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape.
   *
   * ```js
   * var latlngs = [
   *   [ // first polygon
   *     [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
   *     [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
   *   ],
   *   [ // second polygon
   *     [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]]
   *   ]
   * ];
   * ```
   */

  var Polygon = Polyline.extend({
    options: {
      fill: true
    },
    isEmpty: function () {
      return !this._latlngs.length || !this._latlngs[0].length;
    },
    // @method getCenter(): LatLng
    // Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the Polygon.
    getCenter: function () {
      // throws error when not yet added to map as this center calculation requires projected coordinates
      if (!this._map) {
        throw new Error('Must add layer to map before using getCenter()');
      }
      return polygonCenter(this._defaultShape(), this._map.options.crs);
    },
    _convertLatLngs: function (latlngs) {
      var result = Polyline.prototype._convertLatLngs.call(this, latlngs),
        len = result.length;

      // remove last point if it equals first one
      if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) {
        result.pop();
      }
      return result;
    },
    _setLatLngs: function (latlngs) {
      Polyline.prototype._setLatLngs.call(this, latlngs);
      if (isFlat(this._latlngs)) {
        this._latlngs = [this._latlngs];
      }
    },
    _defaultShape: function () {
      return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
    },
    _clipPoints: function () {
      // polygons need a different clipping algorithm so we redefine that

      var bounds = this._renderer._bounds,
        w = this.options.weight,
        p = new Point(w, w);

      // increase clip padding by stroke width to avoid stroke on clip edges
      bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p));
      this._parts = [];
      if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
        return;
      }
      if (this.options.noClip) {
        this._parts = this._rings;
        return;
      }
      for (var i = 0, len = this._rings.length, clipped; i < len; i++) {
        clipped = clipPolygon(this._rings[i], bounds, true);
        if (clipped.length) {
          this._parts.push(clipped);
        }
      }
    },
    _updatePath: function () {
      this._renderer._updatePoly(this, true);
    },
    // Needed by the `Canvas` renderer for interactivity
    _containsPoint: function (p) {
      var inside = false,
        part,
        p1,
        p2,
        i,
        j,
        k,
        len,
        len2;
      if (!this._pxBounds || !this._pxBounds.contains(p)) {
        return false;
      }

      // ray casting algorithm for detecting if point is in polygon
      for (i = 0, len = this._parts.length; i < len; i++) {
        part = this._parts[i];
        for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
          p1 = part[j];
          p2 = part[k];
          if (p1.y > p.y !== p2.y > p.y && p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x) {
            inside = !inside;
          }
        }
      }

      // also check if it's on polygon stroke
      return inside || Polyline.prototype._containsPoint.call(this, p, true);
    }
  });

  // @factory L.polygon(latlngs: LatLng[], options?: Polyline options)
  function polygon(latlngs, options) {
    return new Polygon(latlngs, options);
  }

  /*
   * @class GeoJSON
   * @aka L.GeoJSON
   * @inherits FeatureGroup
   *
   * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse
   * GeoJSON data and display it on the map. Extends `FeatureGroup`.
   *
   * @example
   *
   * ```js
   * L.geoJSON(data, {
   * 	style: function (feature) {
   * 		return {color: feature.properties.color};
   * 	}
   * }).bindPopup(function (layer) {
   * 	return layer.feature.properties.description;
   * }).addTo(map);
   * ```
   */

  var GeoJSON = FeatureGroup.extend({
    /* @section
     * @aka GeoJSON options
     *
     * @option pointToLayer: Function = *
     * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally
     * called when data is added, passing the GeoJSON point feature and its `LatLng`.
     * The default is to spawn a default `Marker`:
     * ```js
     * function(geoJsonPoint, latlng) {
     * 	return L.marker(latlng);
     * }
     * ```
     *
     * @option style: Function = *
     * A `Function` defining the `Path options` for styling GeoJSON lines and polygons,
     * called internally when data is added.
     * The default value is to not override any defaults:
     * ```js
     * function (geoJsonFeature) {
     * 	return {}
     * }
     * ```
     *
     * @option onEachFeature: Function = *
     * A `Function` that will be called once for each created `Feature`, after it has
     * been created and styled. Useful for attaching events and popups to features.
     * The default is to do nothing with the newly created layers:
     * ```js
     * function (feature, layer) {}
     * ```
     *
     * @option filter: Function = *
     * A `Function` that will be used to decide whether to include a feature or not.
     * The default is to include all features:
     * ```js
     * function (geoJsonFeature) {
     * 	return true;
     * }
     * ```
     * Note: dynamically changing the `filter` option will have effect only on newly
     * added data. It will _not_ re-evaluate already included features.
     *
     * @option coordsToLatLng: Function = *
     * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s.
     * The default is the `coordsToLatLng` static method.
     *
     * @option markersInheritOptions: Boolean = false
     * Whether default Markers for "Point" type Features inherit from group options.
     */

    initialize: function (geojson, options) {
      setOptions(this, options);
      this._layers = {};
      if (geojson) {
        this.addData(geojson);
      }
    },
    // @method addData( <GeoJSON> data ): this
    // Adds a GeoJSON object to the layer.
    addData: function (geojson) {
      var features = isArray(geojson) ? geojson : geojson.features,
        i,
        len,
        feature;
      if (features) {
        for (i = 0, len = features.length; i < len; i++) {
          // only add this if geometry or geometries are set and not null
          feature = features[i];
          if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {
            this.addData(feature);
          }
        }
        return this;
      }
      var options = this.options;
      if (options.filter && !options.filter(geojson)) {
        return this;
      }
      var layer = geometryToLayer(geojson, options);
      if (!layer) {
        return this;
      }
      layer.feature = asFeature(geojson);
      layer.defaultOptions = layer.options;
      this.resetStyle(layer);
      if (options.onEachFeature) {
        options.onEachFeature(geojson, layer);
      }
      return this.addLayer(layer);
    },
    // @method resetStyle( <Path> layer? ): this
    // Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.
    // If `layer` is omitted, the style of all features in the current layer is reset.
    resetStyle: function (layer) {
      if (layer === undefined) {
        return this.eachLayer(this.resetStyle, this);
      }
      // reset any custom styles
      layer.options = extend({}, layer.defaultOptions);
      this._setLayerStyle(layer, this.options.style);
      return this;
    },
    // @method setStyle( <Function> style ): this
    // Changes styles of GeoJSON vector layers with the given style function.
    setStyle: function (style) {
      return this.eachLayer(function (layer) {
        this._setLayerStyle(layer, style);
      }, this);
    },
    _setLayerStyle: function (layer, style) {
      if (layer.setStyle) {
        if (typeof style === 'function') {
          style = style(layer.feature);
        }
        layer.setStyle(style);
      }
    }
  });

  // @section
  // There are several static functions which can be called without instantiating L.GeoJSON:

  // @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer
  // Creates a `Layer` from a given GeoJSON feature. Can use a custom
  // [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng)
  // functions if provided as options.
  function geometryToLayer(geojson, options) {
    var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson,
      coords = geometry ? geometry.coordinates : null,
      layers = [],
      pointToLayer = options && options.pointToLayer,
      _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng,
      latlng,
      latlngs,
      i,
      len;
    if (!coords && !geometry) {
      return null;
    }
    switch (geometry.type) {
      case 'Point':
        latlng = _coordsToLatLng(coords);
        return _pointToLayer(pointToLayer, geojson, latlng, options);
      case 'MultiPoint':
        for (i = 0, len = coords.length; i < len; i++) {
          latlng = _coordsToLatLng(coords[i]);
          layers.push(_pointToLayer(pointToLayer, geojson, latlng, options));
        }
        return new FeatureGroup(layers);
      case 'LineString':
      case 'MultiLineString':
        latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng);
        return new Polyline(latlngs, options);
      case 'Polygon':
      case 'MultiPolygon':
        latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng);
        return new Polygon(latlngs, options);
      case 'GeometryCollection':
        for (i = 0, len = geometry.geometries.length; i < len; i++) {
          var geoLayer = geometryToLayer({
            geometry: geometry.geometries[i],
            type: 'Feature',
            properties: geojson.properties
          }, options);
          if (geoLayer) {
            layers.push(geoLayer);
          }
        }
        return new FeatureGroup(layers);
      case 'FeatureCollection':
        for (i = 0, len = geometry.features.length; i < len; i++) {
          var featureLayer = geometryToLayer(geometry.features[i], options);
          if (featureLayer) {
            layers.push(featureLayer);
          }
        }
        return new FeatureGroup(layers);
      default:
        throw new Error('Invalid GeoJSON object.');
    }
  }
  function _pointToLayer(pointToLayerFn, geojson, latlng, options) {
    return pointToLayerFn ? pointToLayerFn(geojson, latlng) : new Marker(latlng, options && options.markersInheritOptions && options);
  }

  // @function coordsToLatLng(coords: Array): LatLng
  // Creates a `LatLng` object from an array of 2 numbers (longitude, latitude)
  // or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.
  function coordsToLatLng(coords) {
    return new LatLng(coords[1], coords[0], coords[2]);
  }

  // @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array
  // Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array.
  // `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default).
  // Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function.
  function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) {
    var latlngs = [];
    for (var i = 0, len = coords.length, latlng; i < len; i++) {
      latlng = levelsDeep ? coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) : (_coordsToLatLng || coordsToLatLng)(coords[i]);
      latlngs.push(latlng);
    }
    return latlngs;
  }

  // @function latLngToCoords(latlng: LatLng, precision?: Number|false): Array
  // Reverse of [`coordsToLatLng`](#geojson-coordstolatlng)
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function.
  function latLngToCoords(latlng, precision) {
    latlng = toLatLng(latlng);
    return latlng.alt !== undefined ? [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] : [formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)];
  }

  // @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean, precision?: Number|false): Array
  // Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs)
  // `closed` determines whether the first point should be appended to the end of the array to close the feature, only used when `levelsDeep` is 0. False by default.
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function.
  function latLngsToCoords(latlngs, levelsDeep, closed, precision) {
    var coords = [];
    for (var i = 0, len = latlngs.length; i < len; i++) {
      // Check for flat arrays required to ensure unbalanced arrays are correctly converted in recursion
      coords.push(levelsDeep ? latLngsToCoords(latlngs[i], isFlat(latlngs[i]) ? 0 : levelsDeep - 1, closed, precision) : latLngToCoords(latlngs[i], precision));
    }
    if (!levelsDeep && closed && coords.length > 0) {
      coords.push(coords[0].slice());
    }
    return coords;
  }
  function getFeature(layer, newGeometry) {
    return layer.feature ? extend({}, layer.feature, {
      geometry: newGeometry
    }) : asFeature(newGeometry);
  }

  // @function asFeature(geojson: Object): Object
  // Normalize GeoJSON geometries/features into GeoJSON features.
  function asFeature(geojson) {
    if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') {
      return geojson;
    }
    return {
      type: 'Feature',
      properties: {},
      geometry: geojson
    };
  }
  var PointToGeoJSON = {
    toGeoJSON: function (precision) {
      return getFeature(this, {
        type: 'Point',
        coordinates: latLngToCoords(this.getLatLng(), precision)
      });
    }
  };

  // @namespace Marker
  // @section Other methods
  // @method toGeoJSON(precision?: Number|false): Object
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`.
  // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature).
  Marker.include(PointToGeoJSON);

  // @namespace CircleMarker
  // @method toGeoJSON(precision?: Number|false): Object
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`.
  // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature).
  Circle.include(PointToGeoJSON);
  CircleMarker.include(PointToGeoJSON);

  // @namespace Polyline
  // @method toGeoJSON(precision?: Number|false): Object
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`.
  // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature).
  Polyline.include({
    toGeoJSON: function (precision) {
      var multi = !isFlat(this._latlngs);
      var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision);
      return getFeature(this, {
        type: (multi ? 'Multi' : '') + 'LineString',
        coordinates: coords
      });
    }
  });

  // @namespace Polygon
  // @method toGeoJSON(precision?: Number|false): Object
  // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`.
  // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature).
  Polygon.include({
    toGeoJSON: function (precision) {
      var holes = !isFlat(this._latlngs),
        multi = holes && !isFlat(this._latlngs[0]);
      var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision);
      if (!holes) {
        coords = [coords];
      }
      return getFeature(this, {
        type: (multi ? 'Multi' : '') + 'Polygon',
        coordinates: coords
      });
    }
  });

  // @namespace LayerGroup
  LayerGroup.include({
    toMultiPoint: function (precision) {
      var coords = [];
      this.eachLayer(function (layer) {
        coords.push(layer.toGeoJSON(precision).geometry.coordinates);
      });
      return getFeature(this, {
        type: 'MultiPoint',
        coordinates: coords
      });
    },
    // @method toGeoJSON(precision?: Number|false): Object
    // Coordinates values are rounded with [`formatNum`](#util-formatnum) function with given `precision`.
    // Returns a [`GeoJSON`](https://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`).
    toGeoJSON: function (precision) {
      var type = this.feature && this.feature.geometry && this.feature.geometry.type;
      if (type === 'MultiPoint') {
        return this.toMultiPoint(precision);
      }
      var isGeometryCollection = type === 'GeometryCollection',
        jsons = [];
      this.eachLayer(function (layer) {
        if (layer.toGeoJSON) {
          var json = layer.toGeoJSON(precision);
          if (isGeometryCollection) {
            jsons.push(json.geometry);
          } else {
            var feature = asFeature(json);
            // Squash nested feature collections
            if (feature.type === 'FeatureCollection') {
              jsons.push.apply(jsons, feature.features);
            } else {
              jsons.push(feature);
            }
          }
        }
      });
      if (isGeometryCollection) {
        return getFeature(this, {
          geometries: jsons,
          type: 'GeometryCollection'
        });
      }
      return {
        type: 'FeatureCollection',
        features: jsons
      };
    }
  });

  // @namespace GeoJSON
  // @factory L.geoJSON(geojson?: Object, options?: GeoJSON options)
  // Creates a GeoJSON layer. Optionally accepts an object in
  // [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map
  // (you can alternatively add it later with `addData` method) and an `options` object.
  function geoJSON(geojson, options) {
    return new GeoJSON(geojson, options);
  }

  // Backward compatibility.
  var geoJson = geoJSON;

  /*
   * @class ImageOverlay
   * @aka L.ImageOverlay
   * @inherits Interactive layer
   *
   * Used to load and display a single image over specific bounds of the map. Extends `Layer`.
   *
   * @example
   *
   * ```js
   * var imageUrl = 'https://maps.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
   * 	imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
   * L.imageOverlay(imageUrl, imageBounds).addTo(map);
   * ```
   */

  var ImageOverlay = Layer.extend({
    // @section
    // @aka ImageOverlay options
    options: {
      // @option opacity: Number = 1.0
      // The opacity of the image overlay.
      opacity: 1,
      // @option alt: String = ''
      // Text for the `alt` attribute of the image (useful for accessibility).
      alt: '',
      // @option interactive: Boolean = false
      // If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered.
      interactive: false,
      // @option crossOrigin: Boolean|String = false
      // Whether the crossOrigin attribute will be added to the image.
      // If a String is provided, the image will have its crossOrigin attribute set to the String provided. This is needed if you want to access image pixel data.
      // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.
      crossOrigin: false,
      // @option errorOverlayUrl: String = ''
      // URL to the overlay image to show in place of the overlay that failed to load.
      errorOverlayUrl: '',
      // @option zIndex: Number = 1
      // The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer.
      zIndex: 1,
      // @option className: String = ''
      // A custom class name to assign to the image. Empty by default.
      className: ''
    },
    initialize: function (url, bounds, options) {
      // (String, LatLngBounds, Object)
      this._url = url;
      this._bounds = toLatLngBounds(bounds);
      setOptions(this, options);
    },
    onAdd: function () {
      if (!this._image) {
        this._initImage();
        if (this.options.opacity < 1) {
          this._updateOpacity();
        }
      }
      if (this.options.interactive) {
        addClass(this._image, 'leaflet-interactive');
        this.addInteractiveTarget(this._image);
      }
      this.getPane().appendChild(this._image);
      this._reset();
    },
    onRemove: function () {
      remove(this._image);
      if (this.options.interactive) {
        this.removeInteractiveTarget(this._image);
      }
    },
    // @method setOpacity(opacity: Number): this
    // Sets the opacity of the overlay.
    setOpacity: function (opacity) {
      this.options.opacity = opacity;
      if (this._image) {
        this._updateOpacity();
      }
      return this;
    },
    setStyle: function (styleOpts) {
      if (styleOpts.opacity) {
        this.setOpacity(styleOpts.opacity);
      }
      return this;
    },
    // @method bringToFront(): this
    // Brings the layer to the top of all overlays.
    bringToFront: function () {
      if (this._map) {
        toFront(this._image);
      }
      return this;
    },
    // @method bringToBack(): this
    // Brings the layer to the bottom of all overlays.
    bringToBack: function () {
      if (this._map) {
        toBack(this._image);
      }
      return this;
    },
    // @method setUrl(url: String): this
    // Changes the URL of the image.
    setUrl: function (url) {
      this._url = url;
      if (this._image) {
        this._image.src = url;
      }
      return this;
    },
    // @method setBounds(bounds: LatLngBounds): this
    // Update the bounds that this ImageOverlay covers
    setBounds: function (bounds) {
      this._bounds = toLatLngBounds(bounds);
      if (this._map) {
        this._reset();
      }
      return this;
    },
    getEvents: function () {
      var events = {
        zoom: this._reset,
        viewreset: this._reset
      };
      if (this._zoomAnimated) {
        events.zoomanim = this._animateZoom;
      }
      return events;
    },
    // @method setZIndex(value: Number): this
    // Changes the [zIndex](#imageoverlay-zindex) of the image overlay.
    setZIndex: function (value) {
      this.options.zIndex = value;
      this._updateZIndex();
      return this;
    },
    // @method getBounds(): LatLngBounds
    // Get the bounds that this ImageOverlay covers
    getBounds: function () {
      return this._bounds;
    },
    // @method getElement(): HTMLElement
    // Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement)
    // used by this overlay.
    getElement: function () {
      return this._image;
    },
    _initImage: function () {
      var wasElementSupplied = this._url.tagName === 'IMG';
      var img = this._image = wasElementSupplied ? this._url : create$1('img');
      addClass(img, 'leaflet-image-layer');
      if (this._zoomAnimated) {
        addClass(img, 'leaflet-zoom-animated');
      }
      if (this.options.className) {
        addClass(img, this.options.className);
      }
      img.onselectstart = falseFn;
      img.onmousemove = falseFn;

      // @event load: Event
      // Fired when the ImageOverlay layer has loaded its image
      img.onload = bind(this.fire, this, 'load');
      img.onerror = bind(this._overlayOnError, this, 'error');
      if (this.options.crossOrigin || this.options.crossOrigin === '') {
        img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
      }
      if (this.options.zIndex) {
        this._updateZIndex();
      }
      if (wasElementSupplied) {
        this._url = img.src;
        return;
      }
      img.src = this._url;
      img.alt = this.options.alt;
    },
    _animateZoom: function (e) {
      var scale = this._map.getZoomScale(e.zoom),
        offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min;
      setTransform(this._image, offset, scale);
    },
    _reset: function () {
      var image = this._image,
        bounds = new Bounds(this._map.latLngToLayerPoint(this._bounds.getNorthWest()), this._map.latLngToLayerPoint(this._bounds.getSouthEast())),
        size = bounds.getSize();
      setPosition(image, bounds.min);
      image.style.width = size.x + 'px';
      image.style.height = size.y + 'px';
    },
    _updateOpacity: function () {
      setOpacity(this._image, this.options.opacity);
    },
    _updateZIndex: function () {
      if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) {
        this._image.style.zIndex = this.options.zIndex;
      }
    },
    _overlayOnError: function () {
      // @event error: Event
      // Fired when the ImageOverlay layer fails to load its image
      this.fire('error');
      var errorUrl = this.options.errorOverlayUrl;
      if (errorUrl && this._url !== errorUrl) {
        this._url = errorUrl;
        this._image.src = errorUrl;
      }
    },
    // @method getCenter(): LatLng
    // Returns the center of the ImageOverlay.
    getCenter: function () {
      return this._bounds.getCenter();
    }
  });

  // @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options)
  // Instantiates an image overlay object given the URL of the image and the
  // geographical bounds it is tied to.
  var imageOverlay = function (url, bounds, options) {
    return new ImageOverlay(url, bounds, options);
  };

  /*
   * @class VideoOverlay
   * @aka L.VideoOverlay
   * @inherits ImageOverlay
   *
   * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`.
   *
   * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video)
   * HTML5 element.
   *
   * @example
   *
   * ```js
   * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
   * 	videoBounds = [[ 32, -130], [ 13, -100]];
   * L.videoOverlay(videoUrl, videoBounds ).addTo(map);
   * ```
   */

  var VideoOverlay = ImageOverlay.extend({
    // @section
    // @aka VideoOverlay options
    options: {
      // @option autoplay: Boolean = true
      // Whether the video starts playing automatically when loaded.
      // On some browsers autoplay will only work with `muted: true`
      autoplay: true,
      // @option loop: Boolean = true
      // Whether the video will loop back to the beginning when played.
      loop: true,
      // @option keepAspectRatio: Boolean = true
      // Whether the video will save aspect ratio after the projection.
      // Relevant for supported browsers. See [browser compatibility](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)
      keepAspectRatio: true,
      // @option muted: Boolean = false
      // Whether the video starts on mute when loaded.
      muted: false,
      // @option playsInline: Boolean = true
      // Mobile browsers will play the video right where it is instead of open it up in fullscreen mode.
      playsInline: true
    },
    _initImage: function () {
      var wasElementSupplied = this._url.tagName === 'VIDEO';
      var vid = this._image = wasElementSupplied ? this._url : create$1('video');
      addClass(vid, 'leaflet-image-layer');
      if (this._zoomAnimated) {
        addClass(vid, 'leaflet-zoom-animated');
      }
      if (this.options.className) {
        addClass(vid, this.options.className);
      }
      vid.onselectstart = falseFn;
      vid.onmousemove = falseFn;

      // @event load: Event
      // Fired when the video has finished loading the first frame
      vid.onloadeddata = bind(this.fire, this, 'load');
      if (wasElementSupplied) {
        var sourceElements = vid.getElementsByTagName('source');
        var sources = [];
        for (var j = 0; j < sourceElements.length; j++) {
          sources.push(sourceElements[j].src);
        }
        this._url = sourceElements.length > 0 ? sources : [vid.src];
        return;
      }
      if (!isArray(this._url)) {
        this._url = [this._url];
      }
      if (!this.options.keepAspectRatio && Object.prototype.hasOwnProperty.call(vid.style, 'objectFit')) {
        vid.style['objectFit'] = 'fill';
      }
      vid.autoplay = !!this.options.autoplay;
      vid.loop = !!this.options.loop;
      vid.muted = !!this.options.muted;
      vid.playsInline = !!this.options.playsInline;
      for (var i = 0; i < this._url.length; i++) {
        var source = create$1('source');
        source.src = this._url[i];
        vid.appendChild(source);
      }
    }

    // @method getElement(): HTMLVideoElement
    // Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement)
    // used by this overlay.
  });

  // @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options)
  // Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the
  // geographical bounds it is tied to.

  function videoOverlay(video, bounds, options) {
    return new VideoOverlay(video, bounds, options);
  }

  /*
   * @class SVGOverlay
   * @aka L.SVGOverlay
   * @inherits ImageOverlay
   *
   * Used to load, display and provide DOM access to an SVG file over specific bounds of the map. Extends `ImageOverlay`.
   *
   * An SVG overlay uses the [`<svg>`](https://developer.mozilla.org/docs/Web/SVG/Element/svg) element.
   *
   * @example
   *
   * ```js
   * var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
   * svgElement.setAttribute('xmlns', "http://www.w3.org/2000/svg");
   * svgElement.setAttribute('viewBox', "0 0 200 200");
   * svgElement.innerHTML = '<rect width="200" height="200"/><rect x="75" y="23" width="50" height="50" style="fill:red"/><rect x="75" y="123" width="50" height="50" style="fill:#0013ff"/>';
   * var svgElementBounds = [ [ 32, -130 ], [ 13, -100 ] ];
   * L.svgOverlay(svgElement, svgElementBounds).addTo(map);
   * ```
   */

  var SVGOverlay = ImageOverlay.extend({
    _initImage: function () {
      var el = this._image = this._url;
      addClass(el, 'leaflet-image-layer');
      if (this._zoomAnimated) {
        addClass(el, 'leaflet-zoom-animated');
      }
      if (this.options.className) {
        addClass(el, this.options.className);
      }
      el.onselectstart = falseFn;
      el.onmousemove = falseFn;
    }

    // @method getElement(): SVGElement
    // Returns the instance of [`SVGElement`](https://developer.mozilla.org/docs/Web/API/SVGElement)
    // used by this overlay.
  });

  // @factory L.svgOverlay(svg: String|SVGElement, bounds: LatLngBounds, options?: SVGOverlay options)
  // Instantiates an image overlay object given an SVG element and the geographical bounds it is tied to.
  // A viewBox attribute is required on the SVG element to zoom in and out properly.

  function svgOverlay(el, bounds, options) {
    return new SVGOverlay(el, bounds, options);
  }

  /*
   * @class DivOverlay
   * @inherits Interactive layer
   * @aka L.DivOverlay
   * Base model for L.Popup and L.Tooltip. Inherit from it for custom overlays like plugins.
   */

  // @namespace DivOverlay
  var DivOverlay = Layer.extend({
    // @section
    // @aka DivOverlay options
    options: {
      // @option interactive: Boolean = false
      // If true, the popup/tooltip will listen to the mouse events.
      interactive: false,
      // @option offset: Point = Point(0, 0)
      // The offset of the overlay position.
      offset: [0, 0],
      // @option className: String = ''
      // A custom CSS class name to assign to the overlay.
      className: '',
      // @option pane: String = undefined
      // `Map pane` where the overlay will be added.
      pane: undefined,
      // @option content: String|HTMLElement|Function = ''
      // Sets the HTML content of the overlay while initializing. If a function is passed the source layer will be
      // passed to the function. The function should return a `String` or `HTMLElement` to be used in the overlay.
      content: ''
    },
    initialize: function (options, source) {
      if (options && (options instanceof LatLng || isArray(options))) {
        this._latlng = toLatLng(options);
        setOptions(this, source);
      } else {
        setOptions(this, options);
        this._source = source;
      }
      if (this.options.content) {
        this._content = this.options.content;
      }
    },
    // @method openOn(map: Map): this
    // Adds the overlay to the map.
    // Alternative to `map.openPopup(popup)`/`.openTooltip(tooltip)`.
    openOn: function (map) {
      map = arguments.length ? map : this._source._map; // experimental, not the part of public api
      if (!map.hasLayer(this)) {
        map.addLayer(this);
      }
      return this;
    },
    // @method close(): this
    // Closes the overlay.
    // Alternative to `map.closePopup(popup)`/`.closeTooltip(tooltip)`
    // and `layer.closePopup()`/`.closeTooltip()`.
    close: function () {
      if (this._map) {
        this._map.removeLayer(this);
      }
      return this;
    },
    // @method toggle(layer?: Layer): this
    // Opens or closes the overlay bound to layer depending on its current state.
    // Argument may be omitted only for overlay bound to layer.
    // Alternative to `layer.togglePopup()`/`.toggleTooltip()`.
    toggle: function (layer) {
      if (this._map) {
        this.close();
      } else {
        if (arguments.length) {
          this._source = layer;
        } else {
          layer = this._source;
        }
        this._prepareOpen();

        // open the overlay on the map
        this.openOn(layer._map);
      }
      return this;
    },
    onAdd: function (map) {
      this._zoomAnimated = map._zoomAnimated;
      if (!this._container) {
        this._initLayout();
      }
      if (map._fadeAnimated) {
        setOpacity(this._container, 0);
      }
      clearTimeout(this._removeTimeout);
      this.getPane().appendChild(this._container);
      this.update();
      if (map._fadeAnimated) {
        setOpacity(this._container, 1);
      }
      this.bringToFront();
      if (this.options.interactive) {
        addClass(this._container, 'leaflet-interactive');
        this.addInteractiveTarget(this._container);
      }
    },
    onRemove: function (map) {
      if (map._fadeAnimated) {
        setOpacity(this._container, 0);
        this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200);
      } else {
        remove(this._container);
      }
      if (this.options.interactive) {
        removeClass(this._container, 'leaflet-interactive');
        this.removeInteractiveTarget(this._container);
      }
    },
    // @namespace DivOverlay
    // @method getLatLng: LatLng
    // Returns the geographical point of the overlay.
    getLatLng: function () {
      return this._latlng;
    },
    // @method setLatLng(latlng: LatLng): this
    // Sets the geographical point where the overlay will open.
    setLatLng: function (latlng) {
      this._latlng = toLatLng(latlng);
      if (this._map) {
        this._updatePosition();
        this._adjustPan();
      }
      return this;
    },
    // @method getContent: String|HTMLElement
    // Returns the content of the overlay.
    getContent: function () {
      return this._content;
    },
    // @method setContent(htmlContent: String|HTMLElement|Function): this
    // Sets the HTML content of the overlay. If a function is passed the source layer will be passed to the function.
    // The function should return a `String` or `HTMLElement` to be used in the overlay.
    setContent: function (content) {
      this._content = content;
      this.update();
      return this;
    },
    // @method getElement: String|HTMLElement
    // Returns the HTML container of the overlay.
    getElement: function () {
      return this._container;
    },
    // @method update: null
    // Updates the overlay content, layout and position. Useful for updating the overlay after something inside changed, e.g. image loaded.
    update: function () {
      if (!this._map) {
        return;
      }
      this._container.style.visibility = 'hidden';
      this._updateContent();
      this._updateLayout();
      this._updatePosition();
      this._container.style.visibility = '';
      this._adjustPan();
    },
    getEvents: function () {
      var events = {
        zoom: this._updatePosition,
        viewreset: this._updatePosition
      };
      if (this._zoomAnimated) {
        events.zoomanim = this._animateZoom;
      }
      return events;
    },
    // @method isOpen: Boolean
    // Returns `true` when the overlay is visible on the map.
    isOpen: function () {
      return !!this._map && this._map.hasLayer(this);
    },
    // @method bringToFront: this
    // Brings this overlay in front of other overlays (in the same map pane).
    bringToFront: function () {
      if (this._map) {
        toFront(this._container);
      }
      return this;
    },
    // @method bringToBack: this
    // Brings this overlay to the back of other overlays (in the same map pane).
    bringToBack: function () {
      if (this._map) {
        toBack(this._container);
      }
      return this;
    },
    // prepare bound overlay to open: update latlng pos / content source (for FeatureGroup)
    _prepareOpen: function (latlng) {
      var source = this._source;
      if (!source._map) {
        return false;
      }
      if (source instanceof FeatureGroup) {
        source = null;
        var layers = this._source._layers;
        for (var id in layers) {
          if (layers[id]._map) {
            source = layers[id];
            break;
          }
        }
        if (!source) {
          return false;
        } // Unable to get source layer.

        // set overlay source to this layer
        this._source = source;
      }
      if (!latlng) {
        if (source.getCenter) {
          latlng = source.getCenter();
        } else if (source.getLatLng) {
          latlng = source.getLatLng();
        } else if (source.getBounds) {
          latlng = source.getBounds().getCenter();
        } else {
          throw new Error('Unable to get source layer LatLng.');
        }
      }
      this.setLatLng(latlng);
      if (this._map) {
        // update the overlay (content, layout, etc...)
        this.update();
      }
      return true;
    },
    _updateContent: function () {
      if (!this._content) {
        return;
      }
      var node = this._contentNode;
      var content = typeof this._content === 'function' ? this._content(this._source || this) : this._content;
      if (typeof content === 'string') {
        node.innerHTML = content;
      } else {
        while (node.hasChildNodes()) {
          node.removeChild(node.firstChild);
        }
        node.appendChild(content);
      }

      // @namespace DivOverlay
      // @section DivOverlay events
      // @event contentupdate: Event
      // Fired when the content of the overlay is updated
      this.fire('contentupdate');
    },
    _updatePosition: function () {
      if (!this._map) {
        return;
      }
      var pos = this._map.latLngToLayerPoint(this._latlng),
        offset = toPoint(this.options.offset),
        anchor = this._getAnchor();
      if (this._zoomAnimated) {
        setPosition(this._container, pos.add(anchor));
      } else {
        offset = offset.add(pos).add(anchor);
      }
      var bottom = this._containerBottom = -offset.y,
        left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;

      // bottom position the overlay in case the height of the overlay changes (images loading etc)
      this._container.style.bottom = bottom + 'px';
      this._container.style.left = left + 'px';
    },
    _getAnchor: function () {
      return [0, 0];
    }
  });
  Map.include({
    _initOverlay: function (OverlayClass, content, latlng, options) {
      var overlay = content;
      if (!(overlay instanceof OverlayClass)) {
        overlay = new OverlayClass(options).setContent(content);
      }
      if (latlng) {
        overlay.setLatLng(latlng);
      }
      return overlay;
    }
  });
  Layer.include({
    _initOverlay: function (OverlayClass, old, content, options) {
      var overlay = content;
      if (overlay instanceof OverlayClass) {
        setOptions(overlay, options);
        overlay._source = this;
      } else {
        overlay = old && !options ? old : new OverlayClass(options, this);
        overlay.setContent(content);
      }
      return overlay;
    }
  });

  /*
   * @class Popup
   * @inherits DivOverlay
   * @aka L.Popup
   * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to
   * open popups while making sure that only one popup is open at one time
   * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want.
   *
   * @example
   *
   * If you want to just bind a popup to marker click and then open it, it's really easy:
   *
   * ```js
   * marker.bindPopup(popupContent).openPopup();
   * ```
   * Path overlays like polylines also have a `bindPopup` method.
   *
   * A popup can be also standalone:
   *
   * ```js
   * var popup = L.popup()
   * 	.setLatLng(latlng)
   * 	.setContent('<p>Hello world!<br />This is a nice popup.</p>')
   * 	.openOn(map);
   * ```
   * or
   * ```js
   * var popup = L.popup(latlng, {content: '<p>Hello world!<br />This is a nice popup.</p>')
   * 	.openOn(map);
   * ```
   */

  // @namespace Popup
  var Popup = DivOverlay.extend({
    // @section
    // @aka Popup options
    options: {
      // @option pane: String = 'popupPane'
      // `Map pane` where the popup will be added.
      pane: 'popupPane',
      // @option offset: Point = Point(0, 7)
      // The offset of the popup position.
      offset: [0, 7],
      // @option maxWidth: Number = 300
      // Max width of the popup, in pixels.
      maxWidth: 300,
      // @option minWidth: Number = 50
      // Min width of the popup, in pixels.
      minWidth: 50,
      // @option maxHeight: Number = null
      // If set, creates a scrollable container of the given height
      // inside a popup if its content exceeds it.
      // The scrollable container can be styled using the
      // `leaflet-popup-scrolled` CSS class selector.
      maxHeight: null,
      // @option autoPan: Boolean = true
      // Set it to `false` if you don't want the map to do panning animation
      // to fit the opened popup.
      autoPan: true,
      // @option autoPanPaddingTopLeft: Point = null
      // The margin between the popup and the top left corner of the map
      // view after autopanning was performed.
      autoPanPaddingTopLeft: null,
      // @option autoPanPaddingBottomRight: Point = null
      // The margin between the popup and the bottom right corner of the map
      // view after autopanning was performed.
      autoPanPaddingBottomRight: null,
      // @option autoPanPadding: Point = Point(5, 5)
      // Equivalent of setting both top left and bottom right autopan padding to the same value.
      autoPanPadding: [5, 5],
      // @option keepInView: Boolean = false
      // Set it to `true` if you want to prevent users from panning the popup
      // off of the screen while it is open.
      keepInView: false,
      // @option closeButton: Boolean = true
      // Controls the presence of a close button in the popup.
      closeButton: true,
      // @option autoClose: Boolean = true
      // Set it to `false` if you want to override the default behavior of
      // the popup closing when another popup is opened.
      autoClose: true,
      // @option closeOnEscapeKey: Boolean = true
      // Set it to `false` if you want to override the default behavior of
      // the ESC key for closing of the popup.
      closeOnEscapeKey: true,
      // @option closeOnClick: Boolean = *
      // Set it if you want to override the default behavior of the popup closing when user clicks
      // on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option.

      // @option className: String = ''
      // A custom CSS class name to assign to the popup.
      className: ''
    },
    // @namespace Popup
    // @method openOn(map: Map): this
    // Alternative to `map.openPopup(popup)`.
    // Adds the popup to the map and closes the previous one.
    openOn: function (map) {
      map = arguments.length ? map : this._source._map; // experimental, not the part of public api

      if (!map.hasLayer(this) && map._popup && map._popup.options.autoClose) {
        map.removeLayer(map._popup);
      }
      map._popup = this;
      return DivOverlay.prototype.openOn.call(this, map);
    },
    onAdd: function (map) {
      DivOverlay.prototype.onAdd.call(this, map);

      // @namespace Map
      // @section Popup events
      // @event popupopen: PopupEvent
      // Fired when a popup is opened in the map
      map.fire('popupopen', {
        popup: this
      });
      if (this._source) {
        // @namespace Layer
        // @section Popup events
        // @event popupopen: PopupEvent
        // Fired when a popup bound to this layer is opened
        this._source.fire('popupopen', {
          popup: this
        }, true);
        // For non-path layers, we toggle the popup when clicking
        // again the layer, so prevent the map to reopen it.
        if (!(this._source instanceof Path)) {
          this._source.on('preclick', stopPropagation);
        }
      }
    },
    onRemove: function (map) {
      DivOverlay.prototype.onRemove.call(this, map);

      // @namespace Map
      // @section Popup events
      // @event popupclose: PopupEvent
      // Fired when a popup in the map is closed
      map.fire('popupclose', {
        popup: this
      });
      if (this._source) {
        // @namespace Layer
        // @section Popup events
        // @event popupclose: PopupEvent
        // Fired when a popup bound to this layer is closed
        this._source.fire('popupclose', {
          popup: this
        }, true);
        if (!(this._source instanceof Path)) {
          this._source.off('preclick', stopPropagation);
        }
      }
    },
    getEvents: function () {
      var events = DivOverlay.prototype.getEvents.call(this);
      if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) {
        events.preclick = this.close;
      }
      if (this.options.keepInView) {
        events.moveend = this._adjustPan;
      }
      return events;
    },
    _initLayout: function () {
      var prefix = 'leaflet-popup',
        container = this._container = create$1('div', prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-animated');
      var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container);
      this._contentNode = create$1('div', prefix + '-content', wrapper);
      disableClickPropagation(container);
      disableScrollPropagation(this._contentNode);
      on(container, 'contextmenu', stopPropagation);
      this._tipContainer = create$1('div', prefix + '-tip-container', container);
      this._tip = create$1('div', prefix + '-tip', this._tipContainer);
      if (this.options.closeButton) {
        var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container);
        closeButton.setAttribute('role', 'button'); // overrides the implicit role=link of <a> elements #7399
        closeButton.setAttribute('aria-label', 'Close popup');
        closeButton.href = '#close';
        closeButton.innerHTML = '<span aria-hidden="true">&#215;</span>';
        on(closeButton, 'click', function (ev) {
          preventDefault(ev);
          this.close();
        }, this);
      }
    },
    _updateLayout: function () {
      var container = this._contentNode,
        style = container.style;
      style.width = '';
      style.whiteSpace = 'nowrap';
      var width = container.offsetWidth;
      width = Math.min(width, this.options.maxWidth);
      width = Math.max(width, this.options.minWidth);
      style.width = width + 1 + 'px';
      style.whiteSpace = '';
      style.height = '';
      var height = container.offsetHeight,
        maxHeight = this.options.maxHeight,
        scrolledClass = 'leaflet-popup-scrolled';
      if (maxHeight && height > maxHeight) {
        style.height = maxHeight + 'px';
        addClass(container, scrolledClass);
      } else {
        removeClass(container, scrolledClass);
      }
      this._containerWidth = this._container.offsetWidth;
    },
    _animateZoom: function (e) {
      var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center),
        anchor = this._getAnchor();
      setPosition(this._container, pos.add(anchor));
    },
    _adjustPan: function () {
      if (!this.options.autoPan) {
        return;
      }
      if (this._map._panAnim) {
        this._map._panAnim.stop();
      }

      // We can endlessly recurse if keepInView is set and the view resets.
      // Let's guard against that by exiting early if we're responding to our own autopan.
      if (this._autopanning) {
        this._autopanning = false;
        return;
      }
      var map = this._map,
        marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0,
        containerHeight = this._container.offsetHeight + marginBottom,
        containerWidth = this._containerWidth,
        layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom);
      layerPos._add(getPosition(this._container));
      var containerPos = map.layerPointToContainerPoint(layerPos),
        padding = toPoint(this.options.autoPanPadding),
        paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding),
        paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding),
        size = map.getSize(),
        dx = 0,
        dy = 0;
      if (containerPos.x + containerWidth + paddingBR.x > size.x) {
        // right
        dx = containerPos.x + containerWidth - size.x + paddingBR.x;
      }
      if (containerPos.x - dx - paddingTL.x < 0) {
        // left
        dx = containerPos.x - paddingTL.x;
      }
      if (containerPos.y + containerHeight + paddingBR.y > size.y) {
        // bottom
        dy = containerPos.y + containerHeight - size.y + paddingBR.y;
      }
      if (containerPos.y - dy - paddingTL.y < 0) {
        // top
        dy = containerPos.y - paddingTL.y;
      }

      // @namespace Map
      // @section Popup events
      // @event autopanstart: Event
      // Fired when the map starts autopanning when opening a popup.
      if (dx || dy) {
        // Track that we're autopanning, as this function will be re-ran on moveend
        if (this.options.keepInView) {
          this._autopanning = true;
        }
        map.fire('autopanstart').panBy([dx, dy]);
      }
    },
    _getAnchor: function () {
      // Where should we anchor the popup on the source layer?
      return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]);
    }
  });

  // @namespace Popup
  // @factory L.popup(options?: Popup options, source?: Layer)
  // Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers.
  // @alternative
  // @factory L.popup(latlng: LatLng, options?: Popup options)
  // Instantiates a `Popup` object given `latlng` where the popup will open and an optional `options` object that describes its appearance and location.
  var popup = function (options, source) {
    return new Popup(options, source);
  };

  /* @namespace Map
   * @section Interaction Options
   * @option closePopupOnClick: Boolean = true
   * Set it to `false` if you don't want popups to close when user clicks the map.
   */
  Map.mergeOptions({
    closePopupOnClick: true
  });

  // @namespace Map
  // @section Methods for Layers and Controls
  Map.include({
    // @method openPopup(popup: Popup): this
    // Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability).
    // @alternative
    // @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this
    // Creates a popup with the specified content and options and opens it in the given point on a map.
    openPopup: function (popup, latlng, options) {
      this._initOverlay(Popup, popup, latlng, options).openOn(this);
      return this;
    },
    // @method closePopup(popup?: Popup): this
    // Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one).
    closePopup: function (popup) {
      popup = arguments.length ? popup : this._popup;
      if (popup) {
        popup.close();
      }
      return this;
    }
  });

  /*
   * @namespace Layer
   * @section Popup methods example
   *
   * All layers share a set of methods convenient for binding popups to it.
   *
   * ```js
   * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map);
   * layer.openPopup();
   * layer.closePopup();
   * ```
   *
   * Popups will also be automatically opened when the layer is clicked on and closed when the layer is removed from the map or another popup is opened.
   */

  // @section Popup methods
  Layer.include({
    // @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this
    // Binds a popup to the layer with the passed `content` and sets up the
    // necessary event listeners. If a `Function` is passed it will receive
    // the layer as the first argument and should return a `String` or `HTMLElement`.
    bindPopup: function (content, options) {
      this._popup = this._initOverlay(Popup, this._popup, content, options);
      if (!this._popupHandlersAdded) {
        this.on({
          click: this._openPopup,
          keypress: this._onKeyPress,
          remove: this.closePopup,
          move: this._movePopup
        });
        this._popupHandlersAdded = true;
      }
      return this;
    },
    // @method unbindPopup(): this
    // Removes the popup previously bound with `bindPopup`.
    unbindPopup: function () {
      if (this._popup) {
        this.off({
          click: this._openPopup,
          keypress: this._onKeyPress,
          remove: this.closePopup,
          move: this._movePopup
        });
        this._popupHandlersAdded = false;
        this._popup = null;
      }
      return this;
    },
    // @method openPopup(latlng?: LatLng): this
    // Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed.
    openPopup: function (latlng) {
      if (this._popup) {
        if (!(this instanceof FeatureGroup)) {
          this._popup._source = this;
        }
        if (this._popup._prepareOpen(latlng || this._latlng)) {
          // open the popup on the map
          this._popup.openOn(this._map);
        }
      }
      return this;
    },
    // @method closePopup(): this
    // Closes the popup bound to this layer if it is open.
    closePopup: function () {
      if (this._popup) {
        this._popup.close();
      }
      return this;
    },
    // @method togglePopup(): this
    // Opens or closes the popup bound to this layer depending on its current state.
    togglePopup: function () {
      if (this._popup) {
        this._popup.toggle(this);
      }
      return this;
    },
    // @method isPopupOpen(): boolean
    // Returns `true` if the popup bound to this layer is currently open.
    isPopupOpen: function () {
      return this._popup ? this._popup.isOpen() : false;
    },
    // @method setPopupContent(content: String|HTMLElement|Popup): this
    // Sets the content of the popup bound to this layer.
    setPopupContent: function (content) {
      if (this._popup) {
        this._popup.setContent(content);
      }
      return this;
    },
    // @method getPopup(): Popup
    // Returns the popup bound to this layer.
    getPopup: function () {
      return this._popup;
    },
    _openPopup: function (e) {
      if (!this._popup || !this._map) {
        return;
      }
      // prevent map click
      stop(e);
      var target = e.layer || e.target;
      if (this._popup._source === target && !(target instanceof Path)) {
        // treat it like a marker and figure out
        // if we should toggle it open/closed
        if (this._map.hasLayer(this._popup)) {
          this.closePopup();
        } else {
          this.openPopup(e.latlng);
        }
        return;
      }
      this._popup._source = target;
      this.openPopup(e.latlng);
    },
    _movePopup: function (e) {
      this._popup.setLatLng(e.latlng);
    },
    _onKeyPress: function (e) {
      if (e.originalEvent.keyCode === 13) {
        this._openPopup(e);
      }
    }
  });

  /*
   * @class Tooltip
   * @inherits DivOverlay
   * @aka L.Tooltip
   * Used to display small texts on top of map layers.
   *
   * @example
   * If you want to just bind a tooltip to marker:
   *
   * ```js
   * marker.bindTooltip("my tooltip text").openTooltip();
   * ```
   * Path overlays like polylines also have a `bindTooltip` method.
   *
   * A tooltip can be also standalone:
   *
   * ```js
   * var tooltip = L.tooltip()
   * 	.setLatLng(latlng)
   * 	.setContent('Hello world!<br />This is a nice tooltip.')
   * 	.addTo(map);
   * ```
   * or
   * ```js
   * var tooltip = L.tooltip(latlng, {content: 'Hello world!<br />This is a nice tooltip.'})
   * 	.addTo(map);
   * ```
   *
   *
   * Note about tooltip offset. Leaflet takes two options in consideration
   * for computing tooltip offsetting:
   * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
   *   Add a positive x offset to move the tooltip to the right, and a positive y offset to
   *   move it to the bottom. Negatives will move to the left and top.
   * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
   *   should adapt this value if you use a custom icon.
   */

  // @namespace Tooltip
  var Tooltip = DivOverlay.extend({
    // @section
    // @aka Tooltip options
    options: {
      // @option pane: String = 'tooltipPane'
      // `Map pane` where the tooltip will be added.
      pane: 'tooltipPane',
      // @option offset: Point = Point(0, 0)
      // Optional offset of the tooltip position.
      offset: [0, 0],
      // @option direction: String = 'auto'
      // Direction where to open the tooltip. Possible values are: `right`, `left`,
      // `top`, `bottom`, `center`, `auto`.
      // `auto` will dynamically switch between `right` and `left` according to the tooltip
      // position on the map.
      direction: 'auto',
      // @option permanent: Boolean = false
      // Whether to open the tooltip permanently or only on mouseover.
      permanent: false,
      // @option sticky: Boolean = false
      // If true, the tooltip will follow the mouse instead of being fixed at the feature center.
      sticky: false,
      // @option opacity: Number = 0.9
      // Tooltip container opacity.
      opacity: 0.9
    },
    onAdd: function (map) {
      DivOverlay.prototype.onAdd.call(this, map);
      this.setOpacity(this.options.opacity);

      // @namespace Map
      // @section Tooltip events
      // @event tooltipopen: TooltipEvent
      // Fired when a tooltip is opened in the map.
      map.fire('tooltipopen', {
        tooltip: this
      });
      if (this._source) {
        this.addEventParent(this._source);

        // @namespace Layer
        // @section Tooltip events
        // @event tooltipopen: TooltipEvent
        // Fired when a tooltip bound to this layer is opened.
        this._source.fire('tooltipopen', {
          tooltip: this
        }, true);
      }
    },
    onRemove: function (map) {
      DivOverlay.prototype.onRemove.call(this, map);

      // @namespace Map
      // @section Tooltip events
      // @event tooltipclose: TooltipEvent
      // Fired when a tooltip in the map is closed.
      map.fire('tooltipclose', {
        tooltip: this
      });
      if (this._source) {
        this.removeEventParent(this._source);

        // @namespace Layer
        // @section Tooltip events
        // @event tooltipclose: TooltipEvent
        // Fired when a tooltip bound to this layer is closed.
        this._source.fire('tooltipclose', {
          tooltip: this
        }, true);
      }
    },
    getEvents: function () {
      var events = DivOverlay.prototype.getEvents.call(this);
      if (!this.options.permanent) {
        events.preclick = this.close;
      }
      return events;
    },
    _initLayout: function () {
      var prefix = 'leaflet-tooltip',
        className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
      this._contentNode = this._container = create$1('div', className);
      this._container.setAttribute('role', 'tooltip');
      this._container.setAttribute('id', 'leaflet-tooltip-' + stamp(this));
    },
    _updateLayout: function () {},
    _adjustPan: function () {},
    _setPosition: function (pos) {
      var subX,
        subY,
        map = this._map,
        container = this._container,
        centerPoint = map.latLngToContainerPoint(map.getCenter()),
        tooltipPoint = map.layerPointToContainerPoint(pos),
        direction = this.options.direction,
        tooltipWidth = container.offsetWidth,
        tooltipHeight = container.offsetHeight,
        offset = toPoint(this.options.offset),
        anchor = this._getAnchor();
      if (direction === 'top') {
        subX = tooltipWidth / 2;
        subY = tooltipHeight;
      } else if (direction === 'bottom') {
        subX = tooltipWidth / 2;
        subY = 0;
      } else if (direction === 'center') {
        subX = tooltipWidth / 2;
        subY = tooltipHeight / 2;
      } else if (direction === 'right') {
        subX = 0;
        subY = tooltipHeight / 2;
      } else if (direction === 'left') {
        subX = tooltipWidth;
        subY = tooltipHeight / 2;
      } else if (tooltipPoint.x < centerPoint.x) {
        direction = 'right';
        subX = 0;
        subY = tooltipHeight / 2;
      } else {
        direction = 'left';
        subX = tooltipWidth + (offset.x + anchor.x) * 2;
        subY = tooltipHeight / 2;
      }
      pos = pos.subtract(toPoint(subX, subY, true)).add(offset).add(anchor);
      removeClass(container, 'leaflet-tooltip-right');
      removeClass(container, 'leaflet-tooltip-left');
      removeClass(container, 'leaflet-tooltip-top');
      removeClass(container, 'leaflet-tooltip-bottom');
      addClass(container, 'leaflet-tooltip-' + direction);
      setPosition(container, pos);
    },
    _updatePosition: function () {
      var pos = this._map.latLngToLayerPoint(this._latlng);
      this._setPosition(pos);
    },
    setOpacity: function (opacity) {
      this.options.opacity = opacity;
      if (this._container) {
        setOpacity(this._container, opacity);
      }
    },
    _animateZoom: function (e) {
      var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
      this._setPosition(pos);
    },
    _getAnchor: function () {
      // Where should we anchor the tooltip on the source layer?
      return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
    }
  });

  // @namespace Tooltip
  // @factory L.tooltip(options?: Tooltip options, source?: Layer)
  // Instantiates a `Tooltip` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
  // @alternative
  // @factory L.tooltip(latlng: LatLng, options?: Tooltip options)
  // Instantiates a `Tooltip` object given `latlng` where the tooltip will open and an optional `options` object that describes its appearance and location.
  var tooltip = function (options, source) {
    return new Tooltip(options, source);
  };

  // @namespace Map
  // @section Methods for Layers and Controls
  Map.include({
    // @method openTooltip(tooltip: Tooltip): this
    // Opens the specified tooltip.
    // @alternative
    // @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this
    // Creates a tooltip with the specified content and options and open it.
    openTooltip: function (tooltip, latlng, options) {
      this._initOverlay(Tooltip, tooltip, latlng, options).openOn(this);
      return this;
    },
    // @method closeTooltip(tooltip: Tooltip): this
    // Closes the tooltip given as parameter.
    closeTooltip: function (tooltip) {
      tooltip.close();
      return this;
    }
  });

  /*
   * @namespace Layer
   * @section Tooltip methods example
   *
   * All layers share a set of methods convenient for binding tooltips to it.
   *
   * ```js
   * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map);
   * layer.openTooltip();
   * layer.closeTooltip();
   * ```
   */

  // @section Tooltip methods
  Layer.include({
    // @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
    // Binds a tooltip to the layer with the passed `content` and sets up the
    // necessary event listeners. If a `Function` is passed it will receive
    // the layer as the first argument and should return a `String` or `HTMLElement`.
    bindTooltip: function (content, options) {
      if (this._tooltip && this.isTooltipOpen()) {
        this.unbindTooltip();
      }
      this._tooltip = this._initOverlay(Tooltip, this._tooltip, content, options);
      this._initTooltipInteractions();
      if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) {
        this.openTooltip();
      }
      return this;
    },
    // @method unbindTooltip(): this
    // Removes the tooltip previously bound with `bindTooltip`.
    unbindTooltip: function () {
      if (this._tooltip) {
        this._initTooltipInteractions(true);
        this.closeTooltip();
        this._tooltip = null;
      }
      return this;
    },
    _initTooltipInteractions: function (remove) {
      if (!remove && this._tooltipHandlersAdded) {
        return;
      }
      var onOff = remove ? 'off' : 'on',
        events = {
          remove: this.closeTooltip,
          move: this._moveTooltip
        };
      if (!this._tooltip.options.permanent) {
        events.mouseover = this._openTooltip;
        events.mouseout = this.closeTooltip;
        events.click = this._openTooltip;
        if (this._map) {
          this._addFocusListeners();
        } else {
          events.add = this._addFocusListeners;
        }
      } else {
        events.add = this._openTooltip;
      }
      if (this._tooltip.options.sticky) {
        events.mousemove = this._moveTooltip;
      }
      this[onOff](events);
      this._tooltipHandlersAdded = !remove;
    },
    // @method openTooltip(latlng?: LatLng): this
    // Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
    openTooltip: function (latlng) {
      if (this._tooltip) {
        if (!(this instanceof FeatureGroup)) {
          this._tooltip._source = this;
        }
        if (this._tooltip._prepareOpen(latlng)) {
          // open the tooltip on the map
          this._tooltip.openOn(this._map);
          if (this.getElement) {
            this._setAriaDescribedByOnLayer(this);
          } else if (this.eachLayer) {
            this.eachLayer(this._setAriaDescribedByOnLayer, this);
          }
        }
      }
      return this;
    },
    // @method closeTooltip(): this
    // Closes the tooltip bound to this layer if it is open.
    closeTooltip: function () {
      if (this._tooltip) {
        return this._tooltip.close();
      }
    },
    // @method toggleTooltip(): this
    // Opens or closes the tooltip bound to this layer depending on its current state.
    toggleTooltip: function () {
      if (this._tooltip) {
        this._tooltip.toggle(this);
      }
      return this;
    },
    // @method isTooltipOpen(): boolean
    // Returns `true` if the tooltip bound to this layer is currently open.
    isTooltipOpen: function () {
      return this._tooltip.isOpen();
    },
    // @method setTooltipContent(content: String|HTMLElement|Tooltip): this
    // Sets the content of the tooltip bound to this layer.
    setTooltipContent: function (content) {
      if (this._tooltip) {
        this._tooltip.setContent(content);
      }
      return this;
    },
    // @method getTooltip(): Tooltip
    // Returns the tooltip bound to this layer.
    getTooltip: function () {
      return this._tooltip;
    },
    _addFocusListeners: function () {
      if (this.getElement) {
        this._addFocusListenersOnLayer(this);
      } else if (this.eachLayer) {
        this.eachLayer(this._addFocusListenersOnLayer, this);
      }
    },
    _addFocusListenersOnLayer: function (layer) {
      var el = typeof layer.getElement === 'function' && layer.getElement();
      if (el) {
        on(el, 'focus', function () {
          this._tooltip._source = layer;
          this.openTooltip();
        }, this);
        on(el, 'blur', this.closeTooltip, this);
      }
    },
    _setAriaDescribedByOnLayer: function (layer) {
      var el = typeof layer.getElement === 'function' && layer.getElement();
      if (el) {
        el.setAttribute('aria-describedby', this._tooltip._container.id);
      }
    },
    _openTooltip: function (e) {
      if (!this._tooltip || !this._map) {
        return;
      }

      // If the map is moving, we will show the tooltip after it's done.
      if (this._map.dragging && this._map.dragging.moving() && !this._openOnceFlag) {
        this._openOnceFlag = true;
        var that = this;
        this._map.once('moveend', function () {
          that._openOnceFlag = false;
          that._openTooltip(e);
        });
        return;
      }
      this._tooltip._source = e.layer || e.target;
      this.openTooltip(this._tooltip.options.sticky ? e.latlng : undefined);
    },
    _moveTooltip: function (e) {
      var latlng = e.latlng,
        containerPoint,
        layerPoint;
      if (this._tooltip.options.sticky && e.originalEvent) {
        containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
        layerPoint = this._map.containerPointToLayerPoint(containerPoint);
        latlng = this._map.layerPointToLatLng(layerPoint);
      }
      this._tooltip.setLatLng(latlng);
    }
  });

  /*
   * @class DivIcon
   * @aka L.DivIcon
   * @inherits Icon
   *
   * Represents a lightweight icon for markers that uses a simple `<div>`
   * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options.
   *
   * @example
   * ```js
   * var myIcon = L.divIcon({className: 'my-div-icon'});
   * // you can set .my-div-icon styles in CSS
   *
   * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
   * ```
   *
   * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow.
   */

  var DivIcon = Icon.extend({
    options: {
      // @section
      // @aka DivIcon options
      iconSize: [12, 12],
      // also can be set through CSS

      // iconAnchor: (Point),
      // popupAnchor: (Point),

      // @option html: String|HTMLElement = ''
      // Custom HTML code to put inside the div element, empty by default. Alternatively,
      // an instance of `HTMLElement`.
      html: false,
      // @option bgPos: Point = [0, 0]
      // Optional relative position of the background, in pixels
      bgPos: null,
      className: 'leaflet-div-icon'
    },
    createIcon: function (oldIcon) {
      var div = oldIcon && oldIcon.tagName === 'DIV' ? oldIcon : document.createElement('div'),
        options = this.options;
      if (options.html instanceof Element) {
        empty(div);
        div.appendChild(options.html);
      } else {
        div.innerHTML = options.html !== false ? options.html : '';
      }
      if (options.bgPos) {
        var bgPos = toPoint(options.bgPos);
        div.style.backgroundPosition = -bgPos.x + 'px ' + -bgPos.y + 'px';
      }
      this._setIconStyles(div, 'icon');
      return div;
    },
    createShadow: function () {
      return null;
    }
  });

  // @factory L.divIcon(options: DivIcon options)
  // Creates a `DivIcon` instance with the given options.
  function divIcon(options) {
    return new DivIcon(options);
  }
  Icon.Default = IconDefault;

  /*
   * @class GridLayer
   * @inherits Layer
   * @aka L.GridLayer
   *
   * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
   * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
   *
   *
   * @section Synchronous usage
   * @example
   *
   * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
   *
   * ```js
   * var CanvasLayer = L.GridLayer.extend({
   *     createTile: function(coords){
   *         // create a <canvas> element for drawing
   *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
   *
   *         // setup tile width and height according to the options
   *         var size = this.getTileSize();
   *         tile.width = size.x;
   *         tile.height = size.y;
   *
   *         // get a canvas context and draw something on it using coords.x, coords.y and coords.z
   *         var ctx = tile.getContext('2d');
   *
   *         // return the tile so it can be rendered on screen
   *         return tile;
   *     }
   * });
   * ```
   *
   * @section Asynchronous usage
   * @example
   *
   * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
   *
   * ```js
   * var CanvasLayer = L.GridLayer.extend({
   *     createTile: function(coords, done){
   *         var error;
   *
   *         // create a <canvas> element for drawing
   *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
   *
   *         // setup tile width and height according to the options
   *         var size = this.getTileSize();
   *         tile.width = size.x;
   *         tile.height = size.y;
   *
   *         // draw something asynchronously and pass the tile to the done() callback
   *         setTimeout(function() {
   *             done(error, tile);
   *         }, 1000);
   *
   *         return tile;
   *     }
   * });
   * ```
   *
   * @section
   */

  var GridLayer = Layer.extend({
    // @section
    // @aka GridLayer options
    options: {
      // @option tileSize: Number|Point = 256
      // Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
      tileSize: 256,
      // @option opacity: Number = 1.0
      // Opacity of the tiles. Can be used in the `createTile()` function.
      opacity: 1,
      // @option updateWhenIdle: Boolean = (depends)
      // Load new tiles only when panning ends.
      // `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
      // `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
      // [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
      updateWhenIdle: Browser.mobile,
      // @option updateWhenZooming: Boolean = true
      // By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
      updateWhenZooming: true,
      // @option updateInterval: Number = 200
      // Tiles will not update more than once every `updateInterval` milliseconds when panning.
      updateInterval: 200,
      // @option zIndex: Number = 1
      // The explicit zIndex of the tile layer.
      zIndex: 1,
      // @option bounds: LatLngBounds = undefined
      // If set, tiles will only be loaded inside the set `LatLngBounds`.
      bounds: null,
      // @option minZoom: Number = 0
      // The minimum zoom level down to which this layer will be displayed (inclusive).
      minZoom: 0,
      // @option maxZoom: Number = undefined
      // The maximum zoom level up to which this layer will be displayed (inclusive).
      maxZoom: undefined,
      // @option maxNativeZoom: Number = undefined
      // Maximum zoom number the tile source has available. If it is specified,
      // the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
      // from `maxNativeZoom` level and auto-scaled.
      maxNativeZoom: undefined,
      // @option minNativeZoom: Number = undefined
      // Minimum zoom number the tile source has available. If it is specified,
      // the tiles on all zoom levels lower than `minNativeZoom` will be loaded
      // from `minNativeZoom` level and auto-scaled.
      minNativeZoom: undefined,
      // @option noWrap: Boolean = false
      // Whether the layer is wrapped around the antimeridian. If `true`, the
      // GridLayer will only be displayed once at low zoom levels. Has no
      // effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
      // in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
      // tiles outside the CRS limits.
      noWrap: false,
      // @option pane: String = 'tilePane'
      // `Map pane` where the grid layer will be added.
      pane: 'tilePane',
      // @option className: String = ''
      // A custom class name to assign to the tile layer. Empty by default.
      className: '',
      // @option keepBuffer: Number = 2
      // When panning the map, keep this many rows and columns of tiles before unloading them.
      keepBuffer: 2
    },
    initialize: function (options) {
      setOptions(this, options);
    },
    onAdd: function () {
      this._initContainer();
      this._levels = {};
      this._tiles = {};
      this._resetView(); // implicit _update() call
    },
    beforeAdd: function (map) {
      map._addZoomLimit(this);
    },
    onRemove: function (map) {
      this._removeAllTiles();
      remove(this._container);
      map._removeZoomLimit(this);
      this._container = null;
      this._tileZoom = undefined;
    },
    // @method bringToFront: this
    // Brings the tile layer to the top of all tile layers.
    bringToFront: function () {
      if (this._map) {
        toFront(this._container);
        this._setAutoZIndex(Math.max);
      }
      return this;
    },
    // @method bringToBack: this
    // Brings the tile layer to the bottom of all tile layers.
    bringToBack: function () {
      if (this._map) {
        toBack(this._container);
        this._setAutoZIndex(Math.min);
      }
      return this;
    },
    // @method getContainer: HTMLElement
    // Returns the HTML element that contains the tiles for this layer.
    getContainer: function () {
      return this._container;
    },
    // @method setOpacity(opacity: Number): this
    // Changes the [opacity](#gridlayer-opacity) of the grid layer.
    setOpacity: function (opacity) {
      this.options.opacity = opacity;
      this._updateOpacity();
      return this;
    },
    // @method setZIndex(zIndex: Number): this
    // Changes the [zIndex](#gridlayer-zindex) of the grid layer.
    setZIndex: function (zIndex) {
      this.options.zIndex = zIndex;
      this._updateZIndex();
      return this;
    },
    // @method isLoading: Boolean
    // Returns `true` if any tile in the grid layer has not finished loading.
    isLoading: function () {
      return this._loading;
    },
    // @method redraw: this
    // Causes the layer to clear all the tiles and request them again.
    redraw: function () {
      if (this._map) {
        this._removeAllTiles();
        var tileZoom = this._clampZoom(this._map.getZoom());
        if (tileZoom !== this._tileZoom) {
          this._tileZoom = tileZoom;
          this._updateLevels();
        }
        this._update();
      }
      return this;
    },
    getEvents: function () {
      var events = {
        viewprereset: this._invalidateAll,
        viewreset: this._resetView,
        zoom: this._resetView,
        moveend: this._onMoveEnd
      };
      if (!this.options.updateWhenIdle) {
        // update tiles on move, but not more often than once per given interval
        if (!this._onMove) {
          this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this);
        }
        events.move = this._onMove;
      }
      if (this._zoomAnimated) {
        events.zoomanim = this._animateZoom;
      }
      return events;
    },
    // @section Extension methods
    // Layers extending `GridLayer` shall reimplement the following method.
    // @method createTile(coords: Object, done?: Function): HTMLElement
    // Called only internally, must be overridden by classes extending `GridLayer`.
    // Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
    // is specified, it must be called when the tile has finished loading and drawing.
    createTile: function () {
      return document.createElement('div');
    },
    // @section
    // @method getTileSize: Point
    // Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
    getTileSize: function () {
      var s = this.options.tileSize;
      return s instanceof Point ? s : new Point(s, s);
    },
    _updateZIndex: function () {
      if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
        this._container.style.zIndex = this.options.zIndex;
      }
    },
    _setAutoZIndex: function (compare) {
      // go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)

      var layers = this.getPane().children,
        edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min

      for (var i = 0, len = layers.length, zIndex; i < len; i++) {
        zIndex = layers[i].style.zIndex;
        if (layers[i] !== this._container && zIndex) {
          edgeZIndex = compare(edgeZIndex, +zIndex);
        }
      }
      if (isFinite(edgeZIndex)) {
        this.options.zIndex = edgeZIndex + compare(-1, 1);
        this._updateZIndex();
      }
    },
    _updateOpacity: function () {
      if (!this._map) {
        return;
      }

      // IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
      if (Browser.ielt9) {
        return;
      }
      setOpacity(this._container, this.options.opacity);
      var now = +new Date(),
        nextFrame = false,
        willPrune = false;
      for (var key in this._tiles) {
        var tile = this._tiles[key];
        if (!tile.current || !tile.loaded) {
          continue;
        }
        var fade = Math.min(1, (now - tile.loaded) / 200);
        setOpacity(tile.el, fade);
        if (fade < 1) {
          nextFrame = true;
        } else {
          if (tile.active) {
            willPrune = true;
          } else {
            this._onOpaqueTile(tile);
          }
          tile.active = true;
        }
      }
      if (willPrune && !this._noPrune) {
        this._pruneTiles();
      }
      if (nextFrame) {
        cancelAnimFrame(this._fadeFrame);
        this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
      }
    },
    _onOpaqueTile: falseFn,
    _initContainer: function () {
      if (this._container) {
        return;
      }
      this._container = create$1('div', 'leaflet-layer ' + (this.options.className || ''));
      this._updateZIndex();
      if (this.options.opacity < 1) {
        this._updateOpacity();
      }
      this.getPane().appendChild(this._container);
    },
    _updateLevels: function () {
      var zoom = this._tileZoom,
        maxZoom = this.options.maxZoom;
      if (zoom === undefined) {
        return undefined;
      }
      for (var z in this._levels) {
        z = Number(z);
        if (this._levels[z].el.children.length || z === zoom) {
          this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
          this._onUpdateLevel(z);
        } else {
          remove(this._levels[z].el);
          this._removeTilesAtZoom(z);
          this._onRemoveLevel(z);
          delete this._levels[z];
        }
      }
      var level = this._levels[zoom],
        map = this._map;
      if (!level) {
        level = this._levels[zoom] = {};
        level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
        level.el.style.zIndex = maxZoom;
        level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
        level.zoom = zoom;
        this._setZoomTransform(level, map.getCenter(), map.getZoom());

        // force the browser to consider the newly added element for transition
        falseFn(level.el.offsetWidth);
        this._onCreateLevel(level);
      }
      this._level = level;
      return level;
    },
    _onUpdateLevel: falseFn,
    _onRemoveLevel: falseFn,
    _onCreateLevel: falseFn,
    _pruneTiles: function () {
      if (!this._map) {
        return;
      }
      var key, tile;
      var zoom = this._map.getZoom();
      if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
        this._removeAllTiles();
        return;
      }
      for (key in this._tiles) {
        tile = this._tiles[key];
        tile.retain = tile.current;
      }
      for (key in this._tiles) {
        tile = this._tiles[key];
        if (tile.current && !tile.active) {
          var coords = tile.coords;
          if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
            this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
          }
        }
      }
      for (key in this._tiles) {
        if (!this._tiles[key].retain) {
          this._removeTile(key);
        }
      }
    },
    _removeTilesAtZoom: function (zoom) {
      for (var key in this._tiles) {
        if (this._tiles[key].coords.z !== zoom) {
          continue;
        }
        this._removeTile(key);
      }
    },
    _removeAllTiles: function () {
      for (var key in this._tiles) {
        this._removeTile(key);
      }
    },
    _invalidateAll: function () {
      for (var z in this._levels) {
        remove(this._levels[z].el);
        this._onRemoveLevel(Number(z));
        delete this._levels[z];
      }
      this._removeAllTiles();
      this._tileZoom = undefined;
    },
    _retainParent: function (x, y, z, minZoom) {
      var x2 = Math.floor(x / 2),
        y2 = Math.floor(y / 2),
        z2 = z - 1,
        coords2 = new Point(+x2, +y2);
      coords2.z = +z2;
      var key = this._tileCoordsToKey(coords2),
        tile = this._tiles[key];
      if (tile && tile.active) {
        tile.retain = true;
        return true;
      } else if (tile && tile.loaded) {
        tile.retain = true;
      }
      if (z2 > minZoom) {
        return this._retainParent(x2, y2, z2, minZoom);
      }
      return false;
    },
    _retainChildren: function (x, y, z, maxZoom) {
      for (var i = 2 * x; i < 2 * x + 2; i++) {
        for (var j = 2 * y; j < 2 * y + 2; j++) {
          var coords = new Point(i, j);
          coords.z = z + 1;
          var key = this._tileCoordsToKey(coords),
            tile = this._tiles[key];
          if (tile && tile.active) {
            tile.retain = true;
            continue;
          } else if (tile && tile.loaded) {
            tile.retain = true;
          }
          if (z + 1 < maxZoom) {
            this._retainChildren(i, j, z + 1, maxZoom);
          }
        }
      }
    },
    _resetView: function (e) {
      var animating = e && (e.pinch || e.flyTo);
      this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
    },
    _animateZoom: function (e) {
      this._setView(e.center, e.zoom, true, e.noUpdate);
    },
    _clampZoom: function (zoom) {
      var options = this.options;
      if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
        return options.minNativeZoom;
      }
      if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
        return options.maxNativeZoom;
      }
      return zoom;
    },
    _setView: function (center, zoom, noPrune, noUpdate) {
      var tileZoom = Math.round(zoom);
      if (this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom || this.options.minZoom !== undefined && tileZoom < this.options.minZoom) {
        tileZoom = undefined;
      } else {
        tileZoom = this._clampZoom(tileZoom);
      }
      var tileZoomChanged = this.options.updateWhenZooming && tileZoom !== this._tileZoom;
      if (!noUpdate || tileZoomChanged) {
        this._tileZoom = tileZoom;
        if (this._abortLoading) {
          this._abortLoading();
        }
        this._updateLevels();
        this._resetGrid();
        if (tileZoom !== undefined) {
          this._update(center);
        }
        if (!noPrune) {
          this._pruneTiles();
        }

        // Flag to prevent _updateOpacity from pruning tiles during
        // a zoom anim or a pinch gesture
        this._noPrune = !!noPrune;
      }
      this._setZoomTransforms(center, zoom);
    },
    _setZoomTransforms: function (center, zoom) {
      for (var i in this._levels) {
        this._setZoomTransform(this._levels[i], center, zoom);
      }
    },
    _setZoomTransform: function (level, center, zoom) {
      var scale = this._map.getZoomScale(zoom, level.zoom),
        translate = level.origin.multiplyBy(scale).subtract(this._map._getNewPixelOrigin(center, zoom)).round();
      if (Browser.any3d) {
        setTransform(level.el, translate, scale);
      } else {
        setPosition(level.el, translate);
      }
    },
    _resetGrid: function () {
      var map = this._map,
        crs = map.options.crs,
        tileSize = this._tileSize = this.getTileSize(),
        tileZoom = this._tileZoom;
      var bounds = this._map.getPixelWorldBounds(this._tileZoom);
      if (bounds) {
        this._globalTileRange = this._pxBoundsToTileRange(bounds);
      }
      this._wrapX = crs.wrapLng && !this.options.noWrap && [Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x), Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)];
      this._wrapY = crs.wrapLat && !this.options.noWrap && [Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x), Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)];
    },
    _onMoveEnd: function () {
      if (!this._map || this._map._animatingZoom) {
        return;
      }
      this._update();
    },
    _getTiledPixelBounds: function (center) {
      var map = this._map,
        mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
        scale = map.getZoomScale(mapZoom, this._tileZoom),
        pixelCenter = map.project(center, this._tileZoom).floor(),
        halfSize = map.getSize().divideBy(scale * 2);
      return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
    },
    // Private method to load tiles in the grid's active zoom level according to map bounds
    _update: function (center) {
      var map = this._map;
      if (!map) {
        return;
      }
      var zoom = this._clampZoom(map.getZoom());
      if (center === undefined) {
        center = map.getCenter();
      }
      if (this._tileZoom === undefined) {
        return;
      } // if out of minzoom/maxzoom

      var pixelBounds = this._getTiledPixelBounds(center),
        tileRange = this._pxBoundsToTileRange(pixelBounds),
        tileCenter = tileRange.getCenter(),
        queue = [],
        margin = this.options.keepBuffer,
        noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]), tileRange.getTopRight().add([margin, -margin]));

      // Sanity check: panic if the tile range contains Infinity somewhere.
      if (!(isFinite(tileRange.min.x) && isFinite(tileRange.min.y) && isFinite(tileRange.max.x) && isFinite(tileRange.max.y))) {
        throw new Error('Attempted to load an infinite number of tiles');
      }
      for (var key in this._tiles) {
        var c = this._tiles[key].coords;
        if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
          this._tiles[key].current = false;
        }
      }

      // _update just loads more tiles. If the tile zoom level differs too much
      // from the map's, let _setView reset levels and prune old tiles.
      if (Math.abs(zoom - this._tileZoom) > 1) {
        this._setView(center, zoom);
        return;
      }

      // create a queue of coordinates to load tiles from
      for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
        for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
          var coords = new Point(i, j);
          coords.z = this._tileZoom;
          if (!this._isValidTile(coords)) {
            continue;
          }
          var tile = this._tiles[this._tileCoordsToKey(coords)];
          if (tile) {
            tile.current = true;
          } else {
            queue.push(coords);
          }
        }
      }

      // sort tile queue to load tiles in order of their distance to center
      queue.sort(function (a, b) {
        return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
      });
      if (queue.length !== 0) {
        // if it's the first batch of tiles to load
        if (!this._loading) {
          this._loading = true;
          // @event loading: Event
          // Fired when the grid layer starts loading tiles.
          this.fire('loading');
        }

        // create DOM fragment to append tiles in one batch
        var fragment = document.createDocumentFragment();
        for (i = 0; i < queue.length; i++) {
          this._addTile(queue[i], fragment);
        }
        this._level.el.appendChild(fragment);
      }
    },
    _isValidTile: function (coords) {
      var crs = this._map.options.crs;
      if (!crs.infinite) {
        // don't load tile if it's out of bounds and not wrapped
        var bounds = this._globalTileRange;
        if (!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x) || !crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y)) {
          return false;
        }
      }
      if (!this.options.bounds) {
        return true;
      }

      // don't load tile if it doesn't intersect the bounds in options
      var tileBounds = this._tileCoordsToBounds(coords);
      return toLatLngBounds(this.options.bounds).overlaps(tileBounds);
    },
    _keyToBounds: function (key) {
      return this._tileCoordsToBounds(this._keyToTileCoords(key));
    },
    _tileCoordsToNwSe: function (coords) {
      var map = this._map,
        tileSize = this.getTileSize(),
        nwPoint = coords.scaleBy(tileSize),
        sePoint = nwPoint.add(tileSize),
        nw = map.unproject(nwPoint, coords.z),
        se = map.unproject(sePoint, coords.z);
      return [nw, se];
    },
    // converts tile coordinates to its geographical bounds
    _tileCoordsToBounds: function (coords) {
      var bp = this._tileCoordsToNwSe(coords),
        bounds = new LatLngBounds(bp[0], bp[1]);
      if (!this.options.noWrap) {
        bounds = this._map.wrapLatLngBounds(bounds);
      }
      return bounds;
    },
    // converts tile coordinates to key for the tile cache
    _tileCoordsToKey: function (coords) {
      return coords.x + ':' + coords.y + ':' + coords.z;
    },
    // converts tile cache key to coordinates
    _keyToTileCoords: function (key) {
      var k = key.split(':'),
        coords = new Point(+k[0], +k[1]);
      coords.z = +k[2];
      return coords;
    },
    _removeTile: function (key) {
      var tile = this._tiles[key];
      if (!tile) {
        return;
      }
      remove(tile.el);
      delete this._tiles[key];

      // @event tileunload: TileEvent
      // Fired when a tile is removed (e.g. when a tile goes off the screen).
      this.fire('tileunload', {
        tile: tile.el,
        coords: this._keyToTileCoords(key)
      });
    },
    _initTile: function (tile) {
      addClass(tile, 'leaflet-tile');
      var tileSize = this.getTileSize();
      tile.style.width = tileSize.x + 'px';
      tile.style.height = tileSize.y + 'px';
      tile.onselectstart = falseFn;
      tile.onmousemove = falseFn;

      // update opacity on tiles in IE7-8 because of filter inheritance problems
      if (Browser.ielt9 && this.options.opacity < 1) {
        setOpacity(tile, this.options.opacity);
      }
    },
    _addTile: function (coords, container) {
      var tilePos = this._getTilePos(coords),
        key = this._tileCoordsToKey(coords);
      var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords));
      this._initTile(tile);

      // if createTile is defined with a second argument ("done" callback),
      // we know that tile is async and will be ready later; otherwise
      if (this.createTile.length < 2) {
        // mark tile as ready, but delay one frame for opacity animation to happen
        requestAnimFrame(bind(this._tileReady, this, coords, null, tile));
      }
      setPosition(tile, tilePos);

      // save tile in cache
      this._tiles[key] = {
        el: tile,
        coords: coords,
        current: true
      };
      container.appendChild(tile);
      // @event tileloadstart: TileEvent
      // Fired when a tile is requested and starts loading.
      this.fire('tileloadstart', {
        tile: tile,
        coords: coords
      });
    },
    _tileReady: function (coords, err, tile) {
      if (err) {
        // @event tileerror: TileErrorEvent
        // Fired when there is an error loading a tile.
        this.fire('tileerror', {
          error: err,
          tile: tile,
          coords: coords
        });
      }
      var key = this._tileCoordsToKey(coords);
      tile = this._tiles[key];
      if (!tile) {
        return;
      }
      tile.loaded = +new Date();
      if (this._map._fadeAnimated) {
        setOpacity(tile.el, 0);
        cancelAnimFrame(this._fadeFrame);
        this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
      } else {
        tile.active = true;
        this._pruneTiles();
      }
      if (!err) {
        addClass(tile.el, 'leaflet-tile-loaded');

        // @event tileload: TileEvent
        // Fired when a tile loads.
        this.fire('tileload', {
          tile: tile.el,
          coords: coords
        });
      }
      if (this._noTilesToLoad()) {
        this._loading = false;
        // @event load: Event
        // Fired when the grid layer loaded all visible tiles.
        this.fire('load');
        if (Browser.ielt9 || !this._map._fadeAnimated) {
          requestAnimFrame(this._pruneTiles, this);
        } else {
          // Wait a bit more than 0.2 secs (the duration of the tile fade-in)
          // to trigger a pruning.
          setTimeout(bind(this._pruneTiles, this), 250);
        }
      }
    },
    _getTilePos: function (coords) {
      return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
    },
    _wrapCoords: function (coords) {
      var newCoords = new Point(this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x, this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y);
      newCoords.z = coords.z;
      return newCoords;
    },
    _pxBoundsToTileRange: function (bounds) {
      var tileSize = this.getTileSize();
      return new Bounds(bounds.min.unscaleBy(tileSize).floor(), bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
    },
    _noTilesToLoad: function () {
      for (var key in this._tiles) {
        if (!this._tiles[key].loaded) {
          return false;
        }
      }
      return true;
    }
  });

  // @factory L.gridLayer(options?: GridLayer options)
  // Creates a new instance of GridLayer with the supplied options.
  function gridLayer(options) {
    return new GridLayer(options);
  }

  /*
   * @class TileLayer
   * @inherits GridLayer
   * @aka L.TileLayer
   * Used to load and display tile layers on the map. Note that most tile servers require attribution, which you can set under `Layer`. Extends `GridLayer`.
   *
   * @example
   *
   * ```js
   * L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar', attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'}).addTo(map);
   * ```
   *
   * @section URL template
   * @example
   *
   * A string of the following form:
   *
   * ```
   * 'https://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'
   * ```
   *
   * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "&commat;2x" to the URL to load retina tiles.
   *
   * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:
   *
   * ```
   * L.tileLayer('https://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});
   * ```
   */

  var TileLayer = GridLayer.extend({
    // @section
    // @aka TileLayer options
    options: {
      // @option minZoom: Number = 0
      // The minimum zoom level down to which this layer will be displayed (inclusive).
      minZoom: 0,
      // @option maxZoom: Number = 18
      // The maximum zoom level up to which this layer will be displayed (inclusive).
      maxZoom: 18,
      // @option subdomains: String|String[] = 'abc'
      // Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings.
      subdomains: 'abc',
      // @option errorTileUrl: String = ''
      // URL to the tile image to show in place of the tile that failed to load.
      errorTileUrl: '',
      // @option zoomOffset: Number = 0
      // The zoom number used in tile URLs will be offset with this value.
      zoomOffset: 0,
      // @option tms: Boolean = false
      // If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services).
      tms: false,
      // @option zoomReverse: Boolean = false
      // If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`)
      zoomReverse: false,
      // @option detectRetina: Boolean = false
      // If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.
      detectRetina: false,
      // @option crossOrigin: Boolean|String = false
      // Whether the crossOrigin attribute will be added to the tiles.
      // If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data.
      // Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.
      crossOrigin: false,
      // @option referrerPolicy: Boolean|String = false
      // Whether the referrerPolicy attribute will be added to the tiles.
      // If a String is provided, all tiles will have their referrerPolicy attribute set to the String provided.
      // This may be needed if your map's rendering context has a strict default but your tile provider expects a valid referrer
      // (e.g. to validate an API token).
      // Refer to [HTMLImageElement.referrerPolicy](https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/referrerPolicy) for valid String values.
      referrerPolicy: false
    },
    initialize: function (url, options) {
      this._url = url;
      options = setOptions(this, options);

      // detecting retina displays, adjusting tileSize and zoom levels
      if (options.detectRetina && Browser.retina && options.maxZoom > 0) {
        options.tileSize = Math.floor(options.tileSize / 2);
        if (!options.zoomReverse) {
          options.zoomOffset++;
          options.maxZoom = Math.max(options.minZoom, options.maxZoom - 1);
        } else {
          options.zoomOffset--;
          options.minZoom = Math.min(options.maxZoom, options.minZoom + 1);
        }
        options.minZoom = Math.max(0, options.minZoom);
      } else if (!options.zoomReverse) {
        // make sure maxZoom is gte minZoom
        options.maxZoom = Math.max(options.minZoom, options.maxZoom);
      } else {
        // make sure minZoom is lte maxZoom
        options.minZoom = Math.min(options.maxZoom, options.minZoom);
      }
      if (typeof options.subdomains === 'string') {
        options.subdomains = options.subdomains.split('');
      }
      this.on('tileunload', this._onTileRemove);
    },
    // @method setUrl(url: String, noRedraw?: Boolean): this
    // Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`).
    // If the URL does not change, the layer will not be redrawn unless
    // the noRedraw parameter is set to false.
    setUrl: function (url, noRedraw) {
      if (this._url === url && noRedraw === undefined) {
        noRedraw = true;
      }
      this._url = url;
      if (!noRedraw) {
        this.redraw();
      }
      return this;
    },
    // @method createTile(coords: Object, done?: Function): HTMLElement
    // Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile)
    // to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done`
    // callback is called when the tile has been loaded.
    createTile: function (coords, done) {
      var tile = document.createElement('img');
      on(tile, 'load', bind(this._tileOnLoad, this, done, tile));
      on(tile, 'error', bind(this._tileOnError, this, done, tile));
      if (this.options.crossOrigin || this.options.crossOrigin === '') {
        tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
      }

      // for this new option we follow the documented behavior
      // more closely by only setting the property when string
      if (typeof this.options.referrerPolicy === 'string') {
        tile.referrerPolicy = this.options.referrerPolicy;
      }

      // The alt attribute is set to the empty string,
      // allowing screen readers to ignore the decorative image tiles.
      // https://www.w3.org/WAI/tutorials/images/decorative/
      // https://www.w3.org/TR/html-aria/#el-img-empty-alt
      tile.alt = '';
      tile.src = this.getTileUrl(coords);
      return tile;
    },
    // @section Extension methods
    // @uninheritable
    // Layers extending `TileLayer` might reimplement the following method.
    // @method getTileUrl(coords: Object): String
    // Called only internally, returns the URL for a tile given its coordinates.
    // Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes.
    getTileUrl: function (coords) {
      var data = {
        r: Browser.retina ? '@2x' : '',
        s: this._getSubdomain(coords),
        x: coords.x,
        y: coords.y,
        z: this._getZoomForUrl()
      };
      if (this._map && !this._map.options.crs.infinite) {
        var invertedY = this._globalTileRange.max.y - coords.y;
        if (this.options.tms) {
          data['y'] = invertedY;
        }
        data['-y'] = invertedY;
      }
      return template(this._url, extend(data, this.options));
    },
    _tileOnLoad: function (done, tile) {
      // For https://github.com/Leaflet/Leaflet/issues/3332
      if (Browser.ielt9) {
        setTimeout(bind(done, this, null, tile), 0);
      } else {
        done(null, tile);
      }
    },
    _tileOnError: function (done, tile, e) {
      var errorUrl = this.options.errorTileUrl;
      if (errorUrl && tile.getAttribute('src') !== errorUrl) {
        tile.src = errorUrl;
      }
      done(e, tile);
    },
    _onTileRemove: function (e) {
      e.tile.onload = null;
    },
    _getZoomForUrl: function () {
      var zoom = this._tileZoom,
        maxZoom = this.options.maxZoom,
        zoomReverse = this.options.zoomReverse,
        zoomOffset = this.options.zoomOffset;
      if (zoomReverse) {
        zoom = maxZoom - zoom;
      }
      return zoom + zoomOffset;
    },
    _getSubdomain: function (tilePoint) {
      var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
      return this.options.subdomains[index];
    },
    // stops loading all tiles in the background layer
    _abortLoading: function () {
      var i, tile;
      for (i in this._tiles) {
        if (this._tiles[i].coords.z !== this._tileZoom) {
          tile = this._tiles[i].el;
          tile.onload = falseFn;
          tile.onerror = falseFn;
          if (!tile.complete) {
            tile.src = emptyImageUrl;
            var coords = this._tiles[i].coords;
            remove(tile);
            delete this._tiles[i];
            // @event tileabort: TileEvent
            // Fired when a tile was loading but is now not wanted.
            this.fire('tileabort', {
              tile: tile,
              coords: coords
            });
          }
        }
      }
    },
    _removeTile: function (key) {
      var tile = this._tiles[key];
      if (!tile) {
        return;
      }

      // Cancels any pending http requests associated with the tile
      tile.el.setAttribute('src', emptyImageUrl);
      return GridLayer.prototype._removeTile.call(this, key);
    },
    _tileReady: function (coords, err, tile) {
      if (!this._map || tile && tile.getAttribute('src') === emptyImageUrl) {
        return;
      }
      return GridLayer.prototype._tileReady.call(this, coords, err, tile);
    }
  });

  // @factory L.tilelayer(urlTemplate: String, options?: TileLayer options)
  // Instantiates a tile layer object given a `URL template` and optionally an options object.

  function tileLayer(url, options) {
    return new TileLayer(url, options);
  }

  /*
   * @class TileLayer.WMS
   * @inherits TileLayer
   * @aka L.TileLayer.WMS
   * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`.
   *
   * @example
   *
   * ```js
   * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
   * 	layers: 'nexrad-n0r-900913',
   * 	format: 'image/png',
   * 	transparent: true,
   * 	attribution: "Weather data © 2012 IEM Nexrad"
   * });
   * ```
   */

  var TileLayerWMS = TileLayer.extend({
    // @section
    // @aka TileLayer.WMS options
    // If any custom options not documented here are used, they will be sent to the
    // WMS server as extra parameters in each request URL. This can be useful for
    // [non-standard vendor WMS parameters](https://docs.geoserver.org/stable/en/user/services/wms/vendor.html).
    defaultWmsParams: {
      service: 'WMS',
      request: 'GetMap',
      // @option layers: String = ''
      // **(required)** Comma-separated list of WMS layers to show.
      layers: '',
      // @option styles: String = ''
      // Comma-separated list of WMS styles.
      styles: '',
      // @option format: String = 'image/jpeg'
      // WMS image format (use `'image/png'` for layers with transparency).
      format: 'image/jpeg',
      // @option transparent: Boolean = false
      // If `true`, the WMS service will return images with transparency.
      transparent: false,
      // @option version: String = '1.1.1'
      // Version of the WMS service to use
      version: '1.1.1'
    },
    options: {
      // @option crs: CRS = null
      // Coordinate Reference System to use for the WMS requests, defaults to
      // map CRS. Don't change this if you're not sure what it means.
      crs: null,
      // @option uppercase: Boolean = false
      // If `true`, WMS request parameter keys will be uppercase.
      uppercase: false
    },
    initialize: function (url, options) {
      this._url = url;
      var wmsParams = extend({}, this.defaultWmsParams);

      // all keys that are not TileLayer options go to WMS params
      for (var i in options) {
        if (!(i in this.options)) {
          wmsParams[i] = options[i];
        }
      }
      options = setOptions(this, options);
      var realRetina = options.detectRetina && Browser.retina ? 2 : 1;
      var tileSize = this.getTileSize();
      wmsParams.width = tileSize.x * realRetina;
      wmsParams.height = tileSize.y * realRetina;
      this.wmsParams = wmsParams;
    },
    onAdd: function (map) {
      this._crs = this.options.crs || map.options.crs;
      this._wmsVersion = parseFloat(this.wmsParams.version);
      var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';
      this.wmsParams[projectionKey] = this._crs.code;
      TileLayer.prototype.onAdd.call(this, map);
    },
    getTileUrl: function (coords) {
      var tileBounds = this._tileCoordsToNwSe(coords),
        crs = this._crs,
        bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])),
        min = bounds.min,
        max = bounds.max,
        bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ? [min.y, min.x, max.y, max.x] : [min.x, min.y, max.x, max.y]).join(','),
        url = TileLayer.prototype.getTileUrl.call(this, coords);
      return url + getParamString(this.wmsParams, url, this.options.uppercase) + (this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox;
    },
    // @method setParams(params: Object, noRedraw?: Boolean): this
    // Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true).
    setParams: function (params, noRedraw) {
      extend(this.wmsParams, params);
      if (!noRedraw) {
        this.redraw();
      }
      return this;
    }
  });

  // @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options)
  // Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object.
  function tileLayerWMS(url, options) {
    return new TileLayerWMS(url, options);
  }
  TileLayer.WMS = TileLayerWMS;
  tileLayer.wms = tileLayerWMS;

  /*
   * @class Renderer
   * @inherits Layer
   * @aka L.Renderer
   *
   * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the
   * DOM container of the renderer, its bounds, and its zoom animation.
   *
   * A `Renderer` works as an implicit layer group for all `Path`s - the renderer
   * itself can be added or removed to the map. All paths use a renderer, which can
   * be implicit (the map will decide the type of renderer and use it automatically)
   * or explicit (using the [`renderer`](#path-renderer) option of the path).
   *
   * Do not use this class directly, use `SVG` and `Canvas` instead.
   *
   * @event update: Event
   * Fired when the renderer updates its bounds, center and zoom, for example when
   * its map has moved
   */

  var Renderer = Layer.extend({
    // @section
    // @aka Renderer options
    options: {
      // @option padding: Number = 0.1
      // How much to extend the clip area around the map view (relative to its size)
      // e.g. 0.1 would be 10% of map view in each direction
      padding: 0.1
    },
    initialize: function (options) {
      setOptions(this, options);
      stamp(this);
      this._layers = this._layers || {};
    },
    onAdd: function () {
      if (!this._container) {
        this._initContainer(); // defined by renderer implementations

        // always keep transform-origin as 0 0
        addClass(this._container, 'leaflet-zoom-animated');
      }
      this.getPane().appendChild(this._container);
      this._update();
      this.on('update', this._updatePaths, this);
    },
    onRemove: function () {
      this.off('update', this._updatePaths, this);
      this._destroyContainer();
    },
    getEvents: function () {
      var events = {
        viewreset: this._reset,
        zoom: this._onZoom,
        moveend: this._update,
        zoomend: this._onZoomEnd
      };
      if (this._zoomAnimated) {
        events.zoomanim = this._onAnimZoom;
      }
      return events;
    },
    _onAnimZoom: function (ev) {
      this._updateTransform(ev.center, ev.zoom);
    },
    _onZoom: function () {
      this._updateTransform(this._map.getCenter(), this._map.getZoom());
    },
    _updateTransform: function (center, zoom) {
      var scale = this._map.getZoomScale(zoom, this._zoom),
        viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding),
        currentCenterPoint = this._map.project(this._center, zoom),
        topLeftOffset = viewHalf.multiplyBy(-scale).add(currentCenterPoint).subtract(this._map._getNewPixelOrigin(center, zoom));
      if (Browser.any3d) {
        setTransform(this._container, topLeftOffset, scale);
      } else {
        setPosition(this._container, topLeftOffset);
      }
    },
    _reset: function () {
      this._update();
      this._updateTransform(this._center, this._zoom);
      for (var id in this._layers) {
        this._layers[id]._reset();
      }
    },
    _onZoomEnd: function () {
      for (var id in this._layers) {
        this._layers[id]._project();
      }
    },
    _updatePaths: function () {
      for (var id in this._layers) {
        this._layers[id]._update();
      }
    },
    _update: function () {
      // Update pixel bounds of renderer container (for positioning/sizing/clipping later)
      // Subclasses are responsible of firing the 'update' event.
      var p = this.options.padding,
        size = this._map.getSize(),
        min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round();
      this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round());
      this._center = this._map.getCenter();
      this._zoom = this._map.getZoom();
    }
  });

  /*
   * @class Canvas
   * @inherits Renderer
   * @aka L.Canvas
   *
   * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
   * Inherits `Renderer`.
   *
   * Due to [technical limitations](https://caniuse.com/canvas), Canvas is not
   * available in all web browsers, notably IE8, and overlapping geometries might
   * not display properly in some edge cases.
   *
   * @example
   *
   * Use Canvas by default for all paths in the map:
   *
   * ```js
   * var map = L.map('map', {
   * 	renderer: L.canvas()
   * });
   * ```
   *
   * Use a Canvas renderer with extra padding for specific vector geometries:
   *
   * ```js
   * var map = L.map('map');
   * var myRenderer = L.canvas({ padding: 0.5 });
   * var line = L.polyline( coordinates, { renderer: myRenderer } );
   * var circle = L.circle( center, { renderer: myRenderer } );
   * ```
   */

  var Canvas = Renderer.extend({
    // @section
    // @aka Canvas options
    options: {
      // @option tolerance: Number = 0
      // How much to extend the click tolerance around a path/object on the map.
      tolerance: 0
    },
    getEvents: function () {
      var events = Renderer.prototype.getEvents.call(this);
      events.viewprereset = this._onViewPreReset;
      return events;
    },
    _onViewPreReset: function () {
      // Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
      this._postponeUpdatePaths = true;
    },
    onAdd: function () {
      Renderer.prototype.onAdd.call(this);

      // Redraw vectors since canvas is cleared upon removal,
      // in case of removing the renderer itself from the map.
      this._draw();
    },
    _initContainer: function () {
      var container = this._container = document.createElement('canvas');
      on(container, 'mousemove', this._onMouseMove, this);
      on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this);
      on(container, 'mouseout', this._handleMouseOut, this);
      container['_leaflet_disable_events'] = true;
      this._ctx = container.getContext('2d');
    },
    _destroyContainer: function () {
      cancelAnimFrame(this._redrawRequest);
      delete this._ctx;
      remove(this._container);
      off(this._container);
      delete this._container;
    },
    _updatePaths: function () {
      if (this._postponeUpdatePaths) {
        return;
      }
      var layer;
      this._redrawBounds = null;
      for (var id in this._layers) {
        layer = this._layers[id];
        layer._update();
      }
      this._redraw();
    },
    _update: function () {
      if (this._map._animatingZoom && this._bounds) {
        return;
      }
      Renderer.prototype._update.call(this);
      var b = this._bounds,
        container = this._container,
        size = b.getSize(),
        m = Browser.retina ? 2 : 1;
      setPosition(container, b.min);

      // set canvas size (also clearing it); use double size on retina
      container.width = m * size.x;
      container.height = m * size.y;
      container.style.width = size.x + 'px';
      container.style.height = size.y + 'px';
      if (Browser.retina) {
        this._ctx.scale(2, 2);
      }

      // translate so we use the same path coordinates after canvas element moves
      this._ctx.translate(-b.min.x, -b.min.y);

      // Tell paths to redraw themselves
      this.fire('update');
    },
    _reset: function () {
      Renderer.prototype._reset.call(this);
      if (this._postponeUpdatePaths) {
        this._postponeUpdatePaths = false;
        this._updatePaths();
      }
    },
    _initPath: function (layer) {
      this._updateDashArray(layer);
      this._layers[stamp(layer)] = layer;
      var order = layer._order = {
        layer: layer,
        prev: this._drawLast,
        next: null
      };
      if (this._drawLast) {
        this._drawLast.next = order;
      }
      this._drawLast = order;
      this._drawFirst = this._drawFirst || this._drawLast;
    },
    _addPath: function (layer) {
      this._requestRedraw(layer);
    },
    _removePath: function (layer) {
      var order = layer._order;
      var next = order.next;
      var prev = order.prev;
      if (next) {
        next.prev = prev;
      } else {
        this._drawLast = prev;
      }
      if (prev) {
        prev.next = next;
      } else {
        this._drawFirst = next;
      }
      delete layer._order;
      delete this._layers[stamp(layer)];
      this._requestRedraw(layer);
    },
    _updatePath: function (layer) {
      // Redraw the union of the layer's old pixel
      // bounds and the new pixel bounds.
      this._extendRedrawBounds(layer);
      layer._project();
      layer._update();
      // The redraw will extend the redraw bounds
      // with the new pixel bounds.
      this._requestRedraw(layer);
    },
    _updateStyle: function (layer) {
      this._updateDashArray(layer);
      this._requestRedraw(layer);
    },
    _updateDashArray: function (layer) {
      if (typeof layer.options.dashArray === 'string') {
        var parts = layer.options.dashArray.split(/[, ]+/),
          dashArray = [],
          dashValue,
          i;
        for (i = 0; i < parts.length; i++) {
          dashValue = Number(parts[i]);
          // Ignore dash array containing invalid lengths
          if (isNaN(dashValue)) {
            return;
          }
          dashArray.push(dashValue);
        }
        layer.options._dashArray = dashArray;
      } else {
        layer.options._dashArray = layer.options.dashArray;
      }
    },
    _requestRedraw: function (layer) {
      if (!this._map) {
        return;
      }
      this._extendRedrawBounds(layer);
      this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this);
    },
    _extendRedrawBounds: function (layer) {
      if (layer._pxBounds) {
        var padding = (layer.options.weight || 0) + 1;
        this._redrawBounds = this._redrawBounds || new Bounds();
        this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding]));
        this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding]));
      }
    },
    _redraw: function () {
      this._redrawRequest = null;
      if (this._redrawBounds) {
        this._redrawBounds.min._floor();
        this._redrawBounds.max._ceil();
      }
      this._clear(); // clear layers in redraw bounds
      this._draw(); // draw layers

      this._redrawBounds = null;
    },
    _clear: function () {
      var bounds = this._redrawBounds;
      if (bounds) {
        var size = bounds.getSize();
        this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y);
      } else {
        this._ctx.save();
        this._ctx.setTransform(1, 0, 0, 1, 0, 0);
        this._ctx.clearRect(0, 0, this._container.width, this._container.height);
        this._ctx.restore();
      }
    },
    _draw: function () {
      var layer,
        bounds = this._redrawBounds;
      this._ctx.save();
      if (bounds) {
        var size = bounds.getSize();
        this._ctx.beginPath();
        this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y);
        this._ctx.clip();
      }
      this._drawing = true;
      for (var order = this._drawFirst; order; order = order.next) {
        layer = order.layer;
        if (!bounds || layer._pxBounds && layer._pxBounds.intersects(bounds)) {
          layer._updatePath();
        }
      }
      this._drawing = false;
      this._ctx.restore(); // Restore state before clipping.
    },
    _updatePoly: function (layer, closed) {
      if (!this._drawing) {
        return;
      }
      var i,
        j,
        len2,
        p,
        parts = layer._parts,
        len = parts.length,
        ctx = this._ctx;
      if (!len) {
        return;
      }
      ctx.beginPath();
      for (i = 0; i < len; i++) {
        for (j = 0, len2 = parts[i].length; j < len2; j++) {
          p = parts[i][j];
          ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y);
        }
        if (closed) {
          ctx.closePath();
        }
      }
      this._fillStroke(ctx, layer);

      // TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
    },
    _updateCircle: function (layer) {
      if (!this._drawing || layer._empty()) {
        return;
      }
      var p = layer._point,
        ctx = this._ctx,
        r = Math.max(Math.round(layer._radius), 1),
        s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
      if (s !== 1) {
        ctx.save();
        ctx.scale(1, s);
      }
      ctx.beginPath();
      ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
      if (s !== 1) {
        ctx.restore();
      }
      this._fillStroke(ctx, layer);
    },
    _fillStroke: function (ctx, layer) {
      var options = layer.options;
      if (options.fill) {
        ctx.globalAlpha = options.fillOpacity;
        ctx.fillStyle = options.fillColor || options.color;
        ctx.fill(options.fillRule || 'evenodd');
      }
      if (options.stroke && options.weight !== 0) {
        if (ctx.setLineDash) {
          ctx.setLineDash(layer.options && layer.options._dashArray || []);
        }
        ctx.globalAlpha = options.opacity;
        ctx.lineWidth = options.weight;
        ctx.strokeStyle = options.color;
        ctx.lineCap = options.lineCap;
        ctx.lineJoin = options.lineJoin;
        ctx.stroke();
      }
    },
    // Canvas obviously doesn't have mouse events for individual drawn objects,
    // so we emulate that by calculating what's under the mouse on mousemove/click manually

    _onClick: function (e) {
      var point = this._map.mouseEventToLayerPoint(e),
        layer,
        clickedLayer;
      for (var order = this._drawFirst; order; order = order.next) {
        layer = order.layer;
        if (layer.options.interactive && layer._containsPoint(point)) {
          if (!(e.type === 'click' || e.type === 'preclick') || !this._map._draggableMoved(layer)) {
            clickedLayer = layer;
          }
        }
      }
      this._fireEvent(clickedLayer ? [clickedLayer] : false, e);
    },
    _onMouseMove: function (e) {
      if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) {
        return;
      }
      var point = this._map.mouseEventToLayerPoint(e);
      this._handleMouseHover(e, point);
    },
    _handleMouseOut: function (e) {
      var layer = this._hoveredLayer;
      if (layer) {
        // if we're leaving the layer, fire mouseout
        removeClass(this._container, 'leaflet-interactive');
        this._fireEvent([layer], e, 'mouseout');
        this._hoveredLayer = null;
        this._mouseHoverThrottled = false;
      }
    },
    _handleMouseHover: function (e, point) {
      if (this._mouseHoverThrottled) {
        return;
      }
      var layer, candidateHoveredLayer;
      for (var order = this._drawFirst; order; order = order.next) {
        layer = order.layer;
        if (layer.options.interactive && layer._containsPoint(point)) {
          candidateHoveredLayer = layer;
        }
      }
      if (candidateHoveredLayer !== this._hoveredLayer) {
        this._handleMouseOut(e);
        if (candidateHoveredLayer) {
          addClass(this._container, 'leaflet-interactive'); // change cursor
          this._fireEvent([candidateHoveredLayer], e, 'mouseover');
          this._hoveredLayer = candidateHoveredLayer;
        }
      }
      this._fireEvent(this._hoveredLayer ? [this._hoveredLayer] : false, e);
      this._mouseHoverThrottled = true;
      setTimeout(bind(function () {
        this._mouseHoverThrottled = false;
      }, this), 32);
    },
    _fireEvent: function (layers, e, type) {
      this._map._fireDOMEvent(e, type || e.type, layers);
    },
    _bringToFront: function (layer) {
      var order = layer._order;
      if (!order) {
        return;
      }
      var next = order.next;
      var prev = order.prev;
      if (next) {
        next.prev = prev;
      } else {
        // Already last
        return;
      }
      if (prev) {
        prev.next = next;
      } else if (next) {
        // Update first entry unless this is the
        // single entry
        this._drawFirst = next;
      }
      order.prev = this._drawLast;
      this._drawLast.next = order;
      order.next = null;
      this._drawLast = order;
      this._requestRedraw(layer);
    },
    _bringToBack: function (layer) {
      var order = layer._order;
      if (!order) {
        return;
      }
      var next = order.next;
      var prev = order.prev;
      if (prev) {
        prev.next = next;
      } else {
        // Already first
        return;
      }
      if (next) {
        next.prev = prev;
      } else if (prev) {
        // Update last entry unless this is the
        // single entry
        this._drawLast = prev;
      }
      order.prev = null;
      order.next = this._drawFirst;
      this._drawFirst.prev = order;
      this._drawFirst = order;
      this._requestRedraw(layer);
    }
  });

  // @factory L.canvas(options?: Renderer options)
  // Creates a Canvas renderer with the given options.
  function canvas(options) {
    return Browser.canvas ? new Canvas(options) : null;
  }

  /*
   * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
   */

  var vmlCreate = function () {
    try {
      document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
      return function (name) {
        return document.createElement('<lvml:' + name + ' class="lvml">');
      };
    } catch (e) {
      // Do not return fn from catch block so `e` can be garbage collected
      // See https://github.com/Leaflet/Leaflet/pull/7279
    }
    return function (name) {
      return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
    };
  }();

  /*
   * @class SVG
   *
   *
   * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility
   * with old versions of Internet Explorer.
   */

  // mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences
  var vmlMixin = {
    _initContainer: function () {
      this._container = create$1('div', 'leaflet-vml-container');
    },
    _update: function () {
      if (this._map._animatingZoom) {
        return;
      }
      Renderer.prototype._update.call(this);
      this.fire('update');
    },
    _initPath: function (layer) {
      var container = layer._container = vmlCreate('shape');
      addClass(container, 'leaflet-vml-shape ' + (this.options.className || ''));
      container.coordsize = '1 1';
      layer._path = vmlCreate('path');
      container.appendChild(layer._path);
      this._updateStyle(layer);
      this._layers[stamp(layer)] = layer;
    },
    _addPath: function (layer) {
      var container = layer._container;
      this._container.appendChild(container);
      if (layer.options.interactive) {
        layer.addInteractiveTarget(container);
      }
    },
    _removePath: function (layer) {
      var container = layer._container;
      remove(container);
      layer.removeInteractiveTarget(container);
      delete this._layers[stamp(layer)];
    },
    _updateStyle: function (layer) {
      var stroke = layer._stroke,
        fill = layer._fill,
        options = layer.options,
        container = layer._container;
      container.stroked = !!options.stroke;
      container.filled = !!options.fill;
      if (options.stroke) {
        if (!stroke) {
          stroke = layer._stroke = vmlCreate('stroke');
        }
        container.appendChild(stroke);
        stroke.weight = options.weight + 'px';
        stroke.color = options.color;
        stroke.opacity = options.opacity;
        if (options.dashArray) {
          stroke.dashStyle = isArray(options.dashArray) ? options.dashArray.join(' ') : options.dashArray.replace(/( *, *)/g, ' ');
        } else {
          stroke.dashStyle = '';
        }
        stroke.endcap = options.lineCap.replace('butt', 'flat');
        stroke.joinstyle = options.lineJoin;
      } else if (stroke) {
        container.removeChild(stroke);
        layer._stroke = null;
      }
      if (options.fill) {
        if (!fill) {
          fill = layer._fill = vmlCreate('fill');
        }
        container.appendChild(fill);
        fill.color = options.fillColor || options.color;
        fill.opacity = options.fillOpacity;
      } else if (fill) {
        container.removeChild(fill);
        layer._fill = null;
      }
    },
    _updateCircle: function (layer) {
      var p = layer._point.round(),
        r = Math.round(layer._radius),
        r2 = Math.round(layer._radiusY || r);
      this._setPath(layer, layer._empty() ? 'M0 0' : 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + 65535 * 360);
    },
    _setPath: function (layer, path) {
      layer._path.v = path;
    },
    _bringToFront: function (layer) {
      toFront(layer._container);
    },
    _bringToBack: function (layer) {
      toBack(layer._container);
    }
  };
  var create = Browser.vml ? vmlCreate : svgCreate;

  /*
   * @class SVG
   * @inherits Renderer
   * @aka L.SVG
   *
   * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG).
   * Inherits `Renderer`.
   *
   * Due to [technical limitations](https://caniuse.com/svg), SVG is not
   * available in all web browsers, notably Android 2.x and 3.x.
   *
   * Although SVG is not available on IE7 and IE8, these browsers support
   * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language)
   * (a now deprecated technology), and the SVG renderer will fall back to VML in
   * this case.
   *
   * @example
   *
   * Use SVG by default for all paths in the map:
   *
   * ```js
   * var map = L.map('map', {
   * 	renderer: L.svg()
   * });
   * ```
   *
   * Use a SVG renderer with extra padding for specific vector geometries:
   *
   * ```js
   * var map = L.map('map');
   * var myRenderer = L.svg({ padding: 0.5 });
   * var line = L.polyline( coordinates, { renderer: myRenderer } );
   * var circle = L.circle( center, { renderer: myRenderer } );
   * ```
   */

  var SVG = Renderer.extend({
    _initContainer: function () {
      this._container = create('svg');

      // makes it possible to click through svg root; we'll reset it back in individual paths
      this._container.setAttribute('pointer-events', 'none');
      this._rootGroup = create('g');
      this._container.appendChild(this._rootGroup);
    },
    _destroyContainer: function () {
      remove(this._container);
      off(this._container);
      delete this._container;
      delete this._rootGroup;
      delete this._svgSize;
    },
    _update: function () {
      if (this._map._animatingZoom && this._bounds) {
        return;
      }
      Renderer.prototype._update.call(this);
      var b = this._bounds,
        size = b.getSize(),
        container = this._container;

      // set size of svg-container if changed
      if (!this._svgSize || !this._svgSize.equals(size)) {
        this._svgSize = size;
        container.setAttribute('width', size.x);
        container.setAttribute('height', size.y);
      }

      // movement: update container viewBox so that we don't have to change coordinates of individual layers
      setPosition(container, b.min);
      container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
      this.fire('update');
    },
    // methods below are called by vector layers implementations

    _initPath: function (layer) {
      var path = layer._path = create('path');

      // @namespace Path
      // @option className: String = null
      // Custom class name set on an element. Only for SVG renderer.
      if (layer.options.className) {
        addClass(path, layer.options.className);
      }
      if (layer.options.interactive) {
        addClass(path, 'leaflet-interactive');
      }
      this._updateStyle(layer);
      this._layers[stamp(layer)] = layer;
    },
    _addPath: function (layer) {
      if (!this._rootGroup) {
        this._initContainer();
      }
      this._rootGroup.appendChild(layer._path);
      layer.addInteractiveTarget(layer._path);
    },
    _removePath: function (layer) {
      remove(layer._path);
      layer.removeInteractiveTarget(layer._path);
      delete this._layers[stamp(layer)];
    },
    _updatePath: function (layer) {
      layer._project();
      layer._update();
    },
    _updateStyle: function (layer) {
      var path = layer._path,
        options = layer.options;
      if (!path) {
        return;
      }
      if (options.stroke) {
        path.setAttribute('stroke', options.color);
        path.setAttribute('stroke-opacity', options.opacity);
        path.setAttribute('stroke-width', options.weight);
        path.setAttribute('stroke-linecap', options.lineCap);
        path.setAttribute('stroke-linejoin', options.lineJoin);
        if (options.dashArray) {
          path.setAttribute('stroke-dasharray', options.dashArray);
        } else {
          path.removeAttribute('stroke-dasharray');
        }
        if (options.dashOffset) {
          path.setAttribute('stroke-dashoffset', options.dashOffset);
        } else {
          path.removeAttribute('stroke-dashoffset');
        }
      } else {
        path.setAttribute('stroke', 'none');
      }
      if (options.fill) {
        path.setAttribute('fill', options.fillColor || options.color);
        path.setAttribute('fill-opacity', options.fillOpacity);
        path.setAttribute('fill-rule', options.fillRule || 'evenodd');
      } else {
        path.setAttribute('fill', 'none');
      }
    },
    _updatePoly: function (layer, closed) {
      this._setPath(layer, pointsToPath(layer._parts, closed));
    },
    _updateCircle: function (layer) {
      var p = layer._point,
        r = Math.max(Math.round(layer._radius), 1),
        r2 = Math.max(Math.round(layer._radiusY), 1) || r,
        arc = 'a' + r + ',' + r2 + ' 0 1,0 ';

      // drawing a circle with two half-arcs
      var d = layer._empty() ? 'M0 0' : 'M' + (p.x - r) + ',' + p.y + arc + r * 2 + ',0 ' + arc + -r * 2 + ',0 ';
      this._setPath(layer, d);
    },
    _setPath: function (layer, path) {
      layer._path.setAttribute('d', path);
    },
    // SVG does not have the concept of zIndex so we resort to changing the DOM order of elements
    _bringToFront: function (layer) {
      toFront(layer._path);
    },
    _bringToBack: function (layer) {
      toBack(layer._path);
    }
  });
  if (Browser.vml) {
    SVG.include(vmlMixin);
  }

  // @namespace SVG
  // @factory L.svg(options?: Renderer options)
  // Creates a SVG renderer with the given options.
  function svg(options) {
    return Browser.svg || Browser.vml ? new SVG(options) : null;
  }
  Map.include({
    // @namespace Map; @method getRenderer(layer: Path): Renderer
    // Returns the instance of `Renderer` that should be used to render the given
    // `Path`. It will ensure that the `renderer` options of the map and paths
    // are respected, and that the renderers do exist on the map.
    getRenderer: function (layer) {
      // @namespace Path; @option renderer: Renderer
      // Use this specific instance of `Renderer` for this path. Takes
      // precedence over the map's [default renderer](#map-renderer).
      var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer;
      if (!renderer) {
        renderer = this._renderer = this._createRenderer();
      }
      if (!this.hasLayer(renderer)) {
        this.addLayer(renderer);
      }
      return renderer;
    },
    _getPaneRenderer: function (name) {
      if (name === 'overlayPane' || name === undefined) {
        return false;
      }
      var renderer = this._paneRenderers[name];
      if (renderer === undefined) {
        renderer = this._createRenderer({
          pane: name
        });
        this._paneRenderers[name] = renderer;
      }
      return renderer;
    },
    _createRenderer: function (options) {
      // @namespace Map; @option preferCanvas: Boolean = false
      // Whether `Path`s should be rendered on a `Canvas` renderer.
      // By default, all `Path`s are rendered in a `SVG` renderer.
      return this.options.preferCanvas && canvas(options) || svg(options);
    }
  });

  /*
   * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object.
   */

  /*
   * @class Rectangle
   * @aka L.Rectangle
   * @inherits Polygon
   *
   * A class for drawing rectangle overlays on a map. Extends `Polygon`.
   *
   * @example
   *
   * ```js
   * // define rectangle geographical bounds
   * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
   *
   * // create an orange rectangle
   * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);
   *
   * // zoom the map to the rectangle bounds
   * map.fitBounds(bounds);
   * ```
   *
   */

  var Rectangle = Polygon.extend({
    initialize: function (latLngBounds, options) {
      Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options);
    },
    // @method setBounds(latLngBounds: LatLngBounds): this
    // Redraws the rectangle with the passed bounds.
    setBounds: function (latLngBounds) {
      return this.setLatLngs(this._boundsToLatLngs(latLngBounds));
    },
    _boundsToLatLngs: function (latLngBounds) {
      latLngBounds = toLatLngBounds(latLngBounds);
      return [latLngBounds.getSouthWest(), latLngBounds.getNorthWest(), latLngBounds.getNorthEast(), latLngBounds.getSouthEast()];
    }
  });

  // @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options)
  function rectangle(latLngBounds, options) {
    return new Rectangle(latLngBounds, options);
  }
  SVG.create = create;
  SVG.pointsToPath = pointsToPath;
  GeoJSON.geometryToLayer = geometryToLayer;
  GeoJSON.coordsToLatLng = coordsToLatLng;
  GeoJSON.coordsToLatLngs = coordsToLatLngs;
  GeoJSON.latLngToCoords = latLngToCoords;
  GeoJSON.latLngsToCoords = latLngsToCoords;
  GeoJSON.getFeature = getFeature;
  GeoJSON.asFeature = asFeature;

  /*
   * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
   * (zoom to a selected bounding box), enabled by default.
   */

  // @namespace Map
  // @section Interaction Options
  Map.mergeOptions({
    // @option boxZoom: Boolean = true
    // Whether the map can be zoomed to a rectangular area specified by
    // dragging the mouse while pressing the shift key.
    boxZoom: true
  });
  var BoxZoom = Handler.extend({
    initialize: function (map) {
      this._map = map;
      this._container = map._container;
      this._pane = map._panes.overlayPane;
      this._resetStateTimeout = 0;
      map.on('unload', this._destroy, this);
    },
    addHooks: function () {
      on(this._container, 'mousedown', this._onMouseDown, this);
    },
    removeHooks: function () {
      off(this._container, 'mousedown', this._onMouseDown, this);
    },
    moved: function () {
      return this._moved;
    },
    _destroy: function () {
      remove(this._pane);
      delete this._pane;
    },
    _resetState: function () {
      this._resetStateTimeout = 0;
      this._moved = false;
    },
    _clearDeferredResetState: function () {
      if (this._resetStateTimeout !== 0) {
        clearTimeout(this._resetStateTimeout);
        this._resetStateTimeout = 0;
      }
    },
    _onMouseDown: function (e) {
      if (!e.shiftKey || e.which !== 1 && e.button !== 1) {
        return false;
      }

      // Clear the deferred resetState if it hasn't executed yet, otherwise it
      // will interrupt the interaction and orphan a box element in the container.
      this._clearDeferredResetState();
      this._resetState();
      disableTextSelection();
      disableImageDrag();
      this._startPoint = this._map.mouseEventToContainerPoint(e);
      on(document, {
        contextmenu: stop,
        mousemove: this._onMouseMove,
        mouseup: this._onMouseUp,
        keydown: this._onKeyDown
      }, this);
    },
    _onMouseMove: function (e) {
      if (!this._moved) {
        this._moved = true;
        this._box = create$1('div', 'leaflet-zoom-box', this._container);
        addClass(this._container, 'leaflet-crosshair');
        this._map.fire('boxzoomstart');
      }
      this._point = this._map.mouseEventToContainerPoint(e);
      var bounds = new Bounds(this._point, this._startPoint),
        size = bounds.getSize();
      setPosition(this._box, bounds.min);
      this._box.style.width = size.x + 'px';
      this._box.style.height = size.y + 'px';
    },
    _finish: function () {
      if (this._moved) {
        remove(this._box);
        removeClass(this._container, 'leaflet-crosshair');
      }
      enableTextSelection();
      enableImageDrag();
      off(document, {
        contextmenu: stop,
        mousemove: this._onMouseMove,
        mouseup: this._onMouseUp,
        keydown: this._onKeyDown
      }, this);
    },
    _onMouseUp: function (e) {
      if (e.which !== 1 && e.button !== 1) {
        return;
      }
      this._finish();
      if (!this._moved) {
        return;
      }
      // Postpone to next JS tick so internal click event handling
      // still see it as "moved".
      this._clearDeferredResetState();
      this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0);
      var bounds = new LatLngBounds(this._map.containerPointToLatLng(this._startPoint), this._map.containerPointToLatLng(this._point));
      this._map.fitBounds(bounds).fire('boxzoomend', {
        boxZoomBounds: bounds
      });
    },
    _onKeyDown: function (e) {
      if (e.keyCode === 27) {
        this._finish();
        this._clearDeferredResetState();
        this._resetState();
      }
    }
  });

  // @section Handlers
  // @property boxZoom: Handler
  // Box (shift-drag with mouse) zoom handler.
  Map.addInitHook('addHandler', 'boxZoom', BoxZoom);

  /*
   * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
   */

  // @namespace Map
  // @section Interaction Options

  Map.mergeOptions({
    // @option doubleClickZoom: Boolean|String = true
    // Whether the map can be zoomed in by double clicking on it and
    // zoomed out by double clicking while holding shift. If passed
    // `'center'`, double-click zoom will zoom to the center of the
    //  view regardless of where the mouse was.
    doubleClickZoom: true
  });
  var DoubleClickZoom = Handler.extend({
    addHooks: function () {
      this._map.on('dblclick', this._onDoubleClick, this);
    },
    removeHooks: function () {
      this._map.off('dblclick', this._onDoubleClick, this);
    },
    _onDoubleClick: function (e) {
      var map = this._map,
        oldZoom = map.getZoom(),
        delta = map.options.zoomDelta,
        zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
      if (map.options.doubleClickZoom === 'center') {
        map.setZoom(zoom);
      } else {
        map.setZoomAround(e.containerPoint, zoom);
      }
    }
  });

  // @section Handlers
  //
  // Map properties include interaction handlers that allow you to control
  // interaction behavior in runtime, enabling or disabling certain features such
  // as dragging or touch zoom (see `Handler` methods). For example:
  //
  // ```js
  // map.doubleClickZoom.disable();
  // ```
  //
  // @property doubleClickZoom: Handler
  // Double click zoom handler.
  Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);

  /*
   * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
   */

  // @namespace Map
  // @section Interaction Options
  Map.mergeOptions({
    // @option dragging: Boolean = true
    // Whether the map is draggable with mouse/touch or not.
    dragging: true,
    // @section Panning Inertia Options
    // @option inertia: Boolean = *
    // If enabled, panning of the map will have an inertia effect where
    // the map builds momentum while dragging and continues moving in
    // the same direction for some time. Feels especially nice on touch
    // devices. Enabled by default.
    inertia: true,
    // @option inertiaDeceleration: Number = 3000
    // The rate with which the inertial movement slows down, in pixels/second².
    inertiaDeceleration: 3400,
    // px/s^2

    // @option inertiaMaxSpeed: Number = Infinity
    // Max speed of the inertial movement, in pixels/second.
    inertiaMaxSpeed: Infinity,
    // px/s

    // @option easeLinearity: Number = 0.2
    easeLinearity: 0.2,
    // TODO refactor, move to CRS
    // @option worldCopyJump: Boolean = false
    // With this option enabled, the map tracks when you pan to another "copy"
    // of the world and seamlessly jumps to the original one so that all overlays
    // like markers and vector layers are still visible.
    worldCopyJump: false,
    // @option maxBoundsViscosity: Number = 0.0
    // If `maxBounds` is set, this option will control how solid the bounds
    // are when dragging the map around. The default value of `0.0` allows the
    // user to drag outside the bounds at normal speed, higher values will
    // slow down map dragging outside bounds, and `1.0` makes the bounds fully
    // solid, preventing the user from dragging outside the bounds.
    maxBoundsViscosity: 0.0
  });
  var Drag = Handler.extend({
    addHooks: function () {
      if (!this._draggable) {
        var map = this._map;
        this._draggable = new Draggable(map._mapPane, map._container);
        this._draggable.on({
          dragstart: this._onDragStart,
          drag: this._onDrag,
          dragend: this._onDragEnd
        }, this);
        this._draggable.on('predrag', this._onPreDragLimit, this);
        if (map.options.worldCopyJump) {
          this._draggable.on('predrag', this._onPreDragWrap, this);
          map.on('zoomend', this._onZoomEnd, this);
          map.whenReady(this._onZoomEnd, this);
        }
      }
      addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
      this._draggable.enable();
      this._positions = [];
      this._times = [];
    },
    removeHooks: function () {
      removeClass(this._map._container, 'leaflet-grab');
      removeClass(this._map._container, 'leaflet-touch-drag');
      this._draggable.disable();
    },
    moved: function () {
      return this._draggable && this._draggable._moved;
    },
    moving: function () {
      return this._draggable && this._draggable._moving;
    },
    _onDragStart: function () {
      var map = this._map;
      map._stop();
      if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
        var bounds = toLatLngBounds(this._map.options.maxBounds);
        this._offsetLimit = toBounds(this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1), this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1).add(this._map.getSize()));
        this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
      } else {
        this._offsetLimit = null;
      }
      map.fire('movestart').fire('dragstart');
      if (map.options.inertia) {
        this._positions = [];
        this._times = [];
      }
    },
    _onDrag: function (e) {
      if (this._map.options.inertia) {
        var time = this._lastTime = +new Date(),
          pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
        this._positions.push(pos);
        this._times.push(time);
        this._prunePositions(time);
      }
      this._map.fire('move', e).fire('drag', e);
    },
    _prunePositions: function (time) {
      while (this._positions.length > 1 && time - this._times[0] > 50) {
        this._positions.shift();
        this._times.shift();
      }
    },
    _onZoomEnd: function () {
      var pxCenter = this._map.getSize().divideBy(2),
        pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
      this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
      this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
    },
    _viscousLimit: function (value, threshold) {
      return value - (value - threshold) * this._viscosity;
    },
    _onPreDragLimit: function () {
      if (!this._viscosity || !this._offsetLimit) {
        return;
      }
      var offset = this._draggable._newPos.subtract(this._draggable._startPos);
      var limit = this._offsetLimit;
      if (offset.x < limit.min.x) {
        offset.x = this._viscousLimit(offset.x, limit.min.x);
      }
      if (offset.y < limit.min.y) {
        offset.y = this._viscousLimit(offset.y, limit.min.y);
      }
      if (offset.x > limit.max.x) {
        offset.x = this._viscousLimit(offset.x, limit.max.x);
      }
      if (offset.y > limit.max.y) {
        offset.y = this._viscousLimit(offset.y, limit.max.y);
      }
      this._draggable._newPos = this._draggable._startPos.add(offset);
    },
    _onPreDragWrap: function () {
      // TODO refactor to be able to adjust map pane position after zoom
      var worldWidth = this._worldWidth,
        halfWidth = Math.round(worldWidth / 2),
        dx = this._initialWorldOffset,
        x = this._draggable._newPos.x,
        newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
        newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
        newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
      this._draggable._absPos = this._draggable._newPos.clone();
      this._draggable._newPos.x = newX;
    },
    _onDragEnd: function (e) {
      var map = this._map,
        options = map.options,
        noInertia = !options.inertia || e.noInertia || this._times.length < 2;
      map.fire('dragend', e);
      if (noInertia) {
        map.fire('moveend');
      } else {
        this._prunePositions(+new Date());
        var direction = this._lastPos.subtract(this._positions[0]),
          duration = (this._lastTime - this._times[0]) / 1000,
          ease = options.easeLinearity,
          speedVector = direction.multiplyBy(ease / duration),
          speed = speedVector.distanceTo([0, 0]),
          limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
          limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
          decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
          offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
        if (!offset.x && !offset.y) {
          map.fire('moveend');
        } else {
          offset = map._limitOffset(offset, map.options.maxBounds);
          requestAnimFrame(function () {
            map.panBy(offset, {
              duration: decelerationDuration,
              easeLinearity: ease,
              noMoveStart: true,
              animate: true
            });
          });
        }
      }
    }
  });

  // @section Handlers
  // @property dragging: Handler
  // Map dragging handler (by both mouse and touch).
  Map.addInitHook('addHandler', 'dragging', Drag);

  /*
   * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
   */

  // @namespace Map
  // @section Keyboard Navigation Options
  Map.mergeOptions({
    // @option keyboard: Boolean = true
    // Makes the map focusable and allows users to navigate the map with keyboard
    // arrows and `+`/`-` keys.
    keyboard: true,
    // @option keyboardPanDelta: Number = 80
    // Amount of pixels to pan when pressing an arrow key.
    keyboardPanDelta: 80
  });
  var Keyboard = Handler.extend({
    keyCodes: {
      left: [37],
      right: [39],
      down: [40],
      up: [38],
      zoomIn: [187, 107, 61, 171],
      zoomOut: [189, 109, 54, 173]
    },
    initialize: function (map) {
      this._map = map;
      this._setPanDelta(map.options.keyboardPanDelta);
      this._setZoomDelta(map.options.zoomDelta);
    },
    addHooks: function () {
      var container = this._map._container;

      // make the container focusable by tabbing
      if (container.tabIndex <= 0) {
        container.tabIndex = '0';
      }
      on(container, {
        focus: this._onFocus,
        blur: this._onBlur,
        mousedown: this._onMouseDown
      }, this);
      this._map.on({
        focus: this._addHooks,
        blur: this._removeHooks
      }, this);
    },
    removeHooks: function () {
      this._removeHooks();
      off(this._map._container, {
        focus: this._onFocus,
        blur: this._onBlur,
        mousedown: this._onMouseDown
      }, this);
      this._map.off({
        focus: this._addHooks,
        blur: this._removeHooks
      }, this);
    },
    _onMouseDown: function () {
      if (this._focused) {
        return;
      }
      var body = document.body,
        docEl = document.documentElement,
        top = body.scrollTop || docEl.scrollTop,
        left = body.scrollLeft || docEl.scrollLeft;
      this._map._container.focus();
      window.scrollTo(left, top);
    },
    _onFocus: function () {
      this._focused = true;
      this._map.fire('focus');
    },
    _onBlur: function () {
      this._focused = false;
      this._map.fire('blur');
    },
    _setPanDelta: function (panDelta) {
      var keys = this._panKeys = {},
        codes = this.keyCodes,
        i,
        len;
      for (i = 0, len = codes.left.length; i < len; i++) {
        keys[codes.left[i]] = [-1 * panDelta, 0];
      }
      for (i = 0, len = codes.right.length; i < len; i++) {
        keys[codes.right[i]] = [panDelta, 0];
      }
      for (i = 0, len = codes.down.length; i < len; i++) {
        keys[codes.down[i]] = [0, panDelta];
      }
      for (i = 0, len = codes.up.length; i < len; i++) {
        keys[codes.up[i]] = [0, -1 * panDelta];
      }
    },
    _setZoomDelta: function (zoomDelta) {
      var keys = this._zoomKeys = {},
        codes = this.keyCodes,
        i,
        len;
      for (i = 0, len = codes.zoomIn.length; i < len; i++) {
        keys[codes.zoomIn[i]] = zoomDelta;
      }
      for (i = 0, len = codes.zoomOut.length; i < len; i++) {
        keys[codes.zoomOut[i]] = -zoomDelta;
      }
    },
    _addHooks: function () {
      on(document, 'keydown', this._onKeyDown, this);
    },
    _removeHooks: function () {
      off(document, 'keydown', this._onKeyDown, this);
    },
    _onKeyDown: function (e) {
      if (e.altKey || e.ctrlKey || e.metaKey) {
        return;
      }
      var key = e.keyCode,
        map = this._map,
        offset;
      if (key in this._panKeys) {
        if (!map._panAnim || !map._panAnim._inProgress) {
          offset = this._panKeys[key];
          if (e.shiftKey) {
            offset = toPoint(offset).multiplyBy(3);
          }
          if (map.options.maxBounds) {
            offset = map._limitOffset(toPoint(offset), map.options.maxBounds);
          }
          if (map.options.worldCopyJump) {
            var newLatLng = map.wrapLatLng(map.unproject(map.project(map.getCenter()).add(offset)));
            map.panTo(newLatLng);
          } else {
            map.panBy(offset);
          }
        }
      } else if (key in this._zoomKeys) {
        map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
      } else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
        map.closePopup();
      } else {
        return;
      }
      stop(e);
    }
  });

  // @section Handlers
  // @section Handlers
  // @property keyboard: Handler
  // Keyboard navigation handler.
  Map.addInitHook('addHandler', 'keyboard', Keyboard);

  /*
   * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
   */

  // @namespace Map
  // @section Interaction Options
  Map.mergeOptions({
    // @section Mouse wheel options
    // @option scrollWheelZoom: Boolean|String = true
    // Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
    // it will zoom to the center of the view regardless of where the mouse was.
    scrollWheelZoom: true,
    // @option wheelDebounceTime: Number = 40
    // Limits the rate at which a wheel can fire (in milliseconds). By default
    // user can't zoom via wheel more often than once per 40 ms.
    wheelDebounceTime: 40,
    // @option wheelPxPerZoomLevel: Number = 60
    // How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
    // mean a change of one full zoom level. Smaller values will make wheel-zooming
    // faster (and vice versa).
    wheelPxPerZoomLevel: 60
  });
  var ScrollWheelZoom = Handler.extend({
    addHooks: function () {
      on(this._map._container, 'wheel', this._onWheelScroll, this);
      this._delta = 0;
    },
    removeHooks: function () {
      off(this._map._container, 'wheel', this._onWheelScroll, this);
    },
    _onWheelScroll: function (e) {
      var delta = getWheelDelta(e);
      var debounce = this._map.options.wheelDebounceTime;
      this._delta += delta;
      this._lastMousePos = this._map.mouseEventToContainerPoint(e);
      if (!this._startTime) {
        this._startTime = +new Date();
      }
      var left = Math.max(debounce - (+new Date() - this._startTime), 0);
      clearTimeout(this._timer);
      this._timer = setTimeout(bind(this._performZoom, this), left);
      stop(e);
    },
    _performZoom: function () {
      var map = this._map,
        zoom = map.getZoom(),
        snap = this._map.options.zoomSnap || 0;
      map._stop(); // stop panning and fly animations if any

      // map the delta with a sigmoid function to -4..4 range leaning on -1..1
      var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
        d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
        d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
        delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
      this._delta = 0;
      this._startTime = null;
      if (!delta) {
        return;
      }
      if (map.options.scrollWheelZoom === 'center') {
        map.setZoom(zoom + delta);
      } else {
        map.setZoomAround(this._lastMousePos, zoom + delta);
      }
    }
  });

  // @section Handlers
  // @property scrollWheelZoom: Handler
  // Scroll wheel zoom handler.
  Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);

  /*
   * L.Map.TapHold is used to simulate `contextmenu` event on long hold,
   * which otherwise is not fired by mobile Safari.
   */

  var tapHoldDelay = 600;

  // @namespace Map
  // @section Interaction Options
  Map.mergeOptions({
    // @section Touch interaction options
    // @option tapHold: Boolean
    // Enables simulation of `contextmenu` event, default is `true` for mobile Safari.
    tapHold: Browser.touchNative && Browser.safari && Browser.mobile,
    // @option tapTolerance: Number = 15
    // The max number of pixels a user can shift his finger during touch
    // for it to be considered a valid tap.
    tapTolerance: 15
  });
  var TapHold = Handler.extend({
    addHooks: function () {
      on(this._map._container, 'touchstart', this._onDown, this);
    },
    removeHooks: function () {
      off(this._map._container, 'touchstart', this._onDown, this);
    },
    _onDown: function (e) {
      clearTimeout(this._holdTimeout);
      if (e.touches.length !== 1) {
        return;
      }
      var first = e.touches[0];
      this._startPos = this._newPos = new Point(first.clientX, first.clientY);
      this._holdTimeout = setTimeout(bind(function () {
        this._cancel();
        if (!this._isTapValid()) {
          return;
        }

        // prevent simulated mouse events https://w3c.github.io/touch-events/#mouse-events
        on(document, 'touchend', preventDefault);
        on(document, 'touchend touchcancel', this._cancelClickPrevent);
        this._simulateEvent('contextmenu', first);
      }, this), tapHoldDelay);
      on(document, 'touchend touchcancel contextmenu', this._cancel, this);
      on(document, 'touchmove', this._onMove, this);
    },
    _cancelClickPrevent: function cancelClickPrevent() {
      off(document, 'touchend', preventDefault);
      off(document, 'touchend touchcancel', cancelClickPrevent);
    },
    _cancel: function () {
      clearTimeout(this._holdTimeout);
      off(document, 'touchend touchcancel contextmenu', this._cancel, this);
      off(document, 'touchmove', this._onMove, this);
    },
    _onMove: function (e) {
      var first = e.touches[0];
      this._newPos = new Point(first.clientX, first.clientY);
    },
    _isTapValid: function () {
      return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
    },
    _simulateEvent: function (type, e) {
      var simulatedEvent = new MouseEvent(type, {
        bubbles: true,
        cancelable: true,
        view: window,
        // detail: 1,
        screenX: e.screenX,
        screenY: e.screenY,
        clientX: e.clientX,
        clientY: e.clientY
        // button: 2,
        // buttons: 2
      });
      simulatedEvent._simulated = true;
      e.target.dispatchEvent(simulatedEvent);
    }
  });

  // @section Handlers
  // @property tapHold: Handler
  // Long tap handler to simulate `contextmenu` event (useful in mobile Safari).
  Map.addInitHook('addHandler', 'tapHold', TapHold);

  /*
   * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
   */

  // @namespace Map
  // @section Interaction Options
  Map.mergeOptions({
    // @section Touch interaction options
    // @option touchZoom: Boolean|String = *
    // Whether the map can be zoomed by touch-dragging with two fingers. If
    // passed `'center'`, it will zoom to the center of the view regardless of
    // where the touch events (fingers) were. Enabled for touch-capable web
    // browsers.
    touchZoom: Browser.touch,
    // @option bounceAtZoomLimits: Boolean = true
    // Set it to false if you don't want the map to zoom beyond min/max zoom
    // and then bounce back when pinch-zooming.
    bounceAtZoomLimits: true
  });
  var TouchZoom = Handler.extend({
    addHooks: function () {
      addClass(this._map._container, 'leaflet-touch-zoom');
      on(this._map._container, 'touchstart', this._onTouchStart, this);
    },
    removeHooks: function () {
      removeClass(this._map._container, 'leaflet-touch-zoom');
      off(this._map._container, 'touchstart', this._onTouchStart, this);
    },
    _onTouchStart: function (e) {
      var map = this._map;
      if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) {
        return;
      }
      var p1 = map.mouseEventToContainerPoint(e.touches[0]),
        p2 = map.mouseEventToContainerPoint(e.touches[1]);
      this._centerPoint = map.getSize()._divideBy(2);
      this._startLatLng = map.containerPointToLatLng(this._centerPoint);
      if (map.options.touchZoom !== 'center') {
        this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
      }
      this._startDist = p1.distanceTo(p2);
      this._startZoom = map.getZoom();
      this._moved = false;
      this._zooming = true;
      map._stop();
      on(document, 'touchmove', this._onTouchMove, this);
      on(document, 'touchend touchcancel', this._onTouchEnd, this);
      preventDefault(e);
    },
    _onTouchMove: function (e) {
      if (!e.touches || e.touches.length !== 2 || !this._zooming) {
        return;
      }
      var map = this._map,
        p1 = map.mouseEventToContainerPoint(e.touches[0]),
        p2 = map.mouseEventToContainerPoint(e.touches[1]),
        scale = p1.distanceTo(p2) / this._startDist;
      this._zoom = map.getScaleZoom(scale, this._startZoom);
      if (!map.options.bounceAtZoomLimits && (this._zoom < map.getMinZoom() && scale < 1 || this._zoom > map.getMaxZoom() && scale > 1)) {
        this._zoom = map._limitZoom(this._zoom);
      }
      if (map.options.touchZoom === 'center') {
        this._center = this._startLatLng;
        if (scale === 1) {
          return;
        }
      } else {
        // Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
        var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
        if (scale === 1 && delta.x === 0 && delta.y === 0) {
          return;
        }
        this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom);
      }
      if (!this._moved) {
        map._moveStart(true, false);
        this._moved = true;
      }
      cancelAnimFrame(this._animRequest);
      var moveFn = bind(map._move, map, this._center, this._zoom, {
        pinch: true,
        round: false
      }, undefined);
      this._animRequest = requestAnimFrame(moveFn, this, true);
      preventDefault(e);
    },
    _onTouchEnd: function () {
      if (!this._moved || !this._zooming) {
        this._zooming = false;
        return;
      }
      this._zooming = false;
      cancelAnimFrame(this._animRequest);
      off(document, 'touchmove', this._onTouchMove, this);
      off(document, 'touchend touchcancel', this._onTouchEnd, this);

      // Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
      if (this._map.options.zoomAnimation) {
        this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
      } else {
        this._map._resetView(this._center, this._map._limitZoom(this._zoom));
      }
    }
  });

  // @section Handlers
  // @property touchZoom: Handler
  // Touch zoom handler.
  Map.addInitHook('addHandler', 'touchZoom', TouchZoom);
  Map.BoxZoom = BoxZoom;
  Map.DoubleClickZoom = DoubleClickZoom;
  Map.Drag = Drag;
  Map.Keyboard = Keyboard;
  Map.ScrollWheelZoom = ScrollWheelZoom;
  Map.TapHold = TapHold;
  Map.TouchZoom = TouchZoom;
  exports.Bounds = Bounds;
  exports.Browser = Browser;
  exports.CRS = CRS;
  exports.Canvas = Canvas;
  exports.Circle = Circle;
  exports.CircleMarker = CircleMarker;
  exports.Class = Class;
  exports.Control = Control;
  exports.DivIcon = DivIcon;
  exports.DivOverlay = DivOverlay;
  exports.DomEvent = DomEvent;
  exports.DomUtil = DomUtil;
  exports.Draggable = Draggable;
  exports.Evented = Evented;
  exports.FeatureGroup = FeatureGroup;
  exports.GeoJSON = GeoJSON;
  exports.GridLayer = GridLayer;
  exports.Handler = Handler;
  exports.Icon = Icon;
  exports.ImageOverlay = ImageOverlay;
  exports.LatLng = LatLng;
  exports.LatLngBounds = LatLngBounds;
  exports.Layer = Layer;
  exports.LayerGroup = LayerGroup;
  exports.LineUtil = LineUtil;
  exports.Map = Map;
  exports.Marker = Marker;
  exports.Mixin = Mixin;
  exports.Path = Path;
  exports.Point = Point;
  exports.PolyUtil = PolyUtil;
  exports.Polygon = Polygon;
  exports.Polyline = Polyline;
  exports.Popup = Popup;
  exports.PosAnimation = PosAnimation;
  exports.Projection = index;
  exports.Rectangle = Rectangle;
  exports.Renderer = Renderer;
  exports.SVG = SVG;
  exports.SVGOverlay = SVGOverlay;
  exports.TileLayer = TileLayer;
  exports.Tooltip = Tooltip;
  exports.Transformation = Transformation;
  exports.Util = Util;
  exports.VideoOverlay = VideoOverlay;
  exports.bind = bind;
  exports.bounds = toBounds;
  exports.canvas = canvas;
  exports.circle = circle;
  exports.circleMarker = circleMarker;
  exports.control = control;
  exports.divIcon = divIcon;
  exports.extend = extend;
  exports.featureGroup = featureGroup;
  exports.geoJSON = geoJSON;
  exports.geoJson = geoJson;
  exports.gridLayer = gridLayer;
  exports.icon = icon;
  exports.imageOverlay = imageOverlay;
  exports.latLng = toLatLng;
  exports.latLngBounds = toLatLngBounds;
  exports.layerGroup = layerGroup;
  exports.map = createMap;
  exports.marker = marker;
  exports.point = toPoint;
  exports.polygon = polygon;
  exports.polyline = polyline;
  exports.popup = popup;
  exports.rectangle = rectangle;
  exports.setOptions = setOptions;
  exports.stamp = stamp;
  exports.svg = svg;
  exports.svgOverlay = svgOverlay;
  exports.tileLayer = tileLayer;
  exports.tooltip = tooltip;
  exports.transformation = toTransformation;
  exports.version = version;
  exports.videoOverlay = videoOverlay;
  var oldL = window.L;
  exports.noConflict = function () {
    window.L = oldL;
    return this;
  };
  // Always export us to window global (see #2364)
  window.L = exports;
});

/***/ }),

/***/ 24335:
/*!********************************************************!*\
  !*** ./node_modules/lottie-web/build/player/lottie.js ***!
  \********************************************************/
/***/ (function(module, exports, __webpack_require__) {

typeof document !== "undefined" && typeof navigator !== "undefined" && function (global, factory) {
   true ? module.exports = factory() : 0;
}(this, function () {
  'use strict';

  var svgNS = 'http://www.w3.org/2000/svg';
  var locationHref = '';
  var _useWebWorker = false;
  var initialDefaultFrame = -999999;
  var setWebWorker = function setWebWorker(flag) {
    _useWebWorker = !!flag;
  };
  var getWebWorker = function getWebWorker() {
    return _useWebWorker;
  };
  var setLocationHref = function setLocationHref(value) {
    locationHref = value;
  };
  var getLocationHref = function getLocationHref() {
    return locationHref;
  };
  function createTag(type) {
    // return {appendChild:function(){},setAttribute:function(){},style:{}}
    return document.createElement(type);
  }
  function extendPrototype(sources, destination) {
    var i;
    var len = sources.length;
    var sourcePrototype;
    for (i = 0; i < len; i += 1) {
      sourcePrototype = sources[i].prototype;
      for (var attr in sourcePrototype) {
        if (Object.prototype.hasOwnProperty.call(sourcePrototype, attr)) destination.prototype[attr] = sourcePrototype[attr];
      }
    }
  }
  function getDescriptor(object, prop) {
    return Object.getOwnPropertyDescriptor(object, prop);
  }
  function createProxyFunction(prototype) {
    function ProxyFunction() {}
    ProxyFunction.prototype = prototype;
    return ProxyFunction;
  }

  // import Howl from '../../3rd_party/howler';

  var audioControllerFactory = function () {
    function AudioController(audioFactory) {
      this.audios = [];
      this.audioFactory = audioFactory;
      this._volume = 1;
      this._isMuted = false;
    }
    AudioController.prototype = {
      addAudio: function addAudio(audio) {
        this.audios.push(audio);
      },
      pause: function pause() {
        var i;
        var len = this.audios.length;
        for (i = 0; i < len; i += 1) {
          this.audios[i].pause();
        }
      },
      resume: function resume() {
        var i;
        var len = this.audios.length;
        for (i = 0; i < len; i += 1) {
          this.audios[i].resume();
        }
      },
      setRate: function setRate(rateValue) {
        var i;
        var len = this.audios.length;
        for (i = 0; i < len; i += 1) {
          this.audios[i].setRate(rateValue);
        }
      },
      createAudio: function createAudio(assetPath) {
        if (this.audioFactory) {
          return this.audioFactory(assetPath);
        }
        if (window.Howl) {
          return new window.Howl({
            src: [assetPath]
          });
        }
        return {
          isPlaying: false,
          play: function play() {
            this.isPlaying = true;
          },
          seek: function seek() {
            this.isPlaying = false;
          },
          playing: function playing() {},
          rate: function rate() {},
          setVolume: function setVolume() {}
        };
      },
      setAudioFactory: function setAudioFactory(audioFactory) {
        this.audioFactory = audioFactory;
      },
      setVolume: function setVolume(value) {
        this._volume = value;
        this._updateVolume();
      },
      mute: function mute() {
        this._isMuted = true;
        this._updateVolume();
      },
      unmute: function unmute() {
        this._isMuted = false;
        this._updateVolume();
      },
      getVolume: function getVolume() {
        return this._volume;
      },
      _updateVolume: function _updateVolume() {
        var i;
        var len = this.audios.length;
        for (i = 0; i < len; i += 1) {
          this.audios[i].volume(this._volume * (this._isMuted ? 0 : 1));
        }
      }
    };
    return function () {
      return new AudioController();
    };
  }();
  var createTypedArray = function () {
    function createRegularArray(type, len) {
      var i = 0;
      var arr = [];
      var value;
      switch (type) {
        case 'int16':
        case 'uint8c':
          value = 1;
          break;
        default:
          value = 1.1;
          break;
      }
      for (i = 0; i < len; i += 1) {
        arr.push(value);
      }
      return arr;
    }
    function createTypedArrayFactory(type, len) {
      if (type === 'float32') {
        return new Float32Array(len);
      }
      if (type === 'int16') {
        return new Int16Array(len);
      }
      if (type === 'uint8c') {
        return new Uint8ClampedArray(len);
      }
      return createRegularArray(type, len);
    }
    if (typeof Uint8ClampedArray === 'function' && typeof Float32Array === 'function') {
      return createTypedArrayFactory;
    }
    return createRegularArray;
  }();
  function createSizedArray(len) {
    return Array.apply(null, {
      length: len
    });
  }
  function _typeof$6(o) {
    "@babel/helpers - typeof";

    return _typeof$6 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$6(o);
  }
  var subframeEnabled = true;
  var expressionsPlugin = null;
  var expressionsInterfaces = null;
  var idPrefix$1 = '';
  var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
  var _shouldRoundValues = false;
  var bmPow = Math.pow;
  var bmSqrt = Math.sqrt;
  var bmFloor = Math.floor;
  var bmMax = Math.max;
  var bmMin = Math.min;
  var BMMath = {};
  (function () {
    var propertyNames = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atanh', 'atan2', 'ceil', 'cbrt', 'expm1', 'clz32', 'cos', 'cosh', 'exp', 'floor', 'fround', 'hypot', 'imul', 'log', 'log1p', 'log2', 'log10', 'max', 'min', 'pow', 'random', 'round', 'sign', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'trunc', 'E', 'LN10', 'LN2', 'LOG10E', 'LOG2E', 'PI', 'SQRT1_2', 'SQRT2'];
    var i;
    var len = propertyNames.length;
    for (i = 0; i < len; i += 1) {
      BMMath[propertyNames[i]] = Math[propertyNames[i]];
    }
  })();
  function ProjectInterface$1() {
    return {};
  }
  BMMath.random = Math.random;
  BMMath.abs = function (val) {
    var tOfVal = _typeof$6(val);
    if (tOfVal === 'object' && val.length) {
      var absArr = createSizedArray(val.length);
      var i;
      var len = val.length;
      for (i = 0; i < len; i += 1) {
        absArr[i] = Math.abs(val[i]);
      }
      return absArr;
    }
    return Math.abs(val);
  };
  var defaultCurveSegments = 150;
  var degToRads = Math.PI / 180;
  var roundCorner = 0.5519;
  function roundValues(flag) {
    _shouldRoundValues = !!flag;
  }
  function bmRnd(value) {
    if (_shouldRoundValues) {
      return Math.round(value);
    }
    return value;
  }
  function styleDiv(element) {
    element.style.position = 'absolute';
    element.style.top = 0;
    element.style.left = 0;
    element.style.display = 'block';
    element.style.transformOrigin = '0 0';
    element.style.webkitTransformOrigin = '0 0';
    element.style.backfaceVisibility = 'visible';
    element.style.webkitBackfaceVisibility = 'visible';
    element.style.transformStyle = 'preserve-3d';
    element.style.webkitTransformStyle = 'preserve-3d';
    element.style.mozTransformStyle = 'preserve-3d';
  }
  function BMEnterFrameEvent(type, currentTime, totalTime, frameMultiplier) {
    this.type = type;
    this.currentTime = currentTime;
    this.totalTime = totalTime;
    this.direction = frameMultiplier < 0 ? -1 : 1;
  }
  function BMCompleteEvent(type, frameMultiplier) {
    this.type = type;
    this.direction = frameMultiplier < 0 ? -1 : 1;
  }
  function BMCompleteLoopEvent(type, totalLoops, currentLoop, frameMultiplier) {
    this.type = type;
    this.currentLoop = currentLoop;
    this.totalLoops = totalLoops;
    this.direction = frameMultiplier < 0 ? -1 : 1;
  }
  function BMSegmentStartEvent(type, firstFrame, totalFrames) {
    this.type = type;
    this.firstFrame = firstFrame;
    this.totalFrames = totalFrames;
  }
  function BMDestroyEvent(type, target) {
    this.type = type;
    this.target = target;
  }
  function BMRenderFrameErrorEvent(nativeError, currentTime) {
    this.type = 'renderFrameError';
    this.nativeError = nativeError;
    this.currentTime = currentTime;
  }
  function BMConfigErrorEvent(nativeError) {
    this.type = 'configError';
    this.nativeError = nativeError;
  }
  function BMAnimationConfigErrorEvent(type, nativeError) {
    this.type = type;
    this.nativeError = nativeError;
  }
  var createElementID = function () {
    var _count = 0;
    return function createID() {
      _count += 1;
      return idPrefix$1 + '__lottie_element_' + _count;
    };
  }();
  function HSVtoRGB(h, s, v) {
    var r;
    var g;
    var b;
    var i;
    var f;
    var p;
    var q;
    var t;
    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);
    switch (i % 6) {
      case 0:
        r = v;
        g = t;
        b = p;
        break;
      case 1:
        r = q;
        g = v;
        b = p;
        break;
      case 2:
        r = p;
        g = v;
        b = t;
        break;
      case 3:
        r = p;
        g = q;
        b = v;
        break;
      case 4:
        r = t;
        g = p;
        b = v;
        break;
      case 5:
        r = v;
        g = p;
        b = q;
        break;
      default:
        break;
    }
    return [r, g, b];
  }
  function RGBtoHSV(r, g, b) {
    var max = Math.max(r, g, b);
    var min = Math.min(r, g, b);
    var d = max - min;
    var h;
    var s = max === 0 ? 0 : d / max;
    var v = max / 255;
    switch (max) {
      case min:
        h = 0;
        break;
      case r:
        h = g - b + d * (g < b ? 6 : 0);
        h /= 6 * d;
        break;
      case g:
        h = b - r + d * 2;
        h /= 6 * d;
        break;
      case b:
        h = r - g + d * 4;
        h /= 6 * d;
        break;
      default:
        break;
    }
    return [h, s, v];
  }
  function addSaturationToRGB(color, offset) {
    var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
    hsv[1] += offset;
    if (hsv[1] > 1) {
      hsv[1] = 1;
    } else if (hsv[1] <= 0) {
      hsv[1] = 0;
    }
    return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
  }
  function addBrightnessToRGB(color, offset) {
    var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
    hsv[2] += offset;
    if (hsv[2] > 1) {
      hsv[2] = 1;
    } else if (hsv[2] < 0) {
      hsv[2] = 0;
    }
    return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
  }
  function addHueToRGB(color, offset) {
    var hsv = RGBtoHSV(color[0] * 255, color[1] * 255, color[2] * 255);
    hsv[0] += offset / 360;
    if (hsv[0] > 1) {
      hsv[0] -= 1;
    } else if (hsv[0] < 0) {
      hsv[0] += 1;
    }
    return HSVtoRGB(hsv[0], hsv[1], hsv[2]);
  }
  var rgbToHex = function () {
    var colorMap = [];
    var i;
    var hex;
    for (i = 0; i < 256; i += 1) {
      hex = i.toString(16);
      colorMap[i] = hex.length === 1 ? '0' + hex : hex;
    }
    return function (r, g, b) {
      if (r < 0) {
        r = 0;
      }
      if (g < 0) {
        g = 0;
      }
      if (b < 0) {
        b = 0;
      }
      return '#' + colorMap[r] + colorMap[g] + colorMap[b];
    };
  }();
  var setSubframeEnabled = function setSubframeEnabled(flag) {
    subframeEnabled = !!flag;
  };
  var getSubframeEnabled = function getSubframeEnabled() {
    return subframeEnabled;
  };
  var setExpressionsPlugin = function setExpressionsPlugin(value) {
    expressionsPlugin = value;
  };
  var getExpressionsPlugin = function getExpressionsPlugin() {
    return expressionsPlugin;
  };
  var setExpressionInterfaces = function setExpressionInterfaces(value) {
    expressionsInterfaces = value;
  };
  var getExpressionInterfaces = function getExpressionInterfaces() {
    return expressionsInterfaces;
  };
  var setDefaultCurveSegments = function setDefaultCurveSegments(value) {
    defaultCurveSegments = value;
  };
  var getDefaultCurveSegments = function getDefaultCurveSegments() {
    return defaultCurveSegments;
  };
  var setIdPrefix = function setIdPrefix(value) {
    idPrefix$1 = value;
  };
  var getIdPrefix = function getIdPrefix() {
    return idPrefix$1;
  };
  function createNS(type) {
    // return {appendChild:function(){},setAttribute:function(){},style:{}}
    return document.createElementNS(svgNS, type);
  }
  function _typeof$5(o) {
    "@babel/helpers - typeof";

    return _typeof$5 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$5(o);
  }
  var dataManager = function () {
    var _counterId = 1;
    var processes = [];
    var workerFn;
    var workerInstance;
    var workerProxy = {
      onmessage: function onmessage() {},
      postMessage: function postMessage(path) {
        workerFn({
          data: path
        });
      }
    };
    var _workerSelf = {
      postMessage: function postMessage(data) {
        workerProxy.onmessage({
          data: data
        });
      }
    };
    function createWorker(fn) {
      if (window.Worker && window.Blob && getWebWorker()) {
        var blob = new Blob(['var _workerSelf = self; self.onmessage = ', fn.toString()], {
          type: 'text/javascript'
        });
        // var blob = new Blob(['self.onmessage = ', fn.toString()], { type: 'text/javascript' });
        var url = URL.createObjectURL(blob);
        return new Worker(url);
      }
      workerFn = fn;
      return workerProxy;
    }
    function setupWorker() {
      if (!workerInstance) {
        workerInstance = createWorker(function workerStart(e) {
          function dataFunctionManager() {
            function completeLayers(layers, comps) {
              var layerData;
              var i;
              var len = layers.length;
              var j;
              var jLen;
              var k;
              var kLen;
              for (i = 0; i < len; i += 1) {
                layerData = layers[i];
                if ('ks' in layerData && !layerData.completed) {
                  layerData.completed = true;
                  if (layerData.hasMask) {
                    var maskProps = layerData.masksProperties;
                    jLen = maskProps.length;
                    for (j = 0; j < jLen; j += 1) {
                      if (maskProps[j].pt.k.i) {
                        convertPathsToAbsoluteValues(maskProps[j].pt.k);
                      } else {
                        kLen = maskProps[j].pt.k.length;
                        for (k = 0; k < kLen; k += 1) {
                          if (maskProps[j].pt.k[k].s) {
                            convertPathsToAbsoluteValues(maskProps[j].pt.k[k].s[0]);
                          }
                          if (maskProps[j].pt.k[k].e) {
                            convertPathsToAbsoluteValues(maskProps[j].pt.k[k].e[0]);
                          }
                        }
                      }
                    }
                  }
                  if (layerData.ty === 0) {
                    layerData.layers = findCompLayers(layerData.refId, comps);
                    completeLayers(layerData.layers, comps);
                  } else if (layerData.ty === 4) {
                    completeShapes(layerData.shapes);
                  } else if (layerData.ty === 5) {
                    completeText(layerData);
                  }
                }
              }
            }
            function completeChars(chars, assets) {
              if (chars) {
                var i = 0;
                var len = chars.length;
                for (i = 0; i < len; i += 1) {
                  if (chars[i].t === 1) {
                    // var compData = findComp(chars[i].data.refId, assets);
                    chars[i].data.layers = findCompLayers(chars[i].data.refId, assets);
                    // chars[i].data.ip = 0;
                    // chars[i].data.op = 99999;
                    // chars[i].data.st = 0;
                    // chars[i].data.sr = 1;
                    // chars[i].w = compData.w;
                    // chars[i].data.ks = {
                    //   a: { k: [0, 0, 0], a: 0 },
                    //   p: { k: [0, -compData.h, 0], a: 0 },
                    //   r: { k: 0, a: 0 },
                    //   s: { k: [100, 100], a: 0 },
                    //   o: { k: 100, a: 0 },
                    // };
                    completeLayers(chars[i].data.layers, assets);
                  }
                }
              }
            }
            function findComp(id, comps) {
              var i = 0;
              var len = comps.length;
              while (i < len) {
                if (comps[i].id === id) {
                  return comps[i];
                }
                i += 1;
              }
              return null;
            }
            function findCompLayers(id, comps) {
              var comp = findComp(id, comps);
              if (comp) {
                if (!comp.layers.__used) {
                  comp.layers.__used = true;
                  return comp.layers;
                }
                return JSON.parse(JSON.stringify(comp.layers));
              }
              return null;
            }
            function completeShapes(arr) {
              var i;
              var len = arr.length;
              var j;
              var jLen;
              for (i = len - 1; i >= 0; i -= 1) {
                if (arr[i].ty === 'sh') {
                  if (arr[i].ks.k.i) {
                    convertPathsToAbsoluteValues(arr[i].ks.k);
                  } else {
                    jLen = arr[i].ks.k.length;
                    for (j = 0; j < jLen; j += 1) {
                      if (arr[i].ks.k[j].s) {
                        convertPathsToAbsoluteValues(arr[i].ks.k[j].s[0]);
                      }
                      if (arr[i].ks.k[j].e) {
                        convertPathsToAbsoluteValues(arr[i].ks.k[j].e[0]);
                      }
                    }
                  }
                } else if (arr[i].ty === 'gr') {
                  completeShapes(arr[i].it);
                }
              }
            }
            function convertPathsToAbsoluteValues(path) {
              var i;
              var len = path.i.length;
              for (i = 0; i < len; i += 1) {
                path.i[i][0] += path.v[i][0];
                path.i[i][1] += path.v[i][1];
                path.o[i][0] += path.v[i][0];
                path.o[i][1] += path.v[i][1];
              }
            }
            function checkVersion(minimum, animVersionString) {
              var animVersion = animVersionString ? animVersionString.split('.') : [100, 100, 100];
              if (minimum[0] > animVersion[0]) {
                return true;
              }
              if (animVersion[0] > minimum[0]) {
                return false;
              }
              if (minimum[1] > animVersion[1]) {
                return true;
              }
              if (animVersion[1] > minimum[1]) {
                return false;
              }
              if (minimum[2] > animVersion[2]) {
                return true;
              }
              if (animVersion[2] > minimum[2]) {
                return false;
              }
              return null;
            }
            var checkText = function () {
              var minimumVersion = [4, 4, 14];
              function updateTextLayer(textLayer) {
                var documentData = textLayer.t.d;
                textLayer.t.d = {
                  k: [{
                    s: documentData,
                    t: 0
                  }]
                };
              }
              function iterateLayers(layers) {
                var i;
                var len = layers.length;
                for (i = 0; i < len; i += 1) {
                  if (layers[i].ty === 5) {
                    updateTextLayer(layers[i]);
                  }
                }
              }
              return function (animationData) {
                if (checkVersion(minimumVersion, animationData.v)) {
                  iterateLayers(animationData.layers);
                  if (animationData.assets) {
                    var i;
                    var len = animationData.assets.length;
                    for (i = 0; i < len; i += 1) {
                      if (animationData.assets[i].layers) {
                        iterateLayers(animationData.assets[i].layers);
                      }
                    }
                  }
                }
              };
            }();
            var checkChars = function () {
              var minimumVersion = [4, 7, 99];
              return function (animationData) {
                if (animationData.chars && !checkVersion(minimumVersion, animationData.v)) {
                  var i;
                  var len = animationData.chars.length;
                  for (i = 0; i < len; i += 1) {
                    var charData = animationData.chars[i];
                    if (charData.data && charData.data.shapes) {
                      completeShapes(charData.data.shapes);
                      charData.data.ip = 0;
                      charData.data.op = 99999;
                      charData.data.st = 0;
                      charData.data.sr = 1;
                      charData.data.ks = {
                        p: {
                          k: [0, 0],
                          a: 0
                        },
                        s: {
                          k: [100, 100],
                          a: 0
                        },
                        a: {
                          k: [0, 0],
                          a: 0
                        },
                        r: {
                          k: 0,
                          a: 0
                        },
                        o: {
                          k: 100,
                          a: 0
                        }
                      };
                      if (!animationData.chars[i].t) {
                        charData.data.shapes.push({
                          ty: 'no'
                        });
                        charData.data.shapes[0].it.push({
                          p: {
                            k: [0, 0],
                            a: 0
                          },
                          s: {
                            k: [100, 100],
                            a: 0
                          },
                          a: {
                            k: [0, 0],
                            a: 0
                          },
                          r: {
                            k: 0,
                            a: 0
                          },
                          o: {
                            k: 100,
                            a: 0
                          },
                          sk: {
                            k: 0,
                            a: 0
                          },
                          sa: {
                            k: 0,
                            a: 0
                          },
                          ty: 'tr'
                        });
                      }
                    }
                  }
                }
              };
            }();
            var checkPathProperties = function () {
              var minimumVersion = [5, 7, 15];
              function updateTextLayer(textLayer) {
                var pathData = textLayer.t.p;
                if (typeof pathData.a === 'number') {
                  pathData.a = {
                    a: 0,
                    k: pathData.a
                  };
                }
                if (typeof pathData.p === 'number') {
                  pathData.p = {
                    a: 0,
                    k: pathData.p
                  };
                }
                if (typeof pathData.r === 'number') {
                  pathData.r = {
                    a: 0,
                    k: pathData.r
                  };
                }
              }
              function iterateLayers(layers) {
                var i;
                var len = layers.length;
                for (i = 0; i < len; i += 1) {
                  if (layers[i].ty === 5) {
                    updateTextLayer(layers[i]);
                  }
                }
              }
              return function (animationData) {
                if (checkVersion(minimumVersion, animationData.v)) {
                  iterateLayers(animationData.layers);
                  if (animationData.assets) {
                    var i;
                    var len = animationData.assets.length;
                    for (i = 0; i < len; i += 1) {
                      if (animationData.assets[i].layers) {
                        iterateLayers(animationData.assets[i].layers);
                      }
                    }
                  }
                }
              };
            }();
            var checkColors = function () {
              var minimumVersion = [4, 1, 9];
              function iterateShapes(shapes) {
                var i;
                var len = shapes.length;
                var j;
                var jLen;
                for (i = 0; i < len; i += 1) {
                  if (shapes[i].ty === 'gr') {
                    iterateShapes(shapes[i].it);
                  } else if (shapes[i].ty === 'fl' || shapes[i].ty === 'st') {
                    if (shapes[i].c.k && shapes[i].c.k[0].i) {
                      jLen = shapes[i].c.k.length;
                      for (j = 0; j < jLen; j += 1) {
                        if (shapes[i].c.k[j].s) {
                          shapes[i].c.k[j].s[0] /= 255;
                          shapes[i].c.k[j].s[1] /= 255;
                          shapes[i].c.k[j].s[2] /= 255;
                          shapes[i].c.k[j].s[3] /= 255;
                        }
                        if (shapes[i].c.k[j].e) {
                          shapes[i].c.k[j].e[0] /= 255;
                          shapes[i].c.k[j].e[1] /= 255;
                          shapes[i].c.k[j].e[2] /= 255;
                          shapes[i].c.k[j].e[3] /= 255;
                        }
                      }
                    } else {
                      shapes[i].c.k[0] /= 255;
                      shapes[i].c.k[1] /= 255;
                      shapes[i].c.k[2] /= 255;
                      shapes[i].c.k[3] /= 255;
                    }
                  }
                }
              }
              function iterateLayers(layers) {
                var i;
                var len = layers.length;
                for (i = 0; i < len; i += 1) {
                  if (layers[i].ty === 4) {
                    iterateShapes(layers[i].shapes);
                  }
                }
              }
              return function (animationData) {
                if (checkVersion(minimumVersion, animationData.v)) {
                  iterateLayers(animationData.layers);
                  if (animationData.assets) {
                    var i;
                    var len = animationData.assets.length;
                    for (i = 0; i < len; i += 1) {
                      if (animationData.assets[i].layers) {
                        iterateLayers(animationData.assets[i].layers);
                      }
                    }
                  }
                }
              };
            }();
            var checkShapes = function () {
              var minimumVersion = [4, 4, 18];
              function completeClosingShapes(arr) {
                var i;
                var len = arr.length;
                var j;
                var jLen;
                for (i = len - 1; i >= 0; i -= 1) {
                  if (arr[i].ty === 'sh') {
                    if (arr[i].ks.k.i) {
                      arr[i].ks.k.c = arr[i].closed;
                    } else {
                      jLen = arr[i].ks.k.length;
                      for (j = 0; j < jLen; j += 1) {
                        if (arr[i].ks.k[j].s) {
                          arr[i].ks.k[j].s[0].c = arr[i].closed;
                        }
                        if (arr[i].ks.k[j].e) {
                          arr[i].ks.k[j].e[0].c = arr[i].closed;
                        }
                      }
                    }
                  } else if (arr[i].ty === 'gr') {
                    completeClosingShapes(arr[i].it);
                  }
                }
              }
              function iterateLayers(layers) {
                var layerData;
                var i;
                var len = layers.length;
                var j;
                var jLen;
                var k;
                var kLen;
                for (i = 0; i < len; i += 1) {
                  layerData = layers[i];
                  if (layerData.hasMask) {
                    var maskProps = layerData.masksProperties;
                    jLen = maskProps.length;
                    for (j = 0; j < jLen; j += 1) {
                      if (maskProps[j].pt.k.i) {
                        maskProps[j].pt.k.c = maskProps[j].cl;
                      } else {
                        kLen = maskProps[j].pt.k.length;
                        for (k = 0; k < kLen; k += 1) {
                          if (maskProps[j].pt.k[k].s) {
                            maskProps[j].pt.k[k].s[0].c = maskProps[j].cl;
                          }
                          if (maskProps[j].pt.k[k].e) {
                            maskProps[j].pt.k[k].e[0].c = maskProps[j].cl;
                          }
                        }
                      }
                    }
                  }
                  if (layerData.ty === 4) {
                    completeClosingShapes(layerData.shapes);
                  }
                }
              }
              return function (animationData) {
                if (checkVersion(minimumVersion, animationData.v)) {
                  iterateLayers(animationData.layers);
                  if (animationData.assets) {
                    var i;
                    var len = animationData.assets.length;
                    for (i = 0; i < len; i += 1) {
                      if (animationData.assets[i].layers) {
                        iterateLayers(animationData.assets[i].layers);
                      }
                    }
                  }
                }
              };
            }();
            function completeData(animationData) {
              if (animationData.__complete) {
                return;
              }
              checkColors(animationData);
              checkText(animationData);
              checkChars(animationData);
              checkPathProperties(animationData);
              checkShapes(animationData);
              completeLayers(animationData.layers, animationData.assets);
              completeChars(animationData.chars, animationData.assets);
              animationData.__complete = true;
            }
            function completeText(data) {
              if (data.t.a.length === 0 && !('m' in data.t.p)) {
                // data.singleShape = true;
              }
            }
            var moduleOb = {};
            moduleOb.completeData = completeData;
            moduleOb.checkColors = checkColors;
            moduleOb.checkChars = checkChars;
            moduleOb.checkPathProperties = checkPathProperties;
            moduleOb.checkShapes = checkShapes;
            moduleOb.completeLayers = completeLayers;
            return moduleOb;
          }
          if (!_workerSelf.dataManager) {
            _workerSelf.dataManager = dataFunctionManager();
          }
          if (!_workerSelf.assetLoader) {
            _workerSelf.assetLoader = function () {
              function formatResponse(xhr) {
                // using typeof doubles the time of execution of this method,
                // so if available, it's better to use the header to validate the type
                var contentTypeHeader = xhr.getResponseHeader('content-type');
                if (contentTypeHeader && xhr.responseType === 'json' && contentTypeHeader.indexOf('json') !== -1) {
                  return xhr.response;
                }
                if (xhr.response && _typeof$5(xhr.response) === 'object') {
                  return xhr.response;
                }
                if (xhr.response && typeof xhr.response === 'string') {
                  return JSON.parse(xhr.response);
                }
                if (xhr.responseText) {
                  return JSON.parse(xhr.responseText);
                }
                return null;
              }
              function loadAsset(path, fullPath, callback, errorCallback) {
                var response;
                var xhr = new XMLHttpRequest();
                // set responseType after calling open or IE will break.
                try {
                  // This crashes on Android WebView prior to KitKat
                  xhr.responseType = 'json';
                } catch (err) {} // eslint-disable-line no-empty
                xhr.onreadystatechange = function () {
                  if (xhr.readyState === 4) {
                    if (xhr.status === 200) {
                      response = formatResponse(xhr);
                      callback(response);
                    } else {
                      try {
                        response = formatResponse(xhr);
                        callback(response);
                      } catch (err) {
                        if (errorCallback) {
                          errorCallback(err);
                        }
                      }
                    }
                  }
                };
                try {
                  // Hack to workaround banner validation
                  xhr.open(['G', 'E', 'T'].join(''), path, true);
                } catch (error) {
                  // Hack to workaround banner validation
                  xhr.open(['G', 'E', 'T'].join(''), fullPath + '/' + path, true);
                }
                xhr.send();
              }
              return {
                load: loadAsset
              };
            }();
          }
          if (e.data.type === 'loadAnimation') {
            _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
              _workerSelf.dataManager.completeData(data);
              _workerSelf.postMessage({
                id: e.data.id,
                payload: data,
                status: 'success'
              });
            }, function () {
              _workerSelf.postMessage({
                id: e.data.id,
                status: 'error'
              });
            });
          } else if (e.data.type === 'complete') {
            var animation = e.data.animation;
            _workerSelf.dataManager.completeData(animation);
            _workerSelf.postMessage({
              id: e.data.id,
              payload: animation,
              status: 'success'
            });
          } else if (e.data.type === 'loadData') {
            _workerSelf.assetLoader.load(e.data.path, e.data.fullPath, function (data) {
              _workerSelf.postMessage({
                id: e.data.id,
                payload: data,
                status: 'success'
              });
            }, function () {
              _workerSelf.postMessage({
                id: e.data.id,
                status: 'error'
              });
            });
          }
        });
        workerInstance.onmessage = function (event) {
          var data = event.data;
          var id = data.id;
          var process = processes[id];
          processes[id] = null;
          if (data.status === 'success') {
            process.onComplete(data.payload);
          } else if (process.onError) {
            process.onError();
          }
        };
      }
    }
    function createProcess(onComplete, onError) {
      _counterId += 1;
      var id = 'processId_' + _counterId;
      processes[id] = {
        onComplete: onComplete,
        onError: onError
      };
      return id;
    }
    function loadAnimation(path, onComplete, onError) {
      setupWorker();
      var processId = createProcess(onComplete, onError);
      workerInstance.postMessage({
        type: 'loadAnimation',
        path: path,
        fullPath: window.location.origin + window.location.pathname,
        id: processId
      });
    }
    function loadData(path, onComplete, onError) {
      setupWorker();
      var processId = createProcess(onComplete, onError);
      workerInstance.postMessage({
        type: 'loadData',
        path: path,
        fullPath: window.location.origin + window.location.pathname,
        id: processId
      });
    }
    function completeAnimation(anim, onComplete, onError) {
      setupWorker();
      var processId = createProcess(onComplete, onError);
      workerInstance.postMessage({
        type: 'complete',
        animation: anim,
        id: processId
      });
    }
    return {
      loadAnimation: loadAnimation,
      loadData: loadData,
      completeAnimation: completeAnimation
    };
  }();
  var ImagePreloader = function () {
    var proxyImage = function () {
      var canvas = createTag('canvas');
      canvas.width = 1;
      canvas.height = 1;
      var ctx = canvas.getContext('2d');
      ctx.fillStyle = 'rgba(0,0,0,0)';
      ctx.fillRect(0, 0, 1, 1);
      return canvas;
    }();
    function imageLoaded() {
      this.loadedAssets += 1;
      if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
        if (this.imagesLoadedCb) {
          this.imagesLoadedCb(null);
        }
      }
    }
    function footageLoaded() {
      this.loadedFootagesCount += 1;
      if (this.loadedAssets === this.totalImages && this.loadedFootagesCount === this.totalFootages) {
        if (this.imagesLoadedCb) {
          this.imagesLoadedCb(null);
        }
      }
    }
    function getAssetsPath(assetData, assetsPath, originalPath) {
      var path = '';
      if (assetData.e) {
        path = assetData.p;
      } else if (assetsPath) {
        var imagePath = assetData.p;
        if (imagePath.indexOf('images/') !== -1) {
          imagePath = imagePath.split('/')[1];
        }
        path = assetsPath + imagePath;
      } else {
        path = originalPath;
        path += assetData.u ? assetData.u : '';
        path += assetData.p;
      }
      return path;
    }
    function testImageLoaded(img) {
      var _count = 0;
      var intervalId = setInterval(function () {
        var box = img.getBBox();
        if (box.width || _count > 500) {
          this._imageLoaded();
          clearInterval(intervalId);
        }
        _count += 1;
      }.bind(this), 50);
    }
    function createImageData(assetData) {
      var path = getAssetsPath(assetData, this.assetsPath, this.path);
      var img = createNS('image');
      if (isSafari) {
        this.testImageLoaded(img);
      } else {
        img.addEventListener('load', this._imageLoaded, false);
      }
      img.addEventListener('error', function () {
        ob.img = proxyImage;
        this._imageLoaded();
      }.bind(this), false);
      img.setAttributeNS('http://www.w3.org/1999/xlink', 'href', path);
      if (this._elementHelper.append) {
        this._elementHelper.append(img);
      } else {
        this._elementHelper.appendChild(img);
      }
      var ob = {
        img: img,
        assetData: assetData
      };
      return ob;
    }
    function createImgData(assetData) {
      var path = getAssetsPath(assetData, this.assetsPath, this.path);
      var img = createTag('img');
      img.crossOrigin = 'anonymous';
      img.addEventListener('load', this._imageLoaded, false);
      img.addEventListener('error', function () {
        ob.img = proxyImage;
        this._imageLoaded();
      }.bind(this), false);
      img.src = path;
      var ob = {
        img: img,
        assetData: assetData
      };
      return ob;
    }
    function createFootageData(data) {
      var ob = {
        assetData: data
      };
      var path = getAssetsPath(data, this.assetsPath, this.path);
      dataManager.loadData(path, function (footageData) {
        ob.img = footageData;
        this._footageLoaded();
      }.bind(this), function () {
        ob.img = {};
        this._footageLoaded();
      }.bind(this));
      return ob;
    }
    function loadAssets(assets, cb) {
      this.imagesLoadedCb = cb;
      var i;
      var len = assets.length;
      for (i = 0; i < len; i += 1) {
        if (!assets[i].layers) {
          if (!assets[i].t || assets[i].t === 'seq') {
            this.totalImages += 1;
            this.images.push(this._createImageData(assets[i]));
          } else if (assets[i].t === 3) {
            this.totalFootages += 1;
            this.images.push(this.createFootageData(assets[i]));
          }
        }
      }
    }
    function setPath(path) {
      this.path = path || '';
    }
    function setAssetsPath(path) {
      this.assetsPath = path || '';
    }
    function getAsset(assetData) {
      var i = 0;
      var len = this.images.length;
      while (i < len) {
        if (this.images[i].assetData === assetData) {
          return this.images[i].img;
        }
        i += 1;
      }
      return null;
    }
    function destroy() {
      this.imagesLoadedCb = null;
      this.images.length = 0;
    }
    function loadedImages() {
      return this.totalImages === this.loadedAssets;
    }
    function loadedFootages() {
      return this.totalFootages === this.loadedFootagesCount;
    }
    function setCacheType(type, elementHelper) {
      if (type === 'svg') {
        this._elementHelper = elementHelper;
        this._createImageData = this.createImageData.bind(this);
      } else {
        this._createImageData = this.createImgData.bind(this);
      }
    }
    function ImagePreloaderFactory() {
      this._imageLoaded = imageLoaded.bind(this);
      this._footageLoaded = footageLoaded.bind(this);
      this.testImageLoaded = testImageLoaded.bind(this);
      this.createFootageData = createFootageData.bind(this);
      this.assetsPath = '';
      this.path = '';
      this.totalImages = 0;
      this.totalFootages = 0;
      this.loadedAssets = 0;
      this.loadedFootagesCount = 0;
      this.imagesLoadedCb = null;
      this.images = [];
    }
    ImagePreloaderFactory.prototype = {
      loadAssets: loadAssets,
      setAssetsPath: setAssetsPath,
      setPath: setPath,
      loadedImages: loadedImages,
      loadedFootages: loadedFootages,
      destroy: destroy,
      getAsset: getAsset,
      createImgData: createImgData,
      createImageData: createImageData,
      imageLoaded: imageLoaded,
      footageLoaded: footageLoaded,
      setCacheType: setCacheType
    };
    return ImagePreloaderFactory;
  }();
  function BaseEvent() {}
  BaseEvent.prototype = {
    triggerEvent: function triggerEvent(eventName, args) {
      if (this._cbs[eventName]) {
        var callbacks = this._cbs[eventName];
        for (var i = 0; i < callbacks.length; i += 1) {
          callbacks[i](args);
        }
      }
    },
    addEventListener: function addEventListener(eventName, callback) {
      if (!this._cbs[eventName]) {
        this._cbs[eventName] = [];
      }
      this._cbs[eventName].push(callback);
      return function () {
        this.removeEventListener(eventName, callback);
      }.bind(this);
    },
    removeEventListener: function removeEventListener(eventName, callback) {
      if (!callback) {
        this._cbs[eventName] = null;
      } else if (this._cbs[eventName]) {
        var i = 0;
        var len = this._cbs[eventName].length;
        while (i < len) {
          if (this._cbs[eventName][i] === callback) {
            this._cbs[eventName].splice(i, 1);
            i -= 1;
            len -= 1;
          }
          i += 1;
        }
        if (!this._cbs[eventName].length) {
          this._cbs[eventName] = null;
        }
      }
    }
  };
  var markerParser = function () {
    function parsePayloadLines(payload) {
      var lines = payload.split('\r\n');
      var keys = {};
      var line;
      var keysCount = 0;
      for (var i = 0; i < lines.length; i += 1) {
        line = lines[i].split(':');
        if (line.length === 2) {
          keys[line[0]] = line[1].trim();
          keysCount += 1;
        }
      }
      if (keysCount === 0) {
        throw new Error();
      }
      return keys;
    }
    return function (_markers) {
      var markers = [];
      for (var i = 0; i < _markers.length; i += 1) {
        var _marker = _markers[i];
        var markerData = {
          time: _marker.tm,
          duration: _marker.dr
        };
        try {
          markerData.payload = JSON.parse(_markers[i].cm);
        } catch (_) {
          try {
            markerData.payload = parsePayloadLines(_markers[i].cm);
          } catch (__) {
            markerData.payload = {
              name: _markers[i].cm
            };
          }
        }
        markers.push(markerData);
      }
      return markers;
    };
  }();
  var ProjectInterface = function () {
    function registerComposition(comp) {
      this.compositions.push(comp);
    }
    return function () {
      function _thisProjectFunction(name) {
        var i = 0;
        var len = this.compositions.length;
        while (i < len) {
          if (this.compositions[i].data && this.compositions[i].data.nm === name) {
            if (this.compositions[i].prepareFrame && this.compositions[i].data.xt) {
              this.compositions[i].prepareFrame(this.currentFrame);
            }
            return this.compositions[i].compInterface;
          }
          i += 1;
        }
        return null;
      }
      _thisProjectFunction.compositions = [];
      _thisProjectFunction.currentFrame = 0;
      _thisProjectFunction.registerComposition = registerComposition;
      return _thisProjectFunction;
    };
  }();
  var renderers = {};
  var registerRenderer = function registerRenderer(key, value) {
    renderers[key] = value;
  };
  function getRenderer(key) {
    return renderers[key];
  }
  function getRegisteredRenderer() {
    // Returns canvas by default for compatibility
    if (renderers.canvas) {
      return 'canvas';
    }
    // Returns any renderer that is registered
    for (var key in renderers) {
      if (renderers[key]) {
        return key;
      }
    }
    return '';
  }
  function _typeof$4(o) {
    "@babel/helpers - typeof";

    return _typeof$4 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$4(o);
  }
  var AnimationItem = function AnimationItem() {
    this._cbs = [];
    this.name = '';
    this.path = '';
    this.isLoaded = false;
    this.currentFrame = 0;
    this.currentRawFrame = 0;
    this.firstFrame = 0;
    this.totalFrames = 0;
    this.frameRate = 0;
    this.frameMult = 0;
    this.playSpeed = 1;
    this.playDirection = 1;
    this.playCount = 0;
    this.animationData = {};
    this.assets = [];
    this.isPaused = true;
    this.autoplay = false;
    this.loop = true;
    this.renderer = null;
    this.animationID = createElementID();
    this.assetsPath = '';
    this.timeCompleted = 0;
    this.segmentPos = 0;
    this.isSubframeEnabled = getSubframeEnabled();
    this.segments = [];
    this._idle = true;
    this._completedLoop = false;
    this.projectInterface = ProjectInterface();
    this.imagePreloader = new ImagePreloader();
    this.audioController = audioControllerFactory();
    this.markers = [];
    this.configAnimation = this.configAnimation.bind(this);
    this.onSetupError = this.onSetupError.bind(this);
    this.onSegmentComplete = this.onSegmentComplete.bind(this);
    this.drawnFrameEvent = new BMEnterFrameEvent('drawnFrame', 0, 0, 0);
    this.expressionsPlugin = getExpressionsPlugin();
  };
  extendPrototype([BaseEvent], AnimationItem);
  AnimationItem.prototype.setParams = function (params) {
    if (params.wrapper || params.container) {
      this.wrapper = params.wrapper || params.container;
    }
    var animType = 'svg';
    if (params.animType) {
      animType = params.animType;
    } else if (params.renderer) {
      animType = params.renderer;
    }
    var RendererClass = getRenderer(animType);
    this.renderer = new RendererClass(this, params.rendererSettings);
    this.imagePreloader.setCacheType(animType, this.renderer.globalData.defs);
    this.renderer.setProjectInterface(this.projectInterface);
    this.animType = animType;
    if (params.loop === '' || params.loop === null || params.loop === undefined || params.loop === true) {
      this.loop = true;
    } else if (params.loop === false) {
      this.loop = false;
    } else {
      this.loop = parseInt(params.loop, 10);
    }
    this.autoplay = 'autoplay' in params ? params.autoplay : true;
    this.name = params.name ? params.name : '';
    this.autoloadSegments = Object.prototype.hasOwnProperty.call(params, 'autoloadSegments') ? params.autoloadSegments : true;
    this.assetsPath = params.assetsPath;
    this.initialSegment = params.initialSegment;
    if (params.audioFactory) {
      this.audioController.setAudioFactory(params.audioFactory);
    }
    if (params.animationData) {
      this.setupAnimation(params.animationData);
    } else if (params.path) {
      if (params.path.lastIndexOf('\\') !== -1) {
        this.path = params.path.substr(0, params.path.lastIndexOf('\\') + 1);
      } else {
        this.path = params.path.substr(0, params.path.lastIndexOf('/') + 1);
      }
      this.fileName = params.path.substr(params.path.lastIndexOf('/') + 1);
      this.fileName = this.fileName.substr(0, this.fileName.lastIndexOf('.json'));
      dataManager.loadAnimation(params.path, this.configAnimation, this.onSetupError);
    }
  };
  AnimationItem.prototype.onSetupError = function () {
    this.trigger('data_failed');
  };
  AnimationItem.prototype.setupAnimation = function (data) {
    dataManager.completeAnimation(data, this.configAnimation);
  };
  AnimationItem.prototype.setData = function (wrapper, animationData) {
    if (animationData) {
      if (_typeof$4(animationData) !== 'object') {
        animationData = JSON.parse(animationData);
      }
    }
    var params = {
      wrapper: wrapper,
      animationData: animationData
    };
    var wrapperAttributes = wrapper.attributes;
    params.path = wrapperAttributes.getNamedItem('data-animation-path') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-animation-path').value : wrapperAttributes.getNamedItem('data-bm-path') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-path').value : wrapperAttributes.getNamedItem('bm-path') ? wrapperAttributes.getNamedItem('bm-path').value : '';
    params.animType = wrapperAttributes.getNamedItem('data-anim-type') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-anim-type').value : wrapperAttributes.getNamedItem('data-bm-type') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-type').value : wrapperAttributes.getNamedItem('bm-type') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('bm-type').value : wrapperAttributes.getNamedItem('data-bm-renderer') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-renderer').value : wrapperAttributes.getNamedItem('bm-renderer') ? wrapperAttributes.getNamedItem('bm-renderer').value : getRegisteredRenderer() || 'canvas';
    var loop = wrapperAttributes.getNamedItem('data-anim-loop') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-anim-loop').value : wrapperAttributes.getNamedItem('data-bm-loop') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-loop').value : wrapperAttributes.getNamedItem('bm-loop') ? wrapperAttributes.getNamedItem('bm-loop').value : '';
    if (loop === 'false') {
      params.loop = false;
    } else if (loop === 'true') {
      params.loop = true;
    } else if (loop !== '') {
      params.loop = parseInt(loop, 10);
    }
    var autoplay = wrapperAttributes.getNamedItem('data-anim-autoplay') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-anim-autoplay').value : wrapperAttributes.getNamedItem('data-bm-autoplay') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-autoplay').value : wrapperAttributes.getNamedItem('bm-autoplay') ? wrapperAttributes.getNamedItem('bm-autoplay').value : true;
    params.autoplay = autoplay !== 'false';
    params.name = wrapperAttributes.getNamedItem('data-name') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-name').value : wrapperAttributes.getNamedItem('data-bm-name') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-name').value : wrapperAttributes.getNamedItem('bm-name') ? wrapperAttributes.getNamedItem('bm-name').value : '';
    var prerender = wrapperAttributes.getNamedItem('data-anim-prerender') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-anim-prerender').value : wrapperAttributes.getNamedItem('data-bm-prerender') // eslint-disable-line no-nested-ternary
    ? wrapperAttributes.getNamedItem('data-bm-prerender').value : wrapperAttributes.getNamedItem('bm-prerender') ? wrapperAttributes.getNamedItem('bm-prerender').value : '';
    if (prerender === 'false') {
      params.prerender = false;
    }
    if (!params.path) {
      this.trigger('destroy');
    } else {
      this.setParams(params);
    }
  };
  AnimationItem.prototype.includeLayers = function (data) {
    if (data.op > this.animationData.op) {
      this.animationData.op = data.op;
      this.totalFrames = Math.floor(data.op - this.animationData.ip);
    }
    var layers = this.animationData.layers;
    var i;
    var len = layers.length;
    var newLayers = data.layers;
    var j;
    var jLen = newLayers.length;
    for (j = 0; j < jLen; j += 1) {
      i = 0;
      while (i < len) {
        if (layers[i].id === newLayers[j].id) {
          layers[i] = newLayers[j];
          break;
        }
        i += 1;
      }
    }
    if (data.chars || data.fonts) {
      this.renderer.globalData.fontManager.addChars(data.chars);
      this.renderer.globalData.fontManager.addFonts(data.fonts, this.renderer.globalData.defs);
    }
    if (data.assets) {
      len = data.assets.length;
      for (i = 0; i < len; i += 1) {
        this.animationData.assets.push(data.assets[i]);
      }
    }
    this.animationData.__complete = false;
    dataManager.completeAnimation(this.animationData, this.onSegmentComplete);
  };
  AnimationItem.prototype.onSegmentComplete = function (data) {
    this.animationData = data;
    var expressionsPlugin = getExpressionsPlugin();
    if (expressionsPlugin) {
      expressionsPlugin.initExpressions(this);
    }
    this.loadNextSegment();
  };
  AnimationItem.prototype.loadNextSegment = function () {
    var segments = this.animationData.segments;
    if (!segments || segments.length === 0 || !this.autoloadSegments) {
      this.trigger('data_ready');
      this.timeCompleted = this.totalFrames;
      return;
    }
    var segment = segments.shift();
    this.timeCompleted = segment.time * this.frameRate;
    var segmentPath = this.path + this.fileName + '_' + this.segmentPos + '.json';
    this.segmentPos += 1;
    dataManager.loadData(segmentPath, this.includeLayers.bind(this), function () {
      this.trigger('data_failed');
    }.bind(this));
  };
  AnimationItem.prototype.loadSegments = function () {
    var segments = this.animationData.segments;
    if (!segments) {
      this.timeCompleted = this.totalFrames;
    }
    this.loadNextSegment();
  };
  AnimationItem.prototype.imagesLoaded = function () {
    this.trigger('loaded_images');
    this.checkLoaded();
  };
  AnimationItem.prototype.preloadImages = function () {
    this.imagePreloader.setAssetsPath(this.assetsPath);
    this.imagePreloader.setPath(this.path);
    this.imagePreloader.loadAssets(this.animationData.assets, this.imagesLoaded.bind(this));
  };
  AnimationItem.prototype.configAnimation = function (animData) {
    if (!this.renderer) {
      return;
    }
    try {
      this.animationData = animData;
      if (this.initialSegment) {
        this.totalFrames = Math.floor(this.initialSegment[1] - this.initialSegment[0]);
        this.firstFrame = Math.round(this.initialSegment[0]);
      } else {
        this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
        this.firstFrame = Math.round(this.animationData.ip);
      }
      this.renderer.configAnimation(animData);
      if (!animData.assets) {
        animData.assets = [];
      }
      this.assets = this.animationData.assets;
      this.frameRate = this.animationData.fr;
      this.frameMult = this.animationData.fr / 1000;
      this.renderer.searchExtraCompositions(animData.assets);
      this.markers = markerParser(animData.markers || []);
      this.trigger('config_ready');
      this.preloadImages();
      this.loadSegments();
      this.updaFrameModifier();
      this.waitForFontsLoaded();
      if (this.isPaused) {
        this.audioController.pause();
      }
    } catch (error) {
      this.triggerConfigError(error);
    }
  };
  AnimationItem.prototype.waitForFontsLoaded = function () {
    if (!this.renderer) {
      return;
    }
    if (this.renderer.globalData.fontManager.isLoaded) {
      this.checkLoaded();
    } else {
      setTimeout(this.waitForFontsLoaded.bind(this), 20);
    }
  };
  AnimationItem.prototype.checkLoaded = function () {
    if (!this.isLoaded && this.renderer.globalData.fontManager.isLoaded && (this.imagePreloader.loadedImages() || this.renderer.rendererType !== 'canvas') && this.imagePreloader.loadedFootages()) {
      this.isLoaded = true;
      var expressionsPlugin = getExpressionsPlugin();
      if (expressionsPlugin) {
        expressionsPlugin.initExpressions(this);
      }
      this.renderer.initItems();
      setTimeout(function () {
        this.trigger('DOMLoaded');
      }.bind(this), 0);
      this.gotoFrame();
      if (this.autoplay) {
        this.play();
      }
    }
  };
  AnimationItem.prototype.resize = function (width, height) {
    // Adding this validation for backwards compatibility in case an event object was being passed down
    var _width = typeof width === 'number' ? width : undefined;
    var _height = typeof height === 'number' ? height : undefined;
    this.renderer.updateContainerSize(_width, _height);
  };
  AnimationItem.prototype.setSubframe = function (flag) {
    this.isSubframeEnabled = !!flag;
  };
  AnimationItem.prototype.gotoFrame = function () {
    this.currentFrame = this.isSubframeEnabled ? this.currentRawFrame : ~~this.currentRawFrame; // eslint-disable-line no-bitwise

    if (this.timeCompleted !== this.totalFrames && this.currentFrame > this.timeCompleted) {
      this.currentFrame = this.timeCompleted;
    }
    this.trigger('enterFrame');
    this.renderFrame();
    this.trigger('drawnFrame');
  };
  AnimationItem.prototype.renderFrame = function () {
    if (this.isLoaded === false || !this.renderer) {
      return;
    }
    try {
      if (this.expressionsPlugin) {
        this.expressionsPlugin.resetFrame();
      }
      this.renderer.renderFrame(this.currentFrame + this.firstFrame);
    } catch (error) {
      this.triggerRenderFrameError(error);
    }
  };
  AnimationItem.prototype.play = function (name) {
    if (name && this.name !== name) {
      return;
    }
    if (this.isPaused === true) {
      this.isPaused = false;
      this.trigger('_play');
      this.audioController.resume();
      if (this._idle) {
        this._idle = false;
        this.trigger('_active');
      }
    }
  };
  AnimationItem.prototype.pause = function (name) {
    if (name && this.name !== name) {
      return;
    }
    if (this.isPaused === false) {
      this.isPaused = true;
      this.trigger('_pause');
      this._idle = true;
      this.trigger('_idle');
      this.audioController.pause();
    }
  };
  AnimationItem.prototype.togglePause = function (name) {
    if (name && this.name !== name) {
      return;
    }
    if (this.isPaused === true) {
      this.play();
    } else {
      this.pause();
    }
  };
  AnimationItem.prototype.stop = function (name) {
    if (name && this.name !== name) {
      return;
    }
    this.pause();
    this.playCount = 0;
    this._completedLoop = false;
    this.setCurrentRawFrameValue(0);
  };
  AnimationItem.prototype.getMarkerData = function (markerName) {
    var marker;
    for (var i = 0; i < this.markers.length; i += 1) {
      marker = this.markers[i];
      if (marker.payload && marker.payload.name === markerName) {
        return marker;
      }
    }
    return null;
  };
  AnimationItem.prototype.goToAndStop = function (value, isFrame, name) {
    if (name && this.name !== name) {
      return;
    }
    var numValue = Number(value);
    if (isNaN(numValue)) {
      var marker = this.getMarkerData(value);
      if (marker) {
        this.goToAndStop(marker.time, true);
      }
    } else if (isFrame) {
      this.setCurrentRawFrameValue(value);
    } else {
      this.setCurrentRawFrameValue(value * this.frameModifier);
    }
    this.pause();
  };
  AnimationItem.prototype.goToAndPlay = function (value, isFrame, name) {
    if (name && this.name !== name) {
      return;
    }
    var numValue = Number(value);
    if (isNaN(numValue)) {
      var marker = this.getMarkerData(value);
      if (marker) {
        if (!marker.duration) {
          this.goToAndStop(marker.time, true);
        } else {
          this.playSegments([marker.time, marker.time + marker.duration], true);
        }
      }
    } else {
      this.goToAndStop(numValue, isFrame, name);
    }
    this.play();
  };
  AnimationItem.prototype.advanceTime = function (value) {
    if (this.isPaused === true || this.isLoaded === false) {
      return;
    }
    var nextValue = this.currentRawFrame + value * this.frameModifier;
    var _isComplete = false;
    // Checking if nextValue > totalFrames - 1 for addressing non looping and looping animations.
    // If animation won't loop, it should stop at totalFrames - 1. If it will loop it should complete the last frame and then loop.
    if (nextValue >= this.totalFrames - 1 && this.frameModifier > 0) {
      if (!this.loop || this.playCount === this.loop) {
        if (!this.checkSegments(nextValue > this.totalFrames ? nextValue % this.totalFrames : 0)) {
          _isComplete = true;
          nextValue = this.totalFrames - 1;
        }
      } else if (nextValue >= this.totalFrames) {
        this.playCount += 1;
        if (!this.checkSegments(nextValue % this.totalFrames)) {
          this.setCurrentRawFrameValue(nextValue % this.totalFrames);
          this._completedLoop = true;
          this.trigger('loopComplete');
        }
      } else {
        this.setCurrentRawFrameValue(nextValue);
      }
    } else if (nextValue < 0) {
      if (!this.checkSegments(nextValue % this.totalFrames)) {
        if (this.loop && !(this.playCount-- <= 0 && this.loop !== true)) {
          // eslint-disable-line no-plusplus
          this.setCurrentRawFrameValue(this.totalFrames + nextValue % this.totalFrames);
          if (!this._completedLoop) {
            this._completedLoop = true;
          } else {
            this.trigger('loopComplete');
          }
        } else {
          _isComplete = true;
          nextValue = 0;
        }
      }
    } else {
      this.setCurrentRawFrameValue(nextValue);
    }
    if (_isComplete) {
      this.setCurrentRawFrameValue(nextValue);
      this.pause();
      this.trigger('complete');
    }
  };
  AnimationItem.prototype.adjustSegment = function (arr, offset) {
    this.playCount = 0;
    if (arr[1] < arr[0]) {
      if (this.frameModifier > 0) {
        if (this.playSpeed < 0) {
          this.setSpeed(-this.playSpeed);
        } else {
          this.setDirection(-1);
        }
      }
      this.totalFrames = arr[0] - arr[1];
      this.timeCompleted = this.totalFrames;
      this.firstFrame = arr[1];
      this.setCurrentRawFrameValue(this.totalFrames - 0.001 - offset);
    } else if (arr[1] > arr[0]) {
      if (this.frameModifier < 0) {
        if (this.playSpeed < 0) {
          this.setSpeed(-this.playSpeed);
        } else {
          this.setDirection(1);
        }
      }
      this.totalFrames = arr[1] - arr[0];
      this.timeCompleted = this.totalFrames;
      this.firstFrame = arr[0];
      this.setCurrentRawFrameValue(0.001 + offset);
    }
    this.trigger('segmentStart');
  };
  AnimationItem.prototype.setSegment = function (init, end) {
    var pendingFrame = -1;
    if (this.isPaused) {
      if (this.currentRawFrame + this.firstFrame < init) {
        pendingFrame = init;
      } else if (this.currentRawFrame + this.firstFrame > end) {
        pendingFrame = end - init;
      }
    }
    this.firstFrame = init;
    this.totalFrames = end - init;
    this.timeCompleted = this.totalFrames;
    if (pendingFrame !== -1) {
      this.goToAndStop(pendingFrame, true);
    }
  };
  AnimationItem.prototype.playSegments = function (arr, forceFlag) {
    if (forceFlag) {
      this.segments.length = 0;
    }
    if (_typeof$4(arr[0]) === 'object') {
      var i;
      var len = arr.length;
      for (i = 0; i < len; i += 1) {
        this.segments.push(arr[i]);
      }
    } else {
      this.segments.push(arr);
    }
    if (this.segments.length && forceFlag) {
      this.adjustSegment(this.segments.shift(), 0);
    }
    if (this.isPaused) {
      this.play();
    }
  };
  AnimationItem.prototype.resetSegments = function (forceFlag) {
    this.segments.length = 0;
    this.segments.push([this.animationData.ip, this.animationData.op]);
    if (forceFlag) {
      this.checkSegments(0);
    }
  };
  AnimationItem.prototype.checkSegments = function (offset) {
    if (this.segments.length) {
      this.adjustSegment(this.segments.shift(), offset);
      return true;
    }
    return false;
  };
  AnimationItem.prototype.destroy = function (name) {
    if (name && this.name !== name || !this.renderer) {
      return;
    }
    this.renderer.destroy();
    this.imagePreloader.destroy();
    this.trigger('destroy');
    this._cbs = null;
    this.onEnterFrame = null;
    this.onLoopComplete = null;
    this.onComplete = null;
    this.onSegmentStart = null;
    this.onDestroy = null;
    this.renderer = null;
    this.expressionsPlugin = null;
    this.imagePreloader = null;
    this.projectInterface = null;
  };
  AnimationItem.prototype.setCurrentRawFrameValue = function (value) {
    this.currentRawFrame = value;
    this.gotoFrame();
  };
  AnimationItem.prototype.setSpeed = function (val) {
    this.playSpeed = val;
    this.updaFrameModifier();
  };
  AnimationItem.prototype.setDirection = function (val) {
    this.playDirection = val < 0 ? -1 : 1;
    this.updaFrameModifier();
  };
  AnimationItem.prototype.setLoop = function (isLooping) {
    this.loop = isLooping;
  };
  AnimationItem.prototype.setVolume = function (val, name) {
    if (name && this.name !== name) {
      return;
    }
    this.audioController.setVolume(val);
  };
  AnimationItem.prototype.getVolume = function () {
    return this.audioController.getVolume();
  };
  AnimationItem.prototype.mute = function (name) {
    if (name && this.name !== name) {
      return;
    }
    this.audioController.mute();
  };
  AnimationItem.prototype.unmute = function (name) {
    if (name && this.name !== name) {
      return;
    }
    this.audioController.unmute();
  };
  AnimationItem.prototype.updaFrameModifier = function () {
    this.frameModifier = this.frameMult * this.playSpeed * this.playDirection;
    this.audioController.setRate(this.playSpeed * this.playDirection);
  };
  AnimationItem.prototype.getPath = function () {
    return this.path;
  };
  AnimationItem.prototype.getAssetsPath = function (assetData) {
    var path = '';
    if (assetData.e) {
      path = assetData.p;
    } else if (this.assetsPath) {
      var imagePath = assetData.p;
      if (imagePath.indexOf('images/') !== -1) {
        imagePath = imagePath.split('/')[1];
      }
      path = this.assetsPath + imagePath;
    } else {
      path = this.path;
      path += assetData.u ? assetData.u : '';
      path += assetData.p;
    }
    return path;
  };
  AnimationItem.prototype.getAssetData = function (id) {
    var i = 0;
    var len = this.assets.length;
    while (i < len) {
      if (id === this.assets[i].id) {
        return this.assets[i];
      }
      i += 1;
    }
    return null;
  };
  AnimationItem.prototype.hide = function () {
    this.renderer.hide();
  };
  AnimationItem.prototype.show = function () {
    this.renderer.show();
  };
  AnimationItem.prototype.getDuration = function (isFrame) {
    return isFrame ? this.totalFrames : this.totalFrames / this.frameRate;
  };
  AnimationItem.prototype.updateDocumentData = function (path, documentData, index) {
    try {
      var element = this.renderer.getElementByPath(path);
      element.updateDocumentData(documentData, index);
    } catch (error) {
      // TODO: decide how to handle catch case
    }
  };
  AnimationItem.prototype.trigger = function (name) {
    if (this._cbs && this._cbs[name]) {
      switch (name) {
        case 'enterFrame':
          this.triggerEvent(name, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameModifier));
          break;
        case 'drawnFrame':
          this.drawnFrameEvent.currentTime = this.currentFrame;
          this.drawnFrameEvent.totalTime = this.totalFrames;
          this.drawnFrameEvent.direction = this.frameModifier;
          this.triggerEvent(name, this.drawnFrameEvent);
          break;
        case 'loopComplete':
          this.triggerEvent(name, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
          break;
        case 'complete':
          this.triggerEvent(name, new BMCompleteEvent(name, this.frameMult));
          break;
        case 'segmentStart':
          this.triggerEvent(name, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
          break;
        case 'destroy':
          this.triggerEvent(name, new BMDestroyEvent(name, this));
          break;
        default:
          this.triggerEvent(name);
      }
    }
    if (name === 'enterFrame' && this.onEnterFrame) {
      this.onEnterFrame.call(this, new BMEnterFrameEvent(name, this.currentFrame, this.totalFrames, this.frameMult));
    }
    if (name === 'loopComplete' && this.onLoopComplete) {
      this.onLoopComplete.call(this, new BMCompleteLoopEvent(name, this.loop, this.playCount, this.frameMult));
    }
    if (name === 'complete' && this.onComplete) {
      this.onComplete.call(this, new BMCompleteEvent(name, this.frameMult));
    }
    if (name === 'segmentStart' && this.onSegmentStart) {
      this.onSegmentStart.call(this, new BMSegmentStartEvent(name, this.firstFrame, this.totalFrames));
    }
    if (name === 'destroy' && this.onDestroy) {
      this.onDestroy.call(this, new BMDestroyEvent(name, this));
    }
  };
  AnimationItem.prototype.triggerRenderFrameError = function (nativeError) {
    var error = new BMRenderFrameErrorEvent(nativeError, this.currentFrame);
    this.triggerEvent('error', error);
    if (this.onError) {
      this.onError.call(this, error);
    }
  };
  AnimationItem.prototype.triggerConfigError = function (nativeError) {
    var error = new BMConfigErrorEvent(nativeError, this.currentFrame);
    this.triggerEvent('error', error);
    if (this.onError) {
      this.onError.call(this, error);
    }
  };
  var animationManager = function () {
    var moduleOb = {};
    var registeredAnimations = [];
    var initTime = 0;
    var len = 0;
    var playingAnimationsNum = 0;
    var _stopped = true;
    var _isFrozen = false;
    function removeElement(ev) {
      var i = 0;
      var animItem = ev.target;
      while (i < len) {
        if (registeredAnimations[i].animation === animItem) {
          registeredAnimations.splice(i, 1);
          i -= 1;
          len -= 1;
          if (!animItem.isPaused) {
            subtractPlayingCount();
          }
        }
        i += 1;
      }
    }
    function registerAnimation(element, animationData) {
      if (!element) {
        return null;
      }
      var i = 0;
      while (i < len) {
        if (registeredAnimations[i].elem === element && registeredAnimations[i].elem !== null) {
          return registeredAnimations[i].animation;
        }
        i += 1;
      }
      var animItem = new AnimationItem();
      setupAnimation(animItem, element);
      animItem.setData(element, animationData);
      return animItem;
    }
    function getRegisteredAnimations() {
      var i;
      var lenAnims = registeredAnimations.length;
      var animations = [];
      for (i = 0; i < lenAnims; i += 1) {
        animations.push(registeredAnimations[i].animation);
      }
      return animations;
    }
    function addPlayingCount() {
      playingAnimationsNum += 1;
      activate();
    }
    function subtractPlayingCount() {
      playingAnimationsNum -= 1;
    }
    function setupAnimation(animItem, element) {
      animItem.addEventListener('destroy', removeElement);
      animItem.addEventListener('_active', addPlayingCount);
      animItem.addEventListener('_idle', subtractPlayingCount);
      registeredAnimations.push({
        elem: element,
        animation: animItem
      });
      len += 1;
    }
    function loadAnimation(params) {
      var animItem = new AnimationItem();
      setupAnimation(animItem, null);
      animItem.setParams(params);
      return animItem;
    }
    function setSpeed(val, animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.setSpeed(val, animation);
      }
    }
    function setDirection(val, animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.setDirection(val, animation);
      }
    }
    function play(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.play(animation);
      }
    }
    function resume(nowTime) {
      var elapsedTime = nowTime - initTime;
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.advanceTime(elapsedTime);
      }
      initTime = nowTime;
      if (playingAnimationsNum && !_isFrozen) {
        window.requestAnimationFrame(resume);
      } else {
        _stopped = true;
      }
    }
    function first(nowTime) {
      initTime = nowTime;
      window.requestAnimationFrame(resume);
    }
    function pause(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.pause(animation);
      }
    }
    function goToAndStop(value, isFrame, animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.goToAndStop(value, isFrame, animation);
      }
    }
    function stop(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.stop(animation);
      }
    }
    function togglePause(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.togglePause(animation);
      }
    }
    function destroy(animation) {
      var i;
      for (i = len - 1; i >= 0; i -= 1) {
        registeredAnimations[i].animation.destroy(animation);
      }
    }
    function searchAnimations(animationData, standalone, renderer) {
      var animElements = [].concat([].slice.call(document.getElementsByClassName('lottie')), [].slice.call(document.getElementsByClassName('bodymovin')));
      var i;
      var lenAnims = animElements.length;
      for (i = 0; i < lenAnims; i += 1) {
        if (renderer) {
          animElements[i].setAttribute('data-bm-type', renderer);
        }
        registerAnimation(animElements[i], animationData);
      }
      if (standalone && lenAnims === 0) {
        if (!renderer) {
          renderer = 'svg';
        }
        var body = document.getElementsByTagName('body')[0];
        body.innerText = '';
        var div = createTag('div');
        div.style.width = '100%';
        div.style.height = '100%';
        div.setAttribute('data-bm-type', renderer);
        body.appendChild(div);
        registerAnimation(div, animationData);
      }
    }
    function resize() {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.resize();
      }
    }
    function activate() {
      if (!_isFrozen && playingAnimationsNum) {
        if (_stopped) {
          window.requestAnimationFrame(first);
          _stopped = false;
        }
      }
    }
    function freeze() {
      _isFrozen = true;
    }
    function unfreeze() {
      _isFrozen = false;
      activate();
    }
    function setVolume(val, animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.setVolume(val, animation);
      }
    }
    function mute(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.mute(animation);
      }
    }
    function unmute(animation) {
      var i;
      for (i = 0; i < len; i += 1) {
        registeredAnimations[i].animation.unmute(animation);
      }
    }
    moduleOb.registerAnimation = registerAnimation;
    moduleOb.loadAnimation = loadAnimation;
    moduleOb.setSpeed = setSpeed;
    moduleOb.setDirection = setDirection;
    moduleOb.play = play;
    moduleOb.pause = pause;
    moduleOb.stop = stop;
    moduleOb.togglePause = togglePause;
    moduleOb.searchAnimations = searchAnimations;
    moduleOb.resize = resize;
    // moduleOb.start = start;
    moduleOb.goToAndStop = goToAndStop;
    moduleOb.destroy = destroy;
    moduleOb.freeze = freeze;
    moduleOb.unfreeze = unfreeze;
    moduleOb.setVolume = setVolume;
    moduleOb.mute = mute;
    moduleOb.unmute = unmute;
    moduleOb.getRegisteredAnimations = getRegisteredAnimations;
    return moduleOb;
  }();

  /* eslint-disable */
  var BezierFactory = function () {
    /**
       * BezierEasing - use bezier curve for transition easing function
       * by Gaëtan Renaudeau 2014 - 2015 – MIT License
       *
       * Credits: is based on Firefox's nsSMILKeySpline.cpp
       * Usage:
       * var spline = BezierEasing([ 0.25, 0.1, 0.25, 1.0 ])
       * spline.get(x) => returns the easing value | x must be in [0, 1] range
       *
       */

    var ob = {};
    ob.getBezierEasing = getBezierEasing;
    var beziers = {};
    function getBezierEasing(a, b, c, d, nm) {
      var str = nm || ('bez_' + a + '_' + b + '_' + c + '_' + d).replace(/\./g, 'p');
      if (beziers[str]) {
        return beziers[str];
      }
      var bezEasing = new BezierEasing([a, b, c, d]);
      beziers[str] = bezEasing;
      return bezEasing;
    }

    // These values are established by empiricism with tests (tradeoff: performance VS precision)
    var NEWTON_ITERATIONS = 4;
    var NEWTON_MIN_SLOPE = 0.001;
    var SUBDIVISION_PRECISION = 0.0000001;
    var SUBDIVISION_MAX_ITERATIONS = 10;
    var kSplineTableSize = 11;
    var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
    var float32ArraySupported = typeof Float32Array === 'function';
    function A(aA1, aA2) {
      return 1.0 - 3.0 * aA2 + 3.0 * aA1;
    }
    function B(aA1, aA2) {
      return 3.0 * aA2 - 6.0 * aA1;
    }
    function C(aA1) {
      return 3.0 * aA1;
    }

    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
    function calcBezier(aT, aA1, aA2) {
      return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
    }

    // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
    function getSlope(aT, aA1, aA2) {
      return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
    }
    function binarySubdivide(aX, aA, aB, mX1, mX2) {
      var currentX,
        currentT,
        i = 0;
      do {
        currentT = aA + (aB - aA) / 2.0;
        currentX = calcBezier(currentT, mX1, mX2) - aX;
        if (currentX > 0.0) {
          aB = currentT;
        } else {
          aA = currentT;
        }
      } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
      return currentT;
    }
    function newtonRaphsonIterate(aX, aGuessT, mX1, mX2) {
      for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
        var currentSlope = getSlope(aGuessT, mX1, mX2);
        if (currentSlope === 0.0) return aGuessT;
        var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
        aGuessT -= currentX / currentSlope;
      }
      return aGuessT;
    }

    /**
       * points is an array of [ mX1, mY1, mX2, mY2 ]
       */
    function BezierEasing(points) {
      this._p = points;
      this._mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
      this._precomputed = false;
      this.get = this.get.bind(this);
    }
    BezierEasing.prototype = {
      get: function get(x) {
        var mX1 = this._p[0],
          mY1 = this._p[1],
          mX2 = this._p[2],
          mY2 = this._p[3];
        if (!this._precomputed) this._precompute();
        if (mX1 === mY1 && mX2 === mY2) return x; // linear
        // Because JavaScript number are imprecise, we should guarantee the extremes are right.
        if (x === 0) return 0;
        if (x === 1) return 1;
        return calcBezier(this._getTForX(x), mY1, mY2);
      },
      // Private part

      _precompute: function _precompute() {
        var mX1 = this._p[0],
          mY1 = this._p[1],
          mX2 = this._p[2],
          mY2 = this._p[3];
        this._precomputed = true;
        if (mX1 !== mY1 || mX2 !== mY2) {
          this._calcSampleValues();
        }
      },
      _calcSampleValues: function _calcSampleValues() {
        var mX1 = this._p[0],
          mX2 = this._p[2];
        for (var i = 0; i < kSplineTableSize; ++i) {
          this._mSampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
        }
      },
      /**
           * getTForX chose the fastest heuristic to determine the percentage value precisely from a given X projection.
           */
      _getTForX: function _getTForX(aX) {
        var mX1 = this._p[0],
          mX2 = this._p[2],
          mSampleValues = this._mSampleValues;
        var intervalStart = 0.0;
        var currentSample = 1;
        var lastSample = kSplineTableSize - 1;
        for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
          intervalStart += kSampleStepSize;
        }
        --currentSample;

        // Interpolate to provide an initial guess for t
        var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]);
        var guessForT = intervalStart + dist * kSampleStepSize;
        var initialSlope = getSlope(guessForT, mX1, mX2);
        if (initialSlope >= NEWTON_MIN_SLOPE) {
          return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
        }
        if (initialSlope === 0.0) {
          return guessForT;
        }
        return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
      }
    };
    return ob;
  }();
  var pooling = function () {
    function _double(arr) {
      return arr.concat(createSizedArray(arr.length));
    }
    return {
      "double": _double
    };
  }();
  var poolFactory = function () {
    return function (initialLength, _create, _release) {
      var _length = 0;
      var _maxLength = initialLength;
      var pool = createSizedArray(_maxLength);
      var ob = {
        newElement: newElement,
        release: release
      };
      function newElement() {
        var element;
        if (_length) {
          _length -= 1;
          element = pool[_length];
        } else {
          element = _create();
        }
        return element;
      }
      function release(element) {
        if (_length === _maxLength) {
          pool = pooling["double"](pool);
          _maxLength *= 2;
        }
        if (_release) {
          _release(element);
        }
        pool[_length] = element;
        _length += 1;
      }
      return ob;
    };
  }();
  var bezierLengthPool = function () {
    function create() {
      return {
        addedLength: 0,
        percents: createTypedArray('float32', getDefaultCurveSegments()),
        lengths: createTypedArray('float32', getDefaultCurveSegments())
      };
    }
    return poolFactory(8, create);
  }();
  var segmentsLengthPool = function () {
    function create() {
      return {
        lengths: [],
        totalLength: 0
      };
    }
    function release(element) {
      var i;
      var len = element.lengths.length;
      for (i = 0; i < len; i += 1) {
        bezierLengthPool.release(element.lengths[i]);
      }
      element.lengths.length = 0;
    }
    return poolFactory(8, create, release);
  }();
  function bezFunction() {
    var math = Math;
    function pointOnLine2D(x1, y1, x2, y2, x3, y3) {
      var det1 = x1 * y2 + y1 * x3 + x2 * y3 - x3 * y2 - y3 * x1 - x2 * y1;
      return det1 > -0.001 && det1 < 0.001;
    }
    function pointOnLine3D(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
      if (z1 === 0 && z2 === 0 && z3 === 0) {
        return pointOnLine2D(x1, y1, x2, y2, x3, y3);
      }
      var dist1 = math.sqrt(math.pow(x2 - x1, 2) + math.pow(y2 - y1, 2) + math.pow(z2 - z1, 2));
      var dist2 = math.sqrt(math.pow(x3 - x1, 2) + math.pow(y3 - y1, 2) + math.pow(z3 - z1, 2));
      var dist3 = math.sqrt(math.pow(x3 - x2, 2) + math.pow(y3 - y2, 2) + math.pow(z3 - z2, 2));
      var diffDist;
      if (dist1 > dist2) {
        if (dist1 > dist3) {
          diffDist = dist1 - dist2 - dist3;
        } else {
          diffDist = dist3 - dist2 - dist1;
        }
      } else if (dist3 > dist2) {
        diffDist = dist3 - dist2 - dist1;
      } else {
        diffDist = dist2 - dist1 - dist3;
      }
      return diffDist > -0.0001 && diffDist < 0.0001;
    }
    var getBezierLength = function () {
      return function (pt1, pt2, pt3, pt4) {
        var curveSegments = getDefaultCurveSegments();
        var k;
        var i;
        var len;
        var ptCoord;
        var perc;
        var addedLength = 0;
        var ptDistance;
        var point = [];
        var lastPoint = [];
        var lengthData = bezierLengthPool.newElement();
        len = pt3.length;
        for (k = 0; k < curveSegments; k += 1) {
          perc = k / (curveSegments - 1);
          ptDistance = 0;
          for (i = 0; i < len; i += 1) {
            ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * pt3[i] + 3 * (1 - perc) * bmPow(perc, 2) * pt4[i] + bmPow(perc, 3) * pt2[i];
            point[i] = ptCoord;
            if (lastPoint[i] !== null) {
              ptDistance += bmPow(point[i] - lastPoint[i], 2);
            }
            lastPoint[i] = point[i];
          }
          if (ptDistance) {
            ptDistance = bmSqrt(ptDistance);
            addedLength += ptDistance;
          }
          lengthData.percents[k] = perc;
          lengthData.lengths[k] = addedLength;
        }
        lengthData.addedLength = addedLength;
        return lengthData;
      };
    }();
    function getSegmentsLength(shapeData) {
      var segmentsLength = segmentsLengthPool.newElement();
      var closed = shapeData.c;
      var pathV = shapeData.v;
      var pathO = shapeData.o;
      var pathI = shapeData.i;
      var i;
      var len = shapeData._length;
      var lengths = segmentsLength.lengths;
      var totalLength = 0;
      for (i = 0; i < len - 1; i += 1) {
        lengths[i] = getBezierLength(pathV[i], pathV[i + 1], pathO[i], pathI[i + 1]);
        totalLength += lengths[i].addedLength;
      }
      if (closed && len) {
        lengths[i] = getBezierLength(pathV[i], pathV[0], pathO[i], pathI[0]);
        totalLength += lengths[i].addedLength;
      }
      segmentsLength.totalLength = totalLength;
      return segmentsLength;
    }
    function BezierData(length) {
      this.segmentLength = 0;
      this.points = new Array(length);
    }
    function PointData(partial, point) {
      this.partialLength = partial;
      this.point = point;
    }
    var buildBezierData = function () {
      var storedData = {};
      return function (pt1, pt2, pt3, pt4) {
        var bezierName = (pt1[0] + '_' + pt1[1] + '_' + pt2[0] + '_' + pt2[1] + '_' + pt3[0] + '_' + pt3[1] + '_' + pt4[0] + '_' + pt4[1]).replace(/\./g, 'p');
        if (!storedData[bezierName]) {
          var curveSegments = getDefaultCurveSegments();
          var k;
          var i;
          var len;
          var ptCoord;
          var perc;
          var addedLength = 0;
          var ptDistance;
          var point;
          var lastPoint = null;
          if (pt1.length === 2 && (pt1[0] !== pt2[0] || pt1[1] !== pt2[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt1[0] + pt3[0], pt1[1] + pt3[1]) && pointOnLine2D(pt1[0], pt1[1], pt2[0], pt2[1], pt2[0] + pt4[0], pt2[1] + pt4[1])) {
            curveSegments = 2;
          }
          var bezierData = new BezierData(curveSegments);
          len = pt3.length;
          for (k = 0; k < curveSegments; k += 1) {
            point = createSizedArray(len);
            perc = k / (curveSegments - 1);
            ptDistance = 0;
            for (i = 0; i < len; i += 1) {
              ptCoord = bmPow(1 - perc, 3) * pt1[i] + 3 * bmPow(1 - perc, 2) * perc * (pt1[i] + pt3[i]) + 3 * (1 - perc) * bmPow(perc, 2) * (pt2[i] + pt4[i]) + bmPow(perc, 3) * pt2[i];
              point[i] = ptCoord;
              if (lastPoint !== null) {
                ptDistance += bmPow(point[i] - lastPoint[i], 2);
              }
            }
            ptDistance = bmSqrt(ptDistance);
            addedLength += ptDistance;
            bezierData.points[k] = new PointData(ptDistance, point);
            lastPoint = point;
          }
          bezierData.segmentLength = addedLength;
          storedData[bezierName] = bezierData;
        }
        return storedData[bezierName];
      };
    }();
    function getDistancePerc(perc, bezierData) {
      var percents = bezierData.percents;
      var lengths = bezierData.lengths;
      var len = percents.length;
      var initPos = bmFloor((len - 1) * perc);
      var lengthPos = perc * bezierData.addedLength;
      var lPerc = 0;
      if (initPos === len - 1 || initPos === 0 || lengthPos === lengths[initPos]) {
        return percents[initPos];
      }
      var dir = lengths[initPos] > lengthPos ? -1 : 1;
      var flag = true;
      while (flag) {
        if (lengths[initPos] <= lengthPos && lengths[initPos + 1] > lengthPos) {
          lPerc = (lengthPos - lengths[initPos]) / (lengths[initPos + 1] - lengths[initPos]);
          flag = false;
        } else {
          initPos += dir;
        }
        if (initPos < 0 || initPos >= len - 1) {
          // FIX for TypedArrays that don't store floating point values with enough accuracy
          if (initPos === len - 1) {
            return percents[initPos];
          }
          flag = false;
        }
      }
      return percents[initPos] + (percents[initPos + 1] - percents[initPos]) * lPerc;
    }
    function getPointInSegment(pt1, pt2, pt3, pt4, percent, bezierData) {
      var t1 = getDistancePerc(percent, bezierData);
      var u1 = 1 - t1;
      var ptX = math.round((u1 * u1 * u1 * pt1[0] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[0] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[0] + t1 * t1 * t1 * pt2[0]) * 1000) / 1000;
      var ptY = math.round((u1 * u1 * u1 * pt1[1] + (t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1) * pt3[1] + (t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1) * pt4[1] + t1 * t1 * t1 * pt2[1]) * 1000) / 1000;
      return [ptX, ptY];
    }
    var bezierSegmentPoints = createTypedArray('float32', 8);
    function getNewSegment(pt1, pt2, pt3, pt4, startPerc, endPerc, bezierData) {
      if (startPerc < 0) {
        startPerc = 0;
      } else if (startPerc > 1) {
        startPerc = 1;
      }
      var t0 = getDistancePerc(startPerc, bezierData);
      endPerc = endPerc > 1 ? 1 : endPerc;
      var t1 = getDistancePerc(endPerc, bezierData);
      var i;
      var len = pt1.length;
      var u0 = 1 - t0;
      var u1 = 1 - t1;
      var u0u0u0 = u0 * u0 * u0;
      var t0u0u0_3 = t0 * u0 * u0 * 3; // eslint-disable-line camelcase
      var t0t0u0_3 = t0 * t0 * u0 * 3; // eslint-disable-line camelcase
      var t0t0t0 = t0 * t0 * t0;
      //
      var u0u0u1 = u0 * u0 * u1;
      var t0u0u1_3 = t0 * u0 * u1 + u0 * t0 * u1 + u0 * u0 * t1; // eslint-disable-line camelcase
      var t0t0u1_3 = t0 * t0 * u1 + u0 * t0 * t1 + t0 * u0 * t1; // eslint-disable-line camelcase
      var t0t0t1 = t0 * t0 * t1;
      //
      var u0u1u1 = u0 * u1 * u1;
      var t0u1u1_3 = t0 * u1 * u1 + u0 * t1 * u1 + u0 * u1 * t1; // eslint-disable-line camelcase
      var t0t1u1_3 = t0 * t1 * u1 + u0 * t1 * t1 + t0 * u1 * t1; // eslint-disable-line camelcase
      var t0t1t1 = t0 * t1 * t1;
      //
      var u1u1u1 = u1 * u1 * u1;
      var t1u1u1_3 = t1 * u1 * u1 + u1 * t1 * u1 + u1 * u1 * t1; // eslint-disable-line camelcase
      var t1t1u1_3 = t1 * t1 * u1 + u1 * t1 * t1 + t1 * u1 * t1; // eslint-disable-line camelcase
      var t1t1t1 = t1 * t1 * t1;
      for (i = 0; i < len; i += 1) {
        bezierSegmentPoints[i * 4] = math.round((u0u0u0 * pt1[i] + t0u0u0_3 * pt3[i] + t0t0u0_3 * pt4[i] + t0t0t0 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
        bezierSegmentPoints[i * 4 + 1] = math.round((u0u0u1 * pt1[i] + t0u0u1_3 * pt3[i] + t0t0u1_3 * pt4[i] + t0t0t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
        bezierSegmentPoints[i * 4 + 2] = math.round((u0u1u1 * pt1[i] + t0u1u1_3 * pt3[i] + t0t1u1_3 * pt4[i] + t0t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
        bezierSegmentPoints[i * 4 + 3] = math.round((u1u1u1 * pt1[i] + t1u1u1_3 * pt3[i] + t1t1u1_3 * pt4[i] + t1t1t1 * pt2[i]) * 1000) / 1000; // eslint-disable-line camelcase
      }
      return bezierSegmentPoints;
    }
    return {
      getSegmentsLength: getSegmentsLength,
      getNewSegment: getNewSegment,
      getPointInSegment: getPointInSegment,
      buildBezierData: buildBezierData,
      pointOnLine2D: pointOnLine2D,
      pointOnLine3D: pointOnLine3D
    };
  }
  var bez = bezFunction();
  var initFrame = initialDefaultFrame;
  var mathAbs = Math.abs;
  function interpolateValue(frameNum, caching) {
    var offsetTime = this.offsetTime;
    var newValue;
    if (this.propType === 'multidimensional') {
      newValue = createTypedArray('float32', this.pv.length);
    }
    var iterationIndex = caching.lastIndex;
    var i = iterationIndex;
    var len = this.keyframes.length - 1;
    var flag = true;
    var keyData;
    var nextKeyData;
    var keyframeMetadata;
    while (flag) {
      keyData = this.keyframes[i];
      nextKeyData = this.keyframes[i + 1];
      if (i === len - 1 && frameNum >= nextKeyData.t - offsetTime) {
        if (keyData.h) {
          keyData = nextKeyData;
        }
        iterationIndex = 0;
        break;
      }
      if (nextKeyData.t - offsetTime > frameNum) {
        iterationIndex = i;
        break;
      }
      if (i < len - 1) {
        i += 1;
      } else {
        iterationIndex = 0;
        flag = false;
      }
    }
    keyframeMetadata = this.keyframesMetadata[i] || {};
    var k;
    var kLen;
    var perc;
    var jLen;
    var j;
    var fnc;
    var nextKeyTime = nextKeyData.t - offsetTime;
    var keyTime = keyData.t - offsetTime;
    var endValue;
    if (keyData.to) {
      if (!keyframeMetadata.bezierData) {
        keyframeMetadata.bezierData = bez.buildBezierData(keyData.s, nextKeyData.s || keyData.e, keyData.to, keyData.ti);
      }
      var bezierData = keyframeMetadata.bezierData;
      if (frameNum >= nextKeyTime || frameNum < keyTime) {
        var ind = frameNum >= nextKeyTime ? bezierData.points.length - 1 : 0;
        kLen = bezierData.points[ind].point.length;
        for (k = 0; k < kLen; k += 1) {
          newValue[k] = bezierData.points[ind].point[k];
        }
        // caching._lastKeyframeIndex = -1;
      } else {
        if (keyframeMetadata.__fnct) {
          fnc = keyframeMetadata.__fnct;
        } else {
          fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y, keyData.n).get;
          keyframeMetadata.__fnct = fnc;
        }
        perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
        var distanceInLine = bezierData.segmentLength * perc;
        var segmentPerc;
        var addedLength = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastAddedLength : 0;
        j = caching.lastFrame < frameNum && caching._lastKeyframeIndex === i ? caching._lastPoint : 0;
        flag = true;
        jLen = bezierData.points.length;
        while (flag) {
          addedLength += bezierData.points[j].partialLength;
          if (distanceInLine === 0 || perc === 0 || j === bezierData.points.length - 1) {
            kLen = bezierData.points[j].point.length;
            for (k = 0; k < kLen; k += 1) {
              newValue[k] = bezierData.points[j].point[k];
            }
            break;
          } else if (distanceInLine >= addedLength && distanceInLine < addedLength + bezierData.points[j + 1].partialLength) {
            segmentPerc = (distanceInLine - addedLength) / bezierData.points[j + 1].partialLength;
            kLen = bezierData.points[j].point.length;
            for (k = 0; k < kLen; k += 1) {
              newValue[k] = bezierData.points[j].point[k] + (bezierData.points[j + 1].point[k] - bezierData.points[j].point[k]) * segmentPerc;
            }
            break;
          }
          if (j < jLen - 1) {
            j += 1;
          } else {
            flag = false;
          }
        }
        caching._lastPoint = j;
        caching._lastAddedLength = addedLength - bezierData.points[j].partialLength;
        caching._lastKeyframeIndex = i;
      }
    } else {
      var outX;
      var outY;
      var inX;
      var inY;
      var keyValue;
      len = keyData.s.length;
      endValue = nextKeyData.s || keyData.e;
      if (this.sh && keyData.h !== 1) {
        if (frameNum >= nextKeyTime) {
          newValue[0] = endValue[0];
          newValue[1] = endValue[1];
          newValue[2] = endValue[2];
        } else if (frameNum <= keyTime) {
          newValue[0] = keyData.s[0];
          newValue[1] = keyData.s[1];
          newValue[2] = keyData.s[2];
        } else {
          var quatStart = createQuaternion(keyData.s);
          var quatEnd = createQuaternion(endValue);
          var time = (frameNum - keyTime) / (nextKeyTime - keyTime);
          quaternionToEuler(newValue, slerp(quatStart, quatEnd, time));
        }
      } else {
        for (i = 0; i < len; i += 1) {
          if (keyData.h !== 1) {
            if (frameNum >= nextKeyTime) {
              perc = 1;
            } else if (frameNum < keyTime) {
              perc = 0;
            } else {
              if (keyData.o.x.constructor === Array) {
                if (!keyframeMetadata.__fnct) {
                  keyframeMetadata.__fnct = [];
                }
                if (!keyframeMetadata.__fnct[i]) {
                  outX = keyData.o.x[i] === undefined ? keyData.o.x[0] : keyData.o.x[i];
                  outY = keyData.o.y[i] === undefined ? keyData.o.y[0] : keyData.o.y[i];
                  inX = keyData.i.x[i] === undefined ? keyData.i.x[0] : keyData.i.x[i];
                  inY = keyData.i.y[i] === undefined ? keyData.i.y[0] : keyData.i.y[i];
                  fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
                  keyframeMetadata.__fnct[i] = fnc;
                } else {
                  fnc = keyframeMetadata.__fnct[i];
                }
              } else if (!keyframeMetadata.__fnct) {
                outX = keyData.o.x;
                outY = keyData.o.y;
                inX = keyData.i.x;
                inY = keyData.i.y;
                fnc = BezierFactory.getBezierEasing(outX, outY, inX, inY).get;
                keyData.keyframeMetadata = fnc;
              } else {
                fnc = keyframeMetadata.__fnct;
              }
              perc = fnc((frameNum - keyTime) / (nextKeyTime - keyTime));
            }
          }
          endValue = nextKeyData.s || keyData.e;
          keyValue = keyData.h === 1 ? keyData.s[i] : keyData.s[i] + (endValue[i] - keyData.s[i]) * perc;
          if (this.propType === 'multidimensional') {
            newValue[i] = keyValue;
          } else {
            newValue = keyValue;
          }
        }
      }
    }
    caching.lastIndex = iterationIndex;
    return newValue;
  }

  // based on @Toji's https://github.com/toji/gl-matrix/
  function slerp(a, b, t) {
    var out = [];
    var ax = a[0];
    var ay = a[1];
    var az = a[2];
    var aw = a[3];
    var bx = b[0];
    var by = b[1];
    var bz = b[2];
    var bw = b[3];
    var omega;
    var cosom;
    var sinom;
    var scale0;
    var scale1;
    cosom = ax * bx + ay * by + az * bz + aw * bw;
    if (cosom < 0.0) {
      cosom = -cosom;
      bx = -bx;
      by = -by;
      bz = -bz;
      bw = -bw;
    }
    if (1.0 - cosom > 0.000001) {
      omega = Math.acos(cosom);
      sinom = Math.sin(omega);
      scale0 = Math.sin((1.0 - t) * omega) / sinom;
      scale1 = Math.sin(t * omega) / sinom;
    } else {
      scale0 = 1.0 - t;
      scale1 = t;
    }
    out[0] = scale0 * ax + scale1 * bx;
    out[1] = scale0 * ay + scale1 * by;
    out[2] = scale0 * az + scale1 * bz;
    out[3] = scale0 * aw + scale1 * bw;
    return out;
  }
  function quaternionToEuler(out, quat) {
    var qx = quat[0];
    var qy = quat[1];
    var qz = quat[2];
    var qw = quat[3];
    var heading = Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy * qy - 2 * qz * qz);
    var attitude = Math.asin(2 * qx * qy + 2 * qz * qw);
    var bank = Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx * qx - 2 * qz * qz);
    out[0] = heading / degToRads;
    out[1] = attitude / degToRads;
    out[2] = bank / degToRads;
  }
  function createQuaternion(values) {
    var heading = values[0] * degToRads;
    var attitude = values[1] * degToRads;
    var bank = values[2] * degToRads;
    var c1 = Math.cos(heading / 2);
    var c2 = Math.cos(attitude / 2);
    var c3 = Math.cos(bank / 2);
    var s1 = Math.sin(heading / 2);
    var s2 = Math.sin(attitude / 2);
    var s3 = Math.sin(bank / 2);
    var w = c1 * c2 * c3 - s1 * s2 * s3;
    var x = s1 * s2 * c3 + c1 * c2 * s3;
    var y = s1 * c2 * c3 + c1 * s2 * s3;
    var z = c1 * s2 * c3 - s1 * c2 * s3;
    return [x, y, z, w];
  }
  function getValueAtCurrentTime() {
    var frameNum = this.comp.renderedFrame - this.offsetTime;
    var initTime = this.keyframes[0].t - this.offsetTime;
    var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
    if (!(frameNum === this._caching.lastFrame || this._caching.lastFrame !== initFrame && (this._caching.lastFrame >= endTime && frameNum >= endTime || this._caching.lastFrame < initTime && frameNum < initTime))) {
      if (this._caching.lastFrame >= frameNum) {
        this._caching._lastKeyframeIndex = -1;
        this._caching.lastIndex = 0;
      }
      var renderResult = this.interpolateValue(frameNum, this._caching);
      this.pv = renderResult;
    }
    this._caching.lastFrame = frameNum;
    return this.pv;
  }
  function setVValue(val) {
    var multipliedValue;
    if (this.propType === 'unidimensional') {
      multipliedValue = val * this.mult;
      if (mathAbs(this.v - multipliedValue) > 0.00001) {
        this.v = multipliedValue;
        this._mdf = true;
      }
    } else {
      var i = 0;
      var len = this.v.length;
      while (i < len) {
        multipliedValue = val[i] * this.mult;
        if (mathAbs(this.v[i] - multipliedValue) > 0.00001) {
          this.v[i] = multipliedValue;
          this._mdf = true;
        }
        i += 1;
      }
    }
  }
  function processEffectsSequence() {
    if (this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) {
      return;
    }
    if (this.lock) {
      this.setVValue(this.pv);
      return;
    }
    this.lock = true;
    this._mdf = this._isFirstFrame;
    var i;
    var len = this.effectsSequence.length;
    var finalValue = this.kf ? this.pv : this.data.k;
    for (i = 0; i < len; i += 1) {
      finalValue = this.effectsSequence[i](finalValue);
    }
    this.setVValue(finalValue);
    this._isFirstFrame = false;
    this.lock = false;
    this.frameId = this.elem.globalData.frameId;
  }
  function addEffect(effectFunction) {
    this.effectsSequence.push(effectFunction);
    this.container.addDynamicProperty(this);
  }
  function ValueProperty(elem, data, mult, container) {
    this.propType = 'unidimensional';
    this.mult = mult || 1;
    this.data = data;
    this.v = mult ? data.k * mult : data.k;
    this.pv = data.k;
    this._mdf = false;
    this.elem = elem;
    this.container = container;
    this.comp = elem.comp;
    this.k = false;
    this.kf = false;
    this.vel = 0;
    this.effectsSequence = [];
    this._isFirstFrame = true;
    this.getValue = processEffectsSequence;
    this.setVValue = setVValue;
    this.addEffect = addEffect;
  }
  function MultiDimensionalProperty(elem, data, mult, container) {
    this.propType = 'multidimensional';
    this.mult = mult || 1;
    this.data = data;
    this._mdf = false;
    this.elem = elem;
    this.container = container;
    this.comp = elem.comp;
    this.k = false;
    this.kf = false;
    this.frameId = -1;
    var i;
    var len = data.k.length;
    this.v = createTypedArray('float32', len);
    this.pv = createTypedArray('float32', len);
    this.vel = createTypedArray('float32', len);
    for (i = 0; i < len; i += 1) {
      this.v[i] = data.k[i] * this.mult;
      this.pv[i] = data.k[i];
    }
    this._isFirstFrame = true;
    this.effectsSequence = [];
    this.getValue = processEffectsSequence;
    this.setVValue = setVValue;
    this.addEffect = addEffect;
  }
  function KeyframedValueProperty(elem, data, mult, container) {
    this.propType = 'unidimensional';
    this.keyframes = data.k;
    this.keyframesMetadata = [];
    this.offsetTime = elem.data.st;
    this.frameId = -1;
    this._caching = {
      lastFrame: initFrame,
      lastIndex: 0,
      value: 0,
      _lastKeyframeIndex: -1
    };
    this.k = true;
    this.kf = true;
    this.data = data;
    this.mult = mult || 1;
    this.elem = elem;
    this.container = container;
    this.comp = elem.comp;
    this.v = initFrame;
    this.pv = initFrame;
    this._isFirstFrame = true;
    this.getValue = processEffectsSequence;
    this.setVValue = setVValue;
    this.interpolateValue = interpolateValue;
    this.effectsSequence = [getValueAtCurrentTime.bind(this)];
    this.addEffect = addEffect;
  }
  function KeyframedMultidimensionalProperty(elem, data, mult, container) {
    this.propType = 'multidimensional';
    var i;
    var len = data.k.length;
    var s;
    var e;
    var to;
    var ti;
    for (i = 0; i < len - 1; i += 1) {
      if (data.k[i].to && data.k[i].s && data.k[i + 1] && data.k[i + 1].s) {
        s = data.k[i].s;
        e = data.k[i + 1].s;
        to = data.k[i].to;
        ti = data.k[i].ti;
        if (s.length === 2 && !(s[0] === e[0] && s[1] === e[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], s[0] + to[0], s[1] + to[1]) && bez.pointOnLine2D(s[0], s[1], e[0], e[1], e[0] + ti[0], e[1] + ti[1]) || s.length === 3 && !(s[0] === e[0] && s[1] === e[1] && s[2] === e[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], s[0] + to[0], s[1] + to[1], s[2] + to[2]) && bez.pointOnLine3D(s[0], s[1], s[2], e[0], e[1], e[2], e[0] + ti[0], e[1] + ti[1], e[2] + ti[2])) {
          data.k[i].to = null;
          data.k[i].ti = null;
        }
        if (s[0] === e[0] && s[1] === e[1] && to[0] === 0 && to[1] === 0 && ti[0] === 0 && ti[1] === 0) {
          if (s.length === 2 || s[2] === e[2] && to[2] === 0 && ti[2] === 0) {
            data.k[i].to = null;
            data.k[i].ti = null;
          }
        }
      }
    }
    this.effectsSequence = [getValueAtCurrentTime.bind(this)];
    this.data = data;
    this.keyframes = data.k;
    this.keyframesMetadata = [];
    this.offsetTime = elem.data.st;
    this.k = true;
    this.kf = true;
    this._isFirstFrame = true;
    this.mult = mult || 1;
    this.elem = elem;
    this.container = container;
    this.comp = elem.comp;
    this.getValue = processEffectsSequence;
    this.setVValue = setVValue;
    this.interpolateValue = interpolateValue;
    this.frameId = -1;
    var arrLen = data.k[0].s.length;
    this.v = createTypedArray('float32', arrLen);
    this.pv = createTypedArray('float32', arrLen);
    for (i = 0; i < arrLen; i += 1) {
      this.v[i] = initFrame;
      this.pv[i] = initFrame;
    }
    this._caching = {
      lastFrame: initFrame,
      lastIndex: 0,
      value: createTypedArray('float32', arrLen)
    };
    this.addEffect = addEffect;
  }
  var PropertyFactory = function () {
    function getProp(elem, data, type, mult, container) {
      if (data.sid) {
        data = elem.globalData.slotManager.getProp(data);
      }
      var p;
      if (!data.k.length) {
        p = new ValueProperty(elem, data, mult, container);
      } else if (typeof data.k[0] === 'number') {
        p = new MultiDimensionalProperty(elem, data, mult, container);
      } else {
        switch (type) {
          case 0:
            p = new KeyframedValueProperty(elem, data, mult, container);
            break;
          case 1:
            p = new KeyframedMultidimensionalProperty(elem, data, mult, container);
            break;
          default:
            break;
        }
      }
      if (p.effectsSequence.length) {
        container.addDynamicProperty(p);
      }
      return p;
    }
    var ob = {
      getProp: getProp
    };
    return ob;
  }();
  function DynamicPropertyContainer() {}
  DynamicPropertyContainer.prototype = {
    addDynamicProperty: function addDynamicProperty(prop) {
      if (this.dynamicProperties.indexOf(prop) === -1) {
        this.dynamicProperties.push(prop);
        this.container.addDynamicProperty(this);
        this._isAnimated = true;
      }
    },
    iterateDynamicProperties: function iterateDynamicProperties() {
      this._mdf = false;
      var i;
      var len = this.dynamicProperties.length;
      for (i = 0; i < len; i += 1) {
        this.dynamicProperties[i].getValue();
        if (this.dynamicProperties[i]._mdf) {
          this._mdf = true;
        }
      }
    },
    initDynamicPropertyContainer: function initDynamicPropertyContainer(container) {
      this.container = container;
      this.dynamicProperties = [];
      this._mdf = false;
      this._isAnimated = false;
    }
  };
  var pointPool = function () {
    function create() {
      return createTypedArray('float32', 2);
    }
    return poolFactory(8, create);
  }();
  function ShapePath() {
    this.c = false;
    this._length = 0;
    this._maxLength = 8;
    this.v = createSizedArray(this._maxLength);
    this.o = createSizedArray(this._maxLength);
    this.i = createSizedArray(this._maxLength);
  }
  ShapePath.prototype.setPathData = function (closed, len) {
    this.c = closed;
    this.setLength(len);
    var i = 0;
    while (i < len) {
      this.v[i] = pointPool.newElement();
      this.o[i] = pointPool.newElement();
      this.i[i] = pointPool.newElement();
      i += 1;
    }
  };
  ShapePath.prototype.setLength = function (len) {
    while (this._maxLength < len) {
      this.doubleArrayLength();
    }
    this._length = len;
  };
  ShapePath.prototype.doubleArrayLength = function () {
    this.v = this.v.concat(createSizedArray(this._maxLength));
    this.i = this.i.concat(createSizedArray(this._maxLength));
    this.o = this.o.concat(createSizedArray(this._maxLength));
    this._maxLength *= 2;
  };
  ShapePath.prototype.setXYAt = function (x, y, type, pos, replace) {
    var arr;
    this._length = Math.max(this._length, pos + 1);
    if (this._length >= this._maxLength) {
      this.doubleArrayLength();
    }
    switch (type) {
      case 'v':
        arr = this.v;
        break;
      case 'i':
        arr = this.i;
        break;
      case 'o':
        arr = this.o;
        break;
      default:
        arr = [];
        break;
    }
    if (!arr[pos] || arr[pos] && !replace) {
      arr[pos] = pointPool.newElement();
    }
    arr[pos][0] = x;
    arr[pos][1] = y;
  };
  ShapePath.prototype.setTripleAt = function (vX, vY, oX, oY, iX, iY, pos, replace) {
    this.setXYAt(vX, vY, 'v', pos, replace);
    this.setXYAt(oX, oY, 'o', pos, replace);
    this.setXYAt(iX, iY, 'i', pos, replace);
  };
  ShapePath.prototype.reverse = function () {
    var newPath = new ShapePath();
    newPath.setPathData(this.c, this._length);
    var vertices = this.v;
    var outPoints = this.o;
    var inPoints = this.i;
    var init = 0;
    if (this.c) {
      newPath.setTripleAt(vertices[0][0], vertices[0][1], inPoints[0][0], inPoints[0][1], outPoints[0][0], outPoints[0][1], 0, false);
      init = 1;
    }
    var cnt = this._length - 1;
    var len = this._length;
    var i;
    for (i = init; i < len; i += 1) {
      newPath.setTripleAt(vertices[cnt][0], vertices[cnt][1], inPoints[cnt][0], inPoints[cnt][1], outPoints[cnt][0], outPoints[cnt][1], i, false);
      cnt -= 1;
    }
    return newPath;
  };
  ShapePath.prototype.length = function () {
    return this._length;
  };
  var shapePool = function () {
    function create() {
      return new ShapePath();
    }
    function release(shapePath) {
      var len = shapePath._length;
      var i;
      for (i = 0; i < len; i += 1) {
        pointPool.release(shapePath.v[i]);
        pointPool.release(shapePath.i[i]);
        pointPool.release(shapePath.o[i]);
        shapePath.v[i] = null;
        shapePath.i[i] = null;
        shapePath.o[i] = null;
      }
      shapePath._length = 0;
      shapePath.c = false;
    }
    function clone(shape) {
      var cloned = factory.newElement();
      var i;
      var len = shape._length === undefined ? shape.v.length : shape._length;
      cloned.setLength(len);
      cloned.c = shape.c;
      for (i = 0; i < len; i += 1) {
        cloned.setTripleAt(shape.v[i][0], shape.v[i][1], shape.o[i][0], shape.o[i][1], shape.i[i][0], shape.i[i][1], i);
      }
      return cloned;
    }
    var factory = poolFactory(4, create, release);
    factory.clone = clone;
    return factory;
  }();
  function ShapeCollection() {
    this._length = 0;
    this._maxLength = 4;
    this.shapes = createSizedArray(this._maxLength);
  }
  ShapeCollection.prototype.addShape = function (shapeData) {
    if (this._length === this._maxLength) {
      this.shapes = this.shapes.concat(createSizedArray(this._maxLength));
      this._maxLength *= 2;
    }
    this.shapes[this._length] = shapeData;
    this._length += 1;
  };
  ShapeCollection.prototype.releaseShapes = function () {
    var i;
    for (i = 0; i < this._length; i += 1) {
      shapePool.release(this.shapes[i]);
    }
    this._length = 0;
  };
  var shapeCollectionPool = function () {
    var ob = {
      newShapeCollection: newShapeCollection,
      release: release
    };
    var _length = 0;
    var _maxLength = 4;
    var pool = createSizedArray(_maxLength);
    function newShapeCollection() {
      var shapeCollection;
      if (_length) {
        _length -= 1;
        shapeCollection = pool[_length];
      } else {
        shapeCollection = new ShapeCollection();
      }
      return shapeCollection;
    }
    function release(shapeCollection) {
      var i;
      var len = shapeCollection._length;
      for (i = 0; i < len; i += 1) {
        shapePool.release(shapeCollection.shapes[i]);
      }
      shapeCollection._length = 0;
      if (_length === _maxLength) {
        pool = pooling["double"](pool);
        _maxLength *= 2;
      }
      pool[_length] = shapeCollection;
      _length += 1;
    }
    return ob;
  }();
  var ShapePropertyFactory = function () {
    var initFrame = -999999;
    function interpolateShape(frameNum, previousValue, caching) {
      var iterationIndex = caching.lastIndex;
      var keyPropS;
      var keyPropE;
      var isHold;
      var j;
      var k;
      var jLen;
      var kLen;
      var perc;
      var vertexValue;
      var kf = this.keyframes;
      if (frameNum < kf[0].t - this.offsetTime) {
        keyPropS = kf[0].s[0];
        isHold = true;
        iterationIndex = 0;
      } else if (frameNum >= kf[kf.length - 1].t - this.offsetTime) {
        keyPropS = kf[kf.length - 1].s ? kf[kf.length - 1].s[0] : kf[kf.length - 2].e[0];
        /* if(kf[kf.length - 1].s){
                  keyPropS = kf[kf.length - 1].s[0];
              }else{
                  keyPropS = kf[kf.length - 2].e[0];
              } */
        isHold = true;
      } else {
        var i = iterationIndex;
        var len = kf.length - 1;
        var flag = true;
        var keyData;
        var nextKeyData;
        var keyframeMetadata;
        while (flag) {
          keyData = kf[i];
          nextKeyData = kf[i + 1];
          if (nextKeyData.t - this.offsetTime > frameNum) {
            break;
          }
          if (i < len - 1) {
            i += 1;
          } else {
            flag = false;
          }
        }
        keyframeMetadata = this.keyframesMetadata[i] || {};
        isHold = keyData.h === 1;
        iterationIndex = i;
        if (!isHold) {
          if (frameNum >= nextKeyData.t - this.offsetTime) {
            perc = 1;
          } else if (frameNum < keyData.t - this.offsetTime) {
            perc = 0;
          } else {
            var fnc;
            if (keyframeMetadata.__fnct) {
              fnc = keyframeMetadata.__fnct;
            } else {
              fnc = BezierFactory.getBezierEasing(keyData.o.x, keyData.o.y, keyData.i.x, keyData.i.y).get;
              keyframeMetadata.__fnct = fnc;
            }
            perc = fnc((frameNum - (keyData.t - this.offsetTime)) / (nextKeyData.t - this.offsetTime - (keyData.t - this.offsetTime)));
          }
          keyPropE = nextKeyData.s ? nextKeyData.s[0] : keyData.e[0];
        }
        keyPropS = keyData.s[0];
      }
      jLen = previousValue._length;
      kLen = keyPropS.i[0].length;
      caching.lastIndex = iterationIndex;
      for (j = 0; j < jLen; j += 1) {
        for (k = 0; k < kLen; k += 1) {
          vertexValue = isHold ? keyPropS.i[j][k] : keyPropS.i[j][k] + (keyPropE.i[j][k] - keyPropS.i[j][k]) * perc;
          previousValue.i[j][k] = vertexValue;
          vertexValue = isHold ? keyPropS.o[j][k] : keyPropS.o[j][k] + (keyPropE.o[j][k] - keyPropS.o[j][k]) * perc;
          previousValue.o[j][k] = vertexValue;
          vertexValue = isHold ? keyPropS.v[j][k] : keyPropS.v[j][k] + (keyPropE.v[j][k] - keyPropS.v[j][k]) * perc;
          previousValue.v[j][k] = vertexValue;
        }
      }
    }
    function interpolateShapeCurrentTime() {
      var frameNum = this.comp.renderedFrame - this.offsetTime;
      var initTime = this.keyframes[0].t - this.offsetTime;
      var endTime = this.keyframes[this.keyframes.length - 1].t - this.offsetTime;
      var lastFrame = this._caching.lastFrame;
      if (!(lastFrame !== initFrame && (lastFrame < initTime && frameNum < initTime || lastFrame > endTime && frameNum > endTime))) {
        /// /
        this._caching.lastIndex = lastFrame < frameNum ? this._caching.lastIndex : 0;
        this.interpolateShape(frameNum, this.pv, this._caching);
        /// /
      }
      this._caching.lastFrame = frameNum;
      return this.pv;
    }
    function resetShape() {
      this.paths = this.localShapeCollection;
    }
    function shapesEqual(shape1, shape2) {
      if (shape1._length !== shape2._length || shape1.c !== shape2.c) {
        return false;
      }
      var i;
      var len = shape1._length;
      for (i = 0; i < len; i += 1) {
        if (shape1.v[i][0] !== shape2.v[i][0] || shape1.v[i][1] !== shape2.v[i][1] || shape1.o[i][0] !== shape2.o[i][0] || shape1.o[i][1] !== shape2.o[i][1] || shape1.i[i][0] !== shape2.i[i][0] || shape1.i[i][1] !== shape2.i[i][1]) {
          return false;
        }
      }
      return true;
    }
    function setVValue(newPath) {
      if (!shapesEqual(this.v, newPath)) {
        this.v = shapePool.clone(newPath);
        this.localShapeCollection.releaseShapes();
        this.localShapeCollection.addShape(this.v);
        this._mdf = true;
        this.paths = this.localShapeCollection;
      }
    }
    function processEffectsSequence() {
      if (this.elem.globalData.frameId === this.frameId) {
        return;
      }
      if (!this.effectsSequence.length) {
        this._mdf = false;
        return;
      }
      if (this.lock) {
        this.setVValue(this.pv);
        return;
      }
      this.lock = true;
      this._mdf = false;
      var finalValue;
      if (this.kf) {
        finalValue = this.pv;
      } else if (this.data.ks) {
        finalValue = this.data.ks.k;
      } else {
        finalValue = this.data.pt.k;
      }
      var i;
      var len = this.effectsSequence.length;
      for (i = 0; i < len; i += 1) {
        finalValue = this.effectsSequence[i](finalValue);
      }
      this.setVValue(finalValue);
      this.lock = false;
      this.frameId = this.elem.globalData.frameId;
    }
    function ShapeProperty(elem, data, type) {
      this.propType = 'shape';
      this.comp = elem.comp;
      this.container = elem;
      this.elem = elem;
      this.data = data;
      this.k = false;
      this.kf = false;
      this._mdf = false;
      var pathData = type === 3 ? data.pt.k : data.ks.k;
      this.v = shapePool.clone(pathData);
      this.pv = shapePool.clone(this.v);
      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
      this.paths = this.localShapeCollection;
      this.paths.addShape(this.v);
      this.reset = resetShape;
      this.effectsSequence = [];
    }
    function addEffect(effectFunction) {
      this.effectsSequence.push(effectFunction);
      this.container.addDynamicProperty(this);
    }
    ShapeProperty.prototype.interpolateShape = interpolateShape;
    ShapeProperty.prototype.getValue = processEffectsSequence;
    ShapeProperty.prototype.setVValue = setVValue;
    ShapeProperty.prototype.addEffect = addEffect;
    function KeyframedShapeProperty(elem, data, type) {
      this.propType = 'shape';
      this.comp = elem.comp;
      this.elem = elem;
      this.container = elem;
      this.offsetTime = elem.data.st;
      this.keyframes = type === 3 ? data.pt.k : data.ks.k;
      this.keyframesMetadata = [];
      this.k = true;
      this.kf = true;
      var len = this.keyframes[0].s[0].i.length;
      this.v = shapePool.newElement();
      this.v.setPathData(this.keyframes[0].s[0].c, len);
      this.pv = shapePool.clone(this.v);
      this.localShapeCollection = shapeCollectionPool.newShapeCollection();
      this.paths = this.localShapeCollection;
      this.paths.addShape(this.v);
      this.lastFrame = initFrame;
      this.reset = resetShape;
      this._caching = {
        lastFrame: initFrame,
        lastIndex: 0
      };
      this.effectsSequence = [interpolateShapeCurrentTime.bind(this)];
    }
    KeyframedShapeProperty.prototype.getValue = processEffectsSequence;
    KeyframedShapeProperty.prototype.interpolateShape = interpolateShape;
    KeyframedShapeProperty.prototype.setVValue = setVValue;
    KeyframedShapeProperty.prototype.addEffect = addEffect;
    var EllShapeProperty = function () {
      var cPoint = roundCorner;
      function EllShapePropertyFactory(elem, data) {
        this.v = shapePool.newElement();
        this.v.setPathData(true, 4);
        this.localShapeCollection = shapeCollectionPool.newShapeCollection();
        this.paths = this.localShapeCollection;
        this.localShapeCollection.addShape(this.v);
        this.d = data.d;
        this.elem = elem;
        this.comp = elem.comp;
        this.frameId = -1;
        this.initDynamicPropertyContainer(elem);
        this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
        this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
        if (this.dynamicProperties.length) {
          this.k = true;
        } else {
          this.k = false;
          this.convertEllToPath();
        }
      }
      EllShapePropertyFactory.prototype = {
        reset: resetShape,
        getValue: function getValue() {
          if (this.elem.globalData.frameId === this.frameId) {
            return;
          }
          this.frameId = this.elem.globalData.frameId;
          this.iterateDynamicProperties();
          if (this._mdf) {
            this.convertEllToPath();
          }
        },
        convertEllToPath: function convertEllToPath() {
          var p0 = this.p.v[0];
          var p1 = this.p.v[1];
          var s0 = this.s.v[0] / 2;
          var s1 = this.s.v[1] / 2;
          var _cw = this.d !== 3;
          var _v = this.v;
          _v.v[0][0] = p0;
          _v.v[0][1] = p1 - s1;
          _v.v[1][0] = _cw ? p0 + s0 : p0 - s0;
          _v.v[1][1] = p1;
          _v.v[2][0] = p0;
          _v.v[2][1] = p1 + s1;
          _v.v[3][0] = _cw ? p0 - s0 : p0 + s0;
          _v.v[3][1] = p1;
          _v.i[0][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
          _v.i[0][1] = p1 - s1;
          _v.i[1][0] = _cw ? p0 + s0 : p0 - s0;
          _v.i[1][1] = p1 - s1 * cPoint;
          _v.i[2][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
          _v.i[2][1] = p1 + s1;
          _v.i[3][0] = _cw ? p0 - s0 : p0 + s0;
          _v.i[3][1] = p1 + s1 * cPoint;
          _v.o[0][0] = _cw ? p0 + s0 * cPoint : p0 - s0 * cPoint;
          _v.o[0][1] = p1 - s1;
          _v.o[1][0] = _cw ? p0 + s0 : p0 - s0;
          _v.o[1][1] = p1 + s1 * cPoint;
          _v.o[2][0] = _cw ? p0 - s0 * cPoint : p0 + s0 * cPoint;
          _v.o[2][1] = p1 + s1;
          _v.o[3][0] = _cw ? p0 - s0 : p0 + s0;
          _v.o[3][1] = p1 - s1 * cPoint;
        }
      };
      extendPrototype([DynamicPropertyContainer], EllShapePropertyFactory);
      return EllShapePropertyFactory;
    }();
    var StarShapeProperty = function () {
      function StarShapePropertyFactory(elem, data) {
        this.v = shapePool.newElement();
        this.v.setPathData(true, 0);
        this.elem = elem;
        this.comp = elem.comp;
        this.data = data;
        this.frameId = -1;
        this.d = data.d;
        this.initDynamicPropertyContainer(elem);
        if (data.sy === 1) {
          this.ir = PropertyFactory.getProp(elem, data.ir, 0, 0, this);
          this.is = PropertyFactory.getProp(elem, data.is, 0, 0.01, this);
          this.convertToPath = this.convertStarToPath;
        } else {
          this.convertToPath = this.convertPolygonToPath;
        }
        this.pt = PropertyFactory.getProp(elem, data.pt, 0, 0, this);
        this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
        this.r = PropertyFactory.getProp(elem, data.r, 0, degToRads, this);
        this.or = PropertyFactory.getProp(elem, data.or, 0, 0, this);
        this.os = PropertyFactory.getProp(elem, data.os, 0, 0.01, this);
        this.localShapeCollection = shapeCollectionPool.newShapeCollection();
        this.localShapeCollection.addShape(this.v);
        this.paths = this.localShapeCollection;
        if (this.dynamicProperties.length) {
          this.k = true;
        } else {
          this.k = false;
          this.convertToPath();
        }
      }
      StarShapePropertyFactory.prototype = {
        reset: resetShape,
        getValue: function getValue() {
          if (this.elem.globalData.frameId === this.frameId) {
            return;
          }
          this.frameId = this.elem.globalData.frameId;
          this.iterateDynamicProperties();
          if (this._mdf) {
            this.convertToPath();
          }
        },
        convertStarToPath: function convertStarToPath() {
          var numPts = Math.floor(this.pt.v) * 2;
          var angle = Math.PI * 2 / numPts;
          /* this.v.v.length = numPts;
                  this.v.i.length = numPts;
                  this.v.o.length = numPts; */
          var longFlag = true;
          var longRad = this.or.v;
          var shortRad = this.ir.v;
          var longRound = this.os.v;
          var shortRound = this.is.v;
          var longPerimSegment = 2 * Math.PI * longRad / (numPts * 2);
          var shortPerimSegment = 2 * Math.PI * shortRad / (numPts * 2);
          var i;
          var rad;
          var roundness;
          var perimSegment;
          var currentAng = -Math.PI / 2;
          currentAng += this.r.v;
          var dir = this.data.d === 3 ? -1 : 1;
          this.v._length = 0;
          for (i = 0; i < numPts; i += 1) {
            rad = longFlag ? longRad : shortRad;
            roundness = longFlag ? longRound : shortRound;
            perimSegment = longFlag ? longPerimSegment : shortPerimSegment;
            var x = rad * Math.cos(currentAng);
            var y = rad * Math.sin(currentAng);
            var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
            var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
            x += +this.p.v[0];
            y += +this.p.v[1];
            this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);

            /* this.v.v[i] = [x,y];
                      this.v.i[i] = [x+ox*perimSegment*roundness*dir,y+oy*perimSegment*roundness*dir];
                      this.v.o[i] = [x-ox*perimSegment*roundness*dir,y-oy*perimSegment*roundness*dir];
                      this.v._length = numPts; */
            longFlag = !longFlag;
            currentAng += angle * dir;
          }
        },
        convertPolygonToPath: function convertPolygonToPath() {
          var numPts = Math.floor(this.pt.v);
          var angle = Math.PI * 2 / numPts;
          var rad = this.or.v;
          var roundness = this.os.v;
          var perimSegment = 2 * Math.PI * rad / (numPts * 4);
          var i;
          var currentAng = -Math.PI * 0.5;
          var dir = this.data.d === 3 ? -1 : 1;
          currentAng += this.r.v;
          this.v._length = 0;
          for (i = 0; i < numPts; i += 1) {
            var x = rad * Math.cos(currentAng);
            var y = rad * Math.sin(currentAng);
            var ox = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
            var oy = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
            x += +this.p.v[0];
            y += +this.p.v[1];
            this.v.setTripleAt(x, y, x - ox * perimSegment * roundness * dir, y - oy * perimSegment * roundness * dir, x + ox * perimSegment * roundness * dir, y + oy * perimSegment * roundness * dir, i, true);
            currentAng += angle * dir;
          }
          this.paths.length = 0;
          this.paths[0] = this.v;
        }
      };
      extendPrototype([DynamicPropertyContainer], StarShapePropertyFactory);
      return StarShapePropertyFactory;
    }();
    var RectShapeProperty = function () {
      function RectShapePropertyFactory(elem, data) {
        this.v = shapePool.newElement();
        this.v.c = true;
        this.localShapeCollection = shapeCollectionPool.newShapeCollection();
        this.localShapeCollection.addShape(this.v);
        this.paths = this.localShapeCollection;
        this.elem = elem;
        this.comp = elem.comp;
        this.frameId = -1;
        this.d = data.d;
        this.initDynamicPropertyContainer(elem);
        this.p = PropertyFactory.getProp(elem, data.p, 1, 0, this);
        this.s = PropertyFactory.getProp(elem, data.s, 1, 0, this);
        this.r = PropertyFactory.getProp(elem, data.r, 0, 0, this);
        if (this.dynamicProperties.length) {
          this.k = true;
        } else {
          this.k = false;
          this.convertRectToPath();
        }
      }
      RectShapePropertyFactory.prototype = {
        convertRectToPath: function convertRectToPath() {
          var p0 = this.p.v[0];
          var p1 = this.p.v[1];
          var v0 = this.s.v[0] / 2;
          var v1 = this.s.v[1] / 2;
          var round = bmMin(v0, v1, this.r.v);
          var cPoint = round * (1 - roundCorner);
          this.v._length = 0;
          if (this.d === 2 || this.d === 1) {
            this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, 0, true);
            this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, p0 + v0, p1 + v1 - round, 1, true);
            if (round !== 0) {
              this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, 2, true);
              this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0 + round, p1 + v1, 3, true);
              this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, 4, true);
              this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1 + round, 5, true);
              this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, 6, true);
              this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, p0 + v0 - round, p1 - v1, 7, true);
            } else {
              this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0 + cPoint, p1 + v1, p0 - v0, p1 + v1, 2);
              this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0, p1 - v1 + cPoint, p0 - v0, p1 - v1, 3);
            }
          } else {
            this.v.setTripleAt(p0 + v0, p1 - v1 + round, p0 + v0, p1 - v1 + cPoint, p0 + v0, p1 - v1 + round, 0, true);
            if (round !== 0) {
              this.v.setTripleAt(p0 + v0 - round, p1 - v1, p0 + v0 - round, p1 - v1, p0 + v0 - cPoint, p1 - v1, 1, true);
              this.v.setTripleAt(p0 - v0 + round, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0 + round, p1 - v1, 2, true);
              this.v.setTripleAt(p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + round, p0 - v0, p1 - v1 + cPoint, 3, true);
              this.v.setTripleAt(p0 - v0, p1 + v1 - round, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1 - round, 4, true);
              this.v.setTripleAt(p0 - v0 + round, p1 + v1, p0 - v0 + round, p1 + v1, p0 - v0 + cPoint, p1 + v1, 5, true);
              this.v.setTripleAt(p0 + v0 - round, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0 - round, p1 + v1, 6, true);
              this.v.setTripleAt(p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - round, p0 + v0, p1 + v1 - cPoint, 7, true);
            } else {
              this.v.setTripleAt(p0 - v0, p1 - v1, p0 - v0 + cPoint, p1 - v1, p0 - v0, p1 - v1, 1, true);
              this.v.setTripleAt(p0 - v0, p1 + v1, p0 - v0, p1 + v1 - cPoint, p0 - v0, p1 + v1, 2, true);
              this.v.setTripleAt(p0 + v0, p1 + v1, p0 + v0 - cPoint, p1 + v1, p0 + v0, p1 + v1, 3, true);
            }
          }
        },
        getValue: function getValue() {
          if (this.elem.globalData.frameId === this.frameId) {
            return;
          }
          this.frameId = this.elem.globalData.frameId;
          this.iterateDynamicProperties();
          if (this._mdf) {
            this.convertRectToPath();
          }
        },
        reset: resetShape
      };
      extendPrototype([DynamicPropertyContainer], RectShapePropertyFactory);
      return RectShapePropertyFactory;
    }();
    function getShapeProp(elem, data, type) {
      var prop;
      if (type === 3 || type === 4) {
        var dataProp = type === 3 ? data.pt : data.ks;
        var keys = dataProp.k;
        if (keys.length) {
          prop = new KeyframedShapeProperty(elem, data, type);
        } else {
          prop = new ShapeProperty(elem, data, type);
        }
      } else if (type === 5) {
        prop = new RectShapeProperty(elem, data);
      } else if (type === 6) {
        prop = new EllShapeProperty(elem, data);
      } else if (type === 7) {
        prop = new StarShapeProperty(elem, data);
      }
      if (prop.k) {
        elem.addDynamicProperty(prop);
      }
      return prop;
    }
    function getConstructorFunction() {
      return ShapeProperty;
    }
    function getKeyframedConstructorFunction() {
      return KeyframedShapeProperty;
    }
    var ob = {};
    ob.getShapeProp = getShapeProp;
    ob.getConstructorFunction = getConstructorFunction;
    ob.getKeyframedConstructorFunction = getKeyframedConstructorFunction;
    return ob;
  }();

  /*!
   Transformation Matrix v2.0
   (c) Epistemex 2014-2015
   www.epistemex.com
   By Ken Fyrstenberg
   Contributions by leeoniya.
   License: MIT, header required.
   */

  /**
   * 2D transformation matrix object initialized with identity matrix.
   *
   * The matrix can synchronize a canvas context by supplying the context
   * as an argument, or later apply current absolute transform to an
   * existing context.
   *
   * All values are handled as floating point values.
   *
   * @param {CanvasRenderingContext2D} [context] - Optional context to sync with Matrix
   * @prop {number} a - scale x
   * @prop {number} b - shear y
   * @prop {number} c - shear x
   * @prop {number} d - scale y
   * @prop {number} e - translate x
   * @prop {number} f - translate y
   * @prop {CanvasRenderingContext2D|null} [context=null] - set or get current canvas context
   * @constructor
   */

  var Matrix = function () {
    var _cos = Math.cos;
    var _sin = Math.sin;
    var _tan = Math.tan;
    var _rnd = Math.round;
    function reset() {
      this.props[0] = 1;
      this.props[1] = 0;
      this.props[2] = 0;
      this.props[3] = 0;
      this.props[4] = 0;
      this.props[5] = 1;
      this.props[6] = 0;
      this.props[7] = 0;
      this.props[8] = 0;
      this.props[9] = 0;
      this.props[10] = 1;
      this.props[11] = 0;
      this.props[12] = 0;
      this.props[13] = 0;
      this.props[14] = 0;
      this.props[15] = 1;
      return this;
    }
    function rotate(angle) {
      if (angle === 0) {
        return this;
      }
      var mCos = _cos(angle);
      var mSin = _sin(angle);
      return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    }
    function rotateX(angle) {
      if (angle === 0) {
        return this;
      }
      var mCos = _cos(angle);
      var mSin = _sin(angle);
      return this._t(1, 0, 0, 0, 0, mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1);
    }
    function rotateY(angle) {
      if (angle === 0) {
        return this;
      }
      var mCos = _cos(angle);
      var mSin = _sin(angle);
      return this._t(mCos, 0, mSin, 0, 0, 1, 0, 0, -mSin, 0, mCos, 0, 0, 0, 0, 1);
    }
    function rotateZ(angle) {
      if (angle === 0) {
        return this;
      }
      var mCos = _cos(angle);
      var mSin = _sin(angle);
      return this._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
    }
    function shear(sx, sy) {
      return this._t(1, sy, sx, 1, 0, 0);
    }
    function skew(ax, ay) {
      return this.shear(_tan(ax), _tan(ay));
    }
    function skewFromAxis(ax, angle) {
      var mCos = _cos(angle);
      var mSin = _sin(angle);
      return this._t(mCos, mSin, 0, 0, -mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(1, 0, 0, 0, _tan(ax), 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)._t(mCos, -mSin, 0, 0, mSin, mCos, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1);
      // return this._t(mCos, mSin, -mSin, mCos, 0, 0)._t(1, 0, _tan(ax), 1, 0, 0)._t(mCos, -mSin, mSin, mCos, 0, 0);
    }
    function scale(sx, sy, sz) {
      if (!sz && sz !== 0) {
        sz = 1;
      }
      if (sx === 1 && sy === 1 && sz === 1) {
        return this;
      }
      return this._t(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, sz, 0, 0, 0, 0, 1);
    }
    function setTransform(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) {
      this.props[0] = a;
      this.props[1] = b;
      this.props[2] = c;
      this.props[3] = d;
      this.props[4] = e;
      this.props[5] = f;
      this.props[6] = g;
      this.props[7] = h;
      this.props[8] = i;
      this.props[9] = j;
      this.props[10] = k;
      this.props[11] = l;
      this.props[12] = m;
      this.props[13] = n;
      this.props[14] = o;
      this.props[15] = p;
      return this;
    }
    function translate(tx, ty, tz) {
      tz = tz || 0;
      if (tx !== 0 || ty !== 0 || tz !== 0) {
        return this._t(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, tx, ty, tz, 1);
      }
      return this;
    }
    function transform(a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) {
      var _p = this.props;
      if (a2 === 1 && b2 === 0 && c2 === 0 && d2 === 0 && e2 === 0 && f2 === 1 && g2 === 0 && h2 === 0 && i2 === 0 && j2 === 0 && k2 === 1 && l2 === 0) {
        // NOTE: commenting this condition because TurboFan deoptimizes code when present
        // if(m2 !== 0 || n2 !== 0 || o2 !== 0){
        _p[12] = _p[12] * a2 + _p[15] * m2;
        _p[13] = _p[13] * f2 + _p[15] * n2;
        _p[14] = _p[14] * k2 + _p[15] * o2;
        _p[15] *= p2;
        // }
        this._identityCalculated = false;
        return this;
      }
      var a1 = _p[0];
      var b1 = _p[1];
      var c1 = _p[2];
      var d1 = _p[3];
      var e1 = _p[4];
      var f1 = _p[5];
      var g1 = _p[6];
      var h1 = _p[7];
      var i1 = _p[8];
      var j1 = _p[9];
      var k1 = _p[10];
      var l1 = _p[11];
      var m1 = _p[12];
      var n1 = _p[13];
      var o1 = _p[14];
      var p1 = _p[15];

      /* matrix order (canvas compatible):
           * ace
           * bdf
           * 001
           */
      _p[0] = a1 * a2 + b1 * e2 + c1 * i2 + d1 * m2;
      _p[1] = a1 * b2 + b1 * f2 + c1 * j2 + d1 * n2;
      _p[2] = a1 * c2 + b1 * g2 + c1 * k2 + d1 * o2;
      _p[3] = a1 * d2 + b1 * h2 + c1 * l2 + d1 * p2;
      _p[4] = e1 * a2 + f1 * e2 + g1 * i2 + h1 * m2;
      _p[5] = e1 * b2 + f1 * f2 + g1 * j2 + h1 * n2;
      _p[6] = e1 * c2 + f1 * g2 + g1 * k2 + h1 * o2;
      _p[7] = e1 * d2 + f1 * h2 + g1 * l2 + h1 * p2;
      _p[8] = i1 * a2 + j1 * e2 + k1 * i2 + l1 * m2;
      _p[9] = i1 * b2 + j1 * f2 + k1 * j2 + l1 * n2;
      _p[10] = i1 * c2 + j1 * g2 + k1 * k2 + l1 * o2;
      _p[11] = i1 * d2 + j1 * h2 + k1 * l2 + l1 * p2;
      _p[12] = m1 * a2 + n1 * e2 + o1 * i2 + p1 * m2;
      _p[13] = m1 * b2 + n1 * f2 + o1 * j2 + p1 * n2;
      _p[14] = m1 * c2 + n1 * g2 + o1 * k2 + p1 * o2;
      _p[15] = m1 * d2 + n1 * h2 + o1 * l2 + p1 * p2;
      this._identityCalculated = false;
      return this;
    }
    function multiply(matrix) {
      var matrixProps = matrix.props;
      return this.transform(matrixProps[0], matrixProps[1], matrixProps[2], matrixProps[3], matrixProps[4], matrixProps[5], matrixProps[6], matrixProps[7], matrixProps[8], matrixProps[9], matrixProps[10], matrixProps[11], matrixProps[12], matrixProps[13], matrixProps[14], matrixProps[15]);
    }
    function isIdentity() {
      if (!this._identityCalculated) {
        this._identity = !(this.props[0] !== 1 || this.props[1] !== 0 || this.props[2] !== 0 || this.props[3] !== 0 || this.props[4] !== 0 || this.props[5] !== 1 || this.props[6] !== 0 || this.props[7] !== 0 || this.props[8] !== 0 || this.props[9] !== 0 || this.props[10] !== 1 || this.props[11] !== 0 || this.props[12] !== 0 || this.props[13] !== 0 || this.props[14] !== 0 || this.props[15] !== 1);
        this._identityCalculated = true;
      }
      return this._identity;
    }
    function equals(matr) {
      var i = 0;
      while (i < 16) {
        if (matr.props[i] !== this.props[i]) {
          return false;
        }
        i += 1;
      }
      return true;
    }
    function clone(matr) {
      var i;
      for (i = 0; i < 16; i += 1) {
        matr.props[i] = this.props[i];
      }
      return matr;
    }
    function cloneFromProps(props) {
      var i;
      for (i = 0; i < 16; i += 1) {
        this.props[i] = props[i];
      }
    }
    function applyToPoint(x, y, z) {
      return {
        x: x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12],
        y: x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13],
        z: x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]
      };
      /* return {
           x: x * me.a + y * me.c + me.e,
           y: x * me.b + y * me.d + me.f
           }; */
    }
    function applyToX(x, y, z) {
      return x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12];
    }
    function applyToY(x, y, z) {
      return x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13];
    }
    function applyToZ(x, y, z) {
      return x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14];
    }
    function getInverseMatrix() {
      var determinant = this.props[0] * this.props[5] - this.props[1] * this.props[4];
      var a = this.props[5] / determinant;
      var b = -this.props[1] / determinant;
      var c = -this.props[4] / determinant;
      var d = this.props[0] / determinant;
      var e = (this.props[4] * this.props[13] - this.props[5] * this.props[12]) / determinant;
      var f = -(this.props[0] * this.props[13] - this.props[1] * this.props[12]) / determinant;
      var inverseMatrix = new Matrix();
      inverseMatrix.props[0] = a;
      inverseMatrix.props[1] = b;
      inverseMatrix.props[4] = c;
      inverseMatrix.props[5] = d;
      inverseMatrix.props[12] = e;
      inverseMatrix.props[13] = f;
      return inverseMatrix;
    }
    function inversePoint(pt) {
      var inverseMatrix = this.getInverseMatrix();
      return inverseMatrix.applyToPointArray(pt[0], pt[1], pt[2] || 0);
    }
    function inversePoints(pts) {
      var i;
      var len = pts.length;
      var retPts = [];
      for (i = 0; i < len; i += 1) {
        retPts[i] = inversePoint(pts[i]);
      }
      return retPts;
    }
    function applyToTriplePoints(pt1, pt2, pt3) {
      var arr = createTypedArray('float32', 6);
      if (this.isIdentity()) {
        arr[0] = pt1[0];
        arr[1] = pt1[1];
        arr[2] = pt2[0];
        arr[3] = pt2[1];
        arr[4] = pt3[0];
        arr[5] = pt3[1];
      } else {
        var p0 = this.props[0];
        var p1 = this.props[1];
        var p4 = this.props[4];
        var p5 = this.props[5];
        var p12 = this.props[12];
        var p13 = this.props[13];
        arr[0] = pt1[0] * p0 + pt1[1] * p4 + p12;
        arr[1] = pt1[0] * p1 + pt1[1] * p5 + p13;
        arr[2] = pt2[0] * p0 + pt2[1] * p4 + p12;
        arr[3] = pt2[0] * p1 + pt2[1] * p5 + p13;
        arr[4] = pt3[0] * p0 + pt3[1] * p4 + p12;
        arr[5] = pt3[0] * p1 + pt3[1] * p5 + p13;
      }
      return arr;
    }
    function applyToPointArray(x, y, z) {
      var arr;
      if (this.isIdentity()) {
        arr = [x, y, z];
      } else {
        arr = [x * this.props[0] + y * this.props[4] + z * this.props[8] + this.props[12], x * this.props[1] + y * this.props[5] + z * this.props[9] + this.props[13], x * this.props[2] + y * this.props[6] + z * this.props[10] + this.props[14]];
      }
      return arr;
    }
    function applyToPointStringified(x, y) {
      if (this.isIdentity()) {
        return x + ',' + y;
      }
      var _p = this.props;
      return Math.round((x * _p[0] + y * _p[4] + _p[12]) * 100) / 100 + ',' + Math.round((x * _p[1] + y * _p[5] + _p[13]) * 100) / 100;
    }
    function toCSS() {
      // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
      /* if(this.isIdentity()) {
              return '';
          } */
      var i = 0;
      var props = this.props;
      var cssValue = 'matrix3d(';
      var v = 10000;
      while (i < 16) {
        cssValue += _rnd(props[i] * v) / v;
        cssValue += i === 15 ? ')' : ',';
        i += 1;
      }
      return cssValue;
    }
    function roundMatrixProperty(val) {
      var v = 10000;
      if (val < 0.000001 && val > 0 || val > -0.000001 && val < 0) {
        return _rnd(val * v) / v;
      }
      return val;
    }
    function to2dCSS() {
      // Doesn't make much sense to add this optimization. If it is an identity matrix, it's very likely this will get called only once since it won't be keyframed.
      /* if(this.isIdentity()) {
              return '';
          } */
      var props = this.props;
      var _a = roundMatrixProperty(props[0]);
      var _b = roundMatrixProperty(props[1]);
      var _c = roundMatrixProperty(props[4]);
      var _d = roundMatrixProperty(props[5]);
      var _e = roundMatrixProperty(props[12]);
      var _f = roundMatrixProperty(props[13]);
      return 'matrix(' + _a + ',' + _b + ',' + _c + ',' + _d + ',' + _e + ',' + _f + ')';
    }
    return function () {
      this.reset = reset;
      this.rotate = rotate;
      this.rotateX = rotateX;
      this.rotateY = rotateY;
      this.rotateZ = rotateZ;
      this.skew = skew;
      this.skewFromAxis = skewFromAxis;
      this.shear = shear;
      this.scale = scale;
      this.setTransform = setTransform;
      this.translate = translate;
      this.transform = transform;
      this.multiply = multiply;
      this.applyToPoint = applyToPoint;
      this.applyToX = applyToX;
      this.applyToY = applyToY;
      this.applyToZ = applyToZ;
      this.applyToPointArray = applyToPointArray;
      this.applyToTriplePoints = applyToTriplePoints;
      this.applyToPointStringified = applyToPointStringified;
      this.toCSS = toCSS;
      this.to2dCSS = to2dCSS;
      this.clone = clone;
      this.cloneFromProps = cloneFromProps;
      this.equals = equals;
      this.inversePoints = inversePoints;
      this.inversePoint = inversePoint;
      this.getInverseMatrix = getInverseMatrix;
      this._t = this.transform;
      this.isIdentity = isIdentity;
      this._identity = true;
      this._identityCalculated = false;
      this.props = createTypedArray('float32', 16);
      this.reset();
    };
  }();
  function _typeof$3(o) {
    "@babel/helpers - typeof";

    return _typeof$3 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$3(o);
  }
  var lottie = {};
  var standalone = '__[STANDALONE]__';
  var animationData = '__[ANIMATIONDATA]__';
  var renderer = '';
  function setLocation(href) {
    setLocationHref(href);
  }
  function searchAnimations() {
    if (standalone === true) {
      animationManager.searchAnimations(animationData, standalone, renderer);
    } else {
      animationManager.searchAnimations();
    }
  }
  function setSubframeRendering(flag) {
    setSubframeEnabled(flag);
  }
  function setPrefix(prefix) {
    setIdPrefix(prefix);
  }
  function loadAnimation(params) {
    if (standalone === true) {
      params.animationData = JSON.parse(animationData);
    }
    return animationManager.loadAnimation(params);
  }
  function setQuality(value) {
    if (typeof value === 'string') {
      switch (value) {
        case 'high':
          setDefaultCurveSegments(200);
          break;
        default:
        case 'medium':
          setDefaultCurveSegments(50);
          break;
        case 'low':
          setDefaultCurveSegments(10);
          break;
      }
    } else if (!isNaN(value) && value > 1) {
      setDefaultCurveSegments(value);
    }
    if (getDefaultCurveSegments() >= 50) {
      roundValues(false);
    } else {
      roundValues(true);
    }
  }
  function inBrowser() {
    return typeof navigator !== 'undefined';
  }
  function installPlugin(type, plugin) {
    if (type === 'expressions') {
      setExpressionsPlugin(plugin);
    }
  }
  function getFactory(name) {
    switch (name) {
      case 'propertyFactory':
        return PropertyFactory;
      case 'shapePropertyFactory':
        return ShapePropertyFactory;
      case 'matrix':
        return Matrix;
      default:
        return null;
    }
  }
  lottie.play = animationManager.play;
  lottie.pause = animationManager.pause;
  lottie.setLocationHref = setLocation;
  lottie.togglePause = animationManager.togglePause;
  lottie.setSpeed = animationManager.setSpeed;
  lottie.setDirection = animationManager.setDirection;
  lottie.stop = animationManager.stop;
  lottie.searchAnimations = searchAnimations;
  lottie.registerAnimation = animationManager.registerAnimation;
  lottie.loadAnimation = loadAnimation;
  lottie.setSubframeRendering = setSubframeRendering;
  lottie.resize = animationManager.resize;
  // lottie.start = start;
  lottie.goToAndStop = animationManager.goToAndStop;
  lottie.destroy = animationManager.destroy;
  lottie.setQuality = setQuality;
  lottie.inBrowser = inBrowser;
  lottie.installPlugin = installPlugin;
  lottie.freeze = animationManager.freeze;
  lottie.unfreeze = animationManager.unfreeze;
  lottie.setVolume = animationManager.setVolume;
  lottie.mute = animationManager.mute;
  lottie.unmute = animationManager.unmute;
  lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
  lottie.useWebWorker = setWebWorker;
  lottie.setIDPrefix = setPrefix;
  lottie.__getFactory = getFactory;
  lottie.version = '5.13.0';
  function checkReady() {
    if (document.readyState === 'complete') {
      clearInterval(readyStateCheckInterval);
      searchAnimations();
    }
  }
  function getQueryVariable(variable) {
    var vars = queryString.split('&');
    for (var i = 0; i < vars.length; i += 1) {
      var pair = vars[i].split('=');
      if (decodeURIComponent(pair[0]) == variable) {
        // eslint-disable-line eqeqeq
        return decodeURIComponent(pair[1]);
      }
    }
    return null;
  }
  var queryString = '';
  if (standalone) {
    var scripts = document.getElementsByTagName('script');
    var index = scripts.length - 1;
    var myScript = scripts[index] || {
      src: ''
    };
    queryString = myScript.src ? myScript.src.replace(/^[^\?]+\??/, '') : ''; // eslint-disable-line no-useless-escape
    renderer = getQueryVariable('renderer');
  }
  var readyStateCheckInterval = setInterval(checkReady, 100);

  // this adds bodymovin to the window object for backwards compatibility
  try {
    if (!(( false ? 0 : _typeof$3(exports)) === 'object' && "object" !== 'undefined') && !( true && __webpack_require__.amdO) // eslint-disable-line no-undef
    ) {}
  } catch (err) {
    //
  }
  var ShapeModifiers = function () {
    var ob = {};
    var modifiers = {};
    ob.registerModifier = registerModifier;
    ob.getModifier = getModifier;
    function registerModifier(nm, factory) {
      if (!modifiers[nm]) {
        modifiers[nm] = factory;
      }
    }
    function getModifier(nm, elem, data) {
      return new modifiers[nm](elem, data);
    }
    return ob;
  }();
  function ShapeModifier() {}
  ShapeModifier.prototype.initModifierProperties = function () {};
  ShapeModifier.prototype.addShapeToModifier = function () {};
  ShapeModifier.prototype.addShape = function (data) {
    if (!this.closed) {
      // Adding shape to dynamic properties. It covers the case where a shape has no effects applied, to reset it's _mdf state on every tick.
      data.sh.container.addDynamicProperty(data.sh);
      var shapeData = {
        shape: data.sh,
        data: data,
        localShapeCollection: shapeCollectionPool.newShapeCollection()
      };
      this.shapes.push(shapeData);
      this.addShapeToModifier(shapeData);
      if (this._isAnimated) {
        data.setAsAnimated();
      }
    }
  };
  ShapeModifier.prototype.init = function (elem, data) {
    this.shapes = [];
    this.elem = elem;
    this.initDynamicPropertyContainer(elem);
    this.initModifierProperties(elem, data);
    this.frameId = initialDefaultFrame;
    this.closed = false;
    this.k = false;
    if (this.dynamicProperties.length) {
      this.k = true;
    } else {
      this.getValue(true);
    }
  };
  ShapeModifier.prototype.processKeys = function () {
    if (this.elem.globalData.frameId === this.frameId) {
      return;
    }
    this.frameId = this.elem.globalData.frameId;
    this.iterateDynamicProperties();
  };
  extendPrototype([DynamicPropertyContainer], ShapeModifier);
  function TrimModifier() {}
  extendPrototype([ShapeModifier], TrimModifier);
  TrimModifier.prototype.initModifierProperties = function (elem, data) {
    this.s = PropertyFactory.getProp(elem, data.s, 0, 0.01, this);
    this.e = PropertyFactory.getProp(elem, data.e, 0, 0.01, this);
    this.o = PropertyFactory.getProp(elem, data.o, 0, 0, this);
    this.sValue = 0;
    this.eValue = 0;
    this.getValue = this.processKeys;
    this.m = data.m;
    this._isAnimated = !!this.s.effectsSequence.length || !!this.e.effectsSequence.length || !!this.o.effectsSequence.length;
  };
  TrimModifier.prototype.addShapeToModifier = function (shapeData) {
    shapeData.pathsData = [];
  };
  TrimModifier.prototype.calculateShapeEdges = function (s, e, shapeLength, addedLength, totalModifierLength) {
    var segments = [];
    if (e <= 1) {
      segments.push({
        s: s,
        e: e
      });
    } else if (s >= 1) {
      segments.push({
        s: s - 1,
        e: e - 1
      });
    } else {
      segments.push({
        s: s,
        e: 1
      });
      segments.push({
        s: 0,
        e: e - 1
      });
    }
    var shapeSegments = [];
    var i;
    var len = segments.length;
    var segmentOb;
    for (i = 0; i < len; i += 1) {
      segmentOb = segments[i];
      if (!(segmentOb.e * totalModifierLength < addedLength || segmentOb.s * totalModifierLength > addedLength + shapeLength)) {
        var shapeS;
        var shapeE;
        if (segmentOb.s * totalModifierLength <= addedLength) {
          shapeS = 0;
        } else {
          shapeS = (segmentOb.s * totalModifierLength - addedLength) / shapeLength;
        }
        if (segmentOb.e * totalModifierLength >= addedLength + shapeLength) {
          shapeE = 1;
        } else {
          shapeE = (segmentOb.e * totalModifierLength - addedLength) / shapeLength;
        }
        shapeSegments.push([shapeS, shapeE]);
      }
    }
    if (!shapeSegments.length) {
      shapeSegments.push([0, 0]);
    }
    return shapeSegments;
  };
  TrimModifier.prototype.releasePathsData = function (pathsData) {
    var i;
    var len = pathsData.length;
    for (i = 0; i < len; i += 1) {
      segmentsLengthPool.release(pathsData[i]);
    }
    pathsData.length = 0;
    return pathsData;
  };
  TrimModifier.prototype.processShapes = function (_isFirstFrame) {
    var s;
    var e;
    if (this._mdf || _isFirstFrame) {
      var o = this.o.v % 360 / 360;
      if (o < 0) {
        o += 1;
      }
      if (this.s.v > 1) {
        s = 1 + o;
      } else if (this.s.v < 0) {
        s = 0 + o;
      } else {
        s = this.s.v + o;
      }
      if (this.e.v > 1) {
        e = 1 + o;
      } else if (this.e.v < 0) {
        e = 0 + o;
      } else {
        e = this.e.v + o;
      }
      if (s > e) {
        var _s = s;
        s = e;
        e = _s;
      }
      s = Math.round(s * 10000) * 0.0001;
      e = Math.round(e * 10000) * 0.0001;
      this.sValue = s;
      this.eValue = e;
    } else {
      s = this.sValue;
      e = this.eValue;
    }
    var shapePaths;
    var i;
    var len = this.shapes.length;
    var j;
    var jLen;
    var pathsData;
    var pathData;
    var totalShapeLength;
    var totalModifierLength = 0;
    if (e === s) {
      for (i = 0; i < len; i += 1) {
        this.shapes[i].localShapeCollection.releaseShapes();
        this.shapes[i].shape._mdf = true;
        this.shapes[i].shape.paths = this.shapes[i].localShapeCollection;
        if (this._mdf) {
          this.shapes[i].pathsData.length = 0;
        }
      }
    } else if (!(e === 1 && s === 0 || e === 0 && s === 1)) {
      var segments = [];
      var shapeData;
      var localShapeCollection;
      for (i = 0; i < len; i += 1) {
        shapeData = this.shapes[i];
        // if shape hasn't changed and trim properties haven't changed, cached previous path can be used
        if (!shapeData.shape._mdf && !this._mdf && !_isFirstFrame && this.m !== 2) {
          shapeData.shape.paths = shapeData.localShapeCollection;
        } else {
          shapePaths = shapeData.shape.paths;
          jLen = shapePaths._length;
          totalShapeLength = 0;
          if (!shapeData.shape._mdf && shapeData.pathsData.length) {
            totalShapeLength = shapeData.totalShapeLength;
          } else {
            pathsData = this.releasePathsData(shapeData.pathsData);
            for (j = 0; j < jLen; j += 1) {
              pathData = bez.getSegmentsLength(shapePaths.shapes[j]);
              pathsData.push(pathData);
              totalShapeLength += pathData.totalLength;
            }
            shapeData.totalShapeLength = totalShapeLength;
            shapeData.pathsData = pathsData;
          }
          totalModifierLength += totalShapeLength;
          shapeData.shape._mdf = true;
        }
      }
      var shapeS = s;
      var shapeE = e;
      var addedLength = 0;
      var edges;
      for (i = len - 1; i >= 0; i -= 1) {
        shapeData = this.shapes[i];
        if (shapeData.shape._mdf) {
          localShapeCollection = shapeData.localShapeCollection;
          localShapeCollection.releaseShapes();
          // if m === 2 means paths are trimmed individually so edges need to be found for this specific shape relative to whoel group
          if (this.m === 2 && len > 1) {
            edges = this.calculateShapeEdges(s, e, shapeData.totalShapeLength, addedLength, totalModifierLength);
            addedLength += shapeData.totalShapeLength;
          } else {
            edges = [[shapeS, shapeE]];
          }
          jLen = edges.length;
          for (j = 0; j < jLen; j += 1) {
            shapeS = edges[j][0];
            shapeE = edges[j][1];
            segments.length = 0;
            if (shapeE <= 1) {
              segments.push({
                s: shapeData.totalShapeLength * shapeS,
                e: shapeData.totalShapeLength * shapeE
              });
            } else if (shapeS >= 1) {
              segments.push({
                s: shapeData.totalShapeLength * (shapeS - 1),
                e: shapeData.totalShapeLength * (shapeE - 1)
              });
            } else {
              segments.push({
                s: shapeData.totalShapeLength * shapeS,
                e: shapeData.totalShapeLength
              });
              segments.push({
                s: 0,
                e: shapeData.totalShapeLength * (shapeE - 1)
              });
            }
            var newShapesData = this.addShapes(shapeData, segments[0]);
            if (segments[0].s !== segments[0].e) {
              if (segments.length > 1) {
                var lastShapeInCollection = shapeData.shape.paths.shapes[shapeData.shape.paths._length - 1];
                if (lastShapeInCollection.c) {
                  var lastShape = newShapesData.pop();
                  this.addPaths(newShapesData, localShapeCollection);
                  newShapesData = this.addShapes(shapeData, segments[1], lastShape);
                } else {
                  this.addPaths(newShapesData, localShapeCollection);
                  newShapesData = this.addShapes(shapeData, segments[1]);
                }
              }
              this.addPaths(newShapesData, localShapeCollection);
            }
          }
          shapeData.shape.paths = localShapeCollection;
        }
      }
    } else if (this._mdf) {
      for (i = 0; i < len; i += 1) {
        // Releasign Trim Cached paths data when no trim applied in case shapes are modified inbetween.
        // Don't remove this even if it's losing cached info.
        this.shapes[i].pathsData.length = 0;
        this.shapes[i].shape._mdf = true;
      }
    }
  };
  TrimModifier.prototype.addPaths = function (newPaths, localShapeCollection) {
    var i;
    var len = newPaths.length;
    for (i = 0; i < len; i += 1) {
      localShapeCollection.addShape(newPaths[i]);
    }
  };
  TrimModifier.prototype.addSegment = function (pt1, pt2, pt3, pt4, shapePath, pos, newShape) {
    shapePath.setXYAt(pt2[0], pt2[1], 'o', pos);
    shapePath.setXYAt(pt3[0], pt3[1], 'i', pos + 1);
    if (newShape) {
      shapePath.setXYAt(pt1[0], pt1[1], 'v', pos);
    }
    shapePath.setXYAt(pt4[0], pt4[1], 'v', pos + 1);
  };
  TrimModifier.prototype.addSegmentFromArray = function (points, shapePath, pos, newShape) {
    shapePath.setXYAt(points[1], points[5], 'o', pos);
    shapePath.setXYAt(points[2], points[6], 'i', pos + 1);
    if (newShape) {
      shapePath.setXYAt(points[0], points[4], 'v', pos);
    }
    shapePath.setXYAt(points[3], points[7], 'v', pos + 1);
  };
  TrimModifier.prototype.addShapes = function (shapeData, shapeSegment, shapePath) {
    var pathsData = shapeData.pathsData;
    var shapePaths = shapeData.shape.paths.shapes;
    var i;
    var len = shapeData.shape.paths._length;
    var j;
    var jLen;
    var addedLength = 0;
    var currentLengthData;
    var segmentCount;
    var lengths;
    var segment;
    var shapes = [];
    var initPos;
    var newShape = true;
    if (!shapePath) {
      shapePath = shapePool.newElement();
      segmentCount = 0;
      initPos = 0;
    } else {
      segmentCount = shapePath._length;
      initPos = shapePath._length;
    }
    shapes.push(shapePath);
    for (i = 0; i < len; i += 1) {
      lengths = pathsData[i].lengths;
      shapePath.c = shapePaths[i].c;
      jLen = shapePaths[i].c ? lengths.length : lengths.length + 1;
      for (j = 1; j < jLen; j += 1) {
        currentLengthData = lengths[j - 1];
        if (addedLength + currentLengthData.addedLength < shapeSegment.s) {
          addedLength += currentLengthData.addedLength;
          shapePath.c = false;
        } else if (addedLength > shapeSegment.e) {
          shapePath.c = false;
          break;
        } else {
          if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + currentLengthData.addedLength) {
            this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[j], shapePaths[i].v[j], shapePath, segmentCount, newShape);
            newShape = false;
          } else {
            segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[j], shapePaths[i].o[j - 1], shapePaths[i].i[j], (shapeSegment.s - addedLength) / currentLengthData.addedLength, (shapeSegment.e - addedLength) / currentLengthData.addedLength, lengths[j - 1]);
            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
            newShape = false;
            shapePath.c = false;
          }
          addedLength += currentLengthData.addedLength;
          segmentCount += 1;
        }
      }
      if (shapePaths[i].c && lengths.length) {
        currentLengthData = lengths[j - 1];
        if (addedLength <= shapeSegment.e) {
          var segmentLength = lengths[j - 1].addedLength;
          if (shapeSegment.s <= addedLength && shapeSegment.e >= addedLength + segmentLength) {
            this.addSegment(shapePaths[i].v[j - 1], shapePaths[i].o[j - 1], shapePaths[i].i[0], shapePaths[i].v[0], shapePath, segmentCount, newShape);
            newShape = false;
          } else {
            segment = bez.getNewSegment(shapePaths[i].v[j - 1], shapePaths[i].v[0], shapePaths[i].o[j - 1], shapePaths[i].i[0], (shapeSegment.s - addedLength) / segmentLength, (shapeSegment.e - addedLength) / segmentLength, lengths[j - 1]);
            this.addSegmentFromArray(segment, shapePath, segmentCount, newShape);
            // this.addSegment(segment.pt1, segment.pt3, segment.pt4, segment.pt2, shapePath, segmentCount, newShape);
            newShape = false;
            shapePath.c = false;
          }
        } else {
          shapePath.c = false;
        }
        addedLength += currentLengthData.addedLength;
        segmentCount += 1;
      }
      if (shapePath._length) {
        shapePath.setXYAt(shapePath.v[initPos][0], shapePath.v[initPos][1], 'i', initPos);
        shapePath.setXYAt(shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1], 'o', shapePath._length - 1);
      }
      if (addedLength > shapeSegment.e) {
        break;
      }
      if (i < len - 1) {
        shapePath = shapePool.newElement();
        newShape = true;
        shapes.push(shapePath);
        segmentCount = 0;
      }
    }
    return shapes;
  };
  function PuckerAndBloatModifier() {}
  extendPrototype([ShapeModifier], PuckerAndBloatModifier);
  PuckerAndBloatModifier.prototype.initModifierProperties = function (elem, data) {
    this.getValue = this.processKeys;
    this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
    this._isAnimated = !!this.amount.effectsSequence.length;
  };
  PuckerAndBloatModifier.prototype.processPath = function (path, amount) {
    var percent = amount / 100;
    var centerPoint = [0, 0];
    var pathLength = path._length;
    var i = 0;
    for (i = 0; i < pathLength; i += 1) {
      centerPoint[0] += path.v[i][0];
      centerPoint[1] += path.v[i][1];
    }
    centerPoint[0] /= pathLength;
    centerPoint[1] /= pathLength;
    var clonedPath = shapePool.newElement();
    clonedPath.c = path.c;
    var vX;
    var vY;
    var oX;
    var oY;
    var iX;
    var iY;
    for (i = 0; i < pathLength; i += 1) {
      vX = path.v[i][0] + (centerPoint[0] - path.v[i][0]) * percent;
      vY = path.v[i][1] + (centerPoint[1] - path.v[i][1]) * percent;
      oX = path.o[i][0] + (centerPoint[0] - path.o[i][0]) * -percent;
      oY = path.o[i][1] + (centerPoint[1] - path.o[i][1]) * -percent;
      iX = path.i[i][0] + (centerPoint[0] - path.i[i][0]) * -percent;
      iY = path.i[i][1] + (centerPoint[1] - path.i[i][1]) * -percent;
      clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, i);
    }
    return clonedPath;
  };
  PuckerAndBloatModifier.prototype.processShapes = function (_isFirstFrame) {
    var shapePaths;
    var i;
    var len = this.shapes.length;
    var j;
    var jLen;
    var amount = this.amount.v;
    if (amount !== 0) {
      var shapeData;
      var localShapeCollection;
      for (i = 0; i < len; i += 1) {
        shapeData = this.shapes[i];
        localShapeCollection = shapeData.localShapeCollection;
        if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
          localShapeCollection.releaseShapes();
          shapeData.shape._mdf = true;
          shapePaths = shapeData.shape.paths.shapes;
          jLen = shapeData.shape.paths._length;
          for (j = 0; j < jLen; j += 1) {
            localShapeCollection.addShape(this.processPath(shapePaths[j], amount));
          }
        }
        shapeData.shape.paths = shapeData.localShapeCollection;
      }
    }
    if (!this.dynamicProperties.length) {
      this._mdf = false;
    }
  };
  var TransformPropertyFactory = function () {
    var defaultVector = [0, 0];
    function applyToMatrix(mat) {
      var _mdf = this._mdf;
      this.iterateDynamicProperties();
      this._mdf = this._mdf || _mdf;
      if (this.a) {
        mat.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
      }
      if (this.s) {
        mat.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
      }
      if (this.sk) {
        mat.skewFromAxis(-this.sk.v, this.sa.v);
      }
      if (this.r) {
        mat.rotate(-this.r.v);
      } else {
        mat.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
      }
      if (this.data.p.s) {
        if (this.data.p.z) {
          mat.translate(this.px.v, this.py.v, -this.pz.v);
        } else {
          mat.translate(this.px.v, this.py.v, 0);
        }
      } else {
        mat.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
      }
    }
    function processKeys(forceRender) {
      if (this.elem.globalData.frameId === this.frameId) {
        return;
      }
      if (this._isDirty) {
        this.precalculateMatrix();
        this._isDirty = false;
      }
      this.iterateDynamicProperties();
      if (this._mdf || forceRender) {
        var frameRate;
        this.v.cloneFromProps(this.pre.props);
        if (this.appliedTransformations < 1) {
          this.v.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
        }
        if (this.appliedTransformations < 2) {
          this.v.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
        }
        if (this.sk && this.appliedTransformations < 3) {
          this.v.skewFromAxis(-this.sk.v, this.sa.v);
        }
        if (this.r && this.appliedTransformations < 4) {
          this.v.rotate(-this.r.v);
        } else if (!this.r && this.appliedTransformations < 4) {
          this.v.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
        }
        if (this.autoOriented) {
          var v1;
          var v2;
          frameRate = this.elem.globalData.frameRate;
          if (this.p && this.p.keyframes && this.p.getValueAtTime) {
            if (this.p._caching.lastFrame + this.p.offsetTime <= this.p.keyframes[0].t) {
              v1 = this.p.getValueAtTime((this.p.keyframes[0].t + 0.01) / frameRate, 0);
              v2 = this.p.getValueAtTime(this.p.keyframes[0].t / frameRate, 0);
            } else if (this.p._caching.lastFrame + this.p.offsetTime >= this.p.keyframes[this.p.keyframes.length - 1].t) {
              v1 = this.p.getValueAtTime(this.p.keyframes[this.p.keyframes.length - 1].t / frameRate, 0);
              v2 = this.p.getValueAtTime((this.p.keyframes[this.p.keyframes.length - 1].t - 0.05) / frameRate, 0);
            } else {
              v1 = this.p.pv;
              v2 = this.p.getValueAtTime((this.p._caching.lastFrame + this.p.offsetTime - 0.01) / frameRate, this.p.offsetTime);
            }
          } else if (this.px && this.px.keyframes && this.py.keyframes && this.px.getValueAtTime && this.py.getValueAtTime) {
            v1 = [];
            v2 = [];
            var px = this.px;
            var py = this.py;
            if (px._caching.lastFrame + px.offsetTime <= px.keyframes[0].t) {
              v1[0] = px.getValueAtTime((px.keyframes[0].t + 0.01) / frameRate, 0);
              v1[1] = py.getValueAtTime((py.keyframes[0].t + 0.01) / frameRate, 0);
              v2[0] = px.getValueAtTime(px.keyframes[0].t / frameRate, 0);
              v2[1] = py.getValueAtTime(py.keyframes[0].t / frameRate, 0);
            } else if (px._caching.lastFrame + px.offsetTime >= px.keyframes[px.keyframes.length - 1].t) {
              v1[0] = px.getValueAtTime(px.keyframes[px.keyframes.length - 1].t / frameRate, 0);
              v1[1] = py.getValueAtTime(py.keyframes[py.keyframes.length - 1].t / frameRate, 0);
              v2[0] = px.getValueAtTime((px.keyframes[px.keyframes.length - 1].t - 0.01) / frameRate, 0);
              v2[1] = py.getValueAtTime((py.keyframes[py.keyframes.length - 1].t - 0.01) / frameRate, 0);
            } else {
              v1 = [px.pv, py.pv];
              v2[0] = px.getValueAtTime((px._caching.lastFrame + px.offsetTime - 0.01) / frameRate, px.offsetTime);
              v2[1] = py.getValueAtTime((py._caching.lastFrame + py.offsetTime - 0.01) / frameRate, py.offsetTime);
            }
          } else {
            v2 = defaultVector;
            v1 = v2;
          }
          this.v.rotate(-Math.atan2(v1[1] - v2[1], v1[0] - v2[0]));
        }
        if (this.data.p && this.data.p.s) {
          if (this.data.p.z) {
            this.v.translate(this.px.v, this.py.v, -this.pz.v);
          } else {
            this.v.translate(this.px.v, this.py.v, 0);
          }
        } else {
          this.v.translate(this.p.v[0], this.p.v[1], -this.p.v[2]);
        }
      }
      this.frameId = this.elem.globalData.frameId;
    }
    function precalculateMatrix() {
      this.appliedTransformations = 0;
      this.pre.reset();
      if (!this.a.effectsSequence.length) {
        this.pre.translate(-this.a.v[0], -this.a.v[1], this.a.v[2]);
        this.appliedTransformations = 1;
      } else {
        return;
      }
      if (!this.s.effectsSequence.length) {
        this.pre.scale(this.s.v[0], this.s.v[1], this.s.v[2]);
        this.appliedTransformations = 2;
      } else {
        return;
      }
      if (this.sk) {
        if (!this.sk.effectsSequence.length && !this.sa.effectsSequence.length) {
          this.pre.skewFromAxis(-this.sk.v, this.sa.v);
          this.appliedTransformations = 3;
        } else {
          return;
        }
      }
      if (this.r) {
        if (!this.r.effectsSequence.length) {
          this.pre.rotate(-this.r.v);
          this.appliedTransformations = 4;
        }
      } else if (!this.rz.effectsSequence.length && !this.ry.effectsSequence.length && !this.rx.effectsSequence.length && !this.or.effectsSequence.length) {
        this.pre.rotateZ(-this.rz.v).rotateY(this.ry.v).rotateX(this.rx.v).rotateZ(-this.or.v[2]).rotateY(this.or.v[1]).rotateX(this.or.v[0]);
        this.appliedTransformations = 4;
      }
    }
    function autoOrient() {
      //
      // var prevP = this.getValueAtTime();
    }
    function addDynamicProperty(prop) {
      this._addDynamicProperty(prop);
      this.elem.addDynamicProperty(prop);
      this._isDirty = true;
    }
    function TransformProperty(elem, data, container) {
      this.elem = elem;
      this.frameId = -1;
      this.propType = 'transform';
      this.data = data;
      this.v = new Matrix();
      // Precalculated matrix with non animated properties
      this.pre = new Matrix();
      this.appliedTransformations = 0;
      this.initDynamicPropertyContainer(container || elem);
      if (data.p && data.p.s) {
        this.px = PropertyFactory.getProp(elem, data.p.x, 0, 0, this);
        this.py = PropertyFactory.getProp(elem, data.p.y, 0, 0, this);
        if (data.p.z) {
          this.pz = PropertyFactory.getProp(elem, data.p.z, 0, 0, this);
        }
      } else {
        this.p = PropertyFactory.getProp(elem, data.p || {
          k: [0, 0, 0]
        }, 1, 0, this);
      }
      if (data.rx) {
        this.rx = PropertyFactory.getProp(elem, data.rx, 0, degToRads, this);
        this.ry = PropertyFactory.getProp(elem, data.ry, 0, degToRads, this);
        this.rz = PropertyFactory.getProp(elem, data.rz, 0, degToRads, this);
        if (data.or.k[0].ti) {
          var i;
          var len = data.or.k.length;
          for (i = 0; i < len; i += 1) {
            data.or.k[i].to = null;
            data.or.k[i].ti = null;
          }
        }
        this.or = PropertyFactory.getProp(elem, data.or, 1, degToRads, this);
        // sh Indicates it needs to be capped between -180 and 180
        this.or.sh = true;
      } else {
        this.r = PropertyFactory.getProp(elem, data.r || {
          k: 0
        }, 0, degToRads, this);
      }
      if (data.sk) {
        this.sk = PropertyFactory.getProp(elem, data.sk, 0, degToRads, this);
        this.sa = PropertyFactory.getProp(elem, data.sa, 0, degToRads, this);
      }
      this.a = PropertyFactory.getProp(elem, data.a || {
        k: [0, 0, 0]
      }, 1, 0, this);
      this.s = PropertyFactory.getProp(elem, data.s || {
        k: [100, 100, 100]
      }, 1, 0.01, this);
      // Opacity is not part of the transform properties, that's why it won't use this.dynamicProperties. That way transforms won't get updated if opacity changes.
      if (data.o) {
        this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, elem);
      } else {
        this.o = {
          _mdf: false,
          v: 1
        };
      }
      this._isDirty = true;
      if (!this.dynamicProperties.length) {
        this.getValue(true);
      }
    }
    TransformProperty.prototype = {
      applyToMatrix: applyToMatrix,
      getValue: processKeys,
      precalculateMatrix: precalculateMatrix,
      autoOrient: autoOrient
    };
    extendPrototype([DynamicPropertyContainer], TransformProperty);
    TransformProperty.prototype.addDynamicProperty = addDynamicProperty;
    TransformProperty.prototype._addDynamicProperty = DynamicPropertyContainer.prototype.addDynamicProperty;
    function getTransformProperty(elem, data, container) {
      return new TransformProperty(elem, data, container);
    }
    return {
      getTransformProperty: getTransformProperty
    };
  }();
  function RepeaterModifier() {}
  extendPrototype([ShapeModifier], RepeaterModifier);
  RepeaterModifier.prototype.initModifierProperties = function (elem, data) {
    this.getValue = this.processKeys;
    this.c = PropertyFactory.getProp(elem, data.c, 0, null, this);
    this.o = PropertyFactory.getProp(elem, data.o, 0, null, this);
    this.tr = TransformPropertyFactory.getTransformProperty(elem, data.tr, this);
    this.so = PropertyFactory.getProp(elem, data.tr.so, 0, 0.01, this);
    this.eo = PropertyFactory.getProp(elem, data.tr.eo, 0, 0.01, this);
    this.data = data;
    if (!this.dynamicProperties.length) {
      this.getValue(true);
    }
    this._isAnimated = !!this.dynamicProperties.length;
    this.pMatrix = new Matrix();
    this.rMatrix = new Matrix();
    this.sMatrix = new Matrix();
    this.tMatrix = new Matrix();
    this.matrix = new Matrix();
  };
  RepeaterModifier.prototype.applyTransforms = function (pMatrix, rMatrix, sMatrix, transform, perc, inv) {
    var dir = inv ? -1 : 1;
    var scaleX = transform.s.v[0] + (1 - transform.s.v[0]) * (1 - perc);
    var scaleY = transform.s.v[1] + (1 - transform.s.v[1]) * (1 - perc);
    pMatrix.translate(transform.p.v[0] * dir * perc, transform.p.v[1] * dir * perc, transform.p.v[2]);
    rMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
    rMatrix.rotate(-transform.r.v * dir * perc);
    rMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
    sMatrix.translate(-transform.a.v[0], -transform.a.v[1], transform.a.v[2]);
    sMatrix.scale(inv ? 1 / scaleX : scaleX, inv ? 1 / scaleY : scaleY);
    sMatrix.translate(transform.a.v[0], transform.a.v[1], transform.a.v[2]);
  };
  RepeaterModifier.prototype.init = function (elem, arr, pos, elemsData) {
    this.elem = elem;
    this.arr = arr;
    this.pos = pos;
    this.elemsData = elemsData;
    this._currentCopies = 0;
    this._elements = [];
    this._groups = [];
    this.frameId = -1;
    this.initDynamicPropertyContainer(elem);
    this.initModifierProperties(elem, arr[pos]);
    while (pos > 0) {
      pos -= 1;
      // this._elements.unshift(arr.splice(pos,1)[0]);
      this._elements.unshift(arr[pos]);
    }
    if (this.dynamicProperties.length) {
      this.k = true;
    } else {
      this.getValue(true);
    }
  };
  RepeaterModifier.prototype.resetElements = function (elements) {
    var i;
    var len = elements.length;
    for (i = 0; i < len; i += 1) {
      elements[i]._processed = false;
      if (elements[i].ty === 'gr') {
        this.resetElements(elements[i].it);
      }
    }
  };
  RepeaterModifier.prototype.cloneElements = function (elements) {
    var newElements = JSON.parse(JSON.stringify(elements));
    this.resetElements(newElements);
    return newElements;
  };
  RepeaterModifier.prototype.changeGroupRender = function (elements, renderFlag) {
    var i;
    var len = elements.length;
    for (i = 0; i < len; i += 1) {
      elements[i]._render = renderFlag;
      if (elements[i].ty === 'gr') {
        this.changeGroupRender(elements[i].it, renderFlag);
      }
    }
  };
  RepeaterModifier.prototype.processShapes = function (_isFirstFrame) {
    var items;
    var itemsTransform;
    var i;
    var dir;
    var cont;
    var hasReloaded = false;
    if (this._mdf || _isFirstFrame) {
      var copies = Math.ceil(this.c.v);
      if (this._groups.length < copies) {
        while (this._groups.length < copies) {
          var group = {
            it: this.cloneElements(this._elements),
            ty: 'gr'
          };
          group.it.push({
            a: {
              a: 0,
              ix: 1,
              k: [0, 0]
            },
            nm: 'Transform',
            o: {
              a: 0,
              ix: 7,
              k: 100
            },
            p: {
              a: 0,
              ix: 2,
              k: [0, 0]
            },
            r: {
              a: 1,
              ix: 6,
              k: [{
                s: 0,
                e: 0,
                t: 0
              }, {
                s: 0,
                e: 0,
                t: 1
              }]
            },
            s: {
              a: 0,
              ix: 3,
              k: [100, 100]
            },
            sa: {
              a: 0,
              ix: 5,
              k: 0
            },
            sk: {
              a: 0,
              ix: 4,
              k: 0
            },
            ty: 'tr'
          });
          this.arr.splice(0, 0, group);
          this._groups.splice(0, 0, group);
          this._currentCopies += 1;
        }
        this.elem.reloadShapes();
        hasReloaded = true;
      }
      cont = 0;
      var renderFlag;
      for (i = 0; i <= this._groups.length - 1; i += 1) {
        renderFlag = cont < copies;
        this._groups[i]._render = renderFlag;
        this.changeGroupRender(this._groups[i].it, renderFlag);
        if (!renderFlag) {
          var elems = this.elemsData[i].it;
          var transformData = elems[elems.length - 1];
          if (transformData.transform.op.v !== 0) {
            transformData.transform.op._mdf = true;
            transformData.transform.op.v = 0;
          } else {
            transformData.transform.op._mdf = false;
          }
        }
        cont += 1;
      }
      this._currentCopies = copies;
      /// /

      var offset = this.o.v;
      var offsetModulo = offset % 1;
      var roundOffset = offset > 0 ? Math.floor(offset) : Math.ceil(offset);
      var pProps = this.pMatrix.props;
      var rProps = this.rMatrix.props;
      var sProps = this.sMatrix.props;
      this.pMatrix.reset();
      this.rMatrix.reset();
      this.sMatrix.reset();
      this.tMatrix.reset();
      this.matrix.reset();
      var iteration = 0;
      if (offset > 0) {
        while (iteration < roundOffset) {
          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
          iteration += 1;
        }
        if (offsetModulo) {
          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, offsetModulo, false);
          iteration += offsetModulo;
        }
      } else if (offset < 0) {
        while (iteration > roundOffset) {
          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, true);
          iteration -= 1;
        }
        if (offsetModulo) {
          this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, -offsetModulo, true);
          iteration -= offsetModulo;
        }
      }
      i = this.data.m === 1 ? 0 : this._currentCopies - 1;
      dir = this.data.m === 1 ? 1 : -1;
      cont = this._currentCopies;
      var j;
      var jLen;
      while (cont) {
        items = this.elemsData[i].it;
        itemsTransform = items[items.length - 1].transform.mProps.v.props;
        jLen = itemsTransform.length;
        items[items.length - 1].transform.mProps._mdf = true;
        items[items.length - 1].transform.op._mdf = true;
        items[items.length - 1].transform.op.v = this._currentCopies === 1 ? this.so.v : this.so.v + (this.eo.v - this.so.v) * (i / (this._currentCopies - 1));
        if (iteration !== 0) {
          if (i !== 0 && dir === 1 || i !== this._currentCopies - 1 && dir === -1) {
            this.applyTransforms(this.pMatrix, this.rMatrix, this.sMatrix, this.tr, 1, false);
          }
          this.matrix.transform(rProps[0], rProps[1], rProps[2], rProps[3], rProps[4], rProps[5], rProps[6], rProps[7], rProps[8], rProps[9], rProps[10], rProps[11], rProps[12], rProps[13], rProps[14], rProps[15]);
          this.matrix.transform(sProps[0], sProps[1], sProps[2], sProps[3], sProps[4], sProps[5], sProps[6], sProps[7], sProps[8], sProps[9], sProps[10], sProps[11], sProps[12], sProps[13], sProps[14], sProps[15]);
          this.matrix.transform(pProps[0], pProps[1], pProps[2], pProps[3], pProps[4], pProps[5], pProps[6], pProps[7], pProps[8], pProps[9], pProps[10], pProps[11], pProps[12], pProps[13], pProps[14], pProps[15]);
          for (j = 0; j < jLen; j += 1) {
            itemsTransform[j] = this.matrix.props[j];
          }
          this.matrix.reset();
        } else {
          this.matrix.reset();
          for (j = 0; j < jLen; j += 1) {
            itemsTransform[j] = this.matrix.props[j];
          }
        }
        iteration += 1;
        cont -= 1;
        i += dir;
      }
    } else {
      cont = this._currentCopies;
      i = 0;
      dir = 1;
      while (cont) {
        items = this.elemsData[i].it;
        itemsTransform = items[items.length - 1].transform.mProps.v.props;
        items[items.length - 1].transform.mProps._mdf = false;
        items[items.length - 1].transform.op._mdf = false;
        cont -= 1;
        i += dir;
      }
    }
    return hasReloaded;
  };
  RepeaterModifier.prototype.addShape = function () {};
  function RoundCornersModifier() {}
  extendPrototype([ShapeModifier], RoundCornersModifier);
  RoundCornersModifier.prototype.initModifierProperties = function (elem, data) {
    this.getValue = this.processKeys;
    this.rd = PropertyFactory.getProp(elem, data.r, 0, null, this);
    this._isAnimated = !!this.rd.effectsSequence.length;
  };
  RoundCornersModifier.prototype.processPath = function (path, round) {
    var clonedPath = shapePool.newElement();
    clonedPath.c = path.c;
    var i;
    var len = path._length;
    var currentV;
    var currentI;
    var currentO;
    var closerV;
    var distance;
    var newPosPerc;
    var index = 0;
    var vX;
    var vY;
    var oX;
    var oY;
    var iX;
    var iY;
    for (i = 0; i < len; i += 1) {
      currentV = path.v[i];
      currentO = path.o[i];
      currentI = path.i[i];
      if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
        if ((i === 0 || i === len - 1) && !path.c) {
          clonedPath.setTripleAt(currentV[0], currentV[1], currentO[0], currentO[1], currentI[0], currentI[1], index);
          /* clonedPath.v[index] = currentV;
                  clonedPath.o[index] = currentO;
                  clonedPath.i[index] = currentI; */
          index += 1;
        } else {
          if (i === 0) {
            closerV = path.v[len - 1];
          } else {
            closerV = path.v[i - 1];
          }
          distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
          newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
          iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
          vX = iX;
          iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
          vY = iY;
          oX = vX - (vX - currentV[0]) * roundCorner;
          oY = vY - (vY - currentV[1]) * roundCorner;
          clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
          index += 1;
          if (i === len - 1) {
            closerV = path.v[0];
          } else {
            closerV = path.v[i + 1];
          }
          distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2) + Math.pow(currentV[1] - closerV[1], 2));
          newPosPerc = distance ? Math.min(distance / 2, round) / distance : 0;
          oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
          vX = oX;
          oY = currentV[1] + (closerV[1] - currentV[1]) * newPosPerc;
          vY = oY;
          iX = vX - (vX - currentV[0]) * roundCorner;
          iY = vY - (vY - currentV[1]) * roundCorner;
          clonedPath.setTripleAt(vX, vY, oX, oY, iX, iY, index);
          index += 1;
        }
      } else {
        clonedPath.setTripleAt(path.v[i][0], path.v[i][1], path.o[i][0], path.o[i][1], path.i[i][0], path.i[i][1], index);
        index += 1;
      }
    }
    return clonedPath;
  };
  RoundCornersModifier.prototype.processShapes = function (_isFirstFrame) {
    var shapePaths;
    var i;
    var len = this.shapes.length;
    var j;
    var jLen;
    var rd = this.rd.v;
    if (rd !== 0) {
      var shapeData;
      var localShapeCollection;
      for (i = 0; i < len; i += 1) {
        shapeData = this.shapes[i];
        localShapeCollection = shapeData.localShapeCollection;
        if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
          localShapeCollection.releaseShapes();
          shapeData.shape._mdf = true;
          shapePaths = shapeData.shape.paths.shapes;
          jLen = shapeData.shape.paths._length;
          for (j = 0; j < jLen; j += 1) {
            localShapeCollection.addShape(this.processPath(shapePaths[j], rd));
          }
        }
        shapeData.shape.paths = shapeData.localShapeCollection;
      }
    }
    if (!this.dynamicProperties.length) {
      this._mdf = false;
    }
  };
  function floatEqual(a, b) {
    return Math.abs(a - b) * 100000 <= Math.min(Math.abs(a), Math.abs(b));
  }
  function floatZero(f) {
    return Math.abs(f) <= 0.00001;
  }
  function lerp(p0, p1, amount) {
    return p0 * (1 - amount) + p1 * amount;
  }
  function lerpPoint(p0, p1, amount) {
    return [lerp(p0[0], p1[0], amount), lerp(p0[1], p1[1], amount)];
  }
  function quadRoots(a, b, c) {
    // no root
    if (a === 0) return [];
    var s = b * b - 4 * a * c;
    // Complex roots
    if (s < 0) return [];
    var singleRoot = -b / (2 * a);
    // 1 root
    if (s === 0) return [singleRoot];
    var delta = Math.sqrt(s) / (2 * a);
    // 2 roots
    return [singleRoot - delta, singleRoot + delta];
  }
  function polynomialCoefficients(p0, p1, p2, p3) {
    return [-p0 + 3 * p1 - 3 * p2 + p3, 3 * p0 - 6 * p1 + 3 * p2, -3 * p0 + 3 * p1, p0];
  }
  function singlePoint(p) {
    return new PolynomialBezier(p, p, p, p, false);
  }
  function PolynomialBezier(p0, p1, p2, p3, linearize) {
    if (linearize && pointEqual(p0, p1)) {
      p1 = lerpPoint(p0, p3, 1 / 3);
    }
    if (linearize && pointEqual(p2, p3)) {
      p2 = lerpPoint(p0, p3, 2 / 3);
    }
    var coeffx = polynomialCoefficients(p0[0], p1[0], p2[0], p3[0]);
    var coeffy = polynomialCoefficients(p0[1], p1[1], p2[1], p3[1]);
    this.a = [coeffx[0], coeffy[0]];
    this.b = [coeffx[1], coeffy[1]];
    this.c = [coeffx[2], coeffy[2]];
    this.d = [coeffx[3], coeffy[3]];
    this.points = [p0, p1, p2, p3];
  }
  PolynomialBezier.prototype.point = function (t) {
    return [((this.a[0] * t + this.b[0]) * t + this.c[0]) * t + this.d[0], ((this.a[1] * t + this.b[1]) * t + this.c[1]) * t + this.d[1]];
  };
  PolynomialBezier.prototype.derivative = function (t) {
    return [(3 * t * this.a[0] + 2 * this.b[0]) * t + this.c[0], (3 * t * this.a[1] + 2 * this.b[1]) * t + this.c[1]];
  };
  PolynomialBezier.prototype.tangentAngle = function (t) {
    var p = this.derivative(t);
    return Math.atan2(p[1], p[0]);
  };
  PolynomialBezier.prototype.normalAngle = function (t) {
    var p = this.derivative(t);
    return Math.atan2(p[0], p[1]);
  };
  PolynomialBezier.prototype.inflectionPoints = function () {
    var denom = this.a[1] * this.b[0] - this.a[0] * this.b[1];
    if (floatZero(denom)) return [];
    var tcusp = -0.5 * (this.a[1] * this.c[0] - this.a[0] * this.c[1]) / denom;
    var square = tcusp * tcusp - 1 / 3 * (this.b[1] * this.c[0] - this.b[0] * this.c[1]) / denom;
    if (square < 0) return [];
    var root = Math.sqrt(square);
    if (floatZero(root)) {
      if (root > 0 && root < 1) return [tcusp];
      return [];
    }
    return [tcusp - root, tcusp + root].filter(function (r) {
      return r > 0 && r < 1;
    });
  };
  PolynomialBezier.prototype.split = function (t) {
    if (t <= 0) return [singlePoint(this.points[0]), this];
    if (t >= 1) return [this, singlePoint(this.points[this.points.length - 1])];
    var p10 = lerpPoint(this.points[0], this.points[1], t);
    var p11 = lerpPoint(this.points[1], this.points[2], t);
    var p12 = lerpPoint(this.points[2], this.points[3], t);
    var p20 = lerpPoint(p10, p11, t);
    var p21 = lerpPoint(p11, p12, t);
    var p3 = lerpPoint(p20, p21, t);
    return [new PolynomialBezier(this.points[0], p10, p20, p3, true), new PolynomialBezier(p3, p21, p12, this.points[3], true)];
  };
  function extrema(bez, comp) {
    var min = bez.points[0][comp];
    var max = bez.points[bez.points.length - 1][comp];
    if (min > max) {
      var e = max;
      max = min;
      min = e;
    }
    // Derivative roots to find min/max
    var f = quadRoots(3 * bez.a[comp], 2 * bez.b[comp], bez.c[comp]);
    for (var i = 0; i < f.length; i += 1) {
      if (f[i] > 0 && f[i] < 1) {
        var val = bez.point(f[i])[comp];
        if (val < min) min = val;else if (val > max) max = val;
      }
    }
    return {
      min: min,
      max: max
    };
  }
  PolynomialBezier.prototype.bounds = function () {
    return {
      x: extrema(this, 0),
      y: extrema(this, 1)
    };
  };
  PolynomialBezier.prototype.boundingBox = function () {
    var bounds = this.bounds();
    return {
      left: bounds.x.min,
      right: bounds.x.max,
      top: bounds.y.min,
      bottom: bounds.y.max,
      width: bounds.x.max - bounds.x.min,
      height: bounds.y.max - bounds.y.min,
      cx: (bounds.x.max + bounds.x.min) / 2,
      cy: (bounds.y.max + bounds.y.min) / 2
    };
  };
  function intersectData(bez, t1, t2) {
    var box = bez.boundingBox();
    return {
      cx: box.cx,
      cy: box.cy,
      width: box.width,
      height: box.height,
      bez: bez,
      t: (t1 + t2) / 2,
      t1: t1,
      t2: t2
    };
  }
  function splitData(data) {
    var split = data.bez.split(0.5);
    return [intersectData(split[0], data.t1, data.t), intersectData(split[1], data.t, data.t2)];
  }
  function boxIntersect(b1, b2) {
    return Math.abs(b1.cx - b2.cx) * 2 < b1.width + b2.width && Math.abs(b1.cy - b2.cy) * 2 < b1.height + b2.height;
  }
  function intersectsImpl(d1, d2, depth, tolerance, intersections, maxRecursion) {
    if (!boxIntersect(d1, d2)) return;
    if (depth >= maxRecursion || d1.width <= tolerance && d1.height <= tolerance && d2.width <= tolerance && d2.height <= tolerance) {
      intersections.push([d1.t, d2.t]);
      return;
    }
    var d1s = splitData(d1);
    var d2s = splitData(d2);
    intersectsImpl(d1s[0], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
    intersectsImpl(d1s[0], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
    intersectsImpl(d1s[1], d2s[0], depth + 1, tolerance, intersections, maxRecursion);
    intersectsImpl(d1s[1], d2s[1], depth + 1, tolerance, intersections, maxRecursion);
  }
  PolynomialBezier.prototype.intersections = function (other, tolerance, maxRecursion) {
    if (tolerance === undefined) tolerance = 2;
    if (maxRecursion === undefined) maxRecursion = 7;
    var intersections = [];
    intersectsImpl(intersectData(this, 0, 1), intersectData(other, 0, 1), 0, tolerance, intersections, maxRecursion);
    return intersections;
  };
  PolynomialBezier.shapeSegment = function (shapePath, index) {
    var nextIndex = (index + 1) % shapePath.length();
    return new PolynomialBezier(shapePath.v[index], shapePath.o[index], shapePath.i[nextIndex], shapePath.v[nextIndex], true);
  };
  PolynomialBezier.shapeSegmentInverted = function (shapePath, index) {
    var nextIndex = (index + 1) % shapePath.length();
    return new PolynomialBezier(shapePath.v[nextIndex], shapePath.i[nextIndex], shapePath.o[index], shapePath.v[index], true);
  };
  function crossProduct(a, b) {
    return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
  }
  function lineIntersection(start1, end1, start2, end2) {
    var v1 = [start1[0], start1[1], 1];
    var v2 = [end1[0], end1[1], 1];
    var v3 = [start2[0], start2[1], 1];
    var v4 = [end2[0], end2[1], 1];
    var r = crossProduct(crossProduct(v1, v2), crossProduct(v3, v4));
    if (floatZero(r[2])) return null;
    return [r[0] / r[2], r[1] / r[2]];
  }
  function polarOffset(p, angle, length) {
    return [p[0] + Math.cos(angle) * length, p[1] - Math.sin(angle) * length];
  }
  function pointDistance(p1, p2) {
    return Math.hypot(p1[0] - p2[0], p1[1] - p2[1]);
  }
  function pointEqual(p1, p2) {
    return floatEqual(p1[0], p2[0]) && floatEqual(p1[1], p2[1]);
  }
  function ZigZagModifier() {}
  extendPrototype([ShapeModifier], ZigZagModifier);
  ZigZagModifier.prototype.initModifierProperties = function (elem, data) {
    this.getValue = this.processKeys;
    this.amplitude = PropertyFactory.getProp(elem, data.s, 0, null, this);
    this.frequency = PropertyFactory.getProp(elem, data.r, 0, null, this);
    this.pointsType = PropertyFactory.getProp(elem, data.pt, 0, null, this);
    this._isAnimated = this.amplitude.effectsSequence.length !== 0 || this.frequency.effectsSequence.length !== 0 || this.pointsType.effectsSequence.length !== 0;
  };
  function setPoint(outputBezier, point, angle, direction, amplitude, outAmplitude, inAmplitude) {
    var angO = angle - Math.PI / 2;
    var angI = angle + Math.PI / 2;
    var px = point[0] + Math.cos(angle) * direction * amplitude;
    var py = point[1] - Math.sin(angle) * direction * amplitude;
    outputBezier.setTripleAt(px, py, px + Math.cos(angO) * outAmplitude, py - Math.sin(angO) * outAmplitude, px + Math.cos(angI) * inAmplitude, py - Math.sin(angI) * inAmplitude, outputBezier.length());
  }
  function getPerpendicularVector(pt1, pt2) {
    var vector = [pt2[0] - pt1[0], pt2[1] - pt1[1]];
    var rot = -Math.PI * 0.5;
    var rotatedVector = [Math.cos(rot) * vector[0] - Math.sin(rot) * vector[1], Math.sin(rot) * vector[0] + Math.cos(rot) * vector[1]];
    return rotatedVector;
  }
  function getProjectingAngle(path, cur) {
    var prevIndex = cur === 0 ? path.length() - 1 : cur - 1;
    var nextIndex = (cur + 1) % path.length();
    var prevPoint = path.v[prevIndex];
    var nextPoint = path.v[nextIndex];
    var pVector = getPerpendicularVector(prevPoint, nextPoint);
    return Math.atan2(0, 1) - Math.atan2(pVector[1], pVector[0]);
  }
  function zigZagCorner(outputBezier, path, cur, amplitude, frequency, pointType, direction) {
    var angle = getProjectingAngle(path, cur);
    var point = path.v[cur % path._length];
    var prevPoint = path.v[cur === 0 ? path._length - 1 : cur - 1];
    var nextPoint = path.v[(cur + 1) % path._length];
    var prevDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - prevPoint[0], 2) + Math.pow(point[1] - prevPoint[1], 2)) : 0;
    var nextDist = pointType === 2 ? Math.sqrt(Math.pow(point[0] - nextPoint[0], 2) + Math.pow(point[1] - nextPoint[1], 2)) : 0;
    setPoint(outputBezier, path.v[cur % path._length], angle, direction, amplitude, nextDist / ((frequency + 1) * 2), prevDist / ((frequency + 1) * 2), pointType);
  }
  function zigZagSegment(outputBezier, segment, amplitude, frequency, pointType, direction) {
    for (var i = 0; i < frequency; i += 1) {
      var t = (i + 1) / (frequency + 1);
      var dist = pointType === 2 ? Math.sqrt(Math.pow(segment.points[3][0] - segment.points[0][0], 2) + Math.pow(segment.points[3][1] - segment.points[0][1], 2)) : 0;
      var angle = segment.normalAngle(t);
      var point = segment.point(t);
      setPoint(outputBezier, point, angle, direction, amplitude, dist / ((frequency + 1) * 2), dist / ((frequency + 1) * 2), pointType);
      direction = -direction;
    }
    return direction;
  }
  ZigZagModifier.prototype.processPath = function (path, amplitude, frequency, pointType) {
    var count = path._length;
    var clonedPath = shapePool.newElement();
    clonedPath.c = path.c;
    if (!path.c) {
      count -= 1;
    }
    if (count === 0) return clonedPath;
    var direction = -1;
    var segment = PolynomialBezier.shapeSegment(path, 0);
    zigZagCorner(clonedPath, path, 0, amplitude, frequency, pointType, direction);
    for (var i = 0; i < count; i += 1) {
      direction = zigZagSegment(clonedPath, segment, amplitude, frequency, pointType, -direction);
      if (i === count - 1 && !path.c) {
        segment = null;
      } else {
        segment = PolynomialBezier.shapeSegment(path, (i + 1) % count);
      }
      zigZagCorner(clonedPath, path, i + 1, amplitude, frequency, pointType, direction);
    }
    return clonedPath;
  };
  ZigZagModifier.prototype.processShapes = function (_isFirstFrame) {
    var shapePaths;
    var i;
    var len = this.shapes.length;
    var j;
    var jLen;
    var amplitude = this.amplitude.v;
    var frequency = Math.max(0, Math.round(this.frequency.v));
    var pointType = this.pointsType.v;
    if (amplitude !== 0) {
      var shapeData;
      var localShapeCollection;
      for (i = 0; i < len; i += 1) {
        shapeData = this.shapes[i];
        localShapeCollection = shapeData.localShapeCollection;
        if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
          localShapeCollection.releaseShapes();
          shapeData.shape._mdf = true;
          shapePaths = shapeData.shape.paths.shapes;
          jLen = shapeData.shape.paths._length;
          for (j = 0; j < jLen; j += 1) {
            localShapeCollection.addShape(this.processPath(shapePaths[j], amplitude, frequency, pointType));
          }
        }
        shapeData.shape.paths = shapeData.localShapeCollection;
      }
    }
    if (!this.dynamicProperties.length) {
      this._mdf = false;
    }
  };
  function linearOffset(p1, p2, amount) {
    var angle = Math.atan2(p2[0] - p1[0], p2[1] - p1[1]);
    return [polarOffset(p1, angle, amount), polarOffset(p2, angle, amount)];
  }
  function offsetSegment(segment, amount) {
    var p0;
    var p1a;
    var p1b;
    var p2b;
    var p2a;
    var p3;
    var e;
    e = linearOffset(segment.points[0], segment.points[1], amount);
    p0 = e[0];
    p1a = e[1];
    e = linearOffset(segment.points[1], segment.points[2], amount);
    p1b = e[0];
    p2b = e[1];
    e = linearOffset(segment.points[2], segment.points[3], amount);
    p2a = e[0];
    p3 = e[1];
    var p1 = lineIntersection(p0, p1a, p1b, p2b);
    if (p1 === null) p1 = p1a;
    var p2 = lineIntersection(p2a, p3, p1b, p2b);
    if (p2 === null) p2 = p2a;
    return new PolynomialBezier(p0, p1, p2, p3);
  }
  function joinLines(outputBezier, seg1, seg2, lineJoin, miterLimit) {
    var p0 = seg1.points[3];
    var p1 = seg2.points[0];

    // Bevel
    if (lineJoin === 3) return p0;

    // Connected, they don't need a joint
    if (pointEqual(p0, p1)) return p0;

    // Round
    if (lineJoin === 2) {
      var angleOut = -seg1.tangentAngle(1);
      var angleIn = -seg2.tangentAngle(0) + Math.PI;
      var center = lineIntersection(p0, polarOffset(p0, angleOut + Math.PI / 2, 100), p1, polarOffset(p1, angleOut + Math.PI / 2, 100));
      var radius = center ? pointDistance(center, p0) : pointDistance(p0, p1) / 2;
      var tan = polarOffset(p0, angleOut, 2 * radius * roundCorner);
      outputBezier.setXYAt(tan[0], tan[1], 'o', outputBezier.length() - 1);
      tan = polarOffset(p1, angleIn, 2 * radius * roundCorner);
      outputBezier.setTripleAt(p1[0], p1[1], p1[0], p1[1], tan[0], tan[1], outputBezier.length());
      return p1;
    }

    // Miter
    var t0 = pointEqual(p0, seg1.points[2]) ? seg1.points[0] : seg1.points[2];
    var t1 = pointEqual(p1, seg2.points[1]) ? seg2.points[3] : seg2.points[1];
    var intersection = lineIntersection(t0, p0, p1, t1);
    if (intersection && pointDistance(intersection, p0) < miterLimit) {
      outputBezier.setTripleAt(intersection[0], intersection[1], intersection[0], intersection[1], intersection[0], intersection[1], outputBezier.length());
      return intersection;
    }
    return p0;
  }
  function getIntersection(a, b) {
    var intersect = a.intersections(b);
    if (intersect.length && floatEqual(intersect[0][0], 1)) intersect.shift();
    if (intersect.length) return intersect[0];
    return null;
  }
  function pruneSegmentIntersection(a, b) {
    var outa = a.slice();
    var outb = b.slice();
    var intersect = getIntersection(a[a.length - 1], b[0]);
    if (intersect) {
      outa[a.length - 1] = a[a.length - 1].split(intersect[0])[0];
      outb[0] = b[0].split(intersect[1])[1];
    }
    if (a.length > 1 && b.length > 1) {
      intersect = getIntersection(a[0], b[b.length - 1]);
      if (intersect) {
        return [[a[0].split(intersect[0])[0]], [b[b.length - 1].split(intersect[1])[1]]];
      }
    }
    return [outa, outb];
  }
  function pruneIntersections(segments) {
    var e;
    for (var i = 1; i < segments.length; i += 1) {
      e = pruneSegmentIntersection(segments[i - 1], segments[i]);
      segments[i - 1] = e[0];
      segments[i] = e[1];
    }
    if (segments.length > 1) {
      e = pruneSegmentIntersection(segments[segments.length - 1], segments[0]);
      segments[segments.length - 1] = e[0];
      segments[0] = e[1];
    }
    return segments;
  }
  function offsetSegmentSplit(segment, amount) {
    /*
      We split each bezier segment into smaller pieces based
      on inflection points, this ensures the control point
      polygon is convex.
       (A cubic bezier can have none, one, or two inflection points)
    */
    var flex = segment.inflectionPoints();
    var left;
    var right;
    var split;
    var mid;
    if (flex.length === 0) {
      return [offsetSegment(segment, amount)];
    }
    if (flex.length === 1 || floatEqual(flex[1], 1)) {
      split = segment.split(flex[0]);
      left = split[0];
      right = split[1];
      return [offsetSegment(left, amount), offsetSegment(right, amount)];
    }
    split = segment.split(flex[0]);
    left = split[0];
    var t = (flex[1] - flex[0]) / (1 - flex[0]);
    split = split[1].split(t);
    mid = split[0];
    right = split[1];
    return [offsetSegment(left, amount), offsetSegment(mid, amount), offsetSegment(right, amount)];
  }
  function OffsetPathModifier() {}
  extendPrototype([ShapeModifier], OffsetPathModifier);
  OffsetPathModifier.prototype.initModifierProperties = function (elem, data) {
    this.getValue = this.processKeys;
    this.amount = PropertyFactory.getProp(elem, data.a, 0, null, this);
    this.miterLimit = PropertyFactory.getProp(elem, data.ml, 0, null, this);
    this.lineJoin = data.lj;
    this._isAnimated = this.amount.effectsSequence.length !== 0;
  };
  OffsetPathModifier.prototype.processPath = function (inputBezier, amount, lineJoin, miterLimit) {
    var outputBezier = shapePool.newElement();
    outputBezier.c = inputBezier.c;
    var count = inputBezier.length();
    if (!inputBezier.c) {
      count -= 1;
    }
    var i;
    var j;
    var segment;
    var multiSegments = [];
    for (i = 0; i < count; i += 1) {
      segment = PolynomialBezier.shapeSegment(inputBezier, i);
      multiSegments.push(offsetSegmentSplit(segment, amount));
    }
    if (!inputBezier.c) {
      for (i = count - 1; i >= 0; i -= 1) {
        segment = PolynomialBezier.shapeSegmentInverted(inputBezier, i);
        multiSegments.push(offsetSegmentSplit(segment, amount));
      }
    }
    multiSegments = pruneIntersections(multiSegments);

    // Add bezier segments to the output and apply line joints
    var lastPoint = null;
    var lastSeg = null;
    for (i = 0; i < multiSegments.length; i += 1) {
      var multiSegment = multiSegments[i];
      if (lastSeg) lastPoint = joinLines(outputBezier, lastSeg, multiSegment[0], lineJoin, miterLimit);
      lastSeg = multiSegment[multiSegment.length - 1];
      for (j = 0; j < multiSegment.length; j += 1) {
        segment = multiSegment[j];
        if (lastPoint && pointEqual(segment.points[0], lastPoint)) {
          outputBezier.setXYAt(segment.points[1][0], segment.points[1][1], 'o', outputBezier.length() - 1);
        } else {
          outputBezier.setTripleAt(segment.points[0][0], segment.points[0][1], segment.points[1][0], segment.points[1][1], segment.points[0][0], segment.points[0][1], outputBezier.length());
        }
        outputBezier.setTripleAt(segment.points[3][0], segment.points[3][1], segment.points[3][0], segment.points[3][1], segment.points[2][0], segment.points[2][1], outputBezier.length());
        lastPoint = segment.points[3];
      }
    }
    if (multiSegments.length) joinLines(outputBezier, lastSeg, multiSegments[0][0], lineJoin, miterLimit);
    return outputBezier;
  };
  OffsetPathModifier.prototype.processShapes = function (_isFirstFrame) {
    var shapePaths;
    var i;
    var len = this.shapes.length;
    var j;
    var jLen;
    var amount = this.amount.v;
    var miterLimit = this.miterLimit.v;
    var lineJoin = this.lineJoin;
    if (amount !== 0) {
      var shapeData;
      var localShapeCollection;
      for (i = 0; i < len; i += 1) {
        shapeData = this.shapes[i];
        localShapeCollection = shapeData.localShapeCollection;
        if (!(!shapeData.shape._mdf && !this._mdf && !_isFirstFrame)) {
          localShapeCollection.releaseShapes();
          shapeData.shape._mdf = true;
          shapePaths = shapeData.shape.paths.shapes;
          jLen = shapeData.shape.paths._length;
          for (j = 0; j < jLen; j += 1) {
            localShapeCollection.addShape(this.processPath(shapePaths[j], amount, lineJoin, miterLimit));
          }
        }
        shapeData.shape.paths = shapeData.localShapeCollection;
      }
    }
    if (!this.dynamicProperties.length) {
      this._mdf = false;
    }
  };
  function getFontProperties(fontData) {
    var styles = fontData.fStyle ? fontData.fStyle.split(' ') : [];
    var fWeight = 'normal';
    var fStyle = 'normal';
    var len = styles.length;
    var styleName;
    for (var i = 0; i < len; i += 1) {
      styleName = styles[i].toLowerCase();
      switch (styleName) {
        case 'italic':
          fStyle = 'italic';
          break;
        case 'bold':
          fWeight = '700';
          break;
        case 'black':
          fWeight = '900';
          break;
        case 'medium':
          fWeight = '500';
          break;
        case 'regular':
        case 'normal':
          fWeight = '400';
          break;
        case 'light':
        case 'thin':
          fWeight = '200';
          break;
        default:
          break;
      }
    }
    return {
      style: fStyle,
      weight: fontData.fWeight || fWeight
    };
  }
  var FontManager = function () {
    var maxWaitingTime = 5000;
    var emptyChar = {
      w: 0,
      size: 0,
      shapes: [],
      data: {
        shapes: []
      }
    };
    var combinedCharacters = [];
    // Hindi characters
    combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366, 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379, 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]);
    var BLACK_FLAG_CODE_POINT = 127988;
    var CANCEL_TAG_CODE_POINT = 917631;
    var A_TAG_CODE_POINT = 917601;
    var Z_TAG_CODE_POINT = 917626;
    var VARIATION_SELECTOR_16_CODE_POINT = 65039;
    var ZERO_WIDTH_JOINER_CODE_POINT = 8205;
    var REGIONAL_CHARACTER_A_CODE_POINT = 127462;
    var REGIONAL_CHARACTER_Z_CODE_POINT = 127487;
    var surrogateModifiers = ['d83cdffb', 'd83cdffc', 'd83cdffd', 'd83cdffe', 'd83cdfff'];
    function trimFontOptions(font) {
      var familyArray = font.split(',');
      var i;
      var len = familyArray.length;
      var enabledFamilies = [];
      for (i = 0; i < len; i += 1) {
        if (familyArray[i] !== 'sans-serif' && familyArray[i] !== 'monospace') {
          enabledFamilies.push(familyArray[i]);
        }
      }
      return enabledFamilies.join(',');
    }
    function setUpNode(font, family) {
      var parentNode = createTag('span');
      // Node is invisible to screen readers.
      parentNode.setAttribute('aria-hidden', true);
      parentNode.style.fontFamily = family;
      var node = createTag('span');
      // Characters that vary significantly among different fonts
      node.innerText = 'giItT1WQy@!-/#';
      // Visible - so we can measure it - but not on the screen
      parentNode.style.position = 'absolute';
      parentNode.style.left = '-10000px';
      parentNode.style.top = '-10000px';
      // Large font size makes even subtle changes obvious
      parentNode.style.fontSize = '300px';
      // Reset any font properties
      parentNode.style.fontVariant = 'normal';
      parentNode.style.fontStyle = 'normal';
      parentNode.style.fontWeight = 'normal';
      parentNode.style.letterSpacing = '0';
      parentNode.appendChild(node);
      document.body.appendChild(parentNode);

      // Remember width with no applied web font
      var width = node.offsetWidth;
      node.style.fontFamily = trimFontOptions(font) + ', ' + family;
      return {
        node: node,
        w: width,
        parent: parentNode
      };
    }
    function checkLoadedFonts() {
      var i;
      var len = this.fonts.length;
      var node;
      var w;
      var loadedCount = len;
      for (i = 0; i < len; i += 1) {
        if (this.fonts[i].loaded) {
          loadedCount -= 1;
        } else if (this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0) {
          this.fonts[i].loaded = true;
        } else {
          node = this.fonts[i].monoCase.node;
          w = this.fonts[i].monoCase.w;
          if (node.offsetWidth !== w) {
            loadedCount -= 1;
            this.fonts[i].loaded = true;
          } else {
            node = this.fonts[i].sansCase.node;
            w = this.fonts[i].sansCase.w;
            if (node.offsetWidth !== w) {
              loadedCount -= 1;
              this.fonts[i].loaded = true;
            }
          }
          if (this.fonts[i].loaded) {
            this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent);
            this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent);
          }
        }
      }
      if (loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime) {
        setTimeout(this.checkLoadedFontsBinded, 20);
      } else {
        setTimeout(this.setIsLoadedBinded, 10);
      }
    }
    function createHelper(fontData, def) {
      var engine = document.body && def ? 'svg' : 'canvas';
      var helper;
      var fontProps = getFontProperties(fontData);
      if (engine === 'svg') {
        var tHelper = createNS('text');
        tHelper.style.fontSize = '100px';
        // tHelper.style.fontFamily = fontData.fFamily;
        tHelper.setAttribute('font-family', fontData.fFamily);
        tHelper.setAttribute('font-style', fontProps.style);
        tHelper.setAttribute('font-weight', fontProps.weight);
        tHelper.textContent = '1';
        if (fontData.fClass) {
          tHelper.style.fontFamily = 'inherit';
          tHelper.setAttribute('class', fontData.fClass);
        } else {
          tHelper.style.fontFamily = fontData.fFamily;
        }
        def.appendChild(tHelper);
        helper = tHelper;
      } else {
        var tCanvasHelper = new OffscreenCanvas(500, 500).getContext('2d');
        tCanvasHelper.font = fontProps.style + ' ' + fontProps.weight + ' 100px ' + fontData.fFamily;
        helper = tCanvasHelper;
      }
      function measure(text) {
        if (engine === 'svg') {
          helper.textContent = text;
          return helper.getComputedTextLength();
        }
        return helper.measureText(text).width;
      }
      return {
        measureText: measure
      };
    }
    function addFonts(fontData, defs) {
      if (!fontData) {
        this.isLoaded = true;
        return;
      }
      if (this.chars) {
        this.isLoaded = true;
        this.fonts = fontData.list;
        return;
      }
      if (!document.body) {
        this.isLoaded = true;
        fontData.list.forEach(function (data) {
          data.helper = createHelper(data);
          data.cache = {};
        });
        this.fonts = fontData.list;
        return;
      }
      var fontArr = fontData.list;
      var i;
      var len = fontArr.length;
      var _pendingFonts = len;
      for (i = 0; i < len; i += 1) {
        var shouldLoadFont = true;
        var loadedSelector;
        var j;
        fontArr[i].loaded = false;
        fontArr[i].monoCase = setUpNode(fontArr[i].fFamily, 'monospace');
        fontArr[i].sansCase = setUpNode(fontArr[i].fFamily, 'sans-serif');
        if (!fontArr[i].fPath) {
          fontArr[i].loaded = true;
          _pendingFonts -= 1;
        } else if (fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3) {
          loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="' + fontArr[i].fFamily + '"], style[f-origin="3"][f-family="' + fontArr[i].fFamily + '"]');
          if (loadedSelector.length > 0) {
            shouldLoadFont = false;
          }
          if (shouldLoadFont) {
            var s = createTag('style');
            s.setAttribute('f-forigin', fontArr[i].fOrigin);
            s.setAttribute('f-origin', fontArr[i].origin);
            s.setAttribute('f-family', fontArr[i].fFamily);
            s.type = 'text/css';
            s.innerText = '@font-face {font-family: ' + fontArr[i].fFamily + "; font-style: normal; src: url('" + fontArr[i].fPath + "');}";
            defs.appendChild(s);
          }
        } else if (fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1) {
          loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]');
          for (j = 0; j < loadedSelector.length; j += 1) {
            if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) {
              // Font is already loaded
              shouldLoadFont = false;
            }
          }
          if (shouldLoadFont) {
            var l = createTag('link');
            l.setAttribute('f-forigin', fontArr[i].fOrigin);
            l.setAttribute('f-origin', fontArr[i].origin);
            l.type = 'text/css';
            l.rel = 'stylesheet';
            l.href = fontArr[i].fPath;
            document.body.appendChild(l);
          }
        } else if (fontArr[i].fOrigin === 't' || fontArr[i].origin === 2) {
          loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]');
          for (j = 0; j < loadedSelector.length; j += 1) {
            if (fontArr[i].fPath === loadedSelector[j].src) {
              // Font is already loaded
              shouldLoadFont = false;
            }
          }
          if (shouldLoadFont) {
            var sc = createTag('link');
            sc.setAttribute('f-forigin', fontArr[i].fOrigin);
            sc.setAttribute('f-origin', fontArr[i].origin);
            sc.setAttribute('rel', 'stylesheet');
            sc.setAttribute('href', fontArr[i].fPath);
            defs.appendChild(sc);
          }
        }
        fontArr[i].helper = createHelper(fontArr[i], defs);
        fontArr[i].cache = {};
        this.fonts.push(fontArr[i]);
      }
      if (_pendingFonts === 0) {
        this.isLoaded = true;
      } else {
        // On some cases even if the font is loaded, it won't load correctly when measuring text on canvas.
        // Adding this timeout seems to fix it
        setTimeout(this.checkLoadedFonts.bind(this), 100);
      }
    }
    function addChars(chars) {
      if (!chars) {
        return;
      }
      if (!this.chars) {
        this.chars = [];
      }
      var i;
      var len = chars.length;
      var j;
      var jLen = this.chars.length;
      var found;
      for (i = 0; i < len; i += 1) {
        j = 0;
        found = false;
        while (j < jLen) {
          if (this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch) {
            found = true;
          }
          j += 1;
        }
        if (!found) {
          this.chars.push(chars[i]);
          jLen += 1;
        }
      }
    }
    function getCharData(_char, style, font) {
      var i = 0;
      var len = this.chars.length;
      while (i < len) {
        if (this.chars[i].ch === _char && this.chars[i].style === style && this.chars[i].fFamily === font) {
          return this.chars[i];
        }
        i += 1;
      }
      if ((typeof _char === 'string' && _char.charCodeAt(0) !== 13 || !_char) && console && console.warn // eslint-disable-line no-console
      && !this._warned) {
        this._warned = true;
        console.warn('Missing character from exported characters list: ', _char, style, font); // eslint-disable-line no-console
      }
      return emptyChar;
    }
    function measureText(_char2, fontName, size) {
      var fontData = this.getFontByName(fontName);
      // Using the char instead of char.charCodeAt(0)
      // to avoid collisions between equal chars
      var index = _char2;
      if (!fontData.cache[index]) {
        var tHelper = fontData.helper;
        if (_char2 === ' ') {
          var doubleSize = tHelper.measureText('|' + _char2 + '|');
          var singleSize = tHelper.measureText('||');
          fontData.cache[index] = (doubleSize - singleSize) / 100;
        } else {
          fontData.cache[index] = tHelper.measureText(_char2) / 100;
        }
      }
      return fontData.cache[index] * size;
    }
    function getFontByName(name) {
      var i = 0;
      var len = this.fonts.length;
      while (i < len) {
        if (this.fonts[i].fName === name) {
          return this.fonts[i];
        }
        i += 1;
      }
      return this.fonts[0];
    }
    function getCodePoint(string) {
      var codePoint = 0;
      var first = string.charCodeAt(0);
      if (first >= 0xD800 && first <= 0xDBFF) {
        var second = string.charCodeAt(1);
        if (second >= 0xDC00 && second <= 0xDFFF) {
          codePoint = (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
        }
      }
      return codePoint;
    }

    // Skin tone modifiers
    function isModifier(firstCharCode, secondCharCode) {
      var sum = firstCharCode.toString(16) + secondCharCode.toString(16);
      return surrogateModifiers.indexOf(sum) !== -1;
    }
    function isZeroWidthJoiner(charCode) {
      return charCode === ZERO_WIDTH_JOINER_CODE_POINT;
    }

    // This codepoint may change the appearance of the preceding character.
    // If that is a symbol, dingbat or emoji, U+FE0F forces it to be rendered
    // as a colorful image as compared to a monochrome text variant.
    function isVariationSelector(charCode) {
      return charCode === VARIATION_SELECTOR_16_CODE_POINT;
    }

    // The regional indicator symbols are a set of 26 alphabetic Unicode
    /// characters (A–Z) intended to be used to encode ISO 3166-1 alpha-2
    // two-letter country codes in a way that allows optional special treatment.
    function isRegionalCode(string) {
      var codePoint = getCodePoint(string);
      if (codePoint >= REGIONAL_CHARACTER_A_CODE_POINT && codePoint <= REGIONAL_CHARACTER_Z_CODE_POINT) {
        return true;
      }
      return false;
    }

    // Some Emoji implementations represent combinations of
    // two “regional indicator” letters as a single flag symbol.
    function isFlagEmoji(string) {
      return isRegionalCode(string.substr(0, 2)) && isRegionalCode(string.substr(2, 2));
    }
    function isCombinedCharacter(_char3) {
      return combinedCharacters.indexOf(_char3) !== -1;
    }

    // Regional flags start with a BLACK_FLAG_CODE_POINT
    // folowed by 5 chars in the TAG range
    // and end with a CANCEL_TAG_CODE_POINT
    function isRegionalFlag(text, index) {
      var codePoint = getCodePoint(text.substr(index, 2));
      if (codePoint !== BLACK_FLAG_CODE_POINT) {
        return false;
      }
      var count = 0;
      index += 2;
      while (count < 5) {
        codePoint = getCodePoint(text.substr(index, 2));
        if (codePoint < A_TAG_CODE_POINT || codePoint > Z_TAG_CODE_POINT) {
          return false;
        }
        count += 1;
        index += 2;
      }
      return getCodePoint(text.substr(index, 2)) === CANCEL_TAG_CODE_POINT;
    }
    function setIsLoaded() {
      this.isLoaded = true;
    }
    var Font = function Font() {
      this.fonts = [];
      this.chars = null;
      this.typekitLoaded = 0;
      this.isLoaded = false;
      this._warned = false;
      this.initTime = Date.now();
      this.setIsLoadedBinded = this.setIsLoaded.bind(this);
      this.checkLoadedFontsBinded = this.checkLoadedFonts.bind(this);
    };
    Font.isModifier = isModifier;
    Font.isZeroWidthJoiner = isZeroWidthJoiner;
    Font.isFlagEmoji = isFlagEmoji;
    Font.isRegionalCode = isRegionalCode;
    Font.isCombinedCharacter = isCombinedCharacter;
    Font.isRegionalFlag = isRegionalFlag;
    Font.isVariationSelector = isVariationSelector;
    Font.BLACK_FLAG_CODE_POINT = BLACK_FLAG_CODE_POINT;
    var fontPrototype = {
      addChars: addChars,
      addFonts: addFonts,
      getCharData: getCharData,
      getFontByName: getFontByName,
      measureText: measureText,
      checkLoadedFonts: checkLoadedFonts,
      setIsLoaded: setIsLoaded
    };
    Font.prototype = fontPrototype;
    return Font;
  }();
  function SlotManager(animationData) {
    this.animationData = animationData;
  }
  SlotManager.prototype.getProp = function (data) {
    if (this.animationData.slots && this.animationData.slots[data.sid]) {
      return Object.assign(data, this.animationData.slots[data.sid].p);
    }
    return data;
  };
  function slotFactory(animationData) {
    return new SlotManager(animationData);
  }
  function RenderableElement() {}
  RenderableElement.prototype = {
    initRenderable: function initRenderable() {
      // layer's visibility related to inpoint and outpoint. Rename isVisible to isInRange
      this.isInRange = false;
      // layer's display state
      this.hidden = false;
      // If layer's transparency equals 0, it can be hidden
      this.isTransparent = false;
      // list of animated components
      this.renderableComponents = [];
    },
    addRenderableComponent: function addRenderableComponent(component) {
      if (this.renderableComponents.indexOf(component) === -1) {
        this.renderableComponents.push(component);
      }
    },
    removeRenderableComponent: function removeRenderableComponent(component) {
      if (this.renderableComponents.indexOf(component) !== -1) {
        this.renderableComponents.splice(this.renderableComponents.indexOf(component), 1);
      }
    },
    prepareRenderableFrame: function prepareRenderableFrame(num) {
      this.checkLayerLimits(num);
    },
    checkTransparency: function checkTransparency() {
      if (this.finalTransform.mProp.o.v <= 0) {
        if (!this.isTransparent && this.globalData.renderConfig.hideOnTransparent) {
          this.isTransparent = true;
          this.hide();
        }
      } else if (this.isTransparent) {
        this.isTransparent = false;
        this.show();
      }
    },
    /**
       * @function
       * Initializes frame related properties.
       *
       * @param {number} num
       * current frame number in Layer's time
       *
       */
    checkLayerLimits: function checkLayerLimits(num) {
      if (this.data.ip - this.data.st <= num && this.data.op - this.data.st > num) {
        if (this.isInRange !== true) {
          this.globalData._mdf = true;
          this._mdf = true;
          this.isInRange = true;
          this.show();
        }
      } else if (this.isInRange !== false) {
        this.globalData._mdf = true;
        this.isInRange = false;
        this.hide();
      }
    },
    renderRenderable: function renderRenderable() {
      var i;
      var len = this.renderableComponents.length;
      for (i = 0; i < len; i += 1) {
        this.renderableComponents[i].renderFrame(this._isFirstFrame);
      }
      /* this.maskManager.renderFrame(this.finalTransform.mat);
          this.renderableEffectsManager.renderFrame(this._isFirstFrame); */
    },
    sourceRectAtTime: function sourceRectAtTime() {
      return {
        top: 0,
        left: 0,
        width: 100,
        height: 100
      };
    },
    getLayerSize: function getLayerSize() {
      if (this.data.ty === 5) {
        return {
          w: this.data.textData.width,
          h: this.data.textData.height
        };
      }
      return {
        w: this.data.width,
        h: this.data.height
      };
    }
  };
  var getBlendMode = function () {
    var blendModeEnums = {
      0: 'source-over',
      1: 'multiply',
      2: 'screen',
      3: 'overlay',
      4: 'darken',
      5: 'lighten',
      6: 'color-dodge',
      7: 'color-burn',
      8: 'hard-light',
      9: 'soft-light',
      10: 'difference',
      11: 'exclusion',
      12: 'hue',
      13: 'saturation',
      14: 'color',
      15: 'luminosity'
    };
    return function (mode) {
      return blendModeEnums[mode] || '';
    };
  }();
  function SliderEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
  }
  function AngleEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
  }
  function ColorEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
  }
  function PointEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 1, 0, container);
  }
  function LayerIndexEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
  }
  function MaskIndexEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
  }
  function CheckboxEffect(data, elem, container) {
    this.p = PropertyFactory.getProp(elem, data.v, 0, 0, container);
  }
  function NoValueEffect() {
    this.p = {};
  }
  function EffectsManager(data, element) {
    var effects = data.ef || [];
    this.effectElements = [];
    var i;
    var len = effects.length;
    var effectItem;
    for (i = 0; i < len; i += 1) {
      effectItem = new GroupEffect(effects[i], element);
      this.effectElements.push(effectItem);
    }
  }
  function GroupEffect(data, element) {
    this.init(data, element);
  }
  extendPrototype([DynamicPropertyContainer], GroupEffect);
  GroupEffect.prototype.getValue = GroupEffect.prototype.iterateDynamicProperties;
  GroupEffect.prototype.init = function (data, element) {
    this.data = data;
    this.effectElements = [];
    this.initDynamicPropertyContainer(element);
    var i;
    var len = this.data.ef.length;
    var eff;
    var effects = this.data.ef;
    for (i = 0; i < len; i += 1) {
      eff = null;
      switch (effects[i].ty) {
        case 0:
          eff = new SliderEffect(effects[i], element, this);
          break;
        case 1:
          eff = new AngleEffect(effects[i], element, this);
          break;
        case 2:
          eff = new ColorEffect(effects[i], element, this);
          break;
        case 3:
          eff = new PointEffect(effects[i], element, this);
          break;
        case 4:
        case 7:
          eff = new CheckboxEffect(effects[i], element, this);
          break;
        case 10:
          eff = new LayerIndexEffect(effects[i], element, this);
          break;
        case 11:
          eff = new MaskIndexEffect(effects[i], element, this);
          break;
        case 5:
          eff = new EffectsManager(effects[i], element, this);
          break;
        // case 6:
        default:
          eff = new NoValueEffect(effects[i], element, this);
          break;
      }
      if (eff) {
        this.effectElements.push(eff);
      }
    }
  };
  function BaseElement() {}
  BaseElement.prototype = {
    checkMasks: function checkMasks() {
      if (!this.data.hasMask) {
        return false;
      }
      var i = 0;
      var len = this.data.masksProperties.length;
      while (i < len) {
        if (this.data.masksProperties[i].mode !== 'n' && this.data.masksProperties[i].cl !== false) {
          return true;
        }
        i += 1;
      }
      return false;
    },
    initExpressions: function initExpressions() {
      var expressionsInterfaces = getExpressionInterfaces();
      if (!expressionsInterfaces) {
        return;
      }
      var LayerExpressionInterface = expressionsInterfaces('layer');
      var EffectsExpressionInterface = expressionsInterfaces('effects');
      var ShapeExpressionInterface = expressionsInterfaces('shape');
      var TextExpressionInterface = expressionsInterfaces('text');
      var CompExpressionInterface = expressionsInterfaces('comp');
      this.layerInterface = LayerExpressionInterface(this);
      if (this.data.hasMask && this.maskManager) {
        this.layerInterface.registerMaskInterface(this.maskManager);
      }
      var effectsInterface = EffectsExpressionInterface.createEffectsInterface(this, this.layerInterface);
      this.layerInterface.registerEffectsInterface(effectsInterface);
      if (this.data.ty === 0 || this.data.xt) {
        this.compInterface = CompExpressionInterface(this);
      } else if (this.data.ty === 4) {
        this.layerInterface.shapeInterface = ShapeExpressionInterface(this.shapesData, this.itemsData, this.layerInterface);
        this.layerInterface.content = this.layerInterface.shapeInterface;
      } else if (this.data.ty === 5) {
        this.layerInterface.textInterface = TextExpressionInterface(this);
        this.layerInterface.text = this.layerInterface.textInterface;
      }
    },
    setBlendMode: function setBlendMode() {
      var blendModeValue = getBlendMode(this.data.bm);
      var elem = this.baseElement || this.layerElement;
      elem.style['mix-blend-mode'] = blendModeValue;
    },
    initBaseData: function initBaseData(data, globalData, comp) {
      this.globalData = globalData;
      this.comp = comp;
      this.data = data;
      this.layerId = createElementID();

      // Stretch factor for old animations missing this property.
      if (!this.data.sr) {
        this.data.sr = 1;
      }
      // effects manager
      this.effectsManager = new EffectsManager(this.data, this, this.dynamicProperties);
    },
    getType: function getType() {
      return this.type;
    },
    sourceRectAtTime: function sourceRectAtTime() {}
  };

  /**
   * @file
   * Handles element's layer frame update.
   * Checks layer in point and out point
   *
   */

  function FrameElement() {}
  FrameElement.prototype = {
    /**
       * @function
       * Initializes frame related properties.
       *
       */
    initFrame: function initFrame() {
      // set to true when inpoint is rendered
      this._isFirstFrame = false;
      // list of animated properties
      this.dynamicProperties = [];
      // If layer has been modified in current tick this will be true
      this._mdf = false;
    },
    /**
       * @function
       * Calculates all dynamic values
       *
       * @param {number} num
       * current frame number in Layer's time
       * @param {boolean} isVisible
       * if layers is currently in range
       *
       */
    prepareProperties: function prepareProperties(num, isVisible) {
      var i;
      var len = this.dynamicProperties.length;
      for (i = 0; i < len; i += 1) {
        if (isVisible || this._isParent && this.dynamicProperties[i].propType === 'transform') {
          this.dynamicProperties[i].getValue();
          if (this.dynamicProperties[i]._mdf) {
            this.globalData._mdf = true;
            this._mdf = true;
          }
        }
      }
    },
    addDynamicProperty: function addDynamicProperty(prop) {
      if (this.dynamicProperties.indexOf(prop) === -1) {
        this.dynamicProperties.push(prop);
      }
    }
  };
  function FootageElement(data, globalData, comp) {
    this.initFrame();
    this.initRenderable();
    this.assetData = globalData.getAssetData(data.refId);
    this.footageData = globalData.imageLoader.getAsset(this.assetData);
    this.initBaseData(data, globalData, comp);
  }
  FootageElement.prototype.prepareFrame = function () {};
  extendPrototype([RenderableElement, BaseElement, FrameElement], FootageElement);
  FootageElement.prototype.getBaseElement = function () {
    return null;
  };
  FootageElement.prototype.renderFrame = function () {};
  FootageElement.prototype.destroy = function () {};
  FootageElement.prototype.initExpressions = function () {
    var expressionsInterfaces = getExpressionInterfaces();
    if (!expressionsInterfaces) {
      return;
    }
    var FootageInterface = expressionsInterfaces('footage');
    this.layerInterface = FootageInterface(this);
  };
  FootageElement.prototype.getFootageData = function () {
    return this.footageData;
  };
  function AudioElement(data, globalData, comp) {
    this.initFrame();
    this.initRenderable();
    this.assetData = globalData.getAssetData(data.refId);
    this.initBaseData(data, globalData, comp);
    this._isPlaying = false;
    this._canPlay = false;
    var assetPath = this.globalData.getAssetsPath(this.assetData);
    this.audio = this.globalData.audioController.createAudio(assetPath);
    this._currentTime = 0;
    this.globalData.audioController.addAudio(this);
    this._volumeMultiplier = 1;
    this._volume = 1;
    this._previousVolume = null;
    this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : {
      _placeholder: true
    };
    this.lv = PropertyFactory.getProp(this, data.au && data.au.lv ? data.au.lv : {
      k: [100]
    }, 1, 0.01, this);
  }
  AudioElement.prototype.prepareFrame = function (num) {
    this.prepareRenderableFrame(num, true);
    this.prepareProperties(num, true);
    if (!this.tm._placeholder) {
      var timeRemapped = this.tm.v;
      this._currentTime = timeRemapped;
    } else {
      this._currentTime = num / this.data.sr;
    }
    this._volume = this.lv.v[0];
    var totalVolume = this._volume * this._volumeMultiplier;
    if (this._previousVolume !== totalVolume) {
      this._previousVolume = totalVolume;
      this.audio.volume(totalVolume);
    }
  };
  extendPrototype([RenderableElement, BaseElement, FrameElement], AudioElement);
  AudioElement.prototype.renderFrame = function () {
    if (this.isInRange && this._canPlay) {
      if (!this._isPlaying) {
        this.audio.play();
        this.audio.seek(this._currentTime / this.globalData.frameRate);
        this._isPlaying = true;
      } else if (!this.audio.playing() || Math.abs(this._currentTime / this.globalData.frameRate - this.audio.seek()) > 0.1) {
        this.audio.seek(this._currentTime / this.globalData.frameRate);
      }
    }
  };
  AudioElement.prototype.show = function () {
    // this.audio.play()
  };
  AudioElement.prototype.hide = function () {
    this.audio.pause();
    this._isPlaying = false;
  };
  AudioElement.prototype.pause = function () {
    this.audio.pause();
    this._isPlaying = false;
    this._canPlay = false;
  };
  AudioElement.prototype.resume = function () {
    this._canPlay = true;
  };
  AudioElement.prototype.setRate = function (rateValue) {
    this.audio.rate(rateValue);
  };
  AudioElement.prototype.volume = function (volumeValue) {
    this._volumeMultiplier = volumeValue;
    this._previousVolume = volumeValue * this._volume;
    this.audio.volume(this._previousVolume);
  };
  AudioElement.prototype.getBaseElement = function () {
    return null;
  };
  AudioElement.prototype.destroy = function () {};
  AudioElement.prototype.sourceRectAtTime = function () {};
  AudioElement.prototype.initExpressions = function () {};
  function BaseRenderer() {}
  BaseRenderer.prototype.checkLayers = function (num) {
    var i;
    var len = this.layers.length;
    var data;
    this.completeLayers = true;
    for (i = len - 1; i >= 0; i -= 1) {
      if (!this.elements[i]) {
        data = this.layers[i];
        if (data.ip - data.st <= num - this.layers[i].st && data.op - data.st > num - this.layers[i].st) {
          this.buildItem(i);
        }
      }
      this.completeLayers = this.elements[i] ? this.completeLayers : false;
    }
    this.checkPendingElements();
  };
  BaseRenderer.prototype.createItem = function (layer) {
    switch (layer.ty) {
      case 2:
        return this.createImage(layer);
      case 0:
        return this.createComp(layer);
      case 1:
        return this.createSolid(layer);
      case 3:
        return this.createNull(layer);
      case 4:
        return this.createShape(layer);
      case 5:
        return this.createText(layer);
      case 6:
        return this.createAudio(layer);
      case 13:
        return this.createCamera(layer);
      case 15:
        return this.createFootage(layer);
      default:
        return this.createNull(layer);
    }
  };
  BaseRenderer.prototype.createCamera = function () {
    throw new Error('You\'re using a 3d camera. Try the html renderer.');
  };
  BaseRenderer.prototype.createAudio = function (data) {
    return new AudioElement(data, this.globalData, this);
  };
  BaseRenderer.prototype.createFootage = function (data) {
    return new FootageElement(data, this.globalData, this);
  };
  BaseRenderer.prototype.buildAllItems = function () {
    var i;
    var len = this.layers.length;
    for (i = 0; i < len; i += 1) {
      this.buildItem(i);
    }
    this.checkPendingElements();
  };
  BaseRenderer.prototype.includeLayers = function (newLayers) {
    this.completeLayers = false;
    var i;
    var len = newLayers.length;
    var j;
    var jLen = this.layers.length;
    for (i = 0; i < len; i += 1) {
      j = 0;
      while (j < jLen) {
        if (this.layers[j].id === newLayers[i].id) {
          this.layers[j] = newLayers[i];
          break;
        }
        j += 1;
      }
    }
  };
  BaseRenderer.prototype.setProjectInterface = function (pInterface) {
    this.globalData.projectInterface = pInterface;
  };
  BaseRenderer.prototype.initItems = function () {
    if (!this.globalData.progressiveLoad) {
      this.buildAllItems();
    }
  };
  BaseRenderer.prototype.buildElementParenting = function (element, parentName, hierarchy) {
    var elements = this.elements;
    var layers = this.layers;
    var i = 0;
    var len = layers.length;
    while (i < len) {
      if (layers[i].ind == parentName) {
        // eslint-disable-line eqeqeq
        if (!elements[i] || elements[i] === true) {
          this.buildItem(i);
          this.addPendingElement(element);
        } else {
          hierarchy.push(elements[i]);
          elements[i].setAsParent();
          if (layers[i].parent !== undefined) {
            this.buildElementParenting(element, layers[i].parent, hierarchy);
          } else {
            element.setHierarchy(hierarchy);
          }
        }
      }
      i += 1;
    }
  };
  BaseRenderer.prototype.addPendingElement = function (element) {
    this.pendingElements.push(element);
  };
  BaseRenderer.prototype.searchExtraCompositions = function (assets) {
    var i;
    var len = assets.length;
    for (i = 0; i < len; i += 1) {
      if (assets[i].xt) {
        var comp = this.createComp(assets[i]);
        comp.initExpressions();
        this.globalData.projectInterface.registerComposition(comp);
      }
    }
  };
  BaseRenderer.prototype.getElementById = function (ind) {
    var i;
    var len = this.elements.length;
    for (i = 0; i < len; i += 1) {
      if (this.elements[i].data.ind === ind) {
        return this.elements[i];
      }
    }
    return null;
  };
  BaseRenderer.prototype.getElementByPath = function (path) {
    var pathValue = path.shift();
    var element;
    if (typeof pathValue === 'number') {
      element = this.elements[pathValue];
    } else {
      var i;
      var len = this.elements.length;
      for (i = 0; i < len; i += 1) {
        if (this.elements[i].data.nm === pathValue) {
          element = this.elements[i];
          break;
        }
      }
    }
    if (path.length === 0) {
      return element;
    }
    return element.getElementByPath(path);
  };
  BaseRenderer.prototype.setupGlobalData = function (animData, fontsContainer) {
    this.globalData.fontManager = new FontManager();
    this.globalData.slotManager = slotFactory(animData);
    this.globalData.fontManager.addChars(animData.chars);
    this.globalData.fontManager.addFonts(animData.fonts, fontsContainer);
    this.globalData.getAssetData = this.animationItem.getAssetData.bind(this.animationItem);
    this.globalData.getAssetsPath = this.animationItem.getAssetsPath.bind(this.animationItem);
    this.globalData.imageLoader = this.animationItem.imagePreloader;
    this.globalData.audioController = this.animationItem.audioController;
    this.globalData.frameId = 0;
    this.globalData.frameRate = animData.fr;
    this.globalData.nm = animData.nm;
    this.globalData.compSize = {
      w: animData.w,
      h: animData.h
    };
  };
  var effectTypes = {
    TRANSFORM_EFFECT: 'transformEFfect'
  };
  function TransformElement() {}
  TransformElement.prototype = {
    initTransform: function initTransform() {
      var mat = new Matrix();
      this.finalTransform = {
        mProp: this.data.ks ? TransformPropertyFactory.getTransformProperty(this, this.data.ks, this) : {
          o: 0
        },
        _matMdf: false,
        _localMatMdf: false,
        _opMdf: false,
        mat: mat,
        localMat: mat,
        localOpacity: 1
      };
      if (this.data.ao) {
        this.finalTransform.mProp.autoOriented = true;
      }

      // TODO: check TYPE 11: Guided elements
      if (this.data.ty !== 11) {
        // this.createElements();
      }
    },
    renderTransform: function renderTransform() {
      this.finalTransform._opMdf = this.finalTransform.mProp.o._mdf || this._isFirstFrame;
      this.finalTransform._matMdf = this.finalTransform.mProp._mdf || this._isFirstFrame;
      if (this.hierarchy) {
        var mat;
        var finalMat = this.finalTransform.mat;
        var i = 0;
        var len = this.hierarchy.length;
        // Checking if any of the transformation matrices in the hierarchy chain has changed.
        if (!this.finalTransform._matMdf) {
          while (i < len) {
            if (this.hierarchy[i].finalTransform.mProp._mdf) {
              this.finalTransform._matMdf = true;
              break;
            }
            i += 1;
          }
        }
        if (this.finalTransform._matMdf) {
          mat = this.finalTransform.mProp.v.props;
          finalMat.cloneFromProps(mat);
          for (i = 0; i < len; i += 1) {
            finalMat.multiply(this.hierarchy[i].finalTransform.mProp.v);
          }
        }
      }
      if (!this.localTransforms || this.finalTransform._matMdf) {
        this.finalTransform._localMatMdf = this.finalTransform._matMdf;
      }
      if (this.finalTransform._opMdf) {
        this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
      }
    },
    renderLocalTransform: function renderLocalTransform() {
      if (this.localTransforms) {
        var i = 0;
        var len = this.localTransforms.length;
        this.finalTransform._localMatMdf = this.finalTransform._matMdf;
        if (!this.finalTransform._localMatMdf || !this.finalTransform._opMdf) {
          while (i < len) {
            if (this.localTransforms[i]._mdf) {
              this.finalTransform._localMatMdf = true;
            }
            if (this.localTransforms[i]._opMdf && !this.finalTransform._opMdf) {
              this.finalTransform.localOpacity = this.finalTransform.mProp.o.v;
              this.finalTransform._opMdf = true;
            }
            i += 1;
          }
        }
        if (this.finalTransform._localMatMdf) {
          var localMat = this.finalTransform.localMat;
          this.localTransforms[0].matrix.clone(localMat);
          for (i = 1; i < len; i += 1) {
            var lmat = this.localTransforms[i].matrix;
            localMat.multiply(lmat);
          }
          localMat.multiply(this.finalTransform.mat);
        }
        if (this.finalTransform._opMdf) {
          var localOp = this.finalTransform.localOpacity;
          for (i = 0; i < len; i += 1) {
            localOp *= this.localTransforms[i].opacity * 0.01;
          }
          this.finalTransform.localOpacity = localOp;
        }
      }
    },
    searchEffectTransforms: function searchEffectTransforms() {
      if (this.renderableEffectsManager) {
        var transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
        if (transformEffects.length) {
          this.localTransforms = [];
          this.finalTransform.localMat = new Matrix();
          var i = 0;
          var len = transformEffects.length;
          for (i = 0; i < len; i += 1) {
            this.localTransforms.push(transformEffects[i]);
          }
        }
      }
    },
    globalToLocal: function globalToLocal(pt) {
      var transforms = [];
      transforms.push(this.finalTransform);
      var flag = true;
      var comp = this.comp;
      while (flag) {
        if (comp.finalTransform) {
          if (comp.data.hasMask) {
            transforms.splice(0, 0, comp.finalTransform);
          }
          comp = comp.comp;
        } else {
          flag = false;
        }
      }
      var i;
      var len = transforms.length;
      var ptNew;
      for (i = 0; i < len; i += 1) {
        ptNew = transforms[i].mat.applyToPointArray(0, 0, 0);
        // ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]);
        pt = [pt[0] - ptNew[0], pt[1] - ptNew[1], 0];
      }
      return pt;
    },
    mHelper: new Matrix()
  };
  function MaskElement(data, element, globalData) {
    this.data = data;
    this.element = element;
    this.globalData = globalData;
    this.storedData = [];
    this.masksProperties = this.data.masksProperties || [];
    this.maskElement = null;
    var defs = this.globalData.defs;
    var i;
    var len = this.masksProperties ? this.masksProperties.length : 0;
    this.viewData = createSizedArray(len);
    this.solidPath = '';
    var path;
    var properties = this.masksProperties;
    var count = 0;
    var currentMasks = [];
    var j;
    var jLen;
    var layerId = createElementID();
    var rect;
    var expansor;
    var feMorph;
    var x;
    var maskType = 'clipPath';
    var maskRef = 'clip-path';
    for (i = 0; i < len; i += 1) {
      if (properties[i].mode !== 'a' && properties[i].mode !== 'n' || properties[i].inv || properties[i].o.k !== 100 || properties[i].o.x) {
        maskType = 'mask';
        maskRef = 'mask';
      }
      if ((properties[i].mode === 's' || properties[i].mode === 'i') && count === 0) {
        rect = createNS('rect');
        rect.setAttribute('fill', '#ffffff');
        rect.setAttribute('width', this.element.comp.data.w || 0);
        rect.setAttribute('height', this.element.comp.data.h || 0);
        currentMasks.push(rect);
      } else {
        rect = null;
      }
      path = createNS('path');
      if (properties[i].mode === 'n') {
        // TODO move this to a factory or to a constructor
        this.viewData[i] = {
          op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
          prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
          elem: path,
          lastPath: ''
        };
        defs.appendChild(path);
      } else {
        count += 1;
        path.setAttribute('fill', properties[i].mode === 's' ? '#000000' : '#ffffff');
        path.setAttribute('clip-rule', 'nonzero');
        var filterID;
        if (properties[i].x.k !== 0) {
          maskType = 'mask';
          maskRef = 'mask';
          x = PropertyFactory.getProp(this.element, properties[i].x, 0, null, this.element);
          filterID = createElementID();
          expansor = createNS('filter');
          expansor.setAttribute('id', filterID);
          feMorph = createNS('feMorphology');
          feMorph.setAttribute('operator', 'erode');
          feMorph.setAttribute('in', 'SourceGraphic');
          feMorph.setAttribute('radius', '0');
          expansor.appendChild(feMorph);
          defs.appendChild(expansor);
          path.setAttribute('stroke', properties[i].mode === 's' ? '#000000' : '#ffffff');
        } else {
          feMorph = null;
          x = null;
        }

        // TODO move this to a factory or to a constructor
        this.storedData[i] = {
          elem: path,
          x: x,
          expan: feMorph,
          lastPath: '',
          lastOperator: '',
          filterId: filterID,
          lastRadius: 0
        };
        if (properties[i].mode === 'i') {
          jLen = currentMasks.length;
          var g = createNS('g');
          for (j = 0; j < jLen; j += 1) {
            g.appendChild(currentMasks[j]);
          }
          var mask = createNS('mask');
          mask.setAttribute('mask-type', 'alpha');
          mask.setAttribute('id', layerId + '_' + count);
          mask.appendChild(path);
          defs.appendChild(mask);
          g.setAttribute('mask', 'url(' + getLocationHref() + '#' + layerId + '_' + count + ')');
          currentMasks.length = 0;
          currentMasks.push(g);
        } else {
          currentMasks.push(path);
        }
        if (properties[i].inv && !this.solidPath) {
          this.solidPath = this.createLayerSolidPath();
        }
        // TODO move this to a factory or to a constructor
        this.viewData[i] = {
          elem: path,
          lastPath: '',
          op: PropertyFactory.getProp(this.element, properties[i].o, 0, 0.01, this.element),
          prop: ShapePropertyFactory.getShapeProp(this.element, properties[i], 3),
          invRect: rect
        };
        if (!this.viewData[i].prop.k) {
          this.drawPath(properties[i], this.viewData[i].prop.v, this.viewData[i]);
        }
      }
    }
    this.maskElement = createNS(maskType);
    len = currentMasks.length;
    for (i = 0; i < len; i += 1) {
      this.maskElement.appendChild(currentMasks[i]);
    }
    if (count > 0) {
      this.maskElement.setAttribute('id', layerId);
      this.element.maskedElement.setAttribute(maskRef, 'url(' + getLocationHref() + '#' + layerId + ')');
      defs.appendChild(this.maskElement);
    }
    if (this.viewData.length) {
      this.element.addRenderableComponent(this);
    }
  }
  MaskElement.prototype.getMaskProperty = function (pos) {
    return this.viewData[pos].prop;
  };
  MaskElement.prototype.renderFrame = function (isFirstFrame) {
    var finalMat = this.element.finalTransform.mat;
    var i;
    var len = this.masksProperties.length;
    for (i = 0; i < len; i += 1) {
      if (this.viewData[i].prop._mdf || isFirstFrame) {
        this.drawPath(this.masksProperties[i], this.viewData[i].prop.v, this.viewData[i]);
      }
      if (this.viewData[i].op._mdf || isFirstFrame) {
        this.viewData[i].elem.setAttribute('fill-opacity', this.viewData[i].op.v);
      }
      if (this.masksProperties[i].mode !== 'n') {
        if (this.viewData[i].invRect && (this.element.finalTransform.mProp._mdf || isFirstFrame)) {
          this.viewData[i].invRect.setAttribute('transform', finalMat.getInverseMatrix().to2dCSS());
        }
        if (this.storedData[i].x && (this.storedData[i].x._mdf || isFirstFrame)) {
          var feMorph = this.storedData[i].expan;
          if (this.storedData[i].x.v < 0) {
            if (this.storedData[i].lastOperator !== 'erode') {
              this.storedData[i].lastOperator = 'erode';
              this.storedData[i].elem.setAttribute('filter', 'url(' + getLocationHref() + '#' + this.storedData[i].filterId + ')');
            }
            feMorph.setAttribute('radius', -this.storedData[i].x.v);
          } else {
            if (this.storedData[i].lastOperator !== 'dilate') {
              this.storedData[i].lastOperator = 'dilate';
              this.storedData[i].elem.setAttribute('filter', null);
            }
            this.storedData[i].elem.setAttribute('stroke-width', this.storedData[i].x.v * 2);
          }
        }
      }
    }
  };
  MaskElement.prototype.getMaskelement = function () {
    return this.maskElement;
  };
  MaskElement.prototype.createLayerSolidPath = function () {
    var path = 'M0,0 ';
    path += ' h' + this.globalData.compSize.w;
    path += ' v' + this.globalData.compSize.h;
    path += ' h-' + this.globalData.compSize.w;
    path += ' v-' + this.globalData.compSize.h + ' ';
    return path;
  };
  MaskElement.prototype.drawPath = function (pathData, pathNodes, viewData) {
    var pathString = ' M' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
    var i;
    var len;
    len = pathNodes._length;
    for (i = 1; i < len; i += 1) {
      // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[i][0]+','+pathNodes.i[i][1] + " "+pathNodes.v[i][0]+','+pathNodes.v[i][1];
      pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[i][0] + ',' + pathNodes.i[i][1] + ' ' + pathNodes.v[i][0] + ',' + pathNodes.v[i][1];
    }
    // pathString += " C"+pathNodes.o[i-1][0]+','+pathNodes.o[i-1][1] + " "+pathNodes.i[0][0]+','+pathNodes.i[0][1] + " "+pathNodes.v[0][0]+','+pathNodes.v[0][1];
    if (pathNodes.c && len > 1) {
      pathString += ' C' + pathNodes.o[i - 1][0] + ',' + pathNodes.o[i - 1][1] + ' ' + pathNodes.i[0][0] + ',' + pathNodes.i[0][1] + ' ' + pathNodes.v[0][0] + ',' + pathNodes.v[0][1];
    }
    // pathNodes.__renderedString = pathString;

    if (viewData.lastPath !== pathString) {
      var pathShapeValue = '';
      if (viewData.elem) {
        if (pathNodes.c) {
          pathShapeValue = pathData.inv ? this.solidPath + pathString : pathString;
        }
        viewData.elem.setAttribute('d', pathShapeValue);
      }
      viewData.lastPath = pathString;
    }
  };
  MaskElement.prototype.destroy = function () {
    this.element = null;
    this.globalData = null;
    this.maskElement = null;
    this.data = null;
    this.masksProperties = null;
  };
  var filtersFactory = function () {
    var ob = {};
    ob.createFilter = createFilter;
    ob.createAlphaToLuminanceFilter = createAlphaToLuminanceFilter;
    function createFilter(filId, skipCoordinates) {
      var fil = createNS('filter');
      fil.setAttribute('id', filId);
      if (skipCoordinates !== true) {
        fil.setAttribute('filterUnits', 'objectBoundingBox');
        fil.setAttribute('x', '0%');
        fil.setAttribute('y', '0%');
        fil.setAttribute('width', '100%');
        fil.setAttribute('height', '100%');
      }
      return fil;
    }
    function createAlphaToLuminanceFilter() {
      var feColorMatrix = createNS('feColorMatrix');
      feColorMatrix.setAttribute('type', 'matrix');
      feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
      feColorMatrix.setAttribute('values', '0 0 0 1 0  0 0 0 1 0  0 0 0 1 0  0 0 0 1 1');
      return feColorMatrix;
    }
    return ob;
  }();
  var featureSupport = function () {
    var ob = {
      maskType: true,
      svgLumaHidden: true,
      offscreenCanvas: typeof OffscreenCanvas !== 'undefined'
    };
    if (/MSIE 10/i.test(navigator.userAgent) || /MSIE 9/i.test(navigator.userAgent) || /rv:11.0/i.test(navigator.userAgent) || /Edge\/\d./i.test(navigator.userAgent)) {
      ob.maskType = false;
    }
    if (/firefox/i.test(navigator.userAgent)) {
      ob.svgLumaHidden = false;
    }
    return ob;
  }();
  var registeredEffects$1 = {};
  var idPrefix = 'filter_result_';
  function SVGEffects(elem) {
    var i;
    var source = 'SourceGraphic';
    var len = elem.data.ef ? elem.data.ef.length : 0;
    var filId = createElementID();
    var fil = filtersFactory.createFilter(filId, true);
    var count = 0;
    this.filters = [];
    var filterManager;
    for (i = 0; i < len; i += 1) {
      filterManager = null;
      var type = elem.data.ef[i].ty;
      if (registeredEffects$1[type]) {
        var Effect = registeredEffects$1[type].effect;
        filterManager = new Effect(fil, elem.effectsManager.effectElements[i], elem, idPrefix + count, source);
        source = idPrefix + count;
        if (registeredEffects$1[type].countsAsEffect) {
          count += 1;
        }
      }
      if (filterManager) {
        this.filters.push(filterManager);
      }
    }
    if (count) {
      elem.globalData.defs.appendChild(fil);
      elem.layerElement.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
    }
    if (this.filters.length) {
      elem.addRenderableComponent(this);
    }
  }
  SVGEffects.prototype.renderFrame = function (_isFirstFrame) {
    var i;
    var len = this.filters.length;
    for (i = 0; i < len; i += 1) {
      this.filters[i].renderFrame(_isFirstFrame);
    }
  };
  SVGEffects.prototype.getEffects = function (type) {
    var i;
    var len = this.filters.length;
    var effects = [];
    for (i = 0; i < len; i += 1) {
      if (this.filters[i].type === type) {
        effects.push(this.filters[i]);
      }
    }
    return effects;
  };
  function registerEffect$1(id, effect, countsAsEffect) {
    registeredEffects$1[id] = {
      effect: effect,
      countsAsEffect: countsAsEffect
    };
  }
  function SVGBaseElement() {}
  SVGBaseElement.prototype = {
    initRendererElement: function initRendererElement() {
      this.layerElement = createNS('g');
    },
    createContainerElements: function createContainerElements() {
      this.matteElement = createNS('g');
      this.transformedElement = this.layerElement;
      this.maskedElement = this.layerElement;
      this._sizeChanged = false;
      var layerElementParent = null;
      // If this layer acts as a mask for the following layer
      if (this.data.td) {
        this.matteMasks = {};
        var gg = createNS('g');
        gg.setAttribute('id', this.layerId);
        gg.appendChild(this.layerElement);
        layerElementParent = gg;
        this.globalData.defs.appendChild(gg);
      } else if (this.data.tt) {
        this.matteElement.appendChild(this.layerElement);
        layerElementParent = this.matteElement;
        this.baseElement = this.matteElement;
      } else {
        this.baseElement = this.layerElement;
      }
      if (this.data.ln) {
        this.layerElement.setAttribute('id', this.data.ln);
      }
      if (this.data.cl) {
        this.layerElement.setAttribute('class', this.data.cl);
      }
      // Clipping compositions to hide content that exceeds boundaries. If collapsed transformations is on, component should not be clipped
      if (this.data.ty === 0 && !this.data.hd) {
        var cp = createNS('clipPath');
        var pt = createNS('path');
        pt.setAttribute('d', 'M0,0 L' + this.data.w + ',0 L' + this.data.w + ',' + this.data.h + ' L0,' + this.data.h + 'z');
        var clipId = createElementID();
        cp.setAttribute('id', clipId);
        cp.appendChild(pt);
        this.globalData.defs.appendChild(cp);
        if (this.checkMasks()) {
          var cpGroup = createNS('g');
          cpGroup.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
          cpGroup.appendChild(this.layerElement);
          this.transformedElement = cpGroup;
          if (layerElementParent) {
            layerElementParent.appendChild(this.transformedElement);
          } else {
            this.baseElement = this.transformedElement;
          }
        } else {
          this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + clipId + ')');
        }
      }
      if (this.data.bm !== 0) {
        this.setBlendMode();
      }
    },
    renderElement: function renderElement() {
      if (this.finalTransform._localMatMdf) {
        this.transformedElement.setAttribute('transform', this.finalTransform.localMat.to2dCSS());
      }
      if (this.finalTransform._opMdf) {
        this.transformedElement.setAttribute('opacity', this.finalTransform.localOpacity);
      }
    },
    destroyBaseElement: function destroyBaseElement() {
      this.layerElement = null;
      this.matteElement = null;
      this.maskManager.destroy();
    },
    getBaseElement: function getBaseElement() {
      if (this.data.hd) {
        return null;
      }
      return this.baseElement;
    },
    createRenderableComponents: function createRenderableComponents() {
      this.maskManager = new MaskElement(this.data, this, this.globalData);
      this.renderableEffectsManager = new SVGEffects(this);
      this.searchEffectTransforms();
    },
    getMatte: function getMatte(matteType) {
      // This should not be a common case. But for backward compatibility, we'll create the matte object.
      // It solves animations that have two consecutive layers marked as matte masks.
      // Which is an undefined behavior in AE.
      if (!this.matteMasks) {
        this.matteMasks = {};
      }
      if (!this.matteMasks[matteType]) {
        var id = this.layerId + '_' + matteType;
        var filId;
        var fil;
        var useElement;
        var gg;
        if (matteType === 1 || matteType === 3) {
          var masker = createNS('mask');
          masker.setAttribute('id', id);
          masker.setAttribute('mask-type', matteType === 3 ? 'luminance' : 'alpha');
          useElement = createNS('use');
          useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
          masker.appendChild(useElement);
          this.globalData.defs.appendChild(masker);
          if (!featureSupport.maskType && matteType === 1) {
            masker.setAttribute('mask-type', 'luminance');
            filId = createElementID();
            fil = filtersFactory.createFilter(filId);
            this.globalData.defs.appendChild(fil);
            fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
            gg = createNS('g');
            gg.appendChild(useElement);
            masker.appendChild(gg);
            gg.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
          }
        } else if (matteType === 2) {
          var maskGroup = createNS('mask');
          maskGroup.setAttribute('id', id);
          maskGroup.setAttribute('mask-type', 'alpha');
          var maskGrouper = createNS('g');
          maskGroup.appendChild(maskGrouper);
          filId = createElementID();
          fil = filtersFactory.createFilter(filId);
          /// /
          var feCTr = createNS('feComponentTransfer');
          feCTr.setAttribute('in', 'SourceGraphic');
          fil.appendChild(feCTr);
          var feFunc = createNS('feFuncA');
          feFunc.setAttribute('type', 'table');
          feFunc.setAttribute('tableValues', '1.0 0.0');
          feCTr.appendChild(feFunc);
          /// /
          this.globalData.defs.appendChild(fil);
          var alphaRect = createNS('rect');
          alphaRect.setAttribute('width', this.comp.data.w);
          alphaRect.setAttribute('height', this.comp.data.h);
          alphaRect.setAttribute('x', '0');
          alphaRect.setAttribute('y', '0');
          alphaRect.setAttribute('fill', '#ffffff');
          alphaRect.setAttribute('opacity', '0');
          maskGrouper.setAttribute('filter', 'url(' + getLocationHref() + '#' + filId + ')');
          maskGrouper.appendChild(alphaRect);
          useElement = createNS('use');
          useElement.setAttributeNS('http://www.w3.org/1999/xlink', 'href', '#' + this.layerId);
          maskGrouper.appendChild(useElement);
          if (!featureSupport.maskType) {
            maskGroup.setAttribute('mask-type', 'luminance');
            fil.appendChild(filtersFactory.createAlphaToLuminanceFilter());
            gg = createNS('g');
            maskGrouper.appendChild(alphaRect);
            gg.appendChild(this.layerElement);
            maskGrouper.appendChild(gg);
          }
          this.globalData.defs.appendChild(maskGroup);
        }
        this.matteMasks[matteType] = id;
      }
      return this.matteMasks[matteType];
    },
    setMatte: function setMatte(id) {
      if (!this.matteElement) {
        return;
      }
      this.matteElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
    }
  };

  /**
   * @file
   * Handles AE's layer parenting property.
   *
   */

  function HierarchyElement() {}
  HierarchyElement.prototype = {
    /**
       * @function
       * Initializes hierarchy properties
       *
       */
    initHierarchy: function initHierarchy() {
      // element's parent list
      this.hierarchy = [];
      // if element is parent of another layer _isParent will be true
      this._isParent = false;
      this.checkParenting();
    },
    /**
       * @function
       * Sets layer's hierarchy.
       * @param {array} hierarch
       * layer's parent list
       *
       */
    setHierarchy: function setHierarchy(hierarchy) {
      this.hierarchy = hierarchy;
    },
    /**
       * @function
       * Sets layer as parent.
       *
       */
    setAsParent: function setAsParent() {
      this._isParent = true;
    },
    /**
       * @function
       * Searches layer's parenting chain
       *
       */
    checkParenting: function checkParenting() {
      if (this.data.parent !== undefined) {
        this.comp.buildElementParenting(this, this.data.parent, []);
      }
    }
  };
  function RenderableDOMElement() {}
  (function () {
    var _prototype = {
      initElement: function initElement(data, globalData, comp) {
        this.initFrame();
        this.initBaseData(data, globalData, comp);
        this.initTransform(data, globalData, comp);
        this.initHierarchy();
        this.initRenderable();
        this.initRendererElement();
        this.createContainerElements();
        this.createRenderableComponents();
        this.createContent();
        this.hide();
      },
      hide: function hide() {
        // console.log('HIDE', this);
        if (!this.hidden && (!this.isInRange || this.isTransparent)) {
          var elem = this.baseElement || this.layerElement;
          elem.style.display = 'none';
          this.hidden = true;
        }
      },
      show: function show() {
        // console.log('SHOW', this);
        if (this.isInRange && !this.isTransparent) {
          if (!this.data.hd) {
            var elem = this.baseElement || this.layerElement;
            elem.style.display = 'block';
          }
          this.hidden = false;
          this._isFirstFrame = true;
        }
      },
      renderFrame: function renderFrame() {
        // If it is exported as hidden (data.hd === true) no need to render
        // If it is not visible no need to render
        if (this.data.hd || this.hidden) {
          return;
        }
        this.renderTransform();
        this.renderRenderable();
        this.renderLocalTransform();
        this.renderElement();
        this.renderInnerContent();
        if (this._isFirstFrame) {
          this._isFirstFrame = false;
        }
      },
      renderInnerContent: function renderInnerContent() {},
      prepareFrame: function prepareFrame(num) {
        this._mdf = false;
        this.prepareRenderableFrame(num);
        this.prepareProperties(num, this.isInRange);
        this.checkTransparency();
      },
      destroy: function destroy() {
        this.innerElem = null;
        this.destroyBaseElement();
      }
    };
    extendPrototype([RenderableElement, createProxyFunction(_prototype)], RenderableDOMElement);
  })();
  function IImageElement(data, globalData, comp) {
    this.assetData = globalData.getAssetData(data.refId);
    if (this.assetData && this.assetData.sid) {
      this.assetData = globalData.slotManager.getProp(this.assetData);
    }
    this.initElement(data, globalData, comp);
    this.sourceRect = {
      top: 0,
      left: 0,
      width: this.assetData.w,
      height: this.assetData.h
    };
  }
  extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], IImageElement);
  IImageElement.prototype.createContent = function () {
    var assetPath = this.globalData.getAssetsPath(this.assetData);
    this.innerElem = createNS('image');
    this.innerElem.setAttribute('width', this.assetData.w + 'px');
    this.innerElem.setAttribute('height', this.assetData.h + 'px');
    this.innerElem.setAttribute('preserveAspectRatio', this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio);
    this.innerElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
    this.layerElement.appendChild(this.innerElem);
  };
  IImageElement.prototype.sourceRectAtTime = function () {
    return this.sourceRect;
  };
  function ProcessedElement(element, position) {
    this.elem = element;
    this.pos = position;
  }
  function IShapeElement() {}
  IShapeElement.prototype = {
    addShapeToModifiers: function addShapeToModifiers(data) {
      var i;
      var len = this.shapeModifiers.length;
      for (i = 0; i < len; i += 1) {
        this.shapeModifiers[i].addShape(data);
      }
    },
    isShapeInAnimatedModifiers: function isShapeInAnimatedModifiers(data) {
      var i = 0;
      var len = this.shapeModifiers.length;
      while (i < len) {
        if (this.shapeModifiers[i].isAnimatedWithShape(data)) {
          return true;
        }
      }
      return false;
    },
    renderModifiers: function renderModifiers() {
      if (!this.shapeModifiers.length) {
        return;
      }
      var i;
      var len = this.shapes.length;
      for (i = 0; i < len; i += 1) {
        this.shapes[i].sh.reset();
      }
      len = this.shapeModifiers.length;
      var shouldBreakProcess;
      for (i = len - 1; i >= 0; i -= 1) {
        shouldBreakProcess = this.shapeModifiers[i].processShapes(this._isFirstFrame);
        // workaround to fix cases where a repeater resets the shape so the following processes get called twice
        // TODO: find a better solution for this
        if (shouldBreakProcess) {
          break;
        }
      }
    },
    searchProcessedElement: function searchProcessedElement(elem) {
      var elements = this.processedElements;
      var i = 0;
      var len = elements.length;
      while (i < len) {
        if (elements[i].elem === elem) {
          return elements[i].pos;
        }
        i += 1;
      }
      return 0;
    },
    addProcessedElement: function addProcessedElement(elem, pos) {
      var elements = this.processedElements;
      var i = elements.length;
      while (i) {
        i -= 1;
        if (elements[i].elem === elem) {
          elements[i].pos = pos;
          return;
        }
      }
      elements.push(new ProcessedElement(elem, pos));
    },
    prepareFrame: function prepareFrame(num) {
      this.prepareRenderableFrame(num);
      this.prepareProperties(num, this.isInRange);
    }
  };
  var lineCapEnum = {
    1: 'butt',
    2: 'round',
    3: 'square'
  };
  var lineJoinEnum = {
    1: 'miter',
    2: 'round',
    3: 'bevel'
  };
  function SVGShapeData(transformers, level, shape) {
    this.caches = [];
    this.styles = [];
    this.transformers = transformers;
    this.lStr = '';
    this.sh = shape;
    this.lvl = level;
    // TODO find if there are some cases where _isAnimated can be false.
    // For now, since shapes add up with other shapes. They have to be calculated every time.
    // One way of finding out is checking if all styles associated to this shape depend only of this shape
    this._isAnimated = !!shape.k;
    // TODO: commenting this for now since all shapes are animated
    var i = 0;
    var len = transformers.length;
    while (i < len) {
      if (transformers[i].mProps.dynamicProperties.length) {
        this._isAnimated = true;
        break;
      }
      i += 1;
    }
  }
  SVGShapeData.prototype.setAsAnimated = function () {
    this._isAnimated = true;
  };
  function SVGStyleData(data, level) {
    this.data = data;
    this.type = data.ty;
    this.d = '';
    this.lvl = level;
    this._mdf = false;
    this.closed = data.hd === true;
    this.pElem = createNS('path');
    this.msElem = null;
  }
  SVGStyleData.prototype.reset = function () {
    this.d = '';
    this._mdf = false;
  };
  function DashProperty(elem, data, renderer, container) {
    this.elem = elem;
    this.frameId = -1;
    this.dataProps = createSizedArray(data.length);
    this.renderer = renderer;
    this.k = false;
    this.dashStr = '';
    this.dashArray = createTypedArray('float32', data.length ? data.length - 1 : 0);
    this.dashoffset = createTypedArray('float32', 1);
    this.initDynamicPropertyContainer(container);
    var i;
    var len = data.length || 0;
    var prop;
    for (i = 0; i < len; i += 1) {
      prop = PropertyFactory.getProp(elem, data[i].v, 0, 0, this);
      this.k = prop.k || this.k;
      this.dataProps[i] = {
        n: data[i].n,
        p: prop
      };
    }
    if (!this.k) {
      this.getValue(true);
    }
    this._isAnimated = this.k;
  }
  DashProperty.prototype.getValue = function (forceRender) {
    if (this.elem.globalData.frameId === this.frameId && !forceRender) {
      return;
    }
    this.frameId = this.elem.globalData.frameId;
    this.iterateDynamicProperties();
    this._mdf = this._mdf || forceRender;
    if (this._mdf) {
      var i = 0;
      var len = this.dataProps.length;
      if (this.renderer === 'svg') {
        this.dashStr = '';
      }
      for (i = 0; i < len; i += 1) {
        if (this.dataProps[i].n !== 'o') {
          if (this.renderer === 'svg') {
            this.dashStr += ' ' + this.dataProps[i].p.v;
          } else {
            this.dashArray[i] = this.dataProps[i].p.v;
          }
        } else {
          this.dashoffset[0] = this.dataProps[i].p.v;
        }
      }
    }
  };
  extendPrototype([DynamicPropertyContainer], DashProperty);
  function SVGStrokeStyleData(elem, data, styleOb) {
    this.initDynamicPropertyContainer(elem);
    this.getValue = this.iterateDynamicProperties;
    this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
    this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
    this.d = new DashProperty(elem, data.d || {}, 'svg', this);
    this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
    this.style = styleOb;
    this._isAnimated = !!this._isAnimated;
  }
  extendPrototype([DynamicPropertyContainer], SVGStrokeStyleData);
  function SVGFillStyleData(elem, data, styleOb) {
    this.initDynamicPropertyContainer(elem);
    this.getValue = this.iterateDynamicProperties;
    this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
    this.c = PropertyFactory.getProp(elem, data.c, 1, 255, this);
    this.style = styleOb;
  }
  extendPrototype([DynamicPropertyContainer], SVGFillStyleData);
  function SVGNoStyleData(elem, data, styleOb) {
    this.initDynamicPropertyContainer(elem);
    this.getValue = this.iterateDynamicProperties;
    this.style = styleOb;
  }
  extendPrototype([DynamicPropertyContainer], SVGNoStyleData);
  function GradientProperty(elem, data, container) {
    this.data = data;
    this.c = createTypedArray('uint8c', data.p * 4);
    var cLength = data.k.k[0].s ? data.k.k[0].s.length - data.p * 4 : data.k.k.length - data.p * 4;
    this.o = createTypedArray('float32', cLength);
    this._cmdf = false;
    this._omdf = false;
    this._collapsable = this.checkCollapsable();
    this._hasOpacity = cLength;
    this.initDynamicPropertyContainer(container);
    this.prop = PropertyFactory.getProp(elem, data.k, 1, null, this);
    this.k = this.prop.k;
    this.getValue(true);
  }
  GradientProperty.prototype.comparePoints = function (values, points) {
    var i = 0;
    var len = this.o.length / 2;
    var diff;
    while (i < len) {
      diff = Math.abs(values[i * 4] - values[points * 4 + i * 2]);
      if (diff > 0.01) {
        return false;
      }
      i += 1;
    }
    return true;
  };
  GradientProperty.prototype.checkCollapsable = function () {
    if (this.o.length / 2 !== this.c.length / 4) {
      return false;
    }
    if (this.data.k.k[0].s) {
      var i = 0;
      var len = this.data.k.k.length;
      while (i < len) {
        if (!this.comparePoints(this.data.k.k[i].s, this.data.p)) {
          return false;
        }
        i += 1;
      }
    } else if (!this.comparePoints(this.data.k.k, this.data.p)) {
      return false;
    }
    return true;
  };
  GradientProperty.prototype.getValue = function (forceRender) {
    this.prop.getValue();
    this._mdf = false;
    this._cmdf = false;
    this._omdf = false;
    if (this.prop._mdf || forceRender) {
      var i;
      var len = this.data.p * 4;
      var mult;
      var val;
      for (i = 0; i < len; i += 1) {
        mult = i % 4 === 0 ? 100 : 255;
        val = Math.round(this.prop.v[i] * mult);
        if (this.c[i] !== val) {
          this.c[i] = val;
          this._cmdf = !forceRender;
        }
      }
      if (this.o.length) {
        len = this.prop.v.length;
        for (i = this.data.p * 4; i < len; i += 1) {
          mult = i % 2 === 0 ? 100 : 1;
          val = i % 2 === 0 ? Math.round(this.prop.v[i] * 100) : this.prop.v[i];
          if (this.o[i - this.data.p * 4] !== val) {
            this.o[i - this.data.p * 4] = val;
            this._omdf = !forceRender;
          }
        }
      }
      this._mdf = !forceRender;
    }
  };
  extendPrototype([DynamicPropertyContainer], GradientProperty);
  function SVGGradientFillStyleData(elem, data, styleOb) {
    this.initDynamicPropertyContainer(elem);
    this.getValue = this.iterateDynamicProperties;
    this.initGradientData(elem, data, styleOb);
  }
  SVGGradientFillStyleData.prototype.initGradientData = function (elem, data, styleOb) {
    this.o = PropertyFactory.getProp(elem, data.o, 0, 0.01, this);
    this.s = PropertyFactory.getProp(elem, data.s, 1, null, this);
    this.e = PropertyFactory.getProp(elem, data.e, 1, null, this);
    this.h = PropertyFactory.getProp(elem, data.h || {
      k: 0
    }, 0, 0.01, this);
    this.a = PropertyFactory.getProp(elem, data.a || {
      k: 0
    }, 0, degToRads, this);
    this.g = new GradientProperty(elem, data.g, this);
    this.style = styleOb;
    this.stops = [];
    this.setGradientData(styleOb.pElem, data);
    this.setGradientOpacity(data, styleOb);
    this._isAnimated = !!this._isAnimated;
  };
  SVGGradientFillStyleData.prototype.setGradientData = function (pathElement, data) {
    var gradientId = createElementID();
    var gfill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
    gfill.setAttribute('id', gradientId);
    gfill.setAttribute('spreadMethod', 'pad');
    gfill.setAttribute('gradientUnits', 'userSpaceOnUse');
    var stops = [];
    var stop;
    var j;
    var jLen;
    jLen = data.g.p * 4;
    for (j = 0; j < jLen; j += 4) {
      stop = createNS('stop');
      gfill.appendChild(stop);
      stops.push(stop);
    }
    pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + gradientId + ')');
    this.gf = gfill;
    this.cst = stops;
  };
  SVGGradientFillStyleData.prototype.setGradientOpacity = function (data, styleOb) {
    if (this.g._hasOpacity && !this.g._collapsable) {
      var stop;
      var j;
      var jLen;
      var mask = createNS('mask');
      var maskElement = createNS('path');
      mask.appendChild(maskElement);
      var opacityId = createElementID();
      var maskId = createElementID();
      mask.setAttribute('id', maskId);
      var opFill = createNS(data.t === 1 ? 'linearGradient' : 'radialGradient');
      opFill.setAttribute('id', opacityId);
      opFill.setAttribute('spreadMethod', 'pad');
      opFill.setAttribute('gradientUnits', 'userSpaceOnUse');
      jLen = data.g.k.k[0].s ? data.g.k.k[0].s.length : data.g.k.k.length;
      var stops = this.stops;
      for (j = data.g.p * 4; j < jLen; j += 2) {
        stop = createNS('stop');
        stop.setAttribute('stop-color', 'rgb(255,255,255)');
        opFill.appendChild(stop);
        stops.push(stop);
      }
      maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + getLocationHref() + '#' + opacityId + ')');
      if (data.ty === 'gs') {
        maskElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
        maskElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
        if (data.lj === 1) {
          maskElement.setAttribute('stroke-miterlimit', data.ml);
        }
      }
      this.of = opFill;
      this.ms = mask;
      this.ost = stops;
      this.maskId = maskId;
      styleOb.msElem = maskElement;
    }
  };
  extendPrototype([DynamicPropertyContainer], SVGGradientFillStyleData);
  function SVGGradientStrokeStyleData(elem, data, styleOb) {
    this.initDynamicPropertyContainer(elem);
    this.getValue = this.iterateDynamicProperties;
    this.w = PropertyFactory.getProp(elem, data.w, 0, null, this);
    this.d = new DashProperty(elem, data.d || {}, 'svg', this);
    this.initGradientData(elem, data, styleOb);
    this._isAnimated = !!this._isAnimated;
  }
  extendPrototype([SVGGradientFillStyleData, DynamicPropertyContainer], SVGGradientStrokeStyleData);
  function ShapeGroupData() {
    this.it = [];
    this.prevViewData = [];
    this.gr = createNS('g');
  }
  function SVGTransformData(mProps, op, container) {
    this.transform = {
      mProps: mProps,
      op: op,
      container: container
    };
    this.elements = [];
    this._isAnimated = this.transform.mProps.dynamicProperties.length || this.transform.op.effectsSequence.length;
  }
  var buildShapeString = function buildShapeString(pathNodes, length, closed, mat) {
    if (length === 0) {
      return '';
    }
    var _o = pathNodes.o;
    var _i = pathNodes.i;
    var _v = pathNodes.v;
    var i;
    var shapeString = ' M' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
    for (i = 1; i < length; i += 1) {
      shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[i][0], _i[i][1]) + ' ' + mat.applyToPointStringified(_v[i][0], _v[i][1]);
    }
    if (closed && length) {
      shapeString += ' C' + mat.applyToPointStringified(_o[i - 1][0], _o[i - 1][1]) + ' ' + mat.applyToPointStringified(_i[0][0], _i[0][1]) + ' ' + mat.applyToPointStringified(_v[0][0], _v[0][1]);
      shapeString += 'z';
    }
    return shapeString;
  };
  var SVGElementsRenderer = function () {
    var _identityMatrix = new Matrix();
    var _matrixHelper = new Matrix();
    var ob = {
      createRenderFunction: createRenderFunction
    };
    function createRenderFunction(data) {
      switch (data.ty) {
        case 'fl':
          return renderFill;
        case 'gf':
          return renderGradient;
        case 'gs':
          return renderGradientStroke;
        case 'st':
          return renderStroke;
        case 'sh':
        case 'el':
        case 'rc':
        case 'sr':
          return renderPath;
        case 'tr':
          return renderContentTransform;
        case 'no':
          return renderNoop;
        default:
          return null;
      }
    }
    function renderContentTransform(styleData, itemData, isFirstFrame) {
      if (isFirstFrame || itemData.transform.op._mdf) {
        itemData.transform.container.setAttribute('opacity', itemData.transform.op.v);
      }
      if (isFirstFrame || itemData.transform.mProps._mdf) {
        itemData.transform.container.setAttribute('transform', itemData.transform.mProps.v.to2dCSS());
      }
    }
    function renderNoop() {}
    function renderPath(styleData, itemData, isFirstFrame) {
      var j;
      var jLen;
      var pathStringTransformed;
      var redraw;
      var pathNodes;
      var l;
      var lLen = itemData.styles.length;
      var lvl = itemData.lvl;
      var paths;
      var mat;
      var iterations;
      var k;
      for (l = 0; l < lLen; l += 1) {
        redraw = itemData.sh._mdf || isFirstFrame;
        if (itemData.styles[l].lvl < lvl) {
          mat = _matrixHelper.reset();
          iterations = lvl - itemData.styles[l].lvl;
          k = itemData.transformers.length - 1;
          while (!redraw && iterations > 0) {
            redraw = itemData.transformers[k].mProps._mdf || redraw;
            iterations -= 1;
            k -= 1;
          }
          if (redraw) {
            iterations = lvl - itemData.styles[l].lvl;
            k = itemData.transformers.length - 1;
            while (iterations > 0) {
              mat.multiply(itemData.transformers[k].mProps.v);
              iterations -= 1;
              k -= 1;
            }
          }
        } else {
          mat = _identityMatrix;
        }
        paths = itemData.sh.paths;
        jLen = paths._length;
        if (redraw) {
          pathStringTransformed = '';
          for (j = 0; j < jLen; j += 1) {
            pathNodes = paths.shapes[j];
            if (pathNodes && pathNodes._length) {
              pathStringTransformed += buildShapeString(pathNodes, pathNodes._length, pathNodes.c, mat);
            }
          }
          itemData.caches[l] = pathStringTransformed;
        } else {
          pathStringTransformed = itemData.caches[l];
        }
        itemData.styles[l].d += styleData.hd === true ? '' : pathStringTransformed;
        itemData.styles[l]._mdf = redraw || itemData.styles[l]._mdf;
      }
    }
    function renderFill(styleData, itemData, isFirstFrame) {
      var styleElem = itemData.style;
      if (itemData.c._mdf || isFirstFrame) {
        styleElem.pElem.setAttribute('fill', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
      }
      if (itemData.o._mdf || isFirstFrame) {
        styleElem.pElem.setAttribute('fill-opacity', itemData.o.v);
      }
    }
    function renderGradientStroke(styleData, itemData, isFirstFrame) {
      renderGradient(styleData, itemData, isFirstFrame);
      renderStroke(styleData, itemData, isFirstFrame);
    }
    function renderGradient(styleData, itemData, isFirstFrame) {
      var gfill = itemData.gf;
      var hasOpacity = itemData.g._hasOpacity;
      var pt1 = itemData.s.v;
      var pt2 = itemData.e.v;
      if (itemData.o._mdf || isFirstFrame) {
        var attr = styleData.ty === 'gf' ? 'fill-opacity' : 'stroke-opacity';
        itemData.style.pElem.setAttribute(attr, itemData.o.v);
      }
      if (itemData.s._mdf || isFirstFrame) {
        var attr1 = styleData.t === 1 ? 'x1' : 'cx';
        var attr2 = attr1 === 'x1' ? 'y1' : 'cy';
        gfill.setAttribute(attr1, pt1[0]);
        gfill.setAttribute(attr2, pt1[1]);
        if (hasOpacity && !itemData.g._collapsable) {
          itemData.of.setAttribute(attr1, pt1[0]);
          itemData.of.setAttribute(attr2, pt1[1]);
        }
      }
      var stops;
      var i;
      var len;
      var stop;
      if (itemData.g._cmdf || isFirstFrame) {
        stops = itemData.cst;
        var cValues = itemData.g.c;
        len = stops.length;
        for (i = 0; i < len; i += 1) {
          stop = stops[i];
          stop.setAttribute('offset', cValues[i * 4] + '%');
          stop.setAttribute('stop-color', 'rgb(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ')');
        }
      }
      if (hasOpacity && (itemData.g._omdf || isFirstFrame)) {
        var oValues = itemData.g.o;
        if (itemData.g._collapsable) {
          stops = itemData.cst;
        } else {
          stops = itemData.ost;
        }
        len = stops.length;
        for (i = 0; i < len; i += 1) {
          stop = stops[i];
          if (!itemData.g._collapsable) {
            stop.setAttribute('offset', oValues[i * 2] + '%');
          }
          stop.setAttribute('stop-opacity', oValues[i * 2 + 1]);
        }
      }
      if (styleData.t === 1) {
        if (itemData.e._mdf || isFirstFrame) {
          gfill.setAttribute('x2', pt2[0]);
          gfill.setAttribute('y2', pt2[1]);
          if (hasOpacity && !itemData.g._collapsable) {
            itemData.of.setAttribute('x2', pt2[0]);
            itemData.of.setAttribute('y2', pt2[1]);
          }
        }
      } else {
        var rad;
        if (itemData.s._mdf || itemData.e._mdf || isFirstFrame) {
          rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
          gfill.setAttribute('r', rad);
          if (hasOpacity && !itemData.g._collapsable) {
            itemData.of.setAttribute('r', rad);
          }
        }
        if (itemData.s._mdf || itemData.e._mdf || itemData.h._mdf || itemData.a._mdf || isFirstFrame) {
          if (!rad) {
            rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
          }
          var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
          var percent = itemData.h.v;
          if (percent >= 1) {
            percent = 0.99;
          } else if (percent <= -1) {
            percent = -0.99;
          }
          var dist = rad * percent;
          var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
          var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
          gfill.setAttribute('fx', x);
          gfill.setAttribute('fy', y);
          if (hasOpacity && !itemData.g._collapsable) {
            itemData.of.setAttribute('fx', x);
            itemData.of.setAttribute('fy', y);
          }
        }
        // gfill.setAttribute('fy','200');
      }
    }
    function renderStroke(styleData, itemData, isFirstFrame) {
      var styleElem = itemData.style;
      var d = itemData.d;
      if (d && (d._mdf || isFirstFrame) && d.dashStr) {
        styleElem.pElem.setAttribute('stroke-dasharray', d.dashStr);
        styleElem.pElem.setAttribute('stroke-dashoffset', d.dashoffset[0]);
      }
      if (itemData.c && (itemData.c._mdf || isFirstFrame)) {
        styleElem.pElem.setAttribute('stroke', 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')');
      }
      if (itemData.o._mdf || isFirstFrame) {
        styleElem.pElem.setAttribute('stroke-opacity', itemData.o.v);
      }
      if (itemData.w._mdf || isFirstFrame) {
        styleElem.pElem.setAttribute('stroke-width', itemData.w.v);
        if (styleElem.msElem) {
          styleElem.msElem.setAttribute('stroke-width', itemData.w.v);
        }
      }
    }
    return ob;
  }();
  function SVGShapeElement(data, globalData, comp) {
    // List of drawable elements
    this.shapes = [];
    // Full shape data
    this.shapesData = data.shapes;
    // List of styles that will be applied to shapes
    this.stylesList = [];
    // List of modifiers that will be applied to shapes
    this.shapeModifiers = [];
    // List of items in shape tree
    this.itemsData = [];
    // List of items in previous shape tree
    this.processedElements = [];
    // List of animated components
    this.animatedContents = [];
    this.initElement(data, globalData, comp);
    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
    // List of elements that have been created
    this.prevViewData = [];
    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
  }
  extendPrototype([BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableDOMElement], SVGShapeElement);
  SVGShapeElement.prototype.initSecondaryElement = function () {};
  SVGShapeElement.prototype.identityMatrix = new Matrix();
  SVGShapeElement.prototype.buildExpressionInterface = function () {};
  SVGShapeElement.prototype.createContent = function () {
    this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
    this.filterUniqueShapes();
  };

  /*
  This method searches for multiple shapes that affect a single element and one of them is animated
  */
  SVGShapeElement.prototype.filterUniqueShapes = function () {
    var i;
    var len = this.shapes.length;
    var shape;
    var j;
    var jLen = this.stylesList.length;
    var style;
    var tempShapes = [];
    var areAnimated = false;
    for (j = 0; j < jLen; j += 1) {
      style = this.stylesList[j];
      areAnimated = false;
      tempShapes.length = 0;
      for (i = 0; i < len; i += 1) {
        shape = this.shapes[i];
        if (shape.styles.indexOf(style) !== -1) {
          tempShapes.push(shape);
          areAnimated = shape._isAnimated || areAnimated;
        }
      }
      if (tempShapes.length > 1 && areAnimated) {
        this.setShapesAsAnimated(tempShapes);
      }
    }
  };
  SVGShapeElement.prototype.setShapesAsAnimated = function (shapes) {
    var i;
    var len = shapes.length;
    for (i = 0; i < len; i += 1) {
      shapes[i].setAsAnimated();
    }
  };
  SVGShapeElement.prototype.createStyleElement = function (data, level) {
    // TODO: prevent drawing of hidden styles
    var elementData;
    var styleOb = new SVGStyleData(data, level);
    var pathElement = styleOb.pElem;
    if (data.ty === 'st') {
      elementData = new SVGStrokeStyleData(this, data, styleOb);
    } else if (data.ty === 'fl') {
      elementData = new SVGFillStyleData(this, data, styleOb);
    } else if (data.ty === 'gf' || data.ty === 'gs') {
      var GradientConstructor = data.ty === 'gf' ? SVGGradientFillStyleData : SVGGradientStrokeStyleData;
      elementData = new GradientConstructor(this, data, styleOb);
      this.globalData.defs.appendChild(elementData.gf);
      if (elementData.maskId) {
        this.globalData.defs.appendChild(elementData.ms);
        this.globalData.defs.appendChild(elementData.of);
        pathElement.setAttribute('mask', 'url(' + getLocationHref() + '#' + elementData.maskId + ')');
      }
    } else if (data.ty === 'no') {
      elementData = new SVGNoStyleData(this, data, styleOb);
    }
    if (data.ty === 'st' || data.ty === 'gs') {
      pathElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
      pathElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
      pathElement.setAttribute('fill-opacity', '0');
      if (data.lj === 1) {
        pathElement.setAttribute('stroke-miterlimit', data.ml);
      }
    }
    if (data.r === 2) {
      pathElement.setAttribute('fill-rule', 'evenodd');
    }
    if (data.ln) {
      pathElement.setAttribute('id', data.ln);
    }
    if (data.cl) {
      pathElement.setAttribute('class', data.cl);
    }
    if (data.bm) {
      pathElement.style['mix-blend-mode'] = getBlendMode(data.bm);
    }
    this.stylesList.push(styleOb);
    this.addToAnimatedContents(data, elementData);
    return elementData;
  };
  SVGShapeElement.prototype.createGroupElement = function (data) {
    var elementData = new ShapeGroupData();
    if (data.ln) {
      elementData.gr.setAttribute('id', data.ln);
    }
    if (data.cl) {
      elementData.gr.setAttribute('class', data.cl);
    }
    if (data.bm) {
      elementData.gr.style['mix-blend-mode'] = getBlendMode(data.bm);
    }
    return elementData;
  };
  SVGShapeElement.prototype.createTransformElement = function (data, container) {
    var transformProperty = TransformPropertyFactory.getTransformProperty(this, data, this);
    var elementData = new SVGTransformData(transformProperty, transformProperty.o, container);
    this.addToAnimatedContents(data, elementData);
    return elementData;
  };
  SVGShapeElement.prototype.createShapeElement = function (data, ownTransformers, level) {
    var ty = 4;
    if (data.ty === 'rc') {
      ty = 5;
    } else if (data.ty === 'el') {
      ty = 6;
    } else if (data.ty === 'sr') {
      ty = 7;
    }
    var shapeProperty = ShapePropertyFactory.getShapeProp(this, data, ty, this);
    var elementData = new SVGShapeData(ownTransformers, level, shapeProperty);
    this.shapes.push(elementData);
    this.addShapeToModifiers(elementData);
    this.addToAnimatedContents(data, elementData);
    return elementData;
  };
  SVGShapeElement.prototype.addToAnimatedContents = function (data, element) {
    var i = 0;
    var len = this.animatedContents.length;
    while (i < len) {
      if (this.animatedContents[i].element === element) {
        return;
      }
      i += 1;
    }
    this.animatedContents.push({
      fn: SVGElementsRenderer.createRenderFunction(data),
      element: element,
      data: data
    });
  };
  SVGShapeElement.prototype.setElementStyles = function (elementData) {
    var arr = elementData.styles;
    var j;
    var jLen = this.stylesList.length;
    for (j = 0; j < jLen; j += 1) {
      if (arr.indexOf(this.stylesList[j]) === -1 && !this.stylesList[j].closed) {
        arr.push(this.stylesList[j]);
      }
    }
  };
  SVGShapeElement.prototype.reloadShapes = function () {
    this._isFirstFrame = true;
    var i;
    var len = this.itemsData.length;
    for (i = 0; i < len; i += 1) {
      this.prevViewData[i] = this.itemsData[i];
    }
    this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.layerElement, 0, [], true);
    this.filterUniqueShapes();
    len = this.dynamicProperties.length;
    for (i = 0; i < len; i += 1) {
      this.dynamicProperties[i].getValue();
    }
    this.renderModifiers();
  };
  SVGShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, container, level, transformers, render) {
    var ownTransformers = [].concat(transformers);
    var i;
    var len = arr.length - 1;
    var j;
    var jLen;
    var ownStyles = [];
    var ownModifiers = [];
    var currentTransform;
    var modifier;
    var processedPos;
    for (i = len; i >= 0; i -= 1) {
      processedPos = this.searchProcessedElement(arr[i]);
      if (!processedPos) {
        arr[i]._render = render;
      } else {
        itemsData[i] = prevViewData[processedPos - 1];
      }
      if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs' || arr[i].ty === 'no') {
        if (!processedPos) {
          itemsData[i] = this.createStyleElement(arr[i], level);
        } else {
          itemsData[i].style.closed = arr[i].hd;
        }
        if (arr[i]._render) {
          if (itemsData[i].style.pElem.parentNode !== container) {
            container.appendChild(itemsData[i].style.pElem);
          }
        }
        ownStyles.push(itemsData[i].style);
      } else if (arr[i].ty === 'gr') {
        if (!processedPos) {
          itemsData[i] = this.createGroupElement(arr[i]);
        } else {
          jLen = itemsData[i].it.length;
          for (j = 0; j < jLen; j += 1) {
            itemsData[i].prevViewData[j] = itemsData[i].it[j];
          }
        }
        this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, itemsData[i].gr, level + 1, ownTransformers, render);
        if (arr[i]._render) {
          if (itemsData[i].gr.parentNode !== container) {
            container.appendChild(itemsData[i].gr);
          }
        }
      } else if (arr[i].ty === 'tr') {
        if (!processedPos) {
          itemsData[i] = this.createTransformElement(arr[i], container);
        }
        currentTransform = itemsData[i].transform;
        ownTransformers.push(currentTransform);
      } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
        if (!processedPos) {
          itemsData[i] = this.createShapeElement(arr[i], ownTransformers, level);
        }
        this.setElementStyles(itemsData[i]);
      } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'ms' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
        if (!processedPos) {
          modifier = ShapeModifiers.getModifier(arr[i].ty);
          modifier.init(this, arr[i]);
          itemsData[i] = modifier;
          this.shapeModifiers.push(modifier);
        } else {
          modifier = itemsData[i];
          modifier.closed = false;
        }
        ownModifiers.push(modifier);
      } else if (arr[i].ty === 'rp') {
        if (!processedPos) {
          modifier = ShapeModifiers.getModifier(arr[i].ty);
          itemsData[i] = modifier;
          modifier.init(this, arr, i, itemsData);
          this.shapeModifiers.push(modifier);
          render = false;
        } else {
          modifier = itemsData[i];
          modifier.closed = true;
        }
        ownModifiers.push(modifier);
      }
      this.addProcessedElement(arr[i], i + 1);
    }
    len = ownStyles.length;
    for (i = 0; i < len; i += 1) {
      ownStyles[i].closed = true;
    }
    len = ownModifiers.length;
    for (i = 0; i < len; i += 1) {
      ownModifiers[i].closed = true;
    }
  };
  SVGShapeElement.prototype.renderInnerContent = function () {
    this.renderModifiers();
    var i;
    var len = this.stylesList.length;
    for (i = 0; i < len; i += 1) {
      this.stylesList[i].reset();
    }
    this.renderShape();
    for (i = 0; i < len; i += 1) {
      if (this.stylesList[i]._mdf || this._isFirstFrame) {
        if (this.stylesList[i].msElem) {
          this.stylesList[i].msElem.setAttribute('d', this.stylesList[i].d);
          // Adding M0 0 fixes same mask bug on all browsers
          this.stylesList[i].d = 'M0 0' + this.stylesList[i].d;
        }
        this.stylesList[i].pElem.setAttribute('d', this.stylesList[i].d || 'M0 0');
      }
    }
  };
  SVGShapeElement.prototype.renderShape = function () {
    var i;
    var len = this.animatedContents.length;
    var animatedContent;
    for (i = 0; i < len; i += 1) {
      animatedContent = this.animatedContents[i];
      if ((this._isFirstFrame || animatedContent.element._isAnimated) && animatedContent.data !== true) {
        animatedContent.fn(animatedContent.data, animatedContent.element, this._isFirstFrame);
      }
    }
  };
  SVGShapeElement.prototype.destroy = function () {
    this.destroyBaseElement();
    this.shapesData = null;
    this.itemsData = null;
  };
  function LetterProps(o, sw, sc, fc, m, p) {
    this.o = o;
    this.sw = sw;
    this.sc = sc;
    this.fc = fc;
    this.m = m;
    this.p = p;
    this._mdf = {
      o: true,
      sw: !!sw,
      sc: !!sc,
      fc: !!fc,
      m: true,
      p: true
    };
  }
  LetterProps.prototype.update = function (o, sw, sc, fc, m, p) {
    this._mdf.o = false;
    this._mdf.sw = false;
    this._mdf.sc = false;
    this._mdf.fc = false;
    this._mdf.m = false;
    this._mdf.p = false;
    var updated = false;
    if (this.o !== o) {
      this.o = o;
      this._mdf.o = true;
      updated = true;
    }
    if (this.sw !== sw) {
      this.sw = sw;
      this._mdf.sw = true;
      updated = true;
    }
    if (this.sc !== sc) {
      this.sc = sc;
      this._mdf.sc = true;
      updated = true;
    }
    if (this.fc !== fc) {
      this.fc = fc;
      this._mdf.fc = true;
      updated = true;
    }
    if (this.m !== m) {
      this.m = m;
      this._mdf.m = true;
      updated = true;
    }
    if (p.length && (this.p[0] !== p[0] || this.p[1] !== p[1] || this.p[4] !== p[4] || this.p[5] !== p[5] || this.p[12] !== p[12] || this.p[13] !== p[13])) {
      this.p = p;
      this._mdf.p = true;
      updated = true;
    }
    return updated;
  };
  function TextProperty(elem, data) {
    this._frameId = initialDefaultFrame;
    this.pv = '';
    this.v = '';
    this.kf = false;
    this._isFirstFrame = true;
    this._mdf = false;
    if (data.d && data.d.sid) {
      data.d = elem.globalData.slotManager.getProp(data.d);
    }
    this.data = data;
    this.elem = elem;
    this.comp = this.elem.comp;
    this.keysIndex = 0;
    this.canResize = false;
    this.minimumFontSize = 1;
    this.effectsSequence = [];
    this.currentData = {
      ascent: 0,
      boxWidth: this.defaultBoxWidth,
      f: '',
      fStyle: '',
      fWeight: '',
      fc: '',
      j: '',
      justifyOffset: '',
      l: [],
      lh: 0,
      lineWidths: [],
      ls: '',
      of: '',
      s: '',
      sc: '',
      sw: 0,
      t: 0,
      tr: 0,
      sz: 0,
      ps: null,
      fillColorAnim: false,
      strokeColorAnim: false,
      strokeWidthAnim: false,
      yOffset: 0,
      finalSize: 0,
      finalText: [],
      finalLineHeight: 0,
      __complete: false
    };
    this.copyData(this.currentData, this.data.d.k[0].s);
    if (!this.searchProperty()) {
      this.completeTextData(this.currentData);
    }
  }
  TextProperty.prototype.defaultBoxWidth = [0, 0];
  TextProperty.prototype.copyData = function (obj, data) {
    for (var s in data) {
      if (Object.prototype.hasOwnProperty.call(data, s)) {
        obj[s] = data[s];
      }
    }
    return obj;
  };
  TextProperty.prototype.setCurrentData = function (data) {
    if (!data.__complete) {
      this.completeTextData(data);
    }
    this.currentData = data;
    this.currentData.boxWidth = this.currentData.boxWidth || this.defaultBoxWidth;
    this._mdf = true;
  };
  TextProperty.prototype.searchProperty = function () {
    return this.searchKeyframes();
  };
  TextProperty.prototype.searchKeyframes = function () {
    this.kf = this.data.d.k.length > 1;
    if (this.kf) {
      this.addEffect(this.getKeyframeValue.bind(this));
    }
    return this.kf;
  };
  TextProperty.prototype.addEffect = function (effectFunction) {
    this.effectsSequence.push(effectFunction);
    this.elem.addDynamicProperty(this);
  };
  TextProperty.prototype.getValue = function (_finalValue) {
    if ((this.elem.globalData.frameId === this.frameId || !this.effectsSequence.length) && !_finalValue) {
      return;
    }
    this.currentData.t = this.data.d.k[this.keysIndex].s.t;
    var currentValue = this.currentData;
    var currentIndex = this.keysIndex;
    if (this.lock) {
      this.setCurrentData(this.currentData);
      return;
    }
    this.lock = true;
    this._mdf = false;
    var i;
    var len = this.effectsSequence.length;
    var finalValue = _finalValue || this.data.d.k[this.keysIndex].s;
    for (i = 0; i < len; i += 1) {
      // Checking if index changed to prevent creating a new object every time the expression updates.
      if (currentIndex !== this.keysIndex) {
        finalValue = this.effectsSequence[i](finalValue, finalValue.t);
      } else {
        finalValue = this.effectsSequence[i](this.currentData, finalValue.t);
      }
    }
    if (currentValue !== finalValue) {
      this.setCurrentData(finalValue);
    }
    this.v = this.currentData;
    this.pv = this.v;
    this.lock = false;
    this.frameId = this.elem.globalData.frameId;
  };
  TextProperty.prototype.getKeyframeValue = function () {
    var textKeys = this.data.d.k;
    var frameNum = this.elem.comp.renderedFrame;
    var i = 0;
    var len = textKeys.length;
    while (i <= len - 1) {
      if (i === len - 1 || textKeys[i + 1].t > frameNum) {
        break;
      }
      i += 1;
    }
    if (this.keysIndex !== i) {
      this.keysIndex = i;
    }
    return this.data.d.k[this.keysIndex].s;
  };
  TextProperty.prototype.buildFinalText = function (text) {
    var charactersArray = [];
    var i = 0;
    var len = text.length;
    var charCode;
    var secondCharCode;
    var shouldCombine = false;
    var shouldCombineNext = false;
    var currentChars = '';
    while (i < len) {
      shouldCombine = shouldCombineNext;
      shouldCombineNext = false;
      charCode = text.charCodeAt(i);
      currentChars = text.charAt(i);
      if (FontManager.isCombinedCharacter(charCode)) {
        shouldCombine = true;
        // It's a potential surrogate pair (this is the High surrogate)
      } else if (charCode >= 0xD800 && charCode <= 0xDBFF) {
        if (FontManager.isRegionalFlag(text, i)) {
          currentChars = text.substr(i, 14);
        } else {
          secondCharCode = text.charCodeAt(i + 1);
          // It's a surrogate pair (this is the Low surrogate)
          if (secondCharCode >= 0xDC00 && secondCharCode <= 0xDFFF) {
            if (FontManager.isModifier(charCode, secondCharCode)) {
              currentChars = text.substr(i, 2);
              shouldCombine = true;
            } else if (FontManager.isFlagEmoji(text.substr(i, 4))) {
              currentChars = text.substr(i, 4);
            } else {
              currentChars = text.substr(i, 2);
            }
          }
        }
      } else if (charCode > 0xDBFF) {
        secondCharCode = text.charCodeAt(i + 1);
        if (FontManager.isVariationSelector(charCode)) {
          shouldCombine = true;
        }
      } else if (FontManager.isZeroWidthJoiner(charCode)) {
        shouldCombine = true;
        shouldCombineNext = true;
      }
      if (shouldCombine) {
        charactersArray[charactersArray.length - 1] += currentChars;
        shouldCombine = false;
      } else {
        charactersArray.push(currentChars);
      }
      i += currentChars.length;
    }
    return charactersArray;
  };
  TextProperty.prototype.completeTextData = function (documentData) {
    documentData.__complete = true;
    var fontManager = this.elem.globalData.fontManager;
    var data = this.data;
    var letters = [];
    var i;
    var len;
    var newLineFlag;
    var index = 0;
    var val;
    var anchorGrouping = data.m.g;
    var currentSize = 0;
    var currentPos = 0;
    var currentLine = 0;
    var lineWidths = [];
    var lineWidth = 0;
    var maxLineWidth = 0;
    var j;
    var jLen;
    var fontData = fontManager.getFontByName(documentData.f);
    var charData;
    var cLength = 0;
    var fontProps = getFontProperties(fontData);
    documentData.fWeight = fontProps.weight;
    documentData.fStyle = fontProps.style;
    documentData.finalSize = documentData.s;
    documentData.finalText = this.buildFinalText(documentData.t);
    len = documentData.finalText.length;
    documentData.finalLineHeight = documentData.lh;
    var trackingOffset = documentData.tr / 1000 * documentData.finalSize;
    var charCode;
    if (documentData.sz) {
      var flag = true;
      var boxWidth = documentData.sz[0];
      var boxHeight = documentData.sz[1];
      var currentHeight;
      var finalText;
      while (flag) {
        finalText = this.buildFinalText(documentData.t);
        currentHeight = 0;
        lineWidth = 0;
        len = finalText.length;
        trackingOffset = documentData.tr / 1000 * documentData.finalSize;
        var lastSpaceIndex = -1;
        for (i = 0; i < len; i += 1) {
          charCode = finalText[i].charCodeAt(0);
          newLineFlag = false;
          if (finalText[i] === ' ') {
            lastSpaceIndex = i;
          } else if (charCode === 13 || charCode === 3) {
            lineWidth = 0;
            newLineFlag = true;
            currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
          }
          if (fontManager.chars) {
            charData = fontManager.getCharData(finalText[i], fontData.fStyle, fontData.fFamily);
            cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
          } else {
            // tCanvasHelper.font = documentData.s + 'px '+ fontData.fFamily;
            cLength = fontManager.measureText(finalText[i], documentData.f, documentData.finalSize);
          }
          if (lineWidth + cLength > boxWidth && finalText[i] !== ' ') {
            if (lastSpaceIndex === -1) {
              len += 1;
            } else {
              i = lastSpaceIndex;
            }
            currentHeight += documentData.finalLineHeight || documentData.finalSize * 1.2;
            finalText.splice(i, lastSpaceIndex === i ? 1 : 0, '\r');
            // finalText = finalText.substr(0,i) + "\r" + finalText.substr(i === lastSpaceIndex ? i + 1 : i);
            lastSpaceIndex = -1;
            lineWidth = 0;
          } else {
            lineWidth += cLength;
            lineWidth += trackingOffset;
          }
        }
        currentHeight += fontData.ascent * documentData.finalSize / 100;
        if (this.canResize && documentData.finalSize > this.minimumFontSize && boxHeight < currentHeight) {
          documentData.finalSize -= 1;
          documentData.finalLineHeight = documentData.finalSize * documentData.lh / documentData.s;
        } else {
          documentData.finalText = finalText;
          len = documentData.finalText.length;
          flag = false;
        }
      }
    }
    lineWidth = -trackingOffset;
    cLength = 0;
    var uncollapsedSpaces = 0;
    var currentChar;
    for (i = 0; i < len; i += 1) {
      newLineFlag = false;
      currentChar = documentData.finalText[i];
      charCode = currentChar.charCodeAt(0);
      if (charCode === 13 || charCode === 3) {
        uncollapsedSpaces = 0;
        lineWidths.push(lineWidth);
        maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
        lineWidth = -2 * trackingOffset;
        val = '';
        newLineFlag = true;
        currentLine += 1;
      } else {
        val = currentChar;
      }
      if (fontManager.chars) {
        charData = fontManager.getCharData(currentChar, fontData.fStyle, fontManager.getFontByName(documentData.f).fFamily);
        cLength = newLineFlag ? 0 : charData.w * documentData.finalSize / 100;
      } else {
        // var charWidth = fontManager.measureText(val, documentData.f, documentData.finalSize);
        // tCanvasHelper.font = documentData.finalSize + 'px '+ fontManager.getFontByName(documentData.f).fFamily;
        cLength = fontManager.measureText(val, documentData.f, documentData.finalSize);
      }

      //
      if (currentChar === ' ') {
        uncollapsedSpaces += cLength + trackingOffset;
      } else {
        lineWidth += cLength + trackingOffset + uncollapsedSpaces;
        uncollapsedSpaces = 0;
      }
      letters.push({
        l: cLength,
        an: cLength,
        add: currentSize,
        n: newLineFlag,
        anIndexes: [],
        val: val,
        line: currentLine,
        animatorJustifyOffset: 0
      });
      if (anchorGrouping == 2) {
        // eslint-disable-line eqeqeq
        currentSize += cLength;
        if (val === '' || val === ' ' || i === len - 1) {
          if (val === '' || val === ' ') {
            currentSize -= cLength;
          }
          while (currentPos <= i) {
            letters[currentPos].an = currentSize;
            letters[currentPos].ind = index;
            letters[currentPos].extra = cLength;
            currentPos += 1;
          }
          index += 1;
          currentSize = 0;
        }
      } else if (anchorGrouping == 3) {
        // eslint-disable-line eqeqeq
        currentSize += cLength;
        if (val === '' || i === len - 1) {
          if (val === '') {
            currentSize -= cLength;
          }
          while (currentPos <= i) {
            letters[currentPos].an = currentSize;
            letters[currentPos].ind = index;
            letters[currentPos].extra = cLength;
            currentPos += 1;
          }
          currentSize = 0;
          index += 1;
        }
      } else {
        letters[index].ind = index;
        letters[index].extra = 0;
        index += 1;
      }
    }
    documentData.l = letters;
    maxLineWidth = lineWidth > maxLineWidth ? lineWidth : maxLineWidth;
    lineWidths.push(lineWidth);
    if (documentData.sz) {
      documentData.boxWidth = documentData.sz[0];
      documentData.justifyOffset = 0;
    } else {
      documentData.boxWidth = maxLineWidth;
      switch (documentData.j) {
        case 1:
          documentData.justifyOffset = -documentData.boxWidth;
          break;
        case 2:
          documentData.justifyOffset = -documentData.boxWidth / 2;
          break;
        default:
          documentData.justifyOffset = 0;
      }
    }
    documentData.lineWidths = lineWidths;
    var animators = data.a;
    var animatorData;
    var letterData;
    jLen = animators.length;
    var based;
    var ind;
    var indexes = [];
    for (j = 0; j < jLen; j += 1) {
      animatorData = animators[j];
      if (animatorData.a.sc) {
        documentData.strokeColorAnim = true;
      }
      if (animatorData.a.sw) {
        documentData.strokeWidthAnim = true;
      }
      if (animatorData.a.fc || animatorData.a.fh || animatorData.a.fs || animatorData.a.fb) {
        documentData.fillColorAnim = true;
      }
      ind = 0;
      based = animatorData.s.b;
      for (i = 0; i < len; i += 1) {
        letterData = letters[i];
        letterData.anIndexes[j] = ind;
        if (based == 1 && letterData.val !== '' || based == 2 && letterData.val !== '' && letterData.val !== ' ' || based == 3 && (letterData.n || letterData.val == ' ' || i == len - 1) || based == 4 && (letterData.n || i == len - 1)) {
          // eslint-disable-line eqeqeq
          if (animatorData.s.rn === 1) {
            indexes.push(ind);
          }
          ind += 1;
        }
      }
      data.a[j].s.totalChars = ind;
      var currentInd = -1;
      var newInd;
      if (animatorData.s.rn === 1) {
        for (i = 0; i < len; i += 1) {
          letterData = letters[i];
          if (currentInd != letterData.anIndexes[j]) {
            // eslint-disable-line eqeqeq
            currentInd = letterData.anIndexes[j];
            newInd = indexes.splice(Math.floor(Math.random() * indexes.length), 1)[0];
          }
          letterData.anIndexes[j] = newInd;
        }
      }
    }
    documentData.yOffset = documentData.finalLineHeight || documentData.finalSize * 1.2;
    documentData.ls = documentData.ls || 0;
    documentData.ascent = fontData.ascent * documentData.finalSize / 100;
  };
  TextProperty.prototype.updateDocumentData = function (newData, index) {
    index = index === undefined ? this.keysIndex : index;
    var dData = this.copyData({}, this.data.d.k[index].s);
    dData = this.copyData(dData, newData);
    this.data.d.k[index].s = dData;
    this.recalculate(index);
    this.setCurrentData(dData);
    this.elem.addDynamicProperty(this);
  };
  TextProperty.prototype.recalculate = function (index) {
    var dData = this.data.d.k[index].s;
    dData.__complete = false;
    this.keysIndex = 0;
    this._isFirstFrame = true;
    this.getValue(dData);
  };
  TextProperty.prototype.canResizeFont = function (_canResize) {
    this.canResize = _canResize;
    this.recalculate(this.keysIndex);
    this.elem.addDynamicProperty(this);
  };
  TextProperty.prototype.setMinimumFontSize = function (_fontValue) {
    this.minimumFontSize = Math.floor(_fontValue) || 1;
    this.recalculate(this.keysIndex);
    this.elem.addDynamicProperty(this);
  };
  var TextSelectorProp = function () {
    var max = Math.max;
    var min = Math.min;
    var floor = Math.floor;
    function TextSelectorPropFactory(elem, data) {
      this._currentTextLength = -1;
      this.k = false;
      this.data = data;
      this.elem = elem;
      this.comp = elem.comp;
      this.finalS = 0;
      this.finalE = 0;
      this.initDynamicPropertyContainer(elem);
      this.s = PropertyFactory.getProp(elem, data.s || {
        k: 0
      }, 0, 0, this);
      if ('e' in data) {
        this.e = PropertyFactory.getProp(elem, data.e, 0, 0, this);
      } else {
        this.e = {
          v: 100
        };
      }
      this.o = PropertyFactory.getProp(elem, data.o || {
        k: 0
      }, 0, 0, this);
      this.xe = PropertyFactory.getProp(elem, data.xe || {
        k: 0
      }, 0, 0, this);
      this.ne = PropertyFactory.getProp(elem, data.ne || {
        k: 0
      }, 0, 0, this);
      this.sm = PropertyFactory.getProp(elem, data.sm || {
        k: 100
      }, 0, 0, this);
      this.a = PropertyFactory.getProp(elem, data.a, 0, 0.01, this);
      if (!this.dynamicProperties.length) {
        this.getValue();
      }
    }
    TextSelectorPropFactory.prototype = {
      getMult: function getMult(ind) {
        if (this._currentTextLength !== this.elem.textProperty.currentData.l.length) {
          this.getValue();
        }
        var x1 = 0;
        var y1 = 0;
        var x2 = 1;
        var y2 = 1;
        if (this.ne.v > 0) {
          x1 = this.ne.v / 100.0;
        } else {
          y1 = -this.ne.v / 100.0;
        }
        if (this.xe.v > 0) {
          x2 = 1.0 - this.xe.v / 100.0;
        } else {
          y2 = 1.0 + this.xe.v / 100.0;
        }
        var easer = BezierFactory.getBezierEasing(x1, y1, x2, y2).get;
        var mult = 0;
        var s = this.finalS;
        var e = this.finalE;
        var type = this.data.sh;
        if (type === 2) {
          if (e === s) {
            mult = ind >= e ? 1 : 0;
          } else {
            mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
          }
          mult = easer(mult);
        } else if (type === 3) {
          if (e === s) {
            mult = ind >= e ? 0 : 1;
          } else {
            mult = 1 - max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
          }
          mult = easer(mult);
        } else if (type === 4) {
          if (e === s) {
            mult = 0;
          } else {
            mult = max(0, min(0.5 / (e - s) + (ind - s) / (e - s), 1));
            if (mult < 0.5) {
              mult *= 2;
            } else {
              mult = 1 - 2 * (mult - 0.5);
            }
          }
          mult = easer(mult);
        } else if (type === 5) {
          if (e === s) {
            mult = 0;
          } else {
            var tot = e - s;
            /* ind += 0.5;
                      mult = -4/(tot*tot)*(ind*ind)+(4/tot)*ind; */
            ind = min(max(0, ind + 0.5 - s), e - s);
            var x = -tot / 2 + ind;
            var a = tot / 2;
            mult = Math.sqrt(1 - x * x / (a * a));
          }
          mult = easer(mult);
        } else if (type === 6) {
          if (e === s) {
            mult = 0;
          } else {
            ind = min(max(0, ind + 0.5 - s), e - s);
            mult = (1 + Math.cos(Math.PI + Math.PI * 2 * ind / (e - s))) / 2; // eslint-disable-line
          }
          mult = easer(mult);
        } else {
          if (ind >= floor(s)) {
            if (ind - s < 0) {
              mult = max(0, min(min(e, 1) - (s - ind), 1));
            } else {
              mult = max(0, min(e - ind, 1));
            }
          }
          mult = easer(mult);
        }
        // Smoothness implementation.
        // The smoothness represents a reduced range of the original [0; 1] range.
        // if smoothness is 25%, the new range will be [0.375; 0.625]
        // Steps are:
        // - find the lower value of the new range (threshold)
        // - if multiplier is smaller than that value, floor it to 0
        // - if it is larger,
        //     - subtract the threshold
        //     - divide it by the smoothness (this will return the range to [0; 1])
        // Note: If it doesn't work on some scenarios, consider applying it before the easer.
        if (this.sm.v !== 100) {
          var smoothness = this.sm.v * 0.01;
          if (smoothness === 0) {
            smoothness = 0.00000001;
          }
          var threshold = 0.5 - smoothness * 0.5;
          if (mult < threshold) {
            mult = 0;
          } else {
            mult = (mult - threshold) / smoothness;
            if (mult > 1) {
              mult = 1;
            }
          }
        }
        return mult * this.a.v;
      },
      getValue: function getValue(newCharsFlag) {
        this.iterateDynamicProperties();
        this._mdf = newCharsFlag || this._mdf;
        this._currentTextLength = this.elem.textProperty.currentData.l.length || 0;
        if (newCharsFlag && this.data.r === 2) {
          this.e.v = this._currentTextLength;
        }
        var divisor = this.data.r === 2 ? 1 : 100 / this.data.totalChars;
        var o = this.o.v / divisor;
        var s = this.s.v / divisor + o;
        var e = this.e.v / divisor + o;
        if (s > e) {
          var _s = s;
          s = e;
          e = _s;
        }
        this.finalS = s;
        this.finalE = e;
      }
    };
    extendPrototype([DynamicPropertyContainer], TextSelectorPropFactory);
    function getTextSelectorProp(elem, data, arr) {
      return new TextSelectorPropFactory(elem, data, arr);
    }
    return {
      getTextSelectorProp: getTextSelectorProp
    };
  }();
  function TextAnimatorDataProperty(elem, animatorProps, container) {
    var defaultData = {
      propType: false
    };
    var getProp = PropertyFactory.getProp;
    var textAnimatorAnimatables = animatorProps.a;
    this.a = {
      r: textAnimatorAnimatables.r ? getProp(elem, textAnimatorAnimatables.r, 0, degToRads, container) : defaultData,
      rx: textAnimatorAnimatables.rx ? getProp(elem, textAnimatorAnimatables.rx, 0, degToRads, container) : defaultData,
      ry: textAnimatorAnimatables.ry ? getProp(elem, textAnimatorAnimatables.ry, 0, degToRads, container) : defaultData,
      sk: textAnimatorAnimatables.sk ? getProp(elem, textAnimatorAnimatables.sk, 0, degToRads, container) : defaultData,
      sa: textAnimatorAnimatables.sa ? getProp(elem, textAnimatorAnimatables.sa, 0, degToRads, container) : defaultData,
      s: textAnimatorAnimatables.s ? getProp(elem, textAnimatorAnimatables.s, 1, 0.01, container) : defaultData,
      a: textAnimatorAnimatables.a ? getProp(elem, textAnimatorAnimatables.a, 1, 0, container) : defaultData,
      o: textAnimatorAnimatables.o ? getProp(elem, textAnimatorAnimatables.o, 0, 0.01, container) : defaultData,
      p: textAnimatorAnimatables.p ? getProp(elem, textAnimatorAnimatables.p, 1, 0, container) : defaultData,
      sw: textAnimatorAnimatables.sw ? getProp(elem, textAnimatorAnimatables.sw, 0, 0, container) : defaultData,
      sc: textAnimatorAnimatables.sc ? getProp(elem, textAnimatorAnimatables.sc, 1, 0, container) : defaultData,
      fc: textAnimatorAnimatables.fc ? getProp(elem, textAnimatorAnimatables.fc, 1, 0, container) : defaultData,
      fh: textAnimatorAnimatables.fh ? getProp(elem, textAnimatorAnimatables.fh, 0, 0, container) : defaultData,
      fs: textAnimatorAnimatables.fs ? getProp(elem, textAnimatorAnimatables.fs, 0, 0.01, container) : defaultData,
      fb: textAnimatorAnimatables.fb ? getProp(elem, textAnimatorAnimatables.fb, 0, 0.01, container) : defaultData,
      t: textAnimatorAnimatables.t ? getProp(elem, textAnimatorAnimatables.t, 0, 0, container) : defaultData
    };
    this.s = TextSelectorProp.getTextSelectorProp(elem, animatorProps.s, container);
    this.s.t = animatorProps.s.t;
  }
  function TextAnimatorProperty(textData, renderType, elem) {
    this._isFirstFrame = true;
    this._hasMaskedPath = false;
    this._frameId = -1;
    this._textData = textData;
    this._renderType = renderType;
    this._elem = elem;
    this._animatorsData = createSizedArray(this._textData.a.length);
    this._pathData = {};
    this._moreOptions = {
      alignment: {}
    };
    this.renderedLetters = [];
    this.lettersChangedFlag = false;
    this.initDynamicPropertyContainer(elem);
  }
  TextAnimatorProperty.prototype.searchProperties = function () {
    var i;
    var len = this._textData.a.length;
    var animatorProps;
    var getProp = PropertyFactory.getProp;
    for (i = 0; i < len; i += 1) {
      animatorProps = this._textData.a[i];
      this._animatorsData[i] = new TextAnimatorDataProperty(this._elem, animatorProps, this);
    }
    if (this._textData.p && 'm' in this._textData.p) {
      this._pathData = {
        a: getProp(this._elem, this._textData.p.a, 0, 0, this),
        f: getProp(this._elem, this._textData.p.f, 0, 0, this),
        l: getProp(this._elem, this._textData.p.l, 0, 0, this),
        r: getProp(this._elem, this._textData.p.r, 0, 0, this),
        p: getProp(this._elem, this._textData.p.p, 0, 0, this),
        m: this._elem.maskManager.getMaskProperty(this._textData.p.m)
      };
      this._hasMaskedPath = true;
    } else {
      this._hasMaskedPath = false;
    }
    this._moreOptions.alignment = getProp(this._elem, this._textData.m.a, 1, 0, this);
  };
  TextAnimatorProperty.prototype.getMeasures = function (documentData, lettersChangedFlag) {
    this.lettersChangedFlag = lettersChangedFlag;
    if (!this._mdf && !this._isFirstFrame && !lettersChangedFlag && (!this._hasMaskedPath || !this._pathData.m._mdf)) {
      return;
    }
    this._isFirstFrame = false;
    var alignment = this._moreOptions.alignment.v;
    var animators = this._animatorsData;
    var textData = this._textData;
    var matrixHelper = this.mHelper;
    var renderType = this._renderType;
    var renderedLettersCount = this.renderedLetters.length;
    var xPos;
    var yPos;
    var i;
    var len;
    var letters = documentData.l;
    var pathInfo;
    var currentLength;
    var currentPoint;
    var segmentLength;
    var flag;
    var pointInd;
    var segmentInd;
    var prevPoint;
    var points;
    var segments;
    var partialLength;
    var totalLength;
    var perc;
    var tanAngle;
    var mask;
    if (this._hasMaskedPath) {
      mask = this._pathData.m;
      if (!this._pathData.n || this._pathData._mdf) {
        var paths = mask.v;
        if (this._pathData.r.v) {
          paths = paths.reverse();
        }
        // TODO: release bezier data cached from previous pathInfo: this._pathData.pi
        pathInfo = {
          tLength: 0,
          segments: []
        };
        len = paths._length - 1;
        var bezierData;
        totalLength = 0;
        for (i = 0; i < len; i += 1) {
          bezierData = bez.buildBezierData(paths.v[i], paths.v[i + 1], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[i + 1][0] - paths.v[i + 1][0], paths.i[i + 1][1] - paths.v[i + 1][1]]);
          pathInfo.tLength += bezierData.segmentLength;
          pathInfo.segments.push(bezierData);
          totalLength += bezierData.segmentLength;
        }
        i = len;
        if (mask.v.c) {
          bezierData = bez.buildBezierData(paths.v[i], paths.v[0], [paths.o[i][0] - paths.v[i][0], paths.o[i][1] - paths.v[i][1]], [paths.i[0][0] - paths.v[0][0], paths.i[0][1] - paths.v[0][1]]);
          pathInfo.tLength += bezierData.segmentLength;
          pathInfo.segments.push(bezierData);
          totalLength += bezierData.segmentLength;
        }
        this._pathData.pi = pathInfo;
      }
      pathInfo = this._pathData.pi;
      currentLength = this._pathData.f.v;
      segmentInd = 0;
      pointInd = 1;
      segmentLength = 0;
      flag = true;
      segments = pathInfo.segments;
      if (currentLength < 0 && mask.v.c) {
        if (pathInfo.tLength < Math.abs(currentLength)) {
          currentLength = -Math.abs(currentLength) % pathInfo.tLength;
        }
        segmentInd = segments.length - 1;
        points = segments[segmentInd].points;
        pointInd = points.length - 1;
        while (currentLength < 0) {
          currentLength += points[pointInd].partialLength;
          pointInd -= 1;
          if (pointInd < 0) {
            segmentInd -= 1;
            points = segments[segmentInd].points;
            pointInd = points.length - 1;
          }
        }
      }
      points = segments[segmentInd].points;
      prevPoint = points[pointInd - 1];
      currentPoint = points[pointInd];
      partialLength = currentPoint.partialLength;
    }
    len = letters.length;
    xPos = 0;
    yPos = 0;
    var yOff = documentData.finalSize * 1.2 * 0.714;
    var firstLine = true;
    var animatorProps;
    var animatorSelector;
    var j;
    var jLen;
    var letterValue;
    jLen = animators.length;
    var mult;
    var ind = -1;
    var offf;
    var xPathPos;
    var yPathPos;
    var initPathPos = currentLength;
    var initSegmentInd = segmentInd;
    var initPointInd = pointInd;
    var currentLine = -1;
    var elemOpacity;
    var sc;
    var sw;
    var fc;
    var k;
    var letterSw;
    var letterSc;
    var letterFc;
    var letterM = '';
    var letterP = this.defaultPropsArray;
    var letterO;

    //
    if (documentData.j === 2 || documentData.j === 1) {
      var animatorJustifyOffset = 0;
      var animatorFirstCharOffset = 0;
      var justifyOffsetMult = documentData.j === 2 ? -0.5 : -1;
      var lastIndex = 0;
      var isNewLine = true;
      for (i = 0; i < len; i += 1) {
        if (letters[i].n) {
          if (animatorJustifyOffset) {
            animatorJustifyOffset += animatorFirstCharOffset;
          }
          while (lastIndex < i) {
            letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
            lastIndex += 1;
          }
          animatorJustifyOffset = 0;
          isNewLine = true;
        } else {
          for (j = 0; j < jLen; j += 1) {
            animatorProps = animators[j].a;
            if (animatorProps.t.propType) {
              if (isNewLine && documentData.j === 2) {
                animatorFirstCharOffset += animatorProps.t.v * justifyOffsetMult;
              }
              animatorSelector = animators[j].s;
              mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
              if (mult.length) {
                animatorJustifyOffset += animatorProps.t.v * mult[0] * justifyOffsetMult;
              } else {
                animatorJustifyOffset += animatorProps.t.v * mult * justifyOffsetMult;
              }
            }
          }
          isNewLine = false;
        }
      }
      if (animatorJustifyOffset) {
        animatorJustifyOffset += animatorFirstCharOffset;
      }
      while (lastIndex < i) {
        letters[lastIndex].animatorJustifyOffset = animatorJustifyOffset;
        lastIndex += 1;
      }
    }
    //

    for (i = 0; i < len; i += 1) {
      matrixHelper.reset();
      elemOpacity = 1;
      if (letters[i].n) {
        xPos = 0;
        yPos += documentData.yOffset;
        yPos += firstLine ? 1 : 0;
        currentLength = initPathPos;
        firstLine = false;
        if (this._hasMaskedPath) {
          segmentInd = initSegmentInd;
          pointInd = initPointInd;
          points = segments[segmentInd].points;
          prevPoint = points[pointInd - 1];
          currentPoint = points[pointInd];
          partialLength = currentPoint.partialLength;
          segmentLength = 0;
        }
        letterM = '';
        letterFc = '';
        letterSw = '';
        letterO = '';
        letterP = this.defaultPropsArray;
      } else {
        if (this._hasMaskedPath) {
          if (currentLine !== letters[i].line) {
            switch (documentData.j) {
              case 1:
                currentLength += totalLength - documentData.lineWidths[letters[i].line];
                break;
              case 2:
                currentLength += (totalLength - documentData.lineWidths[letters[i].line]) / 2;
                break;
              default:
                break;
            }
            currentLine = letters[i].line;
          }
          if (ind !== letters[i].ind) {
            if (letters[ind]) {
              currentLength += letters[ind].extra;
            }
            currentLength += letters[i].an / 2;
            ind = letters[i].ind;
          }
          currentLength += alignment[0] * letters[i].an * 0.005;
          var animatorOffset = 0;
          for (j = 0; j < jLen; j += 1) {
            animatorProps = animators[j].a;
            if (animatorProps.p.propType) {
              animatorSelector = animators[j].s;
              mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
              if (mult.length) {
                animatorOffset += animatorProps.p.v[0] * mult[0];
              } else {
                animatorOffset += animatorProps.p.v[0] * mult;
              }
            }
            if (animatorProps.a.propType) {
              animatorSelector = animators[j].s;
              mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
              if (mult.length) {
                animatorOffset += animatorProps.a.v[0] * mult[0];
              } else {
                animatorOffset += animatorProps.a.v[0] * mult;
              }
            }
          }
          flag = true;
          // Force alignment only works with a single line for now
          if (this._pathData.a.v) {
            currentLength = letters[0].an * 0.5 + (totalLength - this._pathData.f.v - letters[0].an * 0.5 - letters[letters.length - 1].an * 0.5) * ind / (len - 1);
            currentLength += this._pathData.f.v;
          }
          while (flag) {
            if (segmentLength + partialLength >= currentLength + animatorOffset || !points) {
              perc = (currentLength + animatorOffset - segmentLength) / currentPoint.partialLength;
              xPathPos = prevPoint.point[0] + (currentPoint.point[0] - prevPoint.point[0]) * perc;
              yPathPos = prevPoint.point[1] + (currentPoint.point[1] - prevPoint.point[1]) * perc;
              matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -(alignment[1] * yOff) * 0.01);
              flag = false;
            } else if (points) {
              segmentLength += currentPoint.partialLength;
              pointInd += 1;
              if (pointInd >= points.length) {
                pointInd = 0;
                segmentInd += 1;
                if (!segments[segmentInd]) {
                  if (mask.v.c) {
                    pointInd = 0;
                    segmentInd = 0;
                    points = segments[segmentInd].points;
                  } else {
                    segmentLength -= currentPoint.partialLength;
                    points = null;
                  }
                } else {
                  points = segments[segmentInd].points;
                }
              }
              if (points) {
                prevPoint = currentPoint;
                currentPoint = points[pointInd];
                partialLength = currentPoint.partialLength;
              }
            }
          }
          offf = letters[i].an / 2 - letters[i].add;
          matrixHelper.translate(-offf, 0, 0);
        } else {
          offf = letters[i].an / 2 - letters[i].add;
          matrixHelper.translate(-offf, 0, 0);

          // Grouping alignment
          matrixHelper.translate(-alignment[0] * letters[i].an * 0.005, -alignment[1] * yOff * 0.01, 0);
        }
        for (j = 0; j < jLen; j += 1) {
          animatorProps = animators[j].a;
          if (animatorProps.t.propType) {
            animatorSelector = animators[j].s;
            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
            // This condition is to prevent applying tracking to first character in each line. Might be better to use a boolean "isNewLine"
            if (xPos !== 0 || documentData.j !== 0) {
              if (this._hasMaskedPath) {
                if (mult.length) {
                  currentLength += animatorProps.t.v * mult[0];
                } else {
                  currentLength += animatorProps.t.v * mult;
                }
              } else if (mult.length) {
                xPos += animatorProps.t.v * mult[0];
              } else {
                xPos += animatorProps.t.v * mult;
              }
            }
          }
        }
        if (documentData.strokeWidthAnim) {
          sw = documentData.sw || 0;
        }
        if (documentData.strokeColorAnim) {
          if (documentData.sc) {
            sc = [documentData.sc[0], documentData.sc[1], documentData.sc[2]];
          } else {
            sc = [0, 0, 0];
          }
        }
        if (documentData.fillColorAnim && documentData.fc) {
          fc = [documentData.fc[0], documentData.fc[1], documentData.fc[2]];
        }
        for (j = 0; j < jLen; j += 1) {
          animatorProps = animators[j].a;
          if (animatorProps.a.propType) {
            animatorSelector = animators[j].s;
            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
            if (mult.length) {
              matrixHelper.translate(-animatorProps.a.v[0] * mult[0], -animatorProps.a.v[1] * mult[1], animatorProps.a.v[2] * mult[2]);
            } else {
              matrixHelper.translate(-animatorProps.a.v[0] * mult, -animatorProps.a.v[1] * mult, animatorProps.a.v[2] * mult);
            }
          }
        }
        for (j = 0; j < jLen; j += 1) {
          animatorProps = animators[j].a;
          if (animatorProps.s.propType) {
            animatorSelector = animators[j].s;
            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
            if (mult.length) {
              matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult[0], 1 + (animatorProps.s.v[1] - 1) * mult[1], 1);
            } else {
              matrixHelper.scale(1 + (animatorProps.s.v[0] - 1) * mult, 1 + (animatorProps.s.v[1] - 1) * mult, 1);
            }
          }
        }
        for (j = 0; j < jLen; j += 1) {
          animatorProps = animators[j].a;
          animatorSelector = animators[j].s;
          mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
          if (animatorProps.sk.propType) {
            if (mult.length) {
              matrixHelper.skewFromAxis(-animatorProps.sk.v * mult[0], animatorProps.sa.v * mult[1]);
            } else {
              matrixHelper.skewFromAxis(-animatorProps.sk.v * mult, animatorProps.sa.v * mult);
            }
          }
          if (animatorProps.r.propType) {
            if (mult.length) {
              matrixHelper.rotateZ(-animatorProps.r.v * mult[2]);
            } else {
              matrixHelper.rotateZ(-animatorProps.r.v * mult);
            }
          }
          if (animatorProps.ry.propType) {
            if (mult.length) {
              matrixHelper.rotateY(animatorProps.ry.v * mult[1]);
            } else {
              matrixHelper.rotateY(animatorProps.ry.v * mult);
            }
          }
          if (animatorProps.rx.propType) {
            if (mult.length) {
              matrixHelper.rotateX(animatorProps.rx.v * mult[0]);
            } else {
              matrixHelper.rotateX(animatorProps.rx.v * mult);
            }
          }
          if (animatorProps.o.propType) {
            if (mult.length) {
              elemOpacity += (animatorProps.o.v * mult[0] - elemOpacity) * mult[0];
            } else {
              elemOpacity += (animatorProps.o.v * mult - elemOpacity) * mult;
            }
          }
          if (documentData.strokeWidthAnim && animatorProps.sw.propType) {
            if (mult.length) {
              sw += animatorProps.sw.v * mult[0];
            } else {
              sw += animatorProps.sw.v * mult;
            }
          }
          if (documentData.strokeColorAnim && animatorProps.sc.propType) {
            for (k = 0; k < 3; k += 1) {
              if (mult.length) {
                sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult[0];
              } else {
                sc[k] += (animatorProps.sc.v[k] - sc[k]) * mult;
              }
            }
          }
          if (documentData.fillColorAnim && documentData.fc) {
            if (animatorProps.fc.propType) {
              for (k = 0; k < 3; k += 1) {
                if (mult.length) {
                  fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult[0];
                } else {
                  fc[k] += (animatorProps.fc.v[k] - fc[k]) * mult;
                }
              }
            }
            if (animatorProps.fh.propType) {
              if (mult.length) {
                fc = addHueToRGB(fc, animatorProps.fh.v * mult[0]);
              } else {
                fc = addHueToRGB(fc, animatorProps.fh.v * mult);
              }
            }
            if (animatorProps.fs.propType) {
              if (mult.length) {
                fc = addSaturationToRGB(fc, animatorProps.fs.v * mult[0]);
              } else {
                fc = addSaturationToRGB(fc, animatorProps.fs.v * mult);
              }
            }
            if (animatorProps.fb.propType) {
              if (mult.length) {
                fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult[0]);
              } else {
                fc = addBrightnessToRGB(fc, animatorProps.fb.v * mult);
              }
            }
          }
        }
        for (j = 0; j < jLen; j += 1) {
          animatorProps = animators[j].a;
          if (animatorProps.p.propType) {
            animatorSelector = animators[j].s;
            mult = animatorSelector.getMult(letters[i].anIndexes[j], textData.a[j].s.totalChars);
            if (this._hasMaskedPath) {
              if (mult.length) {
                matrixHelper.translate(0, animatorProps.p.v[1] * mult[0], -animatorProps.p.v[2] * mult[1]);
              } else {
                matrixHelper.translate(0, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
              }
            } else if (mult.length) {
              matrixHelper.translate(animatorProps.p.v[0] * mult[0], animatorProps.p.v[1] * mult[1], -animatorProps.p.v[2] * mult[2]);
            } else {
              matrixHelper.translate(animatorProps.p.v[0] * mult, animatorProps.p.v[1] * mult, -animatorProps.p.v[2] * mult);
            }
          }
        }
        if (documentData.strokeWidthAnim) {
          letterSw = sw < 0 ? 0 : sw;
        }
        if (documentData.strokeColorAnim) {
          letterSc = 'rgb(' + Math.round(sc[0] * 255) + ',' + Math.round(sc[1] * 255) + ',' + Math.round(sc[2] * 255) + ')';
        }
        if (documentData.fillColorAnim && documentData.fc) {
          letterFc = 'rgb(' + Math.round(fc[0] * 255) + ',' + Math.round(fc[1] * 255) + ',' + Math.round(fc[2] * 255) + ')';
        }
        if (this._hasMaskedPath) {
          matrixHelper.translate(0, -documentData.ls);
          matrixHelper.translate(0, alignment[1] * yOff * 0.01 + yPos, 0);
          if (this._pathData.p.v) {
            tanAngle = (currentPoint.point[1] - prevPoint.point[1]) / (currentPoint.point[0] - prevPoint.point[0]);
            var rot = Math.atan(tanAngle) * 180 / Math.PI;
            if (currentPoint.point[0] < prevPoint.point[0]) {
              rot += 180;
            }
            matrixHelper.rotate(-rot * Math.PI / 180);
          }
          matrixHelper.translate(xPathPos, yPathPos, 0);
          currentLength -= alignment[0] * letters[i].an * 0.005;
          if (letters[i + 1] && ind !== letters[i + 1].ind) {
            currentLength += letters[i].an / 2;
            currentLength += documentData.tr * 0.001 * documentData.finalSize;
          }
        } else {
          matrixHelper.translate(xPos, yPos, 0);
          if (documentData.ps) {
            // matrixHelper.translate(documentData.ps[0],documentData.ps[1],0);
            matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
          }
          switch (documentData.j) {
            case 1:
              matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]), 0, 0);
              break;
            case 2:
              matrixHelper.translate(letters[i].animatorJustifyOffset + documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[letters[i].line]) / 2, 0, 0);
              break;
            default:
              break;
          }
          matrixHelper.translate(0, -documentData.ls);
          matrixHelper.translate(offf, 0, 0);
          matrixHelper.translate(alignment[0] * letters[i].an * 0.005, alignment[1] * yOff * 0.01, 0);
          xPos += letters[i].l + documentData.tr * 0.001 * documentData.finalSize;
        }
        if (renderType === 'html') {
          letterM = matrixHelper.toCSS();
        } else if (renderType === 'svg') {
          letterM = matrixHelper.to2dCSS();
        } else {
          letterP = [matrixHelper.props[0], matrixHelper.props[1], matrixHelper.props[2], matrixHelper.props[3], matrixHelper.props[4], matrixHelper.props[5], matrixHelper.props[6], matrixHelper.props[7], matrixHelper.props[8], matrixHelper.props[9], matrixHelper.props[10], matrixHelper.props[11], matrixHelper.props[12], matrixHelper.props[13], matrixHelper.props[14], matrixHelper.props[15]];
        }
        letterO = elemOpacity;
      }
      if (renderedLettersCount <= i) {
        letterValue = new LetterProps(letterO, letterSw, letterSc, letterFc, letterM, letterP);
        this.renderedLetters.push(letterValue);
        renderedLettersCount += 1;
        this.lettersChangedFlag = true;
      } else {
        letterValue = this.renderedLetters[i];
        this.lettersChangedFlag = letterValue.update(letterO, letterSw, letterSc, letterFc, letterM, letterP) || this.lettersChangedFlag;
      }
    }
  };
  TextAnimatorProperty.prototype.getValue = function () {
    if (this._elem.globalData.frameId === this._frameId) {
      return;
    }
    this._frameId = this._elem.globalData.frameId;
    this.iterateDynamicProperties();
  };
  TextAnimatorProperty.prototype.mHelper = new Matrix();
  TextAnimatorProperty.prototype.defaultPropsArray = [];
  extendPrototype([DynamicPropertyContainer], TextAnimatorProperty);
  function ITextElement() {}
  ITextElement.prototype.initElement = function (data, globalData, comp) {
    this.lettersChangedFlag = true;
    this.initFrame();
    this.initBaseData(data, globalData, comp);
    this.textProperty = new TextProperty(this, data.t, this.dynamicProperties);
    this.textAnimator = new TextAnimatorProperty(data.t, this.renderType, this);
    this.initTransform(data, globalData, comp);
    this.initHierarchy();
    this.initRenderable();
    this.initRendererElement();
    this.createContainerElements();
    this.createRenderableComponents();
    this.createContent();
    this.hide();
    this.textAnimator.searchProperties(this.dynamicProperties);
  };
  ITextElement.prototype.prepareFrame = function (num) {
    this._mdf = false;
    this.prepareRenderableFrame(num);
    this.prepareProperties(num, this.isInRange);
  };
  ITextElement.prototype.createPathShape = function (matrixHelper, shapes) {
    var j;
    var jLen = shapes.length;
    var pathNodes;
    var shapeStr = '';
    for (j = 0; j < jLen; j += 1) {
      if (shapes[j].ty === 'sh') {
        pathNodes = shapes[j].ks.k;
        shapeStr += buildShapeString(pathNodes, pathNodes.i.length, true, matrixHelper);
      }
    }
    return shapeStr;
  };
  ITextElement.prototype.updateDocumentData = function (newData, index) {
    this.textProperty.updateDocumentData(newData, index);
  };
  ITextElement.prototype.canResizeFont = function (_canResize) {
    this.textProperty.canResizeFont(_canResize);
  };
  ITextElement.prototype.setMinimumFontSize = function (_fontSize) {
    this.textProperty.setMinimumFontSize(_fontSize);
  };
  ITextElement.prototype.applyTextPropertiesToMatrix = function (documentData, matrixHelper, lineNumber, xPos, yPos) {
    if (documentData.ps) {
      matrixHelper.translate(documentData.ps[0], documentData.ps[1] + documentData.ascent, 0);
    }
    matrixHelper.translate(0, -documentData.ls, 0);
    switch (documentData.j) {
      case 1:
        matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]), 0, 0);
        break;
      case 2:
        matrixHelper.translate(documentData.justifyOffset + (documentData.boxWidth - documentData.lineWidths[lineNumber]) / 2, 0, 0);
        break;
      default:
        break;
    }
    matrixHelper.translate(xPos, yPos, 0);
  };
  ITextElement.prototype.buildColor = function (colorData) {
    return 'rgb(' + Math.round(colorData[0] * 255) + ',' + Math.round(colorData[1] * 255) + ',' + Math.round(colorData[2] * 255) + ')';
  };
  ITextElement.prototype.emptyProp = new LetterProps();
  ITextElement.prototype.destroy = function () {};
  ITextElement.prototype.validateText = function () {
    if (this.textProperty._mdf || this.textProperty._isFirstFrame) {
      this.buildNewText();
      this.textProperty._isFirstFrame = false;
      this.textProperty._mdf = false;
    }
  };
  var emptyShapeData = {
    shapes: []
  };
  function SVGTextLottieElement(data, globalData, comp) {
    this.textSpans = [];
    this.renderType = 'svg';
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, SVGBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], SVGTextLottieElement);
  SVGTextLottieElement.prototype.createContent = function () {
    if (this.data.singleShape && !this.globalData.fontManager.chars) {
      this.textContainer = createNS('text');
    }
  };
  SVGTextLottieElement.prototype.buildTextContents = function (textArray) {
    var i = 0;
    var len = textArray.length;
    var textContents = [];
    var currentTextContent = '';
    while (i < len) {
      if (textArray[i] === String.fromCharCode(13) || textArray[i] === String.fromCharCode(3)) {
        textContents.push(currentTextContent);
        currentTextContent = '';
      } else {
        currentTextContent += textArray[i];
      }
      i += 1;
    }
    textContents.push(currentTextContent);
    return textContents;
  };
  SVGTextLottieElement.prototype.buildShapeData = function (data, scale) {
    // data should probably be cloned to apply scale separately to each instance of a text on different layers
    // but since text internal content gets only rendered once and then it's never rerendered,
    // it's probably safe not to clone data and reuse always the same instance even if the object is mutated.
    // Avoiding cloning is preferred since cloning each character shape data is expensive
    if (data.shapes && data.shapes.length) {
      var shape = data.shapes[0];
      if (shape.it) {
        var shapeItem = shape.it[shape.it.length - 1];
        if (shapeItem.s) {
          shapeItem.s.k[0] = scale;
          shapeItem.s.k[1] = scale;
        }
      }
    }
    return data;
  };
  SVGTextLottieElement.prototype.buildNewText = function () {
    this.addDynamicProperty(this);
    var i;
    var len;
    var documentData = this.textProperty.currentData;
    this.renderedLetters = createSizedArray(documentData ? documentData.l.length : 0);
    if (documentData.fc) {
      this.layerElement.setAttribute('fill', this.buildColor(documentData.fc));
    } else {
      this.layerElement.setAttribute('fill', 'rgba(0,0,0,0)');
    }
    if (documentData.sc) {
      this.layerElement.setAttribute('stroke', this.buildColor(documentData.sc));
      this.layerElement.setAttribute('stroke-width', documentData.sw);
    }
    this.layerElement.setAttribute('font-size', documentData.finalSize);
    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
    if (fontData.fClass) {
      this.layerElement.setAttribute('class', fontData.fClass);
    } else {
      this.layerElement.setAttribute('font-family', fontData.fFamily);
      var fWeight = documentData.fWeight;
      var fStyle = documentData.fStyle;
      this.layerElement.setAttribute('font-style', fStyle);
      this.layerElement.setAttribute('font-weight', fWeight);
    }
    this.layerElement.setAttribute('aria-label', documentData.t);
    var letters = documentData.l || [];
    var usesGlyphs = !!this.globalData.fontManager.chars;
    len = letters.length;
    var tSpan;
    var matrixHelper = this.mHelper;
    var shapeStr = '';
    var singleShape = this.data.singleShape;
    var xPos = 0;
    var yPos = 0;
    var firstLine = true;
    var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
    if (singleShape && !usesGlyphs && !documentData.sz) {
      var tElement = this.textContainer;
      var justify = 'start';
      switch (documentData.j) {
        case 1:
          justify = 'end';
          break;
        case 2:
          justify = 'middle';
          break;
        default:
          justify = 'start';
          break;
      }
      tElement.setAttribute('text-anchor', justify);
      tElement.setAttribute('letter-spacing', trackingOffset);
      var textContent = this.buildTextContents(documentData.finalText);
      len = textContent.length;
      yPos = documentData.ps ? documentData.ps[1] + documentData.ascent : 0;
      for (i = 0; i < len; i += 1) {
        tSpan = this.textSpans[i].span || createNS('tspan');
        tSpan.textContent = textContent[i];
        tSpan.setAttribute('x', 0);
        tSpan.setAttribute('y', yPos);
        tSpan.style.display = 'inherit';
        tElement.appendChild(tSpan);
        if (!this.textSpans[i]) {
          this.textSpans[i] = {
            span: null,
            glyph: null
          };
        }
        this.textSpans[i].span = tSpan;
        yPos += documentData.finalLineHeight;
      }
      this.layerElement.appendChild(tElement);
    } else {
      var cachedSpansLength = this.textSpans.length;
      var charData;
      for (i = 0; i < len; i += 1) {
        if (!this.textSpans[i]) {
          this.textSpans[i] = {
            span: null,
            childSpan: null,
            glyph: null
          };
        }
        if (!usesGlyphs || !singleShape || i === 0) {
          tSpan = cachedSpansLength > i ? this.textSpans[i].span : createNS(usesGlyphs ? 'g' : 'text');
          if (cachedSpansLength <= i) {
            tSpan.setAttribute('stroke-linecap', 'butt');
            tSpan.setAttribute('stroke-linejoin', 'round');
            tSpan.setAttribute('stroke-miterlimit', '4');
            this.textSpans[i].span = tSpan;
            if (usesGlyphs) {
              var childSpan = createNS('g');
              tSpan.appendChild(childSpan);
              this.textSpans[i].childSpan = childSpan;
            }
            this.textSpans[i].span = tSpan;
            this.layerElement.appendChild(tSpan);
          }
          tSpan.style.display = 'inherit';
        }
        matrixHelper.reset();
        if (singleShape) {
          if (letters[i].n) {
            xPos = -trackingOffset;
            yPos += documentData.yOffset;
            yPos += firstLine ? 1 : 0;
            firstLine = false;
          }
          this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
          xPos += letters[i].l || 0;
          // xPos += letters[i].val === ' ' ? 0 : trackingOffset;
          xPos += trackingOffset;
        }
        if (usesGlyphs) {
          charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
          var glyphElement;
          // t === 1 means the character has been replaced with an animated shaped
          if (charData.t === 1) {
            glyphElement = new SVGCompElement(charData.data, this.globalData, this);
          } else {
            var data = emptyShapeData;
            if (charData.data && charData.data.shapes) {
              data = this.buildShapeData(charData.data, documentData.finalSize);
            }
            glyphElement = new SVGShapeElement(data, this.globalData, this);
          }
          if (this.textSpans[i].glyph) {
            var glyph = this.textSpans[i].glyph;
            this.textSpans[i].childSpan.removeChild(glyph.layerElement);
            glyph.destroy();
          }
          this.textSpans[i].glyph = glyphElement;
          glyphElement._debug = true;
          glyphElement.prepareFrame(0);
          glyphElement.renderFrame();
          this.textSpans[i].childSpan.appendChild(glyphElement.layerElement);
          // when using animated shapes, the layer will be scaled instead of replacing the internal scale
          // this might have issues with strokes and might need a different solution
          if (charData.t === 1) {
            this.textSpans[i].childSpan.setAttribute('transform', 'scale(' + documentData.finalSize / 100 + ',' + documentData.finalSize / 100 + ')');
          }
        } else {
          if (singleShape) {
            tSpan.setAttribute('transform', 'translate(' + matrixHelper.props[12] + ',' + matrixHelper.props[13] + ')');
          }
          tSpan.textContent = letters[i].val;
          tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
        }
        //
      }
      if (singleShape && tSpan) {
        tSpan.setAttribute('d', shapeStr);
      }
    }
    while (i < this.textSpans.length) {
      this.textSpans[i].span.style.display = 'none';
      i += 1;
    }
    this._sizeChanged = true;
  };
  SVGTextLottieElement.prototype.sourceRectAtTime = function () {
    this.prepareFrame(this.comp.renderedFrame - this.data.st);
    this.renderInnerContent();
    if (this._sizeChanged) {
      this._sizeChanged = false;
      var textBox = this.layerElement.getBBox();
      this.bbox = {
        top: textBox.y,
        left: textBox.x,
        width: textBox.width,
        height: textBox.height
      };
    }
    return this.bbox;
  };
  SVGTextLottieElement.prototype.getValue = function () {
    var i;
    var len = this.textSpans.length;
    var glyphElement;
    this.renderedFrame = this.comp.renderedFrame;
    for (i = 0; i < len; i += 1) {
      glyphElement = this.textSpans[i].glyph;
      if (glyphElement) {
        glyphElement.prepareFrame(this.comp.renderedFrame - this.data.st);
        if (glyphElement._mdf) {
          this._mdf = true;
        }
      }
    }
  };
  SVGTextLottieElement.prototype.renderInnerContent = function () {
    this.validateText();
    if (!this.data.singleShape || this._mdf) {
      this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
      if (this.lettersChangedFlag || this.textAnimator.lettersChangedFlag) {
        this._sizeChanged = true;
        var i;
        var len;
        var renderedLetters = this.textAnimator.renderedLetters;
        var letters = this.textProperty.currentData.l;
        len = letters.length;
        var renderedLetter;
        var textSpan;
        var glyphElement;
        for (i = 0; i < len; i += 1) {
          if (!letters[i].n) {
            renderedLetter = renderedLetters[i];
            textSpan = this.textSpans[i].span;
            glyphElement = this.textSpans[i].glyph;
            if (glyphElement) {
              glyphElement.renderFrame();
            }
            if (renderedLetter._mdf.m) {
              textSpan.setAttribute('transform', renderedLetter.m);
            }
            if (renderedLetter._mdf.o) {
              textSpan.setAttribute('opacity', renderedLetter.o);
            }
            if (renderedLetter._mdf.sw) {
              textSpan.setAttribute('stroke-width', renderedLetter.sw);
            }
            if (renderedLetter._mdf.sc) {
              textSpan.setAttribute('stroke', renderedLetter.sc);
            }
            if (renderedLetter._mdf.fc) {
              textSpan.setAttribute('fill', renderedLetter.fc);
            }
          }
        }
      }
    }
  };
  function ISolidElement(data, globalData, comp) {
    this.initElement(data, globalData, comp);
  }
  extendPrototype([IImageElement], ISolidElement);
  ISolidElement.prototype.createContent = function () {
    var rect = createNS('rect');
    /// /rect.style.width = this.data.sw;
    /// /rect.style.height = this.data.sh;
    /// /rect.style.fill = this.data.sc;
    rect.setAttribute('width', this.data.sw);
    rect.setAttribute('height', this.data.sh);
    rect.setAttribute('fill', this.data.sc);
    this.layerElement.appendChild(rect);
  };
  function NullElement(data, globalData, comp) {
    this.initFrame();
    this.initBaseData(data, globalData, comp);
    this.initFrame();
    this.initTransform(data, globalData, comp);
    this.initHierarchy();
  }
  NullElement.prototype.prepareFrame = function (num) {
    this.prepareProperties(num, true);
  };
  NullElement.prototype.renderFrame = function () {};
  NullElement.prototype.getBaseElement = function () {
    return null;
  };
  NullElement.prototype.destroy = function () {};
  NullElement.prototype.sourceRectAtTime = function () {};
  NullElement.prototype.hide = function () {};
  extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement], NullElement);
  function SVGRendererBase() {}
  extendPrototype([BaseRenderer], SVGRendererBase);
  SVGRendererBase.prototype.createNull = function (data) {
    return new NullElement(data, this.globalData, this);
  };
  SVGRendererBase.prototype.createShape = function (data) {
    return new SVGShapeElement(data, this.globalData, this);
  };
  SVGRendererBase.prototype.createText = function (data) {
    return new SVGTextLottieElement(data, this.globalData, this);
  };
  SVGRendererBase.prototype.createImage = function (data) {
    return new IImageElement(data, this.globalData, this);
  };
  SVGRendererBase.prototype.createSolid = function (data) {
    return new ISolidElement(data, this.globalData, this);
  };
  SVGRendererBase.prototype.configAnimation = function (animData) {
    this.svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
    this.svgElement.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');
    if (this.renderConfig.viewBoxSize) {
      this.svgElement.setAttribute('viewBox', this.renderConfig.viewBoxSize);
    } else {
      this.svgElement.setAttribute('viewBox', '0 0 ' + animData.w + ' ' + animData.h);
    }
    if (!this.renderConfig.viewBoxOnly) {
      this.svgElement.setAttribute('width', animData.w);
      this.svgElement.setAttribute('height', animData.h);
      this.svgElement.style.width = '100%';
      this.svgElement.style.height = '100%';
      this.svgElement.style.transform = 'translate3d(0,0,0)';
      this.svgElement.style.contentVisibility = this.renderConfig.contentVisibility;
    }
    if (this.renderConfig.width) {
      this.svgElement.setAttribute('width', this.renderConfig.width);
    }
    if (this.renderConfig.height) {
      this.svgElement.setAttribute('height', this.renderConfig.height);
    }
    if (this.renderConfig.className) {
      this.svgElement.setAttribute('class', this.renderConfig.className);
    }
    if (this.renderConfig.id) {
      this.svgElement.setAttribute('id', this.renderConfig.id);
    }
    if (this.renderConfig.focusable !== undefined) {
      this.svgElement.setAttribute('focusable', this.renderConfig.focusable);
    }
    this.svgElement.setAttribute('preserveAspectRatio', this.renderConfig.preserveAspectRatio);
    // this.layerElement.style.transform = 'translate3d(0,0,0)';
    // this.layerElement.style.transformOrigin = this.layerElement.style.mozTransformOrigin = this.layerElement.style.webkitTransformOrigin = this.layerElement.style['-webkit-transform'] = "0px 0px 0px";
    this.animationItem.wrapper.appendChild(this.svgElement);
    // Mask animation
    var defs = this.globalData.defs;
    this.setupGlobalData(animData, defs);
    this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
    this.data = animData;
    var maskElement = createNS('clipPath');
    var rect = createNS('rect');
    rect.setAttribute('width', animData.w);
    rect.setAttribute('height', animData.h);
    rect.setAttribute('x', 0);
    rect.setAttribute('y', 0);
    var maskId = createElementID();
    maskElement.setAttribute('id', maskId);
    maskElement.appendChild(rect);
    this.layerElement.setAttribute('clip-path', 'url(' + getLocationHref() + '#' + maskId + ')');
    defs.appendChild(maskElement);
    this.layers = animData.layers;
    this.elements = createSizedArray(animData.layers.length);
  };
  SVGRendererBase.prototype.destroy = function () {
    if (this.animationItem.wrapper) {
      this.animationItem.wrapper.innerText = '';
    }
    this.layerElement = null;
    this.globalData.defs = null;
    var i;
    var len = this.layers ? this.layers.length : 0;
    for (i = 0; i < len; i += 1) {
      if (this.elements[i] && this.elements[i].destroy) {
        this.elements[i].destroy();
      }
    }
    this.elements.length = 0;
    this.destroyed = true;
    this.animationItem = null;
  };
  SVGRendererBase.prototype.updateContainerSize = function () {};
  SVGRendererBase.prototype.findIndexByInd = function (ind) {
    var i = 0;
    var len = this.layers.length;
    for (i = 0; i < len; i += 1) {
      if (this.layers[i].ind === ind) {
        return i;
      }
    }
    return -1;
  };
  SVGRendererBase.prototype.buildItem = function (pos) {
    var elements = this.elements;
    if (elements[pos] || this.layers[pos].ty === 99) {
      return;
    }
    elements[pos] = true;
    var element = this.createItem(this.layers[pos]);
    elements[pos] = element;
    if (getExpressionsPlugin()) {
      if (this.layers[pos].ty === 0) {
        this.globalData.projectInterface.registerComposition(element);
      }
      element.initExpressions();
    }
    this.appendElementInPos(element, pos);
    if (this.layers[pos].tt) {
      var elementIndex = 'tp' in this.layers[pos] ? this.findIndexByInd(this.layers[pos].tp) : pos - 1;
      if (elementIndex === -1) {
        return;
      }
      if (!this.elements[elementIndex] || this.elements[elementIndex] === true) {
        this.buildItem(elementIndex);
        this.addPendingElement(element);
      } else {
        var matteElement = elements[elementIndex];
        var matteMask = matteElement.getMatte(this.layers[pos].tt);
        element.setMatte(matteMask);
      }
    }
  };
  SVGRendererBase.prototype.checkPendingElements = function () {
    while (this.pendingElements.length) {
      var element = this.pendingElements.pop();
      element.checkParenting();
      if (element.data.tt) {
        var i = 0;
        var len = this.elements.length;
        while (i < len) {
          if (this.elements[i] === element) {
            var elementIndex = 'tp' in element.data ? this.findIndexByInd(element.data.tp) : i - 1;
            var matteElement = this.elements[elementIndex];
            var matteMask = matteElement.getMatte(this.layers[i].tt);
            element.setMatte(matteMask);
            break;
          }
          i += 1;
        }
      }
    }
  };
  SVGRendererBase.prototype.renderFrame = function (num) {
    if (this.renderedFrame === num || this.destroyed) {
      return;
    }
    if (num === null) {
      num = this.renderedFrame;
    } else {
      this.renderedFrame = num;
    }
    // console.log('-------');
    // console.log('FRAME ',num);
    this.globalData.frameNum = num;
    this.globalData.frameId += 1;
    this.globalData.projectInterface.currentFrame = num;
    this.globalData._mdf = false;
    var i;
    var len = this.layers.length;
    if (!this.completeLayers) {
      this.checkLayers(num);
    }
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.completeLayers || this.elements[i]) {
        this.elements[i].prepareFrame(num - this.layers[i].st);
      }
    }
    if (this.globalData._mdf) {
      for (i = 0; i < len; i += 1) {
        if (this.completeLayers || this.elements[i]) {
          this.elements[i].renderFrame();
        }
      }
    }
  };
  SVGRendererBase.prototype.appendElementInPos = function (element, pos) {
    var newElement = element.getBaseElement();
    if (!newElement) {
      return;
    }
    var i = 0;
    var nextElement;
    while (i < pos) {
      if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement()) {
        nextElement = this.elements[i].getBaseElement();
      }
      i += 1;
    }
    if (nextElement) {
      this.layerElement.insertBefore(newElement, nextElement);
    } else {
      this.layerElement.appendChild(newElement);
    }
  };
  SVGRendererBase.prototype.hide = function () {
    this.layerElement.style.display = 'none';
  };
  SVGRendererBase.prototype.show = function () {
    this.layerElement.style.display = 'block';
  };
  function ICompElement() {}
  extendPrototype([BaseElement, TransformElement, HierarchyElement, FrameElement, RenderableDOMElement], ICompElement);
  ICompElement.prototype.initElement = function (data, globalData, comp) {
    this.initFrame();
    this.initBaseData(data, globalData, comp);
    this.initTransform(data, globalData, comp);
    this.initRenderable();
    this.initHierarchy();
    this.initRendererElement();
    this.createContainerElements();
    this.createRenderableComponents();
    if (this.data.xt || !globalData.progressiveLoad) {
      this.buildAllItems();
    }
    this.hide();
  };

  /* ICompElement.prototype.hide = function(){
      if(!this.hidden){
          this.hideElement();
          var i,len = this.elements.length;
          for( i = 0; i < len; i+=1 ){
              if(this.elements[i]){
                  this.elements[i].hide();
              }
          }
      }
  }; */

  ICompElement.prototype.prepareFrame = function (num) {
    this._mdf = false;
    this.prepareRenderableFrame(num);
    this.prepareProperties(num, this.isInRange);
    if (!this.isInRange && !this.data.xt) {
      return;
    }
    if (!this.tm._placeholder) {
      var timeRemapped = this.tm.v;
      if (timeRemapped === this.data.op) {
        timeRemapped = this.data.op - 1;
      }
      this.renderedFrame = timeRemapped;
    } else {
      this.renderedFrame = num / this.data.sr;
    }
    var i;
    var len = this.elements.length;
    if (!this.completeLayers) {
      this.checkLayers(this.renderedFrame);
    }
    // This iteration needs to be backwards because of how expressions connect between each other
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.completeLayers || this.elements[i]) {
        this.elements[i].prepareFrame(this.renderedFrame - this.layers[i].st);
        if (this.elements[i]._mdf) {
          this._mdf = true;
        }
      }
    }
  };
  ICompElement.prototype.renderInnerContent = function () {
    var i;
    var len = this.layers.length;
    for (i = 0; i < len; i += 1) {
      if (this.completeLayers || this.elements[i]) {
        this.elements[i].renderFrame();
      }
    }
  };
  ICompElement.prototype.setElements = function (elems) {
    this.elements = elems;
  };
  ICompElement.prototype.getElements = function () {
    return this.elements;
  };
  ICompElement.prototype.destroyElements = function () {
    var i;
    var len = this.layers.length;
    for (i = 0; i < len; i += 1) {
      if (this.elements[i]) {
        this.elements[i].destroy();
      }
    }
  };
  ICompElement.prototype.destroy = function () {
    this.destroyElements();
    this.destroyBaseElement();
  };
  function SVGCompElement(data, globalData, comp) {
    this.layers = data.layers;
    this.supports3d = true;
    this.completeLayers = false;
    this.pendingElements = [];
    this.elements = this.layers ? createSizedArray(this.layers.length) : [];
    this.initElement(data, globalData, comp);
    this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : {
      _placeholder: true
    };
  }
  extendPrototype([SVGRendererBase, ICompElement, SVGBaseElement], SVGCompElement);
  SVGCompElement.prototype.createComp = function (data) {
    return new SVGCompElement(data, this.globalData, this);
  };
  function SVGRenderer(animationItem, config) {
    this.animationItem = animationItem;
    this.layers = null;
    this.renderedFrame = -1;
    this.svgElement = createNS('svg');
    var ariaLabel = '';
    if (config && config.title) {
      var titleElement = createNS('title');
      var titleId = createElementID();
      titleElement.setAttribute('id', titleId);
      titleElement.textContent = config.title;
      this.svgElement.appendChild(titleElement);
      ariaLabel += titleId;
    }
    if (config && config.description) {
      var descElement = createNS('desc');
      var descId = createElementID();
      descElement.setAttribute('id', descId);
      descElement.textContent = config.description;
      this.svgElement.appendChild(descElement);
      ariaLabel += ' ' + descId;
    }
    if (ariaLabel) {
      this.svgElement.setAttribute('aria-labelledby', ariaLabel);
    }
    var defs = createNS('defs');
    this.svgElement.appendChild(defs);
    var maskElement = createNS('g');
    this.svgElement.appendChild(maskElement);
    this.layerElement = maskElement;
    this.renderConfig = {
      preserveAspectRatio: config && config.preserveAspectRatio || 'xMidYMid meet',
      imagePreserveAspectRatio: config && config.imagePreserveAspectRatio || 'xMidYMid slice',
      contentVisibility: config && config.contentVisibility || 'visible',
      progressiveLoad: config && config.progressiveLoad || false,
      hideOnTransparent: !(config && config.hideOnTransparent === false),
      viewBoxOnly: config && config.viewBoxOnly || false,
      viewBoxSize: config && config.viewBoxSize || false,
      className: config && config.className || '',
      id: config && config.id || '',
      focusable: config && config.focusable,
      filterSize: {
        width: config && config.filterSize && config.filterSize.width || '100%',
        height: config && config.filterSize && config.filterSize.height || '100%',
        x: config && config.filterSize && config.filterSize.x || '0%',
        y: config && config.filterSize && config.filterSize.y || '0%'
      },
      width: config && config.width,
      height: config && config.height,
      runExpressions: !config || config.runExpressions === undefined || config.runExpressions
    };
    this.globalData = {
      _mdf: false,
      frameNum: -1,
      defs: defs,
      renderConfig: this.renderConfig
    };
    this.elements = [];
    this.pendingElements = [];
    this.destroyed = false;
    this.rendererType = 'svg';
  }
  extendPrototype([SVGRendererBase], SVGRenderer);
  SVGRenderer.prototype.createComp = function (data) {
    return new SVGCompElement(data, this.globalData, this);
  };
  function ShapeTransformManager() {
    this.sequences = {};
    this.sequenceList = [];
    this.transform_key_count = 0;
  }
  ShapeTransformManager.prototype = {
    addTransformSequence: function addTransformSequence(transforms) {
      var i;
      var len = transforms.length;
      var key = '_';
      for (i = 0; i < len; i += 1) {
        key += transforms[i].transform.key + '_';
      }
      var sequence = this.sequences[key];
      if (!sequence) {
        sequence = {
          transforms: [].concat(transforms),
          finalTransform: new Matrix(),
          _mdf: false
        };
        this.sequences[key] = sequence;
        this.sequenceList.push(sequence);
      }
      return sequence;
    },
    processSequence: function processSequence(sequence, isFirstFrame) {
      var i = 0;
      var len = sequence.transforms.length;
      var _mdf = isFirstFrame;
      while (i < len && !isFirstFrame) {
        if (sequence.transforms[i].transform.mProps._mdf) {
          _mdf = true;
          break;
        }
        i += 1;
      }
      if (_mdf) {
        sequence.finalTransform.reset();
        for (i = len - 1; i >= 0; i -= 1) {
          sequence.finalTransform.multiply(sequence.transforms[i].transform.mProps.v);
        }
      }
      sequence._mdf = _mdf;
    },
    processSequences: function processSequences(isFirstFrame) {
      var i;
      var len = this.sequenceList.length;
      for (i = 0; i < len; i += 1) {
        this.processSequence(this.sequenceList[i], isFirstFrame);
      }
    },
    getNewKey: function getNewKey() {
      this.transform_key_count += 1;
      return '_' + this.transform_key_count;
    }
  };
  var lumaLoader = function lumaLoader() {
    var id = '__lottie_element_luma_buffer';
    var lumaBuffer = null;
    var lumaBufferCtx = null;
    var svg = null;

    // This alternate solution has a slight delay before the filter is applied, resulting in a flicker on the first frame.
    // Keeping this here for reference, and in the future, if offscreen canvas supports url filters, this can be used.
    // For now, neither of them work for offscreen canvas, so canvas workers can't support the luma track matte mask.
    // Naming it solution 2 to mark the extra comment lines.
    /*
    var svgString = [
      '<svg xmlns="http://www.w3.org/2000/svg">',
      '<filter id="' + id + '">',
      '<feColorMatrix type="matrix" color-interpolation-filters="sRGB" values="',
      '0.3, 0.3, 0.3, 0, 0, ',
      '0.3, 0.3, 0.3, 0, 0, ',
      '0.3, 0.3, 0.3, 0, 0, ',
      '0.3, 0.3, 0.3, 0, 0',
      '"/>',
      '</filter>',
      '</svg>',
    ].join('');
    var blob = new Blob([svgString], { type: 'image/svg+xml' });
    var url = URL.createObjectURL(blob);
    */

    function createLumaSvgFilter() {
      var _svg = createNS('svg');
      var fil = createNS('filter');
      var matrix = createNS('feColorMatrix');
      fil.setAttribute('id', id);
      matrix.setAttribute('type', 'matrix');
      matrix.setAttribute('color-interpolation-filters', 'sRGB');
      matrix.setAttribute('values', '0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0, 0.3, 0.3, 0.3, 0, 0');
      fil.appendChild(matrix);
      _svg.appendChild(fil);
      _svg.setAttribute('id', id + '_svg');
      if (featureSupport.svgLumaHidden) {
        _svg.style.display = 'none';
      }
      return _svg;
    }
    function loadLuma() {
      if (!lumaBuffer) {
        svg = createLumaSvgFilter();
        document.body.appendChild(svg);
        lumaBuffer = createTag('canvas');
        lumaBufferCtx = lumaBuffer.getContext('2d');
        // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
        lumaBufferCtx.filter = 'url(#' + id + ')';
        lumaBufferCtx.fillStyle = 'rgba(0,0,0,0)';
        lumaBufferCtx.fillRect(0, 0, 1, 1);
      }
    }
    function getLuma(canvas) {
      if (!lumaBuffer) {
        loadLuma();
      }
      lumaBuffer.width = canvas.width;
      lumaBuffer.height = canvas.height;
      // lumaBufferCtx.filter = `url('${url}#__lottie_element_luma_buffer')`; // part of solution 2
      lumaBufferCtx.filter = 'url(#' + id + ')';
      return lumaBuffer;
    }
    return {
      load: loadLuma,
      get: getLuma
    };
  };
  function createCanvas(width, height) {
    if (featureSupport.offscreenCanvas) {
      return new OffscreenCanvas(width, height);
    }
    var canvas = createTag('canvas');
    canvas.width = width;
    canvas.height = height;
    return canvas;
  }
  var assetLoader = function () {
    return {
      loadLumaCanvas: lumaLoader.load,
      getLumaCanvas: lumaLoader.get,
      createCanvas: createCanvas
    };
  }();
  var registeredEffects = {};
  function CVEffects(elem) {
    var i;
    var len = elem.data.ef ? elem.data.ef.length : 0;
    this.filters = [];
    var filterManager;
    for (i = 0; i < len; i += 1) {
      filterManager = null;
      var type = elem.data.ef[i].ty;
      if (registeredEffects[type]) {
        var Effect = registeredEffects[type].effect;
        filterManager = new Effect(elem.effectsManager.effectElements[i], elem);
      }
      if (filterManager) {
        this.filters.push(filterManager);
      }
    }
    if (this.filters.length) {
      elem.addRenderableComponent(this);
    }
  }
  CVEffects.prototype.renderFrame = function (_isFirstFrame) {
    var i;
    var len = this.filters.length;
    for (i = 0; i < len; i += 1) {
      this.filters[i].renderFrame(_isFirstFrame);
    }
  };
  CVEffects.prototype.getEffects = function (type) {
    var i;
    var len = this.filters.length;
    var effects = [];
    for (i = 0; i < len; i += 1) {
      if (this.filters[i].type === type) {
        effects.push(this.filters[i]);
      }
    }
    return effects;
  };
  function registerEffect(id, effect) {
    registeredEffects[id] = {
      effect: effect
    };
  }
  function CVMaskElement(data, element) {
    this.data = data;
    this.element = element;
    this.masksProperties = this.data.masksProperties || [];
    this.viewData = createSizedArray(this.masksProperties.length);
    var i;
    var len = this.masksProperties.length;
    var hasMasks = false;
    for (i = 0; i < len; i += 1) {
      if (this.masksProperties[i].mode !== 'n') {
        hasMasks = true;
      }
      this.viewData[i] = ShapePropertyFactory.getShapeProp(this.element, this.masksProperties[i], 3);
    }
    this.hasMasks = hasMasks;
    if (hasMasks) {
      this.element.addRenderableComponent(this);
    }
  }
  CVMaskElement.prototype.renderFrame = function () {
    if (!this.hasMasks) {
      return;
    }
    var transform = this.element.finalTransform.mat;
    var ctx = this.element.canvasContext;
    var i;
    var len = this.masksProperties.length;
    var pt;
    var pts;
    var data;
    ctx.beginPath();
    for (i = 0; i < len; i += 1) {
      if (this.masksProperties[i].mode !== 'n') {
        if (this.masksProperties[i].inv) {
          ctx.moveTo(0, 0);
          ctx.lineTo(this.element.globalData.compSize.w, 0);
          ctx.lineTo(this.element.globalData.compSize.w, this.element.globalData.compSize.h);
          ctx.lineTo(0, this.element.globalData.compSize.h);
          ctx.lineTo(0, 0);
        }
        data = this.viewData[i].v;
        pt = transform.applyToPointArray(data.v[0][0], data.v[0][1], 0);
        ctx.moveTo(pt[0], pt[1]);
        var j;
        var jLen = data._length;
        for (j = 1; j < jLen; j += 1) {
          pts = transform.applyToTriplePoints(data.o[j - 1], data.i[j], data.v[j]);
          ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
        }
        pts = transform.applyToTriplePoints(data.o[j - 1], data.i[0], data.v[0]);
        ctx.bezierCurveTo(pts[0], pts[1], pts[2], pts[3], pts[4], pts[5]);
      }
    }
    this.element.globalData.renderer.save(true);
    ctx.clip();
  };
  CVMaskElement.prototype.getMaskProperty = MaskElement.prototype.getMaskProperty;
  CVMaskElement.prototype.destroy = function () {
    this.element = null;
  };
  function CVBaseElement() {}
  var operationsMap = {
    1: 'source-in',
    2: 'source-out',
    3: 'source-in',
    4: 'source-out'
  };
  CVBaseElement.prototype = {
    createElements: function createElements() {},
    initRendererElement: function initRendererElement() {},
    createContainerElements: function createContainerElements() {
      // If the layer is masked we will use two buffers to store each different states of the drawing
      // This solution is not ideal for several reason. But unfortunately, because of the recursive
      // nature of the render tree, it's the only simple way to make sure one inner mask doesn't override an outer mask.
      // TODO: try to reduce the size of these buffers to the size of the composition contaning the layer
      // It might be challenging because the layer most likely is transformed in some way
      if (this.data.tt >= 1) {
        this.buffers = [];
        var canvasContext = this.globalData.canvasContext;
        var bufferCanvas = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
        this.buffers.push(bufferCanvas);
        var bufferCanvas2 = assetLoader.createCanvas(canvasContext.canvas.width, canvasContext.canvas.height);
        this.buffers.push(bufferCanvas2);
        if (this.data.tt >= 3 && !document._isProxy) {
          assetLoader.loadLumaCanvas();
        }
      }
      this.canvasContext = this.globalData.canvasContext;
      this.transformCanvas = this.globalData.transformCanvas;
      this.renderableEffectsManager = new CVEffects(this);
      this.searchEffectTransforms();
    },
    createContent: function createContent() {},
    setBlendMode: function setBlendMode() {
      var globalData = this.globalData;
      if (globalData.blendMode !== this.data.bm) {
        globalData.blendMode = this.data.bm;
        var blendModeValue = getBlendMode(this.data.bm);
        globalData.canvasContext.globalCompositeOperation = blendModeValue;
      }
    },
    createRenderableComponents: function createRenderableComponents() {
      this.maskManager = new CVMaskElement(this.data, this);
      this.transformEffects = this.renderableEffectsManager.getEffects(effectTypes.TRANSFORM_EFFECT);
    },
    hideElement: function hideElement() {
      if (!this.hidden && (!this.isInRange || this.isTransparent)) {
        this.hidden = true;
      }
    },
    showElement: function showElement() {
      if (this.isInRange && !this.isTransparent) {
        this.hidden = false;
        this._isFirstFrame = true;
        this.maskManager._isFirstFrame = true;
      }
    },
    clearCanvas: function clearCanvas(canvasContext) {
      canvasContext.clearRect(this.transformCanvas.tx, this.transformCanvas.ty, this.transformCanvas.w * this.transformCanvas.sx, this.transformCanvas.h * this.transformCanvas.sy);
    },
    prepareLayer: function prepareLayer() {
      if (this.data.tt >= 1) {
        var buffer = this.buffers[0];
        var bufferCtx = buffer.getContext('2d');
        this.clearCanvas(bufferCtx);
        // on the first buffer we store the current state of the global drawing
        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
        // The next four lines are to clear the canvas
        // TODO: Check if there is a way to clear the canvas without resetting the transform
        this.currentTransform = this.canvasContext.getTransform();
        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
        this.clearCanvas(this.canvasContext);
        this.canvasContext.setTransform(this.currentTransform);
      }
    },
    exitLayer: function exitLayer() {
      if (this.data.tt >= 1) {
        var buffer = this.buffers[1];
        // On the second buffer we store the current state of the global drawing
        // that only contains the content of this layer
        // (if it is a composition, it also includes the nested layers)
        var bufferCtx = buffer.getContext('2d');
        this.clearCanvas(bufferCtx);
        bufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
        // We clear the canvas again
        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);
        this.clearCanvas(this.canvasContext);
        this.canvasContext.setTransform(this.currentTransform);
        // We draw the mask
        var mask = this.comp.getElementById('tp' in this.data ? this.data.tp : this.data.ind - 1);
        mask.renderFrame(true);
        // We draw the second buffer (that contains the content of this layer)
        this.canvasContext.setTransform(1, 0, 0, 1, 0, 0);

        // If the mask is a Luma matte, we need to do two extra painting operations
        // the _isProxy check is to avoid drawing a fake canvas in workers that will throw an error
        if (this.data.tt >= 3 && !document._isProxy) {
          // We copy the painted mask to a buffer that has a color matrix filter applied to it
          // that applies the rgb values to the alpha channel
          var lumaBuffer = assetLoader.getLumaCanvas(this.canvasContext.canvas);
          var lumaBufferCtx = lumaBuffer.getContext('2d');
          lumaBufferCtx.drawImage(this.canvasContext.canvas, 0, 0);
          this.clearCanvas(this.canvasContext);
          // we repaint the context with the mask applied to it
          this.canvasContext.drawImage(lumaBuffer, 0, 0);
        }
        this.canvasContext.globalCompositeOperation = operationsMap[this.data.tt];
        this.canvasContext.drawImage(buffer, 0, 0);
        // We finally draw the first buffer (that contains the content of the global drawing)
        // We use destination-over to draw the global drawing below the current layer
        this.canvasContext.globalCompositeOperation = 'destination-over';
        this.canvasContext.drawImage(this.buffers[0], 0, 0);
        this.canvasContext.setTransform(this.currentTransform);
        // We reset the globalCompositeOperation to source-over, the standard type of operation
        this.canvasContext.globalCompositeOperation = 'source-over';
      }
    },
    renderFrame: function renderFrame(forceRender) {
      if (this.hidden || this.data.hd) {
        return;
      }
      if (this.data.td === 1 && !forceRender) {
        return;
      }
      this.renderTransform();
      this.renderRenderable();
      this.renderLocalTransform();
      this.setBlendMode();
      var forceRealStack = this.data.ty === 0;
      this.prepareLayer();
      this.globalData.renderer.save(forceRealStack);
      this.globalData.renderer.ctxTransform(this.finalTransform.localMat.props);
      this.globalData.renderer.ctxOpacity(this.finalTransform.localOpacity);
      this.renderInnerContent();
      this.globalData.renderer.restore(forceRealStack);
      this.exitLayer();
      if (this.maskManager.hasMasks) {
        this.globalData.renderer.restore(true);
      }
      if (this._isFirstFrame) {
        this._isFirstFrame = false;
      }
    },
    destroy: function destroy() {
      this.canvasContext = null;
      this.data = null;
      this.globalData = null;
      this.maskManager.destroy();
    },
    mHelper: new Matrix()
  };
  CVBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
  CVBaseElement.prototype.show = CVBaseElement.prototype.showElement;
  function CVShapeData(element, data, styles, transformsManager) {
    this.styledShapes = [];
    this.tr = [0, 0, 0, 0, 0, 0];
    var ty = 4;
    if (data.ty === 'rc') {
      ty = 5;
    } else if (data.ty === 'el') {
      ty = 6;
    } else if (data.ty === 'sr') {
      ty = 7;
    }
    this.sh = ShapePropertyFactory.getShapeProp(element, data, ty, element);
    var i;
    var len = styles.length;
    var styledShape;
    for (i = 0; i < len; i += 1) {
      if (!styles[i].closed) {
        styledShape = {
          transforms: transformsManager.addTransformSequence(styles[i].transforms),
          trNodes: []
        };
        this.styledShapes.push(styledShape);
        styles[i].elements.push(styledShape);
      }
    }
  }
  CVShapeData.prototype.setAsAnimated = SVGShapeData.prototype.setAsAnimated;
  function CVShapeElement(data, globalData, comp) {
    this.shapes = [];
    this.shapesData = data.shapes;
    this.stylesList = [];
    this.itemsData = [];
    this.prevViewData = [];
    this.shapeModifiers = [];
    this.processedElements = [];
    this.transformsManager = new ShapeTransformManager();
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, CVBaseElement, IShapeElement, HierarchyElement, FrameElement, RenderableElement], CVShapeElement);
  CVShapeElement.prototype.initElement = RenderableDOMElement.prototype.initElement;
  CVShapeElement.prototype.transformHelper = {
    opacity: 1,
    _opMdf: false
  };
  CVShapeElement.prototype.dashResetter = [];
  CVShapeElement.prototype.createContent = function () {
    this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
  };
  CVShapeElement.prototype.createStyleElement = function (data, transforms) {
    var styleElem = {
      data: data,
      type: data.ty,
      preTransforms: this.transformsManager.addTransformSequence(transforms),
      transforms: [],
      elements: [],
      closed: data.hd === true
    };
    var elementData = {};
    if (data.ty === 'fl' || data.ty === 'st') {
      elementData.c = PropertyFactory.getProp(this, data.c, 1, 255, this);
      if (!elementData.c.k) {
        styleElem.co = 'rgb(' + bmFloor(elementData.c.v[0]) + ',' + bmFloor(elementData.c.v[1]) + ',' + bmFloor(elementData.c.v[2]) + ')';
      }
    } else if (data.ty === 'gf' || data.ty === 'gs') {
      elementData.s = PropertyFactory.getProp(this, data.s, 1, null, this);
      elementData.e = PropertyFactory.getProp(this, data.e, 1, null, this);
      elementData.h = PropertyFactory.getProp(this, data.h || {
        k: 0
      }, 0, 0.01, this);
      elementData.a = PropertyFactory.getProp(this, data.a || {
        k: 0
      }, 0, degToRads, this);
      elementData.g = new GradientProperty(this, data.g, this);
    }
    elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
    if (data.ty === 'st' || data.ty === 'gs') {
      styleElem.lc = lineCapEnum[data.lc || 2];
      styleElem.lj = lineJoinEnum[data.lj || 2];
      if (data.lj == 1) {
        // eslint-disable-line eqeqeq
        styleElem.ml = data.ml;
      }
      elementData.w = PropertyFactory.getProp(this, data.w, 0, null, this);
      if (!elementData.w.k) {
        styleElem.wi = elementData.w.v;
      }
      if (data.d) {
        var d = new DashProperty(this, data.d, 'canvas', this);
        elementData.d = d;
        if (!elementData.d.k) {
          styleElem.da = elementData.d.dashArray;
          styleElem["do"] = elementData.d.dashoffset[0];
        }
      }
    } else {
      styleElem.r = data.r === 2 ? 'evenodd' : 'nonzero';
    }
    this.stylesList.push(styleElem);
    elementData.style = styleElem;
    return elementData;
  };
  CVShapeElement.prototype.createGroupElement = function () {
    var elementData = {
      it: [],
      prevViewData: []
    };
    return elementData;
  };
  CVShapeElement.prototype.createTransformElement = function (data) {
    var elementData = {
      transform: {
        opacity: 1,
        _opMdf: false,
        key: this.transformsManager.getNewKey(),
        op: PropertyFactory.getProp(this, data.o, 0, 0.01, this),
        mProps: TransformPropertyFactory.getTransformProperty(this, data, this)
      }
    };
    return elementData;
  };
  CVShapeElement.prototype.createShapeElement = function (data) {
    var elementData = new CVShapeData(this, data, this.stylesList, this.transformsManager);
    this.shapes.push(elementData);
    this.addShapeToModifiers(elementData);
    return elementData;
  };
  CVShapeElement.prototype.reloadShapes = function () {
    this._isFirstFrame = true;
    var i;
    var len = this.itemsData.length;
    for (i = 0; i < len; i += 1) {
      this.prevViewData[i] = this.itemsData[i];
    }
    this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, true, []);
    len = this.dynamicProperties.length;
    for (i = 0; i < len; i += 1) {
      this.dynamicProperties[i].getValue();
    }
    this.renderModifiers();
    this.transformsManager.processSequences(this._isFirstFrame);
  };
  CVShapeElement.prototype.addTransformToStyleList = function (transform) {
    var i;
    var len = this.stylesList.length;
    for (i = 0; i < len; i += 1) {
      if (!this.stylesList[i].closed) {
        this.stylesList[i].transforms.push(transform);
      }
    }
  };
  CVShapeElement.prototype.removeTransformFromStyleList = function () {
    var i;
    var len = this.stylesList.length;
    for (i = 0; i < len; i += 1) {
      if (!this.stylesList[i].closed) {
        this.stylesList[i].transforms.pop();
      }
    }
  };
  CVShapeElement.prototype.closeStyles = function (styles) {
    var i;
    var len = styles.length;
    for (i = 0; i < len; i += 1) {
      styles[i].closed = true;
    }
  };
  CVShapeElement.prototype.searchShapes = function (arr, itemsData, prevViewData, shouldRender, transforms) {
    var i;
    var len = arr.length - 1;
    var j;
    var jLen;
    var ownStyles = [];
    var ownModifiers = [];
    var processedPos;
    var modifier;
    var currentTransform;
    var ownTransforms = [].concat(transforms);
    for (i = len; i >= 0; i -= 1) {
      processedPos = this.searchProcessedElement(arr[i]);
      if (!processedPos) {
        arr[i]._shouldRender = shouldRender;
      } else {
        itemsData[i] = prevViewData[processedPos - 1];
      }
      if (arr[i].ty === 'fl' || arr[i].ty === 'st' || arr[i].ty === 'gf' || arr[i].ty === 'gs') {
        if (!processedPos) {
          itemsData[i] = this.createStyleElement(arr[i], ownTransforms);
        } else {
          itemsData[i].style.closed = false;
        }
        ownStyles.push(itemsData[i].style);
      } else if (arr[i].ty === 'gr') {
        if (!processedPos) {
          itemsData[i] = this.createGroupElement(arr[i]);
        } else {
          jLen = itemsData[i].it.length;
          for (j = 0; j < jLen; j += 1) {
            itemsData[i].prevViewData[j] = itemsData[i].it[j];
          }
        }
        this.searchShapes(arr[i].it, itemsData[i].it, itemsData[i].prevViewData, shouldRender, ownTransforms);
      } else if (arr[i].ty === 'tr') {
        if (!processedPos) {
          currentTransform = this.createTransformElement(arr[i]);
          itemsData[i] = currentTransform;
        }
        ownTransforms.push(itemsData[i]);
        this.addTransformToStyleList(itemsData[i]);
      } else if (arr[i].ty === 'sh' || arr[i].ty === 'rc' || arr[i].ty === 'el' || arr[i].ty === 'sr') {
        if (!processedPos) {
          itemsData[i] = this.createShapeElement(arr[i]);
        }
      } else if (arr[i].ty === 'tm' || arr[i].ty === 'rd' || arr[i].ty === 'pb' || arr[i].ty === 'zz' || arr[i].ty === 'op') {
        if (!processedPos) {
          modifier = ShapeModifiers.getModifier(arr[i].ty);
          modifier.init(this, arr[i]);
          itemsData[i] = modifier;
          this.shapeModifiers.push(modifier);
        } else {
          modifier = itemsData[i];
          modifier.closed = false;
        }
        ownModifiers.push(modifier);
      } else if (arr[i].ty === 'rp') {
        if (!processedPos) {
          modifier = ShapeModifiers.getModifier(arr[i].ty);
          itemsData[i] = modifier;
          modifier.init(this, arr, i, itemsData);
          this.shapeModifiers.push(modifier);
          shouldRender = false;
        } else {
          modifier = itemsData[i];
          modifier.closed = true;
        }
        ownModifiers.push(modifier);
      }
      this.addProcessedElement(arr[i], i + 1);
    }
    this.removeTransformFromStyleList();
    this.closeStyles(ownStyles);
    len = ownModifiers.length;
    for (i = 0; i < len; i += 1) {
      ownModifiers[i].closed = true;
    }
  };
  CVShapeElement.prototype.renderInnerContent = function () {
    this.transformHelper.opacity = 1;
    this.transformHelper._opMdf = false;
    this.renderModifiers();
    this.transformsManager.processSequences(this._isFirstFrame);
    this.renderShape(this.transformHelper, this.shapesData, this.itemsData, true);
  };
  CVShapeElement.prototype.renderShapeTransform = function (parentTransform, groupTransform) {
    if (parentTransform._opMdf || groupTransform.op._mdf || this._isFirstFrame) {
      groupTransform.opacity = parentTransform.opacity;
      groupTransform.opacity *= groupTransform.op.v;
      groupTransform._opMdf = true;
    }
  };
  CVShapeElement.prototype.drawLayer = function () {
    var i;
    var len = this.stylesList.length;
    var j;
    var jLen;
    var k;
    var kLen;
    var elems;
    var nodes;
    var renderer = this.globalData.renderer;
    var ctx = this.globalData.canvasContext;
    var type;
    var currentStyle;
    for (i = 0; i < len; i += 1) {
      currentStyle = this.stylesList[i];
      type = currentStyle.type;

      // Skipping style when
      // Stroke width equals 0
      // style should not be rendered (extra unused repeaters)
      // current opacity equals 0
      // global opacity equals 0
      if (!((type === 'st' || type === 'gs') && currentStyle.wi === 0 || !currentStyle.data._shouldRender || currentStyle.coOp === 0 || this.globalData.currentGlobalAlpha === 0)) {
        renderer.save();
        elems = currentStyle.elements;
        if (type === 'st' || type === 'gs') {
          renderer.ctxStrokeStyle(type === 'st' ? currentStyle.co : currentStyle.grd);
          // ctx.strokeStyle = type === 'st' ? currentStyle.co : currentStyle.grd;
          renderer.ctxLineWidth(currentStyle.wi);
          // ctx.lineWidth = currentStyle.wi;
          renderer.ctxLineCap(currentStyle.lc);
          // ctx.lineCap = currentStyle.lc;
          renderer.ctxLineJoin(currentStyle.lj);
          // ctx.lineJoin = currentStyle.lj;
          renderer.ctxMiterLimit(currentStyle.ml || 0);
          // ctx.miterLimit = currentStyle.ml || 0;
        } else {
          renderer.ctxFillStyle(type === 'fl' ? currentStyle.co : currentStyle.grd);
          // ctx.fillStyle = type === 'fl' ? currentStyle.co : currentStyle.grd;
        }
        renderer.ctxOpacity(currentStyle.coOp);
        if (type !== 'st' && type !== 'gs') {
          ctx.beginPath();
        }
        renderer.ctxTransform(currentStyle.preTransforms.finalTransform.props);
        jLen = elems.length;
        for (j = 0; j < jLen; j += 1) {
          if (type === 'st' || type === 'gs') {
            ctx.beginPath();
            if (currentStyle.da) {
              ctx.setLineDash(currentStyle.da);
              ctx.lineDashOffset = currentStyle["do"];
            }
          }
          nodes = elems[j].trNodes;
          kLen = nodes.length;
          for (k = 0; k < kLen; k += 1) {
            if (nodes[k].t === 'm') {
              ctx.moveTo(nodes[k].p[0], nodes[k].p[1]);
            } else if (nodes[k].t === 'c') {
              ctx.bezierCurveTo(nodes[k].pts[0], nodes[k].pts[1], nodes[k].pts[2], nodes[k].pts[3], nodes[k].pts[4], nodes[k].pts[5]);
            } else {
              ctx.closePath();
            }
          }
          if (type === 'st' || type === 'gs') {
            // ctx.stroke();
            renderer.ctxStroke();
            if (currentStyle.da) {
              ctx.setLineDash(this.dashResetter);
            }
          }
        }
        if (type !== 'st' && type !== 'gs') {
          // ctx.fill(currentStyle.r);
          this.globalData.renderer.ctxFill(currentStyle.r);
        }
        renderer.restore();
      }
    }
  };
  CVShapeElement.prototype.renderShape = function (parentTransform, items, data, isMain) {
    var i;
    var len = items.length - 1;
    var groupTransform;
    groupTransform = parentTransform;
    for (i = len; i >= 0; i -= 1) {
      if (items[i].ty === 'tr') {
        groupTransform = data[i].transform;
        this.renderShapeTransform(parentTransform, groupTransform);
      } else if (items[i].ty === 'sh' || items[i].ty === 'el' || items[i].ty === 'rc' || items[i].ty === 'sr') {
        this.renderPath(items[i], data[i]);
      } else if (items[i].ty === 'fl') {
        this.renderFill(items[i], data[i], groupTransform);
      } else if (items[i].ty === 'st') {
        this.renderStroke(items[i], data[i], groupTransform);
      } else if (items[i].ty === 'gf' || items[i].ty === 'gs') {
        this.renderGradientFill(items[i], data[i], groupTransform);
      } else if (items[i].ty === 'gr') {
        this.renderShape(groupTransform, items[i].it, data[i].it);
      } else if (items[i].ty === 'tm') {
        //
      }
    }
    if (isMain) {
      this.drawLayer();
    }
  };
  CVShapeElement.prototype.renderStyledShape = function (styledShape, shape) {
    if (this._isFirstFrame || shape._mdf || styledShape.transforms._mdf) {
      var shapeNodes = styledShape.trNodes;
      var paths = shape.paths;
      var i;
      var len;
      var j;
      var jLen = paths._length;
      shapeNodes.length = 0;
      var groupTransformMat = styledShape.transforms.finalTransform;
      for (j = 0; j < jLen; j += 1) {
        var pathNodes = paths.shapes[j];
        if (pathNodes && pathNodes.v) {
          len = pathNodes._length;
          for (i = 1; i < len; i += 1) {
            if (i === 1) {
              shapeNodes.push({
                t: 'm',
                p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
              });
            }
            shapeNodes.push({
              t: 'c',
              pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[i], pathNodes.v[i])
            });
          }
          if (len === 1) {
            shapeNodes.push({
              t: 'm',
              p: groupTransformMat.applyToPointArray(pathNodes.v[0][0], pathNodes.v[0][1], 0)
            });
          }
          if (pathNodes.c && len) {
            shapeNodes.push({
              t: 'c',
              pts: groupTransformMat.applyToTriplePoints(pathNodes.o[i - 1], pathNodes.i[0], pathNodes.v[0])
            });
            shapeNodes.push({
              t: 'z'
            });
          }
        }
      }
      styledShape.trNodes = shapeNodes;
    }
  };
  CVShapeElement.prototype.renderPath = function (pathData, itemData) {
    if (pathData.hd !== true && pathData._shouldRender) {
      var i;
      var len = itemData.styledShapes.length;
      for (i = 0; i < len; i += 1) {
        this.renderStyledShape(itemData.styledShapes[i], itemData.sh);
      }
    }
  };
  CVShapeElement.prototype.renderFill = function (styleData, itemData, groupTransform) {
    var styleElem = itemData.style;
    if (itemData.c._mdf || this._isFirstFrame) {
      styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
    }
    if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
      styleElem.coOp = itemData.o.v * groupTransform.opacity;
    }
  };
  CVShapeElement.prototype.renderGradientFill = function (styleData, itemData, groupTransform) {
    var styleElem = itemData.style;
    var grd;
    if (!styleElem.grd || itemData.g._mdf || itemData.s._mdf || itemData.e._mdf || styleData.t !== 1 && (itemData.h._mdf || itemData.a._mdf)) {
      var ctx = this.globalData.canvasContext;
      var pt1 = itemData.s.v;
      var pt2 = itemData.e.v;
      if (styleData.t === 1) {
        grd = ctx.createLinearGradient(pt1[0], pt1[1], pt2[0], pt2[1]);
      } else {
        var rad = Math.sqrt(Math.pow(pt1[0] - pt2[0], 2) + Math.pow(pt1[1] - pt2[1], 2));
        var ang = Math.atan2(pt2[1] - pt1[1], pt2[0] - pt1[0]);
        var percent = itemData.h.v;
        if (percent >= 1) {
          percent = 0.99;
        } else if (percent <= -1) {
          percent = -0.99;
        }
        var dist = rad * percent;
        var x = Math.cos(ang + itemData.a.v) * dist + pt1[0];
        var y = Math.sin(ang + itemData.a.v) * dist + pt1[1];
        grd = ctx.createRadialGradient(x, y, 0, pt1[0], pt1[1], rad);
      }
      var i;
      var len = styleData.g.p;
      var cValues = itemData.g.c;
      var opacity = 1;
      for (i = 0; i < len; i += 1) {
        if (itemData.g._hasOpacity && itemData.g._collapsable) {
          opacity = itemData.g.o[i * 2 + 1];
        }
        grd.addColorStop(cValues[i * 4] / 100, 'rgba(' + cValues[i * 4 + 1] + ',' + cValues[i * 4 + 2] + ',' + cValues[i * 4 + 3] + ',' + opacity + ')');
      }
      styleElem.grd = grd;
    }
    styleElem.coOp = itemData.o.v * groupTransform.opacity;
  };
  CVShapeElement.prototype.renderStroke = function (styleData, itemData, groupTransform) {
    var styleElem = itemData.style;
    var d = itemData.d;
    if (d && (d._mdf || this._isFirstFrame)) {
      styleElem.da = d.dashArray;
      styleElem["do"] = d.dashoffset[0];
    }
    if (itemData.c._mdf || this._isFirstFrame) {
      styleElem.co = 'rgb(' + bmFloor(itemData.c.v[0]) + ',' + bmFloor(itemData.c.v[1]) + ',' + bmFloor(itemData.c.v[2]) + ')';
    }
    if (itemData.o._mdf || groupTransform._opMdf || this._isFirstFrame) {
      styleElem.coOp = itemData.o.v * groupTransform.opacity;
    }
    if (itemData.w._mdf || this._isFirstFrame) {
      styleElem.wi = itemData.w.v;
    }
  };
  CVShapeElement.prototype.destroy = function () {
    this.shapesData = null;
    this.globalData = null;
    this.canvasContext = null;
    this.stylesList.length = 0;
    this.itemsData.length = 0;
  };
  function CVTextElement(data, globalData, comp) {
    this.textSpans = [];
    this.yOffset = 0;
    this.fillColorAnim = false;
    this.strokeColorAnim = false;
    this.strokeWidthAnim = false;
    this.stroke = false;
    this.fill = false;
    this.justifyOffset = 0;
    this.currentRender = null;
    this.renderType = 'canvas';
    this.values = {
      fill: 'rgba(0,0,0,0)',
      stroke: 'rgba(0,0,0,0)',
      sWidth: 0,
      fValue: ''
    };
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement, ITextElement], CVTextElement);
  CVTextElement.prototype.tHelper = createTag('canvas').getContext('2d');
  CVTextElement.prototype.buildNewText = function () {
    var documentData = this.textProperty.currentData;
    this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
    var hasFill = false;
    if (documentData.fc) {
      hasFill = true;
      this.values.fill = this.buildColor(documentData.fc);
    } else {
      this.values.fill = 'rgba(0,0,0,0)';
    }
    this.fill = hasFill;
    var hasStroke = false;
    if (documentData.sc) {
      hasStroke = true;
      this.values.stroke = this.buildColor(documentData.sc);
      this.values.sWidth = documentData.sw;
    }
    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
    var i;
    var len;
    var letters = documentData.l;
    var matrixHelper = this.mHelper;
    this.stroke = hasStroke;
    this.values.fValue = documentData.finalSize + 'px ' + this.globalData.fontManager.getFontByName(documentData.f).fFamily;
    len = documentData.finalText.length;
    // this.tHelper.font = this.values.fValue;
    var charData;
    var shapeData;
    var k;
    var kLen;
    var shapes;
    var j;
    var jLen;
    var pathNodes;
    var commands;
    var pathArr;
    var singleShape = this.data.singleShape;
    var trackingOffset = documentData.tr * 0.001 * documentData.finalSize;
    var xPos = 0;
    var yPos = 0;
    var firstLine = true;
    var cnt = 0;
    for (i = 0; i < len; i += 1) {
      charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
      shapeData = charData && charData.data || {};
      matrixHelper.reset();
      if (singleShape && letters[i].n) {
        xPos = -trackingOffset;
        yPos += documentData.yOffset;
        yPos += firstLine ? 1 : 0;
        firstLine = false;
      }
      shapes = shapeData.shapes ? shapeData.shapes[0].it : [];
      jLen = shapes.length;
      matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
      if (singleShape) {
        this.applyTextPropertiesToMatrix(documentData, matrixHelper, letters[i].line, xPos, yPos);
      }
      commands = createSizedArray(jLen - 1);
      var commandsCounter = 0;
      for (j = 0; j < jLen; j += 1) {
        if (shapes[j].ty === 'sh') {
          kLen = shapes[j].ks.k.i.length;
          pathNodes = shapes[j].ks.k;
          pathArr = [];
          for (k = 1; k < kLen; k += 1) {
            if (k === 1) {
              pathArr.push(matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
            }
            pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToY(pathNodes.i[k][0], pathNodes.i[k][1], 0), matrixHelper.applyToX(pathNodes.v[k][0], pathNodes.v[k][1], 0), matrixHelper.applyToY(pathNodes.v[k][0], pathNodes.v[k][1], 0));
          }
          pathArr.push(matrixHelper.applyToX(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToY(pathNodes.o[k - 1][0], pathNodes.o[k - 1][1], 0), matrixHelper.applyToX(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToY(pathNodes.i[0][0], pathNodes.i[0][1], 0), matrixHelper.applyToX(pathNodes.v[0][0], pathNodes.v[0][1], 0), matrixHelper.applyToY(pathNodes.v[0][0], pathNodes.v[0][1], 0));
          commands[commandsCounter] = pathArr;
          commandsCounter += 1;
        }
      }
      if (singleShape) {
        xPos += letters[i].l;
        xPos += trackingOffset;
      }
      if (this.textSpans[cnt]) {
        this.textSpans[cnt].elem = commands;
      } else {
        this.textSpans[cnt] = {
          elem: commands
        };
      }
      cnt += 1;
    }
  };
  CVTextElement.prototype.renderInnerContent = function () {
    this.validateText();
    var ctx = this.canvasContext;
    ctx.font = this.values.fValue;
    this.globalData.renderer.ctxLineCap('butt');
    // ctx.lineCap = 'butt';
    this.globalData.renderer.ctxLineJoin('miter');
    // ctx.lineJoin = 'miter';
    this.globalData.renderer.ctxMiterLimit(4);
    // ctx.miterLimit = 4;

    if (!this.data.singleShape) {
      this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
    }
    var i;
    var len;
    var j;
    var jLen;
    var k;
    var kLen;
    var renderedLetters = this.textAnimator.renderedLetters;
    var letters = this.textProperty.currentData.l;
    len = letters.length;
    var renderedLetter;
    var lastFill = null;
    var lastStroke = null;
    var lastStrokeW = null;
    var commands;
    var pathArr;
    var renderer = this.globalData.renderer;
    for (i = 0; i < len; i += 1) {
      if (!letters[i].n) {
        renderedLetter = renderedLetters[i];
        if (renderedLetter) {
          renderer.save();
          renderer.ctxTransform(renderedLetter.p);
          renderer.ctxOpacity(renderedLetter.o);
        }
        if (this.fill) {
          if (renderedLetter && renderedLetter.fc) {
            if (lastFill !== renderedLetter.fc) {
              renderer.ctxFillStyle(renderedLetter.fc);
              lastFill = renderedLetter.fc;
              // ctx.fillStyle = renderedLetter.fc;
            }
          } else if (lastFill !== this.values.fill) {
            lastFill = this.values.fill;
            renderer.ctxFillStyle(this.values.fill);
            // ctx.fillStyle = this.values.fill;
          }
          commands = this.textSpans[i].elem;
          jLen = commands.length;
          this.globalData.canvasContext.beginPath();
          for (j = 0; j < jLen; j += 1) {
            pathArr = commands[j];
            kLen = pathArr.length;
            this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
            for (k = 2; k < kLen; k += 6) {
              this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
            }
          }
          this.globalData.canvasContext.closePath();
          renderer.ctxFill();
          // this.globalData.canvasContext.fill();
          /// ctx.fillText(this.textSpans[i].val,0,0);
        }
        if (this.stroke) {
          if (renderedLetter && renderedLetter.sw) {
            if (lastStrokeW !== renderedLetter.sw) {
              lastStrokeW = renderedLetter.sw;
              renderer.ctxLineWidth(renderedLetter.sw);
              // ctx.lineWidth = renderedLetter.sw;
            }
          } else if (lastStrokeW !== this.values.sWidth) {
            lastStrokeW = this.values.sWidth;
            renderer.ctxLineWidth(this.values.sWidth);
            // ctx.lineWidth = this.values.sWidth;
          }
          if (renderedLetter && renderedLetter.sc) {
            if (lastStroke !== renderedLetter.sc) {
              lastStroke = renderedLetter.sc;
              renderer.ctxStrokeStyle(renderedLetter.sc);
              // ctx.strokeStyle = renderedLetter.sc;
            }
          } else if (lastStroke !== this.values.stroke) {
            lastStroke = this.values.stroke;
            renderer.ctxStrokeStyle(this.values.stroke);
            // ctx.strokeStyle = this.values.stroke;
          }
          commands = this.textSpans[i].elem;
          jLen = commands.length;
          this.globalData.canvasContext.beginPath();
          for (j = 0; j < jLen; j += 1) {
            pathArr = commands[j];
            kLen = pathArr.length;
            this.globalData.canvasContext.moveTo(pathArr[0], pathArr[1]);
            for (k = 2; k < kLen; k += 6) {
              this.globalData.canvasContext.bezierCurveTo(pathArr[k], pathArr[k + 1], pathArr[k + 2], pathArr[k + 3], pathArr[k + 4], pathArr[k + 5]);
            }
          }
          this.globalData.canvasContext.closePath();
          renderer.ctxStroke();
          // this.globalData.canvasContext.stroke();
          /// ctx.strokeText(letters[i].val,0,0);
        }
        if (renderedLetter) {
          this.globalData.renderer.restore();
        }
      }
    }
  };
  function CVImageElement(data, globalData, comp) {
    this.assetData = globalData.getAssetData(data.refId);
    this.img = globalData.imageLoader.getAsset(this.assetData);
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVImageElement);
  CVImageElement.prototype.initElement = SVGShapeElement.prototype.initElement;
  CVImageElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
  CVImageElement.prototype.createContent = function () {
    if (this.img.width && (this.assetData.w !== this.img.width || this.assetData.h !== this.img.height)) {
      var canvas = createTag('canvas');
      canvas.width = this.assetData.w;
      canvas.height = this.assetData.h;
      var ctx = canvas.getContext('2d');
      var imgW = this.img.width;
      var imgH = this.img.height;
      var imgRel = imgW / imgH;
      var canvasRel = this.assetData.w / this.assetData.h;
      var widthCrop;
      var heightCrop;
      var par = this.assetData.pr || this.globalData.renderConfig.imagePreserveAspectRatio;
      if (imgRel > canvasRel && par === 'xMidYMid slice' || imgRel < canvasRel && par !== 'xMidYMid slice') {
        heightCrop = imgH;
        widthCrop = heightCrop * canvasRel;
      } else {
        widthCrop = imgW;
        heightCrop = widthCrop / canvasRel;
      }
      ctx.drawImage(this.img, (imgW - widthCrop) / 2, (imgH - heightCrop) / 2, widthCrop, heightCrop, 0, 0, this.assetData.w, this.assetData.h);
      this.img = canvas;
    }
  };
  CVImageElement.prototype.renderInnerContent = function () {
    this.canvasContext.drawImage(this.img, 0, 0);
  };
  CVImageElement.prototype.destroy = function () {
    this.img = null;
  };
  function CVSolidElement(data, globalData, comp) {
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, CVBaseElement, HierarchyElement, FrameElement, RenderableElement], CVSolidElement);
  CVSolidElement.prototype.initElement = SVGShapeElement.prototype.initElement;
  CVSolidElement.prototype.prepareFrame = IImageElement.prototype.prepareFrame;
  CVSolidElement.prototype.renderInnerContent = function () {
    // var ctx = this.canvasContext;
    this.globalData.renderer.ctxFillStyle(this.data.sc);
    // ctx.fillStyle = this.data.sc;
    this.globalData.renderer.ctxFillRect(0, 0, this.data.sw, this.data.sh);
    // ctx.fillRect(0, 0, this.data.sw, this.data.sh);
    //
  };
  function CanvasRendererBase() {}
  extendPrototype([BaseRenderer], CanvasRendererBase);
  CanvasRendererBase.prototype.createShape = function (data) {
    return new CVShapeElement(data, this.globalData, this);
  };
  CanvasRendererBase.prototype.createText = function (data) {
    return new CVTextElement(data, this.globalData, this);
  };
  CanvasRendererBase.prototype.createImage = function (data) {
    return new CVImageElement(data, this.globalData, this);
  };
  CanvasRendererBase.prototype.createSolid = function (data) {
    return new CVSolidElement(data, this.globalData, this);
  };
  CanvasRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
  CanvasRendererBase.prototype.ctxTransform = function (props) {
    if (props[0] === 1 && props[1] === 0 && props[4] === 0 && props[5] === 1 && props[12] === 0 && props[13] === 0) {
      return;
    }
    this.canvasContext.transform(props[0], props[1], props[4], props[5], props[12], props[13]);
  };
  CanvasRendererBase.prototype.ctxOpacity = function (op) {
    this.canvasContext.globalAlpha *= op < 0 ? 0 : op;
  };
  CanvasRendererBase.prototype.ctxFillStyle = function (value) {
    this.canvasContext.fillStyle = value;
  };
  CanvasRendererBase.prototype.ctxStrokeStyle = function (value) {
    this.canvasContext.strokeStyle = value;
  };
  CanvasRendererBase.prototype.ctxLineWidth = function (value) {
    this.canvasContext.lineWidth = value;
  };
  CanvasRendererBase.prototype.ctxLineCap = function (value) {
    this.canvasContext.lineCap = value;
  };
  CanvasRendererBase.prototype.ctxLineJoin = function (value) {
    this.canvasContext.lineJoin = value;
  };
  CanvasRendererBase.prototype.ctxMiterLimit = function (value) {
    this.canvasContext.miterLimit = value;
  };
  CanvasRendererBase.prototype.ctxFill = function (rule) {
    this.canvasContext.fill(rule);
  };
  CanvasRendererBase.prototype.ctxFillRect = function (x, y, w, h) {
    this.canvasContext.fillRect(x, y, w, h);
  };
  CanvasRendererBase.prototype.ctxStroke = function () {
    this.canvasContext.stroke();
  };
  CanvasRendererBase.prototype.reset = function () {
    if (!this.renderConfig.clearCanvas) {
      this.canvasContext.restore();
      return;
    }
    this.contextData.reset();
  };
  CanvasRendererBase.prototype.save = function () {
    this.canvasContext.save();
  };
  CanvasRendererBase.prototype.restore = function (actionFlag) {
    if (!this.renderConfig.clearCanvas) {
      this.canvasContext.restore();
      return;
    }
    if (actionFlag) {
      this.globalData.blendMode = 'source-over';
    }
    this.contextData.restore(actionFlag);
  };
  CanvasRendererBase.prototype.configAnimation = function (animData) {
    if (this.animationItem.wrapper) {
      this.animationItem.container = createTag('canvas');
      var containerStyle = this.animationItem.container.style;
      containerStyle.width = '100%';
      containerStyle.height = '100%';
      var origin = '0px 0px 0px';
      containerStyle.transformOrigin = origin;
      containerStyle.mozTransformOrigin = origin;
      containerStyle.webkitTransformOrigin = origin;
      containerStyle['-webkit-transform'] = origin;
      containerStyle.contentVisibility = this.renderConfig.contentVisibility;
      this.animationItem.wrapper.appendChild(this.animationItem.container);
      this.canvasContext = this.animationItem.container.getContext('2d');
      if (this.renderConfig.className) {
        this.animationItem.container.setAttribute('class', this.renderConfig.className);
      }
      if (this.renderConfig.id) {
        this.animationItem.container.setAttribute('id', this.renderConfig.id);
      }
    } else {
      this.canvasContext = this.renderConfig.context;
    }
    this.contextData.setContext(this.canvasContext);
    this.data = animData;
    this.layers = animData.layers;
    this.transformCanvas = {
      w: animData.w,
      h: animData.h,
      sx: 0,
      sy: 0,
      tx: 0,
      ty: 0
    };
    this.setupGlobalData(animData, document.body);
    this.globalData.canvasContext = this.canvasContext;
    this.globalData.renderer = this;
    this.globalData.isDashed = false;
    this.globalData.progressiveLoad = this.renderConfig.progressiveLoad;
    this.globalData.transformCanvas = this.transformCanvas;
    this.elements = createSizedArray(animData.layers.length);
    this.updateContainerSize();
  };
  CanvasRendererBase.prototype.updateContainerSize = function (width, height) {
    this.reset();
    var elementWidth;
    var elementHeight;
    if (width) {
      elementWidth = width;
      elementHeight = height;
      this.canvasContext.canvas.width = elementWidth;
      this.canvasContext.canvas.height = elementHeight;
    } else {
      if (this.animationItem.wrapper && this.animationItem.container) {
        elementWidth = this.animationItem.wrapper.offsetWidth;
        elementHeight = this.animationItem.wrapper.offsetHeight;
      } else {
        elementWidth = this.canvasContext.canvas.width;
        elementHeight = this.canvasContext.canvas.height;
      }
      this.canvasContext.canvas.width = elementWidth * this.renderConfig.dpr;
      this.canvasContext.canvas.height = elementHeight * this.renderConfig.dpr;
    }
    var elementRel;
    var animationRel;
    if (this.renderConfig.preserveAspectRatio.indexOf('meet') !== -1 || this.renderConfig.preserveAspectRatio.indexOf('slice') !== -1) {
      var par = this.renderConfig.preserveAspectRatio.split(' ');
      var fillType = par[1] || 'meet';
      var pos = par[0] || 'xMidYMid';
      var xPos = pos.substr(0, 4);
      var yPos = pos.substr(4);
      elementRel = elementWidth / elementHeight;
      animationRel = this.transformCanvas.w / this.transformCanvas.h;
      if (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice') {
        this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
        this.transformCanvas.sy = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
      } else {
        this.transformCanvas.sx = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
        this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
      }
      if (xPos === 'xMid' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
        this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) / 2 * this.renderConfig.dpr;
      } else if (xPos === 'xMax' && (animationRel < elementRel && fillType === 'meet' || animationRel > elementRel && fillType === 'slice')) {
        this.transformCanvas.tx = (elementWidth - this.transformCanvas.w * (elementHeight / this.transformCanvas.h)) * this.renderConfig.dpr;
      } else {
        this.transformCanvas.tx = 0;
      }
      if (yPos === 'YMid' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
        this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) / 2 * this.renderConfig.dpr;
      } else if (yPos === 'YMax' && (animationRel > elementRel && fillType === 'meet' || animationRel < elementRel && fillType === 'slice')) {
        this.transformCanvas.ty = (elementHeight - this.transformCanvas.h * (elementWidth / this.transformCanvas.w)) * this.renderConfig.dpr;
      } else {
        this.transformCanvas.ty = 0;
      }
    } else if (this.renderConfig.preserveAspectRatio === 'none') {
      this.transformCanvas.sx = elementWidth / (this.transformCanvas.w / this.renderConfig.dpr);
      this.transformCanvas.sy = elementHeight / (this.transformCanvas.h / this.renderConfig.dpr);
      this.transformCanvas.tx = 0;
      this.transformCanvas.ty = 0;
    } else {
      this.transformCanvas.sx = this.renderConfig.dpr;
      this.transformCanvas.sy = this.renderConfig.dpr;
      this.transformCanvas.tx = 0;
      this.transformCanvas.ty = 0;
    }
    this.transformCanvas.props = [this.transformCanvas.sx, 0, 0, 0, 0, this.transformCanvas.sy, 0, 0, 0, 0, 1, 0, this.transformCanvas.tx, this.transformCanvas.ty, 0, 1];
    /* var i, len = this.elements.length;
      for(i=0;i<len;i+=1){
          if(this.elements[i] && this.elements[i].data.ty === 0){
              this.elements[i].resize(this.globalData.transformCanvas);
          }
      } */
    this.ctxTransform(this.transformCanvas.props);
    this.canvasContext.beginPath();
    this.canvasContext.rect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
    this.canvasContext.closePath();
    this.canvasContext.clip();
    this.renderFrame(this.renderedFrame, true);
  };
  CanvasRendererBase.prototype.destroy = function () {
    if (this.renderConfig.clearCanvas && this.animationItem.wrapper) {
      this.animationItem.wrapper.innerText = '';
    }
    var i;
    var len = this.layers ? this.layers.length : 0;
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.elements[i] && this.elements[i].destroy) {
        this.elements[i].destroy();
      }
    }
    this.elements.length = 0;
    this.globalData.canvasContext = null;
    this.animationItem.container = null;
    this.destroyed = true;
  };
  CanvasRendererBase.prototype.renderFrame = function (num, forceRender) {
    if (this.renderedFrame === num && this.renderConfig.clearCanvas === true && !forceRender || this.destroyed || num === -1) {
      return;
    }
    this.renderedFrame = num;
    this.globalData.frameNum = num - this.animationItem._isFirstFrame;
    this.globalData.frameId += 1;
    this.globalData._mdf = !this.renderConfig.clearCanvas || forceRender;
    this.globalData.projectInterface.currentFrame = num;

    // console.log('--------');
    // console.log('NEW: ',num);
    var i;
    var len = this.layers.length;
    if (!this.completeLayers) {
      this.checkLayers(num);
    }
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.completeLayers || this.elements[i]) {
        this.elements[i].prepareFrame(num - this.layers[i].st);
      }
    }
    if (this.globalData._mdf) {
      if (this.renderConfig.clearCanvas === true) {
        this.canvasContext.clearRect(0, 0, this.transformCanvas.w, this.transformCanvas.h);
      } else {
        this.save();
      }
      for (i = len - 1; i >= 0; i -= 1) {
        if (this.completeLayers || this.elements[i]) {
          this.elements[i].renderFrame();
        }
      }
      if (this.renderConfig.clearCanvas !== true) {
        this.restore();
      }
    }
  };
  CanvasRendererBase.prototype.buildItem = function (pos) {
    var elements = this.elements;
    if (elements[pos] || this.layers[pos].ty === 99) {
      return;
    }
    var element = this.createItem(this.layers[pos], this, this.globalData);
    elements[pos] = element;
    element.initExpressions();
    /* if(this.layers[pos].ty === 0){
          element.resize(this.globalData.transformCanvas);
      } */
  };
  CanvasRendererBase.prototype.checkPendingElements = function () {
    while (this.pendingElements.length) {
      var element = this.pendingElements.pop();
      element.checkParenting();
    }
  };
  CanvasRendererBase.prototype.hide = function () {
    this.animationItem.container.style.display = 'none';
  };
  CanvasRendererBase.prototype.show = function () {
    this.animationItem.container.style.display = 'block';
  };
  function CanvasContext() {
    this.opacity = -1;
    this.transform = createTypedArray('float32', 16);
    this.fillStyle = '';
    this.strokeStyle = '';
    this.lineWidth = '';
    this.lineCap = '';
    this.lineJoin = '';
    this.miterLimit = '';
    this.id = Math.random();
  }
  function CVContextData() {
    this.stack = [];
    this.cArrPos = 0;
    this.cTr = new Matrix();
    var i;
    var len = 15;
    for (i = 0; i < len; i += 1) {
      var canvasContext = new CanvasContext();
      this.stack[i] = canvasContext;
    }
    this._length = len;
    this.nativeContext = null;
    this.transformMat = new Matrix();
    this.currentOpacity = 1;
    //
    this.currentFillStyle = '';
    this.appliedFillStyle = '';
    //
    this.currentStrokeStyle = '';
    this.appliedStrokeStyle = '';
    //
    this.currentLineWidth = '';
    this.appliedLineWidth = '';
    //
    this.currentLineCap = '';
    this.appliedLineCap = '';
    //
    this.currentLineJoin = '';
    this.appliedLineJoin = '';
    //
    this.appliedMiterLimit = '';
    this.currentMiterLimit = '';
  }
  CVContextData.prototype.duplicate = function () {
    var newLength = this._length * 2;
    var i = 0;
    for (i = this._length; i < newLength; i += 1) {
      this.stack[i] = new CanvasContext();
    }
    this._length = newLength;
  };
  CVContextData.prototype.reset = function () {
    this.cArrPos = 0;
    this.cTr.reset();
    this.stack[this.cArrPos].opacity = 1;
  };
  CVContextData.prototype.restore = function (forceRestore) {
    this.cArrPos -= 1;
    var currentContext = this.stack[this.cArrPos];
    var transform = currentContext.transform;
    var i;
    var arr = this.cTr.props;
    for (i = 0; i < 16; i += 1) {
      arr[i] = transform[i];
    }
    if (forceRestore) {
      this.nativeContext.restore();
      var prevStack = this.stack[this.cArrPos + 1];
      this.appliedFillStyle = prevStack.fillStyle;
      this.appliedStrokeStyle = prevStack.strokeStyle;
      this.appliedLineWidth = prevStack.lineWidth;
      this.appliedLineCap = prevStack.lineCap;
      this.appliedLineJoin = prevStack.lineJoin;
      this.appliedMiterLimit = prevStack.miterLimit;
    }
    this.nativeContext.setTransform(transform[0], transform[1], transform[4], transform[5], transform[12], transform[13]);
    if (forceRestore || currentContext.opacity !== -1 && this.currentOpacity !== currentContext.opacity) {
      this.nativeContext.globalAlpha = currentContext.opacity;
      this.currentOpacity = currentContext.opacity;
    }
    this.currentFillStyle = currentContext.fillStyle;
    this.currentStrokeStyle = currentContext.strokeStyle;
    this.currentLineWidth = currentContext.lineWidth;
    this.currentLineCap = currentContext.lineCap;
    this.currentLineJoin = currentContext.lineJoin;
    this.currentMiterLimit = currentContext.miterLimit;
  };
  CVContextData.prototype.save = function (saveOnNativeFlag) {
    if (saveOnNativeFlag) {
      this.nativeContext.save();
    }
    var props = this.cTr.props;
    if (this._length <= this.cArrPos) {
      this.duplicate();
    }
    var currentStack = this.stack[this.cArrPos];
    var i;
    for (i = 0; i < 16; i += 1) {
      currentStack.transform[i] = props[i];
    }
    this.cArrPos += 1;
    var newStack = this.stack[this.cArrPos];
    newStack.opacity = currentStack.opacity;
    newStack.fillStyle = currentStack.fillStyle;
    newStack.strokeStyle = currentStack.strokeStyle;
    newStack.lineWidth = currentStack.lineWidth;
    newStack.lineCap = currentStack.lineCap;
    newStack.lineJoin = currentStack.lineJoin;
    newStack.miterLimit = currentStack.miterLimit;
  };
  CVContextData.prototype.setOpacity = function (value) {
    this.stack[this.cArrPos].opacity = value;
  };
  CVContextData.prototype.setContext = function (value) {
    this.nativeContext = value;
  };
  CVContextData.prototype.fillStyle = function (value) {
    if (this.stack[this.cArrPos].fillStyle !== value) {
      this.currentFillStyle = value;
      this.stack[this.cArrPos].fillStyle = value;
    }
  };
  CVContextData.prototype.strokeStyle = function (value) {
    if (this.stack[this.cArrPos].strokeStyle !== value) {
      this.currentStrokeStyle = value;
      this.stack[this.cArrPos].strokeStyle = value;
    }
  };
  CVContextData.prototype.lineWidth = function (value) {
    if (this.stack[this.cArrPos].lineWidth !== value) {
      this.currentLineWidth = value;
      this.stack[this.cArrPos].lineWidth = value;
    }
  };
  CVContextData.prototype.lineCap = function (value) {
    if (this.stack[this.cArrPos].lineCap !== value) {
      this.currentLineCap = value;
      this.stack[this.cArrPos].lineCap = value;
    }
  };
  CVContextData.prototype.lineJoin = function (value) {
    if (this.stack[this.cArrPos].lineJoin !== value) {
      this.currentLineJoin = value;
      this.stack[this.cArrPos].lineJoin = value;
    }
  };
  CVContextData.prototype.miterLimit = function (value) {
    if (this.stack[this.cArrPos].miterLimit !== value) {
      this.currentMiterLimit = value;
      this.stack[this.cArrPos].miterLimit = value;
    }
  };
  CVContextData.prototype.transform = function (props) {
    this.transformMat.cloneFromProps(props);
    // Taking the last transform value from the stored stack of transforms
    var currentTransform = this.cTr;
    // Applying the last transform value after the new transform to respect the order of transformations
    this.transformMat.multiply(currentTransform);
    // Storing the new transformed value in the stored transform
    currentTransform.cloneFromProps(this.transformMat.props);
    var trProps = currentTransform.props;
    // Applying the new transform to the canvas
    this.nativeContext.setTransform(trProps[0], trProps[1], trProps[4], trProps[5], trProps[12], trProps[13]);
  };
  CVContextData.prototype.opacity = function (op) {
    var currentOpacity = this.stack[this.cArrPos].opacity;
    currentOpacity *= op < 0 ? 0 : op;
    if (this.stack[this.cArrPos].opacity !== currentOpacity) {
      if (this.currentOpacity !== op) {
        this.nativeContext.globalAlpha = op;
        this.currentOpacity = op;
      }
      this.stack[this.cArrPos].opacity = currentOpacity;
    }
  };
  CVContextData.prototype.fill = function (rule) {
    if (this.appliedFillStyle !== this.currentFillStyle) {
      this.appliedFillStyle = this.currentFillStyle;
      this.nativeContext.fillStyle = this.appliedFillStyle;
    }
    this.nativeContext.fill(rule);
  };
  CVContextData.prototype.fillRect = function (x, y, w, h) {
    if (this.appliedFillStyle !== this.currentFillStyle) {
      this.appliedFillStyle = this.currentFillStyle;
      this.nativeContext.fillStyle = this.appliedFillStyle;
    }
    this.nativeContext.fillRect(x, y, w, h);
  };
  CVContextData.prototype.stroke = function () {
    if (this.appliedStrokeStyle !== this.currentStrokeStyle) {
      this.appliedStrokeStyle = this.currentStrokeStyle;
      this.nativeContext.strokeStyle = this.appliedStrokeStyle;
    }
    if (this.appliedLineWidth !== this.currentLineWidth) {
      this.appliedLineWidth = this.currentLineWidth;
      this.nativeContext.lineWidth = this.appliedLineWidth;
    }
    if (this.appliedLineCap !== this.currentLineCap) {
      this.appliedLineCap = this.currentLineCap;
      this.nativeContext.lineCap = this.appliedLineCap;
    }
    if (this.appliedLineJoin !== this.currentLineJoin) {
      this.appliedLineJoin = this.currentLineJoin;
      this.nativeContext.lineJoin = this.appliedLineJoin;
    }
    if (this.appliedMiterLimit !== this.currentMiterLimit) {
      this.appliedMiterLimit = this.currentMiterLimit;
      this.nativeContext.miterLimit = this.appliedMiterLimit;
    }
    this.nativeContext.stroke();
  };
  function CVCompElement(data, globalData, comp) {
    this.completeLayers = false;
    this.layers = data.layers;
    this.pendingElements = [];
    this.elements = createSizedArray(this.layers.length);
    this.initElement(data, globalData, comp);
    this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : {
      _placeholder: true
    };
  }
  extendPrototype([CanvasRendererBase, ICompElement, CVBaseElement], CVCompElement);
  CVCompElement.prototype.renderInnerContent = function () {
    var ctx = this.canvasContext;
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(this.data.w, 0);
    ctx.lineTo(this.data.w, this.data.h);
    ctx.lineTo(0, this.data.h);
    ctx.lineTo(0, 0);
    ctx.clip();
    var i;
    var len = this.layers.length;
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.completeLayers || this.elements[i]) {
        this.elements[i].renderFrame();
      }
    }
  };
  CVCompElement.prototype.destroy = function () {
    var i;
    var len = this.layers.length;
    for (i = len - 1; i >= 0; i -= 1) {
      if (this.elements[i]) {
        this.elements[i].destroy();
      }
    }
    this.layers = null;
    this.elements = null;
  };
  CVCompElement.prototype.createComp = function (data) {
    return new CVCompElement(data, this.globalData, this);
  };
  function CanvasRenderer(animationItem, config) {
    this.animationItem = animationItem;
    this.renderConfig = {
      clearCanvas: config && config.clearCanvas !== undefined ? config.clearCanvas : true,
      context: config && config.context || null,
      progressiveLoad: config && config.progressiveLoad || false,
      preserveAspectRatio: config && config.preserveAspectRatio || 'xMidYMid meet',
      imagePreserveAspectRatio: config && config.imagePreserveAspectRatio || 'xMidYMid slice',
      contentVisibility: config && config.contentVisibility || 'visible',
      className: config && config.className || '',
      id: config && config.id || '',
      runExpressions: !config || config.runExpressions === undefined || config.runExpressions
    };
    this.renderConfig.dpr = config && config.dpr || 1;
    if (this.animationItem.wrapper) {
      this.renderConfig.dpr = config && config.dpr || window.devicePixelRatio || 1;
    }
    this.renderedFrame = -1;
    this.globalData = {
      frameNum: -1,
      _mdf: false,
      renderConfig: this.renderConfig,
      currentGlobalAlpha: -1
    };
    this.contextData = new CVContextData();
    this.elements = [];
    this.pendingElements = [];
    this.transformMat = new Matrix();
    this.completeLayers = false;
    this.rendererType = 'canvas';
    if (this.renderConfig.clearCanvas) {
      this.ctxTransform = this.contextData.transform.bind(this.contextData);
      this.ctxOpacity = this.contextData.opacity.bind(this.contextData);
      this.ctxFillStyle = this.contextData.fillStyle.bind(this.contextData);
      this.ctxStrokeStyle = this.contextData.strokeStyle.bind(this.contextData);
      this.ctxLineWidth = this.contextData.lineWidth.bind(this.contextData);
      this.ctxLineCap = this.contextData.lineCap.bind(this.contextData);
      this.ctxLineJoin = this.contextData.lineJoin.bind(this.contextData);
      this.ctxMiterLimit = this.contextData.miterLimit.bind(this.contextData);
      this.ctxFill = this.contextData.fill.bind(this.contextData);
      this.ctxFillRect = this.contextData.fillRect.bind(this.contextData);
      this.ctxStroke = this.contextData.stroke.bind(this.contextData);
      this.save = this.contextData.save.bind(this.contextData);
    }
  }
  extendPrototype([CanvasRendererBase], CanvasRenderer);
  CanvasRenderer.prototype.createComp = function (data) {
    return new CVCompElement(data, this.globalData, this);
  };
  function HBaseElement() {}
  HBaseElement.prototype = {
    checkBlendMode: function checkBlendMode() {},
    initRendererElement: function initRendererElement() {
      this.baseElement = createTag(this.data.tg || 'div');
      if (this.data.hasMask) {
        this.svgElement = createNS('svg');
        this.layerElement = createNS('g');
        this.maskedElement = this.layerElement;
        this.svgElement.appendChild(this.layerElement);
        this.baseElement.appendChild(this.svgElement);
      } else {
        this.layerElement = this.baseElement;
      }
      styleDiv(this.baseElement);
    },
    createContainerElements: function createContainerElements() {
      this.renderableEffectsManager = new CVEffects(this);
      this.transformedElement = this.baseElement;
      this.maskedElement = this.layerElement;
      if (this.data.ln) {
        this.layerElement.setAttribute('id', this.data.ln);
      }
      if (this.data.cl) {
        this.layerElement.setAttribute('class', this.data.cl);
      }
      if (this.data.bm !== 0) {
        this.setBlendMode();
      }
    },
    renderElement: function renderElement() {
      var transformedElementStyle = this.transformedElement ? this.transformedElement.style : {};
      if (this.finalTransform._matMdf) {
        var matrixValue = this.finalTransform.mat.toCSS();
        transformedElementStyle.transform = matrixValue;
        transformedElementStyle.webkitTransform = matrixValue;
      }
      if (this.finalTransform._opMdf) {
        transformedElementStyle.opacity = this.finalTransform.mProp.o.v;
      }
    },
    renderFrame: function renderFrame() {
      // If it is exported as hidden (data.hd === true) no need to render
      // If it is not visible no need to render
      if (this.data.hd || this.hidden) {
        return;
      }
      this.renderTransform();
      this.renderRenderable();
      this.renderElement();
      this.renderInnerContent();
      if (this._isFirstFrame) {
        this._isFirstFrame = false;
      }
    },
    destroy: function destroy() {
      this.layerElement = null;
      this.transformedElement = null;
      if (this.matteElement) {
        this.matteElement = null;
      }
      if (this.maskManager) {
        this.maskManager.destroy();
        this.maskManager = null;
      }
    },
    createRenderableComponents: function createRenderableComponents() {
      this.maskManager = new MaskElement(this.data, this, this.globalData);
    },
    addEffects: function addEffects() {},
    setMatte: function setMatte() {}
  };
  HBaseElement.prototype.getBaseElement = SVGBaseElement.prototype.getBaseElement;
  HBaseElement.prototype.destroyBaseElement = HBaseElement.prototype.destroy;
  HBaseElement.prototype.buildElementParenting = BaseRenderer.prototype.buildElementParenting;
  function HSolidElement(data, globalData, comp) {
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement], HSolidElement);
  HSolidElement.prototype.createContent = function () {
    var rect;
    if (this.data.hasMask) {
      rect = createNS('rect');
      rect.setAttribute('width', this.data.sw);
      rect.setAttribute('height', this.data.sh);
      rect.setAttribute('fill', this.data.sc);
      this.svgElement.setAttribute('width', this.data.sw);
      this.svgElement.setAttribute('height', this.data.sh);
    } else {
      rect = createTag('div');
      rect.style.width = this.data.sw + 'px';
      rect.style.height = this.data.sh + 'px';
      rect.style.backgroundColor = this.data.sc;
    }
    this.layerElement.appendChild(rect);
  };
  function HShapeElement(data, globalData, comp) {
    // List of drawable elements
    this.shapes = [];
    // Full shape data
    this.shapesData = data.shapes;
    // List of styles that will be applied to shapes
    this.stylesList = [];
    // List of modifiers that will be applied to shapes
    this.shapeModifiers = [];
    // List of items in shape tree
    this.itemsData = [];
    // List of items in previous shape tree
    this.processedElements = [];
    // List of animated components
    this.animatedContents = [];
    this.shapesContainer = createNS('g');
    this.initElement(data, globalData, comp);
    // Moving any property that doesn't get too much access after initialization because of v8 way of handling more than 10 properties.
    // List of elements that have been created
    this.prevViewData = [];
    this.currentBBox = {
      x: 999999,
      y: -999999,
      h: 0,
      w: 0
    };
  }
  extendPrototype([BaseElement, TransformElement, HSolidElement, SVGShapeElement, HBaseElement, HierarchyElement, FrameElement, RenderableElement], HShapeElement);
  HShapeElement.prototype._renderShapeFrame = HShapeElement.prototype.renderInnerContent;
  HShapeElement.prototype.createContent = function () {
    var cont;
    this.baseElement.style.fontSize = 0;
    if (this.data.hasMask) {
      this.layerElement.appendChild(this.shapesContainer);
      cont = this.svgElement;
    } else {
      cont = createNS('svg');
      var size = this.comp.data ? this.comp.data : this.globalData.compSize;
      cont.setAttribute('width', size.w);
      cont.setAttribute('height', size.h);
      cont.appendChild(this.shapesContainer);
      this.layerElement.appendChild(cont);
    }
    this.searchShapes(this.shapesData, this.itemsData, this.prevViewData, this.shapesContainer, 0, [], true);
    this.filterUniqueShapes();
    this.shapeCont = cont;
  };
  HShapeElement.prototype.getTransformedPoint = function (transformers, point) {
    var i;
    var len = transformers.length;
    for (i = 0; i < len; i += 1) {
      point = transformers[i].mProps.v.applyToPointArray(point[0], point[1], 0);
    }
    return point;
  };
  HShapeElement.prototype.calculateShapeBoundingBox = function (item, boundingBox) {
    var shape = item.sh.v;
    var transformers = item.transformers;
    var i;
    var len = shape._length;
    var vPoint;
    var oPoint;
    var nextIPoint;
    var nextVPoint;
    if (len <= 1) {
      return;
    }
    for (i = 0; i < len - 1; i += 1) {
      vPoint = this.getTransformedPoint(transformers, shape.v[i]);
      oPoint = this.getTransformedPoint(transformers, shape.o[i]);
      nextIPoint = this.getTransformedPoint(transformers, shape.i[i + 1]);
      nextVPoint = this.getTransformedPoint(transformers, shape.v[i + 1]);
      this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
    }
    if (shape.c) {
      vPoint = this.getTransformedPoint(transformers, shape.v[i]);
      oPoint = this.getTransformedPoint(transformers, shape.o[i]);
      nextIPoint = this.getTransformedPoint(transformers, shape.i[0]);
      nextVPoint = this.getTransformedPoint(transformers, shape.v[0]);
      this.checkBounds(vPoint, oPoint, nextIPoint, nextVPoint, boundingBox);
    }
  };
  HShapeElement.prototype.checkBounds = function (vPoint, oPoint, nextIPoint, nextVPoint, boundingBox) {
    this.getBoundsOfCurve(vPoint, oPoint, nextIPoint, nextVPoint);
    var bounds = this.shapeBoundingBox;
    boundingBox.x = bmMin(bounds.left, boundingBox.x);
    boundingBox.xMax = bmMax(bounds.right, boundingBox.xMax);
    boundingBox.y = bmMin(bounds.top, boundingBox.y);
    boundingBox.yMax = bmMax(bounds.bottom, boundingBox.yMax);
  };
  HShapeElement.prototype.shapeBoundingBox = {
    left: 0,
    right: 0,
    top: 0,
    bottom: 0
  };
  HShapeElement.prototype.tempBoundingBox = {
    x: 0,
    xMax: 0,
    y: 0,
    yMax: 0,
    width: 0,
    height: 0
  };
  HShapeElement.prototype.getBoundsOfCurve = function (p0, p1, p2, p3) {
    var bounds = [[p0[0], p3[0]], [p0[1], p3[1]]];
    for (var a, b, c, t, b2ac, t1, t2, i = 0; i < 2; ++i) {
      // eslint-disable-line no-plusplus
      b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];
      a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];
      c = 3 * p1[i] - 3 * p0[i];
      b |= 0; // eslint-disable-line no-bitwise
      a |= 0; // eslint-disable-line no-bitwise
      c |= 0; // eslint-disable-line no-bitwise

      if (a === 0 && b === 0) {
        //
      } else if (a === 0) {
        t = -c / b;
        if (t > 0 && t < 1) {
          bounds[i].push(this.calculateF(t, p0, p1, p2, p3, i));
        }
      } else {
        b2ac = b * b - 4 * c * a;
        if (b2ac >= 0) {
          t1 = (-b + bmSqrt(b2ac)) / (2 * a);
          if (t1 > 0 && t1 < 1) bounds[i].push(this.calculateF(t1, p0, p1, p2, p3, i));
          t2 = (-b - bmSqrt(b2ac)) / (2 * a);
          if (t2 > 0 && t2 < 1) bounds[i].push(this.calculateF(t2, p0, p1, p2, p3, i));
        }
      }
    }
    this.shapeBoundingBox.left = bmMin.apply(null, bounds[0]);
    this.shapeBoundingBox.top = bmMin.apply(null, bounds[1]);
    this.shapeBoundingBox.right = bmMax.apply(null, bounds[0]);
    this.shapeBoundingBox.bottom = bmMax.apply(null, bounds[1]);
  };
  HShapeElement.prototype.calculateF = function (t, p0, p1, p2, p3, i) {
    return bmPow(1 - t, 3) * p0[i] + 3 * bmPow(1 - t, 2) * t * p1[i] + 3 * (1 - t) * bmPow(t, 2) * p2[i] + bmPow(t, 3) * p3[i];
  };
  HShapeElement.prototype.calculateBoundingBox = function (itemsData, boundingBox) {
    var i;
    var len = itemsData.length;
    for (i = 0; i < len; i += 1) {
      if (itemsData[i] && itemsData[i].sh) {
        this.calculateShapeBoundingBox(itemsData[i], boundingBox);
      } else if (itemsData[i] && itemsData[i].it) {
        this.calculateBoundingBox(itemsData[i].it, boundingBox);
      } else if (itemsData[i] && itemsData[i].style && itemsData[i].w) {
        this.expandStrokeBoundingBox(itemsData[i].w, boundingBox);
      }
    }
  };
  HShapeElement.prototype.expandStrokeBoundingBox = function (widthProperty, boundingBox) {
    var width = 0;
    if (widthProperty.keyframes) {
      for (var i = 0; i < widthProperty.keyframes.length; i += 1) {
        var kfw = widthProperty.keyframes[i].s;
        if (kfw > width) {
          width = kfw;
        }
      }
      width *= widthProperty.mult;
    } else {
      width = widthProperty.v * widthProperty.mult;
    }
    boundingBox.x -= width;
    boundingBox.xMax += width;
    boundingBox.y -= width;
    boundingBox.yMax += width;
  };
  HShapeElement.prototype.currentBoxContains = function (box) {
    return this.currentBBox.x <= box.x && this.currentBBox.y <= box.y && this.currentBBox.width + this.currentBBox.x >= box.x + box.width && this.currentBBox.height + this.currentBBox.y >= box.y + box.height;
  };
  HShapeElement.prototype.renderInnerContent = function () {
    this._renderShapeFrame();
    if (!this.hidden && (this._isFirstFrame || this._mdf)) {
      var tempBoundingBox = this.tempBoundingBox;
      var max = 999999;
      tempBoundingBox.x = max;
      tempBoundingBox.xMax = -max;
      tempBoundingBox.y = max;
      tempBoundingBox.yMax = -max;
      this.calculateBoundingBox(this.itemsData, tempBoundingBox);
      tempBoundingBox.width = tempBoundingBox.xMax < tempBoundingBox.x ? 0 : tempBoundingBox.xMax - tempBoundingBox.x;
      tempBoundingBox.height = tempBoundingBox.yMax < tempBoundingBox.y ? 0 : tempBoundingBox.yMax - tempBoundingBox.y;
      // var tempBoundingBox = this.shapeCont.getBBox();
      if (this.currentBoxContains(tempBoundingBox)) {
        return;
      }
      var changed = false;
      if (this.currentBBox.w !== tempBoundingBox.width) {
        this.currentBBox.w = tempBoundingBox.width;
        this.shapeCont.setAttribute('width', tempBoundingBox.width);
        changed = true;
      }
      if (this.currentBBox.h !== tempBoundingBox.height) {
        this.currentBBox.h = tempBoundingBox.height;
        this.shapeCont.setAttribute('height', tempBoundingBox.height);
        changed = true;
      }
      if (changed || this.currentBBox.x !== tempBoundingBox.x || this.currentBBox.y !== tempBoundingBox.y) {
        this.currentBBox.w = tempBoundingBox.width;
        this.currentBBox.h = tempBoundingBox.height;
        this.currentBBox.x = tempBoundingBox.x;
        this.currentBBox.y = tempBoundingBox.y;
        this.shapeCont.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
        var shapeStyle = this.shapeCont.style;
        var shapeTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
        shapeStyle.transform = shapeTransform;
        shapeStyle.webkitTransform = shapeTransform;
      }
    }
  };
  function HTextElement(data, globalData, comp) {
    this.textSpans = [];
    this.textPaths = [];
    this.currentBBox = {
      x: 999999,
      y: -999999,
      h: 0,
      w: 0
    };
    this.renderType = 'svg';
    this.isMasked = false;
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement, RenderableDOMElement, ITextElement], HTextElement);
  HTextElement.prototype.createContent = function () {
    this.isMasked = this.checkMasks();
    if (this.isMasked) {
      this.renderType = 'svg';
      this.compW = this.comp.data.w;
      this.compH = this.comp.data.h;
      this.svgElement.setAttribute('width', this.compW);
      this.svgElement.setAttribute('height', this.compH);
      var g = createNS('g');
      this.maskedElement.appendChild(g);
      this.innerElem = g;
    } else {
      this.renderType = 'html';
      this.innerElem = this.layerElement;
    }
    this.checkParenting();
  };
  HTextElement.prototype.buildNewText = function () {
    var documentData = this.textProperty.currentData;
    this.renderedLetters = createSizedArray(documentData.l ? documentData.l.length : 0);
    var innerElemStyle = this.innerElem.style;
    var textColor = documentData.fc ? this.buildColor(documentData.fc) : 'rgba(0,0,0,0)';
    innerElemStyle.fill = textColor;
    innerElemStyle.color = textColor;
    if (documentData.sc) {
      innerElemStyle.stroke = this.buildColor(documentData.sc);
      innerElemStyle.strokeWidth = documentData.sw + 'px';
    }
    var fontData = this.globalData.fontManager.getFontByName(documentData.f);
    if (!this.globalData.fontManager.chars) {
      innerElemStyle.fontSize = documentData.finalSize + 'px';
      innerElemStyle.lineHeight = documentData.finalSize + 'px';
      if (fontData.fClass) {
        this.innerElem.className = fontData.fClass;
      } else {
        innerElemStyle.fontFamily = fontData.fFamily;
        var fWeight = documentData.fWeight;
        var fStyle = documentData.fStyle;
        innerElemStyle.fontStyle = fStyle;
        innerElemStyle.fontWeight = fWeight;
      }
    }
    var i;
    var len;
    var letters = documentData.l;
    len = letters.length;
    var tSpan;
    var tParent;
    var tCont;
    var matrixHelper = this.mHelper;
    var shapes;
    var shapeStr = '';
    var cnt = 0;
    for (i = 0; i < len; i += 1) {
      if (this.globalData.fontManager.chars) {
        if (!this.textPaths[cnt]) {
          tSpan = createNS('path');
          tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
          tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
          tSpan.setAttribute('stroke-miterlimit', '4');
        } else {
          tSpan = this.textPaths[cnt];
        }
        if (!this.isMasked) {
          if (this.textSpans[cnt]) {
            tParent = this.textSpans[cnt];
            tCont = tParent.children[0];
          } else {
            tParent = createTag('div');
            tParent.style.lineHeight = 0;
            tCont = createNS('svg');
            tCont.appendChild(tSpan);
            styleDiv(tParent);
          }
        }
      } else if (!this.isMasked) {
        if (this.textSpans[cnt]) {
          tParent = this.textSpans[cnt];
          tSpan = this.textPaths[cnt];
        } else {
          tParent = createTag('span');
          styleDiv(tParent);
          tSpan = createTag('span');
          styleDiv(tSpan);
          tParent.appendChild(tSpan);
        }
      } else {
        tSpan = this.textPaths[cnt] ? this.textPaths[cnt] : createNS('text');
      }
      // tSpan.setAttribute('visibility', 'hidden');
      if (this.globalData.fontManager.chars) {
        var charData = this.globalData.fontManager.getCharData(documentData.finalText[i], fontData.fStyle, this.globalData.fontManager.getFontByName(documentData.f).fFamily);
        var shapeData;
        if (charData) {
          shapeData = charData.data;
        } else {
          shapeData = null;
        }
        matrixHelper.reset();
        if (shapeData && shapeData.shapes && shapeData.shapes.length) {
          shapes = shapeData.shapes[0].it;
          matrixHelper.scale(documentData.finalSize / 100, documentData.finalSize / 100);
          shapeStr = this.createPathShape(matrixHelper, shapes);
          tSpan.setAttribute('d', shapeStr);
        }
        if (!this.isMasked) {
          this.innerElem.appendChild(tParent);
          if (shapeData && shapeData.shapes) {
            // document.body.appendChild is needed to get exact measure of shape
            document.body.appendChild(tCont);
            var boundingBox = tCont.getBBox();
            tCont.setAttribute('width', boundingBox.width + 2);
            tCont.setAttribute('height', boundingBox.height + 2);
            tCont.setAttribute('viewBox', boundingBox.x - 1 + ' ' + (boundingBox.y - 1) + ' ' + (boundingBox.width + 2) + ' ' + (boundingBox.height + 2));
            var tContStyle = tCont.style;
            var tContTranslation = 'translate(' + (boundingBox.x - 1) + 'px,' + (boundingBox.y - 1) + 'px)';
            tContStyle.transform = tContTranslation;
            tContStyle.webkitTransform = tContTranslation;
            letters[i].yOffset = boundingBox.y - 1;
          } else {
            tCont.setAttribute('width', 1);
            tCont.setAttribute('height', 1);
          }
          tParent.appendChild(tCont);
        } else {
          this.innerElem.appendChild(tSpan);
        }
      } else {
        tSpan.textContent = letters[i].val;
        tSpan.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
        if (!this.isMasked) {
          this.innerElem.appendChild(tParent);
          //
          var tStyle = tSpan.style;
          var tSpanTranslation = 'translate3d(0,' + -documentData.finalSize / 1.2 + 'px,0)';
          tStyle.transform = tSpanTranslation;
          tStyle.webkitTransform = tSpanTranslation;
        } else {
          this.innerElem.appendChild(tSpan);
        }
      }
      //
      if (!this.isMasked) {
        this.textSpans[cnt] = tParent;
      } else {
        this.textSpans[cnt] = tSpan;
      }
      this.textSpans[cnt].style.display = 'block';
      this.textPaths[cnt] = tSpan;
      cnt += 1;
    }
    while (cnt < this.textSpans.length) {
      this.textSpans[cnt].style.display = 'none';
      cnt += 1;
    }
  };
  HTextElement.prototype.renderInnerContent = function () {
    this.validateText();
    var svgStyle;
    if (this.data.singleShape) {
      if (!this._isFirstFrame && !this.lettersChangedFlag) {
        return;
      }
      if (this.isMasked && this.finalTransform._matMdf) {
        // Todo Benchmark if using this is better than getBBox
        this.svgElement.setAttribute('viewBox', -this.finalTransform.mProp.p.v[0] + ' ' + -this.finalTransform.mProp.p.v[1] + ' ' + this.compW + ' ' + this.compH);
        svgStyle = this.svgElement.style;
        var translation = 'translate(' + -this.finalTransform.mProp.p.v[0] + 'px,' + -this.finalTransform.mProp.p.v[1] + 'px)';
        svgStyle.transform = translation;
        svgStyle.webkitTransform = translation;
      }
    }
    this.textAnimator.getMeasures(this.textProperty.currentData, this.lettersChangedFlag);
    if (!this.lettersChangedFlag && !this.textAnimator.lettersChangedFlag) {
      return;
    }
    var i;
    var len;
    var count = 0;
    var renderedLetters = this.textAnimator.renderedLetters;
    var letters = this.textProperty.currentData.l;
    len = letters.length;
    var renderedLetter;
    var textSpan;
    var textPath;
    for (i = 0; i < len; i += 1) {
      if (letters[i].n) {
        count += 1;
      } else {
        textSpan = this.textSpans[i];
        textPath = this.textPaths[i];
        renderedLetter = renderedLetters[count];
        count += 1;
        if (renderedLetter._mdf.m) {
          if (!this.isMasked) {
            textSpan.style.webkitTransform = renderedLetter.m;
            textSpan.style.transform = renderedLetter.m;
          } else {
            textSpan.setAttribute('transform', renderedLetter.m);
          }
        }
        /// /textSpan.setAttribute('opacity',renderedLetter.o);
        textSpan.style.opacity = renderedLetter.o;
        if (renderedLetter.sw && renderedLetter._mdf.sw) {
          textPath.setAttribute('stroke-width', renderedLetter.sw);
        }
        if (renderedLetter.sc && renderedLetter._mdf.sc) {
          textPath.setAttribute('stroke', renderedLetter.sc);
        }
        if (renderedLetter.fc && renderedLetter._mdf.fc) {
          textPath.setAttribute('fill', renderedLetter.fc);
          textPath.style.color = renderedLetter.fc;
        }
      }
    }
    if (this.innerElem.getBBox && !this.hidden && (this._isFirstFrame || this._mdf)) {
      var boundingBox = this.innerElem.getBBox();
      if (this.currentBBox.w !== boundingBox.width) {
        this.currentBBox.w = boundingBox.width;
        this.svgElement.setAttribute('width', boundingBox.width);
      }
      if (this.currentBBox.h !== boundingBox.height) {
        this.currentBBox.h = boundingBox.height;
        this.svgElement.setAttribute('height', boundingBox.height);
      }
      var margin = 1;
      if (this.currentBBox.w !== boundingBox.width + margin * 2 || this.currentBBox.h !== boundingBox.height + margin * 2 || this.currentBBox.x !== boundingBox.x - margin || this.currentBBox.y !== boundingBox.y - margin) {
        this.currentBBox.w = boundingBox.width + margin * 2;
        this.currentBBox.h = boundingBox.height + margin * 2;
        this.currentBBox.x = boundingBox.x - margin;
        this.currentBBox.y = boundingBox.y - margin;
        this.svgElement.setAttribute('viewBox', this.currentBBox.x + ' ' + this.currentBBox.y + ' ' + this.currentBBox.w + ' ' + this.currentBBox.h);
        svgStyle = this.svgElement.style;
        var svgTransform = 'translate(' + this.currentBBox.x + 'px,' + this.currentBBox.y + 'px)';
        svgStyle.transform = svgTransform;
        svgStyle.webkitTransform = svgTransform;
      }
    }
  };
  function HCameraElement(data, globalData, comp) {
    this.initFrame();
    this.initBaseData(data, globalData, comp);
    this.initHierarchy();
    var getProp = PropertyFactory.getProp;
    this.pe = getProp(this, data.pe, 0, 0, this);
    if (data.ks.p.s) {
      this.px = getProp(this, data.ks.p.x, 1, 0, this);
      this.py = getProp(this, data.ks.p.y, 1, 0, this);
      this.pz = getProp(this, data.ks.p.z, 1, 0, this);
    } else {
      this.p = getProp(this, data.ks.p, 1, 0, this);
    }
    if (data.ks.a) {
      this.a = getProp(this, data.ks.a, 1, 0, this);
    }
    if (data.ks.or.k.length && data.ks.or.k[0].to) {
      var i;
      var len = data.ks.or.k.length;
      for (i = 0; i < len; i += 1) {
        data.ks.or.k[i].to = null;
        data.ks.or.k[i].ti = null;
      }
    }
    this.or = getProp(this, data.ks.or, 1, degToRads, this);
    this.or.sh = true;
    this.rx = getProp(this, data.ks.rx, 0, degToRads, this);
    this.ry = getProp(this, data.ks.ry, 0, degToRads, this);
    this.rz = getProp(this, data.ks.rz, 0, degToRads, this);
    this.mat = new Matrix();
    this._prevMat = new Matrix();
    this._isFirstFrame = true;

    // TODO: find a better way to make the HCamera element to be compatible with the LayerInterface and TransformInterface.
    this.finalTransform = {
      mProp: this
    };
  }
  extendPrototype([BaseElement, FrameElement, HierarchyElement], HCameraElement);
  HCameraElement.prototype.setup = function () {
    var i;
    var len = this.comp.threeDElements.length;
    var comp;
    var perspectiveStyle;
    var containerStyle;
    for (i = 0; i < len; i += 1) {
      // [perspectiveElem,container]
      comp = this.comp.threeDElements[i];
      if (comp.type === '3d') {
        perspectiveStyle = comp.perspectiveElem.style;
        containerStyle = comp.container.style;
        var perspective = this.pe.v + 'px';
        var origin = '0px 0px 0px';
        var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
        perspectiveStyle.perspective = perspective;
        perspectiveStyle.webkitPerspective = perspective;
        containerStyle.transformOrigin = origin;
        containerStyle.mozTransformOrigin = origin;
        containerStyle.webkitTransformOrigin = origin;
        perspectiveStyle.transform = matrix;
        perspectiveStyle.webkitTransform = matrix;
      }
    }
  };
  HCameraElement.prototype.createElements = function () {};
  HCameraElement.prototype.hide = function () {};
  HCameraElement.prototype.renderFrame = function () {
    var _mdf = this._isFirstFrame;
    var i;
    var len;
    if (this.hierarchy) {
      len = this.hierarchy.length;
      for (i = 0; i < len; i += 1) {
        _mdf = this.hierarchy[i].finalTransform.mProp._mdf || _mdf;
      }
    }
    if (_mdf || this.pe._mdf || this.p && this.p._mdf || this.px && (this.px._mdf || this.py._mdf || this.pz._mdf) || this.rx._mdf || this.ry._mdf || this.rz._mdf || this.or._mdf || this.a && this.a._mdf) {
      this.mat.reset();
      if (this.hierarchy) {
        len = this.hierarchy.length - 1;
        for (i = len; i >= 0; i -= 1) {
          var mTransf = this.hierarchy[i].finalTransform.mProp;
          this.mat.translate(-mTransf.p.v[0], -mTransf.p.v[1], mTransf.p.v[2]);
          this.mat.rotateX(-mTransf.or.v[0]).rotateY(-mTransf.or.v[1]).rotateZ(mTransf.or.v[2]);
          this.mat.rotateX(-mTransf.rx.v).rotateY(-mTransf.ry.v).rotateZ(mTransf.rz.v);
          this.mat.scale(1 / mTransf.s.v[0], 1 / mTransf.s.v[1], 1 / mTransf.s.v[2]);
          this.mat.translate(mTransf.a.v[0], mTransf.a.v[1], mTransf.a.v[2]);
        }
      }
      if (this.p) {
        this.mat.translate(-this.p.v[0], -this.p.v[1], this.p.v[2]);
      } else {
        this.mat.translate(-this.px.v, -this.py.v, this.pz.v);
      }
      if (this.a) {
        var diffVector;
        if (this.p) {
          diffVector = [this.p.v[0] - this.a.v[0], this.p.v[1] - this.a.v[1], this.p.v[2] - this.a.v[2]];
        } else {
          diffVector = [this.px.v - this.a.v[0], this.py.v - this.a.v[1], this.pz.v - this.a.v[2]];
        }
        var mag = Math.sqrt(Math.pow(diffVector[0], 2) + Math.pow(diffVector[1], 2) + Math.pow(diffVector[2], 2));
        // var lookDir = getNormalizedPoint(getDiffVector(this.a.v,this.p.v));
        var lookDir = [diffVector[0] / mag, diffVector[1] / mag, diffVector[2] / mag];
        var lookLengthOnXZ = Math.sqrt(lookDir[2] * lookDir[2] + lookDir[0] * lookDir[0]);
        var mRotationX = Math.atan2(lookDir[1], lookLengthOnXZ);
        var mRotationY = Math.atan2(lookDir[0], -lookDir[2]);
        this.mat.rotateY(mRotationY).rotateX(-mRotationX);
      }
      this.mat.rotateX(-this.rx.v).rotateY(-this.ry.v).rotateZ(this.rz.v);
      this.mat.rotateX(-this.or.v[0]).rotateY(-this.or.v[1]).rotateZ(this.or.v[2]);
      this.mat.translate(this.globalData.compSize.w / 2, this.globalData.compSize.h / 2, 0);
      this.mat.translate(0, 0, this.pe.v);
      var hasMatrixChanged = !this._prevMat.equals(this.mat);
      if ((hasMatrixChanged || this.pe._mdf) && this.comp.threeDElements) {
        len = this.comp.threeDElements.length;
        var comp;
        var perspectiveStyle;
        var containerStyle;
        for (i = 0; i < len; i += 1) {
          comp = this.comp.threeDElements[i];
          if (comp.type === '3d') {
            if (hasMatrixChanged) {
              var matValue = this.mat.toCSS();
              containerStyle = comp.container.style;
              containerStyle.transform = matValue;
              containerStyle.webkitTransform = matValue;
            }
            if (this.pe._mdf) {
              perspectiveStyle = comp.perspectiveElem.style;
              perspectiveStyle.perspective = this.pe.v + 'px';
              perspectiveStyle.webkitPerspective = this.pe.v + 'px';
            }
          }
        }
        this.mat.clone(this._prevMat);
      }
    }
    this._isFirstFrame = false;
  };
  HCameraElement.prototype.prepareFrame = function (num) {
    this.prepareProperties(num, true);
  };
  HCameraElement.prototype.destroy = function () {};
  HCameraElement.prototype.getBaseElement = function () {
    return null;
  };
  function HImageElement(data, globalData, comp) {
    this.assetData = globalData.getAssetData(data.refId);
    this.initElement(data, globalData, comp);
  }
  extendPrototype([BaseElement, TransformElement, HBaseElement, HSolidElement, HierarchyElement, FrameElement, RenderableElement], HImageElement);
  HImageElement.prototype.createContent = function () {
    var assetPath = this.globalData.getAssetsPath(this.assetData);
    var img = new Image();
    if (this.data.hasMask) {
      this.imageElem = createNS('image');
      this.imageElem.setAttribute('width', this.assetData.w + 'px');
      this.imageElem.setAttribute('height', this.assetData.h + 'px');
      this.imageElem.setAttributeNS('http://www.w3.org/1999/xlink', 'href', assetPath);
      this.layerElement.appendChild(this.imageElem);
      this.baseElement.setAttribute('width', this.assetData.w);
      this.baseElement.setAttribute('height', this.assetData.h);
    } else {
      this.layerElement.appendChild(img);
    }
    img.crossOrigin = 'anonymous';
    img.src = assetPath;
    if (this.data.ln) {
      this.baseElement.setAttribute('id', this.data.ln);
    }
  };
  function HybridRendererBase(animationItem, config) {
    this.animationItem = animationItem;
    this.layers = null;
    this.renderedFrame = -1;
    this.renderConfig = {
      className: config && config.className || '',
      imagePreserveAspectRatio: config && config.imagePreserveAspectRatio || 'xMidYMid slice',
      hideOnTransparent: !(config && config.hideOnTransparent === false),
      filterSize: {
        width: config && config.filterSize && config.filterSize.width || '400%',
        height: config && config.filterSize && config.filterSize.height || '400%',
        x: config && config.filterSize && config.filterSize.x || '-100%',
        y: config && config.filterSize && config.filterSize.y || '-100%'
      }
    };
    this.globalData = {
      _mdf: false,
      frameNum: -1,
      renderConfig: this.renderConfig
    };
    this.pendingElements = [];
    this.elements = [];
    this.threeDElements = [];
    this.destroyed = false;
    this.camera = null;
    this.supports3d = true;
    this.rendererType = 'html';
  }
  extendPrototype([BaseRenderer], HybridRendererBase);
  HybridRendererBase.prototype.buildItem = SVGRenderer.prototype.buildItem;
  HybridRendererBase.prototype.checkPendingElements = function () {
    while (this.pendingElements.length) {
      var element = this.pendingElements.pop();
      element.checkParenting();
    }
  };
  HybridRendererBase.prototype.appendElementInPos = function (element, pos) {
    var newDOMElement = element.getBaseElement();
    if (!newDOMElement) {
      return;
    }
    var layer = this.layers[pos];
    if (!layer.ddd || !this.supports3d) {
      if (this.threeDElements) {
        this.addTo3dContainer(newDOMElement, pos);
      } else {
        var i = 0;
        var nextDOMElement;
        var nextLayer;
        var tmpDOMElement;
        while (i < pos) {
          if (this.elements[i] && this.elements[i] !== true && this.elements[i].getBaseElement) {
            nextLayer = this.elements[i];
            tmpDOMElement = this.layers[i].ddd ? this.getThreeDContainerByPos(i) : nextLayer.getBaseElement();
            nextDOMElement = tmpDOMElement || nextDOMElement;
          }
          i += 1;
        }
        if (nextDOMElement) {
          if (!layer.ddd || !this.supports3d) {
            this.layerElement.insertBefore(newDOMElement, nextDOMElement);
          }
        } else if (!layer.ddd || !this.supports3d) {
          this.layerElement.appendChild(newDOMElement);
        }
      }
    } else {
      this.addTo3dContainer(newDOMElement, pos);
    }
  };
  HybridRendererBase.prototype.createShape = function (data) {
    if (!this.supports3d) {
      return new SVGShapeElement(data, this.globalData, this);
    }
    return new HShapeElement(data, this.globalData, this);
  };
  HybridRendererBase.prototype.createText = function (data) {
    if (!this.supports3d) {
      return new SVGTextLottieElement(data, this.globalData, this);
    }
    return new HTextElement(data, this.globalData, this);
  };
  HybridRendererBase.prototype.createCamera = function (data) {
    this.camera = new HCameraElement(data, this.globalData, this);
    return this.camera;
  };
  HybridRendererBase.prototype.createImage = function (data) {
    if (!this.supports3d) {
      return new IImageElement(data, this.globalData, this);
    }
    return new HImageElement(data, this.globalData, this);
  };
  HybridRendererBase.prototype.createSolid = function (data) {
    if (!this.supports3d) {
      return new ISolidElement(data, this.globalData, this);
    }
    return new HSolidElement(data, this.globalData, this);
  };
  HybridRendererBase.prototype.createNull = SVGRenderer.prototype.createNull;
  HybridRendererBase.prototype.getThreeDContainerByPos = function (pos) {
    var i = 0;
    var len = this.threeDElements.length;
    while (i < len) {
      if (this.threeDElements[i].startPos <= pos && this.threeDElements[i].endPos >= pos) {
        return this.threeDElements[i].perspectiveElem;
      }
      i += 1;
    }
    return null;
  };
  HybridRendererBase.prototype.createThreeDContainer = function (pos, type) {
    var perspectiveElem = createTag('div');
    var style;
    var containerStyle;
    styleDiv(perspectiveElem);
    var container = createTag('div');
    styleDiv(container);
    if (type === '3d') {
      style = perspectiveElem.style;
      style.width = this.globalData.compSize.w + 'px';
      style.height = this.globalData.compSize.h + 'px';
      var center = '50% 50%';
      style.webkitTransformOrigin = center;
      style.mozTransformOrigin = center;
      style.transformOrigin = center;
      containerStyle = container.style;
      var matrix = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
      containerStyle.transform = matrix;
      containerStyle.webkitTransform = matrix;
    }
    perspectiveElem.appendChild(container);
    // this.resizerElem.appendChild(perspectiveElem);
    var threeDContainerData = {
      container: container,
      perspectiveElem: perspectiveElem,
      startPos: pos,
      endPos: pos,
      type: type
    };
    this.threeDElements.push(threeDContainerData);
    return threeDContainerData;
  };
  HybridRendererBase.prototype.build3dContainers = function () {
    var i;
    var len = this.layers.length;
    var lastThreeDContainerData;
    var currentContainer = '';
    for (i = 0; i < len; i += 1) {
      if (this.layers[i].ddd && this.layers[i].ty !== 3) {
        if (currentContainer !== '3d') {
          currentContainer = '3d';
          lastThreeDContainerData = this.createThreeDContainer(i, '3d');
        }
        lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos, i);
      } else {
        if (currentContainer !== '2d') {
          currentContainer = '2d';
          lastThreeDContainerData = this.createThreeDContainer(i, '2d');
        }
        lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos, i);
      }
    }
    len = this.threeDElements.length;
    for (i = len - 1; i >= 0; i -= 1) {
      this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
    }
  };
  HybridRendererBase.prototype.addTo3dContainer = function (elem, pos) {
    var i = 0;
    var len = this.threeDElements.length;
    while (i < len) {
      if (pos <= this.threeDElements[i].endPos) {
        var j = this.threeDElements[i].startPos;
        var nextElement;
        while (j < pos) {
          if (this.elements[j] && this.elements[j].getBaseElement) {
            nextElement = this.elements[j].getBaseElement();
          }
          j += 1;
        }
        if (nextElement) {
          this.threeDElements[i].container.insertBefore(elem, nextElement);
        } else {
          this.threeDElements[i].container.appendChild(elem);
        }
        break;
      }
      i += 1;
    }
  };
  HybridRendererBase.prototype.configAnimation = function (animData) {
    var resizerElem = createTag('div');
    var wrapper = this.animationItem.wrapper;
    var style = resizerElem.style;
    style.width = animData.w + 'px';
    style.height = animData.h + 'px';
    this.resizerElem = resizerElem;
    styleDiv(resizerElem);
    style.transformStyle = 'flat';
    style.mozTransformStyle = 'flat';
    style.webkitTransformStyle = 'flat';
    if (this.renderConfig.className) {
      resizerElem.setAttribute('class', this.renderConfig.className);
    }
    wrapper.appendChild(resizerElem);
    style.overflow = 'hidden';
    var svg = createNS('svg');
    svg.setAttribute('width', '1');
    svg.setAttribute('height', '1');
    styleDiv(svg);
    this.resizerElem.appendChild(svg);
    var defs = createNS('defs');
    svg.appendChild(defs);
    this.data = animData;
    // Mask animation
    this.setupGlobalData(animData, svg);
    this.globalData.defs = defs;
    this.layers = animData.layers;
    this.layerElement = this.resizerElem;
    this.build3dContainers();
    this.updateContainerSize();
  };
  HybridRendererBase.prototype.destroy = function () {
    if (this.animationItem.wrapper) {
      this.animationItem.wrapper.innerText = '';
    }
    this.animationItem.container = null;
    this.globalData.defs = null;
    var i;
    var len = this.layers ? this.layers.length : 0;
    for (i = 0; i < len; i += 1) {
      if (this.elements[i] && this.elements[i].destroy) {
        this.elements[i].destroy();
      }
    }
    this.elements.length = 0;
    this.destroyed = true;
    this.animationItem = null;
  };
  HybridRendererBase.prototype.updateContainerSize = function () {
    var elementWidth = this.animationItem.wrapper.offsetWidth;
    var elementHeight = this.animationItem.wrapper.offsetHeight;
    var elementRel = elementWidth / elementHeight;
    var animationRel = this.globalData.compSize.w / this.globalData.compSize.h;
    var sx;
    var sy;
    var tx;
    var ty;
    if (animationRel > elementRel) {
      sx = elementWidth / this.globalData.compSize.w;
      sy = elementWidth / this.globalData.compSize.w;
      tx = 0;
      ty = (elementHeight - this.globalData.compSize.h * (elementWidth / this.globalData.compSize.w)) / 2;
    } else {
      sx = elementHeight / this.globalData.compSize.h;
      sy = elementHeight / this.globalData.compSize.h;
      tx = (elementWidth - this.globalData.compSize.w * (elementHeight / this.globalData.compSize.h)) / 2;
      ty = 0;
    }
    var style = this.resizerElem.style;
    style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,' + sy + ',0,0,0,0,1,0,' + tx + ',' + ty + ',0,1)';
    style.transform = style.webkitTransform;
  };
  HybridRendererBase.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
  HybridRendererBase.prototype.hide = function () {
    this.resizerElem.style.display = 'none';
  };
  HybridRendererBase.prototype.show = function () {
    this.resizerElem.style.display = 'block';
  };
  HybridRendererBase.prototype.initItems = function () {
    this.buildAllItems();
    if (this.camera) {
      this.camera.setup();
    } else {
      var cWidth = this.globalData.compSize.w;
      var cHeight = this.globalData.compSize.h;
      var i;
      var len = this.threeDElements.length;
      for (i = 0; i < len; i += 1) {
        var style = this.threeDElements[i].perspectiveElem.style;
        style.webkitPerspective = Math.sqrt(Math.pow(cWidth, 2) + Math.pow(cHeight, 2)) + 'px';
        style.perspective = style.webkitPerspective;
      }
    }
  };
  HybridRendererBase.prototype.searchExtraCompositions = function (assets) {
    var i;
    var len = assets.length;
    var floatingContainer = createTag('div');
    for (i = 0; i < len; i += 1) {
      if (assets[i].xt) {
        var comp = this.createComp(assets[i], floatingContainer, this.globalData.comp, null);
        comp.initExpressions();
        this.globalData.projectInterface.registerComposition(comp);
      }
    }
  };
  function HCompElement(data, globalData, comp) {
    this.layers = data.layers;
    this.supports3d = !data.hasMask;
    this.completeLayers = false;
    this.pendingElements = [];
    this.elements = this.layers ? createSizedArray(this.layers.length) : [];
    this.initElement(data, globalData, comp);
    this.tm = data.tm ? PropertyFactory.getProp(this, data.tm, 0, globalData.frameRate, this) : {
      _placeholder: true
    };
  }
  extendPrototype([HybridRendererBase, ICompElement, HBaseElement], HCompElement);
  HCompElement.prototype._createBaseContainerElements = HCompElement.prototype.createContainerElements;
  HCompElement.prototype.createContainerElements = function () {
    this._createBaseContainerElements();
    // divElement.style.clip = 'rect(0px, '+this.data.w+'px, '+this.data.h+'px, 0px)';
    if (this.data.hasMask) {
      this.svgElement.setAttribute('width', this.data.w);
      this.svgElement.setAttribute('height', this.data.h);
      this.transformedElement = this.baseElement;
    } else {
      this.transformedElement = this.layerElement;
    }
  };
  HCompElement.prototype.addTo3dContainer = function (elem, pos) {
    var j = 0;
    var nextElement;
    while (j < pos) {
      if (this.elements[j] && this.elements[j].getBaseElement) {
        nextElement = this.elements[j].getBaseElement();
      }
      j += 1;
    }
    if (nextElement) {
      this.layerElement.insertBefore(elem, nextElement);
    } else {
      this.layerElement.appendChild(elem);
    }
  };
  HCompElement.prototype.createComp = function (data) {
    if (!this.supports3d) {
      return new SVGCompElement(data, this.globalData, this);
    }
    return new HCompElement(data, this.globalData, this);
  };
  function HybridRenderer(animationItem, config) {
    this.animationItem = animationItem;
    this.layers = null;
    this.renderedFrame = -1;
    this.renderConfig = {
      className: config && config.className || '',
      imagePreserveAspectRatio: config && config.imagePreserveAspectRatio || 'xMidYMid slice',
      hideOnTransparent: !(config && config.hideOnTransparent === false),
      filterSize: {
        width: config && config.filterSize && config.filterSize.width || '400%',
        height: config && config.filterSize && config.filterSize.height || '400%',
        x: config && config.filterSize && config.filterSize.x || '-100%',
        y: config && config.filterSize && config.filterSize.y || '-100%'
      },
      runExpressions: !config || config.runExpressions === undefined || config.runExpressions
    };
    this.globalData = {
      _mdf: false,
      frameNum: -1,
      renderConfig: this.renderConfig
    };
    this.pendingElements = [];
    this.elements = [];
    this.threeDElements = [];
    this.destroyed = false;
    this.camera = null;
    this.supports3d = true;
    this.rendererType = 'html';
  }
  extendPrototype([HybridRendererBase], HybridRenderer);
  HybridRenderer.prototype.createComp = function (data) {
    if (!this.supports3d) {
      return new SVGCompElement(data, this.globalData, this);
    }
    return new HCompElement(data, this.globalData, this);
  };
  var CompExpressionInterface = function () {
    return function (comp) {
      function _thisLayerFunction(name) {
        var i = 0;
        var len = comp.layers.length;
        while (i < len) {
          if (comp.layers[i].nm === name || comp.layers[i].ind === name) {
            return comp.elements[i].layerInterface;
          }
          i += 1;
        }
        return null;
        // return {active:false};
      }
      Object.defineProperty(_thisLayerFunction, '_name', {
        value: comp.data.nm
      });
      _thisLayerFunction.layer = _thisLayerFunction;
      _thisLayerFunction.pixelAspect = 1;
      _thisLayerFunction.height = comp.data.h || comp.globalData.compSize.h;
      _thisLayerFunction.width = comp.data.w || comp.globalData.compSize.w;
      _thisLayerFunction.pixelAspect = 1;
      _thisLayerFunction.frameDuration = 1 / comp.globalData.frameRate;
      _thisLayerFunction.displayStartTime = 0;
      _thisLayerFunction.numLayers = comp.layers.length;
      return _thisLayerFunction;
    };
  }();
  function _typeof$2(o) {
    "@babel/helpers - typeof";

    return _typeof$2 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$2(o);
  }
  /* eslint-disable */
  /*
   Copyright 2014 David Bau.
    Permission is hereby granted, free of charge, to any person obtaining
   a copy of this software and associated documentation files (the
   "Software"), to deal in the Software without restriction, including
   without limitation the rights to use, copy, modify, merge, publish,
   distribute, sublicense, and/or sell copies of the Software, and to
   permit persons to whom the Software is furnished to do so, subject to
   the following conditions:
    The above copyright notice and this permission notice shall be
   included in all copies or substantial portions of the Software.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
   MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
   CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
   TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
   SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    */

  function seedRandom(pool, math) {
    //
    // The following constants are related to IEEE 754 limits.
    //
    var global = this,
      width = 256,
      // each RC4 output is 0 <= x < 256
      chunks = 6,
      // at least six RC4 outputs for each double
      digits = 52,
      // there are 52 significant digits in a double
      rngname = 'random',
      // rngname: name for Math.random and Math.seedrandom
      startdenom = math.pow(width, chunks),
      significance = math.pow(2, digits),
      overflow = significance * 2,
      mask = width - 1,
      nodecrypto; // node.js crypto module, initialized at the bottom.

    //
    // seedrandom()
    // This is the seedrandom function described above.
    //
    function seedrandom(seed, options, callback) {
      var key = [];
      options = options === true ? {
        entropy: true
      } : options || {};

      // Flatten the seed string or build one from local entropy if needed.
      var shortseed = mixkey(flatten(options.entropy ? [seed, tostring(pool)] : seed === null ? autoseed() : seed, 3), key);

      // Use the seed to initialize an ARC4 generator.
      var arc4 = new ARC4(key);

      // This function returns a random double in [0, 1) that contains
      // randomness in every bit of the mantissa of the IEEE 754 value.
      var prng = function prng() {
        var n = arc4.g(chunks),
          // Start with a numerator n < 2 ^ 48
          d = startdenom,
          //   and denominator d = 2 ^ 48.
          x = 0; //   and no 'extra last byte'.
        while (n < significance) {
          // Fill up all significant digits by
          n = (n + x) * width; //   shifting numerator and
          d *= width; //   denominator and generating a
          x = arc4.g(1); //   new least-significant-byte.
        }
        while (n >= overflow) {
          // To avoid rounding up, before adding
          n /= 2; //   last byte, shift everything
          d /= 2; //   right using integer math until
          x >>>= 1; //   we have exactly the desired bits.
        }
        return (n + x) / d; // Form the number within [0, 1).
      };
      prng.int32 = function () {
        return arc4.g(4) | 0;
      };
      prng.quick = function () {
        return arc4.g(4) / 0x100000000;
      };
      prng["double"] = prng;

      // Mix the randomness into accumulated entropy.
      mixkey(tostring(arc4.S), pool);

      // Calling convention: what to return as a function of prng, seed, is_math.
      return (options.pass || callback || function (prng, seed, is_math_call, state) {
        if (state) {
          // Load the arc4 state from the given state if it has an S array.
          if (state.S) {
            copy(state, arc4);
          }
          // Only provide the .state method if requested via options.state.
          prng.state = function () {
            return copy(arc4, {});
          };
        }

        // If called as a method of Math (Math.seedrandom()), mutate
        // Math.random because that is how seedrandom.js has worked since v1.0.
        if (is_math_call) {
          math[rngname] = prng;
          return seed;
        }

        // Otherwise, it is a newer calling convention, so return the
        // prng directly.
        else return prng;
      })(prng, shortseed, 'global' in options ? options.global : this == math, options.state);
    }
    math['seed' + rngname] = seedrandom;

    //
    // ARC4
    //
    // An ARC4 implementation.  The constructor takes a key in the form of
    // an array of at most (width) integers that should be 0 <= x < (width).
    //
    // The g(count) method returns a pseudorandom integer that concatenates
    // the next (count) outputs from ARC4.  Its return value is a number x
    // that is in the range 0 <= x < (width ^ count).
    //
    function ARC4(key) {
      var t,
        keylen = key.length,
        me = this,
        i = 0,
        j = me.i = me.j = 0,
        s = me.S = [];

      // The empty key [] is treated as [0].
      if (!keylen) {
        key = [keylen++];
      }

      // Set up S using the standard key scheduling algorithm.
      while (i < width) {
        s[i] = i++;
      }
      for (i = 0; i < width; i++) {
        s[i] = s[j = mask & j + key[i % keylen] + (t = s[i])];
        s[j] = t;
      }

      // The "g" method returns the next (count) outputs as one number.
      me.g = function (count) {
        // Using instance members instead of closure state nearly doubles speed.
        var t,
          r = 0,
          i = me.i,
          j = me.j,
          s = me.S;
        while (count--) {
          t = s[i = mask & i + 1];
          r = r * width + s[mask & (s[i] = s[j = mask & j + t]) + (s[j] = t)];
        }
        me.i = i;
        me.j = j;
        return r;
        // For robust unpredictability, the function call below automatically
        // discards an initial batch of values.  This is called RC4-drop[256].
        // See http://google.com/search?q=rsa+fluhrer+response&btnI
      };
    }

    //
    // copy()
    // Copies internal state of ARC4 to or from a plain object.
    //
    function copy(f, t) {
      t.i = f.i;
      t.j = f.j;
      t.S = f.S.slice();
      return t;
    }

    //
    // flatten()
    // Converts an object tree to nested arrays of strings.
    //
    function flatten(obj, depth) {
      var result = [],
        typ = _typeof$2(obj),
        prop;
      if (depth && typ == 'object') {
        for (prop in obj) {
          try {
            result.push(flatten(obj[prop], depth - 1));
          } catch (e) {}
        }
      }
      return result.length ? result : typ == 'string' ? obj : obj + '\0';
    }

    //
    // mixkey()
    // Mixes a string seed into a key that is an array of integers, and
    // returns a shortened string seed that is equivalent to the result key.
    //
    function mixkey(seed, key) {
      var stringseed = seed + '',
        smear,
        j = 0;
      while (j < stringseed.length) {
        key[mask & j] = mask & (smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++);
      }
      return tostring(key);
    }

    //
    // autoseed()
    // Returns an object for autoseeding, using window.crypto and Node crypto
    // module if available.
    //
    function autoseed() {
      try {
        if (nodecrypto) {
          return tostring(nodecrypto.randomBytes(width));
        }
        var out = new Uint8Array(width);
        (global.crypto || global.msCrypto).getRandomValues(out);
        return tostring(out);
      } catch (e) {
        var browser = global.navigator,
          plugins = browser && browser.plugins;
        return [+new Date(), global, plugins, global.screen, tostring(pool)];
      }
    }

    //
    // tostring()
    // Converts an array of charcodes to a string
    //
    function tostring(a) {
      return String.fromCharCode.apply(0, a);
    }

    //
    // When seedrandom.js is loaded, we immediately mix a few bits
    // from the built-in RNG into the entropy pool.  Because we do
    // not want to interfere with deterministic PRNG state later,
    // seedrandom will not call math.random on its own again after
    // initialization.
    //
    mixkey(math.random(), pool);

    //
    // Nodejs and AMD support: export the implementation as a module using
    // either convention.
    //

    // End anonymous scope, and pass initial values.
  }
  ;
  function initialize$2(BMMath) {
    seedRandom([], BMMath);
  }
  var propTypes = {
    SHAPE: 'shape'
  };
  function _typeof$1(o) {
    "@babel/helpers - typeof";

    return _typeof$1 = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof$1(o);
  }
  var ExpressionManager = function () {
    'use strict';

    var ob = {};
    var Math = BMMath;
    var window = null;
    var document = null;
    var XMLHttpRequest = null;
    var fetch = null;
    var frames = null;
    var _lottieGlobal = {};
    initialize$2(BMMath);
    function resetFrame() {
      _lottieGlobal = {};
    }
    function $bm_isInstanceOfArray(arr) {
      return arr.constructor === Array || arr.constructor === Float32Array;
    }
    function isNumerable(tOfV, v) {
      return tOfV === 'number' || v instanceof Number || tOfV === 'boolean' || tOfV === 'string';
    }
    function $bm_neg(a) {
      var tOfA = _typeof$1(a);
      if (tOfA === 'number' || a instanceof Number || tOfA === 'boolean') {
        return -a;
      }
      if ($bm_isInstanceOfArray(a)) {
        var i;
        var lenA = a.length;
        var retArr = [];
        for (i = 0; i < lenA; i += 1) {
          retArr[i] = -a[i];
        }
        return retArr;
      }
      if (a.propType) {
        return a.v;
      }
      return -a;
    }
    var easeInBez = BezierFactory.getBezierEasing(0.333, 0, 0.833, 0.833, 'easeIn').get;
    var easeOutBez = BezierFactory.getBezierEasing(0.167, 0.167, 0.667, 1, 'easeOut').get;
    var easeInOutBez = BezierFactory.getBezierEasing(0.33, 0, 0.667, 1, 'easeInOut').get;
    function sum(a, b) {
      var tOfA = _typeof$1(a);
      var tOfB = _typeof$1(b);
      if (isNumerable(tOfA, a) && isNumerable(tOfB, b) || tOfA === 'string' || tOfB === 'string') {
        return a + b;
      }
      if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
        a = a.slice(0);
        a[0] += b;
        return a;
      }
      if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
        b = b.slice(0);
        b[0] = a + b[0];
        return b;
      }
      if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
        var i = 0;
        var lenA = a.length;
        var lenB = b.length;
        var retArr = [];
        while (i < lenA || i < lenB) {
          if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
            retArr[i] = a[i] + b[i];
          } else {
            retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
          }
          i += 1;
        }
        return retArr;
      }
      return 0;
    }
    var add = sum;
    function sub(a, b) {
      var tOfA = _typeof$1(a);
      var tOfB = _typeof$1(b);
      if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
        if (tOfA === 'string') {
          a = parseInt(a, 10);
        }
        if (tOfB === 'string') {
          b = parseInt(b, 10);
        }
        return a - b;
      }
      if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
        a = a.slice(0);
        a[0] -= b;
        return a;
      }
      if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
        b = b.slice(0);
        b[0] = a - b[0];
        return b;
      }
      if ($bm_isInstanceOfArray(a) && $bm_isInstanceOfArray(b)) {
        var i = 0;
        var lenA = a.length;
        var lenB = b.length;
        var retArr = [];
        while (i < lenA || i < lenB) {
          if ((typeof a[i] === 'number' || a[i] instanceof Number) && (typeof b[i] === 'number' || b[i] instanceof Number)) {
            retArr[i] = a[i] - b[i];
          } else {
            retArr[i] = b[i] === undefined ? a[i] : a[i] || b[i];
          }
          i += 1;
        }
        return retArr;
      }
      return 0;
    }
    function mul(a, b) {
      var tOfA = _typeof$1(a);
      var tOfB = _typeof$1(b);
      var arr;
      if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
        return a * b;
      }
      var i;
      var len;
      if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
        len = a.length;
        arr = createTypedArray('float32', len);
        for (i = 0; i < len; i += 1) {
          arr[i] = a[i] * b;
        }
        return arr;
      }
      if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
        len = b.length;
        arr = createTypedArray('float32', len);
        for (i = 0; i < len; i += 1) {
          arr[i] = a * b[i];
        }
        return arr;
      }
      return 0;
    }
    function div(a, b) {
      var tOfA = _typeof$1(a);
      var tOfB = _typeof$1(b);
      var arr;
      if (isNumerable(tOfA, a) && isNumerable(tOfB, b)) {
        return a / b;
      }
      var i;
      var len;
      if ($bm_isInstanceOfArray(a) && isNumerable(tOfB, b)) {
        len = a.length;
        arr = createTypedArray('float32', len);
        for (i = 0; i < len; i += 1) {
          arr[i] = a[i] / b;
        }
        return arr;
      }
      if (isNumerable(tOfA, a) && $bm_isInstanceOfArray(b)) {
        len = b.length;
        arr = createTypedArray('float32', len);
        for (i = 0; i < len; i += 1) {
          arr[i] = a / b[i];
        }
        return arr;
      }
      return 0;
    }
    function mod(a, b) {
      if (typeof a === 'string') {
        a = parseInt(a, 10);
      }
      if (typeof b === 'string') {
        b = parseInt(b, 10);
      }
      return a % b;
    }
    var $bm_sum = sum;
    var $bm_sub = sub;
    var $bm_mul = mul;
    var $bm_div = div;
    var $bm_mod = mod;
    function clamp(num, min, max) {
      if (min > max) {
        var mm = max;
        max = min;
        min = mm;
      }
      return Math.min(Math.max(num, min), max);
    }
    function radiansToDegrees(val) {
      return val / degToRads;
    }
    var radians_to_degrees = radiansToDegrees;
    function degreesToRadians(val) {
      return val * degToRads;
    }
    var degrees_to_radians = radiansToDegrees;
    var helperLengthArray = [0, 0, 0, 0, 0, 0];
    function length(arr1, arr2) {
      if (typeof arr1 === 'number' || arr1 instanceof Number) {
        arr2 = arr2 || 0;
        return Math.abs(arr1 - arr2);
      }
      if (!arr2) {
        arr2 = helperLengthArray;
      }
      var i;
      var len = Math.min(arr1.length, arr2.length);
      var addedLength = 0;
      for (i = 0; i < len; i += 1) {
        addedLength += Math.pow(arr2[i] - arr1[i], 2);
      }
      return Math.sqrt(addedLength);
    }
    function normalize(vec) {
      return div(vec, length(vec));
    }
    function rgbToHsl(val) {
      var r = val[0];
      var g = val[1];
      var b = val[2];
      var max = Math.max(r, g, b);
      var min = Math.min(r, g, b);
      var h;
      var s;
      var l = (max + min) / 2;
      if (max === min) {
        h = 0; // achromatic
        s = 0; // achromatic
      } else {
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
          case r:
            h = (g - b) / d + (g < b ? 6 : 0);
            break;
          case g:
            h = (b - r) / d + 2;
            break;
          case b:
            h = (r - g) / d + 4;
            break;
          default:
            break;
        }
        h /= 6;
      }
      return [h, s, l, val[3]];
    }
    function hue2rgb(p, q, t) {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }
    function hslToRgb(val) {
      var h = val[0];
      var s = val[1];
      var l = val[2];
      var r;
      var g;
      var b;
      if (s === 0) {
        r = l; // achromatic
        b = l; // achromatic
        g = l; // achromatic
      } else {
        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = hue2rgb(p, q, h + 1 / 3);
        g = hue2rgb(p, q, h);
        b = hue2rgb(p, q, h - 1 / 3);
      }
      return [r, g, b, val[3]];
    }
    function linear(t, tMin, tMax, value1, value2) {
      if (value1 === undefined || value2 === undefined) {
        value1 = tMin;
        value2 = tMax;
        tMin = 0;
        tMax = 1;
      }
      if (tMax < tMin) {
        var _tMin = tMax;
        tMax = tMin;
        tMin = _tMin;
      }
      if (t <= tMin) {
        return value1;
      }
      if (t >= tMax) {
        return value2;
      }
      var perc = tMax === tMin ? 0 : (t - tMin) / (tMax - tMin);
      if (!value1.length) {
        return value1 + (value2 - value1) * perc;
      }
      var i;
      var len = value1.length;
      var arr = createTypedArray('float32', len);
      for (i = 0; i < len; i += 1) {
        arr[i] = value1[i] + (value2[i] - value1[i]) * perc;
      }
      return arr;
    }
    function random(min, max) {
      if (max === undefined) {
        if (min === undefined) {
          min = 0;
          max = 1;
        } else {
          max = min;
          min = undefined;
        }
      }
      if (max.length) {
        var i;
        var len = max.length;
        if (!min) {
          min = createTypedArray('float32', len);
        }
        var arr = createTypedArray('float32', len);
        var rnd = BMMath.random();
        for (i = 0; i < len; i += 1) {
          arr[i] = min[i] + rnd * (max[i] - min[i]);
        }
        return arr;
      }
      if (min === undefined) {
        min = 0;
      }
      var rndm = BMMath.random();
      return min + rndm * (max - min);
    }
    function createPath(points, inTangents, outTangents, closed) {
      var i;
      var len = points.length;
      var path = shapePool.newElement();
      path.setPathData(!!closed, len);
      var arrPlaceholder = [0, 0];
      var inVertexPoint;
      var outVertexPoint;
      for (i = 0; i < len; i += 1) {
        inVertexPoint = inTangents && inTangents[i] ? inTangents[i] : arrPlaceholder;
        outVertexPoint = outTangents && outTangents[i] ? outTangents[i] : arrPlaceholder;
        path.setTripleAt(points[i][0], points[i][1], outVertexPoint[0] + points[i][0], outVertexPoint[1] + points[i][1], inVertexPoint[0] + points[i][0], inVertexPoint[1] + points[i][1], i, true);
      }
      return path;
    }
    function initiateExpression(elem, data, property) {
      // Bail out if we don't want expressions
      function noOp(_value) {
        return _value;
      }
      if (!elem.globalData.renderConfig.runExpressions) {
        return noOp;
      }
      var val = data.x;
      var needsVelocity = /velocity(?![\w\d])/.test(val);
      var _needsRandom = val.indexOf('random') !== -1;
      var elemType = elem.data.ty;
      var transform;
      var $bm_transform;
      var content;
      var effect;
      var thisProperty = property;
      thisProperty._name = elem.data.nm;
      thisProperty.valueAtTime = thisProperty.getValueAtTime;
      Object.defineProperty(thisProperty, 'value', {
        get: function get() {
          return thisProperty.v;
        }
      });
      elem.comp.frameDuration = 1 / elem.comp.globalData.frameRate;
      elem.comp.displayStartTime = 0;
      var inPoint = elem.data.ip / elem.comp.globalData.frameRate;
      var outPoint = elem.data.op / elem.comp.globalData.frameRate;
      var width = elem.data.sw ? elem.data.sw : 0;
      var height = elem.data.sh ? elem.data.sh : 0;
      var name = elem.data.nm;
      var loopIn;
      var loop_in;
      var loopOut;
      var loop_out;
      var smooth;
      var toWorld;
      var fromWorld;
      var fromComp;
      var toComp;
      var fromCompToSurface;
      var position;
      var rotation;
      var anchorPoint;
      var scale;
      var thisLayer;
      var thisComp;
      var mask;
      var valueAtTime;
      var velocityAtTime;
      var scoped_bm_rt;
      // val = val.replace(/(\\?"|')((http)(s)?(:\/))?\/.*?(\\?"|')/g, "\"\""); // deter potential network calls
      var expression_function = eval('[function _expression_function(){' + val + ';scoped_bm_rt=$bm_rt}]')[0]; // eslint-disable-line no-eval
      var numKeys = property.kf ? data.k.length : 0;
      var active = !this.data || this.data.hd !== true;
      var wiggle = function wiggle(freq, amp) {
        var iWiggle;
        var j;
        var lenWiggle = this.pv.length ? this.pv.length : 1;
        var addedAmps = createTypedArray('float32', lenWiggle);
        freq = 5;
        var iterations = Math.floor(time * freq);
        iWiggle = 0;
        j = 0;
        while (iWiggle < iterations) {
          // var rnd = BMMath.random();
          for (j = 0; j < lenWiggle; j += 1) {
            addedAmps[j] += -amp + amp * 2 * BMMath.random();
            // addedAmps[j] += -amp + amp*2*rnd;
          }
          iWiggle += 1;
        }
        // var rnd2 = BMMath.random();
        var periods = time * freq;
        var perc = periods - Math.floor(periods);
        var arr = createTypedArray('float32', lenWiggle);
        if (lenWiggle > 1) {
          for (j = 0; j < lenWiggle; j += 1) {
            arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp * 2 * BMMath.random()) * perc;
            // arr[j] = this.pv[j] + addedAmps[j] + (-amp + amp*2*rnd)*perc;
            // arr[i] = this.pv[i] + addedAmp + amp1*perc + amp2*(1-perc);
          }
          return arr;
        }
        return this.pv + addedAmps[0] + (-amp + amp * 2 * BMMath.random()) * perc;
      }.bind(this);
      if (thisProperty.loopIn) {
        loopIn = thisProperty.loopIn.bind(thisProperty);
        loop_in = loopIn;
      }
      if (thisProperty.loopOut) {
        loopOut = thisProperty.loopOut.bind(thisProperty);
        loop_out = loopOut;
      }
      if (thisProperty.smooth) {
        smooth = thisProperty.smooth.bind(thisProperty);
      }
      function loopInDuration(type, duration) {
        return loopIn(type, duration, true);
      }
      function loopOutDuration(type, duration) {
        return loopOut(type, duration, true);
      }
      if (this.getValueAtTime) {
        valueAtTime = this.getValueAtTime.bind(this);
      }
      if (this.getVelocityAtTime) {
        velocityAtTime = this.getVelocityAtTime.bind(this);
      }
      var comp = elem.comp.globalData.projectInterface.bind(elem.comp.globalData.projectInterface);
      function lookAt(elem1, elem2) {
        var fVec = [elem2[0] - elem1[0], elem2[1] - elem1[1], elem2[2] - elem1[2]];
        var pitch = Math.atan2(fVec[0], Math.sqrt(fVec[1] * fVec[1] + fVec[2] * fVec[2])) / degToRads;
        var yaw = -Math.atan2(fVec[1], fVec[2]) / degToRads;
        return [yaw, pitch, 0];
      }
      function easeOut(t, tMin, tMax, val1, val2) {
        return applyEase(easeOutBez, t, tMin, tMax, val1, val2);
      }
      function easeIn(t, tMin, tMax, val1, val2) {
        return applyEase(easeInBez, t, tMin, tMax, val1, val2);
      }
      function ease(t, tMin, tMax, val1, val2) {
        return applyEase(easeInOutBez, t, tMin, tMax, val1, val2);
      }
      function applyEase(fn, t, tMin, tMax, val1, val2) {
        if (val1 === undefined) {
          val1 = tMin;
          val2 = tMax;
        } else {
          t = (t - tMin) / (tMax - tMin);
        }
        if (t > 1) {
          t = 1;
        } else if (t < 0) {
          t = 0;
        }
        var mult = fn(t);
        if ($bm_isInstanceOfArray(val1)) {
          var iKey;
          var lenKey = val1.length;
          var arr = createTypedArray('float32', lenKey);
          for (iKey = 0; iKey < lenKey; iKey += 1) {
            arr[iKey] = (val2[iKey] - val1[iKey]) * mult + val1[iKey];
          }
          return arr;
        }
        return (val2 - val1) * mult + val1;
      }
      function nearestKey(time) {
        var iKey;
        var lenKey = data.k.length;
        var index;
        var keyTime;
        if (!data.k.length || typeof data.k[0] === 'number') {
          index = 0;
          keyTime = 0;
        } else {
          index = -1;
          time *= elem.comp.globalData.frameRate;
          if (time < data.k[0].t) {
            index = 1;
            keyTime = data.k[0].t;
          } else {
            for (iKey = 0; iKey < lenKey - 1; iKey += 1) {
              if (time === data.k[iKey].t) {
                index = iKey + 1;
                keyTime = data.k[iKey].t;
                break;
              } else if (time > data.k[iKey].t && time < data.k[iKey + 1].t) {
                if (time - data.k[iKey].t > data.k[iKey + 1].t - time) {
                  index = iKey + 2;
                  keyTime = data.k[iKey + 1].t;
                } else {
                  index = iKey + 1;
                  keyTime = data.k[iKey].t;
                }
                break;
              }
            }
            if (index === -1) {
              index = iKey + 1;
              keyTime = data.k[iKey].t;
            }
          }
        }
        var obKey = {};
        obKey.index = index;
        obKey.time = keyTime / elem.comp.globalData.frameRate;
        return obKey;
      }
      function key(ind) {
        var obKey;
        var iKey;
        var lenKey;
        if (!data.k.length || typeof data.k[0] === 'number') {
          throw new Error('The property has no keyframe at index ' + ind);
        }
        ind -= 1;
        obKey = {
          time: data.k[ind].t / elem.comp.globalData.frameRate,
          value: []
        };
        var arr = Object.prototype.hasOwnProperty.call(data.k[ind], 's') ? data.k[ind].s : data.k[ind - 1].e;
        lenKey = arr.length;
        for (iKey = 0; iKey < lenKey; iKey += 1) {
          obKey[iKey] = arr[iKey];
          obKey.value[iKey] = arr[iKey];
        }
        return obKey;
      }
      function framesToTime(fr, fps) {
        if (!fps) {
          fps = elem.comp.globalData.frameRate;
        }
        return fr / fps;
      }
      function timeToFrames(t, fps) {
        if (!t && t !== 0) {
          t = time;
        }
        if (!fps) {
          fps = elem.comp.globalData.frameRate;
        }
        return t * fps;
      }
      function seedRandom(seed) {
        BMMath.seedrandom(randSeed + seed);
      }
      function sourceRectAtTime() {
        return elem.sourceRectAtTime();
      }
      function substring(init, end) {
        if (typeof value === 'string') {
          if (end === undefined) {
            return value.substring(init);
          }
          return value.substring(init, end);
        }
        return '';
      }
      function substr(init, end) {
        if (typeof value === 'string') {
          if (end === undefined) {
            return value.substr(init);
          }
          return value.substr(init, end);
        }
        return '';
      }
      function posterizeTime(framesPerSecond) {
        time = framesPerSecond === 0 ? 0 : Math.floor(time * framesPerSecond) / framesPerSecond;
        value = valueAtTime(time);
      }
      var time;
      var velocity;
      var value;
      var text;
      var textIndex;
      var textTotal;
      var selectorValue;
      var index = elem.data.ind;
      var hasParent = !!(elem.hierarchy && elem.hierarchy.length);
      var parent;
      var randSeed = Math.floor(Math.random() * 1000000);
      var globalData = elem.globalData;
      function executeExpression(_value) {
        // globalData.pushExpression();
        value = _value;
        if (this.frameExpressionId === elem.globalData.frameId && this.propType !== 'textSelector') {
          return value;
        }
        if (this.propType === 'textSelector') {
          textIndex = this.textIndex;
          textTotal = this.textTotal;
          selectorValue = this.selectorValue;
        }
        if (!thisLayer) {
          text = elem.layerInterface.text;
          thisLayer = elem.layerInterface;
          thisComp = elem.comp.compInterface;
          toWorld = thisLayer.toWorld.bind(thisLayer);
          fromWorld = thisLayer.fromWorld.bind(thisLayer);
          fromComp = thisLayer.fromComp.bind(thisLayer);
          toComp = thisLayer.toComp.bind(thisLayer);
          mask = thisLayer.mask ? thisLayer.mask.bind(thisLayer) : null;
          fromCompToSurface = fromComp;
        }
        if (!transform) {
          transform = elem.layerInterface('ADBE Transform Group');
          $bm_transform = transform;
          if (transform) {
            anchorPoint = transform.anchorPoint;
            /* position = transform.position;
                      rotation = transform.rotation;
                      scale = transform.scale; */
          }
        }
        if (elemType === 4 && !content) {
          content = thisLayer('ADBE Root Vectors Group');
        }
        if (!effect) {
          effect = thisLayer(4);
        }
        hasParent = !!(elem.hierarchy && elem.hierarchy.length);
        if (hasParent && !parent) {
          parent = elem.hierarchy[0].layerInterface;
        }
        time = this.comp.renderedFrame / this.comp.globalData.frameRate;
        if (_needsRandom) {
          seedRandom(randSeed + time);
        }
        if (needsVelocity) {
          velocity = velocityAtTime(time);
        }
        expression_function();
        this.frameExpressionId = elem.globalData.frameId;

        // TODO: Check if it's possible to return on ShapeInterface the .v value
        // Changed this to a ternary operation because Rollup failed compiling it correctly
        scoped_bm_rt = scoped_bm_rt.propType === propTypes.SHAPE ? scoped_bm_rt.v : scoped_bm_rt;
        return scoped_bm_rt;
      }
      // Bundlers will see these as dead code and unless we reference them
      executeExpression.__preventDeadCodeRemoval = [$bm_transform, anchorPoint, time, velocity, inPoint, outPoint, width, height, name, loop_in, loop_out, smooth, toComp, fromCompToSurface, toWorld, fromWorld, mask, position, rotation, scale, thisComp, numKeys, active, wiggle, loopInDuration, loopOutDuration, comp, lookAt, easeOut, easeIn, ease, nearestKey, key, text, textIndex, textTotal, selectorValue, framesToTime, timeToFrames, sourceRectAtTime, substring, substr, posterizeTime, index, globalData];
      return executeExpression;
    }
    ob.initiateExpression = initiateExpression;
    ob.__preventDeadCodeRemoval = [window, document, XMLHttpRequest, fetch, frames, $bm_neg, add, $bm_sum, $bm_sub, $bm_mul, $bm_div, $bm_mod, clamp, radians_to_degrees, degreesToRadians, degrees_to_radians, normalize, rgbToHsl, hslToRgb, linear, random, createPath, _lottieGlobal];
    ob.resetFrame = resetFrame;
    return ob;
  }();
  var Expressions = function () {
    var ob = {};
    ob.initExpressions = initExpressions;
    ob.resetFrame = ExpressionManager.resetFrame;
    function initExpressions(animation) {
      var stackCount = 0;
      var registers = [];
      function pushExpression() {
        stackCount += 1;
      }
      function popExpression() {
        stackCount -= 1;
        if (stackCount === 0) {
          releaseInstances();
        }
      }
      function registerExpressionProperty(expression) {
        if (registers.indexOf(expression) === -1) {
          registers.push(expression);
        }
      }
      function releaseInstances() {
        var i;
        var len = registers.length;
        for (i = 0; i < len; i += 1) {
          registers[i].release();
        }
        registers.length = 0;
      }
      animation.renderer.compInterface = CompExpressionInterface(animation.renderer);
      animation.renderer.globalData.projectInterface.registerComposition(animation.renderer);
      animation.renderer.globalData.pushExpression = pushExpression;
      animation.renderer.globalData.popExpression = popExpression;
      animation.renderer.globalData.registerExpressionProperty = registerExpressionProperty;
    }
    return ob;
  }();
  var MaskManagerInterface = function () {
    function MaskInterface(mask, data) {
      this._mask = mask;
      this._data = data;
    }
    Object.defineProperty(MaskInterface.prototype, 'maskPath', {
      get: function get() {
        if (this._mask.prop.k) {
          this._mask.prop.getValue();
        }
        return this._mask.prop;
      }
    });
    Object.defineProperty(MaskInterface.prototype, 'maskOpacity', {
      get: function get() {
        if (this._mask.op.k) {
          this._mask.op.getValue();
        }
        return this._mask.op.v * 100;
      }
    });
    var MaskManager = function MaskManager(maskManager) {
      var _masksInterfaces = createSizedArray(maskManager.viewData.length);
      var i;
      var len = maskManager.viewData.length;
      for (i = 0; i < len; i += 1) {
        _masksInterfaces[i] = new MaskInterface(maskManager.viewData[i], maskManager.masksProperties[i]);
      }
      var maskFunction = function maskFunction(name) {
        i = 0;
        while (i < len) {
          if (maskManager.masksProperties[i].nm === name) {
            return _masksInterfaces[i];
          }
          i += 1;
        }
        return null;
      };
      return maskFunction;
    };
    return MaskManager;
  }();
  var ExpressionPropertyInterface = function () {
    var defaultUnidimensionalValue = {
      pv: 0,
      v: 0,
      mult: 1
    };
    var defaultMultidimensionalValue = {
      pv: [0, 0, 0],
      v: [0, 0, 0],
      mult: 1
    };
    function completeProperty(expressionValue, property, type) {
      Object.defineProperty(expressionValue, 'velocity', {
        get: function get() {
          return property.getVelocityAtTime(property.comp.currentFrame);
        }
      });
      expressionValue.numKeys = property.keyframes ? property.keyframes.length : 0;
      expressionValue.key = function (pos) {
        if (!expressionValue.numKeys) {
          return 0;
        }
        var value = '';
        if ('s' in property.keyframes[pos - 1]) {
          value = property.keyframes[pos - 1].s;
        } else if ('e' in property.keyframes[pos - 2]) {
          value = property.keyframes[pos - 2].e;
        } else {
          value = property.keyframes[pos - 2].s;
        }
        var valueProp = type === 'unidimensional' ? new Number(value) : Object.assign({}, value); // eslint-disable-line no-new-wrappers
        valueProp.time = property.keyframes[pos - 1].t / property.elem.comp.globalData.frameRate;
        valueProp.value = type === 'unidimensional' ? value[0] : value;
        return valueProp;
      };
      expressionValue.valueAtTime = property.getValueAtTime;
      expressionValue.speedAtTime = property.getSpeedAtTime;
      expressionValue.velocityAtTime = property.getVelocityAtTime;
      expressionValue.propertyGroup = property.propertyGroup;
    }
    function UnidimensionalPropertyInterface(property) {
      if (!property || !('pv' in property)) {
        property = defaultUnidimensionalValue;
      }
      var mult = 1 / property.mult;
      var val = property.pv * mult;
      var expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
      expressionValue.value = val;
      completeProperty(expressionValue, property, 'unidimensional');
      return function () {
        if (property.k) {
          property.getValue();
        }
        val = property.v * mult;
        if (expressionValue.value !== val) {
          expressionValue = new Number(val); // eslint-disable-line no-new-wrappers
          expressionValue.value = val;
          expressionValue[0] = val;
          completeProperty(expressionValue, property, 'unidimensional');
        }
        return expressionValue;
      };
    }
    function MultidimensionalPropertyInterface(property) {
      if (!property || !('pv' in property)) {
        property = defaultMultidimensionalValue;
      }
      var mult = 1 / property.mult;
      var len = property.data && property.data.l || property.pv.length;
      var expressionValue = createTypedArray('float32', len);
      var arrValue = createTypedArray('float32', len);
      expressionValue.value = arrValue;
      completeProperty(expressionValue, property, 'multidimensional');
      return function () {
        if (property.k) {
          property.getValue();
        }
        for (var i = 0; i < len; i += 1) {
          arrValue[i] = property.v[i] * mult;
          expressionValue[i] = arrValue[i];
        }
        return expressionValue;
      };
    }

    // TODO: try to avoid using this getter
    function defaultGetter() {
      return defaultUnidimensionalValue;
    }
    return function (property) {
      if (!property) {
        return defaultGetter;
      }
      if (property.propType === 'unidimensional') {
        return UnidimensionalPropertyInterface(property);
      }
      return MultidimensionalPropertyInterface(property);
    };
  }();
  var TransformExpressionInterface = function () {
    return function (transform) {
      function _thisFunction(name) {
        switch (name) {
          case 'scale':
          case 'Scale':
          case 'ADBE Scale':
          case 6:
            return _thisFunction.scale;
          case 'rotation':
          case 'Rotation':
          case 'ADBE Rotation':
          case 'ADBE Rotate Z':
          case 10:
            return _thisFunction.rotation;
          case 'ADBE Rotate X':
            return _thisFunction.xRotation;
          case 'ADBE Rotate Y':
            return _thisFunction.yRotation;
          case 'position':
          case 'Position':
          case 'ADBE Position':
          case 2:
            return _thisFunction.position;
          case 'ADBE Position_0':
            return _thisFunction.xPosition;
          case 'ADBE Position_1':
            return _thisFunction.yPosition;
          case 'ADBE Position_2':
            return _thisFunction.zPosition;
          case 'anchorPoint':
          case 'AnchorPoint':
          case 'Anchor Point':
          case 'ADBE AnchorPoint':
          case 1:
            return _thisFunction.anchorPoint;
          case 'opacity':
          case 'Opacity':
          case 11:
            return _thisFunction.opacity;
          default:
            return null;
        }
      }
      Object.defineProperty(_thisFunction, 'rotation', {
        get: ExpressionPropertyInterface(transform.r || transform.rz)
      });
      Object.defineProperty(_thisFunction, 'zRotation', {
        get: ExpressionPropertyInterface(transform.rz || transform.r)
      });
      Object.defineProperty(_thisFunction, 'xRotation', {
        get: ExpressionPropertyInterface(transform.rx)
      });
      Object.defineProperty(_thisFunction, 'yRotation', {
        get: ExpressionPropertyInterface(transform.ry)
      });
      Object.defineProperty(_thisFunction, 'scale', {
        get: ExpressionPropertyInterface(transform.s)
      });
      var _px;
      var _py;
      var _pz;
      var _transformFactory;
      if (transform.p) {
        _transformFactory = ExpressionPropertyInterface(transform.p);
      } else {
        _px = ExpressionPropertyInterface(transform.px);
        _py = ExpressionPropertyInterface(transform.py);
        if (transform.pz) {
          _pz = ExpressionPropertyInterface(transform.pz);
        }
      }
      Object.defineProperty(_thisFunction, 'position', {
        get: function get() {
          if (transform.p) {
            return _transformFactory();
          }
          return [_px(), _py(), _pz ? _pz() : 0];
        }
      });
      Object.defineProperty(_thisFunction, 'xPosition', {
        get: ExpressionPropertyInterface(transform.px)
      });
      Object.defineProperty(_thisFunction, 'yPosition', {
        get: ExpressionPropertyInterface(transform.py)
      });
      Object.defineProperty(_thisFunction, 'zPosition', {
        get: ExpressionPropertyInterface(transform.pz)
      });
      Object.defineProperty(_thisFunction, 'anchorPoint', {
        get: ExpressionPropertyInterface(transform.a)
      });
      Object.defineProperty(_thisFunction, 'opacity', {
        get: ExpressionPropertyInterface(transform.o)
      });
      Object.defineProperty(_thisFunction, 'skew', {
        get: ExpressionPropertyInterface(transform.sk)
      });
      Object.defineProperty(_thisFunction, 'skewAxis', {
        get: ExpressionPropertyInterface(transform.sa)
      });
      Object.defineProperty(_thisFunction, 'orientation', {
        get: ExpressionPropertyInterface(transform.or)
      });
      return _thisFunction;
    };
  }();
  var LayerExpressionInterface = function () {
    function getMatrix(time) {
      var toWorldMat = new Matrix();
      if (time !== undefined) {
        var propMatrix = this._elem.finalTransform.mProp.getValueAtTime(time);
        propMatrix.clone(toWorldMat);
      } else {
        var transformMat = this._elem.finalTransform.mProp;
        transformMat.applyToMatrix(toWorldMat);
      }
      return toWorldMat;
    }
    function toWorldVec(arr, time) {
      var toWorldMat = this.getMatrix(time);
      toWorldMat.props[12] = 0;
      toWorldMat.props[13] = 0;
      toWorldMat.props[14] = 0;
      return this.applyPoint(toWorldMat, arr);
    }
    function toWorld(arr, time) {
      var toWorldMat = this.getMatrix(time);
      return this.applyPoint(toWorldMat, arr);
    }
    function fromWorldVec(arr, time) {
      var toWorldMat = this.getMatrix(time);
      toWorldMat.props[12] = 0;
      toWorldMat.props[13] = 0;
      toWorldMat.props[14] = 0;
      return this.invertPoint(toWorldMat, arr);
    }
    function fromWorld(arr, time) {
      var toWorldMat = this.getMatrix(time);
      return this.invertPoint(toWorldMat, arr);
    }
    function applyPoint(matrix, arr) {
      if (this._elem.hierarchy && this._elem.hierarchy.length) {
        var i;
        var len = this._elem.hierarchy.length;
        for (i = 0; i < len; i += 1) {
          this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
        }
      }
      return matrix.applyToPointArray(arr[0], arr[1], arr[2] || 0);
    }
    function invertPoint(matrix, arr) {
      if (this._elem.hierarchy && this._elem.hierarchy.length) {
        var i;
        var len = this._elem.hierarchy.length;
        for (i = 0; i < len; i += 1) {
          this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(matrix);
        }
      }
      return matrix.inversePoint(arr);
    }
    function fromComp(arr) {
      var toWorldMat = new Matrix();
      toWorldMat.reset();
      this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
      if (this._elem.hierarchy && this._elem.hierarchy.length) {
        var i;
        var len = this._elem.hierarchy.length;
        for (i = 0; i < len; i += 1) {
          this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
        }
        return toWorldMat.inversePoint(arr);
      }
      return toWorldMat.inversePoint(arr);
    }
    function sampleImage() {
      return [1, 1, 1, 1];
    }
    return function (elem) {
      var transformInterface;
      function _registerMaskInterface(maskManager) {
        _thisLayerFunction.mask = new MaskManagerInterface(maskManager, elem);
      }
      function _registerEffectsInterface(effects) {
        _thisLayerFunction.effect = effects;
      }
      function _thisLayerFunction(name) {
        switch (name) {
          case 'ADBE Root Vectors Group':
          case 'Contents':
          case 2:
            return _thisLayerFunction.shapeInterface;
          case 1:
          case 6:
          case 'Transform':
          case 'transform':
          case 'ADBE Transform Group':
            return transformInterface;
          case 4:
          case 'ADBE Effect Parade':
          case 'effects':
          case 'Effects':
            return _thisLayerFunction.effect;
          case 'ADBE Text Properties':
            return _thisLayerFunction.textInterface;
          default:
            return null;
        }
      }
      _thisLayerFunction.getMatrix = getMatrix;
      _thisLayerFunction.invertPoint = invertPoint;
      _thisLayerFunction.applyPoint = applyPoint;
      _thisLayerFunction.toWorld = toWorld;
      _thisLayerFunction.toWorldVec = toWorldVec;
      _thisLayerFunction.fromWorld = fromWorld;
      _thisLayerFunction.fromWorldVec = fromWorldVec;
      _thisLayerFunction.toComp = toWorld;
      _thisLayerFunction.fromComp = fromComp;
      _thisLayerFunction.sampleImage = sampleImage;
      _thisLayerFunction.sourceRectAtTime = elem.sourceRectAtTime.bind(elem);
      _thisLayerFunction._elem = elem;
      transformInterface = TransformExpressionInterface(elem.finalTransform.mProp);
      var anchorPointDescriptor = getDescriptor(transformInterface, 'anchorPoint');
      Object.defineProperties(_thisLayerFunction, {
        hasParent: {
          get: function get() {
            return elem.hierarchy.length;
          }
        },
        parent: {
          get: function get() {
            return elem.hierarchy[0].layerInterface;
          }
        },
        rotation: getDescriptor(transformInterface, 'rotation'),
        scale: getDescriptor(transformInterface, 'scale'),
        position: getDescriptor(transformInterface, 'position'),
        opacity: getDescriptor(transformInterface, 'opacity'),
        anchorPoint: anchorPointDescriptor,
        anchor_point: anchorPointDescriptor,
        transform: {
          get: function get() {
            return transformInterface;
          }
        },
        active: {
          get: function get() {
            return elem.isInRange;
          }
        }
      });
      _thisLayerFunction.startTime = elem.data.st;
      _thisLayerFunction.index = elem.data.ind;
      _thisLayerFunction.source = elem.data.refId;
      _thisLayerFunction.height = elem.data.ty === 0 ? elem.data.h : 100;
      _thisLayerFunction.width = elem.data.ty === 0 ? elem.data.w : 100;
      _thisLayerFunction.inPoint = elem.data.ip / elem.comp.globalData.frameRate;
      _thisLayerFunction.outPoint = elem.data.op / elem.comp.globalData.frameRate;
      _thisLayerFunction._name = elem.data.nm;
      _thisLayerFunction.registerMaskInterface = _registerMaskInterface;
      _thisLayerFunction.registerEffectsInterface = _registerEffectsInterface;
      return _thisLayerFunction;
    };
  }();
  var propertyGroupFactory = function () {
    return function (interfaceFunction, parentPropertyGroup) {
      return function (val) {
        val = val === undefined ? 1 : val;
        if (val <= 0) {
          return interfaceFunction;
        }
        return parentPropertyGroup(val - 1);
      };
    };
  }();
  var PropertyInterface = function () {
    return function (propertyName, propertyGroup) {
      var interfaceFunction = {
        _name: propertyName
      };
      function _propertyGroup(val) {
        val = val === undefined ? 1 : val;
        if (val <= 0) {
          return interfaceFunction;
        }
        return propertyGroup(val - 1);
      }
      return _propertyGroup;
    };
  }();
  var EffectsExpressionInterface = function () {
    var ob = {
      createEffectsInterface: createEffectsInterface
    };
    function createEffectsInterface(elem, propertyGroup) {
      if (elem.effectsManager) {
        var effectElements = [];
        var effectsData = elem.data.ef;
        var i;
        var len = elem.effectsManager.effectElements.length;
        for (i = 0; i < len; i += 1) {
          effectElements.push(createGroupInterface(effectsData[i], elem.effectsManager.effectElements[i], propertyGroup, elem));
        }
        var effects = elem.data.ef || [];
        var groupInterface = function groupInterface(name) {
          i = 0;
          len = effects.length;
          while (i < len) {
            if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
              return effectElements[i];
            }
            i += 1;
          }
          return null;
        };
        Object.defineProperty(groupInterface, 'numProperties', {
          get: function get() {
            return effects.length;
          }
        });
        return groupInterface;
      }
      return null;
    }
    function createGroupInterface(data, elements, propertyGroup, elem) {
      function groupInterface(name) {
        var effects = data.ef;
        var i = 0;
        var len = effects.length;
        while (i < len) {
          if (name === effects[i].nm || name === effects[i].mn || name === effects[i].ix) {
            if (effects[i].ty === 5) {
              return effectElements[i];
            }
            return effectElements[i]();
          }
          i += 1;
        }
        throw new Error();
      }
      var _propertyGroup = propertyGroupFactory(groupInterface, propertyGroup);
      var effectElements = [];
      var i;
      var len = data.ef.length;
      for (i = 0; i < len; i += 1) {
        if (data.ef[i].ty === 5) {
          effectElements.push(createGroupInterface(data.ef[i], elements.effectElements[i], elements.effectElements[i].propertyGroup, elem));
        } else {
          effectElements.push(createValueInterface(elements.effectElements[i], data.ef[i].ty, elem, _propertyGroup));
        }
      }
      if (data.mn === 'ADBE Color Control') {
        Object.defineProperty(groupInterface, 'color', {
          get: function get() {
            return effectElements[0]();
          }
        });
      }
      Object.defineProperties(groupInterface, {
        numProperties: {
          get: function get() {
            return data.np;
          }
        },
        _name: {
          value: data.nm
        },
        propertyGroup: {
          value: _propertyGroup
        }
      });
      groupInterface.enabled = data.en !== 0;
      groupInterface.active = groupInterface.enabled;
      return groupInterface;
    }
    function createValueInterface(element, type, elem, propertyGroup) {
      var expressionProperty = ExpressionPropertyInterface(element.p);
      function interfaceFunction() {
        if (type === 10) {
          return elem.comp.compInterface(element.p.v);
        }
        return expressionProperty();
      }
      if (element.p.setGroupProperty) {
        element.p.setGroupProperty(PropertyInterface('', propertyGroup));
      }
      return interfaceFunction;
    }
    return ob;
  }();
  var ShapePathInterface = function () {
    return function pathInterfaceFactory(shape, view, propertyGroup) {
      var prop = view.sh;
      function interfaceFunction(val) {
        if (val === 'Shape' || val === 'shape' || val === 'Path' || val === 'path' || val === 'ADBE Vector Shape' || val === 2) {
          return interfaceFunction.path;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      prop.setGroupProperty(PropertyInterface('Path', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        path: {
          get: function get() {
            if (prop.k) {
              prop.getValue();
            }
            return prop;
          }
        },
        shape: {
          get: function get() {
            if (prop.k) {
              prop.getValue();
            }
            return prop;
          }
        },
        _name: {
          value: shape.nm
        },
        ix: {
          value: shape.ix
        },
        propertyIndex: {
          value: shape.ix
        },
        mn: {
          value: shape.mn
        },
        propertyGroup: {
          value: propertyGroup
        }
      });
      return interfaceFunction;
    };
  }();
  var ShapeExpressionInterface = function () {
    function iterateElements(shapes, view, propertyGroup) {
      var arr = [];
      var i;
      var len = shapes ? shapes.length : 0;
      for (i = 0; i < len; i += 1) {
        if (shapes[i].ty === 'gr') {
          arr.push(groupInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'fl') {
          arr.push(fillInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'st') {
          arr.push(strokeInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'tm') {
          arr.push(trimInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'tr') {
          // arr.push(transformInterfaceFactory(shapes[i],view[i],propertyGroup));
        } else if (shapes[i].ty === 'el') {
          arr.push(ellipseInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'sr') {
          arr.push(starInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'sh') {
          arr.push(ShapePathInterface(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'rc') {
          arr.push(rectInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'rd') {
          arr.push(roundedInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'rp') {
          arr.push(repeaterInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else if (shapes[i].ty === 'gf') {
          arr.push(gradientFillInterfaceFactory(shapes[i], view[i], propertyGroup));
        } else {
          arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
        }
      }
      return arr;
    }
    function contentsInterfaceFactory(shape, view, propertyGroup) {
      var interfaces;
      var interfaceFunction = function _interfaceFunction(value) {
        var i = 0;
        var len = interfaces.length;
        while (i < len) {
          if (interfaces[i]._name === value || interfaces[i].mn === value || interfaces[i].propertyIndex === value || interfaces[i].ix === value || interfaces[i].ind === value) {
            return interfaces[i];
          }
          i += 1;
        }
        if (typeof value === 'number') {
          return interfaces[value - 1];
        }
        return null;
      };
      interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      interfaces = iterateElements(shape.it, view.it, interfaceFunction.propertyGroup);
      interfaceFunction.numProperties = interfaces.length;
      var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
      interfaceFunction.transform = transformInterface;
      interfaceFunction.propertyIndex = shape.cix;
      interfaceFunction._name = shape.nm;
      return interfaceFunction;
    }
    function groupInterfaceFactory(shape, view, propertyGroup) {
      var interfaceFunction = function _interfaceFunction(value) {
        switch (value) {
          case 'ADBE Vectors Group':
          case 'Contents':
          case 2:
            return interfaceFunction.content;
          // Not necessary for now. Keeping them here in case a new case appears
          // case 'ADBE Vector Transform Group':
          // case 3:
          default:
            return interfaceFunction.transform;
        }
      };
      interfaceFunction.propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var content = contentsInterfaceFactory(shape, view, interfaceFunction.propertyGroup);
      var transformInterface = transformInterfaceFactory(shape.it[shape.it.length - 1], view.it[view.it.length - 1], interfaceFunction.propertyGroup);
      interfaceFunction.content = content;
      interfaceFunction.transform = transformInterface;
      Object.defineProperty(interfaceFunction, '_name', {
        get: function get() {
          return shape.nm;
        }
      });
      // interfaceFunction.content = interfaceFunction;
      interfaceFunction.numProperties = shape.np;
      interfaceFunction.propertyIndex = shape.ix;
      interfaceFunction.nm = shape.nm;
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function fillInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(val) {
        if (val === 'Color' || val === 'color') {
          return interfaceFunction.color;
        }
        if (val === 'Opacity' || val === 'opacity') {
          return interfaceFunction.opacity;
        }
        return null;
      }
      Object.defineProperties(interfaceFunction, {
        color: {
          get: ExpressionPropertyInterface(view.c)
        },
        opacity: {
          get: ExpressionPropertyInterface(view.o)
        },
        _name: {
          value: shape.nm
        },
        mn: {
          value: shape.mn
        }
      });
      view.c.setGroupProperty(PropertyInterface('Color', propertyGroup));
      view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
      return interfaceFunction;
    }
    function gradientFillInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(val) {
        if (val === 'Start Point' || val === 'start point') {
          return interfaceFunction.startPoint;
        }
        if (val === 'End Point' || val === 'end point') {
          return interfaceFunction.endPoint;
        }
        if (val === 'Opacity' || val === 'opacity') {
          return interfaceFunction.opacity;
        }
        return null;
      }
      Object.defineProperties(interfaceFunction, {
        startPoint: {
          get: ExpressionPropertyInterface(view.s)
        },
        endPoint: {
          get: ExpressionPropertyInterface(view.e)
        },
        opacity: {
          get: ExpressionPropertyInterface(view.o)
        },
        type: {
          get: function get() {
            return 'a';
          }
        },
        _name: {
          value: shape.nm
        },
        mn: {
          value: shape.mn
        }
      });
      view.s.setGroupProperty(PropertyInterface('Start Point', propertyGroup));
      view.e.setGroupProperty(PropertyInterface('End Point', propertyGroup));
      view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
      return interfaceFunction;
    }
    function defaultInterfaceFactory() {
      function interfaceFunction() {
        return null;
      }
      return interfaceFunction;
    }
    function strokeInterfaceFactory(shape, view, propertyGroup) {
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
      function addPropertyToDashOb(i) {
        Object.defineProperty(dashOb, shape.d[i].nm, {
          get: ExpressionPropertyInterface(view.d.dataProps[i].p)
        });
      }
      var i;
      var len = shape.d ? shape.d.length : 0;
      var dashOb = {};
      for (i = 0; i < len; i += 1) {
        addPropertyToDashOb(i);
        view.d.dataProps[i].p.setGroupProperty(_dashPropertyGroup);
      }
      function interfaceFunction(val) {
        if (val === 'Color' || val === 'color') {
          return interfaceFunction.color;
        }
        if (val === 'Opacity' || val === 'opacity') {
          return interfaceFunction.opacity;
        }
        if (val === 'Stroke Width' || val === 'stroke width') {
          return interfaceFunction.strokeWidth;
        }
        return null;
      }
      Object.defineProperties(interfaceFunction, {
        color: {
          get: ExpressionPropertyInterface(view.c)
        },
        opacity: {
          get: ExpressionPropertyInterface(view.o)
        },
        strokeWidth: {
          get: ExpressionPropertyInterface(view.w)
        },
        dash: {
          get: function get() {
            return dashOb;
          }
        },
        _name: {
          value: shape.nm
        },
        mn: {
          value: shape.mn
        }
      });
      view.c.setGroupProperty(PropertyInterface('Color', _propertyGroup));
      view.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
      view.w.setGroupProperty(PropertyInterface('Stroke Width', _propertyGroup));
      return interfaceFunction;
    }
    function trimInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(val) {
        if (val === shape.e.ix || val === 'End' || val === 'end') {
          return interfaceFunction.end;
        }
        if (val === shape.s.ix) {
          return interfaceFunction.start;
        }
        if (val === shape.o.ix) {
          return interfaceFunction.offset;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      interfaceFunction.propertyIndex = shape.ix;
      view.s.setGroupProperty(PropertyInterface('Start', _propertyGroup));
      view.e.setGroupProperty(PropertyInterface('End', _propertyGroup));
      view.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
      interfaceFunction.propertyIndex = shape.ix;
      interfaceFunction.propertyGroup = propertyGroup;
      Object.defineProperties(interfaceFunction, {
        start: {
          get: ExpressionPropertyInterface(view.s)
        },
        end: {
          get: ExpressionPropertyInterface(view.e)
        },
        offset: {
          get: ExpressionPropertyInterface(view.o)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function transformInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.a.ix === value || value === 'Anchor Point') {
          return interfaceFunction.anchorPoint;
        }
        if (shape.o.ix === value || value === 'Opacity') {
          return interfaceFunction.opacity;
        }
        if (shape.p.ix === value || value === 'Position') {
          return interfaceFunction.position;
        }
        if (shape.r.ix === value || value === 'Rotation' || value === 'ADBE Vector Rotation') {
          return interfaceFunction.rotation;
        }
        if (shape.s.ix === value || value === 'Scale') {
          return interfaceFunction.scale;
        }
        if (shape.sk && shape.sk.ix === value || value === 'Skew') {
          return interfaceFunction.skew;
        }
        if (shape.sa && shape.sa.ix === value || value === 'Skew Axis') {
          return interfaceFunction.skewAxis;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
      view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
      view.transform.mProps.a.setGroupProperty(PropertyInterface('Anchor Point', _propertyGroup));
      view.transform.mProps.s.setGroupProperty(PropertyInterface('Scale', _propertyGroup));
      view.transform.mProps.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
      if (view.transform.mProps.sk) {
        view.transform.mProps.sk.setGroupProperty(PropertyInterface('Skew', _propertyGroup));
        view.transform.mProps.sa.setGroupProperty(PropertyInterface('Skew Angle', _propertyGroup));
      }
      view.transform.op.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        opacity: {
          get: ExpressionPropertyInterface(view.transform.mProps.o)
        },
        position: {
          get: ExpressionPropertyInterface(view.transform.mProps.p)
        },
        anchorPoint: {
          get: ExpressionPropertyInterface(view.transform.mProps.a)
        },
        scale: {
          get: ExpressionPropertyInterface(view.transform.mProps.s)
        },
        rotation: {
          get: ExpressionPropertyInterface(view.transform.mProps.r)
        },
        skew: {
          get: ExpressionPropertyInterface(view.transform.mProps.sk)
        },
        skewAxis: {
          get: ExpressionPropertyInterface(view.transform.mProps.sa)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.ty = 'tr';
      interfaceFunction.mn = shape.mn;
      interfaceFunction.propertyGroup = propertyGroup;
      return interfaceFunction;
    }
    function ellipseInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.p.ix === value) {
          return interfaceFunction.position;
        }
        if (shape.s.ix === value) {
          return interfaceFunction.size;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      interfaceFunction.propertyIndex = shape.ix;
      var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
      prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
      prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        size: {
          get: ExpressionPropertyInterface(prop.s)
        },
        position: {
          get: ExpressionPropertyInterface(prop.p)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function starInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.p.ix === value) {
          return interfaceFunction.position;
        }
        if (shape.r.ix === value) {
          return interfaceFunction.rotation;
        }
        if (shape.pt.ix === value) {
          return interfaceFunction.points;
        }
        if (shape.or.ix === value || value === 'ADBE Vector Star Outer Radius') {
          return interfaceFunction.outerRadius;
        }
        if (shape.os.ix === value) {
          return interfaceFunction.outerRoundness;
        }
        if (shape.ir && (shape.ir.ix === value || value === 'ADBE Vector Star Inner Radius')) {
          return interfaceFunction.innerRadius;
        }
        if (shape.is && shape.is.ix === value) {
          return interfaceFunction.innerRoundness;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
      interfaceFunction.propertyIndex = shape.ix;
      prop.or.setGroupProperty(PropertyInterface('Outer Radius', _propertyGroup));
      prop.os.setGroupProperty(PropertyInterface('Outer Roundness', _propertyGroup));
      prop.pt.setGroupProperty(PropertyInterface('Points', _propertyGroup));
      prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
      prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
      if (shape.ir) {
        prop.ir.setGroupProperty(PropertyInterface('Inner Radius', _propertyGroup));
        prop.is.setGroupProperty(PropertyInterface('Inner Roundness', _propertyGroup));
      }
      Object.defineProperties(interfaceFunction, {
        position: {
          get: ExpressionPropertyInterface(prop.p)
        },
        rotation: {
          get: ExpressionPropertyInterface(prop.r)
        },
        points: {
          get: ExpressionPropertyInterface(prop.pt)
        },
        outerRadius: {
          get: ExpressionPropertyInterface(prop.or)
        },
        outerRoundness: {
          get: ExpressionPropertyInterface(prop.os)
        },
        innerRadius: {
          get: ExpressionPropertyInterface(prop.ir)
        },
        innerRoundness: {
          get: ExpressionPropertyInterface(prop.is)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function rectInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.p.ix === value) {
          return interfaceFunction.position;
        }
        if (shape.r.ix === value) {
          return interfaceFunction.roundness;
        }
        if (shape.s.ix === value || value === 'Size' || value === 'ADBE Vector Rect Size') {
          return interfaceFunction.size;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var prop = view.sh.ty === 'tm' ? view.sh.prop : view.sh;
      interfaceFunction.propertyIndex = shape.ix;
      prop.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
      prop.s.setGroupProperty(PropertyInterface('Size', _propertyGroup));
      prop.r.setGroupProperty(PropertyInterface('Rotation', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        position: {
          get: ExpressionPropertyInterface(prop.p)
        },
        roundness: {
          get: ExpressionPropertyInterface(prop.r)
        },
        size: {
          get: ExpressionPropertyInterface(prop.s)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function roundedInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.r.ix === value || value === 'Round Corners 1') {
          return interfaceFunction.radius;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var prop = view;
      interfaceFunction.propertyIndex = shape.ix;
      prop.rd.setGroupProperty(PropertyInterface('Radius', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        radius: {
          get: ExpressionPropertyInterface(prop.rd)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    function repeaterInterfaceFactory(shape, view, propertyGroup) {
      function interfaceFunction(value) {
        if (shape.c.ix === value || value === 'Copies') {
          return interfaceFunction.copies;
        }
        if (shape.o.ix === value || value === 'Offset') {
          return interfaceFunction.offset;
        }
        return null;
      }
      var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
      var prop = view;
      interfaceFunction.propertyIndex = shape.ix;
      prop.c.setGroupProperty(PropertyInterface('Copies', _propertyGroup));
      prop.o.setGroupProperty(PropertyInterface('Offset', _propertyGroup));
      Object.defineProperties(interfaceFunction, {
        copies: {
          get: ExpressionPropertyInterface(prop.c)
        },
        offset: {
          get: ExpressionPropertyInterface(prop.o)
        },
        _name: {
          value: shape.nm
        }
      });
      interfaceFunction.mn = shape.mn;
      return interfaceFunction;
    }
    return function (shapes, view, propertyGroup) {
      var interfaces;
      function _interfaceFunction(value) {
        if (typeof value === 'number') {
          value = value === undefined ? 1 : value;
          if (value === 0) {
            return propertyGroup;
          }
          return interfaces[value - 1];
        }
        var i = 0;
        var len = interfaces.length;
        while (i < len) {
          if (interfaces[i]._name === value) {
            return interfaces[i];
          }
          i += 1;
        }
        return null;
      }
      function parentGroupWrapper() {
        return propertyGroup;
      }
      _interfaceFunction.propertyGroup = propertyGroupFactory(_interfaceFunction, parentGroupWrapper);
      interfaces = iterateElements(shapes, view, _interfaceFunction.propertyGroup);
      _interfaceFunction.numProperties = interfaces.length;
      _interfaceFunction._name = 'Contents';
      return _interfaceFunction;
    };
  }();
  var TextExpressionInterface = function () {
    return function (elem) {
      var _sourceText;
      function _thisLayerFunction(name) {
        switch (name) {
          case 'ADBE Text Document':
            return _thisLayerFunction.sourceText;
          default:
            return null;
        }
      }
      Object.defineProperty(_thisLayerFunction, 'sourceText', {
        get: function get() {
          elem.textProperty.getValue();
          var stringValue = elem.textProperty.currentData.t;
          if (!_sourceText || stringValue !== _sourceText.value) {
            _sourceText = new String(stringValue); // eslint-disable-line no-new-wrappers
            // If stringValue is an empty string, eval returns undefined, so it has to be returned as a String primitive
            _sourceText.value = stringValue || new String(stringValue); // eslint-disable-line no-new-wrappers
            Object.defineProperty(_sourceText, 'style', {
              get: function get() {
                return {
                  fillColor: elem.textProperty.currentData.fc
                };
              }
            });
          }
          return _sourceText;
        }
      });
      return _thisLayerFunction;
    };
  }();
  function _typeof(o) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
      return typeof o;
    } : function (o) {
      return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
    }, _typeof(o);
  }
  var FootageInterface = function () {
    var outlineInterfaceFactory = function outlineInterfaceFactory(elem) {
      var currentPropertyName = '';
      var currentProperty = elem.getFootageData();
      function init() {
        currentPropertyName = '';
        currentProperty = elem.getFootageData();
        return searchProperty;
      }
      function searchProperty(value) {
        if (currentProperty[value]) {
          currentPropertyName = value;
          currentProperty = currentProperty[value];
          if (_typeof(currentProperty) === 'object') {
            return searchProperty;
          }
          return currentProperty;
        }
        var propertyNameIndex = value.indexOf(currentPropertyName);
        if (propertyNameIndex !== -1) {
          var index = parseInt(value.substr(propertyNameIndex + currentPropertyName.length), 10);
          currentProperty = currentProperty[index];
          if (_typeof(currentProperty) === 'object') {
            return searchProperty;
          }
          return currentProperty;
        }
        return '';
      }
      return init;
    };
    var dataInterfaceFactory = function dataInterfaceFactory(elem) {
      function interfaceFunction(value) {
        if (value === 'Outline') {
          return interfaceFunction.outlineInterface();
        }
        return null;
      }
      interfaceFunction._name = 'Outline';
      interfaceFunction.outlineInterface = outlineInterfaceFactory(elem);
      return interfaceFunction;
    };
    return function (elem) {
      function _interfaceFunction(value) {
        if (value === 'Data') {
          return _interfaceFunction.dataInterface;
        }
        return null;
      }
      _interfaceFunction._name = 'Data';
      _interfaceFunction.dataInterface = dataInterfaceFactory(elem);
      return _interfaceFunction;
    };
  }();
  var interfaces = {
    layer: LayerExpressionInterface,
    effects: EffectsExpressionInterface,
    comp: CompExpressionInterface,
    shape: ShapeExpressionInterface,
    text: TextExpressionInterface,
    footage: FootageInterface
  };
  function getInterface(type) {
    return interfaces[type] || null;
  }
  var expressionHelpers = function () {
    function searchExpressions(elem, data, prop) {
      if (data.x) {
        prop.k = true;
        prop.x = true;
        prop.initiateExpression = ExpressionManager.initiateExpression;
        prop.effectsSequence.push(prop.initiateExpression(elem, data, prop).bind(prop));
      }
    }
    function getValueAtTime(frameNum) {
      frameNum *= this.elem.globalData.frameRate;
      frameNum -= this.offsetTime;
      if (frameNum !== this._cachingAtTime.lastFrame) {
        this._cachingAtTime.lastIndex = this._cachingAtTime.lastFrame < frameNum ? this._cachingAtTime.lastIndex : 0;
        this._cachingAtTime.value = this.interpolateValue(frameNum, this._cachingAtTime);
        this._cachingAtTime.lastFrame = frameNum;
      }
      return this._cachingAtTime.value;
    }
    function getSpeedAtTime(frameNum) {
      var delta = -0.01;
      var v1 = this.getValueAtTime(frameNum);
      var v2 = this.getValueAtTime(frameNum + delta);
      var speed = 0;
      if (v1.length) {
        var i;
        for (i = 0; i < v1.length; i += 1) {
          speed += Math.pow(v2[i] - v1[i], 2);
        }
        speed = Math.sqrt(speed) * 100;
      } else {
        speed = 0;
      }
      return speed;
    }
    function getVelocityAtTime(frameNum) {
      if (this.vel !== undefined) {
        return this.vel;
      }
      var delta = -0.001;
      // frameNum += this.elem.data.st;
      var v1 = this.getValueAtTime(frameNum);
      var v2 = this.getValueAtTime(frameNum + delta);
      var velocity;
      if (v1.length) {
        velocity = createTypedArray('float32', v1.length);
        var i;
        for (i = 0; i < v1.length; i += 1) {
          // removing frameRate
          // if needed, don't add it here
          // velocity[i] = this.elem.globalData.frameRate*((v2[i] - v1[i])/delta);
          velocity[i] = (v2[i] - v1[i]) / delta;
        }
      } else {
        velocity = (v2 - v1) / delta;
      }
      return velocity;
    }
    function getStaticValueAtTime() {
      return this.pv;
    }
    function setGroupProperty(propertyGroup) {
      this.propertyGroup = propertyGroup;
    }
    return {
      searchExpressions: searchExpressions,
      getSpeedAtTime: getSpeedAtTime,
      getVelocityAtTime: getVelocityAtTime,
      getValueAtTime: getValueAtTime,
      getStaticValueAtTime: getStaticValueAtTime,
      setGroupProperty: setGroupProperty
    };
  }();
  function addPropertyDecorator() {
    function loopOut(type, duration, durationFlag) {
      if (!this.k || !this.keyframes) {
        return this.pv;
      }
      type = type ? type.toLowerCase() : '';
      var currentFrame = this.comp.renderedFrame;
      var keyframes = this.keyframes;
      var lastKeyFrame = keyframes[keyframes.length - 1].t;
      if (currentFrame <= lastKeyFrame) {
        return this.pv;
      }
      var cycleDuration;
      var firstKeyFrame;
      if (!durationFlag) {
        if (!duration || duration > keyframes.length - 1) {
          duration = keyframes.length - 1;
        }
        firstKeyFrame = keyframes[keyframes.length - 1 - duration].t;
        cycleDuration = lastKeyFrame - firstKeyFrame;
      } else {
        if (!duration) {
          cycleDuration = Math.max(0, lastKeyFrame - this.elem.data.ip);
        } else {
          cycleDuration = Math.abs(lastKeyFrame - this.elem.comp.globalData.frameRate * duration);
        }
        firstKeyFrame = lastKeyFrame - cycleDuration;
      }
      var i;
      var len;
      var ret;
      if (type === 'pingpong') {
        var iterations = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
        if (iterations % 2 !== 0) {
          return this.getValueAtTime((cycleDuration - (currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
        }
      } else if (type === 'offset') {
        var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
        var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
        var current = this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
        var repeats = Math.floor((currentFrame - firstKeyFrame) / cycleDuration);
        if (this.pv.length) {
          ret = new Array(initV.length);
          len = ret.length;
          for (i = 0; i < len; i += 1) {
            ret[i] = (endV[i] - initV[i]) * repeats + current[i];
          }
          return ret;
        }
        return (endV - initV) * repeats + current;
      } else if (type === 'continue') {
        var lastValue = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
        var nextLastValue = this.getValueAtTime((lastKeyFrame - 0.001) / this.comp.globalData.frameRate, 0);
        if (this.pv.length) {
          ret = new Array(lastValue.length);
          len = ret.length;
          for (i = 0; i < len; i += 1) {
            ret[i] = lastValue[i] + (lastValue[i] - nextLastValue[i]) * ((currentFrame - lastKeyFrame) / this.comp.globalData.frameRate) / 0.0005; // eslint-disable-line
          }
          return ret;
        }
        return lastValue + (lastValue - nextLastValue) * ((currentFrame - lastKeyFrame) / 0.001);
      }
      return this.getValueAtTime(((currentFrame - firstKeyFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
    }
    function loopIn(type, duration, durationFlag) {
      if (!this.k) {
        return this.pv;
      }
      type = type ? type.toLowerCase() : '';
      var currentFrame = this.comp.renderedFrame;
      var keyframes = this.keyframes;
      var firstKeyFrame = keyframes[0].t;
      if (currentFrame >= firstKeyFrame) {
        return this.pv;
      }
      var cycleDuration;
      var lastKeyFrame;
      if (!durationFlag) {
        if (!duration || duration > keyframes.length - 1) {
          duration = keyframes.length - 1;
        }
        lastKeyFrame = keyframes[duration].t;
        cycleDuration = lastKeyFrame - firstKeyFrame;
      } else {
        if (!duration) {
          cycleDuration = Math.max(0, this.elem.data.op - firstKeyFrame);
        } else {
          cycleDuration = Math.abs(this.elem.comp.globalData.frameRate * duration);
        }
        lastKeyFrame = firstKeyFrame + cycleDuration;
      }
      var i;
      var len;
      var ret;
      if (type === 'pingpong') {
        var iterations = Math.floor((firstKeyFrame - currentFrame) / cycleDuration);
        if (iterations % 2 === 0) {
          return this.getValueAtTime(((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0); // eslint-disable-line
        }
      } else if (type === 'offset') {
        var initV = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
        var endV = this.getValueAtTime(lastKeyFrame / this.comp.globalData.frameRate, 0);
        var current = this.getValueAtTime((cycleDuration - (firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame) / this.comp.globalData.frameRate, 0);
        var repeats = Math.floor((firstKeyFrame - currentFrame) / cycleDuration) + 1;
        if (this.pv.length) {
          ret = new Array(initV.length);
          len = ret.length;
          for (i = 0; i < len; i += 1) {
            ret[i] = current[i] - (endV[i] - initV[i]) * repeats;
          }
          return ret;
        }
        return current - (endV - initV) * repeats;
      } else if (type === 'continue') {
        var firstValue = this.getValueAtTime(firstKeyFrame / this.comp.globalData.frameRate, 0);
        var nextFirstValue = this.getValueAtTime((firstKeyFrame + 0.001) / this.comp.globalData.frameRate, 0);
        if (this.pv.length) {
          ret = new Array(firstValue.length);
          len = ret.length;
          for (i = 0; i < len; i += 1) {
            ret[i] = firstValue[i] + (firstValue[i] - nextFirstValue[i]) * (firstKeyFrame - currentFrame) / 0.001;
          }
          return ret;
        }
        return firstValue + (firstValue - nextFirstValue) * (firstKeyFrame - currentFrame) / 0.001;
      }
      return this.getValueAtTime((cycleDuration - ((firstKeyFrame - currentFrame) % cycleDuration + firstKeyFrame)) / this.comp.globalData.frameRate, 0); // eslint-disable-line
    }
    function smooth(width, samples) {
      if (!this.k) {
        return this.pv;
      }
      width = (width || 0.4) * 0.5;
      samples = Math.floor(samples || 5);
      if (samples <= 1) {
        return this.pv;
      }
      var currentTime = this.comp.renderedFrame / this.comp.globalData.frameRate;
      var initFrame = currentTime - width;
      var endFrame = currentTime + width;
      var sampleFrequency = samples > 1 ? (endFrame - initFrame) / (samples - 1) : 1;
      var i = 0;
      var j = 0;
      var value;
      if (this.pv.length) {
        value = createTypedArray('float32', this.pv.length);
      } else {
        value = 0;
      }
      var sampleValue;
      while (i < samples) {
        sampleValue = this.getValueAtTime(initFrame + i * sampleFrequency);
        if (this.pv.length) {
          for (j = 0; j < this.pv.length; j += 1) {
            value[j] += sampleValue[j];
          }
        } else {
          value += sampleValue;
        }
        i += 1;
      }
      if (this.pv.length) {
        for (j = 0; j < this.pv.length; j += 1) {
          value[j] /= samples;
        }
      } else {
        value /= samples;
      }
      return value;
    }
    function getTransformValueAtTime(time) {
      if (!this._transformCachingAtTime) {
        this._transformCachingAtTime = {
          v: new Matrix()
        };
      }
      /// /
      var matrix = this._transformCachingAtTime.v;
      matrix.cloneFromProps(this.pre.props);
      if (this.appliedTransformations < 1) {
        var anchor = this.a.getValueAtTime(time);
        matrix.translate(-anchor[0] * this.a.mult, -anchor[1] * this.a.mult, anchor[2] * this.a.mult);
      }
      if (this.appliedTransformations < 2) {
        var scale = this.s.getValueAtTime(time);
        matrix.scale(scale[0] * this.s.mult, scale[1] * this.s.mult, scale[2] * this.s.mult);
      }
      if (this.sk && this.appliedTransformations < 3) {
        var skew = this.sk.getValueAtTime(time);
        var skewAxis = this.sa.getValueAtTime(time);
        matrix.skewFromAxis(-skew * this.sk.mult, skewAxis * this.sa.mult);
      }
      if (this.r && this.appliedTransformations < 4) {
        var rotation = this.r.getValueAtTime(time);
        matrix.rotate(-rotation * this.r.mult);
      } else if (!this.r && this.appliedTransformations < 4) {
        var rotationZ = this.rz.getValueAtTime(time);
        var rotationY = this.ry.getValueAtTime(time);
        var rotationX = this.rx.getValueAtTime(time);
        var orientation = this.or.getValueAtTime(time);
        matrix.rotateZ(-rotationZ * this.rz.mult).rotateY(rotationY * this.ry.mult).rotateX(rotationX * this.rx.mult).rotateZ(-orientation[2] * this.or.mult).rotateY(orientation[1] * this.or.mult).rotateX(orientation[0] * this.or.mult);
      }
      if (this.data.p && this.data.p.s) {
        var positionX = this.px.getValueAtTime(time);
        var positionY = this.py.getValueAtTime(time);
        if (this.data.p.z) {
          var positionZ = this.pz.getValueAtTime(time);
          matrix.translate(positionX * this.px.mult, positionY * this.py.mult, -positionZ * this.pz.mult);
        } else {
          matrix.translate(positionX * this.px.mult, positionY * this.py.mult, 0);
        }
      } else {
        var position = this.p.getValueAtTime(time);
        matrix.translate(position[0] * this.p.mult, position[1] * this.p.mult, -position[2] * this.p.mult);
      }
      return matrix;
      /// /
    }
    function getTransformStaticValueAtTime() {
      return this.v.clone(new Matrix());
    }
    var getTransformProperty = TransformPropertyFactory.getTransformProperty;
    TransformPropertyFactory.getTransformProperty = function (elem, data, container) {
      var prop = getTransformProperty(elem, data, container);
      if (prop.dynamicProperties.length) {
        prop.getValueAtTime = getTransformValueAtTime.bind(prop);
      } else {
        prop.getValueAtTime = getTransformStaticValueAtTime.bind(prop);
      }
      prop.setGroupProperty = expressionHelpers.setGroupProperty;
      return prop;
    };
    var propertyGetProp = PropertyFactory.getProp;
    PropertyFactory.getProp = function (elem, data, type, mult, container) {
      var prop = propertyGetProp(elem, data, type, mult, container);
      // prop.getVelocityAtTime = getVelocityAtTime;
      // prop.loopOut = loopOut;
      // prop.loopIn = loopIn;
      if (prop.kf) {
        prop.getValueAtTime = expressionHelpers.getValueAtTime.bind(prop);
      } else {
        prop.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(prop);
      }
      prop.setGroupProperty = expressionHelpers.setGroupProperty;
      prop.loopOut = loopOut;
      prop.loopIn = loopIn;
      prop.smooth = smooth;
      prop.getVelocityAtTime = expressionHelpers.getVelocityAtTime.bind(prop);
      prop.getSpeedAtTime = expressionHelpers.getSpeedAtTime.bind(prop);
      prop.numKeys = data.a === 1 ? data.k.length : 0;
      prop.propertyIndex = data.ix;
      var value = 0;
      if (type !== 0) {
        value = createTypedArray('float32', data.a === 1 ? data.k[0].s.length : data.k.length);
      }
      prop._cachingAtTime = {
        lastFrame: initialDefaultFrame,
        lastIndex: 0,
        value: value
      };
      expressionHelpers.searchExpressions(elem, data, prop);
      if (prop.k) {
        container.addDynamicProperty(prop);
      }
      return prop;
    };
    function getShapeValueAtTime(frameNum) {
      // For now this caching object is created only when needed instead of creating it when the shape is initialized.
      if (!this._cachingAtTime) {
        this._cachingAtTime = {
          shapeValue: shapePool.clone(this.pv),
          lastIndex: 0,
          lastTime: initialDefaultFrame
        };
      }
      frameNum *= this.elem.globalData.frameRate;
      frameNum -= this.offsetTime;
      if (frameNum !== this._cachingAtTime.lastTime) {
        this._cachingAtTime.lastIndex = this._cachingAtTime.lastTime < frameNum ? this._caching.lastIndex : 0;
        this._cachingAtTime.lastTime = frameNum;
        this.interpolateShape(frameNum, this._cachingAtTime.shapeValue, this._cachingAtTime);
      }
      return this._cachingAtTime.shapeValue;
    }
    var ShapePropertyConstructorFunction = ShapePropertyFactory.getConstructorFunction();
    var KeyframedShapePropertyConstructorFunction = ShapePropertyFactory.getKeyframedConstructorFunction();
    function ShapeExpressions() {}
    ShapeExpressions.prototype = {
      vertices: function vertices(prop, time) {
        if (this.k) {
          this.getValue();
        }
        var shapePath = this.v;
        if (time !== undefined) {
          shapePath = this.getValueAtTime(time, 0);
        }
        var i;
        var len = shapePath._length;
        var vertices = shapePath[prop];
        var points = shapePath.v;
        var arr = createSizedArray(len);
        for (i = 0; i < len; i += 1) {
          if (prop === 'i' || prop === 'o') {
            arr[i] = [vertices[i][0] - points[i][0], vertices[i][1] - points[i][1]];
          } else {
            arr[i] = [vertices[i][0], vertices[i][1]];
          }
        }
        return arr;
      },
      points: function points(time) {
        return this.vertices('v', time);
      },
      inTangents: function inTangents(time) {
        return this.vertices('i', time);
      },
      outTangents: function outTangents(time) {
        return this.vertices('o', time);
      },
      isClosed: function isClosed() {
        return this.v.c;
      },
      pointOnPath: function pointOnPath(perc, time) {
        var shapePath = this.v;
        if (time !== undefined) {
          shapePath = this.getValueAtTime(time, 0);
        }
        if (!this._segmentsLength) {
          this._segmentsLength = bez.getSegmentsLength(shapePath);
        }
        var segmentsLength = this._segmentsLength;
        var lengths = segmentsLength.lengths;
        var lengthPos = segmentsLength.totalLength * perc;
        var i = 0;
        var len = lengths.length;
        var accumulatedLength = 0;
        var pt;
        while (i < len) {
          if (accumulatedLength + lengths[i].addedLength > lengthPos) {
            var initIndex = i;
            var endIndex = shapePath.c && i === len - 1 ? 0 : i + 1;
            var segmentPerc = (lengthPos - accumulatedLength) / lengths[i].addedLength;
            pt = bez.getPointInSegment(shapePath.v[initIndex], shapePath.v[endIndex], shapePath.o[initIndex], shapePath.i[endIndex], segmentPerc, lengths[i]);
            break;
          } else {
            accumulatedLength += lengths[i].addedLength;
          }
          i += 1;
        }
        if (!pt) {
          pt = shapePath.c ? [shapePath.v[0][0], shapePath.v[0][1]] : [shapePath.v[shapePath._length - 1][0], shapePath.v[shapePath._length - 1][1]];
        }
        return pt;
      },
      vectorOnPath: function vectorOnPath(perc, time, vectorType) {
        // perc doesn't use triple equality because it can be a Number object as well as a primitive.
        if (perc == 1) {
          // eslint-disable-line eqeqeq
          perc = this.v.c;
        } else if (perc == 0) {
          // eslint-disable-line eqeqeq
          perc = 0.999;
        }
        var pt1 = this.pointOnPath(perc, time);
        var pt2 = this.pointOnPath(perc + 0.001, time);
        var xLength = pt2[0] - pt1[0];
        var yLength = pt2[1] - pt1[1];
        var magnitude = Math.sqrt(Math.pow(xLength, 2) + Math.pow(yLength, 2));
        if (magnitude === 0) {
          return [0, 0];
        }
        var unitVector = vectorType === 'tangent' ? [xLength / magnitude, yLength / magnitude] : [-yLength / magnitude, xLength / magnitude];
        return unitVector;
      },
      tangentOnPath: function tangentOnPath(perc, time) {
        return this.vectorOnPath(perc, time, 'tangent');
      },
      normalOnPath: function normalOnPath(perc, time) {
        return this.vectorOnPath(perc, time, 'normal');
      },
      setGroupProperty: expressionHelpers.setGroupProperty,
      getValueAtTime: expressionHelpers.getStaticValueAtTime
    };
    extendPrototype([ShapeExpressions], ShapePropertyConstructorFunction);
    extendPrototype([ShapeExpressions], KeyframedShapePropertyConstructorFunction);
    KeyframedShapePropertyConstructorFunction.prototype.getValueAtTime = getShapeValueAtTime;
    KeyframedShapePropertyConstructorFunction.prototype.initiateExpression = ExpressionManager.initiateExpression;
    var propertyGetShapeProp = ShapePropertyFactory.getShapeProp;
    ShapePropertyFactory.getShapeProp = function (elem, data, type, arr, trims) {
      var prop = propertyGetShapeProp(elem, data, type, arr, trims);
      prop.propertyIndex = data.ix;
      prop.lock = false;
      if (type === 3) {
        expressionHelpers.searchExpressions(elem, data.pt, prop);
      } else if (type === 4) {
        expressionHelpers.searchExpressions(elem, data.ks, prop);
      }
      if (prop.k) {
        elem.addDynamicProperty(prop);
      }
      return prop;
    };
  }
  function initialize$1() {
    addPropertyDecorator();
  }
  function addDecorator() {
    function searchExpressions() {
      if (this.data.d.x) {
        this.calculateExpression = ExpressionManager.initiateExpression.bind(this)(this.elem, this.data.d, this);
        this.addEffect(this.getExpressionValue.bind(this));
        return true;
      }
      return null;
    }
    TextProperty.prototype.getExpressionValue = function (currentValue, text) {
      var newValue = this.calculateExpression(text);
      if (currentValue.t !== newValue) {
        var newData = {};
        this.copyData(newData, currentValue);
        newData.t = newValue.toString();
        newData.__complete = false;
        return newData;
      }
      return currentValue;
    };
    TextProperty.prototype.searchProperty = function () {
      var isKeyframed = this.searchKeyframes();
      var hasExpressions = this.searchExpressions();
      this.kf = isKeyframed || hasExpressions;
      return this.kf;
    };
    TextProperty.prototype.searchExpressions = searchExpressions;
  }
  function initialize() {
    addDecorator();
  }
  function SVGComposableEffect() {}
  SVGComposableEffect.prototype = {
    createMergeNode: function createMergeNode(resultId, ins) {
      var feMerge = createNS('feMerge');
      feMerge.setAttribute('result', resultId);
      var feMergeNode;
      var i;
      for (i = 0; i < ins.length; i += 1) {
        feMergeNode = createNS('feMergeNode');
        feMergeNode.setAttribute('in', ins[i]);
        feMerge.appendChild(feMergeNode);
        feMerge.appendChild(feMergeNode);
      }
      return feMerge;
    }
  };
  var linearFilterValue = '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0';
  function SVGTintFilter(filter, filterManager, elem, id, source) {
    this.filterManager = filterManager;
    var feColorMatrix = createNS('feColorMatrix');
    feColorMatrix.setAttribute('type', 'matrix');
    feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
    feColorMatrix.setAttribute('values', linearFilterValue + ' 1 0');
    this.linearFilter = feColorMatrix;
    feColorMatrix.setAttribute('result', id + '_tint_1');
    filter.appendChild(feColorMatrix);
    feColorMatrix = createNS('feColorMatrix');
    feColorMatrix.setAttribute('type', 'matrix');
    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
    feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
    feColorMatrix.setAttribute('result', id + '_tint_2');
    filter.appendChild(feColorMatrix);
    this.matrixFilter = feColorMatrix;
    var feMerge = this.createMergeNode(id, [source, id + '_tint_1', id + '_tint_2']);
    filter.appendChild(feMerge);
  }
  extendPrototype([SVGComposableEffect], SVGTintFilter);
  SVGTintFilter.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      var colorBlack = this.filterManager.effectElements[0].p.v;
      var colorWhite = this.filterManager.effectElements[1].p.v;
      var opacity = this.filterManager.effectElements[2].p.v / 100;
      this.linearFilter.setAttribute('values', linearFilterValue + ' ' + opacity + ' 0');
      this.matrixFilter.setAttribute('values', colorWhite[0] - colorBlack[0] + ' 0 0 0 ' + colorBlack[0] + ' ' + (colorWhite[1] - colorBlack[1]) + ' 0 0 0 ' + colorBlack[1] + ' ' + (colorWhite[2] - colorBlack[2]) + ' 0 0 0 ' + colorBlack[2] + ' 0 0 0 1 0');
    }
  };
  function SVGFillFilter(filter, filterManager, elem, id) {
    this.filterManager = filterManager;
    var feColorMatrix = createNS('feColorMatrix');
    feColorMatrix.setAttribute('type', 'matrix');
    feColorMatrix.setAttribute('color-interpolation-filters', 'sRGB');
    feColorMatrix.setAttribute('values', '1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0');
    feColorMatrix.setAttribute('result', id);
    filter.appendChild(feColorMatrix);
    this.matrixFilter = feColorMatrix;
  }
  SVGFillFilter.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      var color = this.filterManager.effectElements[2].p.v;
      var opacity = this.filterManager.effectElements[6].p.v;
      this.matrixFilter.setAttribute('values', '0 0 0 0 ' + color[0] + ' 0 0 0 0 ' + color[1] + ' 0 0 0 0 ' + color[2] + ' 0 0 0 ' + opacity + ' 0');
    }
  };
  function SVGStrokeEffect(fil, filterManager, elem) {
    this.initialized = false;
    this.filterManager = filterManager;
    this.elem = elem;
    this.paths = [];
  }
  SVGStrokeEffect.prototype.initialize = function () {
    var elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
    var path;
    var groupPath;
    var i;
    var len;
    if (this.filterManager.effectElements[1].p.v === 1) {
      len = this.elem.maskManager.masksProperties.length;
      i = 0;
    } else {
      i = this.filterManager.effectElements[0].p.v - 1;
      len = i + 1;
    }
    groupPath = createNS('g');
    groupPath.setAttribute('fill', 'none');
    groupPath.setAttribute('stroke-linecap', 'round');
    groupPath.setAttribute('stroke-dashoffset', 1);
    for (i; i < len; i += 1) {
      path = createNS('path');
      groupPath.appendChild(path);
      this.paths.push({
        p: path,
        m: i
      });
    }
    if (this.filterManager.effectElements[10].p.v === 3) {
      var mask = createNS('mask');
      var id = createElementID();
      mask.setAttribute('id', id);
      mask.setAttribute('mask-type', 'alpha');
      mask.appendChild(groupPath);
      this.elem.globalData.defs.appendChild(mask);
      var g = createNS('g');
      g.setAttribute('mask', 'url(' + getLocationHref() + '#' + id + ')');
      while (elemChildren[0]) {
        g.appendChild(elemChildren[0]);
      }
      this.elem.layerElement.appendChild(g);
      this.masker = mask;
      groupPath.setAttribute('stroke', '#fff');
    } else if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
      if (this.filterManager.effectElements[10].p.v === 2) {
        elemChildren = this.elem.layerElement.children || this.elem.layerElement.childNodes;
        while (elemChildren.length) {
          this.elem.layerElement.removeChild(elemChildren[0]);
        }
      }
      this.elem.layerElement.appendChild(groupPath);
      this.elem.layerElement.removeAttribute('mask');
      groupPath.setAttribute('stroke', '#fff');
    }
    this.initialized = true;
    this.pathMasker = groupPath;
  };
  SVGStrokeEffect.prototype.renderFrame = function (forceRender) {
    if (!this.initialized) {
      this.initialize();
    }
    var i;
    var len = this.paths.length;
    var mask;
    var path;
    for (i = 0; i < len; i += 1) {
      if (this.paths[i].m !== -1) {
        mask = this.elem.maskManager.viewData[this.paths[i].m];
        path = this.paths[i].p;
        if (forceRender || this.filterManager._mdf || mask.prop._mdf) {
          path.setAttribute('d', mask.lastPath);
        }
        if (forceRender || this.filterManager.effectElements[9].p._mdf || this.filterManager.effectElements[4].p._mdf || this.filterManager.effectElements[7].p._mdf || this.filterManager.effectElements[8].p._mdf || mask.prop._mdf) {
          var dasharrayValue;
          if (this.filterManager.effectElements[7].p.v !== 0 || this.filterManager.effectElements[8].p.v !== 100) {
            var s = Math.min(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
            var e = Math.max(this.filterManager.effectElements[7].p.v, this.filterManager.effectElements[8].p.v) * 0.01;
            var l = path.getTotalLength();
            dasharrayValue = '0 0 0 ' + l * s + ' ';
            var lineLength = l * (e - s);
            var segment = 1 + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
            var units = Math.floor(lineLength / segment);
            var j;
            for (j = 0; j < units; j += 1) {
              dasharrayValue += '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01 + ' ';
            }
            dasharrayValue += '0 ' + l * 10 + ' 0 0';
          } else {
            dasharrayValue = '1 ' + this.filterManager.effectElements[4].p.v * 2 * this.filterManager.effectElements[9].p.v * 0.01;
          }
          path.setAttribute('stroke-dasharray', dasharrayValue);
        }
      }
    }
    if (forceRender || this.filterManager.effectElements[4].p._mdf) {
      this.pathMasker.setAttribute('stroke-width', this.filterManager.effectElements[4].p.v * 2);
    }
    if (forceRender || this.filterManager.effectElements[6].p._mdf) {
      this.pathMasker.setAttribute('opacity', this.filterManager.effectElements[6].p.v);
    }
    if (this.filterManager.effectElements[10].p.v === 1 || this.filterManager.effectElements[10].p.v === 2) {
      if (forceRender || this.filterManager.effectElements[3].p._mdf) {
        var color = this.filterManager.effectElements[3].p.v;
        this.pathMasker.setAttribute('stroke', 'rgb(' + bmFloor(color[0] * 255) + ',' + bmFloor(color[1] * 255) + ',' + bmFloor(color[2] * 255) + ')');
      }
    }
  };
  function SVGTritoneFilter(filter, filterManager, elem, id) {
    this.filterManager = filterManager;
    var feColorMatrix = createNS('feColorMatrix');
    feColorMatrix.setAttribute('type', 'matrix');
    feColorMatrix.setAttribute('color-interpolation-filters', 'linearRGB');
    feColorMatrix.setAttribute('values', '0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0');
    filter.appendChild(feColorMatrix);
    var feComponentTransfer = createNS('feComponentTransfer');
    feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
    feComponentTransfer.setAttribute('result', id);
    this.matrixFilter = feComponentTransfer;
    var feFuncR = createNS('feFuncR');
    feFuncR.setAttribute('type', 'table');
    feComponentTransfer.appendChild(feFuncR);
    this.feFuncR = feFuncR;
    var feFuncG = createNS('feFuncG');
    feFuncG.setAttribute('type', 'table');
    feComponentTransfer.appendChild(feFuncG);
    this.feFuncG = feFuncG;
    var feFuncB = createNS('feFuncB');
    feFuncB.setAttribute('type', 'table');
    feComponentTransfer.appendChild(feFuncB);
    this.feFuncB = feFuncB;
    filter.appendChild(feComponentTransfer);
  }
  SVGTritoneFilter.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      var color1 = this.filterManager.effectElements[0].p.v;
      var color2 = this.filterManager.effectElements[1].p.v;
      var color3 = this.filterManager.effectElements[2].p.v;
      var tableR = color3[0] + ' ' + color2[0] + ' ' + color1[0];
      var tableG = color3[1] + ' ' + color2[1] + ' ' + color1[1];
      var tableB = color3[2] + ' ' + color2[2] + ' ' + color1[2];
      this.feFuncR.setAttribute('tableValues', tableR);
      this.feFuncG.setAttribute('tableValues', tableG);
      this.feFuncB.setAttribute('tableValues', tableB);
    }
  };
  function SVGProLevelsFilter(filter, filterManager, elem, id) {
    this.filterManager = filterManager;
    var effectElements = this.filterManager.effectElements;
    var feComponentTransfer = createNS('feComponentTransfer');

    // Red
    if (effectElements[10].p.k || effectElements[10].p.v !== 0 || effectElements[11].p.k || effectElements[11].p.v !== 1 || effectElements[12].p.k || effectElements[12].p.v !== 1 || effectElements[13].p.k || effectElements[13].p.v !== 0 || effectElements[14].p.k || effectElements[14].p.v !== 1) {
      this.feFuncR = this.createFeFunc('feFuncR', feComponentTransfer);
    }
    // Green
    if (effectElements[17].p.k || effectElements[17].p.v !== 0 || effectElements[18].p.k || effectElements[18].p.v !== 1 || effectElements[19].p.k || effectElements[19].p.v !== 1 || effectElements[20].p.k || effectElements[20].p.v !== 0 || effectElements[21].p.k || effectElements[21].p.v !== 1) {
      this.feFuncG = this.createFeFunc('feFuncG', feComponentTransfer);
    }
    // Blue
    if (effectElements[24].p.k || effectElements[24].p.v !== 0 || effectElements[25].p.k || effectElements[25].p.v !== 1 || effectElements[26].p.k || effectElements[26].p.v !== 1 || effectElements[27].p.k || effectElements[27].p.v !== 0 || effectElements[28].p.k || effectElements[28].p.v !== 1) {
      this.feFuncB = this.createFeFunc('feFuncB', feComponentTransfer);
    }
    // Alpha
    if (effectElements[31].p.k || effectElements[31].p.v !== 0 || effectElements[32].p.k || effectElements[32].p.v !== 1 || effectElements[33].p.k || effectElements[33].p.v !== 1 || effectElements[34].p.k || effectElements[34].p.v !== 0 || effectElements[35].p.k || effectElements[35].p.v !== 1) {
      this.feFuncA = this.createFeFunc('feFuncA', feComponentTransfer);
    }
    // RGB
    if (this.feFuncR || this.feFuncG || this.feFuncB || this.feFuncA) {
      feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
      filter.appendChild(feComponentTransfer);
    }
    if (effectElements[3].p.k || effectElements[3].p.v !== 0 || effectElements[4].p.k || effectElements[4].p.v !== 1 || effectElements[5].p.k || effectElements[5].p.v !== 1 || effectElements[6].p.k || effectElements[6].p.v !== 0 || effectElements[7].p.k || effectElements[7].p.v !== 1) {
      feComponentTransfer = createNS('feComponentTransfer');
      feComponentTransfer.setAttribute('color-interpolation-filters', 'sRGB');
      feComponentTransfer.setAttribute('result', id);
      filter.appendChild(feComponentTransfer);
      this.feFuncRComposed = this.createFeFunc('feFuncR', feComponentTransfer);
      this.feFuncGComposed = this.createFeFunc('feFuncG', feComponentTransfer);
      this.feFuncBComposed = this.createFeFunc('feFuncB', feComponentTransfer);
    }
  }
  SVGProLevelsFilter.prototype.createFeFunc = function (type, feComponentTransfer) {
    var feFunc = createNS(type);
    feFunc.setAttribute('type', 'table');
    feComponentTransfer.appendChild(feFunc);
    return feFunc;
  };
  SVGProLevelsFilter.prototype.getTableValue = function (inputBlack, inputWhite, gamma, outputBlack, outputWhite) {
    var cnt = 0;
    var segments = 256;
    var perc;
    var min = Math.min(inputBlack, inputWhite);
    var max = Math.max(inputBlack, inputWhite);
    var table = Array.call(null, {
      length: segments
    });
    var colorValue;
    var pos = 0;
    var outputDelta = outputWhite - outputBlack;
    var inputDelta = inputWhite - inputBlack;
    while (cnt <= 256) {
      perc = cnt / 256;
      if (perc <= min) {
        colorValue = inputDelta < 0 ? outputWhite : outputBlack;
      } else if (perc >= max) {
        colorValue = inputDelta < 0 ? outputBlack : outputWhite;
      } else {
        colorValue = outputBlack + outputDelta * Math.pow((perc - inputBlack) / inputDelta, 1 / gamma);
      }
      table[pos] = colorValue;
      pos += 1;
      cnt += 256 / (segments - 1);
    }
    return table.join(' ');
  };
  SVGProLevelsFilter.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      var val;
      var effectElements = this.filterManager.effectElements;
      if (this.feFuncRComposed && (forceRender || effectElements[3].p._mdf || effectElements[4].p._mdf || effectElements[5].p._mdf || effectElements[6].p._mdf || effectElements[7].p._mdf)) {
        val = this.getTableValue(effectElements[3].p.v, effectElements[4].p.v, effectElements[5].p.v, effectElements[6].p.v, effectElements[7].p.v);
        this.feFuncRComposed.setAttribute('tableValues', val);
        this.feFuncGComposed.setAttribute('tableValues', val);
        this.feFuncBComposed.setAttribute('tableValues', val);
      }
      if (this.feFuncR && (forceRender || effectElements[10].p._mdf || effectElements[11].p._mdf || effectElements[12].p._mdf || effectElements[13].p._mdf || effectElements[14].p._mdf)) {
        val = this.getTableValue(effectElements[10].p.v, effectElements[11].p.v, effectElements[12].p.v, effectElements[13].p.v, effectElements[14].p.v);
        this.feFuncR.setAttribute('tableValues', val);
      }
      if (this.feFuncG && (forceRender || effectElements[17].p._mdf || effectElements[18].p._mdf || effectElements[19].p._mdf || effectElements[20].p._mdf || effectElements[21].p._mdf)) {
        val = this.getTableValue(effectElements[17].p.v, effectElements[18].p.v, effectElements[19].p.v, effectElements[20].p.v, effectElements[21].p.v);
        this.feFuncG.setAttribute('tableValues', val);
      }
      if (this.feFuncB && (forceRender || effectElements[24].p._mdf || effectElements[25].p._mdf || effectElements[26].p._mdf || effectElements[27].p._mdf || effectElements[28].p._mdf)) {
        val = this.getTableValue(effectElements[24].p.v, effectElements[25].p.v, effectElements[26].p.v, effectElements[27].p.v, effectElements[28].p.v);
        this.feFuncB.setAttribute('tableValues', val);
      }
      if (this.feFuncA && (forceRender || effectElements[31].p._mdf || effectElements[32].p._mdf || effectElements[33].p._mdf || effectElements[34].p._mdf || effectElements[35].p._mdf)) {
        val = this.getTableValue(effectElements[31].p.v, effectElements[32].p.v, effectElements[33].p.v, effectElements[34].p.v, effectElements[35].p.v);
        this.feFuncA.setAttribute('tableValues', val);
      }
    }
  };
  function SVGDropShadowEffect(filter, filterManager, elem, id, source) {
    var globalFilterSize = filterManager.container.globalData.renderConfig.filterSize;
    var filterSize = filterManager.data.fs || globalFilterSize;
    filter.setAttribute('x', filterSize.x || globalFilterSize.x);
    filter.setAttribute('y', filterSize.y || globalFilterSize.y);
    filter.setAttribute('width', filterSize.width || globalFilterSize.width);
    filter.setAttribute('height', filterSize.height || globalFilterSize.height);
    this.filterManager = filterManager;
    var feGaussianBlur = createNS('feGaussianBlur');
    feGaussianBlur.setAttribute('in', 'SourceAlpha');
    feGaussianBlur.setAttribute('result', id + '_drop_shadow_1');
    feGaussianBlur.setAttribute('stdDeviation', '0');
    this.feGaussianBlur = feGaussianBlur;
    filter.appendChild(feGaussianBlur);
    var feOffset = createNS('feOffset');
    feOffset.setAttribute('dx', '25');
    feOffset.setAttribute('dy', '0');
    feOffset.setAttribute('in', id + '_drop_shadow_1');
    feOffset.setAttribute('result', id + '_drop_shadow_2');
    this.feOffset = feOffset;
    filter.appendChild(feOffset);
    var feFlood = createNS('feFlood');
    feFlood.setAttribute('flood-color', '#00ff00');
    feFlood.setAttribute('flood-opacity', '1');
    feFlood.setAttribute('result', id + '_drop_shadow_3');
    this.feFlood = feFlood;
    filter.appendChild(feFlood);
    var feComposite = createNS('feComposite');
    feComposite.setAttribute('in', id + '_drop_shadow_3');
    feComposite.setAttribute('in2', id + '_drop_shadow_2');
    feComposite.setAttribute('operator', 'in');
    feComposite.setAttribute('result', id + '_drop_shadow_4');
    filter.appendChild(feComposite);
    var feMerge = this.createMergeNode(id, [id + '_drop_shadow_4', source]);
    filter.appendChild(feMerge);
    //
  }
  extendPrototype([SVGComposableEffect], SVGDropShadowEffect);
  SVGDropShadowEffect.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      if (forceRender || this.filterManager.effectElements[4].p._mdf) {
        this.feGaussianBlur.setAttribute('stdDeviation', this.filterManager.effectElements[4].p.v / 4);
      }
      if (forceRender || this.filterManager.effectElements[0].p._mdf) {
        var col = this.filterManager.effectElements[0].p.v;
        this.feFlood.setAttribute('flood-color', rgbToHex(Math.round(col[0] * 255), Math.round(col[1] * 255), Math.round(col[2] * 255)));
      }
      if (forceRender || this.filterManager.effectElements[1].p._mdf) {
        this.feFlood.setAttribute('flood-opacity', this.filterManager.effectElements[1].p.v / 255);
      }
      if (forceRender || this.filterManager.effectElements[2].p._mdf || this.filterManager.effectElements[3].p._mdf) {
        var distance = this.filterManager.effectElements[3].p.v;
        var angle = (this.filterManager.effectElements[2].p.v - 90) * degToRads;
        var x = distance * Math.cos(angle);
        var y = distance * Math.sin(angle);
        this.feOffset.setAttribute('dx', x);
        this.feOffset.setAttribute('dy', y);
      }
    }
  };
  var _svgMatteSymbols = [];
  function SVGMatte3Effect(filterElem, filterManager, elem) {
    this.initialized = false;
    this.filterManager = filterManager;
    this.filterElem = filterElem;
    this.elem = elem;
    elem.matteElement = createNS('g');
    elem.matteElement.appendChild(elem.layerElement);
    elem.matteElement.appendChild(elem.transformedElement);
    elem.baseElement = elem.matteElement;
  }
  SVGMatte3Effect.prototype.findSymbol = function (mask) {
    var i = 0;
    var len = _svgMatteSymbols.length;
    while (i < len) {
      if (_svgMatteSymbols[i] === mask) {
        return _svgMatteSymbols[i];
      }
      i += 1;
    }
    return null;
  };
  SVGMatte3Effect.prototype.replaceInParent = function (mask, symbolId) {
    var parentNode = mask.layerElement.parentNode;
    if (!parentNode) {
      return;
    }
    var children = parentNode.children;
    var i = 0;
    var len = children.length;
    while (i < len) {
      if (children[i] === mask.layerElement) {
        break;
      }
      i += 1;
    }
    var nextChild;
    if (i <= len - 2) {
      nextChild = children[i + 1];
    }
    var useElem = createNS('use');
    useElem.setAttribute('href', '#' + symbolId);
    if (nextChild) {
      parentNode.insertBefore(useElem, nextChild);
    } else {
      parentNode.appendChild(useElem);
    }
  };
  SVGMatte3Effect.prototype.setElementAsMask = function (elem, mask) {
    if (!this.findSymbol(mask)) {
      var symbolId = createElementID();
      var masker = createNS('mask');
      masker.setAttribute('id', mask.layerId);
      masker.setAttribute('mask-type', 'alpha');
      _svgMatteSymbols.push(mask);
      var defs = elem.globalData.defs;
      defs.appendChild(masker);
      var symbol = createNS('symbol');
      symbol.setAttribute('id', symbolId);
      this.replaceInParent(mask, symbolId);
      symbol.appendChild(mask.layerElement);
      defs.appendChild(symbol);
      var useElem = createNS('use');
      useElem.setAttribute('href', '#' + symbolId);
      masker.appendChild(useElem);
      mask.data.hd = false;
      mask.show();
    }
    elem.setMatte(mask.layerId);
  };
  SVGMatte3Effect.prototype.initialize = function () {
    var ind = this.filterManager.effectElements[0].p.v;
    var elements = this.elem.comp.elements;
    var i = 0;
    var len = elements.length;
    while (i < len) {
      if (elements[i] && elements[i].data.ind === ind) {
        this.setElementAsMask(this.elem, elements[i]);
      }
      i += 1;
    }
    this.initialized = true;
  };
  SVGMatte3Effect.prototype.renderFrame = function () {
    if (!this.initialized) {
      this.initialize();
    }
  };
  function SVGGaussianBlurEffect(filter, filterManager, elem, id) {
    // Outset the filter region by 100% on all sides to accommodate blur expansion.
    filter.setAttribute('x', '-100%');
    filter.setAttribute('y', '-100%');
    filter.setAttribute('width', '300%');
    filter.setAttribute('height', '300%');
    this.filterManager = filterManager;
    var feGaussianBlur = createNS('feGaussianBlur');
    feGaussianBlur.setAttribute('result', id);
    filter.appendChild(feGaussianBlur);
    this.feGaussianBlur = feGaussianBlur;
  }
  SVGGaussianBlurEffect.prototype.renderFrame = function (forceRender) {
    if (forceRender || this.filterManager._mdf) {
      // Empirical value, matching AE's blur appearance.
      var kBlurrinessToSigma = 0.3;
      var sigma = this.filterManager.effectElements[0].p.v * kBlurrinessToSigma;

      // Dimensions mapping:
      //
      //   1 -> horizontal & vertical
      //   2 -> horizontal only
      //   3 -> vertical only
      //
      var dimensions = this.filterManager.effectElements[1].p.v;
      var sigmaX = dimensions == 3 ? 0 : sigma; // eslint-disable-line eqeqeq
      var sigmaY = dimensions == 2 ? 0 : sigma; // eslint-disable-line eqeqeq

      this.feGaussianBlur.setAttribute('stdDeviation', sigmaX + ' ' + sigmaY);

      // Repeat edges mapping:
      //
      //   0 -> off -> duplicate
      //   1 -> on  -> wrap
      var edgeMode = this.filterManager.effectElements[2].p.v == 1 ? 'wrap' : 'duplicate'; // eslint-disable-line eqeqeq
      this.feGaussianBlur.setAttribute('edgeMode', edgeMode);
    }
  };
  function TransformEffect() {}
  TransformEffect.prototype.init = function (effectsManager) {
    this.effectsManager = effectsManager;
    this.type = effectTypes.TRANSFORM_EFFECT;
    this.matrix = new Matrix();
    this.opacity = -1;
    this._mdf = false;
    this._opMdf = false;
  };
  TransformEffect.prototype.renderFrame = function (forceFrame) {
    this._opMdf = false;
    this._mdf = false;
    if (forceFrame || this.effectsManager._mdf) {
      var effectElements = this.effectsManager.effectElements;
      var anchor = effectElements[0].p.v;
      var position = effectElements[1].p.v;
      var isUniformScale = effectElements[2].p.v === 1;
      var scaleHeight = effectElements[3].p.v;
      var scaleWidth = isUniformScale ? scaleHeight : effectElements[4].p.v;
      var skew = effectElements[5].p.v;
      var skewAxis = effectElements[6].p.v;
      var rotation = effectElements[7].p.v;
      this.matrix.reset();
      this.matrix.translate(-anchor[0], -anchor[1], anchor[2]);
      this.matrix.scale(scaleWidth * 0.01, scaleHeight * 0.01, 1);
      this.matrix.rotate(-rotation * degToRads);
      this.matrix.skewFromAxis(-skew * degToRads, (skewAxis + 90) * degToRads);
      this.matrix.translate(position[0], position[1], 0);
      this._mdf = true;
      if (this.opacity !== effectElements[8].p.v) {
        this.opacity = effectElements[8].p.v;
        this._opMdf = true;
      }
    }
  };
  function SVGTransformEffect(_, filterManager) {
    this.init(filterManager);
  }
  extendPrototype([TransformEffect], SVGTransformEffect);
  function CVTransformEffect(effectsManager) {
    this.init(effectsManager);
  }
  extendPrototype([TransformEffect], CVTransformEffect);

  // Registering renderers
  registerRenderer('canvas', CanvasRenderer);
  registerRenderer('html', HybridRenderer);
  registerRenderer('svg', SVGRenderer);

  // Registering shape modifiers
  ShapeModifiers.registerModifier('tm', TrimModifier);
  ShapeModifiers.registerModifier('pb', PuckerAndBloatModifier);
  ShapeModifiers.registerModifier('rp', RepeaterModifier);
  ShapeModifiers.registerModifier('rd', RoundCornersModifier);
  ShapeModifiers.registerModifier('zz', ZigZagModifier);
  ShapeModifiers.registerModifier('op', OffsetPathModifier);

  // Registering expression plugin
  setExpressionsPlugin(Expressions);
  setExpressionInterfaces(getInterface);
  initialize$1();
  initialize();

  // Registering svg effects
  registerEffect$1(20, SVGTintFilter, true);
  registerEffect$1(21, SVGFillFilter, true);
  registerEffect$1(22, SVGStrokeEffect, false);
  registerEffect$1(23, SVGTritoneFilter, true);
  registerEffect$1(24, SVGProLevelsFilter, true);
  registerEffect$1(25, SVGDropShadowEffect, true);
  registerEffect$1(28, SVGMatte3Effect, false);
  registerEffect$1(29, SVGGaussianBlurEffect, true);
  registerEffect$1(35, SVGTransformEffect, false);
  registerEffect(35, CVTransformEffect);
  return lottie;
});

/***/ }),

/***/ 6311:
/*!*****************************************!*\
  !*** ./node_modules/ngx-csv/ngx-csv.js ***!
  \*****************************************/
/***/ ((__unused_webpack_module, exports) => {

"use strict";


Object.defineProperty(exports, "__esModule", ({
  value: true
}));
var CsvConfigConsts = function () {
  function CsvConfigConsts() {}
  CsvConfigConsts.EOL = "\r\n";
  CsvConfigConsts.BOM = "\ufeff";
  CsvConfigConsts.DEFAULT_FIELD_SEPARATOR = ',';
  CsvConfigConsts.DEFAULT_DECIMAL_SEPARATOR = '.';
  CsvConfigConsts.DEFAULT_QUOTE = '"';
  CsvConfigConsts.DEFAULT_SHOW_TITLE = false;
  CsvConfigConsts.DEFAULT_TITLE = 'My Report';
  CsvConfigConsts.DEFAULT_FILENAME = 'mycsv.csv';
  CsvConfigConsts.DEFAULT_SHOW_LABELS = false;
  CsvConfigConsts.DEFAULT_USE_BOM = true;
  CsvConfigConsts.DEFAULT_HEADER = [];
  CsvConfigConsts.DEFAULT_NO_DOWNLOAD = false;
  CsvConfigConsts.DEFAULT_REMOVE_EMPTY_VALUES = false;
  return CsvConfigConsts;
}();
exports.CsvConfigConsts = CsvConfigConsts;
exports.ConfigDefaults = {
  filename: CsvConfigConsts.DEFAULT_FILENAME,
  fieldSeparator: CsvConfigConsts.DEFAULT_FIELD_SEPARATOR,
  quoteStrings: CsvConfigConsts.DEFAULT_QUOTE,
  decimalseparator: CsvConfigConsts.DEFAULT_DECIMAL_SEPARATOR,
  showLabels: CsvConfigConsts.DEFAULT_SHOW_LABELS,
  showTitle: CsvConfigConsts.DEFAULT_SHOW_TITLE,
  title: CsvConfigConsts.DEFAULT_TITLE,
  useBom: CsvConfigConsts.DEFAULT_USE_BOM,
  headers: CsvConfigConsts.DEFAULT_HEADER,
  noDownload: CsvConfigConsts.DEFAULT_NO_DOWNLOAD,
  removeEmptyValues: CsvConfigConsts.DEFAULT_REMOVE_EMPTY_VALUES
};
var ngxCsv = function () {
  function ngxCsv(DataJSON, filename, options) {
    this.csv = "";
    var config = options || {};
    this.data = typeof DataJSON != 'object' ? JSON.parse(DataJSON) : DataJSON;
    this._options = objectAssign({}, exports.ConfigDefaults, config);
    if (this._options.filename) {
      this._options.filename = filename;
    }
    this.generateCsv();
  }
  /**
   * Generate and Download Csv
   */
  ngxCsv.prototype.generateCsv = function () {
    if (this._options.useBom) {
      this.csv += CsvConfigConsts.BOM;
    }
    if (this._options.showTitle) {
      this.csv += this._options.title + '\r\n\n';
    }
    this.getHeaders();
    this.getBody();
    if (this.csv == '') {
      console.log("Invalid data");
      return;
    }
    if (this._options.noDownload) {
      return this.csv;
    }
    var blob = new Blob([this.csv], {
      "type": "text/csv;charset=utf8;"
    });
    if (navigator.msSaveBlob) {
      var filename = this._options.filename.replace(/ /g, "_") + ".csv";
      navigator.msSaveBlob(blob, filename);
    } else {
      var uri = 'data:attachment/csv;charset=utf-8,' + encodeURI(this.csv);
      var link = document.createElement("a");
      link.href = URL.createObjectURL(blob);
      link.setAttribute('visibility', 'hidden');
      link.download = this._options.filename.replace(/ /g, "_") + ".csv";
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    }
  };
  /**
   * Create Headers
   */
  ngxCsv.prototype.getHeaders = function () {
    var _this = this;
    if (this._options.headers.length > 0) {
      var headers = this._options.headers;
      var row = headers.reduce(function (headerRow, header) {
        return headerRow + header + _this._options.fieldSeparator;
      }, '');
      row = row.slice(0, -1);
      this.csv += row + CsvConfigConsts.EOL;
    }
  };
  /**
   * Create Body
   */
  ngxCsv.prototype.getBody = function () {
    for (var i = 0; i < this.data.length; i++) {
      var row = "";
      for (var index in this.data[i]) {
        row += this.formartData(this.data[i][index]) + this._options.fieldSeparator;
      }
      row = row.slice(0, -1);
      this.csv += row + CsvConfigConsts.EOL;
    }
  };
  /**
   * Format Data
   * @param {any} data
   */
  ngxCsv.prototype.formartData = function (data) {
    if (this._options.removeEmptyValues && !data) {
      return "";
    }
    if (this._options.decimalseparator === 'locale' && ngxCsv.isFloat(data)) {
      return data.toLocaleString();
    }
    if (this._options.decimalseparator !== '.' && ngxCsv.isFloat(data)) {
      return data.toString().replace('.', this._options.decimalseparator);
    }
    if (typeof data === 'string') {
      data = data.replace(/"/g, '""');
      if (this._options.quoteStrings || data.indexOf(',') > -1 || data.indexOf('\n') > -1 || data.indexOf('\r') > -1) {
        data = this._options.quoteStrings + data + this._options.quoteStrings;
      }
      return data;
    }
    if (typeof data === 'boolean') {
      return data ? 'TRUE' : 'FALSE';
    }
    return data;
  };
  /**
   * Get CSV String
   */
  ngxCsv.prototype.getCsv = function () {
    return this.csv;
  };
  /**
   * Check if is Float
   * @param {any} input
   */
  ngxCsv.isFloat = function (input) {
    return +input === input && (!isFinite(input) || Boolean(input % 1));
  };
  return ngxCsv;
}();
exports.ngxCsv = ngxCsv;
var hasOwnProperty = Object.prototype.hasOwnProperty;
var propIsEnumerable = Object.prototype.propertyIsEnumerable;
/**
 * Convet to Object
 * @param {any} val
 */
function toObject(val) {
  if (val === null || val === undefined) {
    throw new TypeError('Object.assign cannot be called with null or undefined');
  }
  return Object(val);
}
/**
 * Assign data  to new Object
 * @param {any}   target
 * @param {any[]} ...source
 */
function objectAssign(target) {
  var source = [];
  for (var _i = 1; _i < arguments.length; _i++) {
    source[_i - 1] = arguments[_i];
  }
  var from;
  var to = toObject(target);
  var symbols;
  for (var s = 1; s < arguments.length; s++) {
    from = Object(arguments[s]);
    for (var key in from) {
      if (hasOwnProperty.call(from, key)) {
        to[key] = from[key];
      }
    }
    if (Object.getOwnPropertySymbols) {
      symbols = Object.getOwnPropertySymbols(from);
      for (var i = 0; i < symbols.length; i++) {
        if (propIsEnumerable.call(from, symbols[i])) {
          to[symbols[i]] = from[symbols[i]];
        }
      }
    }
  }
  return to;
}

/***/ }),

/***/ 36736:
/*!********************************************!*\
  !*** ./node_modules/ngx-lightbox/index.js ***!
  \********************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LIGHTBOX_EVENT: () => (/* reexport safe */ _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LIGHTBOX_EVENT),
/* harmony export */   Lightbox: () => (/* reexport safe */ _lightbox_service__WEBPACK_IMPORTED_MODULE_0__.Lightbox),
/* harmony export */   LightboxConfig: () => (/* reexport safe */ _lightbox_config_service__WEBPACK_IMPORTED_MODULE_1__.LightboxConfig),
/* harmony export */   LightboxEvent: () => (/* reexport safe */ _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LightboxEvent),
/* harmony export */   LightboxModule: () => (/* reexport safe */ _lightbox_module__WEBPACK_IMPORTED_MODULE_3__.LightboxModule)
/* harmony export */ });
/* harmony import */ var _lightbox_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightbox.service */ 37914);
/* harmony import */ var _lightbox_config_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lightbox-config.service */ 41967);
/* harmony import */ var _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lightbox-event.service */ 60543);
/* harmony import */ var _lightbox_module__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lightbox.module */ 60497);





/***/ }),

/***/ 41967:
/*!**************************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox-config.service.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LightboxConfig: () => (/* binding */ LightboxConfig)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);


class LightboxConfig {
  constructor() {
    this.fadeDuration = 0.7;
    this.resizeDuration = 0.5;
    this.fitImageInViewPort = true;
    this.positionFromTop = 20;
    this.showImageNumberLabel = false;
    this.alwaysShowNavOnTouchDevices = false;
    this.wrapAround = false;
    this.disableKeyboardNav = false;
    this.disableScrolling = false;
    this.centerVertically = false;
    this.enableTransition = true;
    this.albumLabel = 'Image %1 of %2';
    this.showZoom = false;
    this.showRotate = false;
    this.containerElementResolver = documentRef => documentRef.querySelector('body');
  }
}
LightboxConfig.ɵfac = function LightboxConfig_Factory(t) {
  return new (t || LightboxConfig)();
};
LightboxConfig.ɵprov = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
  token: LightboxConfig,
  factory: LightboxConfig.ɵfac
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LightboxConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], function () {
    return [];
  }, null);
})();

/***/ }),

/***/ 60543:
/*!*************************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox-event.service.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LIGHTBOX_EVENT: () => (/* binding */ LIGHTBOX_EVENT),
/* harmony export */   LightboxEvent: () => (/* binding */ LightboxEvent),
/* harmony export */   LightboxWindowRef: () => (/* binding */ LightboxWindowRef)
/* harmony export */ });
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);



const LIGHTBOX_EVENT = {
  CHANGE_PAGE: 1,
  CLOSE: 2,
  OPEN: 3,
  ZOOM_IN: 4,
  ZOOM_OUT: 5,
  ROTATE_LEFT: 6,
  ROTATE_RIGHT: 7
};
class LightboxEvent {
  constructor() {
    this._lightboxEventSource = new rxjs__WEBPACK_IMPORTED_MODULE_0__.Subject();
    this.lightboxEvent$ = this._lightboxEventSource.asObservable();
  }
  broadcastLightboxEvent(event) {
    this._lightboxEventSource.next(event);
  }
}
LightboxEvent.ɵfac = function LightboxEvent_Factory(t) {
  return new (t || LightboxEvent)();
};
LightboxEvent.ɵprov = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
  token: LightboxEvent,
  factory: LightboxEvent.ɵfac
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LightboxEvent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], function () {
    return [];
  }, null);
})();
function getWindow() {
  return window;
}
class LightboxWindowRef {
  get nativeWindow() {
    return getWindow();
  }
}
LightboxWindowRef.ɵfac = function LightboxWindowRef_Factory(t) {
  return new (t || LightboxWindowRef)();
};
LightboxWindowRef.ɵprov = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
  token: LightboxWindowRef,
  factory: LightboxWindowRef.ɵfac
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LightboxWindowRef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();

/***/ }),

/***/ 3763:
/*!*****************************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox-overlay.component.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LightboxOverlayComponent: () => (/* binding */ LightboxOverlayComponent)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightbox-event.service */ 60543);





const _c0 = ["lb-overlay", ""];
class LightboxOverlayComponent {
  constructor(_elemRef, _rendererRef, _lightboxEvent, _documentRef) {
    this._elemRef = _elemRef;
    this._rendererRef = _rendererRef;
    this._lightboxEvent = _lightboxEvent;
    this._documentRef = _documentRef;
    this.classList = 'lightboxOverlay animation fadeInOverlay';
    this._subscription = this._lightboxEvent.lightboxEvent$.subscribe(event => this._onReceivedEvent(event));
  }
  close() {
    // broadcast to itself and all others subscriber including the components
    this._lightboxEvent.broadcastLightboxEvent({
      id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CLOSE,
      data: null
    });
  }
  ngAfterViewInit() {
    const fadeDuration = this.options.fadeDuration;
    this._rendererRef.setStyle(this._elemRef.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._elemRef.nativeElement, 'animation-duration', `${fadeDuration}s`);
    this._sizeOverlay();
  }
  onResize() {
    this._sizeOverlay();
  }
  ngOnDestroy() {
    this._subscription.unsubscribe();
  }
  _sizeOverlay() {
    const width = this._getOverlayWidth();
    const height = this._getOverlayHeight();
    this._rendererRef.setStyle(this._elemRef.nativeElement, 'width', `${width}px`);
    this._rendererRef.setStyle(this._elemRef.nativeElement, 'height', `${height}px`);
  }
  _onReceivedEvent(event) {
    switch (event.id) {
      case _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CLOSE:
        this._end();
        break;
      default:
        break;
    }
  }
  _end() {
    this.classList = 'lightboxOverlay animation fadeOutOverlay';
    // queue self destruction after the animation has finished
    // FIXME: not sure if there is any way better than this
    setTimeout(() => {
      this.cmpRef.destroy();
    }, this.options.fadeDuration * 1000);
  }
  _getOverlayWidth() {
    return Math.max(this._documentRef.body.scrollWidth, this._documentRef.body.offsetWidth, this._documentRef.documentElement.clientWidth, this._documentRef.documentElement.scrollWidth, this._documentRef.documentElement.offsetWidth);
  }
  _getOverlayHeight() {
    return Math.max(this._documentRef.body.scrollHeight, this._documentRef.body.offsetHeight, this._documentRef.documentElement.clientHeight, this._documentRef.documentElement.scrollHeight, this._documentRef.documentElement.offsetHeight);
  }
}
LightboxOverlayComponent.ɵfac = function LightboxOverlayComponent_Factory(t) {
  return new (t || LightboxOverlayComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxEvent), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT));
};
LightboxOverlayComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
  type: LightboxOverlayComponent,
  selectors: [["", "lb-overlay", ""]],
  hostVars: 2,
  hostBindings: function LightboxOverlayComponent_HostBindings(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxOverlayComponent_click_HostBindingHandler() {
        return ctx.close();
      })("resize", function LightboxOverlayComponent_resize_HostBindingHandler() {
        return ctx.onResize();
      }, false, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵresolveWindow"]);
    }
    if (rf & 2) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵclassMap"](ctx.classList);
    }
  },
  inputs: {
    options: "options",
    cmpRef: "cmpRef"
  },
  attrs: _c0,
  decls: 0,
  vars: 0,
  template: function LightboxOverlayComponent_Template(rf, ctx) {},
  encapsulation: 2
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LightboxOverlayComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: '[lb-overlay]',
      template: '',
      host: {
        '[class]': 'classList'
      }
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2
    }, {
      type: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxEvent
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
      }]
    }];
  }, {
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    cmpRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    close: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['click']
    }],
    onResize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['window:resize']
    }]
  });
})();

/***/ }),

/***/ 83954:
/*!*********************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox.component.js ***!
  \*********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LightboxComponent: () => (/* binding */ LightboxComponent)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightbox-event.service */ 60543);
/* harmony import */ var ngx_filesaver__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ngx-filesaver */ 67227);
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/platform-browser */ 80436);









const _c0 = ["outerContainer"];
const _c1 = ["container"];
const _c2 = ["leftArrow"];
const _c3 = ["rightArrow"];
const _c4 = ["navArrow"];
const _c5 = ["dataContainer"];
const _c6 = ["image"];
const _c7 = ["caption"];
const _c8 = ["number"];
const _c9 = ["lb-content", ""];
class LightboxComponent {
  constructor(_elemRef, _rendererRef, _lightboxEvent, _lightboxElem, _lightboxWindowRef, _fileSaverService, _sanitizer, _documentRef) {
    this._elemRef = _elemRef;
    this._rendererRef = _rendererRef;
    this._lightboxEvent = _lightboxEvent;
    this._lightboxElem = _lightboxElem;
    this._lightboxWindowRef = _lightboxWindowRef;
    this._fileSaverService = _fileSaverService;
    this._sanitizer = _sanitizer;
    this._documentRef = _documentRef;
    // initialize data
    this.options = this.options || {};
    this.album = this.album || [];
    this.currentImageIndex = this.currentImageIndex || 0;
    this._windowRef = this._lightboxWindowRef.nativeWindow;
    // control the interactive of the directive
    this.ui = {
      // control the appear of the reloader
      // false: image has loaded completely and ready to be shown
      // true: image is still loading
      showReloader: true,
      // control the appear of the nav arrow
      // the arrowNav is the parent of both left and right arrow
      // in some cases, the parent shows but the child does not show
      showLeftArrow: false,
      showRightArrow: false,
      showArrowNav: false,
      // control the appear of the zoom and rotate buttons
      showZoomButton: false,
      showRotateButton: false,
      // control whether to show the
      // page number or not
      showPageNumber: false,
      showCaption: false,
      // control whether to show the download button or not
      showDownloadButton: false,
      classList: 'lightbox animation fadeIn'
    };
    this.content = {
      pageNumber: ''
    };
    this._event = {};
    this._lightboxElem = this._elemRef;
    this._event.subscription = this._lightboxEvent.lightboxEvent$.subscribe(event => this._onReceivedEvent(event));
    this.rotate = 0;
  }
  ngOnInit() {
    this.album.forEach(album => {
      if (album.caption) {
        album.caption = this._sanitizer.sanitize(_angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.HTML, album.caption);
      }
    });
  }
  ngAfterViewInit() {
    // need to init css value here, after the view ready
    // actually these values are always 0
    this._cssValue = {
      containerTopPadding: Math.round(this._getCssStyleValue(this._containerElem, 'padding-top')),
      containerRightPadding: Math.round(this._getCssStyleValue(this._containerElem, 'padding-right')),
      containerBottomPadding: Math.round(this._getCssStyleValue(this._containerElem, 'padding-bottom')),
      containerLeftPadding: Math.round(this._getCssStyleValue(this._containerElem, 'padding-left')),
      imageBorderWidthTop: Math.round(this._getCssStyleValue(this._imageElem, 'border-top-width')),
      imageBorderWidthBottom: Math.round(this._getCssStyleValue(this._imageElem, 'border-bottom-width')),
      imageBorderWidthLeft: Math.round(this._getCssStyleValue(this._imageElem, 'border-left-width')),
      imageBorderWidthRight: Math.round(this._getCssStyleValue(this._imageElem, 'border-right-width'))
    };
    if (this._validateInputData()) {
      this._prepareComponent();
      this._registerImageLoadingEvent();
    }
  }
  ngOnDestroy() {
    if (!this.options.disableKeyboardNav) {
      // unbind keyboard event
      this._disableKeyboardNav();
    }
    this._event.subscription.unsubscribe();
  }
  close($event) {
    $event.stopPropagation();
    if ($event.target.classList.contains('lightbox') || $event.target.classList.contains('lb-loader') || $event.target.classList.contains('lb-close')) {
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CLOSE,
        data: null
      });
    }
  }
  download($event) {
    $event.stopPropagation();
    const url = this.album[this.currentImageIndex].src;
    const downloadUrl = this.album[this.currentImageIndex].downloadUrl;
    const parts = url.split('/');
    const fileName = parts[parts.length - 1];
    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');
    const preloader = new Image();
    const _this = this;
    preloader.onload = function () {
      // @ts-ignore
      canvas.width = this.naturalWidth;
      // @ts-ignore
      canvas.height = this.naturalHeight;
      // @ts-ignore
      ctx.drawImage(this, 0, 0);
      canvas.toBlob(function (blob) {
        _this._fileSaverService.save(blob, fileName);
      }, 'image/jpeg', 0.75);
    };
    preloader.crossOrigin = '';
    if (downloadUrl && downloadUrl.length > 0) preloader.src = this._sanitizer.sanitize(_angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.URL, downloadUrl);else preloader.src = this._sanitizer.sanitize(_angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.URL, url);
  }
  control($event) {
    $event.stopPropagation();
    let height;
    let width;
    if ($event.target.classList.contains('lb-turnLeft')) {
      this.rotate = this.rotate - 90;
      this._rotateContainer();
      this._calcTransformPoint();
      this._documentRef.getElementById('image').style.transform = `rotate(${this.rotate}deg)`;
      this._documentRef.getElementById('image').style.webkitTransform = `rotate(${this.rotate}deg)`;
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.ROTATE_LEFT,
        data: null
      });
    } else if ($event.target.classList.contains('lb-turnRight')) {
      this.rotate = this.rotate + 90;
      this._rotateContainer();
      this._calcTransformPoint();
      this._documentRef.getElementById('image').style.transform = `rotate(${this.rotate}deg)`;
      this._documentRef.getElementById('image').style.webkitTransform = `rotate(${this.rotate}deg)`;
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.ROTATE_RIGHT,
        data: null
      });
    } else if ($event.target.classList.contains('lb-zoomOut')) {
      height = parseInt(this._documentRef.getElementById('outerContainer').style.height, 10) / 1.5;
      width = parseInt(this._documentRef.getElementById('outerContainer').style.width, 10) / 1.5;
      this._documentRef.getElementById('outerContainer').style.height = height + 'px';
      this._documentRef.getElementById('outerContainer').style.width = width + 'px';
      height = parseInt(this._documentRef.getElementById('image').style.height, 10) / 1.5;
      width = parseInt(this._documentRef.getElementById('image').style.width, 10) / 1.5;
      this._documentRef.getElementById('image').style.height = height + 'px';
      this._documentRef.getElementById('image').style.width = width + 'px';
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.ZOOM_OUT,
        data: null
      });
    } else if ($event.target.classList.contains('lb-zoomIn')) {
      height = parseInt(this._documentRef.getElementById('outerContainer').style.height, 10) * 1.5;
      width = parseInt(this._documentRef.getElementById('outerContainer').style.width, 10) * 1.5;
      this._documentRef.getElementById('outerContainer').style.height = height + 'px';
      this._documentRef.getElementById('outerContainer').style.width = width + 'px';
      height = parseInt(this._documentRef.getElementById('image').style.height, 10) * 1.5;
      width = parseInt(this._documentRef.getElementById('image').style.width, 10) * 1.5;
      this._documentRef.getElementById('image').style.height = height + 'px';
      this._documentRef.getElementById('image').style.width = width + 'px';
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.ZOOM_IN,
        data: null
      });
    }
  }
  _rotateContainer() {
    let temp = this.rotate;
    if (temp < 0) {
      temp *= -1;
    }
    if (temp / 90 % 4 === 1 || temp / 90 % 4 === 3) {
      this._documentRef.getElementById('outerContainer').style.height = this._documentRef.getElementById('image').style.width;
      this._documentRef.getElementById('outerContainer').style.width = this._documentRef.getElementById('image').style.height;
      this._documentRef.getElementById('container').style.height = this._documentRef.getElementById('image').style.width;
      this._documentRef.getElementById('container').style.width = this._documentRef.getElementById('image').style.height;
    } else {
      this._documentRef.getElementById('outerContainer').style.height = this._documentRef.getElementById('image').style.height;
      this._documentRef.getElementById('outerContainer').style.width = this._documentRef.getElementById('image').style.width;
      this._documentRef.getElementById('container').style.height = this._documentRef.getElementById('image').style.width;
      this._documentRef.getElementById('container').style.width = this._documentRef.getElementById('image').style.height;
    }
  }
  _resetImage() {
    this.rotate = 0;
    this._documentRef.getElementById('image').style.transform = `rotate(${this.rotate}deg)`;
    this._documentRef.getElementById('image').style.webkitTransform = `rotate(${this.rotate}deg)`;
  }
  _calcTransformPoint() {
    let height = parseInt(this._documentRef.getElementById('image').style.height, 10);
    let width = parseInt(this._documentRef.getElementById('image').style.width, 10);
    let temp = this.rotate % 360;
    if (temp < 0) {
      temp = 360 + temp;
    }
    if (temp === 90) {
      this._documentRef.getElementById('image').style.transformOrigin = height / 2 + 'px ' + height / 2 + 'px';
    } else if (temp === 180) {
      this._documentRef.getElementById('image').style.transformOrigin = width / 2 + 'px ' + height / 2 + 'px';
    } else if (temp === 270) {
      this._documentRef.getElementById('image').style.transformOrigin = width / 2 + 'px ' + width / 2 + 'px';
    }
  }
  nextImage() {
    if (this.album.length === 1) {
      return;
    } else if (this.currentImageIndex === this.album.length - 1) {
      this._changeImage(0);
    } else {
      this._changeImage(this.currentImageIndex + 1);
    }
  }
  prevImage() {
    if (this.album.length === 1) {
      return;
    } else if (this.currentImageIndex === 0 && this.album.length > 1) {
      this._changeImage(this.album.length - 1);
    } else {
      this._changeImage(this.currentImageIndex - 1);
    }
  }
  _validateInputData() {
    if (this.album && this.album instanceof Array && this.album.length > 0) {
      for (let i = 0; i < this.album.length; i++) {
        // check whether each _nside
        // album has src data or not
        if (this.album[i].src) {
          continue;
        }
        throw new Error('One of the album data does not have source data');
      }
    } else {
      throw new Error('No album data or album data is not correct in type');
    }
    // to prevent data understand as string
    // convert it to number
    if (isNaN(this.currentImageIndex)) {
      throw new Error('Current image index is not a number');
    } else {
      this.currentImageIndex = Number(this.currentImageIndex);
    }
    return true;
  }
  _registerImageLoadingEvent() {
    const preloader = new Image();
    preloader.onload = () => {
      this._onLoadImageSuccess();
    };
    const src = this.album[this.currentImageIndex].src;
    preloader.src = this._sanitizer.sanitize(_angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.URL, src);
  }
  /**
   * Fire when the image is loaded
   */
  _onLoadImageSuccess() {
    if (!this.options.disableKeyboardNav) {
      // unbind keyboard event during transition
      this._disableKeyboardNav();
    }
    let imageHeight;
    let imageWidth;
    let maxImageHeight;
    let maxImageWidth;
    let windowHeight;
    let windowWidth;
    let naturalImageWidth;
    let naturalImageHeight;
    // set default width and height of image to be its natural
    imageWidth = naturalImageWidth = this._imageElem.nativeElement.naturalWidth;
    imageHeight = naturalImageHeight = this._imageElem.nativeElement.naturalHeight;
    if (this.options.fitImageInViewPort) {
      windowWidth = this._windowRef.innerWidth;
      windowHeight = this._windowRef.innerHeight;
      maxImageWidth = windowWidth - this._cssValue.containerLeftPadding - this._cssValue.containerRightPadding - this._cssValue.imageBorderWidthLeft - this._cssValue.imageBorderWidthRight - 20;
      maxImageHeight = windowHeight - this._cssValue.containerTopPadding - this._cssValue.containerTopPadding - this._cssValue.imageBorderWidthTop - this._cssValue.imageBorderWidthBottom - 120;
      if (naturalImageWidth > maxImageWidth || naturalImageHeight > maxImageHeight) {
        if (naturalImageWidth / maxImageWidth > naturalImageHeight / maxImageHeight) {
          imageWidth = maxImageWidth;
          imageHeight = Math.round(naturalImageHeight / (naturalImageWidth / imageWidth));
        } else {
          imageHeight = maxImageHeight;
          imageWidth = Math.round(naturalImageWidth / (naturalImageHeight / imageHeight));
        }
      }
      this._rendererRef.setStyle(this._imageElem.nativeElement, 'width', `${imageWidth}px`);
      this._rendererRef.setStyle(this._imageElem.nativeElement, 'height', `${imageHeight}px`);
    }
    this._sizeContainer(imageWidth, imageHeight);
    if (this.options.centerVertically) {
      this._centerVertically(imageWidth, imageHeight);
    }
  }
  _centerVertically(imageWidth, imageHeight) {
    const scrollOffset = this._documentRef.documentElement.scrollTop;
    const windowHeight = this._windowRef.innerHeight;
    const viewOffset = windowHeight / 2 - imageHeight / 2;
    const topDistance = scrollOffset + viewOffset;
    this._rendererRef.setStyle(this._lightboxElem.nativeElement, 'top', `${topDistance}px`);
  }
  _sizeContainer(imageWidth, imageHeight) {
    const oldWidth = this._outerContainerElem.nativeElement.offsetWidth;
    const oldHeight = this._outerContainerElem.nativeElement.offsetHeight;
    const newWidth = imageWidth + this._cssValue.containerRightPadding + this._cssValue.containerLeftPadding + this._cssValue.imageBorderWidthLeft + this._cssValue.imageBorderWidthRight;
    const newHeight = imageHeight + this._cssValue.containerTopPadding + this._cssValue.containerBottomPadding + this._cssValue.imageBorderWidthTop + this._cssValue.imageBorderWidthBottom;
    // make sure that distances are large enough for transitionend event to be fired, at least 5px.
    if (Math.abs(oldWidth - newWidth) + Math.abs(oldHeight - newHeight) > 5) {
      this._rendererRef.setStyle(this._outerContainerElem.nativeElement, 'width', `${newWidth}px`);
      this._rendererRef.setStyle(this._outerContainerElem.nativeElement, 'height', `${newHeight}px`);
      // bind resize event to outer container
      // use enableTransition to prevent infinite loader
      if (this.options.enableTransition) {
        this._event.transitions = [];
        ['transitionend', 'webkitTransitionEnd', 'oTransitionEnd', 'MSTransitionEnd'].forEach(eventName => {
          this._event.transitions.push(this._rendererRef.listen(this._outerContainerElem.nativeElement, eventName, event => {
            if (event.target === event.currentTarget) {
              this._postResize(newWidth, newHeight);
            }
          }));
        });
      } else {
        this._postResize(newWidth, newHeight);
      }
    } else {
      this._postResize(newWidth, newHeight);
    }
  }
  _postResize(newWidth, newHeight) {
    // unbind resize event
    if (Array.isArray(this._event.transitions)) {
      this._event.transitions.forEach(eventHandler => {
        eventHandler();
      });
      this._event.transitions = [];
    }
    this._rendererRef.setStyle(this._dataContainerElem.nativeElement, 'width', `${newWidth}px`);
    this._showImage();
  }
  _showImage() {
    this.ui.showReloader = false;
    this._updateNav();
    this._updateDetails();
    if (!this.options.disableKeyboardNav) {
      this._enableKeyboardNav();
    }
  }
  _prepareComponent() {
    // add css3 animation
    this._addCssAnimation();
    // position the image according to user's option
    this._positionLightBox();
    // update controls visibility on next view generation
    setTimeout(() => {
      this.ui.showZoomButton = this.options.showZoom;
      this.ui.showRotateButton = this.options.showRotate;
      this.ui.showDownloadButton = this.options.showDownloadButton;
    }, 0);
  }
  _positionLightBox() {
    // @see https://stackoverflow.com/questions/3464876/javascript-get-window-x-y-position-for-scroll
    const top = (this._windowRef.pageYOffset || this._documentRef.documentElement.scrollTop) + this.options.positionFromTop;
    const left = this._windowRef.pageXOffset || this._documentRef.documentElement.scrollLeft;
    if (!this.options.centerVertically) {
      this._rendererRef.setStyle(this._lightboxElem.nativeElement, 'top', `${top}px`);
    }
    this._rendererRef.setStyle(this._lightboxElem.nativeElement, 'left', `${left}px`);
    this._rendererRef.setStyle(this._lightboxElem.nativeElement, 'display', 'block');
    // disable scrolling of the page while open
    if (this.options.disableScrolling) {
      this._rendererRef.addClass(this._documentRef.documentElement, 'lb-disable-scrolling');
    }
  }
  /**
   * addCssAnimation add css3 classes for animate lightbox
   */
  _addCssAnimation() {
    const resizeDuration = this.options.resizeDuration;
    const fadeDuration = this.options.fadeDuration;
    this._rendererRef.setStyle(this._lightboxElem.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._lightboxElem.nativeElement, 'animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._outerContainerElem.nativeElement, '-webkit-transition-duration', `${resizeDuration}s`);
    this._rendererRef.setStyle(this._outerContainerElem.nativeElement, 'transition-duration', `${resizeDuration}s`);
    this._rendererRef.setStyle(this._dataContainerElem.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._dataContainerElem.nativeElement, 'animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._imageElem.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._imageElem.nativeElement, 'animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._captionElem.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._captionElem.nativeElement, 'animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._numberElem.nativeElement, '-webkit-animation-duration', `${fadeDuration}s`);
    this._rendererRef.setStyle(this._numberElem.nativeElement, 'animation-duration', `${fadeDuration}s`);
  }
  _end() {
    this.ui.classList = 'lightbox animation fadeOut';
    if (this.options.disableScrolling) {
      this._rendererRef.removeClass(this._documentRef.documentElement, 'lb-disable-scrolling');
    }
    setTimeout(() => {
      this.cmpRef.destroy();
    }, this.options.fadeDuration * 1000);
  }
  _updateDetails() {
    // update the caption
    if (typeof this.album[this.currentImageIndex].caption !== 'undefined' && this.album[this.currentImageIndex].caption !== '') {
      this.ui.showCaption = true;
    }
    // update the page number if user choose to do so
    // does not perform numbering the page if the
    // array length in album <= 1
    if (this.album.length > 1 && this.options.showImageNumberLabel) {
      this.ui.showPageNumber = true;
      this.content.pageNumber = this._albumLabel();
    }
  }
  _albumLabel() {
    // due to {this.currentImageIndex} is set from 0 to {this.album.length} - 1
    return this.options.albumLabel.replace(/%1/g, Number(this.currentImageIndex + 1)).replace(/%2/g, this.album.length);
  }
  _changeImage(newIndex) {
    this._resetImage();
    this.currentImageIndex = newIndex;
    this._hideImage();
    this._registerImageLoadingEvent();
    this._lightboxEvent.broadcastLightboxEvent({
      id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CHANGE_PAGE,
      data: newIndex
    });
  }
  _hideImage() {
    this.ui.showReloader = true;
    this.ui.showArrowNav = false;
    this.ui.showLeftArrow = false;
    this.ui.showRightArrow = false;
    this.ui.showPageNumber = false;
    this.ui.showCaption = false;
  }
  _updateNav() {
    let alwaysShowNav = false;
    // check to see the browser support touch event
    try {
      this._documentRef.createEvent('TouchEvent');
      alwaysShowNav = this.options.alwaysShowNavOnTouchDevices ? true : false;
    } catch (e) {
      // noop
    }
    // initially show the arrow nav
    // which is the parent of both left and right nav
    this._showArrowNav();
    if (this.album.length > 1) {
      if (this.options.wrapAround) {
        if (alwaysShowNav) {
          // alternatives this.$lightbox.find('.lb-prev, .lb-next').css('opacity', '1');
          this._rendererRef.setStyle(this._leftArrowElem.nativeElement, 'opacity', '1');
          this._rendererRef.setStyle(this._rightArrowElem.nativeElement, 'opacity', '1');
        }
        // alternatives this.$lightbox.find('.lb-prev, .lb-next').show();
        this._showLeftArrowNav();
        this._showRightArrowNav();
      } else {
        if (this.currentImageIndex > 0) {
          // alternatives this.$lightbox.find('.lb-prev').show();
          this._showLeftArrowNav();
          if (alwaysShowNav) {
            // alternatives this.$lightbox.find('.lb-prev').css('opacity', '1');
            this._rendererRef.setStyle(this._leftArrowElem.nativeElement, 'opacity', '1');
          }
        }
        if (this.currentImageIndex < this.album.length - 1) {
          // alternatives this.$lightbox.find('.lb-next').show();
          this._showRightArrowNav();
          if (alwaysShowNav) {
            // alternatives this.$lightbox.find('.lb-next').css('opacity', '1');
            this._rendererRef.setStyle(this._rightArrowElem.nativeElement, 'opacity', '1');
          }
        }
      }
    }
  }
  _showLeftArrowNav() {
    this.ui.showLeftArrow = true;
  }
  _showRightArrowNav() {
    this.ui.showRightArrow = true;
  }
  _showArrowNav() {
    this.ui.showArrowNav = this.album.length !== 1;
  }
  _enableKeyboardNav() {
    this._event.keyup = this._rendererRef.listen('document', 'keyup', event => {
      this._keyboardAction(event);
    });
  }
  _disableKeyboardNav() {
    if (this._event.keyup) {
      this._event.keyup();
    }
  }
  _keyboardAction($event) {
    const KEYCODE_ESC = 27;
    const KEYCODE_LEFTARROW = 37;
    const KEYCODE_RIGHTARROW = 39;
    const keycode = $event.keyCode;
    const key = String.fromCharCode(keycode).toLowerCase();
    if (keycode === KEYCODE_ESC || key.match(/x|o|c/)) {
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CLOSE,
        data: null
      });
    } else if (key === 'p' || keycode === KEYCODE_LEFTARROW) {
      if (this.currentImageIndex !== 0) {
        this._changeImage(this.currentImageIndex - 1);
      } else if (this.options.wrapAround && this.album.length > 1) {
        this._changeImage(this.album.length - 1);
      }
    } else if (key === 'n' || keycode === KEYCODE_RIGHTARROW) {
      if (this.currentImageIndex !== this.album.length - 1) {
        this._changeImage(this.currentImageIndex + 1);
      } else if (this.options.wrapAround && this.album.length > 1) {
        this._changeImage(0);
      }
    }
  }
  _getCssStyleValue(elem, propertyName) {
    return parseFloat(this._windowRef.getComputedStyle(elem.nativeElement, null).getPropertyValue(propertyName));
  }
  _onReceivedEvent(event) {
    switch (event.id) {
      case _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LIGHTBOX_EVENT.CLOSE:
        this._end();
        break;
      default:
        break;
    }
  }
}
LightboxComponent.ɵfac = function LightboxComponent_Factory(t) {
  return new (t || LightboxComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxEvent), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxWindowRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](ngx_filesaver__WEBPACK_IMPORTED_MODULE_2__.FileSaverService), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.DomSanitizer), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_4__.DOCUMENT));
};
LightboxComponent.ɵcmp = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
  type: LightboxComponent,
  selectors: [["", "lb-content", ""]],
  viewQuery: function LightboxComponent_Query(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c0, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c1, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c2, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c3, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c4, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c5, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c6, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c7, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](_c8, 5);
    }
    if (rf & 2) {
      let _t;
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._outerContainerElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._containerElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._leftArrowElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._rightArrowElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._navArrowElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._dataContainerElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._imageElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._captionElem = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._numberElem = _t.first);
    }
  },
  hostVars: 2,
  hostBindings: function LightboxComponent_HostBindings(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_click_HostBindingHandler($event) {
        return ctx.close($event);
      });
    }
    if (rf & 2) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵclassMap"](ctx.ui.classList);
    }
  },
  inputs: {
    album: "album",
    currentImageIndex: "currentImageIndex",
    options: "options",
    cmpRef: "cmpRef"
  },
  attrs: _c9,
  decls: 34,
  vars: 14,
  consts: [["id", "outerContainer", 1, "lb-outerContainer", "transition"], ["outerContainer", ""], ["id", "container", 1, "lb-container"], ["container", ""], ["id", "image", 1, "lb-image", "animation", "fadeIn", 3, "src", "hidden"], ["image", ""], [1, "lb-nav", 3, "hidden"], ["navArrow", ""], [1, "lb-prev", 3, "hidden", "click"], ["leftArrow", ""], [1, "lb-next", 3, "hidden", "click"], ["rightArrow", ""], [1, "lb-loader", 3, "hidden", "click"], [1, "lb-cancel"], [1, "lb-dataContainer", 3, "hidden"], ["dataContainer", ""], [1, "lb-data"], [1, "lb-details"], [1, "lb-caption", "animation", "fadeIn", 3, "hidden", "innerHtml"], ["caption", ""], [1, "lb-number", "animation", "fadeIn", 3, "hidden"], ["number", ""], [1, "lb-controlContainer"], [1, "lb-closeContainer"], [1, "lb-close", 3, "click"], [1, "lb-downloadContainer", 3, "hidden"], [1, "lb-download", 3, "click"], [1, "lb-turnContainer", 3, "hidden"], [1, "lb-turnLeft", 3, "click"], [1, "lb-turnRight", 3, "click"], [1, "lb-zoomContainer", 3, "hidden"], [1, "lb-zoomOut", 3, "click"], [1, "lb-zoomIn", 3, "click"]],
  template: function LightboxComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div", 0, 1)(2, "div", 2, 3);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](4, "img", 4, 5);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](6, "div", 6, 7)(8, "a", 8, 9);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_8_listener() {
        return ctx.prevImage();
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](10, "a", 10, 11);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_10_listener() {
        return ctx.nextImage();
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](12, "div", 12);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_div_click_12_listener($event) {
        return ctx.close($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](13, "a", 13);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](14, "div", 14, 15)(16, "div", 16)(17, "div", 17);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](18, "span", 18, 19);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](20, "span", 20, 21);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](22);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](23, "div", 22)(24, "div", 23)(25, "a", 24);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_25_listener($event) {
        return ctx.close($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](26, "div", 25)(27, "a", 26);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_27_listener($event) {
        return ctx.download($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](28, "div", 27)(29, "a", 28);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_29_listener($event) {
        return ctx.control($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](30, "a", 29);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_30_listener($event) {
        return ctx.control($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](31, "div", 30)(32, "a", 31);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_32_listener($event) {
        return ctx.control($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](33, "a", 32);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function LightboxComponent_Template_a_click_33_listener($event) {
        return ctx.control($event);
      });
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()()()()();
    }
    if (rf & 2) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](4);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("src", ctx.album[ctx.currentImageIndex].src, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵsanitizeUrl"])("hidden", ctx.ui.showReloader);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showArrowNav);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showLeftArrow);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showRightArrow);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showReloader);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", ctx.ui.showReloader);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](4);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showCaption)("innerHtml", ctx.album[ctx.currentImageIndex].caption, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵsanitizeHtml"]);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showPageNumber);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtextInterpolate"](ctx.content.pageNumber);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](4);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showDownloadButton);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showRotateButton);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](3);
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵproperty"]("hidden", !ctx.ui.showZoomButton);
    }
  },
  encapsulation: 2
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LightboxComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      template: `
    <div class="lb-outerContainer transition" #outerContainer id="outerContainer">
      <div class="lb-container" #container id="container">
        <img class="lb-image"
             id="image"
             [src]="album[currentImageIndex].src"
             class="lb-image animation fadeIn"
             [hidden]="ui.showReloader"
             #image>
        <div class="lb-nav" [hidden]="!ui.showArrowNav" #navArrow>
          <a class="lb-prev" [hidden]="!ui.showLeftArrow" (click)="prevImage()" #leftArrow></a>
          <a class="lb-next" [hidden]="!ui.showRightArrow" (click)="nextImage()" #rightArrow></a>
        </div>
        <div class="lb-loader" [hidden]="!ui.showReloader" (click)="close($event)">
          <a class="lb-cancel"></a>
        </div>
      </div>
    </div>
    <div class="lb-dataContainer" [hidden]="ui.showReloader" #dataContainer>
      <div class="lb-data">
        <div class="lb-details">
          <span class="lb-caption animation fadeIn" [hidden]="!ui.showCaption" [innerHtml]="album[currentImageIndex].caption" #caption>
          </span>
          <span class="lb-number animation fadeIn" [hidden]="!ui.showPageNumber" #number>{{ content.pageNumber }}</span>
        </div>
        <div class="lb-controlContainer">
          <div class="lb-closeContainer">
            <a class="lb-close" (click)="close($event)"></a>
          </div>
          <div class="lb-downloadContainer" [hidden]="!ui.showDownloadButton">
            <a class="lb-download" (click)="download($event)"></a>
          </div>
          <div class="lb-turnContainer" [hidden]="!ui.showRotateButton">
            <a class="lb-turnLeft" (click)="control($event)"></a>
            <a class="lb-turnRight" (click)="control($event)"></a>
          </div>
          <div class="lb-zoomContainer" [hidden]="!ui.showZoomButton">
            <a class="lb-zoomOut" (click)="control($event)"></a>
            <a class="lb-zoomIn" (click)="control($event)"></a>
          </div>
        </div>
      </div>
    </div>`,
      selector: '[lb-content]',
      host: {
        '(click)': 'close($event)',
        '[class]': 'ui.classList'
      }
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2
    }, {
      type: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxEvent
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_0__.LightboxWindowRef
    }, {
      type: ngx_filesaver__WEBPACK_IMPORTED_MODULE_2__.FileSaverService
    }, {
      type: _angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.DomSanitizer
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [_angular_common__WEBPACK_IMPORTED_MODULE_4__.DOCUMENT]
      }]
    }];
  }, {
    album: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    currentImageIndex: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    cmpRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    _outerContainerElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['outerContainer', {
        static: false
      }]
    }],
    _containerElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['container', {
        static: false
      }]
    }],
    _leftArrowElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['leftArrow', {
        static: false
      }]
    }],
    _rightArrowElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['rightArrow', {
        static: false
      }]
    }],
    _navArrowElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['navArrow', {
        static: false
      }]
    }],
    _dataContainerElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['dataContainer', {
        static: false
      }]
    }],
    _imageElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['image', {
        static: false
      }]
    }],
    _captionElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['caption', {
        static: false
      }]
    }],
    _numberElem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: ['number', {
        static: false
      }]
    }]
  });
})();

/***/ }),

/***/ 60497:
/*!******************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox.module.js ***!
  \******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LightboxModule: () => (/* binding */ LightboxModule)
/* harmony export */ });
/* harmony import */ var ngx_filesaver__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ngx-filesaver */ 67227);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _lightbox_config_service__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightbox-config.service */ 41967);
/* harmony import */ var _lightbox_event_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lightbox-event.service */ 60543);
/* harmony import */ var _lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lightbox-overlay.component */ 3763);
/* harmony import */ var _lightbox_component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lightbox.component */ 83954);
/* harmony import */ var _lightbox_service__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./lightbox.service */ 37914);








class LightboxModule {}
LightboxModule.ɵfac = function LightboxModule_Factory(t) {
  return new (t || LightboxModule)();
};
LightboxModule.ɵmod = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineNgModule"]({
  type: LightboxModule
});
LightboxModule.ɵinj = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjector"]({
  providers: [_lightbox_service__WEBPACK_IMPORTED_MODULE_4__.Lightbox, _lightbox_config_service__WEBPACK_IMPORTED_MODULE_0__.LightboxConfig, _lightbox_event_service__WEBPACK_IMPORTED_MODULE_1__.LightboxEvent, _lightbox_event_service__WEBPACK_IMPORTED_MODULE_1__.LightboxWindowRef],
  imports: [ngx_filesaver__WEBPACK_IMPORTED_MODULE_6__.FileSaverModule]
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](LightboxModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.NgModule,
    args: [{
      declarations: [_lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_2__.LightboxOverlayComponent, _lightbox_component__WEBPACK_IMPORTED_MODULE_3__.LightboxComponent],
      providers: [_lightbox_service__WEBPACK_IMPORTED_MODULE_4__.Lightbox, _lightbox_config_service__WEBPACK_IMPORTED_MODULE_0__.LightboxConfig, _lightbox_event_service__WEBPACK_IMPORTED_MODULE_1__.LightboxEvent, _lightbox_event_service__WEBPACK_IMPORTED_MODULE_1__.LightboxWindowRef],
      entryComponents: [_lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_2__.LightboxOverlayComponent, _lightbox_component__WEBPACK_IMPORTED_MODULE_3__.LightboxComponent],
      imports: [ngx_filesaver__WEBPACK_IMPORTED_MODULE_6__.FileSaverModule]
    }]
  }], null, null);
})();
(function () {
  (typeof ngJitMode === "undefined" || ngJitMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵsetNgModuleScope"](LightboxModule, {
    declarations: [_lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_2__.LightboxOverlayComponent, _lightbox_component__WEBPACK_IMPORTED_MODULE_3__.LightboxComponent],
    imports: [ngx_filesaver__WEBPACK_IMPORTED_MODULE_6__.FileSaverModule]
  });
})();

/***/ }),

/***/ 37914:
/*!*******************************************************!*\
  !*** ./node_modules/ngx-lightbox/lightbox.service.js ***!
  \*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Lightbox: () => (/* binding */ Lightbox)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _lightbox_component__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightbox.component */ 83954);
/* harmony import */ var _lightbox_config_service__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./lightbox-config.service */ 41967);
/* harmony import */ var _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./lightbox-event.service */ 60543);
/* harmony import */ var _lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./lightbox-overlay.component */ 3763);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/common */ 60316);









class Lightbox {
  constructor(_componentFactoryResolver, _injector, _applicationRef, _lightboxConfig, _lightboxEvent, _documentRef) {
    this._componentFactoryResolver = _componentFactoryResolver;
    this._injector = _injector;
    this._applicationRef = _applicationRef;
    this._lightboxConfig = _lightboxConfig;
    this._lightboxEvent = _lightboxEvent;
    this._documentRef = _documentRef;
  }
  open(album, curIndex = 0, options = {}) {
    const overlayComponentRef = this._createComponent(_lightbox_overlay_component__WEBPACK_IMPORTED_MODULE_3__.LightboxOverlayComponent);
    const componentRef = this._createComponent(_lightbox_component__WEBPACK_IMPORTED_MODULE_0__.LightboxComponent);
    const newOptions = {};
    // broadcast open event
    this._lightboxEvent.broadcastLightboxEvent({
      id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LIGHTBOX_EVENT.OPEN
    });
    Object.assign(newOptions, this._lightboxConfig, options);
    // attach input to lightbox
    componentRef.instance.album = album;
    componentRef.instance.currentImageIndex = curIndex;
    componentRef.instance.options = newOptions;
    componentRef.instance.cmpRef = componentRef;
    // attach input to overlay
    overlayComponentRef.instance.options = newOptions;
    overlayComponentRef.instance.cmpRef = overlayComponentRef;
    // FIXME: not sure why last event is broadcasted (which is CLOSED) and make
    // lightbox can not be opened the second time.
    // Need to timeout so that the OPEN event is set before component is initialized
    setTimeout(() => {
      this._applicationRef.attachView(overlayComponentRef.hostView);
      this._applicationRef.attachView(componentRef.hostView);
      overlayComponentRef.onDestroy(() => {
        this._applicationRef.detachView(overlayComponentRef.hostView);
      });
      componentRef.onDestroy(() => {
        this._applicationRef.detachView(componentRef.hostView);
      });
      const containerElement = newOptions.containerElementResolver(this._documentRef);
      containerElement.appendChild(overlayComponentRef.location.nativeElement);
      containerElement.appendChild(componentRef.location.nativeElement);
    });
  }
  close() {
    if (this._lightboxEvent) {
      this._lightboxEvent.broadcastLightboxEvent({
        id: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LIGHTBOX_EVENT.CLOSE
      });
    }
  }
  _createComponent(ComponentClass) {
    const factory = this._componentFactoryResolver.resolveComponentFactory(ComponentClass);
    const component = factory.create(this._injector);
    return component;
  }
}
Lightbox.ɵfac = function Lightbox_Factory(t) {
  return new (t || Lightbox)(_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_4__.ComponentFactoryResolver), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_4__.Injector), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_4__.ApplicationRef), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_lightbox_config_service__WEBPACK_IMPORTED_MODULE_1__.LightboxConfig), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LightboxEvent), _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_5__.DOCUMENT));
};
Lightbox.ɵprov = /*@__PURE__*/_angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵɵdefineInjectable"]({
  token: Lightbox,
  factory: Lightbox.ɵfac
});
(function () {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_4__["ɵsetClassMetadata"](Lightbox, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injectable
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.ComponentFactoryResolver
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Injector
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.ApplicationRef
    }, {
      type: _lightbox_config_service__WEBPACK_IMPORTED_MODULE_1__.LightboxConfig
    }, {
      type: _lightbox_event_service__WEBPACK_IMPORTED_MODULE_2__.LightboxEvent
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_4__.Inject,
        args: [_angular_common__WEBPACK_IMPORTED_MODULE_5__.DOCUMENT]
      }]
    }];
  }, null);
})();

/***/ }),

/***/ 40174:
/*!**********************************************************!*\
  !*** ./node_modules/preact/compat/dist/compat.module.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Children: () => (/* binding */ O),
/* harmony export */   Component: () => (/* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.Component),
/* harmony export */   Fragment: () => (/* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.Fragment),
/* harmony export */   PureComponent: () => (/* binding */ w),
/* harmony export */   StrictMode: () => (/* binding */ vn),
/* harmony export */   Suspense: () => (/* binding */ D),
/* harmony export */   SuspenseList: () => (/* binding */ V),
/* harmony export */   __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: () => (/* binding */ rn),
/* harmony export */   cloneElement: () => (/* binding */ cn),
/* harmony export */   createContext: () => (/* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createContext),
/* harmony export */   createElement: () => (/* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createElement),
/* harmony export */   createFactory: () => (/* binding */ on),
/* harmony export */   createPortal: () => (/* binding */ j),
/* harmony export */   createRef: () => (/* reexport safe */ preact__WEBPACK_IMPORTED_MODULE_0__.createRef),
/* harmony export */   "default": () => (/* binding */ bn),
/* harmony export */   findDOMNode: () => (/* binding */ an),
/* harmony export */   flushSync: () => (/* binding */ hn),
/* harmony export */   forwardRef: () => (/* binding */ k),
/* harmony export */   hydrate: () => (/* binding */ q),
/* harmony export */   isValidElement: () => (/* binding */ ln),
/* harmony export */   lazy: () => (/* binding */ M),
/* harmony export */   memo: () => (/* binding */ R),
/* harmony export */   render: () => (/* binding */ Y),
/* harmony export */   startTransition: () => (/* binding */ dn),
/* harmony export */   unmountComponentAtNode: () => (/* binding */ fn),
/* harmony export */   unstable_batchedUpdates: () => (/* binding */ sn),
/* harmony export */   useCallback: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useCallback),
/* harmony export */   useContext: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useContext),
/* harmony export */   useDebugValue: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useDebugValue),
/* harmony export */   useDeferredValue: () => (/* binding */ pn),
/* harmony export */   useEffect: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect),
/* harmony export */   useErrorBoundary: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useErrorBoundary),
/* harmony export */   useId: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useId),
/* harmony export */   useImperativeHandle: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle),
/* harmony export */   useInsertionEffect: () => (/* binding */ yn),
/* harmony export */   useLayoutEffect: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect),
/* harmony export */   useMemo: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useMemo),
/* harmony export */   useReducer: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useReducer),
/* harmony export */   useRef: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useRef),
/* harmony export */   useState: () => (/* reexport safe */ preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState),
/* harmony export */   useSyncExternalStore: () => (/* binding */ _n),
/* harmony export */   useTransition: () => (/* binding */ mn),
/* harmony export */   version: () => (/* binding */ un)
/* harmony export */ });
/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ 78048);
/* harmony import */ var preact_hooks__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact/hooks */ 56734);




function g(n, t) {
  for (var e in t) n[e] = t[e];
  return n;
}
function C(n, t) {
  for (var e in n) if ("__source" !== e && !(e in t)) return !0;
  for (var r in t) if ("__source" !== r && n[r] !== t[r]) return !0;
  return !1;
}
function E(n, t) {
  return n === t && (0 !== n || 1 / n == 1 / t) || n != n && t != t;
}
function w(n) {
  this.props = n;
}
function R(n, e) {
  function r(n) {
    var t = this.props.ref,
      r = t == n.ref;
    return !r && t && (t.call ? t(null) : t.current = null), e ? !e(this.props, n) || !r : C(this.props, n);
  }
  function u(e) {
    return this.shouldComponentUpdate = r, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(n, e);
  }
  return u.displayName = "Memo(" + (n.displayName || n.name) + ")", u.prototype.isReactComponent = !0, u.__f = !0, u;
}
(w.prototype = new preact__WEBPACK_IMPORTED_MODULE_0__.Component()).isPureReactComponent = !0, w.prototype.shouldComponentUpdate = function (n, t) {
  return C(this.props, n) || C(this.state, t);
};
var x = preact__WEBPACK_IMPORTED_MODULE_0__.options.__b;
preact__WEBPACK_IMPORTED_MODULE_0__.options.__b = function (n) {
  n.type && n.type.__f && n.ref && (n.props.ref = n.ref, n.ref = null), x && x(n);
};
var N = "undefined" != typeof Symbol && Symbol.for && Symbol.for("react.forward_ref") || 3911;
function k(n) {
  function t(t) {
    var e = g({}, t);
    return delete e.ref, n(e, t.ref || null);
  }
  return t.$$typeof = N, t.render = t, t.prototype.isReactComponent = t.__f = !0, t.displayName = "ForwardRef(" + (n.displayName || n.name) + ")", t;
}
var A = function (n, t) {
    return null == n ? null : (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)((0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n).map(t));
  },
  O = {
    map: A,
    forEach: A,
    count: function (n) {
      return n ? (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n).length : 0;
    },
    only: function (n) {
      var t = (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n);
      if (1 !== t.length) throw "Children.only";
      return t[0];
    },
    toArray: preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray
  },
  T = preact__WEBPACK_IMPORTED_MODULE_0__.options.__e;
preact__WEBPACK_IMPORTED_MODULE_0__.options.__e = function (n, t, e, r) {
  if (n.then) for (var u, o = t; o = o.__;) if ((u = o.__c) && u.__c) return null == t.__e && (t.__e = e.__e, t.__k = e.__k), u.__c(n, t);
  T(n, t, e, r);
};
var I = preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount;
function L(n, t, e) {
  return n && (n.__c && n.__c.__H && (n.__c.__H.__.forEach(function (n) {
    "function" == typeof n.__c && n.__c();
  }), n.__c.__H = null), null != (n = g({}, n)).__c && (n.__c.__P === e && (n.__c.__P = t), n.__c = null), n.__k = n.__k && n.__k.map(function (n) {
    return L(n, t, e);
  })), n;
}
function U(n, t, e) {
  return n && (n.__v = null, n.__k = n.__k && n.__k.map(function (n) {
    return U(n, t, e);
  }), n.__c && n.__c.__P === t && (n.__e && e.insertBefore(n.__e, n.__d), n.__c.__e = !0, n.__c.__P = e)), n;
}
function D() {
  this.__u = 0, this.t = null, this.__b = null;
}
function F(n) {
  var t = n.__.__c;
  return t && t.__a && t.__a(n);
}
function M(n) {
  var e, r, u;
  function o(o) {
    if (e || (e = n()).then(function (n) {
      r = n.default || n;
    }, function (n) {
      u = n;
    }), u) throw u;
    if (!r) throw e;
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(r, o);
  }
  return o.displayName = "Lazy", o.__f = !0, o;
}
function V() {
  this.u = null, this.o = null;
}
preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount = function (n) {
  var t = n.__c;
  t && t.__R && t.__R(), t && !0 === n.__h && (n.type = null), I && I(n);
}, (D.prototype = new preact__WEBPACK_IMPORTED_MODULE_0__.Component()).__c = function (n, t) {
  var e = t.__c,
    r = this;
  null == r.t && (r.t = []), r.t.push(e);
  var u = F(r.__v),
    o = !1,
    i = function () {
      o || (o = !0, e.__R = null, u ? u(l) : l());
    };
  e.__R = i;
  var l = function () {
      if (! --r.__u) {
        if (r.state.__a) {
          var n = r.state.__a;
          r.__v.__k[0] = U(n, n.__c.__P, n.__c.__O);
        }
        var t;
        for (r.setState({
          __a: r.__b = null
        }); t = r.t.pop();) t.forceUpdate();
      }
    },
    c = !0 === t.__h;
  r.__u++ || c || r.setState({
    __a: r.__b = r.__v.__k[0]
  }), n.then(i, i);
}, D.prototype.componentWillUnmount = function () {
  this.t = [];
}, D.prototype.render = function (n, e) {
  if (this.__b) {
    if (this.__v.__k) {
      var r = document.createElement("div"),
        o = this.__v.__k[0].__c;
      this.__v.__k[0] = L(this.__b, r, o.__O = o.__P);
    }
    this.__b = null;
  }
  var i = e.__a && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, n.fallback);
  return i && (i.__h = null), [(0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, e.__a ? null : n.children), i];
};
var W = function (n, t, e) {
  if (++e[1] === e[0] && n.o.delete(t), n.props.revealOrder && ("t" !== n.props.revealOrder[0] || !n.o.size)) for (e = n.u; e;) {
    for (; e.length > 3;) e.pop()();
    if (e[1] < e[0]) break;
    n.u = e = e[2];
  }
};
function P(n) {
  return this.getChildContext = function () {
    return n.context;
  }, n.children;
}
function $(n) {
  var e = this,
    r = n.i;
  e.componentWillUnmount = function () {
    (0,preact__WEBPACK_IMPORTED_MODULE_0__.render)(null, e.l), e.l = null, e.i = null;
  }, e.i && e.i !== r && e.componentWillUnmount(), n.__v ? (e.l || (e.i = r, e.l = {
    nodeType: 1,
    parentNode: r,
    childNodes: [],
    appendChild: function (n) {
      this.childNodes.push(n), e.i.appendChild(n);
    },
    insertBefore: function (n, t) {
      this.childNodes.push(n), e.i.appendChild(n);
    },
    removeChild: function (n) {
      this.childNodes.splice(this.childNodes.indexOf(n) >>> 1, 1), e.i.removeChild(n);
    }
  }), (0,preact__WEBPACK_IMPORTED_MODULE_0__.render)((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(P, {
    context: e.context
  }, n.__v), e.l)) : e.l && e.componentWillUnmount();
}
function j(n, e) {
  var r = (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)($, {
    __v: n,
    i: e
  });
  return r.containerInfo = e, r;
}
(V.prototype = new preact__WEBPACK_IMPORTED_MODULE_0__.Component()).__a = function (n) {
  var t = this,
    e = F(t.__v),
    r = t.o.get(n);
  return r[0]++, function (u) {
    var o = function () {
      t.props.revealOrder ? (r.push(u), W(t, n, r)) : u();
    };
    e ? e(o) : o();
  };
}, V.prototype.render = function (n) {
  this.u = null, this.o = new Map();
  var t = (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(n.children);
  n.revealOrder && "b" === n.revealOrder[0] && t.reverse();
  for (var e = t.length; e--;) this.o.set(t[e], this.u = [1, 0, this.u]);
  return n.children;
}, V.prototype.componentDidUpdate = V.prototype.componentDidMount = function () {
  var n = this;
  this.o.forEach(function (t, e) {
    W(n, e, t);
  });
};
var z = "undefined" != typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103,
  B = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/,
  H = "undefined" != typeof document,
  Z = function (n) {
    return ("undefined" != typeof Symbol && "symbol" == typeof Symbol() ? /fil|che|rad/i : /fil|che|ra/i).test(n);
  };
function Y(n, t, e) {
  return null == t.__k && (t.textContent = ""), (0,preact__WEBPACK_IMPORTED_MODULE_0__.render)(n, t), "function" == typeof e && e(), n ? n.__c : null;
}
function q(n, t, e) {
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.hydrate)(n, t), "function" == typeof e && e(), n ? n.__c : null;
}
preact__WEBPACK_IMPORTED_MODULE_0__.Component.prototype.isReactComponent = {}, ["componentWillMount", "componentWillReceiveProps", "componentWillUpdate"].forEach(function (t) {
  Object.defineProperty(preact__WEBPACK_IMPORTED_MODULE_0__.Component.prototype, t, {
    configurable: !0,
    get: function () {
      return this["UNSAFE_" + t];
    },
    set: function (n) {
      Object.defineProperty(this, t, {
        configurable: !0,
        writable: !0,
        value: n
      });
    }
  });
});
var G = preact__WEBPACK_IMPORTED_MODULE_0__.options.event;
function J() {}
function K() {
  return this.cancelBubble;
}
function Q() {
  return this.defaultPrevented;
}
preact__WEBPACK_IMPORTED_MODULE_0__.options.event = function (n) {
  return G && (n = G(n)), n.persist = J, n.isPropagationStopped = K, n.isDefaultPrevented = Q, n.nativeEvent = n;
};
var X,
  nn = {
    configurable: !0,
    get: function () {
      return this.class;
    }
  },
  tn = preact__WEBPACK_IMPORTED_MODULE_0__.options.vnode;
preact__WEBPACK_IMPORTED_MODULE_0__.options.vnode = function (n) {
  var t = n.type,
    e = n.props,
    u = e;
  if ("string" == typeof t) {
    var o = -1 === t.indexOf("-");
    for (var i in u = {}, e) {
      var l = e[i];
      H && "children" === i && "noscript" === t || "value" === i && "defaultValue" in e && null == l || ("defaultValue" === i && "value" in e && null == e.value ? i = "value" : "download" === i && !0 === l ? l = "" : /ondoubleclick/i.test(i) ? i = "ondblclick" : /^onchange(textarea|input)/i.test(i + t) && !Z(e.type) ? i = "oninput" : /^onfocus$/i.test(i) ? i = "onfocusin" : /^onblur$/i.test(i) ? i = "onfocusout" : /^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(i) ? i = i.toLowerCase() : o && B.test(i) ? i = i.replace(/[A-Z0-9]/g, "-$&").toLowerCase() : null === l && (l = void 0), /^oninput$/i.test(i) && (i = i.toLowerCase(), u[i] && (i = "oninputCapture")), u[i] = l);
    }
    "select" == t && u.multiple && Array.isArray(u.value) && (u.value = (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(e.children).forEach(function (n) {
      n.props.selected = -1 != u.value.indexOf(n.props.value);
    })), "select" == t && null != u.defaultValue && (u.value = (0,preact__WEBPACK_IMPORTED_MODULE_0__.toChildArray)(e.children).forEach(function (n) {
      n.props.selected = u.multiple ? -1 != u.defaultValue.indexOf(n.props.value) : u.defaultValue == n.props.value;
    })), n.props = u, e.class != e.className && (nn.enumerable = "className" in e, null != e.className && (u.class = e.className), Object.defineProperty(u, "className", nn));
  }
  n.$$typeof = z, tn && tn(n);
};
var en = preact__WEBPACK_IMPORTED_MODULE_0__.options.__r;
preact__WEBPACK_IMPORTED_MODULE_0__.options.__r = function (n) {
  en && en(n), X = n.__c;
};
var rn = {
    ReactCurrentDispatcher: {
      current: {
        readContext: function (n) {
          return X.__n[n.__c].props.value;
        }
      }
    }
  },
  un = "17.0.2";
function on(n) {
  return preact__WEBPACK_IMPORTED_MODULE_0__.createElement.bind(null, n);
}
function ln(n) {
  return !!n && n.$$typeof === z;
}
function cn(n) {
  return ln(n) ? preact__WEBPACK_IMPORTED_MODULE_0__.cloneElement.apply(null, arguments) : n;
}
function fn(n) {
  return !!n.__k && ((0,preact__WEBPACK_IMPORTED_MODULE_0__.render)(null, n), !0);
}
function an(n) {
  return n && (n.base || 1 === n.nodeType && n) || null;
}
var sn = function (n, t) {
    return n(t);
  },
  hn = function (n, t) {
    return n(t);
  },
  vn = preact__WEBPACK_IMPORTED_MODULE_0__.Fragment;
function dn(n) {
  n();
}
function pn(n) {
  return n;
}
function mn() {
  return [!1, dn];
}
var yn = preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect;
function _n(n, t) {
  var e = t(),
    r = (0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState)({
      h: {
        __: e,
        v: t
      }
    }),
    u = r[0].h,
    o = r[1];
  return (0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect)(function () {
    u.__ = e, u.v = t, E(u.__, t()) || o({
      h: u
    });
  }, [n, e, t]), (0,preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect)(function () {
    return E(u.__, u.v()) || o({
      h: u
    }), n(function () {
      E(u.__, u.v()) || o({
        h: u
      });
    });
  }, [n]), e;
}
var bn = {
  useState: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useState,
  useId: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useId,
  useReducer: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useReducer,
  useEffect: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useEffect,
  useLayoutEffect: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useLayoutEffect,
  useInsertionEffect: yn,
  useTransition: mn,
  useDeferredValue: pn,
  useSyncExternalStore: _n,
  startTransition: dn,
  useRef: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useRef,
  useImperativeHandle: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useImperativeHandle,
  useMemo: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useMemo,
  useCallback: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useCallback,
  useContext: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useContext,
  useDebugValue: preact_hooks__WEBPACK_IMPORTED_MODULE_1__.useDebugValue,
  version: "17.0.2",
  Children: O,
  render: Y,
  hydrate: q,
  unmountComponentAtNode: fn,
  createPortal: j,
  createElement: preact__WEBPACK_IMPORTED_MODULE_0__.createElement,
  createContext: preact__WEBPACK_IMPORTED_MODULE_0__.createContext,
  createFactory: on,
  cloneElement: cn,
  createRef: preact__WEBPACK_IMPORTED_MODULE_0__.createRef,
  Fragment: preact__WEBPACK_IMPORTED_MODULE_0__.Fragment,
  isValidElement: ln,
  findDOMNode: an,
  Component: preact__WEBPACK_IMPORTED_MODULE_0__.Component,
  PureComponent: w,
  memo: R,
  forwardRef: k,
  flushSync: hn,
  unstable_batchedUpdates: sn,
  StrictMode: vn,
  Suspense: D,
  SuspenseList: V,
  lazy: M,
  __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: rn
};


/***/ }),

/***/ 78048:
/*!***************************************************!*\
  !*** ./node_modules/preact/dist/preact.module.js ***!
  \***************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Component: () => (/* binding */ x),
/* harmony export */   Fragment: () => (/* binding */ _),
/* harmony export */   cloneElement: () => (/* binding */ F),
/* harmony export */   createContext: () => (/* binding */ G),
/* harmony export */   createElement: () => (/* binding */ y),
/* harmony export */   createRef: () => (/* binding */ d),
/* harmony export */   h: () => (/* binding */ y),
/* harmony export */   hydrate: () => (/* binding */ E),
/* harmony export */   isValidElement: () => (/* binding */ i),
/* harmony export */   options: () => (/* binding */ l),
/* harmony export */   render: () => (/* binding */ D),
/* harmony export */   toChildArray: () => (/* binding */ j)
/* harmony export */ });
var n,
  l,
  u,
  i,
  t,
  r,
  o,
  f,
  e,
  c = {},
  s = [],
  a = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;
function h(n, l) {
  for (var u in l) n[u] = l[u];
  return n;
}
function v(n) {
  var l = n.parentNode;
  l && l.removeChild(n);
}
function y(l, u, i) {
  var t,
    r,
    o,
    f = {};
  for (o in u) "key" == o ? t = u[o] : "ref" == o ? r = u[o] : f[o] = u[o];
  if (arguments.length > 2 && (f.children = arguments.length > 3 ? n.call(arguments, 2) : i), "function" == typeof l && null != l.defaultProps) for (o in l.defaultProps) void 0 === f[o] && (f[o] = l.defaultProps[o]);
  return p(l, f, t, r, null);
}
function p(n, i, t, r, o) {
  var f = {
    type: n,
    props: i,
    key: t,
    ref: r,
    __k: null,
    __: null,
    __b: 0,
    __e: null,
    __d: void 0,
    __c: null,
    __h: null,
    constructor: void 0,
    __v: null == o ? ++u : o
  };
  return null == o && null != l.vnode && l.vnode(f), f;
}
function d() {
  return {
    current: null
  };
}
function _(n) {
  return n.children;
}
function k(n, l, u, i, t) {
  var r;
  for (r in u) "children" === r || "key" === r || r in l || g(n, r, null, u[r], i);
  for (r in l) t && "function" != typeof l[r] || "children" === r || "key" === r || "value" === r || "checked" === r || u[r] === l[r] || g(n, r, l[r], u[r], i);
}
function b(n, l, u) {
  "-" === l[0] ? n.setProperty(l, null == u ? "" : u) : n[l] = null == u ? "" : "number" != typeof u || a.test(l) ? u : u + "px";
}
function g(n, l, u, i, t) {
  var r;
  n: if ("style" === l) {
    if ("string" == typeof u) n.style.cssText = u;else {
      if ("string" == typeof i && (n.style.cssText = i = ""), i) for (l in i) u && l in u || b(n.style, l, "");
      if (u) for (l in u) i && u[l] === i[l] || b(n.style, l, u[l]);
    }
  } else if ("o" === l[0] && "n" === l[1]) r = l !== (l = l.replace(/Capture$/, "")), l = l.toLowerCase() in n ? l.toLowerCase().slice(2) : l.slice(2), n.l || (n.l = {}), n.l[l + r] = u, u ? i || n.addEventListener(l, r ? w : m, r) : n.removeEventListener(l, r ? w : m, r);else if ("dangerouslySetInnerHTML" !== l) {
    if (t) l = l.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");else if ("width" !== l && "height" !== l && "href" !== l && "list" !== l && "form" !== l && "tabIndex" !== l && "download" !== l && l in n) try {
      n[l] = null == u ? "" : u;
      break n;
    } catch (n) {}
    "function" == typeof u || (null == u || !1 === u && -1 == l.indexOf("-") ? n.removeAttribute(l) : n.setAttribute(l, u));
  }
}
function m(n) {
  t = !0;
  try {
    return this.l[n.type + !1](l.event ? l.event(n) : n);
  } finally {
    t = !1;
  }
}
function w(n) {
  t = !0;
  try {
    return this.l[n.type + !0](l.event ? l.event(n) : n);
  } finally {
    t = !1;
  }
}
function x(n, l) {
  this.props = n, this.context = l;
}
function A(n, l) {
  if (null == l) return n.__ ? A(n.__, n.__.__k.indexOf(n) + 1) : null;
  for (var u; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) return u.__e;
  return "function" == typeof n.type ? A(n) : null;
}
function P(n) {
  var l, u;
  if (null != (n = n.__) && null != n.__c) {
    for (n.__e = n.__c.base = null, l = 0; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) {
      n.__e = n.__c.base = u.__e;
      break;
    }
    return P(n);
  }
}
function C(n) {
  t ? setTimeout(n) : f(n);
}
function T(n) {
  (!n.__d && (n.__d = !0) && r.push(n) && !$.__r++ || o !== l.debounceRendering) && ((o = l.debounceRendering) || C)($);
}
function $() {
  var n, l, u, i, t, o, f, e;
  for (r.sort(function (n, l) {
    return n.__v.__b - l.__v.__b;
  }); n = r.shift();) n.__d && (l = r.length, i = void 0, t = void 0, f = (o = (u = n).__v).__e, (e = u.__P) && (i = [], (t = h({}, o)).__v = o.__v + 1, M(e, o, t, u.__n, void 0 !== e.ownerSVGElement, null != o.__h ? [f] : null, i, null == f ? A(o) : f, o.__h), N(i, o), o.__e != f && P(o)), r.length > l && r.sort(function (n, l) {
    return n.__v.__b - l.__v.__b;
  }));
  $.__r = 0;
}
function H(n, l, u, i, t, r, o, f, e, a) {
  var h,
    v,
    y,
    d,
    k,
    b,
    g,
    m = i && i.__k || s,
    w = m.length;
  for (u.__k = [], h = 0; h < l.length; h++) if (null != (d = u.__k[h] = null == (d = l[h]) || "boolean" == typeof d ? null : "string" == typeof d || "number" == typeof d || "bigint" == typeof d ? p(null, d, null, null, d) : Array.isArray(d) ? p(_, {
    children: d
  }, null, null, null) : d.__b > 0 ? p(d.type, d.props, d.key, d.ref ? d.ref : null, d.__v) : d)) {
    if (d.__ = u, d.__b = u.__b + 1, null === (y = m[h]) || y && d.key == y.key && d.type === y.type) m[h] = void 0;else for (v = 0; v < w; v++) {
      if ((y = m[v]) && d.key == y.key && d.type === y.type) {
        m[v] = void 0;
        break;
      }
      y = null;
    }
    M(n, d, y = y || c, t, r, o, f, e, a), k = d.__e, (v = d.ref) && y.ref != v && (g || (g = []), y.ref && g.push(y.ref, null, d), g.push(v, d.__c || k, d)), null != k ? (null == b && (b = k), "function" == typeof d.type && d.__k === y.__k ? d.__d = e = I(d, e, n) : e = z(n, d, y, m, k, e), "function" == typeof u.type && (u.__d = e)) : e && y.__e == e && e.parentNode != n && (e = A(y));
  }
  for (u.__e = b, h = w; h--;) null != m[h] && ("function" == typeof u.type && null != m[h].__e && m[h].__e == u.__d && (u.__d = L(i).nextSibling), q(m[h], m[h]));
  if (g) for (h = 0; h < g.length; h++) S(g[h], g[++h], g[++h]);
}
function I(n, l, u) {
  for (var i, t = n.__k, r = 0; t && r < t.length; r++) (i = t[r]) && (i.__ = n, l = "function" == typeof i.type ? I(i, l, u) : z(u, i, i, t, i.__e, l));
  return l;
}
function j(n, l) {
  return l = l || [], null == n || "boolean" == typeof n || (Array.isArray(n) ? n.some(function (n) {
    j(n, l);
  }) : l.push(n)), l;
}
function z(n, l, u, i, t, r) {
  var o, f, e;
  if (void 0 !== l.__d) o = l.__d, l.__d = void 0;else if (null == u || t != r || null == t.parentNode) n: if (null == r || r.parentNode !== n) n.appendChild(t), o = null;else {
    for (f = r, e = 0; (f = f.nextSibling) && e < i.length; e += 1) if (f == t) break n;
    n.insertBefore(t, r), o = r;
  }
  return void 0 !== o ? o : t.nextSibling;
}
function L(n) {
  var l, u, i;
  if (null == n.type || "string" == typeof n.type) return n.__e;
  if (n.__k) for (l = n.__k.length - 1; l >= 0; l--) if ((u = n.__k[l]) && (i = L(u))) return i;
  return null;
}
function M(n, u, i, t, r, o, f, e, c) {
  var s,
    a,
    v,
    y,
    p,
    d,
    k,
    b,
    g,
    m,
    w,
    A,
    P,
    C,
    T,
    $ = u.type;
  if (void 0 !== u.constructor) return null;
  null != i.__h && (c = i.__h, e = u.__e = i.__e, u.__h = null, o = [e]), (s = l.__b) && s(u);
  try {
    n: if ("function" == typeof $) {
      if (b = u.props, g = (s = $.contextType) && t[s.__c], m = s ? g ? g.props.value : s.__ : t, i.__c ? k = (a = u.__c = i.__c).__ = a.__E : ("prototype" in $ && $.prototype.render ? u.__c = a = new $(b, m) : (u.__c = a = new x(b, m), a.constructor = $, a.render = B), g && g.sub(a), a.props = b, a.state || (a.state = {}), a.context = m, a.__n = t, v = a.__d = !0, a.__h = [], a._sb = []), null == a.__s && (a.__s = a.state), null != $.getDerivedStateFromProps && (a.__s == a.state && (a.__s = h({}, a.__s)), h(a.__s, $.getDerivedStateFromProps(b, a.__s))), y = a.props, p = a.state, a.__v = u, v) null == $.getDerivedStateFromProps && null != a.componentWillMount && a.componentWillMount(), null != a.componentDidMount && a.__h.push(a.componentDidMount);else {
        if (null == $.getDerivedStateFromProps && b !== y && null != a.componentWillReceiveProps && a.componentWillReceiveProps(b, m), !a.__e && null != a.shouldComponentUpdate && !1 === a.shouldComponentUpdate(b, a.__s, m) || u.__v === i.__v) {
          for (u.__v !== i.__v && (a.props = b, a.state = a.__s, a.__d = !1), u.__e = i.__e, u.__k = i.__k, u.__k.forEach(function (n) {
            n && (n.__ = u);
          }), w = 0; w < a._sb.length; w++) a.__h.push(a._sb[w]);
          a._sb = [], a.__h.length && f.push(a);
          break n;
        }
        null != a.componentWillUpdate && a.componentWillUpdate(b, a.__s, m), null != a.componentDidUpdate && a.__h.push(function () {
          a.componentDidUpdate(y, p, d);
        });
      }
      if (a.context = m, a.props = b, a.__P = n, A = l.__r, P = 0, "prototype" in $ && $.prototype.render) {
        for (a.state = a.__s, a.__d = !1, A && A(u), s = a.render(a.props, a.state, a.context), C = 0; C < a._sb.length; C++) a.__h.push(a._sb[C]);
        a._sb = [];
      } else do {
        a.__d = !1, A && A(u), s = a.render(a.props, a.state, a.context), a.state = a.__s;
      } while (a.__d && ++P < 25);
      a.state = a.__s, null != a.getChildContext && (t = h(h({}, t), a.getChildContext())), v || null == a.getSnapshotBeforeUpdate || (d = a.getSnapshotBeforeUpdate(y, p)), T = null != s && s.type === _ && null == s.key ? s.props.children : s, H(n, Array.isArray(T) ? T : [T], u, i, t, r, o, f, e, c), a.base = u.__e, u.__h = null, a.__h.length && f.push(a), k && (a.__E = a.__ = null), a.__e = !1;
    } else null == o && u.__v === i.__v ? (u.__k = i.__k, u.__e = i.__e) : u.__e = O(i.__e, u, i, t, r, o, f, c);
    (s = l.diffed) && s(u);
  } catch (n) {
    u.__v = null, (c || null != o) && (u.__e = e, u.__h = !!c, o[o.indexOf(e)] = null), l.__e(n, u, i);
  }
}
function N(n, u) {
  l.__c && l.__c(u, n), n.some(function (u) {
    try {
      n = u.__h, u.__h = [], n.some(function (n) {
        n.call(u);
      });
    } catch (n) {
      l.__e(n, u.__v);
    }
  });
}
function O(l, u, i, t, r, o, f, e) {
  var s,
    a,
    h,
    y = i.props,
    p = u.props,
    d = u.type,
    _ = 0;
  if ("svg" === d && (r = !0), null != o) for (; _ < o.length; _++) if ((s = o[_]) && "setAttribute" in s == !!d && (d ? s.localName === d : 3 === s.nodeType)) {
    l = s, o[_] = null;
    break;
  }
  if (null == l) {
    if (null === d) return document.createTextNode(p);
    l = r ? document.createElementNS("http://www.w3.org/2000/svg", d) : document.createElement(d, p.is && p), o = null, e = !1;
  }
  if (null === d) y === p || e && l.data === p || (l.data = p);else {
    if (o = o && n.call(l.childNodes), a = (y = i.props || c).dangerouslySetInnerHTML, h = p.dangerouslySetInnerHTML, !e) {
      if (null != o) for (y = {}, _ = 0; _ < l.attributes.length; _++) y[l.attributes[_].name] = l.attributes[_].value;
      (h || a) && (h && (a && h.__html == a.__html || h.__html === l.innerHTML) || (l.innerHTML = h && h.__html || ""));
    }
    if (k(l, p, y, r, e), h) u.__k = [];else if (_ = u.props.children, H(l, Array.isArray(_) ? _ : [_], u, i, t, r && "foreignObject" !== d, o, f, o ? o[0] : i.__k && A(i, 0), e), null != o) for (_ = o.length; _--;) null != o[_] && v(o[_]);
    e || ("value" in p && void 0 !== (_ = p.value) && (_ !== l.value || "progress" === d && !_ || "option" === d && _ !== y.value) && g(l, "value", _, y.value, !1), "checked" in p && void 0 !== (_ = p.checked) && _ !== l.checked && g(l, "checked", _, y.checked, !1));
  }
  return l;
}
function S(n, u, i) {
  try {
    "function" == typeof n ? n(u) : n.current = u;
  } catch (n) {
    l.__e(n, i);
  }
}
function q(n, u, i) {
  var t, r;
  if (l.unmount && l.unmount(n), (t = n.ref) && (t.current && t.current !== n.__e || S(t, null, u)), null != (t = n.__c)) {
    if (t.componentWillUnmount) try {
      t.componentWillUnmount();
    } catch (n) {
      l.__e(n, u);
    }
    t.base = t.__P = null, n.__c = void 0;
  }
  if (t = n.__k) for (r = 0; r < t.length; r++) t[r] && q(t[r], u, i || "function" != typeof n.type);
  i || null == n.__e || v(n.__e), n.__ = n.__e = n.__d = void 0;
}
function B(n, l, u) {
  return this.constructor(n, u);
}
function D(u, i, t) {
  var r, o, f;
  l.__ && l.__(u, i), o = (r = "function" == typeof t) ? null : t && t.__k || i.__k, f = [], M(i, u = (!r && t || i).__k = y(_, null, [u]), o || c, c, void 0 !== i.ownerSVGElement, !r && t ? [t] : o ? null : i.firstChild ? n.call(i.childNodes) : null, f, !r && t ? t : o ? o.__e : i.firstChild, r), N(f, u);
}
function E(n, l) {
  D(n, l, E);
}
function F(l, u, i) {
  var t,
    r,
    o,
    f = h({}, l.props);
  for (o in u) "key" == o ? t = u[o] : "ref" == o ? r = u[o] : f[o] = u[o];
  return arguments.length > 2 && (f.children = arguments.length > 3 ? n.call(arguments, 2) : i), p(l.type, f, t || l.key, r || l.ref, null);
}
function G(n, l) {
  var u = {
    __c: l = "__cC" + e++,
    __: n,
    Consumer: function (n, l) {
      return n.children(l);
    },
    Provider: function (n) {
      var u, i;
      return this.getChildContext || (u = [], (i = {})[l] = this, this.getChildContext = function () {
        return i;
      }, this.shouldComponentUpdate = function (n) {
        this.props.value !== n.value && u.some(function (n) {
          n.__e = !0, T(n);
        });
      }, this.sub = function (n) {
        u.push(n);
        var l = n.componentWillUnmount;
        n.componentWillUnmount = function () {
          u.splice(u.indexOf(n), 1), l && l.call(n);
        };
      }), n.children;
    }
  };
  return u.Provider.__ = u.Consumer.contextType = u;
}
n = s.slice, l = {
  __e: function (n, l, u, i) {
    for (var t, r, o; l = l.__;) if ((t = l.__c) && !t.__) try {
      if ((r = t.constructor) && null != r.getDerivedStateFromError && (t.setState(r.getDerivedStateFromError(n)), o = t.__d), null != t.componentDidCatch && (t.componentDidCatch(n, i || {}), o = t.__d), o) return t.__E = t;
    } catch (l) {
      n = l;
    }
    throw n;
  }
}, u = 0, i = function (n) {
  return null != n && void 0 === n.constructor;
}, t = !1, x.prototype.setState = function (n, l) {
  var u;
  u = null != this.__s && this.__s !== this.state ? this.__s : this.__s = h({}, this.state), "function" == typeof n && (n = n(h({}, u), this.props)), n && h(u, n), null != n && this.__v && (l && this._sb.push(l), T(this));
}, x.prototype.forceUpdate = function (n) {
  this.__v && (this.__e = !0, n && this.__h.push(n), T(this));
}, x.prototype.render = _, r = [], f = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, $.__r = 0, e = 0;


/***/ }),

/***/ 56734:
/*!********************************************************!*\
  !*** ./node_modules/preact/hooks/dist/hooks.module.js ***!
  \********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   useCallback: () => (/* binding */ T),
/* harmony export */   useContext: () => (/* binding */ q),
/* harmony export */   useDebugValue: () => (/* binding */ x),
/* harmony export */   useEffect: () => (/* binding */ h),
/* harmony export */   useErrorBoundary: () => (/* binding */ P),
/* harmony export */   useId: () => (/* binding */ V),
/* harmony export */   useImperativeHandle: () => (/* binding */ A),
/* harmony export */   useLayoutEffect: () => (/* binding */ s),
/* harmony export */   useMemo: () => (/* binding */ F),
/* harmony export */   useReducer: () => (/* binding */ y),
/* harmony export */   useRef: () => (/* binding */ _),
/* harmony export */   useState: () => (/* binding */ p)
/* harmony export */ });
/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ 78048);

var t,
  r,
  u,
  i,
  o = 0,
  f = [],
  c = [],
  e = preact__WEBPACK_IMPORTED_MODULE_0__.options.__b,
  a = preact__WEBPACK_IMPORTED_MODULE_0__.options.__r,
  v = preact__WEBPACK_IMPORTED_MODULE_0__.options.diffed,
  l = preact__WEBPACK_IMPORTED_MODULE_0__.options.__c,
  m = preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount;
function d(t, u) {
  preact__WEBPACK_IMPORTED_MODULE_0__.options.__h && preact__WEBPACK_IMPORTED_MODULE_0__.options.__h(r, t, o || u), o = 0;
  var i = r.__H || (r.__H = {
    __: [],
    __h: []
  });
  return t >= i.__.length && i.__.push({
    __V: c
  }), i.__[t];
}
function p(n) {
  return o = 1, y(B, n);
}
function y(n, u, i) {
  var o = d(t++, 2);
  if (o.t = n, !o.__c && (o.__ = [i ? i(u) : B(void 0, u), function (n) {
    var t = o.__N ? o.__N[0] : o.__[0],
      r = o.t(t, n);
    t !== r && (o.__N = [r, o.__[1]], o.__c.setState({}));
  }], o.__c = r, !r.u)) {
    r.u = !0;
    var f = r.shouldComponentUpdate;
    r.shouldComponentUpdate = function (n, t, r) {
      if (!o.__c.__H) return !0;
      var u = o.__c.__H.__.filter(function (n) {
        return n.__c;
      });
      if (u.every(function (n) {
        return !n.__N;
      })) return !f || f.call(this, n, t, r);
      var i = !1;
      return u.forEach(function (n) {
        if (n.__N) {
          var t = n.__[0];
          n.__ = n.__N, n.__N = void 0, t !== n.__[0] && (i = !0);
        }
      }), !(!i && o.__c.props === n) && (!f || f.call(this, n, t, r));
    };
  }
  return o.__N || o.__;
}
function h(u, i) {
  var o = d(t++, 3);
  !preact__WEBPACK_IMPORTED_MODULE_0__.options.__s && z(o.__H, i) && (o.__ = u, o.i = i, r.__H.__h.push(o));
}
function s(u, i) {
  var o = d(t++, 4);
  !preact__WEBPACK_IMPORTED_MODULE_0__.options.__s && z(o.__H, i) && (o.__ = u, o.i = i, r.__h.push(o));
}
function _(n) {
  return o = 5, F(function () {
    return {
      current: n
    };
  }, []);
}
function A(n, t, r) {
  o = 6, s(function () {
    return "function" == typeof n ? (n(t()), function () {
      return n(null);
    }) : n ? (n.current = t(), function () {
      return n.current = null;
    }) : void 0;
  }, null == r ? r : r.concat(n));
}
function F(n, r) {
  var u = d(t++, 7);
  return z(u.__H, r) ? (u.__V = n(), u.i = r, u.__h = n, u.__V) : u.__;
}
function T(n, t) {
  return o = 8, F(function () {
    return n;
  }, t);
}
function q(n) {
  var u = r.context[n.__c],
    i = d(t++, 9);
  return i.c = n, u ? (null == i.__ && (i.__ = !0, u.sub(r)), u.props.value) : n.__;
}
function x(t, r) {
  preact__WEBPACK_IMPORTED_MODULE_0__.options.useDebugValue && preact__WEBPACK_IMPORTED_MODULE_0__.options.useDebugValue(r ? r(t) : t);
}
function P(n) {
  var u = d(t++, 10),
    i = p();
  return u.__ = n, r.componentDidCatch || (r.componentDidCatch = function (n, t) {
    u.__ && u.__(n, t), i[1](n);
  }), [i[0], function () {
    i[1](void 0);
  }];
}
function V() {
  var n = d(t++, 11);
  if (!n.__) {
    for (var u = r.__v; null !== u && !u.__m && null !== u.__;) u = u.__;
    var i = u.__m || (u.__m = [0, 0]);
    n.__ = "P" + i[0] + "-" + i[1]++;
  }
  return n.__;
}
function b() {
  for (var t; t = f.shift();) if (t.__P && t.__H) try {
    t.__H.__h.forEach(k), t.__H.__h.forEach(w), t.__H.__h = [];
  } catch (r) {
    t.__H.__h = [], preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(r, t.__v);
  }
}
preact__WEBPACK_IMPORTED_MODULE_0__.options.__b = function (n) {
  r = null, e && e(n);
}, preact__WEBPACK_IMPORTED_MODULE_0__.options.__r = function (n) {
  a && a(n), t = 0;
  var i = (r = n.__c).__H;
  i && (u === r ? (i.__h = [], r.__h = [], i.__.forEach(function (n) {
    n.__N && (n.__ = n.__N), n.__V = c, n.__N = n.i = void 0;
  })) : (i.__h.forEach(k), i.__h.forEach(w), i.__h = [])), u = r;
}, preact__WEBPACK_IMPORTED_MODULE_0__.options.diffed = function (t) {
  v && v(t);
  var o = t.__c;
  o && o.__H && (o.__H.__h.length && (1 !== f.push(o) && i === preact__WEBPACK_IMPORTED_MODULE_0__.options.requestAnimationFrame || ((i = preact__WEBPACK_IMPORTED_MODULE_0__.options.requestAnimationFrame) || j)(b)), o.__H.__.forEach(function (n) {
    n.i && (n.__H = n.i), n.__V !== c && (n.__ = n.__V), n.i = void 0, n.__V = c;
  })), u = r = null;
}, preact__WEBPACK_IMPORTED_MODULE_0__.options.__c = function (t, r) {
  r.some(function (t) {
    try {
      t.__h.forEach(k), t.__h = t.__h.filter(function (n) {
        return !n.__ || w(n);
      });
    } catch (u) {
      r.some(function (n) {
        n.__h && (n.__h = []);
      }), r = [], preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(u, t.__v);
    }
  }), l && l(t, r);
}, preact__WEBPACK_IMPORTED_MODULE_0__.options.unmount = function (t) {
  m && m(t);
  var r,
    u = t.__c;
  u && u.__H && (u.__H.__.forEach(function (n) {
    try {
      k(n);
    } catch (n) {
      r = n;
    }
  }), u.__H = void 0, r && preact__WEBPACK_IMPORTED_MODULE_0__.options.__e(r, u.__v));
};
var g = "function" == typeof requestAnimationFrame;
function j(n) {
  var t,
    r = function () {
      clearTimeout(u), g && cancelAnimationFrame(t), setTimeout(n);
    },
    u = setTimeout(r, 100);
  g && (t = requestAnimationFrame(r));
}
function k(n) {
  var t = r,
    u = n.__c;
  "function" == typeof u && (n.__c = void 0, u()), r = t;
}
function w(n) {
  var t = r;
  n.__c = n.__(), r = t;
}
function z(n, t) {
  return !n || n.length !== t.length || t.some(function (t, r) {
    return t !== n[r];
  });
}
function B(n, t) {
  return "function" == typeof t ? t(n) : t;
}


/***/ }),

/***/ 75797:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/BehaviorSubject.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BehaviorSubject: () => (/* binding */ BehaviorSubject)
/* harmony export */ });
/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subject */ 10819);

class BehaviorSubject extends _Subject__WEBPACK_IMPORTED_MODULE_0__.Subject {
  constructor(_value) {
    super();
    this._value = _value;
  }
  get value() {
    return this.getValue();
  }
  _subscribe(subscriber) {
    const subscription = super._subscribe(subscriber);
    !subscription.closed && subscriber.next(this._value);
    return subscription;
  }
  getValue() {
    const {
      hasError,
      thrownError,
      _value
    } = this;
    if (hasError) {
      throw thrownError;
    }
    this._throwIfClosed();
    return _value;
  }
  next(value) {
    super.next(this._value = value);
  }
}

/***/ }),

/***/ 52296:
/*!*************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Notification.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Notification: () => (/* binding */ Notification),
/* harmony export */   NotificationKind: () => (/* binding */ NotificationKind),
/* harmony export */   observeNotification: () => (/* binding */ observeNotification)
/* harmony export */ });
/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./observable/empty */ 59400);
/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./observable/of */ 59452);
/* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./observable/throwError */ 77919);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/isFunction */ 81530);




var NotificationKind;
(function (NotificationKind) {
  NotificationKind["NEXT"] = "N";
  NotificationKind["ERROR"] = "E";
  NotificationKind["COMPLETE"] = "C";
})(NotificationKind || (NotificationKind = {}));
class Notification {
  constructor(kind, value, error) {
    this.kind = kind;
    this.value = value;
    this.error = error;
    this.hasValue = kind === 'N';
  }
  observe(observer) {
    return observeNotification(this, observer);
  }
  do(nextHandler, errorHandler, completeHandler) {
    const {
      kind,
      value,
      error
    } = this;
    return kind === 'N' ? nextHandler === null || nextHandler === void 0 ? void 0 : nextHandler(value) : kind === 'E' ? errorHandler === null || errorHandler === void 0 ? void 0 : errorHandler(error) : completeHandler === null || completeHandler === void 0 ? void 0 : completeHandler();
  }
  accept(nextOrObserver, error, complete) {
    var _a;
    return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)((_a = nextOrObserver) === null || _a === void 0 ? void 0 : _a.next) ? this.observe(nextOrObserver) : this.do(nextOrObserver, error, complete);
  }
  toObservable() {
    const {
      kind,
      value,
      error
    } = this;
    const result = kind === 'N' ? (0,_observable_of__WEBPACK_IMPORTED_MODULE_1__.of)(value) : kind === 'E' ? (0,_observable_throwError__WEBPACK_IMPORTED_MODULE_2__.throwError)(() => error) : kind === 'C' ? _observable_empty__WEBPACK_IMPORTED_MODULE_3__.EMPTY : 0;
    if (!result) {
      throw new TypeError(`Unexpected notification kind ${kind}`);
    }
    return result;
  }
  static createNext(value) {
    return new Notification('N', value);
  }
  static createError(err) {
    return new Notification('E', undefined, err);
  }
  static createComplete() {
    return Notification.completeNotification;
  }
}
Notification.completeNotification = new Notification('C');
function observeNotification(notification, observer) {
  var _a, _b, _c;
  const {
    kind,
    value,
    error
  } = notification;
  if (typeof kind !== 'string') {
    throw new TypeError('Invalid notification, missing "kind"');
  }
  kind === 'N' ? (_a = observer.next) === null || _a === void 0 ? void 0 : _a.call(observer, value) : kind === 'E' ? (_b = observer.error) === null || _b === void 0 ? void 0 : _b.call(observer, error) : (_c = observer.complete) === null || _c === void 0 ? void 0 : _c.call(observer);
}

/***/ }),

/***/ 22220:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/NotificationFactories.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   COMPLETE_NOTIFICATION: () => (/* binding */ COMPLETE_NOTIFICATION),
/* harmony export */   createNotification: () => (/* binding */ createNotification),
/* harmony export */   errorNotification: () => (/* binding */ errorNotification),
/* harmony export */   nextNotification: () => (/* binding */ nextNotification)
/* harmony export */ });
const COMPLETE_NOTIFICATION = (() => createNotification('C', undefined, undefined))();
function errorNotification(error) {
  return createNotification('E', undefined, error);
}
function nextNotification(value) {
  return createNotification('N', value, undefined);
}
function createNotification(kind, value, error) {
  return {
    kind,
    value,
    error
  };
}

/***/ }),

/***/ 43942:
/*!***********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Observable.js ***!
  \***********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Observable: () => (/* binding */ Observable)
/* harmony export */ });
/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 89285);
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Subscription */ 2510);
/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./symbol/observable */ 44127);
/* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./util/pipe */ 95682);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./config */ 62213);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/isFunction */ 81530);
/* harmony import */ var _util_errorContext__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/errorContext */ 60023);







class Observable {
  constructor(subscribe) {
    if (subscribe) {
      this._subscribe = subscribe;
    }
  }
  lift(operator) {
    const observable = new Observable();
    observable.source = this;
    observable.operator = operator;
    return observable;
  }
  subscribe(observerOrNext, error, complete) {
    const subscriber = isSubscriber(observerOrNext) ? observerOrNext : new _Subscriber__WEBPACK_IMPORTED_MODULE_0__.SafeSubscriber(observerOrNext, error, complete);
    (0,_util_errorContext__WEBPACK_IMPORTED_MODULE_1__.errorContext)(() => {
      const {
        operator,
        source
      } = this;
      subscriber.add(operator ? operator.call(subscriber, source) : source ? this._subscribe(subscriber) : this._trySubscribe(subscriber));
    });
    return subscriber;
  }
  _trySubscribe(sink) {
    try {
      return this._subscribe(sink);
    } catch (err) {
      sink.error(err);
    }
  }
  forEach(next, promiseCtor) {
    promiseCtor = getPromiseCtor(promiseCtor);
    return new promiseCtor((resolve, reject) => {
      const subscriber = new _Subscriber__WEBPACK_IMPORTED_MODULE_0__.SafeSubscriber({
        next: value => {
          try {
            next(value);
          } catch (err) {
            reject(err);
            subscriber.unsubscribe();
          }
        },
        error: reject,
        complete: resolve
      });
      this.subscribe(subscriber);
    });
  }
  _subscribe(subscriber) {
    var _a;
    return (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber);
  }
  [_symbol_observable__WEBPACK_IMPORTED_MODULE_2__.observable]() {
    return this;
  }
  pipe(...operations) {
    return (0,_util_pipe__WEBPACK_IMPORTED_MODULE_3__.pipeFromArray)(operations)(this);
  }
  toPromise(promiseCtor) {
    promiseCtor = getPromiseCtor(promiseCtor);
    return new promiseCtor((resolve, reject) => {
      let value;
      this.subscribe(x => value = x, err => reject(err), () => resolve(value));
    });
  }
}
Observable.create = subscribe => {
  return new Observable(subscribe);
};
function getPromiseCtor(promiseCtor) {
  var _a;
  return (_a = promiseCtor !== null && promiseCtor !== void 0 ? promiseCtor : _config__WEBPACK_IMPORTED_MODULE_4__.config.Promise) !== null && _a !== void 0 ? _a : Promise;
}
function isObserver(value) {
  return value && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_5__.isFunction)(value.next) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_5__.isFunction)(value.error) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_5__.isFunction)(value.complete);
}
function isSubscriber(value) {
  return value && value instanceof _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber || isObserver(value) && (0,_Subscription__WEBPACK_IMPORTED_MODULE_6__.isSubscription)(value);
}

/***/ }),

/***/ 56042:
/*!**************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/ReplaySubject.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ReplaySubject: () => (/* binding */ ReplaySubject)
/* harmony export */ });
/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subject */ 10819);
/* harmony import */ var _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scheduler/dateTimestampProvider */ 35152);


class ReplaySubject extends _Subject__WEBPACK_IMPORTED_MODULE_0__.Subject {
  constructor(_bufferSize = Infinity, _windowTime = Infinity, _timestampProvider = _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_1__.dateTimestampProvider) {
    super();
    this._bufferSize = _bufferSize;
    this._windowTime = _windowTime;
    this._timestampProvider = _timestampProvider;
    this._buffer = [];
    this._infiniteTimeWindow = true;
    this._infiniteTimeWindow = _windowTime === Infinity;
    this._bufferSize = Math.max(1, _bufferSize);
    this._windowTime = Math.max(1, _windowTime);
  }
  next(value) {
    const {
      isStopped,
      _buffer,
      _infiniteTimeWindow,
      _timestampProvider,
      _windowTime
    } = this;
    if (!isStopped) {
      _buffer.push(value);
      !_infiniteTimeWindow && _buffer.push(_timestampProvider.now() + _windowTime);
    }
    this._trimBuffer();
    super.next(value);
  }
  _subscribe(subscriber) {
    this._throwIfClosed();
    this._trimBuffer();
    const subscription = this._innerSubscribe(subscriber);
    const {
      _infiniteTimeWindow,
      _buffer
    } = this;
    const copy = _buffer.slice();
    for (let i = 0; i < copy.length && !subscriber.closed; i += _infiniteTimeWindow ? 1 : 2) {
      subscriber.next(copy[i]);
    }
    this._checkFinalizedStatuses(subscriber);
    return subscription;
  }
  _trimBuffer() {
    const {
      _bufferSize,
      _timestampProvider,
      _buffer,
      _infiniteTimeWindow
    } = this;
    const adjustedBufferSize = (_infiniteTimeWindow ? 1 : 2) * _bufferSize;
    _bufferSize < Infinity && adjustedBufferSize < _buffer.length && _buffer.splice(0, _buffer.length - adjustedBufferSize);
    if (!_infiniteTimeWindow) {
      const now = _timestampProvider.now();
      let last = 0;
      for (let i = 1; i < _buffer.length && _buffer[i] <= now; i += 2) {
        last = i;
      }
      last && _buffer.splice(0, last + 1);
    }
  }
}

/***/ }),

/***/ 71962:
/*!**********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Scheduler.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Scheduler: () => (/* binding */ Scheduler)
/* harmony export */ });
/* harmony import */ var _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./scheduler/dateTimestampProvider */ 35152);

class Scheduler {
  constructor(schedulerActionCtor, now = Scheduler.now) {
    this.schedulerActionCtor = schedulerActionCtor;
    this.now = now;
  }
  schedule(work, delay = 0, state) {
    return new this.schedulerActionCtor(this, work).schedule(state, delay);
  }
}
Scheduler.now = _scheduler_dateTimestampProvider__WEBPACK_IMPORTED_MODULE_0__.dateTimestampProvider.now;

/***/ }),

/***/ 10819:
/*!********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Subject.js ***!
  \********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnonymousSubject: () => (/* binding */ AnonymousSubject),
/* harmony export */   Subject: () => (/* binding */ Subject)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Observable */ 43942);
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./Subscription */ 2510);
/* harmony import */ var _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/ObjectUnsubscribedError */ 21910);
/* harmony import */ var _util_arrRemove__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./util/arrRemove */ 80967);
/* harmony import */ var _util_errorContext__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/errorContext */ 60023);





class Subject extends _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable {
  constructor() {
    super();
    this.closed = false;
    this.currentObservers = null;
    this.observers = [];
    this.isStopped = false;
    this.hasError = false;
    this.thrownError = null;
  }
  lift(operator) {
    const subject = new AnonymousSubject(this, this);
    subject.operator = operator;
    return subject;
  }
  _throwIfClosed() {
    if (this.closed) {
      throw new _util_ObjectUnsubscribedError__WEBPACK_IMPORTED_MODULE_1__.ObjectUnsubscribedError();
    }
  }
  next(value) {
    (0,_util_errorContext__WEBPACK_IMPORTED_MODULE_2__.errorContext)(() => {
      this._throwIfClosed();
      if (!this.isStopped) {
        if (!this.currentObservers) {
          this.currentObservers = Array.from(this.observers);
        }
        for (const observer of this.currentObservers) {
          observer.next(value);
        }
      }
    });
  }
  error(err) {
    (0,_util_errorContext__WEBPACK_IMPORTED_MODULE_2__.errorContext)(() => {
      this._throwIfClosed();
      if (!this.isStopped) {
        this.hasError = this.isStopped = true;
        this.thrownError = err;
        const {
          observers
        } = this;
        while (observers.length) {
          observers.shift().error(err);
        }
      }
    });
  }
  complete() {
    (0,_util_errorContext__WEBPACK_IMPORTED_MODULE_2__.errorContext)(() => {
      this._throwIfClosed();
      if (!this.isStopped) {
        this.isStopped = true;
        const {
          observers
        } = this;
        while (observers.length) {
          observers.shift().complete();
        }
      }
    });
  }
  unsubscribe() {
    this.isStopped = this.closed = true;
    this.observers = this.currentObservers = null;
  }
  get observed() {
    var _a;
    return ((_a = this.observers) === null || _a === void 0 ? void 0 : _a.length) > 0;
  }
  _trySubscribe(subscriber) {
    this._throwIfClosed();
    return super._trySubscribe(subscriber);
  }
  _subscribe(subscriber) {
    this._throwIfClosed();
    this._checkFinalizedStatuses(subscriber);
    return this._innerSubscribe(subscriber);
  }
  _innerSubscribe(subscriber) {
    const {
      hasError,
      isStopped,
      observers
    } = this;
    if (hasError || isStopped) {
      return _Subscription__WEBPACK_IMPORTED_MODULE_3__.EMPTY_SUBSCRIPTION;
    }
    this.currentObservers = null;
    observers.push(subscriber);
    return new _Subscription__WEBPACK_IMPORTED_MODULE_3__.Subscription(() => {
      this.currentObservers = null;
      (0,_util_arrRemove__WEBPACK_IMPORTED_MODULE_4__.arrRemove)(observers, subscriber);
    });
  }
  _checkFinalizedStatuses(subscriber) {
    const {
      hasError,
      thrownError,
      isStopped
    } = this;
    if (hasError) {
      subscriber.error(thrownError);
    } else if (isStopped) {
      subscriber.complete();
    }
  }
  asObservable() {
    const observable = new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable();
    observable.source = this;
    return observable;
  }
}
Subject.create = (destination, source) => {
  return new AnonymousSubject(destination, source);
};
class AnonymousSubject extends Subject {
  constructor(destination, source) {
    super();
    this.destination = destination;
    this.source = source;
  }
  next(value) {
    var _a, _b;
    (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.next) === null || _b === void 0 ? void 0 : _b.call(_a, value);
  }
  error(err) {
    var _a, _b;
    (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.error) === null || _b === void 0 ? void 0 : _b.call(_a, err);
  }
  complete() {
    var _a, _b;
    (_b = (_a = this.destination) === null || _a === void 0 ? void 0 : _a.complete) === null || _b === void 0 ? void 0 : _b.call(_a);
  }
  _subscribe(subscriber) {
    var _a, _b;
    return (_b = (_a = this.source) === null || _a === void 0 ? void 0 : _a.subscribe(subscriber)) !== null && _b !== void 0 ? _b : _Subscription__WEBPACK_IMPORTED_MODULE_3__.EMPTY_SUBSCRIPTION;
  }
}

/***/ }),

/***/ 89285:
/*!***********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Subscriber.js ***!
  \***********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   EMPTY_OBSERVER: () => (/* binding */ EMPTY_OBSERVER),
/* harmony export */   SafeSubscriber: () => (/* binding */ SafeSubscriber),
/* harmony export */   Subscriber: () => (/* binding */ Subscriber)
/* harmony export */ });
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/isFunction */ 81530);
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscription */ 2510);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./config */ 62213);
/* harmony import */ var _util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./util/reportUnhandledError */ 31411);
/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./util/noop */ 54318);
/* harmony import */ var _NotificationFactories__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./NotificationFactories */ 22220);
/* harmony import */ var _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./scheduler/timeoutProvider */ 59603);
/* harmony import */ var _util_errorContext__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./util/errorContext */ 60023);








class Subscriber extends _Subscription__WEBPACK_IMPORTED_MODULE_0__.Subscription {
  constructor(destination) {
    super();
    this.isStopped = false;
    if (destination) {
      this.destination = destination;
      if ((0,_Subscription__WEBPACK_IMPORTED_MODULE_0__.isSubscription)(destination)) {
        destination.add(this);
      }
    } else {
      this.destination = EMPTY_OBSERVER;
    }
  }
  static create(next, error, complete) {
    return new SafeSubscriber(next, error, complete);
  }
  next(value) {
    if (this.isStopped) {
      handleStoppedNotification((0,_NotificationFactories__WEBPACK_IMPORTED_MODULE_1__.nextNotification)(value), this);
    } else {
      this._next(value);
    }
  }
  error(err) {
    if (this.isStopped) {
      handleStoppedNotification((0,_NotificationFactories__WEBPACK_IMPORTED_MODULE_1__.errorNotification)(err), this);
    } else {
      this.isStopped = true;
      this._error(err);
    }
  }
  complete() {
    if (this.isStopped) {
      handleStoppedNotification(_NotificationFactories__WEBPACK_IMPORTED_MODULE_1__.COMPLETE_NOTIFICATION, this);
    } else {
      this.isStopped = true;
      this._complete();
    }
  }
  unsubscribe() {
    if (!this.closed) {
      this.isStopped = true;
      super.unsubscribe();
      this.destination = null;
    }
  }
  _next(value) {
    this.destination.next(value);
  }
  _error(err) {
    try {
      this.destination.error(err);
    } finally {
      this.unsubscribe();
    }
  }
  _complete() {
    try {
      this.destination.complete();
    } finally {
      this.unsubscribe();
    }
  }
}
const _bind = Function.prototype.bind;
function bind(fn, thisArg) {
  return _bind.call(fn, thisArg);
}
class ConsumerObserver {
  constructor(partialObserver) {
    this.partialObserver = partialObserver;
  }
  next(value) {
    const {
      partialObserver
    } = this;
    if (partialObserver.next) {
      try {
        partialObserver.next(value);
      } catch (error) {
        handleUnhandledError(error);
      }
    }
  }
  error(err) {
    const {
      partialObserver
    } = this;
    if (partialObserver.error) {
      try {
        partialObserver.error(err);
      } catch (error) {
        handleUnhandledError(error);
      }
    } else {
      handleUnhandledError(err);
    }
  }
  complete() {
    const {
      partialObserver
    } = this;
    if (partialObserver.complete) {
      try {
        partialObserver.complete();
      } catch (error) {
        handleUnhandledError(error);
      }
    }
  }
}
class SafeSubscriber extends Subscriber {
  constructor(observerOrNext, error, complete) {
    super();
    let partialObserver;
    if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_2__.isFunction)(observerOrNext) || !observerOrNext) {
      partialObserver = {
        next: observerOrNext !== null && observerOrNext !== void 0 ? observerOrNext : undefined,
        error: error !== null && error !== void 0 ? error : undefined,
        complete: complete !== null && complete !== void 0 ? complete : undefined
      };
    } else {
      let context;
      if (this && _config__WEBPACK_IMPORTED_MODULE_3__.config.useDeprecatedNextContext) {
        context = Object.create(observerOrNext);
        context.unsubscribe = () => this.unsubscribe();
        partialObserver = {
          next: observerOrNext.next && bind(observerOrNext.next, context),
          error: observerOrNext.error && bind(observerOrNext.error, context),
          complete: observerOrNext.complete && bind(observerOrNext.complete, context)
        };
      } else {
        partialObserver = observerOrNext;
      }
    }
    this.destination = new ConsumerObserver(partialObserver);
  }
}
function handleUnhandledError(error) {
  if (_config__WEBPACK_IMPORTED_MODULE_3__.config.useDeprecatedSynchronousErrorHandling) {
    (0,_util_errorContext__WEBPACK_IMPORTED_MODULE_4__.captureError)(error);
  } else {
    (0,_util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_5__.reportUnhandledError)(error);
  }
}
function defaultErrorHandler(err) {
  throw err;
}
function handleStoppedNotification(notification, subscriber) {
  const {
    onStoppedNotification
  } = _config__WEBPACK_IMPORTED_MODULE_3__.config;
  onStoppedNotification && _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_6__.timeoutProvider.setTimeout(() => onStoppedNotification(notification, subscriber));
}
const EMPTY_OBSERVER = {
  closed: true,
  next: _util_noop__WEBPACK_IMPORTED_MODULE_7__.noop,
  error: defaultErrorHandler,
  complete: _util_noop__WEBPACK_IMPORTED_MODULE_7__.noop
};

/***/ }),

/***/ 2510:
/*!*************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/Subscription.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   EMPTY_SUBSCRIPTION: () => (/* binding */ EMPTY_SUBSCRIPTION),
/* harmony export */   Subscription: () => (/* binding */ Subscription),
/* harmony export */   isSubscription: () => (/* binding */ isSubscription)
/* harmony export */ });
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./util/isFunction */ 81530);
/* harmony import */ var _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/UnsubscriptionError */ 42540);
/* harmony import */ var _util_arrRemove__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./util/arrRemove */ 80967);



class Subscription {
  constructor(initialTeardown) {
    this.initialTeardown = initialTeardown;
    this.closed = false;
    this._parentage = null;
    this._finalizers = null;
  }
  unsubscribe() {
    let errors;
    if (!this.closed) {
      this.closed = true;
      const {
        _parentage
      } = this;
      if (_parentage) {
        this._parentage = null;
        if (Array.isArray(_parentage)) {
          for (const parent of _parentage) {
            parent.remove(this);
          }
        } else {
          _parentage.remove(this);
        }
      }
      const {
        initialTeardown: initialFinalizer
      } = this;
      if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(initialFinalizer)) {
        try {
          initialFinalizer();
        } catch (e) {
          errors = e instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError ? e.errors : [e];
        }
      }
      const {
        _finalizers
      } = this;
      if (_finalizers) {
        this._finalizers = null;
        for (const finalizer of _finalizers) {
          try {
            execFinalizer(finalizer);
          } catch (err) {
            errors = errors !== null && errors !== void 0 ? errors : [];
            if (err instanceof _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError) {
              errors = [...errors, ...err.errors];
            } else {
              errors.push(err);
            }
          }
        }
      }
      if (errors) {
        throw new _util_UnsubscriptionError__WEBPACK_IMPORTED_MODULE_1__.UnsubscriptionError(errors);
      }
    }
  }
  add(teardown) {
    var _a;
    if (teardown && teardown !== this) {
      if (this.closed) {
        execFinalizer(teardown);
      } else {
        if (teardown instanceof Subscription) {
          if (teardown.closed || teardown._hasParent(this)) {
            return;
          }
          teardown._addParent(this);
        }
        (this._finalizers = (_a = this._finalizers) !== null && _a !== void 0 ? _a : []).push(teardown);
      }
    }
  }
  _hasParent(parent) {
    const {
      _parentage
    } = this;
    return _parentage === parent || Array.isArray(_parentage) && _parentage.includes(parent);
  }
  _addParent(parent) {
    const {
      _parentage
    } = this;
    this._parentage = Array.isArray(_parentage) ? (_parentage.push(parent), _parentage) : _parentage ? [_parentage, parent] : parent;
  }
  _removeParent(parent) {
    const {
      _parentage
    } = this;
    if (_parentage === parent) {
      this._parentage = null;
    } else if (Array.isArray(_parentage)) {
      (0,_util_arrRemove__WEBPACK_IMPORTED_MODULE_2__.arrRemove)(_parentage, parent);
    }
  }
  remove(teardown) {
    const {
      _finalizers
    } = this;
    _finalizers && (0,_util_arrRemove__WEBPACK_IMPORTED_MODULE_2__.arrRemove)(_finalizers, teardown);
    if (teardown instanceof Subscription) {
      teardown._removeParent(this);
    }
  }
}
Subscription.EMPTY = (() => {
  const empty = new Subscription();
  empty.closed = true;
  return empty;
})();
const EMPTY_SUBSCRIPTION = Subscription.EMPTY;
function isSubscription(value) {
  return value instanceof Subscription || value && 'closed' in value && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(value.remove) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(value.add) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(value.unsubscribe);
}
function execFinalizer(finalizer) {
  if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(finalizer)) {
    finalizer();
  } else {
    finalizer.unsubscribe();
  }
}

/***/ }),

/***/ 62213:
/*!*******************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/config.js ***!
  \*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   config: () => (/* binding */ config)
/* harmony export */ });
const config = {
  onUnhandledError: null,
  onStoppedNotification: null,
  Promise: undefined,
  useDeprecatedSynchronousErrorHandling: false,
  useDeprecatedNextContext: false
};

/***/ }),

/***/ 56196:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/firstValueFrom.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   firstValueFrom: () => (/* binding */ firstValueFrom)
/* harmony export */ });
/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./util/EmptyError */ 93335);
/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Subscriber */ 89285);


function firstValueFrom(source, config) {
  const hasConfig = typeof config === 'object';
  return new Promise((resolve, reject) => {
    const subscriber = new _Subscriber__WEBPACK_IMPORTED_MODULE_0__.SafeSubscriber({
      next: value => {
        resolve(value);
        subscriber.unsubscribe();
      },
      error: reject,
      complete: () => {
        if (hasConfig) {
          resolve(config.defaultValue);
        } else {
          reject(new _util_EmptyError__WEBPACK_IMPORTED_MODULE_1__.EmptyError());
        }
      }
    });
    source.subscribe(subscriber);
  });
}

/***/ }),

/***/ 94982:
/*!*********************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/ConnectableObservable.js ***!
  \*********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ConnectableObservable: () => (/* binding */ ConnectableObservable)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Subscription */ 2510);
/* harmony import */ var _operators_refCount__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../operators/refCount */ 73481);
/* harmony import */ var _operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../operators/OperatorSubscriber */ 91687);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);





class ConnectableObservable extends _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable {
  constructor(source, subjectFactory) {
    super();
    this.source = source;
    this.subjectFactory = subjectFactory;
    this._subject = null;
    this._refCount = 0;
    this._connection = null;
    if ((0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.hasLift)(source)) {
      this.lift = source.lift;
    }
  }
  _subscribe(subscriber) {
    return this.getSubject().subscribe(subscriber);
  }
  getSubject() {
    const subject = this._subject;
    if (!subject || subject.isStopped) {
      this._subject = this.subjectFactory();
    }
    return this._subject;
  }
  _teardown() {
    this._refCount = 0;
    const {
      _connection
    } = this;
    this._subject = this._connection = null;
    _connection === null || _connection === void 0 ? void 0 : _connection.unsubscribe();
  }
  connect() {
    let connection = this._connection;
    if (!connection) {
      connection = this._connection = new _Subscription__WEBPACK_IMPORTED_MODULE_2__.Subscription();
      const subject = this.getSubject();
      connection.add(this.source.subscribe((0,_operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subject, undefined, () => {
        this._teardown();
        subject.complete();
      }, err => {
        this._teardown();
        subject.error(err);
      }, () => this._teardown())));
      if (connection.closed) {
        this._connection = null;
        connection = _Subscription__WEBPACK_IMPORTED_MODULE_2__.Subscription.EMPTY;
      }
    }
    return connection;
  }
  refCount() {
    return (0,_operators_refCount__WEBPACK_IMPORTED_MODULE_4__.refCount)()(this);
  }
}

/***/ }),

/***/ 19999:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/combineLatest.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   combineLatest: () => (/* binding */ combineLatest),
/* harmony export */   combineLatestInit: () => (/* binding */ combineLatestInit)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_argsArgArrayOrObject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/argsArgArrayOrObject */ 57808);
/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./from */ 95429);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/identity */ 1440);
/* harmony import */ var _util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../util/mapOneOrManyArgs */ 38067);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _util_createObject__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/createObject */ 96813);
/* harmony import */ var _operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../operators/OperatorSubscriber */ 91687);
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);









function combineLatest(...args) {
  const scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popScheduler)(args);
  const resultSelector = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popResultSelector)(args);
  const {
    args: observables,
    keys
  } = (0,_util_argsArgArrayOrObject__WEBPACK_IMPORTED_MODULE_1__.argsArgArrayOrObject)(args);
  if (observables.length === 0) {
    return (0,_from__WEBPACK_IMPORTED_MODULE_2__.from)([], scheduler);
  }
  const result = new _Observable__WEBPACK_IMPORTED_MODULE_3__.Observable(combineLatestInit(observables, scheduler, keys ? values => (0,_util_createObject__WEBPACK_IMPORTED_MODULE_4__.createObject)(keys, values) : _util_identity__WEBPACK_IMPORTED_MODULE_5__.identity));
  return resultSelector ? result.pipe((0,_util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_6__.mapOneOrManyArgs)(resultSelector)) : result;
}
function combineLatestInit(observables, scheduler, valueTransform = _util_identity__WEBPACK_IMPORTED_MODULE_5__.identity) {
  return subscriber => {
    maybeSchedule(scheduler, () => {
      const {
        length
      } = observables;
      const values = new Array(length);
      let active = length;
      let remainingFirstValues = length;
      for (let i = 0; i < length; i++) {
        maybeSchedule(scheduler, () => {
          const source = (0,_from__WEBPACK_IMPORTED_MODULE_2__.from)(observables[i], scheduler);
          let hasFirstValue = false;
          source.subscribe((0,_operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_7__.createOperatorSubscriber)(subscriber, value => {
            values[i] = value;
            if (!hasFirstValue) {
              hasFirstValue = true;
              remainingFirstValues--;
            }
            if (!remainingFirstValues) {
              subscriber.next(valueTransform(values.slice()));
            }
          }, () => {
            if (! --active) {
              subscriber.complete();
            }
          }));
        }, subscriber);
      }
    }, subscriber);
  };
}
function maybeSchedule(scheduler, execute, subscription) {
  if (scheduler) {
    (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_8__.executeSchedule)(subscription, scheduler, execute);
  } else {
    execute();
  }
}

/***/ }),

/***/ 44665:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/concat.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   concat: () => (/* binding */ concat)
/* harmony export */ });
/* harmony import */ var _operators_concatAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../operators/concatAll */ 37278);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./from */ 95429);



function concat(...args) {
  return (0,_operators_concatAll__WEBPACK_IMPORTED_MODULE_0__.concatAll)()((0,_from__WEBPACK_IMPORTED_MODULE_1__.from)(args, (0,_util_args__WEBPACK_IMPORTED_MODULE_2__.popScheduler)(args)));
}

/***/ }),

/***/ 137:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/defer.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   defer: () => (/* binding */ defer)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./innerFrom */ 82645);


function defer(observableFactory) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    (0,_innerFrom__WEBPACK_IMPORTED_MODULE_1__.innerFrom)(observableFactory()).subscribe(subscriber);
  });
}

/***/ }),

/***/ 59400:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/empty.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   EMPTY: () => (/* binding */ EMPTY),
/* harmony export */   empty: () => (/* binding */ empty)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);

const EMPTY = new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => subscriber.complete());
function empty(scheduler) {
  return scheduler ? emptyScheduled(scheduler) : EMPTY;
}
function emptyScheduled(scheduler) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => scheduler.schedule(() => subscriber.complete()));
}

/***/ }),

/***/ 61873:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/forkJoin.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   forkJoin: () => (/* binding */ forkJoin)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_argsArgArrayOrObject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/argsArgArrayOrObject */ 57808);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./innerFrom */ 82645);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../operators/OperatorSubscriber */ 91687);
/* harmony import */ var _util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../util/mapOneOrManyArgs */ 38067);
/* harmony import */ var _util_createObject__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/createObject */ 96813);







function forkJoin(...args) {
  const resultSelector = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popResultSelector)(args);
  const {
    args: sources,
    keys
  } = (0,_util_argsArgArrayOrObject__WEBPACK_IMPORTED_MODULE_1__.argsArgArrayOrObject)(args);
  const result = new _Observable__WEBPACK_IMPORTED_MODULE_2__.Observable(subscriber => {
    const {
      length
    } = sources;
    if (!length) {
      subscriber.complete();
      return;
    }
    const values = new Array(length);
    let remainingCompletions = length;
    let remainingEmissions = length;
    for (let sourceIndex = 0; sourceIndex < length; sourceIndex++) {
      let hasValue = false;
      (0,_innerFrom__WEBPACK_IMPORTED_MODULE_3__.innerFrom)(sources[sourceIndex]).subscribe((0,_operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_4__.createOperatorSubscriber)(subscriber, value => {
        if (!hasValue) {
          hasValue = true;
          remainingEmissions--;
        }
        values[sourceIndex] = value;
      }, () => remainingCompletions--, undefined, () => {
        if (!remainingCompletions || !hasValue) {
          if (!remainingEmissions) {
            subscriber.next(keys ? (0,_util_createObject__WEBPACK_IMPORTED_MODULE_5__.createObject)(keys, values) : values);
          }
          subscriber.complete();
        }
      }));
    }
  });
  return resultSelector ? result.pipe((0,_util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_6__.mapOneOrManyArgs)(resultSelector)) : result;
}

/***/ }),

/***/ 95429:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/from.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   from: () => (/* binding */ from)
/* harmony export */ });
/* harmony import */ var _scheduled_scheduled__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduled/scheduled */ 94424);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./innerFrom */ 82645);


function from(input, scheduler) {
  return scheduler ? (0,_scheduled_scheduled__WEBPACK_IMPORTED_MODULE_0__.scheduled)(input, scheduler) : (0,_innerFrom__WEBPACK_IMPORTED_MODULE_1__.innerFrom)(input);
}

/***/ }),

/***/ 18537:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/fromEvent.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   fromEvent: () => (/* binding */ fromEvent)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _operators_mergeMap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../operators/mergeMap */ 13255);
/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isArrayLike */ 88830);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 81530);
/* harmony import */ var _util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/mapOneOrManyArgs */ 38067);






const nodeEventEmitterMethods = ['addListener', 'removeListener'];
const eventTargetMethods = ['addEventListener', 'removeEventListener'];
const jqueryMethods = ['on', 'off'];
function fromEvent(target, eventName, options, resultSelector) {
  if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(options)) {
    resultSelector = options;
    options = undefined;
  }
  if (resultSelector) {
    return fromEvent(target, eventName, options).pipe((0,_util_mapOneOrManyArgs__WEBPACK_IMPORTED_MODULE_1__.mapOneOrManyArgs)(resultSelector));
  }
  const [add, remove] = isEventTarget(target) ? eventTargetMethods.map(methodName => handler => target[methodName](eventName, handler, options)) : isNodeStyleEventEmitter(target) ? nodeEventEmitterMethods.map(toCommonHandlerRegistry(target, eventName)) : isJQueryStyleEventEmitter(target) ? jqueryMethods.map(toCommonHandlerRegistry(target, eventName)) : [];
  if (!add) {
    if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__.isArrayLike)(target)) {
      return (0,_operators_mergeMap__WEBPACK_IMPORTED_MODULE_3__.mergeMap)(subTarget => fromEvent(subTarget, eventName, options))((0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_4__.innerFrom)(target));
    }
  }
  if (!add) {
    throw new TypeError('Invalid event target');
  }
  return new _Observable__WEBPACK_IMPORTED_MODULE_5__.Observable(subscriber => {
    const handler = (...args) => subscriber.next(1 < args.length ? args : args[0]);
    add(handler);
    return () => remove(handler);
  });
}
function toCommonHandlerRegistry(target, eventName) {
  return methodName => handler => target[methodName](eventName, handler);
}
function isNodeStyleEventEmitter(target) {
  return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.addListener) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.removeListener);
}
function isJQueryStyleEventEmitter(target) {
  return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.on) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.off);
}
function isEventTarget(target) {
  return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.addEventListener) && (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(target.removeEventListener);
}

/***/ }),

/***/ 82645:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/innerFrom.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   fromArrayLike: () => (/* binding */ fromArrayLike),
/* harmony export */   fromAsyncIterable: () => (/* binding */ fromAsyncIterable),
/* harmony export */   fromInteropObservable: () => (/* binding */ fromInteropObservable),
/* harmony export */   fromIterable: () => (/* binding */ fromIterable),
/* harmony export */   fromPromise: () => (/* binding */ fromPromise),
/* harmony export */   fromReadableStreamLike: () => (/* binding */ fromReadableStreamLike),
/* harmony export */   innerFrom: () => (/* binding */ innerFrom)
/* harmony export */ });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! tslib */ 24398);
/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isArrayLike */ 88830);
/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/isPromise */ 81117);
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/isInteropObservable */ 31516);
/* harmony import */ var _util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/isAsyncIterable */ 64558);
/* harmony import */ var _util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../util/throwUnobservableError */ 21374);
/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/isIterable */ 30528);
/* harmony import */ var _util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../util/isReadableStreamLike */ 83233);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../util/isFunction */ 81530);
/* harmony import */ var _util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../util/reportUnhandledError */ 31411);
/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../symbol/observable */ 44127);












function innerFrom(input) {
  if (input instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable) {
    return input;
  }
  if (input != null) {
    if ((0,_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_1__.isInteropObservable)(input)) {
      return fromInteropObservable(input);
    }
    if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__.isArrayLike)(input)) {
      return fromArrayLike(input);
    }
    if ((0,_util_isPromise__WEBPACK_IMPORTED_MODULE_3__.isPromise)(input)) {
      return fromPromise(input);
    }
    if ((0,_util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_4__.isAsyncIterable)(input)) {
      return fromAsyncIterable(input);
    }
    if ((0,_util_isIterable__WEBPACK_IMPORTED_MODULE_5__.isIterable)(input)) {
      return fromIterable(input);
    }
    if ((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__.isReadableStreamLike)(input)) {
      return fromReadableStreamLike(input);
    }
  }
  throw (0,_util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_7__.createInvalidObservableTypeError)(input);
}
function fromInteropObservable(obj) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    const obs = obj[_symbol_observable__WEBPACK_IMPORTED_MODULE_8__.observable]();
    if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_9__.isFunction)(obs.subscribe)) {
      return obs.subscribe(subscriber);
    }
    throw new TypeError('Provided object does not correctly implement Symbol.observable');
  });
}
function fromArrayLike(array) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    for (let i = 0; i < array.length && !subscriber.closed; i++) {
      subscriber.next(array[i]);
    }
    subscriber.complete();
  });
}
function fromPromise(promise) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    promise.then(value => {
      if (!subscriber.closed) {
        subscriber.next(value);
        subscriber.complete();
      }
    }, err => subscriber.error(err)).then(null, _util_reportUnhandledError__WEBPACK_IMPORTED_MODULE_10__.reportUnhandledError);
  });
}
function fromIterable(iterable) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    for (const value of iterable) {
      subscriber.next(value);
      if (subscriber.closed) {
        return;
      }
    }
    subscriber.complete();
  });
}
function fromAsyncIterable(asyncIterable) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    process(asyncIterable, subscriber).catch(err => subscriber.error(err));
  });
}
function fromReadableStreamLike(readableStream) {
  return fromAsyncIterable((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_6__.readableStreamLikeToAsyncGenerator)(readableStream));
}
function process(asyncIterable, subscriber) {
  var asyncIterable_1, asyncIterable_1_1;
  var e_1, _a;
  return (0,tslib__WEBPACK_IMPORTED_MODULE_11__.__awaiter)(this, void 0, void 0, function* () {
    try {
      for (asyncIterable_1 = (0,tslib__WEBPACK_IMPORTED_MODULE_11__.__asyncValues)(asyncIterable); asyncIterable_1_1 = yield asyncIterable_1.next(), !asyncIterable_1_1.done;) {
        const value = asyncIterable_1_1.value;
        subscriber.next(value);
        if (subscriber.closed) {
          return;
        }
      }
    } catch (e_1_1) {
      e_1 = {
        error: e_1_1
      };
    } finally {
      try {
        if (asyncIterable_1_1 && !asyncIterable_1_1.done && (_a = asyncIterable_1.return)) yield _a.call(asyncIterable_1);
      } finally {
        if (e_1) throw e_1.error;
      }
    }
    subscriber.complete();
  });
}

/***/ }),

/***/ 19240:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/interval.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   interval: () => (/* binding */ interval)
/* harmony export */ });
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _timer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./timer */ 14876);


function interval(period = 0, scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__.asyncScheduler) {
  if (period < 0) {
    period = 0;
  }
  return (0,_timer__WEBPACK_IMPORTED_MODULE_1__.timer)(period, period, scheduler);
}

/***/ }),

/***/ 63617:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/merge.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   merge: () => (/* binding */ merge)
/* harmony export */ });
/* harmony import */ var _operators_mergeAll__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../operators/mergeAll */ 23222);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./innerFrom */ 82645);
/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./empty */ 59400);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./from */ 95429);





function merge(...args) {
  const scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popScheduler)(args);
  const concurrent = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popNumber)(args, Infinity);
  const sources = args;
  return !sources.length ? _empty__WEBPACK_IMPORTED_MODULE_1__.EMPTY : sources.length === 1 ? (0,_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(sources[0]) : (0,_operators_mergeAll__WEBPACK_IMPORTED_MODULE_3__.mergeAll)(concurrent)((0,_from__WEBPACK_IMPORTED_MODULE_4__.from)(sources, scheduler));
}

/***/ }),

/***/ 79439:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/never.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   NEVER: () => (/* binding */ NEVER),
/* harmony export */   never: () => (/* binding */ never)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/noop */ 54318);


const NEVER = new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(_util_noop__WEBPACK_IMPORTED_MODULE_1__.noop);
function never() {
  return NEVER;
}

/***/ }),

/***/ 59452:
/*!**************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/of.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   of: () => (/* binding */ of)
/* harmony export */ });
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _from__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./from */ 95429);


function of(...args) {
  const scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popScheduler)(args);
  return (0,_from__WEBPACK_IMPORTED_MODULE_1__.from)(args, scheduler);
}

/***/ }),

/***/ 66096:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/race.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   race: () => (/* binding */ race),
/* harmony export */   raceInit: () => (/* binding */ raceInit)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./innerFrom */ 82645);
/* harmony import */ var _util_argsOrArgArray__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/argsOrArgArray */ 41303);
/* harmony import */ var _operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../operators/OperatorSubscriber */ 91687);




function race(...sources) {
  sources = (0,_util_argsOrArgArray__WEBPACK_IMPORTED_MODULE_0__.argsOrArgArray)(sources);
  return sources.length === 1 ? (0,_innerFrom__WEBPACK_IMPORTED_MODULE_1__.innerFrom)(sources[0]) : new _Observable__WEBPACK_IMPORTED_MODULE_2__.Observable(raceInit(sources));
}
function raceInit(sources) {
  return subscriber => {
    let subscriptions = [];
    for (let i = 0; subscriptions && !subscriber.closed && i < sources.length; i++) {
      subscriptions.push((0,_innerFrom__WEBPACK_IMPORTED_MODULE_1__.innerFrom)(sources[i]).subscribe((0,_operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subscriber, value => {
        if (subscriptions) {
          for (let s = 0; s < subscriptions.length; s++) {
            s !== i && subscriptions[s].unsubscribe();
          }
          subscriptions = null;
        }
        subscriber.next(value);
      })));
    }
  };
}

/***/ }),

/***/ 77919:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/throwError.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   throwError: () => (/* binding */ throwError)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 81530);


function throwError(errorOrErrorFactory, scheduler) {
  const errorFactory = (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(errorOrErrorFactory) ? errorOrErrorFactory : () => errorOrErrorFactory;
  const init = subscriber => subscriber.error(errorFactory());
  return new _Observable__WEBPACK_IMPORTED_MODULE_1__.Observable(scheduler ? subscriber => scheduler.schedule(init, 0, subscriber) : init);
}

/***/ }),

/***/ 14876:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/timer.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   timer: () => (/* binding */ timer)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _util_isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/isScheduler */ 89397);
/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/isDate */ 15602);




function timer(dueTime = 0, intervalOrScheduler, scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__.async) {
  let intervalDuration = -1;
  if (intervalOrScheduler != null) {
    if ((0,_util_isScheduler__WEBPACK_IMPORTED_MODULE_1__.isScheduler)(intervalOrScheduler)) {
      scheduler = intervalOrScheduler;
    } else {
      intervalDuration = intervalOrScheduler;
    }
  }
  return new _Observable__WEBPACK_IMPORTED_MODULE_2__.Observable(subscriber => {
    let due = (0,_util_isDate__WEBPACK_IMPORTED_MODULE_3__.isValidDate)(dueTime) ? +dueTime - scheduler.now() : dueTime;
    if (due < 0) {
      due = 0;
    }
    let n = 0;
    return scheduler.schedule(function () {
      if (!subscriber.closed) {
        subscriber.next(n++);
        if (0 <= intervalDuration) {
          this.schedule(undefined, intervalDuration);
        } else {
          subscriber.complete();
        }
      }
    }, due);
  });
}

/***/ }),

/***/ 50774:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/observable/zip.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   zip: () => (/* binding */ zip)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _innerFrom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./innerFrom */ 82645);
/* harmony import */ var _util_argsOrArgArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/argsOrArgArray */ 41303);
/* harmony import */ var _empty__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./empty */ 59400);
/* harmony import */ var _operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../operators/OperatorSubscriber */ 91687);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);






function zip(...args) {
  const resultSelector = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popResultSelector)(args);
  const sources = (0,_util_argsOrArgArray__WEBPACK_IMPORTED_MODULE_1__.argsOrArgArray)(args);
  return sources.length ? new _Observable__WEBPACK_IMPORTED_MODULE_2__.Observable(subscriber => {
    let buffers = sources.map(() => []);
    let completed = sources.map(() => false);
    subscriber.add(() => {
      buffers = completed = null;
    });
    for (let sourceIndex = 0; !subscriber.closed && sourceIndex < sources.length; sourceIndex++) {
      (0,_innerFrom__WEBPACK_IMPORTED_MODULE_3__.innerFrom)(sources[sourceIndex]).subscribe((0,_operators_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_4__.createOperatorSubscriber)(subscriber, value => {
        buffers[sourceIndex].push(value);
        if (buffers.every(buffer => buffer.length)) {
          const result = buffers.map(buffer => buffer.shift());
          subscriber.next(resultSelector ? resultSelector(...result) : result);
          if (buffers.some((buffer, i) => !buffer.length && completed[i])) {
            subscriber.complete();
          }
        }
      }, () => {
        completed[sourceIndex] = true;
        !buffers[sourceIndex].length && subscriber.complete();
      }));
    }
    return () => {
      buffers = completed = null;
    };
  }) : _empty__WEBPACK_IMPORTED_MODULE_5__.EMPTY;
}

/***/ }),

/***/ 91687:
/*!*****************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/OperatorSubscriber.js ***!
  \*****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   OperatorSubscriber: () => (/* binding */ OperatorSubscriber),
/* harmony export */   createOperatorSubscriber: () => (/* binding */ createOperatorSubscriber)
/* harmony export */ });
/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscriber */ 89285);

function createOperatorSubscriber(destination, onNext, onComplete, onError, onFinalize) {
  return new OperatorSubscriber(destination, onNext, onComplete, onError, onFinalize);
}
class OperatorSubscriber extends _Subscriber__WEBPACK_IMPORTED_MODULE_0__.Subscriber {
  constructor(destination, onNext, onComplete, onError, onFinalize, shouldUnsubscribe) {
    super(destination);
    this.onFinalize = onFinalize;
    this.shouldUnsubscribe = shouldUnsubscribe;
    this._next = onNext ? function (value) {
      try {
        onNext(value);
      } catch (err) {
        destination.error(err);
      }
    } : super._next;
    this._error = onError ? function (err) {
      try {
        onError(err);
      } catch (err) {
        destination.error(err);
      } finally {
        this.unsubscribe();
      }
    } : super._error;
    this._complete = onComplete ? function () {
      try {
        onComplete();
      } catch (err) {
        destination.error(err);
      } finally {
        this.unsubscribe();
      }
    } : super._complete;
  }
  unsubscribe() {
    var _a;
    if (!this.shouldUnsubscribe || this.shouldUnsubscribe()) {
      const {
        closed
      } = this;
      super.unsubscribe();
      !closed && ((_a = this.onFinalize) === null || _a === void 0 ? void 0 : _a.call(this));
    }
  }
}

/***/ }),

/***/ 33658:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/audit.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   audit: () => (/* binding */ audit)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function audit(durationSelector) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let hasValue = false;
    let lastValue = null;
    let durationSubscriber = null;
    let isComplete = false;
    const endDuration = () => {
      durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
      durationSubscriber = null;
      if (hasValue) {
        hasValue = false;
        const value = lastValue;
        lastValue = null;
        subscriber.next(value);
      }
      isComplete && subscriber.complete();
    };
    const cleanupDuration = () => {
      durationSubscriber = null;
      isComplete && subscriber.complete();
    };
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      hasValue = true;
      lastValue = value;
      if (!durationSubscriber) {
        (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(durationSelector(value)).subscribe(durationSubscriber = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, endDuration, cleanupDuration));
      }
    }, () => {
      isComplete = true;
      (!hasValue || !durationSubscriber || durationSubscriber.closed) && subscriber.complete();
    }));
  });
}

/***/ }),

/***/ 32351:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/auditTime.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   auditTime: () => (/* binding */ auditTime)
/* harmony export */ });
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./audit */ 33658);
/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/timer */ 14876);



function auditTime(duration, scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__.asyncScheduler) {
  return (0,_audit__WEBPACK_IMPORTED_MODULE_1__.audit)(() => (0,_observable_timer__WEBPACK_IMPORTED_MODULE_2__.timer)(duration, scheduler));
}

/***/ }),

/***/ 61318:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/catchError.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   catchError: () => (/* binding */ catchError)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);



function catchError(selector) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let innerSub = null;
    let syncUnsub = false;
    let handledResult;
    innerSub = source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, undefined, undefined, err => {
      handledResult = (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(selector(err, catchError(selector)(source)));
      if (innerSub) {
        innerSub.unsubscribe();
        innerSub = null;
        handledResult.subscribe(subscriber);
      } else {
        syncUnsub = true;
      }
    }));
    if (syncUnsub) {
      innerSub.unsubscribe();
      innerSub = null;
      handledResult.subscribe(subscriber);
    }
  });
}

/***/ }),

/***/ 37278:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/concatAll.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   concatAll: () => (/* binding */ concatAll)
/* harmony export */ });
/* harmony import */ var _mergeAll__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mergeAll */ 23222);

function concatAll() {
  return (0,_mergeAll__WEBPACK_IMPORTED_MODULE_0__.mergeAll)(1);
}

/***/ }),

/***/ 51903:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/concatMap.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   concatMap: () => (/* binding */ concatMap)
/* harmony export */ });
/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./mergeMap */ 13255);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 81530);


function concatMap(project, resultSelector) {
  return (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(resultSelector) ? (0,_mergeMap__WEBPACK_IMPORTED_MODULE_1__.mergeMap)(project, resultSelector, 1) : (0,_mergeMap__WEBPACK_IMPORTED_MODULE_1__.mergeMap)(project, 1);
}

/***/ }),

/***/ 52575:
/*!***********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/debounceTime.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   debounceTime: () => (/* binding */ debounceTime)
/* harmony export */ });
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function debounceTime(dueTime, scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__.asyncScheduler) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    let activeTask = null;
    let lastValue = null;
    let lastTime = null;
    const emit = () => {
      if (activeTask) {
        activeTask.unsubscribe();
        activeTask = null;
        const value = lastValue;
        lastValue = null;
        subscriber.next(value);
      }
    };
    function emitWhenIdle() {
      const targetTime = lastTime + dueTime;
      const now = scheduler.now();
      if (now < targetTime) {
        activeTask = this.schedule(undefined, targetTime - now);
        subscriber.add(activeTask);
        return;
      }
      emit();
    }
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, value => {
      lastValue = value;
      lastTime = scheduler.now();
      if (!activeTask) {
        activeTask = scheduler.schedule(emitWhenIdle, dueTime);
        subscriber.add(activeTask);
      }
    }, () => {
      emit();
      subscriber.complete();
    }, undefined, () => {
      lastValue = activeTask = null;
    }));
  });
}

/***/ }),

/***/ 90778:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/defaultIfEmpty.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   defaultIfEmpty: () => (/* binding */ defaultIfEmpty)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);


function defaultIfEmpty(defaultValue) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let hasValue = false;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      hasValue = true;
      subscriber.next(value);
    }, () => {
      if (!hasValue) {
        subscriber.next(defaultValue);
      }
      subscriber.complete();
    }));
  });
}

/***/ }),

/***/ 95074:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/delay.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   delay: () => (/* binding */ delay)
/* harmony export */ });
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _delayWhen__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./delayWhen */ 31534);
/* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../observable/timer */ 14876);



function delay(due, scheduler = _scheduler_async__WEBPACK_IMPORTED_MODULE_0__.asyncScheduler) {
  const duration = (0,_observable_timer__WEBPACK_IMPORTED_MODULE_1__.timer)(due, scheduler);
  return (0,_delayWhen__WEBPACK_IMPORTED_MODULE_2__.delayWhen)(() => duration);
}

/***/ }),

/***/ 31534:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/delayWhen.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   delayWhen: () => (/* binding */ delayWhen)
/* harmony export */ });
/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/concat */ 44665);
/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./take */ 64334);
/* harmony import */ var _ignoreElements__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./ignoreElements */ 7242);
/* harmony import */ var _mapTo__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./mapTo */ 87378);
/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./mergeMap */ 13255);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);






function delayWhen(delayDurationSelector, subscriptionDelay) {
  if (subscriptionDelay) {
    return source => (0,_observable_concat__WEBPACK_IMPORTED_MODULE_0__.concat)(subscriptionDelay.pipe((0,_take__WEBPACK_IMPORTED_MODULE_1__.take)(1), (0,_ignoreElements__WEBPACK_IMPORTED_MODULE_2__.ignoreElements)()), source.pipe(delayWhen(delayDurationSelector)));
  }
  return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_3__.mergeMap)((value, index) => (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_4__.innerFrom)(delayDurationSelector(value, index)).pipe((0,_take__WEBPACK_IMPORTED_MODULE_1__.take)(1), (0,_mapTo__WEBPACK_IMPORTED_MODULE_5__.mapTo)(value)));
}

/***/ }),

/***/ 6449:
/*!************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/dematerialize.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   dematerialize: () => (/* binding */ dematerialize)
/* harmony export */ });
/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Notification */ 52296);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function dematerialize() {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, notification => (0,_Notification__WEBPACK_IMPORTED_MODULE_2__.observeNotification)(notification, subscriber)));
  });
}

/***/ }),

/***/ 91817:
/*!*******************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/distinctUntilChanged.js ***!
  \*******************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   distinctUntilChanged: () => (/* binding */ distinctUntilChanged)
/* harmony export */ });
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/identity */ 1440);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function distinctUntilChanged(comparator, keySelector = _util_identity__WEBPACK_IMPORTED_MODULE_0__.identity) {
  comparator = comparator !== null && comparator !== void 0 ? comparator : defaultCompare;
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    let previousKey;
    let first = true;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, value => {
      const currentKey = keySelector(value);
      if (first || !comparator(previousKey, currentKey)) {
        first = false;
        previousKey = currentKey;
        subscriber.next(value);
      }
    }));
  });
}
function defaultCompare(a, b) {
  return a === b;
}

/***/ }),

/***/ 12576:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/endWith.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   endWith: () => (/* binding */ endWith)
/* harmony export */ });
/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/concat */ 44665);
/* harmony import */ var _observable_of__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../observable/of */ 59452);


function endWith(...values) {
  return source => (0,_observable_concat__WEBPACK_IMPORTED_MODULE_0__.concat)(source, (0,_observable_of__WEBPACK_IMPORTED_MODULE_1__.of)(...values));
}

/***/ }),

/***/ 67953:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/exhaustMap.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   exhaustMap: () => (/* binding */ exhaustMap)
/* harmony export */ });
/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map */ 70271);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);




function exhaustMap(project, resultSelector) {
  if (resultSelector) {
    return source => source.pipe(exhaustMap((a, i) => (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__.innerFrom)(project(a, i)).pipe((0,_map__WEBPACK_IMPORTED_MODULE_1__.map)((b, ii) => resultSelector(a, b, i, ii)))));
  }
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_2__.operate)((source, subscriber) => {
    let index = 0;
    let innerSub = null;
    let isComplete = false;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subscriber, outerValue => {
      if (!innerSub) {
        innerSub = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subscriber, undefined, () => {
          innerSub = null;
          isComplete && subscriber.complete();
        });
        (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__.innerFrom)(project(outerValue, index++)).subscribe(innerSub);
      }
    }, () => {
      isComplete = true;
      !innerSub && subscriber.complete();
    }));
  });
}

/***/ }),

/***/ 51567:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/filter.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   filter: () => (/* binding */ filter)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);


function filter(predicate, thisArg) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let index = 0;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => predicate.call(thisArg, value, index++) && subscriber.next(value)));
  });
}

/***/ }),

/***/ 89475:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/finalize.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   finalize: () => (/* binding */ finalize)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);

function finalize(callback) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    try {
      source.subscribe(subscriber);
    } finally {
      subscriber.add(callback);
    }
  });
}

/***/ }),

/***/ 2435:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/first.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   first: () => (/* binding */ first)
/* harmony export */ });
/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/EmptyError */ 93335);
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ 51567);
/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./take */ 64334);
/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./defaultIfEmpty */ 90778);
/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./throwIfEmpty */ 99365);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1440);






function first(predicate, defaultValue) {
  const hasDefaultValue = arguments.length >= 2;
  return source => source.pipe(predicate ? (0,_filter__WEBPACK_IMPORTED_MODULE_0__.filter)((v, i) => predicate(v, i, source)) : _util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, (0,_take__WEBPACK_IMPORTED_MODULE_2__.take)(1), hasDefaultValue ? (0,_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__.defaultIfEmpty)(defaultValue) : (0,_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__.throwIfEmpty)(() => new _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__.EmptyError()));
}

/***/ }),

/***/ 78615:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/groupBy.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   groupBy: () => (/* binding */ groupBy)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Subject */ 10819);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);





function groupBy(keySelector, elementOrOptions, duration, connector) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let element;
    if (!elementOrOptions || typeof elementOrOptions === 'function') {
      element = elementOrOptions;
    } else {
      ({
        duration,
        element,
        connector
      } = elementOrOptions);
    }
    const groups = new Map();
    const notify = cb => {
      groups.forEach(cb);
      cb(subscriber);
    };
    const handleError = err => notify(consumer => consumer.error(err));
    let activeGroups = 0;
    let teardownAttempted = false;
    const groupBySourceSubscriber = new _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.OperatorSubscriber(subscriber, value => {
      try {
        const key = keySelector(value);
        let group = groups.get(key);
        if (!group) {
          groups.set(key, group = connector ? connector() : new _Subject__WEBPACK_IMPORTED_MODULE_2__.Subject());
          const grouped = createGroupedObservable(key, group);
          subscriber.next(grouped);
          if (duration) {
            const durationSubscriber = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(group, () => {
              group.complete();
              durationSubscriber === null || durationSubscriber === void 0 ? void 0 : durationSubscriber.unsubscribe();
            }, undefined, undefined, () => groups.delete(key));
            groupBySourceSubscriber.add((0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__.innerFrom)(duration(grouped)).subscribe(durationSubscriber));
          }
        }
        group.next(element ? element(value) : value);
      } catch (err) {
        handleError(err);
      }
    }, () => notify(consumer => consumer.complete()), handleError, () => groups.clear(), () => {
      teardownAttempted = true;
      return activeGroups === 0;
    });
    source.subscribe(groupBySourceSubscriber);
    function createGroupedObservable(key, groupSubject) {
      const result = new _Observable__WEBPACK_IMPORTED_MODULE_4__.Observable(groupSubscriber => {
        activeGroups++;
        const innerSub = groupSubject.subscribe(groupSubscriber);
        return () => {
          innerSub.unsubscribe();
          --activeGroups === 0 && teardownAttempted && groupBySourceSubscriber.unsubscribe();
        };
      });
      result.key = key;
      return result;
    }
  });
}

/***/ }),

/***/ 7242:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/ignoreElements.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ignoreElements: () => (/* binding */ ignoreElements)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/noop */ 54318);



function ignoreElements() {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, _util_noop__WEBPACK_IMPORTED_MODULE_2__.noop));
  });
}

/***/ }),

/***/ 22157:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/last.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   last: () => (/* binding */ last)
/* harmony export */ });
/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/EmptyError */ 93335);
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ 51567);
/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./takeLast */ 80602);
/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./throwIfEmpty */ 99365);
/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./defaultIfEmpty */ 90778);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1440);






function last(predicate, defaultValue) {
  const hasDefaultValue = arguments.length >= 2;
  return source => source.pipe(predicate ? (0,_filter__WEBPACK_IMPORTED_MODULE_0__.filter)((v, i) => predicate(v, i, source)) : _util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, (0,_takeLast__WEBPACK_IMPORTED_MODULE_2__.takeLast)(1), hasDefaultValue ? (0,_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__.defaultIfEmpty)(defaultValue) : (0,_throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__.throwIfEmpty)(() => new _util_EmptyError__WEBPACK_IMPORTED_MODULE_5__.EmptyError()));
}

/***/ }),

/***/ 70271:
/*!**************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/map.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   map: () => (/* binding */ map)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);


function map(project, thisArg) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let index = 0;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      subscriber.next(project.call(thisArg, value, index++));
    }));
  });
}

/***/ }),

/***/ 87378:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/mapTo.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   mapTo: () => (/* binding */ mapTo)
/* harmony export */ });
/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./map */ 70271);

function mapTo(value) {
  return (0,_map__WEBPACK_IMPORTED_MODULE_0__.map)(() => value);
}

/***/ }),

/***/ 79176:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/materialize.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   materialize: () => (/* binding */ materialize)
/* harmony export */ });
/* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Notification */ 52296);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function materialize() {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      subscriber.next(_Notification__WEBPACK_IMPORTED_MODULE_2__.Notification.createNext(value));
    }, () => {
      subscriber.next(_Notification__WEBPACK_IMPORTED_MODULE_2__.Notification.createComplete());
      subscriber.complete();
    }, err => {
      subscriber.next(_Notification__WEBPACK_IMPORTED_MODULE_2__.Notification.createError(err));
      subscriber.complete();
    }));
  });
}

/***/ }),

/***/ 23222:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/mergeAll.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   mergeAll: () => (/* binding */ mergeAll)
/* harmony export */ });
/* harmony import */ var _mergeMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./mergeMap */ 13255);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/identity */ 1440);


function mergeAll(concurrent = Infinity) {
  return (0,_mergeMap__WEBPACK_IMPORTED_MODULE_0__.mergeMap)(_util_identity__WEBPACK_IMPORTED_MODULE_1__.identity, concurrent);
}

/***/ }),

/***/ 48735:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/mergeInternals.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   mergeInternals: () => (/* binding */ mergeInternals)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function mergeInternals(source, subscriber, project, concurrent, onBeforeNext, expand, innerSubScheduler, additionalFinalizer) {
  const buffer = [];
  let active = 0;
  let index = 0;
  let isComplete = false;
  const checkComplete = () => {
    if (isComplete && !buffer.length && !active) {
      subscriber.complete();
    }
  };
  const outerNext = value => active < concurrent ? doInnerSub(value) : buffer.push(value);
  const doInnerSub = value => {
    expand && subscriber.next(value);
    active++;
    let innerComplete = false;
    (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__.innerFrom)(project(value, index++)).subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, innerValue => {
      onBeforeNext === null || onBeforeNext === void 0 ? void 0 : onBeforeNext(innerValue);
      if (expand) {
        outerNext(innerValue);
      } else {
        subscriber.next(innerValue);
      }
    }, () => {
      innerComplete = true;
    }, undefined, () => {
      if (innerComplete) {
        try {
          active--;
          while (buffer.length && active < concurrent) {
            const bufferedValue = buffer.shift();
            if (innerSubScheduler) {
              (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__.executeSchedule)(subscriber, innerSubScheduler, () => doInnerSub(bufferedValue));
            } else {
              doInnerSub(bufferedValue);
            }
          }
          checkComplete();
        } catch (err) {
          subscriber.error(err);
        }
      }
    }));
  };
  source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, outerNext, () => {
    isComplete = true;
    checkComplete();
  }));
  return () => {
    additionalFinalizer === null || additionalFinalizer === void 0 ? void 0 : additionalFinalizer();
  };
}

/***/ }),

/***/ 13255:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/mergeMap.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   mergeMap: () => (/* binding */ mergeMap)
/* harmony export */ });
/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./map */ 70271);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _mergeInternals__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./mergeInternals */ 48735);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 81530);





function mergeMap(project, resultSelector, concurrent = Infinity) {
  if ((0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(resultSelector)) {
    return mergeMap((a, i) => (0,_map__WEBPACK_IMPORTED_MODULE_1__.map)((b, ii) => resultSelector(a, b, i, ii))((0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(project(a, i))), concurrent);
  } else if (typeof resultSelector === 'number') {
    concurrent = resultSelector;
  }
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_3__.operate)((source, subscriber) => (0,_mergeInternals__WEBPACK_IMPORTED_MODULE_4__.mergeInternals)(source, subscriber, project, concurrent));
}

/***/ }),

/***/ 74304:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/observeOn.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   observeOn: () => (/* binding */ observeOn)
/* harmony export */ });
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function observeOn(scheduler, delay = 0) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__.executeSchedule)(subscriber, scheduler, () => subscriber.next(value), delay), () => (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__.executeSchedule)(subscriber, scheduler, () => subscriber.complete(), delay), err => (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_2__.executeSchedule)(subscriber, scheduler, () => subscriber.error(err), delay)));
  });
}

/***/ }),

/***/ 5057:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/pairwise.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   pairwise: () => (/* binding */ pairwise)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);


function pairwise() {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let prev;
    let hasPrev = false;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      const p = prev;
      prev = value;
      hasPrev && subscriber.next([p, value]);
      hasPrev = true;
    }));
  });
}

/***/ }),

/***/ 15424:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/pluck.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   pluck: () => (/* binding */ pluck)
/* harmony export */ });
/* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./map */ 70271);

function pluck(...properties) {
  const length = properties.length;
  if (length === 0) {
    throw new Error('list of properties cannot be empty.');
  }
  return (0,_map__WEBPACK_IMPORTED_MODULE_0__.map)(x => {
    let currentProp = x;
    for (let i = 0; i < length; i++) {
      const p = currentProp === null || currentProp === void 0 ? void 0 : currentProp[properties[i]];
      if (typeof p !== 'undefined') {
        currentProp = p;
      } else {
        return undefined;
      }
    }
    return currentProp;
  });
}

/***/ }),

/***/ 73481:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/refCount.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   refCount: () => (/* binding */ refCount)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);


function refCount() {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let connection = null;
    source._refCount++;
    const refCounter = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, undefined, undefined, undefined, () => {
      if (!source || source._refCount <= 0 || 0 < --source._refCount) {
        connection = null;
        return;
      }
      const sharedConnection = source._connection;
      const conn = connection;
      connection = null;
      if (sharedConnection && (!conn || sharedConnection === conn)) {
        sharedConnection.unsubscribe();
      }
      subscriber.unsubscribe();
    });
    source.subscribe(refCounter);
    if (!refCounter.closed) {
      connection = source.connect();
    }
  });
}

/***/ }),

/***/ 32112:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/scan.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scan: () => (/* binding */ scan)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _scanInternals__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scanInternals */ 75392);


function scan(accumulator, seed) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((0,_scanInternals__WEBPACK_IMPORTED_MODULE_1__.scanInternals)(accumulator, seed, arguments.length >= 2, true));
}

/***/ }),

/***/ 75392:
/*!************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/scanInternals.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scanInternals: () => (/* binding */ scanInternals)
/* harmony export */ });
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);

function scanInternals(accumulator, seed, hasSeed, emitOnNext, emitBeforeComplete) {
  return (source, subscriber) => {
    let hasState = hasSeed;
    let state = seed;
    let index = 0;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_0__.createOperatorSubscriber)(subscriber, value => {
      const i = index++;
      state = hasState ? accumulator(state, value, i) : (hasState = true, value);
      emitOnNext && subscriber.next(state);
    }, emitBeforeComplete && (() => {
      hasState && subscriber.next(state);
      subscriber.complete();
    })));
  };
}

/***/ }),

/***/ 71870:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/share.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   share: () => (/* binding */ share)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subject */ 10819);
/* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../Subscriber */ 89285);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);




function share(options = {}) {
  const {
    connector = () => new _Subject__WEBPACK_IMPORTED_MODULE_0__.Subject(),
    resetOnError = true,
    resetOnComplete = true,
    resetOnRefCountZero = true
  } = options;
  return wrapperSource => {
    let connection;
    let resetConnection;
    let subject;
    let refCount = 0;
    let hasCompleted = false;
    let hasErrored = false;
    const cancelReset = () => {
      resetConnection === null || resetConnection === void 0 ? void 0 : resetConnection.unsubscribe();
      resetConnection = undefined;
    };
    const reset = () => {
      cancelReset();
      connection = subject = undefined;
      hasCompleted = hasErrored = false;
    };
    const resetAndUnsubscribe = () => {
      const conn = connection;
      reset();
      conn === null || conn === void 0 ? void 0 : conn.unsubscribe();
    };
    return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
      refCount++;
      if (!hasErrored && !hasCompleted) {
        cancelReset();
      }
      const dest = subject = subject !== null && subject !== void 0 ? subject : connector();
      subscriber.add(() => {
        refCount--;
        if (refCount === 0 && !hasErrored && !hasCompleted) {
          resetConnection = handleReset(resetAndUnsubscribe, resetOnRefCountZero);
        }
      });
      dest.subscribe(subscriber);
      if (!connection && refCount > 0) {
        connection = new _Subscriber__WEBPACK_IMPORTED_MODULE_2__.SafeSubscriber({
          next: value => dest.next(value),
          error: err => {
            hasErrored = true;
            cancelReset();
            resetConnection = handleReset(reset, resetOnError, err);
            dest.error(err);
          },
          complete: () => {
            hasCompleted = true;
            cancelReset();
            resetConnection = handleReset(reset, resetOnComplete);
            dest.complete();
          }
        });
        (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__.innerFrom)(source).subscribe(connection);
      }
    })(wrapperSource);
  };
}
function handleReset(reset, on, ...args) {
  if (on === true) {
    reset();
    return;
  }
  if (on === false) {
    return;
  }
  const onSubscriber = new _Subscriber__WEBPACK_IMPORTED_MODULE_2__.SafeSubscriber({
    next: () => {
      onSubscriber.unsubscribe();
      reset();
    }
  });
  return (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_3__.innerFrom)(on(...args)).subscribe(onSubscriber);
}

/***/ }),

/***/ 86301:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/shareReplay.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   shareReplay: () => (/* binding */ shareReplay)
/* harmony export */ });
/* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../ReplaySubject */ 56042);
/* harmony import */ var _share__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./share */ 71870);


function shareReplay(configOrBufferSize, windowTime, scheduler) {
  let bufferSize;
  let refCount = false;
  if (configOrBufferSize && typeof configOrBufferSize === 'object') {
    ({
      bufferSize = Infinity,
      windowTime = Infinity,
      refCount = false,
      scheduler
    } = configOrBufferSize);
  } else {
    bufferSize = configOrBufferSize !== null && configOrBufferSize !== void 0 ? configOrBufferSize : Infinity;
  }
  return (0,_share__WEBPACK_IMPORTED_MODULE_0__.share)({
    connector: () => new _ReplaySubject__WEBPACK_IMPORTED_MODULE_1__.ReplaySubject(bufferSize, windowTime, scheduler),
    resetOnError: true,
    resetOnComplete: false,
    resetOnRefCountZero: refCount
  });
}

/***/ }),

/***/ 47470:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/skip.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   skip: () => (/* binding */ skip)
/* harmony export */ });
/* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./filter */ 51567);

function skip(count) {
  return (0,_filter__WEBPACK_IMPORTED_MODULE_0__.filter)((_, index) => count <= index);
}

/***/ }),

/***/ 63037:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/startWith.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   startWith: () => (/* binding */ startWith)
/* harmony export */ });
/* harmony import */ var _observable_concat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/concat */ 44665);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);



function startWith(...values) {
  const scheduler = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popScheduler)(values);
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    (scheduler ? (0,_observable_concat__WEBPACK_IMPORTED_MODULE_2__.concat)(values, source, scheduler) : (0,_observable_concat__WEBPACK_IMPORTED_MODULE_2__.concat)(values, source)).subscribe(subscriber);
  });
}

/***/ }),

/***/ 12128:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/subscribeOn.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   subscribeOn: () => (/* binding */ subscribeOn)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);

function subscribeOn(scheduler, delay = 0) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    subscriber.add(scheduler.schedule(() => source.subscribe(subscriber), delay));
  });
}

/***/ }),

/***/ 36647:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/switchMap.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   switchMap: () => (/* binding */ switchMap)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function switchMap(project, resultSelector) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let innerSubscriber = null;
    let index = 0;
    let isComplete = false;
    const checkComplete = () => isComplete && !innerSubscriber && subscriber.complete();
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      innerSubscriber === null || innerSubscriber === void 0 ? void 0 : innerSubscriber.unsubscribe();
      let innerIndex = 0;
      const outerIndex = index++;
      (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(project(value, outerIndex)).subscribe(innerSubscriber = (0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, innerValue => subscriber.next(resultSelector ? resultSelector(value, innerValue, outerIndex, innerIndex++) : innerValue), () => {
        innerSubscriber = null;
        checkComplete();
      }));
    }, () => {
      isComplete = true;
      checkComplete();
    }));
  });
}

/***/ }),

/***/ 64334:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/take.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   take: () => (/* binding */ take)
/* harmony export */ });
/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/empty */ 59400);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function take(count) {
  return count <= 0 ? () => _observable_empty__WEBPACK_IMPORTED_MODULE_0__.EMPTY : (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    let seen = 0;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, value => {
      if (++seen <= count) {
        subscriber.next(value);
        if (count <= seen) {
          subscriber.complete();
        }
      }
    }));
  });
}

/***/ }),

/***/ 80602:
/*!*******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/takeLast.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   takeLast: () => (/* binding */ takeLast)
/* harmony export */ });
/* harmony import */ var _observable_empty__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/empty */ 59400);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function takeLast(count) {
  return count <= 0 ? () => _observable_empty__WEBPACK_IMPORTED_MODULE_0__.EMPTY : (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    let buffer = [];
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, value => {
      buffer.push(value);
      count < buffer.length && buffer.shift();
    }, () => {
      for (const value of buffer) {
        subscriber.next(value);
      }
      subscriber.complete();
    }, undefined, () => {
      buffer = null;
    }));
  });
}

/***/ }),

/***/ 33900:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/takeUntil.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   takeUntil: () => (/* binding */ takeUntil)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/noop */ 54318);




function takeUntil(notifier) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_1__.innerFrom)(notifier).subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, () => subscriber.complete(), _util_noop__WEBPACK_IMPORTED_MODULE_3__.noop));
    !subscriber.closed && source.subscribe(subscriber);
  });
}

/***/ }),

/***/ 98764:
/*!**************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/tap.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   tap: () => (/* binding */ tap)
/* harmony export */ });
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isFunction */ 81530);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/identity */ 1440);




function tap(observerOrNext, error, complete) {
  const tapObserver = (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(observerOrNext) || error || complete ? {
    next: observerOrNext,
    error,
    complete
  } : observerOrNext;
  return tapObserver ? (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    var _a;
    (_a = tapObserver.subscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
    let isUnsub = true;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_2__.createOperatorSubscriber)(subscriber, value => {
      var _a;
      (_a = tapObserver.next) === null || _a === void 0 ? void 0 : _a.call(tapObserver, value);
      subscriber.next(value);
    }, () => {
      var _a;
      isUnsub = false;
      (_a = tapObserver.complete) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
      subscriber.complete();
    }, err => {
      var _a;
      isUnsub = false;
      (_a = tapObserver.error) === null || _a === void 0 ? void 0 : _a.call(tapObserver, err);
      subscriber.error(err);
    }, () => {
      var _a, _b;
      if (isUnsub) {
        (_a = tapObserver.unsubscribe) === null || _a === void 0 ? void 0 : _a.call(tapObserver);
      }
      (_b = tapObserver.finalize) === null || _b === void 0 ? void 0 : _b.call(tapObserver);
    }));
  }) : _util_identity__WEBPACK_IMPORTED_MODULE_3__.identity;
}

/***/ }),

/***/ 99365:
/*!***********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/throwIfEmpty.js ***!
  \***********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   throwIfEmpty: () => (/* binding */ throwIfEmpty)
/* harmony export */ });
/* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/EmptyError */ 93335);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);



function throwIfEmpty(errorFactory = defaultErrorFactory) {
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_0__.operate)((source, subscriber) => {
    let hasValue = false;
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_1__.createOperatorSubscriber)(subscriber, value => {
      hasValue = true;
      subscriber.next(value);
    }, () => hasValue ? subscriber.complete() : subscriber.error(errorFactory())));
  });
}
function defaultErrorFactory() {
  return new _util_EmptyError__WEBPACK_IMPORTED_MODULE_2__.EmptyError();
}

/***/ }),

/***/ 72354:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/timeout.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   TimeoutError: () => (/* binding */ TimeoutError),
/* harmony export */   timeout: () => (/* binding */ timeout)
/* harmony export */ });
/* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../scheduler/async */ 18473);
/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isDate */ 15602);
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_createErrorClass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/createErrorClass */ 32384);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);







const TimeoutError = (0,_util_createErrorClass__WEBPACK_IMPORTED_MODULE_0__.createErrorClass)(_super => function TimeoutErrorImpl(info = null) {
  _super(this);
  this.message = 'Timeout has occurred';
  this.name = 'TimeoutError';
  this.info = info;
});
function timeout(config, schedulerArg) {
  const {
    first,
    each,
    with: _with = timeoutErrorFactory,
    scheduler = schedulerArg !== null && schedulerArg !== void 0 ? schedulerArg : _scheduler_async__WEBPACK_IMPORTED_MODULE_1__.asyncScheduler,
    meta = null
  } = (0,_util_isDate__WEBPACK_IMPORTED_MODULE_2__.isValidDate)(config) ? {
    first: config
  } : typeof config === 'number' ? {
    each: config
  } : config;
  if (first == null && each == null) {
    throw new TypeError('No timeout provided.');
  }
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_3__.operate)((source, subscriber) => {
    let originalSourceSubscription;
    let timerSubscription;
    let lastValue = null;
    let seen = 0;
    const startTimer = delay => {
      timerSubscription = (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_4__.executeSchedule)(subscriber, scheduler, () => {
        try {
          originalSourceSubscription.unsubscribe();
          (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_5__.innerFrom)(_with({
            meta,
            lastValue,
            seen
          })).subscribe(subscriber);
        } catch (err) {
          subscriber.error(err);
        }
      }, delay);
    };
    originalSourceSubscription = source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_6__.createOperatorSubscriber)(subscriber, value => {
      timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.unsubscribe();
      seen++;
      subscriber.next(lastValue = value);
      each > 0 && startTimer(each);
    }, undefined, undefined, () => {
      if (!(timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.closed)) {
        timerSubscription === null || timerSubscription === void 0 ? void 0 : timerSubscription.unsubscribe();
      }
      lastValue = null;
    }));
    !seen && startTimer(first != null ? typeof first === 'number' ? first : +first - scheduler.now() : each);
  });
}
function timeoutErrorFactory(info) {
  throw new TimeoutError(info);
}

/***/ }),

/***/ 15842:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/operators/withLatestFrom.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   withLatestFrom: () => (/* binding */ withLatestFrom)
/* harmony export */ });
/* harmony import */ var _util_lift__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/lift */ 50819);
/* harmony import */ var _OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./OperatorSubscriber */ 91687);
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/identity */ 1440);
/* harmony import */ var _util_noop__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../util/noop */ 54318);
/* harmony import */ var _util_args__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/args */ 4083);






function withLatestFrom(...inputs) {
  const project = (0,_util_args__WEBPACK_IMPORTED_MODULE_0__.popResultSelector)(inputs);
  return (0,_util_lift__WEBPACK_IMPORTED_MODULE_1__.operate)((source, subscriber) => {
    const len = inputs.length;
    const otherValues = new Array(len);
    let hasValue = inputs.map(() => false);
    let ready = false;
    for (let i = 0; i < len; i++) {
      (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_2__.innerFrom)(inputs[i]).subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subscriber, value => {
        otherValues[i] = value;
        if (!ready && !hasValue[i]) {
          hasValue[i] = true;
          (ready = hasValue.every(_util_identity__WEBPACK_IMPORTED_MODULE_4__.identity)) && (hasValue = null);
        }
      }, _util_noop__WEBPACK_IMPORTED_MODULE_5__.noop));
    }
    source.subscribe((0,_OperatorSubscriber__WEBPACK_IMPORTED_MODULE_3__.createOperatorSubscriber)(subscriber, value => {
      if (ready) {
        const values = [value, ...otherValues];
        subscriber.next(project ? project(...values) : values);
      }
    }));
  });
}

/***/ }),

/***/ 82345:
/*!************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduleArray.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduleArray: () => (/* binding */ scheduleArray)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);

function scheduleArray(input, scheduler) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    let i = 0;
    return scheduler.schedule(function () {
      if (i === input.length) {
        subscriber.complete();
      } else {
        subscriber.next(input[i++]);
        if (!subscriber.closed) {
          this.schedule();
        }
      }
    });
  });
}

/***/ }),

/***/ 86438:
/*!********************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduleAsyncIterable.js ***!
  \********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduleAsyncIterable: () => (/* binding */ scheduleAsyncIterable)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);


function scheduleAsyncIterable(input, scheduler) {
  if (!input) {
    throw new Error('Iterable cannot be null');
  }
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__.executeSchedule)(subscriber, scheduler, () => {
      const iterator = input[Symbol.asyncIterator]();
      (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__.executeSchedule)(subscriber, scheduler, () => {
        iterator.next().then(result => {
          if (result.done) {
            subscriber.complete();
          } else {
            subscriber.next(result.value);
          }
        });
      }, 0, true);
    });
  });
}

/***/ }),

/***/ 71272:
/*!***************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduleIterable.js ***!
  \***************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduleIterable: () => (/* binding */ scheduleIterable)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../symbol/iterator */ 92476);
/* harmony import */ var _util_isFunction__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../util/isFunction */ 81530);
/* harmony import */ var _util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/executeSchedule */ 20310);




function scheduleIterable(input, scheduler) {
  return new _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable(subscriber => {
    let iterator;
    (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__.executeSchedule)(subscriber, scheduler, () => {
      iterator = input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_2__.iterator]();
      (0,_util_executeSchedule__WEBPACK_IMPORTED_MODULE_1__.executeSchedule)(subscriber, scheduler, () => {
        let value;
        let done;
        try {
          ({
            value,
            done
          } = iterator.next());
        } catch (err) {
          subscriber.error(err);
          return;
        }
        if (done) {
          subscriber.complete();
        } else {
          subscriber.next(value);
        }
      }, 0, true);
    });
    return () => (0,_util_isFunction__WEBPACK_IMPORTED_MODULE_3__.isFunction)(iterator === null || iterator === void 0 ? void 0 : iterator.return) && iterator.return();
  });
}

/***/ }),

/***/ 88143:
/*!*****************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduleObservable.js ***!
  \*****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduleObservable: () => (/* binding */ scheduleObservable)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _operators_observeOn__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../operators/observeOn */ 74304);
/* harmony import */ var _operators_subscribeOn__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../operators/subscribeOn */ 12128);



function scheduleObservable(input, scheduler) {
  return (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__.innerFrom)(input).pipe((0,_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_1__.subscribeOn)(scheduler), (0,_operators_observeOn__WEBPACK_IMPORTED_MODULE_2__.observeOn)(scheduler));
}

/***/ }),

/***/ 60037:
/*!**************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/schedulePromise.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   schedulePromise: () => (/* binding */ schedulePromise)
/* harmony export */ });
/* harmony import */ var _observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../observable/innerFrom */ 82645);
/* harmony import */ var _operators_observeOn__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../operators/observeOn */ 74304);
/* harmony import */ var _operators_subscribeOn__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../operators/subscribeOn */ 12128);



function schedulePromise(input, scheduler) {
  return (0,_observable_innerFrom__WEBPACK_IMPORTED_MODULE_0__.innerFrom)(input).pipe((0,_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_1__.subscribeOn)(scheduler), (0,_operators_observeOn__WEBPACK_IMPORTED_MODULE_2__.observeOn)(scheduler));
}

/***/ }),

/***/ 42777:
/*!*************************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduleReadableStreamLike.js ***!
  \*************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduleReadableStreamLike: () => (/* binding */ scheduleReadableStreamLike)
/* harmony export */ });
/* harmony import */ var _scheduleAsyncIterable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./scheduleAsyncIterable */ 86438);
/* harmony import */ var _util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../util/isReadableStreamLike */ 83233);


function scheduleReadableStreamLike(input, scheduler) {
  return (0,_scheduleAsyncIterable__WEBPACK_IMPORTED_MODULE_0__.scheduleAsyncIterable)((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_1__.readableStreamLikeToAsyncGenerator)(input), scheduler);
}

/***/ }),

/***/ 94424:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduled/scheduled.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   scheduled: () => (/* binding */ scheduled)
/* harmony export */ });
/* harmony import */ var _scheduleObservable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./scheduleObservable */ 88143);
/* harmony import */ var _schedulePromise__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./schedulePromise */ 60037);
/* harmony import */ var _scheduleArray__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./scheduleArray */ 82345);
/* harmony import */ var _scheduleIterable__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./scheduleIterable */ 71272);
/* harmony import */ var _scheduleAsyncIterable__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./scheduleAsyncIterable */ 86438);
/* harmony import */ var _util_isInteropObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/isInteropObservable */ 31516);
/* harmony import */ var _util_isPromise__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../util/isPromise */ 81117);
/* harmony import */ var _util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/isArrayLike */ 88830);
/* harmony import */ var _util_isIterable__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../util/isIterable */ 30528);
/* harmony import */ var _util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../util/isAsyncIterable */ 64558);
/* harmony import */ var _util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../util/throwUnobservableError */ 21374);
/* harmony import */ var _util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../util/isReadableStreamLike */ 83233);
/* harmony import */ var _scheduleReadableStreamLike__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./scheduleReadableStreamLike */ 42777);













function scheduled(input, scheduler) {
  if (input != null) {
    if ((0,_util_isInteropObservable__WEBPACK_IMPORTED_MODULE_0__.isInteropObservable)(input)) {
      return (0,_scheduleObservable__WEBPACK_IMPORTED_MODULE_1__.scheduleObservable)(input, scheduler);
    }
    if ((0,_util_isArrayLike__WEBPACK_IMPORTED_MODULE_2__.isArrayLike)(input)) {
      return (0,_scheduleArray__WEBPACK_IMPORTED_MODULE_3__.scheduleArray)(input, scheduler);
    }
    if ((0,_util_isPromise__WEBPACK_IMPORTED_MODULE_4__.isPromise)(input)) {
      return (0,_schedulePromise__WEBPACK_IMPORTED_MODULE_5__.schedulePromise)(input, scheduler);
    }
    if ((0,_util_isAsyncIterable__WEBPACK_IMPORTED_MODULE_6__.isAsyncIterable)(input)) {
      return (0,_scheduleAsyncIterable__WEBPACK_IMPORTED_MODULE_7__.scheduleAsyncIterable)(input, scheduler);
    }
    if ((0,_util_isIterable__WEBPACK_IMPORTED_MODULE_8__.isIterable)(input)) {
      return (0,_scheduleIterable__WEBPACK_IMPORTED_MODULE_9__.scheduleIterable)(input, scheduler);
    }
    if ((0,_util_isReadableStreamLike__WEBPACK_IMPORTED_MODULE_10__.isReadableStreamLike)(input)) {
      return (0,_scheduleReadableStreamLike__WEBPACK_IMPORTED_MODULE_11__.scheduleReadableStreamLike)(input, scheduler);
    }
  }
  throw (0,_util_throwUnobservableError__WEBPACK_IMPORTED_MODULE_12__.createInvalidObservableTypeError)(input);
}

/***/ }),

/***/ 19103:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/Action.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Action: () => (/* binding */ Action)
/* harmony export */ });
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscription */ 2510);

class Action extends _Subscription__WEBPACK_IMPORTED_MODULE_0__.Subscription {
  constructor(scheduler, work) {
    super();
  }
  schedule(state, delay = 0) {
    return this;
  }
}

/***/ }),

/***/ 91860:
/*!*******************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AnimationFrameAction.js ***!
  \*******************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnimationFrameAction: () => (/* binding */ AnimationFrameAction)
/* harmony export */ });
/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncAction */ 72083);
/* harmony import */ var _animationFrameProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./animationFrameProvider */ 45571);


class AnimationFrameAction extends _AsyncAction__WEBPACK_IMPORTED_MODULE_0__.AsyncAction {
  constructor(scheduler, work) {
    super(scheduler, work);
    this.scheduler = scheduler;
    this.work = work;
  }
  requestAsyncId(scheduler, id, delay = 0) {
    if (delay !== null && delay > 0) {
      return super.requestAsyncId(scheduler, id, delay);
    }
    scheduler.actions.push(this);
    return scheduler._scheduled || (scheduler._scheduled = _animationFrameProvider__WEBPACK_IMPORTED_MODULE_1__.animationFrameProvider.requestAnimationFrame(() => scheduler.flush(undefined)));
  }
  recycleAsyncId(scheduler, id, delay = 0) {
    var _a;
    if (delay != null ? delay > 0 : this.delay > 0) {
      return super.recycleAsyncId(scheduler, id, delay);
    }
    const {
      actions
    } = scheduler;
    if (id != null && id === scheduler._scheduled && ((_a = actions[actions.length - 1]) === null || _a === void 0 ? void 0 : _a.id) !== id) {
      _animationFrameProvider__WEBPACK_IMPORTED_MODULE_1__.animationFrameProvider.cancelAnimationFrame(id);
      scheduler._scheduled = undefined;
    }
    return undefined;
  }
}

/***/ }),

/***/ 74909:
/*!**********************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AnimationFrameScheduler.js ***!
  \**********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnimationFrameScheduler: () => (/* binding */ AnimationFrameScheduler)
/* harmony export */ });
/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncScheduler */ 2400);

class AnimationFrameScheduler extends _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__.AsyncScheduler {
  flush(action) {
    this._active = true;
    let flushId;
    if (action) {
      flushId = action.id;
    } else {
      flushId = this._scheduled;
      this._scheduled = undefined;
    }
    const {
      actions
    } = this;
    let error;
    action = action || actions.shift();
    do {
      if (error = action.execute(action.state, action.delay)) {
        break;
      }
    } while ((action = actions[0]) && action.id === flushId && actions.shift());
    this._active = false;
    if (error) {
      while ((action = actions[0]) && action.id === flushId && actions.shift()) {
        action.unsubscribe();
      }
      throw error;
    }
  }
}

/***/ }),

/***/ 28206:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AsapAction.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AsapAction: () => (/* binding */ AsapAction)
/* harmony export */ });
/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncAction */ 72083);
/* harmony import */ var _immediateProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./immediateProvider */ 73701);


class AsapAction extends _AsyncAction__WEBPACK_IMPORTED_MODULE_0__.AsyncAction {
  constructor(scheduler, work) {
    super(scheduler, work);
    this.scheduler = scheduler;
    this.work = work;
  }
  requestAsyncId(scheduler, id, delay = 0) {
    if (delay !== null && delay > 0) {
      return super.requestAsyncId(scheduler, id, delay);
    }
    scheduler.actions.push(this);
    return scheduler._scheduled || (scheduler._scheduled = _immediateProvider__WEBPACK_IMPORTED_MODULE_1__.immediateProvider.setImmediate(scheduler.flush.bind(scheduler, undefined)));
  }
  recycleAsyncId(scheduler, id, delay = 0) {
    var _a;
    if (delay != null ? delay > 0 : this.delay > 0) {
      return super.recycleAsyncId(scheduler, id, delay);
    }
    const {
      actions
    } = scheduler;
    if (id != null && ((_a = actions[actions.length - 1]) === null || _a === void 0 ? void 0 : _a.id) !== id) {
      _immediateProvider__WEBPACK_IMPORTED_MODULE_1__.immediateProvider.clearImmediate(id);
      if (scheduler._scheduled === id) {
        scheduler._scheduled = undefined;
      }
    }
    return undefined;
  }
}

/***/ }),

/***/ 39835:
/*!************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AsapScheduler.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AsapScheduler: () => (/* binding */ AsapScheduler)
/* harmony export */ });
/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncScheduler */ 2400);

class AsapScheduler extends _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__.AsyncScheduler {
  flush(action) {
    this._active = true;
    const flushId = this._scheduled;
    this._scheduled = undefined;
    const {
      actions
    } = this;
    let error;
    action = action || actions.shift();
    do {
      if (error = action.execute(action.state, action.delay)) {
        break;
      }
    } while ((action = actions[0]) && action.id === flushId && actions.shift());
    this._active = false;
    if (error) {
      while ((action = actions[0]) && action.id === flushId && actions.shift()) {
        action.unsubscribe();
      }
      throw error;
    }
  }
}

/***/ }),

/***/ 72083:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AsyncAction.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AsyncAction: () => (/* binding */ AsyncAction)
/* harmony export */ });
/* harmony import */ var _Action__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Action */ 19103);
/* harmony import */ var _intervalProvider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./intervalProvider */ 28113);
/* harmony import */ var _util_arrRemove__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../util/arrRemove */ 80967);



class AsyncAction extends _Action__WEBPACK_IMPORTED_MODULE_0__.Action {
  constructor(scheduler, work) {
    super(scheduler, work);
    this.scheduler = scheduler;
    this.work = work;
    this.pending = false;
  }
  schedule(state, delay = 0) {
    var _a;
    if (this.closed) {
      return this;
    }
    this.state = state;
    const id = this.id;
    const scheduler = this.scheduler;
    if (id != null) {
      this.id = this.recycleAsyncId(scheduler, id, delay);
    }
    this.pending = true;
    this.delay = delay;
    this.id = (_a = this.id) !== null && _a !== void 0 ? _a : this.requestAsyncId(scheduler, this.id, delay);
    return this;
  }
  requestAsyncId(scheduler, _id, delay = 0) {
    return _intervalProvider__WEBPACK_IMPORTED_MODULE_1__.intervalProvider.setInterval(scheduler.flush.bind(scheduler, this), delay);
  }
  recycleAsyncId(_scheduler, id, delay = 0) {
    if (delay != null && this.delay === delay && this.pending === false) {
      return id;
    }
    if (id != null) {
      _intervalProvider__WEBPACK_IMPORTED_MODULE_1__.intervalProvider.clearInterval(id);
    }
    return undefined;
  }
  execute(state, delay) {
    if (this.closed) {
      return new Error('executing a cancelled action');
    }
    this.pending = false;
    const error = this._execute(state, delay);
    if (error) {
      return error;
    } else if (this.pending === false && this.id != null) {
      this.id = this.recycleAsyncId(this.scheduler, this.id, null);
    }
  }
  _execute(state, _delay) {
    let errored = false;
    let errorValue;
    try {
      this.work(state);
    } catch (e) {
      errored = true;
      errorValue = e ? e : new Error('Scheduled action threw falsy error');
    }
    if (errored) {
      this.unsubscribe();
      return errorValue;
    }
  }
  unsubscribe() {
    if (!this.closed) {
      const {
        id,
        scheduler
      } = this;
      const {
        actions
      } = scheduler;
      this.work = this.state = this.scheduler = null;
      this.pending = false;
      (0,_util_arrRemove__WEBPACK_IMPORTED_MODULE_2__.arrRemove)(actions, this);
      if (id != null) {
        this.id = this.recycleAsyncId(scheduler, id, null);
      }
      this.delay = null;
      super.unsubscribe();
    }
  }
}

/***/ }),

/***/ 2400:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/AsyncScheduler.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AsyncScheduler: () => (/* binding */ AsyncScheduler)
/* harmony export */ });
/* harmony import */ var _Scheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Scheduler */ 71962);

class AsyncScheduler extends _Scheduler__WEBPACK_IMPORTED_MODULE_0__.Scheduler {
  constructor(SchedulerAction, now = _Scheduler__WEBPACK_IMPORTED_MODULE_0__.Scheduler.now) {
    super(SchedulerAction, now);
    this.actions = [];
    this._active = false;
  }
  flush(action) {
    const {
      actions
    } = this;
    if (this._active) {
      actions.push(action);
      return;
    }
    let error;
    this._active = true;
    do {
      if (error = action.execute(action.state, action.delay)) {
        break;
      }
    } while (action = actions.shift());
    this._active = false;
    if (error) {
      while (action = actions.shift()) {
        action.unsubscribe();
      }
      throw error;
    }
  }
}

/***/ }),

/***/ 7380:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/QueueAction.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   QueueAction: () => (/* binding */ QueueAction)
/* harmony export */ });
/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncAction */ 72083);

class QueueAction extends _AsyncAction__WEBPACK_IMPORTED_MODULE_0__.AsyncAction {
  constructor(scheduler, work) {
    super(scheduler, work);
    this.scheduler = scheduler;
    this.work = work;
  }
  schedule(state, delay = 0) {
    if (delay > 0) {
      return super.schedule(state, delay);
    }
    this.delay = delay;
    this.state = state;
    this.scheduler.flush(this);
    return this;
  }
  execute(state, delay) {
    return delay > 0 || this.closed ? super.execute(state, delay) : this._execute(state, delay);
  }
  requestAsyncId(scheduler, id, delay = 0) {
    if (delay != null && delay > 0 || delay == null && this.delay > 0) {
      return super.requestAsyncId(scheduler, id, delay);
    }
    scheduler.flush(this);
    return 0;
  }
}

/***/ }),

/***/ 18045:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/QueueScheduler.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   QueueScheduler: () => (/* binding */ QueueScheduler)
/* harmony export */ });
/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncScheduler */ 2400);

class QueueScheduler extends _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__.AsyncScheduler {}

/***/ }),

/***/ 20614:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/animationFrame.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   animationFrame: () => (/* binding */ animationFrame),
/* harmony export */   animationFrameScheduler: () => (/* binding */ animationFrameScheduler)
/* harmony export */ });
/* harmony import */ var _AnimationFrameAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AnimationFrameAction */ 91860);
/* harmony import */ var _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AnimationFrameScheduler */ 74909);


const animationFrameScheduler = new _AnimationFrameScheduler__WEBPACK_IMPORTED_MODULE_0__.AnimationFrameScheduler(_AnimationFrameAction__WEBPACK_IMPORTED_MODULE_1__.AnimationFrameAction);
const animationFrame = animationFrameScheduler;

/***/ }),

/***/ 45571:
/*!*********************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/animationFrameProvider.js ***!
  \*********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   animationFrameProvider: () => (/* binding */ animationFrameProvider)
/* harmony export */ });
/* harmony import */ var _Subscription__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Subscription */ 2510);

const animationFrameProvider = {
  schedule(callback) {
    let request = requestAnimationFrame;
    let cancel = cancelAnimationFrame;
    const {
      delegate
    } = animationFrameProvider;
    if (delegate) {
      request = delegate.requestAnimationFrame;
      cancel = delegate.cancelAnimationFrame;
    }
    const handle = request(timestamp => {
      cancel = undefined;
      callback(timestamp);
    });
    return new _Subscription__WEBPACK_IMPORTED_MODULE_0__.Subscription(() => cancel === null || cancel === void 0 ? void 0 : cancel(handle));
  },
  requestAnimationFrame(...args) {
    const {
      delegate
    } = animationFrameProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.requestAnimationFrame) || requestAnimationFrame)(...args);
  },
  cancelAnimationFrame(...args) {
    const {
      delegate
    } = animationFrameProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.cancelAnimationFrame) || cancelAnimationFrame)(...args);
  },
  delegate: undefined
};

/***/ }),

/***/ 67180:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/asap.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   asap: () => (/* binding */ asap),
/* harmony export */   asapScheduler: () => (/* binding */ asapScheduler)
/* harmony export */ });
/* harmony import */ var _AsapAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AsapAction */ 28206);
/* harmony import */ var _AsapScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsapScheduler */ 39835);


const asapScheduler = new _AsapScheduler__WEBPACK_IMPORTED_MODULE_0__.AsapScheduler(_AsapAction__WEBPACK_IMPORTED_MODULE_1__.AsapAction);
const asap = asapScheduler;

/***/ }),

/***/ 18473:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/async.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   async: () => (/* binding */ async),
/* harmony export */   asyncScheduler: () => (/* binding */ asyncScheduler)
/* harmony export */ });
/* harmony import */ var _AsyncAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./AsyncAction */ 72083);
/* harmony import */ var _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./AsyncScheduler */ 2400);


const asyncScheduler = new _AsyncScheduler__WEBPACK_IMPORTED_MODULE_0__.AsyncScheduler(_AsyncAction__WEBPACK_IMPORTED_MODULE_1__.AsyncAction);
const async = asyncScheduler;

/***/ }),

/***/ 35152:
/*!********************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/dateTimestampProvider.js ***!
  \********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   dateTimestampProvider: () => (/* binding */ dateTimestampProvider)
/* harmony export */ });
const dateTimestampProvider = {
  now() {
    return (dateTimestampProvider.delegate || Date).now();
  },
  delegate: undefined
};

/***/ }),

/***/ 73701:
/*!****************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/immediateProvider.js ***!
  \****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   immediateProvider: () => (/* binding */ immediateProvider)
/* harmony export */ });
/* harmony import */ var _util_Immediate__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../util/Immediate */ 733);

const {
  setImmediate,
  clearImmediate
} = _util_Immediate__WEBPACK_IMPORTED_MODULE_0__.Immediate;
const immediateProvider = {
  setImmediate(...args) {
    const {
      delegate
    } = immediateProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.setImmediate) || setImmediate)(...args);
  },
  clearImmediate(handle) {
    const {
      delegate
    } = immediateProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearImmediate) || clearImmediate)(handle);
  },
  delegate: undefined
};

/***/ }),

/***/ 28113:
/*!***************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/intervalProvider.js ***!
  \***************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   intervalProvider: () => (/* binding */ intervalProvider)
/* harmony export */ });
const intervalProvider = {
  setInterval(handler, timeout, ...args) {
    const {
      delegate
    } = intervalProvider;
    if (delegate === null || delegate === void 0 ? void 0 : delegate.setInterval) {
      return delegate.setInterval(handler, timeout, ...args);
    }
    return setInterval(handler, timeout, ...args);
  },
  clearInterval(handle) {
    const {
      delegate
    } = intervalProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearInterval) || clearInterval)(handle);
  },
  delegate: undefined
};

/***/ }),

/***/ 67046:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/queue.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   queue: () => (/* binding */ queue),
/* harmony export */   queueScheduler: () => (/* binding */ queueScheduler)
/* harmony export */ });
/* harmony import */ var _QueueAction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./QueueAction */ 7380);
/* harmony import */ var _QueueScheduler__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./QueueScheduler */ 18045);


const queueScheduler = new _QueueScheduler__WEBPACK_IMPORTED_MODULE_0__.QueueScheduler(_QueueAction__WEBPACK_IMPORTED_MODULE_1__.QueueAction);
const queue = queueScheduler;

/***/ }),

/***/ 59603:
/*!**************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/scheduler/timeoutProvider.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   timeoutProvider: () => (/* binding */ timeoutProvider)
/* harmony export */ });
const timeoutProvider = {
  setTimeout(handler, timeout, ...args) {
    const {
      delegate
    } = timeoutProvider;
    if (delegate === null || delegate === void 0 ? void 0 : delegate.setTimeout) {
      return delegate.setTimeout(handler, timeout, ...args);
    }
    return setTimeout(handler, timeout, ...args);
  },
  clearTimeout(handle) {
    const {
      delegate
    } = timeoutProvider;
    return ((delegate === null || delegate === void 0 ? void 0 : delegate.clearTimeout) || clearTimeout)(handle);
  },
  delegate: undefined
};

/***/ }),

/***/ 92476:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/symbol/iterator.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   getSymbolIterator: () => (/* binding */ getSymbolIterator),
/* harmony export */   iterator: () => (/* binding */ iterator)
/* harmony export */ });
function getSymbolIterator() {
  if (typeof Symbol !== 'function' || !Symbol.iterator) {
    return '@@iterator';
  }
  return Symbol.iterator;
}
const iterator = getSymbolIterator();

/***/ }),

/***/ 44127:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/symbol/observable.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   observable: () => (/* binding */ observable)
/* harmony export */ });
const observable = (() => typeof Symbol === 'function' && Symbol.observable || '@@observable')();

/***/ }),

/***/ 93335:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/EmptyError.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   EmptyError: () => (/* binding */ EmptyError)
/* harmony export */ });
/* harmony import */ var _createErrorClass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./createErrorClass */ 32384);

const EmptyError = (0,_createErrorClass__WEBPACK_IMPORTED_MODULE_0__.createErrorClass)(_super => function EmptyErrorImpl() {
  _super(this);
  this.name = 'EmptyError';
  this.message = 'no elements in sequence';
});

/***/ }),

/***/ 733:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/Immediate.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Immediate: () => (/* binding */ Immediate),
/* harmony export */   TestTools: () => (/* binding */ TestTools)
/* harmony export */ });
let nextHandle = 1;
let resolved;
const activeHandles = {};
function findAndClearHandle(handle) {
  if (handle in activeHandles) {
    delete activeHandles[handle];
    return true;
  }
  return false;
}
const Immediate = {
  setImmediate(cb) {
    const handle = nextHandle++;
    activeHandles[handle] = true;
    if (!resolved) {
      resolved = Promise.resolve();
    }
    resolved.then(() => findAndClearHandle(handle) && cb());
    return handle;
  },
  clearImmediate(handle) {
    findAndClearHandle(handle);
  }
};
const TestTools = {
  pending() {
    return Object.keys(activeHandles).length;
  }
};

/***/ }),

/***/ 21910:
/*!*****************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/ObjectUnsubscribedError.js ***!
  \*****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ObjectUnsubscribedError: () => (/* binding */ ObjectUnsubscribedError)
/* harmony export */ });
/* harmony import */ var _createErrorClass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./createErrorClass */ 32384);

const ObjectUnsubscribedError = (0,_createErrorClass__WEBPACK_IMPORTED_MODULE_0__.createErrorClass)(_super => function ObjectUnsubscribedErrorImpl() {
  _super(this);
  this.name = 'ObjectUnsubscribedError';
  this.message = 'object unsubscribed';
});

/***/ }),

/***/ 42540:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/UnsubscriptionError.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   UnsubscriptionError: () => (/* binding */ UnsubscriptionError)
/* harmony export */ });
/* harmony import */ var _createErrorClass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./createErrorClass */ 32384);

const UnsubscriptionError = (0,_createErrorClass__WEBPACK_IMPORTED_MODULE_0__.createErrorClass)(_super => function UnsubscriptionErrorImpl(errors) {
  _super(this);
  this.message = errors ? `${errors.length} errors occurred during unsubscription:
${errors.map((err, i) => `${i + 1}) ${err.toString()}`).join('\n  ')}` : '';
  this.name = 'UnsubscriptionError';
  this.errors = errors;
});

/***/ }),

/***/ 4083:
/*!**********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/args.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   popNumber: () => (/* binding */ popNumber),
/* harmony export */   popResultSelector: () => (/* binding */ popResultSelector),
/* harmony export */   popScheduler: () => (/* binding */ popScheduler)
/* harmony export */ });
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);
/* harmony import */ var _isScheduler__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isScheduler */ 89397);


function last(arr) {
  return arr[arr.length - 1];
}
function popResultSelector(args) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(last(args)) ? args.pop() : undefined;
}
function popScheduler(args) {
  return (0,_isScheduler__WEBPACK_IMPORTED_MODULE_1__.isScheduler)(last(args)) ? args.pop() : undefined;
}
function popNumber(args, defaultValue) {
  return typeof last(args) === 'number' ? args.pop() : defaultValue;
}

/***/ }),

/***/ 57808:
/*!**************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/argsArgArrayOrObject.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   argsArgArrayOrObject: () => (/* binding */ argsArgArrayOrObject)
/* harmony export */ });
const {
  isArray
} = Array;
const {
  getPrototypeOf,
  prototype: objectProto,
  keys: getKeys
} = Object;
function argsArgArrayOrObject(args) {
  if (args.length === 1) {
    const first = args[0];
    if (isArray(first)) {
      return {
        args: first,
        keys: null
      };
    }
    if (isPOJO(first)) {
      const keys = getKeys(first);
      return {
        args: keys.map(key => first[key]),
        keys
      };
    }
  }
  return {
    args: args,
    keys: null
  };
}
function isPOJO(obj) {
  return obj && typeof obj === 'object' && getPrototypeOf(obj) === objectProto;
}

/***/ }),

/***/ 41303:
/*!********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/argsOrArgArray.js ***!
  \********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   argsOrArgArray: () => (/* binding */ argsOrArgArray)
/* harmony export */ });
const {
  isArray
} = Array;
function argsOrArgArray(args) {
  return args.length === 1 && isArray(args[0]) ? args[0] : args;
}

/***/ }),

/***/ 80967:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/arrRemove.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   arrRemove: () => (/* binding */ arrRemove)
/* harmony export */ });
function arrRemove(arr, item) {
  if (arr) {
    const index = arr.indexOf(item);
    0 <= index && arr.splice(index, 1);
  }
}

/***/ }),

/***/ 32384:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/createErrorClass.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createErrorClass: () => (/* binding */ createErrorClass)
/* harmony export */ });
function createErrorClass(createImpl) {
  const _super = instance => {
    Error.call(instance);
    instance.stack = new Error().stack;
  };
  const ctorFunc = createImpl(_super);
  ctorFunc.prototype = Object.create(Error.prototype);
  ctorFunc.prototype.constructor = ctorFunc;
  return ctorFunc;
}

/***/ }),

/***/ 96813:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/createObject.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createObject: () => (/* binding */ createObject)
/* harmony export */ });
function createObject(keys, values) {
  return keys.reduce((result, key, i) => (result[key] = values[i], result), {});
}

/***/ }),

/***/ 60023:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/errorContext.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   captureError: () => (/* binding */ captureError),
/* harmony export */   errorContext: () => (/* binding */ errorContext)
/* harmony export */ });
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../config */ 62213);

let context = null;
function errorContext(cb) {
  if (_config__WEBPACK_IMPORTED_MODULE_0__.config.useDeprecatedSynchronousErrorHandling) {
    const isRoot = !context;
    if (isRoot) {
      context = {
        errorThrown: false,
        error: null
      };
    }
    cb();
    if (isRoot) {
      const {
        errorThrown,
        error
      } = context;
      context = null;
      if (errorThrown) {
        throw error;
      }
    }
  } else {
    cb();
  }
}
function captureError(err) {
  if (_config__WEBPACK_IMPORTED_MODULE_0__.config.useDeprecatedSynchronousErrorHandling && context) {
    context.errorThrown = true;
    context.error = err;
  }
}

/***/ }),

/***/ 20310:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/executeSchedule.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   executeSchedule: () => (/* binding */ executeSchedule)
/* harmony export */ });
function executeSchedule(parentSubscription, scheduler, work, delay = 0, repeat = false) {
  const scheduleSubscription = scheduler.schedule(function () {
    work();
    if (repeat) {
      parentSubscription.add(this.schedule(null, delay));
    } else {
      this.unsubscribe();
    }
  }, delay);
  parentSubscription.add(scheduleSubscription);
  if (!repeat) {
    return scheduleSubscription;
  }
}

/***/ }),

/***/ 1440:
/*!**************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/identity.js ***!
  \**************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   identity: () => (/* binding */ identity)
/* harmony export */ });
function identity(x) {
  return x;
}

/***/ }),

/***/ 88830:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isArrayLike.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isArrayLike: () => (/* binding */ isArrayLike)
/* harmony export */ });
const isArrayLike = x => x && typeof x.length === 'number' && typeof x !== 'function';

/***/ }),

/***/ 64558:
/*!*********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isAsyncIterable.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isAsyncIterable: () => (/* binding */ isAsyncIterable)
/* harmony export */ });
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);

function isAsyncIterable(obj) {
  return Symbol.asyncIterator && (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(obj === null || obj === void 0 ? void 0 : obj[Symbol.asyncIterator]);
}

/***/ }),

/***/ 15602:
/*!************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isDate.js ***!
  \************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isValidDate: () => (/* binding */ isValidDate)
/* harmony export */ });
function isValidDate(value) {
  return value instanceof Date && !isNaN(value);
}

/***/ }),

/***/ 81530:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isFunction.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isFunction: () => (/* binding */ isFunction)
/* harmony export */ });
function isFunction(value) {
  return typeof value === 'function';
}

/***/ }),

/***/ 31516:
/*!*************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isInteropObservable.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isInteropObservable: () => (/* binding */ isInteropObservable)
/* harmony export */ });
/* harmony import */ var _symbol_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../symbol/observable */ 44127);
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);


function isInteropObservable(input) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(input[_symbol_observable__WEBPACK_IMPORTED_MODULE_1__.observable]);
}

/***/ }),

/***/ 30528:
/*!****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isIterable.js ***!
  \****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isIterable: () => (/* binding */ isIterable)
/* harmony export */ });
/* harmony import */ var _symbol_iterator__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../symbol/iterator */ 92476);
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);


function isIterable(input) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(input === null || input === void 0 ? void 0 : input[_symbol_iterator__WEBPACK_IMPORTED_MODULE_1__.iterator]);
}

/***/ }),

/***/ 72551:
/*!******************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isObservable.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isObservable: () => (/* binding */ isObservable)
/* harmony export */ });
/* harmony import */ var _Observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../Observable */ 43942);
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isFunction */ 81530);


function isObservable(obj) {
  return !!obj && (obj instanceof _Observable__WEBPACK_IMPORTED_MODULE_0__.Observable || (0,_isFunction__WEBPACK_IMPORTED_MODULE_1__.isFunction)(obj.lift) && (0,_isFunction__WEBPACK_IMPORTED_MODULE_1__.isFunction)(obj.subscribe));
}

/***/ }),

/***/ 81117:
/*!***************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isPromise.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isPromise: () => (/* binding */ isPromise)
/* harmony export */ });
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);

function isPromise(value) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(value === null || value === void 0 ? void 0 : value.then);
}

/***/ }),

/***/ 83233:
/*!**************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isReadableStreamLike.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isReadableStreamLike: () => (/* binding */ isReadableStreamLike),
/* harmony export */   readableStreamLikeToAsyncGenerator: () => (/* binding */ readableStreamLikeToAsyncGenerator)
/* harmony export */ });
/* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ 24398);
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isFunction */ 81530);


function readableStreamLikeToAsyncGenerator(readableStream) {
  return (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__asyncGenerator)(this, arguments, function* readableStreamLikeToAsyncGenerator_1() {
    const reader = readableStream.getReader();
    try {
      while (true) {
        const {
          value,
          done
        } = yield (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__await)(reader.read());
        if (done) {
          return yield (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__await)(void 0);
        }
        yield yield (0,tslib__WEBPACK_IMPORTED_MODULE_0__.__await)(value);
      }
    } finally {
      reader.releaseLock();
    }
  });
}
function isReadableStreamLike(obj) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_1__.isFunction)(obj === null || obj === void 0 ? void 0 : obj.getReader);
}

/***/ }),

/***/ 89397:
/*!*****************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/isScheduler.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isScheduler: () => (/* binding */ isScheduler)
/* harmony export */ });
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);

function isScheduler(value) {
  return value && (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(value.schedule);
}

/***/ }),

/***/ 50819:
/*!**********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/lift.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   hasLift: () => (/* binding */ hasLift),
/* harmony export */   operate: () => (/* binding */ operate)
/* harmony export */ });
/* harmony import */ var _isFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isFunction */ 81530);

function hasLift(source) {
  return (0,_isFunction__WEBPACK_IMPORTED_MODULE_0__.isFunction)(source === null || source === void 0 ? void 0 : source.lift);
}
function operate(init) {
  return source => {
    if (hasLift(source)) {
      return source.lift(function (liftedSource) {
        try {
          return init(liftedSource, this);
        } catch (err) {
          this.error(err);
        }
      });
    }
    throw new TypeError('Unable to lift unknown Observable type');
  };
}

/***/ }),

/***/ 38067:
/*!**********************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/mapOneOrManyArgs.js ***!
  \**********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   mapOneOrManyArgs: () => (/* binding */ mapOneOrManyArgs)
/* harmony export */ });
/* harmony import */ var _operators_map__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../operators/map */ 70271);

const {
  isArray
} = Array;
function callOrApply(fn, args) {
  return isArray(args) ? fn(...args) : fn(args);
}
function mapOneOrManyArgs(fn) {
  return (0,_operators_map__WEBPACK_IMPORTED_MODULE_0__.map)(args => callOrApply(fn, args));
}

/***/ }),

/***/ 54318:
/*!**********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/noop.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   noop: () => (/* binding */ noop)
/* harmony export */ });
function noop() {}

/***/ }),

/***/ 95682:
/*!**********************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/pipe.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   pipe: () => (/* binding */ pipe),
/* harmony export */   pipeFromArray: () => (/* binding */ pipeFromArray)
/* harmony export */ });
/* harmony import */ var _identity__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./identity */ 1440);

function pipe(...fns) {
  return pipeFromArray(fns);
}
function pipeFromArray(fns) {
  if (fns.length === 0) {
    return _identity__WEBPACK_IMPORTED_MODULE_0__.identity;
  }
  if (fns.length === 1) {
    return fns[0];
  }
  return function piped(input) {
    return fns.reduce((prev, fn) => fn(prev), input);
  };
}

/***/ }),

/***/ 31411:
/*!**************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/reportUnhandledError.js ***!
  \**************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   reportUnhandledError: () => (/* binding */ reportUnhandledError)
/* harmony export */ });
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../config */ 62213);
/* harmony import */ var _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../scheduler/timeoutProvider */ 59603);


function reportUnhandledError(err) {
  _scheduler_timeoutProvider__WEBPACK_IMPORTED_MODULE_0__.timeoutProvider.setTimeout(() => {
    const {
      onUnhandledError
    } = _config__WEBPACK_IMPORTED_MODULE_1__.config;
    if (onUnhandledError) {
      onUnhandledError(err);
    } else {
      throw err;
    }
  });
}

/***/ }),

/***/ 21374:
/*!****************************************************************************!*\
  !*** ./node_modules/rxjs/dist/esm/internal/util/throwUnobservableError.js ***!
  \****************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createInvalidObservableTypeError: () => (/* binding */ createInvalidObservableTypeError)
/* harmony export */ });
function createInvalidObservableTypeError(input) {
  return new TypeError(`You provided ${input !== null && typeof input === 'object' ? 'an invalid object' : `'${input}'`} where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`);
}

/***/ }),

/***/ 37581:
/*!**********************************************************!*\
  !*** ./node_modules/sweetalert2/dist/sweetalert2.all.js ***!
  \**********************************************************/
/***/ (function(module) {

/*!
* sweetalert2 v11.23.0
* Released under the MIT License.
*/
(function (global, factory) {
   true ? module.exports = factory() : 0;
})(this, function () {
  'use strict';

  function _assertClassBrand(e, t, n) {
    if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
    throw new TypeError("Private element is not present on this object");
  }
  function _checkPrivateRedeclaration(e, t) {
    if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
  }
  function _classPrivateFieldGet2(s, a) {
    return s.get(_assertClassBrand(s, a));
  }
  function _classPrivateFieldInitSpec(e, t, a) {
    _checkPrivateRedeclaration(e, t), t.set(e, a);
  }
  function _classPrivateFieldSet2(s, a, r) {
    return s.set(_assertClassBrand(s, a), r), r;
  }
  const RESTORE_FOCUS_TIMEOUT = 100;

  /** @type {GlobalState} */
  const globalState = {};
  const focusPreviousActiveElement = () => {
    if (globalState.previousActiveElement instanceof HTMLElement) {
      globalState.previousActiveElement.focus();
      globalState.previousActiveElement = null;
    } else if (document.body) {
      document.body.focus();
    }
  };

  /**
   * Restore previous active (focused) element
   *
   * @param {boolean} returnFocus
   * @returns {Promise<void>}
   */
  const restoreActiveElement = returnFocus => {
    return new Promise(resolve => {
      if (!returnFocus) {
        return resolve();
      }
      const x = window.scrollX;
      const y = window.scrollY;
      globalState.restoreFocusTimeout = setTimeout(() => {
        focusPreviousActiveElement();
        resolve();
      }, RESTORE_FOCUS_TIMEOUT); // issues/900

      window.scrollTo(x, y);
    });
  };
  const swalPrefix = 'swal2-';

  /**
   * @typedef {Record<SwalClass, string>} SwalClasses
   */

  /**
   * @typedef {'success' | 'warning' | 'info' | 'question' | 'error'} SwalIcon
   * @typedef {Record<SwalIcon, string>} SwalIcons
   */

  /** @type {SwalClass[]} */
  const classNames = ['container', 'shown', 'height-auto', 'iosfix', 'popup', 'modal', 'no-backdrop', 'no-transition', 'toast', 'toast-shown', 'show', 'hide', 'close', 'title', 'html-container', 'actions', 'confirm', 'deny', 'cancel', 'footer', 'icon', 'icon-content', 'image', 'input', 'file', 'range', 'select', 'radio', 'checkbox', 'label', 'textarea', 'inputerror', 'input-label', 'validation-message', 'progress-steps', 'active-progress-step', 'progress-step', 'progress-step-line', 'loader', 'loading', 'styled', 'top', 'top-start', 'top-end', 'top-left', 'top-right', 'center', 'center-start', 'center-end', 'center-left', 'center-right', 'bottom', 'bottom-start', 'bottom-end', 'bottom-left', 'bottom-right', 'grow-row', 'grow-column', 'grow-fullscreen', 'rtl', 'timer-progress-bar', 'timer-progress-bar-container', 'scrollbar-measure', 'icon-success', 'icon-warning', 'icon-info', 'icon-question', 'icon-error', 'draggable', 'dragging'];
  const swalClasses = classNames.reduce((acc, className) => {
    acc[className] = swalPrefix + className;
    return acc;
  }, /** @type {SwalClasses} */{});

  /** @type {SwalIcon[]} */
  const icons = ['success', 'warning', 'info', 'question', 'error'];
  const iconTypes = icons.reduce((acc, icon) => {
    acc[icon] = swalPrefix + icon;
    return acc;
  }, /** @type {SwalIcons} */{});
  const consolePrefix = 'SweetAlert2:';

  /**
   * Capitalize the first letter of a string
   *
   * @param {string} str
   * @returns {string}
   */
  const capitalizeFirstLetter = str => str.charAt(0).toUpperCase() + str.slice(1);

  /**
   * Standardize console warnings
   *
   * @param {string | string[]} message
   */
  const warn = message => {
    console.warn(`${consolePrefix} ${typeof message === 'object' ? message.join(' ') : message}`);
  };

  /**
   * Standardize console errors
   *
   * @param {string} message
   */
  const error = message => {
    console.error(`${consolePrefix} ${message}`);
  };

  /**
   * Private global state for `warnOnce`
   *
   * @type {string[]}
   * @private
   */
  const previousWarnOnceMessages = [];

  /**
   * Show a console warning, but only if it hasn't already been shown
   *
   * @param {string} message
   */
  const warnOnce = message => {
    if (!previousWarnOnceMessages.includes(message)) {
      previousWarnOnceMessages.push(message);
      warn(message);
    }
  };

  /**
   * Show a one-time console warning about deprecated params/methods
   *
   * @param {string} deprecatedParam
   * @param {string?} useInstead
   */
  const warnAboutDeprecation = (deprecatedParam, useInstead = null) => {
    warnOnce(`"${deprecatedParam}" is deprecated and will be removed in the next major release.${useInstead ? ` Use "${useInstead}" instead.` : ''}`);
  };

  /**
   * If `arg` is a function, call it (with no arguments or context) and return the result.
   * Otherwise, just pass the value through
   *
   * @param {Function | any} arg
   * @returns {any}
   */
  const callIfFunction = arg => typeof arg === 'function' ? arg() : arg;

  /**
   * @param {any} arg
   * @returns {boolean}
   */
  const hasToPromiseFn = arg => arg && typeof arg.toPromise === 'function';

  /**
   * @param {any} arg
   * @returns {Promise<any>}
   */
  const asPromise = arg => hasToPromiseFn(arg) ? arg.toPromise() : Promise.resolve(arg);

  /**
   * @param {any} arg
   * @returns {boolean}
   */
  const isPromise = arg => arg && Promise.resolve(arg) === arg;

  /**
   * Gets the popup container which contains the backdrop and the popup itself.
   *
   * @returns {HTMLElement | null}
   */
  const getContainer = () => document.body.querySelector(`.${swalClasses.container}`);

  /**
   * @param {string} selectorString
   * @returns {HTMLElement | null}
   */
  const elementBySelector = selectorString => {
    const container = getContainer();
    return container ? container.querySelector(selectorString) : null;
  };

  /**
   * @param {string} className
   * @returns {HTMLElement | null}
   */
  const elementByClass = className => {
    return elementBySelector(`.${className}`);
  };

  /**
   * @returns {HTMLElement | null}
   */
  const getPopup = () => elementByClass(swalClasses.popup);

  /**
   * @returns {HTMLElement | null}
   */
  const getIcon = () => elementByClass(swalClasses.icon);

  /**
   * @returns {HTMLElement | null}
   */
  const getIconContent = () => elementByClass(swalClasses['icon-content']);

  /**
   * @returns {HTMLElement | null}
   */
  const getTitle = () => elementByClass(swalClasses.title);

  /**
   * @returns {HTMLElement | null}
   */
  const getHtmlContainer = () => elementByClass(swalClasses['html-container']);

  /**
   * @returns {HTMLElement | null}
   */
  const getImage = () => elementByClass(swalClasses.image);

  /**
   * @returns {HTMLElement | null}
   */
  const getProgressSteps = () => elementByClass(swalClasses['progress-steps']);

  /**
   * @returns {HTMLElement | null}
   */
  const getValidationMessage = () => elementByClass(swalClasses['validation-message']);

  /**
   * @returns {HTMLButtonElement | null}
   */
  const getConfirmButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.confirm}`));

  /**
   * @returns {HTMLButtonElement | null}
   */
  const getCancelButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.cancel}`));

  /**
   * @returns {HTMLButtonElement | null}
   */
  const getDenyButton = () => (/** @type {HTMLButtonElement} */elementBySelector(`.${swalClasses.actions} .${swalClasses.deny}`));

  /**
   * @returns {HTMLElement | null}
   */
  const getInputLabel = () => elementByClass(swalClasses['input-label']);

  /**
   * @returns {HTMLElement | null}
   */
  const getLoader = () => elementBySelector(`.${swalClasses.loader}`);

  /**
   * @returns {HTMLElement | null}
   */
  const getActions = () => elementByClass(swalClasses.actions);

  /**
   * @returns {HTMLElement | null}
   */
  const getFooter = () => elementByClass(swalClasses.footer);

  /**
   * @returns {HTMLElement | null}
   */
  const getTimerProgressBar = () => elementByClass(swalClasses['timer-progress-bar']);

  /**
   * @returns {HTMLElement | null}
   */
  const getCloseButton = () => elementByClass(swalClasses.close);

  // https://github.com/jkup/focusable/blob/master/index.js
  const focusable = `
  a[href],
  area[href],
  input:not([disabled]),
  select:not([disabled]),
  textarea:not([disabled]),
  button:not([disabled]),
  iframe,
  object,
  embed,
  [tabindex="0"],
  [contenteditable],
  audio[controls],
  video[controls],
  summary
`;
  /**
   * @returns {HTMLElement[]}
   */
  const getFocusableElements = () => {
    const popup = getPopup();
    if (!popup) {
      return [];
    }
    /** @type {NodeListOf<HTMLElement>} */
    const focusableElementsWithTabindex = popup.querySelectorAll('[tabindex]:not([tabindex="-1"]):not([tabindex="0"])');
    const focusableElementsWithTabindexSorted = Array.from(focusableElementsWithTabindex)
    // sort according to tabindex
    .sort((a, b) => {
      const tabindexA = parseInt(a.getAttribute('tabindex') || '0');
      const tabindexB = parseInt(b.getAttribute('tabindex') || '0');
      if (tabindexA > tabindexB) {
        return 1;
      } else if (tabindexA < tabindexB) {
        return -1;
      }
      return 0;
    });

    /** @type {NodeListOf<HTMLElement>} */
    const otherFocusableElements = popup.querySelectorAll(focusable);
    const otherFocusableElementsFiltered = Array.from(otherFocusableElements).filter(el => el.getAttribute('tabindex') !== '-1');
    return [...new Set(focusableElementsWithTabindexSorted.concat(otherFocusableElementsFiltered))].filter(el => isVisible$1(el));
  };

  /**
   * @returns {boolean}
   */
  const isModal = () => {
    return hasClass(document.body, swalClasses.shown) && !hasClass(document.body, swalClasses['toast-shown']) && !hasClass(document.body, swalClasses['no-backdrop']);
  };

  /**
   * @returns {boolean}
   */
  const isToast = () => {
    const popup = getPopup();
    if (!popup) {
      return false;
    }
    return hasClass(popup, swalClasses.toast);
  };

  /**
   * @returns {boolean}
   */
  const isLoading = () => {
    const popup = getPopup();
    if (!popup) {
      return false;
    }
    return popup.hasAttribute('data-loading');
  };

  /**
   * Securely set innerHTML of an element
   * https://github.com/sweetalert2/sweetalert2/issues/1926
   *
   * @param {HTMLElement} elem
   * @param {string} html
   */
  const setInnerHtml = (elem, html) => {
    elem.textContent = '';
    if (html) {
      const parser = new DOMParser();
      const parsed = parser.parseFromString(html, `text/html`);
      const head = parsed.querySelector('head');
      if (head) {
        Array.from(head.childNodes).forEach(child => {
          elem.appendChild(child);
        });
      }
      const body = parsed.querySelector('body');
      if (body) {
        Array.from(body.childNodes).forEach(child => {
          if (child instanceof HTMLVideoElement || child instanceof HTMLAudioElement) {
            elem.appendChild(child.cloneNode(true)); // https://github.com/sweetalert2/sweetalert2/issues/2507
          } else {
            elem.appendChild(child);
          }
        });
      }
    }
  };

  /**
   * @param {HTMLElement} elem
   * @param {string} className
   * @returns {boolean}
   */
  const hasClass = (elem, className) => {
    if (!className) {
      return false;
    }
    const classList = className.split(/\s+/);
    for (let i = 0; i < classList.length; i++) {
      if (!elem.classList.contains(classList[i])) {
        return false;
      }
    }
    return true;
  };

  /**
   * @param {HTMLElement} elem
   * @param {SweetAlertOptions} params
   */
  const removeCustomClasses = (elem, params) => {
    Array.from(elem.classList).forEach(className => {
      if (!Object.values(swalClasses).includes(className) && !Object.values(iconTypes).includes(className) && !Object.values(params.showClass || {}).includes(className)) {
        elem.classList.remove(className);
      }
    });
  };

  /**
   * @param {HTMLElement} elem
   * @param {SweetAlertOptions} params
   * @param {string} className
   */
  const applyCustomClass = (elem, params, className) => {
    removeCustomClasses(elem, params);
    if (!params.customClass) {
      return;
    }
    const customClass = params.customClass[(/** @type {keyof SweetAlertCustomClass} */className)];
    if (!customClass) {
      return;
    }
    if (typeof customClass !== 'string' && !customClass.forEach) {
      warn(`Invalid type of customClass.${className}! Expected string or iterable object, got "${typeof customClass}"`);
      return;
    }
    addClass(elem, customClass);
  };

  /**
   * @param {HTMLElement} popup
   * @param {import('./renderers/renderInput').InputClass | SweetAlertInput} inputClass
   * @returns {HTMLInputElement | null}
   */
  const getInput$1 = (popup, inputClass) => {
    if (!inputClass) {
      return null;
    }
    switch (inputClass) {
      case 'select':
      case 'textarea':
      case 'file':
        return popup.querySelector(`.${swalClasses.popup} > .${swalClasses[inputClass]}`);
      case 'checkbox':
        return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.checkbox} input`);
      case 'radio':
        return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:checked`) || popup.querySelector(`.${swalClasses.popup} > .${swalClasses.radio} input:first-child`);
      case 'range':
        return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.range} input`);
      default:
        return popup.querySelector(`.${swalClasses.popup} > .${swalClasses.input}`);
    }
  };

  /**
   * @param {HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement} input
   */
  const focusInput = input => {
    input.focus();

    // place cursor at end of text in text input
    if (input.type !== 'file') {
      // http://stackoverflow.com/a/2345915
      const val = input.value;
      input.value = '';
      input.value = val;
    }
  };

  /**
   * @param {HTMLElement | HTMLElement[] | null} target
   * @param {string | string[] | readonly string[] | undefined} classList
   * @param {boolean} condition
   */
  const toggleClass = (target, classList, condition) => {
    if (!target || !classList) {
      return;
    }
    if (typeof classList === 'string') {
      classList = classList.split(/\s+/).filter(Boolean);
    }
    classList.forEach(className => {
      if (Array.isArray(target)) {
        target.forEach(elem => {
          if (condition) {
            elem.classList.add(className);
          } else {
            elem.classList.remove(className);
          }
        });
      } else {
        if (condition) {
          target.classList.add(className);
        } else {
          target.classList.remove(className);
        }
      }
    });
  };

  /**
   * @param {HTMLElement | HTMLElement[] | null} target
   * @param {string | string[] | readonly string[] | undefined} classList
   */
  const addClass = (target, classList) => {
    toggleClass(target, classList, true);
  };

  /**
   * @param {HTMLElement | HTMLElement[] | null} target
   * @param {string | string[] | readonly string[] | undefined} classList
   */
  const removeClass = (target, classList) => {
    toggleClass(target, classList, false);
  };

  /**
   * Get direct child of an element by class name
   *
   * @param {HTMLElement} elem
   * @param {string} className
   * @returns {HTMLElement | undefined}
   */
  const getDirectChildByClass = (elem, className) => {
    const children = Array.from(elem.children);
    for (let i = 0; i < children.length; i++) {
      const child = children[i];
      if (child instanceof HTMLElement && hasClass(child, className)) {
        return child;
      }
    }
  };

  /**
   * @param {HTMLElement} elem
   * @param {string} property
   * @param {*} value
   */
  const applyNumericalStyle = (elem, property, value) => {
    if (value === `${parseInt(value)}`) {
      value = parseInt(value);
    }
    if (value || parseInt(value) === 0) {
      elem.style.setProperty(property, typeof value === 'number' ? `${value}px` : value);
    } else {
      elem.style.removeProperty(property);
    }
  };

  /**
   * @param {HTMLElement | null} elem
   * @param {string} display
   */
  const show = (elem, display = 'flex') => {
    if (!elem) {
      return;
    }
    elem.style.display = display;
  };

  /**
   * @param {HTMLElement | null} elem
   */
  const hide = elem => {
    if (!elem) {
      return;
    }
    elem.style.display = 'none';
  };

  /**
   * @param {HTMLElement | null} elem
   * @param {string} display
   */
  const showWhenInnerHtmlPresent = (elem, display = 'block') => {
    if (!elem) {
      return;
    }
    new MutationObserver(() => {
      toggle(elem, elem.innerHTML, display);
    }).observe(elem, {
      childList: true,
      subtree: true
    });
  };

  /**
   * @param {HTMLElement} parent
   * @param {string} selector
   * @param {string} property
   * @param {string} value
   */
  const setStyle = (parent, selector, property, value) => {
    /** @type {HTMLElement | null} */
    const el = parent.querySelector(selector);
    if (el) {
      el.style.setProperty(property, value);
    }
  };

  /**
   * @param {HTMLElement} elem
   * @param {any} condition
   * @param {string} display
   */
  const toggle = (elem, condition, display = 'flex') => {
    if (condition) {
      show(elem, display);
    } else {
      hide(elem);
    }
  };

  /**
   * borrowed from jquery $(elem).is(':visible') implementation
   *
   * @param {HTMLElement | null} elem
   * @returns {boolean}
   */
  const isVisible$1 = elem => !!(elem && (elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length));

  /**
   * @returns {boolean}
   */
  const allButtonsAreHidden = () => !isVisible$1(getConfirmButton()) && !isVisible$1(getDenyButton()) && !isVisible$1(getCancelButton());

  /**
   * @param {HTMLElement} elem
   * @returns {boolean}
   */
  const isScrollable = elem => !!(elem.scrollHeight > elem.clientHeight);

  /**
   * @param {HTMLElement} element
   * @param {HTMLElement} stopElement
   * @returns {boolean}
   */
  const selfOrParentIsScrollable = (element, stopElement) => {
    let parent = element;
    while (parent && parent !== stopElement) {
      if (isScrollable(parent)) {
        return true;
      }
      parent = parent.parentElement;
    }
    return false;
  };

  /**
   * borrowed from https://stackoverflow.com/a/46352119
   *
   * @param {HTMLElement} elem
   * @returns {boolean}
   */
  const hasCssAnimation = elem => {
    const style = window.getComputedStyle(elem);
    const animDuration = parseFloat(style.getPropertyValue('animation-duration') || '0');
    const transDuration = parseFloat(style.getPropertyValue('transition-duration') || '0');
    return animDuration > 0 || transDuration > 0;
  };

  /**
   * @param {number} timer
   * @param {boolean} reset
   */
  const animateTimerProgressBar = (timer, reset = false) => {
    const timerProgressBar = getTimerProgressBar();
    if (!timerProgressBar) {
      return;
    }
    if (isVisible$1(timerProgressBar)) {
      if (reset) {
        timerProgressBar.style.transition = 'none';
        timerProgressBar.style.width = '100%';
      }
      setTimeout(() => {
        timerProgressBar.style.transition = `width ${timer / 1000}s linear`;
        timerProgressBar.style.width = '0%';
      }, 10);
    }
  };
  const stopTimerProgressBar = () => {
    const timerProgressBar = getTimerProgressBar();
    if (!timerProgressBar) {
      return;
    }
    const timerProgressBarWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
    timerProgressBar.style.removeProperty('transition');
    timerProgressBar.style.width = '100%';
    const timerProgressBarFullWidth = parseInt(window.getComputedStyle(timerProgressBar).width);
    const timerProgressBarPercent = timerProgressBarWidth / timerProgressBarFullWidth * 100;
    timerProgressBar.style.width = `${timerProgressBarPercent}%`;
  };

  /**
   * Detect Node env
   *
   * @returns {boolean}
   */
  const isNodeEnv = () => typeof window === 'undefined' || typeof document === 'undefined';
  const sweetHTML = `
 <div aria-labelledby="${swalClasses.title}" aria-describedby="${swalClasses['html-container']}" class="${swalClasses.popup}" tabindex="-1">
   <button type="button" class="${swalClasses.close}"></button>
   <ul class="${swalClasses['progress-steps']}"></ul>
   <div class="${swalClasses.icon}"></div>
   <img class="${swalClasses.image}" />
   <h2 class="${swalClasses.title}" id="${swalClasses.title}"></h2>
   <div class="${swalClasses['html-container']}" id="${swalClasses['html-container']}"></div>
   <input class="${swalClasses.input}" id="${swalClasses.input}" />
   <input type="file" class="${swalClasses.file}" />
   <div class="${swalClasses.range}">
     <input type="range" />
     <output></output>
   </div>
   <select class="${swalClasses.select}" id="${swalClasses.select}"></select>
   <div class="${swalClasses.radio}"></div>
   <label class="${swalClasses.checkbox}">
     <input type="checkbox" id="${swalClasses.checkbox}" />
     <span class="${swalClasses.label}"></span>
   </label>
   <textarea class="${swalClasses.textarea}" id="${swalClasses.textarea}"></textarea>
   <div class="${swalClasses['validation-message']}" id="${swalClasses['validation-message']}"></div>
   <div class="${swalClasses.actions}">
     <div class="${swalClasses.loader}"></div>
     <button type="button" class="${swalClasses.confirm}"></button>
     <button type="button" class="${swalClasses.deny}"></button>
     <button type="button" class="${swalClasses.cancel}"></button>
   </div>
   <div class="${swalClasses.footer}"></div>
   <div class="${swalClasses['timer-progress-bar-container']}">
     <div class="${swalClasses['timer-progress-bar']}"></div>
   </div>
 </div>
`.replace(/(^|\n)\s*/g, '');

  /**
   * @returns {boolean}
   */
  const resetOldContainer = () => {
    const oldContainer = getContainer();
    if (!oldContainer) {
      return false;
    }
    oldContainer.remove();
    removeClass([document.documentElement, document.body], [swalClasses['no-backdrop'], swalClasses['toast-shown'], swalClasses['has-column']]);
    return true;
  };
  const resetValidationMessage$1 = () => {
    globalState.currentInstance.resetValidationMessage();
  };
  const addInputChangeListeners = () => {
    const popup = getPopup();
    const input = getDirectChildByClass(popup, swalClasses.input);
    const file = getDirectChildByClass(popup, swalClasses.file);
    /** @type {HTMLInputElement} */
    const range = popup.querySelector(`.${swalClasses.range} input`);
    /** @type {HTMLOutputElement} */
    const rangeOutput = popup.querySelector(`.${swalClasses.range} output`);
    const select = getDirectChildByClass(popup, swalClasses.select);
    /** @type {HTMLInputElement} */
    const checkbox = popup.querySelector(`.${swalClasses.checkbox} input`);
    const textarea = getDirectChildByClass(popup, swalClasses.textarea);
    input.oninput = resetValidationMessage$1;
    file.onchange = resetValidationMessage$1;
    select.onchange = resetValidationMessage$1;
    checkbox.onchange = resetValidationMessage$1;
    textarea.oninput = resetValidationMessage$1;
    range.oninput = () => {
      resetValidationMessage$1();
      rangeOutput.value = range.value;
    };
    range.onchange = () => {
      resetValidationMessage$1();
      rangeOutput.value = range.value;
    };
  };

  /**
   * @param {string | HTMLElement} target
   * @returns {HTMLElement}
   */
  const getTarget = target => typeof target === 'string' ? document.querySelector(target) : target;

  /**
   * @param {SweetAlertOptions} params
   */
  const setupAccessibility = params => {
    const popup = getPopup();
    popup.setAttribute('role', params.toast ? 'alert' : 'dialog');
    popup.setAttribute('aria-live', params.toast ? 'polite' : 'assertive');
    if (!params.toast) {
      popup.setAttribute('aria-modal', 'true');
    }
  };

  /**
   * @param {HTMLElement} targetElement
   */
  const setupRTL = targetElement => {
    if (window.getComputedStyle(targetElement).direction === 'rtl') {
      addClass(getContainer(), swalClasses.rtl);
    }
  };

  /**
   * Add modal + backdrop to DOM
   *
   * @param {SweetAlertOptions} params
   */
  const init = params => {
    // Clean up the old popup container if it exists
    const oldContainerExisted = resetOldContainer();
    if (isNodeEnv()) {
      error('SweetAlert2 requires document to initialize');
      return;
    }
    const container = document.createElement('div');
    container.className = swalClasses.container;
    if (oldContainerExisted) {
      addClass(container, swalClasses['no-transition']);
    }
    setInnerHtml(container, sweetHTML);
    container.dataset['swal2Theme'] = params.theme;
    const targetElement = getTarget(params.target);
    targetElement.appendChild(container);
    if (params.topLayer) {
      container.setAttribute('popover', '');
      container.showPopover();
    }
    setupAccessibility(params);
    setupRTL(targetElement);
    addInputChangeListeners();
  };

  /**
   * @param {HTMLElement | object | string} param
   * @param {HTMLElement} target
   */
  const parseHtmlToContainer = (param, target) => {
    // DOM element
    if (param instanceof HTMLElement) {
      target.appendChild(param);
    }

    // Object
    else if (typeof param === 'object') {
      handleObject(param, target);
    }

    // Plain string
    else if (param) {
      setInnerHtml(target, param);
    }
  };

  /**
   * @param {any} param
   * @param {HTMLElement} target
   */
  const handleObject = (param, target) => {
    // JQuery element(s)
    if (param.jquery) {
      handleJqueryElem(target, param);
    }

    // For other objects use their string representation
    else {
      setInnerHtml(target, param.toString());
    }
  };

  /**
   * @param {HTMLElement} target
   * @param {any} elem
   */
  const handleJqueryElem = (target, elem) => {
    target.textContent = '';
    if (0 in elem) {
      for (let i = 0; i in elem; i++) {
        target.appendChild(elem[i].cloneNode(true));
      }
    } else {
      target.appendChild(elem.cloneNode(true));
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderActions = (instance, params) => {
    const actions = getActions();
    const loader = getLoader();
    if (!actions || !loader) {
      return;
    }

    // Actions (buttons) wrapper
    if (!params.showConfirmButton && !params.showDenyButton && !params.showCancelButton) {
      hide(actions);
    } else {
      show(actions);
    }

    // Custom class
    applyCustomClass(actions, params, 'actions');

    // Render all the buttons
    renderButtons(actions, loader, params);

    // Loader
    setInnerHtml(loader, params.loaderHtml || '');
    applyCustomClass(loader, params, 'loader');
  };

  /**
   * @param {HTMLElement} actions
   * @param {HTMLElement} loader
   * @param {SweetAlertOptions} params
   */
  function renderButtons(actions, loader, params) {
    const confirmButton = getConfirmButton();
    const denyButton = getDenyButton();
    const cancelButton = getCancelButton();
    if (!confirmButton || !denyButton || !cancelButton) {
      return;
    }

    // Render buttons
    renderButton(confirmButton, 'confirm', params);
    renderButton(denyButton, 'deny', params);
    renderButton(cancelButton, 'cancel', params);
    handleButtonsStyling(confirmButton, denyButton, cancelButton, params);
    if (params.reverseButtons) {
      if (params.toast) {
        actions.insertBefore(cancelButton, confirmButton);
        actions.insertBefore(denyButton, confirmButton);
      } else {
        actions.insertBefore(cancelButton, loader);
        actions.insertBefore(denyButton, loader);
        actions.insertBefore(confirmButton, loader);
      }
    }
  }

  /**
   * @param {HTMLElement} confirmButton
   * @param {HTMLElement} denyButton
   * @param {HTMLElement} cancelButton
   * @param {SweetAlertOptions} params
   */
  function handleButtonsStyling(confirmButton, denyButton, cancelButton, params) {
    if (!params.buttonsStyling) {
      removeClass([confirmButton, denyButton, cancelButton], swalClasses.styled);
      return;
    }
    addClass([confirmButton, denyButton, cancelButton], swalClasses.styled);

    // Apply custom background colors to action buttons
    if (params.confirmButtonColor) {
      confirmButton.style.setProperty('--swal2-confirm-button-background-color', params.confirmButtonColor);
    }
    if (params.denyButtonColor) {
      denyButton.style.setProperty('--swal2-deny-button-background-color', params.denyButtonColor);
    }
    if (params.cancelButtonColor) {
      cancelButton.style.setProperty('--swal2-cancel-button-background-color', params.cancelButtonColor);
    }

    // Apply the outline color to action buttons
    applyOutlineColor(confirmButton);
    applyOutlineColor(denyButton);
    applyOutlineColor(cancelButton);
  }

  /**
   * @param {HTMLElement} button
   */
  function applyOutlineColor(button) {
    const buttonStyle = window.getComputedStyle(button);
    if (buttonStyle.getPropertyValue('--swal2-action-button-focus-box-shadow')) {
      // If the button already has a custom outline color, no need to change it
      return;
    }
    const outlineColor = buttonStyle.backgroundColor.replace(/rgba?\((\d+), (\d+), (\d+).*/, 'rgba($1, $2, $3, 0.5)');
    button.style.setProperty('--swal2-action-button-focus-box-shadow', buttonStyle.getPropertyValue('--swal2-outline').replace(/ rgba\(.*/, ` ${outlineColor}`));
  }

  /**
   * @param {HTMLElement} button
   * @param {'confirm' | 'deny' | 'cancel'} buttonType
   * @param {SweetAlertOptions} params
   */
  function renderButton(button, buttonType, params) {
    const buttonName = /** @type {'Confirm' | 'Deny' | 'Cancel'} */capitalizeFirstLetter(buttonType);
    toggle(button, params[`show${buttonName}Button`], 'inline-block');
    setInnerHtml(button, params[`${buttonType}ButtonText`] || ''); // Set caption text
    button.setAttribute('aria-label', params[`${buttonType}ButtonAriaLabel`] || ''); // ARIA label

    // Add buttons custom classes
    button.className = swalClasses[buttonType];
    applyCustomClass(button, params, `${buttonType}Button`);
  }

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderCloseButton = (instance, params) => {
    const closeButton = getCloseButton();
    if (!closeButton) {
      return;
    }
    setInnerHtml(closeButton, params.closeButtonHtml || '');

    // Custom class
    applyCustomClass(closeButton, params, 'closeButton');
    toggle(closeButton, params.showCloseButton);
    closeButton.setAttribute('aria-label', params.closeButtonAriaLabel || '');
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderContainer = (instance, params) => {
    const container = getContainer();
    if (!container) {
      return;
    }
    handleBackdropParam(container, params.backdrop);
    handlePositionParam(container, params.position);
    handleGrowParam(container, params.grow);

    // Custom class
    applyCustomClass(container, params, 'container');
  };

  /**
   * @param {HTMLElement} container
   * @param {SweetAlertOptions['backdrop']} backdrop
   */
  function handleBackdropParam(container, backdrop) {
    if (typeof backdrop === 'string') {
      container.style.background = backdrop;
    } else if (!backdrop) {
      addClass([document.documentElement, document.body], swalClasses['no-backdrop']);
    }
  }

  /**
   * @param {HTMLElement} container
   * @param {SweetAlertOptions['position']} position
   */
  function handlePositionParam(container, position) {
    if (!position) {
      return;
    }
    if (position in swalClasses) {
      addClass(container, swalClasses[position]);
    } else {
      warn('The "position" parameter is not valid, defaulting to "center"');
      addClass(container, swalClasses.center);
    }
  }

  /**
   * @param {HTMLElement} container
   * @param {SweetAlertOptions['grow']} grow
   */
  function handleGrowParam(container, grow) {
    if (!grow) {
      return;
    }
    addClass(container, swalClasses[`grow-${grow}`]);
  }

  /**
   * This module contains `WeakMap`s for each effectively-"private  property" that a `Swal` has.
   * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
   * This is the approach that Babel will probably take to implement private methods/fields
   *   https://github.com/tc39/proposal-private-methods
   *   https://github.com/babel/babel/pull/7555
   * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
   *   then we can use that language feature.
   */

  var privateProps = {
    innerParams: new WeakMap(),
    domCache: new WeakMap()
  };

  /// <reference path="../../../../sweetalert2.d.ts"/>

  /** @type {InputClass[]} */
  const inputClasses = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea'];

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderInput = (instance, params) => {
    const popup = getPopup();
    if (!popup) {
      return;
    }
    const innerParams = privateProps.innerParams.get(instance);
    const rerender = !innerParams || params.input !== innerParams.input;
    inputClasses.forEach(inputClass => {
      const inputContainer = getDirectChildByClass(popup, swalClasses[inputClass]);
      if (!inputContainer) {
        return;
      }

      // set attributes
      setAttributes(inputClass, params.inputAttributes);

      // set class
      inputContainer.className = swalClasses[inputClass];
      if (rerender) {
        hide(inputContainer);
      }
    });
    if (params.input) {
      if (rerender) {
        showInput(params);
      }
      // set custom class
      setCustomClass(params);
    }
  };

  /**
   * @param {SweetAlertOptions} params
   */
  const showInput = params => {
    if (!params.input) {
      return;
    }
    if (!renderInputType[params.input]) {
      error(`Unexpected type of input! Expected ${Object.keys(renderInputType).join(' | ')}, got "${params.input}"`);
      return;
    }
    const inputContainer = getInputContainer(params.input);
    if (!inputContainer) {
      return;
    }
    const input = renderInputType[params.input](inputContainer, params);
    show(inputContainer);

    // input autofocus
    if (params.inputAutoFocus) {
      setTimeout(() => {
        focusInput(input);
      });
    }
  };

  /**
   * @param {HTMLInputElement} input
   */
  const removeAttributes = input => {
    for (let i = 0; i < input.attributes.length; i++) {
      const attrName = input.attributes[i].name;
      if (!['id', 'type', 'value', 'style'].includes(attrName)) {
        input.removeAttribute(attrName);
      }
    }
  };

  /**
   * @param {InputClass} inputClass
   * @param {SweetAlertOptions['inputAttributes']} inputAttributes
   */
  const setAttributes = (inputClass, inputAttributes) => {
    const popup = getPopup();
    if (!popup) {
      return;
    }
    const input = getInput$1(popup, inputClass);
    if (!input) {
      return;
    }
    removeAttributes(input);
    for (const attr in inputAttributes) {
      input.setAttribute(attr, inputAttributes[attr]);
    }
  };

  /**
   * @param {SweetAlertOptions} params
   */
  const setCustomClass = params => {
    if (!params.input) {
      return;
    }
    const inputContainer = getInputContainer(params.input);
    if (inputContainer) {
      applyCustomClass(inputContainer, params, 'input');
    }
  };

  /**
   * @param {HTMLInputElement | HTMLTextAreaElement} input
   * @param {SweetAlertOptions} params
   */
  const setInputPlaceholder = (input, params) => {
    if (!input.placeholder && params.inputPlaceholder) {
      input.placeholder = params.inputPlaceholder;
    }
  };

  /**
   * @param {Input} input
   * @param {Input} prependTo
   * @param {SweetAlertOptions} params
   */
  const setInputLabel = (input, prependTo, params) => {
    if (params.inputLabel) {
      const label = document.createElement('label');
      const labelClass = swalClasses['input-label'];
      label.setAttribute('for', input.id);
      label.className = labelClass;
      if (typeof params.customClass === 'object') {
        addClass(label, params.customClass.inputLabel);
      }
      label.innerText = params.inputLabel;
      prependTo.insertAdjacentElement('beforebegin', label);
    }
  };

  /**
   * @param {SweetAlertInput} inputType
   * @returns {HTMLElement | undefined}
   */
  const getInputContainer = inputType => {
    const popup = getPopup();
    if (!popup) {
      return;
    }
    return getDirectChildByClass(popup, swalClasses[(/** @type {SwalClass} */inputType)] || swalClasses.input);
  };

  /**
   * @param {HTMLInputElement | HTMLOutputElement | HTMLTextAreaElement} input
   * @param {SweetAlertOptions['inputValue']} inputValue
   */
  const checkAndSetInputValue = (input, inputValue) => {
    if (['string', 'number'].includes(typeof inputValue)) {
      input.value = `${inputValue}`;
    } else if (!isPromise(inputValue)) {
      warn(`Unexpected type of inputValue! Expected "string", "number" or "Promise", got "${typeof inputValue}"`);
    }
  };

  /** @type {Record<SweetAlertInput, (input: Input | HTMLElement, params: SweetAlertOptions) => Input>} */
  const renderInputType = {};

  /**
   * @param {HTMLInputElement} input
   * @param {SweetAlertOptions} params
   * @returns {HTMLInputElement}
   */
  renderInputType.text = renderInputType.email = renderInputType.password = renderInputType.number = renderInputType.tel = renderInputType.url = renderInputType.search = renderInputType.date = renderInputType['datetime-local'] = renderInputType.time = renderInputType.week = renderInputType.month = /** @type {(input: Input | HTMLElement, params: SweetAlertOptions) => Input} */
  (input, params) => {
    checkAndSetInputValue(input, params.inputValue);
    setInputLabel(input, input, params);
    setInputPlaceholder(input, params);
    input.type = params.input;
    return input;
  };

  /**
   * @param {HTMLInputElement} input
   * @param {SweetAlertOptions} params
   * @returns {HTMLInputElement}
   */
  renderInputType.file = (input, params) => {
    setInputLabel(input, input, params);
    setInputPlaceholder(input, params);
    return input;
  };

  /**
   * @param {HTMLInputElement} range
   * @param {SweetAlertOptions} params
   * @returns {HTMLInputElement}
   */
  renderInputType.range = (range, params) => {
    const rangeInput = range.querySelector('input');
    const rangeOutput = range.querySelector('output');
    checkAndSetInputValue(rangeInput, params.inputValue);
    rangeInput.type = params.input;
    checkAndSetInputValue(rangeOutput, params.inputValue);
    setInputLabel(rangeInput, range, params);
    return range;
  };

  /**
   * @param {HTMLSelectElement} select
   * @param {SweetAlertOptions} params
   * @returns {HTMLSelectElement}
   */
  renderInputType.select = (select, params) => {
    select.textContent = '';
    if (params.inputPlaceholder) {
      const placeholder = document.createElement('option');
      setInnerHtml(placeholder, params.inputPlaceholder);
      placeholder.value = '';
      placeholder.disabled = true;
      placeholder.selected = true;
      select.appendChild(placeholder);
    }
    setInputLabel(select, select, params);
    return select;
  };

  /**
   * @param {HTMLInputElement} radio
   * @returns {HTMLInputElement}
   */
  renderInputType.radio = radio => {
    radio.textContent = '';
    return radio;
  };

  /**
   * @param {HTMLLabelElement} checkboxContainer
   * @param {SweetAlertOptions} params
   * @returns {HTMLInputElement}
   */
  renderInputType.checkbox = (checkboxContainer, params) => {
    const checkbox = getInput$1(getPopup(), 'checkbox');
    checkbox.value = '1';
    checkbox.checked = Boolean(params.inputValue);
    const label = checkboxContainer.querySelector('span');
    setInnerHtml(label, params.inputPlaceholder || params.inputLabel);
    return checkbox;
  };

  /**
   * @param {HTMLTextAreaElement} textarea
   * @param {SweetAlertOptions} params
   * @returns {HTMLTextAreaElement}
   */
  renderInputType.textarea = (textarea, params) => {
    checkAndSetInputValue(textarea, params.inputValue);
    setInputPlaceholder(textarea, params);
    setInputLabel(textarea, textarea, params);

    /**
     * @param {HTMLElement} el
     * @returns {number}
     */
    const getMargin = el => parseInt(window.getComputedStyle(el).marginLeft) + parseInt(window.getComputedStyle(el).marginRight);

    // https://github.com/sweetalert2/sweetalert2/issues/2291
    setTimeout(() => {
      // https://github.com/sweetalert2/sweetalert2/issues/1699
      if ('MutationObserver' in window) {
        const initialPopupWidth = parseInt(window.getComputedStyle(getPopup()).width);
        const textareaResizeHandler = () => {
          // check if texarea is still in document (i.e. popup wasn't closed in the meantime)
          if (!document.body.contains(textarea)) {
            return;
          }
          const textareaWidth = textarea.offsetWidth + getMargin(textarea);
          if (textareaWidth > initialPopupWidth) {
            getPopup().style.width = `${textareaWidth}px`;
          } else {
            applyNumericalStyle(getPopup(), 'width', params.width);
          }
        };
        new MutationObserver(textareaResizeHandler).observe(textarea, {
          attributes: true,
          attributeFilter: ['style']
        });
      }
    });
    return textarea;
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderContent = (instance, params) => {
    const htmlContainer = getHtmlContainer();
    if (!htmlContainer) {
      return;
    }
    showWhenInnerHtmlPresent(htmlContainer);
    applyCustomClass(htmlContainer, params, 'htmlContainer');

    // Content as HTML
    if (params.html) {
      parseHtmlToContainer(params.html, htmlContainer);
      show(htmlContainer, 'block');
    }

    // Content as plain text
    else if (params.text) {
      htmlContainer.textContent = params.text;
      show(htmlContainer, 'block');
    }

    // No content
    else {
      hide(htmlContainer);
    }
    renderInput(instance, params);
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderFooter = (instance, params) => {
    const footer = getFooter();
    if (!footer) {
      return;
    }
    showWhenInnerHtmlPresent(footer);
    toggle(footer, params.footer, 'block');
    if (params.footer) {
      parseHtmlToContainer(params.footer, footer);
    }

    // Custom class
    applyCustomClass(footer, params, 'footer');
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderIcon = (instance, params) => {
    const innerParams = privateProps.innerParams.get(instance);
    const icon = getIcon();
    if (!icon) {
      return;
    }

    // if the given icon already rendered, apply the styling without re-rendering the icon
    if (innerParams && params.icon === innerParams.icon) {
      // Custom or default content
      setContent(icon, params);
      applyStyles(icon, params);
      return;
    }
    if (!params.icon && !params.iconHtml) {
      hide(icon);
      return;
    }
    if (params.icon && Object.keys(iconTypes).indexOf(params.icon) === -1) {
      error(`Unknown icon! Expected "success", "error", "warning", "info" or "question", got "${params.icon}"`);
      hide(icon);
      return;
    }
    show(icon);

    // Custom or default content
    setContent(icon, params);
    applyStyles(icon, params);

    // Animate icon
    addClass(icon, params.showClass && params.showClass.icon);

    // Re-adjust the success icon on system theme change
    const colorSchemeQueryList = window.matchMedia('(prefers-color-scheme: dark)');
    colorSchemeQueryList.addEventListener('change', adjustSuccessIconBackgroundColor);
  };

  /**
   * @param {HTMLElement} icon
   * @param {SweetAlertOptions} params
   */
  const applyStyles = (icon, params) => {
    for (const [iconType, iconClassName] of Object.entries(iconTypes)) {
      if (params.icon !== iconType) {
        removeClass(icon, iconClassName);
      }
    }
    addClass(icon, params.icon && iconTypes[params.icon]);

    // Icon color
    setColor(icon, params);

    // Success icon background color
    adjustSuccessIconBackgroundColor();

    // Custom class
    applyCustomClass(icon, params, 'icon');
  };

  // Adjust success icon background color to match the popup background color
  const adjustSuccessIconBackgroundColor = () => {
    const popup = getPopup();
    if (!popup) {
      return;
    }
    const popupBackgroundColor = window.getComputedStyle(popup).getPropertyValue('background-color');
    /** @type {NodeListOf<HTMLElement>} */
    const successIconParts = popup.querySelectorAll('[class^=swal2-success-circular-line], .swal2-success-fix');
    for (let i = 0; i < successIconParts.length; i++) {
      successIconParts[i].style.backgroundColor = popupBackgroundColor;
    }
  };

  /**
   *
   * @param {SweetAlertOptions} params
   * @returns {string}
   */
  const successIconHtml = params => `
  ${params.animation ? '<div class="swal2-success-circular-line-left"></div>' : ''}
  <span class="swal2-success-line-tip"></span> <span class="swal2-success-line-long"></span>
  <div class="swal2-success-ring"></div>
  ${params.animation ? '<div class="swal2-success-fix"></div>' : ''}
  ${params.animation ? '<div class="swal2-success-circular-line-right"></div>' : ''}
`;
  const errorIconHtml = `
  <span class="swal2-x-mark">
    <span class="swal2-x-mark-line-left"></span>
    <span class="swal2-x-mark-line-right"></span>
  </span>
`;

  /**
   * @param {HTMLElement} icon
   * @param {SweetAlertOptions} params
   */
  const setContent = (icon, params) => {
    if (!params.icon && !params.iconHtml) {
      return;
    }
    let oldContent = icon.innerHTML;
    let newContent = '';
    if (params.iconHtml) {
      newContent = iconContent(params.iconHtml);
    } else if (params.icon === 'success') {
      newContent = successIconHtml(params);
      oldContent = oldContent.replace(/ style=".*?"/g, ''); // undo adjustSuccessIconBackgroundColor()
    } else if (params.icon === 'error') {
      newContent = errorIconHtml;
    } else if (params.icon) {
      const defaultIconHtml = {
        question: '?',
        warning: '!',
        info: 'i'
      };
      newContent = iconContent(defaultIconHtml[params.icon]);
    }
    if (oldContent.trim() !== newContent.trim()) {
      setInnerHtml(icon, newContent);
    }
  };

  /**
   * @param {HTMLElement} icon
   * @param {SweetAlertOptions} params
   */
  const setColor = (icon, params) => {
    if (!params.iconColor) {
      return;
    }
    icon.style.color = params.iconColor;
    icon.style.borderColor = params.iconColor;
    for (const sel of ['.swal2-success-line-tip', '.swal2-success-line-long', '.swal2-x-mark-line-left', '.swal2-x-mark-line-right']) {
      setStyle(icon, sel, 'background-color', params.iconColor);
    }
    setStyle(icon, '.swal2-success-ring', 'border-color', params.iconColor);
  };

  /**
   * @param {string} content
   * @returns {string}
   */
  const iconContent = content => `<div class="${swalClasses['icon-content']}">${content}</div>`;

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderImage = (instance, params) => {
    const image = getImage();
    if (!image) {
      return;
    }
    if (!params.imageUrl) {
      hide(image);
      return;
    }
    show(image, '');

    // Src, alt
    image.setAttribute('src', params.imageUrl);
    image.setAttribute('alt', params.imageAlt || '');

    // Width, height
    applyNumericalStyle(image, 'width', params.imageWidth);
    applyNumericalStyle(image, 'height', params.imageHeight);

    // Class
    image.className = swalClasses.image;
    applyCustomClass(image, params, 'image');
  };
  let dragging = false;
  let mousedownX = 0;
  let mousedownY = 0;
  let initialX = 0;
  let initialY = 0;

  /**
   * @param {HTMLElement} popup
   */
  const addDraggableListeners = popup => {
    popup.addEventListener('mousedown', down);
    document.body.addEventListener('mousemove', move);
    popup.addEventListener('mouseup', up);
    popup.addEventListener('touchstart', down);
    document.body.addEventListener('touchmove', move);
    popup.addEventListener('touchend', up);
  };

  /**
   * @param {HTMLElement} popup
   */
  const removeDraggableListeners = popup => {
    popup.removeEventListener('mousedown', down);
    document.body.removeEventListener('mousemove', move);
    popup.removeEventListener('mouseup', up);
    popup.removeEventListener('touchstart', down);
    document.body.removeEventListener('touchmove', move);
    popup.removeEventListener('touchend', up);
  };

  /**
   * @param {MouseEvent | TouchEvent} event
   */
  const down = event => {
    const popup = getPopup();
    if (event.target === popup || getIcon().contains(/** @type {HTMLElement} */event.target)) {
      dragging = true;
      const clientXY = getClientXY(event);
      mousedownX = clientXY.clientX;
      mousedownY = clientXY.clientY;
      initialX = parseInt(popup.style.insetInlineStart) || 0;
      initialY = parseInt(popup.style.insetBlockStart) || 0;
      addClass(popup, 'swal2-dragging');
    }
  };

  /**
   * @param {MouseEvent | TouchEvent} event
   */
  const move = event => {
    const popup = getPopup();
    if (dragging) {
      let {
        clientX,
        clientY
      } = getClientXY(event);
      popup.style.insetInlineStart = `${initialX + (clientX - mousedownX)}px`;
      popup.style.insetBlockStart = `${initialY + (clientY - mousedownY)}px`;
    }
  };
  const up = () => {
    const popup = getPopup();
    dragging = false;
    removeClass(popup, 'swal2-dragging');
  };

  /**
   * @param {MouseEvent | TouchEvent} event
   * @returns {{ clientX: number, clientY: number }}
   */
  const getClientXY = event => {
    let clientX = 0,
      clientY = 0;
    if (event.type.startsWith('mouse')) {
      clientX = /** @type {MouseEvent} */event.clientX;
      clientY = /** @type {MouseEvent} */event.clientY;
    } else if (event.type.startsWith('touch')) {
      clientX = /** @type {TouchEvent} */event.touches[0].clientX;
      clientY = /** @type {TouchEvent} */event.touches[0].clientY;
    }
    return {
      clientX,
      clientY
    };
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderPopup = (instance, params) => {
    const container = getContainer();
    const popup = getPopup();
    if (!container || !popup) {
      return;
    }

    // Width
    // https://github.com/sweetalert2/sweetalert2/issues/2170
    if (params.toast) {
      applyNumericalStyle(container, 'width', params.width);
      popup.style.width = '100%';
      const loader = getLoader();
      if (loader) {
        popup.insertBefore(loader, getIcon());
      }
    } else {
      applyNumericalStyle(popup, 'width', params.width);
    }

    // Padding
    applyNumericalStyle(popup, 'padding', params.padding);

    // Color
    if (params.color) {
      popup.style.color = params.color;
    }

    // Background
    if (params.background) {
      popup.style.background = params.background;
    }
    hide(getValidationMessage());

    // Classes
    addClasses$1(popup, params);
    if (params.draggable && !params.toast) {
      addClass(popup, swalClasses.draggable);
      addDraggableListeners(popup);
    } else {
      removeClass(popup, swalClasses.draggable);
      removeDraggableListeners(popup);
    }
  };

  /**
   * @param {HTMLElement} popup
   * @param {SweetAlertOptions} params
   */
  const addClasses$1 = (popup, params) => {
    const showClass = params.showClass || {};
    // Default Class + showClass when updating Swal.update({})
    popup.className = `${swalClasses.popup} ${isVisible$1(popup) ? showClass.popup : ''}`;
    if (params.toast) {
      addClass([document.documentElement, document.body], swalClasses['toast-shown']);
      addClass(popup, swalClasses.toast);
    } else {
      addClass(popup, swalClasses.modal);
    }

    // Custom class
    applyCustomClass(popup, params, 'popup');
    // TODO: remove in the next major
    if (typeof params.customClass === 'string') {
      addClass(popup, params.customClass);
    }

    // Icon class (#1842)
    if (params.icon) {
      addClass(popup, swalClasses[`icon-${params.icon}`]);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderProgressSteps = (instance, params) => {
    const progressStepsContainer = getProgressSteps();
    if (!progressStepsContainer) {
      return;
    }
    const {
      progressSteps,
      currentProgressStep
    } = params;
    if (!progressSteps || progressSteps.length === 0 || currentProgressStep === undefined) {
      hide(progressStepsContainer);
      return;
    }
    show(progressStepsContainer);
    progressStepsContainer.textContent = '';
    if (currentProgressStep >= progressSteps.length) {
      warn('Invalid currentProgressStep parameter, it should be less than progressSteps.length ' + '(currentProgressStep like JS arrays starts from 0)');
    }
    progressSteps.forEach((step, index) => {
      const stepEl = createStepElement(step);
      progressStepsContainer.appendChild(stepEl);
      if (index === currentProgressStep) {
        addClass(stepEl, swalClasses['active-progress-step']);
      }
      if (index !== progressSteps.length - 1) {
        const lineEl = createLineElement(params);
        progressStepsContainer.appendChild(lineEl);
      }
    });
  };

  /**
   * @param {string} step
   * @returns {HTMLLIElement}
   */
  const createStepElement = step => {
    const stepEl = document.createElement('li');
    addClass(stepEl, swalClasses['progress-step']);
    setInnerHtml(stepEl, step);
    return stepEl;
  };

  /**
   * @param {SweetAlertOptions} params
   * @returns {HTMLLIElement}
   */
  const createLineElement = params => {
    const lineEl = document.createElement('li');
    addClass(lineEl, swalClasses['progress-step-line']);
    if (params.progressStepsDistance) {
      applyNumericalStyle(lineEl, 'width', params.progressStepsDistance);
    }
    return lineEl;
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const renderTitle = (instance, params) => {
    const title = getTitle();
    if (!title) {
      return;
    }
    showWhenInnerHtmlPresent(title);
    toggle(title, params.title || params.titleText, 'block');
    if (params.title) {
      parseHtmlToContainer(params.title, title);
    }
    if (params.titleText) {
      title.innerText = params.titleText;
    }

    // Custom class
    applyCustomClass(title, params, 'title');
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const render = (instance, params) => {
    renderPopup(instance, params);
    renderContainer(instance, params);
    renderProgressSteps(instance, params);
    renderIcon(instance, params);
    renderImage(instance, params);
    renderTitle(instance, params);
    renderCloseButton(instance, params);
    renderContent(instance, params);
    renderActions(instance, params);
    renderFooter(instance, params);
    const popup = getPopup();
    if (typeof params.didRender === 'function' && popup) {
      params.didRender(popup);
    }
    globalState.eventEmitter.emit('didRender', popup);
  };

  /*
   * Global function to determine if SweetAlert2 popup is shown
   */
  const isVisible = () => {
    return isVisible$1(getPopup());
  };

  /*
   * Global function to click 'Confirm' button
   */
  const clickConfirm = () => {
    var _dom$getConfirmButton;
    return (_dom$getConfirmButton = getConfirmButton()) === null || _dom$getConfirmButton === void 0 ? void 0 : _dom$getConfirmButton.click();
  };

  /*
   * Global function to click 'Deny' button
   */
  const clickDeny = () => {
    var _dom$getDenyButton;
    return (_dom$getDenyButton = getDenyButton()) === null || _dom$getDenyButton === void 0 ? void 0 : _dom$getDenyButton.click();
  };

  /*
   * Global function to click 'Cancel' button
   */
  const clickCancel = () => {
    var _dom$getCancelButton;
    return (_dom$getCancelButton = getCancelButton()) === null || _dom$getCancelButton === void 0 ? void 0 : _dom$getCancelButton.click();
  };

  /** @typedef {'cancel' | 'backdrop' | 'close' | 'esc' | 'timer'} DismissReason */

  /** @type {Record<DismissReason, DismissReason>} */
  const DismissReason = Object.freeze({
    cancel: 'cancel',
    backdrop: 'backdrop',
    close: 'close',
    esc: 'esc',
    timer: 'timer'
  });

  /**
   * @param {GlobalState} globalState
   */
  const removeKeydownHandler = globalState => {
    if (globalState.keydownTarget && globalState.keydownHandlerAdded) {
      globalState.keydownTarget.removeEventListener('keydown', globalState.keydownHandler, {
        capture: globalState.keydownListenerCapture
      });
      globalState.keydownHandlerAdded = false;
    }
  };

  /**
   * @param {GlobalState} globalState
   * @param {SweetAlertOptions} innerParams
   * @param {*} dismissWith
   */
  const addKeydownHandler = (globalState, innerParams, dismissWith) => {
    removeKeydownHandler(globalState);
    if (!innerParams.toast) {
      globalState.keydownHandler = e => keydownHandler(innerParams, e, dismissWith);
      globalState.keydownTarget = innerParams.keydownListenerCapture ? window : getPopup();
      globalState.keydownListenerCapture = innerParams.keydownListenerCapture;
      globalState.keydownTarget.addEventListener('keydown', globalState.keydownHandler, {
        capture: globalState.keydownListenerCapture
      });
      globalState.keydownHandlerAdded = true;
    }
  };

  /**
   * @param {number} index
   * @param {number} increment
   */
  const setFocus = (index, increment) => {
    var _dom$getPopup;
    const focusableElements = getFocusableElements();
    // search for visible elements and select the next possible match
    if (focusableElements.length) {
      index = index + increment;

      // shift + tab when .swal2-popup is focused
      if (index === -2) {
        index = focusableElements.length - 1;
      }

      // rollover to first item
      if (index === focusableElements.length) {
        index = 0;

        // go to last item
      } else if (index === -1) {
        index = focusableElements.length - 1;
      }
      focusableElements[index].focus();
      return;
    }
    // no visible focusable elements, focus the popup
    (_dom$getPopup = getPopup()) === null || _dom$getPopup === void 0 || _dom$getPopup.focus();
  };
  const arrowKeysNextButton = ['ArrowRight', 'ArrowDown'];
  const arrowKeysPreviousButton = ['ArrowLeft', 'ArrowUp'];

  /**
   * @param {SweetAlertOptions} innerParams
   * @param {KeyboardEvent} event
   * @param {Function} dismissWith
   */
  const keydownHandler = (innerParams, event, dismissWith) => {
    if (!innerParams) {
      return; // This instance has already been destroyed
    }

    // Ignore keydown during IME composition
    // https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event#ignoring_keydown_during_ime_composition
    // https://github.com/sweetalert2/sweetalert2/issues/720
    // https://github.com/sweetalert2/sweetalert2/issues/2406
    if (event.isComposing || event.keyCode === 229) {
      return;
    }
    if (innerParams.stopKeydownPropagation) {
      event.stopPropagation();
    }

    // ENTER
    if (event.key === 'Enter') {
      handleEnter(event, innerParams);
    }

    // TAB
    else if (event.key === 'Tab') {
      handleTab(event);
    }

    // ARROWS - switch focus between buttons
    else if ([...arrowKeysNextButton, ...arrowKeysPreviousButton].includes(event.key)) {
      handleArrows(event.key);
    }

    // ESC
    else if (event.key === 'Escape') {
      handleEsc(event, innerParams, dismissWith);
    }
  };

  /**
   * @param {KeyboardEvent} event
   * @param {SweetAlertOptions} innerParams
   */
  const handleEnter = (event, innerParams) => {
    // https://github.com/sweetalert2/sweetalert2/issues/2386
    if (!callIfFunction(innerParams.allowEnterKey)) {
      return;
    }
    const input = getInput$1(getPopup(), innerParams.input);
    if (event.target && input && event.target instanceof HTMLElement && event.target.outerHTML === input.outerHTML) {
      if (['textarea', 'file'].includes(innerParams.input)) {
        return; // do not submit
      }
      clickConfirm();
      event.preventDefault();
    }
  };

  /**
   * @param {KeyboardEvent} event
   */
  const handleTab = event => {
    const targetElement = event.target;
    const focusableElements = getFocusableElements();
    let btnIndex = -1;
    for (let i = 0; i < focusableElements.length; i++) {
      if (targetElement === focusableElements[i]) {
        btnIndex = i;
        break;
      }
    }

    // Cycle to the next button
    if (!event.shiftKey) {
      setFocus(btnIndex, 1);
    }

    // Cycle to the prev button
    else {
      setFocus(btnIndex, -1);
    }
    event.stopPropagation();
    event.preventDefault();
  };

  /**
   * @param {string} key
   */
  const handleArrows = key => {
    const actions = getActions();
    const confirmButton = getConfirmButton();
    const denyButton = getDenyButton();
    const cancelButton = getCancelButton();
    if (!actions || !confirmButton || !denyButton || !cancelButton) {
      return;
    }
    /** @type HTMLElement[] */
    const buttons = [confirmButton, denyButton, cancelButton];
    if (document.activeElement instanceof HTMLElement && !buttons.includes(document.activeElement)) {
      return;
    }
    const sibling = arrowKeysNextButton.includes(key) ? 'nextElementSibling' : 'previousElementSibling';
    let buttonToFocus = document.activeElement;
    if (!buttonToFocus) {
      return;
    }
    for (let i = 0; i < actions.children.length; i++) {
      buttonToFocus = buttonToFocus[sibling];
      if (!buttonToFocus) {
        return;
      }
      if (buttonToFocus instanceof HTMLButtonElement && isVisible$1(buttonToFocus)) {
        break;
      }
    }
    if (buttonToFocus instanceof HTMLButtonElement) {
      buttonToFocus.focus();
    }
  };

  /**
   * @param {KeyboardEvent} event
   * @param {SweetAlertOptions} innerParams
   * @param {Function} dismissWith
   */
  const handleEsc = (event, innerParams, dismissWith) => {
    event.preventDefault();
    if (callIfFunction(innerParams.allowEscapeKey)) {
      dismissWith(DismissReason.esc);
    }
  };

  /**
   * This module contains `WeakMap`s for each effectively-"private  property" that a `Swal` has.
   * For example, to set the private property "foo" of `this` to "bar", you can `privateProps.foo.set(this, 'bar')`
   * This is the approach that Babel will probably take to implement private methods/fields
   *   https://github.com/tc39/proposal-private-methods
   *   https://github.com/babel/babel/pull/7555
   * Once we have the changes from that PR in Babel, and our core class fits reasonable in *one module*
   *   then we can use that language feature.
   */

  var privateMethods = {
    swalPromiseResolve: new WeakMap(),
    swalPromiseReject: new WeakMap()
  };

  // From https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/
  // Adding aria-hidden="true" to elements outside of the active modal dialog ensures that
  // elements not within the active modal dialog will not be surfaced if a user opens a screen
  // reader’s list of elements (headings, form controls, landmarks, etc.) in the document.

  const setAriaHidden = () => {
    const container = getContainer();
    const bodyChildren = Array.from(document.body.children);
    bodyChildren.forEach(el => {
      if (el.contains(container)) {
        return;
      }
      if (el.hasAttribute('aria-hidden')) {
        el.setAttribute('data-previous-aria-hidden', el.getAttribute('aria-hidden') || '');
      }
      el.setAttribute('aria-hidden', 'true');
    });
  };
  const unsetAriaHidden = () => {
    const bodyChildren = Array.from(document.body.children);
    bodyChildren.forEach(el => {
      if (el.hasAttribute('data-previous-aria-hidden')) {
        el.setAttribute('aria-hidden', el.getAttribute('data-previous-aria-hidden') || '');
        el.removeAttribute('data-previous-aria-hidden');
      } else {
        el.removeAttribute('aria-hidden');
      }
    });
  };

  // @ts-ignore
  const isSafariOrIOS = typeof window !== 'undefined' && !!window.GestureEvent; // true for Safari desktop + all iOS browsers https://stackoverflow.com/a/70585394

  /**
   * Fix iOS scrolling
   * http://stackoverflow.com/q/39626302
   */
  const iOSfix = () => {
    if (isSafariOrIOS && !hasClass(document.body, swalClasses.iosfix)) {
      const offset = document.body.scrollTop;
      document.body.style.top = `${offset * -1}px`;
      addClass(document.body, swalClasses.iosfix);
      lockBodyScroll();
    }
  };

  /**
   * https://github.com/sweetalert2/sweetalert2/issues/1246
   */
  const lockBodyScroll = () => {
    const container = getContainer();
    if (!container) {
      return;
    }
    /** @type {boolean} */
    let preventTouchMove;
    /**
     * @param {TouchEvent} event
     */
    container.ontouchstart = event => {
      preventTouchMove = shouldPreventTouchMove(event);
    };
    /**
     * @param {TouchEvent} event
     */
    container.ontouchmove = event => {
      if (preventTouchMove) {
        event.preventDefault();
        event.stopPropagation();
      }
    };
  };

  /**
   * @param {TouchEvent} event
   * @returns {boolean}
   */
  const shouldPreventTouchMove = event => {
    const target = event.target;
    const container = getContainer();
    const htmlContainer = getHtmlContainer();
    if (!container || !htmlContainer) {
      return false;
    }
    if (isStylus(event) || isZoom(event)) {
      return false;
    }
    if (target === container) {
      return true;
    }
    if (!isScrollable(container) && target instanceof HTMLElement && !selfOrParentIsScrollable(target, htmlContainer) &&
    // #2823
    target.tagName !== 'INPUT' &&
    // #1603
    target.tagName !== 'TEXTAREA' &&
    // #2266
    !(isScrollable(htmlContainer) &&
    // #1944
    htmlContainer.contains(target))) {
      return true;
    }
    return false;
  };

  /**
   * https://github.com/sweetalert2/sweetalert2/issues/1786
   *
   * @param {*} event
   * @returns {boolean}
   */
  const isStylus = event => {
    return event.touches && event.touches.length && event.touches[0].touchType === 'stylus';
  };

  /**
   * https://github.com/sweetalert2/sweetalert2/issues/1891
   *
   * @param {TouchEvent} event
   * @returns {boolean}
   */
  const isZoom = event => {
    return event.touches && event.touches.length > 1;
  };
  const undoIOSfix = () => {
    if (hasClass(document.body, swalClasses.iosfix)) {
      const offset = parseInt(document.body.style.top, 10);
      removeClass(document.body, swalClasses.iosfix);
      document.body.style.top = '';
      document.body.scrollTop = offset * -1;
    }
  };

  /**
   * Measure scrollbar width for padding body during modal show/hide
   * https://github.com/twbs/bootstrap/blob/master/js/src/modal.js
   *
   * @returns {number}
   */
  const measureScrollbar = () => {
    const scrollDiv = document.createElement('div');
    scrollDiv.className = swalClasses['scrollbar-measure'];
    document.body.appendChild(scrollDiv);
    const scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
    document.body.removeChild(scrollDiv);
    return scrollbarWidth;
  };

  /**
   * Remember state in cases where opening and handling a modal will fiddle with it.
   * @type {number | null}
   */
  let previousBodyPadding = null;

  /**
   * @param {string} initialBodyOverflow
   */
  const replaceScrollbarWithPadding = initialBodyOverflow => {
    // for queues, do not do this more than once
    if (previousBodyPadding !== null) {
      return;
    }
    // if the body has overflow
    if (document.body.scrollHeight > window.innerHeight || initialBodyOverflow === 'scroll' // https://github.com/sweetalert2/sweetalert2/issues/2663
    ) {
      // add padding so the content doesn't shift after removal of scrollbar
      previousBodyPadding = parseInt(window.getComputedStyle(document.body).getPropertyValue('padding-right'));
      document.body.style.paddingRight = `${previousBodyPadding + measureScrollbar()}px`;
    }
  };
  const undoReplaceScrollbarWithPadding = () => {
    if (previousBodyPadding !== null) {
      document.body.style.paddingRight = `${previousBodyPadding}px`;
      previousBodyPadding = null;
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {HTMLElement} container
   * @param {boolean} returnFocus
   * @param {Function} didClose
   */
  function removePopupAndResetState(instance, container, returnFocus, didClose) {
    if (isToast()) {
      triggerDidCloseAndDispose(instance, didClose);
    } else {
      restoreActiveElement(returnFocus).then(() => triggerDidCloseAndDispose(instance, didClose));
      removeKeydownHandler(globalState);
    }

    // workaround for https://github.com/sweetalert2/sweetalert2/issues/2088
    // for some reason removing the container in Safari will scroll the document to bottom
    if (isSafariOrIOS) {
      container.setAttribute('style', 'display:none !important');
      container.removeAttribute('class');
      container.innerHTML = '';
    } else {
      container.remove();
    }
    if (isModal()) {
      undoReplaceScrollbarWithPadding();
      undoIOSfix();
      unsetAriaHidden();
    }
    removeBodyClasses();
  }

  /**
   * Remove SweetAlert2 classes from body
   */
  function removeBodyClasses() {
    removeClass([document.documentElement, document.body], [swalClasses.shown, swalClasses['height-auto'], swalClasses['no-backdrop'], swalClasses['toast-shown']]);
  }

  /**
   * Instance method to close sweetAlert
   *
   * @param {any} resolveValue
   */
  function close(resolveValue) {
    resolveValue = prepareResolveValue(resolveValue);
    const swalPromiseResolve = privateMethods.swalPromiseResolve.get(this);
    const didClose = triggerClosePopup(this);
    if (this.isAwaitingPromise) {
      // A swal awaiting for a promise (after a click on Confirm or Deny) cannot be dismissed anymore #2335
      if (!resolveValue.isDismissed) {
        handleAwaitingPromise(this);
        swalPromiseResolve(resolveValue);
      }
    } else if (didClose) {
      // Resolve Swal promise
      swalPromiseResolve(resolveValue);
    }
  }
  const triggerClosePopup = instance => {
    const popup = getPopup();
    if (!popup) {
      return false;
    }
    const innerParams = privateProps.innerParams.get(instance);
    if (!innerParams || hasClass(popup, innerParams.hideClass.popup)) {
      return false;
    }
    removeClass(popup, innerParams.showClass.popup);
    addClass(popup, innerParams.hideClass.popup);
    const backdrop = getContainer();
    removeClass(backdrop, innerParams.showClass.backdrop);
    addClass(backdrop, innerParams.hideClass.backdrop);
    handlePopupAnimation(instance, popup, innerParams);
    return true;
  };

  /**
   * @param {any} error
   */
  function rejectPromise(error) {
    const rejectPromise = privateMethods.swalPromiseReject.get(this);
    handleAwaitingPromise(this);
    if (rejectPromise) {
      // Reject Swal promise
      rejectPromise(error);
    }
  }

  /**
   * @param {SweetAlert} instance
   */
  const handleAwaitingPromise = instance => {
    if (instance.isAwaitingPromise) {
      delete instance.isAwaitingPromise;
      // The instance might have been previously partly destroyed, we must resume the destroy process in this case #2335
      if (!privateProps.innerParams.get(instance)) {
        instance._destroy();
      }
    }
  };

  /**
   * @param {any} resolveValue
   * @returns {SweetAlertResult}
   */
  const prepareResolveValue = resolveValue => {
    // When user calls Swal.close()
    if (typeof resolveValue === 'undefined') {
      return {
        isConfirmed: false,
        isDenied: false,
        isDismissed: true
      };
    }
    return Object.assign({
      isConfirmed: false,
      isDenied: false,
      isDismissed: false
    }, resolveValue);
  };

  /**
   * @param {SweetAlert} instance
   * @param {HTMLElement} popup
   * @param {SweetAlertOptions} innerParams
   */
  const handlePopupAnimation = (instance, popup, innerParams) => {
    var _globalState$eventEmi;
    const container = getContainer();
    // If animation is supported, animate
    const animationIsSupported = hasCssAnimation(popup);
    if (typeof innerParams.willClose === 'function') {
      innerParams.willClose(popup);
    }
    (_globalState$eventEmi = globalState.eventEmitter) === null || _globalState$eventEmi === void 0 || _globalState$eventEmi.emit('willClose', popup);
    if (animationIsSupported) {
      animatePopup(instance, popup, container, innerParams.returnFocus, innerParams.didClose);
    } else {
      // Otherwise, remove immediately
      removePopupAndResetState(instance, container, innerParams.returnFocus, innerParams.didClose);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {HTMLElement} popup
   * @param {HTMLElement} container
   * @param {boolean} returnFocus
   * @param {Function} didClose
   */
  const animatePopup = (instance, popup, container, returnFocus, didClose) => {
    globalState.swalCloseEventFinishedCallback = removePopupAndResetState.bind(null, instance, container, returnFocus, didClose);
    /**
     * @param {AnimationEvent | TransitionEvent} e
     */
    const swalCloseAnimationFinished = function (e) {
      if (e.target === popup) {
        var _globalState$swalClos;
        (_globalState$swalClos = globalState.swalCloseEventFinishedCallback) === null || _globalState$swalClos === void 0 || _globalState$swalClos.call(globalState);
        delete globalState.swalCloseEventFinishedCallback;
        popup.removeEventListener('animationend', swalCloseAnimationFinished);
        popup.removeEventListener('transitionend', swalCloseAnimationFinished);
      }
    };
    popup.addEventListener('animationend', swalCloseAnimationFinished);
    popup.addEventListener('transitionend', swalCloseAnimationFinished);
  };

  /**
   * @param {SweetAlert} instance
   * @param {Function} didClose
   */
  const triggerDidCloseAndDispose = (instance, didClose) => {
    setTimeout(() => {
      var _globalState$eventEmi2;
      if (typeof didClose === 'function') {
        didClose.bind(instance.params)();
      }
      (_globalState$eventEmi2 = globalState.eventEmitter) === null || _globalState$eventEmi2 === void 0 || _globalState$eventEmi2.emit('didClose');
      // instance might have been destroyed already
      if (instance._destroy) {
        instance._destroy();
      }
    });
  };

  /**
   * Shows loader (spinner), this is useful with AJAX requests.
   * By default the loader be shown instead of the "Confirm" button.
   *
   * @param {HTMLButtonElement | null} [buttonToReplace]
   */
  const showLoading = buttonToReplace => {
    let popup = getPopup();
    if (!popup) {
      new Swal();
    }
    popup = getPopup();
    if (!popup) {
      return;
    }
    const loader = getLoader();
    if (isToast()) {
      hide(getIcon());
    } else {
      replaceButton(popup, buttonToReplace);
    }
    show(loader);
    popup.setAttribute('data-loading', 'true');
    popup.setAttribute('aria-busy', 'true');
    popup.focus();
  };

  /**
   * @param {HTMLElement} popup
   * @param {HTMLButtonElement | null} [buttonToReplace]
   */
  const replaceButton = (popup, buttonToReplace) => {
    const actions = getActions();
    const loader = getLoader();
    if (!actions || !loader) {
      return;
    }
    if (!buttonToReplace && isVisible$1(getConfirmButton())) {
      buttonToReplace = getConfirmButton();
    }
    show(actions);
    if (buttonToReplace) {
      hide(buttonToReplace);
      loader.setAttribute('data-button-to-replace', buttonToReplace.className);
      actions.insertBefore(loader, buttonToReplace);
    }
    addClass([popup, actions], swalClasses.loading);
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const handleInputOptionsAndValue = (instance, params) => {
    if (params.input === 'select' || params.input === 'radio') {
      handleInputOptions(instance, params);
    } else if (['text', 'email', 'number', 'tel', 'textarea'].some(i => i === params.input) && (hasToPromiseFn(params.inputValue) || isPromise(params.inputValue))) {
      showLoading(getConfirmButton());
      handleInputValue(instance, params);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} innerParams
   * @returns {SweetAlertInputValue}
   */
  const getInputValue = (instance, innerParams) => {
    const input = instance.getInput();
    if (!input) {
      return null;
    }
    switch (innerParams.input) {
      case 'checkbox':
        return getCheckboxValue(input);
      case 'radio':
        return getRadioValue(input);
      case 'file':
        return getFileValue(input);
      default:
        return innerParams.inputAutoTrim ? input.value.trim() : input.value;
    }
  };

  /**
   * @param {HTMLInputElement} input
   * @returns {number}
   */
  const getCheckboxValue = input => input.checked ? 1 : 0;

  /**
   * @param {HTMLInputElement} input
   * @returns {string | null}
   */
  const getRadioValue = input => input.checked ? input.value : null;

  /**
   * @param {HTMLInputElement} input
   * @returns {FileList | File | null}
   */
  const getFileValue = input => input.files && input.files.length ? input.getAttribute('multiple') !== null ? input.files : input.files[0] : null;

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const handleInputOptions = (instance, params) => {
    const popup = getPopup();
    if (!popup) {
      return;
    }
    /**
     * @param {Record<string, any>} inputOptions
     */
    const processInputOptions = inputOptions => {
      if (params.input === 'select') {
        populateSelectOptions(popup, formatInputOptions(inputOptions), params);
      } else if (params.input === 'radio') {
        populateRadioOptions(popup, formatInputOptions(inputOptions), params);
      }
    };
    if (hasToPromiseFn(params.inputOptions) || isPromise(params.inputOptions)) {
      showLoading(getConfirmButton());
      asPromise(params.inputOptions).then(inputOptions => {
        instance.hideLoading();
        processInputOptions(inputOptions);
      });
    } else if (typeof params.inputOptions === 'object') {
      processInputOptions(params.inputOptions);
    } else {
      error(`Unexpected type of inputOptions! Expected object, Map or Promise, got ${typeof params.inputOptions}`);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertOptions} params
   */
  const handleInputValue = (instance, params) => {
    const input = instance.getInput();
    if (!input) {
      return;
    }
    hide(input);
    asPromise(params.inputValue).then(inputValue => {
      input.value = params.input === 'number' ? `${parseFloat(inputValue) || 0}` : `${inputValue}`;
      show(input);
      input.focus();
      instance.hideLoading();
    }).catch(err => {
      error(`Error in inputValue promise: ${err}`);
      input.value = '';
      show(input);
      input.focus();
      instance.hideLoading();
    });
  };

  /**
   * @param {HTMLElement} popup
   * @param {InputOptionFlattened[]} inputOptions
   * @param {SweetAlertOptions} params
   */
  function populateSelectOptions(popup, inputOptions, params) {
    const select = getDirectChildByClass(popup, swalClasses.select);
    if (!select) {
      return;
    }
    /**
     * @param {HTMLElement} parent
     * @param {string} optionLabel
     * @param {string} optionValue
     */
    const renderOption = (parent, optionLabel, optionValue) => {
      const option = document.createElement('option');
      option.value = optionValue;
      setInnerHtml(option, optionLabel);
      option.selected = isSelected(optionValue, params.inputValue);
      parent.appendChild(option);
    };
    inputOptions.forEach(inputOption => {
      const optionValue = inputOption[0];
      const optionLabel = inputOption[1];
      // <optgroup> spec:
      // https://www.w3.org/TR/html401/interact/forms.html#h-17.6
      // "...all OPTGROUP elements must be specified directly within a SELECT element (i.e., groups may not be nested)..."
      // check whether this is a <optgroup>
      if (Array.isArray(optionLabel)) {
        // if it is an array, then it is an <optgroup>
        const optgroup = document.createElement('optgroup');
        optgroup.label = optionValue;
        optgroup.disabled = false; // not configurable for now
        select.appendChild(optgroup);
        optionLabel.forEach(o => renderOption(optgroup, o[1], o[0]));
      } else {
        // case of <option>
        renderOption(select, optionLabel, optionValue);
      }
    });
    select.focus();
  }

  /**
   * @param {HTMLElement} popup
   * @param {InputOptionFlattened[]} inputOptions
   * @param {SweetAlertOptions} params
   */
  function populateRadioOptions(popup, inputOptions, params) {
    const radio = getDirectChildByClass(popup, swalClasses.radio);
    if (!radio) {
      return;
    }
    inputOptions.forEach(inputOption => {
      const radioValue = inputOption[0];
      const radioLabel = inputOption[1];
      const radioInput = document.createElement('input');
      const radioLabelElement = document.createElement('label');
      radioInput.type = 'radio';
      radioInput.name = swalClasses.radio;
      radioInput.value = radioValue;
      if (isSelected(radioValue, params.inputValue)) {
        radioInput.checked = true;
      }
      const label = document.createElement('span');
      setInnerHtml(label, radioLabel);
      label.className = swalClasses.label;
      radioLabelElement.appendChild(radioInput);
      radioLabelElement.appendChild(label);
      radio.appendChild(radioLabelElement);
    });
    const radios = radio.querySelectorAll('input');
    if (radios.length) {
      radios[0].focus();
    }
  }

  /**
   * Converts `inputOptions` into an array of `[value, label]`s
   *
   * @param {Record<string, any>} inputOptions
   * @typedef {string[]} InputOptionFlattened
   * @returns {InputOptionFlattened[]}
   */
  const formatInputOptions = inputOptions => {
    /** @type {InputOptionFlattened[]} */
    const result = [];
    if (inputOptions instanceof Map) {
      inputOptions.forEach((value, key) => {
        let valueFormatted = value;
        if (typeof valueFormatted === 'object') {
          // case of <optgroup>
          valueFormatted = formatInputOptions(valueFormatted);
        }
        result.push([key, valueFormatted]);
      });
    } else {
      Object.keys(inputOptions).forEach(key => {
        let valueFormatted = inputOptions[key];
        if (typeof valueFormatted === 'object') {
          // case of <optgroup>
          valueFormatted = formatInputOptions(valueFormatted);
        }
        result.push([key, valueFormatted]);
      });
    }
    return result;
  };

  /**
   * @param {string} optionValue
   * @param {SweetAlertInputValue} inputValue
   * @returns {boolean}
   */
  const isSelected = (optionValue, inputValue) => {
    return !!inputValue && inputValue.toString() === optionValue.toString();
  };

  /**
   * @param {SweetAlert} instance
   */
  const handleConfirmButtonClick = instance => {
    const innerParams = privateProps.innerParams.get(instance);
    instance.disableButtons();
    if (innerParams.input) {
      handleConfirmOrDenyWithInput(instance, 'confirm');
    } else {
      confirm(instance, true);
    }
  };

  /**
   * @param {SweetAlert} instance
   */
  const handleDenyButtonClick = instance => {
    const innerParams = privateProps.innerParams.get(instance);
    instance.disableButtons();
    if (innerParams.returnInputValueOnDeny) {
      handleConfirmOrDenyWithInput(instance, 'deny');
    } else {
      deny(instance, false);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {Function} dismissWith
   */
  const handleCancelButtonClick = (instance, dismissWith) => {
    instance.disableButtons();
    dismissWith(DismissReason.cancel);
  };

  /**
   * @param {SweetAlert} instance
   * @param {'confirm' | 'deny'} type
   */
  const handleConfirmOrDenyWithInput = (instance, type) => {
    const innerParams = privateProps.innerParams.get(instance);
    if (!innerParams.input) {
      error(`The "input" parameter is needed to be set when using returnInputValueOn${capitalizeFirstLetter(type)}`);
      return;
    }
    const input = instance.getInput();
    const inputValue = getInputValue(instance, innerParams);
    if (innerParams.inputValidator) {
      handleInputValidator(instance, inputValue, type);
    } else if (input && !input.checkValidity()) {
      instance.enableButtons();
      instance.showValidationMessage(innerParams.validationMessage || input.validationMessage);
    } else if (type === 'deny') {
      deny(instance, inputValue);
    } else {
      confirm(instance, inputValue);
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {SweetAlertInputValue} inputValue
   * @param {'confirm' | 'deny'} type
   */
  const handleInputValidator = (instance, inputValue, type) => {
    const innerParams = privateProps.innerParams.get(instance);
    instance.disableInput();
    const validationPromise = Promise.resolve().then(() => asPromise(innerParams.inputValidator(inputValue, innerParams.validationMessage)));
    validationPromise.then(validationMessage => {
      instance.enableButtons();
      instance.enableInput();
      if (validationMessage) {
        instance.showValidationMessage(validationMessage);
      } else if (type === 'deny') {
        deny(instance, inputValue);
      } else {
        confirm(instance, inputValue);
      }
    });
  };

  /**
   * @param {SweetAlert} instance
   * @param {any} value
   */
  const deny = (instance, value) => {
    const innerParams = privateProps.innerParams.get(instance || undefined);
    if (innerParams.showLoaderOnDeny) {
      showLoading(getDenyButton());
    }
    if (innerParams.preDeny) {
      instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preDeny's promise is received
      const preDenyPromise = Promise.resolve().then(() => asPromise(innerParams.preDeny(value, innerParams.validationMessage)));
      preDenyPromise.then(preDenyValue => {
        if (preDenyValue === false) {
          instance.hideLoading();
          handleAwaitingPromise(instance);
        } else {
          instance.close({
            isDenied: true,
            value: typeof preDenyValue === 'undefined' ? value : preDenyValue
          });
        }
      }).catch(error => rejectWith(instance || undefined, error));
    } else {
      instance.close({
        isDenied: true,
        value
      });
    }
  };

  /**
   * @param {SweetAlert} instance
   * @param {any} value
   */
  const succeedWith = (instance, value) => {
    instance.close({
      isConfirmed: true,
      value
    });
  };

  /**
   *
   * @param {SweetAlert} instance
   * @param {string} error
   */
  const rejectWith = (instance, error) => {
    instance.rejectPromise(error);
  };

  /**
   *
   * @param {SweetAlert} instance
   * @param {any} value
   */
  const confirm = (instance, value) => {
    const innerParams = privateProps.innerParams.get(instance || undefined);
    if (innerParams.showLoaderOnConfirm) {
      showLoading();
    }
    if (innerParams.preConfirm) {
      instance.resetValidationMessage();
      instance.isAwaitingPromise = true; // Flagging the instance as awaiting a promise so it's own promise's reject/resolve methods doesn't get destroyed until the result from this preConfirm's promise is received
      const preConfirmPromise = Promise.resolve().then(() => asPromise(innerParams.preConfirm(value, innerParams.validationMessage)));
      preConfirmPromise.then(preConfirmValue => {
        if (isVisible$1(getValidationMessage()) || preConfirmValue === false) {
          instance.hideLoading();
          handleAwaitingPromise(instance);
        } else {
          succeedWith(instance, typeof preConfirmValue === 'undefined' ? value : preConfirmValue);
        }
      }).catch(error => rejectWith(instance || undefined, error));
    } else {
      succeedWith(instance, value);
    }
  };

  /**
   * Hides loader and shows back the button which was hidden by .showLoading()
   */
  function hideLoading() {
    // do nothing if popup is closed
    const innerParams = privateProps.innerParams.get(this);
    if (!innerParams) {
      return;
    }
    const domCache = privateProps.domCache.get(this);
    hide(domCache.loader);
    if (isToast()) {
      if (innerParams.icon) {
        show(getIcon());
      }
    } else {
      showRelatedButton(domCache);
    }
    removeClass([domCache.popup, domCache.actions], swalClasses.loading);
    domCache.popup.removeAttribute('aria-busy');
    domCache.popup.removeAttribute('data-loading');
    domCache.confirmButton.disabled = false;
    domCache.denyButton.disabled = false;
    domCache.cancelButton.disabled = false;
  }
  const showRelatedButton = domCache => {
    const buttonToReplace = domCache.popup.getElementsByClassName(domCache.loader.getAttribute('data-button-to-replace'));
    if (buttonToReplace.length) {
      show(buttonToReplace[0], 'inline-block');
    } else if (allButtonsAreHidden()) {
      hide(domCache.actions);
    }
  };

  /**
   * Gets the input DOM node, this method works with input parameter.
   *
   * @returns {HTMLInputElement | null}
   */
  function getInput() {
    const innerParams = privateProps.innerParams.get(this);
    const domCache = privateProps.domCache.get(this);
    if (!domCache) {
      return null;
    }
    return getInput$1(domCache.popup, innerParams.input);
  }

  /**
   * @param {SweetAlert} instance
   * @param {string[]} buttons
   * @param {boolean} disabled
   */
  function setButtonsDisabled(instance, buttons, disabled) {
    const domCache = privateProps.domCache.get(instance);
    buttons.forEach(button => {
      domCache[button].disabled = disabled;
    });
  }

  /**
   * @param {HTMLInputElement | null} input
   * @param {boolean} disabled
   */
  function setInputDisabled(input, disabled) {
    const popup = getPopup();
    if (!popup || !input) {
      return;
    }
    if (input.type === 'radio') {
      /** @type {NodeListOf<HTMLInputElement>} */
      const radios = popup.querySelectorAll(`[name="${swalClasses.radio}"]`);
      for (let i = 0; i < radios.length; i++) {
        radios[i].disabled = disabled;
      }
    } else {
      input.disabled = disabled;
    }
  }

  /**
   * Enable all the buttons
   * @this {SweetAlert}
   */
  function enableButtons() {
    setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], false);
  }

  /**
   * Disable all the buttons
   * @this {SweetAlert}
   */
  function disableButtons() {
    setButtonsDisabled(this, ['confirmButton', 'denyButton', 'cancelButton'], true);
  }

  /**
   * Enable the input field
   * @this {SweetAlert}
   */
  function enableInput() {
    setInputDisabled(this.getInput(), false);
  }

  /**
   * Disable the input field
   * @this {SweetAlert}
   */
  function disableInput() {
    setInputDisabled(this.getInput(), true);
  }

  /**
   * Show block with validation message
   *
   * @param {string} error
   * @this {SweetAlert}
   */
  function showValidationMessage(error) {
    const domCache = privateProps.domCache.get(this);
    const params = privateProps.innerParams.get(this);
    setInnerHtml(domCache.validationMessage, error);
    domCache.validationMessage.className = swalClasses['validation-message'];
    if (params.customClass && params.customClass.validationMessage) {
      addClass(domCache.validationMessage, params.customClass.validationMessage);
    }
    show(domCache.validationMessage);
    const input = this.getInput();
    if (input) {
      input.setAttribute('aria-invalid', 'true');
      input.setAttribute('aria-describedby', swalClasses['validation-message']);
      focusInput(input);
      addClass(input, swalClasses.inputerror);
    }
  }

  /**
   * Hide block with validation message
   *
   * @this {SweetAlert}
   */
  function resetValidationMessage() {
    const domCache = privateProps.domCache.get(this);
    if (domCache.validationMessage) {
      hide(domCache.validationMessage);
    }
    const input = this.getInput();
    if (input) {
      input.removeAttribute('aria-invalid');
      input.removeAttribute('aria-describedby');
      removeClass(input, swalClasses.inputerror);
    }
  }
  const defaultParams = {
    title: '',
    titleText: '',
    text: '',
    html: '',
    footer: '',
    icon: undefined,
    iconColor: undefined,
    iconHtml: undefined,
    template: undefined,
    toast: false,
    draggable: false,
    animation: true,
    theme: 'light',
    showClass: {
      popup: 'swal2-show',
      backdrop: 'swal2-backdrop-show',
      icon: 'swal2-icon-show'
    },
    hideClass: {
      popup: 'swal2-hide',
      backdrop: 'swal2-backdrop-hide',
      icon: 'swal2-icon-hide'
    },
    customClass: {},
    target: 'body',
    color: undefined,
    backdrop: true,
    heightAuto: true,
    allowOutsideClick: true,
    allowEscapeKey: true,
    allowEnterKey: true,
    stopKeydownPropagation: true,
    keydownListenerCapture: false,
    showConfirmButton: true,
    showDenyButton: false,
    showCancelButton: false,
    preConfirm: undefined,
    preDeny: undefined,
    confirmButtonText: 'OK',
    confirmButtonAriaLabel: '',
    confirmButtonColor: undefined,
    denyButtonText: 'No',
    denyButtonAriaLabel: '',
    denyButtonColor: undefined,
    cancelButtonText: 'Cancel',
    cancelButtonAriaLabel: '',
    cancelButtonColor: undefined,
    buttonsStyling: true,
    reverseButtons: false,
    focusConfirm: true,
    focusDeny: false,
    focusCancel: false,
    returnFocus: true,
    showCloseButton: false,
    closeButtonHtml: '&times;',
    closeButtonAriaLabel: 'Close this dialog',
    loaderHtml: '',
    showLoaderOnConfirm: false,
    showLoaderOnDeny: false,
    imageUrl: undefined,
    imageWidth: undefined,
    imageHeight: undefined,
    imageAlt: '',
    timer: undefined,
    timerProgressBar: false,
    width: undefined,
    padding: undefined,
    background: undefined,
    input: undefined,
    inputPlaceholder: '',
    inputLabel: '',
    inputValue: '',
    inputOptions: {},
    inputAutoFocus: true,
    inputAutoTrim: true,
    inputAttributes: {},
    inputValidator: undefined,
    returnInputValueOnDeny: false,
    validationMessage: undefined,
    grow: false,
    position: 'center',
    progressSteps: [],
    currentProgressStep: undefined,
    progressStepsDistance: undefined,
    willOpen: undefined,
    didOpen: undefined,
    didRender: undefined,
    willClose: undefined,
    didClose: undefined,
    didDestroy: undefined,
    scrollbarPadding: true,
    topLayer: false
  };
  const updatableParams = ['allowEscapeKey', 'allowOutsideClick', 'background', 'buttonsStyling', 'cancelButtonAriaLabel', 'cancelButtonColor', 'cancelButtonText', 'closeButtonAriaLabel', 'closeButtonHtml', 'color', 'confirmButtonAriaLabel', 'confirmButtonColor', 'confirmButtonText', 'currentProgressStep', 'customClass', 'denyButtonAriaLabel', 'denyButtonColor', 'denyButtonText', 'didClose', 'didDestroy', 'draggable', 'footer', 'hideClass', 'html', 'icon', 'iconColor', 'iconHtml', 'imageAlt', 'imageHeight', 'imageUrl', 'imageWidth', 'preConfirm', 'preDeny', 'progressSteps', 'returnFocus', 'reverseButtons', 'showCancelButton', 'showCloseButton', 'showConfirmButton', 'showDenyButton', 'text', 'title', 'titleText', 'theme', 'willClose'];

  /** @type {Record<string, string | undefined>} */
  const deprecatedParams = {
    allowEnterKey: undefined
  };
  const toastIncompatibleParams = ['allowOutsideClick', 'allowEnterKey', 'backdrop', 'draggable', 'focusConfirm', 'focusDeny', 'focusCancel', 'returnFocus', 'heightAuto', 'keydownListenerCapture'];

  /**
   * Is valid parameter
   *
   * @param {string} paramName
   * @returns {boolean}
   */
  const isValidParameter = paramName => {
    return Object.prototype.hasOwnProperty.call(defaultParams, paramName);
  };

  /**
   * Is valid parameter for Swal.update() method
   *
   * @param {string} paramName
   * @returns {boolean}
   */
  const isUpdatableParameter = paramName => {
    return updatableParams.indexOf(paramName) !== -1;
  };

  /**
   * Is deprecated parameter
   *
   * @param {string} paramName
   * @returns {string | undefined}
   */
  const isDeprecatedParameter = paramName => {
    return deprecatedParams[paramName];
  };

  /**
   * @param {string} param
   */
  const checkIfParamIsValid = param => {
    if (!isValidParameter(param)) {
      warn(`Unknown parameter "${param}"`);
    }
  };

  /**
   * @param {string} param
   */
  const checkIfToastParamIsValid = param => {
    if (toastIncompatibleParams.includes(param)) {
      warn(`The parameter "${param}" is incompatible with toasts`);
    }
  };

  /**
   * @param {string} param
   */
  const checkIfParamIsDeprecated = param => {
    const isDeprecated = isDeprecatedParameter(param);
    if (isDeprecated) {
      warnAboutDeprecation(param, isDeprecated);
    }
  };

  /**
   * Show relevant warnings for given params
   *
   * @param {SweetAlertOptions} params
   */
  const showWarningsForParams = params => {
    if (params.backdrop === false && params.allowOutsideClick) {
      warn('"allowOutsideClick" parameter requires `backdrop` parameter to be set to `true`');
    }
    if (params.theme && !['light', 'dark', 'auto', 'minimal', 'borderless', 'embed-iframe', 'bulma', 'bulma-light', 'bulma-dark'].includes(params.theme)) {
      warn(`Invalid theme "${params.theme}"`);
    }
    for (const param in params) {
      checkIfParamIsValid(param);
      if (params.toast) {
        checkIfToastParamIsValid(param);
      }
      checkIfParamIsDeprecated(param);
    }
  };

  /**
   * Updates popup parameters.
   *
   * @param {SweetAlertOptions} params
   */
  function update(params) {
    const container = getContainer();
    const popup = getPopup();
    const innerParams = privateProps.innerParams.get(this);
    if (!popup || hasClass(popup, innerParams.hideClass.popup)) {
      warn(`You're trying to update the closed or closing popup, that won't work. Use the update() method in preConfirm parameter or show a new popup.`);
      return;
    }
    const validUpdatableParams = filterValidParams(params);
    const updatedParams = Object.assign({}, innerParams, validUpdatableParams);
    showWarningsForParams(updatedParams);
    container.dataset['swal2Theme'] = updatedParams.theme;
    render(this, updatedParams);
    privateProps.innerParams.set(this, updatedParams);
    Object.defineProperties(this, {
      params: {
        value: Object.assign({}, this.params, params),
        writable: false,
        enumerable: true
      }
    });
  }

  /**
   * @param {SweetAlertOptions} params
   * @returns {SweetAlertOptions}
   */
  const filterValidParams = params => {
    const validUpdatableParams = {};
    Object.keys(params).forEach(param => {
      if (isUpdatableParameter(param)) {
        validUpdatableParams[param] = params[param];
      } else {
        warn(`Invalid parameter to update: ${param}`);
      }
    });
    return validUpdatableParams;
  };

  /**
   * Dispose the current SweetAlert2 instance
   */
  function _destroy() {
    const domCache = privateProps.domCache.get(this);
    const innerParams = privateProps.innerParams.get(this);
    if (!innerParams) {
      disposeWeakMaps(this); // The WeakMaps might have been partly destroyed, we must recall it to dispose any remaining WeakMaps #2335
      return; // This instance has already been destroyed
    }

    // Check if there is another Swal closing
    if (domCache.popup && globalState.swalCloseEventFinishedCallback) {
      globalState.swalCloseEventFinishedCallback();
      delete globalState.swalCloseEventFinishedCallback;
    }
    if (typeof innerParams.didDestroy === 'function') {
      innerParams.didDestroy();
    }
    globalState.eventEmitter.emit('didDestroy');
    disposeSwal(this);
  }

  /**
   * @param {SweetAlert} instance
   */
  const disposeSwal = instance => {
    disposeWeakMaps(instance);
    // Unset this.params so GC will dispose it (#1569)
    delete instance.params;
    // Unset globalState props so GC will dispose globalState (#1569)
    delete globalState.keydownHandler;
    delete globalState.keydownTarget;
    // Unset currentInstance
    delete globalState.currentInstance;
  };

  /**
   * @param {SweetAlert} instance
   */
  const disposeWeakMaps = instance => {
    // If the current instance is awaiting a promise result, we keep the privateMethods to call them once the promise result is retrieved #2335
    if (instance.isAwaitingPromise) {
      unsetWeakMaps(privateProps, instance);
      instance.isAwaitingPromise = true;
    } else {
      unsetWeakMaps(privateMethods, instance);
      unsetWeakMaps(privateProps, instance);
      delete instance.isAwaitingPromise;
      // Unset instance methods
      delete instance.disableButtons;
      delete instance.enableButtons;
      delete instance.getInput;
      delete instance.disableInput;
      delete instance.enableInput;
      delete instance.hideLoading;
      delete instance.disableLoading;
      delete instance.showValidationMessage;
      delete instance.resetValidationMessage;
      delete instance.close;
      delete instance.closePopup;
      delete instance.closeModal;
      delete instance.closeToast;
      delete instance.rejectPromise;
      delete instance.update;
      delete instance._destroy;
    }
  };

  /**
   * @param {object} obj
   * @param {SweetAlert} instance
   */
  const unsetWeakMaps = (obj, instance) => {
    for (const i in obj) {
      obj[i].delete(instance);
    }
  };
  var instanceMethods = /*#__PURE__*/Object.freeze({
    __proto__: null,
    _destroy: _destroy,
    close: close,
    closeModal: close,
    closePopup: close,
    closeToast: close,
    disableButtons: disableButtons,
    disableInput: disableInput,
    disableLoading: hideLoading,
    enableButtons: enableButtons,
    enableInput: enableInput,
    getInput: getInput,
    handleAwaitingPromise: handleAwaitingPromise,
    hideLoading: hideLoading,
    rejectPromise: rejectPromise,
    resetValidationMessage: resetValidationMessage,
    showValidationMessage: showValidationMessage,
    update: update
  });

  /**
   * @param {SweetAlertOptions} innerParams
   * @param {DomCache} domCache
   * @param {Function} dismissWith
   */
  const handlePopupClick = (innerParams, domCache, dismissWith) => {
    if (innerParams.toast) {
      handleToastClick(innerParams, domCache, dismissWith);
    } else {
      // Ignore click events that had mousedown on the popup but mouseup on the container
      // This can happen when the user drags a slider
      handleModalMousedown(domCache);

      // Ignore click events that had mousedown on the container but mouseup on the popup
      handleContainerMousedown(domCache);
      handleModalClick(innerParams, domCache, dismissWith);
    }
  };

  /**
   * @param {SweetAlertOptions} innerParams
   * @param {DomCache} domCache
   * @param {Function} dismissWith
   */
  const handleToastClick = (innerParams, domCache, dismissWith) => {
    // Closing toast by internal click
    domCache.popup.onclick = () => {
      if (innerParams && (isAnyButtonShown(innerParams) || innerParams.timer || innerParams.input)) {
        return;
      }
      dismissWith(DismissReason.close);
    };
  };

  /**
   * @param {SweetAlertOptions} innerParams
   * @returns {boolean}
   */
  const isAnyButtonShown = innerParams => {
    return !!(innerParams.showConfirmButton || innerParams.showDenyButton || innerParams.showCancelButton || innerParams.showCloseButton);
  };
  let ignoreOutsideClick = false;

  /**
   * @param {DomCache} domCache
   */
  const handleModalMousedown = domCache => {
    domCache.popup.onmousedown = () => {
      domCache.container.onmouseup = function (e) {
        domCache.container.onmouseup = () => {};
        // We only check if the mouseup target is the container because usually it doesn't
        // have any other direct children aside of the popup
        if (e.target === domCache.container) {
          ignoreOutsideClick = true;
        }
      };
    };
  };

  /**
   * @param {DomCache} domCache
   */
  const handleContainerMousedown = domCache => {
    domCache.container.onmousedown = e => {
      // prevent the modal text from being selected on double click on the container (allowOutsideClick: false)
      if (e.target === domCache.container) {
        e.preventDefault();
      }
      domCache.popup.onmouseup = function (e) {
        domCache.popup.onmouseup = () => {};
        // We also need to check if the mouseup target is a child of the popup
        if (e.target === domCache.popup || e.target instanceof HTMLElement && domCache.popup.contains(e.target)) {
          ignoreOutsideClick = true;
        }
      };
    };
  };

  /**
   * @param {SweetAlertOptions} innerParams
   * @param {DomCache} domCache
   * @param {Function} dismissWith
   */
  const handleModalClick = (innerParams, domCache, dismissWith) => {
    domCache.container.onclick = e => {
      if (ignoreOutsideClick) {
        ignoreOutsideClick = false;
        return;
      }
      if (e.target === domCache.container && callIfFunction(innerParams.allowOutsideClick)) {
        dismissWith(DismissReason.backdrop);
      }
    };
  };
  const isJqueryElement = elem => typeof elem === 'object' && elem.jquery;
  const isElement = elem => elem instanceof Element || isJqueryElement(elem);
  const argsToParams = args => {
    const params = {};
    if (typeof args[0] === 'object' && !isElement(args[0])) {
      Object.assign(params, args[0]);
    } else {
      ['title', 'html', 'icon'].forEach((name, index) => {
        const arg = args[index];
        if (typeof arg === 'string' || isElement(arg)) {
          params[name] = arg;
        } else if (arg !== undefined) {
          error(`Unexpected type of ${name}! Expected "string" or "Element", got ${typeof arg}`);
        }
      });
    }
    return params;
  };

  /**
   * Main method to create a new SweetAlert2 popup
   *
   * @param  {...SweetAlertOptions} args
   * @returns {Promise<SweetAlertResult>}
   */
  function fire(...args) {
    return new this(...args);
  }

  /**
   * Returns an extended version of `Swal` containing `params` as defaults.
   * Useful for reusing Swal configuration.
   *
   * For example:
   *
   * Before:
   * const textPromptOptions = { input: 'text', showCancelButton: true }
   * const {value: firstName} = await Swal.fire({ ...textPromptOptions, title: 'What is your first name?' })
   * const {value: lastName} = await Swal.fire({ ...textPromptOptions, title: 'What is your last name?' })
   *
   * After:
   * const TextPrompt = Swal.mixin({ input: 'text', showCancelButton: true })
   * const {value: firstName} = await TextPrompt('What is your first name?')
   * const {value: lastName} = await TextPrompt('What is your last name?')
   *
   * @param {SweetAlertOptions} mixinParams
   * @returns {SweetAlert}
   */
  function mixin(mixinParams) {
    class MixinSwal extends this {
      _main(params, priorityMixinParams) {
        return super._main(params, Object.assign({}, mixinParams, priorityMixinParams));
      }
    }
    // @ts-ignore
    return MixinSwal;
  }

  /**
   * If `timer` parameter is set, returns number of milliseconds of timer remained.
   * Otherwise, returns undefined.
   *
   * @returns {number | undefined}
   */
  const getTimerLeft = () => {
    return globalState.timeout && globalState.timeout.getTimerLeft();
  };

  /**
   * Stop timer. Returns number of milliseconds of timer remained.
   * If `timer` parameter isn't set, returns undefined.
   *
   * @returns {number | undefined}
   */
  const stopTimer = () => {
    if (globalState.timeout) {
      stopTimerProgressBar();
      return globalState.timeout.stop();
    }
  };

  /**
   * Resume timer. Returns number of milliseconds of timer remained.
   * If `timer` parameter isn't set, returns undefined.
   *
   * @returns {number | undefined}
   */
  const resumeTimer = () => {
    if (globalState.timeout) {
      const remaining = globalState.timeout.start();
      animateTimerProgressBar(remaining);
      return remaining;
    }
  };

  /**
   * Resume timer. Returns number of milliseconds of timer remained.
   * If `timer` parameter isn't set, returns undefined.
   *
   * @returns {number | undefined}
   */
  const toggleTimer = () => {
    const timer = globalState.timeout;
    return timer && (timer.running ? stopTimer() : resumeTimer());
  };

  /**
   * Increase timer. Returns number of milliseconds of an updated timer.
   * If `timer` parameter isn't set, returns undefined.
   *
   * @param {number} ms
   * @returns {number | undefined}
   */
  const increaseTimer = ms => {
    if (globalState.timeout) {
      const remaining = globalState.timeout.increase(ms);
      animateTimerProgressBar(remaining, true);
      return remaining;
    }
  };

  /**
   * Check if timer is running. Returns true if timer is running
   * or false if timer is paused or stopped.
   * If `timer` parameter isn't set, returns undefined
   *
   * @returns {boolean}
   */
  const isTimerRunning = () => {
    return !!(globalState.timeout && globalState.timeout.isRunning());
  };
  let bodyClickListenerAdded = false;
  const clickHandlers = {};

  /**
   * @param {string} attr
   */
  function bindClickHandler(attr = 'data-swal-template') {
    clickHandlers[attr] = this;
    if (!bodyClickListenerAdded) {
      document.body.addEventListener('click', bodyClickListener);
      bodyClickListenerAdded = true;
    }
  }
  const bodyClickListener = event => {
    for (let el = event.target; el && el !== document; el = el.parentNode) {
      for (const attr in clickHandlers) {
        const template = el.getAttribute(attr);
        if (template) {
          clickHandlers[attr].fire({
            template
          });
          return;
        }
      }
    }
  };

  // Source: https://gist.github.com/mudge/5830382?permalink_comment_id=2691957#gistcomment-2691957

  class EventEmitter {
    constructor() {
      /** @type {Events} */
      this.events = {};
    }

    /**
     * @param {string} eventName
     * @returns {EventHandlers}
     */
    _getHandlersByEventName(eventName) {
      if (typeof this.events[eventName] === 'undefined') {
        // not Set because we need to keep the FIFO order
        // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1748990334
        this.events[eventName] = [];
      }
      return this.events[eventName];
    }

    /**
     * @param {string} eventName
     * @param {EventHandler} eventHandler
     */
    on(eventName, eventHandler) {
      const currentHandlers = this._getHandlersByEventName(eventName);
      if (!currentHandlers.includes(eventHandler)) {
        currentHandlers.push(eventHandler);
      }
    }

    /**
     * @param {string} eventName
     * @param {EventHandler} eventHandler
     */
    once(eventName, eventHandler) {
      /**
       * @param {Array} args
       */
      const onceFn = (...args) => {
        this.removeListener(eventName, onceFn);
        eventHandler.apply(this, args);
      };
      this.on(eventName, onceFn);
    }

    /**
     * @param {string} eventName
     * @param {Array} args
     */
    emit(eventName, ...args) {
      this._getHandlersByEventName(eventName).forEach(
      /**
       * @param {EventHandler} eventHandler
       */
      eventHandler => {
        try {
          eventHandler.apply(this, args);
        } catch (error) {
          console.error(error);
        }
      });
    }

    /**
     * @param {string} eventName
     * @param {EventHandler} eventHandler
     */
    removeListener(eventName, eventHandler) {
      const currentHandlers = this._getHandlersByEventName(eventName);
      const index = currentHandlers.indexOf(eventHandler);
      if (index > -1) {
        currentHandlers.splice(index, 1);
      }
    }

    /**
     * @param {string} eventName
     */
    removeAllListeners(eventName) {
      if (this.events[eventName] !== undefined) {
        // https://github.com/sweetalert2/sweetalert2/pull/2763#discussion_r1749239222
        this.events[eventName].length = 0;
      }
    }
    reset() {
      this.events = {};
    }
  }
  globalState.eventEmitter = new EventEmitter();

  /**
   * @param {string} eventName
   * @param {EventHandler} eventHandler
   */
  const on = (eventName, eventHandler) => {
    globalState.eventEmitter.on(eventName, eventHandler);
  };

  /**
   * @param {string} eventName
   * @param {EventHandler} eventHandler
   */
  const once = (eventName, eventHandler) => {
    globalState.eventEmitter.once(eventName, eventHandler);
  };

  /**
   * @param {string} [eventName]
   * @param {EventHandler} [eventHandler]
   */
  const off = (eventName, eventHandler) => {
    // Remove all handlers for all events
    if (!eventName) {
      globalState.eventEmitter.reset();
      return;
    }
    if (eventHandler) {
      // Remove a specific handler
      globalState.eventEmitter.removeListener(eventName, eventHandler);
    } else {
      // Remove all handlers for a specific event
      globalState.eventEmitter.removeAllListeners(eventName);
    }
  };
  var staticMethods = /*#__PURE__*/Object.freeze({
    __proto__: null,
    argsToParams: argsToParams,
    bindClickHandler: bindClickHandler,
    clickCancel: clickCancel,
    clickConfirm: clickConfirm,
    clickDeny: clickDeny,
    enableLoading: showLoading,
    fire: fire,
    getActions: getActions,
    getCancelButton: getCancelButton,
    getCloseButton: getCloseButton,
    getConfirmButton: getConfirmButton,
    getContainer: getContainer,
    getDenyButton: getDenyButton,
    getFocusableElements: getFocusableElements,
    getFooter: getFooter,
    getHtmlContainer: getHtmlContainer,
    getIcon: getIcon,
    getIconContent: getIconContent,
    getImage: getImage,
    getInputLabel: getInputLabel,
    getLoader: getLoader,
    getPopup: getPopup,
    getProgressSteps: getProgressSteps,
    getTimerLeft: getTimerLeft,
    getTimerProgressBar: getTimerProgressBar,
    getTitle: getTitle,
    getValidationMessage: getValidationMessage,
    increaseTimer: increaseTimer,
    isDeprecatedParameter: isDeprecatedParameter,
    isLoading: isLoading,
    isTimerRunning: isTimerRunning,
    isUpdatableParameter: isUpdatableParameter,
    isValidParameter: isValidParameter,
    isVisible: isVisible,
    mixin: mixin,
    off: off,
    on: on,
    once: once,
    resumeTimer: resumeTimer,
    showLoading: showLoading,
    stopTimer: stopTimer,
    toggleTimer: toggleTimer
  });
  class Timer {
    /**
     * @param {Function} callback
     * @param {number} delay
     */
    constructor(callback, delay) {
      this.callback = callback;
      this.remaining = delay;
      this.running = false;
      this.start();
    }

    /**
     * @returns {number}
     */
    start() {
      if (!this.running) {
        this.running = true;
        this.started = new Date();
        this.id = setTimeout(this.callback, this.remaining);
      }
      return this.remaining;
    }

    /**
     * @returns {number}
     */
    stop() {
      if (this.started && this.running) {
        this.running = false;
        clearTimeout(this.id);
        this.remaining -= new Date().getTime() - this.started.getTime();
      }
      return this.remaining;
    }

    /**
     * @param {number} n
     * @returns {number}
     */
    increase(n) {
      const running = this.running;
      if (running) {
        this.stop();
      }
      this.remaining += n;
      if (running) {
        this.start();
      }
      return this.remaining;
    }

    /**
     * @returns {number}
     */
    getTimerLeft() {
      if (this.running) {
        this.stop();
        this.start();
      }
      return this.remaining;
    }

    /**
     * @returns {boolean}
     */
    isRunning() {
      return this.running;
    }
  }
  const swalStringParams = ['swal-title', 'swal-html', 'swal-footer'];

  /**
   * @param {SweetAlertOptions} params
   * @returns {SweetAlertOptions}
   */
  const getTemplateParams = params => {
    const template = typeof params.template === 'string' ? (/** @type {HTMLTemplateElement} */document.querySelector(params.template)) : params.template;
    if (!template) {
      return {};
    }
    /** @type {DocumentFragment} */
    const templateContent = template.content;
    showWarningsForElements(templateContent);
    const result = Object.assign(getSwalParams(templateContent), getSwalFunctionParams(templateContent), getSwalButtons(templateContent), getSwalImage(templateContent), getSwalIcon(templateContent), getSwalInput(templateContent), getSwalStringParams(templateContent, swalStringParams));
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Record<string, any>}
   */
  const getSwalParams = templateContent => {
    /** @type {Record<string, any>} */
    const result = {};
    /** @type {HTMLElement[]} */
    const swalParams = Array.from(templateContent.querySelectorAll('swal-param'));
    swalParams.forEach(param => {
      showWarningsForAttributes(param, ['name', 'value']);
      const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
      const value = param.getAttribute('value');
      if (!paramName || !value) {
        return;
      }
      if (typeof defaultParams[paramName] === 'boolean') {
        result[paramName] = value !== 'false';
      } else if (typeof defaultParams[paramName] === 'object') {
        result[paramName] = JSON.parse(value);
      } else {
        result[paramName] = value;
      }
    });
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Record<string, any>}
   */
  const getSwalFunctionParams = templateContent => {
    /** @type {Record<string, any>} */
    const result = {};
    /** @type {HTMLElement[]} */
    const swalFunctions = Array.from(templateContent.querySelectorAll('swal-function-param'));
    swalFunctions.forEach(param => {
      const paramName = /** @type {keyof SweetAlertOptions} */param.getAttribute('name');
      const value = param.getAttribute('value');
      if (!paramName || !value) {
        return;
      }
      result[paramName] = new Function(`return ${value}`)();
    });
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Record<string, any>}
   */
  const getSwalButtons = templateContent => {
    /** @type {Record<string, any>} */
    const result = {};
    /** @type {HTMLElement[]} */
    const swalButtons = Array.from(templateContent.querySelectorAll('swal-button'));
    swalButtons.forEach(button => {
      showWarningsForAttributes(button, ['type', 'color', 'aria-label']);
      const type = button.getAttribute('type');
      if (!type || !['confirm', 'cancel', 'deny'].includes(type)) {
        return;
      }
      result[`${type}ButtonText`] = button.innerHTML;
      result[`show${capitalizeFirstLetter(type)}Button`] = true;
      if (button.hasAttribute('color')) {
        result[`${type}ButtonColor`] = button.getAttribute('color');
      }
      if (button.hasAttribute('aria-label')) {
        result[`${type}ButtonAriaLabel`] = button.getAttribute('aria-label');
      }
    });
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Pick<SweetAlertOptions, 'imageUrl' | 'imageWidth' | 'imageHeight' | 'imageAlt'>}
   */
  const getSwalImage = templateContent => {
    const result = {};
    /** @type {HTMLElement | null} */
    const image = templateContent.querySelector('swal-image');
    if (image) {
      showWarningsForAttributes(image, ['src', 'width', 'height', 'alt']);
      if (image.hasAttribute('src')) {
        result.imageUrl = image.getAttribute('src') || undefined;
      }
      if (image.hasAttribute('width')) {
        result.imageWidth = image.getAttribute('width') || undefined;
      }
      if (image.hasAttribute('height')) {
        result.imageHeight = image.getAttribute('height') || undefined;
      }
      if (image.hasAttribute('alt')) {
        result.imageAlt = image.getAttribute('alt') || undefined;
      }
    }
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Record<string, any>}
   */
  const getSwalIcon = templateContent => {
    const result = {};
    /** @type {HTMLElement | null} */
    const icon = templateContent.querySelector('swal-icon');
    if (icon) {
      showWarningsForAttributes(icon, ['type', 'color']);
      if (icon.hasAttribute('type')) {
        result.icon = icon.getAttribute('type');
      }
      if (icon.hasAttribute('color')) {
        result.iconColor = icon.getAttribute('color');
      }
      result.iconHtml = icon.innerHTML;
    }
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @returns {Record<string, any>}
   */
  const getSwalInput = templateContent => {
    /** @type {Record<string, any>} */
    const result = {};
    /** @type {HTMLElement | null} */
    const input = templateContent.querySelector('swal-input');
    if (input) {
      showWarningsForAttributes(input, ['type', 'label', 'placeholder', 'value']);
      result.input = input.getAttribute('type') || 'text';
      if (input.hasAttribute('label')) {
        result.inputLabel = input.getAttribute('label');
      }
      if (input.hasAttribute('placeholder')) {
        result.inputPlaceholder = input.getAttribute('placeholder');
      }
      if (input.hasAttribute('value')) {
        result.inputValue = input.getAttribute('value');
      }
    }
    /** @type {HTMLElement[]} */
    const inputOptions = Array.from(templateContent.querySelectorAll('swal-input-option'));
    if (inputOptions.length) {
      result.inputOptions = {};
      inputOptions.forEach(option => {
        showWarningsForAttributes(option, ['value']);
        const optionValue = option.getAttribute('value');
        if (!optionValue) {
          return;
        }
        const optionName = option.innerHTML;
        result.inputOptions[optionValue] = optionName;
      });
    }
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   * @param {string[]} paramNames
   * @returns {Record<string, any>}
   */
  const getSwalStringParams = (templateContent, paramNames) => {
    /** @type {Record<string, any>} */
    const result = {};
    for (const i in paramNames) {
      const paramName = paramNames[i];
      /** @type {HTMLElement | null} */
      const tag = templateContent.querySelector(paramName);
      if (tag) {
        showWarningsForAttributes(tag, []);
        result[paramName.replace(/^swal-/, '')] = tag.innerHTML.trim();
      }
    }
    return result;
  };

  /**
   * @param {DocumentFragment} templateContent
   */
  const showWarningsForElements = templateContent => {
    const allowedElements = swalStringParams.concat(['swal-param', 'swal-function-param', 'swal-button', 'swal-image', 'swal-icon', 'swal-input', 'swal-input-option']);
    Array.from(templateContent.children).forEach(el => {
      const tagName = el.tagName.toLowerCase();
      if (!allowedElements.includes(tagName)) {
        warn(`Unrecognized element <${tagName}>`);
      }
    });
  };

  /**
   * @param {HTMLElement} el
   * @param {string[]} allowedAttributes
   */
  const showWarningsForAttributes = (el, allowedAttributes) => {
    Array.from(el.attributes).forEach(attribute => {
      if (allowedAttributes.indexOf(attribute.name) === -1) {
        warn([`Unrecognized attribute "${attribute.name}" on <${el.tagName.toLowerCase()}>.`, `${allowedAttributes.length ? `Allowed attributes are: ${allowedAttributes.join(', ')}` : 'To set the value, use HTML within the element.'}`]);
      }
    });
  };
  const SHOW_CLASS_TIMEOUT = 10;

  /**
   * Open popup, add necessary classes and styles, fix scrollbar
   *
   * @param {SweetAlertOptions} params
   */
  const openPopup = params => {
    const container = getContainer();
    const popup = getPopup();
    if (typeof params.willOpen === 'function') {
      params.willOpen(popup);
    }
    globalState.eventEmitter.emit('willOpen', popup);
    const bodyStyles = window.getComputedStyle(document.body);
    const initialBodyOverflow = bodyStyles.overflowY;
    addClasses(container, popup, params);

    // scrolling is 'hidden' until animation is done, after that 'auto'
    setTimeout(() => {
      setScrollingVisibility(container, popup);
    }, SHOW_CLASS_TIMEOUT);
    if (isModal()) {
      fixScrollContainer(container, params.scrollbarPadding, initialBodyOverflow);
      setAriaHidden();
    }
    if (!isToast() && !globalState.previousActiveElement) {
      globalState.previousActiveElement = document.activeElement;
    }
    if (typeof params.didOpen === 'function') {
      setTimeout(() => params.didOpen(popup));
    }
    globalState.eventEmitter.emit('didOpen', popup);
    removeClass(container, swalClasses['no-transition']);
  };

  /**
   * @param {AnimationEvent} event
   */
  const swalOpenAnimationFinished = event => {
    const popup = getPopup();
    if (event.target !== popup) {
      return;
    }
    const container = getContainer();
    popup.removeEventListener('animationend', swalOpenAnimationFinished);
    popup.removeEventListener('transitionend', swalOpenAnimationFinished);
    container.style.overflowY = 'auto';
  };

  /**
   * @param {HTMLElement} container
   * @param {HTMLElement} popup
   */
  const setScrollingVisibility = (container, popup) => {
    if (hasCssAnimation(popup)) {
      container.style.overflowY = 'hidden';
      popup.addEventListener('animationend', swalOpenAnimationFinished);
      popup.addEventListener('transitionend', swalOpenAnimationFinished);
    } else {
      container.style.overflowY = 'auto';
    }
  };

  /**
   * @param {HTMLElement} container
   * @param {boolean} scrollbarPadding
   * @param {string} initialBodyOverflow
   */
  const fixScrollContainer = (container, scrollbarPadding, initialBodyOverflow) => {
    iOSfix();
    if (scrollbarPadding && initialBodyOverflow !== 'hidden') {
      replaceScrollbarWithPadding(initialBodyOverflow);
    }

    // sweetalert2/issues/1247
    setTimeout(() => {
      container.scrollTop = 0;
    });
  };

  /**
   * @param {HTMLElement} container
   * @param {HTMLElement} popup
   * @param {SweetAlertOptions} params
   */
  const addClasses = (container, popup, params) => {
    addClass(container, params.showClass.backdrop);
    if (params.animation) {
      // this workaround with opacity is needed for https://github.com/sweetalert2/sweetalert2/issues/2059
      popup.style.setProperty('opacity', '0', 'important');
      show(popup, 'grid');
      setTimeout(() => {
        // Animate popup right after showing it
        addClass(popup, params.showClass.popup);
        // and remove the opacity workaround
        popup.style.removeProperty('opacity');
      }, SHOW_CLASS_TIMEOUT); // 10ms in order to fix #2062
    } else {
      show(popup, 'grid');
    }
    addClass([document.documentElement, document.body], swalClasses.shown);
    if (params.heightAuto && params.backdrop && !params.toast) {
      addClass([document.documentElement, document.body], swalClasses['height-auto']);
    }
  };
  var defaultInputValidators = {
    /**
     * @param {string} string
     * @param {string} [validationMessage]
     * @returns {Promise<string | void>}
     */
    email: (string, validationMessage) => {
      return /^[a-zA-Z0-9.+_'-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9-]+$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid email address');
    },
    /**
     * @param {string} string
     * @param {string} [validationMessage]
     * @returns {Promise<string | void>}
     */
    url: (string, validationMessage) => {
      // taken from https://stackoverflow.com/a/3809435 with a small change from #1306 and #2013
      return /^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-z]{2,63}\b([-a-zA-Z0-9@:%_+.~#?&/=]*)$/.test(string) ? Promise.resolve() : Promise.resolve(validationMessage || 'Invalid URL');
    }
  };

  /**
   * @param {SweetAlertOptions} params
   */
  function setDefaultInputValidators(params) {
    // Use default `inputValidator` for supported input types if not provided
    if (params.inputValidator) {
      return;
    }
    if (params.input === 'email') {
      params.inputValidator = defaultInputValidators['email'];
    }
    if (params.input === 'url') {
      params.inputValidator = defaultInputValidators['url'];
    }
  }

  /**
   * @param {SweetAlertOptions} params
   */
  function validateCustomTargetElement(params) {
    // Determine if the custom target element is valid
    if (!params.target || typeof params.target === 'string' && !document.querySelector(params.target) || typeof params.target !== 'string' && !params.target.appendChild) {
      warn('Target parameter is not valid, defaulting to "body"');
      params.target = 'body';
    }
  }

  /**
   * Set type, text and actions on popup
   *
   * @param {SweetAlertOptions} params
   */
  function setParameters(params) {
    setDefaultInputValidators(params);

    // showLoaderOnConfirm && preConfirm
    if (params.showLoaderOnConfirm && !params.preConfirm) {
      warn('showLoaderOnConfirm is set to true, but preConfirm is not defined.\n' + 'showLoaderOnConfirm should be used together with preConfirm, see usage example:\n' + 'https://sweetalert2.github.io/#ajax-request');
    }
    validateCustomTargetElement(params);

    // Replace newlines with <br> in title
    if (typeof params.title === 'string') {
      params.title = params.title.split('\n').join('<br />');
    }
    init(params);
  }

  /** @type {SweetAlert} */
  let currentInstance;
  var _promise = /*#__PURE__*/new WeakMap();
  class SweetAlert {
    /**
     * @param {...any} args
     * @this {SweetAlert}
     */
    constructor(...args) {
      /**
       * @type {Promise<SweetAlertResult>}
       */
      _classPrivateFieldInitSpec(this, _promise, void 0);
      // Prevent run in Node env
      if (typeof window === 'undefined') {
        return;
      }
      currentInstance = this;

      // @ts-ignore
      const outerParams = Object.freeze(this.constructor.argsToParams(args));

      /** @type {Readonly<SweetAlertOptions>} */
      this.params = outerParams;

      /** @type {boolean} */
      this.isAwaitingPromise = false;
      _classPrivateFieldSet2(_promise, this, this._main(currentInstance.params));
    }
    _main(userParams, mixinParams = {}) {
      showWarningsForParams(Object.assign({}, mixinParams, userParams));
      if (globalState.currentInstance) {
        const swalPromiseResolve = privateMethods.swalPromiseResolve.get(globalState.currentInstance);
        const {
          isAwaitingPromise
        } = globalState.currentInstance;
        globalState.currentInstance._destroy();
        if (!isAwaitingPromise) {
          swalPromiseResolve({
            isDismissed: true
          });
        }
        if (isModal()) {
          unsetAriaHidden();
        }
      }
      globalState.currentInstance = currentInstance;
      const innerParams = prepareParams(userParams, mixinParams);
      setParameters(innerParams);
      Object.freeze(innerParams);

      // clear the previous timer
      if (globalState.timeout) {
        globalState.timeout.stop();
        delete globalState.timeout;
      }

      // clear the restore focus timeout
      clearTimeout(globalState.restoreFocusTimeout);
      const domCache = populateDomCache(currentInstance);
      render(currentInstance, innerParams);
      privateProps.innerParams.set(currentInstance, innerParams);
      return swalPromise(currentInstance, domCache, innerParams);
    }

    // `catch` cannot be the name of a module export, so we define our thenable methods here instead
    then(onFulfilled) {
      return _classPrivateFieldGet2(_promise, this).then(onFulfilled);
    }
    finally(onFinally) {
      return _classPrivateFieldGet2(_promise, this).finally(onFinally);
    }
  }

  /**
   * @param {SweetAlert} instance
   * @param {DomCache} domCache
   * @param {SweetAlertOptions} innerParams
   * @returns {Promise}
   */
  const swalPromise = (instance, domCache, innerParams) => {
    return new Promise((resolve, reject) => {
      // functions to handle all closings/dismissals
      /**
       * @param {DismissReason} dismiss
       */
      const dismissWith = dismiss => {
        instance.close({
          isDismissed: true,
          dismiss
        });
      };
      privateMethods.swalPromiseResolve.set(instance, resolve);
      privateMethods.swalPromiseReject.set(instance, reject);
      domCache.confirmButton.onclick = () => {
        handleConfirmButtonClick(instance);
      };
      domCache.denyButton.onclick = () => {
        handleDenyButtonClick(instance);
      };
      domCache.cancelButton.onclick = () => {
        handleCancelButtonClick(instance, dismissWith);
      };
      domCache.closeButton.onclick = () => {
        dismissWith(DismissReason.close);
      };
      handlePopupClick(innerParams, domCache, dismissWith);
      addKeydownHandler(globalState, innerParams, dismissWith);
      handleInputOptionsAndValue(instance, innerParams);
      openPopup(innerParams);
      setupTimer(globalState, innerParams, dismissWith);
      initFocus(domCache, innerParams);

      // Scroll container to top on open (#1247, #1946)
      setTimeout(() => {
        domCache.container.scrollTop = 0;
      });
    });
  };

  /**
   * @param {SweetAlertOptions} userParams
   * @param {SweetAlertOptions} mixinParams
   * @returns {SweetAlertOptions}
   */
  const prepareParams = (userParams, mixinParams) => {
    const templateParams = getTemplateParams(userParams);
    const params = Object.assign({}, defaultParams, mixinParams, templateParams, userParams); // precedence is described in #2131
    params.showClass = Object.assign({}, defaultParams.showClass, params.showClass);
    params.hideClass = Object.assign({}, defaultParams.hideClass, params.hideClass);
    if (params.animation === false) {
      params.showClass = {
        backdrop: 'swal2-noanimation'
      };
      params.hideClass = {};
    }
    return params;
  };

  /**
   * @param {SweetAlert} instance
   * @returns {DomCache}
   */
  const populateDomCache = instance => {
    const domCache = {
      popup: getPopup(),
      container: getContainer(),
      actions: getActions(),
      confirmButton: getConfirmButton(),
      denyButton: getDenyButton(),
      cancelButton: getCancelButton(),
      loader: getLoader(),
      closeButton: getCloseButton(),
      validationMessage: getValidationMessage(),
      progressSteps: getProgressSteps()
    };
    privateProps.domCache.set(instance, domCache);
    return domCache;
  };

  /**
   * @param {GlobalState} globalState
   * @param {SweetAlertOptions} innerParams
   * @param {Function} dismissWith
   */
  const setupTimer = (globalState, innerParams, dismissWith) => {
    const timerProgressBar = getTimerProgressBar();
    hide(timerProgressBar);
    if (innerParams.timer) {
      globalState.timeout = new Timer(() => {
        dismissWith('timer');
        delete globalState.timeout;
      }, innerParams.timer);
      if (innerParams.timerProgressBar) {
        show(timerProgressBar);
        applyCustomClass(timerProgressBar, innerParams, 'timerProgressBar');
        setTimeout(() => {
          if (globalState.timeout && globalState.timeout.running) {
            // timer can be already stopped or unset at this point
            animateTimerProgressBar(innerParams.timer);
          }
        });
      }
    }
  };

  /**
   * Initialize focus in the popup:
   *
   * 1. If `toast` is `true`, don't steal focus from the document.
   * 2. Else if there is an [autofocus] element, focus it.
   * 3. Else if `focusConfirm` is `true` and confirm button is visible, focus it.
   * 4. Else if `focusDeny` is `true` and deny button is visible, focus it.
   * 5. Else if `focusCancel` is `true` and cancel button is visible, focus it.
   * 6. Else focus the first focusable element in a popup (if any).
   *
   * @param {DomCache} domCache
   * @param {SweetAlertOptions} innerParams
   */
  const initFocus = (domCache, innerParams) => {
    if (innerParams.toast) {
      return;
    }
    // TODO: this is dumb, remove `allowEnterKey` param in the next major version
    if (!callIfFunction(innerParams.allowEnterKey)) {
      warnAboutDeprecation('allowEnterKey');
      blurActiveElement();
      return;
    }
    if (focusAutofocus(domCache)) {
      return;
    }
    if (focusButton(domCache, innerParams)) {
      return;
    }
    setFocus(-1, 1);
  };

  /**
   * @param {DomCache} domCache
   * @returns {boolean}
   */
  const focusAutofocus = domCache => {
    const autofocusElements = Array.from(domCache.popup.querySelectorAll('[autofocus]'));
    for (const autofocusElement of autofocusElements) {
      if (autofocusElement instanceof HTMLElement && isVisible$1(autofocusElement)) {
        autofocusElement.focus();
        return true;
      }
    }
    return false;
  };

  /**
   * @param {DomCache} domCache
   * @param {SweetAlertOptions} innerParams
   * @returns {boolean}
   */
  const focusButton = (domCache, innerParams) => {
    if (innerParams.focusDeny && isVisible$1(domCache.denyButton)) {
      domCache.denyButton.focus();
      return true;
    }
    if (innerParams.focusCancel && isVisible$1(domCache.cancelButton)) {
      domCache.cancelButton.focus();
      return true;
    }
    if (innerParams.focusConfirm && isVisible$1(domCache.confirmButton)) {
      domCache.confirmButton.focus();
      return true;
    }
    return false;
  };
  const blurActiveElement = () => {
    if (document.activeElement instanceof HTMLElement && typeof document.activeElement.blur === 'function') {
      document.activeElement.blur();
    }
  };

  // Assign instance methods from src/instanceMethods/*.js to prototype
  SweetAlert.prototype.disableButtons = disableButtons;
  SweetAlert.prototype.enableButtons = enableButtons;
  SweetAlert.prototype.getInput = getInput;
  SweetAlert.prototype.disableInput = disableInput;
  SweetAlert.prototype.enableInput = enableInput;
  SweetAlert.prototype.hideLoading = hideLoading;
  SweetAlert.prototype.disableLoading = hideLoading;
  SweetAlert.prototype.showValidationMessage = showValidationMessage;
  SweetAlert.prototype.resetValidationMessage = resetValidationMessage;
  SweetAlert.prototype.close = close;
  SweetAlert.prototype.closePopup = close;
  SweetAlert.prototype.closeModal = close;
  SweetAlert.prototype.closeToast = close;
  SweetAlert.prototype.rejectPromise = rejectPromise;
  SweetAlert.prototype.update = update;
  SweetAlert.prototype._destroy = _destroy;

  // Assign static methods from src/staticMethods/*.js to constructor
  Object.assign(SweetAlert, staticMethods);

  // Proxy to instance methods to constructor, for now, for backwards compatibility
  Object.keys(instanceMethods).forEach(key => {
    /**
     * @param {...any} args
     * @returns {any | undefined}
     */
    SweetAlert[key] = function (...args) {
      if (currentInstance && currentInstance[key]) {
        return currentInstance[key](...args);
      }
      return null;
    };
  });
  SweetAlert.DismissReason = DismissReason;
  SweetAlert.version = '11.23.0';
  const Swal = SweetAlert;
  // @ts-ignore
  Swal.default = Swal;
  return Swal;
});
if (typeof this !== 'undefined' && this.Sweetalert2) {
  this.swal = this.sweetAlert = this.Swal = this.SweetAlert = this.Sweetalert2;
}
"undefined" != typeof document && function (e, t) {
  var n = e.createElement("style");
  if (e.getElementsByTagName("head")[0].appendChild(n), n.styleSheet) n.styleSheet.disabled || (n.styleSheet.cssText = t);else try {
    n.innerHTML = t;
  } catch (e) {
    n.innerText = t;
  }
}(document, ":root{--swal2-outline: 0 0 0 3px rgba(100, 150, 200, 0.5);--swal2-container-padding: 0.625em;--swal2-backdrop: rgba(0, 0, 0, 0.4);--swal2-backdrop-transition: background-color 0.1s;--swal2-width: 32em;--swal2-padding: 0 0 1.25em;--swal2-border: none;--swal2-border-radius: 0.3125rem;--swal2-background: white;--swal2-color: #545454;--swal2-show-animation: swal2-show 0.3s;--swal2-hide-animation: swal2-hide 0.15s forwards;--swal2-icon-zoom: 1;--swal2-icon-animations: true;--swal2-title-padding: 0.8em 1em 0;--swal2-html-container-padding: 1em 1.6em 0.3em;--swal2-input-border: 1px solid #d9d9d9;--swal2-input-border-radius: 0.1875em;--swal2-input-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-background: transparent;--swal2-input-transition: border-color 0.2s, box-shadow 0.2s;--swal2-input-hover-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px transparent;--swal2-input-focus-border: 1px solid #b4dbed;--swal2-input-focus-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.06), 0 0 0 3px $swal2-outline-color;--swal2-progress-step-background: #add8e6;--swal2-validation-message-background: #f0f0f0;--swal2-validation-message-color: #666;--swal2-footer-border-color: #eee;--swal2-footer-background: transparent;--swal2-footer-color: inherit;--swal2-timer-progress-bar-background: rgba(0, 0, 0, 0.3);--swal2-close-button-position: initial;--swal2-close-button-inset: auto;--swal2-close-button-font-size: 2.5em;--swal2-close-button-color: #ccc;--swal2-close-button-transition: color 0.2s, box-shadow 0.2s;--swal2-close-button-outline: initial;--swal2-close-button-box-shadow: inset 0 0 0 3px transparent;--swal2-close-button-focus-box-shadow: inset var(--swal2-outline);--swal2-close-button-hover-transform: none;--swal2-actions-justify-content: center;--swal2-actions-width: auto;--swal2-actions-margin: 1.25em auto 0;--swal2-actions-padding: 0;--swal2-actions-border-radius: 0;--swal2-actions-background: transparent;--swal2-action-button-transition: background-color 0.2s, box-shadow 0.2s;--swal2-action-button-hover: black 10%;--swal2-action-button-active: black 10%;--swal2-confirm-button-box-shadow: none;--swal2-confirm-button-border-radius: 0.25em;--swal2-confirm-button-background-color: #7066e0;--swal2-confirm-button-color: #fff;--swal2-deny-button-box-shadow: none;--swal2-deny-button-border-radius: 0.25em;--swal2-deny-button-background-color: #dc3741;--swal2-deny-button-color: #fff;--swal2-cancel-button-box-shadow: none;--swal2-cancel-button-border-radius: 0.25em;--swal2-cancel-button-background-color: #6e7881;--swal2-cancel-button-color: #fff;--swal2-toast-show-animation: swal2-toast-show 0.5s;--swal2-toast-hide-animation: swal2-toast-hide 0.1s forwards;--swal2-toast-border: none;--swal2-toast-box-shadow: 0 0 1px hsl(0deg 0% 0% / 0.075), 0 1px 2px hsl(0deg 0% 0% / 0.075), 1px 2px 4px hsl(0deg 0% 0% / 0.075), 1px 3px 8px hsl(0deg 0% 0% / 0.075), 2px 4px 16px hsl(0deg 0% 0% / 0.075)}[data-swal2-theme=dark]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}@media(prefers-color-scheme: dark){[data-swal2-theme=auto]{--swal2-dark-theme-black: #19191a;--swal2-dark-theme-white: #e1e1e1;--swal2-background: var(--swal2-dark-theme-black);--swal2-color: var(--swal2-dark-theme-white);--swal2-footer-border-color: #555;--swal2-input-background: color-mix(in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10%);--swal2-validation-message-background: color-mix( in srgb, var(--swal2-dark-theme-black), var(--swal2-dark-theme-white) 10% );--swal2-validation-message-color: var(--swal2-dark-theme-white);--swal2-timer-progress-bar-background: rgba(255, 255, 255, 0.7)}}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow:hidden}body.swal2-height-auto{height:auto !important}body.swal2-no-backdrop .swal2-container{background-color:rgba(0,0,0,0) !important;pointer-events:none}body.swal2-no-backdrop .swal2-container .swal2-popup{pointer-events:all}body.swal2-no-backdrop .swal2-container .swal2-modal{box-shadow:0 0 10px var(--swal2-backdrop)}body.swal2-toast-shown .swal2-container{box-sizing:border-box;width:360px;max-width:100%;background-color:rgba(0,0,0,0);pointer-events:none}body.swal2-toast-shown .swal2-container.swal2-top{inset:0 auto auto 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-top-end,body.swal2-toast-shown .swal2-container.swal2-top-right{inset:0 0 auto auto}body.swal2-toast-shown .swal2-container.swal2-top-start,body.swal2-toast-shown .swal2-container.swal2-top-left{inset:0 auto auto 0}body.swal2-toast-shown .swal2-container.swal2-center-start,body.swal2-toast-shown .swal2-container.swal2-center-left{inset:50% auto auto 0;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-center{inset:50% auto auto 50%;transform:translate(-50%, -50%)}body.swal2-toast-shown .swal2-container.swal2-center-end,body.swal2-toast-shown .swal2-container.swal2-center-right{inset:50% 0 auto auto;transform:translateY(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-start,body.swal2-toast-shown .swal2-container.swal2-bottom-left{inset:auto auto 0 0}body.swal2-toast-shown .swal2-container.swal2-bottom{inset:auto auto 0 50%;transform:translateX(-50%)}body.swal2-toast-shown .swal2-container.swal2-bottom-end,body.swal2-toast-shown .swal2-container.swal2-bottom-right{inset:auto 0 0 auto}@media print{body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown){overflow-y:scroll !important}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop,.swal2-toast-shown) .swal2-container{position:static !important}}div:where(.swal2-container){display:grid;position:fixed;z-index:1060;inset:0;box-sizing:border-box;grid-template-areas:\"top-start     top            top-end\" \"center-start  center         center-end\" \"bottom-start  bottom-center  bottom-end\";grid-template-rows:minmax(min-content, auto) minmax(min-content, auto) minmax(min-content, auto);height:100%;padding:var(--swal2-container-padding);overflow-x:hidden;transition:var(--swal2-backdrop-transition);-webkit-overflow-scrolling:touch}div:where(.swal2-container).swal2-backdrop-show,div:where(.swal2-container).swal2-noanimation{background:var(--swal2-backdrop)}div:where(.swal2-container).swal2-backdrop-hide{background:rgba(0,0,0,0) !important}div:where(.swal2-container).swal2-top-start,div:where(.swal2-container).swal2-center-start,div:where(.swal2-container).swal2-bottom-start{grid-template-columns:minmax(0, 1fr) auto auto}div:where(.swal2-container).swal2-top,div:where(.swal2-container).swal2-center,div:where(.swal2-container).swal2-bottom{grid-template-columns:auto minmax(0, 1fr) auto}div:where(.swal2-container).swal2-top-end,div:where(.swal2-container).swal2-center-end,div:where(.swal2-container).swal2-bottom-end{grid-template-columns:auto auto minmax(0, 1fr)}div:where(.swal2-container).swal2-top-start>.swal2-popup{align-self:start}div:where(.swal2-container).swal2-top>.swal2-popup{grid-column:2;place-self:start center}div:where(.swal2-container).swal2-top-end>.swal2-popup,div:where(.swal2-container).swal2-top-right>.swal2-popup{grid-column:3;place-self:start end}div:where(.swal2-container).swal2-center-start>.swal2-popup,div:where(.swal2-container).swal2-center-left>.swal2-popup{grid-row:2;align-self:center}div:where(.swal2-container).swal2-center>.swal2-popup{grid-column:2;grid-row:2;place-self:center center}div:where(.swal2-container).swal2-center-end>.swal2-popup,div:where(.swal2-container).swal2-center-right>.swal2-popup{grid-column:3;grid-row:2;place-self:center end}div:where(.swal2-container).swal2-bottom-start>.swal2-popup,div:where(.swal2-container).swal2-bottom-left>.swal2-popup{grid-column:1;grid-row:3;align-self:end}div:where(.swal2-container).swal2-bottom>.swal2-popup{grid-column:2;grid-row:3;place-self:end center}div:where(.swal2-container).swal2-bottom-end>.swal2-popup,div:where(.swal2-container).swal2-bottom-right>.swal2-popup{grid-column:3;grid-row:3;place-self:end end}div:where(.swal2-container).swal2-grow-row>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-column:1/4;width:100%}div:where(.swal2-container).swal2-grow-column>.swal2-popup,div:where(.swal2-container).swal2-grow-fullscreen>.swal2-popup{grid-row:1/4;align-self:stretch}div:where(.swal2-container).swal2-no-transition{transition:none !important}div:where(.swal2-container)[popover]{width:auto;border:0}div:where(.swal2-container) div:where(.swal2-popup){display:none;position:relative;box-sizing:border-box;grid-template-columns:minmax(0, 100%);width:var(--swal2-width);max-width:100%;padding:var(--swal2-padding);border:var(--swal2-border);border-radius:var(--swal2-border-radius);background:var(--swal2-background);color:var(--swal2-color);font-family:inherit;font-size:1rem;container-name:swal2-popup}div:where(.swal2-container) div:where(.swal2-popup):focus{outline:none}div:where(.swal2-container) div:where(.swal2-popup).swal2-loading{overflow-y:hidden}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable{cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-draggable div:where(.swal2-icon){cursor:grab}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging{cursor:grabbing}div:where(.swal2-container) div:where(.swal2-popup).swal2-dragging div:where(.swal2-icon){cursor:grabbing}div:where(.swal2-container) h2:where(.swal2-title){position:relative;max-width:100%;margin:0;padding:var(--swal2-title-padding);color:inherit;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;overflow-wrap:break-word;cursor:initial}div:where(.swal2-container) div:where(.swal2-actions){display:flex;z-index:1;box-sizing:border-box;flex-wrap:wrap;align-items:center;justify-content:var(--swal2-actions-justify-content);width:var(--swal2-actions-width);margin:var(--swal2-actions-margin);padding:var(--swal2-actions-padding);border-radius:var(--swal2-actions-border-radius);background:var(--swal2-actions-background)}div:where(.swal2-container) div:where(.swal2-loader){display:none;align-items:center;justify-content:center;width:2.2em;height:2.2em;margin:0 1.875em;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;border-width:.25em;border-style:solid;border-radius:100%;border-color:#2778c4 rgba(0,0,0,0) #2778c4 rgba(0,0,0,0)}div:where(.swal2-container) button:where(.swal2-styled){margin:.3125em;padding:.625em 1.1em;transition:var(--swal2-action-button-transition);border:none;box-shadow:0 0 0 3px rgba(0,0,0,0);font-weight:500}div:where(.swal2-container) button:where(.swal2-styled):not([disabled]){cursor:pointer}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm){border-radius:var(--swal2-confirm-button-border-radius);background:initial;background-color:var(--swal2-confirm-button-background-color);box-shadow:var(--swal2-confirm-button-box-shadow);color:var(--swal2-confirm-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):hover{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-confirm):active{background-color:color-mix(in srgb, var(--swal2-confirm-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny){border-radius:var(--swal2-deny-button-border-radius);background:initial;background-color:var(--swal2-deny-button-background-color);box-shadow:var(--swal2-deny-button-box-shadow);color:var(--swal2-deny-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):hover{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-deny):active{background-color:color-mix(in srgb, var(--swal2-deny-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel){border-radius:var(--swal2-cancel-button-border-radius);background:initial;background-color:var(--swal2-cancel-button-background-color);box-shadow:var(--swal2-cancel-button-box-shadow);color:var(--swal2-cancel-button-color);font-size:1em}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):hover{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-hover))}div:where(.swal2-container) button:where(.swal2-styled):where(.swal2-cancel):active{background-color:color-mix(in srgb, var(--swal2-cancel-button-background-color), var(--swal2-action-button-active))}div:where(.swal2-container) button:where(.swal2-styled):focus-visible{outline:none;box-shadow:var(--swal2-action-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-styled)[disabled]:not(.swal2-loading){opacity:.4}div:where(.swal2-container) button:where(.swal2-styled)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-footer){margin:1em 0 0;padding:1em 1em 0;border-top:1px solid var(--swal2-footer-border-color);background:var(--swal2-footer-background);color:var(--swal2-footer-color);font-size:1em;text-align:center;cursor:initial}div:where(.swal2-container) .swal2-timer-progress-bar-container{position:absolute;right:0;bottom:0;left:0;grid-column:auto !important;overflow:hidden;border-bottom-right-radius:var(--swal2-border-radius);border-bottom-left-radius:var(--swal2-border-radius)}div:where(.swal2-container) div:where(.swal2-timer-progress-bar){width:100%;height:.25em;background:var(--swal2-timer-progress-bar-background)}div:where(.swal2-container) img:where(.swal2-image){max-width:100%;margin:2em auto 1em;cursor:initial}div:where(.swal2-container) button:where(.swal2-close){position:var(--swal2-close-button-position);inset:var(--swal2-close-button-inset);z-index:2;align-items:center;justify-content:center;width:1.2em;height:1.2em;margin-top:0;margin-right:0;margin-bottom:-1.2em;padding:0;overflow:hidden;transition:var(--swal2-close-button-transition);border:none;border-radius:var(--swal2-border-radius);outline:var(--swal2-close-button-outline);background:rgba(0,0,0,0);color:var(--swal2-close-button-color);font-family:monospace;font-size:var(--swal2-close-button-font-size);cursor:pointer;justify-self:end}div:where(.swal2-container) button:where(.swal2-close):hover{transform:var(--swal2-close-button-hover-transform);background:rgba(0,0,0,0);color:#f27474}div:where(.swal2-container) button:where(.swal2-close):focus-visible{outline:none;box-shadow:var(--swal2-close-button-focus-box-shadow)}div:where(.swal2-container) button:where(.swal2-close)::-moz-focus-inner{border:0}div:where(.swal2-container) div:where(.swal2-html-container){z-index:1;justify-content:center;margin:0;padding:var(--swal2-html-container-padding);overflow:auto;color:inherit;font-size:1.125em;font-weight:normal;line-height:normal;text-align:center;overflow-wrap:break-word;word-break:break-word;cursor:initial}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea),div:where(.swal2-container) select:where(.swal2-select),div:where(.swal2-container) div:where(.swal2-radio),div:where(.swal2-container) label:where(.swal2-checkbox){margin:1em 2em 3px}div:where(.swal2-container) input:where(.swal2-input),div:where(.swal2-container) input:where(.swal2-file),div:where(.swal2-container) textarea:where(.swal2-textarea){box-sizing:border-box;width:auto;transition:var(--swal2-input-transition);border:var(--swal2-input-border);border-radius:var(--swal2-input-border-radius);background:var(--swal2-input-background);box-shadow:var(--swal2-input-box-shadow);color:inherit;font-size:1.125em}div:where(.swal2-container) input:where(.swal2-input).swal2-inputerror,div:where(.swal2-container) input:where(.swal2-file).swal2-inputerror,div:where(.swal2-container) textarea:where(.swal2-textarea).swal2-inputerror{border-color:#f27474 !important;box-shadow:0 0 2px #f27474 !important}div:where(.swal2-container) input:where(.swal2-input):hover,div:where(.swal2-container) input:where(.swal2-file):hover,div:where(.swal2-container) textarea:where(.swal2-textarea):hover{box-shadow:var(--swal2-input-hover-box-shadow)}div:where(.swal2-container) input:where(.swal2-input):focus,div:where(.swal2-container) input:where(.swal2-file):focus,div:where(.swal2-container) textarea:where(.swal2-textarea):focus{border:var(--swal2-input-focus-border);outline:none;box-shadow:var(--swal2-input-focus-box-shadow)}div:where(.swal2-container) input:where(.swal2-input)::placeholder,div:where(.swal2-container) input:where(.swal2-file)::placeholder,div:where(.swal2-container) textarea:where(.swal2-textarea)::placeholder{color:#ccc}div:where(.swal2-container) .swal2-range{margin:1em 2em 3px;background:var(--swal2-background)}div:where(.swal2-container) .swal2-range input{width:80%}div:where(.swal2-container) .swal2-range output{width:20%;color:inherit;font-weight:600;text-align:center}div:where(.swal2-container) .swal2-range input,div:where(.swal2-container) .swal2-range output{height:2.625em;padding:0;font-size:1.125em;line-height:2.625em}div:where(.swal2-container) .swal2-input{height:2.625em;padding:0 .75em}div:where(.swal2-container) .swal2-file{width:75%;margin-right:auto;margin-left:auto;background:var(--swal2-input-background);font-size:1.125em}div:where(.swal2-container) .swal2-textarea{height:6.75em;padding:.75em}div:where(.swal2-container) .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;background:var(--swal2-input-background);color:inherit;font-size:1.125em}div:where(.swal2-container) .swal2-radio,div:where(.swal2-container) .swal2-checkbox{align-items:center;justify-content:center;background:var(--swal2-background);color:inherit}div:where(.swal2-container) .swal2-radio label,div:where(.swal2-container) .swal2-checkbox label{margin:0 .6em;font-size:1.125em}div:where(.swal2-container) .swal2-radio input,div:where(.swal2-container) .swal2-checkbox input{flex-shrink:0;margin:0 .4em}div:where(.swal2-container) label:where(.swal2-input-label){display:flex;justify-content:center;margin:1em auto 0}div:where(.swal2-container) div:where(.swal2-validation-message){align-items:center;justify-content:center;margin:1em 0 0;padding:.625em;overflow:hidden;background:var(--swal2-validation-message-background);color:var(--swal2-validation-message-color);font-size:1em;font-weight:300}div:where(.swal2-container) div:where(.swal2-validation-message)::before{content:\"!\";display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center}div:where(.swal2-container) .swal2-progress-steps{flex-wrap:wrap;align-items:center;max-width:100%;margin:1.25em auto;padding:0;background:rgba(0,0,0,0);font-weight:600}div:where(.swal2-container) .swal2-progress-steps li{display:inline-block;position:relative}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step{z-index:20;flex-shrink:0;width:2em;height:2em;border-radius:2em;background:#2778c4;color:#fff;line-height:2em;text-align:center}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#2778c4}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step{background:var(--swal2-progress-step-background);color:#fff}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step~.swal2-progress-step-line{background:var(--swal2-progress-step-background)}div:where(.swal2-container) .swal2-progress-steps .swal2-progress-step-line{z-index:10;flex-shrink:0;width:2.5em;height:.4em;margin:0 -1px;background:#2778c4}div:where(.swal2-icon){position:relative;box-sizing:content-box;justify-content:center;width:5em;height:5em;margin:2.5em auto .6em;zoom:var(--swal2-icon-zoom);border:.25em solid rgba(0,0,0,0);border-radius:50%;border-color:#000;font-family:inherit;line-height:5em;cursor:default;user-select:none}div:where(.swal2-icon) .swal2-icon-content{display:flex;align-items:center;font-size:3.75em}div:where(.swal2-icon).swal2-error{border-color:#f27474;color:#f27474}div:where(.swal2-icon).swal2-error .swal2-x-mark{position:relative;flex-grow:1}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-error.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-error.swal2-icon-show .swal2-x-mark{animation:swal2-animate-error-x-mark .5s}}div:where(.swal2-icon).swal2-warning{border-color:#f8bb86;color:#f8bb86}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-warning.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-warning.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .5s}}div:where(.swal2-icon).swal2-info{border-color:#3fc3ee;color:#3fc3ee}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-info.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-info.swal2-icon-show .swal2-icon-content{animation:swal2-animate-i-mark .8s}}div:where(.swal2-icon).swal2-question{border-color:#87adbd;color:#87adbd}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-question.swal2-icon-show{animation:swal2-animate-error-icon .5s}div:where(.swal2-icon).swal2-question.swal2-icon-show .swal2-icon-content{animation:swal2-animate-question-mark .8s}}div:where(.swal2-icon).swal2-success{border-color:#a5dc86;color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;border-radius:50%}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.4375em;left:-2.0635em;transform:rotate(-45deg);transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}div:where(.swal2-icon).swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.6875em;left:1.875em;transform:rotate(-45deg);transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}div:where(.swal2-icon).swal2-success .swal2-success-ring{position:absolute;z-index:2;top:-0.25em;left:-0.25em;box-sizing:content-box;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%}div:where(.swal2-icon).swal2-success .swal2-success-fix{position:absolute;z-index:1;top:.5em;left:1.625em;width:.4375em;height:5.625em;transform:rotate(-45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line]{display:block;position:absolute;z-index:2;height:.3125em;border-radius:.125em;background-color:#a5dc86}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.8125em;width:1.5625em;transform:rotate(45deg)}div:where(.swal2-icon).swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;transform:rotate(-45deg)}@container swal2-popup style(--swal2-icon-animations:true){div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-animate-success-line-tip .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-animate-success-line-long .75s}div:where(.swal2-icon).swal2-success.swal2-icon-show .swal2-success-circular-line-right{animation:swal2-rotate-success-circular-line 4.25s ease-in}}[class^=swal2]{-webkit-tap-highlight-color:rgba(0,0,0,0)}.swal2-show{animation:var(--swal2-show-animation)}.swal2-hide{animation:var(--swal2-hide-animation)}.swal2-noanimation{transition:none}.swal2-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}.swal2-rtl .swal2-close{margin-right:initial;margin-left:0}.swal2-rtl .swal2-timer-progress-bar{right:0;left:auto}.swal2-toast{box-sizing:border-box;grid-column:1/4 !important;grid-row:1/4 !important;grid-template-columns:min-content auto min-content;padding:1em;overflow-y:hidden;border:var(--swal2-toast-border);background:var(--swal2-background);box-shadow:var(--swal2-toast-box-shadow);pointer-events:all}.swal2-toast>*{grid-column:2}.swal2-toast h2:where(.swal2-title){margin:.5em 1em;padding:0;font-size:1em;text-align:initial}.swal2-toast .swal2-loading{justify-content:center}.swal2-toast input:where(.swal2-input){height:2em;margin:.5em;font-size:1em}.swal2-toast .swal2-validation-message{font-size:1em}.swal2-toast div:where(.swal2-footer){margin:.5em 0 0;padding:.5em 0 0;font-size:.8em}.swal2-toast button:where(.swal2-close){grid-column:3/3;grid-row:1/99;align-self:center;width:.8em;height:.8em;margin:0;font-size:2em}.swal2-toast div:where(.swal2-html-container){margin:.5em 1em;padding:0;overflow:initial;font-size:1em;text-align:initial}.swal2-toast div:where(.swal2-html-container):empty{padding:0}.swal2-toast .swal2-loader{grid-column:1;grid-row:1/99;align-self:center;width:2em;height:2em;margin:.25em}.swal2-toast .swal2-icon{grid-column:1;grid-row:1/99;align-self:center;width:2em;min-width:2em;height:2em;margin:0 .5em 0 0}.swal2-toast .swal2-icon .swal2-icon-content{display:flex;align-items:center;font-size:1.8em;font-weight:bold}.swal2-toast .swal2-icon.swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line]{top:.875em;width:1.375em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:.3125em}.swal2-toast .swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:.3125em}.swal2-toast div:where(.swal2-actions){justify-content:flex-start;height:auto;margin:0;margin-top:.5em;padding:0 .5em}.swal2-toast button:where(.swal2-styled){margin:.25em .5em;padding:.4em .6em;font-size:1em}.swal2-toast .swal2-success{border-color:#a5dc86}.swal2-toast .swal2-success [class^=swal2-success-circular-line]{position:absolute;width:1.6em;height:3em;border-radius:50%}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=left]{top:-0.8em;left:-0.5em;transform:rotate(-45deg);transform-origin:2em 2em;border-radius:4em 0 0 4em}.swal2-toast .swal2-success [class^=swal2-success-circular-line][class$=right]{top:-0.25em;left:.9375em;transform-origin:0 1.5em;border-radius:0 4em 4em 0}.swal2-toast .swal2-success .swal2-success-ring{width:2em;height:2em}.swal2-toast .swal2-success .swal2-success-fix{top:0;left:.4375em;width:.4375em;height:2.6875em}.swal2-toast .swal2-success [class^=swal2-success-line]{height:.3125em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=tip]{top:1.125em;left:.1875em;width:.75em}.swal2-toast .swal2-success [class^=swal2-success-line][class$=long]{top:.9375em;right:.1875em;width:1.375em}@container swal2-popup style(--swal2-icon-animations:true){.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-tip{animation:swal2-toast-animate-success-line-tip .75s}.swal2-toast .swal2-success.swal2-icon-show .swal2-success-line-long{animation:swal2-toast-animate-success-line-long .75s}}.swal2-toast.swal2-show{animation:var(--swal2-toast-show-animation)}.swal2-toast.swal2-hide{animation:var(--swal2-toast-hide-animation)}@keyframes swal2-show{0%{transform:scale(0.7)}45%{transform:scale(1.05)}80%{transform:scale(0.95)}100%{transform:scale(1)}}@keyframes swal2-hide{0%{transform:scale(1);opacity:1}100%{transform:scale(0.5);opacity:0}}@keyframes swal2-animate-success-line-tip{0%{top:1.1875em;left:.0625em;width:0}54%{top:1.0625em;left:.125em;width:0}70%{top:2.1875em;left:-0.375em;width:3.125em}84%{top:3em;left:1.3125em;width:1.0625em}100%{top:2.8125em;left:.8125em;width:1.5625em}}@keyframes swal2-animate-success-line-long{0%{top:3.375em;right:2.875em;width:0}65%{top:3.375em;right:2.875em;width:0}84%{top:2.1875em;right:0;width:3.4375em}100%{top:2.375em;right:.5em;width:2.9375em}}@keyframes swal2-rotate-success-circular-line{0%{transform:rotate(-45deg)}5%{transform:rotate(-45deg)}12%{transform:rotate(-405deg)}100%{transform:rotate(-405deg)}}@keyframes swal2-animate-error-x-mark{0%{margin-top:1.625em;transform:scale(0.4);opacity:0}50%{margin-top:1.625em;transform:scale(0.4);opacity:0}80%{margin-top:-0.375em;transform:scale(1.15)}100%{margin-top:0;transform:scale(1);opacity:1}}@keyframes swal2-animate-error-icon{0%{transform:rotateX(100deg);opacity:0}100%{transform:rotateX(0deg);opacity:1}}@keyframes swal2-rotate-loading{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}@keyframes swal2-animate-question-mark{0%{transform:rotateY(-360deg)}100%{transform:rotateY(0)}}@keyframes swal2-animate-i-mark{0%{transform:rotateZ(45deg);opacity:0}25%{transform:rotateZ(-25deg);opacity:.4}50%{transform:rotateZ(15deg);opacity:.8}75%{transform:rotateZ(-5deg);opacity:1}100%{transform:rotateX(0);opacity:1}}@keyframes swal2-toast-show{0%{transform:translateY(-0.625em) rotateZ(2deg)}33%{transform:translateY(0) rotateZ(-2deg)}66%{transform:translateY(0.3125em) rotateZ(2deg)}100%{transform:translateY(0) rotateZ(0deg)}}@keyframes swal2-toast-hide{100%{transform:rotateZ(1deg);opacity:0}}@keyframes swal2-toast-animate-success-line-tip{0%{top:.5625em;left:.0625em;width:0}54%{top:.125em;left:.125em;width:0}70%{top:.625em;left:-0.25em;width:1.625em}84%{top:1.0625em;left:.75em;width:.5em}100%{top:1.125em;left:.1875em;width:.75em}}@keyframes swal2-toast-animate-success-line-long{0%{top:1.625em;right:1.375em;width:0}65%{top:1.25em;right:.9375em;width:0}84%{top:.9375em;right:0;width:1.125em}100%{top:.9375em;right:.1875em;width:1.375em}}");

/***/ }),

/***/ 24291:
/*!***************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/clients/WebSocketClient.js ***!
  \***************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ WebSocketClient)
/* harmony export */ });
/* harmony import */ var _utils_log_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../utils/log.js */ 37596);
function _classCallCheck(instance, Constructor) {
  if (!(instance instanceof Constructor)) {
    throw new TypeError("Cannot call a class as a function");
  }
}
function _defineProperties(target, props) {
  for (var i = 0; i < props.length; i++) {
    var descriptor = props[i];
    descriptor.enumerable = descriptor.enumerable || false;
    descriptor.configurable = true;
    if ("value" in descriptor) descriptor.writable = true;
    Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
  }
}
function _createClass(Constructor, protoProps, staticProps) {
  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  if (staticProps) _defineProperties(Constructor, staticProps);
  Object.defineProperty(Constructor, "prototype", {
    writable: false
  });
  return Constructor;
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}

var WebSocketClient = /*#__PURE__*/function () {
  /**
   * @param {string} url
   */
  function WebSocketClient(url) {
    _classCallCheck(this, WebSocketClient);
    this.client = new WebSocket(url);
    this.client.onerror = function (error) {
      _utils_log_js__WEBPACK_IMPORTED_MODULE_0__.log.error(error);
    };
  }

  /**
   * @param {(...args: any[]) => void} f
   */
  _createClass(WebSocketClient, [{
    key: "onOpen",
    value: function onOpen(f) {
      this.client.onopen = f;
    }

    /**
     * @param {(...args: any[]) => void} f
     */
  }, {
    key: "onClose",
    value: function onClose(f) {
      this.client.onclose = f;
    }

    // call f with the message string as the first argument
    /**
     * @param {(...args: any[]) => void} f
     */
  }, {
    key: "onMessage",
    value: function onMessage(f) {
      this.client.onmessage = function (e) {
        f(e.data);
      };
    }
  }]);
  return WebSocketClient;
}();


/***/ }),

/***/ 50886:
/*!******************************************************************************************************************************************************************************************************************************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/index.js?protocol=auto%3A&username=&password=&hostname=0.0.0.0&port=0&pathname=%2Fng-cli-ws&logging=info&overlay=%7B%22errors%22%3Atrue%2C%22warnings%22%3Afalse%2C%22runtimeErrors%22%3Afalse%7D&reconnect=10&hot=false&live-reload=true ***!
  \******************************************************************************************************************************************************************************************************************************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
var __resourceQuery = "?protocol=auto%3A&username=&password=&hostname=0.0.0.0&port=0&pathname=%2Fng-cli-ws&logging=info&overlay=%7B%22errors%22%3Atrue%2C%22warnings%22%3Afalse%2C%22runtimeErrors%22%3Afalse%7D&reconnect=10&hot=false&live-reload=true";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var webpack_hot_log_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webpack/hot/log.js */ 6366);
/* harmony import */ var webpack_hot_log_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webpack_hot_log_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _utils_stripAnsi_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/stripAnsi.js */ 44675);
/* harmony import */ var _utils_parseURL_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./utils/parseURL.js */ 48776);
/* harmony import */ var _socket_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./socket.js */ 52231);
/* harmony import */ var _overlay_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./overlay.js */ 91212);
/* harmony import */ var _utils_log_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils/log.js */ 37596);
/* harmony import */ var _utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./utils/sendMessage.js */ 62975);
/* harmony import */ var _utils_reloadApp_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./utils/reloadApp.js */ 31190);
/* harmony import */ var _utils_createSocketURL_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./utils/createSocketURL.js */ 24804);
function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object);
  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object);
    enumerableOnly && (symbols = symbols.filter(function (sym) {
      return Object.getOwnPropertyDescriptor(object, sym).enumerable;
    })), keys.push.apply(keys, symbols);
  }
  return keys;
}
function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = null != arguments[i] ? arguments[i] : {};
    i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
      _defineProperty(target, key, source[key]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
      Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
    });
  }
  return target;
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
/* global __resourceQuery, __webpack_hash__ */
/// <reference types="webpack/module" />










/**
 * @typedef {Object} OverlayOptions
 * @property {boolean | (error: Error) => boolean} [warnings]
 * @property {boolean | (error: Error) => boolean} [errors]
 * @property {boolean | (error: Error) => boolean} [runtimeErrors]
 * @property {string} [trustedTypesPolicyName]
 */

/**
 * @typedef {Object} Options
 * @property {boolean} hot
 * @property {boolean} liveReload
 * @property {boolean} progress
 * @property {boolean | OverlayOptions} overlay
 * @property {string} [logging]
 * @property {number} [reconnect]
 */

/**
 * @typedef {Object} Status
 * @property {boolean} isUnloading
 * @property {string} currentHash
 * @property {string} [previousHash]
 */

/**
 * @param {boolean | { warnings?: boolean | string; errors?: boolean | string; runtimeErrors?: boolean | string; }} overlayOptions
 */
var decodeOverlayOptions = function decodeOverlayOptions(overlayOptions) {
  if (typeof overlayOptions === "object") {
    ["warnings", "errors", "runtimeErrors"].forEach(function (property) {
      if (typeof overlayOptions[property] === "string") {
        var overlayFilterFunctionString = decodeURIComponent(overlayOptions[property]);

        // eslint-disable-next-line no-new-func
        var overlayFilterFunction = new Function("message", "var callback = ".concat(overlayFilterFunctionString, "\n        return callback(message)"));
        overlayOptions[property] = overlayFilterFunction;
      }
    });
  }
};

/**
 * @type {Status}
 */
var status = {
  isUnloading: false,
  // TODO Workaround for webpack v4, `__webpack_hash__` is not replaced without HotModuleReplacement
  // eslint-disable-next-line camelcase
  currentHash:  true ? __webpack_require__.h() : 0
};

/** @type {Options} */
var options = {
  hot: false,
  liveReload: false,
  progress: false,
  overlay: false
};
var parsedResourceQuery = (0,_utils_parseURL_js__WEBPACK_IMPORTED_MODULE_2__["default"])(__resourceQuery);
var enabledFeatures = {
  "Hot Module Replacement": false,
  "Live Reloading": false,
  Progress: false,
  Overlay: false
};
if (parsedResourceQuery.hot === "true") {
  options.hot = true;
  enabledFeatures["Hot Module Replacement"] = true;
}
if (parsedResourceQuery["live-reload"] === "true") {
  options.liveReload = true;
  enabledFeatures["Live Reloading"] = true;
}
if (parsedResourceQuery.progress === "true") {
  options.progress = true;
  enabledFeatures.Progress = true;
}
if (parsedResourceQuery.overlay) {
  try {
    options.overlay = JSON.parse(parsedResourceQuery.overlay);
  } catch (e) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.error("Error parsing overlay options from resource query:", e);
  }

  // Fill in default "true" params for partially-specified objects.
  if (typeof options.overlay === "object") {
    options.overlay = _objectSpread({
      errors: true,
      warnings: true,
      runtimeErrors: true
    }, options.overlay);
    decodeOverlayOptions(options.overlay);
  }
  enabledFeatures.Overlay = true;
}
if (parsedResourceQuery.logging) {
  options.logging = parsedResourceQuery.logging;
}
if (typeof parsedResourceQuery.reconnect !== "undefined") {
  options.reconnect = Number(parsedResourceQuery.reconnect);
}

/**
 * @param {string} level
 */
function setAllLogLevel(level) {
  // This is needed because the HMR logger operate separately from dev server logger
  webpack_hot_log_js__WEBPACK_IMPORTED_MODULE_0___default().setLogLevel(level === "verbose" || level === "log" ? "info" : level);
  (0,_utils_log_js__WEBPACK_IMPORTED_MODULE_5__.setLogLevel)(level);
}
if (options.logging) {
  setAllLogLevel(options.logging);
}
(0,_utils_log_js__WEBPACK_IMPORTED_MODULE_5__.logEnabledFeatures)(enabledFeatures);
self.addEventListener("beforeunload", function () {
  status.isUnloading = true;
});
var overlay = typeof window !== "undefined" ? (0,_overlay_js__WEBPACK_IMPORTED_MODULE_4__.createOverlay)(typeof options.overlay === "object" ? {
  trustedTypesPolicyName: options.overlay.trustedTypesPolicyName,
  catchRuntimeError: options.overlay.runtimeErrors
} : {
  trustedTypesPolicyName: false,
  catchRuntimeError: options.overlay
}) : {
  send: function send() {}
};
var onSocketMessage = {
  hot: function hot() {
    if (parsedResourceQuery.hot === "false") {
      return;
    }
    options.hot = true;
  },
  liveReload: function liveReload() {
    if (parsedResourceQuery["live-reload"] === "false") {
      return;
    }
    options.liveReload = true;
  },
  invalid: function invalid() {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("App updated. Recompiling...");

    // Fixes #1042. overlay doesn't clear if errors are fixed but warnings remain.
    if (options.overlay) {
      overlay.send({
        type: "DISMISS"
      });
    }
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Invalid");
  },
  /**
   * @param {string} hash
   */
  hash: function hash(_hash) {
    status.previousHash = status.currentHash;
    status.currentHash = _hash;
  },
  logging: setAllLogLevel,
  /**
   * @param {boolean} value
   */
  overlay: function overlay(value) {
    if (typeof document === "undefined") {
      return;
    }
    options.overlay = value;
    decodeOverlayOptions(options.overlay);
  },
  /**
   * @param {number} value
   */
  reconnect: function reconnect(value) {
    if (parsedResourceQuery.reconnect === "false") {
      return;
    }
    options.reconnect = value;
  },
  /**
   * @param {boolean} value
   */
  progress: function progress(value) {
    options.progress = value;
  },
  /**
   * @param {{ pluginName?: string, percent: number, msg: string }} data
   */
  "progress-update": function progressUpdate(data) {
    if (options.progress) {
      _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("".concat(data.pluginName ? "[".concat(data.pluginName, "] ") : "").concat(data.percent, "% - ").concat(data.msg, "."));
    }
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Progress", data);
  },
  "still-ok": function stillOk() {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("Nothing changed.");
    if (options.overlay) {
      overlay.send({
        type: "DISMISS"
      });
    }
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("StillOk");
  },
  ok: function ok() {
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Ok");
    if (options.overlay) {
      overlay.send({
        type: "DISMISS"
      });
    }
    (0,_utils_reloadApp_js__WEBPACK_IMPORTED_MODULE_7__["default"])(options, status);
  },
  // TODO: remove in v5 in favor of 'static-changed'
  /**
   * @param {string} file
   */
  "content-changed": function contentChanged(file) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
    self.location.reload();
  },
  /**
   * @param {string} file
   */
  "static-changed": function staticChanged(file) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("".concat(file ? "\"".concat(file, "\"") : "Content", " from static directory was changed. Reloading..."));
    self.location.reload();
  },
  /**
   * @param {Error[]} warnings
   * @param {any} params
   */
  warnings: function warnings(_warnings, params) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.warn("Warnings while compiling.");
    var printableWarnings = _warnings.map(function (error) {
      var _formatProblem = (0,_overlay_js__WEBPACK_IMPORTED_MODULE_4__.formatProblem)("warning", error),
        header = _formatProblem.header,
        body = _formatProblem.body;
      return "".concat(header, "\n").concat((0,_utils_stripAnsi_js__WEBPACK_IMPORTED_MODULE_1__["default"])(body));
    });
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Warnings", printableWarnings);
    for (var i = 0; i < printableWarnings.length; i++) {
      _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.warn(printableWarnings[i]);
    }
    var overlayWarningsSetting = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.warnings;
    if (overlayWarningsSetting) {
      var warningsToDisplay = typeof overlayWarningsSetting === "function" ? _warnings.filter(overlayWarningsSetting) : _warnings;
      if (warningsToDisplay.length) {
        overlay.send({
          type: "BUILD_ERROR",
          level: "warning",
          messages: _warnings
        });
      }
    }
    if (params && params.preventReloading) {
      return;
    }
    (0,_utils_reloadApp_js__WEBPACK_IMPORTED_MODULE_7__["default"])(options, status);
  },
  /**
   * @param {Error[]} errors
   */
  errors: function errors(_errors) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.error("Errors while compiling. Reload prevented.");
    var printableErrors = _errors.map(function (error) {
      var _formatProblem2 = (0,_overlay_js__WEBPACK_IMPORTED_MODULE_4__.formatProblem)("error", error),
        header = _formatProblem2.header,
        body = _formatProblem2.body;
      return "".concat(header, "\n").concat((0,_utils_stripAnsi_js__WEBPACK_IMPORTED_MODULE_1__["default"])(body));
    });
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Errors", printableErrors);
    for (var i = 0; i < printableErrors.length; i++) {
      _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.error(printableErrors[i]);
    }
    var overlayErrorsSettings = typeof options.overlay === "boolean" ? options.overlay : options.overlay && options.overlay.errors;
    if (overlayErrorsSettings) {
      var errorsToDisplay = typeof overlayErrorsSettings === "function" ? _errors.filter(overlayErrorsSettings) : _errors;
      if (errorsToDisplay.length) {
        overlay.send({
          type: "BUILD_ERROR",
          level: "error",
          messages: _errors
        });
      }
    }
  },
  /**
   * @param {Error} error
   */
  error: function error(_error) {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.error(_error);
  },
  close: function close() {
    _utils_log_js__WEBPACK_IMPORTED_MODULE_5__.log.info("Disconnected!");
    if (options.overlay) {
      overlay.send({
        type: "DISMISS"
      });
    }
    (0,_utils_sendMessage_js__WEBPACK_IMPORTED_MODULE_6__["default"])("Close");
  }
};
var socketURL = (0,_utils_createSocketURL_js__WEBPACK_IMPORTED_MODULE_8__["default"])(parsedResourceQuery);
(0,_socket_js__WEBPACK_IMPORTED_MODULE_3__["default"])(socketURL, onSocketMessage, options.reconnect);

/***/ }),

/***/ 25975:
/*!************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/modules/logger/index.js ***!
  \************************************************************************/
/***/ ((__unused_webpack_module, exports) => {

/******/(function () {
  // webpackBootstrap
  /******/
  "use strict";

  /******/
  var __webpack_modules__ = {
    /***/"./client-src/modules/logger/SyncBailHookFake.js": (
    /*!*******************************************************!*\
      !*** ./client-src/modules/logger/SyncBailHookFake.js ***!
      \*******************************************************/
    /***/
    function (module) {
      /**
       * Client stub for tapable SyncBailHook
       */
      module.exports = function clientTapableSyncBailHook() {
        return {
          call: function call() {}
        };
      };

      /***/
    }),
    /***/"./node_modules/webpack/lib/logging/Logger.js": (
    /*!****************************************************!*\
      !*** ./node_modules/webpack/lib/logging/Logger.js ***!
      \****************************************************/
    /***/
    function (__unused_webpack_module, exports) {
      /*
      	MIT License http://www.opensource.org/licenses/mit-license.php
      	Author Tobias Koppers @sokra
      */

      function _toConsumableArray(arr) {
        return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
      }
      function _nonIterableSpread() {
        throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
      }
      function _unsupportedIterableToArray(o, minLen) {
        if (!o) return;
        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
        var n = Object.prototype.toString.call(o).slice(8, -1);
        if (n === "Object" && o.constructor) n = o.constructor.name;
        if (n === "Map" || n === "Set") return Array.from(o);
        if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
      }
      function _iterableToArray(iter) {
        if (typeof (typeof Symbol !== "undefined" ? Symbol : function (i) {
          return i;
        }) !== "undefined" && iter[(typeof Symbol !== "undefined" ? Symbol : function (i) {
          return i;
        }).iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
      }
      function _arrayWithoutHoles(arr) {
        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
      }
      function _arrayLikeToArray(arr, len) {
        if (len == null || len > arr.length) len = arr.length;
        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
        return arr2;
      }
      function _classCallCheck(instance, Constructor) {
        if (!(instance instanceof Constructor)) {
          throw new TypeError("Cannot call a class as a function");
        }
      }
      function _defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
          var descriptor = props[i];
          descriptor.enumerable = descriptor.enumerable || false;
          descriptor.configurable = true;
          if ("value" in descriptor) descriptor.writable = true;
          Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor);
        }
      }
      function _createClass(Constructor, protoProps, staticProps) {
        if (protoProps) _defineProperties(Constructor.prototype, protoProps);
        if (staticProps) _defineProperties(Constructor, staticProps);
        Object.defineProperty(Constructor, "prototype", {
          writable: false
        });
        return Constructor;
      }
      function _toPropertyKey(arg) {
        var key = _toPrimitive(arg, "string");
        return typeof key === "symbol" ? key : String(key);
      }
      function _toPrimitive(input, hint) {
        if (typeof input !== "object" || input === null) return input;
        var prim = input[(typeof Symbol !== "undefined" ? Symbol : function (i) {
          return i;
        }).toPrimitive];
        if (prim !== undefined) {
          var res = prim.call(input, hint || "default");
          if (typeof res !== "object") return res;
          throw new TypeError("@@toPrimitive must return a primitive value.");
        }
        return (hint === "string" ? String : Number)(input);
      }
      var LogType = Object.freeze({
        error: /** @type {"error"} */"error",
        // message, c style arguments
        warn: /** @type {"warn"} */"warn",
        // message, c style arguments
        info: /** @type {"info"} */"info",
        // message, c style arguments
        log: /** @type {"log"} */"log",
        // message, c style arguments
        debug: /** @type {"debug"} */"debug",
        // message, c style arguments

        trace: /** @type {"trace"} */"trace",
        // no arguments

        group: /** @type {"group"} */"group",
        // [label]
        groupCollapsed: /** @type {"groupCollapsed"} */"groupCollapsed",
        // [label]
        groupEnd: /** @type {"groupEnd"} */"groupEnd",
        // [label]

        profile: /** @type {"profile"} */"profile",
        // [profileName]
        profileEnd: /** @type {"profileEnd"} */"profileEnd",
        // [profileName]

        time: /** @type {"time"} */"time",
        // name, time as [seconds, nanoseconds]

        clear: /** @type {"clear"} */"clear",
        // no arguments
        status: /** @type {"status"} */"status" // message, arguments
      });
      exports.LogType = LogType;

      /** @typedef {typeof LogType[keyof typeof LogType]} LogTypeEnum */

      var LOG_SYMBOL = (typeof Symbol !== "undefined" ? Symbol : function (i) {
        return i;
      })("webpack logger raw log method");
      var TIMERS_SYMBOL = (typeof Symbol !== "undefined" ? Symbol : function (i) {
        return i;
      })("webpack logger times");
      var TIMERS_AGGREGATES_SYMBOL = (typeof Symbol !== "undefined" ? Symbol : function (i) {
        return i;
      })("webpack logger aggregated times");
      var WebpackLogger = /*#__PURE__*/function () {
        /**
         * @param {function(LogTypeEnum, any[]=): void} log log function
         * @param {function(string | function(): string): WebpackLogger} getChildLogger function to create child logger
         */
        function WebpackLogger(log, getChildLogger) {
          _classCallCheck(this, WebpackLogger);
          this[LOG_SYMBOL] = log;
          this.getChildLogger = getChildLogger;
        }
        _createClass(WebpackLogger, [{
          key: "error",
          value: function error() {
            for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
              args[_key] = arguments[_key];
            }
            this[LOG_SYMBOL](LogType.error, args);
          }
        }, {
          key: "warn",
          value: function warn() {
            for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
              args[_key2] = arguments[_key2];
            }
            this[LOG_SYMBOL](LogType.warn, args);
          }
        }, {
          key: "info",
          value: function info() {
            for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
              args[_key3] = arguments[_key3];
            }
            this[LOG_SYMBOL](LogType.info, args);
          }
        }, {
          key: "log",
          value: function log() {
            for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
              args[_key4] = arguments[_key4];
            }
            this[LOG_SYMBOL](LogType.log, args);
          }
        }, {
          key: "debug",
          value: function debug() {
            for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
              args[_key5] = arguments[_key5];
            }
            this[LOG_SYMBOL](LogType.debug, args);
          }
        }, {
          key: "assert",
          value: function assert(assertion) {
            if (!assertion) {
              for (var _len6 = arguments.length, args = new Array(_len6 > 1 ? _len6 - 1 : 0), _key6 = 1; _key6 < _len6; _key6++) {
                args[_key6 - 1] = arguments[_key6];
              }
              this[LOG_SYMBOL](LogType.error, args);
            }
          }
        }, {
          key: "trace",
          value: function trace() {
            this[LOG_SYMBOL](LogType.trace, ["Trace"]);
          }
        }, {
          key: "clear",
          value: function clear() {
            this[LOG_SYMBOL](LogType.clear);
          }
        }, {
          key: "status",
          value: function status() {
            for (var _len7 = arguments.length, args = new Array(_len7), _key7 = 0; _key7 < _len7; _key7++) {
              args[_key7] = arguments[_key7];
            }
            this[LOG_SYMBOL](LogType.status, args);
          }
        }, {
          key: "group",
          value: function group() {
            for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
              args[_key8] = arguments[_key8];
            }
            this[LOG_SYMBOL](LogType.group, args);
          }
        }, {
          key: "groupCollapsed",
          value: function groupCollapsed() {
            for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
              args[_key9] = arguments[_key9];
            }
            this[LOG_SYMBOL](LogType.groupCollapsed, args);
          }
        }, {
          key: "groupEnd",
          value: function groupEnd() {
            for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
              args[_key10] = arguments[_key10];
            }
            this[LOG_SYMBOL](LogType.groupEnd, args);
          }
        }, {
          key: "profile",
          value: function profile(label) {
            this[LOG_SYMBOL](LogType.profile, [label]);
          }
        }, {
          key: "profileEnd",
          value: function profileEnd(label) {
            this[LOG_SYMBOL](LogType.profileEnd, [label]);
          }
        }, {
          key: "time",
          value: function time(label) {
            this[TIMERS_SYMBOL] = this[TIMERS_SYMBOL] || new Map();
            this[TIMERS_SYMBOL].set(label, process.hrtime());
          }
        }, {
          key: "timeLog",
          value: function timeLog(label) {
            var prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
            if (!prev) {
              throw new Error("No such label '".concat(label, "' for WebpackLogger.timeLog()"));
            }
            var time = process.hrtime(prev);
            this[LOG_SYMBOL](LogType.time, [label].concat(_toConsumableArray(time)));
          }
        }, {
          key: "timeEnd",
          value: function timeEnd(label) {
            var prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
            if (!prev) {
              throw new Error("No such label '".concat(label, "' for WebpackLogger.timeEnd()"));
            }
            var time = process.hrtime(prev);
            this[TIMERS_SYMBOL].delete(label);
            this[LOG_SYMBOL](LogType.time, [label].concat(_toConsumableArray(time)));
          }
        }, {
          key: "timeAggregate",
          value: function timeAggregate(label) {
            var prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
            if (!prev) {
              throw new Error("No such label '".concat(label, "' for WebpackLogger.timeAggregate()"));
            }
            var time = process.hrtime(prev);
            this[TIMERS_SYMBOL].delete(label);
            this[TIMERS_AGGREGATES_SYMBOL] = this[TIMERS_AGGREGATES_SYMBOL] || new Map();
            var current = this[TIMERS_AGGREGATES_SYMBOL].get(label);
            if (current !== undefined) {
              if (time[1] + current[1] > 1e9) {
                time[0] += current[0] + 1;
                time[1] = time[1] - 1e9 + current[1];
              } else {
                time[0] += current[0];
                time[1] += current[1];
              }
            }
            this[TIMERS_AGGREGATES_SYMBOL].set(label, time);
          }
        }, {
          key: "timeAggregateEnd",
          value: function timeAggregateEnd(label) {
            if (this[TIMERS_AGGREGATES_SYMBOL] === undefined) return;
            var time = this[TIMERS_AGGREGATES_SYMBOL].get(label);
            if (time === undefined) return;
            this[TIMERS_AGGREGATES_SYMBOL].delete(label);
            this[LOG_SYMBOL](LogType.time, [label].concat(_toConsumableArray(time)));
          }
        }]);
        return WebpackLogger;
      }();
      exports.Logger = WebpackLogger;

      /***/
    }),
    /***/"./node_modules/webpack/lib/logging/createConsoleLogger.js": (
    /*!*****************************************************************!*\
      !*** ./node_modules/webpack/lib/logging/createConsoleLogger.js ***!
      \*****************************************************************/
    /***/
    function (module, __unused_webpack_exports, __nested_webpack_require_13160__) {
      /*
      	MIT License http://www.opensource.org/licenses/mit-license.php
      	Author Tobias Koppers @sokra
      */

      function _toConsumableArray(arr) {
        return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread();
      }
      function _nonIterableSpread() {
        throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
      }
      function _unsupportedIterableToArray(o, minLen) {
        if (!o) return;
        if (typeof o === "string") return _arrayLikeToArray(o, minLen);
        var n = Object.prototype.toString.call(o).slice(8, -1);
        if (n === "Object" && o.constructor) n = o.constructor.name;
        if (n === "Map" || n === "Set") return Array.from(o);
        if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
      }
      function _iterableToArray(iter) {
        if (typeof (typeof Symbol !== "undefined" ? Symbol : function (i) {
          return i;
        }) !== "undefined" && iter[(typeof Symbol !== "undefined" ? Symbol : function (i) {
          return i;
        }).iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
      }
      function _arrayWithoutHoles(arr) {
        if (Array.isArray(arr)) return _arrayLikeToArray(arr);
      }
      function _arrayLikeToArray(arr, len) {
        if (len == null || len > arr.length) len = arr.length;
        for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
        return arr2;
      }
      var _require = __nested_webpack_require_13160__(/*! ./Logger */"./node_modules/webpack/lib/logging/Logger.js"),
        LogType = _require.LogType;

      /** @typedef {import("../../declarations/WebpackOptions").FilterItemTypes} FilterItemTypes */
      /** @typedef {import("../../declarations/WebpackOptions").FilterTypes} FilterTypes */
      /** @typedef {import("./Logger").LogTypeEnum} LogTypeEnum */

      /** @typedef {function(string): boolean} FilterFunction */

      /**
       * @typedef {Object} LoggerConsole
       * @property {function(): void} clear
       * @property {function(): void} trace
       * @property {(...args: any[]) => void} info
       * @property {(...args: any[]) => void} log
       * @property {(...args: any[]) => void} warn
       * @property {(...args: any[]) => void} error
       * @property {(...args: any[]) => void=} debug
       * @property {(...args: any[]) => void=} group
       * @property {(...args: any[]) => void=} groupCollapsed
       * @property {(...args: any[]) => void=} groupEnd
       * @property {(...args: any[]) => void=} status
       * @property {(...args: any[]) => void=} profile
       * @property {(...args: any[]) => void=} profileEnd
       * @property {(...args: any[]) => void=} logTime
       */

      /**
       * @typedef {Object} LoggerOptions
       * @property {false|true|"none"|"error"|"warn"|"info"|"log"|"verbose"} level loglevel
       * @property {FilterTypes|boolean} debug filter for debug logging
       * @property {LoggerConsole} console the console to log to
       */

      /**
       * @param {FilterItemTypes} item an input item
       * @returns {FilterFunction} filter function
       */
      var filterToFunction = function filterToFunction(item) {
        if (typeof item === "string") {
          var regExp = new RegExp("[\\\\/]".concat(item.replace(
          // eslint-disable-next-line no-useless-escape
          /[-[\]{}()*+?.\\^$|]/g, "\\$&"), "([\\\\/]|$|!|\\?)"));
          return function (ident) {
            return regExp.test(ident);
          };
        }
        if (item && typeof item === "object" && typeof item.test === "function") {
          return function (ident) {
            return item.test(ident);
          };
        }
        if (typeof item === "function") {
          return item;
        }
        if (typeof item === "boolean") {
          return function () {
            return item;
          };
        }
      };

      /**
       * @enum {number}
       */
      var LogLevel = {
        none: 6,
        false: 6,
        error: 5,
        warn: 4,
        info: 3,
        log: 2,
        true: 2,
        verbose: 1
      };

      /**
       * @param {LoggerOptions} options options object
       * @returns {function(string, LogTypeEnum, any[]): void} logging function
       */
      module.exports = function (_ref) {
        var _ref$level = _ref.level,
          level = _ref$level === void 0 ? "info" : _ref$level,
          _ref$debug = _ref.debug,
          debug = _ref$debug === void 0 ? false : _ref$debug,
          console = _ref.console;
        var debugFilters = typeof debug === "boolean" ? [function () {
          return debug;
        }] : /** @type {FilterItemTypes[]} */[].concat(debug).map(filterToFunction);
        /** @type {number} */
        var loglevel = LogLevel["".concat(level)] || 0;

        /**
         * @param {string} name name of the logger
         * @param {LogTypeEnum} type type of the log entry
         * @param {any[]} args arguments of the log entry
         * @returns {void}
         */
        var logger = function logger(name, type, args) {
          var labeledArgs = function labeledArgs() {
            if (Array.isArray(args)) {
              if (args.length > 0 && typeof args[0] === "string") {
                return ["[".concat(name, "] ").concat(args[0])].concat(_toConsumableArray(args.slice(1)));
              } else {
                return ["[".concat(name, "]")].concat(_toConsumableArray(args));
              }
            } else {
              return [];
            }
          };
          var debug = debugFilters.some(function (f) {
            return f(name);
          });
          switch (type) {
            case LogType.debug:
              if (!debug) return;
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.debug === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.debug.apply(console, _toConsumableArray(labeledArgs()));
              } else {
                console.log.apply(console, _toConsumableArray(labeledArgs()));
              }
              break;
            case LogType.log:
              if (!debug && loglevel > LogLevel.log) return;
              console.log.apply(console, _toConsumableArray(labeledArgs()));
              break;
            case LogType.info:
              if (!debug && loglevel > LogLevel.info) return;
              console.info.apply(console, _toConsumableArray(labeledArgs()));
              break;
            case LogType.warn:
              if (!debug && loglevel > LogLevel.warn) return;
              console.warn.apply(console, _toConsumableArray(labeledArgs()));
              break;
            case LogType.error:
              if (!debug && loglevel > LogLevel.error) return;
              console.error.apply(console, _toConsumableArray(labeledArgs()));
              break;
            case LogType.trace:
              if (!debug) return;
              console.trace();
              break;
            case LogType.groupCollapsed:
              if (!debug && loglevel > LogLevel.log) return;
              if (!debug && loglevel > LogLevel.verbose) {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                if (typeof console.groupCollapsed === "function") {
                  // eslint-disable-next-line node/no-unsupported-features/node-builtins
                  console.groupCollapsed.apply(console, _toConsumableArray(labeledArgs()));
                } else {
                  console.log.apply(console, _toConsumableArray(labeledArgs()));
                }
                break;
              }
            // falls through
            case LogType.group:
              if (!debug && loglevel > LogLevel.log) return;
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.group === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.group.apply(console, _toConsumableArray(labeledArgs()));
              } else {
                console.log.apply(console, _toConsumableArray(labeledArgs()));
              }
              break;
            case LogType.groupEnd:
              if (!debug && loglevel > LogLevel.log) return;
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.groupEnd === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.groupEnd();
              }
              break;
            case LogType.time:
              {
                if (!debug && loglevel > LogLevel.log) return;
                var ms = args[1] * 1000 + args[2] / 1000000;
                var msg = "[".concat(name, "] ").concat(args[0], ": ").concat(ms, " ms");
                if (typeof console.logTime === "function") {
                  console.logTime(msg);
                } else {
                  console.log(msg);
                }
                break;
              }
            case LogType.profile:
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.profile === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.profile.apply(console, _toConsumableArray(labeledArgs()));
              }
              break;
            case LogType.profileEnd:
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.profileEnd === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.profileEnd.apply(console, _toConsumableArray(labeledArgs()));
              }
              break;
            case LogType.clear:
              if (!debug && loglevel > LogLevel.log) return;
              // eslint-disable-next-line node/no-unsupported-features/node-builtins
              if (typeof console.clear === "function") {
                // eslint-disable-next-line node/no-unsupported-features/node-builtins
                console.clear();
              }
              break;
            case LogType.status:
              if (!debug && loglevel > LogLevel.info) return;
              if (typeof console.status === "function") {
                if (args.length === 0) {
                  console.status();
                } else {
                  console.status.apply(console, _toConsumableArray(labeledArgs()));
                }
              } else {
                if (args.length !== 0) {
                  console.info.apply(console, _toConsumableArray(labeledArgs()));
                }
              }
              break;
            default:
              throw new Error("Unexpected LogType ".concat(type));
          }
        };
        return logger;
      };

      /***/
    }),
    /***/"./node_modules/webpack/lib/logging/runtime.js": (
    /*!*****************************************************!*\
      !*** ./node_modules/webpack/lib/logging/runtime.js ***!
      \*****************************************************/
    /***/
    function (__unused_webpack_module, exports, __nested_webpack_require_24775__) {
      /*
      	MIT License http://www.opensource.org/licenses/mit-license.php
      	Author Tobias Koppers @sokra
      */

      function _extends() {
        _extends = Object.assign ? Object.assign.bind() : function (target) {
          for (var i = 1; i < arguments.length; i++) {
            var source = arguments[i];
            for (var key in source) {
              if (Object.prototype.hasOwnProperty.call(source, key)) {
                target[key] = source[key];
              }
            }
          }
          return target;
        };
        return _extends.apply(this, arguments);
      }
      var SyncBailHook = __nested_webpack_require_24775__(/*! tapable/lib/SyncBailHook */"./client-src/modules/logger/SyncBailHookFake.js");
      var _require = __nested_webpack_require_24775__(/*! ./Logger */"./node_modules/webpack/lib/logging/Logger.js"),
        Logger = _require.Logger;
      var createConsoleLogger = __nested_webpack_require_24775__(/*! ./createConsoleLogger */"./node_modules/webpack/lib/logging/createConsoleLogger.js");

      /** @type {createConsoleLogger.LoggerOptions} */
      var currentDefaultLoggerOptions = {
        level: "info",
        debug: false,
        console: console
      };
      var currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);

      /**
       * @param {string} name name of the logger
       * @returns {Logger} a logger
       */
      exports.getLogger = function (name) {
        return new Logger(function (type, args) {
          if (exports.hooks.log.call(name, type, args) === undefined) {
            currentDefaultLogger(name, type, args);
          }
        }, function (childName) {
          return exports.getLogger("".concat(name, "/").concat(childName));
        });
      };

      /**
       * @param {createConsoleLogger.LoggerOptions} options new options, merge with old options
       * @returns {void}
       */
      exports.configureDefaultLogger = function (options) {
        _extends(currentDefaultLoggerOptions, options);
        currentDefaultLogger = createConsoleLogger(currentDefaultLoggerOptions);
      };
      exports.hooks = {
        log: new SyncBailHook(["origin", "type", "args"])
      };

      /***/
    })

    /******/
  };
  /************************************************************************/
  /******/ // The module cache
  /******/
  var __webpack_module_cache__ = {};
  /******/
  /******/ // The require function
  /******/
  function __nested_webpack_require_27238__(moduleId) {
    /******/ // Check if module is in cache
    /******/var cachedModule = __webpack_module_cache__[moduleId];
    /******/
    if (cachedModule !== undefined) {
      /******/return cachedModule.exports;
      /******/
    }
    /******/ // Create a new module (and put it into the cache)
    /******/
    var module = __webpack_module_cache__[moduleId] = {
      /******/ // no module.id needed
      /******/ // no module.loaded needed
      /******/exports: {}
      /******/
    };
    /******/
    /******/ // Execute the module function
    /******/
    __webpack_modules__[moduleId](module, module.exports, __nested_webpack_require_27238__);
    /******/
    /******/ // Return the exports of the module
    /******/
    return module.exports;
    /******/
  }
  /******/
  /************************************************************************/
  /******/ /* webpack/runtime/define property getters */
  /******/
  !function () {
    /******/ // define getter functions for harmony exports
    /******/__nested_webpack_require_27238__.d = function (exports, definition) {
      /******/for (var key in definition) {
        /******/if (__nested_webpack_require_27238__.o(definition, key) && !__nested_webpack_require_27238__.o(exports, key)) {
          /******/Object.defineProperty(exports, key, {
            enumerable: true,
            get: definition[key]
          });
          /******/
        }
        /******/
      }
      /******/
    };
    /******/
  }();
  /******/
  /******/ /* webpack/runtime/hasOwnProperty shorthand */
  /******/
  !function () {
    /******/__nested_webpack_require_27238__.o = function (obj, prop) {
      return Object.prototype.hasOwnProperty.call(obj, prop);
    };
    /******/
  }();
  /******/
  /******/ /* webpack/runtime/make namespace object */
  /******/
  !function () {
    /******/ // define __esModule on exports
    /******/__nested_webpack_require_27238__.r = function (exports) {
      /******/if (typeof Symbol !== 'undefined' && Symbol.toStringTag) {
        /******/Object.defineProperty(exports, Symbol.toStringTag, {
          value: 'Module'
        });
        /******/
      }
      /******/
      Object.defineProperty(exports, '__esModule', {
        value: true
      });
      /******/
    };
    /******/
  }();
  /******/
  /************************************************************************/
  var __nested_webpack_exports__ = {};
  // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk.
  !function () {
    /*!********************************************!*\
      !*** ./client-src/modules/logger/index.js ***!
      \********************************************/
    __nested_webpack_require_27238__.r(__nested_webpack_exports__);
    /* harmony export */
    __nested_webpack_require_27238__.d(__nested_webpack_exports__, {
      /* harmony export */"default": function () {
        return /* reexport default export from named module */webpack_lib_logging_runtime_js__WEBPACK_IMPORTED_MODULE_0__;
      }
      /* harmony export */
    });
    /* harmony import */
    var webpack_lib_logging_runtime_js__WEBPACK_IMPORTED_MODULE_0__ = __nested_webpack_require_27238__(/*! webpack/lib/logging/runtime.js */"./node_modules/webpack/lib/logging/runtime.js");
  }();
  var __webpack_export_target__ = exports;
  for (var i in __nested_webpack_exports__) __webpack_export_target__[i] = __nested_webpack_exports__[i];
  if (__nested_webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", {
    value: true
  });
  /******/
})();

/***/ }),

/***/ 91212:
/*!***********************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/overlay.js ***!
  \***********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   createOverlay: () => (/* binding */ createOverlay),
/* harmony export */   formatProblem: () => (/* binding */ formatProblem)
/* harmony export */ });
/* harmony import */ var ansi_html_community__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ansi-html-community */ 46972);
/* harmony import */ var ansi_html_community__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(ansi_html_community__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var html_entities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! html-entities */ 2726);
/* harmony import */ var _overlay_runtime_error_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./overlay/runtime-error.js */ 73200);
/* harmony import */ var _overlay_state_machine_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./overlay/state-machine.js */ 89086);
/* harmony import */ var _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./overlay/styles.js */ 48141);
function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object);
  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object);
    enumerableOnly && (symbols = symbols.filter(function (sym) {
      return Object.getOwnPropertyDescriptor(object, sym).enumerable;
    })), keys.push.apply(keys, symbols);
  }
  return keys;
}
function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = null != arguments[i] ? arguments[i] : {};
    i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
      _defineProperty(target, key, source[key]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
      Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
    });
  }
  return target;
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
// The error overlay is inspired (and mostly copied) from Create React App (https://github.com/facebookincubator/create-react-app)
// They, in turn, got inspired by webpack-hot-middleware (https://github.com/glenjamin/webpack-hot-middleware).






var colors = {
  reset: ["transparent", "transparent"],
  black: "181818",
  red: "E36049",
  green: "B3CB74",
  yellow: "FFD080",
  blue: "7CAFC2",
  magenta: "7FACCA",
  cyan: "C3C2EF",
  lightgrey: "EBE7E3",
  darkgrey: "6D7891"
};
ansi_html_community__WEBPACK_IMPORTED_MODULE_0___default().setColors(colors);

/**
 * @param {string} type
 * @param {string  | { file?: string, moduleName?: string, loc?: string, message?: string; stack?: string[] }} item
 * @returns {{ header: string, body: string }}
 */
function formatProblem(type, item) {
  var header = type === "warning" ? "WARNING" : "ERROR";
  var body = "";
  if (typeof item === "string") {
    body += item;
  } else {
    var file = item.file || "";
    // eslint-disable-next-line no-nested-ternary
    var moduleName = item.moduleName ? item.moduleName.indexOf("!") !== -1 ? "".concat(item.moduleName.replace(/^(\s|\S)*!/, ""), " (").concat(item.moduleName, ")") : "".concat(item.moduleName) : "";
    var loc = item.loc;
    header += "".concat(moduleName || file ? " in ".concat(moduleName ? "".concat(moduleName).concat(file ? " (".concat(file, ")") : "") : file).concat(loc ? " ".concat(loc) : "") : "");
    body += item.message || "";
  }
  if (Array.isArray(item.stack)) {
    item.stack.forEach(function (stack) {
      if (typeof stack === "string") {
        body += "\r\n".concat(stack);
      }
    });
  }
  return {
    header: header,
    body: body
  };
}

/**
 * @typedef {Object} CreateOverlayOptions
 * @property {string | null} trustedTypesPolicyName
 * @property {boolean | (error: Error) => void} [catchRuntimeError]
 */

/**
 *
 * @param {CreateOverlayOptions} options
 */
var createOverlay = function createOverlay(options) {
  /** @type {HTMLIFrameElement | null | undefined} */
  var iframeContainerElement;
  /** @type {HTMLDivElement | null | undefined} */
  var containerElement;
  /** @type {HTMLDivElement | null | undefined} */
  var headerElement;
  /** @type {Array<(element: HTMLDivElement) => void>} */
  var onLoadQueue = [];
  /** @type {TrustedTypePolicy | undefined} */
  var overlayTrustedTypesPolicy;

  /**
   *
   * @param {HTMLElement} element
   * @param {CSSStyleDeclaration} style
   */
  function applyStyle(element, style) {
    Object.keys(style).forEach(function (prop) {
      element.style[prop] = style[prop];
    });
  }

  /**
   * @param {string | null} trustedTypesPolicyName
   */
  function createContainer(trustedTypesPolicyName) {
    // Enable Trusted Types if they are available in the current browser.
    if (window.trustedTypes) {
      overlayTrustedTypesPolicy = window.trustedTypes.createPolicy(trustedTypesPolicyName || "webpack-dev-server#overlay", {
        createHTML: function createHTML(value) {
          return value;
        }
      });
    }
    iframeContainerElement = document.createElement("iframe");
    iframeContainerElement.id = "webpack-dev-server-client-overlay";
    iframeContainerElement.src = "about:blank";
    applyStyle(iframeContainerElement, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.iframeStyle);
    iframeContainerElement.onload = function () {
      var contentElement = /** @type {Document} */
      /** @type {HTMLIFrameElement} */
      iframeContainerElement.contentDocument.createElement("div");
      containerElement = /** @type {Document} */
      /** @type {HTMLIFrameElement} */
      iframeContainerElement.contentDocument.createElement("div");
      contentElement.id = "webpack-dev-server-client-overlay-div";
      applyStyle(contentElement, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.containerStyle);
      headerElement = document.createElement("div");
      headerElement.innerText = "Compiled with problems:";
      applyStyle(headerElement, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.headerStyle);
      var closeButtonElement = document.createElement("button");
      applyStyle(closeButtonElement, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.dismissButtonStyle);
      closeButtonElement.innerText = "×";
      closeButtonElement.ariaLabel = "Dismiss";
      closeButtonElement.addEventListener("click", function () {
        // eslint-disable-next-line no-use-before-define
        overlayService.send({
          type: "DISMISS"
        });
      });
      contentElement.appendChild(headerElement);
      contentElement.appendChild(closeButtonElement);
      contentElement.appendChild(containerElement);

      /** @type {Document} */
      /** @type {HTMLIFrameElement} */
      iframeContainerElement.contentDocument.body.appendChild(contentElement);
      onLoadQueue.forEach(function (onLoad) {
        onLoad(/** @type {HTMLDivElement} */contentElement);
      });
      onLoadQueue = [];

      /** @type {HTMLIFrameElement} */
      iframeContainerElement.onload = null;
    };
    document.body.appendChild(iframeContainerElement);
  }

  /**
   * @param {(element: HTMLDivElement) => void} callback
   * @param {string | null} trustedTypesPolicyName
   */
  function ensureOverlayExists(callback, trustedTypesPolicyName) {
    if (containerElement) {
      containerElement.innerHTML = "";
      // Everything is ready, call the callback right away.
      callback(containerElement);
      return;
    }
    onLoadQueue.push(callback);
    if (iframeContainerElement) {
      return;
    }
    createContainer(trustedTypesPolicyName);
  }

  // Successful compilation.
  function hide() {
    if (!iframeContainerElement) {
      return;
    }

    // Clean up and reset internal state.
    document.body.removeChild(iframeContainerElement);
    iframeContainerElement = null;
    containerElement = null;
  }

  // Compilation with errors (e.g. syntax error or missing modules).
  /**
   * @param {string} type
   * @param {Array<string  | { moduleIdentifier?: string, moduleName?: string, loc?: string, message?: string }>} messages
   * @param {string | null} trustedTypesPolicyName
   * @param {'build' | 'runtime'} messageSource
   */
  function show(type, messages, trustedTypesPolicyName, messageSource) {
    ensureOverlayExists(function () {
      headerElement.innerText = messageSource === "runtime" ? "Uncaught runtime errors:" : "Compiled with problems:";
      messages.forEach(function (message) {
        var entryElement = document.createElement("div");
        var msgStyle = type === "warning" ? _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.msgStyles.warning : _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.msgStyles.error;
        applyStyle(entryElement, _objectSpread(_objectSpread({}, msgStyle), {}, {
          padding: "1rem 1rem 1.5rem 1rem"
        }));
        var typeElement = document.createElement("div");
        var _formatProblem = formatProblem(type, message),
          header = _formatProblem.header,
          body = _formatProblem.body;
        typeElement.innerText = header;
        applyStyle(typeElement, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.msgTypeStyle);
        if (message.moduleIdentifier) {
          applyStyle(typeElement, {
            cursor: "pointer"
          });
          // element.dataset not supported in IE
          typeElement.setAttribute("data-can-open", true);
          typeElement.addEventListener("click", function () {
            fetch("/webpack-dev-server/open-editor?fileName=".concat(message.moduleIdentifier));
          });
        }

        // Make it look similar to our terminal.
        var text = ansi_html_community__WEBPACK_IMPORTED_MODULE_0___default()((0,html_entities__WEBPACK_IMPORTED_MODULE_1__.encode)(body));
        var messageTextNode = document.createElement("div");
        applyStyle(messageTextNode, _overlay_styles_js__WEBPACK_IMPORTED_MODULE_4__.msgTextStyle);
        messageTextNode.innerHTML = overlayTrustedTypesPolicy ? overlayTrustedTypesPolicy.createHTML(text) : text;
        entryElement.appendChild(typeElement);
        entryElement.appendChild(messageTextNode);

        /** @type {HTMLDivElement} */
        containerElement.appendChild(entryElement);
      });
    }, trustedTypesPolicyName);
  }
  var overlayService = (0,_overlay_state_machine_js__WEBPACK_IMPORTED_MODULE_3__["default"])({
    showOverlay: function showOverlay(_ref) {
      var _ref$level = _ref.level,
        level = _ref$level === void 0 ? "error" : _ref$level,
        messages = _ref.messages,
        messageSource = _ref.messageSource;
      return show(level, messages, options.trustedTypesPolicyName, messageSource);
    },
    hideOverlay: hide
  });
  if (options.catchRuntimeError) {
    /**
     * @param {Error | undefined} error
     * @param {string} fallbackMessage
     */
    var handleError = function handleError(error, fallbackMessage) {
      var errorObject = error instanceof Error ? error : new Error(error || fallbackMessage);
      var shouldDisplay = typeof options.catchRuntimeError === "function" ? options.catchRuntimeError(errorObject) : true;
      if (shouldDisplay) {
        overlayService.send({
          type: "RUNTIME_ERROR",
          messages: [{
            message: errorObject.message,
            stack: (0,_overlay_runtime_error_js__WEBPACK_IMPORTED_MODULE_2__.parseErrorToStacks)(errorObject)
          }]
        });
      }
    };
    (0,_overlay_runtime_error_js__WEBPACK_IMPORTED_MODULE_2__.listenToRuntimeError)(function (errorEvent) {
      // error property may be empty in older browser like IE
      var error = errorEvent.error,
        message = errorEvent.message;
      if (!error && !message) {
        return;
      }
      handleError(error, message);
    });
    (0,_overlay_runtime_error_js__WEBPACK_IMPORTED_MODULE_2__.listenToUnhandledRejection)(function (promiseRejectionEvent) {
      var reason = promiseRejectionEvent.reason;
      handleError(reason, "Unknown promise rejection reason");
    });
  }
  return overlayService;
};


/***/ }),

/***/ 2693:
/*!***************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/overlay/fsm.js ***!
  \***************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
function ownKeys(object, enumerableOnly) {
  var keys = Object.keys(object);
  if (Object.getOwnPropertySymbols) {
    var symbols = Object.getOwnPropertySymbols(object);
    enumerableOnly && (symbols = symbols.filter(function (sym) {
      return Object.getOwnPropertyDescriptor(object, sym).enumerable;
    })), keys.push.apply(keys, symbols);
  }
  return keys;
}
function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = null != arguments[i] ? arguments[i] : {};
    i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
      _defineProperty(target, key, source[key]);
    }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
      Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
    });
  }
  return target;
}
function _defineProperty(obj, key, value) {
  key = _toPropertyKey(key);
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }
  return obj;
}
function _toPropertyKey(arg) {
  var key = _toPrimitive(arg, "string");
  return typeof key === "symbol" ? key : String(key);
}
function _toPrimitive(input, hint) {
  if (typeof input !== "object" || input === null) return input;
  var prim = input[Symbol.toPrimitive];
  if (prim !== undefined) {
    var res = prim.call(input, hint || "default");
    if (typeof res !== "object") return res;
    throw new TypeError("@@toPrimitive must return a primitive value.");
  }
  return (hint === "string" ? String : Number)(input);
}
/**
 * @typedef {Object} StateDefinitions
 * @property {{[event: string]: { target: string; actions?: Array<string> }}} [on]
 */

/**
 * @typedef {Object} Options
 * @property {{[state: string]: StateDefinitions}} states
 * @property {object} context;
 * @property {string} initial
 */

/**
 * @typedef {Object} Implementation
 * @property {{[actionName: string]: (ctx: object, event: any) => object}} actions
 */

/**
 * A simplified `createMachine` from `@xstate/fsm` with the following differences:
 *
 *  - the returned machine is technically a "service". No `interpret(machine).start()` is needed.
 *  - the state definition only support `on` and target must be declared with { target: 'nextState', actions: [] } explicitly.
 *  - event passed to `send` must be an object with `type` property.
 *  - actions implementation will be [assign action](https://xstate.js.org/docs/guides/context.html#assign-action) if you return any value.
 *  Do not return anything if you just want to invoke side effect.
 *
 * The goal of this custom function is to avoid installing the entire `'xstate/fsm'` package, while enabling modeling using
 * state machine. You can copy the first parameter into the editor at https://stately.ai/viz to visualize the state machine.
 *
 * @param {Options} options
 * @param {Implementation} implementation
 */
function createMachine(_ref, _ref2) {
  var states = _ref.states,
    context = _ref.context,
    initial = _ref.initial;
  var actions = _ref2.actions;
  var currentState = initial;
  var currentContext = context;
  return {
    send: function send(event) {
      var currentStateOn = states[currentState].on;
      var transitionConfig = currentStateOn && currentStateOn[event.type];
      if (transitionConfig) {
        currentState = transitionConfig.target;
        if (transitionConfig.actions) {
          transitionConfig.actions.forEach(function (actName) {
            var actionImpl = actions[actName];
            var nextContextValue = actionImpl && actionImpl(currentContext, event);
            if (nextContextValue) {
              currentContext = _objectSpread(_objectSpread({}, currentContext), nextContextValue);
            }
          });
        }
      }
    }
  };
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createMachine);

/***/ }),

/***/ 73200:
/*!*************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/overlay/runtime-error.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   listenToRuntimeError: () => (/* binding */ listenToRuntimeError),
/* harmony export */   listenToUnhandledRejection: () => (/* binding */ listenToUnhandledRejection),
/* harmony export */   parseErrorToStacks: () => (/* binding */ parseErrorToStacks)
/* harmony export */ });
/**
 *
 * @param {Error} error
 */
function parseErrorToStacks(error) {
  if (!error || !(error instanceof Error)) {
    throw new Error("parseErrorToStacks expects Error object");
  }
  if (typeof error.stack === "string") {
    return error.stack.split("\n").filter(function (stack) {
      return stack !== "Error: ".concat(error.message);
    });
  }
}

/**
 * @callback ErrorCallback
 * @param {ErrorEvent} error
 * @returns {void}
 */

/**
 * @param {ErrorCallback} callback
 */
function listenToRuntimeError(callback) {
  window.addEventListener("error", callback);
  return function cleanup() {
    window.removeEventListener("error", callback);
  };
}

/**
 * @callback UnhandledRejectionCallback
 * @param {PromiseRejectionEvent} rejectionEvent
 * @returns {void}
 */

/**
 * @param {UnhandledRejectionCallback} callback
 */
function listenToUnhandledRejection(callback) {
  window.addEventListener("unhandledrejection", callback);
  return function cleanup() {
    window.removeEventListener("unhandledrejection", callback);
  };
}


/***/ }),

/***/ 89086:
/*!*************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/overlay/state-machine.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _fsm_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./fsm.js */ 2693);


/**
 * @typedef {Object} ShowOverlayData
 * @property {'warning' | 'error'} level
 * @property {Array<string  | { moduleIdentifier?: string, moduleName?: string, loc?: string, message?: string }>} messages
 * @property {'build' | 'runtime'} messageSource
 */

/**
 * @typedef {Object} CreateOverlayMachineOptions
 * @property {(data: ShowOverlayData) => void} showOverlay
 * @property {() => void} hideOverlay
 */

/**
 * @param {CreateOverlayMachineOptions} options
 */
var createOverlayMachine = function createOverlayMachine(options) {
  var hideOverlay = options.hideOverlay,
    showOverlay = options.showOverlay;
  var overlayMachine = (0,_fsm_js__WEBPACK_IMPORTED_MODULE_0__["default"])({
    initial: "hidden",
    context: {
      level: "error",
      messages: [],
      messageSource: "build"
    },
    states: {
      hidden: {
        on: {
          BUILD_ERROR: {
            target: "displayBuildError",
            actions: ["setMessages", "showOverlay"]
          },
          RUNTIME_ERROR: {
            target: "displayRuntimeError",
            actions: ["setMessages", "showOverlay"]
          }
        }
      },
      displayBuildError: {
        on: {
          DISMISS: {
            target: "hidden",
            actions: ["dismissMessages", "hideOverlay"]
          },
          BUILD_ERROR: {
            target: "displayBuildError",
            actions: ["appendMessages", "showOverlay"]
          }
        }
      },
      displayRuntimeError: {
        on: {
          DISMISS: {
            target: "hidden",
            actions: ["dismissMessages", "hideOverlay"]
          },
          RUNTIME_ERROR: {
            target: "displayRuntimeError",
            actions: ["appendMessages", "showOverlay"]
          },
          BUILD_ERROR: {
            target: "displayBuildError",
            actions: ["setMessages", "showOverlay"]
          }
        }
      }
    }
  }, {
    actions: {
      dismissMessages: function dismissMessages() {
        return {
          messages: [],
          level: "error",
          messageSource: "build"
        };
      },
      appendMessages: function appendMessages(context, event) {
        return {
          messages: context.messages.concat(event.messages),
          level: event.level || context.level,
          messageSource: event.type === "RUNTIME_ERROR" ? "runtime" : "build"
        };
      },
      setMessages: function setMessages(context, event) {
        return {
          messages: event.messages,
          level: event.level || context.level,
          messageSource: event.type === "RUNTIME_ERROR" ? "runtime" : "build"
        };
      },
      hideOverlay: hideOverlay,
      showOverlay: showOverlay
    }
  });
  return overlayMachine;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createOverlayMachine);

/***/ }),

/***/ 48141:
/*!******************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/overlay/styles.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   containerStyle: () => (/* binding */ containerStyle),
/* harmony export */   dismissButtonStyle: () => (/* binding */ dismissButtonStyle),
/* harmony export */   headerStyle: () => (/* binding */ headerStyle),
/* harmony export */   iframeStyle: () => (/* binding */ iframeStyle),
/* harmony export */   msgStyles: () => (/* binding */ msgStyles),
/* harmony export */   msgTextStyle: () => (/* binding */ msgTextStyle),
/* harmony export */   msgTypeStyle: () => (/* binding */ msgTypeStyle)
/* harmony export */ });
// styles are inspired by `react-error-overlay`

var msgStyles = {
  error: {
    backgroundColor: "rgba(206, 17, 38, 0.1)",
    color: "#fccfcf"
  },
  warning: {
    backgroundColor: "rgba(251, 245, 180, 0.1)",
    color: "#fbf5b4"
  }
};
var iframeStyle = {
  position: "fixed",
  top: 0,
  left: 0,
  right: 0,
  bottom: 0,
  width: "100vw",
  height: "100vh",
  border: "none",
  "z-index": 9999999999
};
var containerStyle = {
  position: "fixed",
  boxSizing: "border-box",
  left: 0,
  top: 0,
  right: 0,
  bottom: 0,
  width: "100vw",
  height: "100vh",
  fontSize: "large",
  padding: "2rem 2rem 4rem 2rem",
  lineHeight: "1.2",
  whiteSpace: "pre-wrap",
  overflow: "auto",
  backgroundColor: "rgba(0, 0, 0, 0.9)",
  color: "white"
};
var headerStyle = {
  color: "#e83b46",
  fontSize: "2em",
  whiteSpace: "pre-wrap",
  fontFamily: "sans-serif",
  margin: "0 2rem 2rem 0",
  flex: "0 0 auto",
  maxHeight: "50%",
  overflow: "auto"
};
var dismissButtonStyle = {
  color: "#ffffff",
  lineHeight: "1rem",
  fontSize: "1.5rem",
  padding: "1rem",
  cursor: "pointer",
  position: "absolute",
  right: 0,
  top: 0,
  backgroundColor: "transparent",
  border: "none"
};
var msgTypeStyle = {
  color: "#e83b46",
  fontSize: "1.2em",
  marginBottom: "1rem",
  fontFamily: "sans-serif"
};
var msgTextStyle = {
  lineHeight: "1.5",
  fontSize: "1rem",
  fontFamily: "Menlo, Consolas, monospace"
};


/***/ }),

/***/ 52231:
/*!**********************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/socket.js ***!
  \**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   client: () => (/* binding */ client),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _clients_WebSocketClient_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./clients/WebSocketClient.js */ 24291);
/* harmony import */ var _utils_log_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/log.js */ 37596);
/* provided dependency */ var __webpack_dev_server_client__ = __webpack_require__(/*! ./node_modules/webpack-dev-server/client/clients/WebSocketClient.js */ 24291);
/* global __webpack_dev_server_client__ */




// this WebsocketClient is here as a default fallback, in case the client is not injected
/* eslint-disable camelcase */
var Client =
// eslint-disable-next-line no-nested-ternary
typeof __webpack_dev_server_client__ !== "undefined" ? typeof __webpack_dev_server_client__.default !== "undefined" ? __webpack_dev_server_client__.default : __webpack_dev_server_client__ : _clients_WebSocketClient_js__WEBPACK_IMPORTED_MODULE_0__["default"];
/* eslint-enable camelcase */

var retries = 0;
var maxRetries = 10;

// Initialized client is exported so external consumers can utilize the same instance
// It is mutable to enforce singleton
// eslint-disable-next-line import/no-mutable-exports
var client = null;

/**
 * @param {string} url
 * @param {{ [handler: string]: (data?: any, params?: any) => any }} handlers
 * @param {number} [reconnect]
 */
var socket = function initSocket(url, handlers, reconnect) {
  client = new Client(url);
  client.onOpen(function () {
    retries = 0;
    if (typeof reconnect !== "undefined") {
      maxRetries = reconnect;
    }
  });
  client.onClose(function () {
    if (retries === 0) {
      handlers.close();
    }

    // Try to reconnect.
    client = null;

    // After 10 retries stop trying, to prevent logspam.
    if (retries < maxRetries) {
      // Exponentially increase timeout to reconnect.
      // Respectfully copied from the package `got`.
      // eslint-disable-next-line no-restricted-properties
      var retryInMs = 1000 * Math.pow(2, retries) + Math.random() * 100;
      retries += 1;
      _utils_log_js__WEBPACK_IMPORTED_MODULE_1__.log.info("Trying to reconnect...");
      setTimeout(function () {
        socket(url, handlers, reconnect);
      }, retryInMs);
    }
  });
  client.onMessage(
  /**
   * @param {any} data
   */
  function (data) {
    var message = JSON.parse(data);
    if (handlers[message.type]) {
      handlers[message.type](message.data, message.params);
    }
  });
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (socket);

/***/ }),

/***/ 24804:
/*!*************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/createSocketURL.js ***!
  \*************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * @param {{ protocol?: string, auth?: string, hostname?: string, port?: string, pathname?: string, search?: string, hash?: string, slashes?: boolean }} objURL
 * @returns {string}
 */
function format(objURL) {
  var protocol = objURL.protocol || "";
  if (protocol && protocol.substr(-1) !== ":") {
    protocol += ":";
  }
  var auth = objURL.auth || "";
  if (auth) {
    auth = encodeURIComponent(auth);
    auth = auth.replace(/%3A/i, ":");
    auth += "@";
  }
  var host = "";
  if (objURL.hostname) {
    host = auth + (objURL.hostname.indexOf(":") === -1 ? objURL.hostname : "[".concat(objURL.hostname, "]"));
    if (objURL.port) {
      host += ":".concat(objURL.port);
    }
  }
  var pathname = objURL.pathname || "";
  if (objURL.slashes) {
    host = "//".concat(host || "");
    if (pathname && pathname.charAt(0) !== "/") {
      pathname = "/".concat(pathname);
    }
  } else if (!host) {
    host = "";
  }
  var search = objURL.search || "";
  if (search && search.charAt(0) !== "?") {
    search = "?".concat(search);
  }
  var hash = objURL.hash || "";
  if (hash && hash.charAt(0) !== "#") {
    hash = "#".concat(hash);
  }
  pathname = pathname.replace(/[?#]/g,
  /**
   * @param {string} match
   * @returns {string}
   */
  function (match) {
    return encodeURIComponent(match);
  });
  search = search.replace("#", "%23");
  return "".concat(protocol).concat(host).concat(pathname).concat(search).concat(hash);
}

/**
 * @param {URL & { fromCurrentScript?: boolean }} parsedURL
 * @returns {string}
 */
function createSocketURL(parsedURL) {
  var hostname = parsedURL.hostname;

  // Node.js module parses it as `::`
  // `new URL(urlString, [baseURLString])` parses it as '[::]'
  var isInAddrAny = hostname === "0.0.0.0" || hostname === "::" || hostname === "[::]";

  // why do we need this check?
  // hostname n/a for file protocol (example, when using electron, ionic)
  // see: https://github.com/webpack/webpack-dev-server/pull/384
  if (isInAddrAny && self.location.hostname && self.location.protocol.indexOf("http") === 0) {
    hostname = self.location.hostname;
  }
  var socketURLProtocol = parsedURL.protocol || self.location.protocol;

  // When https is used in the app, secure web sockets are always necessary because the browser doesn't accept non-secure web sockets.
  if (socketURLProtocol === "auto:" || hostname && isInAddrAny && self.location.protocol === "https:") {
    socketURLProtocol = self.location.protocol;
  }
  socketURLProtocol = socketURLProtocol.replace(/^(?:http|.+-extension|file)/i, "ws");
  var socketURLAuth = "";

  // `new URL(urlString, [baseURLstring])` doesn't have `auth` property
  // Parse authentication credentials in case we need them
  if (parsedURL.username) {
    socketURLAuth = parsedURL.username;

    // Since HTTP basic authentication does not allow empty username,
    // we only include password if the username is not empty.
    if (parsedURL.password) {
      // Result: <username>:<password>
      socketURLAuth = socketURLAuth.concat(":", parsedURL.password);
    }
  }

  // In case the host is a raw IPv6 address, it can be enclosed in
  // the brackets as the brackets are needed in the final URL string.
  // Need to remove those as url.format blindly adds its own set of brackets
  // if the host string contains colons. That would lead to non-working
  // double brackets (e.g. [[::]]) host
  //
  // All of these web socket url params are optionally passed in through resourceQuery,
  // so we need to fall back to the default if they are not provided
  var socketURLHostname = (hostname || self.location.hostname || "localhost").replace(/^\[(.*)\]$/, "$1");
  var socketURLPort = parsedURL.port;
  if (!socketURLPort || socketURLPort === "0") {
    socketURLPort = self.location.port;
  }

  // If path is provided it'll be passed in via the resourceQuery as a
  // query param so it has to be parsed out of the querystring in order for the
  // client to open the socket to the correct location.
  var socketURLPathname = "/ws";
  if (parsedURL.pathname && !parsedURL.fromCurrentScript) {
    socketURLPathname = parsedURL.pathname;
  }
  return format({
    protocol: socketURLProtocol,
    auth: socketURLAuth,
    hostname: socketURLHostname,
    port: socketURLPort,
    pathname: socketURLPathname,
    slashes: true
  });
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (createSocketURL);

/***/ }),

/***/ 30815:
/*!********************************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/getCurrentScriptSource.js ***!
  \********************************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * @returns {string}
 */
function getCurrentScriptSource() {
  // `document.currentScript` is the most accurate way to find the current script,
  // but is not supported in all browsers.
  if (document.currentScript) {
    return document.currentScript.getAttribute("src");
  }

  // Fallback to getting all scripts running in the document.
  var scriptElements = document.scripts || [];
  var scriptElementsWithSrc = Array.prototype.filter.call(scriptElements, function (element) {
    return element.getAttribute("src");
  });
  if (scriptElementsWithSrc.length > 0) {
    var currentScript = scriptElementsWithSrc[scriptElementsWithSrc.length - 1];
    return currentScript.getAttribute("src");
  }

  // Fail as there was no script to use.
  throw new Error("[webpack-dev-server] Failed to get current script source.");
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getCurrentScriptSource);

/***/ }),

/***/ 37596:
/*!*************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/log.js ***!
  \*************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   log: () => (/* binding */ log),
/* harmony export */   logEnabledFeatures: () => (/* binding */ logEnabledFeatures),
/* harmony export */   setLogLevel: () => (/* binding */ setLogLevel)
/* harmony export */ });
/* harmony import */ var _modules_logger_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../modules/logger/index.js */ 25975);
/* harmony import */ var _modules_logger_index_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_modules_logger_index_js__WEBPACK_IMPORTED_MODULE_0__);

var name = "webpack-dev-server";
// default level is set on the client side, so it does not need
// to be set by the CLI or API
var defaultLevel = "info";

// options new options, merge with old options
/**
 * @param {false | true | "none" | "error" | "warn" | "info" | "log" | "verbose"} level
 * @returns {void}
 */
function setLogLevel(level) {
  _modules_logger_index_js__WEBPACK_IMPORTED_MODULE_0___default().configureDefaultLogger({
    level: level
  });
}
setLogLevel(defaultLevel);
var log = _modules_logger_index_js__WEBPACK_IMPORTED_MODULE_0___default().getLogger(name);
var logEnabledFeatures = function logEnabledFeatures(features) {
  var enabledFeatures = Object.keys(features);
  if (!features || enabledFeatures.length === 0) {
    return;
  }
  var logString = "Server started:";

  // Server started: Hot Module Replacement enabled, Live Reloading enabled, Overlay disabled.
  for (var i = 0; i < enabledFeatures.length; i++) {
    var key = enabledFeatures[i];
    logString += " ".concat(key, " ").concat(features[key] ? "enabled" : "disabled", ",");
  }
  // replace last comma with a period
  logString = logString.slice(0, -1).concat(".");
  log.info(logString);
};


/***/ }),

/***/ 48776:
/*!******************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/parseURL.js ***!
  \******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getCurrentScriptSource_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getCurrentScriptSource.js */ 30815);


/**
 * @param {string} resourceQuery
 * @returns {{ [key: string]: string | boolean }}
 */
function parseURL(resourceQuery) {
  /** @type {{ [key: string]: string }} */
  var options = {};
  if (typeof resourceQuery === "string" && resourceQuery !== "") {
    var searchParams = resourceQuery.slice(1).split("&");
    for (var i = 0; i < searchParams.length; i++) {
      var pair = searchParams[i].split("=");
      options[pair[0]] = decodeURIComponent(pair[1]);
    }
  } else {
    // Else, get the url from the <script> this file was called with.
    var scriptSource = (0,_getCurrentScriptSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])();
    var scriptSourceURL;
    try {
      // The placeholder `baseURL` with `window.location.href`,
      // is to allow parsing of path-relative or protocol-relative URLs,
      // and will have no effect if `scriptSource` is a fully valid URL.
      scriptSourceURL = new URL(scriptSource, self.location.href);
    } catch (error) {
      // URL parsing failed, do nothing.
      // We will still proceed to see if we can recover using `resourceQuery`
    }
    if (scriptSourceURL) {
      options = scriptSourceURL;
      options.fromCurrentScript = true;
    }
  }
  return options;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (parseURL);

/***/ }),

/***/ 31190:
/*!*******************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/reloadApp.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var webpack_hot_emitter_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! webpack/hot/emitter.js */ 7202);
/* harmony import */ var webpack_hot_emitter_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(webpack_hot_emitter_js__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _log_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./log.js */ 37596);



/** @typedef {import("../index").Options} Options
/** @typedef {import("../index").Status} Status

/**
 * @param {Options} options
 * @param {Status} status
 */
function reloadApp(_ref, status) {
  var hot = _ref.hot,
    liveReload = _ref.liveReload;
  if (status.isUnloading) {
    return;
  }
  var currentHash = status.currentHash,
    previousHash = status.previousHash;
  var isInitial = currentHash.indexOf(/** @type {string} */previousHash) >= 0;
  if (isInitial) {
    return;
  }

  /**
   * @param {Window} rootWindow
   * @param {number} intervalId
   */
  function applyReload(rootWindow, intervalId) {
    clearInterval(intervalId);
    _log_js__WEBPACK_IMPORTED_MODULE_1__.log.info("App updated. Reloading...");
    rootWindow.location.reload();
  }
  var search = self.location.search.toLowerCase();
  var allowToHot = search.indexOf("webpack-dev-server-hot=false") === -1;
  var allowToLiveReload = search.indexOf("webpack-dev-server-live-reload=false") === -1;
  if (hot && allowToHot) {
    _log_js__WEBPACK_IMPORTED_MODULE_1__.log.info("App hot update...");
    webpack_hot_emitter_js__WEBPACK_IMPORTED_MODULE_0___default().emit("webpackHotUpdate", status.currentHash);
    if (typeof self !== "undefined" && self.window) {
      // broadcast update to window
      self.postMessage("webpackHotUpdate".concat(status.currentHash), "*");
    }
  }
  // allow refreshing the page only if liveReload isn't disabled
  else if (liveReload && allowToLiveReload) {
    var rootWindow = self;

    // use parent window for reload (in case we're in an iframe with no valid src)
    var intervalId = self.setInterval(function () {
      if (rootWindow.location.protocol !== "about:") {
        // reload immediately if protocol is valid
        applyReload(rootWindow, intervalId);
      } else {
        rootWindow = rootWindow.parent;
        if (rootWindow.parent === rootWindow) {
          // if parent equals current window we've reached the root which would continue forever, so trigger a reload anyways
          applyReload(rootWindow, intervalId);
        }
      }
    });
  }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (reloadApp);

/***/ }),

/***/ 62975:
/*!*********************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/sendMessage.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* global __resourceQuery WorkerGlobalScope */

// Send messages to the outside, so plugins can consume it.
/**
 * @param {string} type
 * @param {any} [data]
 */
function sendMsg(type, data) {
  if (typeof self !== "undefined" && (typeof WorkerGlobalScope === "undefined" || !(self instanceof WorkerGlobalScope))) {
    self.postMessage({
      type: "webpack".concat(type),
      data: data
    }, "*");
  }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (sendMsg);

/***/ }),

/***/ 44675:
/*!*******************************************************************!*\
  !*** ./node_modules/webpack-dev-server/client/utils/stripAnsi.js ***!
  \*******************************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
var ansiRegex = new RegExp(["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|"), "g");

/**
 *
 * Strip [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from a string.
 * Adapted from code originally released by Sindre Sorhus
 * Licensed the MIT License
 *
 * @param {string} string
 * @return {string}
 */
function stripAnsi(string) {
  if (typeof string !== "string") {
    throw new TypeError("Expected a `string`, got `".concat(typeof string, "`"));
  }
  return string.replace(ansiRegex, "");
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stripAnsi);

/***/ }),

/***/ 7202:
/*!*********************************************!*\
  !*** ./node_modules/webpack/hot/emitter.js ***!
  \*********************************************/
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

var EventEmitter = __webpack_require__(/*! events */ 44339);
module.exports = new EventEmitter();

/***/ }),

/***/ 6366:
/*!*****************************************!*\
  !*** ./node_modules/webpack/hot/log.js ***!
  \*****************************************/
/***/ ((module) => {

/** @typedef {"info" | "warning" | "error"} LogLevel */

/** @type {LogLevel} */
var logLevel = "info";
function dummy() {}

/**
 * @param {LogLevel} level log level
 * @returns {boolean} true, if should log
 */
function shouldLog(level) {
  var shouldLog = logLevel === "info" && level === "info" || ["info", "warning"].indexOf(logLevel) >= 0 && level === "warning" || ["info", "warning", "error"].indexOf(logLevel) >= 0 && level === "error";
  return shouldLog;
}

/**
 * @param {(msg?: string) => void} logFn log function
 * @returns {(level: LogLevel, msg?: string) => void} function that logs when log level is sufficient
 */
function logGroup(logFn) {
  return function (level, msg) {
    if (shouldLog(level)) {
      logFn(msg);
    }
  };
}

/**
 * @param {LogLevel} level log level
 * @param {string|Error} msg message
 */
module.exports = function (level, msg) {
  if (shouldLog(level)) {
    if (level === "info") {
      console.log(msg);
    } else if (level === "warning") {
      console.warn(msg);
    } else if (level === "error") {
      console.error(msg);
    }
  }
};
var group = console.group || dummy;
var groupCollapsed = console.groupCollapsed || dummy;
var groupEnd = console.groupEnd || dummy;
module.exports.group = logGroup(group);
module.exports.groupCollapsed = logGroup(groupCollapsed);
module.exports.groupEnd = logGroup(groupEnd);

/**
 * @param {LogLevel} level log level
 */
module.exports.setLogLevel = function (level) {
  logLevel = level;
};

/**
 * @param {Error} err error
 * @returns {string} formatted error
 */
module.exports.formatError = function (err) {
  var message = err.message;
  var stack = err.stack;
  if (!stack) {
    return message;
  } else if (stack.indexOf(message) < 0) {
    return message + "\n" + stack;
  }
  return stack;
};

/***/ }),

/***/ 47172:
/*!******************************************************************!*\
  !*** ./node_modules/@angular/animations/fesm2022/animations.mjs ***!
  \******************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AUTO_STYLE: () => (/* binding */ AUTO_STYLE),
/* harmony export */   AnimationBuilder: () => (/* binding */ AnimationBuilder),
/* harmony export */   AnimationFactory: () => (/* binding */ AnimationFactory),
/* harmony export */   AnimationMetadataType: () => (/* binding */ AnimationMetadataType),
/* harmony export */   NoopAnimationPlayer: () => (/* binding */ NoopAnimationPlayer),
/* harmony export */   animate: () => (/* binding */ animate),
/* harmony export */   animateChild: () => (/* binding */ animateChild),
/* harmony export */   animation: () => (/* binding */ animation),
/* harmony export */   group: () => (/* binding */ group),
/* harmony export */   keyframes: () => (/* binding */ keyframes),
/* harmony export */   query: () => (/* binding */ query),
/* harmony export */   sequence: () => (/* binding */ sequence),
/* harmony export */   stagger: () => (/* binding */ stagger),
/* harmony export */   state: () => (/* binding */ state),
/* harmony export */   style: () => (/* binding */ style),
/* harmony export */   transition: () => (/* binding */ transition),
/* harmony export */   trigger: () => (/* binding */ trigger),
/* harmony export */   useAnimation: () => (/* binding */ useAnimation),
/* harmony export */   "ɵAnimationGroupPlayer": () => (/* binding */ AnimationGroupPlayer),
/* harmony export */   "ɵBrowserAnimationBuilder": () => (/* binding */ BrowserAnimationBuilder),
/* harmony export */   "ɵPRE_STYLE": () => (/* binding */ ɵPRE_STYLE)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */





/**
 * @description Constants for the categories of parameters that can be defined for animations.
 *
 * A corresponding function defines a set of parameters for each category, and
 * collects them into a corresponding `AnimationMetadata` object.
 *
 * @publicApi
 */
var AnimationMetadataType;
(function (AnimationMetadataType) {
  /**
   * Associates a named animation state with a set of CSS styles.
   * See [`state()`](api/animations/state)
   */
  AnimationMetadataType[AnimationMetadataType["State"] = 0] = "State";
  /**
   * Data for a transition from one animation state to another.
   * See `transition()`
   */
  AnimationMetadataType[AnimationMetadataType["Transition"] = 1] = "Transition";
  /**
   * Contains a set of animation steps.
   * See `sequence()`
   */
  AnimationMetadataType[AnimationMetadataType["Sequence"] = 2] = "Sequence";
  /**
   * Contains a set of animation steps.
   * See `{@link animations/group group()}`
   */
  AnimationMetadataType[AnimationMetadataType["Group"] = 3] = "Group";
  /**
   * Contains an animation step.
   * See `animate()`
   */
  AnimationMetadataType[AnimationMetadataType["Animate"] = 4] = "Animate";
  /**
   * Contains a set of animation steps.
   * See `keyframes()`
   */
  AnimationMetadataType[AnimationMetadataType["Keyframes"] = 5] = "Keyframes";
  /**
   * Contains a set of CSS property-value pairs into a named style.
   * See `style()`
   */
  AnimationMetadataType[AnimationMetadataType["Style"] = 6] = "Style";
  /**
   * Associates an animation with an entry trigger that can be attached to an element.
   * See `trigger()`
   */
  AnimationMetadataType[AnimationMetadataType["Trigger"] = 7] = "Trigger";
  /**
   * Contains a re-usable animation.
   * See `animation()`
   */
  AnimationMetadataType[AnimationMetadataType["Reference"] = 8] = "Reference";
  /**
   * Contains data to use in executing child animations returned by a query.
   * See `animateChild()`
   */
  AnimationMetadataType[AnimationMetadataType["AnimateChild"] = 9] = "AnimateChild";
  /**
   * Contains animation parameters for a re-usable animation.
   * See `useAnimation()`
   */
  AnimationMetadataType[AnimationMetadataType["AnimateRef"] = 10] = "AnimateRef";
  /**
   * Contains child-animation query data.
   * See `query()`
   */
  AnimationMetadataType[AnimationMetadataType["Query"] = 11] = "Query";
  /**
   * Contains data for staggering an animation sequence.
   * See `stagger()`
   */
  AnimationMetadataType[AnimationMetadataType["Stagger"] = 12] = "Stagger";
})(AnimationMetadataType || (AnimationMetadataType = {}));
/**
 * Specifies automatic styling.
 *
 * @publicApi
 */
const AUTO_STYLE = '*';
/**
 * Creates a named animation trigger, containing a  list of [`state()`](api/animations/state)
 * and `transition()` entries to be evaluated when the expression
 * bound to the trigger changes.
 *
 * @param name An identifying string.
 * @param definitions  An animation definition object, containing an array of
 * [`state()`](api/animations/state) and `transition()` declarations.
 *
 * @return An object that encapsulates the trigger data.
 *
 * @usageNotes
 * Define an animation trigger in the `animations` section of `@Component` metadata.
 * In the template, reference the trigger by name and bind it to a trigger expression that
 * evaluates to a defined animation state, using the following format:
 *
 * `[@triggerName]="expression"`
 *
 * Animation trigger bindings convert all values to strings, and then match the
 * previous and current values against any linked transitions.
 * Booleans can be specified as `1` or `true` and `0` or `false`.
 *
 * ### Usage Example
 *
 * The following example creates an animation trigger reference based on the provided
 * name value.
 * The provided animation value is expected to be an array consisting of state and
 * transition declarations.
 *
 * ```typescript
 * @Component({
 *   selector: "my-component",
 *   templateUrl: "my-component-tpl.html",
 *   animations: [
 *     trigger("myAnimationTrigger", [
 *       state(...),
 *       state(...),
 *       transition(...),
 *       transition(...)
 *     ])
 *   ]
 * })
 * class MyComponent {
 *   myStatusExp = "something";
 * }
 * ```
 *
 * The template associated with this component makes use of the defined trigger
 * by binding to an element within its template code.
 *
 * ```html
 * <!-- somewhere inside of my-component-tpl.html -->
 * <div [@myAnimationTrigger]="myStatusExp">...</div>
 * ```
 *
 * ### Using an inline function
 * The `transition` animation method also supports reading an inline function which can decide
 * if its associated animation should be run.
 *
 * ```typescript
 * // this method is run each time the `myAnimationTrigger` trigger value changes.
 * function myInlineMatcherFn(fromState: string, toState: string, element: any, params: {[key:
 string]: any}): boolean {
 *   // notice that `element` and `params` are also available here
 *   return toState == 'yes-please-animate';
 * }
 *
 * @Component({
 *   selector: 'my-component',
 *   templateUrl: 'my-component-tpl.html',
 *   animations: [
 *     trigger('myAnimationTrigger', [
 *       transition(myInlineMatcherFn, [
 *         // the animation sequence code
 *       ]),
 *     ])
 *   ]
 * })
 * class MyComponent {
 *   myStatusExp = "yes-please-animate";
 * }
 * ```
 *
 * ### Disabling Animations
 * When true, the special animation control binding `@.disabled` binding prevents
 * all animations from rendering.
 * Place the  `@.disabled` binding on an element to disable
 * animations on the element itself, as well as any inner animation triggers
 * within the element.
 *
 * The following example shows how to use this feature:
 *
 * ```typescript
 * @Component({
 *   selector: 'my-component',
 *   template: `
 *     <div [@.disabled]="isDisabled">
 *       <div [@childAnimation]="exp"></div>
 *     </div>
 *   `,
 *   animations: [
 *     trigger("childAnimation", [
 *       // ...
 *     ])
 *   ]
 * })
 * class MyComponent {
 *   isDisabled = true;
 *   exp = '...';
 * }
 * ```
 *
 * When `@.disabled` is true, it prevents the `@childAnimation` trigger from animating,
 * along with any inner animations.
 *
 * ### Disable animations application-wide
 * When an area of the template is set to have animations disabled,
 * **all** inner components have their animations disabled as well.
 * This means that you can disable all animations for an app
 * by placing a host binding set on `@.disabled` on the topmost Angular component.
 *
 * ```typescript
 * import {Component, HostBinding} from '@angular/core';
 *
 * @Component({
 *   selector: 'app-component',
 *   templateUrl: 'app.component.html',
 * })
 * class AppComponent {
 *   @HostBinding('@.disabled')
 *   public animationsDisabled = true;
 * }
 * ```
 *
 * ### Overriding disablement of inner animations
 * Despite inner animations being disabled, a parent animation can `query()`
 * for inner elements located in disabled areas of the template and still animate
 * them if needed. This is also the case for when a sub animation is
 * queried by a parent and then later animated using `animateChild()`.
 *
 * ### Detecting when an animation is disabled
 * If a region of the DOM (or the entire application) has its animations disabled, the animation
 * trigger callbacks still fire, but for zero seconds. When the callback fires, it provides
 * an instance of an `AnimationEvent`. If animations are disabled,
 * the `.disabled` flag on the event is true.
 *
 * @publicApi
 */
function trigger(name, definitions) {
  return {
    type: AnimationMetadataType.Trigger,
    name,
    definitions,
    options: {}
  };
}
/**
 * Defines an animation step that combines styling information with timing information.
 *
 * @param timings Sets `AnimateTimings` for the parent animation.
 * A string in the format "duration [delay] [easing]".
 *  - Duration and delay are expressed as a number and optional time unit,
 * such as "1s" or "10ms" for one second and 10 milliseconds, respectively.
 * The default unit is milliseconds.
 *  - The easing value controls how the animation accelerates and decelerates
 * during its runtime. Value is one of  `ease`, `ease-in`, `ease-out`,
 * `ease-in-out`, or a `cubic-bezier()` function call.
 * If not supplied, no easing is applied.
 *
 * For example, the string "1s 100ms ease-out" specifies a duration of
 * 1000 milliseconds, and delay of 100 ms, and the "ease-out" easing style,
 * which decelerates near the end of the duration.
 * @param styles Sets AnimationStyles for the parent animation.
 * A function call to either `style()` or `keyframes()`
 * that returns a collection of CSS style entries to be applied to the parent animation.
 * When null, uses the styles from the destination state.
 * This is useful when describing an animation step that will complete an animation;
 * see "Animating to the final state" in `transitions()`.
 * @returns An object that encapsulates the animation step.
 *
 * @usageNotes
 * Call within an animation `sequence()`, `{@link animations/group group()}`, or
 * `transition()` call to specify an animation step
 * that applies given style data to the parent animation for a given amount of time.
 *
 * ### Syntax Examples
 * **Timing examples**
 *
 * The following examples show various `timings` specifications.
 * - `animate(500)` : Duration is 500 milliseconds.
 * - `animate("1s")` : Duration is 1000 milliseconds.
 * - `animate("100ms 0.5s")` : Duration is 100 milliseconds, delay is 500 milliseconds.
 * - `animate("5s ease-in")` : Duration is 5000 milliseconds, easing in.
 * - `animate("5s 10ms cubic-bezier(.17,.67,.88,.1)")` : Duration is 5000 milliseconds, delay is 10
 * milliseconds, easing according to a bezier curve.
 *
 * **Style examples**
 *
 * The following example calls `style()` to set a single CSS style.
 * ```typescript
 * animate(500, style({ background: "red" }))
 * ```
 * The following example calls `keyframes()` to set a CSS style
 * to different values for successive keyframes.
 * ```typescript
 * animate(500, keyframes(
 *  [
 *   style({ background: "blue" }),
 *   style({ background: "red" })
 *  ])
 * ```
 *
 * @publicApi
 */
function animate(timings, styles = null) {
  return {
    type: AnimationMetadataType.Animate,
    styles,
    timings
  };
}
/**
 * @description Defines a list of animation steps to be run in parallel.
 *
 * @param steps An array of animation step objects.
 * - When steps are defined by `style()` or `animate()`
 * function calls, each call within the group is executed instantly.
 * - To specify offset styles to be applied at a later time, define steps with
 * `keyframes()`, or use `animate()` calls with a delay value.
 * For example:
 *
 * ```typescript
 * group([
 *   animate("1s", style({ background: "black" })),
 *   animate("2s", style({ color: "white" }))
 * ])
 * ```
 *
 * @param options An options object containing a delay and
 * developer-defined parameters that provide styling defaults and
 * can be overridden on invocation.
 *
 * @return An object that encapsulates the group data.
 *
 * @usageNotes
 * Grouped animations are useful when a series of styles must be
 * animated at different starting times and closed off at different ending times.
 *
 * When called within a `sequence()` or a
 * `transition()` call, does not continue to the next
 * instruction until all of the inner animation steps have completed.
 *
 * @publicApi
 */
function group(steps, options = null) {
  return {
    type: AnimationMetadataType.Group,
    steps,
    options
  };
}
/**
 * Defines a list of animation steps to be run sequentially, one by one.
 *
 * @param steps An array of animation step objects.
 * - Steps defined by `style()` calls apply the styling data immediately.
 * - Steps defined by `animate()` calls apply the styling data over time
 *   as specified by the timing data.
 *
 * ```typescript
 * sequence([
 *   style({ opacity: 0 }),
 *   animate("1s", style({ opacity: 1 }))
 * ])
 * ```
 *
 * @param options An options object containing a delay and
 * developer-defined parameters that provide styling defaults and
 * can be overridden on invocation.
 *
 * @return An object that encapsulates the sequence data.
 *
 * @usageNotes
 * When you pass an array of steps to a
 * `transition()` call, the steps run sequentially by default.
 * Compare this to the `{@link animations/group group()}` call, which runs animation steps in
 *parallel.
 *
 * When a sequence is used within a `{@link animations/group group()}` or a `transition()` call,
 * execution continues to the next instruction only after each of the inner animation
 * steps have completed.
 *
 * @publicApi
 **/
function sequence(steps, options = null) {
  return {
    type: AnimationMetadataType.Sequence,
    steps,
    options
  };
}
/**
 * Declares a key/value object containing CSS properties/styles that
 * can then be used for an animation [`state`](api/animations/state), within an animation
 *`sequence`, or as styling data for calls to `animate()` and `keyframes()`.
 *
 * @param tokens A set of CSS styles or HTML styles associated with an animation state.
 * The value can be any of the following:
 * - A key-value style pair associating a CSS property with a value.
 * - An array of key-value style pairs.
 * - An asterisk (*), to use auto-styling, where styles are derived from the element
 * being animated and applied to the animation when it starts.
 *
 * Auto-styling can be used to define a state that depends on layout or other
 * environmental factors.
 *
 * @return An object that encapsulates the style data.
 *
 * @usageNotes
 * The following examples create animation styles that collect a set of
 * CSS property values:
 *
 * ```typescript
 * // string values for CSS properties
 * style({ background: "red", color: "blue" })
 *
 * // numerical pixel values
 * style({ width: 100, height: 0 })
 * ```
 *
 * The following example uses auto-styling to allow an element to animate from
 * a height of 0 up to its full height:
 *
 * ```
 * style({ height: 0 }),
 * animate("1s", style({ height: "*" }))
 * ```
 *
 * @publicApi
 **/
function style(tokens) {
  return {
    type: AnimationMetadataType.Style,
    styles: tokens,
    offset: null
  };
}
/**
 * Declares an animation state within a trigger attached to an element.
 *
 * @param name One or more names for the defined state in a comma-separated string.
 * The following reserved state names can be supplied to define a style for specific use
 * cases:
 *
 * - `void` You can associate styles with this name to be used when
 * the element is detached from the application. For example, when an `ngIf` evaluates
 * to false, the state of the associated element is void.
 *  - `*` (asterisk) Indicates the default state. You can associate styles with this name
 * to be used as the fallback when the state that is being animated is not declared
 * within the trigger.
 *
 * @param styles A set of CSS styles associated with this state, created using the
 * `style()` function.
 * This set of styles persists on the element once the state has been reached.
 * @param options Parameters that can be passed to the state when it is invoked.
 * 0 or more key-value pairs.
 * @return An object that encapsulates the new state data.
 *
 * @usageNotes
 * Use the `trigger()` function to register states to an animation trigger.
 * Use the `transition()` function to animate between states.
 * When a state is active within a component, its associated styles persist on the element,
 * even when the animation ends.
 *
 * @publicApi
 **/
function state(name, styles, options) {
  return {
    type: AnimationMetadataType.State,
    name,
    styles,
    options
  };
}
/**
 * Defines a set of animation styles, associating each style with an optional `offset` value.
 *
 * @param steps A set of animation styles with optional offset data.
 * The optional `offset` value for a style specifies a percentage of the total animation
 * time at which that style is applied.
 * @returns An object that encapsulates the keyframes data.
 *
 * @usageNotes
 * Use with the `animate()` call. Instead of applying animations
 * from the current state
 * to the destination state, keyframes describe how each style entry is applied and at what point
 * within the animation arc.
 * Compare [CSS Keyframe Animations](https://www.w3schools.com/css/css3_animations.asp).
 *
 * ### Usage
 *
 * In the following example, the offset values describe
 * when each `backgroundColor` value is applied. The color is red at the start, and changes to
 * blue when 20% of the total time has elapsed.
 *
 * ```typescript
 * // the provided offset values
 * animate("5s", keyframes([
 *   style({ backgroundColor: "red", offset: 0 }),
 *   style({ backgroundColor: "blue", offset: 0.2 }),
 *   style({ backgroundColor: "orange", offset: 0.3 }),
 *   style({ backgroundColor: "black", offset: 1 })
 * ]))
 * ```
 *
 * If there are no `offset` values specified in the style entries, the offsets
 * are calculated automatically.
 *
 * ```typescript
 * animate("5s", keyframes([
 *   style({ backgroundColor: "red" }) // offset = 0
 *   style({ backgroundColor: "blue" }) // offset = 0.33
 *   style({ backgroundColor: "orange" }) // offset = 0.66
 *   style({ backgroundColor: "black" }) // offset = 1
 * ]))
 *```

 * @publicApi
 */
function keyframes(steps) {
  return {
    type: AnimationMetadataType.Keyframes,
    steps
  };
}
/**
 * Declares an animation transition which is played when a certain specified condition is met.
 *
 * @param stateChangeExpr A string with a specific format or a function that specifies when the
 * animation transition should occur (see [State Change Expression](#state-change-expression)).
 *
 * @param steps One or more animation objects that represent the animation's instructions.
 *
 * @param options An options object that can be used to specify a delay for the animation or provide
 * custom parameters for it.
 *
 * @returns An object that encapsulates the transition data.
 *
 * @usageNotes
 *
 * ### State Change Expression
 *
 * The State Change Expression instructs Angular when to run the transition's animations, it can
 *either be
 *  - a string with a specific syntax
 *  - or a function that compares the previous and current state (value of the expression bound to
 *    the element's trigger) and returns `true` if the transition should occur or `false` otherwise
 *
 * The string format can be:
 *  - `fromState => toState`, which indicates that the transition's animations should occur then the
 *    expression bound to the trigger's element goes from `fromState` to `toState`
 *
 *    _Example:_
 *      ```typescript
 *        transition('open => closed', animate('.5s ease-out', style({ height: 0 }) ))
 *      ```
 *
 *  - `fromState <=> toState`, which indicates that the transition's animations should occur then
 *    the expression bound to the trigger's element goes from `fromState` to `toState` or vice versa
 *
 *    _Example:_
 *      ```typescript
 *        transition('enabled <=> disabled', animate('1s cubic-bezier(0.8,0.3,0,1)'))
 *      ```
 *
 *  - `:enter`/`:leave`, which indicates that the transition's animations should occur when the
 *    element enters or exists the DOM
 *
 *    _Example:_
 *      ```typescript
 *        transition(':enter', [
 *          style({ opacity: 0 }),
 *          animate('500ms', style({ opacity: 1 }))
 *        ])
 *      ```
 *
 *  - `:increment`/`:decrement`, which indicates that the transition's animations should occur when
 *    the numerical expression bound to the trigger's element has increased in value or decreased
 *
 *    _Example:_
 *      ```typescript
 *        transition(':increment', query('@counter', animateChild()))
 *      ```
 *
 *  - a sequence of any of the above divided by commas, which indicates that transition's animations
 *    should occur whenever one of the state change expressions matches
 *
 *    _Example:_
 *      ```typescript
 *        transition(':increment, * => enabled, :enter', animate('1s ease', keyframes([
 *          style({ transform: 'scale(1)', offset: 0}),
 *          style({ transform: 'scale(1.1)', offset: 0.7}),
 *          style({ transform: 'scale(1)', offset: 1})
 *        ]))),
 *      ```
 *
 * Also note that in such context:
 *  - `void` can be used to indicate the absence of the element
 *  - asterisks can be used as wildcards that match any state
 *  - (as a consequence of the above, `void => *` is equivalent to `:enter` and `* => void` is
 *    equivalent to `:leave`)
 *  - `true` and `false` also match expression values of `1` and `0` respectively (but do not match
 *    _truthy_ and _falsy_ values)
 *
 * <div class="alert is-helpful">
 *
 *  Be careful about entering end leaving elements as their transitions present a common
 *  pitfall for developers.
 *
 *  Note that when an element with a trigger enters the DOM its `:enter` transition always
 *  gets executed, but its `:leave` transition will not be executed if the element is removed
 *  alongside its parent (as it will be removed "without warning" before its transition has
 *  a chance to be executed, the only way that such transition can occur is if the element
 *  is exiting the DOM on its own).
 *
 *
 * </div>
 *
 * ### Animating to a Final State
 *
 * If the final step in a transition is a call to `animate()` that uses a timing value
 * with no `style` data, that step is automatically considered the final animation arc,
 * for the element to reach the final state, in such case Angular automatically adds or removes
 * CSS styles to ensure that the element is in the correct final state.
 *
 *
 * ### Usage Examples
 *
 *  - Transition animations applied based on
 *    the trigger's expression value
 *
 *   ```HTML
 *   <div [@myAnimationTrigger]="myStatusExp">
 *    ...
 *   </div>
 *   ```
 *
 *   ```typescript
 *   trigger("myAnimationTrigger", [
 *     ..., // states
 *     transition("on => off, open => closed", animate(500)),
 *     transition("* <=> error", query('.indicator', animateChild()))
 *   ])
 *   ```
 *
 *  - Transition animations applied based on custom logic dependent
 *    on the trigger's expression value and provided parameters
 *
 *    ```HTML
 *    <div [@myAnimationTrigger]="{
 *     value: stepName,
 *     params: { target: currentTarget }
 *    }">
 *     ...
 *    </div>
 *    ```
 *
 *    ```typescript
 *    trigger("myAnimationTrigger", [
 *      ..., // states
 *      transition(
 *        (fromState, toState, _element, params) =>
 *          ['firststep', 'laststep'].includes(fromState.toLowerCase())
 *          && toState === params?.['target'],
 *        animate('1s')
 *      )
 *    ])
 *    ```
 *
 * @publicApi
 **/
function transition(stateChangeExpr, steps, options = null) {
  return {
    type: AnimationMetadataType.Transition,
    expr: stateChangeExpr,
    animation: steps,
    options
  };
}
/**
 * Produces a reusable animation that can be invoked in another animation or sequence,
 * by calling the `useAnimation()` function.
 *
 * @param steps One or more animation objects, as returned by the `animate()`
 * or `sequence()` function, that form a transformation from one state to another.
 * A sequence is used by default when you pass an array.
 * @param options An options object that can contain a delay value for the start of the
 * animation, and additional developer-defined parameters.
 * Provided values for additional parameters are used as defaults,
 * and override values can be passed to the caller on invocation.
 * @returns An object that encapsulates the animation data.
 *
 * @usageNotes
 * The following example defines a reusable animation, providing some default parameter
 * values.
 *
 * ```typescript
 * var fadeAnimation = animation([
 *   style({ opacity: '{{ start }}' }),
 *   animate('{{ time }}',
 *   style({ opacity: '{{ end }}'}))
 *   ],
 *   { params: { time: '1000ms', start: 0, end: 1 }});
 * ```
 *
 * The following invokes the defined animation with a call to `useAnimation()`,
 * passing in override parameter values.
 *
 * ```js
 * useAnimation(fadeAnimation, {
 *   params: {
 *     time: '2s',
 *     start: 1,
 *     end: 0
 *   }
 * })
 * ```
 *
 * If any of the passed-in parameter values are missing from this call,
 * the default values are used. If one or more parameter values are missing before a step is
 * animated, `useAnimation()` throws an error.
 *
 * @publicApi
 */
function animation(steps, options = null) {
  return {
    type: AnimationMetadataType.Reference,
    animation: steps,
    options
  };
}
/**
 * Executes a queried inner animation element within an animation sequence.
 *
 * @param options An options object that can contain a delay value for the start of the
 * animation, and additional override values for developer-defined parameters.
 * @return An object that encapsulates the child animation data.
 *
 * @usageNotes
 * Each time an animation is triggered in Angular, the parent animation
 * has priority and any child animations are blocked. In order
 * for a child animation to run, the parent animation must query each of the elements
 * containing child animations, and run them using this function.
 *
 * Note that this feature is designed to be used with `query()` and it will only work
 * with animations that are assigned using the Angular animation library. CSS keyframes
 * and transitions are not handled by this API.
 *
 * @publicApi
 */
function animateChild(options = null) {
  return {
    type: AnimationMetadataType.AnimateChild,
    options
  };
}
/**
 * Starts a reusable animation that is created using the `animation()` function.
 *
 * @param animation The reusable animation to start.
 * @param options An options object that can contain a delay value for the start of
 * the animation, and additional override values for developer-defined parameters.
 * @return An object that contains the animation parameters.
 *
 * @publicApi
 */
function useAnimation(animation, options = null) {
  return {
    type: AnimationMetadataType.AnimateRef,
    animation,
    options
  };
}
/**
 * Finds one or more inner elements within the current element that is
 * being animated within a sequence. Use with `animate()`.
 *
 * @param selector The element to query, or a set of elements that contain Angular-specific
 * characteristics, specified with one or more of the following tokens.
 *  - `query(":enter")` or `query(":leave")` : Query for newly inserted/removed elements (not
 *     all elements can be queried via these tokens, see
 *     [Entering and Leaving Elements](#entering-and-leaving-elements))
 *  - `query(":animating")` : Query all currently animating elements.
 *  - `query("@triggerName")` : Query elements that contain an animation trigger.
 *  - `query("@*")` : Query all elements that contain an animation triggers.
 *  - `query(":self")` : Include the current element into the animation sequence.
 *
 * @param animation One or more animation steps to apply to the queried element or elements.
 * An array is treated as an animation sequence.
 * @param options An options object. Use the 'limit' field to limit the total number of
 * items to collect.
 * @return An object that encapsulates the query data.
 *
 * @usageNotes
 *
 * ### Multiple Tokens
 *
 * Tokens can be merged into a combined query selector string. For example:
 *
 * ```typescript
 *  query(':self, .record:enter, .record:leave, @subTrigger', [...])
 * ```
 *
 * The `query()` function collects multiple elements and works internally by using
 * `element.querySelectorAll`. Use the `limit` field of an options object to limit
 * the total number of items to be collected. For example:
 *
 * ```js
 * query('div', [
 *   animate(...),
 *   animate(...)
 * ], { limit: 1 })
 * ```
 *
 * By default, throws an error when zero items are found. Set the
 * `optional` flag to ignore this error. For example:
 *
 * ```js
 * query('.some-element-that-may-not-be-there', [
 *   animate(...),
 *   animate(...)
 * ], { optional: true })
 * ```
 *
 * ### Entering and Leaving Elements
 *
 * Not all elements can be queried via the `:enter` and `:leave` tokens, the only ones
 * that can are those that Angular assumes can enter/leave based on their own logic
 * (if their insertion/removal is simply a consequence of that of their parent they
 * should be queried via a different token in their parent's `:enter`/`:leave` transitions).
 *
 * The only elements Angular assumes can enter/leave based on their own logic (thus the only
 * ones that can be queried via the `:enter` and `:leave` tokens) are:
 *  - Those inserted dynamically (via `ViewContainerRef`)
 *  - Those that have a structural directive (which, under the hood, are a subset of the above ones)
 *
 * <div class="alert is-helpful">
 *
 *  Note that elements will be successfully queried via `:enter`/`:leave` even if their
 *  insertion/removal is not done manually via `ViewContainerRef`or caused by their structural
 *  directive (e.g. they enter/exit alongside their parent).
 *
 * </div>
 *
 * <div class="alert is-important">
 *
 *  There is an exception to what previously mentioned, besides elements entering/leaving based on
 *  their own logic, elements with an animation trigger can always be queried via `:leave` when
 * their parent is also leaving.
 *
 * </div>
 *
 * ### Usage Example
 *
 * The following example queries for inner elements and animates them
 * individually using `animate()`.
 *
 * ```typescript
 * @Component({
 *   selector: 'inner',
 *   template: `
 *     <div [@queryAnimation]="exp">
 *       <h1>Title</h1>
 *       <div class="content">
 *         Blah blah blah
 *       </div>
 *     </div>
 *   `,
 *   animations: [
 *    trigger('queryAnimation', [
 *      transition('* => goAnimate', [
 *        // hide the inner elements
 *        query('h1', style({ opacity: 0 })),
 *        query('.content', style({ opacity: 0 })),
 *
 *        // animate the inner elements in, one by one
 *        query('h1', animate(1000, style({ opacity: 1 }))),
 *        query('.content', animate(1000, style({ opacity: 1 }))),
 *      ])
 *    ])
 *  ]
 * })
 * class Cmp {
 *   exp = '';
 *
 *   goAnimate() {
 *     this.exp = 'goAnimate';
 *   }
 * }
 * ```
 *
 * @publicApi
 */
function query(selector, animation, options = null) {
  return {
    type: AnimationMetadataType.Query,
    selector,
    animation,
    options
  };
}
/**
 * Use within an animation `query()` call to issue a timing gap after
 * each queried item is animated.
 *
 * @param timings A delay value.
 * @param animation One ore more animation steps.
 * @returns An object that encapsulates the stagger data.
 *
 * @usageNotes
 * In the following example, a container element wraps a list of items stamped out
 * by an `ngFor`. The container element contains an animation trigger that will later be set
 * to query for each of the inner items.
 *
 * Each time items are added, the opacity fade-in animation runs,
 * and each removed item is faded out.
 * When either of these animations occur, the stagger effect is
 * applied after each item's animation is started.
 *
 * ```html
 * <!-- list.component.html -->
 * <button (click)="toggle()">Show / Hide Items</button>
 * <hr />
 * <div [@listAnimation]="items.length">
 *   <div *ngFor="let item of items">
 *     {{ item }}
 *   </div>
 * </div>
 * ```
 *
 * Here is the component code:
 *
 * ```typescript
 * import {trigger, transition, style, animate, query, stagger} from '@angular/animations';
 * @Component({
 *   templateUrl: 'list.component.html',
 *   animations: [
 *     trigger('listAnimation', [
 *     ...
 *     ])
 *   ]
 * })
 * class ListComponent {
 *   items = [];
 *
 *   showItems() {
 *     this.items = [0,1,2,3,4];
 *   }
 *
 *   hideItems() {
 *     this.items = [];
 *   }
 *
 *   toggle() {
 *     this.items.length ? this.hideItems() : this.showItems();
 *    }
 *  }
 * ```
 *
 * Here is the animation trigger code:
 *
 * ```typescript
 * trigger('listAnimation', [
 *   transition('* => *', [ // each time the binding value changes
 *     query(':leave', [
 *       stagger(100, [
 *         animate('0.5s', style({ opacity: 0 }))
 *       ])
 *     ]),
 *     query(':enter', [
 *       style({ opacity: 0 }),
 *       stagger(100, [
 *         animate('0.5s', style({ opacity: 1 }))
 *       ])
 *     ])
 *   ])
 * ])
 * ```
 *
 * @publicApi
 */
function stagger(timings, animation) {
  return {
    type: AnimationMetadataType.Stagger,
    timings,
    animation
  };
}

/**
 * An injectable service that produces an animation sequence programmatically within an
 * Angular component or directive.
 * Provided by the `BrowserAnimationsModule` or `NoopAnimationsModule`.
 *
 * @usageNotes
 *
 * To use this service, add it to your component or directive as a dependency.
 * The service is instantiated along with your component.
 *
 * Apps do not typically need to create their own animation players, but if you
 * do need to, follow these steps:
 *
 * 1. Use the <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code> method
 * to create a programmatic animation. The method returns an `AnimationFactory` instance.
 *
 * 2. Use the factory object to create an `AnimationPlayer` and attach it to a DOM element.
 *
 * 3. Use the player object to control the animation programmatically.
 *
 * For example:
 *
 * ```ts
 * // import the service from BrowserAnimationsModule
 * import {AnimationBuilder} from '@angular/animations';
 * // require the service as a dependency
 * class MyCmp {
 *   constructor(private _builder: AnimationBuilder) {}
 *
 *   makeAnimation(element: any) {
 *     // first define a reusable animation
 *     const myAnimation = this._builder.build([
 *       style({ width: 0 }),
 *       animate(1000, style({ width: '100px' }))
 *     ]);
 *
 *     // use the returned factory object to create a player
 *     const player = myAnimation.create(element);
 *
 *     player.play();
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class AnimationBuilder {
  static {
    this.ɵfac = function AnimationBuilder_Factory(t) {
      return new (t || AnimationBuilder)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: AnimationBuilder,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(BrowserAnimationBuilder))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AnimationBuilder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(BrowserAnimationBuilder)
    }]
  }], null, null);
})();
/**
 * A factory object returned from the
 * <code>[AnimationBuilder.build](api/animations/AnimationBuilder#build)()</code>
 * method.
 *
 * @publicApi
 */
class AnimationFactory {}
class BrowserAnimationBuilder extends AnimationBuilder {
  constructor(rootRenderer, doc) {
    super();
    this.animationModuleType = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE, {
      optional: true
    });
    this._nextAnimationId = 0;
    const typeData = {
      id: '0',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      styles: [],
      data: {
        animation: []
      }
    };
    this._renderer = rootRenderer.createRenderer(doc.body, typeData);
    if (this.animationModuleType === null && !isAnimationRenderer(this._renderer)) {
      // We only support AnimationRenderer & DynamicDelegationRenderer for this AnimationBuilder
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3600 /* RuntimeErrorCode.BROWSER_ANIMATION_BUILDER_INJECTED_WITHOUT_ANIMATIONS */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Angular detected that the `AnimationBuilder` was injected, but animation support was not enabled. ' + 'Please make sure that you enable animations in your application by calling `provideAnimations()` or `provideAnimationsAsync()` function.');
    }
  }
  build(animation) {
    const id = this._nextAnimationId;
    this._nextAnimationId++;
    const entry = Array.isArray(animation) ? sequence(animation) : animation;
    issueAnimationCommand(this._renderer, null, id, 'register', [entry]);
    return new BrowserAnimationFactory(id, this._renderer);
  }
  static {
    this.ɵfac = function BrowserAnimationBuilder_Factory(t) {
      return new (t || BrowserAnimationBuilder)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: BrowserAnimationBuilder,
      factory: BrowserAnimationBuilder.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserAnimationBuilder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2
  }, {
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }], null);
})();
class BrowserAnimationFactory extends AnimationFactory {
  constructor(_id, _renderer) {
    super();
    this._id = _id;
    this._renderer = _renderer;
  }
  create(element, options) {
    return new RendererAnimationPlayer(this._id, element, options || {}, this._renderer);
  }
}
class RendererAnimationPlayer {
  constructor(id, element, options, _renderer) {
    this.id = id;
    this.element = element;
    this._renderer = _renderer;
    this.parentPlayer = null;
    this._started = false;
    this.totalTime = 0;
    this._command('create', options);
  }
  _listen(eventName, callback) {
    return this._renderer.listen(this.element, `@@${this.id}:${eventName}`, callback);
  }
  _command(command, ...args) {
    issueAnimationCommand(this._renderer, this.element, this.id, command, args);
  }
  onDone(fn) {
    this._listen('done', fn);
  }
  onStart(fn) {
    this._listen('start', fn);
  }
  onDestroy(fn) {
    this._listen('destroy', fn);
  }
  init() {
    this._command('init');
  }
  hasStarted() {
    return this._started;
  }
  play() {
    this._command('play');
    this._started = true;
  }
  pause() {
    this._command('pause');
  }
  restart() {
    this._command('restart');
  }
  finish() {
    this._command('finish');
  }
  destroy() {
    this._command('destroy');
  }
  reset() {
    this._command('reset');
    this._started = false;
  }
  setPosition(p) {
    this._command('setPosition', p);
  }
  getPosition() {
    return unwrapAnimationRenderer(this._renderer)?.engine?.players[this.id]?.getPosition() ?? 0;
  }
}
function issueAnimationCommand(renderer, element, id, command, args) {
  renderer.setProperty(element, `@@${id}:${command}`, args);
}
/**
 * The following 2 methods cannot reference their correct types (AnimationRenderer &
 * DynamicDelegationRenderer) since this would introduce a import cycle.
 */
function unwrapAnimationRenderer(renderer) {
  const type = renderer.ɵtype;
  if (type === 0 /* AnimationRendererType.Regular */) {
    return renderer;
  } else if (type === 1 /* AnimationRendererType.Delegated */) {
    return renderer.animationRenderer;
  }
  return null;
}
function isAnimationRenderer(renderer) {
  const type = renderer.ɵtype;
  return type === 0 /* AnimationRendererType.Regular */ || type === 1 /* AnimationRendererType.Delegated */;
}

/**
 * An empty programmatic controller for reusable animations.
 * Used internally when animations are disabled, to avoid
 * checking for the null case when an animation player is expected.
 *
 * @see {@link animate}
 * @see {@link AnimationPlayer}
 * @see {@link ɵAnimationGroupPlayer AnimationGroupPlayer}
 *
 * @publicApi
 */
class NoopAnimationPlayer {
  constructor(duration = 0, delay = 0) {
    this._onDoneFns = [];
    this._onStartFns = [];
    this._onDestroyFns = [];
    this._originalOnDoneFns = [];
    this._originalOnStartFns = [];
    this._started = false;
    this._destroyed = false;
    this._finished = false;
    this._position = 0;
    this.parentPlayer = null;
    this.totalTime = duration + delay;
  }
  _onFinish() {
    if (!this._finished) {
      this._finished = true;
      this._onDoneFns.forEach(fn => fn());
      this._onDoneFns = [];
    }
  }
  onStart(fn) {
    this._originalOnStartFns.push(fn);
    this._onStartFns.push(fn);
  }
  onDone(fn) {
    this._originalOnDoneFns.push(fn);
    this._onDoneFns.push(fn);
  }
  onDestroy(fn) {
    this._onDestroyFns.push(fn);
  }
  hasStarted() {
    return this._started;
  }
  init() {}
  play() {
    if (!this.hasStarted()) {
      this._onStart();
      this.triggerMicrotask();
    }
    this._started = true;
  }
  /** @internal */
  triggerMicrotask() {
    queueMicrotask(() => this._onFinish());
  }
  _onStart() {
    this._onStartFns.forEach(fn => fn());
    this._onStartFns = [];
  }
  pause() {}
  restart() {}
  finish() {
    this._onFinish();
  }
  destroy() {
    if (!this._destroyed) {
      this._destroyed = true;
      if (!this.hasStarted()) {
        this._onStart();
      }
      this.finish();
      this._onDestroyFns.forEach(fn => fn());
      this._onDestroyFns = [];
    }
  }
  reset() {
    this._started = false;
    this._finished = false;
    this._onStartFns = this._originalOnStartFns;
    this._onDoneFns = this._originalOnDoneFns;
  }
  setPosition(position) {
    this._position = this.totalTime ? position * this.totalTime : 1;
  }
  getPosition() {
    return this.totalTime ? this._position / this.totalTime : 1;
  }
  /** @internal */
  triggerCallback(phaseName) {
    const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
    methods.forEach(fn => fn());
    methods.length = 0;
  }
}

/**
 * A programmatic controller for a group of reusable animations.
 * Used internally to control animations.
 *
 * @see {@link AnimationPlayer}
 * @see {@link animations/group group}
 *
 */
class AnimationGroupPlayer {
  constructor(_players) {
    this._onDoneFns = [];
    this._onStartFns = [];
    this._finished = false;
    this._started = false;
    this._destroyed = false;
    this._onDestroyFns = [];
    this.parentPlayer = null;
    this.totalTime = 0;
    this.players = _players;
    let doneCount = 0;
    let destroyCount = 0;
    let startCount = 0;
    const total = this.players.length;
    if (total == 0) {
      queueMicrotask(() => this._onFinish());
    } else {
      this.players.forEach(player => {
        player.onDone(() => {
          if (++doneCount == total) {
            this._onFinish();
          }
        });
        player.onDestroy(() => {
          if (++destroyCount == total) {
            this._onDestroy();
          }
        });
        player.onStart(() => {
          if (++startCount == total) {
            this._onStart();
          }
        });
      });
    }
    this.totalTime = this.players.reduce((time, player) => Math.max(time, player.totalTime), 0);
  }
  _onFinish() {
    if (!this._finished) {
      this._finished = true;
      this._onDoneFns.forEach(fn => fn());
      this._onDoneFns = [];
    }
  }
  init() {
    this.players.forEach(player => player.init());
  }
  onStart(fn) {
    this._onStartFns.push(fn);
  }
  _onStart() {
    if (!this.hasStarted()) {
      this._started = true;
      this._onStartFns.forEach(fn => fn());
      this._onStartFns = [];
    }
  }
  onDone(fn) {
    this._onDoneFns.push(fn);
  }
  onDestroy(fn) {
    this._onDestroyFns.push(fn);
  }
  hasStarted() {
    return this._started;
  }
  play() {
    if (!this.parentPlayer) {
      this.init();
    }
    this._onStart();
    this.players.forEach(player => player.play());
  }
  pause() {
    this.players.forEach(player => player.pause());
  }
  restart() {
    this.players.forEach(player => player.restart());
  }
  finish() {
    this._onFinish();
    this.players.forEach(player => player.finish());
  }
  destroy() {
    this._onDestroy();
  }
  _onDestroy() {
    if (!this._destroyed) {
      this._destroyed = true;
      this._onFinish();
      this.players.forEach(player => player.destroy());
      this._onDestroyFns.forEach(fn => fn());
      this._onDestroyFns = [];
    }
  }
  reset() {
    this.players.forEach(player => player.reset());
    this._destroyed = false;
    this._finished = false;
    this._started = false;
  }
  setPosition(p) {
    const timeAtPosition = p * this.totalTime;
    this.players.forEach(player => {
      const position = player.totalTime ? Math.min(1, timeAtPosition / player.totalTime) : 1;
      player.setPosition(position);
    });
  }
  getPosition() {
    const longestPlayer = this.players.reduce((longestSoFar, player) => {
      const newPlayerIsLongest = longestSoFar === null || player.totalTime > longestSoFar.totalTime;
      return newPlayerIsLongest ? player : longestSoFar;
    }, null);
    return longestPlayer != null ? longestPlayer.getPosition() : 0;
  }
  beforeDestroy() {
    this.players.forEach(player => {
      if (player.beforeDestroy) {
        player.beforeDestroy();
      }
    });
  }
  /** @internal */
  triggerCallback(phaseName) {
    const methods = phaseName == 'start' ? this._onStartFns : this._onDoneFns;
    methods.forEach(fn => fn());
    methods.length = 0;
  }
}
const ɵPRE_STYLE = '!';

/**
 * @module
 * @description
 * Entry point for all animation APIs of the animation package.
 */

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 10655:
/*!***************************************************************!*\
  !*** ./node_modules/@angular/animations/fesm2022/browser.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnimationDriver: () => (/* binding */ AnimationDriver),
/* harmony export */   NoopAnimationDriver: () => (/* binding */ NoopAnimationDriver),
/* harmony export */   "ɵAnimation": () => (/* binding */ Animation),
/* harmony export */   "ɵAnimationEngine": () => (/* binding */ AnimationEngine),
/* harmony export */   "ɵAnimationRenderer": () => (/* binding */ AnimationRenderer),
/* harmony export */   "ɵAnimationRendererFactory": () => (/* binding */ AnimationRendererFactory),
/* harmony export */   "ɵAnimationStyleNormalizer": () => (/* binding */ AnimationStyleNormalizer),
/* harmony export */   "ɵBaseAnimationRenderer": () => (/* binding */ BaseAnimationRenderer),
/* harmony export */   "ɵNoopAnimationStyleNormalizer": () => (/* binding */ NoopAnimationStyleNormalizer),
/* harmony export */   "ɵWebAnimationsDriver": () => (/* binding */ WebAnimationsDriver),
/* harmony export */   "ɵWebAnimationsPlayer": () => (/* binding */ WebAnimationsPlayer),
/* harmony export */   "ɵWebAnimationsStyleNormalizer": () => (/* binding */ WebAnimationsStyleNormalizer),
/* harmony export */   "ɵallowPreviousPlayerStylesMerge": () => (/* binding */ allowPreviousPlayerStylesMerge),
/* harmony export */   "ɵcamelCaseToDashCase": () => (/* binding */ camelCaseToDashCase),
/* harmony export */   "ɵcontainsElement": () => (/* binding */ containsElement),
/* harmony export */   "ɵcreateEngine": () => (/* binding */ createEngine),
/* harmony export */   "ɵgetParentElement": () => (/* binding */ getParentElement),
/* harmony export */   "ɵinvokeQuery": () => (/* binding */ invokeQuery),
/* harmony export */   "ɵnormalizeKeyframes": () => (/* binding */ normalizeKeyframes),
/* harmony export */   "ɵvalidateStyleProperty": () => (/* binding */ validateStyleProperty),
/* harmony export */   "ɵvalidateWebAnimatableStyleProperty": () => (/* binding */ validateWebAnimatableStyleProperty)
/* harmony export */ });
/* harmony import */ var _angular_animations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/animations */ 47172);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */




const LINE_START = '\n - ';
function invalidTimingValue(exp) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3000 /* RuntimeErrorCode.INVALID_TIMING_VALUE */, ngDevMode && `The provided timing value "${exp}" is invalid.`);
}
function negativeStepValue() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3100 /* RuntimeErrorCode.NEGATIVE_STEP_VALUE */, ngDevMode && 'Duration values below 0 are not allowed for this animation step.');
}
function negativeDelayValue() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3101 /* RuntimeErrorCode.NEGATIVE_DELAY_VALUE */, ngDevMode && 'Delay values below 0 are not allowed for this animation step.');
}
function invalidStyleParams(varName) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3001 /* RuntimeErrorCode.INVALID_STYLE_PARAMS */, ngDevMode && `Unable to resolve the local animation param ${varName} in the given list of values`);
}
function invalidParamValue(varName) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3003 /* RuntimeErrorCode.INVALID_PARAM_VALUE */, ngDevMode && `Please provide a value for the animation param ${varName}`);
}
function invalidNodeType(nodeType) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3004 /* RuntimeErrorCode.INVALID_NODE_TYPE */, ngDevMode && `Unable to resolve animation metadata node #${nodeType}`);
}
function invalidCssUnitValue(userProvidedProperty, value) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3005 /* RuntimeErrorCode.INVALID_CSS_UNIT_VALUE */, ngDevMode && `Please provide a CSS unit value for ${userProvidedProperty}:${value}`);
}
function invalidTrigger() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3006 /* RuntimeErrorCode.INVALID_TRIGGER */, ngDevMode && "animation triggers cannot be prefixed with an `@` sign (e.g. trigger('@foo', [...]))");
}
function invalidDefinition() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3007 /* RuntimeErrorCode.INVALID_DEFINITION */, ngDevMode && 'only state() and transition() definitions can sit inside of a trigger()');
}
function invalidState(metadataName, missingSubs) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3008 /* RuntimeErrorCode.INVALID_STATE */, ngDevMode && `state("${metadataName}", ...) must define default values for all the following style substitutions: ${missingSubs.join(', ')}`);
}
function invalidStyleValue(value) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3002 /* RuntimeErrorCode.INVALID_STYLE_VALUE */, ngDevMode && `The provided style string value ${value} is not allowed.`);
}
function invalidProperty(prop) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3009 /* RuntimeErrorCode.INVALID_PROPERTY */, ngDevMode && `The provided animation property "${prop}" is not a supported CSS property for animations`);
}
function invalidParallelAnimation(prop, firstStart, firstEnd, secondStart, secondEnd) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3010 /* RuntimeErrorCode.INVALID_PARALLEL_ANIMATION */, ngDevMode && `The CSS property "${prop}" that exists between the times of "${firstStart}ms" and "${firstEnd}ms" is also being animated in a parallel animation between the times of "${secondStart}ms" and "${secondEnd}ms"`);
}
function invalidKeyframes() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3011 /* RuntimeErrorCode.INVALID_KEYFRAMES */, ngDevMode && `keyframes() must be placed inside of a call to animate()`);
}
function invalidOffset() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3012 /* RuntimeErrorCode.INVALID_OFFSET */, ngDevMode && `Please ensure that all keyframe offsets are between 0 and 1`);
}
function keyframeOffsetsOutOfOrder() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3200 /* RuntimeErrorCode.KEYFRAME_OFFSETS_OUT_OF_ORDER */, ngDevMode && `Please ensure that all keyframe offsets are in order`);
}
function keyframesMissingOffsets() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3202 /* RuntimeErrorCode.KEYFRAMES_MISSING_OFFSETS */, ngDevMode && `Not all style() steps within the declared keyframes() contain offsets`);
}
function invalidStagger() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3013 /* RuntimeErrorCode.INVALID_STAGGER */, ngDevMode && `stagger() can only be used inside of query()`);
}
function invalidQuery(selector) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3014 /* RuntimeErrorCode.INVALID_QUERY */, ngDevMode && `\`query("${selector}")\` returned zero elements. (Use \`query("${selector}", { optional: true })\` if you wish to allow this.)`);
}
function invalidExpression(expr) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3015 /* RuntimeErrorCode.INVALID_EXPRESSION */, ngDevMode && `The provided transition expression "${expr}" is not supported`);
}
function invalidTransitionAlias(alias) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3016 /* RuntimeErrorCode.INVALID_TRANSITION_ALIAS */, ngDevMode && `The transition alias value "${alias}" is not supported`);
}
function validationFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3500 /* RuntimeErrorCode.VALIDATION_FAILED */, ngDevMode && `animation validation failed:\n${errors.map(err => err.message).join('\n')}`);
}
function buildingFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3501 /* RuntimeErrorCode.BUILDING_FAILED */, ngDevMode && `animation building failed:\n${errors.map(err => err.message).join('\n')}`);
}
function triggerBuildFailed(name, errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3404 /* RuntimeErrorCode.TRIGGER_BUILD_FAILED */, ngDevMode && `The animation trigger "${name}" has failed to build due to the following errors:\n - ${errors.map(err => err.message).join('\n - ')}`);
}
function animationFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3502 /* RuntimeErrorCode.ANIMATION_FAILED */, ngDevMode && `Unable to animate due to the following errors:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
}
function registerFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3503 /* RuntimeErrorCode.REGISTRATION_FAILED */, ngDevMode && `Unable to build the animation due to the following errors: ${errors.map(err => err.message).join('\n')}`);
}
function missingOrDestroyedAnimation() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3300 /* RuntimeErrorCode.MISSING_OR_DESTROYED_ANIMATION */, ngDevMode && "The requested animation doesn't exist or has already been destroyed");
}
function createAnimationFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3504 /* RuntimeErrorCode.CREATE_ANIMATION_FAILED */, ngDevMode && `Unable to create the animation due to the following errors:${errors.map(err => err.message).join('\n')}`);
}
function missingPlayer(id) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3301 /* RuntimeErrorCode.MISSING_PLAYER */, ngDevMode && `Unable to find the timeline player referenced by ${id}`);
}
function missingTrigger(phase, name) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3302 /* RuntimeErrorCode.MISSING_TRIGGER */, ngDevMode && `Unable to listen on the animation trigger event "${phase}" because the animation trigger "${name}" doesn\'t exist!`);
}
function missingEvent(name) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3303 /* RuntimeErrorCode.MISSING_EVENT */, ngDevMode && `Unable to listen on the animation trigger "${name}" because the provided event is undefined!`);
}
function unsupportedTriggerEvent(phase, name) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3400 /* RuntimeErrorCode.UNSUPPORTED_TRIGGER_EVENT */, ngDevMode && `The provided animation trigger event "${phase}" for the animation trigger "${name}" is not supported!`);
}
function unregisteredTrigger(name) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3401 /* RuntimeErrorCode.UNREGISTERED_TRIGGER */, ngDevMode && `The provided animation trigger "${name}" has not been registered!`);
}
function triggerTransitionsFailed(errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3402 /* RuntimeErrorCode.TRIGGER_TRANSITIONS_FAILED */, ngDevMode && `Unable to process animations due to the following failed trigger transitions\n ${errors.map(err => err.message).join('\n')}`);
}
function triggerParsingFailed(name, errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3403 /* RuntimeErrorCode.TRIGGER_PARSING_FAILED */, ngDevMode && `Animation parsing for the ${name} trigger have failed:${LINE_START}${errors.map(err => err.message).join(LINE_START)}`);
}
function transitionFailed(name, errors) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](3505 /* RuntimeErrorCode.TRANSITION_FAILED */, ngDevMode && `@${name} has failed due to:\n ${errors.map(err => err.message).join('\n- ')}`);
}

/**
 * Set of all animatable CSS properties
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
 */
const ANIMATABLE_PROP_SET = new Set(['-moz-outline-radius', '-moz-outline-radius-bottomleft', '-moz-outline-radius-bottomright', '-moz-outline-radius-topleft', '-moz-outline-radius-topright', '-ms-grid-columns', '-ms-grid-rows', '-webkit-line-clamp', '-webkit-text-fill-color', '-webkit-text-stroke', '-webkit-text-stroke-color', 'accent-color', 'all', 'backdrop-filter', 'background', 'background-color', 'background-position', 'background-size', 'block-size', 'border', 'border-block-end', 'border-block-end-color', 'border-block-end-width', 'border-block-start', 'border-block-start-color', 'border-block-start-width', 'border-bottom', 'border-bottom-color', 'border-bottom-left-radius', 'border-bottom-right-radius', 'border-bottom-width', 'border-color', 'border-end-end-radius', 'border-end-start-radius', 'border-image-outset', 'border-image-slice', 'border-image-width', 'border-inline-end', 'border-inline-end-color', 'border-inline-end-width', 'border-inline-start', 'border-inline-start-color', 'border-inline-start-width', 'border-left', 'border-left-color', 'border-left-width', 'border-radius', 'border-right', 'border-right-color', 'border-right-width', 'border-start-end-radius', 'border-start-start-radius', 'border-top', 'border-top-color', 'border-top-left-radius', 'border-top-right-radius', 'border-top-width', 'border-width', 'bottom', 'box-shadow', 'caret-color', 'clip', 'clip-path', 'color', 'column-count', 'column-gap', 'column-rule', 'column-rule-color', 'column-rule-width', 'column-width', 'columns', 'filter', 'flex', 'flex-basis', 'flex-grow', 'flex-shrink', 'font', 'font-size', 'font-size-adjust', 'font-stretch', 'font-variation-settings', 'font-weight', 'gap', 'grid-column-gap', 'grid-gap', 'grid-row-gap', 'grid-template-columns', 'grid-template-rows', 'height', 'inline-size', 'input-security', 'inset', 'inset-block', 'inset-block-end', 'inset-block-start', 'inset-inline', 'inset-inline-end', 'inset-inline-start', 'left', 'letter-spacing', 'line-clamp', 'line-height', 'margin', 'margin-block-end', 'margin-block-start', 'margin-bottom', 'margin-inline-end', 'margin-inline-start', 'margin-left', 'margin-right', 'margin-top', 'mask', 'mask-border', 'mask-position', 'mask-size', 'max-block-size', 'max-height', 'max-inline-size', 'max-lines', 'max-width', 'min-block-size', 'min-height', 'min-inline-size', 'min-width', 'object-position', 'offset', 'offset-anchor', 'offset-distance', 'offset-path', 'offset-position', 'offset-rotate', 'opacity', 'order', 'outline', 'outline-color', 'outline-offset', 'outline-width', 'padding', 'padding-block-end', 'padding-block-start', 'padding-bottom', 'padding-inline-end', 'padding-inline-start', 'padding-left', 'padding-right', 'padding-top', 'perspective', 'perspective-origin', 'right', 'rotate', 'row-gap', 'scale', 'scroll-margin', 'scroll-margin-block', 'scroll-margin-block-end', 'scroll-margin-block-start', 'scroll-margin-bottom', 'scroll-margin-inline', 'scroll-margin-inline-end', 'scroll-margin-inline-start', 'scroll-margin-left', 'scroll-margin-right', 'scroll-margin-top', 'scroll-padding', 'scroll-padding-block', 'scroll-padding-block-end', 'scroll-padding-block-start', 'scroll-padding-bottom', 'scroll-padding-inline', 'scroll-padding-inline-end', 'scroll-padding-inline-start', 'scroll-padding-left', 'scroll-padding-right', 'scroll-padding-top', 'scroll-snap-coordinate', 'scroll-snap-destination', 'scrollbar-color', 'shape-image-threshold', 'shape-margin', 'shape-outside', 'tab-size', 'text-decoration', 'text-decoration-color', 'text-decoration-thickness', 'text-emphasis', 'text-emphasis-color', 'text-indent', 'text-shadow', 'text-underline-offset', 'top', 'transform', 'transform-origin', 'translate', 'vertical-align', 'visibility', 'width', 'word-spacing', 'z-index', 'zoom']);
function optimizeGroupPlayer(players) {
  switch (players.length) {
    case 0:
      return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer();
    case 1:
      return players[0];
    default:
      return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationGroupPlayer"](players);
  }
}
function normalizeKeyframes$1(normalizer, keyframes, preStyles = new Map(), postStyles = new Map()) {
  const errors = [];
  const normalizedKeyframes = [];
  let previousOffset = -1;
  let previousKeyframe = null;
  keyframes.forEach(kf => {
    const offset = kf.get('offset');
    const isSameOffset = offset == previousOffset;
    const normalizedKeyframe = isSameOffset && previousKeyframe || new Map();
    kf.forEach((val, prop) => {
      let normalizedProp = prop;
      let normalizedValue = val;
      if (prop !== 'offset') {
        normalizedProp = normalizer.normalizePropertyName(normalizedProp, errors);
        switch (normalizedValue) {
          case _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]:
            normalizedValue = preStyles.get(prop);
            break;
          case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE:
            normalizedValue = postStyles.get(prop);
            break;
          default:
            normalizedValue = normalizer.normalizeStyleValue(prop, normalizedProp, normalizedValue, errors);
            break;
        }
      }
      normalizedKeyframe.set(normalizedProp, normalizedValue);
    });
    if (!isSameOffset) {
      normalizedKeyframes.push(normalizedKeyframe);
    }
    previousKeyframe = normalizedKeyframe;
    previousOffset = offset;
  });
  if (errors.length) {
    throw animationFailed(errors);
  }
  return normalizedKeyframes;
}
function listenOnPlayer(player, eventName, event, callback) {
  switch (eventName) {
    case 'start':
      player.onStart(() => callback(event && copyAnimationEvent(event, 'start', player)));
      break;
    case 'done':
      player.onDone(() => callback(event && copyAnimationEvent(event, 'done', player)));
      break;
    case 'destroy':
      player.onDestroy(() => callback(event && copyAnimationEvent(event, 'destroy', player)));
      break;
  }
}
function copyAnimationEvent(e, phaseName, player) {
  const totalTime = player.totalTime;
  const disabled = player.disabled ? true : false;
  const event = makeAnimationEvent(e.element, e.triggerName, e.fromState, e.toState, phaseName || e.phaseName, totalTime == undefined ? e.totalTime : totalTime, disabled);
  const data = e['_data'];
  if (data != null) {
    event['_data'] = data;
  }
  return event;
}
function makeAnimationEvent(element, triggerName, fromState, toState, phaseName = '', totalTime = 0, disabled) {
  return {
    element,
    triggerName,
    fromState,
    toState,
    phaseName,
    totalTime,
    disabled: !!disabled
  };
}
function getOrSetDefaultValue(map, key, defaultValue) {
  let value = map.get(key);
  if (!value) {
    map.set(key, value = defaultValue);
  }
  return value;
}
function parseTimelineCommand(command) {
  const separatorPos = command.indexOf(':');
  const id = command.substring(1, separatorPos);
  const action = command.slice(separatorPos + 1);
  return [id, action];
}
const documentElement = /* @__PURE__ */(() => typeof document === 'undefined' ? null : document.documentElement)();
function getParentElement(element) {
  const parent = element.parentNode || element.host || null; // consider host to support shadow DOM
  if (parent === documentElement) {
    return null;
  }
  return parent;
}
function containsVendorPrefix(prop) {
  // Webkit is the only real popular vendor prefix nowadays
  // cc: http://shouldiprefix.com/
  return prop.substring(1, 6) == 'ebkit'; // webkit or Webkit
}
let _CACHED_BODY = null;
let _IS_WEBKIT = false;
function validateStyleProperty(prop) {
  if (!_CACHED_BODY) {
    _CACHED_BODY = getBodyNode() || {};
    _IS_WEBKIT = _CACHED_BODY.style ? 'WebkitAppearance' in _CACHED_BODY.style : false;
  }
  let result = true;
  if (_CACHED_BODY.style && !containsVendorPrefix(prop)) {
    result = prop in _CACHED_BODY.style;
    if (!result && _IS_WEBKIT) {
      const camelProp = 'Webkit' + prop.charAt(0).toUpperCase() + prop.slice(1);
      result = camelProp in _CACHED_BODY.style;
    }
  }
  return result;
}
function validateWebAnimatableStyleProperty(prop) {
  return ANIMATABLE_PROP_SET.has(prop);
}
function getBodyNode() {
  if (typeof document != 'undefined') {
    return document.body;
  }
  return null;
}
function containsElement(elm1, elm2) {
  while (elm2) {
    if (elm2 === elm1) {
      return true;
    }
    elm2 = getParentElement(elm2);
  }
  return false;
}
function invokeQuery(element, selector, multi) {
  if (multi) {
    return Array.from(element.querySelectorAll(selector));
  }
  const elem = element.querySelector(selector);
  return elem ? [elem] : [];
}
function hypenatePropsKeys(original) {
  const newMap = new Map();
  original.forEach((val, prop) => {
    const newProp = prop.replace(/([a-z])([A-Z])/g, '$1-$2');
    newMap.set(newProp, val);
  });
  return newMap;
}

/**
 * @publicApi
 *
 * `AnimationDriver` implentation for Noop animations
 */
class NoopAnimationDriver {
  /**
   * @returns Whether `prop` is a valid CSS property
   */
  validateStyleProperty(prop) {
    return validateStyleProperty(prop);
  }
  /**
   * @deprecated unused
   */
  matchesElement(_element, _selector) {
    // This method is deprecated and no longer in use so we return false.
    return false;
  }
  /**
   *
   * @returns Whether elm1 contains elm2.
   */
  containsElement(elm1, elm2) {
    return containsElement(elm1, elm2);
  }
  /**
   * @returns Rhe parent of the given element or `null` if the element is the `document`
   */
  getParentElement(element) {
    return getParentElement(element);
  }
  /**
   * @returns The result of the query selector on the element. The array will contain up to 1 item
   *     if `multi` is  `false`.
   */
  query(element, selector, multi) {
    return invokeQuery(element, selector, multi);
  }
  /**
   * @returns The `defaultValue` or empty string
   */
  computeStyle(element, prop, defaultValue) {
    return defaultValue || '';
  }
  /**
   * @returns An `NoopAnimationPlayer`
   */
  animate(element, keyframes, duration, delay, easing, previousPlayers = [], scrubberAccessRequested) {
    return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(duration, delay);
  }
  static {
    this.ɵfac = function NoopAnimationDriver_Factory(t) {
      return new (t || NoopAnimationDriver)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NoopAnimationDriver,
      factory: NoopAnimationDriver.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NoopAnimationDriver, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
/**
 * @publicApi
 */
class AnimationDriver {
  /**
   * @deprecated Use the NoopAnimationDriver class.
   */
  static {
    this.NOOP = new NoopAnimationDriver();
  }
}
class AnimationStyleNormalizer {}
class NoopAnimationStyleNormalizer {
  normalizePropertyName(propertyName, errors) {
    return propertyName;
  }
  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
    return value;
  }
}
const ONE_SECOND = 1000;
const SUBSTITUTION_EXPR_START = '{{';
const SUBSTITUTION_EXPR_END = '}}';
const ENTER_CLASSNAME = 'ng-enter';
const LEAVE_CLASSNAME = 'ng-leave';
const NG_TRIGGER_CLASSNAME = 'ng-trigger';
const NG_TRIGGER_SELECTOR = '.ng-trigger';
const NG_ANIMATING_CLASSNAME = 'ng-animating';
const NG_ANIMATING_SELECTOR = '.ng-animating';
function resolveTimingValue(value) {
  if (typeof value == 'number') return value;
  const matches = value.match(/^(-?[\.\d]+)(m?s)/);
  if (!matches || matches.length < 2) return 0;
  return _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
}
function _convertTimeValueToMS(value, unit) {
  switch (unit) {
    case 's':
      return value * ONE_SECOND;
    default:
      // ms or something else
      return value;
  }
}
function resolveTiming(timings, errors, allowNegativeValues) {
  return timings.hasOwnProperty('duration') ? timings : parseTimeExpression(timings, errors, allowNegativeValues);
}
function parseTimeExpression(exp, errors, allowNegativeValues) {
  const regex = /^(-?[\.\d]+)(m?s)(?:\s+(-?[\.\d]+)(m?s))?(?:\s+([-a-z]+(?:\(.+?\))?))?$/i;
  let duration;
  let delay = 0;
  let easing = '';
  if (typeof exp === 'string') {
    const matches = exp.match(regex);
    if (matches === null) {
      errors.push(invalidTimingValue(exp));
      return {
        duration: 0,
        delay: 0,
        easing: ''
      };
    }
    duration = _convertTimeValueToMS(parseFloat(matches[1]), matches[2]);
    const delayMatch = matches[3];
    if (delayMatch != null) {
      delay = _convertTimeValueToMS(parseFloat(delayMatch), matches[4]);
    }
    const easingVal = matches[5];
    if (easingVal) {
      easing = easingVal;
    }
  } else {
    duration = exp;
  }
  if (!allowNegativeValues) {
    let containsErrors = false;
    let startIndex = errors.length;
    if (duration < 0) {
      errors.push(negativeStepValue());
      containsErrors = true;
    }
    if (delay < 0) {
      errors.push(negativeDelayValue());
      containsErrors = true;
    }
    if (containsErrors) {
      errors.splice(startIndex, 0, invalidTimingValue(exp));
    }
  }
  return {
    duration,
    delay,
    easing
  };
}
function normalizeKeyframes(keyframes) {
  if (!keyframes.length) {
    return [];
  }
  if (keyframes[0] instanceof Map) {
    return keyframes;
  }
  return keyframes.map(kf => new Map(Object.entries(kf)));
}
function normalizeStyles(styles) {
  return Array.isArray(styles) ? new Map(...styles) : new Map(styles);
}
function setStyles(element, styles, formerStyles) {
  styles.forEach((val, prop) => {
    const camelProp = dashCaseToCamelCase(prop);
    if (formerStyles && !formerStyles.has(prop)) {
      formerStyles.set(prop, element.style[camelProp]);
    }
    element.style[camelProp] = val;
  });
}
function eraseStyles(element, styles) {
  styles.forEach((_, prop) => {
    const camelProp = dashCaseToCamelCase(prop);
    element.style[camelProp] = '';
  });
}
function normalizeAnimationEntry(steps) {
  if (Array.isArray(steps)) {
    if (steps.length == 1) return steps[0];
    return (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.sequence)(steps);
  }
  return steps;
}
function validateStyleParams(value, options, errors) {
  const params = options.params || {};
  const matches = extractStyleParams(value);
  if (matches.length) {
    matches.forEach(varName => {
      if (!params.hasOwnProperty(varName)) {
        errors.push(invalidStyleParams(varName));
      }
    });
  }
}
const PARAM_REGEX = new RegExp(`${SUBSTITUTION_EXPR_START}\\s*(.+?)\\s*${SUBSTITUTION_EXPR_END}`, 'g');
function extractStyleParams(value) {
  let params = [];
  if (typeof value === 'string') {
    let match;
    while (match = PARAM_REGEX.exec(value)) {
      params.push(match[1]);
    }
    PARAM_REGEX.lastIndex = 0;
  }
  return params;
}
function interpolateParams(value, params, errors) {
  const original = `${value}`;
  const str = original.replace(PARAM_REGEX, (_, varName) => {
    let localVal = params[varName];
    // this means that the value was never overridden by the data passed in by the user
    if (localVal == null) {
      errors.push(invalidParamValue(varName));
      localVal = '';
    }
    return localVal.toString();
  });
  // we do this to assert that numeric values stay as they are
  return str == original ? value : str;
}
const DASH_CASE_REGEXP = /-+([a-z0-9])/g;
function dashCaseToCamelCase(input) {
  return input.replace(DASH_CASE_REGEXP, (...m) => m[1].toUpperCase());
}
function camelCaseToDashCase(input) {
  return input.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
}
function allowPreviousPlayerStylesMerge(duration, delay) {
  return duration === 0 || delay === 0;
}
function balancePreviousStylesIntoKeyframes(element, keyframes, previousStyles) {
  if (previousStyles.size && keyframes.length) {
    let startingKeyframe = keyframes[0];
    let missingStyleProps = [];
    previousStyles.forEach((val, prop) => {
      if (!startingKeyframe.has(prop)) {
        missingStyleProps.push(prop);
      }
      startingKeyframe.set(prop, val);
    });
    if (missingStyleProps.length) {
      for (let i = 1; i < keyframes.length; i++) {
        let kf = keyframes[i];
        missingStyleProps.forEach(prop => kf.set(prop, computeStyle(element, prop)));
      }
    }
  }
  return keyframes;
}
function visitDslNode(visitor, node, context) {
  switch (node.type) {
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Trigger:
      return visitor.visitTrigger(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.State:
      return visitor.visitState(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Transition:
      return visitor.visitTransition(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Sequence:
      return visitor.visitSequence(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Group:
      return visitor.visitGroup(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Animate:
      return visitor.visitAnimate(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Keyframes:
      return visitor.visitKeyframes(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Style:
      return visitor.visitStyle(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Reference:
      return visitor.visitReference(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.AnimateChild:
      return visitor.visitAnimateChild(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.AnimateRef:
      return visitor.visitAnimateRef(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Query:
      return visitor.visitQuery(node, context);
    case _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Stagger:
      return visitor.visitStagger(node, context);
    default:
      throw invalidNodeType(node.type);
  }
}
function computeStyle(element, prop) {
  return window.getComputedStyle(element)[prop];
}
const DIMENSIONAL_PROP_SET = new Set(['width', 'height', 'minWidth', 'minHeight', 'maxWidth', 'maxHeight', 'left', 'top', 'bottom', 'right', 'fontSize', 'outlineWidth', 'outlineOffset', 'paddingTop', 'paddingLeft', 'paddingBottom', 'paddingRight', 'marginTop', 'marginLeft', 'marginBottom', 'marginRight', 'borderRadius', 'borderWidth', 'borderTopWidth', 'borderLeftWidth', 'borderRightWidth', 'borderBottomWidth', 'textIndent', 'perspective']);
class WebAnimationsStyleNormalizer extends AnimationStyleNormalizer {
  normalizePropertyName(propertyName, errors) {
    return dashCaseToCamelCase(propertyName);
  }
  normalizeStyleValue(userProvidedProperty, normalizedProperty, value, errors) {
    let unit = '';
    const strVal = value.toString().trim();
    if (DIMENSIONAL_PROP_SET.has(normalizedProperty) && value !== 0 && value !== '0') {
      if (typeof value === 'number') {
        unit = 'px';
      } else {
        const valAndSuffixMatch = value.match(/^[+-]?[\d\.]+([a-z]*)$/);
        if (valAndSuffixMatch && valAndSuffixMatch[1].length == 0) {
          errors.push(invalidCssUnitValue(userProvidedProperty, value));
        }
      }
    }
    return strVal + unit;
  }
}
function createListOfWarnings(warnings) {
  const LINE_START = '\n - ';
  return `${LINE_START}${warnings.filter(Boolean).map(warning => warning).join(LINE_START)}`;
}
function warnValidation(warnings) {
  (typeof ngDevMode === 'undefined' || ngDevMode) && console.warn(`animation validation warnings:${createListOfWarnings(warnings)}`);
}
function warnTriggerBuild(name, warnings) {
  (typeof ngDevMode === 'undefined' || ngDevMode) && console.warn(`The animation trigger "${name}" has built with the following warnings:${createListOfWarnings(warnings)}`);
}
function warnRegister(warnings) {
  (typeof ngDevMode === 'undefined' || ngDevMode) && console.warn(`Animation built with the following warnings:${createListOfWarnings(warnings)}`);
}
function triggerParsingWarnings(name, warnings) {
  (typeof ngDevMode === 'undefined' || ngDevMode) && console.warn(`Animation parsing for the ${name} trigger presents the following warnings:${createListOfWarnings(warnings)}`);
}
function pushUnrecognizedPropertiesWarning(warnings, props) {
  if (props.length) {
    warnings.push(`The following provided properties are not recognized: ${props.join(', ')}`);
  }
}
const ANY_STATE = '*';
function parseTransitionExpr(transitionValue, errors) {
  const expressions = [];
  if (typeof transitionValue == 'string') {
    transitionValue.split(/\s*,\s*/).forEach(str => parseInnerTransitionStr(str, expressions, errors));
  } else {
    expressions.push(transitionValue);
  }
  return expressions;
}
function parseInnerTransitionStr(eventStr, expressions, errors) {
  if (eventStr[0] == ':') {
    const result = parseAnimationAlias(eventStr, errors);
    if (typeof result == 'function') {
      expressions.push(result);
      return;
    }
    eventStr = result;
  }
  const match = eventStr.match(/^(\*|[-\w]+)\s*(<?[=-]>)\s*(\*|[-\w]+)$/);
  if (match == null || match.length < 4) {
    errors.push(invalidExpression(eventStr));
    return expressions;
  }
  const fromState = match[1];
  const separator = match[2];
  const toState = match[3];
  expressions.push(makeLambdaFromStates(fromState, toState));
  const isFullAnyStateExpr = fromState == ANY_STATE && toState == ANY_STATE;
  if (separator[0] == '<' && !isFullAnyStateExpr) {
    expressions.push(makeLambdaFromStates(toState, fromState));
  }
  return;
}
function parseAnimationAlias(alias, errors) {
  switch (alias) {
    case ':enter':
      return 'void => *';
    case ':leave':
      return '* => void';
    case ':increment':
      return (fromState, toState) => parseFloat(toState) > parseFloat(fromState);
    case ':decrement':
      return (fromState, toState) => parseFloat(toState) < parseFloat(fromState);
    default:
      errors.push(invalidTransitionAlias(alias));
      return '* => *';
  }
}
// DO NOT REFACTOR ... keep the follow set instantiations
// with the values intact (closure compiler for some reason
// removes follow-up lines that add the values outside of
// the constructor...
const TRUE_BOOLEAN_VALUES = new Set(['true', '1']);
const FALSE_BOOLEAN_VALUES = new Set(['false', '0']);
function makeLambdaFromStates(lhs, rhs) {
  const LHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(lhs) || FALSE_BOOLEAN_VALUES.has(lhs);
  const RHS_MATCH_BOOLEAN = TRUE_BOOLEAN_VALUES.has(rhs) || FALSE_BOOLEAN_VALUES.has(rhs);
  return (fromState, toState) => {
    let lhsMatch = lhs == ANY_STATE || lhs == fromState;
    let rhsMatch = rhs == ANY_STATE || rhs == toState;
    if (!lhsMatch && LHS_MATCH_BOOLEAN && typeof fromState === 'boolean') {
      lhsMatch = fromState ? TRUE_BOOLEAN_VALUES.has(lhs) : FALSE_BOOLEAN_VALUES.has(lhs);
    }
    if (!rhsMatch && RHS_MATCH_BOOLEAN && typeof toState === 'boolean') {
      rhsMatch = toState ? TRUE_BOOLEAN_VALUES.has(rhs) : FALSE_BOOLEAN_VALUES.has(rhs);
    }
    return lhsMatch && rhsMatch;
  };
}
const SELF_TOKEN = ':self';
const SELF_TOKEN_REGEX = new RegExp(`s*${SELF_TOKEN}s*,?`, 'g');
/*
 * [Validation]
 * The visitor code below will traverse the animation AST generated by the animation verb functions
 * (the output is a tree of objects) and attempt to perform a series of validations on the data. The
 * following corner-cases will be validated:
 *
 * 1. Overlap of animations
 * Given that a CSS property cannot be animated in more than one place at the same time, it's
 * important that this behavior is detected and validated. The way in which this occurs is that
 * each time a style property is examined, a string-map containing the property will be updated with
 * the start and end times for when the property is used within an animation step.
 *
 * If there are two or more parallel animations that are currently running (these are invoked by the
 * group()) on the same element then the validator will throw an error. Since the start/end timing
 * values are collected for each property then if the current animation step is animating the same
 * property and its timing values fall anywhere into the window of time that the property is
 * currently being animated within then this is what causes an error.
 *
 * 2. Timing values
 * The validator will validate to see if a timing value of `duration delay easing` or
 * `durationNumber` is valid or not.
 *
 * (note that upon validation the code below will replace the timing data with an object containing
 * {duration,delay,easing}.
 *
 * 3. Offset Validation
 * Each of the style() calls are allowed to have an offset value when placed inside of keyframes().
 * Offsets within keyframes() are considered valid when:
 *
 *   - No offsets are used at all
 *   - Each style() entry contains an offset value
 *   - Each offset is between 0 and 1
 *   - Each offset is greater to or equal than the previous one
 *
 * Otherwise an error will be thrown.
 */
function buildAnimationAst(driver, metadata, errors, warnings) {
  return new AnimationAstBuilderVisitor(driver).build(metadata, errors, warnings);
}
const ROOT_SELECTOR = '';
class AnimationAstBuilderVisitor {
  constructor(_driver) {
    this._driver = _driver;
  }
  build(metadata, errors, warnings) {
    const context = new AnimationAstBuilderContext(errors);
    this._resetContextStyleTimingState(context);
    const ast = visitDslNode(this, normalizeAnimationEntry(metadata), context);
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (context.unsupportedCSSPropertiesFound.size) {
        pushUnrecognizedPropertiesWarning(warnings, [...context.unsupportedCSSPropertiesFound.keys()]);
      }
    }
    return ast;
  }
  _resetContextStyleTimingState(context) {
    context.currentQuerySelector = ROOT_SELECTOR;
    context.collectedStyles = new Map();
    context.collectedStyles.set(ROOT_SELECTOR, new Map());
    context.currentTime = 0;
  }
  visitTrigger(metadata, context) {
    let queryCount = context.queryCount = 0;
    let depCount = context.depCount = 0;
    const states = [];
    const transitions = [];
    if (metadata.name.charAt(0) == '@') {
      context.errors.push(invalidTrigger());
    }
    metadata.definitions.forEach(def => {
      this._resetContextStyleTimingState(context);
      if (def.type == _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.State) {
        const stateDef = def;
        const name = stateDef.name;
        name.toString().split(/\s*,\s*/).forEach(n => {
          stateDef.name = n;
          states.push(this.visitState(stateDef, context));
        });
        stateDef.name = name;
      } else if (def.type == _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Transition) {
        const transition = this.visitTransition(def, context);
        queryCount += transition.queryCount;
        depCount += transition.depCount;
        transitions.push(transition);
      } else {
        context.errors.push(invalidDefinition());
      }
    });
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Trigger,
      name: metadata.name,
      states,
      transitions,
      queryCount,
      depCount,
      options: null
    };
  }
  visitState(metadata, context) {
    const styleAst = this.visitStyle(metadata.styles, context);
    const astParams = metadata.options && metadata.options.params || null;
    if (styleAst.containsDynamicStyles) {
      const missingSubs = new Set();
      const params = astParams || {};
      styleAst.styles.forEach(style => {
        if (style instanceof Map) {
          style.forEach(value => {
            extractStyleParams(value).forEach(sub => {
              if (!params.hasOwnProperty(sub)) {
                missingSubs.add(sub);
              }
            });
          });
        }
      });
      if (missingSubs.size) {
        context.errors.push(invalidState(metadata.name, [...missingSubs.values()]));
      }
    }
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.State,
      name: metadata.name,
      style: styleAst,
      options: astParams ? {
        params: astParams
      } : null
    };
  }
  visitTransition(metadata, context) {
    context.queryCount = 0;
    context.depCount = 0;
    const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
    const matchers = parseTransitionExpr(metadata.expr, context.errors);
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Transition,
      matchers,
      animation,
      queryCount: context.queryCount,
      depCount: context.depCount,
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitSequence(metadata, context) {
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Sequence,
      steps: metadata.steps.map(s => visitDslNode(this, s, context)),
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitGroup(metadata, context) {
    const currentTime = context.currentTime;
    let furthestTime = 0;
    const steps = metadata.steps.map(step => {
      context.currentTime = currentTime;
      const innerAst = visitDslNode(this, step, context);
      furthestTime = Math.max(furthestTime, context.currentTime);
      return innerAst;
    });
    context.currentTime = furthestTime;
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Group,
      steps,
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitAnimate(metadata, context) {
    const timingAst = constructTimingAst(metadata.timings, context.errors);
    context.currentAnimateTimings = timingAst;
    let styleAst;
    let styleMetadata = metadata.styles ? metadata.styles : (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.style)({});
    if (styleMetadata.type == _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Keyframes) {
      styleAst = this.visitKeyframes(styleMetadata, context);
    } else {
      let styleMetadata = metadata.styles;
      let isEmpty = false;
      if (!styleMetadata) {
        isEmpty = true;
        const newStyleData = {};
        if (timingAst.easing) {
          newStyleData['easing'] = timingAst.easing;
        }
        styleMetadata = (0,_angular_animations__WEBPACK_IMPORTED_MODULE_1__.style)(newStyleData);
      }
      context.currentTime += timingAst.duration + timingAst.delay;
      const _styleAst = this.visitStyle(styleMetadata, context);
      _styleAst.isEmptyStep = isEmpty;
      styleAst = _styleAst;
    }
    context.currentAnimateTimings = null;
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Animate,
      timings: timingAst,
      style: styleAst,
      options: null
    };
  }
  visitStyle(metadata, context) {
    const ast = this._makeStyleAst(metadata, context);
    this._validateStyleAst(ast, context);
    return ast;
  }
  _makeStyleAst(metadata, context) {
    const styles = [];
    const metadataStyles = Array.isArray(metadata.styles) ? metadata.styles : [metadata.styles];
    for (let styleTuple of metadataStyles) {
      if (typeof styleTuple === 'string') {
        if (styleTuple === _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE) {
          styles.push(styleTuple);
        } else {
          context.errors.push(invalidStyleValue(styleTuple));
        }
      } else {
        styles.push(new Map(Object.entries(styleTuple)));
      }
    }
    let containsDynamicStyles = false;
    let collectedEasing = null;
    styles.forEach(styleData => {
      if (styleData instanceof Map) {
        if (styleData.has('easing')) {
          collectedEasing = styleData.get('easing');
          styleData.delete('easing');
        }
        if (!containsDynamicStyles) {
          for (let value of styleData.values()) {
            if (value.toString().indexOf(SUBSTITUTION_EXPR_START) >= 0) {
              containsDynamicStyles = true;
              break;
            }
          }
        }
      }
    });
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Style,
      styles,
      easing: collectedEasing,
      offset: metadata.offset,
      containsDynamicStyles,
      options: null
    };
  }
  _validateStyleAst(ast, context) {
    const timings = context.currentAnimateTimings;
    let endTime = context.currentTime;
    let startTime = context.currentTime;
    if (timings && startTime > 0) {
      startTime -= timings.duration + timings.delay;
    }
    ast.styles.forEach(tuple => {
      if (typeof tuple === 'string') return;
      tuple.forEach((value, prop) => {
        if (typeof ngDevMode === 'undefined' || ngDevMode) {
          if (!this._driver.validateStyleProperty(prop)) {
            tuple.delete(prop);
            context.unsupportedCSSPropertiesFound.add(prop);
            return;
          }
        }
        // This is guaranteed to have a defined Map at this querySelector location making it
        // safe to add the assertion here. It is set as a default empty map in prior methods.
        const collectedStyles = context.collectedStyles.get(context.currentQuerySelector);
        const collectedEntry = collectedStyles.get(prop);
        let updateCollectedStyle = true;
        if (collectedEntry) {
          if (startTime != endTime && startTime >= collectedEntry.startTime && endTime <= collectedEntry.endTime) {
            context.errors.push(invalidParallelAnimation(prop, collectedEntry.startTime, collectedEntry.endTime, startTime, endTime));
            updateCollectedStyle = false;
          }
          // we always choose the smaller start time value since we
          // want to have a record of the entire animation window where
          // the style property is being animated in between
          startTime = collectedEntry.startTime;
        }
        if (updateCollectedStyle) {
          collectedStyles.set(prop, {
            startTime,
            endTime
          });
        }
        if (context.options) {
          validateStyleParams(value, context.options, context.errors);
        }
      });
    });
  }
  visitKeyframes(metadata, context) {
    const ast = {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Keyframes,
      styles: [],
      options: null
    };
    if (!context.currentAnimateTimings) {
      context.errors.push(invalidKeyframes());
      return ast;
    }
    const MAX_KEYFRAME_OFFSET = 1;
    let totalKeyframesWithOffsets = 0;
    const offsets = [];
    let offsetsOutOfOrder = false;
    let keyframesOutOfRange = false;
    let previousOffset = 0;
    const keyframes = metadata.steps.map(styles => {
      const style = this._makeStyleAst(styles, context);
      let offsetVal = style.offset != null ? style.offset : consumeOffset(style.styles);
      let offset = 0;
      if (offsetVal != null) {
        totalKeyframesWithOffsets++;
        offset = style.offset = offsetVal;
      }
      keyframesOutOfRange = keyframesOutOfRange || offset < 0 || offset > 1;
      offsetsOutOfOrder = offsetsOutOfOrder || offset < previousOffset;
      previousOffset = offset;
      offsets.push(offset);
      return style;
    });
    if (keyframesOutOfRange) {
      context.errors.push(invalidOffset());
    }
    if (offsetsOutOfOrder) {
      context.errors.push(keyframeOffsetsOutOfOrder());
    }
    const length = metadata.steps.length;
    let generatedOffset = 0;
    if (totalKeyframesWithOffsets > 0 && totalKeyframesWithOffsets < length) {
      context.errors.push(keyframesMissingOffsets());
    } else if (totalKeyframesWithOffsets == 0) {
      generatedOffset = MAX_KEYFRAME_OFFSET / (length - 1);
    }
    const limit = length - 1;
    const currentTime = context.currentTime;
    const currentAnimateTimings = context.currentAnimateTimings;
    const animateDuration = currentAnimateTimings.duration;
    keyframes.forEach((kf, i) => {
      const offset = generatedOffset > 0 ? i == limit ? 1 : generatedOffset * i : offsets[i];
      const durationUpToThisFrame = offset * animateDuration;
      context.currentTime = currentTime + currentAnimateTimings.delay + durationUpToThisFrame;
      currentAnimateTimings.duration = durationUpToThisFrame;
      this._validateStyleAst(kf, context);
      kf.offset = offset;
      ast.styles.push(kf);
    });
    return ast;
  }
  visitReference(metadata, context) {
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Reference,
      animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitAnimateChild(metadata, context) {
    context.depCount++;
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.AnimateChild,
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitAnimateRef(metadata, context) {
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.AnimateRef,
      animation: this.visitReference(metadata.animation, context),
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitQuery(metadata, context) {
    const parentSelector = context.currentQuerySelector;
    const options = metadata.options || {};
    context.queryCount++;
    context.currentQuery = metadata;
    const [selector, includeSelf] = normalizeSelector(metadata.selector);
    context.currentQuerySelector = parentSelector.length ? parentSelector + ' ' + selector : selector;
    getOrSetDefaultValue(context.collectedStyles, context.currentQuerySelector, new Map());
    const animation = visitDslNode(this, normalizeAnimationEntry(metadata.animation), context);
    context.currentQuery = null;
    context.currentQuerySelector = parentSelector;
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Query,
      selector,
      limit: options.limit || 0,
      optional: !!options.optional,
      includeSelf,
      animation,
      originalSelector: metadata.selector,
      options: normalizeAnimationOptions(metadata.options)
    };
  }
  visitStagger(metadata, context) {
    if (!context.currentQuery) {
      context.errors.push(invalidStagger());
    }
    const timings = metadata.timings === 'full' ? {
      duration: 0,
      delay: 0,
      easing: 'full'
    } : resolveTiming(metadata.timings, context.errors, true);
    return {
      type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Stagger,
      animation: visitDslNode(this, normalizeAnimationEntry(metadata.animation), context),
      timings,
      options: null
    };
  }
}
function normalizeSelector(selector) {
  const hasAmpersand = selector.split(/\s*,\s*/).find(token => token == SELF_TOKEN) ? true : false;
  if (hasAmpersand) {
    selector = selector.replace(SELF_TOKEN_REGEX, '');
  }
  // Note: the :enter and :leave aren't normalized here since those
  // selectors are filled in at runtime during timeline building
  selector = selector.replace(/@\*/g, NG_TRIGGER_SELECTOR).replace(/@\w+/g, match => NG_TRIGGER_SELECTOR + '-' + match.slice(1)).replace(/:animating/g, NG_ANIMATING_SELECTOR);
  return [selector, hasAmpersand];
}
function normalizeParams(obj) {
  return obj ? {
    ...obj
  } : null;
}
class AnimationAstBuilderContext {
  constructor(errors) {
    this.errors = errors;
    this.queryCount = 0;
    this.depCount = 0;
    this.currentTransition = null;
    this.currentQuery = null;
    this.currentQuerySelector = null;
    this.currentAnimateTimings = null;
    this.currentTime = 0;
    this.collectedStyles = new Map();
    this.options = null;
    this.unsupportedCSSPropertiesFound = new Set();
  }
}
function consumeOffset(styles) {
  if (typeof styles == 'string') return null;
  let offset = null;
  if (Array.isArray(styles)) {
    styles.forEach(styleTuple => {
      if (styleTuple instanceof Map && styleTuple.has('offset')) {
        const obj = styleTuple;
        offset = parseFloat(obj.get('offset'));
        obj.delete('offset');
      }
    });
  } else if (styles instanceof Map && styles.has('offset')) {
    const obj = styles;
    offset = parseFloat(obj.get('offset'));
    obj.delete('offset');
  }
  return offset;
}
function constructTimingAst(value, errors) {
  if (value.hasOwnProperty('duration')) {
    return value;
  }
  if (typeof value == 'number') {
    const duration = resolveTiming(value, errors).duration;
    return makeTimingAst(duration, 0, '');
  }
  const strValue = value;
  const isDynamic = strValue.split(/\s+/).some(v => v.charAt(0) == '{' && v.charAt(1) == '{');
  if (isDynamic) {
    const ast = makeTimingAst(0, 0, '');
    ast.dynamic = true;
    ast.strValue = strValue;
    return ast;
  }
  const timings = resolveTiming(strValue, errors);
  return makeTimingAst(timings.duration, timings.delay, timings.easing);
}
function normalizeAnimationOptions(options) {
  if (options) {
    options = {
      ...options
    };
    if (options['params']) {
      options['params'] = normalizeParams(options['params']);
    }
  } else {
    options = {};
  }
  return options;
}
function makeTimingAst(duration, delay, easing) {
  return {
    duration,
    delay,
    easing
  };
}
function createTimelineInstruction(element, keyframes, preStyleProps, postStyleProps, duration, delay, easing = null, subTimeline = false) {
  return {
    type: 1 /* AnimationTransitionInstructionType.TimelineAnimation */,
    element,
    keyframes,
    preStyleProps,
    postStyleProps,
    duration,
    delay,
    totalTime: duration + delay,
    easing,
    subTimeline
  };
}
class ElementInstructionMap {
  constructor() {
    this._map = new Map();
  }
  get(element) {
    return this._map.get(element) || [];
  }
  append(element, instructions) {
    let existingInstructions = this._map.get(element);
    if (!existingInstructions) {
      this._map.set(element, existingInstructions = []);
    }
    existingInstructions.push(...instructions);
  }
  has(element) {
    return this._map.has(element);
  }
  clear() {
    this._map.clear();
  }
}
const ONE_FRAME_IN_MILLISECONDS = 1;
const ENTER_TOKEN = ':enter';
const ENTER_TOKEN_REGEX = new RegExp(ENTER_TOKEN, 'g');
const LEAVE_TOKEN = ':leave';
const LEAVE_TOKEN_REGEX = new RegExp(LEAVE_TOKEN, 'g');
/*
 * The code within this file aims to generate web-animations-compatible keyframes from Angular's
 * animation DSL code.
 *
 * The code below will be converted from:
 *
 * ```
 * sequence([
 *   style({ opacity: 0 }),
 *   animate(1000, style({ opacity: 0 }))
 * ])
 * ```
 *
 * To:
 * ```
 * keyframes = [{ opacity: 0, offset: 0 }, { opacity: 1, offset: 1 }]
 * duration = 1000
 * delay = 0
 * easing = ''
 * ```
 *
 * For this operation to cover the combination of animation verbs (style, animate, group, etc...) a
 * combination of AST traversal and merge-sort-like algorithms are used.
 *
 * [AST Traversal]
 * Each of the animation verbs, when executed, will return an string-map object representing what
 * type of action it is (style, animate, group, etc...) and the data associated with it. This means
 * that when functional composition mix of these functions is evaluated (like in the example above)
 * then it will end up producing a tree of objects representing the animation itself.
 *
 * When this animation object tree is processed by the visitor code below it will visit each of the
 * verb statements within the visitor. And during each visit it will build the context of the
 * animation keyframes by interacting with the `TimelineBuilder`.
 *
 * [TimelineBuilder]
 * This class is responsible for tracking the styles and building a series of keyframe objects for a
 * timeline between a start and end time. The builder starts off with an initial timeline and each
 * time the AST comes across a `group()`, `keyframes()` or a combination of the two within a
 * `sequence()` then it will generate a sub timeline for each step as well as a new one after
 * they are complete.
 *
 * As the AST is traversed, the timing state on each of the timelines will be incremented. If a sub
 * timeline was created (based on one of the cases above) then the parent timeline will attempt to
 * merge the styles used within the sub timelines into itself (only with group() this will happen).
 * This happens with a merge operation (much like how the merge works in mergeSort) and it will only
 * copy the most recently used styles from the sub timelines into the parent timeline. This ensures
 * that if the styles are used later on in another phase of the animation then they will be the most
 * up-to-date values.
 *
 * [How Missing Styles Are Updated]
 * Each timeline has a `backFill` property which is responsible for filling in new styles into
 * already processed keyframes if a new style shows up later within the animation sequence.
 *
 * ```
 * sequence([
 *   style({ width: 0 }),
 *   animate(1000, style({ width: 100 })),
 *   animate(1000, style({ width: 200 })),
 *   animate(1000, style({ width: 300 }))
 *   animate(1000, style({ width: 400, height: 400 })) // notice how `height` doesn't exist anywhere
 * else
 * ])
 * ```
 *
 * What is happening here is that the `height` value is added later in the sequence, but is missing
 * from all previous animation steps. Therefore when a keyframe is created it would also be missing
 * from all previous keyframes up until where it is first used. For the timeline keyframe generation
 * to properly fill in the style it will place the previous value (the value from the parent
 * timeline) or a default value of `*` into the backFill map.
 *
 * When a sub-timeline is created it will have its own backFill property. This is done so that
 * styles present within the sub-timeline do not accidentally seep into the previous/future timeline
 * keyframes
 *
 * [Validation]
 * The code in this file is not responsible for validation. That functionality happens with within
 * the `AnimationValidatorVisitor` code.
 */
function buildAnimationTimelines(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles = new Map(), finalStyles = new Map(), options, subInstructions, errors = []) {
  return new AnimationTimelineBuilderVisitor().buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors);
}
class AnimationTimelineBuilderVisitor {
  buildKeyframes(driver, rootElement, ast, enterClassName, leaveClassName, startingStyles, finalStyles, options, subInstructions, errors = []) {
    subInstructions = subInstructions || new ElementInstructionMap();
    const context = new AnimationTimelineContext(driver, rootElement, subInstructions, enterClassName, leaveClassName, errors, []);
    context.options = options;
    const delay = options.delay ? resolveTimingValue(options.delay) : 0;
    context.currentTimeline.delayNextStep(delay);
    context.currentTimeline.setStyles([startingStyles], null, context.errors, options);
    visitDslNode(this, ast, context);
    // this checks to see if an actual animation happened
    const timelines = context.timelines.filter(timeline => timeline.containsAnimation());
    // note: we just want to apply the final styles for the rootElement, so we do not
    //       just apply the styles to the last timeline but the last timeline which
    //       element is the root one (basically `*`-styles are replaced with the actual
    //       state style values only for the root element)
    if (timelines.length && finalStyles.size) {
      let lastRootTimeline;
      for (let i = timelines.length - 1; i >= 0; i--) {
        const timeline = timelines[i];
        if (timeline.element === rootElement) {
          lastRootTimeline = timeline;
          break;
        }
      }
      if (lastRootTimeline && !lastRootTimeline.allowOnlyTimelineStyles()) {
        lastRootTimeline.setStyles([finalStyles], null, context.errors, options);
      }
    }
    return timelines.length ? timelines.map(timeline => timeline.buildKeyframes()) : [createTimelineInstruction(rootElement, [], [], [], 0, delay, '', false)];
  }
  visitTrigger(ast, context) {
    // these values are not visited in this AST
  }
  visitState(ast, context) {
    // these values are not visited in this AST
  }
  visitTransition(ast, context) {
    // these values are not visited in this AST
  }
  visitAnimateChild(ast, context) {
    const elementInstructions = context.subInstructions.get(context.element);
    if (elementInstructions) {
      const innerContext = context.createSubContext(ast.options);
      const startTime = context.currentTimeline.currentTime;
      const endTime = this._visitSubInstructions(elementInstructions, innerContext, innerContext.options);
      if (startTime != endTime) {
        // we do this on the upper context because we created a sub context for
        // the sub child animations
        context.transformIntoNewTimeline(endTime);
      }
    }
    context.previousNode = ast;
  }
  visitAnimateRef(ast, context) {
    const innerContext = context.createSubContext(ast.options);
    innerContext.transformIntoNewTimeline();
    this._applyAnimationRefDelays([ast.options, ast.animation.options], context, innerContext);
    this.visitReference(ast.animation, innerContext);
    context.transformIntoNewTimeline(innerContext.currentTimeline.currentTime);
    context.previousNode = ast;
  }
  _applyAnimationRefDelays(animationsRefsOptions, context, innerContext) {
    for (const animationRefOptions of animationsRefsOptions) {
      const animationDelay = animationRefOptions?.delay;
      if (animationDelay) {
        const animationDelayValue = typeof animationDelay === 'number' ? animationDelay : resolveTimingValue(interpolateParams(animationDelay, animationRefOptions?.params ?? {}, context.errors));
        innerContext.delayNextStep(animationDelayValue);
      }
    }
  }
  _visitSubInstructions(instructions, context, options) {
    const startTime = context.currentTimeline.currentTime;
    let furthestTime = startTime;
    // this is a special-case for when a user wants to skip a sub
    // animation from being fired entirely.
    const duration = options.duration != null ? resolveTimingValue(options.duration) : null;
    const delay = options.delay != null ? resolveTimingValue(options.delay) : null;
    if (duration !== 0) {
      instructions.forEach(instruction => {
        const instructionTimings = context.appendInstructionToTimeline(instruction, duration, delay);
        furthestTime = Math.max(furthestTime, instructionTimings.duration + instructionTimings.delay);
      });
    }
    return furthestTime;
  }
  visitReference(ast, context) {
    context.updateOptions(ast.options, true);
    visitDslNode(this, ast.animation, context);
    context.previousNode = ast;
  }
  visitSequence(ast, context) {
    const subContextCount = context.subContextCount;
    let ctx = context;
    const options = ast.options;
    if (options && (options.params || options.delay)) {
      ctx = context.createSubContext(options);
      ctx.transformIntoNewTimeline();
      if (options.delay != null) {
        if (ctx.previousNode.type == _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Style) {
          ctx.currentTimeline.snapshotCurrentStyles();
          ctx.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
        }
        const delay = resolveTimingValue(options.delay);
        ctx.delayNextStep(delay);
      }
    }
    if (ast.steps.length) {
      ast.steps.forEach(s => visitDslNode(this, s, ctx));
      // this is here just in case the inner steps only contain or end with a style() call
      ctx.currentTimeline.applyStylesToKeyframe();
      // this means that some animation function within the sequence
      // ended up creating a sub timeline (which means the current
      // timeline cannot overlap with the contents of the sequence)
      if (ctx.subContextCount > subContextCount) {
        ctx.transformIntoNewTimeline();
      }
    }
    context.previousNode = ast;
  }
  visitGroup(ast, context) {
    const innerTimelines = [];
    let furthestTime = context.currentTimeline.currentTime;
    const delay = ast.options && ast.options.delay ? resolveTimingValue(ast.options.delay) : 0;
    ast.steps.forEach(s => {
      const innerContext = context.createSubContext(ast.options);
      if (delay) {
        innerContext.delayNextStep(delay);
      }
      visitDslNode(this, s, innerContext);
      furthestTime = Math.max(furthestTime, innerContext.currentTimeline.currentTime);
      innerTimelines.push(innerContext.currentTimeline);
    });
    // this operation is run after the AST loop because otherwise
    // if the parent timeline's collected styles were updated then
    // it would pass in invalid data into the new-to-be forked items
    innerTimelines.forEach(timeline => context.currentTimeline.mergeTimelineCollectedStyles(timeline));
    context.transformIntoNewTimeline(furthestTime);
    context.previousNode = ast;
  }
  _visitTiming(ast, context) {
    if (ast.dynamic) {
      const strValue = ast.strValue;
      const timingValue = context.params ? interpolateParams(strValue, context.params, context.errors) : strValue;
      return resolveTiming(timingValue, context.errors);
    } else {
      return {
        duration: ast.duration,
        delay: ast.delay,
        easing: ast.easing
      };
    }
  }
  visitAnimate(ast, context) {
    const timings = context.currentAnimateTimings = this._visitTiming(ast.timings, context);
    const timeline = context.currentTimeline;
    if (timings.delay) {
      context.incrementTime(timings.delay);
      timeline.snapshotCurrentStyles();
    }
    const style = ast.style;
    if (style.type == _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Keyframes) {
      this.visitKeyframes(style, context);
    } else {
      context.incrementTime(timings.duration);
      this.visitStyle(style, context);
      timeline.applyStylesToKeyframe();
    }
    context.currentAnimateTimings = null;
    context.previousNode = ast;
  }
  visitStyle(ast, context) {
    const timeline = context.currentTimeline;
    const timings = context.currentAnimateTimings;
    // this is a special case for when a style() call
    // directly follows  an animate() call (but not inside of an animate() call)
    if (!timings && timeline.hasCurrentStyleProperties()) {
      timeline.forwardFrame();
    }
    const easing = timings && timings.easing || ast.easing;
    if (ast.isEmptyStep) {
      timeline.applyEmptyStep(easing);
    } else {
      timeline.setStyles(ast.styles, easing, context.errors, context.options);
    }
    context.previousNode = ast;
  }
  visitKeyframes(ast, context) {
    const currentAnimateTimings = context.currentAnimateTimings;
    const startTime = context.currentTimeline.duration;
    const duration = currentAnimateTimings.duration;
    const innerContext = context.createSubContext();
    const innerTimeline = innerContext.currentTimeline;
    innerTimeline.easing = currentAnimateTimings.easing;
    ast.styles.forEach(step => {
      const offset = step.offset || 0;
      innerTimeline.forwardTime(offset * duration);
      innerTimeline.setStyles(step.styles, step.easing, context.errors, context.options);
      innerTimeline.applyStylesToKeyframe();
    });
    // this will ensure that the parent timeline gets all the styles from
    // the child even if the new timeline below is not used
    context.currentTimeline.mergeTimelineCollectedStyles(innerTimeline);
    // we do this because the window between this timeline and the sub timeline
    // should ensure that the styles within are exactly the same as they were before
    context.transformIntoNewTimeline(startTime + duration);
    context.previousNode = ast;
  }
  visitQuery(ast, context) {
    // in the event that the first step before this is a style step we need
    // to ensure the styles are applied before the children are animated
    const startTime = context.currentTimeline.currentTime;
    const options = ast.options || {};
    const delay = options.delay ? resolveTimingValue(options.delay) : 0;
    if (delay && (context.previousNode.type === _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Style || startTime == 0 && context.currentTimeline.hasCurrentStyleProperties())) {
      context.currentTimeline.snapshotCurrentStyles();
      context.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
    }
    let furthestTime = startTime;
    const elms = context.invokeQuery(ast.selector, ast.originalSelector, ast.limit, ast.includeSelf, options.optional ? true : false, context.errors);
    context.currentQueryTotal = elms.length;
    let sameElementTimeline = null;
    elms.forEach((element, i) => {
      context.currentQueryIndex = i;
      const innerContext = context.createSubContext(ast.options, element);
      if (delay) {
        innerContext.delayNextStep(delay);
      }
      if (element === context.element) {
        sameElementTimeline = innerContext.currentTimeline;
      }
      visitDslNode(this, ast.animation, innerContext);
      // this is here just incase the inner steps only contain or end
      // with a style() call (which is here to signal that this is a preparatory
      // call to style an element before it is animated again)
      innerContext.currentTimeline.applyStylesToKeyframe();
      const endTime = innerContext.currentTimeline.currentTime;
      furthestTime = Math.max(furthestTime, endTime);
    });
    context.currentQueryIndex = 0;
    context.currentQueryTotal = 0;
    context.transformIntoNewTimeline(furthestTime);
    if (sameElementTimeline) {
      context.currentTimeline.mergeTimelineCollectedStyles(sameElementTimeline);
      context.currentTimeline.snapshotCurrentStyles();
    }
    context.previousNode = ast;
  }
  visitStagger(ast, context) {
    const parentContext = context.parentContext;
    const tl = context.currentTimeline;
    const timings = ast.timings;
    const duration = Math.abs(timings.duration);
    const maxTime = duration * (context.currentQueryTotal - 1);
    let delay = duration * context.currentQueryIndex;
    let staggerTransformer = timings.duration < 0 ? 'reverse' : timings.easing;
    switch (staggerTransformer) {
      case 'reverse':
        delay = maxTime - delay;
        break;
      case 'full':
        delay = parentContext.currentStaggerTime;
        break;
    }
    const timeline = context.currentTimeline;
    if (delay) {
      timeline.delayNextStep(delay);
    }
    const startingTime = timeline.currentTime;
    visitDslNode(this, ast.animation, context);
    context.previousNode = ast;
    // time = duration + delay
    // the reason why this computation is so complex is because
    // the inner timeline may either have a delay value or a stretched
    // keyframe depending on if a subtimeline is not used or is used.
    parentContext.currentStaggerTime = tl.currentTime - startingTime + (tl.startTime - parentContext.currentTimeline.startTime);
  }
}
const DEFAULT_NOOP_PREVIOUS_NODE = {};
class AnimationTimelineContext {
  constructor(_driver, element, subInstructions, _enterClassName, _leaveClassName, errors, timelines, initialTimeline) {
    this._driver = _driver;
    this.element = element;
    this.subInstructions = subInstructions;
    this._enterClassName = _enterClassName;
    this._leaveClassName = _leaveClassName;
    this.errors = errors;
    this.timelines = timelines;
    this.parentContext = null;
    this.currentAnimateTimings = null;
    this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
    this.subContextCount = 0;
    this.options = {};
    this.currentQueryIndex = 0;
    this.currentQueryTotal = 0;
    this.currentStaggerTime = 0;
    this.currentTimeline = initialTimeline || new TimelineBuilder(this._driver, element, 0);
    timelines.push(this.currentTimeline);
  }
  get params() {
    return this.options.params;
  }
  updateOptions(options, skipIfExists) {
    if (!options) return;
    const newOptions = options;
    let optionsToUpdate = this.options;
    // NOTE: this will get patched up when other animation methods support duration overrides
    if (newOptions.duration != null) {
      optionsToUpdate.duration = resolveTimingValue(newOptions.duration);
    }
    if (newOptions.delay != null) {
      optionsToUpdate.delay = resolveTimingValue(newOptions.delay);
    }
    const newParams = newOptions.params;
    if (newParams) {
      let paramsToUpdate = optionsToUpdate.params;
      if (!paramsToUpdate) {
        paramsToUpdate = this.options.params = {};
      }
      Object.keys(newParams).forEach(name => {
        if (!skipIfExists || !paramsToUpdate.hasOwnProperty(name)) {
          paramsToUpdate[name] = interpolateParams(newParams[name], paramsToUpdate, this.errors);
        }
      });
    }
  }
  _copyOptions() {
    const options = {};
    if (this.options) {
      const oldParams = this.options.params;
      if (oldParams) {
        const params = options['params'] = {};
        Object.keys(oldParams).forEach(name => {
          params[name] = oldParams[name];
        });
      }
    }
    return options;
  }
  createSubContext(options = null, element, newTime) {
    const target = element || this.element;
    const context = new AnimationTimelineContext(this._driver, target, this.subInstructions, this._enterClassName, this._leaveClassName, this.errors, this.timelines, this.currentTimeline.fork(target, newTime || 0));
    context.previousNode = this.previousNode;
    context.currentAnimateTimings = this.currentAnimateTimings;
    context.options = this._copyOptions();
    context.updateOptions(options);
    context.currentQueryIndex = this.currentQueryIndex;
    context.currentQueryTotal = this.currentQueryTotal;
    context.parentContext = this;
    this.subContextCount++;
    return context;
  }
  transformIntoNewTimeline(newTime) {
    this.previousNode = DEFAULT_NOOP_PREVIOUS_NODE;
    this.currentTimeline = this.currentTimeline.fork(this.element, newTime);
    this.timelines.push(this.currentTimeline);
    return this.currentTimeline;
  }
  appendInstructionToTimeline(instruction, duration, delay) {
    const updatedTimings = {
      duration: duration != null ? duration : instruction.duration,
      delay: this.currentTimeline.currentTime + (delay != null ? delay : 0) + instruction.delay,
      easing: ''
    };
    const builder = new SubTimelineBuilder(this._driver, instruction.element, instruction.keyframes, instruction.preStyleProps, instruction.postStyleProps, updatedTimings, instruction.stretchStartingKeyframe);
    this.timelines.push(builder);
    return updatedTimings;
  }
  incrementTime(time) {
    this.currentTimeline.forwardTime(this.currentTimeline.duration + time);
  }
  delayNextStep(delay) {
    // negative delays are not yet supported
    if (delay > 0) {
      this.currentTimeline.delayNextStep(delay);
    }
  }
  invokeQuery(selector, originalSelector, limit, includeSelf, optional, errors) {
    let results = [];
    if (includeSelf) {
      results.push(this.element);
    }
    if (selector.length > 0) {
      // only if :self is used then the selector can be empty
      selector = selector.replace(ENTER_TOKEN_REGEX, '.' + this._enterClassName);
      selector = selector.replace(LEAVE_TOKEN_REGEX, '.' + this._leaveClassName);
      const multi = limit != 1;
      let elements = this._driver.query(this.element, selector, multi);
      if (limit !== 0) {
        elements = limit < 0 ? elements.slice(elements.length + limit, elements.length) : elements.slice(0, limit);
      }
      results.push(...elements);
    }
    if (!optional && results.length == 0) {
      errors.push(invalidQuery(originalSelector));
    }
    return results;
  }
}
class TimelineBuilder {
  constructor(_driver, element, startTime, _elementTimelineStylesLookup) {
    this._driver = _driver;
    this.element = element;
    this.startTime = startTime;
    this._elementTimelineStylesLookup = _elementTimelineStylesLookup;
    this.duration = 0;
    this.easing = null;
    this._previousKeyframe = new Map();
    this._currentKeyframe = new Map();
    this._keyframes = new Map();
    this._styleSummary = new Map();
    this._localTimelineStyles = new Map();
    this._pendingStyles = new Map();
    this._backFill = new Map();
    this._currentEmptyStepKeyframe = null;
    if (!this._elementTimelineStylesLookup) {
      this._elementTimelineStylesLookup = new Map();
    }
    this._globalTimelineStyles = this._elementTimelineStylesLookup.get(element);
    if (!this._globalTimelineStyles) {
      this._globalTimelineStyles = this._localTimelineStyles;
      this._elementTimelineStylesLookup.set(element, this._localTimelineStyles);
    }
    this._loadKeyframe();
  }
  containsAnimation() {
    switch (this._keyframes.size) {
      case 0:
        return false;
      case 1:
        return this.hasCurrentStyleProperties();
      default:
        return true;
    }
  }
  hasCurrentStyleProperties() {
    return this._currentKeyframe.size > 0;
  }
  get currentTime() {
    return this.startTime + this.duration;
  }
  delayNextStep(delay) {
    // in the event that a style() step is placed right before a stagger()
    // and that style() step is the very first style() value in the animation
    // then we need to make a copy of the keyframe [0, copy, 1] so that the delay
    // properly applies the style() values to work with the stagger...
    const hasPreStyleStep = this._keyframes.size === 1 && this._pendingStyles.size;
    if (this.duration || hasPreStyleStep) {
      this.forwardTime(this.currentTime + delay);
      if (hasPreStyleStep) {
        this.snapshotCurrentStyles();
      }
    } else {
      this.startTime += delay;
    }
  }
  fork(element, currentTime) {
    this.applyStylesToKeyframe();
    return new TimelineBuilder(this._driver, element, currentTime || this.currentTime, this._elementTimelineStylesLookup);
  }
  _loadKeyframe() {
    if (this._currentKeyframe) {
      this._previousKeyframe = this._currentKeyframe;
    }
    this._currentKeyframe = this._keyframes.get(this.duration);
    if (!this._currentKeyframe) {
      this._currentKeyframe = new Map();
      this._keyframes.set(this.duration, this._currentKeyframe);
    }
  }
  forwardFrame() {
    this.duration += ONE_FRAME_IN_MILLISECONDS;
    this._loadKeyframe();
  }
  forwardTime(time) {
    this.applyStylesToKeyframe();
    this.duration = time;
    this._loadKeyframe();
  }
  _updateStyle(prop, value) {
    this._localTimelineStyles.set(prop, value);
    this._globalTimelineStyles.set(prop, value);
    this._styleSummary.set(prop, {
      time: this.currentTime,
      value
    });
  }
  allowOnlyTimelineStyles() {
    return this._currentEmptyStepKeyframe !== this._currentKeyframe;
  }
  applyEmptyStep(easing) {
    if (easing) {
      this._previousKeyframe.set('easing', easing);
    }
    // special case for animate(duration):
    // all missing styles are filled with a `*` value then
    // if any destination styles are filled in later on the same
    // keyframe then they will override the overridden styles
    // We use `_globalTimelineStyles` here because there may be
    // styles in previous keyframes that are not present in this timeline
    for (let [prop, value] of this._globalTimelineStyles) {
      this._backFill.set(prop, value || _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
      this._currentKeyframe.set(prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
    }
    this._currentEmptyStepKeyframe = this._currentKeyframe;
  }
  setStyles(input, easing, errors, options) {
    if (easing) {
      this._previousKeyframe.set('easing', easing);
    }
    const params = options && options.params || {};
    const styles = flattenStyles(input, this._globalTimelineStyles);
    for (let [prop, value] of styles) {
      const val = interpolateParams(value, params, errors);
      this._pendingStyles.set(prop, val);
      if (!this._localTimelineStyles.has(prop)) {
        this._backFill.set(prop, this._globalTimelineStyles.get(prop) ?? _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
      }
      this._updateStyle(prop, val);
    }
  }
  applyStylesToKeyframe() {
    if (this._pendingStyles.size == 0) return;
    this._pendingStyles.forEach((val, prop) => {
      this._currentKeyframe.set(prop, val);
    });
    this._pendingStyles.clear();
    this._localTimelineStyles.forEach((val, prop) => {
      if (!this._currentKeyframe.has(prop)) {
        this._currentKeyframe.set(prop, val);
      }
    });
  }
  snapshotCurrentStyles() {
    for (let [prop, val] of this._localTimelineStyles) {
      this._pendingStyles.set(prop, val);
      this._updateStyle(prop, val);
    }
  }
  getFinalKeyframe() {
    return this._keyframes.get(this.duration);
  }
  get properties() {
    const properties = [];
    for (let prop in this._currentKeyframe) {
      properties.push(prop);
    }
    return properties;
  }
  mergeTimelineCollectedStyles(timeline) {
    timeline._styleSummary.forEach((details1, prop) => {
      const details0 = this._styleSummary.get(prop);
      if (!details0 || details1.time > details0.time) {
        this._updateStyle(prop, details1.value);
      }
    });
  }
  buildKeyframes() {
    this.applyStylesToKeyframe();
    const preStyleProps = new Set();
    const postStyleProps = new Set();
    const isEmpty = this._keyframes.size === 1 && this.duration === 0;
    let finalKeyframes = [];
    this._keyframes.forEach((keyframe, time) => {
      const finalKeyframe = new Map([...this._backFill, ...keyframe]);
      finalKeyframe.forEach((value, prop) => {
        if (value === _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]) {
          preStyleProps.add(prop);
        } else if (value === _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE) {
          postStyleProps.add(prop);
        }
      });
      if (!isEmpty) {
        finalKeyframe.set('offset', time / this.duration);
      }
      finalKeyframes.push(finalKeyframe);
    });
    const preProps = [...preStyleProps.values()];
    const postProps = [...postStyleProps.values()];
    // special case for a 0-second animation (which is designed just to place styles onscreen)
    if (isEmpty) {
      const kf0 = finalKeyframes[0];
      const kf1 = new Map(kf0);
      kf0.set('offset', 0);
      kf1.set('offset', 1);
      finalKeyframes = [kf0, kf1];
    }
    return createTimelineInstruction(this.element, finalKeyframes, preProps, postProps, this.duration, this.startTime, this.easing, false);
  }
}
class SubTimelineBuilder extends TimelineBuilder {
  constructor(driver, element, keyframes, preStyleProps, postStyleProps, timings, _stretchStartingKeyframe = false) {
    super(driver, element, timings.delay);
    this.keyframes = keyframes;
    this.preStyleProps = preStyleProps;
    this.postStyleProps = postStyleProps;
    this._stretchStartingKeyframe = _stretchStartingKeyframe;
    this.timings = {
      duration: timings.duration,
      delay: timings.delay,
      easing: timings.easing
    };
  }
  containsAnimation() {
    return this.keyframes.length > 1;
  }
  buildKeyframes() {
    let keyframes = this.keyframes;
    let {
      delay,
      duration,
      easing
    } = this.timings;
    if (this._stretchStartingKeyframe && delay) {
      const newKeyframes = [];
      const totalTime = duration + delay;
      const startingGap = delay / totalTime;
      // the original starting keyframe now starts once the delay is done
      const newFirstKeyframe = new Map(keyframes[0]);
      newFirstKeyframe.set('offset', 0);
      newKeyframes.push(newFirstKeyframe);
      const oldFirstKeyframe = new Map(keyframes[0]);
      oldFirstKeyframe.set('offset', roundOffset(startingGap));
      newKeyframes.push(oldFirstKeyframe);
      /*
        When the keyframe is stretched then it means that the delay before the animation
        starts is gone. Instead the first keyframe is placed at the start of the animation
        and it is then copied to where it starts when the original delay is over. This basically
        means nothing animates during that delay, but the styles are still rendered. For this
        to work the original offset values that exist in the original keyframes must be "warped"
        so that they can take the new keyframe + delay into account.
               delay=1000, duration=1000, keyframes = 0 .5 1
               turns into
               delay=0, duration=2000, keyframes = 0 .33 .66 1
       */
      // offsets between 1 ... n -1 are all warped by the keyframe stretch
      const limit = keyframes.length - 1;
      for (let i = 1; i <= limit; i++) {
        let kf = new Map(keyframes[i]);
        const oldOffset = kf.get('offset');
        const timeAtKeyframe = delay + oldOffset * duration;
        kf.set('offset', roundOffset(timeAtKeyframe / totalTime));
        newKeyframes.push(kf);
      }
      // the new starting keyframe should be added at the start
      duration = totalTime;
      delay = 0;
      easing = '';
      keyframes = newKeyframes;
    }
    return createTimelineInstruction(this.element, keyframes, this.preStyleProps, this.postStyleProps, duration, delay, easing, true);
  }
}
function roundOffset(offset, decimalPoints = 3) {
  const mult = Math.pow(10, decimalPoints - 1);
  return Math.round(offset * mult) / mult;
}
function flattenStyles(input, allStyles) {
  const styles = new Map();
  let allProperties;
  input.forEach(token => {
    if (token === '*') {
      allProperties ??= allStyles.keys();
      for (let prop of allProperties) {
        styles.set(prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
      }
    } else {
      for (let [prop, val] of token) {
        styles.set(prop, val);
      }
    }
  });
  return styles;
}
function createTransitionInstruction(element, triggerName, fromState, toState, isRemovalTransition, fromStyles, toStyles, timelines, queriedElements, preStyleProps, postStyleProps, totalTime, errors) {
  return {
    type: 0 /* AnimationTransitionInstructionType.TransitionAnimation */,
    element,
    triggerName,
    isRemovalTransition,
    fromState,
    fromStyles,
    toState,
    toStyles,
    timelines,
    queriedElements,
    preStyleProps,
    postStyleProps,
    totalTime,
    errors
  };
}
const EMPTY_OBJECT = {};
class AnimationTransitionFactory {
  constructor(_triggerName, ast, _stateStyles) {
    this._triggerName = _triggerName;
    this.ast = ast;
    this._stateStyles = _stateStyles;
  }
  match(currentState, nextState, element, params) {
    return oneOrMoreTransitionsMatch(this.ast.matchers, currentState, nextState, element, params);
  }
  buildStyles(stateName, params, errors) {
    let styler = this._stateStyles.get('*');
    if (stateName !== undefined) {
      styler = this._stateStyles.get(stateName?.toString()) || styler;
    }
    return styler ? styler.buildStyles(params, errors) : new Map();
  }
  build(driver, element, currentState, nextState, enterClassName, leaveClassName, currentOptions, nextOptions, subInstructions, skipAstBuild) {
    const errors = [];
    const transitionAnimationParams = this.ast.options && this.ast.options.params || EMPTY_OBJECT;
    const currentAnimationParams = currentOptions && currentOptions.params || EMPTY_OBJECT;
    const currentStateStyles = this.buildStyles(currentState, currentAnimationParams, errors);
    const nextAnimationParams = nextOptions && nextOptions.params || EMPTY_OBJECT;
    const nextStateStyles = this.buildStyles(nextState, nextAnimationParams, errors);
    const queriedElements = new Set();
    const preStyleMap = new Map();
    const postStyleMap = new Map();
    const isRemoval = nextState === 'void';
    const animationOptions = {
      params: applyParamDefaults(nextAnimationParams, transitionAnimationParams),
      delay: this.ast.options?.delay
    };
    const timelines = skipAstBuild ? [] : buildAnimationTimelines(driver, element, this.ast.animation, enterClassName, leaveClassName, currentStateStyles, nextStateStyles, animationOptions, subInstructions, errors);
    let totalTime = 0;
    timelines.forEach(tl => {
      totalTime = Math.max(tl.duration + tl.delay, totalTime);
    });
    if (errors.length) {
      return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, [], [], preStyleMap, postStyleMap, totalTime, errors);
    }
    timelines.forEach(tl => {
      const elm = tl.element;
      const preProps = getOrSetDefaultValue(preStyleMap, elm, new Set());
      tl.preStyleProps.forEach(prop => preProps.add(prop));
      const postProps = getOrSetDefaultValue(postStyleMap, elm, new Set());
      tl.postStyleProps.forEach(prop => postProps.add(prop));
      if (elm !== element) {
        queriedElements.add(elm);
      }
    });
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      checkNonAnimatableInTimelines(timelines, this._triggerName, driver);
    }
    return createTransitionInstruction(element, this._triggerName, currentState, nextState, isRemoval, currentStateStyles, nextStateStyles, timelines, [...queriedElements.values()], preStyleMap, postStyleMap, totalTime);
  }
}
/**
 * Checks inside a set of timelines if they try to animate a css property which is not considered
 * animatable, in that case it prints a warning on the console.
 * Besides that the function doesn't have any other effect.
 *
 * Note: this check is done here after the timelines are built instead of doing on a lower level so
 * that we can make sure that the warning appears only once per instruction (we can aggregate here
 * all the issues instead of finding them separately).
 *
 * @param timelines The built timelines for the current instruction.
 * @param triggerName The name of the trigger for the current instruction.
 * @param driver Animation driver used to perform the check.
 *
 */
function checkNonAnimatableInTimelines(timelines, triggerName, driver) {
  if (!driver.validateAnimatableStyleProperty) {
    return;
  }
  const allowedNonAnimatableProps = new Set([
  // 'easing' is a utility/synthetic prop we use to represent
  // easing functions, it represents a property of the animation
  // which is not animatable but different values can be used
  // in different steps
  'easing']);
  const invalidNonAnimatableProps = new Set();
  timelines.forEach(({
    keyframes
  }) => {
    const nonAnimatablePropsInitialValues = new Map();
    keyframes.forEach(keyframe => {
      const entriesToCheck = Array.from(keyframe.entries()).filter(([prop]) => !allowedNonAnimatableProps.has(prop));
      for (const [prop, value] of entriesToCheck) {
        if (!driver.validateAnimatableStyleProperty(prop)) {
          if (nonAnimatablePropsInitialValues.has(prop) && !invalidNonAnimatableProps.has(prop)) {
            const propInitialValue = nonAnimatablePropsInitialValues.get(prop);
            if (propInitialValue !== value) {
              invalidNonAnimatableProps.add(prop);
            }
          } else {
            nonAnimatablePropsInitialValues.set(prop, value);
          }
        }
      }
    });
  });
  if (invalidNonAnimatableProps.size > 0) {
    console.warn(`Warning: The animation trigger "${triggerName}" is attempting to animate the following` + ' not animatable properties: ' + Array.from(invalidNonAnimatableProps).join(', ') + '\n' + '(to check the list of all animatable properties visit https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties)');
  }
}
function oneOrMoreTransitionsMatch(matchFns, currentState, nextState, element, params) {
  return matchFns.some(fn => fn(currentState, nextState, element, params));
}
function applyParamDefaults(userParams, defaults) {
  const result = {
    ...defaults
  };
  Object.entries(userParams).forEach(([key, value]) => {
    if (value != null) {
      result[key] = value;
    }
  });
  return result;
}
class AnimationStateStyles {
  constructor(styles, defaultParams, normalizer) {
    this.styles = styles;
    this.defaultParams = defaultParams;
    this.normalizer = normalizer;
  }
  buildStyles(params, errors) {
    const finalStyles = new Map();
    const combinedParams = applyParamDefaults(params, this.defaultParams);
    this.styles.styles.forEach(value => {
      if (typeof value !== 'string') {
        value.forEach((val, prop) => {
          if (val) {
            val = interpolateParams(val, combinedParams, errors);
          }
          const normalizedProp = this.normalizer.normalizePropertyName(prop, errors);
          val = this.normalizer.normalizeStyleValue(prop, normalizedProp, val, errors);
          finalStyles.set(prop, val);
        });
      }
    });
    return finalStyles;
  }
}
function buildTrigger(name, ast, normalizer) {
  return new AnimationTrigger(name, ast, normalizer);
}
class AnimationTrigger {
  constructor(name, ast, _normalizer) {
    this.name = name;
    this.ast = ast;
    this._normalizer = _normalizer;
    this.transitionFactories = [];
    this.states = new Map();
    ast.states.forEach(ast => {
      const defaultParams = ast.options && ast.options.params || {};
      this.states.set(ast.name, new AnimationStateStyles(ast.style, defaultParams, _normalizer));
    });
    balanceProperties(this.states, 'true', '1');
    balanceProperties(this.states, 'false', '0');
    ast.transitions.forEach(ast => {
      this.transitionFactories.push(new AnimationTransitionFactory(name, ast, this.states));
    });
    this.fallbackTransition = createFallbackTransition(name, this.states, this._normalizer);
  }
  get containsQueries() {
    return this.ast.queryCount > 0;
  }
  matchTransition(currentState, nextState, element, params) {
    const entry = this.transitionFactories.find(f => f.match(currentState, nextState, element, params));
    return entry || null;
  }
  matchStyles(currentState, params, errors) {
    return this.fallbackTransition.buildStyles(currentState, params, errors);
  }
}
function createFallbackTransition(triggerName, states, normalizer) {
  const matchers = [(fromState, toState) => true];
  const animation = {
    type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Sequence,
    steps: [],
    options: null
  };
  const transition = {
    type: _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AnimationMetadataType.Transition,
    animation,
    matchers,
    options: null,
    queryCount: 0,
    depCount: 0
  };
  return new AnimationTransitionFactory(triggerName, transition, states);
}
function balanceProperties(stateMap, key1, key2) {
  if (stateMap.has(key1)) {
    if (!stateMap.has(key2)) {
      stateMap.set(key2, stateMap.get(key1));
    }
  } else if (stateMap.has(key2)) {
    stateMap.set(key1, stateMap.get(key2));
  }
}
const EMPTY_INSTRUCTION_MAP = new ElementInstructionMap();
class TimelineAnimationEngine {
  constructor(bodyNode, _driver, _normalizer) {
    this.bodyNode = bodyNode;
    this._driver = _driver;
    this._normalizer = _normalizer;
    this._animations = new Map();
    this._playersById = new Map();
    this.players = [];
  }
  register(id, metadata) {
    const errors = [];
    const warnings = [];
    const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
    if (errors.length) {
      throw registerFailed(errors);
    } else {
      if (warnings.length) {
        warnRegister(warnings);
      }
      this._animations.set(id, ast);
    }
  }
  _buildPlayer(i, preStyles, postStyles) {
    const element = i.element;
    const keyframes = normalizeKeyframes$1(this._normalizer, i.keyframes, preStyles, postStyles);
    return this._driver.animate(element, keyframes, i.duration, i.delay, i.easing, [], true);
  }
  create(id, element, options = {}) {
    const errors = [];
    const ast = this._animations.get(id);
    let instructions;
    const autoStylesMap = new Map();
    if (ast) {
      instructions = buildAnimationTimelines(this._driver, element, ast, ENTER_CLASSNAME, LEAVE_CLASSNAME, new Map(), new Map(), options, EMPTY_INSTRUCTION_MAP, errors);
      instructions.forEach(inst => {
        const styles = getOrSetDefaultValue(autoStylesMap, inst.element, new Map());
        inst.postStyleProps.forEach(prop => styles.set(prop, null));
      });
    } else {
      errors.push(missingOrDestroyedAnimation());
      instructions = [];
    }
    if (errors.length) {
      throw createAnimationFailed(errors);
    }
    autoStylesMap.forEach((styles, element) => {
      styles.forEach((_, prop) => {
        styles.set(prop, this._driver.computeStyle(element, prop, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE));
      });
    });
    const players = instructions.map(i => {
      const styles = autoStylesMap.get(i.element);
      return this._buildPlayer(i, new Map(), styles);
    });
    const player = optimizeGroupPlayer(players);
    this._playersById.set(id, player);
    player.onDestroy(() => this.destroy(id));
    this.players.push(player);
    return player;
  }
  destroy(id) {
    const player = this._getPlayer(id);
    player.destroy();
    this._playersById.delete(id);
    const index = this.players.indexOf(player);
    if (index >= 0) {
      this.players.splice(index, 1);
    }
  }
  _getPlayer(id) {
    const player = this._playersById.get(id);
    if (!player) {
      throw missingPlayer(id);
    }
    return player;
  }
  listen(id, element, eventName, callback) {
    // triggerName, fromState, toState are all ignored for timeline animations
    const baseEvent = makeAnimationEvent(element, '', '', '');
    listenOnPlayer(this._getPlayer(id), eventName, baseEvent, callback);
    return () => {};
  }
  command(id, element, command, args) {
    if (command == 'register') {
      this.register(id, args[0]);
      return;
    }
    if (command == 'create') {
      const options = args[0] || {};
      this.create(id, element, options);
      return;
    }
    const player = this._getPlayer(id);
    switch (command) {
      case 'play':
        player.play();
        break;
      case 'pause':
        player.pause();
        break;
      case 'reset':
        player.reset();
        break;
      case 'restart':
        player.restart();
        break;
      case 'finish':
        player.finish();
        break;
      case 'init':
        player.init();
        break;
      case 'setPosition':
        player.setPosition(parseFloat(args[0]));
        break;
      case 'destroy':
        this.destroy(id);
        break;
    }
  }
}
const QUEUED_CLASSNAME = 'ng-animate-queued';
const QUEUED_SELECTOR = '.ng-animate-queued';
const DISABLED_CLASSNAME = 'ng-animate-disabled';
const DISABLED_SELECTOR = '.ng-animate-disabled';
const STAR_CLASSNAME = 'ng-star-inserted';
const STAR_SELECTOR = '.ng-star-inserted';
const EMPTY_PLAYER_ARRAY = [];
const NULL_REMOVAL_STATE = {
  namespaceId: '',
  setForRemoval: false,
  setForMove: false,
  hasAnimation: false,
  removedBeforeQueried: false
};
const NULL_REMOVED_QUERIED_STATE = {
  namespaceId: '',
  setForMove: false,
  setForRemoval: false,
  hasAnimation: false,
  removedBeforeQueried: true
};
const REMOVAL_FLAG = '__ng_removed';
class StateValue {
  get params() {
    return this.options.params;
  }
  constructor(input, namespaceId = '') {
    this.namespaceId = namespaceId;
    const isObj = input && input.hasOwnProperty('value');
    const value = isObj ? input['value'] : input;
    this.value = normalizeTriggerValue(value);
    if (isObj) {
      // we drop the value property from options.
      const {
        value,
        ...options
      } = input;
      this.options = options;
    } else {
      this.options = {};
    }
    if (!this.options.params) {
      this.options.params = {};
    }
  }
  absorbOptions(options) {
    const newParams = options.params;
    if (newParams) {
      const oldParams = this.options.params;
      Object.keys(newParams).forEach(prop => {
        if (oldParams[prop] == null) {
          oldParams[prop] = newParams[prop];
        }
      });
    }
  }
}
const VOID_VALUE = 'void';
const DEFAULT_STATE_VALUE = new StateValue(VOID_VALUE);
class AnimationTransitionNamespace {
  constructor(id, hostElement, _engine) {
    this.id = id;
    this.hostElement = hostElement;
    this._engine = _engine;
    this.players = [];
    this._triggers = new Map();
    this._queue = [];
    this._elementListeners = new Map();
    this._hostClassName = 'ng-tns-' + id;
    addClass(hostElement, this._hostClassName);
  }
  listen(element, name, phase, callback) {
    if (!this._triggers.has(name)) {
      throw missingTrigger(phase, name);
    }
    if (phase == null || phase.length == 0) {
      throw missingEvent(name);
    }
    if (!isTriggerEventValid(phase)) {
      throw unsupportedTriggerEvent(phase, name);
    }
    const listeners = getOrSetDefaultValue(this._elementListeners, element, []);
    const data = {
      name,
      phase,
      callback
    };
    listeners.push(data);
    const triggersWithStates = getOrSetDefaultValue(this._engine.statesByElement, element, new Map());
    if (!triggersWithStates.has(name)) {
      addClass(element, NG_TRIGGER_CLASSNAME);
      addClass(element, NG_TRIGGER_CLASSNAME + '-' + name);
      triggersWithStates.set(name, DEFAULT_STATE_VALUE);
    }
    return () => {
      // the event listener is removed AFTER the flush has occurred such
      // that leave animations callbacks can fire (otherwise if the node
      // is removed in between then the listeners would be deregistered)
      this._engine.afterFlush(() => {
        const index = listeners.indexOf(data);
        if (index >= 0) {
          listeners.splice(index, 1);
        }
        if (!this._triggers.has(name)) {
          triggersWithStates.delete(name);
        }
      });
    };
  }
  register(name, ast) {
    if (this._triggers.has(name)) {
      // throw
      return false;
    } else {
      this._triggers.set(name, ast);
      return true;
    }
  }
  _getTrigger(name) {
    const trigger = this._triggers.get(name);
    if (!trigger) {
      throw unregisteredTrigger(name);
    }
    return trigger;
  }
  trigger(element, triggerName, value, defaultToFallback = true) {
    const trigger = this._getTrigger(triggerName);
    const player = new TransitionAnimationPlayer(this.id, triggerName, element);
    let triggersWithStates = this._engine.statesByElement.get(element);
    if (!triggersWithStates) {
      addClass(element, NG_TRIGGER_CLASSNAME);
      addClass(element, NG_TRIGGER_CLASSNAME + '-' + triggerName);
      this._engine.statesByElement.set(element, triggersWithStates = new Map());
    }
    let fromState = triggersWithStates.get(triggerName);
    const toState = new StateValue(value, this.id);
    const isObj = value && value.hasOwnProperty('value');
    if (!isObj && fromState) {
      toState.absorbOptions(fromState.options);
    }
    triggersWithStates.set(triggerName, toState);
    if (!fromState) {
      fromState = DEFAULT_STATE_VALUE;
    }
    const isRemoval = toState.value === VOID_VALUE;
    // normally this isn't reached by here, however, if an object expression
    // is passed in then it may be a new object each time. Comparing the value
    // is important since that will stay the same despite there being a new object.
    // The removal arc here is special cased because the same element is triggered
    // twice in the event that it contains animations on the outer/inner portions
    // of the host container
    if (!isRemoval && fromState.value === toState.value) {
      // this means that despite the value not changing, some inner params
      // have changed which means that the animation final styles need to be applied
      if (!objEquals(fromState.params, toState.params)) {
        const errors = [];
        const fromStyles = trigger.matchStyles(fromState.value, fromState.params, errors);
        const toStyles = trigger.matchStyles(toState.value, toState.params, errors);
        if (errors.length) {
          this._engine.reportError(errors);
        } else {
          this._engine.afterFlush(() => {
            eraseStyles(element, fromStyles);
            setStyles(element, toStyles);
          });
        }
      }
      return;
    }
    const playersOnElement = getOrSetDefaultValue(this._engine.playersByElement, element, []);
    playersOnElement.forEach(player => {
      // only remove the player if it is queued on the EXACT same trigger/namespace
      // we only also deal with queued players here because if the animation has
      // started then we want to keep the player alive until the flush happens
      // (which is where the previousPlayers are passed into the new player)
      if (player.namespaceId == this.id && player.triggerName == triggerName && player.queued) {
        player.destroy();
      }
    });
    let transition = trigger.matchTransition(fromState.value, toState.value, element, toState.params);
    let isFallbackTransition = false;
    if (!transition) {
      if (!defaultToFallback) return;
      transition = trigger.fallbackTransition;
      isFallbackTransition = true;
    }
    this._engine.totalQueuedPlayers++;
    this._queue.push({
      element,
      triggerName,
      transition,
      fromState,
      toState,
      player,
      isFallbackTransition
    });
    if (!isFallbackTransition) {
      addClass(element, QUEUED_CLASSNAME);
      player.onStart(() => {
        removeClass(element, QUEUED_CLASSNAME);
      });
    }
    player.onDone(() => {
      let index = this.players.indexOf(player);
      if (index >= 0) {
        this.players.splice(index, 1);
      }
      const players = this._engine.playersByElement.get(element);
      if (players) {
        let index = players.indexOf(player);
        if (index >= 0) {
          players.splice(index, 1);
        }
      }
    });
    this.players.push(player);
    playersOnElement.push(player);
    return player;
  }
  deregister(name) {
    this._triggers.delete(name);
    this._engine.statesByElement.forEach(stateMap => stateMap.delete(name));
    this._elementListeners.forEach((listeners, element) => {
      this._elementListeners.set(element, listeners.filter(entry => {
        return entry.name != name;
      }));
    });
  }
  clearElementCache(element) {
    this._engine.statesByElement.delete(element);
    this._elementListeners.delete(element);
    const elementPlayers = this._engine.playersByElement.get(element);
    if (elementPlayers) {
      elementPlayers.forEach(player => player.destroy());
      this._engine.playersByElement.delete(element);
    }
  }
  _signalRemovalForInnerTriggers(rootElement, context) {
    const elements = this._engine.driver.query(rootElement, NG_TRIGGER_SELECTOR, true);
    // emulate a leave animation for all inner nodes within this node.
    // If there are no animations found for any of the nodes then clear the cache
    // for the element.
    elements.forEach(elm => {
      // this means that an inner remove() operation has already kicked off
      // the animation on this element...
      if (elm[REMOVAL_FLAG]) return;
      const namespaces = this._engine.fetchNamespacesByElement(elm);
      if (namespaces.size) {
        namespaces.forEach(ns => ns.triggerLeaveAnimation(elm, context, false, true));
      } else {
        this.clearElementCache(elm);
      }
    });
    // If the child elements were removed along with the parent, their animations might not
    // have completed. Clear all the elements from the cache so we don't end up with a memory leak.
    this._engine.afterFlushAnimationsDone(() => elements.forEach(elm => this.clearElementCache(elm)));
  }
  triggerLeaveAnimation(element, context, destroyAfterComplete, defaultToFallback) {
    const triggerStates = this._engine.statesByElement.get(element);
    const previousTriggersValues = new Map();
    if (triggerStates) {
      const players = [];
      triggerStates.forEach((state, triggerName) => {
        previousTriggersValues.set(triggerName, state.value);
        // this check is here in the event that an element is removed
        // twice (both on the host level and the component level)
        if (this._triggers.has(triggerName)) {
          const player = this.trigger(element, triggerName, VOID_VALUE, defaultToFallback);
          if (player) {
            players.push(player);
          }
        }
      });
      if (players.length) {
        this._engine.markElementAsRemoved(this.id, element, true, context, previousTriggersValues);
        if (destroyAfterComplete) {
          optimizeGroupPlayer(players).onDone(() => this._engine.processLeaveNode(element));
        }
        return true;
      }
    }
    return false;
  }
  prepareLeaveAnimationListeners(element) {
    const listeners = this._elementListeners.get(element);
    const elementStates = this._engine.statesByElement.get(element);
    // if this statement fails then it means that the element was picked up
    // by an earlier flush (or there are no listeners at all to track the leave).
    if (listeners && elementStates) {
      const visitedTriggers = new Set();
      listeners.forEach(listener => {
        const triggerName = listener.name;
        if (visitedTriggers.has(triggerName)) return;
        visitedTriggers.add(triggerName);
        const trigger = this._triggers.get(triggerName);
        const transition = trigger.fallbackTransition;
        const fromState = elementStates.get(triggerName) || DEFAULT_STATE_VALUE;
        const toState = new StateValue(VOID_VALUE);
        const player = new TransitionAnimationPlayer(this.id, triggerName, element);
        this._engine.totalQueuedPlayers++;
        this._queue.push({
          element,
          triggerName,
          transition,
          fromState,
          toState,
          player,
          isFallbackTransition: true
        });
      });
    }
  }
  removeNode(element, context) {
    const engine = this._engine;
    if (element.childElementCount) {
      this._signalRemovalForInnerTriggers(element, context);
    }
    // this means that a * => VOID animation was detected and kicked off
    if (this.triggerLeaveAnimation(element, context, true)) return;
    // find the player that is animating and make sure that the
    // removal is delayed until that player has completed
    let containsPotentialParentTransition = false;
    if (engine.totalAnimations) {
      const currentPlayers = engine.players.length ? engine.playersByQueriedElement.get(element) : [];
      // when this `if statement` does not continue forward it means that
      // a previous animation query has selected the current element and
      // is animating it. In this situation want to continue forwards and
      // allow the element to be queued up for animation later.
      if (currentPlayers && currentPlayers.length) {
        containsPotentialParentTransition = true;
      } else {
        let parent = element;
        while (parent = parent.parentNode) {
          const triggers = engine.statesByElement.get(parent);
          if (triggers) {
            containsPotentialParentTransition = true;
            break;
          }
        }
      }
    }
    // at this stage we know that the element will either get removed
    // during flush or will be picked up by a parent query. Either way
    // we need to fire the listeners for this element when it DOES get
    // removed (once the query parent animation is done or after flush)
    this.prepareLeaveAnimationListeners(element);
    // whether or not a parent has an animation we need to delay the deferral of the leave
    // operation until we have more information (which we do after flush() has been called)
    if (containsPotentialParentTransition) {
      engine.markElementAsRemoved(this.id, element, false, context);
    } else {
      const removalFlag = element[REMOVAL_FLAG];
      if (!removalFlag || removalFlag === NULL_REMOVAL_STATE) {
        // we do this after the flush has occurred such
        // that the callbacks can be fired
        engine.afterFlush(() => this.clearElementCache(element));
        engine.destroyInnerAnimations(element);
        engine._onRemovalComplete(element, context);
      }
    }
  }
  insertNode(element, parent) {
    addClass(element, this._hostClassName);
  }
  drainQueuedTransitions(microtaskId) {
    const instructions = [];
    this._queue.forEach(entry => {
      const player = entry.player;
      if (player.destroyed) return;
      const element = entry.element;
      const listeners = this._elementListeners.get(element);
      if (listeners) {
        listeners.forEach(listener => {
          if (listener.name == entry.triggerName) {
            const baseEvent = makeAnimationEvent(element, entry.triggerName, entry.fromState.value, entry.toState.value);
            baseEvent['_data'] = microtaskId;
            listenOnPlayer(entry.player, listener.phase, baseEvent, listener.callback);
          }
        });
      }
      if (player.markedForDestroy) {
        this._engine.afterFlush(() => {
          // now we can destroy the element properly since the event listeners have
          // been bound to the player
          player.destroy();
        });
      } else {
        instructions.push(entry);
      }
    });
    this._queue = [];
    return instructions.sort((a, b) => {
      // if depCount == 0 them move to front
      // otherwise if a contains b then move back
      const d0 = a.transition.ast.depCount;
      const d1 = b.transition.ast.depCount;
      if (d0 == 0 || d1 == 0) {
        return d0 - d1;
      }
      return this._engine.driver.containsElement(a.element, b.element) ? 1 : -1;
    });
  }
  destroy(context) {
    this.players.forEach(p => p.destroy());
    this._signalRemovalForInnerTriggers(this.hostElement, context);
  }
}
class TransitionAnimationEngine {
  /** @internal */
  _onRemovalComplete(element, context) {
    this.onRemovalComplete(element, context);
  }
  constructor(bodyNode, driver, _normalizer, scheduler) {
    this.bodyNode = bodyNode;
    this.driver = driver;
    this._normalizer = _normalizer;
    this.scheduler = scheduler;
    this.players = [];
    this.newHostElements = new Map();
    this.playersByElement = new Map();
    this.playersByQueriedElement = new Map();
    this.statesByElement = new Map();
    this.disabledNodes = new Set();
    this.totalAnimations = 0;
    this.totalQueuedPlayers = 0;
    this._namespaceLookup = {};
    this._namespaceList = [];
    this._flushFns = [];
    this._whenQuietFns = [];
    this.namespacesByHostElement = new Map();
    this.collectedEnterElements = [];
    this.collectedLeaveElements = [];
    // this method is designed to be overridden by the code that uses this engine
    this.onRemovalComplete = (element, context) => {};
  }
  get queuedPlayers() {
    const players = [];
    this._namespaceList.forEach(ns => {
      ns.players.forEach(player => {
        if (player.queued) {
          players.push(player);
        }
      });
    });
    return players;
  }
  createNamespace(namespaceId, hostElement) {
    const ns = new AnimationTransitionNamespace(namespaceId, hostElement, this);
    if (this.bodyNode && this.driver.containsElement(this.bodyNode, hostElement)) {
      this._balanceNamespaceList(ns, hostElement);
    } else {
      // defer this later until flush during when the host element has
      // been inserted so that we know exactly where to place it in
      // the namespace list
      this.newHostElements.set(hostElement, ns);
      // given that this host element is a part of the animation code, it
      // may or may not be inserted by a parent node that is of an
      // animation renderer type. If this happens then we can still have
      // access to this item when we query for :enter nodes. If the parent
      // is a renderer then the set data-structure will normalize the entry
      this.collectEnterElement(hostElement);
    }
    return this._namespaceLookup[namespaceId] = ns;
  }
  _balanceNamespaceList(ns, hostElement) {
    const namespaceList = this._namespaceList;
    const namespacesByHostElement = this.namespacesByHostElement;
    const limit = namespaceList.length - 1;
    if (limit >= 0) {
      let found = false;
      // Find the closest ancestor with an existing namespace so we can then insert `ns` after it,
      // establishing a top-down ordering of namespaces in `this._namespaceList`.
      let ancestor = this.driver.getParentElement(hostElement);
      while (ancestor) {
        const ancestorNs = namespacesByHostElement.get(ancestor);
        if (ancestorNs) {
          // An animation namespace has been registered for this ancestor, so we insert `ns`
          // right after it to establish top-down ordering of animation namespaces.
          const index = namespaceList.indexOf(ancestorNs);
          namespaceList.splice(index + 1, 0, ns);
          found = true;
          break;
        }
        ancestor = this.driver.getParentElement(ancestor);
      }
      if (!found) {
        // No namespace exists that is an ancestor of `ns`, so `ns` is inserted at the front to
        // ensure that any existing descendants are ordered after `ns`, retaining the desired
        // top-down ordering.
        namespaceList.unshift(ns);
      }
    } else {
      namespaceList.push(ns);
    }
    namespacesByHostElement.set(hostElement, ns);
    return ns;
  }
  register(namespaceId, hostElement) {
    let ns = this._namespaceLookup[namespaceId];
    if (!ns) {
      ns = this.createNamespace(namespaceId, hostElement);
    }
    return ns;
  }
  registerTrigger(namespaceId, name, trigger) {
    let ns = this._namespaceLookup[namespaceId];
    if (ns && ns.register(name, trigger)) {
      this.totalAnimations++;
    }
  }
  destroy(namespaceId, context) {
    if (!namespaceId) return;
    this.afterFlush(() => {});
    this.afterFlushAnimationsDone(() => {
      const ns = this._fetchNamespace(namespaceId);
      this.namespacesByHostElement.delete(ns.hostElement);
      const index = this._namespaceList.indexOf(ns);
      if (index >= 0) {
        this._namespaceList.splice(index, 1);
      }
      ns.destroy(context);
      delete this._namespaceLookup[namespaceId];
    });
  }
  _fetchNamespace(id) {
    return this._namespaceLookup[id];
  }
  fetchNamespacesByElement(element) {
    // normally there should only be one namespace per element, however
    // if @triggers are placed on both the component element and then
    // its host element (within the component code) then there will be
    // two namespaces returned. We use a set here to simply deduplicate
    // the namespaces in case (for the reason described above) there are multiple triggers
    const namespaces = new Set();
    const elementStates = this.statesByElement.get(element);
    if (elementStates) {
      for (let stateValue of elementStates.values()) {
        if (stateValue.namespaceId) {
          const ns = this._fetchNamespace(stateValue.namespaceId);
          if (ns) {
            namespaces.add(ns);
          }
        }
      }
    }
    return namespaces;
  }
  trigger(namespaceId, element, name, value) {
    if (isElementNode(element)) {
      const ns = this._fetchNamespace(namespaceId);
      if (ns) {
        ns.trigger(element, name, value);
        return true;
      }
    }
    return false;
  }
  insertNode(namespaceId, element, parent, insertBefore) {
    if (!isElementNode(element)) return;
    // special case for when an element is removed and reinserted (move operation)
    // when this occurs we do not want to use the element for deletion later
    const details = element[REMOVAL_FLAG];
    if (details && details.setForRemoval) {
      details.setForRemoval = false;
      details.setForMove = true;
      const index = this.collectedLeaveElements.indexOf(element);
      if (index >= 0) {
        this.collectedLeaveElements.splice(index, 1);
      }
    }
    // in the event that the namespaceId is blank then the caller
    // code does not contain any animation code in it, but it is
    // just being called so that the node is marked as being inserted
    if (namespaceId) {
      const ns = this._fetchNamespace(namespaceId);
      // This if-statement is a workaround for router issue #21947.
      // The router sometimes hits a race condition where while a route
      // is being instantiated a new navigation arrives, triggering leave
      // animation of DOM that has not been fully initialized, until this
      // is resolved, we need to handle the scenario when DOM is not in a
      // consistent state during the animation.
      if (ns) {
        ns.insertNode(element, parent);
      }
    }
    // only *directives and host elements are inserted before
    if (insertBefore) {
      this.collectEnterElement(element);
    }
  }
  collectEnterElement(element) {
    this.collectedEnterElements.push(element);
  }
  markElementAsDisabled(element, value) {
    if (value) {
      if (!this.disabledNodes.has(element)) {
        this.disabledNodes.add(element);
        addClass(element, DISABLED_CLASSNAME);
      }
    } else if (this.disabledNodes.has(element)) {
      this.disabledNodes.delete(element);
      removeClass(element, DISABLED_CLASSNAME);
    }
  }
  removeNode(namespaceId, element, context) {
    if (isElementNode(element)) {
      this.scheduler?.notify();
      const ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
      if (ns) {
        ns.removeNode(element, context);
      } else {
        this.markElementAsRemoved(namespaceId, element, false, context);
      }
      const hostNS = this.namespacesByHostElement.get(element);
      if (hostNS && hostNS.id !== namespaceId) {
        hostNS.removeNode(element, context);
      }
    } else {
      this._onRemovalComplete(element, context);
    }
  }
  markElementAsRemoved(namespaceId, element, hasAnimation, context, previousTriggersValues) {
    this.collectedLeaveElements.push(element);
    element[REMOVAL_FLAG] = {
      namespaceId,
      setForRemoval: context,
      hasAnimation,
      removedBeforeQueried: false,
      previousTriggersValues
    };
  }
  listen(namespaceId, element, name, phase, callback) {
    if (isElementNode(element)) {
      return this._fetchNamespace(namespaceId).listen(element, name, phase, callback);
    }
    return () => {};
  }
  _buildInstruction(entry, subTimelines, enterClassName, leaveClassName, skipBuildAst) {
    return entry.transition.build(this.driver, entry.element, entry.fromState.value, entry.toState.value, enterClassName, leaveClassName, entry.fromState.options, entry.toState.options, subTimelines, skipBuildAst);
  }
  destroyInnerAnimations(containerElement) {
    let elements = this.driver.query(containerElement, NG_TRIGGER_SELECTOR, true);
    elements.forEach(element => this.destroyActiveAnimationsForElement(element));
    if (this.playersByQueriedElement.size == 0) return;
    elements = this.driver.query(containerElement, NG_ANIMATING_SELECTOR, true);
    elements.forEach(element => this.finishActiveQueriedAnimationOnElement(element));
  }
  destroyActiveAnimationsForElement(element) {
    const players = this.playersByElement.get(element);
    if (players) {
      players.forEach(player => {
        // special case for when an element is set for destruction, but hasn't started.
        // in this situation we want to delay the destruction until the flush occurs
        // so that any event listeners attached to the player are triggered.
        if (player.queued) {
          player.markedForDestroy = true;
        } else {
          player.destroy();
        }
      });
    }
  }
  finishActiveQueriedAnimationOnElement(element) {
    const players = this.playersByQueriedElement.get(element);
    if (players) {
      players.forEach(player => player.finish());
    }
  }
  whenRenderingDone() {
    return new Promise(resolve => {
      if (this.players.length) {
        return optimizeGroupPlayer(this.players).onDone(() => resolve());
      } else {
        resolve();
      }
    });
  }
  processLeaveNode(element) {
    const details = element[REMOVAL_FLAG];
    if (details && details.setForRemoval) {
      // this will prevent it from removing it twice
      element[REMOVAL_FLAG] = NULL_REMOVAL_STATE;
      if (details.namespaceId) {
        this.destroyInnerAnimations(element);
        const ns = this._fetchNamespace(details.namespaceId);
        if (ns) {
          ns.clearElementCache(element);
        }
      }
      this._onRemovalComplete(element, details.setForRemoval);
    }
    if (element.classList?.contains(DISABLED_CLASSNAME)) {
      this.markElementAsDisabled(element, false);
    }
    this.driver.query(element, DISABLED_SELECTOR, true).forEach(node => {
      this.markElementAsDisabled(node, false);
    });
  }
  flush(microtaskId = -1) {
    let players = [];
    if (this.newHostElements.size) {
      this.newHostElements.forEach((ns, element) => this._balanceNamespaceList(ns, element));
      this.newHostElements.clear();
    }
    if (this.totalAnimations && this.collectedEnterElements.length) {
      for (let i = 0; i < this.collectedEnterElements.length; i++) {
        const elm = this.collectedEnterElements[i];
        addClass(elm, STAR_CLASSNAME);
      }
    }
    if (this._namespaceList.length && (this.totalQueuedPlayers || this.collectedLeaveElements.length)) {
      const cleanupFns = [];
      try {
        players = this._flushAnimations(cleanupFns, microtaskId);
      } finally {
        for (let i = 0; i < cleanupFns.length; i++) {
          cleanupFns[i]();
        }
      }
    } else {
      for (let i = 0; i < this.collectedLeaveElements.length; i++) {
        const element = this.collectedLeaveElements[i];
        this.processLeaveNode(element);
      }
    }
    this.totalQueuedPlayers = 0;
    this.collectedEnterElements.length = 0;
    this.collectedLeaveElements.length = 0;
    this._flushFns.forEach(fn => fn());
    this._flushFns = [];
    if (this._whenQuietFns.length) {
      // we move these over to a variable so that
      // if any new callbacks are registered in another
      // flush they do not populate the existing set
      const quietFns = this._whenQuietFns;
      this._whenQuietFns = [];
      if (players.length) {
        optimizeGroupPlayer(players).onDone(() => {
          quietFns.forEach(fn => fn());
        });
      } else {
        quietFns.forEach(fn => fn());
      }
    }
  }
  reportError(errors) {
    throw triggerTransitionsFailed(errors);
  }
  _flushAnimations(cleanupFns, microtaskId) {
    const subTimelines = new ElementInstructionMap();
    const skippedPlayers = [];
    const skippedPlayersMap = new Map();
    const queuedInstructions = [];
    const queriedElements = new Map();
    const allPreStyleElements = new Map();
    const allPostStyleElements = new Map();
    const disabledElementsSet = new Set();
    this.disabledNodes.forEach(node => {
      disabledElementsSet.add(node);
      const nodesThatAreDisabled = this.driver.query(node, QUEUED_SELECTOR, true);
      for (let i = 0; i < nodesThatAreDisabled.length; i++) {
        disabledElementsSet.add(nodesThatAreDisabled[i]);
      }
    });
    const bodyNode = this.bodyNode;
    const allTriggerElements = Array.from(this.statesByElement.keys());
    const enterNodeMap = buildRootMap(allTriggerElements, this.collectedEnterElements);
    // this must occur before the instructions are built below such that
    // the :enter queries match the elements (since the timeline queries
    // are fired during instruction building).
    const enterNodeMapIds = new Map();
    let i = 0;
    enterNodeMap.forEach((nodes, root) => {
      const className = ENTER_CLASSNAME + i++;
      enterNodeMapIds.set(root, className);
      nodes.forEach(node => addClass(node, className));
    });
    const allLeaveNodes = [];
    const mergedLeaveNodes = new Set();
    const leaveNodesWithoutAnimations = new Set();
    for (let i = 0; i < this.collectedLeaveElements.length; i++) {
      const element = this.collectedLeaveElements[i];
      const details = element[REMOVAL_FLAG];
      if (details && details.setForRemoval) {
        allLeaveNodes.push(element);
        mergedLeaveNodes.add(element);
        if (details.hasAnimation) {
          this.driver.query(element, STAR_SELECTOR, true).forEach(elm => mergedLeaveNodes.add(elm));
        } else {
          leaveNodesWithoutAnimations.add(element);
        }
      }
    }
    const leaveNodeMapIds = new Map();
    const leaveNodeMap = buildRootMap(allTriggerElements, Array.from(mergedLeaveNodes));
    leaveNodeMap.forEach((nodes, root) => {
      const className = LEAVE_CLASSNAME + i++;
      leaveNodeMapIds.set(root, className);
      nodes.forEach(node => addClass(node, className));
    });
    cleanupFns.push(() => {
      enterNodeMap.forEach((nodes, root) => {
        const className = enterNodeMapIds.get(root);
        nodes.forEach(node => removeClass(node, className));
      });
      leaveNodeMap.forEach((nodes, root) => {
        const className = leaveNodeMapIds.get(root);
        nodes.forEach(node => removeClass(node, className));
      });
      allLeaveNodes.forEach(element => {
        this.processLeaveNode(element);
      });
    });
    const allPlayers = [];
    const erroneousTransitions = [];
    for (let i = this._namespaceList.length - 1; i >= 0; i--) {
      const ns = this._namespaceList[i];
      ns.drainQueuedTransitions(microtaskId).forEach(entry => {
        const player = entry.player;
        const element = entry.element;
        allPlayers.push(player);
        if (this.collectedEnterElements.length) {
          const details = element[REMOVAL_FLAG];
          // animations for move operations (elements being removed and reinserted,
          // e.g. when the order of an *ngFor list changes) are currently not supported
          if (details && details.setForMove) {
            if (details.previousTriggersValues && details.previousTriggersValues.has(entry.triggerName)) {
              const previousValue = details.previousTriggersValues.get(entry.triggerName);
              // we need to restore the previous trigger value since the element has
              // only been moved and hasn't actually left the DOM
              const triggersWithStates = this.statesByElement.get(entry.element);
              if (triggersWithStates && triggersWithStates.has(entry.triggerName)) {
                const state = triggersWithStates.get(entry.triggerName);
                state.value = previousValue;
                triggersWithStates.set(entry.triggerName, state);
              }
            }
            player.destroy();
            return;
          }
        }
        const nodeIsOrphaned = !bodyNode || !this.driver.containsElement(bodyNode, element);
        const leaveClassName = leaveNodeMapIds.get(element);
        const enterClassName = enterNodeMapIds.get(element);
        const instruction = this._buildInstruction(entry, subTimelines, enterClassName, leaveClassName, nodeIsOrphaned);
        if (instruction.errors && instruction.errors.length) {
          erroneousTransitions.push(instruction);
          return;
        }
        // even though the element may not be in the DOM, it may still
        // be added at a later point (due to the mechanics of content
        // projection and/or dynamic component insertion) therefore it's
        // important to still style the element.
        if (nodeIsOrphaned) {
          player.onStart(() => eraseStyles(element, instruction.fromStyles));
          player.onDestroy(() => setStyles(element, instruction.toStyles));
          skippedPlayers.push(player);
          return;
        }
        // if an unmatched transition is queued and ready to go
        // then it SHOULD NOT render an animation and cancel the
        // previously running animations.
        if (entry.isFallbackTransition) {
          player.onStart(() => eraseStyles(element, instruction.fromStyles));
          player.onDestroy(() => setStyles(element, instruction.toStyles));
          skippedPlayers.push(player);
          return;
        }
        // this means that if a parent animation uses this animation as a sub-trigger
        // then it will instruct the timeline builder not to add a player delay, but
        // instead stretch the first keyframe gap until the animation starts. This is
        // important in order to prevent extra initialization styles from being
        // required by the user for the animation.
        const timelines = [];
        instruction.timelines.forEach(tl => {
          tl.stretchStartingKeyframe = true;
          if (!this.disabledNodes.has(tl.element)) {
            timelines.push(tl);
          }
        });
        instruction.timelines = timelines;
        subTimelines.append(element, instruction.timelines);
        const tuple = {
          instruction,
          player,
          element
        };
        queuedInstructions.push(tuple);
        instruction.queriedElements.forEach(element => getOrSetDefaultValue(queriedElements, element, []).push(player));
        instruction.preStyleProps.forEach((stringMap, element) => {
          if (stringMap.size) {
            let setVal = allPreStyleElements.get(element);
            if (!setVal) {
              allPreStyleElements.set(element, setVal = new Set());
            }
            stringMap.forEach((_, prop) => setVal.add(prop));
          }
        });
        instruction.postStyleProps.forEach((stringMap, element) => {
          let setVal = allPostStyleElements.get(element);
          if (!setVal) {
            allPostStyleElements.set(element, setVal = new Set());
          }
          stringMap.forEach((_, prop) => setVal.add(prop));
        });
      });
    }
    if (erroneousTransitions.length) {
      const errors = [];
      erroneousTransitions.forEach(instruction => {
        errors.push(transitionFailed(instruction.triggerName, instruction.errors));
      });
      allPlayers.forEach(player => player.destroy());
      this.reportError(errors);
    }
    const allPreviousPlayersMap = new Map();
    // this map tells us which element in the DOM tree is contained by
    // which animation. Further down this map will get populated once
    // the players are built and in doing so we can use it to efficiently
    // figure out if a sub player is skipped due to a parent player having priority.
    const animationElementMap = new Map();
    queuedInstructions.forEach(entry => {
      const element = entry.element;
      if (subTimelines.has(element)) {
        animationElementMap.set(element, element);
        this._beforeAnimationBuild(entry.player.namespaceId, entry.instruction, allPreviousPlayersMap);
      }
    });
    skippedPlayers.forEach(player => {
      const element = player.element;
      const previousPlayers = this._getPreviousPlayers(element, false, player.namespaceId, player.triggerName, null);
      previousPlayers.forEach(prevPlayer => {
        getOrSetDefaultValue(allPreviousPlayersMap, element, []).push(prevPlayer);
        prevPlayer.destroy();
      });
    });
    // this is a special case for nodes that will be removed either by
    // having their own leave animations or by being queried in a container
    // that will be removed once a parent animation is complete. The idea
    // here is that * styles must be identical to ! styles because of
    // backwards compatibility (* is also filled in by default in many places).
    // Otherwise * styles will return an empty value or "auto" since the element
    // passed to getComputedStyle will not be visible (since * === destination)
    const replaceNodes = allLeaveNodes.filter(node => {
      return replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements);
    });
    // POST STAGE: fill the * styles
    const postStylesMap = new Map();
    const allLeaveQueriedNodes = cloakAndComputeStyles(postStylesMap, this.driver, leaveNodesWithoutAnimations, allPostStyleElements, _angular_animations__WEBPACK_IMPORTED_MODULE_1__.AUTO_STYLE);
    allLeaveQueriedNodes.forEach(node => {
      if (replacePostStylesAsPre(node, allPreStyleElements, allPostStyleElements)) {
        replaceNodes.push(node);
      }
    });
    // PRE STAGE: fill the ! styles
    const preStylesMap = new Map();
    enterNodeMap.forEach((nodes, root) => {
      cloakAndComputeStyles(preStylesMap, this.driver, new Set(nodes), allPreStyleElements, _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵPRE_STYLE"]);
    });
    replaceNodes.forEach(node => {
      const post = postStylesMap.get(node);
      const pre = preStylesMap.get(node);
      postStylesMap.set(node, new Map([...(post?.entries() ?? []), ...(pre?.entries() ?? [])]));
    });
    const rootPlayers = [];
    const subPlayers = [];
    const NO_PARENT_ANIMATION_ELEMENT_DETECTED = {};
    queuedInstructions.forEach(entry => {
      const {
        element,
        player,
        instruction
      } = entry;
      // this means that it was never consumed by a parent animation which
      // means that it is independent and therefore should be set for animation
      if (subTimelines.has(element)) {
        if (disabledElementsSet.has(element)) {
          player.onDestroy(() => setStyles(element, instruction.toStyles));
          player.disabled = true;
          player.overrideTotalTime(instruction.totalTime);
          skippedPlayers.push(player);
          return;
        }
        // this will flow up the DOM and query the map to figure out
        // if a parent animation has priority over it. In the situation
        // that a parent is detected then it will cancel the loop. If
        // nothing is detected, or it takes a few hops to find a parent,
        // then it will fill in the missing nodes and signal them as having
        // a detected parent (or a NO_PARENT value via a special constant).
        let parentWithAnimation = NO_PARENT_ANIMATION_ELEMENT_DETECTED;
        if (animationElementMap.size > 1) {
          let elm = element;
          const parentsToAdd = [];
          while (elm = elm.parentNode) {
            const detectedParent = animationElementMap.get(elm);
            if (detectedParent) {
              parentWithAnimation = detectedParent;
              break;
            }
            parentsToAdd.push(elm);
          }
          parentsToAdd.forEach(parent => animationElementMap.set(parent, parentWithAnimation));
        }
        const innerPlayer = this._buildAnimation(player.namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap);
        player.setRealPlayer(innerPlayer);
        if (parentWithAnimation === NO_PARENT_ANIMATION_ELEMENT_DETECTED) {
          rootPlayers.push(player);
        } else {
          const parentPlayers = this.playersByElement.get(parentWithAnimation);
          if (parentPlayers && parentPlayers.length) {
            player.parentPlayer = optimizeGroupPlayer(parentPlayers);
          }
          skippedPlayers.push(player);
        }
      } else {
        eraseStyles(element, instruction.fromStyles);
        player.onDestroy(() => setStyles(element, instruction.toStyles));
        // there still might be a ancestor player animating this
        // element therefore we will still add it as a sub player
        // even if its animation may be disabled
        subPlayers.push(player);
        if (disabledElementsSet.has(element)) {
          skippedPlayers.push(player);
        }
      }
    });
    // find all of the sub players' corresponding inner animation players
    subPlayers.forEach(player => {
      // even if no players are found for a sub animation it
      // will still complete itself after the next tick since it's Noop
      const playersForElement = skippedPlayersMap.get(player.element);
      if (playersForElement && playersForElement.length) {
        const innerPlayer = optimizeGroupPlayer(playersForElement);
        player.setRealPlayer(innerPlayer);
      }
    });
    // the reason why we don't actually play the animation is
    // because all that a skipped player is designed to do is to
    // fire the start/done transition callback events
    skippedPlayers.forEach(player => {
      if (player.parentPlayer) {
        player.syncPlayerEvents(player.parentPlayer);
      } else {
        player.destroy();
      }
    });
    // run through all of the queued removals and see if they
    // were picked up by a query. If not then perform the removal
    // operation right away unless a parent animation is ongoing.
    for (let i = 0; i < allLeaveNodes.length; i++) {
      const element = allLeaveNodes[i];
      const details = element[REMOVAL_FLAG];
      removeClass(element, LEAVE_CLASSNAME);
      // this means the element has a removal animation that is being
      // taken care of and therefore the inner elements will hang around
      // until that animation is over (or the parent queried animation)
      if (details && details.hasAnimation) continue;
      let players = [];
      // if this element is queried or if it contains queried children
      // then we want for the element not to be removed from the page
      // until the queried animations have finished
      if (queriedElements.size) {
        let queriedPlayerResults = queriedElements.get(element);
        if (queriedPlayerResults && queriedPlayerResults.length) {
          players.push(...queriedPlayerResults);
        }
        let queriedInnerElements = this.driver.query(element, NG_ANIMATING_SELECTOR, true);
        for (let j = 0; j < queriedInnerElements.length; j++) {
          let queriedPlayers = queriedElements.get(queriedInnerElements[j]);
          if (queriedPlayers && queriedPlayers.length) {
            players.push(...queriedPlayers);
          }
        }
      }
      const activePlayers = players.filter(p => !p.destroyed);
      if (activePlayers.length) {
        removeNodesAfterAnimationDone(this, element, activePlayers);
      } else {
        this.processLeaveNode(element);
      }
    }
    // this is required so the cleanup method doesn't remove them
    allLeaveNodes.length = 0;
    rootPlayers.forEach(player => {
      this.players.push(player);
      player.onDone(() => {
        player.destroy();
        const index = this.players.indexOf(player);
        this.players.splice(index, 1);
      });
      player.play();
    });
    return rootPlayers;
  }
  afterFlush(callback) {
    this._flushFns.push(callback);
  }
  afterFlushAnimationsDone(callback) {
    this._whenQuietFns.push(callback);
  }
  _getPreviousPlayers(element, isQueriedElement, namespaceId, triggerName, toStateValue) {
    let players = [];
    if (isQueriedElement) {
      const queriedElementPlayers = this.playersByQueriedElement.get(element);
      if (queriedElementPlayers) {
        players = queriedElementPlayers;
      }
    } else {
      const elementPlayers = this.playersByElement.get(element);
      if (elementPlayers) {
        const isRemovalAnimation = !toStateValue || toStateValue == VOID_VALUE;
        elementPlayers.forEach(player => {
          if (player.queued) return;
          if (!isRemovalAnimation && player.triggerName != triggerName) return;
          players.push(player);
        });
      }
    }
    if (namespaceId || triggerName) {
      players = players.filter(player => {
        if (namespaceId && namespaceId != player.namespaceId) return false;
        if (triggerName && triggerName != player.triggerName) return false;
        return true;
      });
    }
    return players;
  }
  _beforeAnimationBuild(namespaceId, instruction, allPreviousPlayersMap) {
    const triggerName = instruction.triggerName;
    const rootElement = instruction.element;
    // when a removal animation occurs, ALL previous players are collected
    // and destroyed (even if they are outside of the current namespace)
    const targetNameSpaceId = instruction.isRemovalTransition ? undefined : namespaceId;
    const targetTriggerName = instruction.isRemovalTransition ? undefined : triggerName;
    for (const timelineInstruction of instruction.timelines) {
      const element = timelineInstruction.element;
      const isQueriedElement = element !== rootElement;
      const players = getOrSetDefaultValue(allPreviousPlayersMap, element, []);
      const previousPlayers = this._getPreviousPlayers(element, isQueriedElement, targetNameSpaceId, targetTriggerName, instruction.toState);
      previousPlayers.forEach(player => {
        const realPlayer = player.getRealPlayer();
        if (realPlayer.beforeDestroy) {
          realPlayer.beforeDestroy();
        }
        player.destroy();
        players.push(player);
      });
    }
    // this needs to be done so that the PRE/POST styles can be
    // computed properly without interfering with the previous animation
    eraseStyles(rootElement, instruction.fromStyles);
  }
  _buildAnimation(namespaceId, instruction, allPreviousPlayersMap, skippedPlayersMap, preStylesMap, postStylesMap) {
    const triggerName = instruction.triggerName;
    const rootElement = instruction.element;
    // we first run this so that the previous animation player
    // data can be passed into the successive animation players
    const allQueriedPlayers = [];
    const allConsumedElements = new Set();
    const allSubElements = new Set();
    const allNewPlayers = instruction.timelines.map(timelineInstruction => {
      const element = timelineInstruction.element;
      allConsumedElements.add(element);
      // FIXME (matsko): make sure to-be-removed animations are removed properly
      const details = element[REMOVAL_FLAG];
      if (details && details.removedBeforeQueried) return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(timelineInstruction.duration, timelineInstruction.delay);
      const isQueriedElement = element !== rootElement;
      const previousPlayers = flattenGroupPlayers((allPreviousPlayersMap.get(element) || EMPTY_PLAYER_ARRAY).map(p => p.getRealPlayer())).filter(p => {
        // the `element` is not apart of the AnimationPlayer definition, but
        // Mock/WebAnimations
        // use the element within their implementation. This will be added in Angular5 to
        // AnimationPlayer
        const pp = p;
        return pp.element ? pp.element === element : false;
      });
      const preStyles = preStylesMap.get(element);
      const postStyles = postStylesMap.get(element);
      const keyframes = normalizeKeyframes$1(this._normalizer, timelineInstruction.keyframes, preStyles, postStyles);
      const player = this._buildPlayer(timelineInstruction, keyframes, previousPlayers);
      // this means that this particular player belongs to a sub trigger. It is
      // important that we match this player up with the corresponding (@trigger.listener)
      if (timelineInstruction.subTimeline && skippedPlayersMap) {
        allSubElements.add(element);
      }
      if (isQueriedElement) {
        const wrappedPlayer = new TransitionAnimationPlayer(namespaceId, triggerName, element);
        wrappedPlayer.setRealPlayer(player);
        allQueriedPlayers.push(wrappedPlayer);
      }
      return player;
    });
    allQueriedPlayers.forEach(player => {
      getOrSetDefaultValue(this.playersByQueriedElement, player.element, []).push(player);
      player.onDone(() => deleteOrUnsetInMap(this.playersByQueriedElement, player.element, player));
    });
    allConsumedElements.forEach(element => addClass(element, NG_ANIMATING_CLASSNAME));
    const player = optimizeGroupPlayer(allNewPlayers);
    player.onDestroy(() => {
      allConsumedElements.forEach(element => removeClass(element, NG_ANIMATING_CLASSNAME));
      setStyles(rootElement, instruction.toStyles);
    });
    // this basically makes all of the callbacks for sub element animations
    // be dependent on the upper players for when they finish
    allSubElements.forEach(element => {
      getOrSetDefaultValue(skippedPlayersMap, element, []).push(player);
    });
    return player;
  }
  _buildPlayer(instruction, keyframes, previousPlayers) {
    if (keyframes.length > 0) {
      return this.driver.animate(instruction.element, keyframes, instruction.duration, instruction.delay, instruction.easing, previousPlayers);
    }
    // special case for when an empty transition|definition is provided
    // ... there is no point in rendering an empty animation
    return new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer(instruction.duration, instruction.delay);
  }
}
class TransitionAnimationPlayer {
  constructor(namespaceId, triggerName, element) {
    this.namespaceId = namespaceId;
    this.triggerName = triggerName;
    this.element = element;
    this._player = new _angular_animations__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationPlayer();
    this._containsRealPlayer = false;
    this._queuedCallbacks = new Map();
    this.destroyed = false;
    this.parentPlayer = null;
    this.markedForDestroy = false;
    this.disabled = false;
    this.queued = true;
    this.totalTime = 0;
  }
  setRealPlayer(player) {
    if (this._containsRealPlayer) return;
    this._player = player;
    this._queuedCallbacks.forEach((callbacks, phase) => {
      callbacks.forEach(callback => listenOnPlayer(player, phase, undefined, callback));
    });
    this._queuedCallbacks.clear();
    this._containsRealPlayer = true;
    this.overrideTotalTime(player.totalTime);
    this.queued = false;
  }
  getRealPlayer() {
    return this._player;
  }
  overrideTotalTime(totalTime) {
    this.totalTime = totalTime;
  }
  syncPlayerEvents(player) {
    const p = this._player;
    if (p.triggerCallback) {
      player.onStart(() => p.triggerCallback('start'));
    }
    player.onDone(() => this.finish());
    player.onDestroy(() => this.destroy());
  }
  _queueEvent(name, callback) {
    getOrSetDefaultValue(this._queuedCallbacks, name, []).push(callback);
  }
  onDone(fn) {
    if (this.queued) {
      this._queueEvent('done', fn);
    }
    this._player.onDone(fn);
  }
  onStart(fn) {
    if (this.queued) {
      this._queueEvent('start', fn);
    }
    this._player.onStart(fn);
  }
  onDestroy(fn) {
    if (this.queued) {
      this._queueEvent('destroy', fn);
    }
    this._player.onDestroy(fn);
  }
  init() {
    this._player.init();
  }
  hasStarted() {
    return this.queued ? false : this._player.hasStarted();
  }
  play() {
    !this.queued && this._player.play();
  }
  pause() {
    !this.queued && this._player.pause();
  }
  restart() {
    !this.queued && this._player.restart();
  }
  finish() {
    this._player.finish();
  }
  destroy() {
    this.destroyed = true;
    this._player.destroy();
  }
  reset() {
    !this.queued && this._player.reset();
  }
  setPosition(p) {
    if (!this.queued) {
      this._player.setPosition(p);
    }
  }
  getPosition() {
    return this.queued ? 0 : this._player.getPosition();
  }
  /** @internal */
  triggerCallback(phaseName) {
    const p = this._player;
    if (p.triggerCallback) {
      p.triggerCallback(phaseName);
    }
  }
}
function deleteOrUnsetInMap(map, key, value) {
  let currentValues = map.get(key);
  if (currentValues) {
    if (currentValues.length) {
      const index = currentValues.indexOf(value);
      currentValues.splice(index, 1);
    }
    if (currentValues.length == 0) {
      map.delete(key);
    }
  }
  return currentValues;
}
function normalizeTriggerValue(value) {
  // we use `!= null` here because it's the most simple
  // way to test against a "falsy" value without mixing
  // in empty strings or a zero value. DO NOT OPTIMIZE.
  return value != null ? value : null;
}
function isElementNode(node) {
  return node && node['nodeType'] === 1;
}
function isTriggerEventValid(eventName) {
  return eventName == 'start' || eventName == 'done';
}
function cloakElement(element, value) {
  const oldValue = element.style.display;
  element.style.display = value != null ? value : 'none';
  return oldValue;
}
function cloakAndComputeStyles(valuesMap, driver, elements, elementPropsMap, defaultStyle) {
  const cloakVals = [];
  elements.forEach(element => cloakVals.push(cloakElement(element)));
  const failedElements = [];
  elementPropsMap.forEach((props, element) => {
    const styles = new Map();
    props.forEach(prop => {
      const value = driver.computeStyle(element, prop, defaultStyle);
      styles.set(prop, value);
      // there is no easy way to detect this because a sub element could be removed
      // by a parent animation element being detached.
      if (!value || value.length == 0) {
        element[REMOVAL_FLAG] = NULL_REMOVED_QUERIED_STATE;
        failedElements.push(element);
      }
    });
    valuesMap.set(element, styles);
  });
  // we use a index variable here since Set.forEach(a, i) does not return
  // an index value for the closure (but instead just the value)
  let i = 0;
  elements.forEach(element => cloakElement(element, cloakVals[i++]));
  return failedElements;
}
/*
Since the Angular renderer code will return a collection of inserted
nodes in all areas of a DOM tree, it's up to this algorithm to figure
out which nodes are roots for each animation @trigger.

By placing each inserted node into a Set and traversing upwards, it
is possible to find the @trigger elements and well any direct *star
insertion nodes, if a @trigger root is found then the enter element
is placed into the Map[@trigger] spot.
 */
function buildRootMap(roots, nodes) {
  const rootMap = new Map();
  roots.forEach(root => rootMap.set(root, []));
  if (nodes.length == 0) return rootMap;
  const NULL_NODE = 1;
  const nodeSet = new Set(nodes);
  const localRootMap = new Map();
  function getRoot(node) {
    if (!node) return NULL_NODE;
    let root = localRootMap.get(node);
    if (root) return root;
    const parent = node.parentNode;
    if (rootMap.has(parent)) {
      // ngIf inside @trigger
      root = parent;
    } else if (nodeSet.has(parent)) {
      // ngIf inside ngIf
      root = NULL_NODE;
    } else {
      // recurse upwards
      root = getRoot(parent);
    }
    localRootMap.set(node, root);
    return root;
  }
  nodes.forEach(node => {
    const root = getRoot(node);
    if (root !== NULL_NODE) {
      rootMap.get(root).push(node);
    }
  });
  return rootMap;
}
function addClass(element, className) {
  element.classList?.add(className);
}
function removeClass(element, className) {
  element.classList?.remove(className);
}
function removeNodesAfterAnimationDone(engine, element, players) {
  optimizeGroupPlayer(players).onDone(() => engine.processLeaveNode(element));
}
function flattenGroupPlayers(players) {
  const finalPlayers = [];
  _flattenGroupPlayersRecur(players, finalPlayers);
  return finalPlayers;
}
function _flattenGroupPlayersRecur(players, finalPlayers) {
  for (let i = 0; i < players.length; i++) {
    const player = players[i];
    if (player instanceof _angular_animations__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationGroupPlayer"]) {
      _flattenGroupPlayersRecur(player.players, finalPlayers);
    } else {
      finalPlayers.push(player);
    }
  }
}
function objEquals(a, b) {
  const k1 = Object.keys(a);
  const k2 = Object.keys(b);
  if (k1.length != k2.length) return false;
  for (let i = 0; i < k1.length; i++) {
    const prop = k1[i];
    if (!b.hasOwnProperty(prop) || a[prop] !== b[prop]) return false;
  }
  return true;
}
function replacePostStylesAsPre(element, allPreStyleElements, allPostStyleElements) {
  const postEntry = allPostStyleElements.get(element);
  if (!postEntry) return false;
  let preEntry = allPreStyleElements.get(element);
  if (preEntry) {
    postEntry.forEach(data => preEntry.add(data));
  } else {
    allPreStyleElements.set(element, postEntry);
  }
  allPostStyleElements.delete(element);
  return true;
}
class AnimationEngine {
  constructor(doc, _driver, _normalizer, scheduler) {
    this._driver = _driver;
    this._normalizer = _normalizer;
    this._triggerCache = {};
    // this method is designed to be overridden by the code that uses this engine
    this.onRemovalComplete = (element, context) => {};
    this._transitionEngine = new TransitionAnimationEngine(doc.body, _driver, _normalizer, scheduler);
    this._timelineEngine = new TimelineAnimationEngine(doc.body, _driver, _normalizer);
    this._transitionEngine.onRemovalComplete = (element, context) => this.onRemovalComplete(element, context);
  }
  registerTrigger(componentId, namespaceId, hostElement, name, metadata) {
    const cacheKey = componentId + '-' + name;
    let trigger = this._triggerCache[cacheKey];
    if (!trigger) {
      const errors = [];
      const warnings = [];
      const ast = buildAnimationAst(this._driver, metadata, errors, warnings);
      if (errors.length) {
        throw triggerBuildFailed(name, errors);
      }
      if (warnings.length) {
        warnTriggerBuild(name, warnings);
      }
      trigger = buildTrigger(name, ast, this._normalizer);
      this._triggerCache[cacheKey] = trigger;
    }
    this._transitionEngine.registerTrigger(namespaceId, name, trigger);
  }
  register(namespaceId, hostElement) {
    this._transitionEngine.register(namespaceId, hostElement);
  }
  destroy(namespaceId, context) {
    this._transitionEngine.destroy(namespaceId, context);
  }
  onInsert(namespaceId, element, parent, insertBefore) {
    this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
  }
  onRemove(namespaceId, element, context) {
    this._transitionEngine.removeNode(namespaceId, element, context);
  }
  disableAnimations(element, disable) {
    this._transitionEngine.markElementAsDisabled(element, disable);
  }
  process(namespaceId, element, property, value) {
    if (property.charAt(0) == '@') {
      const [id, action] = parseTimelineCommand(property);
      const args = value;
      this._timelineEngine.command(id, element, action, args);
    } else {
      this._transitionEngine.trigger(namespaceId, element, property, value);
    }
  }
  listen(namespaceId, element, eventName, eventPhase, callback) {
    // @@listen
    if (eventName.charAt(0) == '@') {
      const [id, action] = parseTimelineCommand(eventName);
      return this._timelineEngine.listen(id, element, action, callback);
    }
    return this._transitionEngine.listen(namespaceId, element, eventName, eventPhase, callback);
  }
  flush(microtaskId = -1) {
    this._transitionEngine.flush(microtaskId);
  }
  get players() {
    return [...this._transitionEngine.players, ...this._timelineEngine.players];
  }
  whenRenderingDone() {
    return this._transitionEngine.whenRenderingDone();
  }
  afterFlushAnimationsDone(cb) {
    this._transitionEngine.afterFlushAnimationsDone(cb);
  }
}

/**
 * Returns an instance of `SpecialCasedStyles` if and when any special (non animateable) styles are
 * detected.
 *
 * In CSS there exist properties that cannot be animated within a keyframe animation
 * (whether it be via CSS keyframes or web-animations) and the animation implementation
 * will ignore them. This function is designed to detect those special cased styles and
 * return a container that will be executed at the start and end of the animation.
 *
 * @returns an instance of `SpecialCasedStyles` if any special styles are detected otherwise `null`
 */
function packageNonAnimatableStyles(element, styles) {
  let startStyles = null;
  let endStyles = null;
  if (Array.isArray(styles) && styles.length) {
    startStyles = filterNonAnimatableStyles(styles[0]);
    if (styles.length > 1) {
      endStyles = filterNonAnimatableStyles(styles[styles.length - 1]);
    }
  } else if (styles instanceof Map) {
    startStyles = filterNonAnimatableStyles(styles);
  }
  return startStyles || endStyles ? new SpecialCasedStyles(element, startStyles, endStyles) : null;
}
/**
 * Designed to be executed during a keyframe-based animation to apply any special-cased styles.
 *
 * When started (when the `start()` method is run) then the provided `startStyles`
 * will be applied. When finished (when the `finish()` method is called) the
 * `endStyles` will be applied as well any any starting styles. Finally when
 * `destroy()` is called then all styles will be removed.
 */
class SpecialCasedStyles {
  static {
    this.initialStylesByElement = new WeakMap();
  }
  constructor(_element, _startStyles, _endStyles) {
    this._element = _element;
    this._startStyles = _startStyles;
    this._endStyles = _endStyles;
    this._state = 0 /* SpecialCasedStylesState.Pending */;
    let initialStyles = SpecialCasedStyles.initialStylesByElement.get(_element);
    if (!initialStyles) {
      SpecialCasedStyles.initialStylesByElement.set(_element, initialStyles = new Map());
    }
    this._initialStyles = initialStyles;
  }
  start() {
    if (this._state < 1 /* SpecialCasedStylesState.Started */) {
      if (this._startStyles) {
        setStyles(this._element, this._startStyles, this._initialStyles);
      }
      this._state = 1 /* SpecialCasedStylesState.Started */;
    }
  }
  finish() {
    this.start();
    if (this._state < 2 /* SpecialCasedStylesState.Finished */) {
      setStyles(this._element, this._initialStyles);
      if (this._endStyles) {
        setStyles(this._element, this._endStyles);
        this._endStyles = null;
      }
      this._state = 1 /* SpecialCasedStylesState.Started */;
    }
  }
  destroy() {
    this.finish();
    if (this._state < 3 /* SpecialCasedStylesState.Destroyed */) {
      SpecialCasedStyles.initialStylesByElement.delete(this._element);
      if (this._startStyles) {
        eraseStyles(this._element, this._startStyles);
        this._endStyles = null;
      }
      if (this._endStyles) {
        eraseStyles(this._element, this._endStyles);
        this._endStyles = null;
      }
      setStyles(this._element, this._initialStyles);
      this._state = 3 /* SpecialCasedStylesState.Destroyed */;
    }
  }
}
function filterNonAnimatableStyles(styles) {
  let result = null;
  styles.forEach((val, prop) => {
    if (isNonAnimatableStyle(prop)) {
      result = result || new Map();
      result.set(prop, val);
    }
  });
  return result;
}
function isNonAnimatableStyle(prop) {
  return prop === 'display' || prop === 'position';
}
class WebAnimationsPlayer {
  constructor(element, keyframes, options, _specialStyles) {
    this.element = element;
    this.keyframes = keyframes;
    this.options = options;
    this._specialStyles = _specialStyles;
    this._onDoneFns = [];
    this._onStartFns = [];
    this._onDestroyFns = [];
    this._initialized = false;
    this._finished = false;
    this._started = false;
    this._destroyed = false;
    // the following original fns are persistent copies of the _onStartFns and _onDoneFns
    // and are used to reset the fns to their original values upon reset()
    // (since the _onStartFns and _onDoneFns get deleted after they are called)
    this._originalOnDoneFns = [];
    this._originalOnStartFns = [];
    this.time = 0;
    this.parentPlayer = null;
    this.currentSnapshot = new Map();
    this._duration = options['duration'];
    this._delay = options['delay'] || 0;
    this.time = this._duration + this._delay;
  }
  _onFinish() {
    if (!this._finished) {
      this._finished = true;
      this._onDoneFns.forEach(fn => fn());
      this._onDoneFns = [];
    }
  }
  init() {
    this._buildPlayer();
    this._preparePlayerBeforeStart();
  }
  _buildPlayer() {
    if (this._initialized) return;
    this._initialized = true;
    const keyframes = this.keyframes;
    // @ts-expect-error overwriting a readonly property
    this.domPlayer = this._triggerWebAnimation(this.element, keyframes, this.options);
    this._finalKeyframe = keyframes.length ? keyframes[keyframes.length - 1] : new Map();
    const onFinish = () => this._onFinish();
    this.domPlayer.addEventListener('finish', onFinish);
    this.onDestroy(() => {
      // We must remove the `finish` event listener once an animation has completed all its
      // iterations. This action is necessary to prevent a memory leak since the listener captures
      // `this`, creating a closure that prevents `this` from being garbage collected.
      this.domPlayer.removeEventListener('finish', onFinish);
    });
  }
  _preparePlayerBeforeStart() {
    // this is required so that the player doesn't start to animate right away
    if (this._delay) {
      this._resetDomPlayerState();
    } else {
      this.domPlayer.pause();
    }
  }
  _convertKeyframesToObject(keyframes) {
    const kfs = [];
    keyframes.forEach(frame => {
      kfs.push(Object.fromEntries(frame));
    });
    return kfs;
  }
  /** @internal */
  _triggerWebAnimation(element, keyframes, options) {
    return element.animate(this._convertKeyframesToObject(keyframes), options);
  }
  onStart(fn) {
    this._originalOnStartFns.push(fn);
    this._onStartFns.push(fn);
  }
  onDone(fn) {
    this._originalOnDoneFns.push(fn);
    this._onDoneFns.push(fn);
  }
  onDestroy(fn) {
    this._onDestroyFns.push(fn);
  }
  play() {
    this._buildPlayer();
    if (!this.hasStarted()) {
      this._onStartFns.forEach(fn => fn());
      this._onStartFns = [];
      this._started = true;
      if (this._specialStyles) {
        this._specialStyles.start();
      }
    }
    this.domPlayer.play();
  }
  pause() {
    this.init();
    this.domPlayer.pause();
  }
  finish() {
    this.init();
    if (this._specialStyles) {
      this._specialStyles.finish();
    }
    this._onFinish();
    this.domPlayer.finish();
  }
  reset() {
    this._resetDomPlayerState();
    this._destroyed = false;
    this._finished = false;
    this._started = false;
    this._onStartFns = this._originalOnStartFns;
    this._onDoneFns = this._originalOnDoneFns;
  }
  _resetDomPlayerState() {
    if (this.domPlayer) {
      this.domPlayer.cancel();
    }
  }
  restart() {
    this.reset();
    this.play();
  }
  hasStarted() {
    return this._started;
  }
  destroy() {
    if (!this._destroyed) {
      this._destroyed = true;
      this._resetDomPlayerState();
      this._onFinish();
      if (this._specialStyles) {
        this._specialStyles.destroy();
      }
      this._onDestroyFns.forEach(fn => fn());
      this._onDestroyFns = [];
    }
  }
  setPosition(p) {
    if (this.domPlayer === undefined) {
      this.init();
    }
    this.domPlayer.currentTime = p * this.time;
  }
  getPosition() {
    // tsc is complaining with TS2362 without the conversion to number
    return +(this.domPlayer.currentTime ?? 0) / this.time;
  }
  get totalTime() {
    return this._delay + this._duration;
  }
  beforeDestroy() {
    const styles = new Map();
    if (this.hasStarted()) {
      // note: this code is invoked only when the `play` function was called prior to this
      // (thus `hasStarted` returns true), this implies that the code that initializes
      // `_finalKeyframe` has also been executed and the non-null assertion can be safely used here
      const finalKeyframe = this._finalKeyframe;
      finalKeyframe.forEach((val, prop) => {
        if (prop !== 'offset') {
          styles.set(prop, this._finished ? val : computeStyle(this.element, prop));
        }
      });
    }
    this.currentSnapshot = styles;
  }
  /** @internal */
  triggerCallback(phaseName) {
    const methods = phaseName === 'start' ? this._onStartFns : this._onDoneFns;
    methods.forEach(fn => fn());
    methods.length = 0;
  }
}
class WebAnimationsDriver {
  validateStyleProperty(prop) {
    // Perform actual validation in dev mode only, in prod mode this check is a noop.
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      return validateStyleProperty(prop);
    }
    return true;
  }
  validateAnimatableStyleProperty(prop) {
    // Perform actual validation in dev mode only, in prod mode this check is a noop.
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      const cssProp = camelCaseToDashCase(prop);
      return validateWebAnimatableStyleProperty(cssProp);
    }
    return true;
  }
  matchesElement(_element, _selector) {
    // This method is deprecated and no longer in use so we return false.
    return false;
  }
  containsElement(elm1, elm2) {
    return containsElement(elm1, elm2);
  }
  getParentElement(element) {
    return getParentElement(element);
  }
  query(element, selector, multi) {
    return invokeQuery(element, selector, multi);
  }
  computeStyle(element, prop, defaultValue) {
    return computeStyle(element, prop);
  }
  animate(element, keyframes, duration, delay, easing, previousPlayers = []) {
    const fill = delay == 0 ? 'both' : 'forwards';
    const playerOptions = {
      duration,
      delay,
      fill
    };
    // we check for this to avoid having a null|undefined value be present
    // for the easing (which results in an error for certain browsers #9752)
    if (easing) {
      playerOptions['easing'] = easing;
    }
    const previousStyles = new Map();
    const previousWebAnimationPlayers = previousPlayers.filter(player => player instanceof WebAnimationsPlayer);
    if (allowPreviousPlayerStylesMerge(duration, delay)) {
      previousWebAnimationPlayers.forEach(player => {
        player.currentSnapshot.forEach((val, prop) => previousStyles.set(prop, val));
      });
    }
    let _keyframes = normalizeKeyframes(keyframes).map(styles => new Map(styles));
    _keyframes = balancePreviousStylesIntoKeyframes(element, _keyframes, previousStyles);
    const specialStyles = packageNonAnimatableStyles(element, _keyframes);
    return new WebAnimationsPlayer(element, _keyframes, playerOptions, specialStyles);
  }
}
function createEngine(type, doc, scheduler) {
  // TODO: find a way to make this tree shakable.
  if (type === 'noop') {
    return new AnimationEngine(doc, new NoopAnimationDriver(), new NoopAnimationStyleNormalizer(), scheduler);
  }
  return new AnimationEngine(doc, new WebAnimationsDriver(), new WebAnimationsStyleNormalizer(), scheduler);
}
class Animation {
  constructor(_driver, input) {
    this._driver = _driver;
    const errors = [];
    const warnings = [];
    const ast = buildAnimationAst(_driver, input, errors, warnings);
    if (errors.length) {
      throw validationFailed(errors);
    }
    if (warnings.length) {
      warnValidation(warnings);
    }
    this._animationAst = ast;
  }
  buildTimelines(element, startingStyles, destinationStyles, options, subInstructions) {
    const start = Array.isArray(startingStyles) ? normalizeStyles(startingStyles) : startingStyles;
    const dest = Array.isArray(destinationStyles) ? normalizeStyles(destinationStyles) : destinationStyles;
    const errors = [];
    subInstructions = subInstructions || new ElementInstructionMap();
    const result = buildAnimationTimelines(this._driver, element, this._animationAst, ENTER_CLASSNAME, LEAVE_CLASSNAME, start, dest, options, subInstructions, errors);
    if (errors.length) {
      throw buildingFailed(errors);
    }
    return result;
  }
}
const ANIMATION_PREFIX = '@';
const DISABLE_ANIMATIONS_FLAG = '@.disabled';
class BaseAnimationRenderer {
  constructor(namespaceId, delegate, engine, _onDestroy) {
    this.namespaceId = namespaceId;
    this.delegate = delegate;
    this.engine = engine;
    this._onDestroy = _onDestroy;
    // We need to explicitly type this property because of an api-extractor bug
    // See https://github.com/microsoft/rushstack/issues/4390
    this.ɵtype = 0 /* AnimationRendererType.Regular */;
  }
  get data() {
    return this.delegate.data;
  }
  destroyNode(node) {
    this.delegate.destroyNode?.(node);
  }
  destroy() {
    this.engine.destroy(this.namespaceId, this.delegate);
    this.engine.afterFlushAnimationsDone(() => {
      // Call the renderer destroy method after the animations has finished as otherwise
      // styles will be removed too early which will cause an unstyled animation.
      queueMicrotask(() => {
        this.delegate.destroy();
      });
    });
    this._onDestroy?.();
  }
  createElement(name, namespace) {
    return this.delegate.createElement(name, namespace);
  }
  createComment(value) {
    return this.delegate.createComment(value);
  }
  createText(value) {
    return this.delegate.createText(value);
  }
  appendChild(parent, newChild) {
    this.delegate.appendChild(parent, newChild);
    this.engine.onInsert(this.namespaceId, newChild, parent, false);
  }
  insertBefore(parent, newChild, refChild, isMove = true) {
    this.delegate.insertBefore(parent, newChild, refChild);
    // If `isMove` true than we should animate this insert.
    this.engine.onInsert(this.namespaceId, newChild, parent, isMove);
  }
  removeChild(parent, oldChild, isHostElement) {
    this.engine.onRemove(this.namespaceId, oldChild, this.delegate);
  }
  selectRootElement(selectorOrNode, preserveContent) {
    return this.delegate.selectRootElement(selectorOrNode, preserveContent);
  }
  parentNode(node) {
    return this.delegate.parentNode(node);
  }
  nextSibling(node) {
    return this.delegate.nextSibling(node);
  }
  setAttribute(el, name, value, namespace) {
    this.delegate.setAttribute(el, name, value, namespace);
  }
  removeAttribute(el, name, namespace) {
    this.delegate.removeAttribute(el, name, namespace);
  }
  addClass(el, name) {
    this.delegate.addClass(el, name);
  }
  removeClass(el, name) {
    this.delegate.removeClass(el, name);
  }
  setStyle(el, style, value, flags) {
    this.delegate.setStyle(el, style, value, flags);
  }
  removeStyle(el, style, flags) {
    this.delegate.removeStyle(el, style, flags);
  }
  setProperty(el, name, value) {
    if (name.charAt(0) == ANIMATION_PREFIX && name == DISABLE_ANIMATIONS_FLAG) {
      this.disableAnimations(el, !!value);
    } else {
      this.delegate.setProperty(el, name, value);
    }
  }
  setValue(node, value) {
    this.delegate.setValue(node, value);
  }
  listen(target, eventName, callback) {
    return this.delegate.listen(target, eventName, callback);
  }
  disableAnimations(element, value) {
    this.engine.disableAnimations(element, value);
  }
}
class AnimationRenderer extends BaseAnimationRenderer {
  constructor(factory, namespaceId, delegate, engine, onDestroy) {
    super(namespaceId, delegate, engine, onDestroy);
    this.factory = factory;
    this.namespaceId = namespaceId;
  }
  setProperty(el, name, value) {
    if (name.charAt(0) == ANIMATION_PREFIX) {
      if (name.charAt(1) == '.' && name == DISABLE_ANIMATIONS_FLAG) {
        value = value === undefined ? true : !!value;
        this.disableAnimations(el, value);
      } else {
        this.engine.process(this.namespaceId, el, name.slice(1), value);
      }
    } else {
      this.delegate.setProperty(el, name, value);
    }
  }
  listen(target, eventName, callback) {
    if (eventName.charAt(0) == ANIMATION_PREFIX) {
      const element = resolveElementFromTarget(target);
      let name = eventName.slice(1);
      let phase = '';
      // @listener.phase is for trigger animation callbacks
      // @@listener is for animation builder callbacks
      if (name.charAt(0) != ANIMATION_PREFIX) {
        [name, phase] = parseTriggerCallbackName(name);
      }
      return this.engine.listen(this.namespaceId, element, name, phase, event => {
        const countId = event['_data'] || -1;
        this.factory.scheduleListenerCallback(countId, callback, event);
      });
    }
    return this.delegate.listen(target, eventName, callback);
  }
}
function resolveElementFromTarget(target) {
  switch (target) {
    case 'body':
      return document.body;
    case 'document':
      return document;
    case 'window':
      return window;
    default:
      return target;
  }
}
function parseTriggerCallbackName(triggerName) {
  const dotIndex = triggerName.indexOf('.');
  const trigger = triggerName.substring(0, dotIndex);
  const phase = triggerName.slice(dotIndex + 1);
  return [trigger, phase];
}
class AnimationRendererFactory {
  constructor(delegate, engine, _zone) {
    this.delegate = delegate;
    this.engine = engine;
    this._zone = _zone;
    this._currentId = 0;
    this._microtaskId = 1;
    this._animationCallbacksBuffer = [];
    this._rendererCache = new Map();
    this._cdRecurDepth = 0;
    engine.onRemovalComplete = (element, delegate) => {
      // Note: if a component element has a leave animation, and a host leave animation,
      // the view engine will call `removeChild` for the parent
      // component renderer as well as for the child component renderer.
      // Therefore, we need to check if we already removed the element.
      const parentNode = delegate?.parentNode(element);
      if (parentNode) {
        delegate.removeChild(parentNode, element);
      }
    };
  }
  createRenderer(hostElement, type) {
    const EMPTY_NAMESPACE_ID = '';
    // cache the delegates to find out which cached delegate can
    // be used by which cached renderer
    const delegate = this.delegate.createRenderer(hostElement, type);
    if (!hostElement || !type?.data?.['animation']) {
      const cache = this._rendererCache;
      let renderer = cache.get(delegate);
      if (!renderer) {
        // Ensure that the renderer is removed from the cache on destroy
        // since it may contain references to detached DOM nodes.
        const onRendererDestroy = () => cache.delete(delegate);
        renderer = new BaseAnimationRenderer(EMPTY_NAMESPACE_ID, delegate, this.engine, onRendererDestroy);
        // only cache this result when the base renderer is used
        cache.set(delegate, renderer);
      }
      return renderer;
    }
    const componentId = type.id;
    const namespaceId = type.id + '-' + this._currentId;
    this._currentId++;
    this.engine.register(namespaceId, hostElement);
    const registerTrigger = trigger => {
      if (Array.isArray(trigger)) {
        trigger.forEach(registerTrigger);
      } else {
        this.engine.registerTrigger(componentId, namespaceId, hostElement, trigger.name, trigger);
      }
    };
    const animationTriggers = type.data['animation'];
    animationTriggers.forEach(registerTrigger);
    return new AnimationRenderer(this, namespaceId, delegate, this.engine);
  }
  begin() {
    this._cdRecurDepth++;
    if (this.delegate.begin) {
      this.delegate.begin();
    }
  }
  _scheduleCountTask() {
    queueMicrotask(() => {
      this._microtaskId++;
    });
  }
  /** @internal */
  scheduleListenerCallback(count, fn, data) {
    if (count >= 0 && count < this._microtaskId) {
      this._zone.run(() => fn(data));
      return;
    }
    const animationCallbacksBuffer = this._animationCallbacksBuffer;
    if (animationCallbacksBuffer.length == 0) {
      queueMicrotask(() => {
        this._zone.run(() => {
          animationCallbacksBuffer.forEach(tuple => {
            const [fn, data] = tuple;
            fn(data);
          });
          this._animationCallbacksBuffer = [];
        });
      });
    }
    animationCallbacksBuffer.push([fn, data]);
  }
  end() {
    this._cdRecurDepth--;
    // this is to prevent animations from running twice when an inner
    // component does CD when a parent component instead has inserted it
    if (this._cdRecurDepth == 0) {
      this._zone.runOutsideAngular(() => {
        this._scheduleCountTask();
        this.engine.flush(this._microtaskId);
      });
    }
    if (this.delegate.end) {
      this.delegate.end();
    }
  }
  whenRenderingDone() {
    return this.engine.whenRenderingDone();
  }
}

/**
 * @module
 * @description
 * Entry point for all animation APIs of the animation browser package.
 */

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 72102:
/*!*****************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/a11y.mjs ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A11yModule: () => (/* binding */ A11yModule),
/* harmony export */   ActiveDescendantKeyManager: () => (/* binding */ ActiveDescendantKeyManager),
/* harmony export */   AriaDescriber: () => (/* binding */ AriaDescriber),
/* harmony export */   CDK_DESCRIBEDBY_HOST_ATTRIBUTE: () => (/* binding */ CDK_DESCRIBEDBY_HOST_ATTRIBUTE),
/* harmony export */   CDK_DESCRIBEDBY_ID_PREFIX: () => (/* binding */ CDK_DESCRIBEDBY_ID_PREFIX),
/* harmony export */   CdkAriaLive: () => (/* binding */ CdkAriaLive),
/* harmony export */   CdkMonitorFocus: () => (/* binding */ CdkMonitorFocus),
/* harmony export */   CdkTrapFocus: () => (/* binding */ CdkTrapFocus),
/* harmony export */   ConfigurableFocusTrap: () => (/* binding */ ConfigurableFocusTrap),
/* harmony export */   ConfigurableFocusTrapFactory: () => (/* binding */ ConfigurableFocusTrapFactory),
/* harmony export */   EventListenerFocusTrapInertStrategy: () => (/* binding */ EventListenerFocusTrapInertStrategy),
/* harmony export */   FOCUS_MONITOR_DEFAULT_OPTIONS: () => (/* binding */ FOCUS_MONITOR_DEFAULT_OPTIONS),
/* harmony export */   FOCUS_TRAP_INERT_STRATEGY: () => (/* binding */ FOCUS_TRAP_INERT_STRATEGY),
/* harmony export */   FocusKeyManager: () => (/* binding */ FocusKeyManager),
/* harmony export */   FocusMonitor: () => (/* binding */ FocusMonitor),
/* harmony export */   FocusMonitorDetectionMode: () => (/* binding */ FocusMonitorDetectionMode),
/* harmony export */   FocusTrap: () => (/* binding */ FocusTrap),
/* harmony export */   FocusTrapFactory: () => (/* binding */ FocusTrapFactory),
/* harmony export */   HighContrastMode: () => (/* binding */ HighContrastMode),
/* harmony export */   HighContrastModeDetector: () => (/* binding */ HighContrastModeDetector),
/* harmony export */   INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS: () => (/* binding */ INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS),
/* harmony export */   INPUT_MODALITY_DETECTOR_OPTIONS: () => (/* binding */ INPUT_MODALITY_DETECTOR_OPTIONS),
/* harmony export */   InputModalityDetector: () => (/* binding */ InputModalityDetector),
/* harmony export */   InteractivityChecker: () => (/* binding */ InteractivityChecker),
/* harmony export */   IsFocusableConfig: () => (/* binding */ IsFocusableConfig),
/* harmony export */   LIVE_ANNOUNCER_DEFAULT_OPTIONS: () => (/* binding */ LIVE_ANNOUNCER_DEFAULT_OPTIONS),
/* harmony export */   LIVE_ANNOUNCER_ELEMENT_TOKEN: () => (/* binding */ LIVE_ANNOUNCER_ELEMENT_TOKEN),
/* harmony export */   LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY: () => (/* binding */ LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY),
/* harmony export */   ListKeyManager: () => (/* binding */ ListKeyManager),
/* harmony export */   LiveAnnouncer: () => (/* binding */ LiveAnnouncer),
/* harmony export */   MESSAGES_CONTAINER_ID: () => (/* binding */ MESSAGES_CONTAINER_ID),
/* harmony export */   NOOP_TREE_KEY_MANAGER_FACTORY: () => (/* binding */ NOOP_TREE_KEY_MANAGER_FACTORY),
/* harmony export */   NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER: () => (/* binding */ NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER),
/* harmony export */   NoopTreeKeyManager: () => (/* binding */ NoopTreeKeyManager),
/* harmony export */   TREE_KEY_MANAGER: () => (/* binding */ TREE_KEY_MANAGER),
/* harmony export */   TREE_KEY_MANAGER_FACTORY: () => (/* binding */ TREE_KEY_MANAGER_FACTORY),
/* harmony export */   TREE_KEY_MANAGER_FACTORY_PROVIDER: () => (/* binding */ TREE_KEY_MANAGER_FACTORY_PROVIDER),
/* harmony export */   TreeKeyManager: () => (/* binding */ TreeKeyManager),
/* harmony export */   addAriaReferencedId: () => (/* binding */ addAriaReferencedId),
/* harmony export */   getAriaReferenceIds: () => (/* binding */ getAriaReferenceIds),
/* harmony export */   isFakeMousedownFromScreenReader: () => (/* binding */ isFakeMousedownFromScreenReader),
/* harmony export */   isFakeTouchstartFromScreenReader: () => (/* binding */ isFakeTouchstartFromScreenReader),
/* harmony export */   removeAriaReferencedId: () => (/* binding */ removeAriaReferencedId)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);
/* harmony import */ var _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/cdk/keycodes */ 74879);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 2510);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 52575);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs/operators */ 47470);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs/operators */ 91817);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var _angular_cdk_coercion_private__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @angular/cdk/coercion/private */ 22810);
/* harmony import */ var _angular_cdk_observers__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @angular/cdk/observers */ 39539);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var _angular_cdk_layout__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! @angular/cdk/layout */ 87912);














/** IDs are delimited by an empty space, as per the spec. */
const ID_DELIMITER = ' ';
/**
 * Adds the given ID to the specified ARIA attribute on an element.
 * Used for attributes such as aria-labelledby, aria-owns, etc.
 */
function addAriaReferencedId(el, attr, id) {
  const ids = getAriaReferenceIds(el, attr);
  id = id.trim();
  if (ids.some(existingId => existingId.trim() === id)) {
    return;
  }
  ids.push(id);
  el.setAttribute(attr, ids.join(ID_DELIMITER));
}
/**
 * Removes the given ID from the specified ARIA attribute on an element.
 * Used for attributes such as aria-labelledby, aria-owns, etc.
 */
function removeAriaReferencedId(el, attr, id) {
  const ids = getAriaReferenceIds(el, attr);
  id = id.trim();
  const filteredIds = ids.filter(val => val !== id);
  if (filteredIds.length) {
    el.setAttribute(attr, filteredIds.join(ID_DELIMITER));
  } else {
    el.removeAttribute(attr);
  }
}
/**
 * Gets the list of IDs referenced by the given ARIA attribute on an element.
 * Used for attributes such as aria-labelledby, aria-owns, etc.
 */
function getAriaReferenceIds(el, attr) {
  // Get string array of all individual ids (whitespace delimited) in the attribute value
  const attrValue = el.getAttribute(attr);
  return attrValue?.match(/\S+/g) ?? [];
}

/**
 * ID used for the body container where all messages are appended.
 * @deprecated No longer being used. To be removed.
 * @breaking-change 14.0.0
 */
const MESSAGES_CONTAINER_ID = 'cdk-describedby-message-container';
/**
 * ID prefix used for each created message element.
 * @deprecated To be turned into a private variable.
 * @breaking-change 14.0.0
 */
const CDK_DESCRIBEDBY_ID_PREFIX = 'cdk-describedby-message';
/**
 * Attribute given to each host element that is described by a message element.
 * @deprecated To be turned into a private variable.
 * @breaking-change 14.0.0
 */
const CDK_DESCRIBEDBY_HOST_ATTRIBUTE = 'cdk-describedby-host';
/** Global incremental identifier for each registered message element. */
let nextId = 0;
/**
 * Utility that creates visually hidden elements with a message content. Useful for elements that
 * want to use aria-describedby to further describe themselves without adding additional visual
 * content.
 */
class AriaDescriber {
  constructor(_document,
  /**
   * @deprecated To be turned into a required parameter.
   * @breaking-change 14.0.0
   */
  _platform) {
    this._platform = _platform;
    /** Map of all registered message elements that have been placed into the document. */
    this._messageRegistry = new Map();
    /** Container for all registered messages. */
    this._messagesContainer = null;
    /** Unique ID for the service. */
    this._id = `${nextId++}`;
    this._document = _document;
    this._id = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.APP_ID) + '-' + nextId++;
  }
  describe(hostElement, message, role) {
    if (!this._canBeDescribed(hostElement, message)) {
      return;
    }
    const key = getKey(message, role);
    if (typeof message !== 'string') {
      // We need to ensure that the element has an ID.
      setMessageId(message, this._id);
      this._messageRegistry.set(key, {
        messageElement: message,
        referenceCount: 0
      });
    } else if (!this._messageRegistry.has(key)) {
      this._createMessageElement(message, role);
    }
    if (!this._isElementDescribedByMessage(hostElement, key)) {
      this._addMessageReference(hostElement, key);
    }
  }
  removeDescription(hostElement, message, role) {
    if (!message || !this._isElementNode(hostElement)) {
      return;
    }
    const key = getKey(message, role);
    if (this._isElementDescribedByMessage(hostElement, key)) {
      this._removeMessageReference(hostElement, key);
    }
    // If the message is a string, it means that it's one that we created for the
    // consumer so we can remove it safely, otherwise we should leave it in place.
    if (typeof message === 'string') {
      const registeredMessage = this._messageRegistry.get(key);
      if (registeredMessage && registeredMessage.referenceCount === 0) {
        this._deleteMessageElement(key);
      }
    }
    if (this._messagesContainer?.childNodes.length === 0) {
      this._messagesContainer.remove();
      this._messagesContainer = null;
    }
  }
  /** Unregisters all created message elements and removes the message container. */
  ngOnDestroy() {
    const describedElements = this._document.querySelectorAll(`[${CDK_DESCRIBEDBY_HOST_ATTRIBUTE}="${this._id}"]`);
    for (let i = 0; i < describedElements.length; i++) {
      this._removeCdkDescribedByReferenceIds(describedElements[i]);
      describedElements[i].removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
    }
    this._messagesContainer?.remove();
    this._messagesContainer = null;
    this._messageRegistry.clear();
  }
  /**
   * Creates a new element in the visually hidden message container element with the message
   * as its content and adds it to the message registry.
   */
  _createMessageElement(message, role) {
    const messageElement = this._document.createElement('div');
    setMessageId(messageElement, this._id);
    messageElement.textContent = message;
    if (role) {
      messageElement.setAttribute('role', role);
    }
    this._createMessagesContainer();
    this._messagesContainer.appendChild(messageElement);
    this._messageRegistry.set(getKey(message, role), {
      messageElement,
      referenceCount: 0
    });
  }
  /** Deletes the message element from the global messages container. */
  _deleteMessageElement(key) {
    this._messageRegistry.get(key)?.messageElement?.remove();
    this._messageRegistry.delete(key);
  }
  /** Creates the global container for all aria-describedby messages. */
  _createMessagesContainer() {
    if (this._messagesContainer) {
      return;
    }
    const containerClassName = 'cdk-describedby-message-container';
    const serverContainers = this._document.querySelectorAll(`.${containerClassName}[platform="server"]`);
    for (let i = 0; i < serverContainers.length; i++) {
      // When going from the server to the client, we may end up in a situation where there's
      // already a container on the page, but we don't have a reference to it. Clear the
      // old container so we don't get duplicates. Doing this, instead of emptying the previous
      // container, should be slightly faster.
      serverContainers[i].remove();
    }
    const messagesContainer = this._document.createElement('div');
    // We add `visibility: hidden` in order to prevent text in this container from
    // being searchable by the browser's Ctrl + F functionality.
    // Screen-readers will still read the description for elements with aria-describedby even
    // when the description element is not visible.
    messagesContainer.style.visibility = 'hidden';
    // Even though we use `visibility: hidden`, we still apply `cdk-visually-hidden` so that
    // the description element doesn't impact page layout.
    messagesContainer.classList.add(containerClassName);
    messagesContainer.classList.add('cdk-visually-hidden');
    // @breaking-change 14.0.0 Remove null check for `_platform`.
    if (this._platform && !this._platform.isBrowser) {
      messagesContainer.setAttribute('platform', 'server');
    }
    this._document.body.appendChild(messagesContainer);
    this._messagesContainer = messagesContainer;
  }
  /** Removes all cdk-describedby messages that are hosted through the element. */
  _removeCdkDescribedByReferenceIds(element) {
    // Remove all aria-describedby reference IDs that are prefixed by CDK_DESCRIBEDBY_ID_PREFIX
    const originalReferenceIds = getAriaReferenceIds(element, 'aria-describedby').filter(id => id.indexOf(CDK_DESCRIBEDBY_ID_PREFIX) != 0);
    element.setAttribute('aria-describedby', originalReferenceIds.join(' '));
  }
  /**
   * Adds a message reference to the element using aria-describedby and increments the registered
   * message's reference count.
   */
  _addMessageReference(element, key) {
    const registeredMessage = this._messageRegistry.get(key);
    // Add the aria-describedby reference and set the
    // describedby_host attribute to mark the element.
    addAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
    element.setAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE, this._id);
    registeredMessage.referenceCount++;
  }
  /**
   * Removes a message reference from the element using aria-describedby
   * and decrements the registered message's reference count.
   */
  _removeMessageReference(element, key) {
    const registeredMessage = this._messageRegistry.get(key);
    registeredMessage.referenceCount--;
    removeAriaReferencedId(element, 'aria-describedby', registeredMessage.messageElement.id);
    element.removeAttribute(CDK_DESCRIBEDBY_HOST_ATTRIBUTE);
  }
  /** Returns true if the element has been described by the provided message ID. */
  _isElementDescribedByMessage(element, key) {
    const referenceIds = getAriaReferenceIds(element, 'aria-describedby');
    const registeredMessage = this._messageRegistry.get(key);
    const messageId = registeredMessage && registeredMessage.messageElement.id;
    return !!messageId && referenceIds.indexOf(messageId) != -1;
  }
  /** Determines whether a message can be described on a particular element. */
  _canBeDescribed(element, message) {
    if (!this._isElementNode(element)) {
      return false;
    }
    if (message && typeof message === 'object') {
      // We'd have to make some assumptions about the description element's text, if the consumer
      // passed in an element. Assume that if an element is passed in, the consumer has verified
      // that it can be used as a description.
      return true;
    }
    const trimmedMessage = message == null ? '' : `${message}`.trim();
    const ariaLabel = element.getAttribute('aria-label');
    // We shouldn't set descriptions if they're exactly the same as the `aria-label` of the
    // element, because screen readers will end up reading out the same text twice in a row.
    return trimmedMessage ? !ariaLabel || ariaLabel.trim() !== trimmedMessage : false;
  }
  /** Checks whether a node is an Element node. */
  _isElementNode(element) {
    return element.nodeType === this._document.ELEMENT_NODE;
  }
  static {
    this.ɵfac = function AriaDescriber_Factory(t) {
      return new (t || AriaDescriber)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: AriaDescriber,
      factory: AriaDescriber.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AriaDescriber, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }, {
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform
  }], null);
})();
/** Gets a key that can be used to look messages up in the registry. */
function getKey(message, role) {
  return typeof message === 'string' ? `${role || ''}/${message}` : message;
}
/** Assigns a unique ID to an element, if it doesn't have one already. */
function setMessageId(element, serviceId) {
  if (!element.id) {
    element.id = `${CDK_DESCRIBEDBY_ID_PREFIX}-${serviceId}-${nextId++}`;
  }
}
const DEFAULT_TYPEAHEAD_DEBOUNCE_INTERVAL_MS = 200;
/**
 * Selects items based on keyboard inputs. Implements the typeahead functionality of
 * `role="listbox"` or `role="tree"` and other related roles.
 */
class Typeahead {
  constructor(initialItems, config) {
    this._letterKeyStream = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this._items = [];
    this._selectedItemIndex = -1;
    /** Buffer for the letters that the user has pressed */
    this._pressedLetters = [];
    this._selectedItem = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this.selectedItem = this._selectedItem;
    const typeAheadInterval = typeof config?.debounceInterval === 'number' ? config.debounceInterval : DEFAULT_TYPEAHEAD_DEBOUNCE_INTERVAL_MS;
    if (config?.skipPredicate) {
      this._skipPredicateFn = config.skipPredicate;
    }
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && initialItems.length && initialItems.some(item => typeof item.getLabel !== 'function')) {
      throw new Error('KeyManager items in typeahead mode must implement the `getLabel` method.');
    }
    this.setItems(initialItems);
    this._setupKeyHandler(typeAheadInterval);
  }
  destroy() {
    this._pressedLetters = [];
    this._letterKeyStream.complete();
    this._selectedItem.complete();
  }
  setCurrentSelectedItemIndex(index) {
    this._selectedItemIndex = index;
  }
  setItems(items) {
    this._items = items;
  }
  handleKey(event) {
    const keyCode = event.keyCode;
    // Attempt to use the `event.key` which also maps it to the user's keyboard language,
    // otherwise fall back to resolving alphanumeric characters via the keyCode.
    if (event.key && event.key.length === 1) {
      this._letterKeyStream.next(event.key.toLocaleUpperCase());
    } else if (keyCode >= _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.A && keyCode <= _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.Z || keyCode >= _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.ZERO && keyCode <= _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.NINE) {
      this._letterKeyStream.next(String.fromCharCode(keyCode));
    }
  }
  /** Gets whether the user is currently typing into the manager using the typeahead feature. */
  isTyping() {
    return this._pressedLetters.length > 0;
  }
  /** Resets the currently stored sequence of typed letters. */
  reset() {
    this._pressedLetters = [];
  }
  _setupKeyHandler(typeAheadInterval) {
    // Debounce the presses of non-navigational keys, collect the ones that correspond to letters
    // and convert those letters back into a string. Afterwards find the first item that starts
    // with that string and select it.
    this._letterKeyStream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.tap)(letter => this._pressedLetters.push(letter)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.debounceTime)(typeAheadInterval), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.filter)(() => this._pressedLetters.length > 0), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.map)(() => this._pressedLetters.join('').toLocaleUpperCase())).subscribe(inputString => {
      // Start at 1 because we want to start searching at the item immediately
      // following the current active item.
      for (let i = 1; i < this._items.length + 1; i++) {
        const index = (this._selectedItemIndex + i) % this._items.length;
        const item = this._items[index];
        if (!this._skipPredicateFn?.(item) && item.getLabel?.().toLocaleUpperCase().trim().indexOf(inputString) === 0) {
          this._selectedItem.next(item);
          break;
        }
      }
      this._pressedLetters = [];
    });
  }
}

/**
 * This class manages keyboard events for selectable lists. If you pass it a query list
 * of items, it will set the active item correctly when arrow events occur.
 */
class ListKeyManager {
  constructor(_items, injector) {
    this._items = _items;
    this._activeItemIndex = -1;
    this._activeItem = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.signal)(null);
    this._wrap = false;
    this._typeaheadSubscription = rxjs__WEBPACK_IMPORTED_MODULE_9__.Subscription.EMPTY;
    this._vertical = true;
    this._allowedModifierKeys = [];
    this._homeAndEnd = false;
    this._pageUpAndDown = {
      enabled: false,
      delta: 10
    };
    /**
     * Predicate function that can be used to check whether an item should be skipped
     * by the key manager. By default, disabled items are skipped.
     */
    this._skipPredicateFn = item => item.disabled;
    /**
     * Stream that emits any time the TAB key is pressed, so components can react
     * when focus is shifted off of the list.
     */
    this.tabOut = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    /** Stream that emits whenever the active item of the list manager changes. */
    this.change = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    // We allow for the items to be an array because, in some cases, the consumer may
    // not have access to a QueryList of the items they want to manage (e.g. when the
    // items aren't being collected via `ViewChildren` or `ContentChildren`).
    if (_items instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.QueryList) {
      this._itemChangesSubscription = _items.changes.subscribe(newItems => this._itemsChanged(newItems.toArray()));
    } else if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.isSignal)(_items)) {
      if (!injector && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw new Error('ListKeyManager constructed with a signal must receive an injector');
      }
      this._effectRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.effect)(() => this._itemsChanged(_items()), {
        injector
      });
    }
  }
  /**
   * Sets the predicate function that determines which items should be skipped by the
   * list key manager.
   * @param predicate Function that determines whether the given item should be skipped.
   */
  skipPredicate(predicate) {
    this._skipPredicateFn = predicate;
    return this;
  }
  /**
   * Configures wrapping mode, which determines whether the active item will wrap to
   * the other end of list when there are no more items in the given direction.
   * @param shouldWrap Whether the list should wrap when reaching the end.
   */
  withWrap(shouldWrap = true) {
    this._wrap = shouldWrap;
    return this;
  }
  /**
   * Configures whether the key manager should be able to move the selection vertically.
   * @param enabled Whether vertical selection should be enabled.
   */
  withVerticalOrientation(enabled = true) {
    this._vertical = enabled;
    return this;
  }
  /**
   * Configures the key manager to move the selection horizontally.
   * Passing in `null` will disable horizontal movement.
   * @param direction Direction in which the selection can be moved.
   */
  withHorizontalOrientation(direction) {
    this._horizontal = direction;
    return this;
  }
  /**
   * Modifier keys which are allowed to be held down and whose default actions will be prevented
   * as the user is pressing the arrow keys. Defaults to not allowing any modifier keys.
   */
  withAllowedModifierKeys(keys) {
    this._allowedModifierKeys = keys;
    return this;
  }
  /**
   * Turns on typeahead mode which allows users to set the active item by typing.
   * @param debounceInterval Time to wait after the last keystroke before setting the active item.
   */
  withTypeAhead(debounceInterval = 200) {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      const items = this._getItemsArray();
      if (items.length > 0 && items.some(item => typeof item.getLabel !== 'function')) {
        throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
      }
    }
    this._typeaheadSubscription.unsubscribe();
    const items = this._getItemsArray();
    this._typeahead = new Typeahead(items, {
      debounceInterval: typeof debounceInterval === 'number' ? debounceInterval : undefined,
      skipPredicate: item => this._skipPredicateFn(item)
    });
    this._typeaheadSubscription = this._typeahead.selectedItem.subscribe(item => {
      this.setActiveItem(item);
    });
    return this;
  }
  /** Cancels the current typeahead sequence. */
  cancelTypeahead() {
    this._typeahead?.reset();
    return this;
  }
  /**
   * Configures the key manager to activate the first and last items
   * respectively when the Home or End key is pressed.
   * @param enabled Whether pressing the Home or End key activates the first/last item.
   */
  withHomeAndEnd(enabled = true) {
    this._homeAndEnd = enabled;
    return this;
  }
  /**
   * Configures the key manager to activate every 10th, configured or first/last element in up/down direction
   * respectively when the Page-Up or Page-Down key is pressed.
   * @param enabled Whether pressing the Page-Up or Page-Down key activates the first/last item.
   * @param delta Whether pressing the Home or End key activates the first/last item.
   */
  withPageUpDown(enabled = true, delta = 10) {
    this._pageUpAndDown = {
      enabled,
      delta
    };
    return this;
  }
  setActiveItem(item) {
    const previousActiveItem = this._activeItem();
    this.updateActiveItem(item);
    if (this._activeItem() !== previousActiveItem) {
      this.change.next(this._activeItemIndex);
    }
  }
  /**
   * Sets the active item depending on the key event passed in.
   * @param event Keyboard event to be used for determining which element should be active.
   */
  onKeydown(event) {
    const keyCode = event.keyCode;
    const modifiers = ['altKey', 'ctrlKey', 'metaKey', 'shiftKey'];
    const isModifierAllowed = modifiers.every(modifier => {
      return !event[modifier] || this._allowedModifierKeys.indexOf(modifier) > -1;
    });
    switch (keyCode) {
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.TAB:
        this.tabOut.next();
        return;
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.DOWN_ARROW:
        if (this._vertical && isModifierAllowed) {
          this.setNextItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.UP_ARROW:
        if (this._vertical && isModifierAllowed) {
          this.setPreviousItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.RIGHT_ARROW:
        if (this._horizontal && isModifierAllowed) {
          this._horizontal === 'rtl' ? this.setPreviousItemActive() : this.setNextItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.LEFT_ARROW:
        if (this._horizontal && isModifierAllowed) {
          this._horizontal === 'rtl' ? this.setNextItemActive() : this.setPreviousItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.HOME:
        if (this._homeAndEnd && isModifierAllowed) {
          this.setFirstItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.END:
        if (this._homeAndEnd && isModifierAllowed) {
          this.setLastItemActive();
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.PAGE_UP:
        if (this._pageUpAndDown.enabled && isModifierAllowed) {
          const targetIndex = this._activeItemIndex - this._pageUpAndDown.delta;
          this._setActiveItemByIndex(targetIndex > 0 ? targetIndex : 0, 1);
          break;
        } else {
          return;
        }
      case _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.PAGE_DOWN:
        if (this._pageUpAndDown.enabled && isModifierAllowed) {
          const targetIndex = this._activeItemIndex + this._pageUpAndDown.delta;
          const itemsLength = this._getItemsArray().length;
          this._setActiveItemByIndex(targetIndex < itemsLength ? targetIndex : itemsLength - 1, -1);
          break;
        } else {
          return;
        }
      default:
        if (isModifierAllowed || (0,_angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.hasModifierKey)(event, 'shiftKey')) {
          this._typeahead?.handleKey(event);
        }
        // Note that we return here, in order to avoid preventing
        // the default action of non-navigational keys.
        return;
    }
    this._typeahead?.reset();
    event.preventDefault();
  }
  /** Index of the currently active item. */
  get activeItemIndex() {
    return this._activeItemIndex;
  }
  /** The active item. */
  get activeItem() {
    return this._activeItem();
  }
  /** Gets whether the user is currently typing into the manager using the typeahead feature. */
  isTyping() {
    return !!this._typeahead && this._typeahead.isTyping();
  }
  /** Sets the active item to the first enabled item in the list. */
  setFirstItemActive() {
    this._setActiveItemByIndex(0, 1);
  }
  /** Sets the active item to the last enabled item in the list. */
  setLastItemActive() {
    this._setActiveItemByIndex(this._getItemsArray().length - 1, -1);
  }
  /** Sets the active item to the next enabled item in the list. */
  setNextItemActive() {
    this._activeItemIndex < 0 ? this.setFirstItemActive() : this._setActiveItemByDelta(1);
  }
  /** Sets the active item to a previous enabled item in the list. */
  setPreviousItemActive() {
    this._activeItemIndex < 0 && this._wrap ? this.setLastItemActive() : this._setActiveItemByDelta(-1);
  }
  updateActiveItem(item) {
    const itemArray = this._getItemsArray();
    const index = typeof item === 'number' ? item : itemArray.indexOf(item);
    const activeItem = itemArray[index];
    // Explicitly check for `null` and `undefined` because other falsy values are valid.
    this._activeItem.set(activeItem == null ? null : activeItem);
    this._activeItemIndex = index;
    this._typeahead?.setCurrentSelectedItemIndex(index);
  }
  /** Cleans up the key manager. */
  destroy() {
    this._typeaheadSubscription.unsubscribe();
    this._itemChangesSubscription?.unsubscribe();
    this._effectRef?.destroy();
    this._typeahead?.destroy();
    this.tabOut.complete();
    this.change.complete();
  }
  /**
   * This method sets the active item, given a list of items and the delta between the
   * currently active item and the new active item. It will calculate differently
   * depending on whether wrap mode is turned on.
   */
  _setActiveItemByDelta(delta) {
    this._wrap ? this._setActiveInWrapMode(delta) : this._setActiveInDefaultMode(delta);
  }
  /**
   * Sets the active item properly given "wrap" mode. In other words, it will continue to move
   * down the list until it finds an item that is not disabled, and it will wrap if it
   * encounters either end of the list.
   */
  _setActiveInWrapMode(delta) {
    const items = this._getItemsArray();
    for (let i = 1; i <= items.length; i++) {
      const index = (this._activeItemIndex + delta * i + items.length) % items.length;
      const item = items[index];
      if (!this._skipPredicateFn(item)) {
        this.setActiveItem(index);
        return;
      }
    }
  }
  /**
   * Sets the active item properly given the default mode. In other words, it will
   * continue to move down the list until it finds an item that is not disabled. If
   * it encounters either end of the list, it will stop and not wrap.
   */
  _setActiveInDefaultMode(delta) {
    this._setActiveItemByIndex(this._activeItemIndex + delta, delta);
  }
  /**
   * Sets the active item to the first enabled item starting at the index specified. If the
   * item is disabled, it will move in the fallbackDelta direction until it either
   * finds an enabled item or encounters the end of the list.
   */
  _setActiveItemByIndex(index, fallbackDelta) {
    const items = this._getItemsArray();
    if (!items[index]) {
      return;
    }
    while (this._skipPredicateFn(items[index])) {
      index += fallbackDelta;
      if (!items[index]) {
        return;
      }
    }
    this.setActiveItem(index);
  }
  /** Returns the items as an array. */
  _getItemsArray() {
    if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.isSignal)(this._items)) {
      return this._items();
    }
    return this._items instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.QueryList ? this._items.toArray() : this._items;
  }
  /** Callback for when the items have changed. */
  _itemsChanged(newItems) {
    this._typeahead?.setItems(newItems);
    const activeItem = this._activeItem();
    if (activeItem) {
      const newIndex = newItems.indexOf(activeItem);
      if (newIndex > -1 && newIndex !== this._activeItemIndex) {
        this._activeItemIndex = newIndex;
        this._typeahead?.setCurrentSelectedItemIndex(newIndex);
      }
    }
  }
}
class ActiveDescendantKeyManager extends ListKeyManager {
  setActiveItem(index) {
    if (this.activeItem) {
      this.activeItem.setInactiveStyles();
    }
    super.setActiveItem(index);
    if (this.activeItem) {
      this.activeItem.setActiveStyles();
    }
  }
}
class FocusKeyManager extends ListKeyManager {
  constructor() {
    super(...arguments);
    this._origin = 'program';
  }
  /**
   * Sets the focus origin that will be passed in to the items for any subsequent `focus` calls.
   * @param origin Focus origin to be used when focusing items.
   */
  setFocusOrigin(origin) {
    this._origin = origin;
    return this;
  }
  setActiveItem(item) {
    super.setActiveItem(item);
    if (this.activeItem) {
      this.activeItem.focus(this._origin);
    }
  }
}

/**
 * This class manages keyboard events for trees. If you pass it a QueryList or other list of tree
 * items, it will set the active item, focus, handle expansion and typeahead correctly when
 * keyboard events occur.
 */
class TreeKeyManager {
  _initializeFocus() {
    if (this._hasInitialFocused || this._items.length === 0) {
      return;
    }
    let activeIndex = 0;
    for (let i = 0; i < this._items.length; i++) {
      if (!this._skipPredicateFn(this._items[i]) && !this._isItemDisabled(this._items[i])) {
        activeIndex = i;
        break;
      }
    }
    const activeItem = this._items[activeIndex];
    // Use `makeFocusable` here, because we want the item to just be focusable, not actually
    // capture the focus since the user isn't interacting with it. See #29628.
    if (activeItem.makeFocusable) {
      this._activeItem?.unfocus();
      this._activeItemIndex = activeIndex;
      this._activeItem = activeItem;
      this._typeahead?.setCurrentSelectedItemIndex(activeIndex);
      activeItem.makeFocusable();
    } else {
      // Backwards compatibility for items that don't implement `makeFocusable`.
      this.focusItem(activeIndex);
    }
    this._hasInitialFocused = true;
  }
  /**
   *
   * @param items List of TreeKeyManager options. Can be synchronous or asynchronous.
   * @param config Optional configuration options. By default, use 'ltr' horizontal orientation. By
   * default, do not skip any nodes. By default, key manager only calls `focus` method when items
   * are focused and does not call `activate`. If `typeaheadDefaultInterval` is `true`, use a
   * default interval of 200ms.
   */
  constructor(items, config) {
    /** The index of the currently active (focused) item. */
    this._activeItemIndex = -1;
    /** The currently active (focused) item. */
    this._activeItem = null;
    /** Whether or not we activate the item when it's focused. */
    this._shouldActivationFollowFocus = false;
    /**
     * The orientation that the tree is laid out in. In `rtl` mode, the behavior of Left and
     * Right arrow are switched.
     */
    this._horizontalOrientation = 'ltr';
    /**
     * Predicate function that can be used to check whether an item should be skipped
     * by the key manager.
     *
     * The default value for this doesn't skip any elements in order to keep tree items focusable
     * when disabled. This aligns with ARIA guidelines:
     * https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/#focusabilityofdisabledcontrols.
     */
    this._skipPredicateFn = _item => false;
    /** Function to determine equivalent items. */
    this._trackByFn = item => item;
    /** Synchronous cache of the items to manage. */
    this._items = [];
    this._typeaheadSubscription = rxjs__WEBPACK_IMPORTED_MODULE_9__.Subscription.EMPTY;
    this._hasInitialFocused = false;
    /** Stream that emits any time the focused item changes. */
    this.change = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    // We allow for the items to be an array or Observable because, in some cases, the consumer may
    // not have access to a QueryList of the items they want to manage (e.g. when the
    // items aren't being collected via `ViewChildren` or `ContentChildren`).
    if (items instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.QueryList) {
      this._items = items.toArray();
      items.changes.subscribe(newItems => {
        this._items = newItems.toArray();
        this._typeahead?.setItems(this._items);
        this._updateActiveItemIndex(this._items);
        this._initializeFocus();
      });
    } else if ((0,rxjs__WEBPACK_IMPORTED_MODULE_10__.isObservable)(items)) {
      items.subscribe(newItems => {
        this._items = newItems;
        this._typeahead?.setItems(newItems);
        this._updateActiveItemIndex(newItems);
        this._initializeFocus();
      });
    } else {
      this._items = items;
      this._initializeFocus();
    }
    if (typeof config.shouldActivationFollowFocus === 'boolean') {
      this._shouldActivationFollowFocus = config.shouldActivationFollowFocus;
    }
    if (config.horizontalOrientation) {
      this._horizontalOrientation = config.horizontalOrientation;
    }
    if (config.skipPredicate) {
      this._skipPredicateFn = config.skipPredicate;
    }
    if (config.trackBy) {
      this._trackByFn = config.trackBy;
    }
    if (typeof config.typeAheadDebounceInterval !== 'undefined') {
      this._setTypeAhead(config.typeAheadDebounceInterval);
    }
  }
  /** Cleans up the key manager. */
  destroy() {
    this._typeaheadSubscription.unsubscribe();
    this._typeahead?.destroy();
    this.change.complete();
  }
  /**
   * Handles a keyboard event on the tree.
   * @param event Keyboard event that represents the user interaction with the tree.
   */
  onKeydown(event) {
    const key = event.key;
    switch (key) {
      case 'Tab':
        // Return early here, in order to allow Tab to actually tab out of the tree
        return;
      case 'ArrowDown':
        this._focusNextItem();
        break;
      case 'ArrowUp':
        this._focusPreviousItem();
        break;
      case 'ArrowRight':
        this._horizontalOrientation === 'rtl' ? this._collapseCurrentItem() : this._expandCurrentItem();
        break;
      case 'ArrowLeft':
        this._horizontalOrientation === 'rtl' ? this._expandCurrentItem() : this._collapseCurrentItem();
        break;
      case 'Home':
        this._focusFirstItem();
        break;
      case 'End':
        this._focusLastItem();
        break;
      case 'Enter':
      case ' ':
        this._activateCurrentItem();
        break;
      default:
        if (event.key === '*') {
          this._expandAllItemsAtCurrentItemLevel();
          break;
        }
        this._typeahead?.handleKey(event);
        // Return here, in order to avoid preventing the default action of non-navigational
        // keys or resetting the buffer of pressed letters.
        return;
    }
    // Reset the typeahead since the user has used a navigational key.
    this._typeahead?.reset();
    event.preventDefault();
  }
  /** Index of the currently active item. */
  getActiveItemIndex() {
    return this._activeItemIndex;
  }
  /** The currently active item. */
  getActiveItem() {
    return this._activeItem;
  }
  /** Focus the first available item. */
  _focusFirstItem() {
    this.focusItem(this._findNextAvailableItemIndex(-1));
  }
  /** Focus the last available item. */
  _focusLastItem() {
    this.focusItem(this._findPreviousAvailableItemIndex(this._items.length));
  }
  /** Focus the next available item. */
  _focusNextItem() {
    this.focusItem(this._findNextAvailableItemIndex(this._activeItemIndex));
  }
  /** Focus the previous available item. */
  _focusPreviousItem() {
    this.focusItem(this._findPreviousAvailableItemIndex(this._activeItemIndex));
  }
  focusItem(itemOrIndex, options = {}) {
    // Set default options
    options.emitChangeEvent ??= true;
    let index = typeof itemOrIndex === 'number' ? itemOrIndex : this._items.findIndex(item => this._trackByFn(item) === this._trackByFn(itemOrIndex));
    if (index < 0 || index >= this._items.length) {
      return;
    }
    const activeItem = this._items[index];
    // If we're just setting the same item, don't re-call activate or focus
    if (this._activeItem !== null && this._trackByFn(activeItem) === this._trackByFn(this._activeItem)) {
      return;
    }
    const previousActiveItem = this._activeItem;
    this._activeItem = activeItem ?? null;
    this._activeItemIndex = index;
    this._typeahead?.setCurrentSelectedItemIndex(index);
    this._activeItem?.focus();
    previousActiveItem?.unfocus();
    if (options.emitChangeEvent) {
      this.change.next(this._activeItem);
    }
    if (this._shouldActivationFollowFocus) {
      this._activateCurrentItem();
    }
  }
  _updateActiveItemIndex(newItems) {
    const activeItem = this._activeItem;
    if (!activeItem) {
      return;
    }
    const newIndex = newItems.findIndex(item => this._trackByFn(item) === this._trackByFn(activeItem));
    if (newIndex > -1 && newIndex !== this._activeItemIndex) {
      this._activeItemIndex = newIndex;
      this._typeahead?.setCurrentSelectedItemIndex(newIndex);
    }
  }
  _setTypeAhead(debounceInterval) {
    this._typeahead = new Typeahead(this._items, {
      debounceInterval: typeof debounceInterval === 'number' ? debounceInterval : undefined,
      skipPredicate: item => this._skipPredicateFn(item)
    });
    this._typeaheadSubscription = this._typeahead.selectedItem.subscribe(item => {
      this.focusItem(item);
    });
  }
  _findNextAvailableItemIndex(startingIndex) {
    for (let i = startingIndex + 1; i < this._items.length; i++) {
      if (!this._skipPredicateFn(this._items[i])) {
        return i;
      }
    }
    return startingIndex;
  }
  _findPreviousAvailableItemIndex(startingIndex) {
    for (let i = startingIndex - 1; i >= 0; i--) {
      if (!this._skipPredicateFn(this._items[i])) {
        return i;
      }
    }
    return startingIndex;
  }
  /**
   * If the item is already expanded, we collapse the item. Otherwise, we will focus the parent.
   */
  _collapseCurrentItem() {
    if (!this._activeItem) {
      return;
    }
    if (this._isCurrentItemExpanded()) {
      this._activeItem.collapse();
    } else {
      const parent = this._activeItem.getParent();
      if (!parent || this._skipPredicateFn(parent)) {
        return;
      }
      this.focusItem(parent);
    }
  }
  /**
   * If the item is already collapsed, we expand the item. Otherwise, we will focus the first child.
   */
  _expandCurrentItem() {
    if (!this._activeItem) {
      return;
    }
    if (!this._isCurrentItemExpanded()) {
      this._activeItem.expand();
    } else {
      (0,_angular_cdk_coercion_private__WEBPACK_IMPORTED_MODULE_11__.coerceObservable)(this._activeItem.getChildren()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.take)(1)).subscribe(children => {
        const firstChild = children.find(child => !this._skipPredicateFn(child));
        if (!firstChild) {
          return;
        }
        this.focusItem(firstChild);
      });
    }
  }
  _isCurrentItemExpanded() {
    if (!this._activeItem) {
      return false;
    }
    return typeof this._activeItem.isExpanded === 'boolean' ? this._activeItem.isExpanded : this._activeItem.isExpanded();
  }
  _isItemDisabled(item) {
    return typeof item.isDisabled === 'boolean' ? item.isDisabled : item.isDisabled?.();
  }
  /** For all items that are the same level as the current item, we expand those items. */
  _expandAllItemsAtCurrentItemLevel() {
    if (!this._activeItem) {
      return;
    }
    const parent = this._activeItem.getParent();
    let itemsToExpand;
    if (!parent) {
      itemsToExpand = (0,rxjs__WEBPACK_IMPORTED_MODULE_13__.of)(this._items.filter(item => item.getParent() === null));
    } else {
      itemsToExpand = (0,_angular_cdk_coercion_private__WEBPACK_IMPORTED_MODULE_11__.coerceObservable)(parent.getChildren());
    }
    itemsToExpand.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.take)(1)).subscribe(items => {
      for (const item of items) {
        item.expand();
      }
    });
  }
  _activateCurrentItem() {
    this._activeItem?.activate();
  }
}
/** @docs-private */
function TREE_KEY_MANAGER_FACTORY() {
  return (items, options) => new TreeKeyManager(items, options);
}
/** Injection token that determines the key manager to use. */
const TREE_KEY_MANAGER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('tree-key-manager', {
  providedIn: 'root',
  factory: TREE_KEY_MANAGER_FACTORY
});
/** @docs-private */
const TREE_KEY_MANAGER_FACTORY_PROVIDER = {
  provide: TREE_KEY_MANAGER,
  useFactory: TREE_KEY_MANAGER_FACTORY
};

// NoopTreeKeyManager is a "noop" implementation of TreeKeyMangerStrategy. Methods are noops. Does
// not emit to streams.
//
// Used for applications built before TreeKeyManager to opt-out of TreeKeyManager and revert to
// legacy behavior.
/**
 * @docs-private
 *
 * Opt-out of Tree of key manager behavior.
 *
 * When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
 *  - Tree does not respond to keyboard interaction
 *  - Tree node allows tabindex to be set by Input binding
 *  - Tree node allows tabindex to be set by attribute binding
 *
 * @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
 * TreeKeyManagerStrategy instead. To be removed in a future version.
 *
 * @breaking-change 21.0.0
 */
class NoopTreeKeyManager {
  constructor() {
    this._isNoopTreeKeyManager = true;
    // Provide change as required by TreeKeyManagerStrategy. NoopTreeKeyManager is a "noop"
    // implementation that does not emit to streams.
    this.change = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
  }
  destroy() {
    this.change.complete();
  }
  onKeydown() {
    // noop
  }
  getActiveItemIndex() {
    // Always return null. NoopTreeKeyManager is a "noop" implementation that does not maintain
    // the active item.
    return null;
  }
  getActiveItem() {
    // Always return null. NoopTreeKeyManager is a "noop" implementation that does not maintain
    // the active item.
    return null;
  }
  focusItem() {
    // noop
  }
}
/**
 * @docs-private
 *
 * Opt-out of Tree of key manager behavior.
 *
 * When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
 *  - Tree does not respond to keyboard interaction
 *  - Tree node allows tabindex to be set by Input binding
 *  - Tree node allows tabindex to be set by attribute binding
 *
 * @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
 * TreeKeyManagerStrategy instead. To be removed in a future version.
 *
 * @breaking-change 21.0.0
 */
function NOOP_TREE_KEY_MANAGER_FACTORY() {
  return () => new NoopTreeKeyManager();
}
/**
 * @docs-private
 *
 * Opt-out of Tree of key manager behavior.
 *
 * When provided, Tree has same focus management behavior as before TreeKeyManager was introduced.
 *  - Tree does not respond to keyboard interaction
 *  - Tree node allows tabindex to be set by Input binding
 *  - Tree node allows tabindex to be set by attribute binding
 *
 * @deprecated NoopTreeKeyManager deprecated. Use TreeKeyManager or inject a
 * TreeKeyManagerStrategy instead. To be removed in a future version.
 *
 * @breaking-change 21.0.0
 */
const NOOP_TREE_KEY_MANAGER_FACTORY_PROVIDER = {
  provide: TREE_KEY_MANAGER,
  useFactory: NOOP_TREE_KEY_MANAGER_FACTORY
};

/**
 * Configuration for the isFocusable method.
 */
class IsFocusableConfig {
  constructor() {
    /**
     * Whether to count an element as focusable even if it is not currently visible.
     */
    this.ignoreVisibility = false;
  }
}
// The InteractivityChecker leans heavily on the ally.js accessibility utilities.
// Methods like `isTabbable` are only covering specific edge-cases for the browsers which are
// supported.
/**
 * Utility for checking the interactivity of an element, such as whether it is focusable or
 * tabbable.
 */
class InteractivityChecker {
  constructor(_platform) {
    this._platform = _platform;
  }
  /**
   * Gets whether an element is disabled.
   *
   * @param element Element to be checked.
   * @returns Whether the element is disabled.
   */
  isDisabled(element) {
    // This does not capture some cases, such as a non-form control with a disabled attribute or
    // a form control inside of a disabled form, but should capture the most common cases.
    return element.hasAttribute('disabled');
  }
  /**
   * Gets whether an element is visible for the purposes of interactivity.
   *
   * This will capture states like `display: none` and `visibility: hidden`, but not things like
   * being clipped by an `overflow: hidden` parent or being outside the viewport.
   *
   * @returns Whether the element is visible.
   */
  isVisible(element) {
    return hasGeometry(element) && getComputedStyle(element).visibility === 'visible';
  }
  /**
   * Gets whether an element can be reached via Tab key.
   * Assumes that the element has already been checked with isFocusable.
   *
   * @param element Element to be checked.
   * @returns Whether the element is tabbable.
   */
  isTabbable(element) {
    // Nothing is tabbable on the server 😎
    if (!this._platform.isBrowser) {
      return false;
    }
    const frameElement = getFrameElement(getWindow(element));
    if (frameElement) {
      // Frame elements inherit their tabindex onto all child elements.
      if (getTabIndexValue(frameElement) === -1) {
        return false;
      }
      // Browsers disable tabbing to an element inside of an invisible frame.
      if (!this.isVisible(frameElement)) {
        return false;
      }
    }
    let nodeName = element.nodeName.toLowerCase();
    let tabIndexValue = getTabIndexValue(element);
    if (element.hasAttribute('contenteditable')) {
      return tabIndexValue !== -1;
    }
    if (nodeName === 'iframe' || nodeName === 'object') {
      // The frame or object's content may be tabbable depending on the content, but it's
      // not possibly to reliably detect the content of the frames. We always consider such
      // elements as non-tabbable.
      return false;
    }
    // In iOS, the browser only considers some specific elements as tabbable.
    if (this._platform.WEBKIT && this._platform.IOS && !isPotentiallyTabbableIOS(element)) {
      return false;
    }
    if (nodeName === 'audio') {
      // Audio elements without controls enabled are never tabbable, regardless
      // of the tabindex attribute explicitly being set.
      if (!element.hasAttribute('controls')) {
        return false;
      }
      // Audio elements with controls are by default tabbable unless the
      // tabindex attribute is set to `-1` explicitly.
      return tabIndexValue !== -1;
    }
    if (nodeName === 'video') {
      // For all video elements, if the tabindex attribute is set to `-1`, the video
      // is not tabbable. Note: We cannot rely on the default `HTMLElement.tabIndex`
      // property as that one is set to `-1` in Chrome, Edge and Safari v13.1. The
      // tabindex attribute is the source of truth here.
      if (tabIndexValue === -1) {
        return false;
      }
      // If the tabindex is explicitly set, and not `-1` (as per check before), the
      // video element is always tabbable (regardless of whether it has controls or not).
      if (tabIndexValue !== null) {
        return true;
      }
      // Otherwise (when no explicit tabindex is set), a video is only tabbable if it
      // has controls enabled. Firefox is special as videos are always tabbable regardless
      // of whether there are controls or not.
      return this._platform.FIREFOX || element.hasAttribute('controls');
    }
    return element.tabIndex >= 0;
  }
  /**
   * Gets whether an element can be focused by the user.
   *
   * @param element Element to be checked.
   * @param config The config object with options to customize this method's behavior
   * @returns Whether the element is focusable.
   */
  isFocusable(element, config) {
    // Perform checks in order of left to most expensive.
    // Again, naive approach that does not capture many edge cases and browser quirks.
    return isPotentiallyFocusable(element) && !this.isDisabled(element) && (config?.ignoreVisibility || this.isVisible(element));
  }
  static {
    this.ɵfac = function InteractivityChecker_Factory(t) {
      return new (t || InteractivityChecker)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: InteractivityChecker,
      factory: InteractivityChecker.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InteractivityChecker, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform
  }], null);
})();
/**
 * Returns the frame element from a window object. Since browsers like MS Edge throw errors if
 * the frameElement property is being accessed from a different host address, this property
 * should be accessed carefully.
 */
function getFrameElement(window) {
  try {
    return window.frameElement;
  } catch {
    return null;
  }
}
/** Checks whether the specified element has any geometry / rectangles. */
function hasGeometry(element) {
  // Use logic from jQuery to check for an invisible element.
  // See https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js#L12
  return !!(element.offsetWidth || element.offsetHeight || typeof element.getClientRects === 'function' && element.getClientRects().length);
}
/** Gets whether an element's  */
function isNativeFormElement(element) {
  let nodeName = element.nodeName.toLowerCase();
  return nodeName === 'input' || nodeName === 'select' || nodeName === 'button' || nodeName === 'textarea';
}
/** Gets whether an element is an `<input type="hidden">`. */
function isHiddenInput(element) {
  return isInputElement(element) && element.type == 'hidden';
}
/** Gets whether an element is an anchor that has an href attribute. */
function isAnchorWithHref(element) {
  return isAnchorElement(element) && element.hasAttribute('href');
}
/** Gets whether an element is an input element. */
function isInputElement(element) {
  return element.nodeName.toLowerCase() == 'input';
}
/** Gets whether an element is an anchor element. */
function isAnchorElement(element) {
  return element.nodeName.toLowerCase() == 'a';
}
/** Gets whether an element has a valid tabindex. */
function hasValidTabIndex(element) {
  if (!element.hasAttribute('tabindex') || element.tabIndex === undefined) {
    return false;
  }
  let tabIndex = element.getAttribute('tabindex');
  return !!(tabIndex && !isNaN(parseInt(tabIndex, 10)));
}
/**
 * Returns the parsed tabindex from the element attributes instead of returning the
 * evaluated tabindex from the browsers defaults.
 */
function getTabIndexValue(element) {
  if (!hasValidTabIndex(element)) {
    return null;
  }
  // See browser issue in Gecko https://bugzilla.mozilla.org/show_bug.cgi?id=1128054
  const tabIndex = parseInt(element.getAttribute('tabindex') || '', 10);
  return isNaN(tabIndex) ? -1 : tabIndex;
}
/** Checks whether the specified element is potentially tabbable on iOS */
function isPotentiallyTabbableIOS(element) {
  let nodeName = element.nodeName.toLowerCase();
  let inputType = nodeName === 'input' && element.type;
  return inputType === 'text' || inputType === 'password' || nodeName === 'select' || nodeName === 'textarea';
}
/**
 * Gets whether an element is potentially focusable without taking current visible/disabled state
 * into account.
 */
function isPotentiallyFocusable(element) {
  // Inputs are potentially focusable *unless* they're type="hidden".
  if (isHiddenInput(element)) {
    return false;
  }
  return isNativeFormElement(element) || isAnchorWithHref(element) || element.hasAttribute('contenteditable') || hasValidTabIndex(element);
}
/** Gets the parent window of a DOM node with regards of being inside of an iframe. */
function getWindow(node) {
  // ownerDocument is null if `node` itself *is* a document.
  return node.ownerDocument && node.ownerDocument.defaultView || window;
}

/**
 * Class that allows for trapping focus within a DOM element.
 *
 * This class currently uses a relatively simple approach to focus trapping.
 * It assumes that the tab order is the same as DOM order, which is not necessarily true.
 * Things like `tabIndex > 0`, flex `order`, and shadow roots can cause the two to be misaligned.
 */
class FocusTrap {
  /** Whether the focus trap is active. */
  get enabled() {
    return this._enabled;
  }
  set enabled(value) {
    this._enabled = value;
    if (this._startAnchor && this._endAnchor) {
      this._toggleAnchorTabIndex(value, this._startAnchor);
      this._toggleAnchorTabIndex(value, this._endAnchor);
    }
  }
  constructor(_element, _checker, _ngZone, _document, deferAnchors = false, /** @breaking-change 20.0.0 param to become required */
  _injector) {
    this._element = _element;
    this._checker = _checker;
    this._ngZone = _ngZone;
    this._document = _document;
    this._injector = _injector;
    this._hasAttached = false;
    // Event listeners for the anchors. Need to be regular functions so that we can unbind them later.
    this.startAnchorListener = () => this.focusLastTabbableElement();
    this.endAnchorListener = () => this.focusFirstTabbableElement();
    this._enabled = true;
    if (!deferAnchors) {
      this.attachAnchors();
    }
  }
  /** Destroys the focus trap by cleaning up the anchors. */
  destroy() {
    const startAnchor = this._startAnchor;
    const endAnchor = this._endAnchor;
    if (startAnchor) {
      startAnchor.removeEventListener('focus', this.startAnchorListener);
      startAnchor.remove();
    }
    if (endAnchor) {
      endAnchor.removeEventListener('focus', this.endAnchorListener);
      endAnchor.remove();
    }
    this._startAnchor = this._endAnchor = null;
    this._hasAttached = false;
  }
  /**
   * Inserts the anchors into the DOM. This is usually done automatically
   * in the constructor, but can be deferred for cases like directives with `*ngIf`.
   * @returns Whether the focus trap managed to attach successfully. This may not be the case
   * if the target element isn't currently in the DOM.
   */
  attachAnchors() {
    // If we're not on the browser, there can be no focus to trap.
    if (this._hasAttached) {
      return true;
    }
    this._ngZone.runOutsideAngular(() => {
      if (!this._startAnchor) {
        this._startAnchor = this._createAnchor();
        this._startAnchor.addEventListener('focus', this.startAnchorListener);
      }
      if (!this._endAnchor) {
        this._endAnchor = this._createAnchor();
        this._endAnchor.addEventListener('focus', this.endAnchorListener);
      }
    });
    if (this._element.parentNode) {
      this._element.parentNode.insertBefore(this._startAnchor, this._element);
      this._element.parentNode.insertBefore(this._endAnchor, this._element.nextSibling);
      this._hasAttached = true;
    }
    return this._hasAttached;
  }
  /**
   * Waits for the zone to stabilize, then focuses the first tabbable element.
   * @returns Returns a promise that resolves with a boolean, depending
   * on whether focus was moved successfully.
   */
  focusInitialElementWhenReady(options) {
    return new Promise(resolve => {
      this._executeOnStable(() => resolve(this.focusInitialElement(options)));
    });
  }
  /**
   * Waits for the zone to stabilize, then focuses
   * the first tabbable element within the focus trap region.
   * @returns Returns a promise that resolves with a boolean, depending
   * on whether focus was moved successfully.
   */
  focusFirstTabbableElementWhenReady(options) {
    return new Promise(resolve => {
      this._executeOnStable(() => resolve(this.focusFirstTabbableElement(options)));
    });
  }
  /**
   * Waits for the zone to stabilize, then focuses
   * the last tabbable element within the focus trap region.
   * @returns Returns a promise that resolves with a boolean, depending
   * on whether focus was moved successfully.
   */
  focusLastTabbableElementWhenReady(options) {
    return new Promise(resolve => {
      this._executeOnStable(() => resolve(this.focusLastTabbableElement(options)));
    });
  }
  /**
   * Get the specified boundary element of the trapped region.
   * @param bound The boundary to get (start or end of trapped region).
   * @returns The boundary element.
   */
  _getRegionBoundary(bound) {
    // Contains the deprecated version of selector, for temporary backwards comparability.
    const markers = this._element.querySelectorAll(`[cdk-focus-region-${bound}], ` + `[cdkFocusRegion${bound}], ` + `[cdk-focus-${bound}]`);
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      for (let i = 0; i < markers.length; i++) {
        // @breaking-change 8.0.0
        if (markers[i].hasAttribute(`cdk-focus-${bound}`)) {
          console.warn(`Found use of deprecated attribute 'cdk-focus-${bound}', ` + `use 'cdkFocusRegion${bound}' instead. The deprecated ` + `attribute will be removed in 8.0.0.`, markers[i]);
        } else if (markers[i].hasAttribute(`cdk-focus-region-${bound}`)) {
          console.warn(`Found use of deprecated attribute 'cdk-focus-region-${bound}', ` + `use 'cdkFocusRegion${bound}' instead. The deprecated attribute ` + `will be removed in 8.0.0.`, markers[i]);
        }
      }
    }
    if (bound == 'start') {
      return markers.length ? markers[0] : this._getFirstTabbableElement(this._element);
    }
    return markers.length ? markers[markers.length - 1] : this._getLastTabbableElement(this._element);
  }
  /**
   * Focuses the element that should be focused when the focus trap is initialized.
   * @returns Whether focus was moved successfully.
   */
  focusInitialElement(options) {
    // Contains the deprecated version of selector, for temporary backwards comparability.
    const redirectToElement = this._element.querySelector(`[cdk-focus-initial], ` + `[cdkFocusInitial]`);
    if (redirectToElement) {
      // @breaking-change 8.0.0
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && redirectToElement.hasAttribute(`cdk-focus-initial`)) {
        console.warn(`Found use of deprecated attribute 'cdk-focus-initial', ` + `use 'cdkFocusInitial' instead. The deprecated attribute ` + `will be removed in 8.0.0`, redirectToElement);
      }
      // Warn the consumer if the element they've pointed to
      // isn't focusable, when not in production mode.
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && !this._checker.isFocusable(redirectToElement)) {
        console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement);
      }
      if (!this._checker.isFocusable(redirectToElement)) {
        const focusableChild = this._getFirstTabbableElement(redirectToElement);
        focusableChild?.focus(options);
        return !!focusableChild;
      }
      redirectToElement.focus(options);
      return true;
    }
    return this.focusFirstTabbableElement(options);
  }
  /**
   * Focuses the first tabbable element within the focus trap region.
   * @returns Whether focus was moved successfully.
   */
  focusFirstTabbableElement(options) {
    const redirectToElement = this._getRegionBoundary('start');
    if (redirectToElement) {
      redirectToElement.focus(options);
    }
    return !!redirectToElement;
  }
  /**
   * Focuses the last tabbable element within the focus trap region.
   * @returns Whether focus was moved successfully.
   */
  focusLastTabbableElement(options) {
    const redirectToElement = this._getRegionBoundary('end');
    if (redirectToElement) {
      redirectToElement.focus(options);
    }
    return !!redirectToElement;
  }
  /**
   * Checks whether the focus trap has successfully been attached.
   */
  hasAttached() {
    return this._hasAttached;
  }
  /** Get the first tabbable element from a DOM subtree (inclusive). */
  _getFirstTabbableElement(root) {
    if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
      return root;
    }
    const children = root.children;
    for (let i = 0; i < children.length; i++) {
      const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ? this._getFirstTabbableElement(children[i]) : null;
      if (tabbableChild) {
        return tabbableChild;
      }
    }
    return null;
  }
  /** Get the last tabbable element from a DOM subtree (inclusive). */
  _getLastTabbableElement(root) {
    if (this._checker.isFocusable(root) && this._checker.isTabbable(root)) {
      return root;
    }
    // Iterate in reverse DOM order.
    const children = root.children;
    for (let i = children.length - 1; i >= 0; i--) {
      const tabbableChild = children[i].nodeType === this._document.ELEMENT_NODE ? this._getLastTabbableElement(children[i]) : null;
      if (tabbableChild) {
        return tabbableChild;
      }
    }
    return null;
  }
  /** Creates an anchor element. */
  _createAnchor() {
    const anchor = this._document.createElement('div');
    this._toggleAnchorTabIndex(this._enabled, anchor);
    anchor.classList.add('cdk-visually-hidden');
    anchor.classList.add('cdk-focus-trap-anchor');
    anchor.setAttribute('aria-hidden', 'true');
    return anchor;
  }
  /**
   * Toggles the `tabindex` of an anchor, based on the enabled state of the focus trap.
   * @param isEnabled Whether the focus trap is enabled.
   * @param anchor Anchor on which to toggle the tabindex.
   */
  _toggleAnchorTabIndex(isEnabled, anchor) {
    // Remove the tabindex completely, rather than setting it to -1, because if the
    // element has a tabindex, the user might still hit it when navigating with the arrow keys.
    isEnabled ? anchor.setAttribute('tabindex', '0') : anchor.removeAttribute('tabindex');
  }
  /**
   * Toggles the`tabindex` of both anchors to either trap Tab focus or allow it to escape.
   * @param enabled: Whether the anchors should trap Tab.
   */
  toggleAnchors(enabled) {
    if (this._startAnchor && this._endAnchor) {
      this._toggleAnchorTabIndex(enabled, this._startAnchor);
      this._toggleAnchorTabIndex(enabled, this._endAnchor);
    }
  }
  /** Executes a function when the zone is stable. */
  _executeOnStable(fn) {
    // TODO: remove this conditional when injector is required in the constructor.
    if (this._injector) {
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.afterNextRender)(fn, {
        injector: this._injector
      });
    } else {
      setTimeout(fn);
    }
  }
}
/**
 * Factory that allows easy instantiation of focus traps.
 */
class FocusTrapFactory {
  constructor(_checker, _ngZone, _document) {
    this._checker = _checker;
    this._ngZone = _ngZone;
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._document = _document;
  }
  /**
   * Creates a focus-trapped region around the given element.
   * @param element The element around which focus will be trapped.
   * @param deferCaptureElements Defers the creation of focus-capturing elements to be done
   *     manually by the user.
   * @returns The created focus trap instance.
   */
  create(element, deferCaptureElements = false) {
    return new FocusTrap(element, this._checker, this._ngZone, this._document, deferCaptureElements, this._injector);
  }
  static {
    this.ɵfac = function FocusTrapFactory_Factory(t) {
      return new (t || FocusTrapFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](InteractivityChecker), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: FocusTrapFactory,
      factory: FocusTrapFactory.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FocusTrapFactory, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: InteractivityChecker
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }], null);
})();
/** Directive for trapping focus within a region. */
class CdkTrapFocus {
  /** Whether the focus trap is active. */
  get enabled() {
    return this.focusTrap?.enabled || false;
  }
  set enabled(value) {
    if (this.focusTrap) {
      this.focusTrap.enabled = value;
    }
  }
  constructor(_elementRef, _focusTrapFactory,
  /**
   * @deprecated No longer being used. To be removed.
   * @breaking-change 13.0.0
   */
  _document) {
    this._elementRef = _elementRef;
    this._focusTrapFactory = _focusTrapFactory;
    /** Previously focused element to restore focus to upon destroy when using autoCapture. */
    this._previouslyFocusedElement = null;
    const platform = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform);
    if (platform.isBrowser) {
      this.focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement, true);
    }
  }
  ngOnDestroy() {
    this.focusTrap?.destroy();
    // If we stored a previously focused element when using autoCapture, return focus to that
    // element now that the trapped region is being destroyed.
    if (this._previouslyFocusedElement) {
      this._previouslyFocusedElement.focus();
      this._previouslyFocusedElement = null;
    }
  }
  ngAfterContentInit() {
    this.focusTrap?.attachAnchors();
    if (this.autoCapture) {
      this._captureFocus();
    }
  }
  ngDoCheck() {
    if (this.focusTrap && !this.focusTrap.hasAttached()) {
      this.focusTrap.attachAnchors();
    }
  }
  ngOnChanges(changes) {
    const autoCaptureChange = changes['autoCapture'];
    if (autoCaptureChange && !autoCaptureChange.firstChange && this.autoCapture && this.focusTrap?.hasAttached()) {
      this._captureFocus();
    }
  }
  _captureFocus() {
    this._previouslyFocusedElement = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getFocusedElementPierceShadowDom)();
    this.focusTrap?.focusInitialElementWhenReady();
  }
  static {
    this.ɵfac = function CdkTrapFocus_Factory(t) {
      return new (t || CdkTrapFocus)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](FocusTrapFactory), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkTrapFocus,
      selectors: [["", "cdkTrapFocus", ""]],
      inputs: {
        enabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkTrapFocus", "enabled", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute],
        autoCapture: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkTrapFocusAutoCapture", "autoCapture", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      exportAs: ["cdkTrapFocus"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkTrapFocus, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkTrapFocus]',
      exportAs: 'cdkTrapFocus',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: FocusTrapFactory
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }], {
    enabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        alias: 'cdkTrapFocus',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    autoCapture: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        alias: 'cdkTrapFocusAutoCapture',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }]
  });
})();

/**
 * Class that allows for trapping focus within a DOM element.
 *
 * This class uses a strategy pattern that determines how it traps focus.
 * See FocusTrapInertStrategy.
 */
class ConfigurableFocusTrap extends FocusTrap {
  /** Whether the FocusTrap is enabled. */
  get enabled() {
    return this._enabled;
  }
  set enabled(value) {
    this._enabled = value;
    if (this._enabled) {
      this._focusTrapManager.register(this);
    } else {
      this._focusTrapManager.deregister(this);
    }
  }
  constructor(_element, _checker, _ngZone, _document, _focusTrapManager, _inertStrategy, config, injector) {
    super(_element, _checker, _ngZone, _document, config.defer, injector);
    this._focusTrapManager = _focusTrapManager;
    this._inertStrategy = _inertStrategy;
    this._focusTrapManager.register(this);
  }
  /** Notifies the FocusTrapManager that this FocusTrap will be destroyed. */
  destroy() {
    this._focusTrapManager.deregister(this);
    super.destroy();
  }
  /** @docs-private Implemented as part of ManagedFocusTrap. */
  _enable() {
    this._inertStrategy.preventFocus(this);
    this.toggleAnchors(true);
  }
  /** @docs-private Implemented as part of ManagedFocusTrap. */
  _disable() {
    this._inertStrategy.allowFocus(this);
    this.toggleAnchors(false);
  }
}

/**
 * Lightweight FocusTrapInertStrategy that adds a document focus event
 * listener to redirect focus back inside the FocusTrap.
 */
class EventListenerFocusTrapInertStrategy {
  constructor() {
    /** Focus event handler. */
    this._listener = null;
  }
  /** Adds a document event listener that keeps focus inside the FocusTrap. */
  preventFocus(focusTrap) {
    // Ensure there's only one listener per document
    if (this._listener) {
      focusTrap._document.removeEventListener('focus', this._listener, true);
    }
    this._listener = e => this._trapFocus(focusTrap, e);
    focusTrap._ngZone.runOutsideAngular(() => {
      focusTrap._document.addEventListener('focus', this._listener, true);
    });
  }
  /** Removes the event listener added in preventFocus. */
  allowFocus(focusTrap) {
    if (!this._listener) {
      return;
    }
    focusTrap._document.removeEventListener('focus', this._listener, true);
    this._listener = null;
  }
  /**
   * Refocuses the first element in the FocusTrap if the focus event target was outside
   * the FocusTrap.
   *
   * This is an event listener callback. The event listener is added in runOutsideAngular,
   * so all this code runs outside Angular as well.
   */
  _trapFocus(focusTrap, event) {
    const target = event.target;
    const focusTrapRoot = focusTrap._element;
    // Don't refocus if target was in an overlay, because the overlay might be associated
    // with an element inside the FocusTrap, ex. mat-select.
    if (target && !focusTrapRoot.contains(target) && !target.closest?.('div.cdk-overlay-pane')) {
      // Some legacy FocusTrap usages have logic that focuses some element on the page
      // just before FocusTrap is destroyed. For backwards compatibility, wait
      // to be sure FocusTrap is still enabled before refocusing.
      setTimeout(() => {
        // Check whether focus wasn't put back into the focus trap while the timeout was pending.
        if (focusTrap.enabled && !focusTrapRoot.contains(focusTrap._document.activeElement)) {
          focusTrap.focusFirstTabbableElement();
        }
      });
    }
  }
}

/** The injection token used to specify the inert strategy. */
const FOCUS_TRAP_INERT_STRATEGY = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('FOCUS_TRAP_INERT_STRATEGY');

/** Injectable that ensures only the most recently enabled FocusTrap is active. */
class FocusTrapManager {
  constructor() {
    // A stack of the FocusTraps on the page. Only the FocusTrap at the
    // top of the stack is active.
    this._focusTrapStack = [];
  }
  /**
   * Disables the FocusTrap at the top of the stack, and then pushes
   * the new FocusTrap onto the stack.
   */
  register(focusTrap) {
    // Dedupe focusTraps that register multiple times.
    this._focusTrapStack = this._focusTrapStack.filter(ft => ft !== focusTrap);
    let stack = this._focusTrapStack;
    if (stack.length) {
      stack[stack.length - 1]._disable();
    }
    stack.push(focusTrap);
    focusTrap._enable();
  }
  /**
   * Removes the FocusTrap from the stack, and activates the
   * FocusTrap that is the new top of the stack.
   */
  deregister(focusTrap) {
    focusTrap._disable();
    const stack = this._focusTrapStack;
    const i = stack.indexOf(focusTrap);
    if (i !== -1) {
      stack.splice(i, 1);
      if (stack.length) {
        stack[stack.length - 1]._enable();
      }
    }
  }
  static {
    this.ɵfac = function FocusTrapManager_Factory(t) {
      return new (t || FocusTrapManager)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: FocusTrapManager,
      factory: FocusTrapManager.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FocusTrapManager, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/** Factory that allows easy instantiation of configurable focus traps. */
class ConfigurableFocusTrapFactory {
  constructor(_checker, _ngZone, _focusTrapManager, _document, _inertStrategy) {
    this._checker = _checker;
    this._ngZone = _ngZone;
    this._focusTrapManager = _focusTrapManager;
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._document = _document;
    // TODO split up the strategies into different modules, similar to DateAdapter.
    this._inertStrategy = _inertStrategy || new EventListenerFocusTrapInertStrategy();
  }
  create(element, config = {
    defer: false
  }) {
    let configObject;
    if (typeof config === 'boolean') {
      configObject = {
        defer: config
      };
    } else {
      configObject = config;
    }
    return new ConfigurableFocusTrap(element, this._checker, this._ngZone, this._document, this._focusTrapManager, this._inertStrategy, configObject, this._injector);
  }
  static {
    this.ɵfac = function ConfigurableFocusTrapFactory_Factory(t) {
      return new (t || ConfigurableFocusTrapFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](InteractivityChecker), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](FocusTrapManager), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](FOCUS_TRAP_INERT_STRATEGY, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ConfigurableFocusTrapFactory,
      factory: ConfigurableFocusTrapFactory.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ConfigurableFocusTrapFactory, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: InteractivityChecker
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: FocusTrapManager
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [FOCUS_TRAP_INERT_STRATEGY]
    }]
  }], null);
})();

/** Gets whether an event could be a faked `mousedown` event dispatched by a screen reader. */
function isFakeMousedownFromScreenReader(event) {
  // Some screen readers will dispatch a fake `mousedown` event when pressing enter or space on
  // a clickable element. We can distinguish these events when `event.buttons` is zero, or
  // `event.detail` is zero depending on the browser:
  // - `event.buttons` works on Firefox, but fails on Chrome.
  // - `detail` works on Chrome, but fails on Firefox.
  return event.buttons === 0 || event.detail === 0;
}
/** Gets whether an event could be a faked `touchstart` event dispatched by a screen reader. */
function isFakeTouchstartFromScreenReader(event) {
  const touch = event.touches && event.touches[0] || event.changedTouches && event.changedTouches[0];
  // A fake `touchstart` can be distinguished from a real one by looking at the `identifier`
  // which is typically >= 0 on a real device versus -1 from a screen reader. Just to be safe,
  // we can also look at `radiusX` and `radiusY`. This behavior was observed against a Windows 10
  // device with a touch screen running NVDA v2020.4 and Firefox 85 or Chrome 88.
  return !!touch && touch.identifier === -1 && (touch.radiusX == null || touch.radiusX === 1) && (touch.radiusY == null || touch.radiusY === 1);
}

/**
 * Injectable options for the InputModalityDetector. These are shallowly merged with the default
 * options.
 */
const INPUT_MODALITY_DETECTOR_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('cdk-input-modality-detector-options');
/**
 * Default options for the InputModalityDetector.
 *
 * Modifier keys are ignored by default (i.e. when pressed won't cause the service to detect
 * keyboard input modality) for two reasons:
 *
 * 1. Modifier keys are commonly used with mouse to perform actions such as 'right click' or 'open
 *    in new tab', and are thus less representative of actual keyboard interaction.
 * 2. VoiceOver triggers some keyboard events when linearly navigating with Control + Option (but
 *    confusingly not with Caps Lock). Thus, to have parity with other screen readers, we ignore
 *    these keys so as to not update the input modality.
 *
 * Note that we do not by default ignore the right Meta key on Safari because it has the same key
 * code as the ContextMenu key on other browsers. When we switch to using event.key, we can
 * distinguish between the two.
 */
const INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS = {
  ignoreKeys: [_angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.ALT, _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.CONTROL, _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.MAC_META, _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.META, _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_4__.SHIFT]
};
/**
 * The amount of time needed to pass after a touchstart event in order for a subsequent mousedown
 * event to be attributed as mouse and not touch.
 *
 * This is the value used by AngularJS Material. Through trial and error (on iPhone 6S) they found
 * that a value of around 650ms seems appropriate.
 */
const TOUCH_BUFFER_MS = 650;
/**
 * Event listener options that enable capturing and also mark the listener as passive if the browser
 * supports it.
 */
const modalityEventListenerOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.normalizePassiveListenerOptions)({
  passive: true,
  capture: true
});
/**
 * Service that detects the user's input modality.
 *
 * This service does not update the input modality when a user navigates with a screen reader
 * (e.g. linear navigation with VoiceOver, object navigation / browse mode with NVDA, virtual PC
 * cursor mode with JAWS). This is in part due to technical limitations (i.e. keyboard events do not
 * fire as expected in these modes) but is also arguably the correct behavior. Navigating with a
 * screen reader is akin to visually scanning a page, and should not be interpreted as actual user
 * input interaction.
 *
 * When a user is not navigating but *interacting* with a screen reader, this service attempts to
 * update the input modality to keyboard, but in general this service's behavior is largely
 * undefined.
 */
class InputModalityDetector {
  /** The most recently detected input modality. */
  get mostRecentModality() {
    return this._modality.value;
  }
  constructor(_platform, ngZone, document, options) {
    this._platform = _platform;
    /**
     * The most recently detected input modality event target. Is null if no input modality has been
     * detected or if the associated event target is null for some unknown reason.
     */
    this._mostRecentTarget = null;
    /** The underlying BehaviorSubject that emits whenever an input modality is detected. */
    this._modality = new rxjs__WEBPACK_IMPORTED_MODULE_14__.BehaviorSubject(null);
    /**
     * The timestamp of the last touch input modality. Used to determine whether mousedown events
     * should be attributed to mouse or touch.
     */
    this._lastTouchMs = 0;
    /**
     * Handles keydown events. Must be an arrow function in order to preserve the context when it gets
     * bound.
     */
    this._onKeydown = event => {
      // If this is one of the keys we should ignore, then ignore it and don't update the input
      // modality to keyboard.
      if (this._options?.ignoreKeys?.some(keyCode => keyCode === event.keyCode)) {
        return;
      }
      this._modality.next('keyboard');
      this._mostRecentTarget = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getEventTarget)(event);
    };
    /**
     * Handles mousedown events. Must be an arrow function in order to preserve the context when it
     * gets bound.
     */
    this._onMousedown = event => {
      // Touches trigger both touch and mouse events, so we need to distinguish between mouse events
      // that were triggered via mouse vs touch. To do so, check if the mouse event occurs closely
      // after the previous touch event.
      if (Date.now() - this._lastTouchMs < TOUCH_BUFFER_MS) {
        return;
      }
      // Fake mousedown events are fired by some screen readers when controls are activated by the
      // screen reader. Attribute them to keyboard input modality.
      this._modality.next(isFakeMousedownFromScreenReader(event) ? 'keyboard' : 'mouse');
      this._mostRecentTarget = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getEventTarget)(event);
    };
    /**
     * Handles touchstart events. Must be an arrow function in order to preserve the context when it
     * gets bound.
     */
    this._onTouchstart = event => {
      // Same scenario as mentioned in _onMousedown, but on touch screen devices, fake touchstart
      // events are fired. Again, attribute to keyboard input modality.
      if (isFakeTouchstartFromScreenReader(event)) {
        this._modality.next('keyboard');
        return;
      }
      // Store the timestamp of this touch event, as it's used to distinguish between mouse events
      // triggered via mouse vs touch.
      this._lastTouchMs = Date.now();
      this._modality.next('touch');
      this._mostRecentTarget = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getEventTarget)(event);
    };
    this._options = {
      ...INPUT_MODALITY_DETECTOR_DEFAULT_OPTIONS,
      ...options
    };
    // Skip the first emission as it's null.
    this.modalityDetected = this._modality.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.skip)(1));
    this.modalityChanged = this.modalityDetected.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.distinctUntilChanged)());
    // If we're not in a browser, this service should do nothing, as there's no relevant input
    // modality to detect.
    if (_platform.isBrowser) {
      ngZone.runOutsideAngular(() => {
        document.addEventListener('keydown', this._onKeydown, modalityEventListenerOptions);
        document.addEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);
        document.addEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
      });
    }
  }
  ngOnDestroy() {
    this._modality.complete();
    if (this._platform.isBrowser) {
      document.removeEventListener('keydown', this._onKeydown, modalityEventListenerOptions);
      document.removeEventListener('mousedown', this._onMousedown, modalityEventListenerOptions);
      document.removeEventListener('touchstart', this._onTouchstart, modalityEventListenerOptions);
    }
  }
  static {
    this.ɵfac = function InputModalityDetector_Factory(t) {
      return new (t || InputModalityDetector)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](INPUT_MODALITY_DETECTOR_OPTIONS, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: InputModalityDetector,
      factory: InputModalityDetector.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InputModalityDetector, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [INPUT_MODALITY_DETECTOR_OPTIONS]
    }]
  }], null);
})();
const LIVE_ANNOUNCER_ELEMENT_TOKEN = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('liveAnnouncerElement', {
  providedIn: 'root',
  factory: LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY
});
/** @docs-private */
function LIVE_ANNOUNCER_ELEMENT_TOKEN_FACTORY() {
  return null;
}
/** Injection token that can be used to configure the default options for the LiveAnnouncer. */
const LIVE_ANNOUNCER_DEFAULT_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('LIVE_ANNOUNCER_DEFAULT_OPTIONS');
let uniqueIds = 0;
class LiveAnnouncer {
  constructor(elementToken, _ngZone, _document, _defaultOptions) {
    this._ngZone = _ngZone;
    this._defaultOptions = _defaultOptions;
    // We inject the live element and document as `any` because the constructor signature cannot
    // reference browser globals (HTMLElement, Document) on non-browser environments, since having
    // a class decorator causes TypeScript to preserve the constructor signature types.
    this._document = _document;
    this._liveElement = elementToken || this._createLiveElement();
  }
  announce(message, ...args) {
    const defaultOptions = this._defaultOptions;
    let politeness;
    let duration;
    if (args.length === 1 && typeof args[0] === 'number') {
      duration = args[0];
    } else {
      [politeness, duration] = args;
    }
    this.clear();
    clearTimeout(this._previousTimeout);
    if (!politeness) {
      politeness = defaultOptions && defaultOptions.politeness ? defaultOptions.politeness : 'polite';
    }
    if (duration == null && defaultOptions) {
      duration = defaultOptions.duration;
    }
    // TODO: ensure changing the politeness works on all environments we support.
    this._liveElement.setAttribute('aria-live', politeness);
    if (this._liveElement.id) {
      this._exposeAnnouncerToModals(this._liveElement.id);
    }
    // This 100ms timeout is necessary for some browser + screen-reader combinations:
    // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.
    // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a
    //   second time without clearing and then using a non-zero delay.
    // (using JAWS 17 at time of this writing).
    return this._ngZone.runOutsideAngular(() => {
      if (!this._currentPromise) {
        this._currentPromise = new Promise(resolve => this._currentResolve = resolve);
      }
      clearTimeout(this._previousTimeout);
      this._previousTimeout = setTimeout(() => {
        this._liveElement.textContent = message;
        if (typeof duration === 'number') {
          this._previousTimeout = setTimeout(() => this.clear(), duration);
        }
        // For some reason in tests this can be undefined
        // Probably related to ZoneJS and every other thing that patches browser APIs in tests
        this._currentResolve?.();
        this._currentPromise = this._currentResolve = undefined;
      }, 100);
      return this._currentPromise;
    });
  }
  /**
   * Clears the current text from the announcer element. Can be used to prevent
   * screen readers from reading the text out again while the user is going
   * through the page landmarks.
   */
  clear() {
    if (this._liveElement) {
      this._liveElement.textContent = '';
    }
  }
  ngOnDestroy() {
    clearTimeout(this._previousTimeout);
    this._liveElement?.remove();
    this._liveElement = null;
    this._currentResolve?.();
    this._currentPromise = this._currentResolve = undefined;
  }
  _createLiveElement() {
    const elementClass = 'cdk-live-announcer-element';
    const previousElements = this._document.getElementsByClassName(elementClass);
    const liveEl = this._document.createElement('div');
    // Remove any old containers. This can happen when coming in from a server-side-rendered page.
    for (let i = 0; i < previousElements.length; i++) {
      previousElements[i].remove();
    }
    liveEl.classList.add(elementClass);
    liveEl.classList.add('cdk-visually-hidden');
    liveEl.setAttribute('aria-atomic', 'true');
    liveEl.setAttribute('aria-live', 'polite');
    liveEl.id = `cdk-live-announcer-${uniqueIds++}`;
    this._document.body.appendChild(liveEl);
    return liveEl;
  }
  /**
   * Some browsers won't expose the accessibility node of the live announcer element if there is an
   * `aria-modal` and the live announcer is outside of it. This method works around the issue by
   * pointing the `aria-owns` of all modals to the live announcer element.
   */
  _exposeAnnouncerToModals(id) {
    // TODO(http://github.com/angular/components/issues/26853): consider de-duplicating this with
    // the `SnakBarContainer` and other usages.
    //
    // Note that the selector here is limited to CDK overlays at the moment in order to reduce the
    // section of the DOM we need to look through. This should cover all the cases we support, but
    // the selector can be expanded if it turns out to be too narrow.
    const modals = this._document.querySelectorAll('body > .cdk-overlay-container [aria-modal="true"]');
    for (let i = 0; i < modals.length; i++) {
      const modal = modals[i];
      const ariaOwns = modal.getAttribute('aria-owns');
      if (!ariaOwns) {
        modal.setAttribute('aria-owns', id);
      } else if (ariaOwns.indexOf(id) === -1) {
        modal.setAttribute('aria-owns', ariaOwns + ' ' + id);
      }
    }
  }
  static {
    this.ɵfac = function LiveAnnouncer_Factory(t) {
      return new (t || LiveAnnouncer)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](LIVE_ANNOUNCER_ELEMENT_TOKEN, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](LIVE_ANNOUNCER_DEFAULT_OPTIONS, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: LiveAnnouncer,
      factory: LiveAnnouncer.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LiveAnnouncer, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [LIVE_ANNOUNCER_ELEMENT_TOKEN]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [LIVE_ANNOUNCER_DEFAULT_OPTIONS]
    }]
  }], null);
})();
/**
 * A directive that works similarly to aria-live, but uses the LiveAnnouncer to ensure compatibility
 * with a wider range of browsers and screen readers.
 */
class CdkAriaLive {
  /** The aria-live politeness level to use when announcing messages. */
  get politeness() {
    return this._politeness;
  }
  set politeness(value) {
    this._politeness = value === 'off' || value === 'assertive' ? value : 'polite';
    if (this._politeness === 'off') {
      if (this._subscription) {
        this._subscription.unsubscribe();
        this._subscription = null;
      }
    } else if (!this._subscription) {
      this._subscription = this._ngZone.runOutsideAngular(() => {
        return this._contentObserver.observe(this._elementRef).subscribe(() => {
          // Note that we use textContent here, rather than innerText, in order to avoid a reflow.
          const elementText = this._elementRef.nativeElement.textContent;
          // The `MutationObserver` fires also for attribute
          // changes which we don't want to announce.
          if (elementText !== this._previousAnnouncedText) {
            this._liveAnnouncer.announce(elementText, this._politeness, this.duration);
            this._previousAnnouncedText = elementText;
          }
        });
      });
    }
  }
  constructor(_elementRef, _liveAnnouncer, _contentObserver, _ngZone) {
    this._elementRef = _elementRef;
    this._liveAnnouncer = _liveAnnouncer;
    this._contentObserver = _contentObserver;
    this._ngZone = _ngZone;
    this._politeness = 'polite';
  }
  ngOnDestroy() {
    if (this._subscription) {
      this._subscription.unsubscribe();
    }
  }
  static {
    this.ɵfac = function CdkAriaLive_Factory(t) {
      return new (t || CdkAriaLive)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](LiveAnnouncer), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_observers__WEBPACK_IMPORTED_MODULE_17__.ContentObserver), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkAriaLive,
      selectors: [["", "cdkAriaLive", ""]],
      inputs: {
        politeness: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "cdkAriaLive", "politeness"],
        duration: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "cdkAriaLiveDuration", "duration"]
      },
      exportAs: ["cdkAriaLive"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkAriaLive, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkAriaLive]',
      exportAs: 'cdkAriaLive',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: LiveAnnouncer
  }, {
    type: _angular_cdk_observers__WEBPACK_IMPORTED_MODULE_17__.ContentObserver
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }], {
    politeness: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['cdkAriaLive']
    }],
    duration: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['cdkAriaLiveDuration']
    }]
  });
})();

/** Detection mode used for attributing the origin of a focus event. */
var FocusMonitorDetectionMode;
(function (FocusMonitorDetectionMode) {
  /**
   * Any mousedown, keydown, or touchstart event that happened in the previous
   * tick or the current tick will be used to assign a focus event's origin (to
   * either mouse, keyboard, or touch). This is the default option.
   */
  FocusMonitorDetectionMode[FocusMonitorDetectionMode["IMMEDIATE"] = 0] = "IMMEDIATE";
  /**
   * A focus event's origin is always attributed to the last corresponding
   * mousedown, keydown, or touchstart event, no matter how long ago it occurred.
   */
  FocusMonitorDetectionMode[FocusMonitorDetectionMode["EVENTUAL"] = 1] = "EVENTUAL";
})(FocusMonitorDetectionMode || (FocusMonitorDetectionMode = {}));
/** InjectionToken for FocusMonitorOptions. */
const FOCUS_MONITOR_DEFAULT_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('cdk-focus-monitor-default-options');
/**
 * Event listener options that enable capturing and also
 * mark the listener as passive if the browser supports it.
 */
const captureEventListenerOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.normalizePassiveListenerOptions)({
  passive: true,
  capture: true
});
/** Monitors mouse and keyboard events to determine the cause of focus events. */
class FocusMonitor {
  constructor(_ngZone, _platform, _inputModalityDetector, /** @breaking-change 11.0.0 make document required */
  document, options) {
    this._ngZone = _ngZone;
    this._platform = _platform;
    this._inputModalityDetector = _inputModalityDetector;
    /** The focus origin that the next focus event is a result of. */
    this._origin = null;
    /** Whether the window has just been focused. */
    this._windowFocused = false;
    /**
     * Whether the origin was determined via a touch interaction. Necessary as properly attributing
     * focus events to touch interactions requires special logic.
     */
    this._originFromTouchInteraction = false;
    /** Map of elements being monitored to their info. */
    this._elementInfo = new Map();
    /** The number of elements currently being monitored. */
    this._monitoredElementCount = 0;
    /**
     * Keeps track of the root nodes to which we've currently bound a focus/blur handler,
     * as well as the number of monitored elements that they contain. We have to treat focus/blur
     * handlers differently from the rest of the events, because the browser won't emit events
     * to the document when focus moves inside of a shadow root.
     */
    this._rootNodeFocusListenerCount = new Map();
    /**
     * Event listener for `focus` events on the window.
     * Needs to be an arrow function in order to preserve the context when it gets bound.
     */
    this._windowFocusListener = () => {
      // Make a note of when the window regains focus, so we can
      // restore the origin info for the focused element.
      this._windowFocused = true;
      this._windowFocusTimeoutId = window.setTimeout(() => this._windowFocused = false);
    };
    /** Subject for stopping our InputModalityDetector subscription. */
    this._stopInputModalityDetector = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    /**
     * Event listener for `focus` and 'blur' events on the document.
     * Needs to be an arrow function in order to preserve the context when it gets bound.
     */
    this._rootNodeFocusAndBlurListener = event => {
      const target = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getEventTarget)(event);
      // We need to walk up the ancestor chain in order to support `checkChildren`.
      for (let element = target; element; element = element.parentElement) {
        if (event.type === 'focus') {
          this._onFocus(event, element);
        } else {
          this._onBlur(event, element);
        }
      }
    };
    this._document = document;
    this._detectionMode = options?.detectionMode || FocusMonitorDetectionMode.IMMEDIATE;
  }
  monitor(element, checkChildren = false) {
    const nativeElement = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_18__.coerceElement)(element);
    // Do nothing if we're not on the browser platform or the passed in node isn't an element.
    if (!this._platform.isBrowser || nativeElement.nodeType !== 1) {
      // Note: we don't want the observable to emit at all so we don't pass any parameters.
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_13__.of)();
    }
    // If the element is inside the shadow DOM, we need to bind our focus/blur listeners to
    // the shadow root, rather than the `document`, because the browser won't emit focus events
    // to the `document`, if focus is moving within the same shadow root.
    const rootNode = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getShadowRoot)(nativeElement) || this._getDocument();
    const cachedInfo = this._elementInfo.get(nativeElement);
    // Check if we're already monitoring this element.
    if (cachedInfo) {
      if (checkChildren) {
        // TODO(COMP-318): this can be problematic, because it'll turn all non-checkChildren
        // observers into ones that behave as if `checkChildren` was turned on. We need a more
        // robust solution.
        cachedInfo.checkChildren = true;
      }
      return cachedInfo.subject;
    }
    // Create monitored element info.
    const info = {
      checkChildren: checkChildren,
      subject: new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject(),
      rootNode
    };
    this._elementInfo.set(nativeElement, info);
    this._registerGlobalListeners(info);
    return info.subject;
  }
  stopMonitoring(element) {
    const nativeElement = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_18__.coerceElement)(element);
    const elementInfo = this._elementInfo.get(nativeElement);
    if (elementInfo) {
      elementInfo.subject.complete();
      this._setClasses(nativeElement);
      this._elementInfo.delete(nativeElement);
      this._removeGlobalListeners(elementInfo);
    }
  }
  focusVia(element, origin, options) {
    const nativeElement = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_18__.coerceElement)(element);
    const focusedElement = this._getDocument().activeElement;
    // If the element is focused already, calling `focus` again won't trigger the event listener
    // which means that the focus classes won't be updated. If that's the case, update the classes
    // directly without waiting for an event.
    if (nativeElement === focusedElement) {
      this._getClosestElementsInfo(nativeElement).forEach(([currentElement, info]) => this._originChanged(currentElement, origin, info));
    } else {
      this._setOrigin(origin);
      // `focus` isn't available on the server
      if (typeof nativeElement.focus === 'function') {
        nativeElement.focus(options);
      }
    }
  }
  ngOnDestroy() {
    this._elementInfo.forEach((_info, element) => this.stopMonitoring(element));
  }
  /** Access injected document if available or fallback to global document reference */
  _getDocument() {
    return this._document || document;
  }
  /** Use defaultView of injected document if available or fallback to global window reference */
  _getWindow() {
    const doc = this._getDocument();
    return doc.defaultView || window;
  }
  _getFocusOrigin(focusEventTarget) {
    if (this._origin) {
      // If the origin was realized via a touch interaction, we need to perform additional checks
      // to determine whether the focus origin should be attributed to touch or program.
      if (this._originFromTouchInteraction) {
        return this._shouldBeAttributedToTouch(focusEventTarget) ? 'touch' : 'program';
      } else {
        return this._origin;
      }
    }
    // If the window has just regained focus, we can restore the most recent origin from before the
    // window blurred. Otherwise, we've reached the point where we can't identify the source of the
    // focus. This typically means one of two things happened:
    //
    // 1) The element was programmatically focused, or
    // 2) The element was focused via screen reader navigation (which generally doesn't fire
    //    events).
    //
    // Because we can't distinguish between these two cases, we default to setting `program`.
    if (this._windowFocused && this._lastFocusOrigin) {
      return this._lastFocusOrigin;
    }
    // If the interaction is coming from an input label, we consider it a mouse interactions.
    // This is a special case where focus moves on `click`, rather than `mousedown` which breaks
    // our detection, because all our assumptions are for `mousedown`. We need to handle this
    // special case, because it's very common for checkboxes and radio buttons.
    if (focusEventTarget && this._isLastInteractionFromInputLabel(focusEventTarget)) {
      return 'mouse';
    }
    return 'program';
  }
  /**
   * Returns whether the focus event should be attributed to touch. Recall that in IMMEDIATE mode, a
   * touch origin isn't immediately reset at the next tick (see _setOrigin). This means that when we
   * handle a focus event following a touch interaction, we need to determine whether (1) the focus
   * event was directly caused by the touch interaction or (2) the focus event was caused by a
   * subsequent programmatic focus call triggered by the touch interaction.
   * @param focusEventTarget The target of the focus event under examination.
   */
  _shouldBeAttributedToTouch(focusEventTarget) {
    // Please note that this check is not perfect. Consider the following edge case:
    //
    // <div #parent tabindex="0">
    //   <div #child tabindex="0" (click)="#parent.focus()"></div>
    // </div>
    //
    // Suppose there is a FocusMonitor in IMMEDIATE mode attached to #parent. When the user touches
    // #child, #parent is programmatically focused. This code will attribute the focus to touch
    // instead of program. This is a relatively minor edge-case that can be worked around by using
    // focusVia(parent, 'program') to focus #parent.
    return this._detectionMode === FocusMonitorDetectionMode.EVENTUAL || !!focusEventTarget?.contains(this._inputModalityDetector._mostRecentTarget);
  }
  /**
   * Sets the focus classes on the element based on the given focus origin.
   * @param element The element to update the classes on.
   * @param origin The focus origin.
   */
  _setClasses(element, origin) {
    element.classList.toggle('cdk-focused', !!origin);
    element.classList.toggle('cdk-touch-focused', origin === 'touch');
    element.classList.toggle('cdk-keyboard-focused', origin === 'keyboard');
    element.classList.toggle('cdk-mouse-focused', origin === 'mouse');
    element.classList.toggle('cdk-program-focused', origin === 'program');
  }
  /**
   * Updates the focus origin. If we're using immediate detection mode, we schedule an async
   * function to clear the origin at the end of a timeout. The duration of the timeout depends on
   * the origin being set.
   * @param origin The origin to set.
   * @param isFromInteraction Whether we are setting the origin from an interaction event.
   */
  _setOrigin(origin, isFromInteraction = false) {
    this._ngZone.runOutsideAngular(() => {
      this._origin = origin;
      this._originFromTouchInteraction = origin === 'touch' && isFromInteraction;
      // If we're in IMMEDIATE mode, reset the origin at the next tick (or in `TOUCH_BUFFER_MS` ms
      // for a touch event). We reset the origin at the next tick because Firefox focuses one tick
      // after the interaction event. We wait `TOUCH_BUFFER_MS` ms before resetting the origin for
      // a touch event because when a touch event is fired, the associated focus event isn't yet in
      // the event queue. Before doing so, clear any pending timeouts.
      if (this._detectionMode === FocusMonitorDetectionMode.IMMEDIATE) {
        clearTimeout(this._originTimeoutId);
        const ms = this._originFromTouchInteraction ? TOUCH_BUFFER_MS : 1;
        this._originTimeoutId = setTimeout(() => this._origin = null, ms);
      }
    });
  }
  /**
   * Handles focus events on a registered element.
   * @param event The focus event.
   * @param element The monitored element.
   */
  _onFocus(event, element) {
    // NOTE(mmalerba): We currently set the classes based on the focus origin of the most recent
    // focus event affecting the monitored element. If we want to use the origin of the first event
    // instead we should check for the cdk-focused class here and return if the element already has
    // it. (This only matters for elements that have includesChildren = true).
    // If we are not counting child-element-focus as focused, make sure that the event target is the
    // monitored element itself.
    const elementInfo = this._elementInfo.get(element);
    const focusEventTarget = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__._getEventTarget)(event);
    if (!elementInfo || !elementInfo.checkChildren && element !== focusEventTarget) {
      return;
    }
    this._originChanged(element, this._getFocusOrigin(focusEventTarget), elementInfo);
  }
  /**
   * Handles blur events on a registered element.
   * @param event The blur event.
   * @param element The monitored element.
   */
  _onBlur(event, element) {
    // If we are counting child-element-focus as focused, make sure that we aren't just blurring in
    // order to focus another child of the monitored element.
    const elementInfo = this._elementInfo.get(element);
    if (!elementInfo || elementInfo.checkChildren && event.relatedTarget instanceof Node && element.contains(event.relatedTarget)) {
      return;
    }
    this._setClasses(element);
    this._emitOrigin(elementInfo, null);
  }
  _emitOrigin(info, origin) {
    if (info.subject.observers.length) {
      this._ngZone.run(() => info.subject.next(origin));
    }
  }
  _registerGlobalListeners(elementInfo) {
    if (!this._platform.isBrowser) {
      return;
    }
    const rootNode = elementInfo.rootNode;
    const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode) || 0;
    if (!rootNodeFocusListeners) {
      this._ngZone.runOutsideAngular(() => {
        rootNode.addEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
        rootNode.addEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
      });
    }
    this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners + 1);
    // Register global listeners when first element is monitored.
    if (++this._monitoredElementCount === 1) {
      // Note: we listen to events in the capture phase so we
      // can detect them even if the user stops propagation.
      this._ngZone.runOutsideAngular(() => {
        const window = this._getWindow();
        window.addEventListener('focus', this._windowFocusListener);
      });
      // The InputModalityDetector is also just a collection of global listeners.
      this._inputModalityDetector.modalityDetected.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.takeUntil)(this._stopInputModalityDetector)).subscribe(modality => {
        this._setOrigin(modality, true /* isFromInteraction */);
      });
    }
  }
  _removeGlobalListeners(elementInfo) {
    const rootNode = elementInfo.rootNode;
    if (this._rootNodeFocusListenerCount.has(rootNode)) {
      const rootNodeFocusListeners = this._rootNodeFocusListenerCount.get(rootNode);
      if (rootNodeFocusListeners > 1) {
        this._rootNodeFocusListenerCount.set(rootNode, rootNodeFocusListeners - 1);
      } else {
        rootNode.removeEventListener('focus', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
        rootNode.removeEventListener('blur', this._rootNodeFocusAndBlurListener, captureEventListenerOptions);
        this._rootNodeFocusListenerCount.delete(rootNode);
      }
    }
    // Unregister global listeners when last element is unmonitored.
    if (! --this._monitoredElementCount) {
      const window = this._getWindow();
      window.removeEventListener('focus', this._windowFocusListener);
      // Equivalently, stop our InputModalityDetector subscription.
      this._stopInputModalityDetector.next();
      // Clear timeouts for all potentially pending timeouts to prevent the leaks.
      clearTimeout(this._windowFocusTimeoutId);
      clearTimeout(this._originTimeoutId);
    }
  }
  /** Updates all the state on an element once its focus origin has changed. */
  _originChanged(element, origin, elementInfo) {
    this._setClasses(element, origin);
    this._emitOrigin(elementInfo, origin);
    this._lastFocusOrigin = origin;
  }
  /**
   * Collects the `MonitoredElementInfo` of a particular element and
   * all of its ancestors that have enabled `checkChildren`.
   * @param element Element from which to start the search.
   */
  _getClosestElementsInfo(element) {
    const results = [];
    this._elementInfo.forEach((info, currentElement) => {
      if (currentElement === element || info.checkChildren && currentElement.contains(element)) {
        results.push([currentElement, info]);
      }
    });
    return results;
  }
  /**
   * Returns whether an interaction is likely to have come from the user clicking the `label` of
   * an `input` or `textarea` in order to focus it.
   * @param focusEventTarget Target currently receiving focus.
   */
  _isLastInteractionFromInputLabel(focusEventTarget) {
    const {
      _mostRecentTarget: mostRecentTarget,
      mostRecentModality
    } = this._inputModalityDetector;
    // If the last interaction used the mouse on an element contained by one of the labels
    // of an `input`/`textarea` that is currently focused, it is very likely that the
    // user redirected focus using the label.
    if (mostRecentModality !== 'mouse' || !mostRecentTarget || mostRecentTarget === focusEventTarget || focusEventTarget.nodeName !== 'INPUT' && focusEventTarget.nodeName !== 'TEXTAREA' || focusEventTarget.disabled) {
      return false;
    }
    const labels = focusEventTarget.labels;
    if (labels) {
      for (let i = 0; i < labels.length; i++) {
        if (labels[i].contains(mostRecentTarget)) {
          return true;
        }
      }
    }
    return false;
  }
  static {
    this.ɵfac = function FocusMonitor_Factory(t) {
      return new (t || FocusMonitor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](InputModalityDetector), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](FOCUS_MONITOR_DEFAULT_OPTIONS, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: FocusMonitor,
      factory: FocusMonitor.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FocusMonitor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform
  }, {
    type: InputModalityDetector
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [FOCUS_MONITOR_DEFAULT_OPTIONS]
    }]
  }], null);
})();
/**
 * Directive that determines how a particular element was focused (via keyboard, mouse, touch, or
 * programmatically) and adds corresponding classes to the element.
 *
 * There are two variants of this directive:
 * 1) cdkMonitorElementFocus: does not consider an element to be focused if one of its children is
 *    focused.
 * 2) cdkMonitorSubtreeFocus: considers an element focused if it or any of its children are focused.
 */
class CdkMonitorFocus {
  constructor(_elementRef, _focusMonitor) {
    this._elementRef = _elementRef;
    this._focusMonitor = _focusMonitor;
    this._focusOrigin = null;
    this.cdkFocusChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  get focusOrigin() {
    return this._focusOrigin;
  }
  ngAfterViewInit() {
    const element = this._elementRef.nativeElement;
    this._monitorSubscription = this._focusMonitor.monitor(element, element.nodeType === 1 && element.hasAttribute('cdkMonitorSubtreeFocus')).subscribe(origin => {
      this._focusOrigin = origin;
      this.cdkFocusChange.emit(origin);
    });
  }
  ngOnDestroy() {
    this._focusMonitor.stopMonitoring(this._elementRef);
    if (this._monitorSubscription) {
      this._monitorSubscription.unsubscribe();
    }
  }
  static {
    this.ɵfac = function CdkMonitorFocus_Factory(t) {
      return new (t || CdkMonitorFocus)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](FocusMonitor));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkMonitorFocus,
      selectors: [["", "cdkMonitorElementFocus", ""], ["", "cdkMonitorSubtreeFocus", ""]],
      outputs: {
        cdkFocusChange: "cdkFocusChange"
      },
      exportAs: ["cdkMonitorFocus"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkMonitorFocus, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkMonitorElementFocus], [cdkMonitorSubtreeFocus]',
      exportAs: 'cdkMonitorFocus',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: FocusMonitor
  }], {
    cdkFocusChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();

/** Set of possible high-contrast mode backgrounds. */
var HighContrastMode;
(function (HighContrastMode) {
  HighContrastMode[HighContrastMode["NONE"] = 0] = "NONE";
  HighContrastMode[HighContrastMode["BLACK_ON_WHITE"] = 1] = "BLACK_ON_WHITE";
  HighContrastMode[HighContrastMode["WHITE_ON_BLACK"] = 2] = "WHITE_ON_BLACK";
})(HighContrastMode || (HighContrastMode = {}));
/** CSS class applied to the document body when in black-on-white high-contrast mode. */
const BLACK_ON_WHITE_CSS_CLASS = 'cdk-high-contrast-black-on-white';
/** CSS class applied to the document body when in white-on-black high-contrast mode. */
const WHITE_ON_BLACK_CSS_CLASS = 'cdk-high-contrast-white-on-black';
/** CSS class applied to the document body when in high-contrast mode. */
const HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS = 'cdk-high-contrast-active';
/**
 * Service to determine whether the browser is currently in a high-contrast-mode environment.
 *
 * Microsoft Windows supports an accessibility feature called "High Contrast Mode". This mode
 * changes the appearance of all applications, including web applications, to dramatically increase
 * contrast.
 *
 * IE, Edge, and Firefox currently support this mode. Chrome does not support Windows High Contrast
 * Mode. This service does not detect high-contrast mode as added by the Chrome "High Contrast"
 * browser extension.
 */
class HighContrastModeDetector {
  constructor(_platform, document) {
    this._platform = _platform;
    this._document = document;
    this._breakpointSubscription = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_cdk_layout__WEBPACK_IMPORTED_MODULE_20__.BreakpointObserver).observe('(forced-colors: active)').subscribe(() => {
      if (this._hasCheckedHighContrastMode) {
        this._hasCheckedHighContrastMode = false;
        this._applyBodyHighContrastModeCssClasses();
      }
    });
  }
  /** Gets the current high-contrast-mode for the page. */
  getHighContrastMode() {
    if (!this._platform.isBrowser) {
      return HighContrastMode.NONE;
    }
    // Create a test element with an arbitrary background-color that is neither black nor
    // white; high-contrast mode will coerce the color to either black or white. Also ensure that
    // appending the test element to the DOM does not affect layout by absolutely positioning it
    const testElement = this._document.createElement('div');
    testElement.style.backgroundColor = 'rgb(1,2,3)';
    testElement.style.position = 'absolute';
    this._document.body.appendChild(testElement);
    // Get the computed style for the background color, collapsing spaces to normalize between
    // browsers. Once we get this color, we no longer need the test element. Access the `window`
    // via the document so we can fake it in tests. Note that we have extra null checks, because
    // this logic will likely run during app bootstrap and throwing can break the entire app.
    const documentWindow = this._document.defaultView || window;
    const computedStyle = documentWindow && documentWindow.getComputedStyle ? documentWindow.getComputedStyle(testElement) : null;
    const computedColor = (computedStyle && computedStyle.backgroundColor || '').replace(/ /g, '');
    testElement.remove();
    switch (computedColor) {
      // Pre Windows 11 dark theme.
      case 'rgb(0,0,0)':
      // Windows 11 dark themes.
      case 'rgb(45,50,54)':
      case 'rgb(32,32,32)':
        return HighContrastMode.WHITE_ON_BLACK;
      // Pre Windows 11 light theme.
      case 'rgb(255,255,255)':
      // Windows 11 light theme.
      case 'rgb(255,250,239)':
        return HighContrastMode.BLACK_ON_WHITE;
    }
    return HighContrastMode.NONE;
  }
  ngOnDestroy() {
    this._breakpointSubscription.unsubscribe();
  }
  /** Applies CSS classes indicating high-contrast mode to document body (browser-only). */
  _applyBodyHighContrastModeCssClasses() {
    if (!this._hasCheckedHighContrastMode && this._platform.isBrowser && this._document.body) {
      const bodyClasses = this._document.body.classList;
      bodyClasses.remove(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);
      this._hasCheckedHighContrastMode = true;
      const mode = this.getHighContrastMode();
      if (mode === HighContrastMode.BLACK_ON_WHITE) {
        bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, BLACK_ON_WHITE_CSS_CLASS);
      } else if (mode === HighContrastMode.WHITE_ON_BLACK) {
        bodyClasses.add(HIGH_CONTRAST_MODE_ACTIVE_CSS_CLASS, WHITE_ON_BLACK_CSS_CLASS);
      }
    }
  }
  static {
    this.ɵfac = function HighContrastModeDetector_Factory(t) {
      return new (t || HighContrastModeDetector)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: HighContrastModeDetector,
      factory: HighContrastModeDetector.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](HighContrastModeDetector, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_2__.Platform
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT]
    }]
  }], null);
})();
class A11yModule {
  constructor(highContrastModeDetector) {
    highContrastModeDetector._applyBodyHighContrastModeCssClasses();
  }
  static {
    this.ɵfac = function A11yModule_Factory(t) {
      return new (t || A11yModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](HighContrastModeDetector));
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: A11yModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [_angular_cdk_observers__WEBPACK_IMPORTED_MODULE_17__.ObserversModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](A11yModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [_angular_cdk_observers__WEBPACK_IMPORTED_MODULE_17__.ObserversModule, CdkAriaLive, CdkTrapFocus, CdkMonitorFocus],
      exports: [CdkAriaLive, CdkTrapFocus, CdkMonitorFocus]
    }]
  }], () => [{
    type: HighContrastModeDetector
  }], null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 63680:
/*!*****************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/bidi.mjs ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BidiModule: () => (/* binding */ BidiModule),
/* harmony export */   DIR_DOCUMENT: () => (/* binding */ DIR_DOCUMENT),
/* harmony export */   Dir: () => (/* binding */ Dir),
/* harmony export */   Directionality: () => (/* binding */ Directionality)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);




/**
 * Injection token used to inject the document into Directionality.
 * This is used so that the value can be faked in tests.
 *
 * We can't use the real document in tests because changing the real `dir` causes geometry-based
 * tests in Safari to fail.
 *
 * We also can't re-provide the DOCUMENT token from platform-browser because the unit tests
 * themselves use things like `querySelector` in test code.
 *
 * This token is defined in a separate file from Directionality as a workaround for
 * https://github.com/angular/angular/issues/22559
 *
 * @docs-private
 */
const DIR_DOCUMENT = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('cdk-dir-doc', {
  providedIn: 'root',
  factory: DIR_DOCUMENT_FACTORY
});
/** @docs-private */
function DIR_DOCUMENT_FACTORY() {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_1__.DOCUMENT);
}

/** Regex that matches locales with an RTL script. Taken from `goog.i18n.bidi.isRtlLanguage`. */
const RTL_LOCALE_PATTERN = /^(ar|ckb|dv|he|iw|fa|nqo|ps|sd|ug|ur|yi|.*[-_](Adlm|Arab|Hebr|Nkoo|Rohg|Thaa))(?!.*[-_](Latn|Cyrl)($|-|_))($|-|_)/i;
/** Resolves a string value to a specific direction. */
function _resolveDirectionality(rawValue) {
  const value = rawValue?.toLowerCase() || '';
  if (value === 'auto' && typeof navigator !== 'undefined' && navigator?.language) {
    return RTL_LOCALE_PATTERN.test(navigator.language) ? 'rtl' : 'ltr';
  }
  return value === 'rtl' ? 'rtl' : 'ltr';
}
/**
 * The directionality (LTR / RTL) context for the application (or a subtree of it).
 * Exposes the current direction and a stream of direction changes.
 */
class Directionality {
  constructor(_document) {
    /** The current 'ltr' or 'rtl' value. */
    this.value = 'ltr';
    /** Stream that emits whenever the 'ltr' / 'rtl' state changes. */
    this.change = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    if (_document) {
      const bodyDir = _document.body ? _document.body.dir : null;
      const htmlDir = _document.documentElement ? _document.documentElement.dir : null;
      this.value = _resolveDirectionality(bodyDir || htmlDir || 'ltr');
    }
  }
  ngOnDestroy() {
    this.change.complete();
  }
  static {
    this.ɵfac = function Directionality_Factory(t) {
      return new (t || Directionality)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](DIR_DOCUMENT, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: Directionality,
      factory: Directionality.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Directionality, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [DIR_DOCUMENT]
    }]
  }], null);
})();

/**
 * Directive to listen for changes of direction of part of the DOM.
 *
 * Provides itself as Directionality such that descendant directives only need to ever inject
 * Directionality to get the closest direction.
 */
class Dir {
  constructor() {
    /** Normalized direction that accounts for invalid/unsupported values. */
    this._dir = 'ltr';
    /** Whether the `value` has been set to its initial value. */
    this._isInitialized = false;
    /** Event emitted when the direction changes. */
    this.change = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  /** @docs-private */
  get dir() {
    return this._dir;
  }
  set dir(value) {
    const previousValue = this._dir;
    // Note: `_resolveDirectionality` resolves the language based on the browser's language,
    // whereas the browser does it based on the content of the element. Since doing so based
    // on the content can be expensive, for now we're doing the simpler matching.
    this._dir = _resolveDirectionality(value);
    this._rawDir = value;
    if (previousValue !== this._dir && this._isInitialized) {
      this.change.emit(this._dir);
    }
  }
  /** Current layout direction of the element. */
  get value() {
    return this.dir;
  }
  /** Initialize once default value has been set. */
  ngAfterContentInit() {
    this._isInitialized = true;
  }
  ngOnDestroy() {
    this.change.complete();
  }
  static {
    this.ɵfac = function Dir_Factory(t) {
      return new (t || Dir)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: Dir,
      selectors: [["", "dir", ""]],
      hostVars: 1,
      hostBindings: function Dir_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("dir", ctx._rawDir);
        }
      },
      inputs: {
        dir: "dir"
      },
      outputs: {
        change: "dirChange"
      },
      exportAs: ["dir"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: Directionality,
        useExisting: Dir
      }])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Dir, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dir]',
      providers: [{
        provide: Directionality,
        useExisting: Dir
      }],
      host: {
        '[attr.dir]': '_rawDir'
      },
      exportAs: 'dir',
      standalone: true
    }]
  }], null, {
    change: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['dirChange']
    }],
    dir: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class BidiModule {
  static {
    this.ɵfac = function BidiModule_Factory(t) {
      return new (t || BidiModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: BidiModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BidiModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [Dir],
      exports: [Dir]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 31398:
/*!****************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/cdk.mjs ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   VERSION: () => (/* binding */ VERSION)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);


/** Current version of the Angular Component Development Kit. */
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('18.2.14');


/***/ }),

/***/ 2814:
/*!*********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/coercion.mjs ***!
  \*********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   _isNumberValue: () => (/* binding */ _isNumberValue),
/* harmony export */   coerceArray: () => (/* binding */ coerceArray),
/* harmony export */   coerceBooleanProperty: () => (/* binding */ coerceBooleanProperty),
/* harmony export */   coerceCssPixelValue: () => (/* binding */ coerceCssPixelValue),
/* harmony export */   coerceElement: () => (/* binding */ coerceElement),
/* harmony export */   coerceNumberProperty: () => (/* binding */ coerceNumberProperty),
/* harmony export */   coerceStringArray: () => (/* binding */ coerceStringArray)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);


/** Coerces a data-bound value (typically a string) to a boolean. */
function coerceBooleanProperty(value) {
  return value != null && `${value}` !== 'false';
}
function coerceNumberProperty(value, fallbackValue = 0) {
  if (_isNumberValue(value)) {
    return Number(value);
  }
  return arguments.length === 2 ? fallbackValue : 0;
}
/**
 * Whether the provided value is considered a number.
 * @docs-private
 */
function _isNumberValue(value) {
  // parseFloat(value) handles most of the cases we're interested in (it treats null, empty string,
  // and other non-number values as NaN, where Number just uses 0) but it considers the string
  // '123hello' to be a valid number. Therefore we also check if Number(value) is NaN.
  return !isNaN(parseFloat(value)) && !isNaN(Number(value));
}
function coerceArray(value) {
  return Array.isArray(value) ? value : [value];
}

/** Coerces a value to a CSS pixel value. */
function coerceCssPixelValue(value) {
  if (value == null) {
    return '';
  }
  return typeof value === 'string' ? value : `${value}px`;
}

/**
 * Coerces an ElementRef or an Element into an element.
 * Useful for APIs that can accept either a ref or the native element itself.
 */
function coerceElement(elementOrRef) {
  return elementOrRef instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef ? elementOrRef.nativeElement : elementOrRef;
}

/**
 * Coerces a value to an array of trimmed non-empty strings.
 * Any input that is not an array, `null` or `undefined` will be turned into a string
 * via `toString()` and subsequently split with the given separator.
 * `null` and `undefined` will result in an empty array.
 * This results in the following outcomes:
 * - `null` -&gt; `[]`
 * - `[null]` -&gt; `["null"]`
 * - `["a", "b ", " "]` -&gt; `["a", "b"]`
 * - `[1, [2, 3]]` -&gt; `["1", "2,3"]`
 * - `[{ a: 0 }]` -&gt; `["[object Object]"]`
 * - `{ a: 0 }` -&gt; `["[object", "Object]"]`
 *
 * Useful for defining CSS classes or table columns.
 * @param value the value to coerce into an array of strings
 * @param separator split-separator if value isn't an array
 */
function coerceStringArray(value, separator = /\s+/) {
  const result = [];
  if (value != null) {
    const sourceValues = Array.isArray(value) ? value : `${value}`.split(separator);
    for (const sourceValue of sourceValues) {
      const trimmedString = `${sourceValue}`.trim();
      if (trimmedString) {
        result.push(trimmedString);
      }
    }
  }
  return result;
}


/***/ }),

/***/ 22810:
/*!*****************************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/coercion/private.mjs ***!
  \*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   coerceObservable: () => (/* binding */ coerceObservable)
/* harmony export */ });
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 59452);


/**
 * Given either an Observable or non-Observable value, returns either the original
 * Observable, or wraps it in an Observable that emits the non-Observable value.
 */
function coerceObservable(data) {
  if (!(0,rxjs__WEBPACK_IMPORTED_MODULE_0__.isObservable)(data)) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.of)(data);
  }
  return data;
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 37989:
/*!************************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/collections.mjs ***!
  \************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ArrayDataSource: () => (/* binding */ ArrayDataSource),
/* harmony export */   DataSource: () => (/* binding */ DataSource),
/* harmony export */   SelectionModel: () => (/* binding */ SelectionModel),
/* harmony export */   UniqueSelectionDispatcher: () => (/* binding */ UniqueSelectionDispatcher),
/* harmony export */   _DisposeViewRepeaterStrategy: () => (/* binding */ _DisposeViewRepeaterStrategy),
/* harmony export */   _RecycleViewRepeaterStrategy: () => (/* binding */ _RecycleViewRepeaterStrategy),
/* harmony export */   _VIEW_REPEATER_STRATEGY: () => (/* binding */ _VIEW_REPEATER_STRATEGY),
/* harmony export */   _ViewRepeaterOperation: () => (/* binding */ _ViewRepeaterOperation),
/* harmony export */   getMultipleValuesInSingleSelectionError: () => (/* binding */ getMultipleValuesInSingleSelectionError),
/* harmony export */   isDataSource: () => (/* binding */ isDataSource)
/* harmony export */ });
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 94982);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/core */ 37580);



class DataSource {}
/** Checks whether an object is a data source. */
function isDataSource(value) {
  // Check if the value is a DataSource by observing if it has a connect function. Cannot
  // be checked as an `instanceof DataSource` since people could create their own sources
  // that match the interface, but don't extend DataSource. We also can't use `isObservable`
  // here, because of some internal apps.
  return value && typeof value.connect === 'function' && !(value instanceof rxjs__WEBPACK_IMPORTED_MODULE_0__.ConnectableObservable);
}

/** DataSource wrapper for a native array. */
class ArrayDataSource extends DataSource {
  constructor(_data) {
    super();
    this._data = _data;
  }
  connect() {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.isObservable)(this._data) ? this._data : (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.of)(this._data);
  }
  disconnect() {}
}

/** Indicates how a view was changed by a {@link _ViewRepeater}. */
var _ViewRepeaterOperation;
(function (_ViewRepeaterOperation) {
  /** The content of an existing view was replaced with another item. */
  _ViewRepeaterOperation[_ViewRepeaterOperation["REPLACED"] = 0] = "REPLACED";
  /** A new view was created with `createEmbeddedView`. */
  _ViewRepeaterOperation[_ViewRepeaterOperation["INSERTED"] = 1] = "INSERTED";
  /** The position of a view changed, but the content remains the same. */
  _ViewRepeaterOperation[_ViewRepeaterOperation["MOVED"] = 2] = "MOVED";
  /** A view was detached from the view container. */
  _ViewRepeaterOperation[_ViewRepeaterOperation["REMOVED"] = 3] = "REMOVED";
})(_ViewRepeaterOperation || (_ViewRepeaterOperation = {}));
/**
 * Injection token for {@link _ViewRepeater}. This token is for use by Angular Material only.
 * @docs-private
 */
const _VIEW_REPEATER_STRATEGY = new _angular_core__WEBPACK_IMPORTED_MODULE_3__.InjectionToken('_ViewRepeater');

/**
 * A repeater that destroys views when they are removed from a
 * {@link ViewContainerRef}. When new items are inserted into the container,
 * the repeater will always construct a new embedded view for each item.
 *
 * @template T The type for the embedded view's $implicit property.
 * @template R The type for the item in each IterableDiffer change record.
 * @template C The type for the context passed to each embedded view.
 */
class _DisposeViewRepeaterStrategy {
  applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {
    changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {
      let view;
      let operation;
      if (record.previousIndex == null) {
        const insertContext = itemContextFactory(record, adjustedPreviousIndex, currentIndex);
        view = viewContainerRef.createEmbeddedView(insertContext.templateRef, insertContext.context, insertContext.index);
        operation = _ViewRepeaterOperation.INSERTED;
      } else if (currentIndex == null) {
        viewContainerRef.remove(adjustedPreviousIndex);
        operation = _ViewRepeaterOperation.REMOVED;
      } else {
        view = viewContainerRef.get(adjustedPreviousIndex);
        viewContainerRef.move(view, currentIndex);
        operation = _ViewRepeaterOperation.MOVED;
      }
      if (itemViewChanged) {
        itemViewChanged({
          context: view?.context,
          operation,
          record
        });
      }
    });
  }
  detach() {}
}

/**
 * A repeater that caches views when they are removed from a
 * {@link ViewContainerRef}. When new items are inserted into the container,
 * the repeater will reuse one of the cached views instead of creating a new
 * embedded view. Recycling cached views reduces the quantity of expensive DOM
 * inserts.
 *
 * @template T The type for the embedded view's $implicit property.
 * @template R The type for the item in each IterableDiffer change record.
 * @template C The type for the context passed to each embedded view.
 */
class _RecycleViewRepeaterStrategy {
  constructor() {
    /**
     * The size of the cache used to store unused views.
     * Setting the cache size to `0` will disable caching. Defaults to 20 views.
     */
    this.viewCacheSize = 20;
    /**
     * View cache that stores embedded view instances that have been previously stamped out,
     * but don't are not currently rendered. The view repeater will reuse these views rather than
     * creating brand new ones.
     *
     * TODO(michaeljamesparsons) Investigate whether using a linked list would improve performance.
     */
    this._viewCache = [];
  }
  /** Apply changes to the DOM. */
  applyChanges(changes, viewContainerRef, itemContextFactory, itemValueResolver, itemViewChanged) {
    // Rearrange the views to put them in the right location.
    changes.forEachOperation((record, adjustedPreviousIndex, currentIndex) => {
      let view;
      let operation;
      if (record.previousIndex == null) {
        // Item added.
        const viewArgsFactory = () => itemContextFactory(record, adjustedPreviousIndex, currentIndex);
        view = this._insertView(viewArgsFactory, currentIndex, viewContainerRef, itemValueResolver(record));
        operation = view ? _ViewRepeaterOperation.INSERTED : _ViewRepeaterOperation.REPLACED;
      } else if (currentIndex == null) {
        // Item removed.
        this._detachAndCacheView(adjustedPreviousIndex, viewContainerRef);
        operation = _ViewRepeaterOperation.REMOVED;
      } else {
        // Item moved.
        view = this._moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, itemValueResolver(record));
        operation = _ViewRepeaterOperation.MOVED;
      }
      if (itemViewChanged) {
        itemViewChanged({
          context: view?.context,
          operation,
          record
        });
      }
    });
  }
  detach() {
    for (const view of this._viewCache) {
      view.destroy();
    }
    this._viewCache = [];
  }
  /**
   * Inserts a view for a new item, either from the cache or by creating a new
   * one. Returns `undefined` if the item was inserted into a cached view.
   */
  _insertView(viewArgsFactory, currentIndex, viewContainerRef, value) {
    const cachedView = this._insertViewFromCache(currentIndex, viewContainerRef);
    if (cachedView) {
      cachedView.context.$implicit = value;
      return undefined;
    }
    const viewArgs = viewArgsFactory();
    return viewContainerRef.createEmbeddedView(viewArgs.templateRef, viewArgs.context, viewArgs.index);
  }
  /** Detaches the view at the given index and inserts into the view cache. */
  _detachAndCacheView(index, viewContainerRef) {
    const detachedView = viewContainerRef.detach(index);
    this._maybeCacheView(detachedView, viewContainerRef);
  }
  /** Moves view at the previous index to the current index. */
  _moveView(adjustedPreviousIndex, currentIndex, viewContainerRef, value) {
    const view = viewContainerRef.get(adjustedPreviousIndex);
    viewContainerRef.move(view, currentIndex);
    view.context.$implicit = value;
    return view;
  }
  /**
   * Cache the given detached view. If the cache is full, the view will be
   * destroyed.
   */
  _maybeCacheView(view, viewContainerRef) {
    if (this._viewCache.length < this.viewCacheSize) {
      this._viewCache.push(view);
    } else {
      const index = viewContainerRef.indexOf(view);
      // The host component could remove views from the container outside of
      // the view repeater. It's unlikely this will occur, but just in case,
      // destroy the view on its own, otherwise destroy it through the
      // container to ensure that all the references are removed.
      if (index === -1) {
        view.destroy();
      } else {
        viewContainerRef.remove(index);
      }
    }
  }
  /** Inserts a recycled view from the cache at the given index. */
  _insertViewFromCache(index, viewContainerRef) {
    const cachedView = this._viewCache.pop();
    if (cachedView) {
      viewContainerRef.insert(cachedView, index);
    }
    return cachedView || null;
  }
}

/**
 * Class to be used to power selecting one or more options from a list.
 */
class SelectionModel {
  /** Selected values. */
  get selected() {
    if (!this._selected) {
      this._selected = Array.from(this._selection.values());
    }
    return this._selected;
  }
  constructor(_multiple = false, initiallySelectedValues, _emitChanges = true, compareWith) {
    this._multiple = _multiple;
    this._emitChanges = _emitChanges;
    this.compareWith = compareWith;
    /** Currently-selected values. */
    this._selection = new Set();
    /** Keeps track of the deselected options that haven't been emitted by the change event. */
    this._deselectedToEmit = [];
    /** Keeps track of the selected options that haven't been emitted by the change event. */
    this._selectedToEmit = [];
    /** Event emitted when the value has changed. */
    this.changed = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    if (initiallySelectedValues && initiallySelectedValues.length) {
      if (_multiple) {
        initiallySelectedValues.forEach(value => this._markSelected(value));
      } else {
        this._markSelected(initiallySelectedValues[0]);
      }
      // Clear the array in order to avoid firing the change event for preselected values.
      this._selectedToEmit.length = 0;
    }
  }
  /**
   * Selects a value or an array of values.
   * @param values The values to select
   * @return Whether the selection changed as a result of this call
   * @breaking-change 16.0.0 make return type boolean
   */
  select(...values) {
    this._verifyValueAssignment(values);
    values.forEach(value => this._markSelected(value));
    const changed = this._hasQueuedChanges();
    this._emitChangeEvent();
    return changed;
  }
  /**
   * Deselects a value or an array of values.
   * @param values The values to deselect
   * @return Whether the selection changed as a result of this call
   * @breaking-change 16.0.0 make return type boolean
   */
  deselect(...values) {
    this._verifyValueAssignment(values);
    values.forEach(value => this._unmarkSelected(value));
    const changed = this._hasQueuedChanges();
    this._emitChangeEvent();
    return changed;
  }
  /**
   * Sets the selected values
   * @param values The new selected values
   * @return Whether the selection changed as a result of this call
   * @breaking-change 16.0.0 make return type boolean
   */
  setSelection(...values) {
    this._verifyValueAssignment(values);
    const oldValues = this.selected;
    const newSelectedSet = new Set(values);
    values.forEach(value => this._markSelected(value));
    oldValues.filter(value => !newSelectedSet.has(this._getConcreteValue(value, newSelectedSet))).forEach(value => this._unmarkSelected(value));
    const changed = this._hasQueuedChanges();
    this._emitChangeEvent();
    return changed;
  }
  /**
   * Toggles a value between selected and deselected.
   * @param value The value to toggle
   * @return Whether the selection changed as a result of this call
   * @breaking-change 16.0.0 make return type boolean
   */
  toggle(value) {
    return this.isSelected(value) ? this.deselect(value) : this.select(value);
  }
  /**
   * Clears all of the selected values.
   * @param flushEvent Whether to flush the changes in an event.
   *   If false, the changes to the selection will be flushed along with the next event.
   * @return Whether the selection changed as a result of this call
   * @breaking-change 16.0.0 make return type boolean
   */
  clear(flushEvent = true) {
    this._unmarkAll();
    const changed = this._hasQueuedChanges();
    if (flushEvent) {
      this._emitChangeEvent();
    }
    return changed;
  }
  /**
   * Determines whether a value is selected.
   */
  isSelected(value) {
    return this._selection.has(this._getConcreteValue(value));
  }
  /**
   * Determines whether the model does not have a value.
   */
  isEmpty() {
    return this._selection.size === 0;
  }
  /**
   * Determines whether the model has a value.
   */
  hasValue() {
    return !this.isEmpty();
  }
  /**
   * Sorts the selected values based on a predicate function.
   */
  sort(predicate) {
    if (this._multiple && this.selected) {
      this._selected.sort(predicate);
    }
  }
  /**
   * Gets whether multiple values can be selected.
   */
  isMultipleSelection() {
    return this._multiple;
  }
  /** Emits a change event and clears the records of selected and deselected values. */
  _emitChangeEvent() {
    // Clear the selected values so they can be re-cached.
    this._selected = null;
    if (this._selectedToEmit.length || this._deselectedToEmit.length) {
      this.changed.next({
        source: this,
        added: this._selectedToEmit,
        removed: this._deselectedToEmit
      });
      this._deselectedToEmit = [];
      this._selectedToEmit = [];
    }
  }
  /** Selects a value. */
  _markSelected(value) {
    value = this._getConcreteValue(value);
    if (!this.isSelected(value)) {
      if (!this._multiple) {
        this._unmarkAll();
      }
      if (!this.isSelected(value)) {
        this._selection.add(value);
      }
      if (this._emitChanges) {
        this._selectedToEmit.push(value);
      }
    }
  }
  /** Deselects a value. */
  _unmarkSelected(value) {
    value = this._getConcreteValue(value);
    if (this.isSelected(value)) {
      this._selection.delete(value);
      if (this._emitChanges) {
        this._deselectedToEmit.push(value);
      }
    }
  }
  /** Clears out the selected values. */
  _unmarkAll() {
    if (!this.isEmpty()) {
      this._selection.forEach(value => this._unmarkSelected(value));
    }
  }
  /**
   * Verifies the value assignment and throws an error if the specified value array is
   * including multiple values while the selection model is not supporting multiple values.
   */
  _verifyValueAssignment(values) {
    if (values.length > 1 && !this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getMultipleValuesInSingleSelectionError();
    }
  }
  /** Whether there are queued up change to be emitted. */
  _hasQueuedChanges() {
    return !!(this._deselectedToEmit.length || this._selectedToEmit.length);
  }
  /** Returns a value that is comparable to inputValue by applying compareWith function, returns the same inputValue otherwise. */
  _getConcreteValue(inputValue, selection) {
    if (!this.compareWith) {
      return inputValue;
    } else {
      selection = selection ?? this._selection;
      for (let selectedValue of selection) {
        if (this.compareWith(inputValue, selectedValue)) {
          return selectedValue;
        }
      }
      return inputValue;
    }
  }
}
/**
 * Returns an error that reports that multiple values are passed into a selection model
 * with a single value.
 * @docs-private
 */
function getMultipleValuesInSingleSelectionError() {
  return Error('Cannot pass multiple values into SelectionModel with single-value mode.');
}

/**
 * Class to coordinate unique selection based on name.
 * Intended to be consumed as an Angular service.
 * This service is needed because native radio change events are only fired on the item currently
 * being selected, and we still need to uncheck the previous selection.
 *
 * This service does not *store* any IDs and names because they may change at any time, so it is
 * less error-prone if they are simply passed through when the events occur.
 */
class UniqueSelectionDispatcher {
  constructor() {
    this._listeners = [];
  }
  /**
   * Notify other items that selection for the given name has been set.
   * @param id ID of the item.
   * @param name Name of the item.
   */
  notify(id, name) {
    for (let listener of this._listeners) {
      listener(id, name);
    }
  }
  /**
   * Listen for future changes to item selection.
   * @return Function used to deregister listener
   */
  listen(listener) {
    this._listeners.push(listener);
    return () => {
      this._listeners = this._listeners.filter(registered => {
        return listener !== registered;
      });
    };
  }
  ngOnDestroy() {
    this._listeners = [];
  }
  static {
    this.ɵfac = function UniqueSelectionDispatcher_Factory(t) {
      return new (t || UniqueSelectionDispatcher)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_3__["ɵɵdefineInjectable"]({
      token: UniqueSelectionDispatcher,
      factory: UniqueSelectionDispatcher.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_3__["ɵsetClassMetadata"](UniqueSelectionDispatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_3__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 50854:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/drag-drop.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CDK_DRAG_CONFIG: () => (/* binding */ CDK_DRAG_CONFIG),
/* harmony export */   CDK_DRAG_HANDLE: () => (/* binding */ CDK_DRAG_HANDLE),
/* harmony export */   CDK_DRAG_PARENT: () => (/* binding */ CDK_DRAG_PARENT),
/* harmony export */   CDK_DRAG_PLACEHOLDER: () => (/* binding */ CDK_DRAG_PLACEHOLDER),
/* harmony export */   CDK_DRAG_PREVIEW: () => (/* binding */ CDK_DRAG_PREVIEW),
/* harmony export */   CDK_DROP_LIST: () => (/* binding */ CDK_DROP_LIST),
/* harmony export */   CDK_DROP_LIST_GROUP: () => (/* binding */ CDK_DROP_LIST_GROUP),
/* harmony export */   CdkDrag: () => (/* binding */ CdkDrag),
/* harmony export */   CdkDragHandle: () => (/* binding */ CdkDragHandle),
/* harmony export */   CdkDragPlaceholder: () => (/* binding */ CdkDragPlaceholder),
/* harmony export */   CdkDragPreview: () => (/* binding */ CdkDragPreview),
/* harmony export */   CdkDropList: () => (/* binding */ CdkDropList),
/* harmony export */   CdkDropListGroup: () => (/* binding */ CdkDropListGroup),
/* harmony export */   DragDrop: () => (/* binding */ DragDrop),
/* harmony export */   DragDropModule: () => (/* binding */ DragDropModule),
/* harmony export */   DragDropRegistry: () => (/* binding */ DragDropRegistry),
/* harmony export */   DragRef: () => (/* binding */ DragRef),
/* harmony export */   DropListRef: () => (/* binding */ DropListRef),
/* harmony export */   copyArrayItem: () => (/* binding */ copyArrayItem),
/* harmony export */   moveItemInArray: () => (/* binding */ moveItemInArray),
/* harmony export */   transferArrayItem: () => (/* binding */ transferArrayItem)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @angular/cdk/scrolling */ 79975);
/* harmony import */ var _angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/cdk/a11y */ 72102);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 2510);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 19240);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 20614);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! @angular/cdk/bidi */ 63680);












/** Creates a deep clone of an element. */
function deepCloneNode(node) {
  const clone = node.cloneNode(true);
  const descendantsWithId = clone.querySelectorAll('[id]');
  const nodeName = node.nodeName.toLowerCase();
  // Remove the `id` to avoid having multiple elements with the same id on the page.
  clone.removeAttribute('id');
  for (let i = 0; i < descendantsWithId.length; i++) {
    descendantsWithId[i].removeAttribute('id');
  }
  if (nodeName === 'canvas') {
    transferCanvasData(node, clone);
  } else if (nodeName === 'input' || nodeName === 'select' || nodeName === 'textarea') {
    transferInputData(node, clone);
  }
  transferData('canvas', node, clone, transferCanvasData);
  transferData('input, textarea, select', node, clone, transferInputData);
  return clone;
}
/** Matches elements between an element and its clone and allows for their data to be cloned. */
function transferData(selector, node, clone, callback) {
  const descendantElements = node.querySelectorAll(selector);
  if (descendantElements.length) {
    const cloneElements = clone.querySelectorAll(selector);
    for (let i = 0; i < descendantElements.length; i++) {
      callback(descendantElements[i], cloneElements[i]);
    }
  }
}
// Counter for unique cloned radio button names.
let cloneUniqueId = 0;
/** Transfers the data of one input element to another. */
function transferInputData(source, clone) {
  // Browsers throw an error when assigning the value of a file input programmatically.
  if (clone.type !== 'file') {
    clone.value = source.value;
  }
  // Radio button `name` attributes must be unique for radio button groups
  // otherwise original radio buttons can lose their checked state
  // once the clone is inserted in the DOM.
  if (clone.type === 'radio' && clone.name) {
    clone.name = `mat-clone-${clone.name}-${cloneUniqueId++}`;
  }
}
/** Transfers the data of one canvas element to another. */
function transferCanvasData(source, clone) {
  const context = clone.getContext('2d');
  if (context) {
    // In some cases `drawImage` can throw (e.g. if the canvas size is 0x0).
    // We can't do much about it so just ignore the error.
    try {
      context.drawImage(source, 0, 0);
    } catch {}
  }
}

/** Gets a mutable version of an element's bounding `DOMRect`. */
function getMutableClientRect(element) {
  const rect = element.getBoundingClientRect();
  // We need to clone the `clientRect` here, because all the values on it are readonly
  // and we need to be able to update them. Also we can't use a spread here, because
  // the values on a `DOMRect` aren't own properties. See:
  // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
  return {
    top: rect.top,
    right: rect.right,
    bottom: rect.bottom,
    left: rect.left,
    width: rect.width,
    height: rect.height,
    x: rect.x,
    y: rect.y
  };
}
/**
 * Checks whether some coordinates are within a `DOMRect`.
 * @param clientRect DOMRect that is being checked.
 * @param x Coordinates along the X axis.
 * @param y Coordinates along the Y axis.
 */
function isInsideClientRect(clientRect, x, y) {
  const {
    top,
    bottom,
    left,
    right
  } = clientRect;
  return y >= top && y <= bottom && x >= left && x <= right;
}
/**
 * Updates the top/left positions of a `DOMRect`, as well as their bottom/right counterparts.
 * @param domRect `DOMRect` that should be updated.
 * @param top Amount to add to the `top` position.
 * @param left Amount to add to the `left` position.
 */
function adjustDomRect(domRect, top, left) {
  domRect.top += top;
  domRect.bottom = domRect.top + domRect.height;
  domRect.left += left;
  domRect.right = domRect.left + domRect.width;
}
/**
 * Checks whether the pointer coordinates are close to a DOMRect.
 * @param rect DOMRect to check against.
 * @param threshold Threshold around the DOMRect.
 * @param pointerX Coordinates along the X axis.
 * @param pointerY Coordinates along the Y axis.
 */
function isPointerNearDomRect(rect, threshold, pointerX, pointerY) {
  const {
    top,
    right,
    bottom,
    left,
    width,
    height
  } = rect;
  const xThreshold = width * threshold;
  const yThreshold = height * threshold;
  return pointerY > top - yThreshold && pointerY < bottom + yThreshold && pointerX > left - xThreshold && pointerX < right + xThreshold;
}

/** Keeps track of the scroll position and dimensions of the parents of an element. */
class ParentPositionTracker {
  constructor(_document) {
    this._document = _document;
    /** Cached positions of the scrollable parent elements. */
    this.positions = new Map();
  }
  /** Clears the cached positions. */
  clear() {
    this.positions.clear();
  }
  /** Caches the positions. Should be called at the beginning of a drag sequence. */
  cache(elements) {
    this.clear();
    this.positions.set(this._document, {
      scrollPosition: this.getViewportScrollPosition()
    });
    elements.forEach(element => {
      this.positions.set(element, {
        scrollPosition: {
          top: element.scrollTop,
          left: element.scrollLeft
        },
        clientRect: getMutableClientRect(element)
      });
    });
  }
  /** Handles scrolling while a drag is taking place. */
  handleScroll(event) {
    const target = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getEventTarget)(event);
    const cachedPosition = this.positions.get(target);
    if (!cachedPosition) {
      return null;
    }
    const scrollPosition = cachedPosition.scrollPosition;
    let newTop;
    let newLeft;
    if (target === this._document) {
      const viewportScrollPosition = this.getViewportScrollPosition();
      newTop = viewportScrollPosition.top;
      newLeft = viewportScrollPosition.left;
    } else {
      newTop = target.scrollTop;
      newLeft = target.scrollLeft;
    }
    const topDifference = scrollPosition.top - newTop;
    const leftDifference = scrollPosition.left - newLeft;
    // Go through and update the cached positions of the scroll
    // parents that are inside the element that was scrolled.
    this.positions.forEach((position, node) => {
      if (position.clientRect && target !== node && target.contains(node)) {
        adjustDomRect(position.clientRect, topDifference, leftDifference);
      }
    });
    scrollPosition.top = newTop;
    scrollPosition.left = newLeft;
    return {
      top: topDifference,
      left: leftDifference
    };
  }
  /**
   * Gets the scroll position of the viewport. Note that we use the scrollX and scrollY directly,
   * instead of going through the `ViewportRuler`, because the first value the ruler looks at is
   * the top/left offset of the `document.documentElement` which works for most cases, but breaks
   * if the element is offset by something like the `BlockScrollStrategy`.
   */
  getViewportScrollPosition() {
    return {
      top: window.scrollY,
      left: window.scrollX
    };
  }
}

/**
 * Gets the root HTML element of an embedded view.
 * If the root is not an HTML element it gets wrapped in one.
 */
function getRootNode(viewRef, _document) {
  const rootNodes = viewRef.rootNodes;
  if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
    return rootNodes[0];
  }
  const wrapper = _document.createElement('div');
  rootNodes.forEach(node => wrapper.appendChild(node));
  return wrapper;
}

/**
 * Shallow-extends a stylesheet object with another stylesheet-like object.
 * Note that the keys in `source` have to be dash-cased.
 * @docs-private
 */
function extendStyles(dest, source, importantProperties) {
  for (let key in source) {
    if (source.hasOwnProperty(key)) {
      const value = source[key];
      if (value) {
        dest.setProperty(key, value, importantProperties?.has(key) ? 'important' : '');
      } else {
        dest.removeProperty(key);
      }
    }
  }
  return dest;
}
/**
 * Toggles whether the native drag interactions should be enabled for an element.
 * @param element Element on which to toggle the drag interactions.
 * @param enable Whether the drag interactions should be enabled.
 * @docs-private
 */
function toggleNativeDragInteractions(element, enable) {
  const userSelect = enable ? '' : 'none';
  extendStyles(element.style, {
    'touch-action': enable ? '' : 'none',
    '-webkit-user-drag': enable ? '' : 'none',
    '-webkit-tap-highlight-color': enable ? '' : 'transparent',
    'user-select': userSelect,
    '-ms-user-select': userSelect,
    '-webkit-user-select': userSelect,
    '-moz-user-select': userSelect
  });
}
/**
 * Toggles whether an element is visible while preserving its dimensions.
 * @param element Element whose visibility to toggle
 * @param enable Whether the element should be visible.
 * @param importantProperties Properties to be set as `!important`.
 * @docs-private
 */
function toggleVisibility(element, enable, importantProperties) {
  extendStyles(element.style, {
    position: enable ? '' : 'fixed',
    top: enable ? '' : '0',
    opacity: enable ? '' : '0',
    left: enable ? '' : '-999em'
  }, importantProperties);
}
/**
 * Combines a transform string with an optional other transform
 * that exited before the base transform was applied.
 */
function combineTransforms(transform, initialTransform) {
  return initialTransform && initialTransform != 'none' ? transform + ' ' + initialTransform : transform;
}
/**
 * Matches the target element's size to the source's size.
 * @param target Element that needs to be resized.
 * @param sourceRect Dimensions of the source element.
 */
function matchElementSize(target, sourceRect) {
  target.style.width = `${sourceRect.width}px`;
  target.style.height = `${sourceRect.height}px`;
  target.style.transform = getTransform(sourceRect.left, sourceRect.top);
}
/**
 * Gets a 3d `transform` that can be applied to an element.
 * @param x Desired position of the element along the X axis.
 * @param y Desired position of the element along the Y axis.
 */
function getTransform(x, y) {
  // Round the transforms since some browsers will
  // blur the elements for sub-pixel transforms.
  return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;
}

/** Parses a CSS time value to milliseconds. */
function parseCssTimeUnitsToMs(value) {
  // Some browsers will return it in seconds, whereas others will return milliseconds.
  const multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
  return parseFloat(value) * multiplier;
}
/** Gets the transform transition duration, including the delay, of an element in milliseconds. */
function getTransformTransitionDurationInMs(element) {
  const computedStyle = getComputedStyle(element);
  const transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
  const property = transitionedProperties.find(prop => prop === 'transform' || prop === 'all');
  // If there's no transition for `all` or `transform`, we shouldn't do anything.
  if (!property) {
    return 0;
  }
  // Get the index of the property that we're interested in and match
  // it up to the same index in `transition-delay` and `transition-duration`.
  const propertyIndex = transitionedProperties.indexOf(property);
  const rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
  const rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
  return parseCssTimeUnitsToMs(rawDurations[propertyIndex]) + parseCssTimeUnitsToMs(rawDelays[propertyIndex]);
}
/** Parses out multiple values from a computed style into an array. */
function parseCssPropertyValue(computedStyle, name) {
  const value = computedStyle.getPropertyValue(name);
  return value.split(',').map(part => part.trim());
}

/** Inline styles to be set as `!important` while dragging. */
const importantProperties = new Set([
// Needs to be important, because some `mat-table` sets `position: sticky !important`. See #22781.
'position']);
class PreviewRef {
  get element() {
    return this._preview;
  }
  constructor(_document, _rootElement, _direction, _initialDomRect, _previewTemplate, _previewClass, _pickupPositionOnPage, _initialTransform, _zIndex) {
    this._document = _document;
    this._rootElement = _rootElement;
    this._direction = _direction;
    this._initialDomRect = _initialDomRect;
    this._previewTemplate = _previewTemplate;
    this._previewClass = _previewClass;
    this._pickupPositionOnPage = _pickupPositionOnPage;
    this._initialTransform = _initialTransform;
    this._zIndex = _zIndex;
  }
  attach(parent) {
    this._preview = this._createPreview();
    parent.appendChild(this._preview);
    // The null check is necessary for browsers that don't support the popover API.
    // Note that we use a string access for compatibility with Closure.
    if (supportsPopover(this._preview)) {
      this._preview['showPopover']();
    }
  }
  destroy() {
    this._preview.remove();
    this._previewEmbeddedView?.destroy();
    this._preview = this._previewEmbeddedView = null;
  }
  setTransform(value) {
    this._preview.style.transform = value;
  }
  getBoundingClientRect() {
    return this._preview.getBoundingClientRect();
  }
  addClass(className) {
    this._preview.classList.add(className);
  }
  getTransitionDuration() {
    return getTransformTransitionDurationInMs(this._preview);
  }
  addEventListener(name, handler) {
    this._preview.addEventListener(name, handler);
  }
  removeEventListener(name, handler) {
    this._preview.removeEventListener(name, handler);
  }
  _createPreview() {
    const previewConfig = this._previewTemplate;
    const previewClass = this._previewClass;
    const previewTemplate = previewConfig ? previewConfig.template : null;
    let preview;
    if (previewTemplate && previewConfig) {
      // Measure the element before we've inserted the preview
      // since the insertion could throw off the measurement.
      const rootRect = previewConfig.matchSize ? this._initialDomRect : null;
      const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
      viewRef.detectChanges();
      preview = getRootNode(viewRef, this._document);
      this._previewEmbeddedView = viewRef;
      if (previewConfig.matchSize) {
        matchElementSize(preview, rootRect);
      } else {
        preview.style.transform = getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);
      }
    } else {
      preview = deepCloneNode(this._rootElement);
      matchElementSize(preview, this._initialDomRect);
      if (this._initialTransform) {
        preview.style.transform = this._initialTransform;
      }
    }
    extendStyles(preview.style, {
      // It's important that we disable the pointer events on the preview, because
      // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
      'pointer-events': 'none',
      // If the preview has a margin, it can throw off our positioning so we reset it. The reset
      // value for `margin-right` needs to be `auto` when opened as a popover, because our
      // positioning is always top/left based, but native popover seems to position itself
      // to the top/right if `<html>` or `<body>` have `dir="rtl"` (see #29604). Setting it
      // to `auto` pushed it to the top/left corner in RTL and is a noop in LTR.
      'margin': supportsPopover(preview) ? '0 auto 0 0' : '0',
      'position': 'fixed',
      'top': '0',
      'left': '0',
      'z-index': this._zIndex + ''
    }, importantProperties);
    toggleNativeDragInteractions(preview, false);
    preview.classList.add('cdk-drag-preview');
    preview.setAttribute('popover', 'manual');
    preview.setAttribute('dir', this._direction);
    if (previewClass) {
      if (Array.isArray(previewClass)) {
        previewClass.forEach(className => preview.classList.add(className));
      } else {
        preview.classList.add(previewClass);
      }
    }
    return preview;
  }
}
/** Checks whether a specific element supports the popover API. */
function supportsPopover(element) {
  return 'showPopover' in element;
}

/** Options that can be used to bind a passive event listener. */
const passiveEventListenerOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__.normalizePassiveListenerOptions)({
  passive: true
});
/** Options that can be used to bind an active event listener. */
const activeEventListenerOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__.normalizePassiveListenerOptions)({
  passive: false
});
/** Event options that can be used to bind an active, capturing event. */
const activeCapturingEventOptions$1 = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__.normalizePassiveListenerOptions)({
  passive: false,
  capture: true
});
/**
 * Time in milliseconds for which to ignore mouse events, after
 * receiving a touch event. Used to avoid doing double work for
 * touch devices where the browser fires fake mouse events, in
 * addition to touch events.
 */
const MOUSE_EVENT_IGNORE_TIME = 800;
/** Inline styles to be set as `!important` while dragging. */
const dragImportantProperties = new Set([
// Needs to be important, because some `mat-table` sets `position: sticky !important`. See #22781.
'position']);
/**
 * Reference to a draggable item. Used to manipulate or dispose of the item.
 */
class DragRef {
  /** Whether starting to drag this element is disabled. */
  get disabled() {
    return this._disabled || !!(this._dropContainer && this._dropContainer.disabled);
  }
  set disabled(value) {
    if (value !== this._disabled) {
      this._disabled = value;
      this._toggleNativeDragInteractions();
      this._handles.forEach(handle => toggleNativeDragInteractions(handle, value));
    }
  }
  constructor(element, _config, _document, _ngZone, _viewportRuler, _dragDropRegistry) {
    this._config = _config;
    this._document = _document;
    this._ngZone = _ngZone;
    this._viewportRuler = _viewportRuler;
    this._dragDropRegistry = _dragDropRegistry;
    /**
     * CSS `transform` applied to the element when it isn't being dragged. We need a
     * passive transform in order for the dragged element to retain its new position
     * after the user has stopped dragging and because we need to know the relative
     * position in case they start dragging again. This corresponds to `element.style.transform`.
     */
    this._passiveTransform = {
      x: 0,
      y: 0
    };
    /** CSS `transform` that is applied to the element while it's being dragged. */
    this._activeTransform = {
      x: 0,
      y: 0
    };
    /**
     * Whether the dragging sequence has been started. Doesn't
     * necessarily mean that the element has been moved.
     */
    this._hasStartedDragging = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.signal)(false);
    /** Emits when the item is being moved. */
    this._moveEvents = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Subscription to pointer movement events. */
    this._pointerMoveSubscription = rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription.EMPTY;
    /** Subscription to the event that is dispatched when the user lifts their pointer. */
    this._pointerUpSubscription = rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription.EMPTY;
    /** Subscription to the viewport being scrolled. */
    this._scrollSubscription = rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription.EMPTY;
    /** Subscription to the viewport being resized. */
    this._resizeSubscription = rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription.EMPTY;
    /** Cached reference to the boundary element. */
    this._boundaryElement = null;
    /** Whether the native dragging interactions have been enabled on the root element. */
    this._nativeInteractionsEnabled = true;
    /** Elements that can be used to drag the draggable item. */
    this._handles = [];
    /** Registered handles that are currently disabled. */
    this._disabledHandles = new Set();
    /** Layout direction of the item. */
    this._direction = 'ltr';
    /**
     * Amount of milliseconds to wait after the user has put their
     * pointer down before starting to drag the element.
     */
    this.dragStartDelay = 0;
    /**
     * If the parent of the dragged element has a `scale` transform, it can throw off the
     * positioning when the user starts dragging. Use this input to notify the CDK of the scale.
     */
    this.scale = 1;
    this._disabled = false;
    /** Emits as the drag sequence is being prepared. */
    this.beforeStarted = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user starts dragging the item. */
    this.started = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user has released a drag item, before any animations have started. */
    this.released = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user stops dragging an item in the container. */
    this.ended = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user has moved the item into a new container. */
    this.entered = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user removes the item its container by dragging it into another container. */
    this.exited = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user drops the item inside a container. */
    this.dropped = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Emits as the user is dragging the item. Use with caution,
     * because this event will fire for every pixel that the user has dragged.
     */
    this.moved = this._moveEvents;
    /** Handler for the `mousedown`/`touchstart` events. */
    this._pointerDown = event => {
      this.beforeStarted.next();
      // Delegate the event based on whether it started from a handle or the element itself.
      if (this._handles.length) {
        const targetHandle = this._getTargetHandle(event);
        if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {
          this._initializeDragSequence(targetHandle, event);
        }
      } else if (!this.disabled) {
        this._initializeDragSequence(this._rootElement, event);
      }
    };
    /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
    this._pointerMove = event => {
      const pointerPosition = this._getPointerPositionOnPage(event);
      if (!this._hasStartedDragging()) {
        const distanceX = Math.abs(pointerPosition.x - this._pickupPositionOnPage.x);
        const distanceY = Math.abs(pointerPosition.y - this._pickupPositionOnPage.y);
        const isOverThreshold = distanceX + distanceY >= this._config.dragStartThreshold;
        // Only start dragging after the user has moved more than the minimum distance in either
        // direction. Note that this is preferable over doing something like `skip(minimumDistance)`
        // in the `pointerMove` subscription, because we're not guaranteed to have one move event
        // per pixel of movement (e.g. if the user moves their pointer quickly).
        if (isOverThreshold) {
          const isDelayElapsed = Date.now() >= this._dragStartTime + this._getDragStartDelay(event);
          const container = this._dropContainer;
          if (!isDelayElapsed) {
            this._endDragSequence(event);
            return;
          }
          // Prevent other drag sequences from starting while something in the container is still
          // being dragged. This can happen while we're waiting for the drop animation to finish
          // and can cause errors, because some elements might still be moving around.
          if (!container || !container.isDragging() && !container.isReceiving()) {
            // Prevent the default action as soon as the dragging sequence is considered as
            // "started" since waiting for the next event can allow the device to begin scrolling.
            if (event.cancelable) {
              event.preventDefault();
            }
            this._hasStartedDragging.set(true);
            this._ngZone.run(() => this._startDragSequence(event));
          }
        }
        return;
      }
      // We prevent the default action down here so that we know that dragging has started. This is
      // important for touch devices where doing this too early can unnecessarily block scrolling,
      // if there's a dragging delay.
      if (event.cancelable) {
        event.preventDefault();
      }
      const constrainedPointerPosition = this._getConstrainedPointerPosition(pointerPosition);
      this._hasMoved = true;
      this._lastKnownPointerPosition = pointerPosition;
      this._updatePointerDirectionDelta(constrainedPointerPosition);
      if (this._dropContainer) {
        this._updateActiveDropContainer(constrainedPointerPosition, pointerPosition);
      } else {
        // If there's a position constraint function, we want the element's top/left to be at the
        // specific position on the page. Use the initial position as a reference if that's the case.
        const offset = this.constrainPosition ? this._initialDomRect : this._pickupPositionOnPage;
        const activeTransform = this._activeTransform;
        activeTransform.x = constrainedPointerPosition.x - offset.x + this._passiveTransform.x;
        activeTransform.y = constrainedPointerPosition.y - offset.y + this._passiveTransform.y;
        this._applyRootElementTransform(activeTransform.x, activeTransform.y);
      }
      // Since this event gets fired for every pixel while dragging, we only
      // want to fire it if the consumer opted into it. Also we have to
      // re-enter the zone because we run all of the events on the outside.
      if (this._moveEvents.observers.length) {
        this._ngZone.run(() => {
          this._moveEvents.next({
            source: this,
            pointerPosition: constrainedPointerPosition,
            event,
            distance: this._getDragDistance(constrainedPointerPosition),
            delta: this._pointerDirectionDelta
          });
        });
      }
    };
    /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
    this._pointerUp = event => {
      this._endDragSequence(event);
    };
    /** Handles a native `dragstart` event. */
    this._nativeDragStart = event => {
      if (this._handles.length) {
        const targetHandle = this._getTargetHandle(event);
        if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {
          event.preventDefault();
        }
      } else if (!this.disabled) {
        // Usually this isn't necessary since the we prevent the default action in `pointerDown`,
        // but some cases like dragging of links can slip through (see #24403).
        event.preventDefault();
      }
    };
    this.withRootElement(element).withParent(_config.parentDragRef || null);
    this._parentPositions = new ParentPositionTracker(_document);
    _dragDropRegistry.registerDragItem(this);
  }
  /**
   * Returns the element that is being used as a placeholder
   * while the current element is being dragged.
   */
  getPlaceholderElement() {
    return this._placeholder;
  }
  /** Returns the root draggable element. */
  getRootElement() {
    return this._rootElement;
  }
  /**
   * Gets the currently-visible element that represents the drag item.
   * While dragging this is the placeholder, otherwise it's the root element.
   */
  getVisibleElement() {
    return this.isDragging() ? this.getPlaceholderElement() : this.getRootElement();
  }
  /** Registers the handles that can be used to drag the element. */
  withHandles(handles) {
    this._handles = handles.map(handle => (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(handle));
    this._handles.forEach(handle => toggleNativeDragInteractions(handle, this.disabled));
    this._toggleNativeDragInteractions();
    // Delete any lingering disabled handles that may have been destroyed. Note that we re-create
    // the set, rather than iterate over it and filter out the destroyed handles, because while
    // the ES spec allows for sets to be modified while they're being iterated over, some polyfills
    // use an array internally which may throw an error.
    const disabledHandles = new Set();
    this._disabledHandles.forEach(handle => {
      if (this._handles.indexOf(handle) > -1) {
        disabledHandles.add(handle);
      }
    });
    this._disabledHandles = disabledHandles;
    return this;
  }
  /**
   * Registers the template that should be used for the drag preview.
   * @param template Template that from which to stamp out the preview.
   */
  withPreviewTemplate(template) {
    this._previewTemplate = template;
    return this;
  }
  /**
   * Registers the template that should be used for the drag placeholder.
   * @param template Template that from which to stamp out the placeholder.
   */
  withPlaceholderTemplate(template) {
    this._placeholderTemplate = template;
    return this;
  }
  /**
   * Sets an alternate drag root element. The root element is the element that will be moved as
   * the user is dragging. Passing an alternate root element is useful when trying to enable
   * dragging on an element that you might not have access to.
   */
  withRootElement(rootElement) {
    const element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(rootElement);
    if (element !== this._rootElement) {
      if (this._rootElement) {
        this._removeRootElementListeners(this._rootElement);
      }
      this._ngZone.runOutsideAngular(() => {
        element.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
        element.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
        element.addEventListener('dragstart', this._nativeDragStart, activeEventListenerOptions);
      });
      this._initialTransform = undefined;
      this._rootElement = element;
    }
    if (typeof SVGElement !== 'undefined' && this._rootElement instanceof SVGElement) {
      this._ownerSVGElement = this._rootElement.ownerSVGElement;
    }
    return this;
  }
  /**
   * Element to which the draggable's position will be constrained.
   */
  withBoundaryElement(boundaryElement) {
    this._boundaryElement = boundaryElement ? (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(boundaryElement) : null;
    this._resizeSubscription.unsubscribe();
    if (boundaryElement) {
      this._resizeSubscription = this._viewportRuler.change(10).subscribe(() => this._containInsideBoundaryOnResize());
    }
    return this;
  }
  /** Sets the parent ref that the ref is nested in.  */
  withParent(parent) {
    this._parentDragRef = parent;
    return this;
  }
  /** Removes the dragging functionality from the DOM element. */
  dispose() {
    this._removeRootElementListeners(this._rootElement);
    // Do this check before removing from the registry since it'll
    // stop being considered as dragged once it is removed.
    if (this.isDragging()) {
      // Since we move out the element to the end of the body while it's being
      // dragged, we have to make sure that it's removed if it gets destroyed.
      this._rootElement?.remove();
    }
    this._anchor?.remove();
    this._destroyPreview();
    this._destroyPlaceholder();
    this._dragDropRegistry.removeDragItem(this);
    this._removeListeners();
    this.beforeStarted.complete();
    this.started.complete();
    this.released.complete();
    this.ended.complete();
    this.entered.complete();
    this.exited.complete();
    this.dropped.complete();
    this._moveEvents.complete();
    this._handles = [];
    this._disabledHandles.clear();
    this._dropContainer = undefined;
    this._resizeSubscription.unsubscribe();
    this._parentPositions.clear();
    this._boundaryElement = this._rootElement = this._ownerSVGElement = this._placeholderTemplate = this._previewTemplate = this._anchor = this._parentDragRef = null;
  }
  /** Checks whether the element is currently being dragged. */
  isDragging() {
    return this._hasStartedDragging() && this._dragDropRegistry.isDragging(this);
  }
  /** Resets a standalone drag item to its initial position. */
  reset() {
    this._rootElement.style.transform = this._initialTransform || '';
    this._activeTransform = {
      x: 0,
      y: 0
    };
    this._passiveTransform = {
      x: 0,
      y: 0
    };
  }
  /**
   * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.
   * @param handle Handle element that should be disabled.
   */
  disableHandle(handle) {
    if (!this._disabledHandles.has(handle) && this._handles.indexOf(handle) > -1) {
      this._disabledHandles.add(handle);
      toggleNativeDragInteractions(handle, true);
    }
  }
  /**
   * Enables a handle, if it has been disabled.
   * @param handle Handle element to be enabled.
   */
  enableHandle(handle) {
    if (this._disabledHandles.has(handle)) {
      this._disabledHandles.delete(handle);
      toggleNativeDragInteractions(handle, this.disabled);
    }
  }
  /** Sets the layout direction of the draggable item. */
  withDirection(direction) {
    this._direction = direction;
    return this;
  }
  /** Sets the container that the item is part of. */
  _withDropContainer(container) {
    this._dropContainer = container;
  }
  /**
   * Gets the current position in pixels the draggable outside of a drop container.
   */
  getFreeDragPosition() {
    const position = this.isDragging() ? this._activeTransform : this._passiveTransform;
    return {
      x: position.x,
      y: position.y
    };
  }
  /**
   * Sets the current position in pixels the draggable outside of a drop container.
   * @param value New position to be set.
   */
  setFreeDragPosition(value) {
    this._activeTransform = {
      x: 0,
      y: 0
    };
    this._passiveTransform.x = value.x;
    this._passiveTransform.y = value.y;
    if (!this._dropContainer) {
      this._applyRootElementTransform(value.x, value.y);
    }
    return this;
  }
  /**
   * Sets the container into which to insert the preview element.
   * @param value Container into which to insert the preview.
   */
  withPreviewContainer(value) {
    this._previewContainer = value;
    return this;
  }
  /** Updates the item's sort order based on the last-known pointer position. */
  _sortFromLastPointerPosition() {
    const position = this._lastKnownPointerPosition;
    if (position && this._dropContainer) {
      this._updateActiveDropContainer(this._getConstrainedPointerPosition(position), position);
    }
  }
  /** Unsubscribes from the global subscriptions. */
  _removeListeners() {
    this._pointerMoveSubscription.unsubscribe();
    this._pointerUpSubscription.unsubscribe();
    this._scrollSubscription.unsubscribe();
    this._getShadowRoot()?.removeEventListener('selectstart', shadowDomSelectStart, activeCapturingEventOptions$1);
  }
  /** Destroys the preview element and its ViewRef. */
  _destroyPreview() {
    this._preview?.destroy();
    this._preview = null;
  }
  /** Destroys the placeholder element and its ViewRef. */
  _destroyPlaceholder() {
    this._placeholder?.remove();
    this._placeholderRef?.destroy();
    this._placeholder = this._placeholderRef = null;
  }
  /**
   * Clears subscriptions and stops the dragging sequence.
   * @param event Browser event object that ended the sequence.
   */
  _endDragSequence(event) {
    // Note that here we use `isDragging` from the service, rather than from `this`.
    // The difference is that the one from the service reflects whether a dragging sequence
    // has been initiated, whereas the one on `this` includes whether the user has passed
    // the minimum dragging threshold.
    if (!this._dragDropRegistry.isDragging(this)) {
      return;
    }
    this._removeListeners();
    this._dragDropRegistry.stopDragging(this);
    this._toggleNativeDragInteractions();
    if (this._handles) {
      this._rootElement.style.webkitTapHighlightColor = this._rootElementTapHighlight;
    }
    if (!this._hasStartedDragging()) {
      return;
    }
    this.released.next({
      source: this,
      event
    });
    if (this._dropContainer) {
      // Stop scrolling immediately, instead of waiting for the animation to finish.
      this._dropContainer._stopScrolling();
      this._animatePreviewToPlaceholder().then(() => {
        this._cleanupDragArtifacts(event);
        this._cleanupCachedDimensions();
        this._dragDropRegistry.stopDragging(this);
      });
    } else {
      // Convert the active transform into a passive one. This means that next time
      // the user starts dragging the item, its position will be calculated relatively
      // to the new passive transform.
      this._passiveTransform.x = this._activeTransform.x;
      const pointerPosition = this._getPointerPositionOnPage(event);
      this._passiveTransform.y = this._activeTransform.y;
      this._ngZone.run(() => {
        this.ended.next({
          source: this,
          distance: this._getDragDistance(pointerPosition),
          dropPoint: pointerPosition,
          event
        });
      });
      this._cleanupCachedDimensions();
      this._dragDropRegistry.stopDragging(this);
    }
  }
  /** Starts the dragging sequence. */
  _startDragSequence(event) {
    if (isTouchEvent(event)) {
      this._lastTouchEventTime = Date.now();
    }
    this._toggleNativeDragInteractions();
    // Needs to happen before the root element is moved.
    const shadowRoot = this._getShadowRoot();
    const dropContainer = this._dropContainer;
    if (shadowRoot) {
      // In some browsers the global `selectstart` that we maintain in the `DragDropRegistry`
      // doesn't cross the shadow boundary so we have to prevent it at the shadow root (see #28792).
      this._ngZone.runOutsideAngular(() => {
        shadowRoot.addEventListener('selectstart', shadowDomSelectStart, activeCapturingEventOptions$1);
      });
    }
    if (dropContainer) {
      const element = this._rootElement;
      const parent = element.parentNode;
      const placeholder = this._placeholder = this._createPlaceholderElement();
      const anchor = this._anchor = this._anchor || this._document.createComment(typeof ngDevMode === 'undefined' || ngDevMode ? 'cdk-drag-anchor' : '');
      // Insert an anchor node so that we can restore the element's position in the DOM.
      parent.insertBefore(anchor, element);
      // There's no risk of transforms stacking when inside a drop container so
      // we can keep the initial transform up to date any time dragging starts.
      this._initialTransform = element.style.transform || '';
      // Create the preview after the initial transform has
      // been cached, because it can be affected by the transform.
      this._preview = new PreviewRef(this._document, this._rootElement, this._direction, this._initialDomRect, this._previewTemplate || null, this.previewClass || null, this._pickupPositionOnPage, this._initialTransform, this._config.zIndex || 1000);
      this._preview.attach(this._getPreviewInsertionPoint(parent, shadowRoot));
      // We move the element out at the end of the body and we make it hidden, because keeping it in
      // place will throw off the consumer's `:last-child` selectors. We can't remove the element
      // from the DOM completely, because iOS will stop firing all subsequent events in the chain.
      toggleVisibility(element, false, dragImportantProperties);
      this._document.body.appendChild(parent.replaceChild(placeholder, element));
      this.started.next({
        source: this,
        event
      }); // Emit before notifying the container.
      dropContainer.start();
      this._initialContainer = dropContainer;
      this._initialIndex = dropContainer.getItemIndex(this);
    } else {
      this.started.next({
        source: this,
        event
      });
      this._initialContainer = this._initialIndex = undefined;
    }
    // Important to run after we've called `start` on the parent container
    // so that it has had time to resolve its scrollable parents.
    this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);
  }
  /**
   * Sets up the different variables and subscriptions
   * that will be necessary for the dragging sequence.
   * @param referenceElement Element that started the drag sequence.
   * @param event Browser event object that started the sequence.
   */
  _initializeDragSequence(referenceElement, event) {
    // Stop propagation if the item is inside another
    // draggable so we don't start multiple drag sequences.
    if (this._parentDragRef) {
      event.stopPropagation();
    }
    const isDragging = this.isDragging();
    const isTouchSequence = isTouchEvent(event);
    const isAuxiliaryMouseButton = !isTouchSequence && event.button !== 0;
    const rootElement = this._rootElement;
    const target = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getEventTarget)(event);
    const isSyntheticEvent = !isTouchSequence && this._lastTouchEventTime && this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();
    const isFakeEvent = isTouchSequence ? (0,_angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_5__.isFakeTouchstartFromScreenReader)(event) : (0,_angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_5__.isFakeMousedownFromScreenReader)(event);
    // If the event started from an element with the native HTML drag&drop, it'll interfere
    // with our own dragging (e.g. `img` tags do it by default). Prevent the default action
    // to stop it from happening. Note that preventing on `dragstart` also seems to work, but
    // it's flaky and it fails if the user drags it away quickly. Also note that we only want
    // to do this for `mousedown` since doing the same for `touchstart` will stop any `click`
    // events from firing on touch devices.
    if (target && target.draggable && event.type === 'mousedown') {
      event.preventDefault();
    }
    // Abort if the user is already dragging or is using a mouse button other than the primary one.
    if (isDragging || isAuxiliaryMouseButton || isSyntheticEvent || isFakeEvent) {
      return;
    }
    // If we've got handles, we need to disable the tap highlight on the entire root element,
    // otherwise iOS will still add it, even though all the drag interactions on the handle
    // are disabled.
    if (this._handles.length) {
      const rootStyles = rootElement.style;
      this._rootElementTapHighlight = rootStyles.webkitTapHighlightColor || '';
      rootStyles.webkitTapHighlightColor = 'transparent';
    }
    this._hasMoved = false;
    this._hasStartedDragging.set(this._hasMoved);
    // Avoid multiple subscriptions and memory leaks when multi touch
    // (isDragging check above isn't enough because of possible temporal and/or dimensional delays)
    this._removeListeners();
    this._initialDomRect = this._rootElement.getBoundingClientRect();
    this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
    this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
    this._scrollSubscription = this._dragDropRegistry.scrolled(this._getShadowRoot()).subscribe(scrollEvent => this._updateOnScroll(scrollEvent));
    if (this._boundaryElement) {
      this._boundaryRect = getMutableClientRect(this._boundaryElement);
    }
    // If we have a custom preview we can't know ahead of time how large it'll be so we position
    // it next to the cursor. The exception is when the consumer has opted into making the preview
    // the same size as the root element, in which case we do know the size.
    const previewTemplate = this._previewTemplate;
    this._pickupPositionInElement = previewTemplate && previewTemplate.template && !previewTemplate.matchSize ? {
      x: 0,
      y: 0
    } : this._getPointerPositionInElement(this._initialDomRect, referenceElement, event);
    const pointerPosition = this._pickupPositionOnPage = this._lastKnownPointerPosition = this._getPointerPositionOnPage(event);
    this._pointerDirectionDelta = {
      x: 0,
      y: 0
    };
    this._pointerPositionAtLastDirectionChange = {
      x: pointerPosition.x,
      y: pointerPosition.y
    };
    this._dragStartTime = Date.now();
    this._dragDropRegistry.startDragging(this, event);
  }
  /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */
  _cleanupDragArtifacts(event) {
    // Restore the element's visibility and insert it at its old position in the DOM.
    // It's important that we maintain the position, because moving the element around in the DOM
    // can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,
    // while moving the existing elements in all other cases.
    toggleVisibility(this._rootElement, true, dragImportantProperties);
    this._anchor.parentNode.replaceChild(this._rootElement, this._anchor);
    this._destroyPreview();
    this._destroyPlaceholder();
    this._initialDomRect = this._boundaryRect = this._previewRect = this._initialTransform = undefined;
    // Re-enter the NgZone since we bound `document` events on the outside.
    this._ngZone.run(() => {
      const container = this._dropContainer;
      const currentIndex = container.getItemIndex(this);
      const pointerPosition = this._getPointerPositionOnPage(event);
      const distance = this._getDragDistance(pointerPosition);
      const isPointerOverContainer = container._isOverContainer(pointerPosition.x, pointerPosition.y);
      this.ended.next({
        source: this,
        distance,
        dropPoint: pointerPosition,
        event
      });
      this.dropped.next({
        item: this,
        currentIndex,
        previousIndex: this._initialIndex,
        container: container,
        previousContainer: this._initialContainer,
        isPointerOverContainer,
        distance,
        dropPoint: pointerPosition,
        event
      });
      container.drop(this, currentIndex, this._initialIndex, this._initialContainer, isPointerOverContainer, distance, pointerPosition, event);
      this._dropContainer = this._initialContainer;
    });
  }
  /**
   * Updates the item's position in its drop container, or moves it
   * into a new one, depending on its current drag position.
   */
  _updateActiveDropContainer({
    x,
    y
  }, {
    x: rawX,
    y: rawY
  }) {
    // Drop container that draggable has been moved into.
    let newContainer = this._initialContainer._getSiblingContainerFromPosition(this, x, y);
    // If we couldn't find a new container to move the item into, and the item has left its
    // initial container, check whether the it's over the initial container. This handles the
    // case where two containers are connected one way and the user tries to undo dragging an
    // item into a new container.
    if (!newContainer && this._dropContainer !== this._initialContainer && this._initialContainer._isOverContainer(x, y)) {
      newContainer = this._initialContainer;
    }
    if (newContainer && newContainer !== this._dropContainer) {
      this._ngZone.run(() => {
        // Notify the old container that the item has left.
        this.exited.next({
          item: this,
          container: this._dropContainer
        });
        this._dropContainer.exit(this);
        // Notify the new container that the item has entered.
        this._dropContainer = newContainer;
        this._dropContainer.enter(this, x, y, newContainer === this._initialContainer &&
        // If we're re-entering the initial container and sorting is disabled,
        // put item the into its starting index to begin with.
        newContainer.sortingDisabled ? this._initialIndex : undefined);
        this.entered.next({
          item: this,
          container: newContainer,
          currentIndex: newContainer.getItemIndex(this)
        });
      });
    }
    // Dragging may have been interrupted as a result of the events above.
    if (this.isDragging()) {
      this._dropContainer._startScrollingIfNecessary(rawX, rawY);
      this._dropContainer._sortItem(this, x, y, this._pointerDirectionDelta);
      if (this.constrainPosition) {
        this._applyPreviewTransform(x, y);
      } else {
        this._applyPreviewTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
      }
    }
  }
  /**
   * Animates the preview element from its current position to the location of the drop placeholder.
   * @returns Promise that resolves when the animation completes.
   */
  _animatePreviewToPlaceholder() {
    // If the user hasn't moved yet, the transitionend event won't fire.
    if (!this._hasMoved) {
      return Promise.resolve();
    }
    const placeholderRect = this._placeholder.getBoundingClientRect();
    // Apply the class that adds a transition to the preview.
    this._preview.addClass('cdk-drag-animating');
    // Move the preview to the placeholder position.
    this._applyPreviewTransform(placeholderRect.left, placeholderRect.top);
    // If the element doesn't have a `transition`, the `transitionend` event won't fire. Since
    // we need to trigger a style recalculation in order for the `cdk-drag-animating` class to
    // apply its style, we take advantage of the available info to figure out whether we need to
    // bind the event in the first place.
    const duration = this._preview.getTransitionDuration();
    if (duration === 0) {
      return Promise.resolve();
    }
    return this._ngZone.runOutsideAngular(() => {
      return new Promise(resolve => {
        const handler = event => {
          if (!event || this._preview && (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getEventTarget)(event) === this._preview.element && event.propertyName === 'transform') {
            this._preview?.removeEventListener('transitionend', handler);
            resolve();
            clearTimeout(timeout);
          }
        };
        // If a transition is short enough, the browser might not fire the `transitionend` event.
        // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
        // fire if the transition hasn't completed when it was supposed to.
        const timeout = setTimeout(handler, duration * 1.5);
        this._preview.addEventListener('transitionend', handler);
      });
    });
  }
  /** Creates an element that will be shown instead of the current element while dragging. */
  _createPlaceholderElement() {
    const placeholderConfig = this._placeholderTemplate;
    const placeholderTemplate = placeholderConfig ? placeholderConfig.template : null;
    let placeholder;
    if (placeholderTemplate) {
      this._placeholderRef = placeholderConfig.viewContainer.createEmbeddedView(placeholderTemplate, placeholderConfig.context);
      this._placeholderRef.detectChanges();
      placeholder = getRootNode(this._placeholderRef, this._document);
    } else {
      placeholder = deepCloneNode(this._rootElement);
    }
    // Stop pointer events on the preview so the user can't
    // interact with it while the preview is animating.
    placeholder.style.pointerEvents = 'none';
    placeholder.classList.add('cdk-drag-placeholder');
    return placeholder;
  }
  /**
   * Figures out the coordinates at which an element was picked up.
   * @param referenceElement Element that initiated the dragging.
   * @param event Event that initiated the dragging.
   */
  _getPointerPositionInElement(elementRect, referenceElement, event) {
    const handleElement = referenceElement === this._rootElement ? null : referenceElement;
    const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
    const point = isTouchEvent(event) ? event.targetTouches[0] : event;
    const scrollPosition = this._getViewportScrollPosition();
    const x = point.pageX - referenceRect.left - scrollPosition.left;
    const y = point.pageY - referenceRect.top - scrollPosition.top;
    return {
      x: referenceRect.left - elementRect.left + x,
      y: referenceRect.top - elementRect.top + y
    };
  }
  /** Determines the point of the page that was touched by the user. */
  _getPointerPositionOnPage(event) {
    const scrollPosition = this._getViewportScrollPosition();
    const point = isTouchEvent(event) ?
    // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
    // Also note that on real devices we're guaranteed for either `touches` or `changedTouches`
    // to have a value, but Firefox in device emulation mode has a bug where both can be empty
    // for `touchstart` and `touchend` so we fall back to a dummy object in order to avoid
    // throwing an error. The value returned here will be incorrect, but since this only
    // breaks inside a developer tool and the value is only used for secondary information,
    // we can get away with it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1615824.
    event.touches[0] || event.changedTouches[0] || {
      pageX: 0,
      pageY: 0
    } : event;
    const x = point.pageX - scrollPosition.left;
    const y = point.pageY - scrollPosition.top;
    // if dragging SVG element, try to convert from the screen coordinate system to the SVG
    // coordinate system
    if (this._ownerSVGElement) {
      const svgMatrix = this._ownerSVGElement.getScreenCTM();
      if (svgMatrix) {
        const svgPoint = this._ownerSVGElement.createSVGPoint();
        svgPoint.x = x;
        svgPoint.y = y;
        return svgPoint.matrixTransform(svgMatrix.inverse());
      }
    }
    return {
      x,
      y
    };
  }
  /** Gets the pointer position on the page, accounting for any position constraints. */
  _getConstrainedPointerPosition(point) {
    const dropContainerLock = this._dropContainer ? this._dropContainer.lockAxis : null;
    let {
      x,
      y
    } = this.constrainPosition ? this.constrainPosition(point, this, this._initialDomRect, this._pickupPositionInElement) : point;
    if (this.lockAxis === 'x' || dropContainerLock === 'x') {
      y = this._pickupPositionOnPage.y - (this.constrainPosition ? this._pickupPositionInElement.y : 0);
    } else if (this.lockAxis === 'y' || dropContainerLock === 'y') {
      x = this._pickupPositionOnPage.x - (this.constrainPosition ? this._pickupPositionInElement.x : 0);
    }
    if (this._boundaryRect) {
      // If not using a custom constrain we need to account for the pickup position in the element
      // otherwise we do not need to do this, as it has already been accounted for
      const {
        x: pickupX,
        y: pickupY
      } = !this.constrainPosition ? this._pickupPositionInElement : {
        x: 0,
        y: 0
      };
      const boundaryRect = this._boundaryRect;
      const {
        width: previewWidth,
        height: previewHeight
      } = this._getPreviewRect();
      const minY = boundaryRect.top + pickupY;
      const maxY = boundaryRect.bottom - (previewHeight - pickupY);
      const minX = boundaryRect.left + pickupX;
      const maxX = boundaryRect.right - (previewWidth - pickupX);
      x = clamp$1(x, minX, maxX);
      y = clamp$1(y, minY, maxY);
    }
    return {
      x,
      y
    };
  }
  /** Updates the current drag delta, based on the user's current pointer position on the page. */
  _updatePointerDirectionDelta(pointerPositionOnPage) {
    const {
      x,
      y
    } = pointerPositionOnPage;
    const delta = this._pointerDirectionDelta;
    const positionSinceLastChange = this._pointerPositionAtLastDirectionChange;
    // Amount of pixels the user has dragged since the last time the direction changed.
    const changeX = Math.abs(x - positionSinceLastChange.x);
    const changeY = Math.abs(y - positionSinceLastChange.y);
    // Because we handle pointer events on a per-pixel basis, we don't want the delta
    // to change for every pixel, otherwise anything that depends on it can look erratic.
    // To make the delta more consistent, we track how much the user has moved since the last
    // delta change and we only update it after it has reached a certain threshold.
    if (changeX > this._config.pointerDirectionChangeThreshold) {
      delta.x = x > positionSinceLastChange.x ? 1 : -1;
      positionSinceLastChange.x = x;
    }
    if (changeY > this._config.pointerDirectionChangeThreshold) {
      delta.y = y > positionSinceLastChange.y ? 1 : -1;
      positionSinceLastChange.y = y;
    }
    return delta;
  }
  /** Toggles the native drag interactions, based on how many handles are registered. */
  _toggleNativeDragInteractions() {
    if (!this._rootElement || !this._handles) {
      return;
    }
    const shouldEnable = this._handles.length > 0 || !this.isDragging();
    if (shouldEnable !== this._nativeInteractionsEnabled) {
      this._nativeInteractionsEnabled = shouldEnable;
      toggleNativeDragInteractions(this._rootElement, shouldEnable);
    }
  }
  /** Removes the manually-added event listeners from the root element. */
  _removeRootElementListeners(element) {
    element.removeEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
    element.removeEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
    element.removeEventListener('dragstart', this._nativeDragStart, activeEventListenerOptions);
  }
  /**
   * Applies a `transform` to the root element, taking into account any existing transforms on it.
   * @param x New transform value along the X axis.
   * @param y New transform value along the Y axis.
   */
  _applyRootElementTransform(x, y) {
    const scale = 1 / this.scale;
    const transform = getTransform(x * scale, y * scale);
    const styles = this._rootElement.style;
    // Cache the previous transform amount only after the first drag sequence, because
    // we don't want our own transforms to stack on top of each other.
    // Should be excluded none because none + translate3d(x, y, x) is invalid css
    if (this._initialTransform == null) {
      this._initialTransform = styles.transform && styles.transform != 'none' ? styles.transform : '';
    }
    // Preserve the previous `transform` value, if there was one. Note that we apply our own
    // transform before the user's, because things like rotation can affect which direction
    // the element will be translated towards.
    styles.transform = combineTransforms(transform, this._initialTransform);
  }
  /**
   * Applies a `transform` to the preview, taking into account any existing transforms on it.
   * @param x New transform value along the X axis.
   * @param y New transform value along the Y axis.
   */
  _applyPreviewTransform(x, y) {
    // Only apply the initial transform if the preview is a clone of the original element, otherwise
    // it could be completely different and the transform might not make sense anymore.
    const initialTransform = this._previewTemplate?.template ? undefined : this._initialTransform;
    const transform = getTransform(x, y);
    this._preview.setTransform(combineTransforms(transform, initialTransform));
  }
  /**
   * Gets the distance that the user has dragged during the current drag sequence.
   * @param currentPosition Current position of the user's pointer.
   */
  _getDragDistance(currentPosition) {
    const pickupPosition = this._pickupPositionOnPage;
    if (pickupPosition) {
      return {
        x: currentPosition.x - pickupPosition.x,
        y: currentPosition.y - pickupPosition.y
      };
    }
    return {
      x: 0,
      y: 0
    };
  }
  /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */
  _cleanupCachedDimensions() {
    this._boundaryRect = this._previewRect = undefined;
    this._parentPositions.clear();
  }
  /**
   * Checks whether the element is still inside its boundary after the viewport has been resized.
   * If not, the position is adjusted so that the element fits again.
   */
  _containInsideBoundaryOnResize() {
    let {
      x,
      y
    } = this._passiveTransform;
    if (x === 0 && y === 0 || this.isDragging() || !this._boundaryElement) {
      return;
    }
    // Note: don't use `_clientRectAtStart` here, because we want the latest position.
    const elementRect = this._rootElement.getBoundingClientRect();
    const boundaryRect = this._boundaryElement.getBoundingClientRect();
    // It's possible that the element got hidden away after dragging (e.g. by switching to a
    // different tab). Don't do anything in this case so we don't clear the user's position.
    if (boundaryRect.width === 0 && boundaryRect.height === 0 || elementRect.width === 0 && elementRect.height === 0) {
      return;
    }
    const leftOverflow = boundaryRect.left - elementRect.left;
    const rightOverflow = elementRect.right - boundaryRect.right;
    const topOverflow = boundaryRect.top - elementRect.top;
    const bottomOverflow = elementRect.bottom - boundaryRect.bottom;
    // If the element has become wider than the boundary, we can't
    // do much to make it fit so we just anchor it to the left.
    if (boundaryRect.width > elementRect.width) {
      if (leftOverflow > 0) {
        x += leftOverflow;
      }
      if (rightOverflow > 0) {
        x -= rightOverflow;
      }
    } else {
      x = 0;
    }
    // If the element has become taller than the boundary, we can't
    // do much to make it fit so we just anchor it to the top.
    if (boundaryRect.height > elementRect.height) {
      if (topOverflow > 0) {
        y += topOverflow;
      }
      if (bottomOverflow > 0) {
        y -= bottomOverflow;
      }
    } else {
      y = 0;
    }
    if (x !== this._passiveTransform.x || y !== this._passiveTransform.y) {
      this.setFreeDragPosition({
        y,
        x
      });
    }
  }
  /** Gets the drag start delay, based on the event type. */
  _getDragStartDelay(event) {
    const value = this.dragStartDelay;
    if (typeof value === 'number') {
      return value;
    } else if (isTouchEvent(event)) {
      return value.touch;
    }
    return value ? value.mouse : 0;
  }
  /** Updates the internal state of the draggable element when scrolling has occurred. */
  _updateOnScroll(event) {
    const scrollDifference = this._parentPositions.handleScroll(event);
    if (scrollDifference) {
      const target = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getEventTarget)(event);
      // DOMRect dimensions are based on the scroll position of the page and its parent
      // node so we have to update the cached boundary DOMRect if the user has scrolled.
      if (this._boundaryRect && target !== this._boundaryElement && target.contains(this._boundaryElement)) {
        adjustDomRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
      }
      this._pickupPositionOnPage.x += scrollDifference.left;
      this._pickupPositionOnPage.y += scrollDifference.top;
      // If we're in free drag mode, we have to update the active transform, because
      // it isn't relative to the viewport like the preview inside a drop list.
      if (!this._dropContainer) {
        this._activeTransform.x -= scrollDifference.left;
        this._activeTransform.y -= scrollDifference.top;
        this._applyRootElementTransform(this._activeTransform.x, this._activeTransform.y);
      }
    }
  }
  /** Gets the scroll position of the viewport. */
  _getViewportScrollPosition() {
    return this._parentPositions.positions.get(this._document)?.scrollPosition || this._parentPositions.getViewportScrollPosition();
  }
  /**
   * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
   * than saving it in property directly on init, because we want to resolve it as late as possible
   * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
   * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
   */
  _getShadowRoot() {
    if (this._cachedShadowRoot === undefined) {
      this._cachedShadowRoot = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getShadowRoot)(this._rootElement);
    }
    return this._cachedShadowRoot;
  }
  /** Gets the element into which the drag preview should be inserted. */
  _getPreviewInsertionPoint(initialParent, shadowRoot) {
    const previewContainer = this._previewContainer || 'global';
    if (previewContainer === 'parent') {
      return initialParent;
    }
    if (previewContainer === 'global') {
      const documentRef = this._document;
      // We can't use the body if the user is in fullscreen mode,
      // because the preview will render under the fullscreen element.
      // TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.
      return shadowRoot || documentRef.fullscreenElement || documentRef.webkitFullscreenElement || documentRef.mozFullScreenElement || documentRef.msFullscreenElement || documentRef.body;
    }
    return (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(previewContainer);
  }
  /** Lazily resolves and returns the dimensions of the preview. */
  _getPreviewRect() {
    // Cache the preview element rect if we haven't cached it already or if
    // we cached it too early before the element dimensions were computed.
    if (!this._previewRect || !this._previewRect.width && !this._previewRect.height) {
      this._previewRect = this._preview ? this._preview.getBoundingClientRect() : this._initialDomRect;
    }
    return this._previewRect;
  }
  /** Gets a handle that is the target of an event. */
  _getTargetHandle(event) {
    return this._handles.find(handle => {
      return event.target && (event.target === handle || handle.contains(event.target));
    });
  }
}
/** Clamps a value between a minimum and a maximum. */
function clamp$1(value, min, max) {
  return Math.max(min, Math.min(max, value));
}
/** Determines whether an event is a touch event. */
function isTouchEvent(event) {
  // This function is called for every pixel that the user has dragged so we need it to be
  // as fast as possible. Since we only bind mouse events and touch events, we can assume
  // that if the event's name starts with `t`, it's a touch event.
  return event.type[0] === 't';
}
/** Callback invoked for `selectstart` events inside the shadow DOM. */
function shadowDomSelectStart(event) {
  event.preventDefault();
}

/**
 * Moves an item one index in an array to another.
 * @param array Array in which to move the item.
 * @param fromIndex Starting index of the item.
 * @param toIndex Index to which the item should be moved.
 */
function moveItemInArray(array, fromIndex, toIndex) {
  const from = clamp(fromIndex, array.length - 1);
  const to = clamp(toIndex, array.length - 1);
  if (from === to) {
    return;
  }
  const target = array[from];
  const delta = to < from ? -1 : 1;
  for (let i = from; i !== to; i += delta) {
    array[i] = array[i + delta];
  }
  array[to] = target;
}
/**
 * Moves an item from one array to another.
 * @param currentArray Array from which to transfer the item.
 * @param targetArray Array into which to put the item.
 * @param currentIndex Index of the item in its current array.
 * @param targetIndex Index at which to insert the item.
 */
function transferArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
  const from = clamp(currentIndex, currentArray.length - 1);
  const to = clamp(targetIndex, targetArray.length);
  if (currentArray.length) {
    targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);
  }
}
/**
 * Copies an item from one array to another, leaving it in its
 * original position in current array.
 * @param currentArray Array from which to copy the item.
 * @param targetArray Array into which is copy the item.
 * @param currentIndex Index of the item in its current array.
 * @param targetIndex Index at which to insert the item.
 *
 */
function copyArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
  const to = clamp(targetIndex, targetArray.length);
  if (currentArray.length) {
    targetArray.splice(to, 0, currentArray[currentIndex]);
  }
}
/** Clamps a number between zero and a maximum. */
function clamp(value, max) {
  return Math.max(0, Math.min(max, value));
}

/**
 * Strategy that only supports sorting along a single axis.
 * Items are reordered using CSS transforms which allows for sorting to be animated.
 * @docs-private
 */
class SingleAxisSortStrategy {
  constructor(_dragDropRegistry) {
    this._dragDropRegistry = _dragDropRegistry;
    /** Cache of the dimensions of all the items inside the container. */
    this._itemPositions = [];
    /** Direction in which the list is oriented. */
    this.orientation = 'vertical';
    /**
     * Keeps track of the item that was last swapped with the dragged item, as well as what direction
     * the pointer was moving in when the swap occurred and whether the user's pointer continued to
     * overlap with the swapped item after the swapping occurred.
     */
    this._previousSwap = {
      drag: null,
      delta: 0,
      overlaps: false
    };
  }
  /**
   * To be called when the drag sequence starts.
   * @param items Items that are currently in the list.
   */
  start(items) {
    this.withItems(items);
  }
  /**
   * To be called when an item is being sorted.
   * @param item Item to be sorted.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param pointerDelta Direction in which the pointer is moving along each axis.
   */
  sort(item, pointerX, pointerY, pointerDelta) {
    const siblings = this._itemPositions;
    const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);
    if (newIndex === -1 && siblings.length > 0) {
      return null;
    }
    const isHorizontal = this.orientation === 'horizontal';
    const currentIndex = siblings.findIndex(currentItem => currentItem.drag === item);
    const siblingAtNewPosition = siblings[newIndex];
    const currentPosition = siblings[currentIndex].clientRect;
    const newPosition = siblingAtNewPosition.clientRect;
    const delta = currentIndex > newIndex ? 1 : -1;
    // How many pixels the item's placeholder should be offset.
    const itemOffset = this._getItemOffsetPx(currentPosition, newPosition, delta);
    // How many pixels all the other items should be offset.
    const siblingOffset = this._getSiblingOffsetPx(currentIndex, siblings, delta);
    // Save the previous order of the items before moving the item to its new index.
    // We use this to check whether an item has been moved as a result of the sorting.
    const oldOrder = siblings.slice();
    // Shuffle the array in place.
    moveItemInArray(siblings, currentIndex, newIndex);
    siblings.forEach((sibling, index) => {
      // Don't do anything if the position hasn't changed.
      if (oldOrder[index] === sibling) {
        return;
      }
      const isDraggedItem = sibling.drag === item;
      const offset = isDraggedItem ? itemOffset : siblingOffset;
      const elementToOffset = isDraggedItem ? item.getPlaceholderElement() : sibling.drag.getRootElement();
      // Update the offset to reflect the new position.
      sibling.offset += offset;
      const transformAmount = Math.round(sibling.offset * (1 / sibling.drag.scale));
      // Since we're moving the items with a `transform`, we need to adjust their cached
      // client rects to reflect their new position, as well as swap their positions in the cache.
      // Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the
      // elements may be mid-animation which will give us a wrong result.
      if (isHorizontal) {
        // Round the transforms since some browsers will
        // blur the elements, for sub-pixel transforms.
        elementToOffset.style.transform = combineTransforms(`translate3d(${transformAmount}px, 0, 0)`, sibling.initialTransform);
        adjustDomRect(sibling.clientRect, 0, offset);
      } else {
        elementToOffset.style.transform = combineTransforms(`translate3d(0, ${transformAmount}px, 0)`, sibling.initialTransform);
        adjustDomRect(sibling.clientRect, offset, 0);
      }
    });
    // Note that it's important that we do this after the client rects have been adjusted.
    this._previousSwap.overlaps = isInsideClientRect(newPosition, pointerX, pointerY);
    this._previousSwap.drag = siblingAtNewPosition.drag;
    this._previousSwap.delta = isHorizontal ? pointerDelta.x : pointerDelta.y;
    return {
      previousIndex: currentIndex,
      currentIndex: newIndex
    };
  }
  /**
   * Called when an item is being moved into the container.
   * @param item Item that was moved into the container.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param index Index at which the item entered. If omitted, the container will try to figure it
   *   out automatically.
   */
  enter(item, pointerX, pointerY, index) {
    const newIndex = index == null || index < 0 ?
    // We use the coordinates of where the item entered the drop
    // zone to figure out at which index it should be inserted.
    this._getItemIndexFromPointerPosition(item, pointerX, pointerY) : index;
    const activeDraggables = this._activeDraggables;
    const currentIndex = activeDraggables.indexOf(item);
    const placeholder = item.getPlaceholderElement();
    let newPositionReference = activeDraggables[newIndex];
    // If the item at the new position is the same as the item that is being dragged,
    // it means that we're trying to restore the item to its initial position. In this
    // case we should use the next item from the list as the reference.
    if (newPositionReference === item) {
      newPositionReference = activeDraggables[newIndex + 1];
    }
    // If we didn't find a new position reference, it means that either the item didn't start off
    // in this container, or that the item requested to be inserted at the end of the list.
    if (!newPositionReference && (newIndex == null || newIndex === -1 || newIndex < activeDraggables.length - 1) && this._shouldEnterAsFirstChild(pointerX, pointerY)) {
      newPositionReference = activeDraggables[0];
    }
    // Since the item may be in the `activeDraggables` already (e.g. if the user dragged it
    // into another container and back again), we have to ensure that it isn't duplicated.
    if (currentIndex > -1) {
      activeDraggables.splice(currentIndex, 1);
    }
    // Don't use items that are being dragged as a reference, because
    // their element has been moved down to the bottom of the body.
    if (newPositionReference && !this._dragDropRegistry.isDragging(newPositionReference)) {
      const element = newPositionReference.getRootElement();
      element.parentElement.insertBefore(placeholder, element);
      activeDraggables.splice(newIndex, 0, item);
    } else {
      this._element.appendChild(placeholder);
      activeDraggables.push(item);
    }
    // The transform needs to be cleared so it doesn't throw off the measurements.
    placeholder.style.transform = '';
    // Note that usually `start` is called together with `enter` when an item goes into a new
    // container. This will cache item positions, but we need to refresh them since the amount
    // of items has changed.
    this._cacheItemPositions();
  }
  /** Sets the items that are currently part of the list. */
  withItems(items) {
    this._activeDraggables = items.slice();
    this._cacheItemPositions();
  }
  /** Assigns a sort predicate to the strategy. */
  withSortPredicate(predicate) {
    this._sortPredicate = predicate;
  }
  /** Resets the strategy to its initial state before dragging was started. */
  reset() {
    // TODO(crisbeto): may have to wait for the animations to finish.
    this._activeDraggables?.forEach(item => {
      const rootElement = item.getRootElement();
      if (rootElement) {
        const initialTransform = this._itemPositions.find(p => p.drag === item)?.initialTransform;
        rootElement.style.transform = initialTransform || '';
      }
    });
    this._itemPositions = [];
    this._activeDraggables = [];
    this._previousSwap.drag = null;
    this._previousSwap.delta = 0;
    this._previousSwap.overlaps = false;
  }
  /**
   * Gets a snapshot of items currently in the list.
   * Can include items that we dragged in from another list.
   */
  getActiveItemsSnapshot() {
    return this._activeDraggables;
  }
  /** Gets the index of a specific item. */
  getItemIndex(item) {
    // Items are sorted always by top/left in the cache, however they flow differently in RTL.
    // The rest of the logic still stands no matter what orientation we're in, however
    // we need to invert the array when determining the index.
    const items = this.orientation === 'horizontal' && this.direction === 'rtl' ? this._itemPositions.slice().reverse() : this._itemPositions;
    return items.findIndex(currentItem => currentItem.drag === item);
  }
  /** Used to notify the strategy that the scroll position has changed. */
  updateOnScroll(topDifference, leftDifference) {
    // Since we know the amount that the user has scrolled we can shift all of the
    // client rectangles ourselves. This is cheaper than re-measuring everything and
    // we can avoid inconsistent behavior where we might be measuring the element before
    // its position has changed.
    this._itemPositions.forEach(({
      clientRect
    }) => {
      adjustDomRect(clientRect, topDifference, leftDifference);
    });
    // We need two loops for this, because we want all of the cached
    // positions to be up-to-date before we re-sort the item.
    this._itemPositions.forEach(({
      drag
    }) => {
      if (this._dragDropRegistry.isDragging(drag)) {
        // We need to re-sort the item manually, because the pointer move
        // events won't be dispatched while the user is scrolling.
        drag._sortFromLastPointerPosition();
      }
    });
  }
  withElementContainer(container) {
    this._element = container;
  }
  /** Refreshes the position cache of the items and sibling containers. */
  _cacheItemPositions() {
    const isHorizontal = this.orientation === 'horizontal';
    this._itemPositions = this._activeDraggables.map(drag => {
      const elementToMeasure = drag.getVisibleElement();
      return {
        drag,
        offset: 0,
        initialTransform: elementToMeasure.style.transform || '',
        clientRect: getMutableClientRect(elementToMeasure)
      };
    }).sort((a, b) => {
      return isHorizontal ? a.clientRect.left - b.clientRect.left : a.clientRect.top - b.clientRect.top;
    });
  }
  /**
   * Gets the offset in pixels by which the item that is being dragged should be moved.
   * @param currentPosition Current position of the item.
   * @param newPosition Position of the item where the current item should be moved.
   * @param delta Direction in which the user is moving.
   */
  _getItemOffsetPx(currentPosition, newPosition, delta) {
    const isHorizontal = this.orientation === 'horizontal';
    let itemOffset = isHorizontal ? newPosition.left - currentPosition.left : newPosition.top - currentPosition.top;
    // Account for differences in the item width/height.
    if (delta === -1) {
      itemOffset += isHorizontal ? newPosition.width - currentPosition.width : newPosition.height - currentPosition.height;
    }
    return itemOffset;
  }
  /**
   * Gets the offset in pixels by which the items that aren't being dragged should be moved.
   * @param currentIndex Index of the item currently being dragged.
   * @param siblings All of the items in the list.
   * @param delta Direction in which the user is moving.
   */
  _getSiblingOffsetPx(currentIndex, siblings, delta) {
    const isHorizontal = this.orientation === 'horizontal';
    const currentPosition = siblings[currentIndex].clientRect;
    const immediateSibling = siblings[currentIndex + delta * -1];
    let siblingOffset = currentPosition[isHorizontal ? 'width' : 'height'] * delta;
    if (immediateSibling) {
      const start = isHorizontal ? 'left' : 'top';
      const end = isHorizontal ? 'right' : 'bottom';
      // Get the spacing between the start of the current item and the end of the one immediately
      // after it in the direction in which the user is dragging, or vice versa. We add it to the
      // offset in order to push the element to where it will be when it's inline and is influenced
      // by the `margin` of its siblings.
      if (delta === -1) {
        siblingOffset -= immediateSibling.clientRect[start] - currentPosition[end];
      } else {
        siblingOffset += currentPosition[start] - immediateSibling.clientRect[end];
      }
    }
    return siblingOffset;
  }
  /**
   * Checks if pointer is entering in the first position
   * @param pointerX Position of the user's pointer along the X axis.
   * @param pointerY Position of the user's pointer along the Y axis.
   */
  _shouldEnterAsFirstChild(pointerX, pointerY) {
    if (!this._activeDraggables.length) {
      return false;
    }
    const itemPositions = this._itemPositions;
    const isHorizontal = this.orientation === 'horizontal';
    // `itemPositions` are sorted by position while `activeDraggables` are sorted by child index
    // check if container is using some sort of "reverse" ordering (eg: flex-direction: row-reverse)
    const reversed = itemPositions[0].drag !== this._activeDraggables[0];
    if (reversed) {
      const lastItemRect = itemPositions[itemPositions.length - 1].clientRect;
      return isHorizontal ? pointerX >= lastItemRect.right : pointerY >= lastItemRect.bottom;
    } else {
      const firstItemRect = itemPositions[0].clientRect;
      return isHorizontal ? pointerX <= firstItemRect.left : pointerY <= firstItemRect.top;
    }
  }
  /**
   * Gets the index of an item in the drop container, based on the position of the user's pointer.
   * @param item Item that is being sorted.
   * @param pointerX Position of the user's pointer along the X axis.
   * @param pointerY Position of the user's pointer along the Y axis.
   * @param delta Direction in which the user is moving their pointer.
   */
  _getItemIndexFromPointerPosition(item, pointerX, pointerY, delta) {
    const isHorizontal = this.orientation === 'horizontal';
    const index = this._itemPositions.findIndex(({
      drag,
      clientRect
    }) => {
      // Skip the item itself.
      if (drag === item) {
        return false;
      }
      if (delta) {
        const direction = isHorizontal ? delta.x : delta.y;
        // If the user is still hovering over the same item as last time, their cursor hasn't left
        // the item after we made the swap, and they didn't change the direction in which they're
        // dragging, we don't consider it a direction swap.
        if (drag === this._previousSwap.drag && this._previousSwap.overlaps && direction === this._previousSwap.delta) {
          return false;
        }
      }
      return isHorizontal ?
      // Round these down since most browsers report client rects with
      // sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
      pointerX >= Math.floor(clientRect.left) && pointerX < Math.floor(clientRect.right) : pointerY >= Math.floor(clientRect.top) && pointerY < Math.floor(clientRect.bottom);
    });
    return index === -1 || !this._sortPredicate(index, item) ? -1 : index;
  }
}

/**
 * Strategy that only supports sorting on a list that might wrap.
 * Items are reordered by moving their DOM nodes around.
 * @docs-private
 */
class MixedSortStrategy {
  constructor(_document, _dragDropRegistry) {
    this._document = _document;
    this._dragDropRegistry = _dragDropRegistry;
    /**
     * Keeps track of the item that was last swapped with the dragged item, as well as what direction
     * the pointer was moving in when the swap occurred and whether the user's pointer continued to
     * overlap with the swapped item after the swapping occurred.
     */
    this._previousSwap = {
      drag: null,
      deltaX: 0,
      deltaY: 0,
      overlaps: false
    };
    /**
     * Keeps track of the relationship between a node and its next sibling. This information
     * is used to restore the DOM to the order it was in before dragging started.
     */
    this._relatedNodes = [];
  }
  /**
   * To be called when the drag sequence starts.
   * @param items Items that are currently in the list.
   */
  start(items) {
    const childNodes = this._element.childNodes;
    this._relatedNodes = [];
    for (let i = 0; i < childNodes.length; i++) {
      const node = childNodes[i];
      this._relatedNodes.push([node, node.nextSibling]);
    }
    this.withItems(items);
  }
  /**
   * To be called when an item is being sorted.
   * @param item Item to be sorted.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param pointerDelta Direction in which the pointer is moving along each axis.
   */
  sort(item, pointerX, pointerY, pointerDelta) {
    const newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY);
    const previousSwap = this._previousSwap;
    if (newIndex === -1 || this._activeItems[newIndex] === item) {
      return null;
    }
    const toSwapWith = this._activeItems[newIndex];
    // Prevent too many swaps over the same item.
    if (previousSwap.drag === toSwapWith && previousSwap.overlaps && previousSwap.deltaX === pointerDelta.x && previousSwap.deltaY === pointerDelta.y) {
      return null;
    }
    const previousIndex = this.getItemIndex(item);
    const current = item.getPlaceholderElement();
    const overlapElement = toSwapWith.getRootElement();
    if (newIndex > previousIndex) {
      overlapElement.after(current);
    } else {
      overlapElement.before(current);
    }
    moveItemInArray(this._activeItems, previousIndex, newIndex);
    const newOverlapElement = this._getRootNode().elementFromPoint(pointerX, pointerY);
    // Note: it's tempting to save the entire `pointerDelta` object here, however that'll
    // break this functionality, because the same object is passed for all `sort` calls.
    previousSwap.deltaX = pointerDelta.x;
    previousSwap.deltaY = pointerDelta.y;
    previousSwap.drag = toSwapWith;
    previousSwap.overlaps = overlapElement === newOverlapElement || overlapElement.contains(newOverlapElement);
    return {
      previousIndex,
      currentIndex: newIndex
    };
  }
  /**
   * Called when an item is being moved into the container.
   * @param item Item that was moved into the container.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param index Index at which the item entered. If omitted, the container will try to figure it
   *   out automatically.
   */
  enter(item, pointerX, pointerY, index) {
    let enterIndex = index == null || index < 0 ? this._getItemIndexFromPointerPosition(item, pointerX, pointerY) : index;
    // In some cases (e.g. when the container has padding) we might not be able to figure
    // out which item to insert the dragged item next to, because the pointer didn't overlap
    // with anything. In that case we find the item that's closest to the pointer.
    if (enterIndex === -1) {
      enterIndex = this._getClosestItemIndexToPointer(item, pointerX, pointerY);
    }
    const targetItem = this._activeItems[enterIndex];
    const currentIndex = this._activeItems.indexOf(item);
    if (currentIndex > -1) {
      this._activeItems.splice(currentIndex, 1);
    }
    if (targetItem && !this._dragDropRegistry.isDragging(targetItem)) {
      this._activeItems.splice(enterIndex, 0, item);
      targetItem.getRootElement().before(item.getPlaceholderElement());
    } else {
      this._activeItems.push(item);
      this._element.appendChild(item.getPlaceholderElement());
    }
  }
  /** Sets the items that are currently part of the list. */
  withItems(items) {
    this._activeItems = items.slice();
  }
  /** Assigns a sort predicate to the strategy. */
  withSortPredicate(predicate) {
    this._sortPredicate = predicate;
  }
  /** Resets the strategy to its initial state before dragging was started. */
  reset() {
    const root = this._element;
    const previousSwap = this._previousSwap;
    // Moving elements around in the DOM can break things like the `@for` loop, because it
    // uses comment nodes to know where to insert elements. To avoid such issues, we restore
    // the DOM nodes in the list to their original order when the list is reset.
    // Note that this could be simpler if we just saved all the nodes, cleared the root
    // and then appended them in the original order. We don't do it, because it can break
    // down depending on when the snapshot was taken. E.g. we may end up snapshotting the
    // placeholder element which is removed after dragging.
    for (let i = this._relatedNodes.length - 1; i > -1; i--) {
      const [node, nextSibling] = this._relatedNodes[i];
      if (node.parentNode === root && node.nextSibling !== nextSibling) {
        if (nextSibling === null) {
          root.appendChild(node);
        } else if (nextSibling.parentNode === root) {
          root.insertBefore(node, nextSibling);
        }
      }
    }
    this._relatedNodes = [];
    this._activeItems = [];
    previousSwap.drag = null;
    previousSwap.deltaX = previousSwap.deltaY = 0;
    previousSwap.overlaps = false;
  }
  /**
   * Gets a snapshot of items currently in the list.
   * Can include items that we dragged in from another list.
   */
  getActiveItemsSnapshot() {
    return this._activeItems;
  }
  /** Gets the index of a specific item. */
  getItemIndex(item) {
    return this._activeItems.indexOf(item);
  }
  /** Used to notify the strategy that the scroll position has changed. */
  updateOnScroll() {
    this._activeItems.forEach(item => {
      if (this._dragDropRegistry.isDragging(item)) {
        // We need to re-sort the item manually, because the pointer move
        // events won't be dispatched while the user is scrolling.
        item._sortFromLastPointerPosition();
      }
    });
  }
  withElementContainer(container) {
    if (container !== this._element) {
      this._element = container;
      this._rootNode = undefined;
    }
  }
  /**
   * Gets the index of an item in the drop container, based on the position of the user's pointer.
   * @param item Item that is being sorted.
   * @param pointerX Position of the user's pointer along the X axis.
   * @param pointerY Position of the user's pointer along the Y axis.
   * @param delta Direction in which the user is moving their pointer.
   */
  _getItemIndexFromPointerPosition(item, pointerX, pointerY) {
    const elementAtPoint = this._getRootNode().elementFromPoint(Math.floor(pointerX), Math.floor(pointerY));
    const index = elementAtPoint ? this._activeItems.findIndex(item => {
      const root = item.getRootElement();
      return elementAtPoint === root || root.contains(elementAtPoint);
    }) : -1;
    return index === -1 || !this._sortPredicate(index, item) ? -1 : index;
  }
  /** Lazily resolves the list's root node. */
  _getRootNode() {
    // Resolve the root node lazily to ensure that the drop list is in its final place in the DOM.
    if (!this._rootNode) {
      this._rootNode = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getShadowRoot)(this._element) || this._document;
    }
    return this._rootNode;
  }
  /**
   * Finds the index of the item that's closest to the item being dragged.
   * @param item Item being dragged.
   * @param pointerX Position of the user's pointer along the X axis.
   * @param pointerY Position of the user's pointer along the Y axis.
   */
  _getClosestItemIndexToPointer(item, pointerX, pointerY) {
    if (this._activeItems.length === 0) {
      return -1;
    }
    if (this._activeItems.length === 1) {
      return 0;
    }
    let minDistance = Infinity;
    let minIndex = -1;
    // Find the Euclidean distance (https://en.wikipedia.org/wiki/Euclidean_distance) between each
    // item and the pointer, and return the smallest one. Note that this is a bit flawed in that DOM
    // nodes are rectangles, not points, so we use the top/left coordinates. It should be enough
    // for our purposes.
    for (let i = 0; i < this._activeItems.length; i++) {
      const current = this._activeItems[i];
      if (current !== item) {
        const {
          x,
          y
        } = current.getRootElement().getBoundingClientRect();
        const distance = Math.hypot(pointerX - x, pointerY - y);
        if (distance < minDistance) {
          minDistance = distance;
          minIndex = i;
        }
      }
    }
    return minIndex;
  }
}

/**
 * Proximity, as a ratio to width/height, at which a
 * dragged item will affect the drop container.
 */
const DROP_PROXIMITY_THRESHOLD = 0.05;
/**
 * Proximity, as a ratio to width/height at which to start auto-scrolling the drop list or the
 * viewport. The value comes from trying it out manually until it feels right.
 */
const SCROLL_PROXIMITY_THRESHOLD = 0.05;
/** Vertical direction in which we can auto-scroll. */
var AutoScrollVerticalDirection;
(function (AutoScrollVerticalDirection) {
  AutoScrollVerticalDirection[AutoScrollVerticalDirection["NONE"] = 0] = "NONE";
  AutoScrollVerticalDirection[AutoScrollVerticalDirection["UP"] = 1] = "UP";
  AutoScrollVerticalDirection[AutoScrollVerticalDirection["DOWN"] = 2] = "DOWN";
})(AutoScrollVerticalDirection || (AutoScrollVerticalDirection = {}));
/** Horizontal direction in which we can auto-scroll. */
var AutoScrollHorizontalDirection;
(function (AutoScrollHorizontalDirection) {
  AutoScrollHorizontalDirection[AutoScrollHorizontalDirection["NONE"] = 0] = "NONE";
  AutoScrollHorizontalDirection[AutoScrollHorizontalDirection["LEFT"] = 1] = "LEFT";
  AutoScrollHorizontalDirection[AutoScrollHorizontalDirection["RIGHT"] = 2] = "RIGHT";
})(AutoScrollHorizontalDirection || (AutoScrollHorizontalDirection = {}));
/**
 * Reference to a drop list. Used to manipulate or dispose of the container.
 */
class DropListRef {
  constructor(element, _dragDropRegistry, _document, _ngZone, _viewportRuler) {
    this._dragDropRegistry = _dragDropRegistry;
    this._ngZone = _ngZone;
    this._viewportRuler = _viewportRuler;
    /** Whether starting a dragging sequence from this container is disabled. */
    this.disabled = false;
    /** Whether sorting items within the list is disabled. */
    this.sortingDisabled = false;
    /**
     * Whether auto-scrolling the view when the user
     * moves their pointer close to the edges is disabled.
     */
    this.autoScrollDisabled = false;
    /** Number of pixels to scroll for each frame when auto-scrolling an element. */
    this.autoScrollStep = 2;
    /**
     * Function that is used to determine whether an item
     * is allowed to be moved into a drop container.
     */
    this.enterPredicate = () => true;
    /** Function that is used to determine whether an item can be sorted into a particular index. */
    this.sortPredicate = () => true;
    /** Emits right before dragging has started. */
    this.beforeStarted = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Emits when the user has moved a new drag item into this container.
     */
    this.entered = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Emits when the user removes an item from the container
     * by dragging it into another container.
     */
    this.exited = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when the user drops an item inside the container. */
    this.dropped = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits as the user is swapping items while actively dragging. */
    this.sorted = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when a dragging sequence is started in a list connected to the current one. */
    this.receivingStarted = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Emits when a dragging sequence is stopped from a list connected to the current one. */
    this.receivingStopped = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Whether an item in the list is being dragged. */
    this._isDragging = false;
    /** Draggable items in the container. */
    this._draggables = [];
    /** Drop lists that are connected to the current one. */
    this._siblings = [];
    /** Connected siblings that currently have a dragged item. */
    this._activeSiblings = new Set();
    /** Subscription to the window being scrolled. */
    this._viewportScrollSubscription = rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription.EMPTY;
    /** Vertical direction in which the list is currently scrolling. */
    this._verticalScrollDirection = AutoScrollVerticalDirection.NONE;
    /** Horizontal direction in which the list is currently scrolling. */
    this._horizontalScrollDirection = AutoScrollHorizontalDirection.NONE;
    /** Used to signal to the current auto-scroll sequence when to stop. */
    this._stopScrollTimers = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /** Shadow root of the current element. Necessary for `elementFromPoint` to resolve correctly. */
    this._cachedShadowRoot = null;
    /** Elements that can be scrolled while the user is dragging. */
    this._scrollableElements = [];
    /** Direction of the list's layout. */
    this._direction = 'ltr';
    /** Starts the interval that'll auto-scroll the element. */
    this._startScrollInterval = () => {
      this._stopScrolling();
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.interval)(0, rxjs__WEBPACK_IMPORTED_MODULE_7__.animationFrameScheduler).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.takeUntil)(this._stopScrollTimers)).subscribe(() => {
        const node = this._scrollNode;
        const scrollStep = this.autoScrollStep;
        if (this._verticalScrollDirection === AutoScrollVerticalDirection.UP) {
          node.scrollBy(0, -scrollStep);
        } else if (this._verticalScrollDirection === AutoScrollVerticalDirection.DOWN) {
          node.scrollBy(0, scrollStep);
        }
        if (this._horizontalScrollDirection === AutoScrollHorizontalDirection.LEFT) {
          node.scrollBy(-scrollStep, 0);
        } else if (this._horizontalScrollDirection === AutoScrollHorizontalDirection.RIGHT) {
          node.scrollBy(scrollStep, 0);
        }
      });
    };
    const coercedElement = this.element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(element);
    this._document = _document;
    this.withOrientation('vertical').withElementContainer(coercedElement);
    _dragDropRegistry.registerDropContainer(this);
    this._parentPositions = new ParentPositionTracker(_document);
  }
  /** Removes the drop list functionality from the DOM element. */
  dispose() {
    this._stopScrolling();
    this._stopScrollTimers.complete();
    this._viewportScrollSubscription.unsubscribe();
    this.beforeStarted.complete();
    this.entered.complete();
    this.exited.complete();
    this.dropped.complete();
    this.sorted.complete();
    this.receivingStarted.complete();
    this.receivingStopped.complete();
    this._activeSiblings.clear();
    this._scrollNode = null;
    this._parentPositions.clear();
    this._dragDropRegistry.removeDropContainer(this);
  }
  /** Whether an item from this list is currently being dragged. */
  isDragging() {
    return this._isDragging;
  }
  /** Starts dragging an item. */
  start() {
    this._draggingStarted();
    this._notifyReceivingSiblings();
  }
  /**
   * Attempts to move an item into the container.
   * @param item Item that was moved into the container.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param index Index at which the item entered. If omitted, the container will try to figure it
   *   out automatically.
   */
  enter(item, pointerX, pointerY, index) {
    this._draggingStarted();
    // If sorting is disabled, we want the item to return to its starting
    // position if the user is returning it to its initial container.
    if (index == null && this.sortingDisabled) {
      index = this._draggables.indexOf(item);
    }
    this._sortStrategy.enter(item, pointerX, pointerY, index);
    // Note that this usually happens inside `_draggingStarted` as well, but the dimensions
    // can change when the sort strategy moves the item around inside `enter`.
    this._cacheParentPositions();
    // Notify siblings at the end so that the item has been inserted into the `activeDraggables`.
    this._notifyReceivingSiblings();
    this.entered.next({
      item,
      container: this,
      currentIndex: this.getItemIndex(item)
    });
  }
  /**
   * Removes an item from the container after it was dragged into another container by the user.
   * @param item Item that was dragged out.
   */
  exit(item) {
    this._reset();
    this.exited.next({
      item,
      container: this
    });
  }
  /**
   * Drops an item into this container.
   * @param item Item being dropped into the container.
   * @param currentIndex Index at which the item should be inserted.
   * @param previousIndex Index of the item when dragging started.
   * @param previousContainer Container from which the item got dragged in.
   * @param isPointerOverContainer Whether the user's pointer was over the
   *    container when the item was dropped.
   * @param distance Distance the user has dragged since the start of the dragging sequence.
   * @param event Event that triggered the dropping sequence.
   *
   * @breaking-change 15.0.0 `previousIndex` and `event` parameters to become required.
   */
  drop(item, currentIndex, previousIndex, previousContainer, isPointerOverContainer, distance, dropPoint, event = {}) {
    this._reset();
    this.dropped.next({
      item,
      currentIndex,
      previousIndex,
      container: this,
      previousContainer,
      isPointerOverContainer,
      distance,
      dropPoint,
      event
    });
  }
  /**
   * Sets the draggable items that are a part of this list.
   * @param items Items that are a part of this list.
   */
  withItems(items) {
    const previousItems = this._draggables;
    this._draggables = items;
    items.forEach(item => item._withDropContainer(this));
    if (this.isDragging()) {
      const draggedItems = previousItems.filter(item => item.isDragging());
      // If all of the items being dragged were removed
      // from the list, abort the current drag sequence.
      if (draggedItems.every(item => items.indexOf(item) === -1)) {
        this._reset();
      } else {
        this._sortStrategy.withItems(this._draggables);
      }
    }
    return this;
  }
  /** Sets the layout direction of the drop list. */
  withDirection(direction) {
    this._direction = direction;
    if (this._sortStrategy instanceof SingleAxisSortStrategy) {
      this._sortStrategy.direction = direction;
    }
    return this;
  }
  /**
   * Sets the containers that are connected to this one. When two or more containers are
   * connected, the user will be allowed to transfer items between them.
   * @param connectedTo Other containers that the current containers should be connected to.
   */
  connectedTo(connectedTo) {
    this._siblings = connectedTo.slice();
    return this;
  }
  /**
   * Sets the orientation of the container.
   * @param orientation New orientation for the container.
   */
  withOrientation(orientation) {
    if (orientation === 'mixed') {
      this._sortStrategy = new MixedSortStrategy(this._document, this._dragDropRegistry);
    } else {
      const strategy = new SingleAxisSortStrategy(this._dragDropRegistry);
      strategy.direction = this._direction;
      strategy.orientation = orientation;
      this._sortStrategy = strategy;
    }
    this._sortStrategy.withElementContainer(this._container);
    this._sortStrategy.withSortPredicate((index, item) => this.sortPredicate(index, item, this));
    return this;
  }
  /**
   * Sets which parent elements are can be scrolled while the user is dragging.
   * @param elements Elements that can be scrolled.
   */
  withScrollableParents(elements) {
    const element = this._container;
    // We always allow the current element to be scrollable
    // so we need to ensure that it's in the array.
    this._scrollableElements = elements.indexOf(element) === -1 ? [element, ...elements] : elements.slice();
    return this;
  }
  /**
   * Configures the drop list so that a different element is used as the container for the
   * dragged items. This is useful for the cases when one might not have control over the
   * full DOM that sets up the dragging.
   * Note that the alternate container needs to be a descendant of the drop list.
   * @param container New element container to be assigned.
   */
  withElementContainer(container) {
    if (container === this._container) {
      return this;
    }
    const element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(this.element);
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && container !== element && !element.contains(container)) {
      throw new Error('Invalid DOM structure for drop list. Alternate container element must be a descendant of the drop list.');
    }
    const oldContainerIndex = this._scrollableElements.indexOf(this._container);
    const newContainerIndex = this._scrollableElements.indexOf(container);
    if (oldContainerIndex > -1) {
      this._scrollableElements.splice(oldContainerIndex, 1);
    }
    if (newContainerIndex > -1) {
      this._scrollableElements.splice(newContainerIndex, 1);
    }
    if (this._sortStrategy) {
      this._sortStrategy.withElementContainer(container);
    }
    this._cachedShadowRoot = null;
    this._scrollableElements.unshift(container);
    this._container = container;
    return this;
  }
  /** Gets the scrollable parents that are registered with this drop container. */
  getScrollableParents() {
    return this._scrollableElements;
  }
  /**
   * Figures out the index of an item in the container.
   * @param item Item whose index should be determined.
   */
  getItemIndex(item) {
    return this._isDragging ? this._sortStrategy.getItemIndex(item) : this._draggables.indexOf(item);
  }
  /**
   * Whether the list is able to receive the item that
   * is currently being dragged inside a connected drop list.
   */
  isReceiving() {
    return this._activeSiblings.size > 0;
  }
  /**
   * Sorts an item inside the container based on its position.
   * @param item Item to be sorted.
   * @param pointerX Position of the item along the X axis.
   * @param pointerY Position of the item along the Y axis.
   * @param pointerDelta Direction in which the pointer is moving along each axis.
   */
  _sortItem(item, pointerX, pointerY, pointerDelta) {
    // Don't sort the item if sorting is disabled or it's out of range.
    if (this.sortingDisabled || !this._domRect || !isPointerNearDomRect(this._domRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {
      return;
    }
    const result = this._sortStrategy.sort(item, pointerX, pointerY, pointerDelta);
    if (result) {
      this.sorted.next({
        previousIndex: result.previousIndex,
        currentIndex: result.currentIndex,
        container: this,
        item
      });
    }
  }
  /**
   * Checks whether the user's pointer is close to the edges of either the
   * viewport or the drop list and starts the auto-scroll sequence.
   * @param pointerX User's pointer position along the x axis.
   * @param pointerY User's pointer position along the y axis.
   */
  _startScrollingIfNecessary(pointerX, pointerY) {
    if (this.autoScrollDisabled) {
      return;
    }
    let scrollNode;
    let verticalScrollDirection = AutoScrollVerticalDirection.NONE;
    let horizontalScrollDirection = AutoScrollHorizontalDirection.NONE;
    // Check whether we should start scrolling any of the parent containers.
    this._parentPositions.positions.forEach((position, element) => {
      // We have special handling for the `document` below. Also this would be
      // nicer with a  for...of loop, but it requires changing a compiler flag.
      if (element === this._document || !position.clientRect || scrollNode) {
        return;
      }
      if (isPointerNearDomRect(position.clientRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {
        [verticalScrollDirection, horizontalScrollDirection] = getElementScrollDirections(element, position.clientRect, this._direction, pointerX, pointerY);
        if (verticalScrollDirection || horizontalScrollDirection) {
          scrollNode = element;
        }
      }
    });
    // Otherwise check if we can start scrolling the viewport.
    if (!verticalScrollDirection && !horizontalScrollDirection) {
      const {
        width,
        height
      } = this._viewportRuler.getViewportSize();
      const domRect = {
        width,
        height,
        top: 0,
        right: width,
        bottom: height,
        left: 0
      };
      verticalScrollDirection = getVerticalScrollDirection(domRect, pointerY);
      horizontalScrollDirection = getHorizontalScrollDirection(domRect, pointerX);
      scrollNode = window;
    }
    if (scrollNode && (verticalScrollDirection !== this._verticalScrollDirection || horizontalScrollDirection !== this._horizontalScrollDirection || scrollNode !== this._scrollNode)) {
      this._verticalScrollDirection = verticalScrollDirection;
      this._horizontalScrollDirection = horizontalScrollDirection;
      this._scrollNode = scrollNode;
      if ((verticalScrollDirection || horizontalScrollDirection) && scrollNode) {
        this._ngZone.runOutsideAngular(this._startScrollInterval);
      } else {
        this._stopScrolling();
      }
    }
  }
  /** Stops any currently-running auto-scroll sequences. */
  _stopScrolling() {
    this._stopScrollTimers.next();
  }
  /** Starts the dragging sequence within the list. */
  _draggingStarted() {
    const styles = this._container.style;
    this.beforeStarted.next();
    this._isDragging = true;
    if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
    // Prevent the check from running on apps not using an alternate container. Ideally we
    // would always run it, but introducing it at this stage would be a breaking change.
    this._container !== (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(this.element)) {
      for (const drag of this._draggables) {
        if (!drag.isDragging() && drag.getVisibleElement().parentNode !== this._container) {
          throw new Error('Invalid DOM structure for drop list. All items must be placed directly inside of the element container.');
        }
      }
    }
    // We need to disable scroll snapping while the user is dragging, because it breaks automatic
    // scrolling. The browser seems to round the value based on the snapping points which means
    // that we can't increment/decrement the scroll position.
    this._initialScrollSnap = styles.msScrollSnapType || styles.scrollSnapType || '';
    styles.scrollSnapType = styles.msScrollSnapType = 'none';
    this._sortStrategy.start(this._draggables);
    this._cacheParentPositions();
    this._viewportScrollSubscription.unsubscribe();
    this._listenToScrollEvents();
  }
  /** Caches the positions of the configured scrollable parents. */
  _cacheParentPositions() {
    this._parentPositions.cache(this._scrollableElements);
    // The list element is always in the `scrollableElements`
    // so we can take advantage of the cached `DOMRect`.
    this._domRect = this._parentPositions.positions.get(this._container).clientRect;
  }
  /** Resets the container to its initial state. */
  _reset() {
    this._isDragging = false;
    const styles = this._container.style;
    styles.scrollSnapType = styles.msScrollSnapType = this._initialScrollSnap;
    this._siblings.forEach(sibling => sibling._stopReceiving(this));
    this._sortStrategy.reset();
    this._stopScrolling();
    this._viewportScrollSubscription.unsubscribe();
    this._parentPositions.clear();
  }
  /**
   * Checks whether the user's pointer is positioned over the container.
   * @param x Pointer position along the X axis.
   * @param y Pointer position along the Y axis.
   */
  _isOverContainer(x, y) {
    return this._domRect != null && isInsideClientRect(this._domRect, x, y);
  }
  /**
   * Figures out whether an item should be moved into a sibling
   * drop container, based on its current position.
   * @param item Drag item that is being moved.
   * @param x Position of the item along the X axis.
   * @param y Position of the item along the Y axis.
   */
  _getSiblingContainerFromPosition(item, x, y) {
    return this._siblings.find(sibling => sibling._canReceive(item, x, y));
  }
  /**
   * Checks whether the drop list can receive the passed-in item.
   * @param item Item that is being dragged into the list.
   * @param x Position of the item along the X axis.
   * @param y Position of the item along the Y axis.
   */
  _canReceive(item, x, y) {
    if (!this._domRect || !isInsideClientRect(this._domRect, x, y) || !this.enterPredicate(item, this)) {
      return false;
    }
    const elementFromPoint = this._getShadowRoot().elementFromPoint(x, y);
    // If there's no element at the pointer position, then
    // the client rect is probably scrolled out of the view.
    if (!elementFromPoint) {
      return false;
    }
    // The `DOMRect`, that we're using to find the container over which the user is
    // hovering, doesn't give us any information on whether the element has been scrolled
    // out of the view or whether it's overlapping with other containers. This means that
    // we could end up transferring the item into a container that's invisible or is positioned
    // below another one. We use the result from `elementFromPoint` to get the top-most element
    // at the pointer position and to find whether it's one of the intersecting drop containers.
    return elementFromPoint === this._container || this._container.contains(elementFromPoint);
  }
  /**
   * Called by one of the connected drop lists when a dragging sequence has started.
   * @param sibling Sibling in which dragging has started.
   */
  _startReceiving(sibling, items) {
    const activeSiblings = this._activeSiblings;
    if (!activeSiblings.has(sibling) && items.every(item => {
      // Note that we have to add an exception to the `enterPredicate` for items that started off
      // in this drop list. The drag ref has logic that allows an item to return to its initial
      // container, if it has left the initial container and none of the connected containers
      // allow it to enter. See `DragRef._updateActiveDropContainer` for more context.
      return this.enterPredicate(item, this) || this._draggables.indexOf(item) > -1;
    })) {
      activeSiblings.add(sibling);
      this._cacheParentPositions();
      this._listenToScrollEvents();
      this.receivingStarted.next({
        initiator: sibling,
        receiver: this,
        items
      });
    }
  }
  /**
   * Called by a connected drop list when dragging has stopped.
   * @param sibling Sibling whose dragging has stopped.
   */
  _stopReceiving(sibling) {
    this._activeSiblings.delete(sibling);
    this._viewportScrollSubscription.unsubscribe();
    this.receivingStopped.next({
      initiator: sibling,
      receiver: this
    });
  }
  /**
   * Starts listening to scroll events on the viewport.
   * Used for updating the internal state of the list.
   */
  _listenToScrollEvents() {
    this._viewportScrollSubscription = this._dragDropRegistry.scrolled(this._getShadowRoot()).subscribe(event => {
      if (this.isDragging()) {
        const scrollDifference = this._parentPositions.handleScroll(event);
        if (scrollDifference) {
          this._sortStrategy.updateOnScroll(scrollDifference.top, scrollDifference.left);
        }
      } else if (this.isReceiving()) {
        this._cacheParentPositions();
      }
    });
  }
  /**
   * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
   * than saving it in property directly on init, because we want to resolve it as late as possible
   * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
   * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
   */
  _getShadowRoot() {
    if (!this._cachedShadowRoot) {
      const shadowRoot = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__._getShadowRoot)(this._container);
      this._cachedShadowRoot = shadowRoot || this._document;
    }
    return this._cachedShadowRoot;
  }
  /** Notifies any siblings that may potentially receive the item. */
  _notifyReceivingSiblings() {
    const draggedItems = this._sortStrategy.getActiveItemsSnapshot().filter(item => item.isDragging());
    this._siblings.forEach(sibling => sibling._startReceiving(this, draggedItems));
  }
}
/**
 * Gets whether the vertical auto-scroll direction of a node.
 * @param clientRect Dimensions of the node.
 * @param pointerY Position of the user's pointer along the y axis.
 */
function getVerticalScrollDirection(clientRect, pointerY) {
  const {
    top,
    bottom,
    height
  } = clientRect;
  const yThreshold = height * SCROLL_PROXIMITY_THRESHOLD;
  if (pointerY >= top - yThreshold && pointerY <= top + yThreshold) {
    return AutoScrollVerticalDirection.UP;
  } else if (pointerY >= bottom - yThreshold && pointerY <= bottom + yThreshold) {
    return AutoScrollVerticalDirection.DOWN;
  }
  return AutoScrollVerticalDirection.NONE;
}
/**
 * Gets whether the horizontal auto-scroll direction of a node.
 * @param clientRect Dimensions of the node.
 * @param pointerX Position of the user's pointer along the x axis.
 */
function getHorizontalScrollDirection(clientRect, pointerX) {
  const {
    left,
    right,
    width
  } = clientRect;
  const xThreshold = width * SCROLL_PROXIMITY_THRESHOLD;
  if (pointerX >= left - xThreshold && pointerX <= left + xThreshold) {
    return AutoScrollHorizontalDirection.LEFT;
  } else if (pointerX >= right - xThreshold && pointerX <= right + xThreshold) {
    return AutoScrollHorizontalDirection.RIGHT;
  }
  return AutoScrollHorizontalDirection.NONE;
}
/**
 * Gets the directions in which an element node should be scrolled,
 * assuming that the user's pointer is already within it scrollable region.
 * @param element Element for which we should calculate the scroll direction.
 * @param clientRect Bounding client rectangle of the element.
 * @param direction Layout direction of the drop list.
 * @param pointerX Position of the user's pointer along the x axis.
 * @param pointerY Position of the user's pointer along the y axis.
 */
function getElementScrollDirections(element, clientRect, direction, pointerX, pointerY) {
  const computedVertical = getVerticalScrollDirection(clientRect, pointerY);
  const computedHorizontal = getHorizontalScrollDirection(clientRect, pointerX);
  let verticalScrollDirection = AutoScrollVerticalDirection.NONE;
  let horizontalScrollDirection = AutoScrollHorizontalDirection.NONE;
  // Note that we here we do some extra checks for whether the element is actually scrollable in
  // a certain direction and we only assign the scroll direction if it is. We do this so that we
  // can allow other elements to be scrolled, if the current element can't be scrolled anymore.
  // This allows us to handle cases where the scroll regions of two scrollable elements overlap.
  if (computedVertical) {
    const scrollTop = element.scrollTop;
    if (computedVertical === AutoScrollVerticalDirection.UP) {
      if (scrollTop > 0) {
        verticalScrollDirection = AutoScrollVerticalDirection.UP;
      }
    } else if (element.scrollHeight - scrollTop > element.clientHeight) {
      verticalScrollDirection = AutoScrollVerticalDirection.DOWN;
    }
  }
  if (computedHorizontal) {
    const scrollLeft = element.scrollLeft;
    if (direction === 'rtl') {
      if (computedHorizontal === AutoScrollHorizontalDirection.RIGHT) {
        // In RTL `scrollLeft` will be negative when scrolled.
        if (scrollLeft < 0) {
          horizontalScrollDirection = AutoScrollHorizontalDirection.RIGHT;
        }
      } else if (element.scrollWidth + scrollLeft > element.clientWidth) {
        horizontalScrollDirection = AutoScrollHorizontalDirection.LEFT;
      }
    } else {
      if (computedHorizontal === AutoScrollHorizontalDirection.LEFT) {
        if (scrollLeft > 0) {
          horizontalScrollDirection = AutoScrollHorizontalDirection.LEFT;
        }
      } else if (element.scrollWidth - scrollLeft > element.clientWidth) {
        horizontalScrollDirection = AutoScrollHorizontalDirection.RIGHT;
      }
    }
  }
  return [verticalScrollDirection, horizontalScrollDirection];
}

/** Event options that can be used to bind an active, capturing event. */
const activeCapturingEventOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_0__.normalizePassiveListenerOptions)({
  passive: false,
  capture: true
});
/** Keeps track of the apps currently containing drag items. */
const activeApps = new Set();
/**
 * Component used to load the drag&drop reset styles.
 * @docs-private
 */
class _ResetsLoader {
  static {
    this.ɵfac = function _ResetsLoader_Factory(t) {
      return new (t || _ResetsLoader)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: _ResetsLoader,
      selectors: [["ng-component"]],
      hostAttrs: ["cdk-drag-resets-container", ""],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 0,
      vars: 0,
      template: function _ResetsLoader_Template(rf, ctx) {},
      styles: ["@layer cdk-resets{.cdk-drag-preview{background:none;border:none;padding:0;color:inherit;inset:auto}}.cdk-drag-placeholder *,.cdk-drag-preview *{pointer-events:none !important}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](_ResetsLoader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      standalone: true,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      template: '',
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.OnPush,
      host: {
        'cdk-drag-resets-container': ''
      },
      styles: ["@layer cdk-resets{.cdk-drag-preview{background:none;border:none;padding:0;color:inherit;inset:auto}}.cdk-drag-placeholder *,.cdk-drag-preview *{pointer-events:none !important}"]
    }]
  }], null, null);
})();
// TODO(crisbeto): remove generics when making breaking changes.
/**
 * Service that keeps track of all the drag item and drop container
 * instances, and manages global event listeners on the `document`.
 * @docs-private
 */
class DragDropRegistry {
  constructor(_ngZone, _document) {
    this._ngZone = _ngZone;
    this._appRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationRef);
    this._environmentInjector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.EnvironmentInjector);
    /** Registered drop container instances. */
    this._dropInstances = new Set();
    /** Registered drag item instances. */
    this._dragInstances = new Set();
    /** Drag item instances that are currently being dragged. */
    this._activeDragInstances = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.signal)([]);
    /** Keeps track of the event listeners that we've bound to the `document`. */
    this._globalListeners = new Map();
    /**
     * Predicate function to check if an item is being dragged.  Moved out into a property,
     * because it'll be called a lot and we don't want to create a new function every time.
     */
    this._draggingPredicate = item => item.isDragging();
    /**
     * Emits the `touchmove` or `mousemove` events that are dispatched
     * while the user is dragging a drag item instance.
     */
    this.pointerMove = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Emits the `touchend` or `mouseup` events that are dispatched
     * while the user is dragging a drag item instance.
     */
    this.pointerUp = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Emits when the viewport has been scrolled while the user is dragging an item.
     * @deprecated To be turned into a private member. Use the `scrolled` method instead.
     * @breaking-change 13.0.0
     */
    this.scroll = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Event listener that will prevent the default browser action while the user is dragging.
     * @param event Event whose default action should be prevented.
     */
    this._preventDefaultWhileDragging = event => {
      if (this._activeDragInstances().length > 0) {
        event.preventDefault();
      }
    };
    /** Event listener for `touchmove` that is bound even if no dragging is happening. */
    this._persistentTouchmoveListener = event => {
      if (this._activeDragInstances().length > 0) {
        // Note that we only want to prevent the default action after dragging has actually started.
        // Usually this is the same time at which the item is added to the `_activeDragInstances`,
        // but it could be pushed back if the user has set up a drag delay or threshold.
        if (this._activeDragInstances().some(this._draggingPredicate)) {
          event.preventDefault();
        }
        this.pointerMove.next(event);
      }
    };
    this._document = _document;
  }
  /** Adds a drop container to the registry. */
  registerDropContainer(drop) {
    if (!this._dropInstances.has(drop)) {
      this._dropInstances.add(drop);
    }
  }
  /** Adds a drag item instance to the registry. */
  registerDragItem(drag) {
    this._dragInstances.add(drag);
    // The `touchmove` event gets bound once, ahead of time, because WebKit
    // won't preventDefault on a dynamically-added `touchmove` listener.
    // See https://bugs.webkit.org/show_bug.cgi?id=184250.
    if (this._dragInstances.size === 1) {
      this._ngZone.runOutsideAngular(() => {
        // The event handler has to be explicitly active,
        // because newer browsers make it passive by default.
        this._document.addEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);
      });
    }
  }
  /** Removes a drop container from the registry. */
  removeDropContainer(drop) {
    this._dropInstances.delete(drop);
  }
  /** Removes a drag item instance from the registry. */
  removeDragItem(drag) {
    this._dragInstances.delete(drag);
    this.stopDragging(drag);
    if (this._dragInstances.size === 0) {
      this._document.removeEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);
    }
  }
  /**
   * Starts the dragging sequence for a drag instance.
   * @param drag Drag instance which is being dragged.
   * @param event Event that initiated the dragging.
   */
  startDragging(drag, event) {
    // Do not process the same drag twice to avoid memory leaks and redundant listeners
    if (this._activeDragInstances().indexOf(drag) > -1) {
      return;
    }
    this._loadResets();
    this._activeDragInstances.update(instances => [...instances, drag]);
    if (this._activeDragInstances().length === 1) {
      const isTouchEvent = event.type.startsWith('touch');
      // We explicitly bind __active__ listeners here, because newer browsers will default to
      // passive ones for `mousemove` and `touchmove`. The events need to be active, because we
      // use `preventDefault` to prevent the page from scrolling while the user is dragging.
      this._globalListeners.set(isTouchEvent ? 'touchend' : 'mouseup', {
        handler: e => this.pointerUp.next(e),
        options: true
      }).set('scroll', {
        handler: e => this.scroll.next(e),
        // Use capturing so that we pick up scroll changes in any scrollable nodes that aren't
        // the document. See https://github.com/angular/components/issues/17144.
        options: true
      })
      // Preventing the default action on `mousemove` isn't enough to disable text selection
      // on Safari so we need to prevent the selection event as well. Alternatively this can
      // be done by setting `user-select: none` on the `body`, however it has causes a style
      // recalculation which can be expensive on pages with a lot of elements.
      .set('selectstart', {
        handler: this._preventDefaultWhileDragging,
        options: activeCapturingEventOptions
      });
      // We don't have to bind a move event for touch drag sequences, because
      // we already have a persistent global one bound from `registerDragItem`.
      if (!isTouchEvent) {
        this._globalListeners.set('mousemove', {
          handler: e => this.pointerMove.next(e),
          options: activeCapturingEventOptions
        });
      }
      this._ngZone.runOutsideAngular(() => {
        this._globalListeners.forEach((config, name) => {
          this._document.addEventListener(name, config.handler, config.options);
        });
      });
    }
  }
  /** Stops dragging a drag item instance. */
  stopDragging(drag) {
    this._activeDragInstances.update(instances => {
      const index = instances.indexOf(drag);
      if (index > -1) {
        instances.splice(index, 1);
        return [...instances];
      }
      return instances;
    });
    if (this._activeDragInstances().length === 0) {
      this._clearGlobalListeners();
    }
  }
  /** Gets whether a drag item instance is currently being dragged. */
  isDragging(drag) {
    return this._activeDragInstances().indexOf(drag) > -1;
  }
  /**
   * Gets a stream that will emit when any element on the page is scrolled while an item is being
   * dragged.
   * @param shadowRoot Optional shadow root that the current dragging sequence started from.
   *   Top-level listeners won't pick up events coming from the shadow DOM so this parameter can
   *   be used to include an additional top-level listener at the shadow root level.
   */
  scrolled(shadowRoot) {
    const streams = [this.scroll];
    if (shadowRoot && shadowRoot !== this._document) {
      // Note that this is basically the same as `fromEvent` from rxjs, but we do it ourselves,
      // because we want to guarantee that the event is bound outside of the `NgZone`. With
      // `fromEvent` it'll only happen if the subscription is outside the `NgZone`.
      streams.push(new rxjs__WEBPACK_IMPORTED_MODULE_9__.Observable(observer => {
        return this._ngZone.runOutsideAngular(() => {
          const eventOptions = true;
          const callback = event => {
            if (this._activeDragInstances().length) {
              observer.next(event);
            }
          };
          shadowRoot.addEventListener('scroll', callback, eventOptions);
          return () => {
            shadowRoot.removeEventListener('scroll', callback, eventOptions);
          };
        });
      }));
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.merge)(...streams);
  }
  ngOnDestroy() {
    this._dragInstances.forEach(instance => this.removeDragItem(instance));
    this._dropInstances.forEach(instance => this.removeDropContainer(instance));
    this._clearGlobalListeners();
    this.pointerMove.complete();
    this.pointerUp.complete();
  }
  /** Clears out the global event listeners from the `document`. */
  _clearGlobalListeners() {
    this._globalListeners.forEach((config, name) => {
      this._document.removeEventListener(name, config.handler, config.options);
    });
    this._globalListeners.clear();
  }
  // TODO(crisbeto): abstract this away into something reusable.
  /** Loads the CSS resets needed for the module to work correctly. */
  _loadResets() {
    if (!activeApps.has(this._appRef)) {
      activeApps.add(this._appRef);
      const componentRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.createComponent)(_ResetsLoader, {
        environmentInjector: this._environmentInjector
      });
      this._appRef.onDestroy(() => {
        activeApps.delete(this._appRef);
        if (activeApps.size === 0) {
          componentRef.destroy();
        }
      });
    }
  }
  static {
    this.ɵfac = function DragDropRegistry_Factory(t) {
      return new (t || DragDropRegistry)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DragDropRegistry,
      factory: DragDropRegistry.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DragDropRegistry, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT]
    }]
  }], null);
})();

/** Default configuration to be used when creating a `DragRef`. */
const DEFAULT_CONFIG = {
  dragStartThreshold: 5,
  pointerDirectionChangeThreshold: 5
};
/**
 * Service that allows for drag-and-drop functionality to be attached to DOM elements.
 */
class DragDrop {
  constructor(_document, _ngZone, _viewportRuler, _dragDropRegistry) {
    this._document = _document;
    this._ngZone = _ngZone;
    this._viewportRuler = _viewportRuler;
    this._dragDropRegistry = _dragDropRegistry;
  }
  /**
   * Turns an element into a draggable item.
   * @param element Element to which to attach the dragging functionality.
   * @param config Object used to configure the dragging behavior.
   */
  createDrag(element, config = DEFAULT_CONFIG) {
    return new DragRef(element, config, this._document, this._ngZone, this._viewportRuler, this._dragDropRegistry);
  }
  /**
   * Turns an element into a drop list.
   * @param element Element to which to attach the drop list functionality.
   */
  createDropList(element) {
    return new DropListRef(element, this._dragDropRegistry, this._document, this._ngZone, this._viewportRuler);
  }
  static {
    this.ɵfac = function DragDrop_Factory(t) {
      return new (t || DragDrop)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.ViewportRuler), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](DragDropRegistry));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DragDrop,
      factory: DragDrop.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DragDrop, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }, {
    type: _angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.ViewportRuler
  }, {
    type: DragDropRegistry
  }], null);
})();

/**
 * Injection token that can be used for a `CdkDrag` to provide itself as a parent to the
 * drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily
 * to avoid circular imports.
 * @docs-private
 */
const CDK_DRAG_PARENT = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CDK_DRAG_PARENT');

/**
 * Asserts that a particular node is an element.
 * @param node Node to be checked.
 * @param name Name to attach to the error message.
 */
function assertElementNode(node, name) {
  if (node.nodeType !== 1) {
    throw Error(`${name} must be attached to an element node. ` + `Currently attached to "${node.nodeName}".`);
  }
}

/**
 * Injection token that can be used to reference instances of `CdkDragHandle`. It serves as
 * alternative token to the actual `CdkDragHandle` class which could cause unnecessary
 * retention of the class and its directive metadata.
 */
const CDK_DRAG_HANDLE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CdkDragHandle');
/** Handle that can be used to drag a CdkDrag instance. */
class CdkDragHandle {
  /** Whether starting to drag through this handle is disabled. */
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    this._disabled = value;
    this._stateChanges.next(this);
  }
  constructor(element, _parentDrag) {
    this.element = element;
    this._parentDrag = _parentDrag;
    /** Emits when the state of the handle has changed. */
    this._stateChanges = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    this._disabled = false;
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      assertElementNode(element.nativeElement, 'cdkDragHandle');
    }
    _parentDrag?._addHandle(this);
  }
  ngOnDestroy() {
    this._parentDrag?._removeHandle(this);
    this._stateChanges.complete();
  }
  static {
    this.ɵfac = function CdkDragHandle_Factory(t) {
      return new (t || CdkDragHandle)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DRAG_PARENT, 12));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDragHandle,
      selectors: [["", "cdkDragHandle", ""]],
      hostAttrs: [1, "cdk-drag-handle"],
      inputs: {
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDragHandleDisabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_DRAG_HANDLE,
        useExisting: CdkDragHandle
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDragHandle, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkDragHandle]',
      standalone: true,
      host: {
        'class': 'cdk-drag-handle'
      },
      providers: [{
        provide: CDK_DRAG_HANDLE,
        useExisting: CdkDragHandle
      }]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DRAG_PARENT]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }]
  }], {
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDragHandleDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }]
  });
})();

/**
 * Injection token that can be used to configure the
 * behavior of the drag&drop-related components.
 */
const CDK_DRAG_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CDK_DRAG_CONFIG');
const DRAG_HOST_CLASS = 'cdk-drag';
/**
 * Injection token that can be used to reference instances of `CdkDropList`. It serves as
 * alternative token to the actual `CdkDropList` class which could cause unnecessary
 * retention of the class and its directive metadata.
 */
const CDK_DROP_LIST = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CdkDropList');
/** Element that can be moved inside a CdkDropList container. */
class CdkDrag {
  static {
    this._dragInstances = [];
  }
  /** Whether starting to drag this element is disabled. */
  get disabled() {
    return this._disabled || this.dropContainer && this.dropContainer.disabled;
  }
  set disabled(value) {
    this._disabled = value;
    this._dragRef.disabled = this._disabled;
  }
  constructor(/** Element that the draggable is attached to. */
  element, /** Droppable container that the draggable is a part of. */
  dropContainer,
  /**
   * @deprecated `_document` parameter no longer being used and will be removed.
   * @breaking-change 12.0.0
   */
  _document, _ngZone, _viewContainerRef, config, _dir, dragDrop, _changeDetectorRef, _selfHandle, _parentDrag) {
    this.element = element;
    this.dropContainer = dropContainer;
    this._ngZone = _ngZone;
    this._viewContainerRef = _viewContainerRef;
    this._dir = _dir;
    this._changeDetectorRef = _changeDetectorRef;
    this._selfHandle = _selfHandle;
    this._parentDrag = _parentDrag;
    this._destroyed = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    this._handles = new rxjs__WEBPACK_IMPORTED_MODULE_13__.BehaviorSubject([]);
    /**
     * If the parent of the dragged element has a `scale` transform, it can throw off the
     * positioning when the user starts dragging. Use this input to notify the CDK of the scale.
     */
    this.scale = 1;
    /** Emits when the user starts dragging the item. */
    this.started = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits when the user has released a drag item, before any animations have started. */
    this.released = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits when the user stops dragging an item in the container. */
    this.ended = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits when the user has moved the item into a new container. */
    this.entered = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits when the user removes the item its container by dragging it into another container. */
    this.exited = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits when the user drops the item inside a container. */
    this.dropped = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Emits as the user is dragging the item. Use with caution,
     * because this event will fire for every pixel that the user has dragged.
     */
    this.moved = new rxjs__WEBPACK_IMPORTED_MODULE_9__.Observable(observer => {
      const subscription = this._dragRef.moved.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.map)(movedEvent => ({
        source: this,
        pointerPosition: movedEvent.pointerPosition,
        event: movedEvent.event,
        delta: movedEvent.delta,
        distance: movedEvent.distance
      }))).subscribe(observer);
      return () => {
        subscription.unsubscribe();
      };
    });
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector);
    this._dragRef = dragDrop.createDrag(element, {
      dragStartThreshold: config && config.dragStartThreshold != null ? config.dragStartThreshold : 5,
      pointerDirectionChangeThreshold: config && config.pointerDirectionChangeThreshold != null ? config.pointerDirectionChangeThreshold : 5,
      zIndex: config?.zIndex
    });
    this._dragRef.data = this;
    // We have to keep track of the drag instances in order to be able to match an element to
    // a drag instance. We can't go through the global registry of `DragRef`, because the root
    // element could be different.
    CdkDrag._dragInstances.push(this);
    if (config) {
      this._assignDefaults(config);
    }
    // Note that usually the container is assigned when the drop list is picks up the item, but in
    // some cases (mainly transplanted views with OnPush, see #18341) we may end up in a situation
    // where there are no items on the first change detection pass, but the items get picked up as
    // soon as the user triggers another pass by dragging. This is a problem, because the item would
    // have to switch from standalone mode to drag mode in the middle of the dragging sequence which
    // is too late since the two modes save different kinds of information. We work around it by
    // assigning the drop container both from here and the list.
    if (dropContainer) {
      this._dragRef._withDropContainer(dropContainer._dropListRef);
      dropContainer.addItem(this);
      // The drop container reads this so we need to sync it here.
      dropContainer._dropListRef.beforeStarted.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.takeUntil)(this._destroyed)).subscribe(() => {
        this._dragRef.scale = this.scale;
      });
    }
    this._syncInputs(this._dragRef);
    this._handleEvents(this._dragRef);
  }
  /**
   * Returns the element that is being used as a placeholder
   * while the current element is being dragged.
   */
  getPlaceholderElement() {
    return this._dragRef.getPlaceholderElement();
  }
  /** Returns the root draggable element. */
  getRootElement() {
    return this._dragRef.getRootElement();
  }
  /** Resets a standalone drag item to its initial position. */
  reset() {
    this._dragRef.reset();
  }
  /**
   * Gets the pixel coordinates of the draggable outside of a drop container.
   */
  getFreeDragPosition() {
    return this._dragRef.getFreeDragPosition();
  }
  /**
   * Sets the current position in pixels the draggable outside of a drop container.
   * @param value New position to be set.
   */
  setFreeDragPosition(value) {
    this._dragRef.setFreeDragPosition(value);
  }
  ngAfterViewInit() {
    // We need to wait until after render, in order for the reference
    // element to be in the proper place in the DOM. This is mostly relevant
    // for draggable elements inside portals since they get stamped out in
    // their original DOM position, and then they get transferred to the portal.
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.afterNextRender)(() => {
      this._updateRootElement();
      this._setupHandlesListener();
      this._dragRef.scale = this.scale;
      if (this.freeDragPosition) {
        this._dragRef.setFreeDragPosition(this.freeDragPosition);
      }
    }, {
      injector: this._injector
    });
  }
  ngOnChanges(changes) {
    const rootSelectorChange = changes['rootElementSelector'];
    const positionChange = changes['freeDragPosition'];
    // We don't have to react to the first change since it's being
    // handled in the `afterNextRender` queued up in the constructor.
    if (rootSelectorChange && !rootSelectorChange.firstChange) {
      this._updateRootElement();
    }
    // Scale affects the free drag position so we need to sync it up here.
    this._dragRef.scale = this.scale;
    // Skip the first change since it's being handled in the `afterNextRender` queued up in the
    // constructor.
    if (positionChange && !positionChange.firstChange && this.freeDragPosition) {
      this._dragRef.setFreeDragPosition(this.freeDragPosition);
    }
  }
  ngOnDestroy() {
    if (this.dropContainer) {
      this.dropContainer.removeItem(this);
    }
    const index = CdkDrag._dragInstances.indexOf(this);
    if (index > -1) {
      CdkDrag._dragInstances.splice(index, 1);
    }
    // Unnecessary in most cases, but used to avoid extra change detections with `zone-paths-rxjs`.
    this._ngZone.runOutsideAngular(() => {
      this._handles.complete();
      this._destroyed.next();
      this._destroyed.complete();
      this._dragRef.dispose();
    });
  }
  _addHandle(handle) {
    const handles = this._handles.getValue();
    handles.push(handle);
    this._handles.next(handles);
  }
  _removeHandle(handle) {
    const handles = this._handles.getValue();
    const index = handles.indexOf(handle);
    if (index > -1) {
      handles.splice(index, 1);
      this._handles.next(handles);
    }
  }
  _setPreviewTemplate(preview) {
    this._previewTemplate = preview;
  }
  _resetPreviewTemplate(preview) {
    if (preview === this._previewTemplate) {
      this._previewTemplate = null;
    }
  }
  _setPlaceholderTemplate(placeholder) {
    this._placeholderTemplate = placeholder;
  }
  _resetPlaceholderTemplate(placeholder) {
    if (placeholder === this._placeholderTemplate) {
      this._placeholderTemplate = null;
    }
  }
  /** Syncs the root element with the `DragRef`. */
  _updateRootElement() {
    const element = this.element.nativeElement;
    let rootElement = element;
    if (this.rootElementSelector) {
      rootElement = element.closest !== undefined ? element.closest(this.rootElementSelector) :
      // Comment tag doesn't have closest method, so use parent's one.
      element.parentElement?.closest(this.rootElementSelector);
    }
    if (rootElement && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      assertElementNode(rootElement, 'cdkDrag');
    }
    this._dragRef.withRootElement(rootElement || element);
  }
  /** Gets the boundary element, based on the `boundaryElement` value. */
  _getBoundaryElement() {
    const boundary = this.boundaryElement;
    if (!boundary) {
      return null;
    }
    if (typeof boundary === 'string') {
      return this.element.nativeElement.closest(boundary);
    }
    return (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceElement)(boundary);
  }
  /** Syncs the inputs of the CdkDrag with the options of the underlying DragRef. */
  _syncInputs(ref) {
    ref.beforeStarted.subscribe(() => {
      if (!ref.isDragging()) {
        const dir = this._dir;
        const dragStartDelay = this.dragStartDelay;
        const placeholder = this._placeholderTemplate ? {
          template: this._placeholderTemplate.templateRef,
          context: this._placeholderTemplate.data,
          viewContainer: this._viewContainerRef
        } : null;
        const preview = this._previewTemplate ? {
          template: this._previewTemplate.templateRef,
          context: this._previewTemplate.data,
          matchSize: this._previewTemplate.matchSize,
          viewContainer: this._viewContainerRef
        } : null;
        ref.disabled = this.disabled;
        ref.lockAxis = this.lockAxis;
        ref.scale = this.scale;
        ref.dragStartDelay = typeof dragStartDelay === 'object' && dragStartDelay ? dragStartDelay : (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceNumberProperty)(dragStartDelay);
        ref.constrainPosition = this.constrainPosition;
        ref.previewClass = this.previewClass;
        ref.withBoundaryElement(this._getBoundaryElement()).withPlaceholderTemplate(placeholder).withPreviewTemplate(preview).withPreviewContainer(this.previewContainer || 'global');
        if (dir) {
          ref.withDirection(dir.value);
        }
      }
    });
    // This only needs to be resolved once.
    ref.beforeStarted.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.take)(1)).subscribe(() => {
      // If we managed to resolve a parent through DI, use it.
      if (this._parentDrag) {
        ref.withParent(this._parentDrag._dragRef);
        return;
      }
      // Otherwise fall back to resolving the parent by looking up the DOM. This can happen if
      // the item was projected into another item by something like `ngTemplateOutlet`.
      let parent = this.element.nativeElement.parentElement;
      while (parent) {
        if (parent.classList.contains(DRAG_HOST_CLASS)) {
          ref.withParent(CdkDrag._dragInstances.find(drag => {
            return drag.element.nativeElement === parent;
          })?._dragRef || null);
          break;
        }
        parent = parent.parentElement;
      }
    });
  }
  /** Handles the events from the underlying `DragRef`. */
  _handleEvents(ref) {
    ref.started.subscribe(startEvent => {
      this.started.emit({
        source: this,
        event: startEvent.event
      });
      // Since all of these events run outside of change detection,
      // we need to ensure that everything is marked correctly.
      this._changeDetectorRef.markForCheck();
    });
    ref.released.subscribe(releaseEvent => {
      this.released.emit({
        source: this,
        event: releaseEvent.event
      });
    });
    ref.ended.subscribe(endEvent => {
      this.ended.emit({
        source: this,
        distance: endEvent.distance,
        dropPoint: endEvent.dropPoint,
        event: endEvent.event
      });
      // Since all of these events run outside of change detection,
      // we need to ensure that everything is marked correctly.
      this._changeDetectorRef.markForCheck();
    });
    ref.entered.subscribe(enterEvent => {
      this.entered.emit({
        container: enterEvent.container.data,
        item: this,
        currentIndex: enterEvent.currentIndex
      });
    });
    ref.exited.subscribe(exitEvent => {
      this.exited.emit({
        container: exitEvent.container.data,
        item: this
      });
    });
    ref.dropped.subscribe(dropEvent => {
      this.dropped.emit({
        previousIndex: dropEvent.previousIndex,
        currentIndex: dropEvent.currentIndex,
        previousContainer: dropEvent.previousContainer.data,
        container: dropEvent.container.data,
        isPointerOverContainer: dropEvent.isPointerOverContainer,
        item: this,
        distance: dropEvent.distance,
        dropPoint: dropEvent.dropPoint,
        event: dropEvent.event
      });
    });
  }
  /** Assigns the default input values based on a provided config object. */
  _assignDefaults(config) {
    const {
      lockAxis,
      dragStartDelay,
      constrainPosition,
      previewClass,
      boundaryElement,
      draggingDisabled,
      rootElementSelector,
      previewContainer
    } = config;
    this.disabled = draggingDisabled == null ? false : draggingDisabled;
    this.dragStartDelay = dragStartDelay || 0;
    if (lockAxis) {
      this.lockAxis = lockAxis;
    }
    if (constrainPosition) {
      this.constrainPosition = constrainPosition;
    }
    if (previewClass) {
      this.previewClass = previewClass;
    }
    if (boundaryElement) {
      this.boundaryElement = boundaryElement;
    }
    if (rootElementSelector) {
      this.rootElementSelector = rootElementSelector;
    }
    if (previewContainer) {
      this.previewContainer = previewContainer;
    }
  }
  /** Sets up the listener that syncs the handles with the drag ref. */
  _setupHandlesListener() {
    // Listen for any newly-added handles.
    this._handles.pipe(
    // Sync the new handles with the DragRef.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.tap)(handles => {
      const handleElements = handles.map(handle => handle.element);
      // Usually handles are only allowed to be a descendant of the drag element, but if
      // the consumer defined a different drag root, we should allow the drag element
      // itself to be a handle too.
      if (this._selfHandle && this.rootElementSelector) {
        handleElements.push(this.element);
      }
      this._dragRef.withHandles(handleElements);
    }),
    // Listen if the state of any of the handles changes.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.switchMap)(handles => {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.merge)(...handles.map(item => item._stateChanges.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_18__.startWith)(item))));
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.takeUntil)(this._destroyed)).subscribe(handleInstance => {
      // Enabled/disable the handle that changed in the DragRef.
      const dragRef = this._dragRef;
      const handle = handleInstance.element.nativeElement;
      handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);
    });
  }
  static {
    this.ɵfac = function CdkDrag_Factory(t) {
      return new (t || CdkDrag)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DROP_LIST, 12), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DRAG_CONFIG, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_19__.Directionality, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](DragDrop), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DRAG_HANDLE, 10), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DRAG_PARENT, 12));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDrag,
      selectors: [["", "cdkDrag", ""]],
      hostAttrs: [1, "cdk-drag"],
      hostVars: 4,
      hostBindings: function CdkDrag_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵclassProp"]("cdk-drag-disabled", ctx.disabled)("cdk-drag-dragging", ctx._dragRef.isDragging());
        }
      },
      inputs: {
        data: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragData", "data"],
        lockAxis: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragLockAxis", "lockAxis"],
        rootElementSelector: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragRootElement", "rootElementSelector"],
        boundaryElement: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragBoundary", "boundaryElement"],
        dragStartDelay: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragStartDelay", "dragStartDelay"],
        freeDragPosition: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragFreeDragPosition", "freeDragPosition"],
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDragDisabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        constrainPosition: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragConstrainPosition", "constrainPosition"],
        previewClass: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragPreviewClass", "previewClass"],
        previewContainer: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDragPreviewContainer", "previewContainer"],
        scale: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDragScale", "scale", _angular_core__WEBPACK_IMPORTED_MODULE_1__.numberAttribute]
      },
      outputs: {
        started: "cdkDragStarted",
        released: "cdkDragReleased",
        ended: "cdkDragEnded",
        entered: "cdkDragEntered",
        exited: "cdkDragExited",
        dropped: "cdkDragDropped",
        moved: "cdkDragMoved"
      },
      exportAs: ["cdkDrag"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_DRAG_PARENT,
        useExisting: CdkDrag
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDrag, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkDrag]',
      exportAs: 'cdkDrag',
      standalone: true,
      host: {
        'class': DRAG_HOST_CLASS,
        '[class.cdk-drag-disabled]': 'disabled',
        '[class.cdk-drag-dragging]': '_dragRef.isDragging()'
      },
      providers: [{
        provide: CDK_DRAG_PARENT,
        useExisting: CdkDrag
      }]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DROP_LIST]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_11__.DOCUMENT]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DRAG_CONFIG]
    }]
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_19__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }, {
    type: DragDrop
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef
  }, {
    type: CdkDragHandle,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DRAG_HANDLE]
    }]
  }, {
    type: CdkDrag,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DRAG_PARENT]
    }]
  }], {
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragData']
    }],
    lockAxis: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragLockAxis']
    }],
    rootElementSelector: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragRootElement']
    }],
    boundaryElement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragBoundary']
    }],
    dragStartDelay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragStartDelay']
    }],
    freeDragPosition: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragFreeDragPosition']
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDragDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    constrainPosition: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragConstrainPosition']
    }],
    previewClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragPreviewClass']
    }],
    previewContainer: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDragPreviewContainer']
    }],
    scale: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDragScale',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.numberAttribute
      }]
    }],
    started: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragStarted']
    }],
    released: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragReleased']
    }],
    ended: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragEnded']
    }],
    entered: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragEntered']
    }],
    exited: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragExited']
    }],
    dropped: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragDropped']
    }],
    moved: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDragMoved']
    }]
  });
})();

/**
 * Injection token that can be used to reference instances of `CdkDropListGroup`. It serves as
 * alternative token to the actual `CdkDropListGroup` class which could cause unnecessary
 * retention of the class and its directive metadata.
 */
const CDK_DROP_LIST_GROUP = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CdkDropListGroup');
/**
 * Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`
 * elements that are placed inside a `cdkDropListGroup` will be connected to each other
 * automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
 * from `cdkDropList`.
 */
class CdkDropListGroup {
  constructor() {
    /** Drop lists registered inside the group. */
    this._items = new Set();
    /** Whether starting a dragging sequence from inside this group is disabled. */
    this.disabled = false;
  }
  ngOnDestroy() {
    this._items.clear();
  }
  static {
    this.ɵfac = function CdkDropListGroup_Factory(t) {
      return new (t || CdkDropListGroup)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDropListGroup,
      selectors: [["", "cdkDropListGroup", ""]],
      inputs: {
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDropListGroupDisabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      exportAs: ["cdkDropListGroup"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_DROP_LIST_GROUP,
        useExisting: CdkDropListGroup
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDropListGroup, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkDropListGroup]',
      exportAs: 'cdkDropListGroup',
      standalone: true,
      providers: [{
        provide: CDK_DROP_LIST_GROUP,
        useExisting: CdkDropListGroup
      }]
    }]
  }], null, {
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDropListGroupDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }]
  });
})();

/** Counter used to generate unique ids for drop zones. */
let _uniqueIdCounter = 0;
/** Container that wraps a set of draggable items. */
class CdkDropList {
  /** Keeps track of the drop lists that are currently on the page. */
  static {
    this._dropLists = [];
  }
  /** Whether starting a dragging sequence from this container is disabled. */
  get disabled() {
    return this._disabled || !!this._group && this._group.disabled;
  }
  set disabled(value) {
    // Usually we sync the directive and ref state right before dragging starts, in order to have
    // a single point of failure and to avoid having to use setters for everything. `disabled` is
    // a special case, because it can prevent the `beforeStarted` event from firing, which can lock
    // the user in a disabled state, so we also need to sync it as it's being set.
    this._dropListRef.disabled = this._disabled = value;
  }
  constructor(/** Element that the drop list is attached to. */
  element, dragDrop, _changeDetectorRef, _scrollDispatcher, _dir, _group, config) {
    this.element = element;
    this._changeDetectorRef = _changeDetectorRef;
    this._scrollDispatcher = _scrollDispatcher;
    this._dir = _dir;
    this._group = _group;
    /** Emits when the list has been destroyed. */
    this._destroyed = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Other draggable containers that this container is connected to and into which the
     * container's items can be transferred. Can either be references to other drop containers,
     * or their unique IDs.
     */
    this.connectedTo = [];
    /**
     * Unique ID for the drop zone. Can be used as a reference
     * in the `connectedTo` of another `CdkDropList`.
     */
    this.id = `cdk-drop-list-${_uniqueIdCounter++}`;
    /**
     * Function that is used to determine whether an item
     * is allowed to be moved into a drop container.
     */
    this.enterPredicate = () => true;
    /** Functions that is used to determine whether an item can be sorted into a particular index. */
    this.sortPredicate = () => true;
    /** Emits when the user drops an item inside the container. */
    this.dropped = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Emits when the user has moved a new drag item into this container.
     */
    this.entered = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Emits when the user removes an item from the container
     * by dragging it into another container.
     */
    this.exited = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /** Emits as the user is swapping items while actively dragging. */
    this.sorted = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Keeps track of the items that are registered with this container. Historically we used to
     * do this with a `ContentChildren` query, however queries don't handle transplanted views very
     * well which means that we can't handle cases like dragging the headers of a `mat-table`
     * correctly. What we do instead is to have the items register themselves with the container
     * and then we sort them based on their position in the DOM.
     */
    this._unsortedItems = new Set();
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      assertElementNode(element.nativeElement, 'cdkDropList');
    }
    this._dropListRef = dragDrop.createDropList(element);
    this._dropListRef.data = this;
    if (config) {
      this._assignDefaults(config);
    }
    this._dropListRef.enterPredicate = (drag, drop) => {
      return this.enterPredicate(drag.data, drop.data);
    };
    this._dropListRef.sortPredicate = (index, drag, drop) => {
      return this.sortPredicate(index, drag.data, drop.data);
    };
    this._setupInputSyncSubscription(this._dropListRef);
    this._handleEvents(this._dropListRef);
    CdkDropList._dropLists.push(this);
    if (_group) {
      _group._items.add(this);
    }
  }
  /** Registers an items with the drop list. */
  addItem(item) {
    this._unsortedItems.add(item);
    if (this._dropListRef.isDragging()) {
      this._syncItemsWithRef();
    }
  }
  /** Removes an item from the drop list. */
  removeItem(item) {
    this._unsortedItems.delete(item);
    if (this._dropListRef.isDragging()) {
      this._syncItemsWithRef();
    }
  }
  /** Gets the registered items in the list, sorted by their position in the DOM. */
  getSortedItems() {
    return Array.from(this._unsortedItems).sort((a, b) => {
      const documentPosition = a._dragRef.getVisibleElement().compareDocumentPosition(b._dragRef.getVisibleElement());
      // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.
      // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
      // tslint:disable-next-line:no-bitwise
      return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
    });
  }
  ngOnDestroy() {
    const index = CdkDropList._dropLists.indexOf(this);
    if (index > -1) {
      CdkDropList._dropLists.splice(index, 1);
    }
    if (this._group) {
      this._group._items.delete(this);
    }
    this._unsortedItems.clear();
    this._dropListRef.dispose();
    this._destroyed.next();
    this._destroyed.complete();
  }
  /** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */
  _setupInputSyncSubscription(ref) {
    if (this._dir) {
      this._dir.change.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_18__.startWith)(this._dir.value), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.takeUntil)(this._destroyed)).subscribe(value => ref.withDirection(value));
    }
    ref.beforeStarted.subscribe(() => {
      const siblings = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceArray)(this.connectedTo).map(drop => {
        if (typeof drop === 'string') {
          const correspondingDropList = CdkDropList._dropLists.find(list => list.id === drop);
          if (!correspondingDropList && (typeof ngDevMode === 'undefined' || ngDevMode)) {
            console.warn(`CdkDropList could not find connected drop list with id "${drop}"`);
          }
          return correspondingDropList;
        }
        return drop;
      });
      if (this._group) {
        this._group._items.forEach(drop => {
          if (siblings.indexOf(drop) === -1) {
            siblings.push(drop);
          }
        });
      }
      // Note that we resolve the scrollable parents here so that we delay the resolution
      // as long as possible, ensuring that the element is in its final place in the DOM.
      if (!this._scrollableParentsResolved) {
        const scrollableParents = this._scrollDispatcher.getAncestorScrollContainers(this.element).map(scrollable => scrollable.getElementRef().nativeElement);
        this._dropListRef.withScrollableParents(scrollableParents);
        // Only do this once since it involves traversing the DOM and the parents
        // shouldn't be able to change without the drop list being destroyed.
        this._scrollableParentsResolved = true;
      }
      if (this.elementContainerSelector) {
        const container = this.element.nativeElement.querySelector(this.elementContainerSelector);
        if (!container && (typeof ngDevMode === 'undefined' || ngDevMode)) {
          throw new Error(`CdkDropList could not find an element container matching the selector "${this.elementContainerSelector}"`);
        }
        ref.withElementContainer(container);
      }
      ref.disabled = this.disabled;
      ref.lockAxis = this.lockAxis;
      ref.sortingDisabled = this.sortingDisabled;
      ref.autoScrollDisabled = this.autoScrollDisabled;
      ref.autoScrollStep = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_4__.coerceNumberProperty)(this.autoScrollStep, 2);
      ref.connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef)).withOrientation(this.orientation);
    });
  }
  /** Handles events from the underlying DropListRef. */
  _handleEvents(ref) {
    ref.beforeStarted.subscribe(() => {
      this._syncItemsWithRef();
      this._changeDetectorRef.markForCheck();
    });
    ref.entered.subscribe(event => {
      this.entered.emit({
        container: this,
        item: event.item.data,
        currentIndex: event.currentIndex
      });
    });
    ref.exited.subscribe(event => {
      this.exited.emit({
        container: this,
        item: event.item.data
      });
      this._changeDetectorRef.markForCheck();
    });
    ref.sorted.subscribe(event => {
      this.sorted.emit({
        previousIndex: event.previousIndex,
        currentIndex: event.currentIndex,
        container: this,
        item: event.item.data
      });
    });
    ref.dropped.subscribe(dropEvent => {
      this.dropped.emit({
        previousIndex: dropEvent.previousIndex,
        currentIndex: dropEvent.currentIndex,
        previousContainer: dropEvent.previousContainer.data,
        container: dropEvent.container.data,
        item: dropEvent.item.data,
        isPointerOverContainer: dropEvent.isPointerOverContainer,
        distance: dropEvent.distance,
        dropPoint: dropEvent.dropPoint,
        event: dropEvent.event
      });
      // Mark for check since all of these events run outside of change
      // detection and we're not guaranteed for something else to have triggered it.
      this._changeDetectorRef.markForCheck();
    });
    (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.merge)(ref.receivingStarted, ref.receivingStopped).subscribe(() => this._changeDetectorRef.markForCheck());
  }
  /** Assigns the default input values based on a provided config object. */
  _assignDefaults(config) {
    const {
      lockAxis,
      draggingDisabled,
      sortingDisabled,
      listAutoScrollDisabled,
      listOrientation
    } = config;
    this.disabled = draggingDisabled == null ? false : draggingDisabled;
    this.sortingDisabled = sortingDisabled == null ? false : sortingDisabled;
    this.autoScrollDisabled = listAutoScrollDisabled == null ? false : listAutoScrollDisabled;
    this.orientation = listOrientation || 'vertical';
    if (lockAxis) {
      this.lockAxis = lockAxis;
    }
  }
  /** Syncs up the registered drag items with underlying drop list ref. */
  _syncItemsWithRef() {
    this._dropListRef.withItems(this.getSortedItems().map(item => item._dragRef));
  }
  static {
    this.ɵfac = function CdkDropList_Factory(t) {
      return new (t || CdkDropList)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](DragDrop), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_19__.Directionality, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DROP_LIST_GROUP, 12), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_DRAG_CONFIG, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDropList,
      selectors: [["", "cdkDropList", ""], ["cdk-drop-list"]],
      hostAttrs: [1, "cdk-drop-list"],
      hostVars: 7,
      hostBindings: function CdkDropList_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵattribute"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵclassProp"]("cdk-drop-list-disabled", ctx.disabled)("cdk-drop-list-dragging", ctx._dropListRef.isDragging())("cdk-drop-list-receiving", ctx._dropListRef.isReceiving());
        }
      },
      inputs: {
        connectedTo: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListConnectedTo", "connectedTo"],
        data: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListData", "data"],
        orientation: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListOrientation", "orientation"],
        id: "id",
        lockAxis: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListLockAxis", "lockAxis"],
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDropListDisabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        sortingDisabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDropListSortingDisabled", "sortingDisabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        enterPredicate: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListEnterPredicate", "enterPredicate"],
        sortPredicate: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListSortPredicate", "sortPredicate"],
        autoScrollDisabled: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkDropListAutoScrollDisabled", "autoScrollDisabled", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        autoScrollStep: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListAutoScrollStep", "autoScrollStep"],
        elementContainerSelector: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkDropListElementContainer", "elementContainerSelector"]
      },
      outputs: {
        dropped: "cdkDropListDropped",
        entered: "cdkDropListEntered",
        exited: "cdkDropListExited",
        sorted: "cdkDropListSorted"
      },
      exportAs: ["cdkDropList"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([
      // Prevent child drop lists from picking up the same group as their parent.
      {
        provide: CDK_DROP_LIST_GROUP,
        useValue: undefined
      }, {
        provide: CDK_DROP_LIST,
        useExisting: CdkDropList
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDropList, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkDropList], cdk-drop-list',
      exportAs: 'cdkDropList',
      standalone: true,
      providers: [
      // Prevent child drop lists from picking up the same group as their parent.
      {
        provide: CDK_DROP_LIST_GROUP,
        useValue: undefined
      }, {
        provide: CDK_DROP_LIST,
        useExisting: CdkDropList
      }],
      host: {
        'class': 'cdk-drop-list',
        '[attr.id]': 'id',
        '[class.cdk-drop-list-disabled]': 'disabled',
        '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
        '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()'
      }
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: DragDrop
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef
  }, {
    type: _angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.ScrollDispatcher
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_19__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }, {
    type: CdkDropListGroup,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DROP_LIST_GROUP]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_DRAG_CONFIG]
    }]
  }], {
    connectedTo: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListConnectedTo']
    }],
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListData']
    }],
    orientation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListOrientation']
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    lockAxis: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListLockAxis']
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDropListDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    sortingDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDropListSortingDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    enterPredicate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListEnterPredicate']
    }],
    sortPredicate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListSortPredicate']
    }],
    autoScrollDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkDropListAutoScrollDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    autoScrollStep: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListAutoScrollStep']
    }],
    elementContainerSelector: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkDropListElementContainer']
    }],
    dropped: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDropListDropped']
    }],
    entered: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDropListEntered']
    }],
    exited: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDropListExited']
    }],
    sorted: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['cdkDropListSorted']
    }]
  });
})();

/**
 * Injection token that can be used to reference instances of `CdkDragPreview`. It serves as
 * alternative token to the actual `CdkDragPreview` class which could cause unnecessary
 * retention of the class and its directive metadata.
 */
const CDK_DRAG_PREVIEW = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CdkDragPreview');
/**
 * Element that will be used as a template for the preview
 * of a CdkDrag when it is being dragged.
 */
class CdkDragPreview {
  constructor(templateRef) {
    this.templateRef = templateRef;
    this._drag = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_DRAG_PARENT, {
      optional: true
    });
    /** Whether the preview should preserve the same size as the item that is being dragged. */
    this.matchSize = false;
    this._drag?._setPreviewTemplate(this);
  }
  ngOnDestroy() {
    this._drag?._resetPreviewTemplate(this);
  }
  static {
    this.ɵfac = function CdkDragPreview_Factory(t) {
      return new (t || CdkDragPreview)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDragPreview,
      selectors: [["ng-template", "cdkDragPreview", ""]],
      inputs: {
        data: "data",
        matchSize: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "matchSize", "matchSize", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_DRAG_PREVIEW,
        useExisting: CdkDragPreview
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDragPreview, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'ng-template[cdkDragPreview]',
      standalone: true,
      providers: [{
        provide: CDK_DRAG_PREVIEW,
        useExisting: CdkDragPreview
      }]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], {
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    matchSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }]
  });
})();

/**
 * Injection token that can be used to reference instances of `CdkDragPlaceholder`. It serves as
 * alternative token to the actual `CdkDragPlaceholder` class which could cause unnecessary
 * retention of the class and its directive metadata.
 */
const CDK_DRAG_PLACEHOLDER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CdkDragPlaceholder');
/**
 * Element that will be used as a template for the placeholder of a CdkDrag when
 * it is being dragged. The placeholder is displayed in place of the element being dragged.
 */
class CdkDragPlaceholder {
  constructor(templateRef) {
    this.templateRef = templateRef;
    this._drag = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_DRAG_PARENT, {
      optional: true
    });
    this._drag?._setPlaceholderTemplate(this);
  }
  ngOnDestroy() {
    this._drag?._resetPlaceholderTemplate(this);
  }
  static {
    this.ɵfac = function CdkDragPlaceholder_Factory(t) {
      return new (t || CdkDragPlaceholder)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkDragPlaceholder,
      selectors: [["ng-template", "cdkDragPlaceholder", ""]],
      inputs: {
        data: "data"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_DRAG_PLACEHOLDER,
        useExisting: CdkDragPlaceholder
      }])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkDragPlaceholder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'ng-template[cdkDragPlaceholder]',
      standalone: true,
      providers: [{
        provide: CDK_DRAG_PLACEHOLDER,
        useExisting: CdkDragPlaceholder
      }]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], {
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }]
  });
})();
const DRAG_DROP_DIRECTIVES = [CdkDropList, CdkDropListGroup, CdkDrag, CdkDragHandle, CdkDragPreview, CdkDragPlaceholder];
class DragDropModule {
  static {
    this.ɵfac = function DragDropModule_Factory(t) {
      return new (t || DragDropModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: DragDropModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
      providers: [DragDrop],
      imports: [_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.CdkScrollableModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DragDropModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      imports: DRAG_DROP_DIRECTIVES,
      exports: [_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_12__.CdkScrollableModule, ...DRAG_DROP_DIRECTIVES],
      providers: [DragDrop]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 74879:
/*!*********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/keycodes.mjs ***!
  \*********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (/* binding */ A),
/* harmony export */   ALT: () => (/* binding */ ALT),
/* harmony export */   APOSTROPHE: () => (/* binding */ APOSTROPHE),
/* harmony export */   AT_SIGN: () => (/* binding */ AT_SIGN),
/* harmony export */   B: () => (/* binding */ B),
/* harmony export */   BACKSLASH: () => (/* binding */ BACKSLASH),
/* harmony export */   BACKSPACE: () => (/* binding */ BACKSPACE),
/* harmony export */   C: () => (/* binding */ C),
/* harmony export */   CAPS_LOCK: () => (/* binding */ CAPS_LOCK),
/* harmony export */   CLOSE_SQUARE_BRACKET: () => (/* binding */ CLOSE_SQUARE_BRACKET),
/* harmony export */   COMMA: () => (/* binding */ COMMA),
/* harmony export */   CONTEXT_MENU: () => (/* binding */ CONTEXT_MENU),
/* harmony export */   CONTROL: () => (/* binding */ CONTROL),
/* harmony export */   D: () => (/* binding */ D),
/* harmony export */   DASH: () => (/* binding */ DASH),
/* harmony export */   DELETE: () => (/* binding */ DELETE),
/* harmony export */   DOWN_ARROW: () => (/* binding */ DOWN_ARROW),
/* harmony export */   E: () => (/* binding */ E),
/* harmony export */   EIGHT: () => (/* binding */ EIGHT),
/* harmony export */   END: () => (/* binding */ END),
/* harmony export */   ENTER: () => (/* binding */ ENTER),
/* harmony export */   EQUALS: () => (/* binding */ EQUALS),
/* harmony export */   ESCAPE: () => (/* binding */ ESCAPE),
/* harmony export */   F: () => (/* binding */ F),
/* harmony export */   F1: () => (/* binding */ F1),
/* harmony export */   F10: () => (/* binding */ F10),
/* harmony export */   F11: () => (/* binding */ F11),
/* harmony export */   F12: () => (/* binding */ F12),
/* harmony export */   F2: () => (/* binding */ F2),
/* harmony export */   F3: () => (/* binding */ F3),
/* harmony export */   F4: () => (/* binding */ F4),
/* harmony export */   F5: () => (/* binding */ F5),
/* harmony export */   F6: () => (/* binding */ F6),
/* harmony export */   F7: () => (/* binding */ F7),
/* harmony export */   F8: () => (/* binding */ F8),
/* harmony export */   F9: () => (/* binding */ F9),
/* harmony export */   FF_EQUALS: () => (/* binding */ FF_EQUALS),
/* harmony export */   FF_MINUS: () => (/* binding */ FF_MINUS),
/* harmony export */   FF_MUTE: () => (/* binding */ FF_MUTE),
/* harmony export */   FF_SEMICOLON: () => (/* binding */ FF_SEMICOLON),
/* harmony export */   FF_VOLUME_DOWN: () => (/* binding */ FF_VOLUME_DOWN),
/* harmony export */   FF_VOLUME_UP: () => (/* binding */ FF_VOLUME_UP),
/* harmony export */   FIRST_MEDIA: () => (/* binding */ FIRST_MEDIA),
/* harmony export */   FIVE: () => (/* binding */ FIVE),
/* harmony export */   FOUR: () => (/* binding */ FOUR),
/* harmony export */   G: () => (/* binding */ G),
/* harmony export */   H: () => (/* binding */ H),
/* harmony export */   HOME: () => (/* binding */ HOME),
/* harmony export */   I: () => (/* binding */ I),
/* harmony export */   INSERT: () => (/* binding */ INSERT),
/* harmony export */   J: () => (/* binding */ J),
/* harmony export */   K: () => (/* binding */ K),
/* harmony export */   L: () => (/* binding */ L),
/* harmony export */   LAST_MEDIA: () => (/* binding */ LAST_MEDIA),
/* harmony export */   LEFT_ARROW: () => (/* binding */ LEFT_ARROW),
/* harmony export */   M: () => (/* binding */ M),
/* harmony export */   MAC_ENTER: () => (/* binding */ MAC_ENTER),
/* harmony export */   MAC_META: () => (/* binding */ MAC_META),
/* harmony export */   MAC_WK_CMD_LEFT: () => (/* binding */ MAC_WK_CMD_LEFT),
/* harmony export */   MAC_WK_CMD_RIGHT: () => (/* binding */ MAC_WK_CMD_RIGHT),
/* harmony export */   META: () => (/* binding */ META),
/* harmony export */   MUTE: () => (/* binding */ MUTE),
/* harmony export */   N: () => (/* binding */ N),
/* harmony export */   NINE: () => (/* binding */ NINE),
/* harmony export */   NUMPAD_DIVIDE: () => (/* binding */ NUMPAD_DIVIDE),
/* harmony export */   NUMPAD_EIGHT: () => (/* binding */ NUMPAD_EIGHT),
/* harmony export */   NUMPAD_FIVE: () => (/* binding */ NUMPAD_FIVE),
/* harmony export */   NUMPAD_FOUR: () => (/* binding */ NUMPAD_FOUR),
/* harmony export */   NUMPAD_MINUS: () => (/* binding */ NUMPAD_MINUS),
/* harmony export */   NUMPAD_MULTIPLY: () => (/* binding */ NUMPAD_MULTIPLY),
/* harmony export */   NUMPAD_NINE: () => (/* binding */ NUMPAD_NINE),
/* harmony export */   NUMPAD_ONE: () => (/* binding */ NUMPAD_ONE),
/* harmony export */   NUMPAD_PERIOD: () => (/* binding */ NUMPAD_PERIOD),
/* harmony export */   NUMPAD_PLUS: () => (/* binding */ NUMPAD_PLUS),
/* harmony export */   NUMPAD_SEVEN: () => (/* binding */ NUMPAD_SEVEN),
/* harmony export */   NUMPAD_SIX: () => (/* binding */ NUMPAD_SIX),
/* harmony export */   NUMPAD_THREE: () => (/* binding */ NUMPAD_THREE),
/* harmony export */   NUMPAD_TWO: () => (/* binding */ NUMPAD_TWO),
/* harmony export */   NUMPAD_ZERO: () => (/* binding */ NUMPAD_ZERO),
/* harmony export */   NUM_CENTER: () => (/* binding */ NUM_CENTER),
/* harmony export */   NUM_LOCK: () => (/* binding */ NUM_LOCK),
/* harmony export */   O: () => (/* binding */ O),
/* harmony export */   ONE: () => (/* binding */ ONE),
/* harmony export */   OPEN_SQUARE_BRACKET: () => (/* binding */ OPEN_SQUARE_BRACKET),
/* harmony export */   P: () => (/* binding */ P),
/* harmony export */   PAGE_DOWN: () => (/* binding */ PAGE_DOWN),
/* harmony export */   PAGE_UP: () => (/* binding */ PAGE_UP),
/* harmony export */   PAUSE: () => (/* binding */ PAUSE),
/* harmony export */   PERIOD: () => (/* binding */ PERIOD),
/* harmony export */   PLUS_SIGN: () => (/* binding */ PLUS_SIGN),
/* harmony export */   PRINT_SCREEN: () => (/* binding */ PRINT_SCREEN),
/* harmony export */   Q: () => (/* binding */ Q),
/* harmony export */   QUESTION_MARK: () => (/* binding */ QUESTION_MARK),
/* harmony export */   R: () => (/* binding */ R),
/* harmony export */   RIGHT_ARROW: () => (/* binding */ RIGHT_ARROW),
/* harmony export */   S: () => (/* binding */ S),
/* harmony export */   SCROLL_LOCK: () => (/* binding */ SCROLL_LOCK),
/* harmony export */   SEMICOLON: () => (/* binding */ SEMICOLON),
/* harmony export */   SEVEN: () => (/* binding */ SEVEN),
/* harmony export */   SHIFT: () => (/* binding */ SHIFT),
/* harmony export */   SINGLE_QUOTE: () => (/* binding */ SINGLE_QUOTE),
/* harmony export */   SIX: () => (/* binding */ SIX),
/* harmony export */   SLASH: () => (/* binding */ SLASH),
/* harmony export */   SPACE: () => (/* binding */ SPACE),
/* harmony export */   T: () => (/* binding */ T),
/* harmony export */   TAB: () => (/* binding */ TAB),
/* harmony export */   THREE: () => (/* binding */ THREE),
/* harmony export */   TILDE: () => (/* binding */ TILDE),
/* harmony export */   TWO: () => (/* binding */ TWO),
/* harmony export */   U: () => (/* binding */ U),
/* harmony export */   UP_ARROW: () => (/* binding */ UP_ARROW),
/* harmony export */   V: () => (/* binding */ V),
/* harmony export */   VOLUME_DOWN: () => (/* binding */ VOLUME_DOWN),
/* harmony export */   VOLUME_UP: () => (/* binding */ VOLUME_UP),
/* harmony export */   W: () => (/* binding */ W),
/* harmony export */   X: () => (/* binding */ X),
/* harmony export */   Y: () => (/* binding */ Y),
/* harmony export */   Z: () => (/* binding */ Z),
/* harmony export */   ZERO: () => (/* binding */ ZERO),
/* harmony export */   hasModifierKey: () => (/* binding */ hasModifierKey)
/* harmony export */ });
const MAC_ENTER = 3;
const BACKSPACE = 8;
const TAB = 9;
const NUM_CENTER = 12;
const ENTER = 13;
const SHIFT = 16;
const CONTROL = 17;
const ALT = 18;
const PAUSE = 19;
const CAPS_LOCK = 20;
const ESCAPE = 27;
const SPACE = 32;
const PAGE_UP = 33;
const PAGE_DOWN = 34;
const END = 35;
const HOME = 36;
const LEFT_ARROW = 37;
const UP_ARROW = 38;
const RIGHT_ARROW = 39;
const DOWN_ARROW = 40;
const PLUS_SIGN = 43;
const PRINT_SCREEN = 44;
const INSERT = 45;
const DELETE = 46;
const ZERO = 48;
const ONE = 49;
const TWO = 50;
const THREE = 51;
const FOUR = 52;
const FIVE = 53;
const SIX = 54;
const SEVEN = 55;
const EIGHT = 56;
const NINE = 57;
const FF_SEMICOLON = 59; // Firefox (Gecko) fires this for semicolon instead of 186
const FF_EQUALS = 61; // Firefox (Gecko) fires this for equals instead of 187
const QUESTION_MARK = 63;
const AT_SIGN = 64;
const A = 65;
const B = 66;
const C = 67;
const D = 68;
const E = 69;
const F = 70;
const G = 71;
const H = 72;
const I = 73;
const J = 74;
const K = 75;
const L = 76;
const M = 77;
const N = 78;
const O = 79;
const P = 80;
const Q = 81;
const R = 82;
const S = 83;
const T = 84;
const U = 85;
const V = 86;
const W = 87;
const X = 88;
const Y = 89;
const Z = 90;
const META = 91; // WIN_KEY_LEFT
const MAC_WK_CMD_LEFT = 91;
const MAC_WK_CMD_RIGHT = 93;
const CONTEXT_MENU = 93;
const NUMPAD_ZERO = 96;
const NUMPAD_ONE = 97;
const NUMPAD_TWO = 98;
const NUMPAD_THREE = 99;
const NUMPAD_FOUR = 100;
const NUMPAD_FIVE = 101;
const NUMPAD_SIX = 102;
const NUMPAD_SEVEN = 103;
const NUMPAD_EIGHT = 104;
const NUMPAD_NINE = 105;
const NUMPAD_MULTIPLY = 106;
const NUMPAD_PLUS = 107;
const NUMPAD_MINUS = 109;
const NUMPAD_PERIOD = 110;
const NUMPAD_DIVIDE = 111;
const F1 = 112;
const F2 = 113;
const F3 = 114;
const F4 = 115;
const F5 = 116;
const F6 = 117;
const F7 = 118;
const F8 = 119;
const F9 = 120;
const F10 = 121;
const F11 = 122;
const F12 = 123;
const NUM_LOCK = 144;
const SCROLL_LOCK = 145;
const FIRST_MEDIA = 166;
const FF_MINUS = 173;
const MUTE = 173; // Firefox (Gecko) fires 181 for MUTE
const VOLUME_DOWN = 174; // Firefox (Gecko) fires 182 for VOLUME_DOWN
const VOLUME_UP = 175; // Firefox (Gecko) fires 183 for VOLUME_UP
const FF_MUTE = 181;
const FF_VOLUME_DOWN = 182;
const LAST_MEDIA = 183;
const FF_VOLUME_UP = 183;
const SEMICOLON = 186; // Firefox (Gecko) fires 59 for SEMICOLON
const EQUALS = 187; // Firefox (Gecko) fires 61 for EQUALS
const COMMA = 188;
const DASH = 189; // Firefox (Gecko) fires 173 for DASH/MINUS
const PERIOD = 190;
const SLASH = 191;
const APOSTROPHE = 192;
const TILDE = 192;
const OPEN_SQUARE_BRACKET = 219;
const BACKSLASH = 220;
const CLOSE_SQUARE_BRACKET = 221;
const SINGLE_QUOTE = 222;
const MAC_META = 224;

/**
 * Checks whether a modifier key is pressed.
 * @param event Event to be checked.
 */
function hasModifierKey(event, ...modifiers) {
  if (modifiers.length) {
    return modifiers.some(modifier => event[modifier]);
  }
  return event.altKey || event.shiftKey || event.ctrlKey || event.metaKey;
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 87912:
/*!*******************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/layout.mjs ***!
  \*******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BreakpointObserver: () => (/* binding */ BreakpointObserver),
/* harmony export */   Breakpoints: () => (/* binding */ Breakpoints),
/* harmony export */   LayoutModule: () => (/* binding */ LayoutModule),
/* harmony export */   MediaMatcher: () => (/* binding */ MediaMatcher)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 19999);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 44665);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 47470);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 52575);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);






class LayoutModule {
  static {
    this.ɵfac = function LayoutModule_Factory(t) {
      return new (t || LayoutModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: LayoutModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LayoutModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], null, null);
})();

/** Global registry for all dynamically-created, injected media queries. */
const mediaQueriesForWebkitCompatibility = new Set();
/** Style tag that holds all of the dynamically-created media queries. */
let mediaQueryStyleNode;
/** A utility for calling matchMedia queries. */
class MediaMatcher {
  constructor(_platform, _nonce) {
    this._platform = _platform;
    this._nonce = _nonce;
    this._matchMedia = this._platform.isBrowser && window.matchMedia ?
    // matchMedia is bound to the window scope intentionally as it is an illegal invocation to
    // call it from a different scope.
    window.matchMedia.bind(window) : noopMatchMedia;
  }
  /**
   * Evaluates the given media query and returns the native MediaQueryList from which results
   * can be retrieved.
   * Confirms the layout engine will trigger for the selector query provided and returns the
   * MediaQueryList for the query provided.
   */
  matchMedia(query) {
    if (this._platform.WEBKIT || this._platform.BLINK) {
      createEmptyStyleRule(query, this._nonce);
    }
    return this._matchMedia(query);
  }
  static {
    this.ɵfac = function MediaMatcher_Factory(t) {
      return new (t || MediaMatcher)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.CSP_NONCE, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: MediaMatcher,
      factory: MediaMatcher.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MediaMatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.CSP_NONCE]
    }]
  }], null);
})();
/**
 * Creates an empty stylesheet that is used to work around browser inconsistencies related to
 * `matchMedia`. At the time of writing, it handles the following cases:
 * 1. On WebKit browsers, a media query has to have at least one rule in order for `matchMedia`
 * to fire. We work around it by declaring a dummy stylesheet with a `@media` declaration.
 * 2. In some cases Blink browsers will stop firing the `matchMedia` listener if none of the rules
 * inside the `@media` match existing elements on the page. We work around it by having one rule
 * targeting the `body`. See https://github.com/angular/components/issues/23546.
 */
function createEmptyStyleRule(query, nonce) {
  if (mediaQueriesForWebkitCompatibility.has(query)) {
    return;
  }
  try {
    if (!mediaQueryStyleNode) {
      mediaQueryStyleNode = document.createElement('style');
      if (nonce) {
        mediaQueryStyleNode.setAttribute('nonce', nonce);
      }
      mediaQueryStyleNode.setAttribute('type', 'text/css');
      document.head.appendChild(mediaQueryStyleNode);
    }
    if (mediaQueryStyleNode.sheet) {
      mediaQueryStyleNode.sheet.insertRule(`@media ${query} {body{ }}`, 0);
      mediaQueriesForWebkitCompatibility.add(query);
    }
  } catch (e) {
    console.error(e);
  }
}
/** No-op matchMedia replacement for non-browser platforms. */
function noopMatchMedia(query) {
  // Use `as any` here to avoid adding additional necessary properties for
  // the noop matcher.
  return {
    matches: query === 'all' || query === '',
    media: query,
    addListener: () => {},
    removeListener: () => {}
  };
}

/** Utility for checking the matching state of @media queries. */
class BreakpointObserver {
  constructor(_mediaMatcher, _zone) {
    this._mediaMatcher = _mediaMatcher;
    this._zone = _zone;
    /**  A map of all media queries currently being listened for. */
    this._queries = new Map();
    /** A subject for all other observables to takeUntil based on. */
    this._destroySubject = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
  }
  /** Completes the active subject, signalling to all other observables to complete. */
  ngOnDestroy() {
    this._destroySubject.next();
    this._destroySubject.complete();
  }
  /**
   * Whether one or more media queries match the current viewport size.
   * @param value One or more media queries to check.
   * @returns Whether any of the media queries match.
   */
  isMatched(value) {
    const queries = splitQueries((0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceArray)(value));
    return queries.some(mediaQuery => this._registerQuery(mediaQuery).mql.matches);
  }
  /**
   * Gets an observable of results for the given queries that will emit new results for any changes
   * in matching of the given queries.
   * @param value One or more media queries to check.
   * @returns A stream of matches for the given queries.
   */
  observe(value) {
    const queries = splitQueries((0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceArray)(value));
    const observables = queries.map(query => this._registerQuery(query).observable);
    let stateObservable = (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.combineLatest)(observables);
    // Emit the first state immediately, and then debounce the subsequent emissions.
    stateObservable = (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.concat)(stateObservable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.take)(1)), stateObservable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.skip)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.debounceTime)(0)));
    return stateObservable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.map)(breakpointStates => {
      const response = {
        matches: false,
        breakpoints: {}
      };
      breakpointStates.forEach(({
        matches,
        query
      }) => {
        response.matches = response.matches || matches;
        response.breakpoints[query] = matches;
      });
      return response;
    }));
  }
  /** Registers a specific query to be listened for. */
  _registerQuery(query) {
    // Only set up a new MediaQueryList if it is not already being listened for.
    if (this._queries.has(query)) {
      return this._queries.get(query);
    }
    const mql = this._mediaMatcher.matchMedia(query);
    // Create callback for match changes and add it is as a listener.
    const queryObservable = new rxjs__WEBPACK_IMPORTED_MODULE_10__.Observable(observer => {
      // Listener callback methods are wrapped to be placed back in ngZone. Callbacks must be placed
      // back into the zone because matchMedia is only included in Zone.js by loading the
      // webapis-media-query.js file alongside the zone.js file.  Additionally, some browsers do not
      // have MediaQueryList inherit from EventTarget, which causes inconsistencies in how Zone.js
      // patches it.
      const handler = e => this._zone.run(() => observer.next(e));
      mql.addListener(handler);
      return () => {
        mql.removeListener(handler);
      };
    }).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.startWith)(mql), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.map)(({
      matches
    }) => ({
      query,
      matches
    })), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.takeUntil)(this._destroySubject));
    // Add the MediaQueryList to the set of queries.
    const output = {
      observable: queryObservable,
      mql
    };
    this._queries.set(query, output);
    return output;
  }
  static {
    this.ɵfac = function BreakpointObserver_Factory(t) {
      return new (t || BreakpointObserver)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](MediaMatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: BreakpointObserver,
      factory: BreakpointObserver.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BreakpointObserver, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: MediaMatcher
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }], null);
})();
/**
 * Split each query string into separate query strings if two queries are provided as comma
 * separated.
 */
function splitQueries(queries) {
  return queries.map(query => query.split(',')).reduce((a1, a2) => a1.concat(a2)).map(query => query.trim());
}

// PascalCase is being used as Breakpoints is used like an enum.
// tslint:disable-next-line:variable-name
const Breakpoints = {
  XSmall: '(max-width: 599.98px)',
  Small: '(min-width: 600px) and (max-width: 959.98px)',
  Medium: '(min-width: 960px) and (max-width: 1279.98px)',
  Large: '(min-width: 1280px) and (max-width: 1919.98px)',
  XLarge: '(min-width: 1920px)',
  Handset: '(max-width: 599.98px) and (orientation: portrait), ' + '(max-width: 959.98px) and (orientation: landscape)',
  Tablet: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait), ' + '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',
  Web: '(min-width: 840px) and (orientation: portrait), ' + '(min-width: 1280px) and (orientation: landscape)',
  HandsetPortrait: '(max-width: 599.98px) and (orientation: portrait)',
  TabletPortrait: '(min-width: 600px) and (max-width: 839.98px) and (orientation: portrait)',
  WebPortrait: '(min-width: 840px) and (orientation: portrait)',
  HandsetLandscape: '(max-width: 959.98px) and (orientation: landscape)',
  TabletLandscape: '(min-width: 960px) and (max-width: 1279.98px) and (orientation: landscape)',
  WebLandscape: '(min-width: 1280px) and (orientation: landscape)'
};

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 39539:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/observers.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CdkObserveContent: () => (/* binding */ CdkObserveContent),
/* harmony export */   ContentObserver: () => (/* binding */ ContentObserver),
/* harmony export */   MutationObserverFactory: () => (/* binding */ MutationObserverFactory),
/* harmony export */   ObserversModule: () => (/* binding */ ObserversModule)
/* harmony export */ });
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 52575);






// Angular may add, remove, or edit comment nodes during change detection. We don't care about
// these changes because they don't affect the user-preceived content, and worse it can cause
// infinite change detection cycles where the change detection updates a comment, triggering the
// MutationObserver, triggering another change detection and kicking the cycle off again.
function shouldIgnoreRecord(record) {
  // Ignore changes to comment text.
  if (record.type === 'characterData' && record.target instanceof Comment) {
    return true;
  }
  // Ignore addition / removal of comments.
  if (record.type === 'childList') {
    for (let i = 0; i < record.addedNodes.length; i++) {
      if (!(record.addedNodes[i] instanceof Comment)) {
        return false;
      }
    }
    for (let i = 0; i < record.removedNodes.length; i++) {
      if (!(record.removedNodes[i] instanceof Comment)) {
        return false;
      }
    }
    return true;
  }
  // Observe everything else.
  return false;
}
/**
 * Factory that creates a new MutationObserver and allows us to stub it out in unit tests.
 * @docs-private
 */
class MutationObserverFactory {
  create(callback) {
    return typeof MutationObserver === 'undefined' ? null : new MutationObserver(callback);
  }
  static {
    this.ɵfac = function MutationObserverFactory_Factory(t) {
      return new (t || MutationObserverFactory)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: MutationObserverFactory,
      factory: MutationObserverFactory.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MutationObserverFactory, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/** An injectable service that allows watching elements for changes to their content. */
class ContentObserver {
  constructor(_mutationObserverFactory) {
    this._mutationObserverFactory = _mutationObserverFactory;
    /** Keeps track of the existing MutationObservers so they can be reused. */
    this._observedElements = new Map();
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  }
  ngOnDestroy() {
    this._observedElements.forEach((_, element) => this._cleanupObserver(element));
  }
  observe(elementOrRef) {
    const element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_1__.coerceElement)(elementOrRef);
    return new rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable(observer => {
      const stream = this._observeElement(element);
      const subscription = stream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(records => records.filter(record => !shouldIgnoreRecord(record))), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.filter)(records => !!records.length)).subscribe(records => {
        this._ngZone.run(() => {
          observer.next(records);
        });
      });
      return () => {
        subscription.unsubscribe();
        this._unobserveElement(element);
      };
    });
  }
  /**
   * Observes the given element by using the existing MutationObserver if available, or creating a
   * new one if not.
   */
  _observeElement(element) {
    return this._ngZone.runOutsideAngular(() => {
      if (!this._observedElements.has(element)) {
        const stream = new rxjs__WEBPACK_IMPORTED_MODULE_5__.Subject();
        const observer = this._mutationObserverFactory.create(mutations => stream.next(mutations));
        if (observer) {
          observer.observe(element, {
            characterData: true,
            childList: true,
            subtree: true
          });
        }
        this._observedElements.set(element, {
          observer,
          stream,
          count: 1
        });
      } else {
        this._observedElements.get(element).count++;
      }
      return this._observedElements.get(element).stream;
    });
  }
  /**
   * Un-observes the given element and cleans up the underlying MutationObserver if nobody else is
   * observing this element.
   */
  _unobserveElement(element) {
    if (this._observedElements.has(element)) {
      this._observedElements.get(element).count--;
      if (!this._observedElements.get(element).count) {
        this._cleanupObserver(element);
      }
    }
  }
  /** Clean up the underlying MutationObserver for the specified element. */
  _cleanupObserver(element) {
    if (this._observedElements.has(element)) {
      const {
        observer,
        stream
      } = this._observedElements.get(element);
      if (observer) {
        observer.disconnect();
      }
      stream.complete();
      this._observedElements.delete(element);
    }
  }
  static {
    this.ɵfac = function ContentObserver_Factory(t) {
      return new (t || ContentObserver)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](MutationObserverFactory));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ContentObserver,
      factory: ContentObserver.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ContentObserver, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: MutationObserverFactory
  }], null);
})();
/**
 * Directive that triggers a callback whenever the content of
 * its associated element has changed.
 */
class CdkObserveContent {
  /**
   * Whether observing content is disabled. This option can be used
   * to disconnect the underlying MutationObserver until it is needed.
   */
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    this._disabled = value;
    this._disabled ? this._unsubscribe() : this._subscribe();
  }
  /** Debounce interval for emitting the changes. */
  get debounce() {
    return this._debounce;
  }
  set debounce(value) {
    this._debounce = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_1__.coerceNumberProperty)(value);
    this._subscribe();
  }
  constructor(_contentObserver, _elementRef) {
    this._contentObserver = _contentObserver;
    this._elementRef = _elementRef;
    /** Event emitted for each change in the element's content. */
    this.event = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._disabled = false;
    this._currentSubscription = null;
  }
  ngAfterContentInit() {
    if (!this._currentSubscription && !this.disabled) {
      this._subscribe();
    }
  }
  ngOnDestroy() {
    this._unsubscribe();
  }
  _subscribe() {
    this._unsubscribe();
    const stream = this._contentObserver.observe(this._elementRef);
    this._currentSubscription = (this.debounce ? stream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.debounceTime)(this.debounce)) : stream).subscribe(this.event);
  }
  _unsubscribe() {
    this._currentSubscription?.unsubscribe();
  }
  static {
    this.ɵfac = function CdkObserveContent_Factory(t) {
      return new (t || CdkObserveContent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ContentObserver), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkObserveContent,
      selectors: [["", "cdkObserveContent", ""]],
      inputs: {
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkObserveContentDisabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute],
        debounce: "debounce"
      },
      outputs: {
        event: "cdkObserveContent"
      },
      exportAs: ["cdkObserveContent"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkObserveContent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkObserveContent]',
      exportAs: 'cdkObserveContent',
      standalone: true
    }]
  }], () => [{
    type: ContentObserver
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }], {
    event: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['cdkObserveContent']
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        alias: 'cdkObserveContentDisabled',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    debounce: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class ObserversModule {
  static {
    this.ɵfac = function ObserversModule_Factory(t) {
      return new (t || ObserversModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: ObserversModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: [MutationObserverFactory]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ObserversModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [CdkObserveContent],
      exports: [CdkObserveContent],
      providers: [MutationObserverFactory]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 17699:
/*!*********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/platform.mjs ***!
  \*********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Platform: () => (/* binding */ Platform),
/* harmony export */   PlatformModule: () => (/* binding */ PlatformModule),
/* harmony export */   RtlScrollAxisType: () => (/* binding */ RtlScrollAxisType),
/* harmony export */   _getEventTarget: () => (/* binding */ _getEventTarget),
/* harmony export */   _getFocusedElementPierceShadowDom: () => (/* binding */ _getFocusedElementPierceShadowDom),
/* harmony export */   _getShadowRoot: () => (/* binding */ _getShadowRoot),
/* harmony export */   _isTestEnvironment: () => (/* binding */ _isTestEnvironment),
/* harmony export */   _supportsShadowDom: () => (/* binding */ _supportsShadowDom),
/* harmony export */   getRtlScrollAxisType: () => (/* binding */ getRtlScrollAxisType),
/* harmony export */   getSupportedInputTypes: () => (/* binding */ getSupportedInputTypes),
/* harmony export */   normalizePassiveListenerOptions: () => (/* binding */ normalizePassiveListenerOptions),
/* harmony export */   supportsPassiveEventListeners: () => (/* binding */ supportsPassiveEventListeners),
/* harmony export */   supportsScrollBehavior: () => (/* binding */ supportsScrollBehavior)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/common */ 60316);




// Whether the current platform supports the V8 Break Iterator. The V8 check
// is necessary to detect all Blink based browsers.
let hasV8BreakIterator;
// We need a try/catch around the reference to `Intl`, because accessing it in some cases can
// cause IE to throw. These cases are tied to particular versions of Windows and can happen if
// the consumer is providing a polyfilled `Map`. See:
// https://github.com/Microsoft/ChakraCore/issues/3189
// https://github.com/angular/components/issues/15687
try {
  hasV8BreakIterator = typeof Intl !== 'undefined' && Intl.v8BreakIterator;
} catch {
  hasV8BreakIterator = false;
}
/**
 * Service to detect the current platform by comparing the userAgent strings and
 * checking browser-specific global properties.
 */
class Platform {
  constructor(_platformId) {
    this._platformId = _platformId;
    // We want to use the Angular platform check because if the Document is shimmed
    // without the navigator, the following checks will fail. This is preferred because
    // sometimes the Document may be shimmed without the user's knowledge or intention
    /** Whether the Angular application is being rendered in the browser. */
    this.isBrowser = this._platformId ? (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__.isPlatformBrowser)(this._platformId) : typeof document === 'object' && !!document;
    /** Whether the current browser is Microsoft Edge. */
    this.EDGE = this.isBrowser && /(edge)/i.test(navigator.userAgent);
    /** Whether the current rendering engine is Microsoft Trident. */
    this.TRIDENT = this.isBrowser && /(msie|trident)/i.test(navigator.userAgent);
    // EdgeHTML and Trident mock Blink specific things and need to be excluded from this check.
    /** Whether the current rendering engine is Blink. */
    this.BLINK = this.isBrowser && !!(window.chrome || hasV8BreakIterator) && typeof CSS !== 'undefined' && !this.EDGE && !this.TRIDENT;
    // Webkit is part of the userAgent in EdgeHTML, Blink and Trident. Therefore we need to
    // ensure that Webkit runs standalone and is not used as another engine's base.
    /** Whether the current rendering engine is WebKit. */
    this.WEBKIT = this.isBrowser && /AppleWebKit/i.test(navigator.userAgent) && !this.BLINK && !this.EDGE && !this.TRIDENT;
    /** Whether the current platform is Apple iOS. */
    this.IOS = this.isBrowser && /iPad|iPhone|iPod/.test(navigator.userAgent) && !('MSStream' in window);
    // It's difficult to detect the plain Gecko engine, because most of the browsers identify
    // them self as Gecko-like browsers and modify the userAgent's according to that.
    // Since we only cover one explicit Firefox case, we can simply check for Firefox
    // instead of having an unstable check for Gecko.
    /** Whether the current browser is Firefox. */
    this.FIREFOX = this.isBrowser && /(firefox|minefield)/i.test(navigator.userAgent);
    /** Whether the current platform is Android. */
    // Trident on mobile adds the android platform to the userAgent to trick detections.
    this.ANDROID = this.isBrowser && /android/i.test(navigator.userAgent) && !this.TRIDENT;
    // Safari browsers will include the Safari keyword in their userAgent. Some browsers may fake
    // this and just place the Safari keyword in the userAgent. To be more safe about Safari every
    // Safari browser should also use Webkit as its layout engine.
    /** Whether the current browser is Safari. */
    this.SAFARI = this.isBrowser && /safari/i.test(navigator.userAgent) && this.WEBKIT;
  }
  static {
    this.ɵfac = function Platform_Factory(t) {
      return new (t || Platform)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: Platform,
      factory: Platform.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Platform, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: Object,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
    }]
  }], null);
})();
class PlatformModule {
  static {
    this.ɵfac = function PlatformModule_Factory(t) {
      return new (t || PlatformModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: PlatformModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](PlatformModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{}]
  }], null, null);
})();

/** Cached result Set of input types support by the current browser. */
let supportedInputTypes;
/** Types of `<input>` that *might* be supported. */
const candidateInputTypes = [
// `color` must come first. Chrome 56 shows a warning if we change the type to `color` after
// first changing it to something else:
// The specified value "" does not conform to the required format.
// The format is "#rrggbb" where rr, gg, bb are two-digit hexadecimal numbers.
'color', 'button', 'checkbox', 'date', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month', 'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time', 'url', 'week'];
/** @returns The input types supported by this browser. */
function getSupportedInputTypes() {
  // Result is cached.
  if (supportedInputTypes) {
    return supportedInputTypes;
  }
  // We can't check if an input type is not supported until we're on the browser, so say that
  // everything is supported when not on the browser. We don't use `Platform` here since it's
  // just a helper function and can't inject it.
  if (typeof document !== 'object' || !document) {
    supportedInputTypes = new Set(candidateInputTypes);
    return supportedInputTypes;
  }
  let featureTestInput = document.createElement('input');
  supportedInputTypes = new Set(candidateInputTypes.filter(value => {
    featureTestInput.setAttribute('type', value);
    return featureTestInput.type === value;
  }));
  return supportedInputTypes;
}

/** Cached result of whether the user's browser supports passive event listeners. */
let supportsPassiveEvents;
/**
 * Checks whether the user's browser supports passive event listeners.
 * See: https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md
 */
function supportsPassiveEventListeners() {
  if (supportsPassiveEvents == null && typeof window !== 'undefined') {
    try {
      window.addEventListener('test', null, Object.defineProperty({}, 'passive', {
        get: () => supportsPassiveEvents = true
      }));
    } finally {
      supportsPassiveEvents = supportsPassiveEvents || false;
    }
  }
  return supportsPassiveEvents;
}
/**
 * Normalizes an `AddEventListener` object to something that can be passed
 * to `addEventListener` on any browser, no matter whether it supports the
 * `options` parameter.
 * @param options Object to be normalized.
 */
function normalizePassiveListenerOptions(options) {
  return supportsPassiveEventListeners() ? options : !!options.capture;
}

/** The possible ways the browser may handle the horizontal scroll axis in RTL languages. */
var RtlScrollAxisType;
(function (RtlScrollAxisType) {
  /**
   * scrollLeft is 0 when scrolled all the way left and (scrollWidth - clientWidth) when scrolled
   * all the way right.
   */
  RtlScrollAxisType[RtlScrollAxisType["NORMAL"] = 0] = "NORMAL";
  /**
   * scrollLeft is -(scrollWidth - clientWidth) when scrolled all the way left and 0 when scrolled
   * all the way right.
   */
  RtlScrollAxisType[RtlScrollAxisType["NEGATED"] = 1] = "NEGATED";
  /**
   * scrollLeft is (scrollWidth - clientWidth) when scrolled all the way left and 0 when scrolled
   * all the way right.
   */
  RtlScrollAxisType[RtlScrollAxisType["INVERTED"] = 2] = "INVERTED";
})(RtlScrollAxisType || (RtlScrollAxisType = {}));
/** Cached result of the way the browser handles the horizontal scroll axis in RTL mode. */
let rtlScrollAxisType;
/** Cached result of the check that indicates whether the browser supports scroll behaviors. */
let scrollBehaviorSupported;
/** Check whether the browser supports scroll behaviors. */
function supportsScrollBehavior() {
  if (scrollBehaviorSupported == null) {
    // If we're not in the browser, it can't be supported. Also check for `Element`, because
    // some projects stub out the global `document` during SSR which can throw us off.
    if (typeof document !== 'object' || !document || typeof Element !== 'function' || !Element) {
      scrollBehaviorSupported = false;
      return scrollBehaviorSupported;
    }
    // If the element can have a `scrollBehavior` style, we can be sure that it's supported.
    if ('scrollBehavior' in document.documentElement.style) {
      scrollBehaviorSupported = true;
    } else {
      // At this point we have 3 possibilities: `scrollTo` isn't supported at all, it's
      // supported but it doesn't handle scroll behavior, or it has been polyfilled.
      const scrollToFunction = Element.prototype.scrollTo;
      if (scrollToFunction) {
        // We can detect if the function has been polyfilled by calling `toString` on it. Native
        // functions are obfuscated using `[native code]`, whereas if it was overwritten we'd get
        // the actual function source. Via https://davidwalsh.name/detect-native-function. Consider
        // polyfilled functions as supporting scroll behavior.
        scrollBehaviorSupported = !/\{\s*\[native code\]\s*\}/.test(scrollToFunction.toString());
      } else {
        scrollBehaviorSupported = false;
      }
    }
  }
  return scrollBehaviorSupported;
}
/**
 * Checks the type of RTL scroll axis used by this browser. As of time of writing, Chrome is NORMAL,
 * Firefox & Safari are NEGATED, and IE & Edge are INVERTED.
 */
function getRtlScrollAxisType() {
  // We can't check unless we're on the browser. Just assume 'normal' if we're not.
  if (typeof document !== 'object' || !document) {
    return RtlScrollAxisType.NORMAL;
  }
  if (rtlScrollAxisType == null) {
    // Create a 1px wide scrolling container and a 2px wide content element.
    const scrollContainer = document.createElement('div');
    const containerStyle = scrollContainer.style;
    scrollContainer.dir = 'rtl';
    containerStyle.width = '1px';
    containerStyle.overflow = 'auto';
    containerStyle.visibility = 'hidden';
    containerStyle.pointerEvents = 'none';
    containerStyle.position = 'absolute';
    const content = document.createElement('div');
    const contentStyle = content.style;
    contentStyle.width = '2px';
    contentStyle.height = '1px';
    scrollContainer.appendChild(content);
    document.body.appendChild(scrollContainer);
    rtlScrollAxisType = RtlScrollAxisType.NORMAL;
    // The viewport starts scrolled all the way to the right in RTL mode. If we are in a NORMAL
    // browser this would mean that the scrollLeft should be 1. If it's zero instead we know we're
    // dealing with one of the other two types of browsers.
    if (scrollContainer.scrollLeft === 0) {
      // In a NEGATED browser the scrollLeft is always somewhere in [-maxScrollAmount, 0]. For an
      // INVERTED browser it is always somewhere in [0, maxScrollAmount]. We can determine which by
      // setting to the scrollLeft to 1. This is past the max for a NEGATED browser, so it will
      // return 0 when we read it again.
      scrollContainer.scrollLeft = 1;
      rtlScrollAxisType = scrollContainer.scrollLeft === 0 ? RtlScrollAxisType.NEGATED : RtlScrollAxisType.INVERTED;
    }
    scrollContainer.remove();
  }
  return rtlScrollAxisType;
}
let shadowDomIsSupported;
/** Checks whether the user's browser support Shadow DOM. */
function _supportsShadowDom() {
  if (shadowDomIsSupported == null) {
    const head = typeof document !== 'undefined' ? document.head : null;
    shadowDomIsSupported = !!(head && (head.createShadowRoot || head.attachShadow));
  }
  return shadowDomIsSupported;
}
/** Gets the shadow root of an element, if supported and the element is inside the Shadow DOM. */
function _getShadowRoot(element) {
  if (_supportsShadowDom()) {
    const rootNode = element.getRootNode ? element.getRootNode() : null;
    // Note that this should be caught by `_supportsShadowDom`, but some
    // teams have been able to hit this code path on unsupported browsers.
    if (typeof ShadowRoot !== 'undefined' && ShadowRoot && rootNode instanceof ShadowRoot) {
      return rootNode;
    }
  }
  return null;
}
/**
 * Gets the currently-focused element on the page while
 * also piercing through Shadow DOM boundaries.
 */
function _getFocusedElementPierceShadowDom() {
  let activeElement = typeof document !== 'undefined' && document ? document.activeElement : null;
  while (activeElement && activeElement.shadowRoot) {
    const newActiveElement = activeElement.shadowRoot.activeElement;
    if (newActiveElement === activeElement) {
      break;
    } else {
      activeElement = newActiveElement;
    }
  }
  return activeElement;
}
/** Gets the target of an event while accounting for Shadow DOM. */
function _getEventTarget(event) {
  // If an event is bound outside the Shadow DOM, the `event.target` will
  // point to the shadow root so we have to use `composedPath` instead.
  return event.composedPath ? event.composedPath()[0] : event.target;
}

/** Gets whether the code is currently running in a test environment. */
function _isTestEnvironment() {
  // We can't use `declare const` because it causes conflicts inside Google with the real typings
  // for these symbols and we can't read them off the global object, because they don't appear to
  // be attached there for some runners like Jest.
  // (see: https://github.com/angular/components/issues/23365#issuecomment-938146643)
  return (
    // @ts-ignore
    typeof __karma__ !== 'undefined' && !!__karma__ ||
    // @ts-ignore
    typeof jasmine !== 'undefined' && !!jasmine ||
    // @ts-ignore
    typeof jest !== 'undefined' && !!jest ||
    // @ts-ignore
    typeof Mocha !== 'undefined' && !!Mocha
  );
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 79975:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/scrolling.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CdkFixedSizeVirtualScroll: () => (/* binding */ CdkFixedSizeVirtualScroll),
/* harmony export */   CdkScrollable: () => (/* binding */ CdkScrollable),
/* harmony export */   CdkScrollableModule: () => (/* binding */ CdkScrollableModule),
/* harmony export */   CdkVirtualForOf: () => (/* binding */ CdkVirtualForOf),
/* harmony export */   CdkVirtualScrollViewport: () => (/* binding */ CdkVirtualScrollViewport),
/* harmony export */   CdkVirtualScrollable: () => (/* binding */ CdkVirtualScrollable),
/* harmony export */   CdkVirtualScrollableElement: () => (/* binding */ CdkVirtualScrollableElement),
/* harmony export */   CdkVirtualScrollableWindow: () => (/* binding */ CdkVirtualScrollableWindow),
/* harmony export */   DEFAULT_RESIZE_TIME: () => (/* binding */ DEFAULT_RESIZE_TIME),
/* harmony export */   DEFAULT_SCROLL_TIME: () => (/* binding */ DEFAULT_SCROLL_TIME),
/* harmony export */   FixedSizeVirtualScrollStrategy: () => (/* binding */ FixedSizeVirtualScrollStrategy),
/* harmony export */   ScrollDispatcher: () => (/* binding */ ScrollDispatcher),
/* harmony export */   ScrollingModule: () => (/* binding */ ScrollingModule),
/* harmony export */   VIRTUAL_SCROLLABLE: () => (/* binding */ VIRTUAL_SCROLLABLE),
/* harmony export */   VIRTUAL_SCROLL_STRATEGY: () => (/* binding */ VIRTUAL_SCROLL_STRATEGY),
/* harmony export */   ViewportRuler: () => (/* binding */ ViewportRuler),
/* harmony export */   _fixedSizeVirtualScrollStrategyFactory: () => (/* binding */ _fixedSizeVirtualScrollStrategyFactory)
/* harmony export */ });
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs */ 18537);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs */ 20614);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs */ 67180);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs */ 2510);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 91817);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 32351);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs/operators */ 5057);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! rxjs/operators */ 86301);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @angular/cdk/bidi */ 63680);
/* harmony import */ var _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! @angular/cdk/collections */ 37989);













/** The injection token used to specify the virtual scrolling strategy. */
const _c0 = ["contentWrapper"];
const _c1 = ["*"];
const VIRTUAL_SCROLL_STRATEGY = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('VIRTUAL_SCROLL_STRATEGY');

/** Virtual scrolling strategy for lists with items of known fixed size. */
class FixedSizeVirtualScrollStrategy {
  /**
   * @param itemSize The size of the items in the virtually scrolling list.
   * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more
   * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.
   */
  constructor(itemSize, minBufferPx, maxBufferPx) {
    this._scrolledIndexChange = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** @docs-private Implemented as part of VirtualScrollStrategy. */
    this.scrolledIndexChange = this._scrolledIndexChange.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.distinctUntilChanged)());
    /** The attached viewport. */
    this._viewport = null;
    this._itemSize = itemSize;
    this._minBufferPx = minBufferPx;
    this._maxBufferPx = maxBufferPx;
  }
  /**
   * Attaches this scroll strategy to a viewport.
   * @param viewport The viewport to attach this strategy to.
   */
  attach(viewport) {
    this._viewport = viewport;
    this._updateTotalContentSize();
    this._updateRenderedRange();
  }
  /** Detaches this scroll strategy from the currently attached viewport. */
  detach() {
    this._scrolledIndexChange.complete();
    this._viewport = null;
  }
  /**
   * Update the item size and buffer size.
   * @param itemSize The size of the items in the virtually scrolling list.
   * @param minBufferPx The minimum amount of buffer (in pixels) before needing to render more
   * @param maxBufferPx The amount of buffer (in pixels) to render when rendering more.
   */
  updateItemAndBufferSize(itemSize, minBufferPx, maxBufferPx) {
    if (maxBufferPx < minBufferPx && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CDK virtual scroll: maxBufferPx must be greater than or equal to minBufferPx');
    }
    this._itemSize = itemSize;
    this._minBufferPx = minBufferPx;
    this._maxBufferPx = maxBufferPx;
    this._updateTotalContentSize();
    this._updateRenderedRange();
  }
  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onContentScrolled() {
    this._updateRenderedRange();
  }
  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onDataLengthChanged() {
    this._updateTotalContentSize();
    this._updateRenderedRange();
  }
  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onContentRendered() {
    /* no-op */
  }
  /** @docs-private Implemented as part of VirtualScrollStrategy. */
  onRenderedOffsetChanged() {
    /* no-op */
  }
  /**
   * Scroll to the offset for the given index.
   * @param index The index of the element to scroll to.
   * @param behavior The ScrollBehavior to use when scrolling.
   */
  scrollToIndex(index, behavior) {
    if (this._viewport) {
      this._viewport.scrollToOffset(index * this._itemSize, behavior);
    }
  }
  /** Update the viewport's total content size. */
  _updateTotalContentSize() {
    if (!this._viewport) {
      return;
    }
    this._viewport.setTotalContentSize(this._viewport.getDataLength() * this._itemSize);
  }
  /** Update the viewport's rendered range. */
  _updateRenderedRange() {
    if (!this._viewport) {
      return;
    }
    const renderedRange = this._viewport.getRenderedRange();
    const newRange = {
      start: renderedRange.start,
      end: renderedRange.end
    };
    const viewportSize = this._viewport.getViewportSize();
    const dataLength = this._viewport.getDataLength();
    let scrollOffset = this._viewport.measureScrollOffset();
    // Prevent NaN as result when dividing by zero.
    let firstVisibleIndex = this._itemSize > 0 ? scrollOffset / this._itemSize : 0;
    // If user scrolls to the bottom of the list and data changes to a smaller list
    if (newRange.end > dataLength) {
      // We have to recalculate the first visible index based on new data length and viewport size.
      const maxVisibleItems = Math.ceil(viewportSize / this._itemSize);
      const newVisibleIndex = Math.max(0, Math.min(firstVisibleIndex, dataLength - maxVisibleItems));
      // If first visible index changed we must update scroll offset to handle start/end buffers
      // Current range must also be adjusted to cover the new position (bottom of new list).
      if (firstVisibleIndex != newVisibleIndex) {
        firstVisibleIndex = newVisibleIndex;
        scrollOffset = newVisibleIndex * this._itemSize;
        newRange.start = Math.floor(firstVisibleIndex);
      }
      newRange.end = Math.max(0, Math.min(dataLength, newRange.start + maxVisibleItems));
    }
    const startBuffer = scrollOffset - newRange.start * this._itemSize;
    if (startBuffer < this._minBufferPx && newRange.start != 0) {
      const expandStart = Math.ceil((this._maxBufferPx - startBuffer) / this._itemSize);
      newRange.start = Math.max(0, newRange.start - expandStart);
      newRange.end = Math.min(dataLength, Math.ceil(firstVisibleIndex + (viewportSize + this._minBufferPx) / this._itemSize));
    } else {
      const endBuffer = newRange.end * this._itemSize - (scrollOffset + viewportSize);
      if (endBuffer < this._minBufferPx && newRange.end != dataLength) {
        const expandEnd = Math.ceil((this._maxBufferPx - endBuffer) / this._itemSize);
        if (expandEnd > 0) {
          newRange.end = Math.min(dataLength, newRange.end + expandEnd);
          newRange.start = Math.max(0, Math.floor(firstVisibleIndex - this._minBufferPx / this._itemSize));
        }
      }
    }
    this._viewport.setRenderedRange(newRange);
    this._viewport.setRenderedContentOffset(this._itemSize * newRange.start);
    this._scrolledIndexChange.next(Math.floor(firstVisibleIndex));
  }
}
/**
 * Provider factory for `FixedSizeVirtualScrollStrategy` that simply extracts the already created
 * `FixedSizeVirtualScrollStrategy` from the given directive.
 * @param fixedSizeDir The instance of `CdkFixedSizeVirtualScroll` to extract the
 *     `FixedSizeVirtualScrollStrategy` from.
 */
function _fixedSizeVirtualScrollStrategyFactory(fixedSizeDir) {
  return fixedSizeDir._scrollStrategy;
}
/** A virtual scroll strategy that supports fixed-size items. */
class CdkFixedSizeVirtualScroll {
  constructor() {
    this._itemSize = 20;
    this._minBufferPx = 100;
    this._maxBufferPx = 200;
    /** The scroll strategy used by this directive. */
    this._scrollStrategy = new FixedSizeVirtualScrollStrategy(this.itemSize, this.minBufferPx, this.maxBufferPx);
  }
  /** The size of the items in the list (in pixels). */
  get itemSize() {
    return this._itemSize;
  }
  set itemSize(value) {
    this._itemSize = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceNumberProperty)(value);
  }
  /**
   * The minimum amount of buffer rendered beyond the viewport (in pixels).
   * If the amount of buffer dips below this number, more items will be rendered. Defaults to 100px.
   */
  get minBufferPx() {
    return this._minBufferPx;
  }
  set minBufferPx(value) {
    this._minBufferPx = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceNumberProperty)(value);
  }
  /**
   * The number of pixels worth of buffer to render for when rendering new items. Defaults to 200px.
   */
  get maxBufferPx() {
    return this._maxBufferPx;
  }
  set maxBufferPx(value) {
    this._maxBufferPx = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceNumberProperty)(value);
  }
  ngOnChanges() {
    this._scrollStrategy.updateItemAndBufferSize(this.itemSize, this.minBufferPx, this.maxBufferPx);
  }
  static {
    this.ɵfac = function CdkFixedSizeVirtualScroll_Factory(t) {
      return new (t || CdkFixedSizeVirtualScroll)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkFixedSizeVirtualScroll,
      selectors: [["cdk-virtual-scroll-viewport", "itemSize", ""]],
      inputs: {
        itemSize: "itemSize",
        minBufferPx: "minBufferPx",
        maxBufferPx: "maxBufferPx"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: VIRTUAL_SCROLL_STRATEGY,
        useFactory: _fixedSizeVirtualScrollStrategyFactory,
        deps: [(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CdkFixedSizeVirtualScroll)]
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkFixedSizeVirtualScroll, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'cdk-virtual-scroll-viewport[itemSize]',
      standalone: true,
      providers: [{
        provide: VIRTUAL_SCROLL_STRATEGY,
        useFactory: _fixedSizeVirtualScrollStrategyFactory,
        deps: [(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CdkFixedSizeVirtualScroll)]
      }]
    }]
  }], null, {
    itemSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    minBufferPx: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    maxBufferPx: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();

/** Time in ms to throttle the scrolling events by default. */
const DEFAULT_SCROLL_TIME = 20;
/**
 * Service contained all registered Scrollable references and emits an event when any one of the
 * Scrollable references emit a scrolled event.
 */
class ScrollDispatcher {
  constructor(_ngZone, _platform, document) {
    this._ngZone = _ngZone;
    this._platform = _platform;
    /** Subject for notifying that a registered scrollable reference element has been scrolled. */
    this._scrolled = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** Keeps track of the global `scroll` and `resize` subscriptions. */
    this._globalSubscription = null;
    /** Keeps track of the amount of subscriptions to `scrolled`. Used for cleaning up afterwards. */
    this._scrolledCount = 0;
    /**
     * Map of all the scrollable references that are registered with the service and their
     * scroll event subscriptions.
     */
    this.scrollContainers = new Map();
    this._document = document;
  }
  /**
   * Registers a scrollable instance with the service and listens for its scrolled events. When the
   * scrollable is scrolled, the service emits the event to its scrolled observable.
   * @param scrollable Scrollable instance to be registered.
   */
  register(scrollable) {
    if (!this.scrollContainers.has(scrollable)) {
      this.scrollContainers.set(scrollable, scrollable.elementScrolled().subscribe(() => this._scrolled.next(scrollable)));
    }
  }
  /**
   * De-registers a Scrollable reference and unsubscribes from its scroll event observable.
   * @param scrollable Scrollable instance to be deregistered.
   */
  deregister(scrollable) {
    const scrollableReference = this.scrollContainers.get(scrollable);
    if (scrollableReference) {
      scrollableReference.unsubscribe();
      this.scrollContainers.delete(scrollable);
    }
  }
  /**
   * Returns an observable that emits an event whenever any of the registered Scrollable
   * references (or window, document, or body) fire a scrolled event. Can provide a time in ms
   * to override the default "throttle" time.
   *
   * **Note:** in order to avoid hitting change detection for every scroll event,
   * all of the events emitted from this stream will be run outside the Angular zone.
   * If you need to update any data bindings as a result of a scroll event, you have
   * to run the callback using `NgZone.run`.
   */
  scrolled(auditTimeInMs = DEFAULT_SCROLL_TIME) {
    if (!this._platform.isBrowser) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)();
    }
    return new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => {
      if (!this._globalSubscription) {
        this._addGlobalListener();
      }
      // In the case of a 0ms delay, use an observable without auditTime
      // since it does add a perceptible delay in processing overhead.
      const subscription = auditTimeInMs > 0 ? this._scrolled.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.auditTime)(auditTimeInMs)).subscribe(observer) : this._scrolled.subscribe(observer);
      this._scrolledCount++;
      return () => {
        subscription.unsubscribe();
        this._scrolledCount--;
        if (!this._scrolledCount) {
          this._removeGlobalListener();
        }
      };
    });
  }
  ngOnDestroy() {
    this._removeGlobalListener();
    this.scrollContainers.forEach((_, container) => this.deregister(container));
    this._scrolled.complete();
  }
  /**
   * Returns an observable that emits whenever any of the
   * scrollable ancestors of an element are scrolled.
   * @param elementOrElementRef Element whose ancestors to listen for.
   * @param auditTimeInMs Time to throttle the scroll events.
   */
  ancestorScrolled(elementOrElementRef, auditTimeInMs) {
    const ancestors = this.getAncestorScrollContainers(elementOrElementRef);
    return this.scrolled(auditTimeInMs).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.filter)(target => {
      return !target || ancestors.indexOf(target) > -1;
    }));
  }
  /** Returns all registered Scrollables that contain the provided element. */
  getAncestorScrollContainers(elementOrElementRef) {
    const scrollingContainers = [];
    this.scrollContainers.forEach((_subscription, scrollable) => {
      if (this._scrollableContainsElement(scrollable, elementOrElementRef)) {
        scrollingContainers.push(scrollable);
      }
    });
    return scrollingContainers;
  }
  /** Use defaultView of injected document if available or fallback to global window reference */
  _getWindow() {
    return this._document.defaultView || window;
  }
  /** Returns true if the element is contained within the provided Scrollable. */
  _scrollableContainsElement(scrollable, elementOrElementRef) {
    let element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceElement)(elementOrElementRef);
    let scrollableElement = scrollable.getElementRef().nativeElement;
    // Traverse through the element parents until we reach null, checking if any of the elements
    // are the scrollable's element.
    do {
      if (element == scrollableElement) {
        return true;
      }
    } while (element = element.parentElement);
    return false;
  }
  /** Sets up the global scroll listeners. */
  _addGlobalListener() {
    this._globalSubscription = this._ngZone.runOutsideAngular(() => {
      const window = this._getWindow();
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.fromEvent)(window.document, 'scroll').subscribe(() => this._scrolled.next());
    });
  }
  /** Cleans up the global scroll listener. */
  _removeGlobalListener() {
    if (this._globalSubscription) {
      this._globalSubscription.unsubscribe();
      this._globalSubscription = null;
    }
  }
  static {
    this.ɵfac = function ScrollDispatcher_Factory(t) {
      return new (t || ScrollDispatcher)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_10__.DOCUMENT, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ScrollDispatcher,
      factory: ScrollDispatcher.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ScrollDispatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_10__.DOCUMENT]
    }]
  }], null);
})();

/**
 * Sends an event when the directive's element is scrolled. Registers itself with the
 * ScrollDispatcher service to include itself as part of its collection of scrolling events that it
 * can be listened to through the service.
 */
class CdkScrollable {
  constructor(elementRef, scrollDispatcher, ngZone, dir) {
    this.elementRef = elementRef;
    this.scrollDispatcher = scrollDispatcher;
    this.ngZone = ngZone;
    this.dir = dir;
    this._destroyed = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    this._elementScrolled = new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => this.ngZone.runOutsideAngular(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.fromEvent)(this.elementRef.nativeElement, 'scroll').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.takeUntil)(this._destroyed)).subscribe(observer)));
  }
  ngOnInit() {
    this.scrollDispatcher.register(this);
  }
  ngOnDestroy() {
    this.scrollDispatcher.deregister(this);
    this._destroyed.next();
    this._destroyed.complete();
  }
  /** Returns observable that emits when a scroll event is fired on the host element. */
  elementScrolled() {
    return this._elementScrolled;
  }
  /** Gets the ElementRef for the viewport. */
  getElementRef() {
    return this.elementRef;
  }
  /**
   * Scrolls to the specified offsets. This is a normalized version of the browser's native scrollTo
   * method, since browsers are not consistent about what scrollLeft means in RTL. For this method
   * left and right always refer to the left and right side of the scrolling container irrespective
   * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
   * in an RTL context.
   * @param options specified the offsets to scroll to.
   */
  scrollTo(options) {
    const el = this.elementRef.nativeElement;
    const isRtl = this.dir && this.dir.value == 'rtl';
    // Rewrite start & end offsets as right or left offsets.
    if (options.left == null) {
      options.left = isRtl ? options.end : options.start;
    }
    if (options.right == null) {
      options.right = isRtl ? options.start : options.end;
    }
    // Rewrite the bottom offset as a top offset.
    if (options.bottom != null) {
      options.top = el.scrollHeight - el.clientHeight - options.bottom;
    }
    // Rewrite the right offset as a left offset.
    if (isRtl && (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.getRtlScrollAxisType)() != _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.RtlScrollAxisType.NORMAL) {
      if (options.left != null) {
        options.right = el.scrollWidth - el.clientWidth - options.left;
      }
      if ((0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.getRtlScrollAxisType)() == _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.RtlScrollAxisType.INVERTED) {
        options.left = options.right;
      } else if ((0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.getRtlScrollAxisType)() == _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.RtlScrollAxisType.NEGATED) {
        options.left = options.right ? -options.right : options.right;
      }
    } else {
      if (options.right != null) {
        options.left = el.scrollWidth - el.clientWidth - options.right;
      }
    }
    this._applyScrollToOptions(options);
  }
  _applyScrollToOptions(options) {
    const el = this.elementRef.nativeElement;
    if ((0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.supportsScrollBehavior)()) {
      el.scrollTo(options);
    } else {
      if (options.top != null) {
        el.scrollTop = options.top;
      }
      if (options.left != null) {
        el.scrollLeft = options.left;
      }
    }
  }
  /**
   * Measures the scroll offset relative to the specified edge of the viewport. This method can be
   * used instead of directly checking scrollLeft or scrollTop, since browsers are not consistent
   * about what scrollLeft means in RTL. The values returned by this method are normalized such that
   * left and right always refer to the left and right side of the scrolling container irrespective
   * of the layout direction. start and end refer to left and right in an LTR context and vice-versa
   * in an RTL context.
   * @param from The edge to measure from.
   */
  measureScrollOffset(from) {
    const LEFT = 'left';
    const RIGHT = 'right';
    const el = this.elementRef.nativeElement;
    if (from == 'top') {
      return el.scrollTop;
    }
    if (from == 'bottom') {
      return el.scrollHeight - el.clientHeight - el.scrollTop;
    }
    // Rewrite start & end as left or right offsets.
    const isRtl = this.dir && this.dir.value == 'rtl';
    if (from == 'start') {
      from = isRtl ? RIGHT : LEFT;
    } else if (from == 'end') {
      from = isRtl ? LEFT : RIGHT;
    }
    if (isRtl && (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.getRtlScrollAxisType)() == _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.RtlScrollAxisType.INVERTED) {
      // For INVERTED, scrollLeft is (scrollWidth - clientWidth) when scrolled all the way left and
      // 0 when scrolled all the way right.
      if (from == LEFT) {
        return el.scrollWidth - el.clientWidth - el.scrollLeft;
      } else {
        return el.scrollLeft;
      }
    } else if (isRtl && (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.getRtlScrollAxisType)() == _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.RtlScrollAxisType.NEGATED) {
      // For NEGATED, scrollLeft is -(scrollWidth - clientWidth) when scrolled all the way left and
      // 0 when scrolled all the way right.
      if (from == LEFT) {
        return el.scrollLeft + el.scrollWidth - el.clientWidth;
      } else {
        return -el.scrollLeft;
      }
    } else {
      // For NORMAL, as well as non-RTL contexts, scrollLeft is 0 when scrolled all the way left and
      // (scrollWidth - clientWidth) when scrolled all the way right.
      if (from == LEFT) {
        return el.scrollLeft;
      } else {
        return el.scrollWidth - el.clientWidth - el.scrollLeft;
      }
    }
  }
  static {
    this.ɵfac = function CdkScrollable_Factory(t) {
      return new (t || CdkScrollable)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkScrollable,
      selectors: [["", "cdk-scrollable", ""], ["", "cdkScrollable", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkScrollable, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdk-scrollable], [cdkScrollable]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: ScrollDispatcher
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();

/** Time in ms to throttle the resize events by default. */
const DEFAULT_RESIZE_TIME = 20;
/**
 * Simple utility for getting the bounds of the browser viewport.
 * @docs-private
 */
class ViewportRuler {
  constructor(_platform, ngZone, document) {
    this._platform = _platform;
    /** Stream of viewport change events. */
    this._change = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** Event listener that will be used to handle the viewport change events. */
    this._changeListener = event => {
      this._change.next(event);
    };
    this._document = document;
    ngZone.runOutsideAngular(() => {
      if (_platform.isBrowser) {
        const window = this._getWindow();
        // Note that bind the events ourselves, rather than going through something like RxJS's
        // `fromEvent` so that we can ensure that they're bound outside of the NgZone.
        window.addEventListener('resize', this._changeListener);
        window.addEventListener('orientationchange', this._changeListener);
      }
      // Clear the cached position so that the viewport is re-measured next time it is required.
      // We don't need to keep track of the subscription, because it is completed on destroy.
      this.change().subscribe(() => this._viewportSize = null);
    });
  }
  ngOnDestroy() {
    if (this._platform.isBrowser) {
      const window = this._getWindow();
      window.removeEventListener('resize', this._changeListener);
      window.removeEventListener('orientationchange', this._changeListener);
    }
    this._change.complete();
  }
  /** Returns the viewport's width and height. */
  getViewportSize() {
    if (!this._viewportSize) {
      this._updateViewportSize();
    }
    const output = {
      width: this._viewportSize.width,
      height: this._viewportSize.height
    };
    // If we're not on a browser, don't cache the size since it'll be mocked out anyway.
    if (!this._platform.isBrowser) {
      this._viewportSize = null;
    }
    return output;
  }
  /** Gets a DOMRect for the viewport's bounds. */
  getViewportRect() {
    // Use the document element's bounding rect rather than the window scroll properties
    // (e.g. pageYOffset, scrollY) due to in issue in Chrome and IE where window scroll
    // properties and client coordinates (boundingClientRect, clientX/Y, etc.) are in different
    // conceptual viewports. Under most circumstances these viewports are equivalent, but they
    // can disagree when the page is pinch-zoomed (on devices that support touch).
    // See https://bugs.chromium.org/p/chromium/issues/detail?id=489206#c4
    // We use the documentElement instead of the body because, by default (without a css reset)
    // browsers typically give the document body an 8px margin, which is not included in
    // getBoundingClientRect().
    const scrollPosition = this.getViewportScrollPosition();
    const {
      width,
      height
    } = this.getViewportSize();
    return {
      top: scrollPosition.top,
      left: scrollPosition.left,
      bottom: scrollPosition.top + height,
      right: scrollPosition.left + width,
      height,
      width
    };
  }
  /** Gets the (top, left) scroll position of the viewport. */
  getViewportScrollPosition() {
    // While we can get a reference to the fake document
    // during SSR, it doesn't have getBoundingClientRect.
    if (!this._platform.isBrowser) {
      return {
        top: 0,
        left: 0
      };
    }
    // The top-left-corner of the viewport is determined by the scroll position of the document
    // body, normally just (scrollLeft, scrollTop). However, Chrome and Firefox disagree about
    // whether `document.body` or `document.documentElement` is the scrolled element, so reading
    // `scrollTop` and `scrollLeft` is inconsistent. However, using the bounding rect of
    // `document.documentElement` works consistently, where the `top` and `left` values will
    // equal negative the scroll position.
    const document = this._document;
    const window = this._getWindow();
    const documentElement = document.documentElement;
    const documentRect = documentElement.getBoundingClientRect();
    const top = -documentRect.top || document.body.scrollTop || window.scrollY || documentElement.scrollTop || 0;
    const left = -documentRect.left || document.body.scrollLeft || window.scrollX || documentElement.scrollLeft || 0;
    return {
      top,
      left
    };
  }
  /**
   * Returns a stream that emits whenever the size of the viewport changes.
   * This stream emits outside of the Angular zone.
   * @param throttleTime Time in milliseconds to throttle the stream.
   */
  change(throttleTime = DEFAULT_RESIZE_TIME) {
    return throttleTime > 0 ? this._change.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.auditTime)(throttleTime)) : this._change;
  }
  /** Use defaultView of injected document if available or fallback to global window reference */
  _getWindow() {
    return this._document.defaultView || window;
  }
  /** Updates the cached viewport size. */
  _updateViewportSize() {
    const window = this._getWindow();
    this._viewportSize = this._platform.isBrowser ? {
      width: window.innerWidth,
      height: window.innerHeight
    } : {
      width: 0,
      height: 0
    };
  }
  static {
    this.ɵfac = function ViewportRuler_Factory(t) {
      return new (t || ViewportRuler)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_10__.DOCUMENT, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ViewportRuler,
      factory: ViewportRuler.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ViewportRuler, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_10__.DOCUMENT]
    }]
  }], null);
})();
const VIRTUAL_SCROLLABLE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('VIRTUAL_SCROLLABLE');
/**
 * Extending the {@link CdkScrollable} to be used as scrolling container for virtual scrolling.
 */
class CdkVirtualScrollable extends CdkScrollable {
  constructor(elementRef, scrollDispatcher, ngZone, dir) {
    super(elementRef, scrollDispatcher, ngZone, dir);
  }
  /**
   * Measure the viewport size for the provided orientation.
   *
   * @param orientation The orientation to measure the size from.
   */
  measureViewportSize(orientation) {
    const viewportEl = this.elementRef.nativeElement;
    return orientation === 'horizontal' ? viewportEl.clientWidth : viewportEl.clientHeight;
  }
  static {
    this.ɵfac = function CdkVirtualScrollable_Factory(t) {
      return new (t || CdkVirtualScrollable)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkVirtualScrollable,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkVirtualScrollable, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: ScrollDispatcher
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();

/** Checks if the given ranges are equal. */
function rangesEqual(r1, r2) {
  return r1.start == r2.start && r1.end == r2.end;
}
/**
 * Scheduler to be used for scroll events. Needs to fall back to
 * something that doesn't rely on requestAnimationFrame on environments
 * that don't support it (e.g. server-side rendering).
 */
const SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? rxjs__WEBPACK_IMPORTED_MODULE_13__.animationFrameScheduler : rxjs__WEBPACK_IMPORTED_MODULE_14__.asapScheduler;
/** A viewport that virtualizes its scrolling with the help of `CdkVirtualForOf`. */
class CdkVirtualScrollViewport extends CdkVirtualScrollable {
  /** The direction the viewport scrolls. */
  get orientation() {
    return this._orientation;
  }
  set orientation(orientation) {
    if (this._orientation !== orientation) {
      this._orientation = orientation;
      this._calculateSpacerSize();
    }
  }
  constructor(elementRef, _changeDetectorRef, ngZone, _scrollStrategy, dir, scrollDispatcher, viewportRuler, scrollable) {
    super(elementRef, scrollDispatcher, ngZone, dir);
    this.elementRef = elementRef;
    this._changeDetectorRef = _changeDetectorRef;
    this._scrollStrategy = _scrollStrategy;
    this.scrollable = scrollable;
    this._platform = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform);
    /** Emits when the viewport is detached from a CdkVirtualForOf. */
    this._detachedSubject = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** Emits when the rendered range changes. */
    this._renderedRangeSubject = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    this._orientation = 'vertical';
    /**
     * Whether rendered items should persist in the DOM after scrolling out of view. By default, items
     * will be removed.
     */
    this.appendOnly = false;
    // Note: we don't use the typical EventEmitter here because we need to subscribe to the scroll
    // strategy lazily (i.e. only if the user is actually listening to the events). We do this because
    // depending on how the strategy calculates the scrolled index, it may come at a cost to
    // performance.
    /** Emits when the index of the first element visible in the viewport changes. */
    this.scrolledIndexChange = new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => this._scrollStrategy.scrolledIndexChange.subscribe(index => Promise.resolve().then(() => this.ngZone.run(() => observer.next(index)))));
    /** A stream that emits whenever the rendered range changes. */
    this.renderedRangeStream = this._renderedRangeSubject;
    /**
     * The total size of all content (in pixels), including content that is not currently rendered.
     */
    this._totalContentSize = 0;
    /** A string representing the `style.width` property value to be used for the spacer element. */
    this._totalContentWidth = '';
    /** A string representing the `style.height` property value to be used for the spacer element. */
    this._totalContentHeight = '';
    /** The currently rendered range of indices. */
    this._renderedRange = {
      start: 0,
      end: 0
    };
    /** The length of the data bound to this viewport (in number of items). */
    this._dataLength = 0;
    /** The size of the viewport (in pixels). */
    this._viewportSize = 0;
    /** The last rendered content offset that was set. */
    this._renderedContentOffset = 0;
    /**
     * Whether the last rendered content offset was to the end of the content (and therefore needs to
     * be rewritten as an offset to the start of the content).
     */
    this._renderedContentOffsetNeedsRewrite = false;
    /** Whether there is a pending change detection cycle. */
    this._isChangeDetectionPending = false;
    /** A list of functions to run after the next change detection cycle. */
    this._runAfterChangeDetection = [];
    /** Subscription to changes in the viewport size. */
    this._viewportChanges = rxjs__WEBPACK_IMPORTED_MODULE_15__.Subscription.EMPTY;
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._isDestroyed = false;
    if (!_scrollStrategy && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('Error: cdk-virtual-scroll-viewport requires the "itemSize" property to be set.');
    }
    this._viewportChanges = viewportRuler.change().subscribe(() => {
      this.checkViewportSize();
    });
    if (!this.scrollable) {
      // No scrollable is provided, so the virtual-scroll-viewport needs to become a scrollable
      this.elementRef.nativeElement.classList.add('cdk-virtual-scrollable');
      this.scrollable = this;
    }
  }
  ngOnInit() {
    // Scrolling depends on the element dimensions which we can't get during SSR.
    if (!this._platform.isBrowser) {
      return;
    }
    if (this.scrollable === this) {
      super.ngOnInit();
    }
    // It's still too early to measure the viewport at this point. Deferring with a promise allows
    // the Viewport to be rendered with the correct size before we measure. We run this outside the
    // zone to avoid causing more change detection cycles. We handle the change detection loop
    // ourselves instead.
    this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
      this._measureViewportSize();
      this._scrollStrategy.attach(this);
      this.scrollable.elementScrolled().pipe(
      // Start off with a fake scroll event so we properly detect our initial position.
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.startWith)(null),
      // Collect multiple events into one until the next animation frame. This way if
      // there are multiple scroll events in the same frame we only need to recheck
      // our layout once.
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.auditTime)(0, SCROLL_SCHEDULER),
      // Usually `elementScrolled` is completed when the scrollable is destroyed, but
      // that may not be the case if a `CdkVirtualScrollableElement` is used so we have
      // to unsubscribe here just in case.
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.takeUntil)(this._destroyed)).subscribe(() => this._scrollStrategy.onContentScrolled());
      this._markChangeDetectionNeeded();
    }));
  }
  ngOnDestroy() {
    this.detach();
    this._scrollStrategy.detach();
    // Complete all subjects
    this._renderedRangeSubject.complete();
    this._detachedSubject.complete();
    this._viewportChanges.unsubscribe();
    this._isDestroyed = true;
    super.ngOnDestroy();
  }
  /** Attaches a `CdkVirtualScrollRepeater` to this viewport. */
  attach(forOf) {
    if (this._forOf && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error('CdkVirtualScrollViewport is already attached.');
    }
    // Subscribe to the data stream of the CdkVirtualForOf to keep track of when the data length
    // changes. Run outside the zone to avoid triggering change detection, since we're managing the
    // change detection loop ourselves.
    this.ngZone.runOutsideAngular(() => {
      this._forOf = forOf;
      this._forOf.dataStream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.takeUntil)(this._detachedSubject)).subscribe(data => {
        const newLength = data.length;
        if (newLength !== this._dataLength) {
          this._dataLength = newLength;
          this._scrollStrategy.onDataLengthChanged();
        }
        this._doChangeDetection();
      });
    });
  }
  /** Detaches the current `CdkVirtualForOf`. */
  detach() {
    this._forOf = null;
    this._detachedSubject.next();
  }
  /** Gets the length of the data bound to this viewport (in number of items). */
  getDataLength() {
    return this._dataLength;
  }
  /** Gets the size of the viewport (in pixels). */
  getViewportSize() {
    return this._viewportSize;
  }
  // TODO(mmalerba): This is technically out of sync with what's really rendered until a render
  // cycle happens. I'm being careful to only call it after the render cycle is complete and before
  // setting it to something else, but its error prone and should probably be split into
  // `pendingRange` and `renderedRange`, the latter reflecting whats actually in the DOM.
  /** Get the current rendered range of items. */
  getRenderedRange() {
    return this._renderedRange;
  }
  measureBoundingClientRectWithScrollOffset(from) {
    return this.getElementRef().nativeElement.getBoundingClientRect()[from];
  }
  /**
   * Sets the total size of all content (in pixels), including content that is not currently
   * rendered.
   */
  setTotalContentSize(size) {
    if (this._totalContentSize !== size) {
      this._totalContentSize = size;
      this._calculateSpacerSize();
      this._markChangeDetectionNeeded();
    }
  }
  /** Sets the currently rendered range of indices. */
  setRenderedRange(range) {
    if (!rangesEqual(this._renderedRange, range)) {
      if (this.appendOnly) {
        range = {
          start: 0,
          end: Math.max(this._renderedRange.end, range.end)
        };
      }
      this._renderedRangeSubject.next(this._renderedRange = range);
      this._markChangeDetectionNeeded(() => this._scrollStrategy.onContentRendered());
    }
  }
  /**
   * Gets the offset from the start of the viewport to the start of the rendered data (in pixels).
   */
  getOffsetToRenderedContentStart() {
    return this._renderedContentOffsetNeedsRewrite ? null : this._renderedContentOffset;
  }
  /**
   * Sets the offset from the start of the viewport to either the start or end of the rendered data
   * (in pixels).
   */
  setRenderedContentOffset(offset, to = 'to-start') {
    // In appendOnly, we always start from the top
    offset = this.appendOnly && to === 'to-start' ? 0 : offset;
    // For a horizontal viewport in a right-to-left language we need to translate along the x-axis
    // in the negative direction.
    const isRtl = this.dir && this.dir.value == 'rtl';
    const isHorizontal = this.orientation == 'horizontal';
    const axis = isHorizontal ? 'X' : 'Y';
    const axisDirection = isHorizontal && isRtl ? -1 : 1;
    let transform = `translate${axis}(${Number(axisDirection * offset)}px)`;
    this._renderedContentOffset = offset;
    if (to === 'to-end') {
      transform += ` translate${axis}(-100%)`;
      // The viewport should rewrite this as a `to-start` offset on the next render cycle. Otherwise
      // elements will appear to expand in the wrong direction (e.g. `mat-expansion-panel` would
      // expand upward).
      this._renderedContentOffsetNeedsRewrite = true;
    }
    if (this._renderedContentTransform != transform) {
      // We know this value is safe because we parse `offset` with `Number()` before passing it
      // into the string.
      this._renderedContentTransform = transform;
      this._markChangeDetectionNeeded(() => {
        if (this._renderedContentOffsetNeedsRewrite) {
          this._renderedContentOffset -= this.measureRenderedContentSize();
          this._renderedContentOffsetNeedsRewrite = false;
          this.setRenderedContentOffset(this._renderedContentOffset);
        } else {
          this._scrollStrategy.onRenderedOffsetChanged();
        }
      });
    }
  }
  /**
   * Scrolls to the given offset from the start of the viewport. Please note that this is not always
   * the same as setting `scrollTop` or `scrollLeft`. In a horizontal viewport with right-to-left
   * direction, this would be the equivalent of setting a fictional `scrollRight` property.
   * @param offset The offset to scroll to.
   * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
   */
  scrollToOffset(offset, behavior = 'auto') {
    const options = {
      behavior
    };
    if (this.orientation === 'horizontal') {
      options.start = offset;
    } else {
      options.top = offset;
    }
    this.scrollable.scrollTo(options);
  }
  /**
   * Scrolls to the offset for the given index.
   * @param index The index of the element to scroll to.
   * @param behavior The ScrollBehavior to use when scrolling. Default is behavior is `auto`.
   */
  scrollToIndex(index, behavior = 'auto') {
    this._scrollStrategy.scrollToIndex(index, behavior);
  }
  /**
   * Gets the current scroll offset from the start of the scrollable (in pixels).
   * @param from The edge to measure the offset from. Defaults to 'top' in vertical mode and 'start'
   *     in horizontal mode.
   */
  measureScrollOffset(from) {
    // This is to break the call cycle
    let measureScrollOffset;
    if (this.scrollable == this) {
      measureScrollOffset = _from => super.measureScrollOffset(_from);
    } else {
      measureScrollOffset = _from => this.scrollable.measureScrollOffset(_from);
    }
    return Math.max(0, measureScrollOffset(from ?? (this.orientation === 'horizontal' ? 'start' : 'top')) - this.measureViewportOffset());
  }
  /**
   * Measures the offset of the viewport from the scrolling container
   * @param from The edge to measure from.
   */
  measureViewportOffset(from) {
    let fromRect;
    const LEFT = 'left';
    const RIGHT = 'right';
    const isRtl = this.dir?.value == 'rtl';
    if (from == 'start') {
      fromRect = isRtl ? RIGHT : LEFT;
    } else if (from == 'end') {
      fromRect = isRtl ? LEFT : RIGHT;
    } else if (from) {
      fromRect = from;
    } else {
      fromRect = this.orientation === 'horizontal' ? 'left' : 'top';
    }
    const scrollerClientRect = this.scrollable.measureBoundingClientRectWithScrollOffset(fromRect);
    const viewportClientRect = this.elementRef.nativeElement.getBoundingClientRect()[fromRect];
    return viewportClientRect - scrollerClientRect;
  }
  /** Measure the combined size of all of the rendered items. */
  measureRenderedContentSize() {
    const contentEl = this._contentWrapper.nativeElement;
    return this.orientation === 'horizontal' ? contentEl.offsetWidth : contentEl.offsetHeight;
  }
  /**
   * Measure the total combined size of the given range. Throws if the range includes items that are
   * not rendered.
   */
  measureRangeSize(range) {
    if (!this._forOf) {
      return 0;
    }
    return this._forOf.measureRangeSize(range, this.orientation);
  }
  /** Update the viewport dimensions and re-render. */
  checkViewportSize() {
    // TODO: Cleanup later when add logic for handling content resize
    this._measureViewportSize();
    this._scrollStrategy.onDataLengthChanged();
  }
  /** Measure the viewport size. */
  _measureViewportSize() {
    this._viewportSize = this.scrollable.measureViewportSize(this.orientation);
  }
  /** Queue up change detection to run. */
  _markChangeDetectionNeeded(runAfter) {
    if (runAfter) {
      this._runAfterChangeDetection.push(runAfter);
    }
    // Use a Promise to batch together calls to `_doChangeDetection`. This way if we set a bunch of
    // properties sequentially we only have to run `_doChangeDetection` once at the end.
    if (!this._isChangeDetectionPending) {
      this._isChangeDetectionPending = true;
      this.ngZone.runOutsideAngular(() => Promise.resolve().then(() => {
        this._doChangeDetection();
      }));
    }
  }
  /** Run change detection. */
  _doChangeDetection() {
    if (this._isDestroyed) {
      return;
    }
    this.ngZone.run(() => {
      // Apply changes to Angular bindings. Note: We must call `markForCheck` to run change detection
      // from the root, since the repeated items are content projected in. Calling `detectChanges`
      // instead does not properly check the projected content.
      this._changeDetectorRef.markForCheck();
      // Apply the content transform. The transform can't be set via an Angular binding because
      // bypassSecurityTrustStyle is banned in Google. However the value is safe, it's composed of
      // string literals, a variable that can only be 'X' or 'Y', and user input that is run through
      // the `Number` function first to coerce it to a numeric value.
      this._contentWrapper.nativeElement.style.transform = this._renderedContentTransform;
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.afterNextRender)(() => {
        this._isChangeDetectionPending = false;
        const runAfterChangeDetection = this._runAfterChangeDetection;
        this._runAfterChangeDetection = [];
        for (const fn of runAfterChangeDetection) {
          fn();
        }
      }, {
        injector: this._injector
      });
    });
  }
  /** Calculates the `style.width` and `style.height` for the spacer element. */
  _calculateSpacerSize() {
    this._totalContentHeight = this.orientation === 'horizontal' ? '' : `${this._totalContentSize}px`;
    this._totalContentWidth = this.orientation === 'horizontal' ? `${this._totalContentSize}px` : '';
  }
  static {
    this.ɵfac = function CdkVirtualScrollViewport_Factory(t) {
      return new (t || CdkVirtualScrollViewport)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](VIRTUAL_SCROLL_STRATEGY, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ViewportRuler), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](VIRTUAL_SCROLLABLE, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: CdkVirtualScrollViewport,
      selectors: [["cdk-virtual-scroll-viewport"]],
      viewQuery: function CdkVirtualScrollViewport_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._contentWrapper = _t.first);
        }
      },
      hostAttrs: [1, "cdk-virtual-scroll-viewport"],
      hostVars: 4,
      hostBindings: function CdkVirtualScrollViewport_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("cdk-virtual-scroll-orientation-horizontal", ctx.orientation === "horizontal")("cdk-virtual-scroll-orientation-vertical", ctx.orientation !== "horizontal");
        }
      },
      inputs: {
        orientation: "orientation",
        appendOnly: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "appendOnly", "appendOnly", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      outputs: {
        scrolledIndexChange: "scrolledIndexChange"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: CdkScrollable,
        useFactory: (virtualScrollable, viewport) => virtualScrollable || viewport,
        deps: [[new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject(VIRTUAL_SCROLLABLE)], CdkVirtualScrollViewport]
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c1,
      decls: 4,
      vars: 4,
      consts: [["contentWrapper", ""], [1, "cdk-virtual-scroll-content-wrapper"], [1, "cdk-virtual-scroll-spacer"]],
      template: function CdkVirtualScrollViewport_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 1, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](3, "div", 2);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("width", ctx._totalContentWidth)("height", ctx._totalContentHeight);
        }
      },
      styles: ["cdk-virtual-scroll-viewport{display:block;position:relative;transform:translateZ(0)}.cdk-virtual-scrollable{overflow:auto;will-change:scroll-position;contain:strict;-webkit-overflow-scrolling:touch}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:none}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:none}.cdk-virtual-scroll-spacer{height:1px;transform-origin:0 0;flex:0 0 auto}[dir=rtl] .cdk-virtual-scroll-spacer{transform-origin:100% 0}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkVirtualScrollViewport, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'cdk-virtual-scroll-viewport',
      host: {
        'class': 'cdk-virtual-scroll-viewport',
        '[class.cdk-virtual-scroll-orientation-horizontal]': 'orientation === "horizontal"',
        '[class.cdk-virtual-scroll-orientation-vertical]': 'orientation !== "horizontal"'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      standalone: true,
      providers: [{
        provide: CdkScrollable,
        useFactory: (virtualScrollable, viewport) => virtualScrollable || viewport,
        deps: [[new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional(), new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject(VIRTUAL_SCROLLABLE)], CdkVirtualScrollViewport]
      }],
      template: "<!--\n  Wrap the rendered content in an element that will be used to offset it based on the scroll\n  position.\n-->\n<div #contentWrapper class=\"cdk-virtual-scroll-content-wrapper\">\n  <ng-content></ng-content>\n</div>\n<!--\n  Spacer used to force the scrolling container to the correct size for the *total* number of items\n  so that the scrollbar captures the size of the entire data set.\n-->\n<div class=\"cdk-virtual-scroll-spacer\"\n     [style.width]=\"_totalContentWidth\" [style.height]=\"_totalContentHeight\"></div>\n",
      styles: ["cdk-virtual-scroll-viewport{display:block;position:relative;transform:translateZ(0)}.cdk-virtual-scrollable{overflow:auto;will-change:scroll-position;contain:strict;-webkit-overflow-scrolling:touch}.cdk-virtual-scroll-content-wrapper{position:absolute;top:0;left:0;contain:content}[dir=rtl] .cdk-virtual-scroll-content-wrapper{right:0;left:auto}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper{min-height:100%}.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-horizontal .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-left:0;padding-right:0;margin-left:0;margin-right:0;border-left-width:0;border-right-width:0;outline:none}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper{min-width:100%}.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>dl:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ol:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>table:not([cdkVirtualFor]),.cdk-virtual-scroll-orientation-vertical .cdk-virtual-scroll-content-wrapper>ul:not([cdkVirtualFor]){padding-top:0;padding-bottom:0;margin-top:0;margin-bottom:0;border-top-width:0;border-bottom-width:0;outline:none}.cdk-virtual-scroll-spacer{height:1px;transform-origin:0 0;flex:0 0 auto}[dir=rtl] .cdk-virtual-scroll-spacer{transform-origin:100% 0}"]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [VIRTUAL_SCROLL_STRATEGY]
    }]
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }, {
    type: ScrollDispatcher
  }, {
    type: ViewportRuler
  }, {
    type: CdkVirtualScrollable,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [VIRTUAL_SCROLLABLE]
    }]
  }], {
    orientation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    appendOnly: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    scrolledIndexChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    _contentWrapper: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['contentWrapper', {
        static: true
      }]
    }]
  });
})();

/** Helper to extract the offset of a DOM Node in a certain direction. */
function getOffset(orientation, direction, node) {
  const el = node;
  if (!el.getBoundingClientRect) {
    return 0;
  }
  const rect = el.getBoundingClientRect();
  if (orientation === 'horizontal') {
    return direction === 'start' ? rect.left : rect.right;
  }
  return direction === 'start' ? rect.top : rect.bottom;
}
/**
 * A directive similar to `ngForOf` to be used for rendering data inside a virtual scrolling
 * container.
 */
class CdkVirtualForOf {
  /** The DataSource to display. */
  get cdkVirtualForOf() {
    return this._cdkVirtualForOf;
  }
  set cdkVirtualForOf(value) {
    this._cdkVirtualForOf = value;
    if ((0,_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__.isDataSource)(value)) {
      this._dataSourceChanges.next(value);
    } else {
      // If value is an an NgIterable, convert it to an array.
      this._dataSourceChanges.next(new _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__.ArrayDataSource((0,rxjs__WEBPACK_IMPORTED_MODULE_18__.isObservable)(value) ? value : Array.from(value || [])));
    }
  }
  /**
   * The `TrackByFunction` to use for tracking changes. The `TrackByFunction` takes the index and
   * the item and produces a value to be used as the item's identity when tracking changes.
   */
  get cdkVirtualForTrackBy() {
    return this._cdkVirtualForTrackBy;
  }
  set cdkVirtualForTrackBy(fn) {
    this._needsUpdate = true;
    this._cdkVirtualForTrackBy = fn ? (index, item) => fn(index + (this._renderedRange ? this._renderedRange.start : 0), item) : undefined;
  }
  /** The template used to stamp out new elements. */
  set cdkVirtualForTemplate(value) {
    if (value) {
      this._needsUpdate = true;
      this._template = value;
    }
  }
  /**
   * The size of the cache used to store templates that are not being used for re-use later.
   * Setting the cache size to `0` will disable caching. Defaults to 20 templates.
   */
  get cdkVirtualForTemplateCacheSize() {
    return this._viewRepeater.viewCacheSize;
  }
  set cdkVirtualForTemplateCacheSize(size) {
    this._viewRepeater.viewCacheSize = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_3__.coerceNumberProperty)(size);
  }
  constructor(/** The view container to add items to. */
  _viewContainerRef, /** The template to use when stamping out new items. */
  _template, /** The set of available differs. */
  _differs, /** The strategy used to render items in the virtual scroll viewport. */
  _viewRepeater, /** The virtual scrolling viewport that these items are being rendered in. */
  _viewport, ngZone) {
    this._viewContainerRef = _viewContainerRef;
    this._template = _template;
    this._differs = _differs;
    this._viewRepeater = _viewRepeater;
    this._viewport = _viewport;
    /** Emits when the rendered view of the data changes. */
    this.viewChange = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** Subject that emits when a new DataSource instance is given. */
    this._dataSourceChanges = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    /** Emits whenever the data in the current DataSource changes. */
    this.dataStream = this._dataSourceChanges.pipe(
    // Start off with null `DataSource`.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.startWith)(null),
    // Bundle up the previous and current data sources so we can work with both.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.pairwise)(),
    // Use `_changeDataSource` to disconnect from the previous data source and connect to the
    // new one, passing back a stream of data changes which we run through `switchMap` to give
    // us a data stream that emits the latest data from whatever the current `DataSource` is.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.switchMap)(([prev, cur]) => this._changeDataSource(prev, cur)),
    // Replay the last emitted data when someone subscribes.
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.shareReplay)(1));
    /** The differ used to calculate changes to the data. */
    this._differ = null;
    /** Whether the rendered data should be updated during the next ngDoCheck cycle. */
    this._needsUpdate = false;
    this._destroyed = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
    this.dataStream.subscribe(data => {
      this._data = data;
      this._onRenderedDataChange();
    });
    this._viewport.renderedRangeStream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.takeUntil)(this._destroyed)).subscribe(range => {
      this._renderedRange = range;
      if (this.viewChange.observers.length) {
        ngZone.run(() => this.viewChange.next(this._renderedRange));
      }
      this._onRenderedDataChange();
    });
    this._viewport.attach(this);
  }
  /**
   * Measures the combined size (width for horizontal orientation, height for vertical) of all items
   * in the specified range. Throws an error if the range includes items that are not currently
   * rendered.
   */
  measureRangeSize(range, orientation) {
    if (range.start >= range.end) {
      return 0;
    }
    if ((range.start < this._renderedRange.start || range.end > this._renderedRange.end) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error(`Error: attempted to measure an item that isn't rendered.`);
    }
    // The index into the list of rendered views for the first item in the range.
    const renderedStartIndex = range.start - this._renderedRange.start;
    // The length of the range we're measuring.
    const rangeLen = range.end - range.start;
    // Loop over all the views, find the first and land node and compute the size by subtracting
    // the top of the first node from the bottom of the last one.
    let firstNode;
    let lastNode;
    // Find the first node by starting from the beginning and going forwards.
    for (let i = 0; i < rangeLen; i++) {
      const view = this._viewContainerRef.get(i + renderedStartIndex);
      if (view && view.rootNodes.length) {
        firstNode = lastNode = view.rootNodes[0];
        break;
      }
    }
    // Find the last node by starting from the end and going backwards.
    for (let i = rangeLen - 1; i > -1; i--) {
      const view = this._viewContainerRef.get(i + renderedStartIndex);
      if (view && view.rootNodes.length) {
        lastNode = view.rootNodes[view.rootNodes.length - 1];
        break;
      }
    }
    return firstNode && lastNode ? getOffset(orientation, 'end', lastNode) - getOffset(orientation, 'start', firstNode) : 0;
  }
  ngDoCheck() {
    if (this._differ && this._needsUpdate) {
      // TODO(mmalerba): We should differentiate needs update due to scrolling and a new portion of
      // this list being rendered (can use simpler algorithm) vs needs update due to data actually
      // changing (need to do this diff).
      const changes = this._differ.diff(this._renderedItems);
      if (!changes) {
        this._updateContext();
      } else {
        this._applyChanges(changes);
      }
      this._needsUpdate = false;
    }
  }
  ngOnDestroy() {
    this._viewport.detach();
    this._dataSourceChanges.next(undefined);
    this._dataSourceChanges.complete();
    this.viewChange.complete();
    this._destroyed.next();
    this._destroyed.complete();
    this._viewRepeater.detach();
  }
  /** React to scroll state changes in the viewport. */
  _onRenderedDataChange() {
    if (!this._renderedRange) {
      return;
    }
    this._renderedItems = this._data.slice(this._renderedRange.start, this._renderedRange.end);
    if (!this._differ) {
      // Use a wrapper function for the `trackBy` so any new values are
      // picked up automatically without having to recreate the differ.
      this._differ = this._differs.find(this._renderedItems).create((index, item) => {
        return this.cdkVirtualForTrackBy ? this.cdkVirtualForTrackBy(index, item) : item;
      });
    }
    this._needsUpdate = true;
  }
  /** Swap out one `DataSource` for another. */
  _changeDataSource(oldDs, newDs) {
    if (oldDs) {
      oldDs.disconnect(this);
    }
    this._needsUpdate = true;
    return newDs ? newDs.connect(this) : (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)();
  }
  /** Update the `CdkVirtualForOfContext` for all views. */
  _updateContext() {
    const count = this._data.length;
    let i = this._viewContainerRef.length;
    while (i--) {
      const view = this._viewContainerRef.get(i);
      view.context.index = this._renderedRange.start + i;
      view.context.count = count;
      this._updateComputedContextProperties(view.context);
      view.detectChanges();
    }
  }
  /** Apply changes to the DOM. */
  _applyChanges(changes) {
    this._viewRepeater.applyChanges(changes, this._viewContainerRef, (record, _adjustedPreviousIndex, currentIndex) => this._getEmbeddedViewArgs(record, currentIndex), record => record.item);
    // Update $implicit for any items that had an identity change.
    changes.forEachIdentityChange(record => {
      const view = this._viewContainerRef.get(record.currentIndex);
      view.context.$implicit = record.item;
    });
    // Update the context variables on all items.
    const count = this._data.length;
    let i = this._viewContainerRef.length;
    while (i--) {
      const view = this._viewContainerRef.get(i);
      view.context.index = this._renderedRange.start + i;
      view.context.count = count;
      this._updateComputedContextProperties(view.context);
    }
  }
  /** Update the computed properties on the `CdkVirtualForOfContext`. */
  _updateComputedContextProperties(context) {
    context.first = context.index === 0;
    context.last = context.index === context.count - 1;
    context.even = context.index % 2 === 0;
    context.odd = !context.even;
  }
  _getEmbeddedViewArgs(record, index) {
    // Note that it's important that we insert the item directly at the proper index,
    // rather than inserting it and the moving it in place, because if there's a directive
    // on the same node that injects the `ViewContainerRef`, Angular will insert another
    // comment node which can throw off the move when it's being repeated for all items.
    return {
      templateRef: this._template,
      context: {
        $implicit: record.item,
        // It's guaranteed that the iterable is not "undefined" or "null" because we only
        // generate views for elements if the "cdkVirtualForOf" iterable has elements.
        cdkVirtualForOf: this._cdkVirtualForOf,
        index: -1,
        count: -1,
        first: false,
        last: false,
        odd: false,
        even: false
      },
      index
    };
  }
  static {
    this.ɵfac = function CdkVirtualForOf_Factory(t) {
      return new (t || CdkVirtualForOf)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._VIEW_REPEATER_STRATEGY), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](CdkVirtualScrollViewport, 4), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkVirtualForOf,
      selectors: [["", "cdkVirtualFor", "", "cdkVirtualForOf", ""]],
      inputs: {
        cdkVirtualForOf: "cdkVirtualForOf",
        cdkVirtualForTrackBy: "cdkVirtualForTrackBy",
        cdkVirtualForTemplate: "cdkVirtualForTemplate",
        cdkVirtualForTemplateCacheSize: "cdkVirtualForTemplateCacheSize"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._RecycleViewRepeaterStrategy
      }])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkVirtualForOf, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkVirtualFor][cdkVirtualForOf]',
      providers: [{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._RecycleViewRepeaterStrategy
      }],
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers
  }, {
    type: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._RecycleViewRepeaterStrategy,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_17__._VIEW_REPEATER_STRATEGY]
    }]
  }, {
    type: CdkVirtualScrollViewport,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }], {
    cdkVirtualForOf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    cdkVirtualForTrackBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    cdkVirtualForTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    cdkVirtualForTemplateCacheSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();

/**
 * Provides a virtual scrollable for the element it is attached to.
 */
class CdkVirtualScrollableElement extends CdkVirtualScrollable {
  constructor(elementRef, scrollDispatcher, ngZone, dir) {
    super(elementRef, scrollDispatcher, ngZone, dir);
  }
  measureBoundingClientRectWithScrollOffset(from) {
    return this.getElementRef().nativeElement.getBoundingClientRect()[from] - this.measureScrollOffset(from);
  }
  static {
    this.ɵfac = function CdkVirtualScrollableElement_Factory(t) {
      return new (t || CdkVirtualScrollableElement)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkVirtualScrollableElement,
      selectors: [["", "cdkVirtualScrollingElement", ""]],
      hostAttrs: [1, "cdk-virtual-scrollable"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: VIRTUAL_SCROLLABLE,
        useExisting: CdkVirtualScrollableElement
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkVirtualScrollableElement, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[cdkVirtualScrollingElement]',
      providers: [{
        provide: VIRTUAL_SCROLLABLE,
        useExisting: CdkVirtualScrollableElement
      }],
      standalone: true,
      host: {
        'class': 'cdk-virtual-scrollable'
      }
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: ScrollDispatcher
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();

/**
 * Provides as virtual scrollable for the global / window scrollbar.
 */
class CdkVirtualScrollableWindow extends CdkVirtualScrollable {
  constructor(scrollDispatcher, ngZone, dir) {
    super(new _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef(document.documentElement), scrollDispatcher, ngZone, dir);
    this._elementScrolled = new rxjs__WEBPACK_IMPORTED_MODULE_5__.Observable(observer => this.ngZone.runOutsideAngular(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.fromEvent)(document, 'scroll').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.takeUntil)(this._destroyed)).subscribe(observer)));
  }
  measureBoundingClientRectWithScrollOffset(from) {
    return this.getElementRef().nativeElement.getBoundingClientRect()[from];
  }
  static {
    this.ɵfac = function CdkVirtualScrollableWindow_Factory(t) {
      return new (t || CdkVirtualScrollableWindow)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ScrollDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CdkVirtualScrollableWindow,
      selectors: [["cdk-virtual-scroll-viewport", "scrollWindow", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: VIRTUAL_SCROLLABLE,
        useExisting: CdkVirtualScrollableWindow
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkVirtualScrollableWindow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'cdk-virtual-scroll-viewport[scrollWindow]',
      providers: [{
        provide: VIRTUAL_SCROLLABLE,
        useExisting: CdkVirtualScrollableWindow
      }],
      standalone: true
    }]
  }], () => [{
    type: ScrollDispatcher
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();
class CdkScrollableModule {
  static {
    this.ɵfac = function CdkScrollableModule_Factory(t) {
      return new (t || CdkScrollableModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: CdkScrollableModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CdkScrollableModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: [CdkScrollable],
      imports: [CdkScrollable]
    }]
  }], null, null);
})();
/**
 * @docs-primary-export
 */
class ScrollingModule {
  static {
    this.ɵfac = function ScrollingModule_Factory(t) {
      return new (t || ScrollingModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: ScrollingModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.BidiModule, CdkScrollableModule, _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.BidiModule, CdkScrollableModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ScrollingModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.BidiModule, CdkScrollableModule, CdkVirtualScrollViewport, CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollableWindow, CdkVirtualScrollableElement],
      exports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_12__.BidiModule, CdkScrollableModule, CdkFixedSizeVirtualScroll, CdkVirtualForOf, CdkVirtualScrollViewport, CdkVirtualScrollableWindow, CdkVirtualScrollableElement]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 90198:
/*!******************************************************!*\
  !*** ./node_modules/@angular/cdk/fesm2022/table.mjs ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BaseCdkCell: () => (/* binding */ BaseCdkCell),
/* harmony export */   BaseRowDef: () => (/* binding */ BaseRowDef),
/* harmony export */   CDK_ROW_TEMPLATE: () => (/* binding */ CDK_ROW_TEMPLATE),
/* harmony export */   CDK_TABLE: () => (/* binding */ CDK_TABLE),
/* harmony export */   CDK_TABLE_TEMPLATE: () => (/* binding */ CDK_TABLE_TEMPLATE),
/* harmony export */   CdkCell: () => (/* binding */ CdkCell),
/* harmony export */   CdkCellDef: () => (/* binding */ CdkCellDef),
/* harmony export */   CdkCellOutlet: () => (/* binding */ CdkCellOutlet),
/* harmony export */   CdkColumnDef: () => (/* binding */ CdkColumnDef),
/* harmony export */   CdkFooterCell: () => (/* binding */ CdkFooterCell),
/* harmony export */   CdkFooterCellDef: () => (/* binding */ CdkFooterCellDef),
/* harmony export */   CdkFooterRow: () => (/* binding */ CdkFooterRow),
/* harmony export */   CdkFooterRowDef: () => (/* binding */ CdkFooterRowDef),
/* harmony export */   CdkHeaderCell: () => (/* binding */ CdkHeaderCell),
/* harmony export */   CdkHeaderCellDef: () => (/* binding */ CdkHeaderCellDef),
/* harmony export */   CdkHeaderRow: () => (/* binding */ CdkHeaderRow),
/* harmony export */   CdkHeaderRowDef: () => (/* binding */ CdkHeaderRowDef),
/* harmony export */   CdkNoDataRow: () => (/* binding */ CdkNoDataRow),
/* harmony export */   CdkRecycleRows: () => (/* binding */ CdkRecycleRows),
/* harmony export */   CdkRow: () => (/* binding */ CdkRow),
/* harmony export */   CdkRowDef: () => (/* binding */ CdkRowDef),
/* harmony export */   CdkTable: () => (/* binding */ CdkTable),
/* harmony export */   CdkTableModule: () => (/* binding */ CdkTableModule),
/* harmony export */   CdkTextColumn: () => (/* binding */ CdkTextColumn),
/* harmony export */   DataRowOutlet: () => (/* binding */ DataRowOutlet),
/* harmony export */   DataSource: () => (/* reexport safe */ _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__.DataSource),
/* harmony export */   FooterRowOutlet: () => (/* binding */ FooterRowOutlet),
/* harmony export */   HeaderRowOutlet: () => (/* binding */ HeaderRowOutlet),
/* harmony export */   NoDataRowOutlet: () => (/* binding */ NoDataRowOutlet),
/* harmony export */   STICKY_DIRECTIONS: () => (/* binding */ STICKY_DIRECTIONS),
/* harmony export */   STICKY_POSITIONING_LISTENER: () => (/* binding */ STICKY_POSITIONING_LISTENER),
/* harmony export */   StickyStyler: () => (/* binding */ StickyStyler),
/* harmony export */   TEXT_COLUMN_OPTIONS: () => (/* binding */ TEXT_COLUMN_OPTIONS),
/* harmony export */   _COALESCED_STYLE_SCHEDULER: () => (/* binding */ _COALESCED_STYLE_SCHEDULER),
/* harmony export */   _CoalescedStyleScheduler: () => (/* binding */ _CoalescedStyleScheduler),
/* harmony export */   _Schedule: () => (/* binding */ _Schedule),
/* harmony export */   mixinHasStickyInput: () => (/* binding */ mixinHasStickyInput)
/* harmony export */ });
/* harmony import */ var _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @angular/cdk/bidi */ 63680);
/* harmony import */ var _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/cdk/collections */ 37989);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);
/* harmony import */ var _angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @angular/cdk/scrolling */ 79975);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);













/**
 * Used to provide a table to some of the sub-components without causing a circular dependency.
 * @docs-private
 */
const _c0 = [[["caption"]], [["colgroup"], ["col"]], "*"];
const _c1 = ["caption", "colgroup, col", "*"];
function CdkTable_Conditional_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojection"](0, 2);
  }
}
function CdkTable_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "thead", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](1, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](2, "tbody", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](3, 2)(4, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](5, "tfoot", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](6, 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
  }
}
function CdkTable_Conditional_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](0, 1)(1, 2)(2, 3)(3, 4);
  }
}
function CdkTextColumn_th_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "th", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵstyleProp"]("text-align", ctx_r0.justify);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtextInterpolate1"](" ", ctx_r0.headerText, " ");
  }
}
function CdkTextColumn_td_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "td", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const data_r2 = ctx.$implicit;
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵstyleProp"]("text-align", ctx_r0.justify);
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtextInterpolate1"](" ", ctx_r0.dataAccessor(data_r2, ctx_r0.name), " ");
  }
}
const CDK_TABLE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CDK_TABLE');
/** Injection token that can be used to specify the text column options. */
const TEXT_COLUMN_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('text-column-options');

/**
 * Cell definition for a CDK table.
 * Captures the template of a column's data row cell as well as cell-specific properties.
 */
class CdkCellDef {
  constructor(/** @docs-private */template) {
    this.template = template;
  }
  static {
    this.ɵfac = function CdkCellDef_Factory(t) {
      return new (t || CdkCellDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkCellDef,
      selectors: [["", "cdkCellDef", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkCellDef]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], null);
})();
/**
 * Header cell definition for a CDK table.
 * Captures the template of a column's header cell and as well as cell-specific properties.
 */
class CdkHeaderCellDef {
  constructor(/** @docs-private */template) {
    this.template = template;
  }
  static {
    this.ɵfac = function CdkHeaderCellDef_Factory(t) {
      return new (t || CdkHeaderCellDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkHeaderCellDef,
      selectors: [["", "cdkHeaderCellDef", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkHeaderCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkHeaderCellDef]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], null);
})();
/**
 * Footer cell definition for a CDK table.
 * Captures the template of a column's footer cell and as well as cell-specific properties.
 */
class CdkFooterCellDef {
  constructor(/** @docs-private */template) {
    this.template = template;
  }
  static {
    this.ɵfac = function CdkFooterCellDef_Factory(t) {
      return new (t || CdkFooterCellDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkFooterCellDef,
      selectors: [["", "cdkFooterCellDef", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkFooterCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkFooterCellDef]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], null);
})();
/**
 * Column definition for the CDK table.
 * Defines a set of cells available for a table column.
 */
class CdkColumnDef {
  /** Unique name for this column. */
  get name() {
    return this._name;
  }
  set name(name) {
    this._setNameInput(name);
  }
  /** Whether the cell is sticky. */
  get sticky() {
    return this._sticky;
  }
  set sticky(value) {
    if (value !== this._sticky) {
      this._sticky = value;
      this._hasStickyChanged = true;
    }
  }
  /**
   * Whether this column should be sticky positioned on the end of the row. Should make sure
   * that it mimics the `CanStick` mixin such that `_hasStickyChanged` is set to true if the value
   * has been changed.
   */
  get stickyEnd() {
    return this._stickyEnd;
  }
  set stickyEnd(value) {
    if (value !== this._stickyEnd) {
      this._stickyEnd = value;
      this._hasStickyChanged = true;
    }
  }
  constructor(_table) {
    this._table = _table;
    this._hasStickyChanged = false;
    this._sticky = false;
    this._stickyEnd = false;
  }
  /** Whether the sticky state has changed. */
  hasStickyChanged() {
    const hasStickyChanged = this._hasStickyChanged;
    this.resetStickyChanged();
    return hasStickyChanged;
  }
  /** Resets the sticky changed state. */
  resetStickyChanged() {
    this._hasStickyChanged = false;
  }
  /**
   * Overridable method that sets the css classes that will be added to every cell in this
   * column.
   * In the future, columnCssClassName will change from type string[] to string and this
   * will set a single string value.
   * @docs-private
   */
  _updateColumnCssClassName() {
    this._columnCssClassName = [`cdk-column-${this.cssClassFriendlyName}`];
  }
  /**
   * This has been extracted to a util because of TS 4 and VE.
   * View Engine doesn't support property rename inheritance.
   * TS 4.0 doesn't allow properties to override accessors or vice-versa.
   * @docs-private
   */
  _setNameInput(value) {
    // If the directive is set without a name (updated programmatically), then this setter will
    // trigger with an empty string and should not overwrite the programmatically set value.
    if (value) {
      this._name = value;
      this.cssClassFriendlyName = value.replace(/[^a-z0-9_-]/gi, '-');
      this._updateColumnCssClassName();
    }
  }
  static {
    this.ɵfac = function CdkColumnDef_Factory(t) {
      return new (t || CdkColumnDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_TABLE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkColumnDef,
      selectors: [["", "cdkColumnDef", ""]],
      contentQueries: function CdkColumnDef_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkCellDef, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkHeaderCellDef, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkFooterCellDef, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.cell = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.headerCell = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.footerCell = _t.first);
        }
      },
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkColumnDef", "name"],
        sticky: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "sticky", "sticky", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        stickyEnd: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "stickyEnd", "stickyEnd", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: 'MAT_SORT_HEADER_COLUMN_DEF',
        useExisting: CdkColumnDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkColumnDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkColumnDef]',
      providers: [{
        provide: 'MAT_SORT_HEADER_COLUMN_DEF',
        useExisting: CdkColumnDef
      }],
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_TABLE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['cdkColumnDef']
    }],
    sticky: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    stickyEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    cell: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChild,
      args: [CdkCellDef]
    }],
    headerCell: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChild,
      args: [CdkHeaderCellDef]
    }],
    footerCell: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChild,
      args: [CdkFooterCellDef]
    }]
  });
})();
/** Base class for the cells. Adds a CSS classname that identifies the column it renders in. */
class BaseCdkCell {
  constructor(columnDef, elementRef) {
    elementRef.nativeElement.classList.add(...columnDef._columnCssClassName);
  }
}
/** Header cell template container that adds the right classes and role. */
class CdkHeaderCell extends BaseCdkCell {
  constructor(columnDef, elementRef) {
    super(columnDef, elementRef);
  }
  static {
    this.ɵfac = function CdkHeaderCell_Factory(t) {
      return new (t || CdkHeaderCell)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CdkColumnDef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkHeaderCell,
      selectors: [["cdk-header-cell"], ["th", "cdk-header-cell", ""]],
      hostAttrs: ["role", "columnheader", 1, "cdk-header-cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkHeaderCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'cdk-header-cell, th[cdk-header-cell]',
      host: {
        'class': 'cdk-header-cell',
        'role': 'columnheader'
      },
      standalone: true
    }]
  }], () => [{
    type: CdkColumnDef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/** Footer cell template container that adds the right classes and role. */
class CdkFooterCell extends BaseCdkCell {
  constructor(columnDef, elementRef) {
    super(columnDef, elementRef);
    const role = columnDef._table?._getCellRole();
    if (role) {
      elementRef.nativeElement.setAttribute('role', role);
    }
  }
  static {
    this.ɵfac = function CdkFooterCell_Factory(t) {
      return new (t || CdkFooterCell)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CdkColumnDef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkFooterCell,
      selectors: [["cdk-footer-cell"], ["td", "cdk-footer-cell", ""]],
      hostAttrs: [1, "cdk-footer-cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkFooterCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'cdk-footer-cell, td[cdk-footer-cell]',
      host: {
        'class': 'cdk-footer-cell'
      },
      standalone: true
    }]
  }], () => [{
    type: CdkColumnDef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/** Cell template container that adds the right classes and role. */
class CdkCell extends BaseCdkCell {
  constructor(columnDef, elementRef) {
    super(columnDef, elementRef);
    const role = columnDef._table?._getCellRole();
    if (role) {
      elementRef.nativeElement.setAttribute('role', role);
    }
  }
  static {
    this.ɵfac = function CdkCell_Factory(t) {
      return new (t || CdkCell)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CdkColumnDef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkCell,
      selectors: [["cdk-cell"], ["td", "cdk-cell", ""]],
      hostAttrs: [1, "cdk-cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'cdk-cell, td[cdk-cell]',
      host: {
        'class': 'cdk-cell'
      },
      standalone: true
    }]
  }], () => [{
    type: CdkColumnDef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();

/**
 * @docs-private
 */
class _Schedule {
  constructor() {
    this.tasks = [];
    this.endTasks = [];
  }
}
/** Injection token used to provide a coalesced style scheduler. */
const _COALESCED_STYLE_SCHEDULER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('_COALESCED_STYLE_SCHEDULER');
/**
 * Allows grouping up CSSDom mutations after the current execution context.
 * This can significantly improve performance when separate consecutive functions are
 * reading from the CSSDom and then mutating it.
 *
 * @docs-private
 */
class _CoalescedStyleScheduler {
  constructor(_unusedNgZone) {
    this._currentSchedule = null;
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone);
  }
  /**
   * Schedules the specified task to run at the end of the current VM turn.
   */
  schedule(task) {
    this._createScheduleIfNeeded();
    this._currentSchedule.tasks.push(task);
  }
  /**
   * Schedules the specified task to run after other scheduled tasks at the end of the current
   * VM turn.
   */
  scheduleEnd(task) {
    this._createScheduleIfNeeded();
    this._currentSchedule.endTasks.push(task);
  }
  _createScheduleIfNeeded() {
    if (this._currentSchedule) {
      return;
    }
    this._currentSchedule = new _Schedule();
    this._ngZone.runOutsideAngular(() =>
    // TODO(mmalerba): Scheduling this using something that runs less frequently
    //  (e.g. requestAnimationFrame, setTimeout, etc.) causes noticeable jank with the column
    //  resizer. We should audit the usages of schedule / scheduleEnd in that component and see
    //  if we can refactor it so that we don't need to flush the tasks quite so frequently.
    queueMicrotask(() => {
      while (this._currentSchedule.tasks.length || this._currentSchedule.endTasks.length) {
        const schedule = this._currentSchedule;
        // Capture new tasks scheduled by the current set of tasks.
        this._currentSchedule = new _Schedule();
        for (const task of schedule.tasks) {
          task();
        }
        for (const task of schedule.endTasks) {
          task();
        }
      }
      this._currentSchedule = null;
    }));
  }
  static {
    this.ɵfac = function _CoalescedStyleScheduler_Factory(t) {
      return new (t || _CoalescedStyleScheduler)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: _CoalescedStyleScheduler,
      factory: _CoalescedStyleScheduler.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](_CoalescedStyleScheduler, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], null);
})();

/**
 * The row template that can be used by the mat-table. Should not be used outside of the
 * material library.
 */
const CDK_ROW_TEMPLATE = `<ng-container cdkCellOutlet></ng-container>`;
/**
 * Base class for the CdkHeaderRowDef and CdkRowDef that handles checking their columns inputs
 * for changes and notifying the table.
 */
class BaseRowDef {
  constructor(/** @docs-private */template, _differs) {
    this.template = template;
    this._differs = _differs;
  }
  ngOnChanges(changes) {
    // Create a new columns differ if one does not yet exist. Initialize it based on initial value
    // of the columns property or an empty array if none is provided.
    if (!this._columnsDiffer) {
      const columns = changes['columns'] && changes['columns'].currentValue || [];
      this._columnsDiffer = this._differs.find(columns).create();
      this._columnsDiffer.diff(columns);
    }
  }
  /**
   * Returns the difference between the current columns and the columns from the last diff, or null
   * if there is no difference.
   */
  getColumnsDiff() {
    return this._columnsDiffer.diff(this.columns);
  }
  /** Gets this row def's relevant cell template from the provided column def. */
  extractCellTemplate(column) {
    if (this instanceof CdkHeaderRowDef) {
      return column.headerCell.template;
    }
    if (this instanceof CdkFooterRowDef) {
      return column.footerCell.template;
    } else {
      return column.cell.template;
    }
  }
  static {
    this.ɵfac = function BaseRowDef_Factory(t) {
      return new (t || BaseRowDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: BaseRowDef,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BaseRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }], null);
})();
/**
 * Header row definition for the CDK table.
 * Captures the header row's template and other header properties such as the columns to display.
 */
class CdkHeaderRowDef extends BaseRowDef {
  /** Whether the row is sticky. */
  get sticky() {
    return this._sticky;
  }
  set sticky(value) {
    if (value !== this._sticky) {
      this._sticky = value;
      this._hasStickyChanged = true;
    }
  }
  constructor(template, _differs, _table) {
    super(template, _differs);
    this._table = _table;
    this._hasStickyChanged = false;
    this._sticky = false;
  }
  // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance.
  // Explicitly define it so that the method is called as part of the Angular lifecycle.
  ngOnChanges(changes) {
    super.ngOnChanges(changes);
  }
  /** Whether the sticky state has changed. */
  hasStickyChanged() {
    const hasStickyChanged = this._hasStickyChanged;
    this.resetStickyChanged();
    return hasStickyChanged;
  }
  /** Resets the sticky changed state. */
  resetStickyChanged() {
    this._hasStickyChanged = false;
  }
  static {
    this.ɵfac = function CdkHeaderRowDef_Factory(t) {
      return new (t || CdkHeaderRowDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_TABLE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkHeaderRowDef,
      selectors: [["", "cdkHeaderRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkHeaderRowDef", "columns"],
        sticky: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkHeaderRowDefSticky", "sticky", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkHeaderRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkHeaderRowDef]',
      inputs: [{
        name: 'columns',
        alias: 'cdkHeaderRowDef'
      }],
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_TABLE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }], {
    sticky: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkHeaderRowDefSticky',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }]
  });
})();
/**
 * Footer row definition for the CDK table.
 * Captures the footer row's template and other footer properties such as the columns to display.
 */
class CdkFooterRowDef extends BaseRowDef {
  /** Whether the row is sticky. */
  get sticky() {
    return this._sticky;
  }
  set sticky(value) {
    if (value !== this._sticky) {
      this._sticky = value;
      this._hasStickyChanged = true;
    }
  }
  constructor(template, _differs, _table) {
    super(template, _differs);
    this._table = _table;
    this._hasStickyChanged = false;
    this._sticky = false;
  }
  // Prerender fails to recognize that ngOnChanges in a part of this class through inheritance.
  // Explicitly define it so that the method is called as part of the Angular lifecycle.
  ngOnChanges(changes) {
    super.ngOnChanges(changes);
  }
  /** Whether the sticky state has changed. */
  hasStickyChanged() {
    const hasStickyChanged = this._hasStickyChanged;
    this.resetStickyChanged();
    return hasStickyChanged;
  }
  /** Resets the sticky changed state. */
  resetStickyChanged() {
    this._hasStickyChanged = false;
  }
  static {
    this.ɵfac = function CdkFooterRowDef_Factory(t) {
      return new (t || CdkFooterRowDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_TABLE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkFooterRowDef,
      selectors: [["", "cdkFooterRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkFooterRowDef", "columns"],
        sticky: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "cdkFooterRowDefSticky", "sticky", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkFooterRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkFooterRowDef]',
      inputs: [{
        name: 'columns',
        alias: 'cdkFooterRowDef'
      }],
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_TABLE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }], {
    sticky: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        alias: 'cdkFooterRowDefSticky',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }]
  });
})();
/**
 * Data row definition for the CDK table.
 * Captures the header row's template and other row properties such as the columns to display and
 * a when predicate that describes when this row should be used.
 */
class CdkRowDef extends BaseRowDef {
  // TODO(andrewseguin): Add an input for providing a switch function to determine
  //   if this template should be used.
  constructor(template, _differs, _table) {
    super(template, _differs);
    this._table = _table;
  }
  static {
    this.ɵfac = function CdkRowDef_Factory(t) {
      return new (t || CdkRowDef)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CDK_TABLE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkRowDef,
      selectors: [["", "cdkRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkRowDefColumns", "columns"],
        when: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "cdkRowDefWhen", "when"]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkRowDef]',
      inputs: [{
        name: 'columns',
        alias: 'cdkRowDefColumns'
      }, {
        name: 'when',
        alias: 'cdkRowDefWhen'
      }],
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [CDK_TABLE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }], null);
})();
/**
 * Outlet for rendering cells inside of a row or header row.
 * @docs-private
 */
class CdkCellOutlet {
  /**
   * Static property containing the latest constructed instance of this class.
   * Used by the CDK table when each CdkHeaderRow and CdkRow component is created using
   * createEmbeddedView. After one of these components are created, this property will provide
   * a handle to provide that component's cells and context. After init, the CdkCellOutlet will
   * construct the cells with the provided context.
   */
  static {
    this.mostRecentCellOutlet = null;
  }
  constructor(_viewContainer) {
    this._viewContainer = _viewContainer;
    CdkCellOutlet.mostRecentCellOutlet = this;
  }
  ngOnDestroy() {
    // If this was the last outlet being rendered in the view, remove the reference
    // from the static property after it has been destroyed to avoid leaking memory.
    if (CdkCellOutlet.mostRecentCellOutlet === this) {
      CdkCellOutlet.mostRecentCellOutlet = null;
    }
  }
  static {
    this.ɵfac = function CdkCellOutlet_Factory(t) {
      return new (t || CdkCellOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkCellOutlet,
      selectors: [["", "cdkCellOutlet", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkCellOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[cdkCellOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }], null);
})();
/** Header template container that contains the cell outlet. Adds the right class and role. */
class CdkHeaderRow {
  static {
    this.ɵfac = function CdkHeaderRow_Factory(t) {
      return new (t || CdkHeaderRow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: CdkHeaderRow,
      selectors: [["cdk-header-row"], ["tr", "cdk-header-row", ""]],
      hostAttrs: ["role", "row", 1, "cdk-header-row"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function CdkHeaderRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkHeaderRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'cdk-header-row, tr[cdk-header-row]',
      template: CDK_ROW_TEMPLATE,
      host: {
        'class': 'cdk-header-row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      standalone: true,
      imports: [CdkCellOutlet]
    }]
  }], null, null);
})();
/** Footer template container that contains the cell outlet. Adds the right class and role. */
class CdkFooterRow {
  static {
    this.ɵfac = function CdkFooterRow_Factory(t) {
      return new (t || CdkFooterRow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: CdkFooterRow,
      selectors: [["cdk-footer-row"], ["tr", "cdk-footer-row", ""]],
      hostAttrs: ["role", "row", 1, "cdk-footer-row"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function CdkFooterRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkFooterRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'cdk-footer-row, tr[cdk-footer-row]',
      template: CDK_ROW_TEMPLATE,
      host: {
        'class': 'cdk-footer-row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      standalone: true,
      imports: [CdkCellOutlet]
    }]
  }], null, null);
})();
/** Data row template container that contains the cell outlet. Adds the right class and role. */
class CdkRow {
  static {
    this.ɵfac = function CdkRow_Factory(t) {
      return new (t || CdkRow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: CdkRow,
      selectors: [["cdk-row"], ["tr", "cdk-row", ""]],
      hostAttrs: ["role", "row", 1, "cdk-row"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function CdkRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'cdk-row, tr[cdk-row]',
      template: CDK_ROW_TEMPLATE,
      host: {
        'class': 'cdk-row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      standalone: true,
      imports: [CdkCellOutlet]
    }]
  }], null, null);
})();
/** Row that can be used to display a message when no data is shown in the table. */
class CdkNoDataRow {
  constructor(templateRef) {
    this.templateRef = templateRef;
    this._contentClassName = 'cdk-no-data-row';
  }
  static {
    this.ɵfac = function CdkNoDataRow_Factory(t) {
      return new (t || CdkNoDataRow)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkNoDataRow,
      selectors: [["ng-template", "cdkNoDataRow", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkNoDataRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'ng-template[cdkNoDataRow]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.TemplateRef
  }], null);
})();

/**
 * List of all possible directions that can be used for sticky positioning.
 * @docs-private
 */
const STICKY_DIRECTIONS = ['top', 'bottom', 'left', 'right'];
/**
 * Applies and removes sticky positioning styles to the `CdkTable` rows and columns cells.
 * @docs-private
 */
class StickyStyler {
  /**
   * @param _isNativeHtmlTable Whether the sticky logic should be based on a table
   *     that uses the native `<table>` element.
   * @param _stickCellCss The CSS class that will be applied to every row/cell that has
   *     sticky positioning applied.
   * @param direction The directionality context of the table (ltr/rtl); affects column positioning
   *     by reversing left/right positions.
   * @param _isBrowser Whether the table is currently being rendered on the server or the client.
   * @param _needsPositionStickyOnElement Whether we need to specify position: sticky on cells
   *     using inline styles. If false, it is assumed that position: sticky is included in
   *     the component stylesheet for _stickCellCss.
   * @param _positionListener A listener that is notified of changes to sticky rows/columns
   *     and their dimensions.
   */
  constructor(_isNativeHtmlTable, _stickCellCss, direction, _coalescedStyleScheduler, _isBrowser = true, _needsPositionStickyOnElement = true, _positionListener) {
    this._isNativeHtmlTable = _isNativeHtmlTable;
    this._stickCellCss = _stickCellCss;
    this.direction = direction;
    this._coalescedStyleScheduler = _coalescedStyleScheduler;
    this._isBrowser = _isBrowser;
    this._needsPositionStickyOnElement = _needsPositionStickyOnElement;
    this._positionListener = _positionListener;
    this._elemSizeCache = new WeakMap();
    this._resizeObserver = globalThis?.ResizeObserver ? new globalThis.ResizeObserver(entries => this._updateCachedSizes(entries)) : null;
    this._updatedStickyColumnsParamsToReplay = [];
    this._stickyColumnsReplayTimeout = null;
    this._cachedCellWidths = [];
    this._borderCellCss = {
      'top': `${_stickCellCss}-border-elem-top`,
      'bottom': `${_stickCellCss}-border-elem-bottom`,
      'left': `${_stickCellCss}-border-elem-left`,
      'right': `${_stickCellCss}-border-elem-right`
    };
  }
  /**
   * Clears the sticky positioning styles from the row and its cells by resetting the `position`
   * style, setting the zIndex to 0, and unsetting each provided sticky direction.
   * @param rows The list of rows that should be cleared from sticking in the provided directions
   * @param stickyDirections The directions that should no longer be set as sticky on the rows.
   */
  clearStickyPositioning(rows, stickyDirections) {
    if (stickyDirections.includes('left') || stickyDirections.includes('right')) {
      this._removeFromStickyColumnReplayQueue(rows);
    }
    const elementsToClear = [];
    for (const row of rows) {
      // If the row isn't an element (e.g. if it's an `ng-container`),
      // it won't have inline styles or `children` so we skip it.
      if (row.nodeType !== row.ELEMENT_NODE) {
        continue;
      }
      elementsToClear.push(row);
      for (let i = 0; i < row.children.length; i++) {
        elementsToClear.push(row.children[i]);
      }
    }
    // Coalesce with sticky row/column updates (and potentially other changes like column resize).
    this._coalescedStyleScheduler.schedule(() => {
      for (const element of elementsToClear) {
        this._removeStickyStyle(element, stickyDirections);
      }
    });
  }
  /**
   * Applies sticky left and right positions to the cells of each row according to the sticky
   * states of the rendered column definitions.
   * @param rows The rows that should have its set of cells stuck according to the sticky states.
   * @param stickyStartStates A list of boolean states where each state represents whether the cell
   *     in this index position should be stuck to the start of the row.
   * @param stickyEndStates A list of boolean states where each state represents whether the cell
   *     in this index position should be stuck to the end of the row.
   * @param recalculateCellWidths Whether the sticky styler should recalculate the width of each
   *     column cell. If `false` cached widths will be used instead.
   * @param replay Whether to enqueue this call for replay after a ResizeObserver update.
   */
  updateStickyColumns(rows, stickyStartStates, stickyEndStates, recalculateCellWidths = true, replay = true) {
    if (replay) {
      this._updateStickyColumnReplayQueue({
        rows: [...rows],
        stickyStartStates: [...stickyStartStates],
        stickyEndStates: [...stickyEndStates]
      });
    }
    if (!rows.length || !this._isBrowser || !(stickyStartStates.some(state => state) || stickyEndStates.some(state => state))) {
      if (this._positionListener) {
        this._positionListener.stickyColumnsUpdated({
          sizes: []
        });
        this._positionListener.stickyEndColumnsUpdated({
          sizes: []
        });
      }
      return;
    }
    // Coalesce with sticky row updates (and potentially other changes like column resize).
    this._coalescedStyleScheduler.schedule(() => {
      const firstRow = rows[0];
      const numCells = firstRow.children.length;
      const cellWidths = this._getCellWidths(firstRow, recalculateCellWidths);
      const startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates);
      const endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates);
      const lastStickyStart = stickyStartStates.lastIndexOf(true);
      const firstStickyEnd = stickyEndStates.indexOf(true);
      const isRtl = this.direction === 'rtl';
      const start = isRtl ? 'right' : 'left';
      const end = isRtl ? 'left' : 'right';
      for (const row of rows) {
        for (let i = 0; i < numCells; i++) {
          const cell = row.children[i];
          if (stickyStartStates[i]) {
            this._addStickyStyle(cell, start, startPositions[i], i === lastStickyStart);
          }
          if (stickyEndStates[i]) {
            this._addStickyStyle(cell, end, endPositions[i], i === firstStickyEnd);
          }
        }
      }
      if (this._positionListener) {
        this._positionListener.stickyColumnsUpdated({
          sizes: lastStickyStart === -1 ? [] : cellWidths.slice(0, lastStickyStart + 1).map((width, index) => stickyStartStates[index] ? width : null)
        });
        this._positionListener.stickyEndColumnsUpdated({
          sizes: firstStickyEnd === -1 ? [] : cellWidths.slice(firstStickyEnd).map((width, index) => stickyEndStates[index + firstStickyEnd] ? width : null).reverse()
        });
      }
    });
  }
  /**
   * Applies sticky positioning to the row's cells if using the native table layout, and to the
   * row itself otherwise.
   * @param rowsToStick The list of rows that should be stuck according to their corresponding
   *     sticky state and to the provided top or bottom position.
   * @param stickyStates A list of boolean states where each state represents whether the row
   *     should be stuck in the particular top or bottom position.
   * @param position The position direction in which the row should be stuck if that row should be
   *     sticky.
   *
   */
  stickRows(rowsToStick, stickyStates, position) {
    // Since we can't measure the rows on the server, we can't stick the rows properly.
    if (!this._isBrowser) {
      return;
    }
    // Coalesce with other sticky row updates (top/bottom), sticky columns updates
    // (and potentially other changes like column resize).
    this._coalescedStyleScheduler.schedule(() => {
      // If positioning the rows to the bottom, reverse their order when evaluating the sticky
      // position such that the last row stuck will be "bottom: 0px" and so on. Note that the
      // sticky states need to be reversed as well.
      const rows = position === 'bottom' ? rowsToStick.slice().reverse() : rowsToStick;
      const states = position === 'bottom' ? stickyStates.slice().reverse() : stickyStates;
      // Measure row heights all at once before adding sticky styles to reduce layout thrashing.
      const stickyOffsets = [];
      const stickyCellHeights = [];
      const elementsToStick = [];
      for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
        if (!states[rowIndex]) {
          continue;
        }
        stickyOffsets[rowIndex] = stickyOffset;
        const row = rows[rowIndex];
        elementsToStick[rowIndex] = this._isNativeHtmlTable ? Array.from(row.children) : [row];
        const height = this._retrieveElementSize(row).height;
        stickyOffset += height;
        stickyCellHeights[rowIndex] = height;
      }
      const borderedRowIndex = states.lastIndexOf(true);
      for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
        if (!states[rowIndex]) {
          continue;
        }
        const offset = stickyOffsets[rowIndex];
        const isBorderedRowIndex = rowIndex === borderedRowIndex;
        for (const element of elementsToStick[rowIndex]) {
          this._addStickyStyle(element, position, offset, isBorderedRowIndex);
        }
      }
      if (position === 'top') {
        this._positionListener?.stickyHeaderRowsUpdated({
          sizes: stickyCellHeights,
          offsets: stickyOffsets,
          elements: elementsToStick
        });
      } else {
        this._positionListener?.stickyFooterRowsUpdated({
          sizes: stickyCellHeights,
          offsets: stickyOffsets,
          elements: elementsToStick
        });
      }
    });
  }
  /**
   * When using the native table in Safari, sticky footer cells do not stick. The only way to stick
   * footer rows is to apply sticky styling to the tfoot container. This should only be done if
   * all footer rows are sticky. If not all footer rows are sticky, remove sticky positioning from
   * the tfoot element.
   */
  updateStickyFooterContainer(tableElement, stickyStates) {
    if (!this._isNativeHtmlTable) {
      return;
    }
    // Coalesce with other sticky updates (and potentially other changes like column resize).
    this._coalescedStyleScheduler.schedule(() => {
      const tfoot = tableElement.querySelector('tfoot');
      if (tfoot) {
        if (stickyStates.some(state => !state)) {
          this._removeStickyStyle(tfoot, ['bottom']);
        } else {
          this._addStickyStyle(tfoot, 'bottom', 0, false);
        }
      }
    });
  }
  /**
   * Removes the sticky style on the element by removing the sticky cell CSS class, re-evaluating
   * the zIndex, removing each of the provided sticky directions, and removing the
   * sticky position if there are no more directions.
   */
  _removeStickyStyle(element, stickyDirections) {
    for (const dir of stickyDirections) {
      element.style[dir] = '';
      element.classList.remove(this._borderCellCss[dir]);
    }
    // If the element no longer has any more sticky directions, remove sticky positioning and
    // the sticky CSS class.
    // Short-circuit checking element.style[dir] for stickyDirections as they
    // were already removed above.
    const hasDirection = STICKY_DIRECTIONS.some(dir => stickyDirections.indexOf(dir) === -1 && element.style[dir]);
    if (hasDirection) {
      element.style.zIndex = this._getCalculatedZIndex(element);
    } else {
      // When not hasDirection, _getCalculatedZIndex will always return ''.
      element.style.zIndex = '';
      if (this._needsPositionStickyOnElement) {
        element.style.position = '';
      }
      element.classList.remove(this._stickCellCss);
    }
  }
  /**
   * Adds the sticky styling to the element by adding the sticky style class, changing position
   * to be sticky (and -webkit-sticky), setting the appropriate zIndex, and adding a sticky
   * direction and value.
   */
  _addStickyStyle(element, dir, dirValue, isBorderElement) {
    element.classList.add(this._stickCellCss);
    if (isBorderElement) {
      element.classList.add(this._borderCellCss[dir]);
    }
    element.style[dir] = `${dirValue}px`;
    element.style.zIndex = this._getCalculatedZIndex(element);
    if (this._needsPositionStickyOnElement) {
      element.style.cssText += 'position: -webkit-sticky; position: sticky; ';
    }
  }
  /**
   * Calculate what the z-index should be for the element, depending on what directions (top,
   * bottom, left, right) have been set. It should be true that elements with a top direction
   * should have the highest index since these are elements like a table header. If any of those
   * elements are also sticky in another direction, then they should appear above other elements
   * that are only sticky top (e.g. a sticky column on a sticky header). Bottom-sticky elements
   * (e.g. footer rows) should then be next in the ordering such that they are below the header
   * but above any non-sticky elements. Finally, left/right sticky elements (e.g. sticky columns)
   * should minimally increment so that they are above non-sticky elements but below top and bottom
   * elements.
   */
  _getCalculatedZIndex(element) {
    const zIndexIncrements = {
      top: 100,
      bottom: 10,
      left: 1,
      right: 1
    };
    let zIndex = 0;
    // Use `Iterable` instead of `Array` because TypeScript, as of 3.6.3,
    // loses the array generic type in the `for of`. But we *also* have to use `Array` because
    // typescript won't iterate over an `Iterable` unless you compile with `--downlevelIteration`
    for (const dir of STICKY_DIRECTIONS) {
      if (element.style[dir]) {
        zIndex += zIndexIncrements[dir];
      }
    }
    return zIndex ? `${zIndex}` : '';
  }
  /** Gets the widths for each cell in the provided row. */
  _getCellWidths(row, recalculateCellWidths = true) {
    if (!recalculateCellWidths && this._cachedCellWidths.length) {
      return this._cachedCellWidths;
    }
    const cellWidths = [];
    const firstRowCells = row.children;
    for (let i = 0; i < firstRowCells.length; i++) {
      const cell = firstRowCells[i];
      cellWidths.push(this._retrieveElementSize(cell).width);
    }
    this._cachedCellWidths = cellWidths;
    return cellWidths;
  }
  /**
   * Determines the left and right positions of each sticky column cell, which will be the
   * accumulation of all sticky column cell widths to the left and right, respectively.
   * Non-sticky cells do not need to have a value set since their positions will not be applied.
   */
  _getStickyStartColumnPositions(widths, stickyStates) {
    const positions = [];
    let nextPosition = 0;
    for (let i = 0; i < widths.length; i++) {
      if (stickyStates[i]) {
        positions[i] = nextPosition;
        nextPosition += widths[i];
      }
    }
    return positions;
  }
  /**
   * Determines the left and right positions of each sticky column cell, which will be the
   * accumulation of all sticky column cell widths to the left and right, respectively.
   * Non-sticky cells do not need to have a value set since their positions will not be applied.
   */
  _getStickyEndColumnPositions(widths, stickyStates) {
    const positions = [];
    let nextPosition = 0;
    for (let i = widths.length; i > 0; i--) {
      if (stickyStates[i]) {
        positions[i] = nextPosition;
        nextPosition += widths[i];
      }
    }
    return positions;
  }
  /**
   * Retreives the most recently observed size of the specified element from the cache, or
   * meaures it directly if not yet cached.
   */
  _retrieveElementSize(element) {
    const cachedSize = this._elemSizeCache.get(element);
    if (cachedSize) {
      return cachedSize;
    }
    const clientRect = element.getBoundingClientRect();
    const size = {
      width: clientRect.width,
      height: clientRect.height
    };
    if (!this._resizeObserver) {
      return size;
    }
    this._elemSizeCache.set(element, size);
    this._resizeObserver.observe(element, {
      box: 'border-box'
    });
    return size;
  }
  /**
   * Conditionally enqueue the requested sticky update and clear previously queued updates
   * for the same rows.
   */
  _updateStickyColumnReplayQueue(params) {
    this._removeFromStickyColumnReplayQueue(params.rows);
    // No need to replay if a flush is pending.
    if (this._stickyColumnsReplayTimeout) {
      return;
    }
    this._updatedStickyColumnsParamsToReplay.push(params);
  }
  /** Remove updates for the specified rows from the queue. */
  _removeFromStickyColumnReplayQueue(rows) {
    const rowsSet = new Set(rows);
    for (const update of this._updatedStickyColumnsParamsToReplay) {
      update.rows = update.rows.filter(row => !rowsSet.has(row));
    }
    this._updatedStickyColumnsParamsToReplay = this._updatedStickyColumnsParamsToReplay.filter(update => !!update.rows.length);
  }
  /** Update _elemSizeCache with the observed sizes. */
  _updateCachedSizes(entries) {
    let needsColumnUpdate = false;
    for (const entry of entries) {
      const newEntry = entry.borderBoxSize?.length ? {
        width: entry.borderBoxSize[0].inlineSize,
        height: entry.borderBoxSize[0].blockSize
      } : {
        width: entry.contentRect.width,
        height: entry.contentRect.height
      };
      if (newEntry.width !== this._elemSizeCache.get(entry.target)?.width && isCell(entry.target)) {
        needsColumnUpdate = true;
      }
      this._elemSizeCache.set(entry.target, newEntry);
    }
    if (needsColumnUpdate && this._updatedStickyColumnsParamsToReplay.length) {
      if (this._stickyColumnsReplayTimeout) {
        clearTimeout(this._stickyColumnsReplayTimeout);
      }
      this._stickyColumnsReplayTimeout = setTimeout(() => {
        for (const update of this._updatedStickyColumnsParamsToReplay) {
          this.updateStickyColumns(update.rows, update.stickyStartStates, update.stickyEndStates, true, false);
        }
        this._updatedStickyColumnsParamsToReplay = [];
        this._stickyColumnsReplayTimeout = null;
      }, 0);
    }
  }
}
function isCell(element) {
  return ['cdk-cell', 'cdk-header-cell', 'cdk-footer-cell'].some(klass => element.classList.contains(klass));
}

/**
 * Returns an error to be thrown when attempting to find an nonexistent column.
 * @param id Id whose lookup failed.
 * @docs-private
 */
function getTableUnknownColumnError(id) {
  return Error(`Could not find column with id "${id}".`);
}
/**
 * Returns an error to be thrown when two column definitions have the same name.
 * @docs-private
 */
function getTableDuplicateColumnNameError(name) {
  return Error(`Duplicate column definition name provided: "${name}".`);
}
/**
 * Returns an error to be thrown when there are multiple rows that are missing a when function.
 * @docs-private
 */
function getTableMultipleDefaultRowDefsError() {
  return Error(`There can only be one default row without a when predicate function.`);
}
/**
 * Returns an error to be thrown when there are no matching row defs for a particular set of data.
 * @docs-private
 */
function getTableMissingMatchingRowDefError(data) {
  return Error(`Could not find a matching row definition for the` + `provided row data: ${JSON.stringify(data)}`);
}
/**
 * Returns an error to be thrown when there is no row definitions present in the content.
 * @docs-private
 */
function getTableMissingRowDefsError() {
  return Error('Missing definitions for header, footer, and row; ' + 'cannot determine which columns should be rendered.');
}
/**
 * Returns an error to be thrown when the data source does not match the compatible types.
 * @docs-private
 */
function getTableUnknownDataSourceError() {
  return Error(`Provided data source did not match an array, Observable, or DataSource`);
}
/**
 * Returns an error to be thrown when the text column cannot find a parent table to inject.
 * @docs-private
 */
function getTableTextColumnMissingParentTableError() {
  return Error(`Text column could not find a parent table for registration.`);
}
/**
 * Returns an error to be thrown when a table text column doesn't have a name.
 * @docs-private
 */
function getTableTextColumnMissingNameError() {
  return Error(`Table text column must have a name.`);
}

/** The injection token used to specify the StickyPositioningListener. */
const STICKY_POSITIONING_LISTENER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('CDK_SPL');

/**
 * Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
 * tables that animate rows.
 */
class CdkRecycleRows {
  static {
    this.ɵfac = function CdkRecycleRows_Factory(t) {
      return new (t || CdkRecycleRows)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: CdkRecycleRows,
      selectors: [["cdk-table", "recycleRows", ""], ["table", "cdk-table", "", "recycleRows", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._RecycleViewRepeaterStrategy
      }])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkRecycleRows, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'cdk-table[recycleRows], table[cdk-table][recycleRows]',
      providers: [{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._RecycleViewRepeaterStrategy
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Provides a handle for the table to grab the view container's ng-container to insert data rows.
 * @docs-private
 */
class DataRowOutlet {
  constructor(viewContainer, elementRef) {
    this.viewContainer = viewContainer;
    this.elementRef = elementRef;
    const table = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_TABLE);
    table._rowOutlet = this;
    table._outletAssigned();
  }
  static {
    this.ɵfac = function DataRowOutlet_Factory(t) {
      return new (t || DataRowOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: DataRowOutlet,
      selectors: [["", "rowOutlet", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DataRowOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[rowOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/**
 * Provides a handle for the table to grab the view container's ng-container to insert the header.
 * @docs-private
 */
class HeaderRowOutlet {
  constructor(viewContainer, elementRef) {
    this.viewContainer = viewContainer;
    this.elementRef = elementRef;
    const table = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_TABLE);
    table._headerRowOutlet = this;
    table._outletAssigned();
  }
  static {
    this.ɵfac = function HeaderRowOutlet_Factory(t) {
      return new (t || HeaderRowOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: HeaderRowOutlet,
      selectors: [["", "headerRowOutlet", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HeaderRowOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[headerRowOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/**
 * Provides a handle for the table to grab the view container's ng-container to insert the footer.
 * @docs-private
 */
class FooterRowOutlet {
  constructor(viewContainer, elementRef) {
    this.viewContainer = viewContainer;
    this.elementRef = elementRef;
    const table = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_TABLE);
    table._footerRowOutlet = this;
    table._outletAssigned();
  }
  static {
    this.ɵfac = function FooterRowOutlet_Factory(t) {
      return new (t || FooterRowOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: FooterRowOutlet,
      selectors: [["", "footerRowOutlet", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FooterRowOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[footerRowOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/**
 * Provides a handle for the table to grab the view
 * container's ng-container to insert the no data row.
 * @docs-private
 */
class NoDataRowOutlet {
  constructor(viewContainer, elementRef) {
    this.viewContainer = viewContainer;
    this.elementRef = elementRef;
    const table = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(CDK_TABLE);
    table._noDataRowOutlet = this;
    table._outletAssigned();
  }
  static {
    this.ɵfac = function NoDataRowOutlet_Factory(t) {
      return new (t || NoDataRowOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: NoDataRowOutlet,
      selectors: [["", "noDataRowOutlet", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NoDataRowOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[noDataRowOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }], null);
})();
/**
 * The table template that can be used by the mat-table. Should not be used outside of the
 * material library.
 * @docs-private
 */
const CDK_TABLE_TEMPLATE =
// Note that according to MDN, the `caption` element has to be projected as the **first**
// element in the table. See https://developer.mozilla.org/en-US/docs/Web/HTML/Element/caption
`
  <ng-content select="caption"/>
  <ng-content select="colgroup, col"/>

  <!--
    Unprojected content throws a hydration error so we need this to capture it.
    It gets removed on the client so it doesn't affect the layout.
  -->
  @if (_isServer) {
    <ng-content/>
  }

  @if (_isNativeHtmlTable) {
    <thead role="rowgroup">
      <ng-container headerRowOutlet/>
    </thead>
    <tbody role="rowgroup">
      <ng-container rowOutlet/>
      <ng-container noDataRowOutlet/>
    </tbody>
    <tfoot role="rowgroup">
      <ng-container footerRowOutlet/>
    </tfoot>
  } @else {
    <ng-container headerRowOutlet/>
    <ng-container rowOutlet/>
    <ng-container noDataRowOutlet/>
    <ng-container footerRowOutlet/>
  }
`;
/**
 * Class used to conveniently type the embedded view ref for rows with a context.
 * @docs-private
 */
class RowViewRef extends _angular_core__WEBPACK_IMPORTED_MODULE_1__.EmbeddedViewRef {}
/**
 * A data table that can render a header row, data rows, and a footer row.
 * Uses the dataSource input to determine the data to be rendered. The data can be provided either
 * as a data array, an Observable stream that emits the data array to render, or a DataSource with a
 * connect function that will return an Observable stream that emits the data array to render.
 */
class CdkTable {
  /** Aria role to apply to the table's cells based on the table's own role. */
  _getCellRole() {
    // Perform this lazily in case the table's role was updated by a directive after construction.
    if (this._cellRoleInternal === undefined) {
      // Note that we set `role="cell"` even on native `td` elements,
      // because some browsers seem to require it. See #29784.
      const tableRole = this._elementRef.nativeElement.getAttribute('role');
      return tableRole === 'grid' || tableRole === 'treegrid' ? 'gridcell' : 'cell';
    }
    return this._cellRoleInternal;
  }
  /**
   * Tracking function that will be used to check the differences in data changes. Used similarly
   * to `ngFor` `trackBy` function. Optimize row operations by identifying a row based on its data
   * relative to the function to know if a row should be added/removed/moved.
   * Accepts a function that takes two parameters, `index` and `item`.
   */
  get trackBy() {
    return this._trackByFn;
  }
  set trackBy(fn) {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && fn != null && typeof fn !== 'function') {
      console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}.`);
    }
    this._trackByFn = fn;
  }
  /**
   * The table's source of data, which can be provided in three ways (in order of complexity):
   *   - Simple data array (each object represents one table row)
   *   - Stream that emits a data array each time the array changes
   *   - `DataSource` object that implements the connect/disconnect interface.
   *
   * If a data array is provided, the table must be notified when the array's objects are
   * added, removed, or moved. This can be done by calling the `renderRows()` function which will
   * render the diff since the last table render. If the data array reference is changed, the table
   * will automatically trigger an update to the rows.
   *
   * When providing an Observable stream, the table will trigger an update automatically when the
   * stream emits a new array of data.
   *
   * Finally, when providing a `DataSource` object, the table will use the Observable stream
   * provided by the connect function and trigger updates when that stream emits new data array
   * values. During the table's ngOnDestroy or when the data source is removed from the table, the
   * table will call the DataSource's `disconnect` function (may be useful for cleaning up any
   * subscriptions registered during the connect process).
   */
  get dataSource() {
    return this._dataSource;
  }
  set dataSource(dataSource) {
    if (this._dataSource !== dataSource) {
      this._switchDataSource(dataSource);
    }
  }
  /**
   * Whether to allow multiple rows per data object by evaluating which rows evaluate their 'when'
   * predicate to true. If `multiTemplateDataRows` is false, which is the default value, then each
   * dataobject will render the first row that evaluates its when predicate to true, in the order
   * defined in the table, or otherwise the default row which does not have a when predicate.
   */
  get multiTemplateDataRows() {
    return this._multiTemplateDataRows;
  }
  set multiTemplateDataRows(value) {
    this._multiTemplateDataRows = value;
    // In Ivy if this value is set via a static attribute (e.g. <table multiTemplateDataRows>),
    // this setter will be invoked before the row outlet has been defined hence the null check.
    if (this._rowOutlet && this._rowOutlet.viewContainer.length) {
      this._forceRenderDataRows();
      this.updateStickyColumnStyles();
    }
  }
  /**
   * Whether to use a fixed table layout. Enabling this option will enforce consistent column widths
   * and optimize rendering sticky styles for native tables. No-op for flex tables.
   */
  get fixedLayout() {
    return this._fixedLayout;
  }
  set fixedLayout(value) {
    this._fixedLayout = value;
    // Toggling `fixedLayout` may change column widths. Sticky column styles should be recalculated.
    this._forceRecalculateCellWidths = true;
    this._stickyColumnStylesNeedReset = true;
  }
  constructor(_differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform, _viewRepeater, _coalescedStyleScheduler, _viewportRuler,
  /**
   * @deprecated `_stickyPositioningListener` parameter to become required.
   * @breaking-change 13.0.0
   */
  _stickyPositioningListener,
  /**
   * @deprecated `_unusedNgZone` parameter to be removed.
   * @breaking-change 19.0.0
   */
  _unusedNgZone) {
    this._differs = _differs;
    this._changeDetectorRef = _changeDetectorRef;
    this._elementRef = _elementRef;
    this._dir = _dir;
    this._platform = _platform;
    this._viewRepeater = _viewRepeater;
    this._coalescedStyleScheduler = _coalescedStyleScheduler;
    this._viewportRuler = _viewportRuler;
    this._stickyPositioningListener = _stickyPositioningListener;
    /** Subject that emits when the component has been destroyed. */
    this._onDestroy = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Map of all the user's defined columns (header, data, and footer cell template) identified by
     * name. Collection populated by the column definitions gathered by `ContentChildren` as well as
     * any custom column definitions added to `_customColumnDefs`.
     */
    this._columnDefsByName = new Map();
    /**
     * Column definitions that were defined outside of the direct content children of the table.
     * These will be defined when, e.g., creating a wrapper around the cdkTable that has
     * column definitions as *its* content child.
     */
    this._customColumnDefs = new Set();
    /**
     * Data row definitions that were defined outside of the direct content children of the table.
     * These will be defined when, e.g., creating a wrapper around the cdkTable that has
     * built-in data rows as *its* content child.
     */
    this._customRowDefs = new Set();
    /**
     * Header row definitions that were defined outside of the direct content children of the table.
     * These will be defined when, e.g., creating a wrapper around the cdkTable that has
     * built-in header rows as *its* content child.
     */
    this._customHeaderRowDefs = new Set();
    /**
     * Footer row definitions that were defined outside of the direct content children of the table.
     * These will be defined when, e.g., creating a wrapper around the cdkTable that has a
     * built-in footer row as *its* content child.
     */
    this._customFooterRowDefs = new Set();
    /**
     * Whether the header row definition has been changed. Triggers an update to the header row after
     * content is checked. Initialized as true so that the table renders the initial set of rows.
     */
    this._headerRowDefChanged = true;
    /**
     * Whether the footer row definition has been changed. Triggers an update to the footer row after
     * content is checked. Initialized as true so that the table renders the initial set of rows.
     */
    this._footerRowDefChanged = true;
    /**
     * Whether the sticky column styles need to be updated. Set to `true` when the visible columns
     * change.
     */
    this._stickyColumnStylesNeedReset = true;
    /**
     * Whether the sticky styler should recalculate cell widths when applying sticky styles. If
     * `false`, cached values will be used instead. This is only applicable to tables with
     * {@link fixedLayout} enabled. For other tables, cell widths will always be recalculated.
     */
    this._forceRecalculateCellWidths = true;
    /**
     * Cache of the latest rendered `RenderRow` objects as a map for easy retrieval when constructing
     * a new list of `RenderRow` objects for rendering rows. Since the new list is constructed with
     * the cached `RenderRow` objects when possible, the row identity is preserved when the data
     * and row template matches, which allows the `IterableDiffer` to check rows by reference
     * and understand which rows are added/moved/removed.
     *
     * Implemented as a map of maps where the first key is the `data: T` object and the second is the
     * `CdkRowDef<T>` object. With the two keys, the cache points to a `RenderRow<T>` object that
     * contains an array of created pairs. The array is necessary to handle cases where the data
     * array contains multiple duplicate data objects and each instantiated `RenderRow` must be
     * stored.
     */
    this._cachedRenderRowsMap = new Map();
    /**
     * CSS class added to any row or cell that has sticky positioning applied. May be overridden by
     * table subclasses.
     */
    this.stickyCssClass = 'cdk-table-sticky';
    /**
     * Whether to manually add position: sticky to all sticky cell elements. Not needed if
     * the position is set in a selector associated with the value of stickyCssClass. May be
     * overridden by table subclasses
     */
    this.needsPositionStickyOnElement = true;
    /** Whether the no data row is currently showing anything. */
    this._isShowingNoDataRow = false;
    /** Whether the table has rendered out all the outlets for the first time. */
    this._hasAllOutlets = false;
    /** Whether the table is done initializing. */
    this._hasInitialized = false;
    this._cellRoleInternal = undefined;
    this._multiTemplateDataRows = false;
    this._fixedLayout = false;
    /**
     * Emits when the table completes rendering a set of data rows based on the latest data from the
     * data source, even if the set of rows is empty.
     */
    this.contentChanged = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    // TODO(andrewseguin): Remove max value as the end index
    //   and instead calculate the view on init and scroll.
    /**
     * Stream containing the latest information on what rows are being displayed on screen.
     * Can be used by the data source to as a heuristic of what data should be provided.
     *
     * @docs-private
     */
    this.viewChange = new rxjs__WEBPACK_IMPORTED_MODULE_3__.BehaviorSubject({
      start: 0,
      end: Number.MAX_VALUE
    });
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.Injector);
    if (!role) {
      _elementRef.nativeElement.setAttribute('role', 'table');
    }
    this._document = _document;
    this._isServer = !_platform.isBrowser;
    this._isNativeHtmlTable = _elementRef.nativeElement.nodeName === 'TABLE';
  }
  ngOnInit() {
    this._setupStickyStyler();
    // Set up the trackBy function so that it uses the `RenderRow` as its identity by default. If
    // the user has provided a custom trackBy, return the result of that function as evaluated
    // with the values of the `RenderRow`'s data and index.
    this._dataDiffer = this._differs.find([]).create((_i, dataRow) => {
      return this.trackBy ? this.trackBy(dataRow.dataIndex, dataRow.data) : dataRow;
    });
    this._viewportRuler.change().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.takeUntil)(this._onDestroy)).subscribe(() => {
      this._forceRecalculateCellWidths = true;
    });
  }
  ngAfterContentInit() {
    this._hasInitialized = true;
  }
  ngAfterContentChecked() {
    // Only start re-rendering in `ngAfterContentChecked` after the first render.
    if (this._canRender()) {
      this._render();
    }
  }
  ngOnDestroy() {
    [this._rowOutlet?.viewContainer, this._headerRowOutlet?.viewContainer, this._footerRowOutlet?.viewContainer, this._cachedRenderRowsMap, this._customColumnDefs, this._customRowDefs, this._customHeaderRowDefs, this._customFooterRowDefs, this._columnDefsByName].forEach(def => {
      def?.clear();
    });
    this._headerRowDefs = [];
    this._footerRowDefs = [];
    this._defaultRowDef = null;
    this._onDestroy.next();
    this._onDestroy.complete();
    if ((0,_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__.isDataSource)(this.dataSource)) {
      this.dataSource.disconnect(this);
    }
  }
  /**
   * Renders rows based on the table's latest set of data, which was either provided directly as an
   * input or retrieved through an Observable stream (directly or from a DataSource).
   * Checks for differences in the data since the last diff to perform only the necessary
   * changes (add/remove/move rows).
   *
   * If the table's data source is a DataSource or Observable, this will be invoked automatically
   * each time the provided Observable stream emits a new data array. Otherwise if your data is
   * an array, this function will need to be called to render any changes.
   */
  renderRows() {
    this._renderRows = this._getAllRenderRows();
    const changes = this._dataDiffer.diff(this._renderRows);
    if (!changes) {
      this._updateNoDataRow();
      this.contentChanged.next();
      return;
    }
    const viewContainer = this._rowOutlet.viewContainer;
    this._viewRepeater.applyChanges(changes, viewContainer, (record, _adjustedPreviousIndex, currentIndex) => this._getEmbeddedViewArgs(record.item, currentIndex), record => record.item.data, change => {
      if (change.operation === _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._ViewRepeaterOperation.INSERTED && change.context) {
        this._renderCellTemplateForItem(change.record.item.rowDef, change.context);
      }
    });
    // Update the meta context of a row's context data (index, count, first, last, ...)
    this._updateRowIndexContext();
    // Update rows that did not get added/removed/moved but may have had their identity changed,
    // e.g. if trackBy matched data on some property but the actual data reference changed.
    changes.forEachIdentityChange(record => {
      const rowView = viewContainer.get(record.currentIndex);
      rowView.context.$implicit = record.item.data;
    });
    this._updateNoDataRow();
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.afterNextRender)(() => {
      this.updateStickyColumnStyles();
    }, {
      injector: this._injector
    });
    this.contentChanged.next();
  }
  /** Adds a column definition that was not included as part of the content children. */
  addColumnDef(columnDef) {
    this._customColumnDefs.add(columnDef);
  }
  /** Removes a column definition that was not included as part of the content children. */
  removeColumnDef(columnDef) {
    this._customColumnDefs.delete(columnDef);
  }
  /** Adds a row definition that was not included as part of the content children. */
  addRowDef(rowDef) {
    this._customRowDefs.add(rowDef);
  }
  /** Removes a row definition that was not included as part of the content children. */
  removeRowDef(rowDef) {
    this._customRowDefs.delete(rowDef);
  }
  /** Adds a header row definition that was not included as part of the content children. */
  addHeaderRowDef(headerRowDef) {
    this._customHeaderRowDefs.add(headerRowDef);
    this._headerRowDefChanged = true;
  }
  /** Removes a header row definition that was not included as part of the content children. */
  removeHeaderRowDef(headerRowDef) {
    this._customHeaderRowDefs.delete(headerRowDef);
    this._headerRowDefChanged = true;
  }
  /** Adds a footer row definition that was not included as part of the content children. */
  addFooterRowDef(footerRowDef) {
    this._customFooterRowDefs.add(footerRowDef);
    this._footerRowDefChanged = true;
  }
  /** Removes a footer row definition that was not included as part of the content children. */
  removeFooterRowDef(footerRowDef) {
    this._customFooterRowDefs.delete(footerRowDef);
    this._footerRowDefChanged = true;
  }
  /** Sets a no data row definition that was not included as a part of the content children. */
  setNoDataRow(noDataRow) {
    this._customNoDataRow = noDataRow;
  }
  /**
   * Updates the header sticky styles. First resets all applied styles with respect to the cells
   * sticking to the top. Then, evaluating which cells need to be stuck to the top. This is
   * automatically called when the header row changes its displayed set of columns, or if its
   * sticky input changes. May be called manually for cases where the cell content changes outside
   * of these events.
   */
  updateStickyHeaderRowStyles() {
    const headerRows = this._getRenderedRows(this._headerRowOutlet);
    // Hide the thead element if there are no header rows. This is necessary to satisfy
    // overzealous a11y checkers that fail because the `rowgroup` element does not contain
    // required child `row`.
    if (this._isNativeHtmlTable) {
      const thead = closestTableSection(this._headerRowOutlet, 'thead');
      if (thead) {
        thead.style.display = headerRows.length ? '' : 'none';
      }
    }
    const stickyStates = this._headerRowDefs.map(def => def.sticky);
    this._stickyStyler.clearStickyPositioning(headerRows, ['top']);
    this._stickyStyler.stickRows(headerRows, stickyStates, 'top');
    // Reset the dirty state of the sticky input change since it has been used.
    this._headerRowDefs.forEach(def => def.resetStickyChanged());
  }
  /**
   * Updates the footer sticky styles. First resets all applied styles with respect to the cells
   * sticking to the bottom. Then, evaluating which cells need to be stuck to the bottom. This is
   * automatically called when the footer row changes its displayed set of columns, or if its
   * sticky input changes. May be called manually for cases where the cell content changes outside
   * of these events.
   */
  updateStickyFooterRowStyles() {
    const footerRows = this._getRenderedRows(this._footerRowOutlet);
    // Hide the tfoot element if there are no footer rows. This is necessary to satisfy
    // overzealous a11y checkers that fail because the `rowgroup` element does not contain
    // required child `row`.
    if (this._isNativeHtmlTable) {
      const tfoot = closestTableSection(this._footerRowOutlet, 'tfoot');
      if (tfoot) {
        tfoot.style.display = footerRows.length ? '' : 'none';
      }
    }
    const stickyStates = this._footerRowDefs.map(def => def.sticky);
    this._stickyStyler.clearStickyPositioning(footerRows, ['bottom']);
    this._stickyStyler.stickRows(footerRows, stickyStates, 'bottom');
    this._stickyStyler.updateStickyFooterContainer(this._elementRef.nativeElement, stickyStates);
    // Reset the dirty state of the sticky input change since it has been used.
    this._footerRowDefs.forEach(def => def.resetStickyChanged());
  }
  /**
   * Updates the column sticky styles. First resets all applied styles with respect to the cells
   * sticking to the left and right. Then sticky styles are added for the left and right according
   * to the column definitions for each cell in each row. This is automatically called when
   * the data source provides a new set of data or when a column definition changes its sticky
   * input. May be called manually for cases where the cell content changes outside of these events.
   */
  updateStickyColumnStyles() {
    const headerRows = this._getRenderedRows(this._headerRowOutlet);
    const dataRows = this._getRenderedRows(this._rowOutlet);
    const footerRows = this._getRenderedRows(this._footerRowOutlet);
    // For tables not using a fixed layout, the column widths may change when new rows are rendered.
    // In a table using a fixed layout, row content won't affect column width, so sticky styles
    // don't need to be cleared unless either the sticky column config changes or one of the row
    // defs change.
    if (this._isNativeHtmlTable && !this._fixedLayout || this._stickyColumnStylesNeedReset) {
      // Clear the left and right positioning from all columns in the table across all rows since
      // sticky columns span across all table sections (header, data, footer)
      this._stickyStyler.clearStickyPositioning([...headerRows, ...dataRows, ...footerRows], ['left', 'right']);
      this._stickyColumnStylesNeedReset = false;
    }
    // Update the sticky styles for each header row depending on the def's sticky state
    headerRows.forEach((headerRow, i) => {
      this._addStickyColumnStyles([headerRow], this._headerRowDefs[i]);
    });
    // Update the sticky styles for each data row depending on its def's sticky state
    this._rowDefs.forEach(rowDef => {
      // Collect all the rows rendered with this row definition.
      const rows = [];
      for (let i = 0; i < dataRows.length; i++) {
        if (this._renderRows[i].rowDef === rowDef) {
          rows.push(dataRows[i]);
        }
      }
      this._addStickyColumnStyles(rows, rowDef);
    });
    // Update the sticky styles for each footer row depending on the def's sticky state
    footerRows.forEach((footerRow, i) => {
      this._addStickyColumnStyles([footerRow], this._footerRowDefs[i]);
    });
    // Reset the dirty state of the sticky input change since it has been used.
    Array.from(this._columnDefsByName.values()).forEach(def => def.resetStickyChanged());
  }
  /** Invoked whenever an outlet is created and has been assigned to the table. */
  _outletAssigned() {
    // Trigger the first render once all outlets have been assigned. We do it this way, as
    // opposed to waiting for the next `ngAfterContentChecked`, because we don't know when
    // the next change detection will happen.
    // Also we can't use queries to resolve the outlets, because they're wrapped in a
    // conditional, so we have to rely on them being assigned via DI.
    if (!this._hasAllOutlets && this._rowOutlet && this._headerRowOutlet && this._footerRowOutlet && this._noDataRowOutlet) {
      this._hasAllOutlets = true;
      // In some setups this may fire before `ngAfterContentInit`
      // so we need a check here. See #28538.
      if (this._canRender()) {
        this._render();
      }
    }
  }
  /** Whether the table has all the information to start rendering. */
  _canRender() {
    return this._hasAllOutlets && this._hasInitialized;
  }
  /** Renders the table if its state has changed. */
  _render() {
    // Cache the row and column definitions gathered by ContentChildren and programmatic injection.
    this._cacheRowDefs();
    this._cacheColumnDefs();
    // Make sure that the user has at least added header, footer, or data row def.
    if (!this._headerRowDefs.length && !this._footerRowDefs.length && !this._rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableMissingRowDefsError();
    }
    // Render updates if the list of columns have been changed for the header, row, or footer defs.
    const columnsChanged = this._renderUpdatedColumns();
    const rowDefsChanged = columnsChanged || this._headerRowDefChanged || this._footerRowDefChanged;
    // Ensure sticky column styles are reset if set to `true` elsewhere.
    this._stickyColumnStylesNeedReset = this._stickyColumnStylesNeedReset || rowDefsChanged;
    this._forceRecalculateCellWidths = rowDefsChanged;
    // If the header row definition has been changed, trigger a render to the header row.
    if (this._headerRowDefChanged) {
      this._forceRenderHeaderRows();
      this._headerRowDefChanged = false;
    }
    // If the footer row definition has been changed, trigger a render to the footer row.
    if (this._footerRowDefChanged) {
      this._forceRenderFooterRows();
      this._footerRowDefChanged = false;
    }
    // If there is a data source and row definitions, connect to the data source unless a
    // connection has already been made.
    if (this.dataSource && this._rowDefs.length > 0 && !this._renderChangeSubscription) {
      this._observeRenderChanges();
    } else if (this._stickyColumnStylesNeedReset) {
      // In the above case, _observeRenderChanges will result in updateStickyColumnStyles being
      // called when it row data arrives. Otherwise, we need to call it proactively.
      this.updateStickyColumnStyles();
    }
    this._checkStickyStates();
  }
  /**
   * Get the list of RenderRow objects to render according to the current list of data and defined
   * row definitions. If the previous list already contained a particular pair, it should be reused
   * so that the differ equates their references.
   */
  _getAllRenderRows() {
    const renderRows = [];
    // Store the cache and create a new one. Any re-used RenderRow objects will be moved into the
    // new cache while unused ones can be picked up by garbage collection.
    const prevCachedRenderRows = this._cachedRenderRowsMap;
    this._cachedRenderRowsMap = new Map();
    // For each data object, get the list of rows that should be rendered, represented by the
    // respective `RenderRow` object which is the pair of `data` and `CdkRowDef`.
    for (let i = 0; i < this._data.length; i++) {
      let data = this._data[i];
      const renderRowsForData = this._getRenderRowsForData(data, i, prevCachedRenderRows.get(data));
      if (!this._cachedRenderRowsMap.has(data)) {
        this._cachedRenderRowsMap.set(data, new WeakMap());
      }
      for (let j = 0; j < renderRowsForData.length; j++) {
        let renderRow = renderRowsForData[j];
        const cache = this._cachedRenderRowsMap.get(renderRow.data);
        if (cache.has(renderRow.rowDef)) {
          cache.get(renderRow.rowDef).push(renderRow);
        } else {
          cache.set(renderRow.rowDef, [renderRow]);
        }
        renderRows.push(renderRow);
      }
    }
    return renderRows;
  }
  /**
   * Gets a list of `RenderRow<T>` for the provided data object and any `CdkRowDef` objects that
   * should be rendered for this data. Reuses the cached RenderRow objects if they match the same
   * `(T, CdkRowDef)` pair.
   */
  _getRenderRowsForData(data, dataIndex, cache) {
    const rowDefs = this._getRowDefs(data, dataIndex);
    return rowDefs.map(rowDef => {
      const cachedRenderRows = cache && cache.has(rowDef) ? cache.get(rowDef) : [];
      if (cachedRenderRows.length) {
        const dataRow = cachedRenderRows.shift();
        dataRow.dataIndex = dataIndex;
        return dataRow;
      } else {
        return {
          data,
          rowDef,
          dataIndex
        };
      }
    });
  }
  /** Update the map containing the content's column definitions. */
  _cacheColumnDefs() {
    this._columnDefsByName.clear();
    const columnDefs = mergeArrayAndSet(this._getOwnDefs(this._contentColumnDefs), this._customColumnDefs);
    columnDefs.forEach(columnDef => {
      if (this._columnDefsByName.has(columnDef.name) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw getTableDuplicateColumnNameError(columnDef.name);
      }
      this._columnDefsByName.set(columnDef.name, columnDef);
    });
  }
  /** Update the list of all available row definitions that can be used. */
  _cacheRowDefs() {
    this._headerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentHeaderRowDefs), this._customHeaderRowDefs);
    this._footerRowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentFooterRowDefs), this._customFooterRowDefs);
    this._rowDefs = mergeArrayAndSet(this._getOwnDefs(this._contentRowDefs), this._customRowDefs);
    // After all row definitions are determined, find the row definition to be considered default.
    const defaultRowDefs = this._rowDefs.filter(def => !def.when);
    if (!this.multiTemplateDataRows && defaultRowDefs.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableMultipleDefaultRowDefsError();
    }
    this._defaultRowDef = defaultRowDefs[0];
  }
  /**
   * Check if the header, data, or footer rows have changed what columns they want to display or
   * whether the sticky states have changed for the header or footer. If there is a diff, then
   * re-render that section.
   */
  _renderUpdatedColumns() {
    const columnsDiffReducer = (acc, def) => {
      // The differ should be run for every column, even if `acc` is already
      // true (see #29922)
      const diff = !!def.getColumnsDiff();
      return acc || diff;
    };
    // Force re-render data rows if the list of column definitions have changed.
    const dataColumnsChanged = this._rowDefs.reduce(columnsDiffReducer, false);
    if (dataColumnsChanged) {
      this._forceRenderDataRows();
    }
    // Force re-render header/footer rows if the list of column definitions have changed.
    const headerColumnsChanged = this._headerRowDefs.reduce(columnsDiffReducer, false);
    if (headerColumnsChanged) {
      this._forceRenderHeaderRows();
    }
    const footerColumnsChanged = this._footerRowDefs.reduce(columnsDiffReducer, false);
    if (footerColumnsChanged) {
      this._forceRenderFooterRows();
    }
    return dataColumnsChanged || headerColumnsChanged || footerColumnsChanged;
  }
  /**
   * Switch to the provided data source by resetting the data and unsubscribing from the current
   * render change subscription if one exists. If the data source is null, interpret this by
   * clearing the row outlet. Otherwise start listening for new data.
   */
  _switchDataSource(dataSource) {
    this._data = [];
    if ((0,_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__.isDataSource)(this.dataSource)) {
      this.dataSource.disconnect(this);
    }
    // Stop listening for data from the previous data source.
    if (this._renderChangeSubscription) {
      this._renderChangeSubscription.unsubscribe();
      this._renderChangeSubscription = null;
    }
    if (!dataSource) {
      if (this._dataDiffer) {
        this._dataDiffer.diff([]);
      }
      if (this._rowOutlet) {
        this._rowOutlet.viewContainer.clear();
      }
    }
    this._dataSource = dataSource;
  }
  /** Set up a subscription for the data provided by the data source. */
  _observeRenderChanges() {
    // If no data source has been set, there is nothing to observe for changes.
    if (!this.dataSource) {
      return;
    }
    let dataStream;
    if ((0,_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__.isDataSource)(this.dataSource)) {
      dataStream = this.dataSource.connect(this);
    } else if ((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(this.dataSource)) {
      dataStream = this.dataSource;
    } else if (Array.isArray(this.dataSource)) {
      dataStream = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.of)(this.dataSource);
    }
    if (dataStream === undefined && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableUnknownDataSourceError();
    }
    this._renderChangeSubscription = dataStream.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.takeUntil)(this._onDestroy)).subscribe(data => {
      this._data = data || [];
      this.renderRows();
    });
  }
  /**
   * Clears any existing content in the header row outlet and creates a new embedded view
   * in the outlet using the header row definition.
   */
  _forceRenderHeaderRows() {
    // Clear the header row outlet if any content exists.
    if (this._headerRowOutlet.viewContainer.length > 0) {
      this._headerRowOutlet.viewContainer.clear();
    }
    this._headerRowDefs.forEach((def, i) => this._renderRow(this._headerRowOutlet, def, i));
    this.updateStickyHeaderRowStyles();
  }
  /**
   * Clears any existing content in the footer row outlet and creates a new embedded view
   * in the outlet using the footer row definition.
   */
  _forceRenderFooterRows() {
    // Clear the footer row outlet if any content exists.
    if (this._footerRowOutlet.viewContainer.length > 0) {
      this._footerRowOutlet.viewContainer.clear();
    }
    this._footerRowDefs.forEach((def, i) => this._renderRow(this._footerRowOutlet, def, i));
    this.updateStickyFooterRowStyles();
  }
  /** Adds the sticky column styles for the rows according to the columns' stick states. */
  _addStickyColumnStyles(rows, rowDef) {
    const columnDefs = Array.from(rowDef.columns || []).map(columnName => {
      const columnDef = this._columnDefsByName.get(columnName);
      if (!columnDef && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw getTableUnknownColumnError(columnName);
      }
      return columnDef;
    });
    const stickyStartStates = columnDefs.map(columnDef => columnDef.sticky);
    const stickyEndStates = columnDefs.map(columnDef => columnDef.stickyEnd);
    this._stickyStyler.updateStickyColumns(rows, stickyStartStates, stickyEndStates, !this._fixedLayout || this._forceRecalculateCellWidths);
  }
  /** Gets the list of rows that have been rendered in the row outlet. */
  _getRenderedRows(rowOutlet) {
    const renderedRows = [];
    for (let i = 0; i < rowOutlet.viewContainer.length; i++) {
      const viewRef = rowOutlet.viewContainer.get(i);
      renderedRows.push(viewRef.rootNodes[0]);
    }
    return renderedRows;
  }
  /**
   * Get the matching row definitions that should be used for this row data. If there is only
   * one row definition, it is returned. Otherwise, find the row definitions that has a when
   * predicate that returns true with the data. If none return true, return the default row
   * definition.
   */
  _getRowDefs(data, dataIndex) {
    if (this._rowDefs.length == 1) {
      return [this._rowDefs[0]];
    }
    let rowDefs = [];
    if (this.multiTemplateDataRows) {
      rowDefs = this._rowDefs.filter(def => !def.when || def.when(dataIndex, data));
    } else {
      let rowDef = this._rowDefs.find(def => def.when && def.when(dataIndex, data)) || this._defaultRowDef;
      if (rowDef) {
        rowDefs.push(rowDef);
      }
    }
    if (!rowDefs.length && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableMissingMatchingRowDefError(data);
    }
    return rowDefs;
  }
  _getEmbeddedViewArgs(renderRow, index) {
    const rowDef = renderRow.rowDef;
    const context = {
      $implicit: renderRow.data
    };
    return {
      templateRef: rowDef.template,
      context,
      index
    };
  }
  /**
   * Creates a new row template in the outlet and fills it with the set of cell templates.
   * Optionally takes a context to provide to the row and cells, as well as an optional index
   * of where to place the new row template in the outlet.
   */
  _renderRow(outlet, rowDef, index, context = {}) {
    // TODO(andrewseguin): enforce that one outlet was instantiated from createEmbeddedView
    const view = outlet.viewContainer.createEmbeddedView(rowDef.template, context, index);
    this._renderCellTemplateForItem(rowDef, context);
    return view;
  }
  _renderCellTemplateForItem(rowDef, context) {
    for (let cellTemplate of this._getCellTemplates(rowDef)) {
      if (CdkCellOutlet.mostRecentCellOutlet) {
        CdkCellOutlet.mostRecentCellOutlet._viewContainer.createEmbeddedView(cellTemplate, context);
      }
    }
    this._changeDetectorRef.markForCheck();
  }
  /**
   * Updates the index-related context for each row to reflect any changes in the index of the rows,
   * e.g. first/last/even/odd.
   */
  _updateRowIndexContext() {
    const viewContainer = this._rowOutlet.viewContainer;
    for (let renderIndex = 0, count = viewContainer.length; renderIndex < count; renderIndex++) {
      const viewRef = viewContainer.get(renderIndex);
      const context = viewRef.context;
      context.count = count;
      context.first = renderIndex === 0;
      context.last = renderIndex === count - 1;
      context.even = renderIndex % 2 === 0;
      context.odd = !context.even;
      if (this.multiTemplateDataRows) {
        context.dataIndex = this._renderRows[renderIndex].dataIndex;
        context.renderIndex = renderIndex;
      } else {
        context.index = this._renderRows[renderIndex].dataIndex;
      }
    }
  }
  /** Gets the column definitions for the provided row def. */
  _getCellTemplates(rowDef) {
    if (!rowDef || !rowDef.columns) {
      return [];
    }
    return Array.from(rowDef.columns, columnId => {
      const column = this._columnDefsByName.get(columnId);
      if (!column && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw getTableUnknownColumnError(columnId);
      }
      return rowDef.extractCellTemplate(column);
    });
  }
  /**
   * Forces a re-render of the data rows. Should be called in cases where there has been an input
   * change that affects the evaluation of which rows should be rendered, e.g. toggling
   * `multiTemplateDataRows` or adding/removing row definitions.
   */
  _forceRenderDataRows() {
    this._dataDiffer.diff([]);
    this._rowOutlet.viewContainer.clear();
    this.renderRows();
  }
  /**
   * Checks if there has been a change in sticky states since last check and applies the correct
   * sticky styles. Since checking resets the "dirty" state, this should only be performed once
   * during a change detection and after the inputs are settled (after content check).
   */
  _checkStickyStates() {
    const stickyCheckReducer = (acc, d) => {
      return acc || d.hasStickyChanged();
    };
    // Note that the check needs to occur for every definition since it notifies the definition
    // that it can reset its dirty state. Using another operator like `some` may short-circuit
    // remaining definitions and leave them in an unchecked state.
    if (this._headerRowDefs.reduce(stickyCheckReducer, false)) {
      this.updateStickyHeaderRowStyles();
    }
    if (this._footerRowDefs.reduce(stickyCheckReducer, false)) {
      this.updateStickyFooterRowStyles();
    }
    if (Array.from(this._columnDefsByName.values()).reduce(stickyCheckReducer, false)) {
      this._stickyColumnStylesNeedReset = true;
      this.updateStickyColumnStyles();
    }
  }
  /**
   * Creates the sticky styler that will be used for sticky rows and columns. Listens
   * for directionality changes and provides the latest direction to the styler. Re-applies column
   * stickiness when directionality changes.
   */
  _setupStickyStyler() {
    const direction = this._dir ? this._dir.value : 'ltr';
    this._stickyStyler = new StickyStyler(this._isNativeHtmlTable, this.stickyCssClass, direction, this._coalescedStyleScheduler, this._platform.isBrowser, this.needsPositionStickyOnElement, this._stickyPositioningListener);
    (this._dir ? this._dir.change : (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.of)()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.takeUntil)(this._onDestroy)).subscribe(value => {
      this._stickyStyler.direction = value;
      this.updateStickyColumnStyles();
    });
  }
  /** Filters definitions that belong to this table from a QueryList. */
  _getOwnDefs(items) {
    return items.filter(item => !item._table || item._table === this);
  }
  /** Creates or removes the no data row, depending on whether any data is being shown. */
  _updateNoDataRow() {
    const noDataRow = this._customNoDataRow || this._noDataRow;
    if (!noDataRow) {
      return;
    }
    const shouldShow = this._rowOutlet.viewContainer.length === 0;
    if (shouldShow === this._isShowingNoDataRow) {
      return;
    }
    const container = this._noDataRowOutlet.viewContainer;
    if (shouldShow) {
      const view = container.createEmbeddedView(noDataRow.templateRef);
      const rootNode = view.rootNodes[0];
      // Only add the attributes if we have a single root node since it's hard
      // to figure out which one to add it to when there are multiple.
      if (view.rootNodes.length === 1 && rootNode?.nodeType === this._document.ELEMENT_NODE) {
        rootNode.setAttribute('role', 'row');
        rootNode.classList.add(noDataRow._contentClassName);
      }
    } else {
      container.clear();
    }
    this._isShowingNoDataRow = shouldShow;
    this._changeDetectorRef.markForCheck();
  }
  static {
    this.ɵfac = function CdkTable_Factory(t) {
      return new (t || CdkTable)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinjectAttribute"]('role'), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_7__.Directionality, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_COALESCED_STYLE_SCHEDULER), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_10__.ViewportRuler), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](STICKY_POSITIONING_LISTENER, 12), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: CdkTable,
      selectors: [["cdk-table"], ["table", "cdk-table", ""]],
      contentQueries: function CdkTable_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkNoDataRow, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkColumnDef, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkRowDef, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkHeaderRowDef, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵcontentQuery"](dirIndex, CdkFooterRowDef, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._noDataRow = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._contentColumnDefs = _t);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._contentRowDefs = _t);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._contentHeaderRowDefs = _t);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx._contentFooterRowDefs = _t);
        }
      },
      hostAttrs: [1, "cdk-table"],
      hostVars: 2,
      hostBindings: function CdkTable_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵclassProp"]("cdk-table-fixed-layout", ctx.fixedLayout);
        }
      },
      inputs: {
        trackBy: "trackBy",
        dataSource: "dataSource",
        multiTemplateDataRows: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "multiTemplateDataRows", "multiTemplateDataRows", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute],
        fixedLayout: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].HasDecoratorInputTransform, "fixedLayout", "fixedLayout", _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute]
      },
      outputs: {
        contentChanged: "contentChanged"
      },
      exportAs: ["cdkTable"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: CDK_TABLE,
        useExisting: CdkTable
      }, {
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._DisposeViewRepeaterStrategy
      }, {
        provide: _COALESCED_STYLE_SCHEDULER,
        useClass: _CoalescedStyleScheduler
      },
      // Prevent nested tables from seeing this table's StickyPositioningListener.
      {
        provide: STICKY_POSITIONING_LISTENER,
        useValue: null
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c1,
      decls: 5,
      vars: 2,
      consts: [["role", "rowgroup"], ["headerRowOutlet", ""], ["rowOutlet", ""], ["noDataRowOutlet", ""], ["footerRowOutlet", ""]],
      template: function CdkTable_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojectionDef"](_c0);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojection"](0);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojection"](1, 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtemplate"](2, CdkTable_Conditional_2_Template, 1, 0)(3, CdkTable_Conditional_3_Template, 7, 0)(4, CdkTable_Conditional_4_Template, 4, 0);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵconditional"](2, ctx._isServer ? 2 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵconditional"](3, ctx._isNativeHtmlTable ? 3 : 4);
        }
      },
      dependencies: [HeaderRowOutlet, DataRowOutlet, NoDataRowOutlet, FooterRowOutlet],
      styles: [".cdk-table-fixed-layout{table-layout:fixed}"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkTable, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'cdk-table, table[cdk-table]',
      exportAs: 'cdkTable',
      template: CDK_TABLE_TEMPLATE,
      host: {
        'class': 'cdk-table',
        '[class.cdk-table-fixed-layout]': 'fixedLayout'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.Default,
      providers: [{
        provide: CDK_TABLE,
        useExisting: CdkTable
      }, {
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._DisposeViewRepeaterStrategy
      }, {
        provide: _COALESCED_STYLE_SCHEDULER,
        useClass: _CoalescedStyleScheduler
      },
      // Prevent nested tables from seeing this table's StickyPositioningListener.
      {
        provide: STICKY_POSITIONING_LISTENER,
        useValue: null
      }],
      standalone: true,
      imports: [HeaderRowOutlet, DataRowOutlet, NoDataRowOutlet, FooterRowOutlet],
      styles: [".cdk-table-fixed-layout{table-layout:fixed}"]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Attribute,
      args: ['role']
    }]
  }, {
    type: _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_7__.Directionality,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT]
    }]
  }, {
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_9__.Platform
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_cdk_collections__WEBPACK_IMPORTED_MODULE_0__._VIEW_REPEATER_STRATEGY]
    }]
  }, {
    type: _CoalescedStyleScheduler,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_COALESCED_STYLE_SCHEDULER]
    }]
  }, {
    type: _angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_10__.ViewportRuler
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [STICKY_POSITIONING_LISTENER]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }], {
    trackBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    dataSource: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    multiTemplateDataRows: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    fixedLayout: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_1__.booleanAttribute
      }]
    }],
    contentChanged: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    _contentColumnDefs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChildren,
      args: [CdkColumnDef, {
        descendants: true
      }]
    }],
    _contentRowDefs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChildren,
      args: [CdkRowDef, {
        descendants: true
      }]
    }],
    _contentHeaderRowDefs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChildren,
      args: [CdkHeaderRowDef, {
        descendants: true
      }]
    }],
    _contentFooterRowDefs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChildren,
      args: [CdkFooterRowDef, {
        descendants: true
      }]
    }],
    _noDataRow: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ContentChild,
      args: [CdkNoDataRow]
    }]
  });
})();
/** Utility function that gets a merged list of the entries in an array and values of a Set. */
function mergeArrayAndSet(array, set) {
  return array.concat(Array.from(set));
}
/**
 * Finds the closest table section to an outlet. We can't use `HTMLElement.closest` for this,
 * because the node representing the outlet is a comment.
 */
function closestTableSection(outlet, section) {
  const uppercaseSection = section.toUpperCase();
  let current = outlet.viewContainer.element.nativeElement;
  while (current) {
    // 1 is an element node.
    const nodeName = current.nodeType === 1 ? current.nodeName : null;
    if (nodeName === uppercaseSection) {
      return current;
    } else if (nodeName === 'TABLE') {
      // Stop traversing past the `table` node.
      break;
    }
    current = current.parentNode;
  }
  return null;
}

/**
 * Column that simply shows text content for the header and row cells. Assumes that the table
 * is using the native table implementation (`<table>`).
 *
 * By default, the name of this column will be the header text and data property accessor.
 * The header text can be overridden with the `headerText` input. Cell values can be overridden with
 * the `dataAccessor` input. Change the text justification to the start or end using the `justify`
 * input.
 */
class CdkTextColumn {
  /** Column name that should be used to reference this column. */
  get name() {
    return this._name;
  }
  set name(name) {
    this._name = name;
    // With Ivy, inputs can be initialized before static query results are
    // available. In that case, we defer the synchronization until "ngOnInit" fires.
    this._syncColumnDefName();
  }
  constructor(
  // `CdkTextColumn` is always requiring a table, but we just assert it manually
  // for better error reporting.
  // tslint:disable-next-line: lightweight-tokens
  _table, _options) {
    this._table = _table;
    this._options = _options;
    /** Alignment of the cell values. */
    this.justify = 'start';
    this._options = _options || {};
  }
  ngOnInit() {
    this._syncColumnDefName();
    if (this.headerText === undefined) {
      this.headerText = this._createDefaultHeaderText();
    }
    if (!this.dataAccessor) {
      this.dataAccessor = this._options.defaultDataAccessor || ((data, name) => data[name]);
    }
    if (this._table) {
      // Provide the cell and headerCell directly to the table with the static `ViewChild` query,
      // since the columnDef will not pick up its content by the time the table finishes checking
      // its content and initializing the rows.
      this.columnDef.cell = this.cell;
      this.columnDef.headerCell = this.headerCell;
      this._table.addColumnDef(this.columnDef);
    } else if (typeof ngDevMode === 'undefined' || ngDevMode) {
      throw getTableTextColumnMissingParentTableError();
    }
  }
  ngOnDestroy() {
    if (this._table) {
      this._table.removeColumnDef(this.columnDef);
    }
  }
  /**
   * Creates a default header text. Use the options' header text transformation function if one
   * has been provided. Otherwise simply capitalize the column name.
   */
  _createDefaultHeaderText() {
    const name = this.name;
    if (!name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw getTableTextColumnMissingNameError();
    }
    if (this._options && this._options.defaultHeaderTextTransform) {
      return this._options.defaultHeaderTextTransform(name);
    }
    return name[0].toUpperCase() + name.slice(1);
  }
  /** Synchronizes the column definition name with the text column name. */
  _syncColumnDefName() {
    if (this.columnDef) {
      this.columnDef.name = this.name;
    }
  }
  static {
    this.ɵfac = function CdkTextColumn_Factory(t) {
      return new (t || CdkTextColumn)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](CdkTable, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](TEXT_COLUMN_OPTIONS, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: CdkTextColumn,
      selectors: [["cdk-text-column"]],
      viewQuery: function CdkTextColumn_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](CdkColumnDef, 7);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](CdkCellDef, 7);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuery"](CdkHeaderCellDef, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.columnDef = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.cell = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵloadQuery"]()) && (ctx.headerCell = _t.first);
        }
      },
      inputs: {
        name: "name",
        headerText: "headerText",
        dataAccessor: "dataAccessor",
        justify: "justify"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 3,
      vars: 0,
      consts: [["cdkColumnDef", ""], ["cdk-header-cell", "", 3, "text-align", 4, "cdkHeaderCellDef"], ["cdk-cell", "", 3, "text-align", 4, "cdkCellDef"], ["cdk-header-cell", ""], ["cdk-cell", ""]],
      template: function CdkTextColumn_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainerStart"](0, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵtemplate"](1, CdkTextColumn_th_1_Template, 2, 3, "th", 1)(2, CdkTextColumn_td_2_Template, 2, 3, "td", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementContainerEnd"]();
        }
      },
      dependencies: [CdkColumnDef, CdkHeaderCellDef, CdkHeaderCell, CdkCellDef, CdkCell],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkTextColumn, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'cdk-text-column',
      template: `
    <ng-container cdkColumnDef>
      <th cdk-header-cell *cdkHeaderCellDef [style.text-align]="justify">
        {{headerText}}
      </th>
      <td cdk-cell *cdkCellDef="let data" [style.text-align]="justify">
        {{dataAccessor(data, name)}}
      </td>
    </ng-container>
  `,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      // Change detection is intentionally not set to OnPush. This component's template will be provided
      // to the table to be inserted into its view. This is problematic when change detection runs since
      // the bindings in this template will be evaluated _after_ the table's view is evaluated, which
      // mean's the template in the table's view will not have the updated value (and in fact will cause
      // an ExpressionChangedAfterItHasBeenCheckedError).
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.Default,
      standalone: true,
      imports: [CdkColumnDef, CdkHeaderCellDef, CdkHeaderCell, CdkCellDef, CdkCell]
    }]
  }], () => [{
    type: CdkTable,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [TEXT_COLUMN_OPTIONS]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    headerText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    dataAccessor: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    justify: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    columnDef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: [CdkColumnDef, {
        static: true
      }]
    }],
    cell: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: [CdkCellDef, {
        static: true
      }]
    }],
    headerCell: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewChild,
      args: [CdkHeaderCellDef, {
        static: true
      }]
    }]
  });
})();
const EXPORTED_DECLARATIONS = [CdkTable, CdkRowDef, CdkCellDef, CdkCellOutlet, CdkHeaderCellDef, CdkFooterCellDef, CdkColumnDef, CdkCell, CdkRow, CdkHeaderCell, CdkFooterCell, CdkHeaderRow, CdkHeaderRowDef, CdkFooterRow, CdkFooterRowDef, DataRowOutlet, HeaderRowOutlet, FooterRowOutlet, CdkTextColumn, CdkNoDataRow, CdkRecycleRows, NoDataRowOutlet];
class CdkTableModule {
  static {
    this.ɵfac = function CdkTableModule_Factory(t) {
      return new (t || CdkTableModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: CdkTableModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
      imports: [_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_10__.ScrollingModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CdkTableModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      exports: EXPORTED_DECLARATIONS,
      imports: [_angular_cdk_scrolling__WEBPACK_IMPORTED_MODULE_10__.ScrollingModule, ...EXPORTED_DECLARATIONS]
    }]
  }], null, null);
})();

/**
 * Mixin to provide a directive with a function that checks if the sticky input has been
 * changed since the last time the function was called. Essentially adds a dirty-check to the
 * sticky value.
 * @docs-private
 * @deprecated Implement the `CanStick` interface instead.
 * @breaking-change 19.0.0
 */
function mixinHasStickyInput(base) {
  return class extends base {
    /** Whether sticky positioning should be applied. */
    get sticky() {
      return this._sticky;
    }
    set sticky(v) {
      const prevValue = this._sticky;
      this._sticky = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_11__.coerceBooleanProperty)(v);
      this._hasStickyChanged = prevValue !== this._sticky;
    }
    /** Whether the sticky value has changed since this was last called. */
    hasStickyChanged() {
      const hasStickyChanged = this._hasStickyChanged;
      this._hasStickyChanged = false;
      return hasStickyChanged;
    }
    /** Resets the dirty check for cases where the sticky state has been used without checking. */
    resetStickyChanged() {
      this._hasStickyChanged = false;
    }
    constructor(...args) {
      super(...args);
      this._sticky = false;
      /** Whether the sticky input has changed since it was last checked. */
      this._hasStickyChanged = false;
    }
  };
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 60316:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/common/fesm2022/common.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   APP_BASE_HREF: () => (/* binding */ APP_BASE_HREF),
/* harmony export */   AsyncPipe: () => (/* binding */ AsyncPipe),
/* harmony export */   BrowserPlatformLocation: () => (/* binding */ BrowserPlatformLocation),
/* harmony export */   CommonModule: () => (/* binding */ CommonModule),
/* harmony export */   CurrencyPipe: () => (/* binding */ CurrencyPipe),
/* harmony export */   DATE_PIPE_DEFAULT_OPTIONS: () => (/* binding */ DATE_PIPE_DEFAULT_OPTIONS),
/* harmony export */   DATE_PIPE_DEFAULT_TIMEZONE: () => (/* binding */ DATE_PIPE_DEFAULT_TIMEZONE),
/* harmony export */   DOCUMENT: () => (/* binding */ DOCUMENT),
/* harmony export */   DatePipe: () => (/* binding */ DatePipe),
/* harmony export */   DecimalPipe: () => (/* binding */ DecimalPipe),
/* harmony export */   FormStyle: () => (/* binding */ FormStyle),
/* harmony export */   FormatWidth: () => (/* binding */ FormatWidth),
/* harmony export */   HashLocationStrategy: () => (/* binding */ HashLocationStrategy),
/* harmony export */   I18nPluralPipe: () => (/* binding */ I18nPluralPipe),
/* harmony export */   I18nSelectPipe: () => (/* binding */ I18nSelectPipe),
/* harmony export */   IMAGE_CONFIG: () => (/* reexport safe */ _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵIMAGE_CONFIG"]),
/* harmony export */   IMAGE_LOADER: () => (/* binding */ IMAGE_LOADER),
/* harmony export */   JsonPipe: () => (/* binding */ JsonPipe),
/* harmony export */   KeyValuePipe: () => (/* binding */ KeyValuePipe),
/* harmony export */   LOCATION_INITIALIZED: () => (/* binding */ LOCATION_INITIALIZED),
/* harmony export */   Location: () => (/* binding */ Location),
/* harmony export */   LocationStrategy: () => (/* binding */ LocationStrategy),
/* harmony export */   LowerCasePipe: () => (/* binding */ LowerCasePipe),
/* harmony export */   NgClass: () => (/* binding */ NgClass),
/* harmony export */   NgComponentOutlet: () => (/* binding */ NgComponentOutlet),
/* harmony export */   NgFor: () => (/* binding */ NgForOf),
/* harmony export */   NgForOf: () => (/* binding */ NgForOf),
/* harmony export */   NgForOfContext: () => (/* binding */ NgForOfContext),
/* harmony export */   NgIf: () => (/* binding */ NgIf),
/* harmony export */   NgIfContext: () => (/* binding */ NgIfContext),
/* harmony export */   NgLocaleLocalization: () => (/* binding */ NgLocaleLocalization),
/* harmony export */   NgLocalization: () => (/* binding */ NgLocalization),
/* harmony export */   NgOptimizedImage: () => (/* binding */ NgOptimizedImage),
/* harmony export */   NgPlural: () => (/* binding */ NgPlural),
/* harmony export */   NgPluralCase: () => (/* binding */ NgPluralCase),
/* harmony export */   NgStyle: () => (/* binding */ NgStyle),
/* harmony export */   NgSwitch: () => (/* binding */ NgSwitch),
/* harmony export */   NgSwitchCase: () => (/* binding */ NgSwitchCase),
/* harmony export */   NgSwitchDefault: () => (/* binding */ NgSwitchDefault),
/* harmony export */   NgTemplateOutlet: () => (/* binding */ NgTemplateOutlet),
/* harmony export */   NumberFormatStyle: () => (/* binding */ NumberFormatStyle),
/* harmony export */   NumberSymbol: () => (/* binding */ NumberSymbol),
/* harmony export */   PRECONNECT_CHECK_BLOCKLIST: () => (/* binding */ PRECONNECT_CHECK_BLOCKLIST),
/* harmony export */   PathLocationStrategy: () => (/* binding */ PathLocationStrategy),
/* harmony export */   PercentPipe: () => (/* binding */ PercentPipe),
/* harmony export */   PlatformLocation: () => (/* binding */ PlatformLocation),
/* harmony export */   Plural: () => (/* binding */ Plural),
/* harmony export */   SlicePipe: () => (/* binding */ SlicePipe),
/* harmony export */   TitleCasePipe: () => (/* binding */ TitleCasePipe),
/* harmony export */   TranslationWidth: () => (/* binding */ TranslationWidth),
/* harmony export */   UpperCasePipe: () => (/* binding */ UpperCasePipe),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   ViewportScroller: () => (/* binding */ ViewportScroller),
/* harmony export */   WeekDay: () => (/* binding */ WeekDay),
/* harmony export */   XhrFactory: () => (/* binding */ XhrFactory),
/* harmony export */   formatCurrency: () => (/* binding */ formatCurrency),
/* harmony export */   formatDate: () => (/* binding */ formatDate),
/* harmony export */   formatNumber: () => (/* binding */ formatNumber),
/* harmony export */   formatPercent: () => (/* binding */ formatPercent),
/* harmony export */   getCurrencySymbol: () => (/* binding */ getCurrencySymbol),
/* harmony export */   getLocaleCurrencyCode: () => (/* binding */ getLocaleCurrencyCode),
/* harmony export */   getLocaleCurrencyName: () => (/* binding */ getLocaleCurrencyName),
/* harmony export */   getLocaleCurrencySymbol: () => (/* binding */ getLocaleCurrencySymbol),
/* harmony export */   getLocaleDateFormat: () => (/* binding */ getLocaleDateFormat),
/* harmony export */   getLocaleDateTimeFormat: () => (/* binding */ getLocaleDateTimeFormat),
/* harmony export */   getLocaleDayNames: () => (/* binding */ getLocaleDayNames),
/* harmony export */   getLocaleDayPeriods: () => (/* binding */ getLocaleDayPeriods),
/* harmony export */   getLocaleDirection: () => (/* binding */ getLocaleDirection),
/* harmony export */   getLocaleEraNames: () => (/* binding */ getLocaleEraNames),
/* harmony export */   getLocaleExtraDayPeriodRules: () => (/* binding */ getLocaleExtraDayPeriodRules),
/* harmony export */   getLocaleExtraDayPeriods: () => (/* binding */ getLocaleExtraDayPeriods),
/* harmony export */   getLocaleFirstDayOfWeek: () => (/* binding */ getLocaleFirstDayOfWeek),
/* harmony export */   getLocaleId: () => (/* binding */ getLocaleId),
/* harmony export */   getLocaleMonthNames: () => (/* binding */ getLocaleMonthNames),
/* harmony export */   getLocaleNumberFormat: () => (/* binding */ getLocaleNumberFormat),
/* harmony export */   getLocaleNumberSymbol: () => (/* binding */ getLocaleNumberSymbol),
/* harmony export */   getLocalePluralCase: () => (/* binding */ getLocalePluralCase),
/* harmony export */   getLocaleTimeFormat: () => (/* binding */ getLocaleTimeFormat),
/* harmony export */   getLocaleWeekEndRange: () => (/* binding */ getLocaleWeekEndRange),
/* harmony export */   getNumberOfCurrencyDigits: () => (/* binding */ getNumberOfCurrencyDigits),
/* harmony export */   isPlatformBrowser: () => (/* binding */ isPlatformBrowser),
/* harmony export */   isPlatformServer: () => (/* binding */ isPlatformServer),
/* harmony export */   isPlatformWorkerApp: () => (/* binding */ isPlatformWorkerApp),
/* harmony export */   isPlatformWorkerUi: () => (/* binding */ isPlatformWorkerUi),
/* harmony export */   provideCloudflareLoader: () => (/* binding */ provideCloudflareLoader),
/* harmony export */   provideCloudinaryLoader: () => (/* binding */ provideCloudinaryLoader),
/* harmony export */   provideImageKitLoader: () => (/* binding */ provideImageKitLoader),
/* harmony export */   provideImgixLoader: () => (/* binding */ provideImgixLoader),
/* harmony export */   provideNetlifyLoader: () => (/* binding */ provideNetlifyLoader),
/* harmony export */   registerLocaleData: () => (/* binding */ registerLocaleData),
/* harmony export */   "ɵDomAdapter": () => (/* binding */ DomAdapter),
/* harmony export */   "ɵNullViewportScroller": () => (/* binding */ NullViewportScroller),
/* harmony export */   "ɵPLATFORM_BROWSER_ID": () => (/* binding */ PLATFORM_BROWSER_ID),
/* harmony export */   "ɵPLATFORM_SERVER_ID": () => (/* binding */ PLATFORM_SERVER_ID),
/* harmony export */   "ɵPLATFORM_WORKER_APP_ID": () => (/* binding */ PLATFORM_WORKER_APP_ID),
/* harmony export */   "ɵPLATFORM_WORKER_UI_ID": () => (/* binding */ PLATFORM_WORKER_UI_ID),
/* harmony export */   "ɵPlatformNavigation": () => (/* binding */ PlatformNavigation),
/* harmony export */   "ɵgetDOM": () => (/* binding */ getDOM),
/* harmony export */   "ɵnormalizeQueryParams": () => (/* binding */ normalizeQueryParams),
/* harmony export */   "ɵparseCookieValue": () => (/* binding */ parseCookieValue),
/* harmony export */   "ɵsetRootDomAdapter": () => (/* binding */ setRootDomAdapter)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */




let _DOM = null;
function getDOM() {
  return _DOM;
}
function setRootDomAdapter(adapter) {
  _DOM ??= adapter;
}
/* tslint:disable:requireParameterType */
/**
 * Provides DOM operations in an environment-agnostic way.
 *
 * @security Tread carefully! Interacting with the DOM directly is dangerous and
 * can introduce XSS risks.
 */
class DomAdapter {}

/**
 * This class wraps the platform Navigation API which allows server-specific and test
 * implementations.
 */
class PlatformNavigation {
  static {
    this.ɵfac = function PlatformNavigation_Factory(t) {
      return new (t || PlatformNavigation)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: PlatformNavigation,
      factory: () => (() => window.navigation)(),
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PlatformNavigation, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'platform',
      useFactory: () => window.navigation
    }]
  }], null, null);
})();

/**
 * A DI Token representing the main rendering context.
 * In a browser and SSR this is the DOM Document.
 * When using SSR, that document is created by [Domino](https://github.com/angular/domino).
 *
 * @publicApi
 */
const DOCUMENT = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'DocumentToken' : '');

/**
 * This class should not be used directly by an application developer. Instead, use
 * {@link Location}.
 *
 * `PlatformLocation` encapsulates all calls to DOM APIs, which allows the Router to be
 * platform-agnostic.
 * This means that we can have different implementation of `PlatformLocation` for the different
 * platforms that Angular supports. For example, `@angular/platform-browser` provides an
 * implementation specific to the browser environment, while `@angular/platform-server` provides
 * one suitable for use with server-side rendering.
 *
 * The `PlatformLocation` class is used directly by all implementations of {@link LocationStrategy}
 * when they need to interact with the DOM APIs like pushState, popState, etc.
 *
 * {@link LocationStrategy} in turn is used by the {@link Location} service which is used directly
 * by the {@link Router} in order to navigate between routes. Since all interactions between {@link
 * Router} /
 * {@link Location} / {@link LocationStrategy} and DOM APIs flow through the `PlatformLocation`
 * class, they are all platform-agnostic.
 *
 * @publicApi
 */
class PlatformLocation {
  historyGo(relativePosition) {
    throw new Error(ngDevMode ? 'Not implemented' : '');
  }
  static {
    this.ɵfac = function PlatformLocation_Factory(t) {
      return new (t || PlatformLocation)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: PlatformLocation,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(BrowserPlatformLocation))(),
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PlatformLocation, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'platform',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(BrowserPlatformLocation)
    }]
  }], null, null);
})();
/**
 * @description
 * Indicates when a location is initialized.
 *
 * @publicApi
 */
const LOCATION_INITIALIZED = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'Location Initialized' : '');
/**
 * `PlatformLocation` encapsulates all of the direct calls to platform APIs.
 * This class should not be used directly by an application developer. Instead, use
 * {@link Location}.
 *
 * @publicApi
 */
class BrowserPlatformLocation extends PlatformLocation {
  constructor() {
    super();
    this._doc = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT);
    this._location = window.location;
    this._history = window.history;
  }
  getBaseHrefFromDOM() {
    return getDOM().getBaseHref(this._doc);
  }
  onPopState(fn) {
    const window = getDOM().getGlobalEventTarget(this._doc, 'window');
    window.addEventListener('popstate', fn, false);
    return () => window.removeEventListener('popstate', fn);
  }
  onHashChange(fn) {
    const window = getDOM().getGlobalEventTarget(this._doc, 'window');
    window.addEventListener('hashchange', fn, false);
    return () => window.removeEventListener('hashchange', fn);
  }
  get href() {
    return this._location.href;
  }
  get protocol() {
    return this._location.protocol;
  }
  get hostname() {
    return this._location.hostname;
  }
  get port() {
    return this._location.port;
  }
  get pathname() {
    return this._location.pathname;
  }
  get search() {
    return this._location.search;
  }
  get hash() {
    return this._location.hash;
  }
  set pathname(newPath) {
    this._location.pathname = newPath;
  }
  pushState(state, title, url) {
    this._history.pushState(state, title, url);
  }
  replaceState(state, title, url) {
    this._history.replaceState(state, title, url);
  }
  forward() {
    this._history.forward();
  }
  back() {
    this._history.back();
  }
  historyGo(relativePosition = 0) {
    this._history.go(relativePosition);
  }
  getState() {
    return this._history.state;
  }
  static {
    this.ɵfac = function BrowserPlatformLocation_Factory(t) {
      return new (t || BrowserPlatformLocation)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: BrowserPlatformLocation,
      factory: () => (() => new BrowserPlatformLocation())(),
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserPlatformLocation, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'platform',
      useFactory: () => new BrowserPlatformLocation()
    }]
  }], () => [], null);
})();

/**
 * Joins two parts of a URL with a slash if needed.
 *
 * @param start  URL string
 * @param end    URL string
 *
 *
 * @returns The joined URL string.
 */
function joinWithSlash(start, end) {
  if (start.length == 0) {
    return end;
  }
  if (end.length == 0) {
    return start;
  }
  let slashes = 0;
  if (start.endsWith('/')) {
    slashes++;
  }
  if (end.startsWith('/')) {
    slashes++;
  }
  if (slashes == 2) {
    return start + end.substring(1);
  }
  if (slashes == 1) {
    return start + end;
  }
  return start + '/' + end;
}
/**
 * Removes a trailing slash from a URL string if needed.
 * Looks for the first occurrence of either `#`, `?`, or the end of the
 * line as `/` characters and removes the trailing slash if one exists.
 *
 * @param url URL string.
 *
 * @returns The URL string, modified if needed.
 */
function stripTrailingSlash(url) {
  const match = url.match(/#|\?|$/);
  const pathEndIdx = match && match.index || url.length;
  const droppedSlashIdx = pathEndIdx - (url[pathEndIdx - 1] === '/' ? 1 : 0);
  return url.slice(0, droppedSlashIdx) + url.slice(pathEndIdx);
}
/**
 * Normalizes URL parameters by prepending with `?` if needed.
 *
 * @param  params String of URL parameters.
 *
 * @returns The normalized URL parameters string.
 */
function normalizeQueryParams(params) {
  return params && params[0] !== '?' ? '?' + params : params;
}

/**
 * Enables the `Location` service to read route state from the browser's URL.
 * Angular provides two strategies:
 * `HashLocationStrategy` and `PathLocationStrategy`.
 *
 * Applications should use the `Router` or `Location` services to
 * interact with application route state.
 *
 * For instance, `HashLocationStrategy` produces URLs like
 * <code class="no-auto-link">http://example.com#/foo</code>,
 * and `PathLocationStrategy` produces
 * <code class="no-auto-link">http://example.com/foo</code> as an equivalent URL.
 *
 * See these two classes for more.
 *
 * @publicApi
 */
class LocationStrategy {
  historyGo(relativePosition) {
    throw new Error(ngDevMode ? 'Not implemented' : '');
  }
  static {
    this.ɵfac = function LocationStrategy_Factory(t) {
      return new (t || LocationStrategy)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: LocationStrategy,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PathLocationStrategy))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LocationStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PathLocationStrategy)
    }]
  }], null, null);
})();
/**
 * A predefined [DI token](guide/glossary#di-token) for the base href
 * to be used with the `PathLocationStrategy`.
 * The base href is the URL prefix that should be preserved when generating
 * and recognizing URLs.
 *
 * @usageNotes
 *
 * The following example shows how to use this token to configure the root app injector
 * with a base href value, so that the DI framework can supply the dependency anywhere in the app.
 *
 * ```typescript
 * import {NgModule} from '@angular/core';
 * import {APP_BASE_HREF} from '@angular/common';
 *
 * @NgModule({
 *   providers: [{provide: APP_BASE_HREF, useValue: '/my/app'}]
 * })
 * class AppModule {}
 * ```
 *
 * @publicApi
 */
const APP_BASE_HREF = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'appBaseHref' : '');
/**
 * @description
 * A {@link LocationStrategy} used to configure the {@link Location} service to
 * represent its state in the
 * [path](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax) of the
 * browser's URL.
 *
 * If you're using `PathLocationStrategy`, you may provide a {@link APP_BASE_HREF}
 * or add a `<base href>` element to the document to override the default.
 *
 * For instance, if you provide an `APP_BASE_HREF` of `'/my/app/'` and call
 * `location.go('/foo')`, the browser's URL will become
 * `example.com/my/app/foo`. To ensure all relative URIs resolve correctly,
 * the `<base href>` and/or `APP_BASE_HREF` should end with a `/`.
 *
 * Similarly, if you add `<base href='/my/app/'/>` to the document and call
 * `location.go('/foo')`, the browser's URL will become
 * `example.com/my/app/foo`.
 *
 * Note that when using `PathLocationStrategy`, neither the query nor
 * the fragment in the `<base href>` will be preserved, as outlined
 * by the [RFC](https://tools.ietf.org/html/rfc3986#section-5.2.2).
 *
 * @usageNotes
 *
 * ### Example
 *
 * {@example common/location/ts/path_location_component.ts region='LocationComponent'}
 *
 * @publicApi
 */
class PathLocationStrategy extends LocationStrategy {
  constructor(_platformLocation, href) {
    super();
    this._platformLocation = _platformLocation;
    this._removeListenerFns = [];
    this._baseHref = href ?? this._platformLocation.getBaseHrefFromDOM() ?? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT).location?.origin ?? '';
  }
  /** @nodoc */
  ngOnDestroy() {
    while (this._removeListenerFns.length) {
      this._removeListenerFns.pop()();
    }
  }
  onPopState(fn) {
    this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn));
  }
  getBaseHref() {
    return this._baseHref;
  }
  prepareExternalUrl(internal) {
    return joinWithSlash(this._baseHref, internal);
  }
  path(includeHash = false) {
    const pathname = this._platformLocation.pathname + normalizeQueryParams(this._platformLocation.search);
    const hash = this._platformLocation.hash;
    return hash && includeHash ? `${pathname}${hash}` : pathname;
  }
  pushState(state, title, url, queryParams) {
    const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
    this._platformLocation.pushState(state, title, externalUrl);
  }
  replaceState(state, title, url, queryParams) {
    const externalUrl = this.prepareExternalUrl(url + normalizeQueryParams(queryParams));
    this._platformLocation.replaceState(state, title, externalUrl);
  }
  forward() {
    this._platformLocation.forward();
  }
  back() {
    this._platformLocation.back();
  }
  getState() {
    return this._platformLocation.getState();
  }
  historyGo(relativePosition = 0) {
    this._platformLocation.historyGo?.(relativePosition);
  }
  static {
    this.ɵfac = function PathLocationStrategy_Factory(t) {
      return new (t || PathLocationStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](PlatformLocation), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](APP_BASE_HREF, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: PathLocationStrategy,
      factory: PathLocationStrategy.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PathLocationStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: PlatformLocation
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [APP_BASE_HREF]
    }]
  }], null);
})();

/**
 * @description
 * A {@link LocationStrategy} used to configure the {@link Location} service to
 * represent its state in the
 * [hash fragment](https://en.wikipedia.org/wiki/Uniform_Resource_Locator#Syntax)
 * of the browser's URL.
 *
 * For instance, if you call `location.go('/foo')`, the browser's URL will become
 * `example.com#/foo`.
 *
 * @usageNotes
 *
 * ### Example
 *
 * {@example common/location/ts/hash_location_component.ts region='LocationComponent'}
 *
 * @publicApi
 */
class HashLocationStrategy extends LocationStrategy {
  constructor(_platformLocation, _baseHref) {
    super();
    this._platformLocation = _platformLocation;
    this._baseHref = '';
    this._removeListenerFns = [];
    if (_baseHref != null) {
      this._baseHref = _baseHref;
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    while (this._removeListenerFns.length) {
      this._removeListenerFns.pop()();
    }
  }
  onPopState(fn) {
    this._removeListenerFns.push(this._platformLocation.onPopState(fn), this._platformLocation.onHashChange(fn));
  }
  getBaseHref() {
    return this._baseHref;
  }
  path(includeHash = false) {
    // the hash value is always prefixed with a `#`
    // and if it is empty then it will stay empty
    const path = this._platformLocation.hash ?? '#';
    return path.length > 0 ? path.substring(1) : path;
  }
  prepareExternalUrl(internal) {
    const url = joinWithSlash(this._baseHref, internal);
    return url.length > 0 ? '#' + url : url;
  }
  pushState(state, title, path, queryParams) {
    let url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
    if (url.length == 0) {
      url = this._platformLocation.pathname;
    }
    this._platformLocation.pushState(state, title, url);
  }
  replaceState(state, title, path, queryParams) {
    let url = this.prepareExternalUrl(path + normalizeQueryParams(queryParams));
    if (url.length == 0) {
      url = this._platformLocation.pathname;
    }
    this._platformLocation.replaceState(state, title, url);
  }
  forward() {
    this._platformLocation.forward();
  }
  back() {
    this._platformLocation.back();
  }
  getState() {
    return this._platformLocation.getState();
  }
  historyGo(relativePosition = 0) {
    this._platformLocation.historyGo?.(relativePosition);
  }
  static {
    this.ɵfac = function HashLocationStrategy_Factory(t) {
      return new (t || HashLocationStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](PlatformLocation), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](APP_BASE_HREF, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: HashLocationStrategy,
      factory: HashLocationStrategy.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](HashLocationStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: PlatformLocation
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [APP_BASE_HREF]
    }]
  }], null);
})();

/**
 * @description
 *
 * A service that applications can use to interact with a browser's URL.
 *
 * Depending on the `LocationStrategy` used, `Location` persists
 * to the URL's path or the URL's hash segment.
 *
 * @usageNotes
 *
 * It's better to use the `Router.navigate()` service to trigger route changes. Use
 * `Location` only if you need to interact with or create normalized URLs outside of
 * routing.
 *
 * `Location` is responsible for normalizing the URL against the application's base href.
 * A normalized URL is absolute from the URL host, includes the application's base href, and has no
 * trailing slash:
 * - `/my/app/user/123` is normalized
 * - `my/app/user/123` **is not** normalized
 * - `/my/app/user/123/` **is not** normalized
 *
 * ### Example
 *
 * <code-example path='common/location/ts/path_location_component.ts'
 * region='LocationComponent'></code-example>
 *
 * @publicApi
 */
class Location {
  constructor(locationStrategy) {
    /** @internal */
    this._subject = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /** @internal */
    this._urlChangeListeners = [];
    /** @internal */
    this._urlChangeSubscription = null;
    this._locationStrategy = locationStrategy;
    const baseHref = this._locationStrategy.getBaseHref();
    // Note: This class's interaction with base HREF does not fully follow the rules
    // outlined in the spec https://www.freesoft.org/CIE/RFC/1808/18.htm.
    // Instead of trying to fix individual bugs with more and more code, we should
    // investigate using the URL constructor and providing the base as a second
    // argument.
    // https://developer.mozilla.org/en-US/docs/Web/API/URL/URL#parameters
    this._basePath = _stripOrigin(stripTrailingSlash(_stripIndexHtml(baseHref)));
    this._locationStrategy.onPopState(ev => {
      this._subject.emit({
        'url': this.path(true),
        'pop': true,
        'state': ev.state,
        'type': ev.type
      });
    });
  }
  /** @nodoc */
  ngOnDestroy() {
    this._urlChangeSubscription?.unsubscribe();
    this._urlChangeListeners = [];
  }
  /**
   * Normalizes the URL path for this location.
   *
   * @param includeHash True to include an anchor fragment in the path.
   *
   * @returns The normalized URL path.
   */
  // TODO: vsavkin. Remove the boolean flag and always include hash once the deprecated router is
  // removed.
  path(includeHash = false) {
    return this.normalize(this._locationStrategy.path(includeHash));
  }
  /**
   * Reports the current state of the location history.
   * @returns The current value of the `history.state` object.
   */
  getState() {
    return this._locationStrategy.getState();
  }
  /**
   * Normalizes the given path and compares to the current normalized path.
   *
   * @param path The given URL path.
   * @param query Query parameters.
   *
   * @returns True if the given URL path is equal to the current normalized path, false
   * otherwise.
   */
  isCurrentPathEqualTo(path, query = '') {
    return this.path() == this.normalize(path + normalizeQueryParams(query));
  }
  /**
   * Normalizes a URL path by stripping any trailing slashes.
   *
   * @param url String representing a URL.
   *
   * @returns The normalized URL string.
   */
  normalize(url) {
    return Location.stripTrailingSlash(_stripBasePath(this._basePath, _stripIndexHtml(url)));
  }
  /**
   * Normalizes an external URL path.
   * If the given URL doesn't begin with a leading slash (`'/'`), adds one
   * before normalizing. Adds a hash if `HashLocationStrategy` is
   * in use, or the `APP_BASE_HREF` if the `PathLocationStrategy` is in use.
   *
   * @param url String representing a URL.
   *
   * @returns  A normalized platform-specific URL.
   */
  prepareExternalUrl(url) {
    if (url && url[0] !== '/') {
      url = '/' + url;
    }
    return this._locationStrategy.prepareExternalUrl(url);
  }
  // TODO: rename this method to pushState
  /**
   * Changes the browser's URL to a normalized version of a given URL, and pushes a
   * new item onto the platform's history.
   *
   * @param path  URL path to normalize.
   * @param query Query parameters.
   * @param state Location history state.
   *
   */
  go(path, query = '', state = null) {
    this._locationStrategy.pushState(state, '', path, query);
    this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);
  }
  /**
   * Changes the browser's URL to a normalized version of the given URL, and replaces
   * the top item on the platform's history stack.
   *
   * @param path  URL path to normalize.
   * @param query Query parameters.
   * @param state Location history state.
   */
  replaceState(path, query = '', state = null) {
    this._locationStrategy.replaceState(state, '', path, query);
    this._notifyUrlChangeListeners(this.prepareExternalUrl(path + normalizeQueryParams(query)), state);
  }
  /**
   * Navigates forward in the platform's history.
   */
  forward() {
    this._locationStrategy.forward();
  }
  /**
   * Navigates back in the platform's history.
   */
  back() {
    this._locationStrategy.back();
  }
  /**
   * Navigate to a specific page from session history, identified by its relative position to the
   * current page.
   *
   * @param relativePosition  Position of the target page in the history relative to the current
   *     page.
   * A negative value moves backwards, a positive value moves forwards, e.g. `location.historyGo(2)`
   * moves forward two pages and `location.historyGo(-2)` moves back two pages. When we try to go
   * beyond what's stored in the history session, we stay in the current page. Same behaviour occurs
   * when `relativePosition` equals 0.
   * @see https://developer.mozilla.org/en-US/docs/Web/API/History_API#Moving_to_a_specific_point_in_history
   */
  historyGo(relativePosition = 0) {
    this._locationStrategy.historyGo?.(relativePosition);
  }
  /**
   * Registers a URL change listener. Use to catch updates performed by the Angular
   * framework that are not detectible through "popstate" or "hashchange" events.
   *
   * @param fn The change handler function, which take a URL and a location history state.
   * @returns A function that, when executed, unregisters a URL change listener.
   */
  onUrlChange(fn) {
    this._urlChangeListeners.push(fn);
    this._urlChangeSubscription ??= this.subscribe(v => {
      this._notifyUrlChangeListeners(v.url, v.state);
    });
    return () => {
      const fnIndex = this._urlChangeListeners.indexOf(fn);
      this._urlChangeListeners.splice(fnIndex, 1);
      if (this._urlChangeListeners.length === 0) {
        this._urlChangeSubscription?.unsubscribe();
        this._urlChangeSubscription = null;
      }
    };
  }
  /** @internal */
  _notifyUrlChangeListeners(url = '', state) {
    this._urlChangeListeners.forEach(fn => fn(url, state));
  }
  /**
   * Subscribes to the platform's `popState` events.
   *
   * Note: `Location.go()` does not trigger the `popState` event in the browser. Use
   * `Location.onUrlChange()` to subscribe to URL changes instead.
   *
   * @param value Event that is triggered when the state history changes.
   * @param exception The exception to throw.
   *
   * @see [onpopstate](https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate)
   *
   * @returns Subscribed events.
   */
  subscribe(onNext, onThrow, onReturn) {
    return this._subject.subscribe({
      next: onNext,
      error: onThrow,
      complete: onReturn
    });
  }
  /**
   * Normalizes URL parameters by prepending with `?` if needed.
   *
   * @param  params String of URL parameters.
   *
   * @returns The normalized URL parameters string.
   */
  static {
    this.normalizeQueryParams = normalizeQueryParams;
  }
  /**
   * Joins two parts of a URL with a slash if needed.
   *
   * @param start  URL string
   * @param end    URL string
   *
   *
   * @returns The joined URL string.
   */
  static {
    this.joinWithSlash = joinWithSlash;
  }
  /**
   * Removes a trailing slash from a URL string if needed.
   * Looks for the first occurrence of either `#`, `?`, or the end of the
   * line as `/` characters and removes the trailing slash if one exists.
   *
   * @param url URL string.
   *
   * @returns The URL string, modified if needed.
   */
  static {
    this.stripTrailingSlash = stripTrailingSlash;
  }
  static {
    this.ɵfac = function Location_Factory(t) {
      return new (t || Location)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](LocationStrategy));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: Location,
      factory: () => createLocation(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Location, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      // See #23917
      useFactory: createLocation
    }]
  }], () => [{
    type: LocationStrategy
  }], null);
})();
function createLocation() {
  return new Location((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"])(LocationStrategy));
}
function _stripBasePath(basePath, url) {
  if (!basePath || !url.startsWith(basePath)) {
    return url;
  }
  const strippedUrl = url.substring(basePath.length);
  if (strippedUrl === '' || ['/', ';', '?', '#'].includes(strippedUrl[0])) {
    return strippedUrl;
  }
  return url;
}
function _stripIndexHtml(url) {
  return url.replace(/\/index.html$/, '');
}
function _stripOrigin(baseHref) {
  // DO NOT REFACTOR! Previously, this check looked like this:
  // `/^(https?:)?\/\//.test(baseHref)`, but that resulted in
  // syntactically incorrect code after Closure Compiler minification.
  // This was likely caused by a bug in Closure Compiler, but
  // for now, the check is rewritten to use `new RegExp` instead.
  const isAbsoluteUrl = new RegExp('^(https?:)?//').test(baseHref);
  if (isAbsoluteUrl) {
    const [, pathname] = baseHref.split(/\/\/[^\/]+/);
    return pathname;
  }
  return baseHref;
}

/** @internal */
const CURRENCIES_EN = {
  "ADP": [undefined, undefined, 0],
  "AFN": [undefined, "؋", 0],
  "ALL": [undefined, undefined, 0],
  "AMD": [undefined, "֏", 2],
  "AOA": [undefined, "Kz"],
  "ARS": [undefined, "$"],
  "AUD": ["A$", "$"],
  "AZN": [undefined, "₼"],
  "BAM": [undefined, "KM"],
  "BBD": [undefined, "$"],
  "BDT": [undefined, "৳"],
  "BHD": [undefined, undefined, 3],
  "BIF": [undefined, undefined, 0],
  "BMD": [undefined, "$"],
  "BND": [undefined, "$"],
  "BOB": [undefined, "Bs"],
  "BRL": ["R$"],
  "BSD": [undefined, "$"],
  "BWP": [undefined, "P"],
  "BYN": [undefined, undefined, 2],
  "BYR": [undefined, undefined, 0],
  "BZD": [undefined, "$"],
  "CAD": ["CA$", "$", 2],
  "CHF": [undefined, undefined, 2],
  "CLF": [undefined, undefined, 4],
  "CLP": [undefined, "$", 0],
  "CNY": ["CN¥", "¥"],
  "COP": [undefined, "$", 2],
  "CRC": [undefined, "₡", 2],
  "CUC": [undefined, "$"],
  "CUP": [undefined, "$"],
  "CZK": [undefined, "Kč", 2],
  "DJF": [undefined, undefined, 0],
  "DKK": [undefined, "kr", 2],
  "DOP": [undefined, "$"],
  "EGP": [undefined, "E£"],
  "ESP": [undefined, "₧", 0],
  "EUR": ["€"],
  "FJD": [undefined, "$"],
  "FKP": [undefined, "£"],
  "GBP": ["£"],
  "GEL": [undefined, "₾"],
  "GHS": [undefined, "GH₵"],
  "GIP": [undefined, "£"],
  "GNF": [undefined, "FG", 0],
  "GTQ": [undefined, "Q"],
  "GYD": [undefined, "$", 2],
  "HKD": ["HK$", "$"],
  "HNL": [undefined, "L"],
  "HRK": [undefined, "kn"],
  "HUF": [undefined, "Ft", 2],
  "IDR": [undefined, "Rp", 2],
  "ILS": ["₪"],
  "INR": ["₹"],
  "IQD": [undefined, undefined, 0],
  "IRR": [undefined, undefined, 0],
  "ISK": [undefined, "kr", 0],
  "ITL": [undefined, undefined, 0],
  "JMD": [undefined, "$"],
  "JOD": [undefined, undefined, 3],
  "JPY": ["¥", undefined, 0],
  "KHR": [undefined, "៛"],
  "KMF": [undefined, "CF", 0],
  "KPW": [undefined, "₩", 0],
  "KRW": ["₩", undefined, 0],
  "KWD": [undefined, undefined, 3],
  "KYD": [undefined, "$"],
  "KZT": [undefined, "₸"],
  "LAK": [undefined, "₭", 0],
  "LBP": [undefined, "L£", 0],
  "LKR": [undefined, "Rs"],
  "LRD": [undefined, "$"],
  "LTL": [undefined, "Lt"],
  "LUF": [undefined, undefined, 0],
  "LVL": [undefined, "Ls"],
  "LYD": [undefined, undefined, 3],
  "MGA": [undefined, "Ar", 0],
  "MGF": [undefined, undefined, 0],
  "MMK": [undefined, "K", 0],
  "MNT": [undefined, "₮", 2],
  "MRO": [undefined, undefined, 0],
  "MUR": [undefined, "Rs", 2],
  "MXN": ["MX$", "$"],
  "MYR": [undefined, "RM"],
  "NAD": [undefined, "$"],
  "NGN": [undefined, "₦"],
  "NIO": [undefined, "C$"],
  "NOK": [undefined, "kr", 2],
  "NPR": [undefined, "Rs"],
  "NZD": ["NZ$", "$"],
  "OMR": [undefined, undefined, 3],
  "PHP": ["₱"],
  "PKR": [undefined, "Rs", 2],
  "PLN": [undefined, "zł"],
  "PYG": [undefined, "₲", 0],
  "RON": [undefined, "lei"],
  "RSD": [undefined, undefined, 0],
  "RUB": [undefined, "₽"],
  "RWF": [undefined, "RF", 0],
  "SBD": [undefined, "$"],
  "SEK": [undefined, "kr", 2],
  "SGD": [undefined, "$"],
  "SHP": [undefined, "£"],
  "SLE": [undefined, undefined, 2],
  "SLL": [undefined, undefined, 0],
  "SOS": [undefined, undefined, 0],
  "SRD": [undefined, "$"],
  "SSP": [undefined, "£"],
  "STD": [undefined, undefined, 0],
  "STN": [undefined, "Db"],
  "SYP": [undefined, "£", 0],
  "THB": [undefined, "฿"],
  "TMM": [undefined, undefined, 0],
  "TND": [undefined, undefined, 3],
  "TOP": [undefined, "T$"],
  "TRL": [undefined, undefined, 0],
  "TRY": [undefined, "₺"],
  "TTD": [undefined, "$"],
  "TWD": ["NT$", "$", 2],
  "TZS": [undefined, undefined, 2],
  "UAH": [undefined, "₴"],
  "UGX": [undefined, undefined, 0],
  "USD": ["$"],
  "UYI": [undefined, undefined, 0],
  "UYU": [undefined, "$"],
  "UYW": [undefined, undefined, 4],
  "UZS": [undefined, undefined, 2],
  "VEF": [undefined, "Bs", 2],
  "VND": ["₫", undefined, 0],
  "VUV": [undefined, undefined, 0],
  "XAF": ["FCFA", undefined, 0],
  "XCD": ["EC$", "$"],
  "XOF": ["F CFA", undefined, 0],
  "XPF": ["CFPF", undefined, 0],
  "XXX": ["¤"],
  "YER": [undefined, undefined, 0],
  "ZAR": [undefined, "R"],
  "ZMK": [undefined, undefined, 0],
  "ZMW": [undefined, "ZK"],
  "ZWD": [undefined, undefined, 0]
};

/**
 * Format styles that can be used to represent numbers.
 * @see {@link getLocaleNumberFormat}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
var NumberFormatStyle;
(function (NumberFormatStyle) {
  NumberFormatStyle[NumberFormatStyle["Decimal"] = 0] = "Decimal";
  NumberFormatStyle[NumberFormatStyle["Percent"] = 1] = "Percent";
  NumberFormatStyle[NumberFormatStyle["Currency"] = 2] = "Currency";
  NumberFormatStyle[NumberFormatStyle["Scientific"] = 3] = "Scientific";
})(NumberFormatStyle || (NumberFormatStyle = {}));
/**
 * Plurality cases used for translating plurals to different languages.
 *
 * @see {@link NgPlural}
 * @see {@link NgPluralCase}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
var Plural;
(function (Plural) {
  Plural[Plural["Zero"] = 0] = "Zero";
  Plural[Plural["One"] = 1] = "One";
  Plural[Plural["Two"] = 2] = "Two";
  Plural[Plural["Few"] = 3] = "Few";
  Plural[Plural["Many"] = 4] = "Many";
  Plural[Plural["Other"] = 5] = "Other";
})(Plural || (Plural = {}));
/**
 * Context-dependant translation forms for strings.
 * Typically the standalone version is for the nominative form of the word,
 * and the format version is used for the genitive case.
 * @see [CLDR website](http://cldr.unicode.org/translation/date-time-1/date-time#TOC-Standalone-vs.-Format-Styles)
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
var FormStyle;
(function (FormStyle) {
  FormStyle[FormStyle["Format"] = 0] = "Format";
  FormStyle[FormStyle["Standalone"] = 1] = "Standalone";
})(FormStyle || (FormStyle = {}));
/**
 * String widths available for translations.
 * The specific character widths are locale-specific.
 * Examples are given for the word "Sunday" in English.
 *
 * @publicApi
 */
var TranslationWidth;
(function (TranslationWidth) {
  /** 1 character for `en-US`. For example: 'S' */
  TranslationWidth[TranslationWidth["Narrow"] = 0] = "Narrow";
  /** 3 characters for `en-US`. For example: 'Sun' */
  TranslationWidth[TranslationWidth["Abbreviated"] = 1] = "Abbreviated";
  /** Full length for `en-US`. For example: "Sunday" */
  TranslationWidth[TranslationWidth["Wide"] = 2] = "Wide";
  /** 2 characters for `en-US`, For example: "Su" */
  TranslationWidth[TranslationWidth["Short"] = 3] = "Short";
})(TranslationWidth || (TranslationWidth = {}));
/**
 * String widths available for date-time formats.
 * The specific character widths are locale-specific.
 * Examples are given for `en-US`.
 *
 * @see {@link getLocaleDateFormat}
 * @see {@link getLocaleTimeFormat}
 * @see {@link getLocaleDateTimeFormat}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 * @publicApi
 */
var FormatWidth;
(function (FormatWidth) {
  /**
   * For `en-US`, `'M/d/yy, h:mm a'`
   * (Example: `6/15/15, 9:03 AM`)
   */
  FormatWidth[FormatWidth["Short"] = 0] = "Short";
  /**
   * For `en-US`, `'MMM d, y, h:mm:ss a'`
   * (Example: `Jun 15, 2015, 9:03:01 AM`)
   */
  FormatWidth[FormatWidth["Medium"] = 1] = "Medium";
  /**
   * For `en-US`, `'MMMM d, y, h:mm:ss a z'`
   * (Example: `June 15, 2015 at 9:03:01 AM GMT+1`)
   */
  FormatWidth[FormatWidth["Long"] = 2] = "Long";
  /**
   * For `en-US`, `'EEEE, MMMM d, y, h:mm:ss a zzzz'`
   * (Example: `Monday, June 15, 2015 at 9:03:01 AM GMT+01:00`)
   */
  FormatWidth[FormatWidth["Full"] = 3] = "Full";
})(FormatWidth || (FormatWidth = {}));
// This needs to be an object literal, rather than an enum, because TypeScript 5.4+
// doesn't allow numeric keys and we have `Infinity` and `NaN`.
/**
 * Symbols that can be used to replace placeholders in number patterns.
 * Examples are based on `en-US` values.
 *
 * @see {@link getLocaleNumberSymbol}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 * @object-literal-as-enum
 */
const NumberSymbol = {
  /**
   * Decimal separator.
   * For `en-US`, the dot character.
   * Example: 2,345`.`67
   */
  Decimal: 0,
  /**
   * Grouping separator, typically for thousands.
   * For `en-US`, the comma character.
   * Example: 2`,`345.67
   */
  Group: 1,
  /**
   * List-item separator.
   * Example: "one, two, and three"
   */
  List: 2,
  /**
   * Sign for percentage (out of 100).
   * Example: 23.4%
   */
  PercentSign: 3,
  /**
   * Sign for positive numbers.
   * Example: +23
   */
  PlusSign: 4,
  /**
   * Sign for negative numbers.
   * Example: -23
   */
  MinusSign: 5,
  /**
   * Computer notation for exponential value (n times a power of 10).
   * Example: 1.2E3
   */
  Exponential: 6,
  /**
   * Human-readable format of exponential.
   * Example: 1.2x103
   */
  SuperscriptingExponent: 7,
  /**
   * Sign for permille (out of 1000).
   * Example: 23.4‰
   */
  PerMille: 8,
  /**
   * Infinity, can be used with plus and minus.
   * Example: ∞, +∞, -∞
   */
  Infinity: 9,
  /**
   * Not a number.
   * Example: NaN
   */
  NaN: 10,
  /**
   * Symbol used between time units.
   * Example: 10:52
   */
  TimeSeparator: 11,
  /**
   * Decimal separator for currency values (fallback to `Decimal`).
   * Example: $2,345.67
   */
  CurrencyDecimal: 12,
  /**
   * Group separator for currency values (fallback to `Group`).
   * Example: $2,345.67
   */
  CurrencyGroup: 13
};
/**
 * The value for each day of the week, based on the `en-US` locale
 *
 * @publicApi
 */
var WeekDay;
(function (WeekDay) {
  WeekDay[WeekDay["Sunday"] = 0] = "Sunday";
  WeekDay[WeekDay["Monday"] = 1] = "Monday";
  WeekDay[WeekDay["Tuesday"] = 2] = "Tuesday";
  WeekDay[WeekDay["Wednesday"] = 3] = "Wednesday";
  WeekDay[WeekDay["Thursday"] = 4] = "Thursday";
  WeekDay[WeekDay["Friday"] = 5] = "Friday";
  WeekDay[WeekDay["Saturday"] = 6] = "Saturday";
})(WeekDay || (WeekDay = {}));
/**
 * Retrieves the locale ID from the currently loaded locale.
 * The loaded locale could be, for example, a global one rather than a regional one.
 * @param locale A locale code, such as `fr-FR`.
 * @returns The locale code. For example, `fr`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleId(locale) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale)[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].LocaleId];
}
/**
 * Retrieves day period strings for the given locale.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param formStyle The required grammatical form.
 * @param width The required character width.
 * @returns An array of localized period strings. For example, `[AM, PM]` for `en-US`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleDayPeriods(locale, formStyle, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const amPmData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DayPeriodsFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DayPeriodsStandalone]];
  const amPm = getLastDefinedValue(amPmData, formStyle);
  return getLastDefinedValue(amPm, width);
}
/**
 * Retrieves days of the week for the given locale, using the Gregorian calendar.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param formStyle The required grammatical form.
 * @param width The required character width.
 * @returns An array of localized name strings.
 * For example,`[Sunday, Monday, ... Saturday]` for `en-US`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleDayNames(locale, formStyle, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const daysData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DaysFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DaysStandalone]];
  const days = getLastDefinedValue(daysData, formStyle);
  return getLastDefinedValue(days, width);
}
/**
 * Retrieves months of the year for the given locale, using the Gregorian calendar.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param formStyle The required grammatical form.
 * @param width The required character width.
 * @returns An array of localized name strings.
 * For example,  `[January, February, ...]` for `en-US`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleMonthNames(locale, formStyle, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const monthsData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].MonthsFormat], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].MonthsStandalone]];
  const months = getLastDefinedValue(monthsData, formStyle);
  return getLastDefinedValue(months, width);
}
/**
 * Retrieves Gregorian-calendar eras for the given locale.
 * @param locale A locale code for the locale format rules to use.
 * @param width The required character width.

 * @returns An array of localized era strings.
 * For example, `[AD, BC]` for `en-US`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleEraNames(locale, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const erasData = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Eras];
  return getLastDefinedValue(erasData, width);
}
/**
 * Retrieves the first day of the week for the given locale.
 *
 * @param locale A locale code for the locale format rules to use.
 * @returns A day index number, using the 0-based week-day index for `en-US`
 * (Sunday = 0, Monday = 1, ...).
 * For example, for `fr-FR`, returns 1 to indicate that the first day is Monday.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleFirstDayOfWeek(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].FirstDayOfWeek];
}
/**
 * Range of week days that are considered the week-end for the given locale.
 *
 * @param locale A locale code for the locale format rules to use.
 * @returns The range of day values, `[startDay, endDay]`.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleWeekEndRange(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].WeekendRange];
}
/**
 * Retrieves a localized date-value formatting string.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param width The format type.
 * @returns The localized formatting string.
 * @see {@link FormatWidth}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleDateFormat(locale, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return getLastDefinedValue(data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DateFormat], width);
}
/**
 * Retrieves a localized time-value formatting string.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param width The format type.
 * @returns The localized formatting string.
 * @see {@link FormatWidth}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)

 * @publicApi
 */
function getLocaleTimeFormat(locale, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return getLastDefinedValue(data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].TimeFormat], width);
}
/**
 * Retrieves a localized date-time formatting string.
 *
 * @param locale A locale code for the locale format rules to use.
 * @param width The format type.
 * @returns The localized formatting string.
 * @see {@link FormatWidth}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleDateTimeFormat(locale, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const dateTimeFormatData = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].DateTimeFormat];
  return getLastDefinedValue(dateTimeFormatData, width);
}
/**
 * Retrieves a localized number symbol that can be used to replace placeholders in number formats.
 * @param locale The locale code.
 * @param symbol The symbol to localize. Must be one of `NumberSymbol`.
 * @returns The character for the localized symbol.
 * @see {@link NumberSymbol}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleNumberSymbol(locale, symbol) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  const res = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][symbol];
  if (typeof res === 'undefined') {
    if (symbol === NumberSymbol.CurrencyDecimal) {
      return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][NumberSymbol.Decimal];
    } else if (symbol === NumberSymbol.CurrencyGroup) {
      return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberSymbols][NumberSymbol.Group];
    }
  }
  return res;
}
/**
 * Retrieves a number format for a given locale.
 *
 * Numbers are formatted using patterns, like `#,###.00`. For example, the pattern `#,###.00`
 * when used to format the number 12345.678 could result in "12'345,678". That would happen if the
 * grouping separator for your language is an apostrophe, and the decimal separator is a comma.
 *
 * <b>Important:</b> The characters `.` `,` `0` `#` (and others below) are special placeholders
 * that stand for the decimal separator, and so on, and are NOT real characters.
 * You must NOT "translate" the placeholders. For example, don't change `.` to `,` even though in
 * your language the decimal point is written with a comma. The symbols should be replaced by the
 * local equivalents, using the appropriate `NumberSymbol` for your language.
 *
 * Here are the special characters used in number patterns:
 *
 * | Symbol | Meaning |
 * |--------|---------|
 * | . | Replaced automatically by the character used for the decimal point. |
 * | , | Replaced by the "grouping" (thousands) separator. |
 * | 0 | Replaced by a digit (or zero if there aren't enough digits). |
 * | # | Replaced by a digit (or nothing if there aren't enough). |
 * | ¤ | Replaced by a currency symbol, such as $ or USD. |
 * | % | Marks a percent format. The % symbol may change position, but must be retained. |
 * | E | Marks a scientific format. The E symbol may change position, but must be retained. |
 * | ' | Special characters used as literal characters are quoted with ASCII single quotes. |
 *
 * @param locale A locale code for the locale format rules to use.
 * @param type The type of numeric value to be formatted (such as `Decimal` or `Currency`.)
 * @returns The localized format string.
 * @see {@link NumberFormatStyle}
 * @see [CLDR website](http://cldr.unicode.org/translation/number-patterns)
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleNumberFormat(locale, type) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].NumberFormats][type];
}
/**
 * Retrieves the symbol used to represent the currency for the main country
 * corresponding to a given locale. For example, '$' for `en-US`.
 *
 * @param locale A locale code for the locale format rules to use.
 * @returns The localized symbol character,
 * or `null` if the main country cannot be determined.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleCurrencySymbol(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].CurrencySymbol] || null;
}
/**
 * Retrieves the name of the currency for the main country corresponding
 * to a given locale. For example, 'US Dollar' for `en-US`.
 * @param locale A locale code for the locale format rules to use.
 * @returns The currency name,
 * or `null` if the main country cannot be determined.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleCurrencyName(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].CurrencyName] || null;
}
/**
 * Retrieves the default currency code for the given locale.
 *
 * The default is defined as the first currency which is still in use.
 *
 * @param locale The code of the locale whose currency code we want.
 * @returns The code of the default currency for the given locale.
 *
 * @publicApi
 */
function getLocaleCurrencyCode(locale) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵgetLocaleCurrencyCode"])(locale);
}
/**
 * Retrieves the currency values for a given locale.
 * @param locale A locale code for the locale format rules to use.
 * @returns The currency values.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 */
function getLocaleCurrencies(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Currencies];
}
/**
 * @alias core/ɵgetLocalePluralCase
 * @publicApi
 */
const getLocalePluralCase = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵgetLocalePluralCase"];
function checkFullData(data) {
  if (!data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData]) {
    throw new Error(`Missing extra locale data for the locale "${data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].LocaleId]}". Use "registerLocaleData" to load new data. See the "I18n guide" on angular.io to know more.`);
  }
}
/**
 * Retrieves locale-specific rules used to determine which day period to use
 * when more than one period is defined for a locale.
 *
 * There is a rule for each defined day period. The
 * first rule is applied to the first day period and so on.
 * Fall back to AM/PM when no rules are available.
 *
 * A rule can specify a period as time range, or as a single time value.
 *
 * This functionality is only available when you have loaded the full locale data.
 * See the ["I18n guide"](guide/i18n-common-format-data-locale).
 *
 * @param locale A locale code for the locale format rules to use.
 * @returns The rules for the locale, a single time value or array of *from-time, to-time*,
 * or null if no periods are available.
 *
 * @see {@link getLocaleExtraDayPeriods}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleExtraDayPeriodRules(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  checkFullData(data);
  const rules = data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][2 /* ɵExtraLocaleDataIndex.ExtraDayPeriodsRules */] || [];
  return rules.map(rule => {
    if (typeof rule === 'string') {
      return extractTime(rule);
    }
    return [extractTime(rule[0]), extractTime(rule[1])];
  });
}
/**
 * Retrieves locale-specific day periods, which indicate roughly how a day is broken up
 * in different languages.
 * For example, for `en-US`, periods are morning, noon, afternoon, evening, and midnight.
 *
 * This functionality is only available when you have loaded the full locale data.
 * See the ["I18n guide"](guide/i18n-common-format-data-locale).
 *
 * @param locale A locale code for the locale format rules to use.
 * @param formStyle The required grammatical form.
 * @param width The required character width.
 * @returns The translated day-period strings.
 * @see {@link getLocaleExtraDayPeriodRules}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLocaleExtraDayPeriods(locale, formStyle, width) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  checkFullData(data);
  const dayPeriodsData = [data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][0 /* ɵExtraLocaleDataIndex.ExtraDayPeriodFormats */], data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].ExtraData][1 /* ɵExtraLocaleDataIndex.ExtraDayPeriodStandalone */]];
  const dayPeriods = getLastDefinedValue(dayPeriodsData, formStyle) || [];
  return getLastDefinedValue(dayPeriods, width) || [];
}
/**
 * Retrieves the writing direction of a specified locale
 * @param locale A locale code for the locale format rules to use.
 * @publicApi
 * @returns 'rtl' or 'ltr'
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 */
function getLocaleDirection(locale) {
  const data = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵfindLocaleData"])(locale);
  return data[_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵLocaleDataIndex"].Directionality];
}
/**
 * Retrieves the first value that is defined in an array, going backwards from an index position.
 *
 * To avoid repeating the same data (as when the "format" and "standalone" forms are the same)
 * add the first value to the locale data arrays, and add other values only if they are different.
 *
 * @param data The data array to retrieve from.
 * @param index A 0-based index into the array to start from.
 * @returns The value immediately before the given index position.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getLastDefinedValue(data, index) {
  for (let i = index; i > -1; i--) {
    if (typeof data[i] !== 'undefined') {
      return data[i];
    }
  }
  throw new Error('Locale data API: locale data undefined');
}
/**
 * Extracts the hours and minutes from a string like "15:45"
 */
function extractTime(time) {
  const [h, m] = time.split(':');
  return {
    hours: +h,
    minutes: +m
  };
}
/**
 * Retrieves the currency symbol for a given currency code.
 *
 * For example, for the default `en-US` locale, the code `USD` can
 * be represented by the narrow symbol `$` or the wide symbol `US$`.
 *
 * @param code The currency code.
 * @param format The format, `wide` or `narrow`.
 * @param locale A locale code for the locale format rules to use.
 *
 * @returns The symbol, or the currency code if no symbol is available.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getCurrencySymbol(code, format, locale = 'en') {
  const currency = getLocaleCurrencies(locale)[code] || CURRENCIES_EN[code] || [];
  const symbolNarrow = currency[1 /* ɵCurrencyIndex.SymbolNarrow */];
  if (format === 'narrow' && typeof symbolNarrow === 'string') {
    return symbolNarrow;
  }
  return currency[0 /* ɵCurrencyIndex.Symbol */] || code;
}
// Most currencies have cents, that's why the default is 2
const DEFAULT_NB_OF_CURRENCY_DIGITS = 2;
/**
 * Reports the number of decimal digits for a given currency.
 * The value depends upon the presence of cents in that particular currency.
 *
 * @param code The currency code.
 * @returns The number of decimal digits, typically 0 or 2.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function getNumberOfCurrencyDigits(code) {
  let digits;
  const currency = CURRENCIES_EN[code];
  if (currency) {
    digits = currency[2 /* ɵCurrencyIndex.NbOfDigits */];
  }
  return typeof digits === 'number' ? digits : DEFAULT_NB_OF_CURRENCY_DIGITS;
}
const ISO8601_DATE_REGEX = /^(\d{4,})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;
//    1        2       3         4          5          6          7          8  9     10      11
const NAMED_FORMATS = {};
const DATE_FORMATS_SPLIT = /((?:[^BEGHLMOSWYZabcdhmswyz']+)|(?:'(?:[^']|'')*')|(?:G{1,5}|y{1,4}|Y{1,4}|M{1,5}|L{1,5}|w{1,2}|W{1}|d{1,2}|E{1,6}|c{1,6}|a{1,5}|b{1,5}|B{1,5}|h{1,2}|H{1,2}|m{1,2}|s{1,2}|S{1,3}|z{1,4}|Z{1,5}|O{1,4}))([\s\S]*)/;
var ZoneWidth;
(function (ZoneWidth) {
  ZoneWidth[ZoneWidth["Short"] = 0] = "Short";
  ZoneWidth[ZoneWidth["ShortGMT"] = 1] = "ShortGMT";
  ZoneWidth[ZoneWidth["Long"] = 2] = "Long";
  ZoneWidth[ZoneWidth["Extended"] = 3] = "Extended";
})(ZoneWidth || (ZoneWidth = {}));
var DateType;
(function (DateType) {
  DateType[DateType["FullYear"] = 0] = "FullYear";
  DateType[DateType["Month"] = 1] = "Month";
  DateType[DateType["Date"] = 2] = "Date";
  DateType[DateType["Hours"] = 3] = "Hours";
  DateType[DateType["Minutes"] = 4] = "Minutes";
  DateType[DateType["Seconds"] = 5] = "Seconds";
  DateType[DateType["FractionalSeconds"] = 6] = "FractionalSeconds";
  DateType[DateType["Day"] = 7] = "Day";
})(DateType || (DateType = {}));
var TranslationType;
(function (TranslationType) {
  TranslationType[TranslationType["DayPeriods"] = 0] = "DayPeriods";
  TranslationType[TranslationType["Days"] = 1] = "Days";
  TranslationType[TranslationType["Months"] = 2] = "Months";
  TranslationType[TranslationType["Eras"] = 3] = "Eras";
})(TranslationType || (TranslationType = {}));
/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a date according to locale rules.
 *
 * @param value The date to format, as a Date, or a number (milliseconds since UTC epoch)
 * or an [ISO date-time string](https://www.w3.org/TR/NOTE-datetime).
 * @param format The date-time components to include. See `DatePipe` for details.
 * @param locale A locale code for the locale format rules to use.
 * @param timezone The time zone. A time zone offset from GMT (such as `'+0430'`),
 * or a standard UTC/GMT or continental US time zone abbreviation.
 * If not specified, uses host system settings.
 *
 * @returns The formatted date string.
 *
 * @see {@link DatePipe}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function formatDate(value, format, locale, timezone) {
  let date = toDate(value);
  const namedFormat = getNamedFormat(locale, format);
  format = namedFormat || format;
  let parts = [];
  let match;
  while (format) {
    match = DATE_FORMATS_SPLIT.exec(format);
    if (match) {
      parts = parts.concat(match.slice(1));
      const part = parts.pop();
      if (!part) {
        break;
      }
      format = part;
    } else {
      parts.push(format);
      break;
    }
  }
  let dateTimezoneOffset = date.getTimezoneOffset();
  if (timezone) {
    dateTimezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
    date = convertTimezoneToLocal(date, timezone, true);
  }
  let text = '';
  parts.forEach(value => {
    const dateFormatter = getDateFormatter(value);
    text += dateFormatter ? dateFormatter(date, locale, dateTimezoneOffset) : value === "''" ? "'" : value.replace(/(^'|'$)/g, '').replace(/''/g, "'");
  });
  return text;
}
/**
 * Create a new Date object with the given date value, and the time set to midnight.
 *
 * We cannot use `new Date(year, month, date)` because it maps years between 0 and 99 to 1900-1999.
 * See: https://github.com/angular/angular/issues/40377
 *
 * Note that this function returns a Date object whose time is midnight in the current locale's
 * timezone. In the future we might want to change this to be midnight in UTC, but this would be a
 * considerable breaking change.
 */
function createDate(year, month, date) {
  // The `newDate` is set to midnight (UTC) on January 1st 1970.
  // - In PST this will be December 31st 1969 at 4pm.
  // - In GMT this will be January 1st 1970 at 1am.
  // Note that they even have different years, dates and months!
  const newDate = new Date(0);
  // `setFullYear()` allows years like 0001 to be set correctly. This function does not
  // change the internal time of the date.
  // Consider calling `setFullYear(2019, 8, 20)` (September 20, 2019).
  // - In PST this will now be September 20, 2019 at 4pm
  // - In GMT this will now be September 20, 2019 at 1am
  newDate.setFullYear(year, month, date);
  // We want the final date to be at local midnight, so we reset the time.
  // - In PST this will now be September 20, 2019 at 12am
  // - In GMT this will now be September 20, 2019 at 12am
  newDate.setHours(0, 0, 0);
  return newDate;
}
function getNamedFormat(locale, format) {
  const localeId = getLocaleId(locale);
  NAMED_FORMATS[localeId] ??= {};
  if (NAMED_FORMATS[localeId][format]) {
    return NAMED_FORMATS[localeId][format];
  }
  let formatValue = '';
  switch (format) {
    case 'shortDate':
      formatValue = getLocaleDateFormat(locale, FormatWidth.Short);
      break;
    case 'mediumDate':
      formatValue = getLocaleDateFormat(locale, FormatWidth.Medium);
      break;
    case 'longDate':
      formatValue = getLocaleDateFormat(locale, FormatWidth.Long);
      break;
    case 'fullDate':
      formatValue = getLocaleDateFormat(locale, FormatWidth.Full);
      break;
    case 'shortTime':
      formatValue = getLocaleTimeFormat(locale, FormatWidth.Short);
      break;
    case 'mediumTime':
      formatValue = getLocaleTimeFormat(locale, FormatWidth.Medium);
      break;
    case 'longTime':
      formatValue = getLocaleTimeFormat(locale, FormatWidth.Long);
      break;
    case 'fullTime':
      formatValue = getLocaleTimeFormat(locale, FormatWidth.Full);
      break;
    case 'short':
      const shortTime = getNamedFormat(locale, 'shortTime');
      const shortDate = getNamedFormat(locale, 'shortDate');
      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Short), [shortTime, shortDate]);
      break;
    case 'medium':
      const mediumTime = getNamedFormat(locale, 'mediumTime');
      const mediumDate = getNamedFormat(locale, 'mediumDate');
      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Medium), [mediumTime, mediumDate]);
      break;
    case 'long':
      const longTime = getNamedFormat(locale, 'longTime');
      const longDate = getNamedFormat(locale, 'longDate');
      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Long), [longTime, longDate]);
      break;
    case 'full':
      const fullTime = getNamedFormat(locale, 'fullTime');
      const fullDate = getNamedFormat(locale, 'fullDate');
      formatValue = formatDateTime(getLocaleDateTimeFormat(locale, FormatWidth.Full), [fullTime, fullDate]);
      break;
  }
  if (formatValue) {
    NAMED_FORMATS[localeId][format] = formatValue;
  }
  return formatValue;
}
function formatDateTime(str, opt_values) {
  if (opt_values) {
    str = str.replace(/\{([^}]+)}/g, function (match, key) {
      return opt_values != null && key in opt_values ? opt_values[key] : match;
    });
  }
  return str;
}
function padNumber(num, digits, minusSign = '-', trim, negWrap) {
  let neg = '';
  if (num < 0 || negWrap && num <= 0) {
    if (negWrap) {
      num = -num + 1;
    } else {
      num = -num;
      neg = minusSign;
    }
  }
  let strNum = String(num);
  while (strNum.length < digits) {
    strNum = '0' + strNum;
  }
  if (trim) {
    strNum = strNum.slice(strNum.length - digits);
  }
  return neg + strNum;
}
function formatFractionalSeconds(milliseconds, digits) {
  const strMs = padNumber(milliseconds, 3);
  return strMs.substring(0, digits);
}
/**
 * Returns a date formatter that transforms a date into its locale digit representation
 */
function dateGetter(name, size, offset = 0, trim = false, negWrap = false) {
  return function (date, locale) {
    let part = getDatePart(name, date);
    if (offset > 0 || part > -offset) {
      part += offset;
    }
    if (name === DateType.Hours) {
      if (part === 0 && offset === -12) {
        part = 12;
      }
    } else if (name === DateType.FractionalSeconds) {
      return formatFractionalSeconds(part, size);
    }
    const localeMinus = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
    return padNumber(part, size, localeMinus, trim, negWrap);
  };
}
function getDatePart(part, date) {
  switch (part) {
    case DateType.FullYear:
      return date.getFullYear();
    case DateType.Month:
      return date.getMonth();
    case DateType.Date:
      return date.getDate();
    case DateType.Hours:
      return date.getHours();
    case DateType.Minutes:
      return date.getMinutes();
    case DateType.Seconds:
      return date.getSeconds();
    case DateType.FractionalSeconds:
      return date.getMilliseconds();
    case DateType.Day:
      return date.getDay();
    default:
      throw new Error(`Unknown DateType value "${part}".`);
  }
}
/**
 * Returns a date formatter that transforms a date into its locale string representation
 */
function dateStrGetter(name, width, form = FormStyle.Format, extended = false) {
  return function (date, locale) {
    return getDateTranslation(date, locale, name, width, form, extended);
  };
}
/**
 * Returns the locale translation of a date for a given form, type and width
 */
function getDateTranslation(date, locale, name, width, form, extended) {
  switch (name) {
    case TranslationType.Months:
      return getLocaleMonthNames(locale, form, width)[date.getMonth()];
    case TranslationType.Days:
      return getLocaleDayNames(locale, form, width)[date.getDay()];
    case TranslationType.DayPeriods:
      const currentHours = date.getHours();
      const currentMinutes = date.getMinutes();
      if (extended) {
        const rules = getLocaleExtraDayPeriodRules(locale);
        const dayPeriods = getLocaleExtraDayPeriods(locale, form, width);
        const index = rules.findIndex(rule => {
          if (Array.isArray(rule)) {
            // morning, afternoon, evening, night
            const [from, to] = rule;
            const afterFrom = currentHours >= from.hours && currentMinutes >= from.minutes;
            const beforeTo = currentHours < to.hours || currentHours === to.hours && currentMinutes < to.minutes;
            // We must account for normal rules that span a period during the day (e.g. 6am-9am)
            // where `from` is less (earlier) than `to`. But also rules that span midnight (e.g.
            // 10pm - 5am) where `from` is greater (later!) than `to`.
            //
            // In the first case the current time must be BOTH after `from` AND before `to`
            // (e.g. 8am is after 6am AND before 10am).
            //
            // In the second case the current time must be EITHER after `from` OR before `to`
            // (e.g. 4am is before 5am but not after 10pm; and 11pm is not before 5am but it is
            // after 10pm).
            if (from.hours < to.hours) {
              if (afterFrom && beforeTo) {
                return true;
              }
            } else if (afterFrom || beforeTo) {
              return true;
            }
          } else {
            // noon or midnight
            if (rule.hours === currentHours && rule.minutes === currentMinutes) {
              return true;
            }
          }
          return false;
        });
        if (index !== -1) {
          return dayPeriods[index];
        }
      }
      // if no rules for the day periods, we use am/pm by default
      return getLocaleDayPeriods(locale, form, width)[currentHours < 12 ? 0 : 1];
    case TranslationType.Eras:
      return getLocaleEraNames(locale, width)[date.getFullYear() <= 0 ? 0 : 1];
    default:
      // This default case is not needed by TypeScript compiler, as the switch is exhaustive.
      // However Closure Compiler does not understand that and reports an error in typed mode.
      // The `throw new Error` below works around the problem, and the unexpected: never variable
      // makes sure tsc still checks this code is unreachable.
      const unexpected = name;
      throw new Error(`unexpected translation type ${unexpected}`);
  }
}
/**
 * Returns a date formatter that transforms a date and an offset into a timezone with ISO8601 or
 * GMT format depending on the width (eg: short = +0430, short:GMT = GMT+4, long = GMT+04:30,
 * extended = +04:30)
 */
function timeZoneGetter(width) {
  return function (date, locale, offset) {
    const zone = -1 * offset;
    const minusSign = getLocaleNumberSymbol(locale, NumberSymbol.MinusSign);
    const hours = zone > 0 ? Math.floor(zone / 60) : Math.ceil(zone / 60);
    switch (width) {
      case ZoneWidth.Short:
        return (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + padNumber(Math.abs(zone % 60), 2, minusSign);
      case ZoneWidth.ShortGMT:
        return 'GMT' + (zone >= 0 ? '+' : '') + padNumber(hours, 1, minusSign);
      case ZoneWidth.Long:
        return 'GMT' + (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + ':' + padNumber(Math.abs(zone % 60), 2, minusSign);
      case ZoneWidth.Extended:
        if (offset === 0) {
          return 'Z';
        } else {
          return (zone >= 0 ? '+' : '') + padNumber(hours, 2, minusSign) + ':' + padNumber(Math.abs(zone % 60), 2, minusSign);
        }
      default:
        throw new Error(`Unknown zone width "${width}"`);
    }
  };
}
const JANUARY = 0;
const THURSDAY = 4;
function getFirstThursdayOfYear(year) {
  const firstDayOfYear = createDate(year, JANUARY, 1).getDay();
  return createDate(year, 0, 1 + (firstDayOfYear <= THURSDAY ? THURSDAY : THURSDAY + 7) - firstDayOfYear);
}
/**
 *  ISO Week starts on day 1 (Monday) and ends with day 0 (Sunday)
 */
function getThursdayThisIsoWeek(datetime) {
  // getDay returns 0-6 range with sunday as 0.
  const currentDay = datetime.getDay();
  // On a Sunday, read the previous Thursday since ISO weeks start on Monday.
  const deltaToThursday = currentDay === 0 ? -3 : THURSDAY - currentDay;
  return createDate(datetime.getFullYear(), datetime.getMonth(), datetime.getDate() + deltaToThursday);
}
function weekGetter(size, monthBased = false) {
  return function (date, locale) {
    let result;
    if (monthBased) {
      const nbDaysBefore1stDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1).getDay() - 1;
      const today = date.getDate();
      result = 1 + Math.floor((today + nbDaysBefore1stDayOfMonth) / 7);
    } else {
      const thisThurs = getThursdayThisIsoWeek(date);
      // Some days of a year are part of next year according to ISO 8601.
      // Compute the firstThurs from the year of this week's Thursday
      const firstThurs = getFirstThursdayOfYear(thisThurs.getFullYear());
      const diff = thisThurs.getTime() - firstThurs.getTime();
      result = 1 + Math.round(diff / 6.048e8); // 6.048e8 ms per week
    }
    return padNumber(result, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
  };
}
/**
 * Returns a date formatter that provides the week-numbering year for the input date.
 */
function weekNumberingYearGetter(size, trim = false) {
  return function (date, locale) {
    const thisThurs = getThursdayThisIsoWeek(date);
    const weekNumberingYear = thisThurs.getFullYear();
    return padNumber(weekNumberingYear, size, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign), trim);
  };
}
const DATE_FORMATS = {};
// Based on CLDR formats:
// See complete list: http://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
// See also explanations: http://cldr.unicode.org/translation/date-time
// TODO(ocombe): support all missing cldr formats: U, Q, D, F, e, j, J, C, A, v, V, X, x
function getDateFormatter(format) {
  if (DATE_FORMATS[format]) {
    return DATE_FORMATS[format];
  }
  let formatter;
  switch (format) {
    // Era name (AD/BC)
    case 'G':
    case 'GG':
    case 'GGG':
      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Abbreviated);
      break;
    case 'GGGG':
      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Wide);
      break;
    case 'GGGGG':
      formatter = dateStrGetter(TranslationType.Eras, TranslationWidth.Narrow);
      break;
    // 1 digit representation of the year, e.g. (AD 1 => 1, AD 199 => 199)
    case 'y':
      formatter = dateGetter(DateType.FullYear, 1, 0, false, true);
      break;
    // 2 digit representation of the year, padded (00-99). (e.g. AD 2001 => 01, AD 2010 => 10)
    case 'yy':
      formatter = dateGetter(DateType.FullYear, 2, 0, true, true);
      break;
    // 3 digit representation of the year, padded (000-999). (e.g. AD 2001 => 01, AD 2010 => 10)
    case 'yyy':
      formatter = dateGetter(DateType.FullYear, 3, 0, false, true);
      break;
    // 4 digit representation of the year (e.g. AD 1 => 0001, AD 2010 => 2010)
    case 'yyyy':
      formatter = dateGetter(DateType.FullYear, 4, 0, false, true);
      break;
    // 1 digit representation of the week-numbering year, e.g. (AD 1 => 1, AD 199 => 199)
    case 'Y':
      formatter = weekNumberingYearGetter(1);
      break;
    // 2 digit representation of the week-numbering year, padded (00-99). (e.g. AD 2001 => 01, AD
    // 2010 => 10)
    case 'YY':
      formatter = weekNumberingYearGetter(2, true);
      break;
    // 3 digit representation of the week-numbering year, padded (000-999). (e.g. AD 1 => 001, AD
    // 2010 => 2010)
    case 'YYY':
      formatter = weekNumberingYearGetter(3);
      break;
    // 4 digit representation of the week-numbering year (e.g. AD 1 => 0001, AD 2010 => 2010)
    case 'YYYY':
      formatter = weekNumberingYearGetter(4);
      break;
    // Month of the year (1-12), numeric
    case 'M':
    case 'L':
      formatter = dateGetter(DateType.Month, 1, 1);
      break;
    case 'MM':
    case 'LL':
      formatter = dateGetter(DateType.Month, 2, 1);
      break;
    // Month of the year (January, ...), string, format
    case 'MMM':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Abbreviated);
      break;
    case 'MMMM':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Wide);
      break;
    case 'MMMMM':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Narrow);
      break;
    // Month of the year (January, ...), string, standalone
    case 'LLL':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Abbreviated, FormStyle.Standalone);
      break;
    case 'LLLL':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Wide, FormStyle.Standalone);
      break;
    case 'LLLLL':
      formatter = dateStrGetter(TranslationType.Months, TranslationWidth.Narrow, FormStyle.Standalone);
      break;
    // Week of the year (1, ... 52)
    case 'w':
      formatter = weekGetter(1);
      break;
    case 'ww':
      formatter = weekGetter(2);
      break;
    // Week of the month (1, ...)
    case 'W':
      formatter = weekGetter(1, true);
      break;
    // Day of the month (1-31)
    case 'd':
      formatter = dateGetter(DateType.Date, 1);
      break;
    case 'dd':
      formatter = dateGetter(DateType.Date, 2);
      break;
    // Day of the Week StandAlone (1, 1, Mon, Monday, M, Mo)
    case 'c':
    case 'cc':
      formatter = dateGetter(DateType.Day, 1);
      break;
    case 'ccc':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Abbreviated, FormStyle.Standalone);
      break;
    case 'cccc':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Wide, FormStyle.Standalone);
      break;
    case 'ccccc':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Narrow, FormStyle.Standalone);
      break;
    case 'cccccc':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Short, FormStyle.Standalone);
      break;
    // Day of the Week
    case 'E':
    case 'EE':
    case 'EEE':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Abbreviated);
      break;
    case 'EEEE':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Wide);
      break;
    case 'EEEEE':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Narrow);
      break;
    case 'EEEEEE':
      formatter = dateStrGetter(TranslationType.Days, TranslationWidth.Short);
      break;
    // Generic period of the day (am-pm)
    case 'a':
    case 'aa':
    case 'aaa':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated);
      break;
    case 'aaaa':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide);
      break;
    case 'aaaaa':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow);
      break;
    // Extended period of the day (midnight, at night, ...), standalone
    case 'b':
    case 'bb':
    case 'bbb':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated, FormStyle.Standalone, true);
      break;
    case 'bbbb':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide, FormStyle.Standalone, true);
      break;
    case 'bbbbb':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow, FormStyle.Standalone, true);
      break;
    // Extended period of the day (midnight, night, ...), standalone
    case 'B':
    case 'BB':
    case 'BBB':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Abbreviated, FormStyle.Format, true);
      break;
    case 'BBBB':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Wide, FormStyle.Format, true);
      break;
    case 'BBBBB':
      formatter = dateStrGetter(TranslationType.DayPeriods, TranslationWidth.Narrow, FormStyle.Format, true);
      break;
    // Hour in AM/PM, (1-12)
    case 'h':
      formatter = dateGetter(DateType.Hours, 1, -12);
      break;
    case 'hh':
      formatter = dateGetter(DateType.Hours, 2, -12);
      break;
    // Hour of the day (0-23)
    case 'H':
      formatter = dateGetter(DateType.Hours, 1);
      break;
    // Hour in day, padded (00-23)
    case 'HH':
      formatter = dateGetter(DateType.Hours, 2);
      break;
    // Minute of the hour (0-59)
    case 'm':
      formatter = dateGetter(DateType.Minutes, 1);
      break;
    case 'mm':
      formatter = dateGetter(DateType.Minutes, 2);
      break;
    // Second of the minute (0-59)
    case 's':
      formatter = dateGetter(DateType.Seconds, 1);
      break;
    case 'ss':
      formatter = dateGetter(DateType.Seconds, 2);
      break;
    // Fractional second
    case 'S':
      formatter = dateGetter(DateType.FractionalSeconds, 1);
      break;
    case 'SS':
      formatter = dateGetter(DateType.FractionalSeconds, 2);
      break;
    case 'SSS':
      formatter = dateGetter(DateType.FractionalSeconds, 3);
      break;
    // Timezone ISO8601 short format (-0430)
    case 'Z':
    case 'ZZ':
    case 'ZZZ':
      formatter = timeZoneGetter(ZoneWidth.Short);
      break;
    // Timezone ISO8601 extended format (-04:30)
    case 'ZZZZZ':
      formatter = timeZoneGetter(ZoneWidth.Extended);
      break;
    // Timezone GMT short format (GMT+4)
    case 'O':
    case 'OO':
    case 'OOO':
    // Should be location, but fallback to format O instead because we don't have the data yet
    case 'z':
    case 'zz':
    case 'zzz':
      formatter = timeZoneGetter(ZoneWidth.ShortGMT);
      break;
    // Timezone GMT long format (GMT+0430)
    case 'OOOO':
    case 'ZZZZ':
    // Should be location, but fallback to format O instead because we don't have the data yet
    case 'zzzz':
      formatter = timeZoneGetter(ZoneWidth.Long);
      break;
    default:
      return null;
  }
  DATE_FORMATS[format] = formatter;
  return formatter;
}
function timezoneToOffset(timezone, fallback) {
  // Support: IE 11 only, Edge 13-15+
  // IE/Edge do not "understand" colon (`:`) in timezone
  timezone = timezone.replace(/:/g, '');
  const requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
  return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
}
function addDateMinutes(date, minutes) {
  date = new Date(date.getTime());
  date.setMinutes(date.getMinutes() + minutes);
  return date;
}
function convertTimezoneToLocal(date, timezone, reverse) {
  const reverseValue = reverse ? -1 : 1;
  const dateTimezoneOffset = date.getTimezoneOffset();
  const timezoneOffset = timezoneToOffset(timezone, dateTimezoneOffset);
  return addDateMinutes(date, reverseValue * (timezoneOffset - dateTimezoneOffset));
}
/**
 * Converts a value to date.
 *
 * Supported input formats:
 * - `Date`
 * - number: timestamp
 * - string: numeric (e.g. "1234"), ISO and date strings in a format supported by
 *   [Date.parse()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
 *   Note: ISO strings without time return a date without timeoffset.
 *
 * Throws if unable to convert to a date.
 */
function toDate(value) {
  if (isDate(value)) {
    return value;
  }
  if (typeof value === 'number' && !isNaN(value)) {
    return new Date(value);
  }
  if (typeof value === 'string') {
    value = value.trim();
    if (/^(\d{4}(-\d{1,2}(-\d{1,2})?)?)$/.test(value)) {
      /* For ISO Strings without time the day, month and year must be extracted from the ISO String
      before Date creation to avoid time offset and errors in the new Date.
      If we only replace '-' with ',' in the ISO String ("2015,01,01"), and try to create a new
      date, some browsers (e.g. IE 9) will throw an invalid Date error.
      If we leave the '-' ("2015-01-01") and try to create a new Date("2015-01-01") the timeoffset
      is applied.
      Note: ISO months are 0 for January, 1 for February, ... */
      const [y, m = 1, d = 1] = value.split('-').map(val => +val);
      return createDate(y, m - 1, d);
    }
    const parsedNb = parseFloat(value);
    // any string that only contains numbers, like "1234" but not like "1234hello"
    if (!isNaN(value - parsedNb)) {
      return new Date(parsedNb);
    }
    let match;
    if (match = value.match(ISO8601_DATE_REGEX)) {
      return isoStringToDate(match);
    }
  }
  const date = new Date(value);
  if (!isDate(date)) {
    throw new Error(`Unable to convert "${value}" into a date`);
  }
  return date;
}
/**
 * Converts a date in ISO8601 to a Date.
 * Used instead of `Date.parse` because of browser discrepancies.
 */
function isoStringToDate(match) {
  const date = new Date(0);
  let tzHour = 0;
  let tzMin = 0;
  // match[8] means that the string contains "Z" (UTC) or a timezone like "+01:00" or "+0100"
  const dateSetter = match[8] ? date.setUTCFullYear : date.setFullYear;
  const timeSetter = match[8] ? date.setUTCHours : date.setHours;
  // if there is a timezone defined like "+01:00" or "+0100"
  if (match[9]) {
    tzHour = Number(match[9] + match[10]);
    tzMin = Number(match[9] + match[11]);
  }
  dateSetter.call(date, Number(match[1]), Number(match[2]) - 1, Number(match[3]));
  const h = Number(match[4] || 0) - tzHour;
  const m = Number(match[5] || 0) - tzMin;
  const s = Number(match[6] || 0);
  // The ECMAScript specification (https://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.11)
  // defines that `DateTime` milliseconds should always be rounded down, so that `999.9ms`
  // becomes `999ms`.
  const ms = Math.floor(parseFloat('0.' + (match[7] || 0)) * 1000);
  timeSetter.call(date, h, m, s, ms);
  return date;
}
function isDate(value) {
  return value instanceof Date && !isNaN(value.valueOf());
}
const NUMBER_FORMAT_REGEXP = /^(\d+)?\.((\d+)(-(\d+))?)?$/;
const MAX_DIGITS = 22;
const DECIMAL_SEP = '.';
const ZERO_CHAR = '0';
const PATTERN_SEP = ';';
const GROUP_SEP = ',';
const DIGIT_CHAR = '#';
const CURRENCY_CHAR = '¤';
const PERCENT_CHAR = '%';
/**
 * Transforms a number to a locale string based on a style and a format.
 */
function formatNumberToLocaleString(value, pattern, locale, groupSymbol, decimalSymbol, digitsInfo, isPercent = false) {
  let formattedText = '';
  let isZero = false;
  if (!isFinite(value)) {
    formattedText = getLocaleNumberSymbol(locale, NumberSymbol.Infinity);
  } else {
    let parsedNumber = parseNumber(value);
    if (isPercent) {
      parsedNumber = toPercent(parsedNumber);
    }
    let minInt = pattern.minInt;
    let minFraction = pattern.minFrac;
    let maxFraction = pattern.maxFrac;
    if (digitsInfo) {
      const parts = digitsInfo.match(NUMBER_FORMAT_REGEXP);
      if (parts === null) {
        throw new Error(`${digitsInfo} is not a valid digit info`);
      }
      const minIntPart = parts[1];
      const minFractionPart = parts[3];
      const maxFractionPart = parts[5];
      if (minIntPart != null) {
        minInt = parseIntAutoRadix(minIntPart);
      }
      if (minFractionPart != null) {
        minFraction = parseIntAutoRadix(minFractionPart);
      }
      if (maxFractionPart != null) {
        maxFraction = parseIntAutoRadix(maxFractionPart);
      } else if (minFractionPart != null && minFraction > maxFraction) {
        maxFraction = minFraction;
      }
    }
    roundNumber(parsedNumber, minFraction, maxFraction);
    let digits = parsedNumber.digits;
    let integerLen = parsedNumber.integerLen;
    const exponent = parsedNumber.exponent;
    let decimals = [];
    isZero = digits.every(d => !d);
    // pad zeros for small numbers
    for (; integerLen < minInt; integerLen++) {
      digits.unshift(0);
    }
    // pad zeros for small numbers
    for (; integerLen < 0; integerLen++) {
      digits.unshift(0);
    }
    // extract decimals digits
    if (integerLen > 0) {
      decimals = digits.splice(integerLen, digits.length);
    } else {
      decimals = digits;
      digits = [0];
    }
    // format the integer digits with grouping separators
    const groups = [];
    if (digits.length >= pattern.lgSize) {
      groups.unshift(digits.splice(-pattern.lgSize, digits.length).join(''));
    }
    while (digits.length > pattern.gSize) {
      groups.unshift(digits.splice(-pattern.gSize, digits.length).join(''));
    }
    if (digits.length) {
      groups.unshift(digits.join(''));
    }
    formattedText = groups.join(getLocaleNumberSymbol(locale, groupSymbol));
    // append the decimal digits
    if (decimals.length) {
      formattedText += getLocaleNumberSymbol(locale, decimalSymbol) + decimals.join('');
    }
    if (exponent) {
      formattedText += getLocaleNumberSymbol(locale, NumberSymbol.Exponential) + '+' + exponent;
    }
  }
  if (value < 0 && !isZero) {
    formattedText = pattern.negPre + formattedText + pattern.negSuf;
  } else {
    formattedText = pattern.posPre + formattedText + pattern.posSuf;
  }
  return formattedText;
}
/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a number as currency using locale rules.
 *
 * @param value The number to format.
 * @param locale A locale code for the locale format rules to use.
 * @param currency A string containing the currency symbol or its name,
 * such as "$" or "Canadian Dollar". Used in output string, but does not affect the operation
 * of the function.
 * @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217)
 * currency code, such as `USD` for the US dollar and `EUR` for the euro.
 * Used to determine the number of digits in the decimal part.
 * @param digitsInfo Decimal representation options, specified by a string in the following format:
 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
 *
 * @returns The formatted currency value.
 *
 * @see {@link formatNumber}
 * @see {@link DecimalPipe}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function formatCurrency(value, locale, currency, currencyCode, digitsInfo) {
  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Currency);
  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
  pattern.minFrac = getNumberOfCurrencyDigits(currencyCode);
  pattern.maxFrac = pattern.minFrac;
  const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.CurrencyGroup, NumberSymbol.CurrencyDecimal, digitsInfo);
  return res.replace(CURRENCY_CHAR, currency)
  // if we have 2 time the currency character, the second one is ignored
  .replace(CURRENCY_CHAR, '')
  // If there is a spacing between currency character and the value and
  // the currency character is suppressed by passing an empty string, the
  // spacing character would remain as part of the string. Then we
  // should remove it.
  .trim();
}
/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a number as a percentage according to locale rules.
 *
 * @param value The number to format.
 * @param locale A locale code for the locale format rules to use.
 * @param digitsInfo Decimal representation options, specified by a string in the following format:
 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
 *
 * @returns The formatted percentage value.
 *
 * @see {@link formatNumber}
 * @see {@link DecimalPipe}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 * @publicApi
 *
 */
function formatPercent(value, locale, digitsInfo) {
  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Percent);
  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
  const res = formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo, true);
  return res.replace(new RegExp(PERCENT_CHAR, 'g'), getLocaleNumberSymbol(locale, NumberSymbol.PercentSign));
}
/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a number as text, with group sizing, separator, and other
 * parameters based on the locale.
 *
 * @param value The number to format.
 * @param locale A locale code for the locale format rules to use.
 * @param digitsInfo Decimal representation options, specified by a string in the following format:
 * `{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}`. See `DecimalPipe` for more details.
 *
 * @returns The formatted text string.
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 *
 * @publicApi
 */
function formatNumber(value, locale, digitsInfo) {
  const format = getLocaleNumberFormat(locale, NumberFormatStyle.Decimal);
  const pattern = parseNumberFormat(format, getLocaleNumberSymbol(locale, NumberSymbol.MinusSign));
  return formatNumberToLocaleString(value, pattern, locale, NumberSymbol.Group, NumberSymbol.Decimal, digitsInfo);
}
function parseNumberFormat(format, minusSign = '-') {
  const p = {
    minInt: 1,
    minFrac: 0,
    maxFrac: 0,
    posPre: '',
    posSuf: '',
    negPre: '',
    negSuf: '',
    gSize: 0,
    lgSize: 0
  };
  const patternParts = format.split(PATTERN_SEP);
  const positive = patternParts[0];
  const negative = patternParts[1];
  const positiveParts = positive.indexOf(DECIMAL_SEP) !== -1 ? positive.split(DECIMAL_SEP) : [positive.substring(0, positive.lastIndexOf(ZERO_CHAR) + 1), positive.substring(positive.lastIndexOf(ZERO_CHAR) + 1)],
    integer = positiveParts[0],
    fraction = positiveParts[1] || '';
  p.posPre = integer.substring(0, integer.indexOf(DIGIT_CHAR));
  for (let i = 0; i < fraction.length; i++) {
    const ch = fraction.charAt(i);
    if (ch === ZERO_CHAR) {
      p.minFrac = p.maxFrac = i + 1;
    } else if (ch === DIGIT_CHAR) {
      p.maxFrac = i + 1;
    } else {
      p.posSuf += ch;
    }
  }
  const groups = integer.split(GROUP_SEP);
  p.gSize = groups[1] ? groups[1].length : 0;
  p.lgSize = groups[2] || groups[1] ? (groups[2] || groups[1]).length : 0;
  if (negative) {
    const trunkLen = positive.length - p.posPre.length - p.posSuf.length,
      pos = negative.indexOf(DIGIT_CHAR);
    p.negPre = negative.substring(0, pos).replace(/'/g, '');
    p.negSuf = negative.slice(pos + trunkLen).replace(/'/g, '');
  } else {
    p.negPre = minusSign + p.posPre;
    p.negSuf = p.posSuf;
  }
  return p;
}
// Transforms a parsed number into a percentage by multiplying it by 100
function toPercent(parsedNumber) {
  // if the number is 0, don't do anything
  if (parsedNumber.digits[0] === 0) {
    return parsedNumber;
  }
  // Getting the current number of decimals
  const fractionLen = parsedNumber.digits.length - parsedNumber.integerLen;
  if (parsedNumber.exponent) {
    parsedNumber.exponent += 2;
  } else {
    if (fractionLen === 0) {
      parsedNumber.digits.push(0, 0);
    } else if (fractionLen === 1) {
      parsedNumber.digits.push(0);
    }
    parsedNumber.integerLen += 2;
  }
  return parsedNumber;
}
/**
 * Parses a number.
 * Significant bits of this parse algorithm came from https://github.com/MikeMcl/big.js/
 */
function parseNumber(num) {
  let numStr = Math.abs(num) + '';
  let exponent = 0,
    digits,
    integerLen;
  let i, j, zeros;
  // Decimal point?
  if ((integerLen = numStr.indexOf(DECIMAL_SEP)) > -1) {
    numStr = numStr.replace(DECIMAL_SEP, '');
  }
  // Exponential form?
  if ((i = numStr.search(/e/i)) > 0) {
    // Work out the exponent.
    if (integerLen < 0) integerLen = i;
    integerLen += +numStr.slice(i + 1);
    numStr = numStr.substring(0, i);
  } else if (integerLen < 0) {
    // There was no decimal point or exponent so it is an integer.
    integerLen = numStr.length;
  }
  // Count the number of leading zeros.
  for (i = 0; numStr.charAt(i) === ZERO_CHAR; i++) {
    /* empty */
  }
  if (i === (zeros = numStr.length)) {
    // The digits are all zero.
    digits = [0];
    integerLen = 1;
  } else {
    // Count the number of trailing zeros
    zeros--;
    while (numStr.charAt(zeros) === ZERO_CHAR) zeros--;
    // Trailing zeros are insignificant so ignore them
    integerLen -= i;
    digits = [];
    // Convert string to array of digits without leading/trailing zeros.
    for (j = 0; i <= zeros; i++, j++) {
      digits[j] = Number(numStr.charAt(i));
    }
  }
  // If the number overflows the maximum allowed digits then use an exponent.
  if (integerLen > MAX_DIGITS) {
    digits = digits.splice(0, MAX_DIGITS - 1);
    exponent = integerLen - 1;
    integerLen = 1;
  }
  return {
    digits,
    exponent,
    integerLen
  };
}
/**
 * Round the parsed number to the specified number of decimal places
 * This function changes the parsedNumber in-place
 */
function roundNumber(parsedNumber, minFrac, maxFrac) {
  if (minFrac > maxFrac) {
    throw new Error(`The minimum number of digits after fraction (${minFrac}) is higher than the maximum (${maxFrac}).`);
  }
  let digits = parsedNumber.digits;
  let fractionLen = digits.length - parsedNumber.integerLen;
  const fractionSize = Math.min(Math.max(minFrac, fractionLen), maxFrac);
  // The index of the digit to where rounding is to occur
  let roundAt = fractionSize + parsedNumber.integerLen;
  let digit = digits[roundAt];
  if (roundAt > 0) {
    // Drop fractional digits beyond `roundAt`
    digits.splice(Math.max(parsedNumber.integerLen, roundAt));
    // Set non-fractional digits beyond `roundAt` to 0
    for (let j = roundAt; j < digits.length; j++) {
      digits[j] = 0;
    }
  } else {
    // We rounded to zero so reset the parsedNumber
    fractionLen = Math.max(0, fractionLen);
    parsedNumber.integerLen = 1;
    digits.length = Math.max(1, roundAt = fractionSize + 1);
    digits[0] = 0;
    for (let i = 1; i < roundAt; i++) digits[i] = 0;
  }
  if (digit >= 5) {
    if (roundAt - 1 < 0) {
      for (let k = 0; k > roundAt; k--) {
        digits.unshift(0);
        parsedNumber.integerLen++;
      }
      digits.unshift(1);
      parsedNumber.integerLen++;
    } else {
      digits[roundAt - 1]++;
    }
  }
  // Pad out with zeros to get the required fraction length
  for (; fractionLen < Math.max(0, fractionSize); fractionLen++) digits.push(0);
  let dropTrailingZeros = fractionSize !== 0;
  // Minimal length = nb of decimals required + current nb of integers
  // Any number besides that is optional and can be removed if it's a trailing 0
  const minLen = minFrac + parsedNumber.integerLen;
  // Do any carrying, e.g. a digit was rounded up to 10
  const carry = digits.reduceRight(function (carry, d, i, digits) {
    d = d + carry;
    digits[i] = d < 10 ? d : d - 10; // d % 10
    if (dropTrailingZeros) {
      // Do not keep meaningless fractional trailing zeros (e.g. 15.52000 --> 15.52)
      if (digits[i] === 0 && i >= minLen) {
        digits.pop();
      } else {
        dropTrailingZeros = false;
      }
    }
    return d >= 10 ? 1 : 0; // Math.floor(d / 10);
  }, 0);
  if (carry) {
    digits.unshift(carry);
    parsedNumber.integerLen++;
  }
}
function parseIntAutoRadix(text) {
  const result = parseInt(text);
  if (isNaN(result)) {
    throw new Error('Invalid integer literal when parsing ' + text);
  }
  return result;
}

/**
 * @publicApi
 */
class NgLocalization {
  static {
    this.ɵfac = function NgLocalization_Factory(t) {
      return new (t || NgLocalization)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgLocalization,
      factory: function NgLocalization_Factory(t) {
        let r = null;
        if (t) {
          r = new t();
        } else {
          r = (locale => new NgLocaleLocalization(locale))(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID));
        }
        return r;
      },
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLocalization, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: locale => new NgLocaleLocalization(locale),
      deps: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }], null, null);
})();
/**
 * Returns the plural category for a given value.
 * - "=value" when the case exists,
 * - the plural category otherwise
 */
function getPluralCategory(value, cases, ngLocalization, locale) {
  let key = `=${value}`;
  if (cases.indexOf(key) > -1) {
    return key;
  }
  key = ngLocalization.getPluralCategory(value, locale);
  if (cases.indexOf(key) > -1) {
    return key;
  }
  if (cases.indexOf('other') > -1) {
    return 'other';
  }
  throw new Error(`No plural message found for value "${value}"`);
}
/**
 * Returns the plural case based on the locale
 *
 * @publicApi
 */
class NgLocaleLocalization extends NgLocalization {
  constructor(locale) {
    super();
    this.locale = locale;
  }
  getPluralCategory(value, locale) {
    const plural = getLocalePluralCase(locale || this.locale)(value);
    switch (plural) {
      case Plural.Zero:
        return 'zero';
      case Plural.One:
        return 'one';
      case Plural.Two:
        return 'two';
      case Plural.Few:
        return 'few';
      case Plural.Many:
        return 'many';
      default:
        return 'other';
    }
  }
  static {
    this.ɵfac = function NgLocaleLocalization_Factory(t) {
      return new (t || NgLocaleLocalization)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgLocaleLocalization,
      factory: NgLocaleLocalization.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLocaleLocalization, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }], null);
})();

/**
 * Register global data to be used internally by Angular. See the
 * ["I18n guide"](guide/i18n-common-format-data-locale) to know how to import additional locale
 * data.
 *
 * The signature registerLocaleData(data: any, extraData?: any) is deprecated since v5.1
 *
 * @publicApi
 */
function registerLocaleData(data, localeId, extraData) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵregisterLocaleData"])(data, localeId, extraData);
}
function parseCookieValue(cookieStr, name) {
  name = encodeURIComponent(name);
  for (const cookie of cookieStr.split(';')) {
    const eqIndex = cookie.indexOf('=');
    const [cookieName, cookieValue] = eqIndex == -1 ? [cookie, ''] : [cookie.slice(0, eqIndex), cookie.slice(eqIndex + 1)];
    if (cookieName.trim() === name) {
      return decodeURIComponent(cookieValue);
    }
  }
  return null;
}
const WS_REGEXP = /\s+/;
const EMPTY_ARRAY = [];
/**
 * @ngModule CommonModule
 *
 * @usageNotes
 * ```
 *     <some-element [ngClass]="'first second'">...</some-element>
 *
 *     <some-element [ngClass]="['first', 'second']">...</some-element>
 *
 *     <some-element [ngClass]="{'first': true, 'second': true, 'third': false}">...</some-element>
 *
 *     <some-element [ngClass]="stringExp|arrayExp|objExp">...</some-element>
 *
 *     <some-element [ngClass]="{'class1 class2 class3' : true}">...</some-element>
 * ```
 *
 * @description
 *
 * Adds and removes CSS classes on an HTML element.
 *
 * The CSS classes are updated as follows, depending on the type of the expression evaluation:
 * - `string` - the CSS classes listed in the string (space delimited) are added,
 * - `Array` - the CSS classes declared as Array elements are added,
 * - `Object` - keys are CSS classes that get added when the expression given in the value
 *              evaluates to a truthy value, otherwise they are removed.
 *
 * @publicApi
 */
class NgClass {
  constructor(_ngEl, _renderer) {
    this._ngEl = _ngEl;
    this._renderer = _renderer;
    this.initialClasses = EMPTY_ARRAY;
    this.stateMap = new Map();
  }
  set klass(value) {
    this.initialClasses = value != null ? value.trim().split(WS_REGEXP) : EMPTY_ARRAY;
  }
  set ngClass(value) {
    this.rawClass = typeof value === 'string' ? value.trim().split(WS_REGEXP) : value;
  }
  /*
  The NgClass directive uses the custom change detection algorithm for its inputs. The custom
  algorithm is necessary since inputs are represented as complex object or arrays that need to be
  deeply-compared.
     This algorithm is perf-sensitive since NgClass is used very frequently and its poor performance
  might negatively impact runtime performance of the entire change detection cycle. The design of
  this algorithm is making sure that:
  - there is no unnecessary DOM manipulation (CSS classes are added / removed from the DOM only when
  needed), even if references to bound objects change;
  - there is no memory allocation if nothing changes (even relatively modest memory allocation
  during the change detection cycle can result in GC pauses for some of the CD cycles).
     The algorithm works by iterating over the set of bound classes, staring with [class] binding and
  then going over [ngClass] binding. For each CSS class name:
  - check if it was seen before (this information is tracked in the state map) and if its value
  changed;
  - mark it as "touched" - names that are not marked are not present in the latest set of binding
  and we can remove such class name from the internal data structures;
     After iteration over all the CSS class names we've got data structure with all the information
  necessary to synchronize changes to the DOM - it is enough to iterate over the state map, flush
  changes to the DOM and reset internal data structures so those are ready for the next change
  detection cycle.
   */
  ngDoCheck() {
    // classes from the [class] binding
    for (const klass of this.initialClasses) {
      this._updateState(klass, true);
    }
    // classes from the [ngClass] binding
    const rawClass = this.rawClass;
    if (Array.isArray(rawClass) || rawClass instanceof Set) {
      for (const klass of rawClass) {
        this._updateState(klass, true);
      }
    } else if (rawClass != null) {
      for (const klass of Object.keys(rawClass)) {
        this._updateState(klass, Boolean(rawClass[klass]));
      }
    }
    this._applyStateDiff();
  }
  _updateState(klass, nextEnabled) {
    const state = this.stateMap.get(klass);
    if (state !== undefined) {
      if (state.enabled !== nextEnabled) {
        state.changed = true;
        state.enabled = nextEnabled;
      }
      state.touched = true;
    } else {
      this.stateMap.set(klass, {
        enabled: nextEnabled,
        changed: true,
        touched: true
      });
    }
  }
  _applyStateDiff() {
    for (const stateEntry of this.stateMap) {
      const klass = stateEntry[0];
      const state = stateEntry[1];
      if (state.changed) {
        this._toggleClass(klass, state.enabled);
        state.changed = false;
      } else if (!state.touched) {
        // A class that was previously active got removed from the new collection of classes -
        // remove from the DOM as well.
        if (state.enabled) {
          this._toggleClass(klass, false);
        }
        this.stateMap.delete(klass);
      }
      state.touched = false;
    }
  }
  _toggleClass(klass, enabled) {
    if (ngDevMode) {
      if (typeof klass !== 'string') {
        throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(klass)}`);
      }
    }
    klass = klass.trim();
    if (klass.length > 0) {
      klass.split(WS_REGEXP).forEach(klass => {
        if (enabled) {
          this._renderer.addClass(this._ngEl.nativeElement, klass);
        } else {
          this._renderer.removeClass(this._ngEl.nativeElement, klass);
        }
      });
    }
  }
  static {
    this.ɵfac = function NgClass_Factory(t) {
      return new (t || NgClass)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgClass,
      selectors: [["", "ngClass", ""]],
      inputs: {
        klass: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "class", "klass"],
        ngClass: "ngClass"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgClass, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngClass]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }], {
    klass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['class']
    }],
    ngClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngClass']
    }]
  });
})();

/**
 * Instantiates a {@link Component} type and inserts its Host View into the current View.
 * `NgComponentOutlet` provides a declarative approach for dynamic component creation.
 *
 * `NgComponentOutlet` requires a component type, if a falsy value is set the view will clear and
 * any existing component will be destroyed.
 *
 * @usageNotes
 *
 * ### Fine tune control
 *
 * You can control the component creation process by using the following optional attributes:
 *
 * * `ngComponentOutletInputs`: Optional component inputs object, which will be bind to the
 * component.
 *
 * * `ngComponentOutletInjector`: Optional custom {@link Injector} that will be used as parent for
 * the Component. Defaults to the injector of the current view container.
 *
 * * `ngComponentOutletContent`: Optional list of projectable nodes to insert into the content
 * section of the component, if it exists.
 *
 * * `ngComponentOutletNgModule`: Optional NgModule class reference to allow loading another
 * module dynamically, then loading a component from that module.
 *
 * * `ngComponentOutletNgModuleFactory`: Deprecated config option that allows providing optional
 * NgModule factory to allow loading another module dynamically, then loading a component from that
 * module. Use `ngComponentOutletNgModule` instead.
 *
 * ### Syntax
 *
 * Simple
 * ```
 * <ng-container *ngComponentOutlet="componentTypeExpression"></ng-container>
 * ```
 *
 * With inputs
 * ```
 * <ng-container *ngComponentOutlet="componentTypeExpression;
 *                                   inputs: inputsExpression;">
 * </ng-container>
 * ```
 *
 * Customized injector/content
 * ```
 * <ng-container *ngComponentOutlet="componentTypeExpression;
 *                                   injector: injectorExpression;
 *                                   content: contentNodesExpression;">
 * </ng-container>
 * ```
 *
 * Customized NgModule reference
 * ```
 * <ng-container *ngComponentOutlet="componentTypeExpression;
 *                                   ngModule: ngModuleClass;">
 * </ng-container>
 * ```
 *
 * ### A simple example
 *
 * {@example common/ngComponentOutlet/ts/module.ts region='SimpleExample'}
 *
 * A more complete example with additional options:
 *
 * {@example common/ngComponentOutlet/ts/module.ts region='CompleteExample'}
 *
 * @publicApi
 * @ngModule CommonModule
 */
class NgComponentOutlet {
  constructor(_viewContainerRef) {
    this._viewContainerRef = _viewContainerRef;
    this.ngComponentOutlet = null;
    /**
     * A helper data structure that allows us to track inputs that were part of the
     * ngComponentOutletInputs expression. Tracking inputs is necessary for proper removal of ones
     * that are no longer referenced.
     */
    this._inputsUsed = new Map();
  }
  _needToReCreateNgModuleInstance(changes) {
    // Note: square brackets property accessor is safe for Closure compiler optimizations (the
    // `changes` argument of the `ngOnChanges` lifecycle hook retains the names of the fields that
    // were changed).
    return changes['ngComponentOutletNgModule'] !== undefined || changes['ngComponentOutletNgModuleFactory'] !== undefined;
  }
  _needToReCreateComponentInstance(changes) {
    // Note: square brackets property accessor is safe for Closure compiler optimizations (the
    // `changes` argument of the `ngOnChanges` lifecycle hook retains the names of the fields that
    // were changed).
    return changes['ngComponentOutlet'] !== undefined || changes['ngComponentOutletContent'] !== undefined || changes['ngComponentOutletInjector'] !== undefined || this._needToReCreateNgModuleInstance(changes);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (this._needToReCreateComponentInstance(changes)) {
      this._viewContainerRef.clear();
      this._inputsUsed.clear();
      this._componentRef = undefined;
      if (this.ngComponentOutlet) {
        const injector = this.ngComponentOutletInjector || this._viewContainerRef.parentInjector;
        if (this._needToReCreateNgModuleInstance(changes)) {
          this._moduleRef?.destroy();
          if (this.ngComponentOutletNgModule) {
            this._moduleRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createNgModule)(this.ngComponentOutletNgModule, getParentInjector(injector));
          } else if (this.ngComponentOutletNgModuleFactory) {
            this._moduleRef = this.ngComponentOutletNgModuleFactory.create(getParentInjector(injector));
          } else {
            this._moduleRef = undefined;
          }
        }
        this._componentRef = this._viewContainerRef.createComponent(this.ngComponentOutlet, {
          injector,
          ngModuleRef: this._moduleRef,
          projectableNodes: this.ngComponentOutletContent
        });
      }
    }
  }
  /** @nodoc */
  ngDoCheck() {
    if (this._componentRef) {
      if (this.ngComponentOutletInputs) {
        for (const inputName of Object.keys(this.ngComponentOutletInputs)) {
          this._inputsUsed.set(inputName, true);
        }
      }
      this._applyInputStateDiff(this._componentRef);
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    this._moduleRef?.destroy();
  }
  _applyInputStateDiff(componentRef) {
    for (const [inputName, touched] of this._inputsUsed) {
      if (!touched) {
        // The input that was previously active no longer exists and needs to be set to undefined.
        componentRef.setInput(inputName, undefined);
        this._inputsUsed.delete(inputName);
      } else {
        // Since touched is true, it can be asserted that the inputs object is not empty.
        componentRef.setInput(inputName, this.ngComponentOutletInputs[inputName]);
        this._inputsUsed.set(inputName, false);
      }
    }
  }
  static {
    this.ɵfac = function NgComponentOutlet_Factory(t) {
      return new (t || NgComponentOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgComponentOutlet,
      selectors: [["", "ngComponentOutlet", ""]],
      inputs: {
        ngComponentOutlet: "ngComponentOutlet",
        ngComponentOutletInputs: "ngComponentOutletInputs",
        ngComponentOutletInjector: "ngComponentOutletInjector",
        ngComponentOutletContent: "ngComponentOutletContent",
        ngComponentOutletNgModule: "ngComponentOutletNgModule",
        ngComponentOutletNgModuleFactory: "ngComponentOutletNgModuleFactory"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgComponentOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngComponentOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }], {
    ngComponentOutlet: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngComponentOutletInputs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngComponentOutletInjector: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngComponentOutletContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngComponentOutletNgModule: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngComponentOutletNgModuleFactory: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
// Helper function that returns an Injector instance of a parent NgModule.
function getParentInjector(injector) {
  const parentNgModule = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModuleRef);
  return parentNgModule.injector;
}

/**
 * @publicApi
 */
class NgForOfContext {
  constructor($implicit, ngForOf, index, count) {
    this.$implicit = $implicit;
    this.ngForOf = ngForOf;
    this.index = index;
    this.count = count;
  }
  get first() {
    return this.index === 0;
  }
  get last() {
    return this.index === this.count - 1;
  }
  get even() {
    return this.index % 2 === 0;
  }
  get odd() {
    return !this.even;
  }
}
/**
 * A [structural directive](guide/structural-directives) that renders
 * a template for each item in a collection.
 * The directive is placed on an element, which becomes the parent
 * of the cloned templates.
 *
 * The `ngForOf` directive is generally used in the
 * [shorthand form](guide/structural-directives#asterisk) `*ngFor`.
 * In this form, the template to be rendered for each iteration is the content
 * of an anchor element containing the directive.
 *
 * The following example shows the shorthand syntax with some options,
 * contained in an `<li>` element.
 *
 * ```
 * <li *ngFor="let item of items; index as i; trackBy: trackByFn">...</li>
 * ```
 *
 * The shorthand form expands into a long form that uses the `ngForOf` selector
 * on an `<ng-template>` element.
 * The content of the `<ng-template>` element is the `<li>` element that held the
 * short-form directive.
 *
 * Here is the expanded version of the short-form example.
 *
 * ```
 * <ng-template ngFor let-item [ngForOf]="items" let-i="index" [ngForTrackBy]="trackByFn">
 *   <li>...</li>
 * </ng-template>
 * ```
 *
 * Angular automatically expands the shorthand syntax as it compiles the template.
 * The context for each embedded view is logically merged to the current component
 * context according to its lexical position.
 *
 * When using the shorthand syntax, Angular allows only [one structural directive
 * on an element](guide/structural-directives#one-per-element).
 * If you want to iterate conditionally, for example,
 * put the `*ngIf` on a container element that wraps the `*ngFor` element.
 * For further discussion, see
 * [Structural Directives](guide/structural-directives#one-per-element).
 *
 * @usageNotes
 *
 * ### Local variables
 *
 * `NgForOf` provides exported values that can be aliased to local variables.
 * For example:
 *
 *  ```
 * <li *ngFor="let user of users; index as i; first as isFirst">
 *    {{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
 * </li>
 * ```
 *
 * The following exported values can be aliased to local variables:
 *
 * - `$implicit: T`: The value of the individual items in the iterable (`ngForOf`).
 * - `ngForOf: NgIterable<T>`: The value of the iterable expression. Useful when the expression is
 * more complex then a property access, for example when using the async pipe (`userStreams |
 * async`).
 * - `index: number`: The index of the current item in the iterable.
 * - `count: number`: The length of the iterable.
 * - `first: boolean`: True when the item is the first item in the iterable.
 * - `last: boolean`: True when the item is the last item in the iterable.
 * - `even: boolean`: True when the item has an even index in the iterable.
 * - `odd: boolean`: True when the item has an odd index in the iterable.
 *
 * ### Change propagation
 *
 * When the contents of the iterator changes, `NgForOf` makes the corresponding changes to the DOM:
 *
 * * When an item is added, a new instance of the template is added to the DOM.
 * * When an item is removed, its template instance is removed from the DOM.
 * * When items are reordered, their respective templates are reordered in the DOM.
 *
 * Angular uses object identity to track insertions and deletions within the iterator and reproduce
 * those changes in the DOM. This has important implications for animations and any stateful
 * controls that are present, such as `<input>` elements that accept user input. Inserted rows can
 * be animated in, deleted rows can be animated out, and unchanged rows retain any unsaved state
 * such as user input.
 * For more on animations, see [Transitions and Triggers](guide/transition-and-triggers).
 *
 * The identities of elements in the iterator can change while the data does not.
 * This can happen, for example, if the iterator is produced from an RPC to the server, and that
 * RPC is re-run. Even if the data hasn't changed, the second response produces objects with
 * different identities, and Angular must tear down the entire DOM and rebuild it (as if all old
 * elements were deleted and all new elements inserted).
 *
 * To avoid this expensive operation, you can customize the default tracking algorithm.
 * by supplying the `trackBy` option to `NgForOf`.
 * `trackBy` takes a function that has two arguments: `index` and `item`.
 * If `trackBy` is given, Angular tracks changes by the return value of the function.
 *
 * @see [Structural Directives](guide/structural-directives)
 * @ngModule CommonModule
 * @publicApi
 */
class NgForOf {
  /**
   * The value of the iterable expression, which can be used as a
   * [template input variable](guide/structural-directives#shorthand).
   */
  set ngForOf(ngForOf) {
    this._ngForOf = ngForOf;
    this._ngForOfDirty = true;
  }
  /**
   * Specifies a custom `TrackByFunction` to compute the identity of items in an iterable.
   *
   * If a custom `TrackByFunction` is not provided, `NgForOf` will use the item's [object
   * identity](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is)
   * as the key.
   *
   * `NgForOf` uses the computed key to associate items in an iterable with DOM elements
   * it produces for these items.
   *
   * A custom `TrackByFunction` is useful to provide good user experience in cases when items in an
   * iterable rendered using `NgForOf` have a natural identifier (for example, custom ID or a
   * primary key), and this iterable could be updated with new object instances that still
   * represent the same underlying entity (for example, when data is re-fetched from the server,
   * and the iterable is recreated and re-rendered, but most of the data is still the same).
   *
   * @see {@link TrackByFunction}
   */
  set ngForTrackBy(fn) {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && fn != null && typeof fn !== 'function') {
      console.warn(`trackBy must be a function, but received ${JSON.stringify(fn)}. ` + `See https://angular.io/api/common/NgForOf#change-propagation for more information.`);
    }
    this._trackByFn = fn;
  }
  get ngForTrackBy() {
    return this._trackByFn;
  }
  constructor(_viewContainer, _template, _differs) {
    this._viewContainer = _viewContainer;
    this._template = _template;
    this._differs = _differs;
    this._ngForOf = null;
    this._ngForOfDirty = true;
    this._differ = null;
  }
  /**
   * A reference to the template that is stamped out for each item in the iterable.
   * @see [template reference variable](guide/template-reference-variables)
   */
  set ngForTemplate(value) {
    // TODO(TS2.1): make TemplateRef<Partial<NgForRowOf<T>>> once we move to TS v2.1
    // The current type is too restrictive; a template that just uses index, for example,
    // should be acceptable.
    if (value) {
      this._template = value;
    }
  }
  /**
   * Applies the changes when needed.
   * @nodoc
   */
  ngDoCheck() {
    if (this._ngForOfDirty) {
      this._ngForOfDirty = false;
      // React on ngForOf changes only once all inputs have been initialized
      const value = this._ngForOf;
      if (!this._differ && value) {
        if (typeof ngDevMode === 'undefined' || ngDevMode) {
          try {
            // CAUTION: this logic is duplicated for production mode below, as the try-catch
            // is only present in development builds.
            this._differ = this._differs.find(value).create(this.ngForTrackBy);
          } catch {
            let errorMessage = `Cannot find a differ supporting object '${value}' of type '` + `${getTypeName(value)}'. NgFor only supports binding to Iterables, such as Arrays.`;
            if (typeof value === 'object') {
              errorMessage += ' Did you mean to use the keyvalue pipe?';
            }
            throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](-2200 /* RuntimeErrorCode.NG_FOR_MISSING_DIFFER */, errorMessage);
          }
        } else {
          // CAUTION: this logic is duplicated for development mode above, as the try-catch
          // is only present in development builds.
          this._differ = this._differs.find(value).create(this.ngForTrackBy);
        }
      }
    }
    if (this._differ) {
      const changes = this._differ.diff(this._ngForOf);
      if (changes) this._applyChanges(changes);
    }
  }
  _applyChanges(changes) {
    const viewContainer = this._viewContainer;
    changes.forEachOperation((item, adjustedPreviousIndex, currentIndex) => {
      if (item.previousIndex == null) {
        // NgForOf is never "null" or "undefined" here because the differ detected
        // that a new item needs to be inserted from the iterable. This implies that
        // there is an iterable value for "_ngForOf".
        viewContainer.createEmbeddedView(this._template, new NgForOfContext(item.item, this._ngForOf, -1, -1), currentIndex === null ? undefined : currentIndex);
      } else if (currentIndex == null) {
        viewContainer.remove(adjustedPreviousIndex === null ? undefined : adjustedPreviousIndex);
      } else if (adjustedPreviousIndex !== null) {
        const view = viewContainer.get(adjustedPreviousIndex);
        viewContainer.move(view, currentIndex);
        applyViewChange(view, item);
      }
    });
    for (let i = 0, ilen = viewContainer.length; i < ilen; i++) {
      const viewRef = viewContainer.get(i);
      const context = viewRef.context;
      context.index = i;
      context.count = ilen;
      context.ngForOf = this._ngForOf;
    }
    changes.forEachIdentityChange(record => {
      const viewRef = viewContainer.get(record.currentIndex);
      applyViewChange(viewRef, record);
    });
  }
  /**
   * Asserts the correct type of the context for the template that `NgForOf` will render.
   *
   * The presence of this method is a signal to the Ivy template type-check compiler that the
   * `NgForOf` structural directive renders its template with a specific context type.
   */
  static ngTemplateContextGuard(dir, ctx) {
    return true;
  }
  static {
    this.ɵfac = function NgForOf_Factory(t) {
      return new (t || NgForOf)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgForOf,
      selectors: [["", "ngFor", "", "ngForOf", ""]],
      inputs: {
        ngForOf: "ngForOf",
        ngForTrackBy: "ngForTrackBy",
        ngForTemplate: "ngForTemplate"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgForOf, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngFor][ngForOf]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.IterableDiffers
  }], {
    ngForOf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngForTrackBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngForTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
function applyViewChange(view, record) {
  view.context.$implicit = record.item;
}
function getTypeName(type) {
  return type['name'] || typeof type;
}

/**
 * A structural directive that conditionally includes a template based on the value of
 * an expression coerced to Boolean.
 * When the expression evaluates to true, Angular renders the template
 * provided in a `then` clause, and when  false or null,
 * Angular renders the template provided in an optional `else` clause. The default
 * template for the `else` clause is blank.
 *
 * A [shorthand form](guide/structural-directives#asterisk) of the directive,
 * `*ngIf="condition"`, is generally used, provided
 * as an attribute of the anchor element for the inserted template.
 * Angular expands this into a more explicit version, in which the anchor element
 * is contained in an `<ng-template>` element.
 *
 * Simple form with shorthand syntax:
 *
 * ```
 * <div *ngIf="condition">Content to render when condition is true.</div>
 * ```
 *
 * Simple form with expanded syntax:
 *
 * ```
 * <ng-template [ngIf]="condition"><div>Content to render when condition is
 * true.</div></ng-template>
 * ```
 *
 * Form with an "else" block:
 *
 * ```
 * <div *ngIf="condition; else elseBlock">Content to render when condition is true.</div>
 * <ng-template #elseBlock>Content to render when condition is false.</ng-template>
 * ```
 *
 * Shorthand form with "then" and "else" blocks:
 *
 * ```
 * <div *ngIf="condition; then thenBlock else elseBlock"></div>
 * <ng-template #thenBlock>Content to render when condition is true.</ng-template>
 * <ng-template #elseBlock>Content to render when condition is false.</ng-template>
 * ```
 *
 * Form with storing the value locally:
 *
 * ```
 * <div *ngIf="condition as value; else elseBlock">{{value}}</div>
 * <ng-template #elseBlock>Content to render when value is null.</ng-template>
 * ```
 *
 * @usageNotes
 *
 * The `*ngIf` directive is most commonly used to conditionally show an inline template,
 * as seen in the following  example.
 * The default `else` template is blank.
 *
 * {@example common/ngIf/ts/module.ts region='NgIfSimple'}
 *
 * ### Showing an alternative template using `else`
 *
 * To display a template when `expression` evaluates to false, use an `else` template
 * binding as shown in the following example.
 * The `else` binding points to an `<ng-template>`  element labeled `#elseBlock`.
 * The template can be defined anywhere in the component view, but is typically placed right after
 * `ngIf` for readability.
 *
 * {@example common/ngIf/ts/module.ts region='NgIfElse'}
 *
 * ### Using an external `then` template
 *
 * In the previous example, the then-clause template is specified inline, as the content of the
 * tag that contains the `ngIf` directive. You can also specify a template that is defined
 * externally, by referencing a labeled `<ng-template>` element. When you do this, you can
 * change which template to use at runtime, as shown in the following example.
 *
 * {@example common/ngIf/ts/module.ts region='NgIfThenElse'}
 *
 * ### Storing a conditional result in a variable
 *
 * You might want to show a set of properties from the same object. If you are waiting
 * for asynchronous data, the object can be undefined.
 * In this case, you can use `ngIf` and store the result of the condition in a local
 * variable as shown in the following example.
 *
 * {@example common/ngIf/ts/module.ts region='NgIfAs'}
 *
 * This code uses only one `AsyncPipe`, so only one subscription is created.
 * The conditional statement stores the result of `userStream|async` in the local variable `user`.
 * You can then bind the local `user` repeatedly.
 *
 * The conditional displays the data only if `userStream` returns a value,
 * so you don't need to use the
 * safe-navigation-operator (`?.`)
 * to guard against null values when accessing properties.
 * You can display an alternative template while waiting for the data.
 *
 * ### Shorthand syntax
 *
 * The shorthand syntax `*ngIf` expands into two separate template specifications
 * for the "then" and "else" clauses. For example, consider the following shorthand statement,
 * that is meant to show a loading page while waiting for data to be loaded.
 *
 * ```
 * <div class="hero-list" *ngIf="heroes else loading">
 *  ...
 * </div>
 *
 * <ng-template #loading>
 *  <div>Loading...</div>
 * </ng-template>
 * ```
 *
 * You can see that the "else" clause references the `<ng-template>`
 * with the `#loading` label, and the template for the "then" clause
 * is provided as the content of the anchor element.
 *
 * However, when Angular expands the shorthand syntax, it creates
 * another `<ng-template>` tag, with `ngIf` and `ngIfElse` directives.
 * The anchor element containing the template for the "then" clause becomes
 * the content of this unlabeled `<ng-template>` tag.
 *
 * ```
 * <ng-template [ngIf]="heroes" [ngIfElse]="loading">
 *  <div class="hero-list">
 *   ...
 *  </div>
 * </ng-template>
 *
 * <ng-template #loading>
 *  <div>Loading...</div>
 * </ng-template>
 * ```
 *
 * The presence of the implicit template object has implications for the nesting of
 * structural directives. For more on this subject, see
 * [Structural Directives](guide/structural-directives#one-per-element).
 *
 * @ngModule CommonModule
 * @publicApi
 */
class NgIf {
  constructor(_viewContainer, templateRef) {
    this._viewContainer = _viewContainer;
    this._context = new NgIfContext();
    this._thenTemplateRef = null;
    this._elseTemplateRef = null;
    this._thenViewRef = null;
    this._elseViewRef = null;
    this._thenTemplateRef = templateRef;
  }
  /**
   * The Boolean expression to evaluate as the condition for showing a template.
   */
  set ngIf(condition) {
    this._context.$implicit = this._context.ngIf = condition;
    this._updateView();
  }
  /**
   * A template to show if the condition expression evaluates to true.
   */
  set ngIfThen(templateRef) {
    assertTemplate('ngIfThen', templateRef);
    this._thenTemplateRef = templateRef;
    this._thenViewRef = null; // clear previous view if any.
    this._updateView();
  }
  /**
   * A template to show if the condition expression evaluates to false.
   */
  set ngIfElse(templateRef) {
    assertTemplate('ngIfElse', templateRef);
    this._elseTemplateRef = templateRef;
    this._elseViewRef = null; // clear previous view if any.
    this._updateView();
  }
  _updateView() {
    if (this._context.$implicit) {
      if (!this._thenViewRef) {
        this._viewContainer.clear();
        this._elseViewRef = null;
        if (this._thenTemplateRef) {
          this._thenViewRef = this._viewContainer.createEmbeddedView(this._thenTemplateRef, this._context);
        }
      }
    } else {
      if (!this._elseViewRef) {
        this._viewContainer.clear();
        this._thenViewRef = null;
        if (this._elseTemplateRef) {
          this._elseViewRef = this._viewContainer.createEmbeddedView(this._elseTemplateRef, this._context);
        }
      }
    }
  }
  /**
   * Asserts the correct type of the context for the template that `NgIf` will render.
   *
   * The presence of this method is a signal to the Ivy template type-check compiler that the
   * `NgIf` structural directive renders its template with a specific context type.
   */
  static ngTemplateContextGuard(dir, ctx) {
    return true;
  }
  static {
    this.ɵfac = function NgIf_Factory(t) {
      return new (t || NgIf)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgIf,
      selectors: [["", "ngIf", ""]],
      inputs: {
        ngIf: "ngIf",
        ngIfThen: "ngIfThen",
        ngIfElse: "ngIfElse"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgIf, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngIf]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], {
    ngIf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngIfThen: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngIfElse: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @publicApi
 */
class NgIfContext {
  constructor() {
    this.$implicit = null;
    this.ngIf = null;
  }
}
function assertTemplate(property, templateRef) {
  const isTemplateRefOrNull = !!(!templateRef || templateRef.createEmbeddedView);
  if (!isTemplateRefOrNull) {
    throw new Error(`${property} must be a TemplateRef, but received '${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(templateRef)}'.`);
  }
}

/**
 * A constant indicating a type of comparison that NgSwitch uses to match cases. Extracted to a
 * separate file to facilitate G3 patches.
 */
const NG_SWITCH_USE_STRICT_EQUALS = true;
class SwitchView {
  constructor(_viewContainerRef, _templateRef) {
    this._viewContainerRef = _viewContainerRef;
    this._templateRef = _templateRef;
    this._created = false;
  }
  create() {
    this._created = true;
    this._viewContainerRef.createEmbeddedView(this._templateRef);
  }
  destroy() {
    this._created = false;
    this._viewContainerRef.clear();
  }
  enforceState(created) {
    if (created && !this._created) {
      this.create();
    } else if (!created && this._created) {
      this.destroy();
    }
  }
}
/**
 * @ngModule CommonModule
 *
 * @description
 * The `[ngSwitch]` directive on a container specifies an expression to match against.
 * The expressions to match are provided by `ngSwitchCase` directives on views within the container.
 * - Every view that matches is rendered.
 * - If there are no matches, a view with the `ngSwitchDefault` directive is rendered.
 * - Elements within the `[NgSwitch]` statement but outside of any `NgSwitchCase`
 * or `ngSwitchDefault` directive are preserved at the location.
 *
 * @usageNotes
 * Define a container element for the directive, and specify the switch expression
 * to match against as an attribute:
 *
 * ```
 * <container-element [ngSwitch]="switch_expression">
 * ```
 *
 * Within the container, `*ngSwitchCase` statements specify the match expressions
 * as attributes. Include `*ngSwitchDefault` as the final case.
 *
 * ```
 * <container-element [ngSwitch]="switch_expression">
 *    <some-element *ngSwitchCase="match_expression_1">...</some-element>
 * ...
 *    <some-element *ngSwitchDefault>...</some-element>
 * </container-element>
 * ```
 *
 * ### Usage Examples
 *
 * The following example shows how to use more than one case to display the same view:
 *
 * ```
 * <container-element [ngSwitch]="switch_expression">
 *   <!-- the same view can be shown in more than one case -->
 *   <some-element *ngSwitchCase="match_expression_1">...</some-element>
 *   <some-element *ngSwitchCase="match_expression_2">...</some-element>
 *   <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
 *   <!--default case when there are no matches -->
 *   <some-element *ngSwitchDefault>...</some-element>
 * </container-element>
 * ```
 *
 * The following example shows how cases can be nested:
 * ```
 * <container-element [ngSwitch]="switch_expression">
 *       <some-element *ngSwitchCase="match_expression_1">...</some-element>
 *       <some-element *ngSwitchCase="match_expression_2">...</some-element>
 *       <some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
 *       <ng-container *ngSwitchCase="match_expression_3">
 *         <!-- use a ng-container to group multiple root nodes -->
 *         <inner-element></inner-element>
 *         <inner-other-element></inner-other-element>
 *       </ng-container>
 *       <some-element *ngSwitchDefault>...</some-element>
 *     </container-element>
 * ```
 *
 * @publicApi
 * @see {@link NgSwitchCase}
 * @see {@link NgSwitchDefault}
 * @see [Structural Directives](guide/structural-directives)
 *
 */
class NgSwitch {
  constructor() {
    this._defaultViews = [];
    this._defaultUsed = false;
    this._caseCount = 0;
    this._lastCaseCheckIndex = 0;
    this._lastCasesMatched = false;
  }
  set ngSwitch(newValue) {
    this._ngSwitch = newValue;
    if (this._caseCount === 0) {
      this._updateDefaultCases(true);
    }
  }
  /** @internal */
  _addCase() {
    return this._caseCount++;
  }
  /** @internal */
  _addDefault(view) {
    this._defaultViews.push(view);
  }
  /** @internal */
  _matchCase(value) {
    const matched = NG_SWITCH_USE_STRICT_EQUALS ? value === this._ngSwitch : value == this._ngSwitch;
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && matched !== (value == this._ngSwitch)) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2001 /* RuntimeErrorCode.EQUALITY_NG_SWITCH_DIFFERENCE */, 'As of Angular v17 the NgSwitch directive uses strict equality comparison === instead of == to match different cases. ' + `Previously the case value "${stringifyValue(value)}" matched switch expression value "${stringifyValue(this._ngSwitch)}", but this is no longer the case with the stricter equality check. ` + 'Your comparison results return different results using === vs. == and you should adjust your ngSwitch expression and / or values to conform with the strict equality requirements.'));
    }
    this._lastCasesMatched ||= matched;
    this._lastCaseCheckIndex++;
    if (this._lastCaseCheckIndex === this._caseCount) {
      this._updateDefaultCases(!this._lastCasesMatched);
      this._lastCaseCheckIndex = 0;
      this._lastCasesMatched = false;
    }
    return matched;
  }
  _updateDefaultCases(useDefault) {
    if (this._defaultViews.length > 0 && useDefault !== this._defaultUsed) {
      this._defaultUsed = useDefault;
      for (const defaultView of this._defaultViews) {
        defaultView.enforceState(useDefault);
      }
    }
  }
  static {
    this.ɵfac = function NgSwitch_Factory(t) {
      return new (t || NgSwitch)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgSwitch,
      selectors: [["", "ngSwitch", ""]],
      inputs: {
        ngSwitch: "ngSwitch"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitch, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngSwitch]',
      standalone: true
    }]
  }], null, {
    ngSwitch: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @ngModule CommonModule
 *
 * @description
 * Provides a switch case expression to match against an enclosing `ngSwitch` expression.
 * When the expressions match, the given `NgSwitchCase` template is rendered.
 * If multiple match expressions match the switch expression value, all of them are displayed.
 *
 * @usageNotes
 *
 * Within a switch container, `*ngSwitchCase` statements specify the match expressions
 * as attributes. Include `*ngSwitchDefault` as the final case.
 *
 * ```
 * <container-element [ngSwitch]="switch_expression">
 *   <some-element *ngSwitchCase="match_expression_1">...</some-element>
 *   ...
 *   <some-element *ngSwitchDefault>...</some-element>
 * </container-element>
 * ```
 *
 * Each switch-case statement contains an in-line HTML template or template reference
 * that defines the subtree to be selected if the value of the match expression
 * matches the value of the switch expression.
 *
 * As of Angular v17 the NgSwitch directive uses strict equality comparison (`===`) instead of
 * loose equality (`==`) to match different cases.
 *
 * @publicApi
 * @see {@link NgSwitch}
 * @see {@link NgSwitchDefault}
 *
 */
class NgSwitchCase {
  constructor(viewContainer, templateRef, ngSwitch) {
    this.ngSwitch = ngSwitch;
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
      throwNgSwitchProviderNotFoundError('ngSwitchCase', 'NgSwitchCase');
    }
    ngSwitch._addCase();
    this._view = new SwitchView(viewContainer, templateRef);
  }
  /**
   * Performs case matching. For internal use only.
   * @nodoc
   */
  ngDoCheck() {
    this._view.enforceState(this.ngSwitch._matchCase(this.ngSwitchCase));
  }
  static {
    this.ɵfac = function NgSwitchCase_Factory(t) {
      return new (t || NgSwitchCase)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgSwitch, 9));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgSwitchCase,
      selectors: [["", "ngSwitchCase", ""]],
      inputs: {
        ngSwitchCase: "ngSwitchCase"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitchCase, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngSwitchCase]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }, {
    type: NgSwitch,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }], {
    ngSwitchCase: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @ngModule CommonModule
 *
 * @description
 *
 * Creates a view that is rendered when no `NgSwitchCase` expressions
 * match the `NgSwitch` expression.
 * This statement should be the final case in an `NgSwitch`.
 *
 * @publicApi
 * @see {@link NgSwitch}
 * @see {@link NgSwitchCase}
 *
 */
class NgSwitchDefault {
  constructor(viewContainer, templateRef, ngSwitch) {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !ngSwitch) {
      throwNgSwitchProviderNotFoundError('ngSwitchDefault', 'NgSwitchDefault');
    }
    ngSwitch._addDefault(new SwitchView(viewContainer, templateRef));
  }
  static {
    this.ɵfac = function NgSwitchDefault_Factory(t) {
      return new (t || NgSwitchDefault)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgSwitch, 9));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgSwitchDefault,
      selectors: [["", "ngSwitchDefault", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSwitchDefault, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngSwitchDefault]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }, {
    type: NgSwitch,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }], null);
})();
function throwNgSwitchProviderNotFoundError(attrName, directiveName) {
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2000 /* RuntimeErrorCode.PARENT_NG_SWITCH_NOT_FOUND */, `An element with the "${attrName}" attribute ` + `(matching the "${directiveName}" directive) must be located inside an element with the "ngSwitch" attribute ` + `(matching "NgSwitch" directive)`);
}
function stringifyValue(value) {
  return typeof value === 'string' ? `'${value}'` : String(value);
}

/**
 * @ngModule CommonModule
 *
 * @usageNotes
 * ```
 * <some-element [ngPlural]="value">
 *   <ng-template ngPluralCase="=0">there is nothing</ng-template>
 *   <ng-template ngPluralCase="=1">there is one</ng-template>
 *   <ng-template ngPluralCase="few">there are a few</ng-template>
 * </some-element>
 * ```
 *
 * @description
 *
 * Adds / removes DOM sub-trees based on a numeric value. Tailored for pluralization.
 *
 * Displays DOM sub-trees that match the switch expression value, or failing that, DOM sub-trees
 * that match the switch expression's pluralization category.
 *
 * To use this directive you must provide a container element that sets the `[ngPlural]` attribute
 * to a switch expression. Inner elements with a `[ngPluralCase]` will display based on their
 * expression:
 * - if `[ngPluralCase]` is set to a value starting with `=`, it will only display if the value
 *   matches the switch expression exactly,
 * - otherwise, the view will be treated as a "category match", and will only display if exact
 *   value matches aren't found and the value maps to its category for the defined locale.
 *
 * See http://cldr.unicode.org/index/cldr-spec/plural-rules
 *
 * @publicApi
 */
class NgPlural {
  constructor(_localization) {
    this._localization = _localization;
    this._caseViews = {};
  }
  set ngPlural(value) {
    this._updateView(value);
  }
  addCase(value, switchView) {
    this._caseViews[value] = switchView;
  }
  _updateView(switchValue) {
    this._clearViews();
    const cases = Object.keys(this._caseViews);
    const key = getPluralCategory(switchValue, cases, this._localization);
    this._activateView(this._caseViews[key]);
  }
  _clearViews() {
    if (this._activeView) this._activeView.destroy();
  }
  _activateView(view) {
    if (view) {
      this._activeView = view;
      this._activeView.create();
    }
  }
  static {
    this.ɵfac = function NgPlural_Factory(t) {
      return new (t || NgPlural)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgLocalization));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgPlural,
      selectors: [["", "ngPlural", ""]],
      inputs: {
        ngPlural: "ngPlural"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgPlural, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngPlural]',
      standalone: true
    }]
  }], () => [{
    type: NgLocalization
  }], {
    ngPlural: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @ngModule CommonModule
 *
 * @description
 *
 * Creates a view that will be added/removed from the parent {@link NgPlural} when the
 * given expression matches the plural expression according to CLDR rules.
 *
 * @usageNotes
 * ```
 * <some-element [ngPlural]="value">
 *   <ng-template ngPluralCase="=0">...</ng-template>
 *   <ng-template ngPluralCase="other">...</ng-template>
 * </some-element>
 *```
 *
 * See {@link NgPlural} for more details and example.
 *
 * @publicApi
 */
class NgPluralCase {
  constructor(value, template, viewContainer, ngPlural) {
    this.value = value;
    const isANumber = !isNaN(Number(value));
    ngPlural.addCase(isANumber ? `=${value}` : value, new SwitchView(viewContainer, template));
  }
  static {
    this.ɵfac = function NgPluralCase_Factory(t) {
      return new (t || NgPluralCase)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('ngPluralCase'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgPlural, 1));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgPluralCase,
      selectors: [["", "ngPluralCase", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgPluralCase, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngPluralCase]',
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['ngPluralCase']
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }, {
    type: NgPlural,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }], null);
})();

/**
 * @ngModule CommonModule
 *
 * @usageNotes
 *
 * Set the font of the containing element to the result of an expression.
 *
 * ```
 * <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
 * ```
 *
 * Set the width of the containing element to a pixel value returned by an expression.
 *
 * ```
 * <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
 * ```
 *
 * Set a collection of style values using an expression that returns key-value pairs.
 *
 * ```
 * <some-element [ngStyle]="objExp">...</some-element>
 * ```
 *
 * @description
 *
 * An attribute directive that updates styles for the containing HTML element.
 * Sets one or more style properties, specified as colon-separated key-value pairs.
 * The key is a style name, with an optional `.<unit>` suffix
 * (such as 'top.px', 'font-style.em').
 * The value is an expression to be evaluated.
 * The resulting non-null value, expressed in the given unit,
 * is assigned to the given style property.
 * If the result of evaluation is null, the corresponding style is removed.
 *
 * @publicApi
 */
class NgStyle {
  constructor(_ngEl, _differs, _renderer) {
    this._ngEl = _ngEl;
    this._differs = _differs;
    this._renderer = _renderer;
    this._ngStyle = null;
    this._differ = null;
  }
  set ngStyle(values) {
    this._ngStyle = values;
    if (!this._differ && values) {
      this._differ = this._differs.find(values).create();
    }
  }
  ngDoCheck() {
    if (this._differ) {
      const changes = this._differ.diff(this._ngStyle);
      if (changes) {
        this._applyChanges(changes);
      }
    }
  }
  _setStyle(nameAndUnit, value) {
    const [name, unit] = nameAndUnit.split('.');
    const flags = name.indexOf('-') === -1 ? undefined : _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererStyleFlags2.DashCase;
    if (value != null) {
      this._renderer.setStyle(this._ngEl.nativeElement, name, unit ? `${value}${unit}` : value, flags);
    } else {
      this._renderer.removeStyle(this._ngEl.nativeElement, name, flags);
    }
  }
  _applyChanges(changes) {
    changes.forEachRemovedItem(record => this._setStyle(record.key, null));
    changes.forEachAddedItem(record => this._setStyle(record.key, record.currentValue));
    changes.forEachChangedItem(record => this._setStyle(record.key, record.currentValue));
  }
  static {
    this.ɵfac = function NgStyle_Factory(t) {
      return new (t || NgStyle)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgStyle,
      selectors: [["", "ngStyle", ""]],
      inputs: {
        ngStyle: "ngStyle"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgStyle, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngStyle]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }], {
    ngStyle: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngStyle']
    }]
  });
})();

/**
 * @ngModule CommonModule
 *
 * @description
 *
 * Inserts an embedded view from a prepared `TemplateRef`.
 *
 * You can attach a context object to the `EmbeddedViewRef` by setting `[ngTemplateOutletContext]`.
 * `[ngTemplateOutletContext]` should be an object, the object's keys will be available for binding
 * by the local template `let` declarations.
 *
 * @usageNotes
 * ```
 * <ng-container *ngTemplateOutlet="templateRefExp; context: contextExp"></ng-container>
 * ```
 *
 * Using the key `$implicit` in the context object will set its value as default.
 *
 * ### Example
 *
 * {@example common/ngTemplateOutlet/ts/module.ts region='NgTemplateOutlet'}
 *
 * @publicApi
 */
class NgTemplateOutlet {
  constructor(_viewContainerRef) {
    this._viewContainerRef = _viewContainerRef;
    this._viewRef = null;
    /**
     * A context object to attach to the {@link EmbeddedViewRef}. This should be an
     * object, the object's keys will be available for binding by the local template `let`
     * declarations.
     * Using the key `$implicit` in the context object will set its value as default.
     */
    this.ngTemplateOutletContext = null;
    /**
     * A string defining the template reference and optionally the context object for the template.
     */
    this.ngTemplateOutlet = null;
    /** Injector to be used within the embedded view. */
    this.ngTemplateOutletInjector = null;
  }
  ngOnChanges(changes) {
    if (this._shouldRecreateView(changes)) {
      const viewContainerRef = this._viewContainerRef;
      if (this._viewRef) {
        viewContainerRef.remove(viewContainerRef.indexOf(this._viewRef));
      }
      // If there is no outlet, clear the destroyed view ref.
      if (!this.ngTemplateOutlet) {
        this._viewRef = null;
        return;
      }
      // Create a context forward `Proxy` that will always bind to the user-specified context,
      // without having to destroy and re-create views whenever the context changes.
      const viewContext = this._createContextForwardProxy();
      this._viewRef = viewContainerRef.createEmbeddedView(this.ngTemplateOutlet, viewContext, {
        injector: this.ngTemplateOutletInjector ?? undefined
      });
    }
  }
  /**
   * We need to re-create existing embedded view if either is true:
   * - the outlet changed.
   * - the injector changed.
   */
  _shouldRecreateView(changes) {
    return !!changes['ngTemplateOutlet'] || !!changes['ngTemplateOutletInjector'];
  }
  /**
   * For a given outlet instance, we create a proxy object that delegates
   * to the user-specified context. This allows changing, or swapping out
   * the context object completely without having to destroy/re-create the view.
   */
  _createContextForwardProxy() {
    return new Proxy({}, {
      set: (_target, prop, newValue) => {
        if (!this.ngTemplateOutletContext) {
          return false;
        }
        return Reflect.set(this.ngTemplateOutletContext, prop, newValue);
      },
      get: (_target, prop, receiver) => {
        if (!this.ngTemplateOutletContext) {
          return undefined;
        }
        return Reflect.get(this.ngTemplateOutletContext, prop, receiver);
      }
    });
  }
  static {
    this.ɵfac = function NgTemplateOutlet_Factory(t) {
      return new (t || NgTemplateOutlet)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgTemplateOutlet,
      selectors: [["", "ngTemplateOutlet", ""]],
      inputs: {
        ngTemplateOutletContext: "ngTemplateOutletContext",
        ngTemplateOutlet: "ngTemplateOutlet",
        ngTemplateOutletInjector: "ngTemplateOutletInjector"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgTemplateOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngTemplateOutlet]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef
  }], {
    ngTemplateOutletContext: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngTemplateOutlet: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngTemplateOutletInjector: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();

/**
 * A collection of Angular directives that are likely to be used in each and every Angular
 * application.
 */
const COMMON_DIRECTIVES = [NgClass, NgComponentOutlet, NgForOf, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchCase, NgSwitchDefault, NgPlural, NgPluralCase];
function invalidPipeArgumentError(type, value) {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2100 /* RuntimeErrorCode.INVALID_PIPE_ARGUMENT */, ngDevMode && `InvalidPipeArgument: '${value}' for pipe '${(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵstringify"])(type)}'`);
}
class SubscribableStrategy {
  createSubscription(async, updateLatestValue) {
    // Subscription can be side-effectful, and we don't want any signal reads which happen in the
    // side effect of the subscription to be tracked by a component's template when that
    // subscription is triggered via the async pipe. So we wrap the subscription in `untracked` to
    // decouple from the current reactive context.
    //
    // `untracked` also prevents signal _writes_ which happen in the subscription side effect from
    // being treated as signal writes during the template evaluation (which throws errors).
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.untracked)(() => async.subscribe({
      next: updateLatestValue,
      error: e => {
        throw e;
      }
    }));
  }
  dispose(subscription) {
    // See the comment in `createSubscription` above on the use of `untracked`.
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.untracked)(() => subscription.unsubscribe());
  }
}
class PromiseStrategy {
  createSubscription(async, updateLatestValue) {
    return async.then(updateLatestValue, e => {
      throw e;
    });
  }
  dispose(subscription) {}
}
const _promiseStrategy = new PromiseStrategy();
const _subscribableStrategy = new SubscribableStrategy();
/**
 * @ngModule CommonModule
 * @description
 *
 * Unwraps a value from an asynchronous primitive.
 *
 * The `async` pipe subscribes to an `Observable` or `Promise` and returns the latest value it has
 * emitted. When a new value is emitted, the `async` pipe marks the component to be checked for
 * changes. When the component gets destroyed, the `async` pipe unsubscribes automatically to avoid
 * potential memory leaks. When the reference of the expression changes, the `async` pipe
 * automatically unsubscribes from the old `Observable` or `Promise` and subscribes to the new one.
 *
 * @usageNotes
 *
 * ### Examples
 *
 * This example binds a `Promise` to the view. Clicking the `Resolve` button resolves the
 * promise.
 *
 * {@example common/pipes/ts/async_pipe.ts region='AsyncPipePromise'}
 *
 * It's also possible to use `async` with Observables. The example below binds the `time` Observable
 * to the view. The Observable continuously updates the view with the current time.
 *
 * {@example common/pipes/ts/async_pipe.ts region='AsyncPipeObservable'}
 *
 * @publicApi
 */
class AsyncPipe {
  constructor(ref) {
    this._latestValue = null;
    this.markForCheckOnValueUpdate = true;
    this._subscription = null;
    this._obj = null;
    this._strategy = null;
    // Assign `ref` into `this._ref` manually instead of declaring `_ref` in the constructor
    // parameter list, as the type of `this._ref` includes `null` unlike the type of `ref`.
    this._ref = ref;
  }
  ngOnDestroy() {
    if (this._subscription) {
      this._dispose();
    }
    // Clear the `ChangeDetectorRef` and its association with the view data, to mitigate
    // potential memory leaks in Observables that could otherwise cause the view data to
    // be retained.
    // https://github.com/angular/angular/issues/17624
    this._ref = null;
  }
  transform(obj) {
    if (!this._obj) {
      if (obj) {
        try {
          // Only call `markForCheck` if the value is updated asynchronously.
          // Synchronous updates _during_ subscription should not wastefully mark for check -
          // this value is already going to be returned from the transform function.
          this.markForCheckOnValueUpdate = false;
          this._subscribe(obj);
        } finally {
          this.markForCheckOnValueUpdate = true;
        }
      }
      return this._latestValue;
    }
    if (obj !== this._obj) {
      this._dispose();
      return this.transform(obj);
    }
    return this._latestValue;
  }
  _subscribe(obj) {
    this._obj = obj;
    this._strategy = this._selectStrategy(obj);
    this._subscription = this._strategy.createSubscription(obj, value => this._updateLatestValue(obj, value));
  }
  _selectStrategy(obj) {
    if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisPromise"])(obj)) {
      return _promiseStrategy;
    }
    if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisSubscribable"])(obj)) {
      return _subscribableStrategy;
    }
    throw invalidPipeArgumentError(AsyncPipe, obj);
  }
  _dispose() {
    // Note: `dispose` is only called if a subscription has been initialized before, indicating
    // that `this._strategy` is also available.
    this._strategy.dispose(this._subscription);
    this._latestValue = null;
    this._subscription = null;
    this._obj = null;
  }
  _updateLatestValue(async, value) {
    if (async === this._obj) {
      this._latestValue = value;
      if (this.markForCheckOnValueUpdate) {
        this._ref?.markForCheck();
      }
    }
  }
  static {
    this.ɵfac = function AsyncPipe_Factory(t) {
      return new (t || AsyncPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "async",
      type: AsyncPipe,
      pure: false,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AsyncPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'async',
      pure: false,
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
  }], null);
})();

/**
 * Transforms text to all lower case.
 *
 * @see {@link UpperCasePipe}
 * @see {@link TitleCasePipe}
 * @usageNotes
 *
 * The following example defines a view that allows the user to enter
 * text, and then uses the pipe to convert the input text to all lower case.
 *
 * <code-example path="common/pipes/ts/lowerupper_pipe.ts" region='LowerUpperPipe'></code-example>
 *
 * @ngModule CommonModule
 * @publicApi
 */
class LowerCasePipe {
  transform(value) {
    if (value == null) return null;
    if (typeof value !== 'string') {
      throw invalidPipeArgumentError(LowerCasePipe, value);
    }
    return value.toLowerCase();
  }
  static {
    this.ɵfac = function LowerCasePipe_Factory(t) {
      return new (t || LowerCasePipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "lowercase",
      type: LowerCasePipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LowerCasePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'lowercase',
      standalone: true
    }]
  }], null, null);
})();
//
// Regex below matches any Unicode word and number compatible with ES5. In ES2018 the same result
// can be achieved by using /[0-9\p{L}]\S*/gu and also known as Unicode Property Escapes
// (https://2ality.com/2017/07/regexp-unicode-property-escapes.html). Since there is no
// transpilation of this functionality down to ES5 without external tool, the only solution is
// to use already transpiled form. Example can be found here -
// https://mothereff.in/regexpu#input=var+regex+%3D+%2F%5B0-9%5Cp%7BL%7D%5D%5CS*%2Fgu%3B%0A%0A&unicodePropertyEscape=1
//
const unicodeWordMatch = /(?:[0-9A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])\S*/g;
/**
 * Transforms text to title case.
 * Capitalizes the first letter of each word and transforms the
 * rest of the word to lower case.
 * Words are delimited by any whitespace character, such as a space, tab, or line-feed character.
 *
 * @see {@link LowerCasePipe}
 * @see {@link UpperCasePipe}
 *
 * @usageNotes
 * The following example shows the result of transforming various strings into title case.
 *
 * <code-example path="common/pipes/ts/titlecase_pipe.ts" region='TitleCasePipe'></code-example>
 *
 * @ngModule CommonModule
 * @publicApi
 */
class TitleCasePipe {
  transform(value) {
    if (value == null) return null;
    if (typeof value !== 'string') {
      throw invalidPipeArgumentError(TitleCasePipe, value);
    }
    return value.replace(unicodeWordMatch, txt => txt[0].toUpperCase() + txt.slice(1).toLowerCase());
  }
  static {
    this.ɵfac = function TitleCasePipe_Factory(t) {
      return new (t || TitleCasePipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "titlecase",
      type: TitleCasePipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TitleCasePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'titlecase',
      standalone: true
    }]
  }], null, null);
})();
/**
 * Transforms text to all upper case.
 * @see {@link LowerCasePipe}
 * @see {@link TitleCasePipe}
 *
 * @ngModule CommonModule
 * @publicApi
 */
class UpperCasePipe {
  transform(value) {
    if (value == null) return null;
    if (typeof value !== 'string') {
      throw invalidPipeArgumentError(UpperCasePipe, value);
    }
    return value.toUpperCase();
  }
  static {
    this.ɵfac = function UpperCasePipe_Factory(t) {
      return new (t || UpperCasePipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "uppercase",
      type: UpperCasePipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UpperCasePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'uppercase',
      standalone: true
    }]
  }], null, null);
})();

/**
 * The default date format of Angular date pipe, which corresponds to the following format:
 * `'MMM d,y'` (e.g. `Jun 15, 2015`)
 */
const DEFAULT_DATE_FORMAT = 'mediumDate';

/**
 * Optionally-provided default timezone to use for all instances of `DatePipe` (such as `'+0430'`).
 * If the value isn't provided, the `DatePipe` will use the end-user's local system timezone.
 *
 * @deprecated use DATE_PIPE_DEFAULT_OPTIONS token to configure DatePipe
 */
const DATE_PIPE_DEFAULT_TIMEZONE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'DATE_PIPE_DEFAULT_TIMEZONE' : '');
/**
 * DI token that allows to provide default configuration for the `DatePipe` instances in an
 * application. The value is an object which can include the following fields:
 * - `dateFormat`: configures the default date format. If not provided, the `DatePipe`
 * will use the 'mediumDate' as a value.
 * - `timezone`: configures the default timezone. If not provided, the `DatePipe` will
 * use the end-user's local system timezone.
 *
 * @see {@link DatePipeConfig}
 *
 * @usageNotes
 *
 * Various date pipe default values can be overwritten by providing this token with
 * the value that has this interface.
 *
 * For example:
 *
 * Override the default date format by providing a value using the token:
 * ```typescript
 * providers: [
 *   {provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: {dateFormat: 'shortDate'}}
 * ]
 * ```
 *
 * Override the default timezone by providing a value using the token:
 * ```typescript
 * providers: [
 *   {provide: DATE_PIPE_DEFAULT_OPTIONS, useValue: {timezone: '-1200'}}
 * ]
 * ```
 */
const DATE_PIPE_DEFAULT_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'DATE_PIPE_DEFAULT_OPTIONS' : '');
// clang-format off
/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a date value according to locale rules.
 *
 * `DatePipe` is executed only when it detects a pure change to the input value.
 * A pure change is either a change to a primitive input value
 * (such as `String`, `Number`, `Boolean`, or `Symbol`),
 * or a changed object reference (such as `Date`, `Array`, `Function`, or `Object`).
 *
 * Note that mutating a `Date` object does not cause the pipe to be rendered again.
 * To ensure that the pipe is executed, you must create a new `Date` object.
 *
 * Only the `en-US` locale data comes with Angular. To localize dates
 * in another language, you must import the corresponding locale data.
 * See the [I18n guide](guide/i18n-common-format-data-locale) for more information.
 *
 * The time zone of the formatted value can be specified either by passing it in as the second
 * parameter of the pipe, or by setting the default through the `DATE_PIPE_DEFAULT_OPTIONS`
 * injection token. The value that is passed in as the second parameter takes precedence over
 * the one defined using the injection token.
 *
 * @see {@link formatDate}
 *
 *
 * @usageNotes
 *
 * The result of this pipe is not reevaluated when the input is mutated. To avoid the need to
 * reformat the date on every change-detection cycle, treat the date as an immutable object
 * and change the reference when the pipe needs to run again.
 *
 * ### Pre-defined format options
 *
 * | Option        | Equivalent to                       | Examples (given in `en-US` locale)              |
 * |---------------|-------------------------------------|-------------------------------------------------|
 * | `'short'`     | `'M/d/yy, h:mm a'`                  | `6/15/15, 9:03 AM`                              |
 * | `'medium'`    | `'MMM d, y, h:mm:ss a'`             | `Jun 15, 2015, 9:03:01 AM`                      |
 * | `'long'`      | `'MMMM d, y, h:mm:ss a z'`          | `June 15, 2015 at 9:03:01 AM GMT+1`             |
 * | `'full'`      | `'EEEE, MMMM d, y, h:mm:ss a zzzz'` | `Monday, June 15, 2015 at 9:03:01 AM GMT+01:00` |
 * | `'shortDate'` | `'M/d/yy'`                          | `6/15/15`                                       |
 * | `'mediumDate'`| `'MMM d, y'`                        | `Jun 15, 2015`                                  |
 * | `'longDate'`  | `'MMMM d, y'`                       | `June 15, 2015`                                 |
 * | `'fullDate'`  | `'EEEE, MMMM d, y'`                 | `Monday, June 15, 2015`                         |
 * | `'shortTime'` | `'h:mm a'`                          | `9:03 AM`                                       |
 * | `'mediumTime'`| `'h:mm:ss a'`                       | `9:03:01 AM`                                    |
 * | `'longTime'`  | `'h:mm:ss a z'`                     | `9:03:01 AM GMT+1`                              |
 * | `'fullTime'`  | `'h:mm:ss a zzzz'`                  | `9:03:01 AM GMT+01:00`                          |
 *
 * ### Custom format options
 *
 * You can construct a format string using symbols to specify the components
 * of a date-time value, as described in the following table.
 * Format details depend on the locale.
 * Fields marked with (*) are only available in the extra data set for the given locale.
 *
 *  | Field type              | Format      | Description                                                   | Example Value                                              |
 *  |-------------------------|-------------|---------------------------------------------------------------|------------------------------------------------------------|
 *  | Era                     | G, GG & GGG | Abbreviated                                                   | AD                                                         |
 *  |                         | GGGG        | Wide                                                          | Anno Domini                                                |
 *  |                         | GGGGG       | Narrow                                                        | A                                                          |
 *  | Year                    | y           | Numeric: minimum digits                                       | 2, 20, 201, 2017, 20173                                    |
 *  |                         | yy          | Numeric: 2 digits + zero padded                               | 02, 20, 01, 17, 73                                         |
 *  |                         | yyy         | Numeric: 3 digits + zero padded                               | 002, 020, 201, 2017, 20173                                 |
 *  |                         | yyyy        | Numeric: 4 digits or more + zero padded                       | 0002, 0020, 0201, 2017, 20173                              |
 *  | ISO Week-numbering year | Y           | Numeric: minimum digits                                       | 2, 20, 201, 2017, 20173                                    |
 *  |                         | YY          | Numeric: 2 digits + zero padded                               | 02, 20, 01, 17, 73                                         |
 *  |                         | YYY         | Numeric: 3 digits + zero padded                               | 002, 020, 201, 2017, 20173                                 |
 *  |                         | YYYY        | Numeric: 4 digits or more + zero padded                       | 0002, 0020, 0201, 2017, 20173                              |
 *  | Month                   | M           | Numeric: 1 digit                                              | 9, 12                                                      |
 *  |                         | MM          | Numeric: 2 digits + zero padded                               | 09, 12                                                     |
 *  |                         | MMM         | Abbreviated                                                   | Sep                                                        |
 *  |                         | MMMM        | Wide                                                          | September                                                  |
 *  |                         | MMMMM       | Narrow                                                        | S                                                          |
 *  | Month standalone        | L           | Numeric: 1 digit                                              | 9, 12                                                      |
 *  |                         | LL          | Numeric: 2 digits + zero padded                               | 09, 12                                                     |
 *  |                         | LLL         | Abbreviated                                                   | Sep                                                        |
 *  |                         | LLLL        | Wide                                                          | September                                                  |
 *  |                         | LLLLL       | Narrow                                                        | S                                                          |
 *  | ISO Week of year        | w           | Numeric: minimum digits                                       | 1... 53                                                    |
 *  |                         | ww          | Numeric: 2 digits + zero padded                               | 01... 53                                                   |
 *  | Week of month           | W           | Numeric: 1 digit                                              | 1... 5                                                     |
 *  | Day of month            | d           | Numeric: minimum digits                                       | 1                                                          |
 *  |                         | dd          | Numeric: 2 digits + zero padded                               | 01                                                         |
 *  | Week day                | E, EE & EEE | Abbreviated                                                   | Tue                                                        |
 *  |                         | EEEE        | Wide                                                          | Tuesday                                                    |
 *  |                         | EEEEE       | Narrow                                                        | T                                                          |
 *  |                         | EEEEEE      | Short                                                         | Tu                                                         |
 *  | Week day standalone     | c, cc       | Numeric: 1 digit                                              | 2                                                          |
 *  |                         | ccc         | Abbreviated                                                   | Tue                                                        |
 *  |                         | cccc        | Wide                                                          | Tuesday                                                    |
 *  |                         | ccccc       | Narrow                                                        | T                                                          |
 *  |                         | cccccc      | Short                                                         | Tu                                                         |
 *  | Period                  | a, aa & aaa | Abbreviated                                                   | am/pm or AM/PM                                             |
 *  |                         | aaaa        | Wide (fallback to `a` when missing)                           | ante meridiem/post meridiem                                |
 *  |                         | aaaaa       | Narrow                                                        | a/p                                                        |
 *  | Period*                 | B, BB & BBB | Abbreviated                                                   | mid.                                                       |
 *  |                         | BBBB        | Wide                                                          | am, pm, midnight, noon, morning, afternoon, evening, night |
 *  |                         | BBBBB       | Narrow                                                        | md                                                         |
 *  | Period standalone*      | b, bb & bbb | Abbreviated                                                   | mid.                                                       |
 *  |                         | bbbb        | Wide                                                          | am, pm, midnight, noon, morning, afternoon, evening, night |
 *  |                         | bbbbb       | Narrow                                                        | md                                                         |
 *  | Hour 1-12               | h           | Numeric: minimum digits                                       | 1, 12                                                      |
 *  |                         | hh          | Numeric: 2 digits + zero padded                               | 01, 12                                                     |
 *  | Hour 0-23               | H           | Numeric: minimum digits                                       | 0, 23                                                      |
 *  |                         | HH          | Numeric: 2 digits + zero padded                               | 00, 23                                                     |
 *  | Minute                  | m           | Numeric: minimum digits                                       | 8, 59                                                      |
 *  |                         | mm          | Numeric: 2 digits + zero padded                               | 08, 59                                                     |
 *  | Second                  | s           | Numeric: minimum digits                                       | 0... 59                                                    |
 *  |                         | ss          | Numeric: 2 digits + zero padded                               | 00... 59                                                   |
 *  | Fractional seconds      | S           | Numeric: 1 digit                                              | 0... 9                                                     |
 *  |                         | SS          | Numeric: 2 digits + zero padded                               | 00... 99                                                   |
 *  |                         | SSS         | Numeric: 3 digits + zero padded (= milliseconds)              | 000... 999                                                 |
 *  | Zone                    | z, zz & zzz | Short specific non location format (fallback to O)            | GMT-8                                                      |
 *  |                         | zzzz        | Long specific non location format (fallback to OOOO)          | GMT-08:00                                                  |
 *  |                         | Z, ZZ & ZZZ | ISO8601 basic format                                          | -0800                                                      |
 *  |                         | ZZZZ        | Long localized GMT format                                     | GMT-8:00                                                   |
 *  |                         | ZZZZZ       | ISO8601 extended format + Z indicator for offset 0 (= XXXXX)  | -08:00                                                     |
 *  |                         | O, OO & OOO | Short localized GMT format                                    | GMT-8                                                      |
 *  |                         | OOOO        | Long localized GMT format                                     | GMT-08:00                                                  |
 *
 *
 * ### Format examples
 *
 * These examples transform a date into various formats,
 * assuming that `dateObj` is a JavaScript `Date` object for
 * year: 2015, month: 6, day: 15, hour: 21, minute: 43, second: 11,
 * given in the local time for the `en-US` locale.
 *
 * ```
 * {{ dateObj | date }}               // output is 'Jun 15, 2015'
 * {{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
 * {{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
 * {{ dateObj | date:'mm:ss' }}       // output is '43:11'
 * {{ dateObj | date:"MMM dd, yyyy 'at' hh:mm a" }}  // output is 'Jun 15, 2015 at 09:43 PM'
 * ```
 *
 * ### Usage example
 *
 * The following component uses a date pipe to display the current date in different formats.
 *
 * ```
 * @Component({
 *  selector: 'date-pipe',
 *  template: `<div>
 *    <p>Today is {{today | date}}</p>
 *    <p>Or if you prefer, {{today | date:'fullDate'}}</p>
 *    <p>The time is {{today | date:'h:mm a z'}}</p>
 *  </div>`
 * })
 * // Get the current date and time as a date-time value.
 * export class DatePipeComponent {
 *   today: number = Date.now();
 * }
 * ```
 *
 * @publicApi
 */
// clang-format on
class DatePipe {
  constructor(locale, defaultTimezone, defaultOptions) {
    this.locale = locale;
    this.defaultTimezone = defaultTimezone;
    this.defaultOptions = defaultOptions;
  }
  transform(value, format, timezone, locale) {
    if (value == null || value === '' || value !== value) return null;
    try {
      const _format = format ?? this.defaultOptions?.dateFormat ?? DEFAULT_DATE_FORMAT;
      const _timezone = timezone ?? this.defaultOptions?.timezone ?? this.defaultTimezone ?? undefined;
      return formatDate(value, _format, locale || this.locale, _timezone);
    } catch (error) {
      throw invalidPipeArgumentError(DatePipe, error.message);
    }
  }
  static {
    this.ɵfac = function DatePipe_Factory(t) {
      return new (t || DatePipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](DATE_PIPE_DEFAULT_TIMEZONE, 24), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](DATE_PIPE_DEFAULT_OPTIONS, 24));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "date",
      type: DatePipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DatePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'date',
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [DATE_PIPE_DEFAULT_TIMEZONE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [DATE_PIPE_DEFAULT_OPTIONS]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();
const _INTERPOLATION_REGEXP = /#/g;
/**
 * @ngModule CommonModule
 * @description
 *
 * Maps a value to a string that pluralizes the value according to locale rules.
 *
 * @usageNotes
 *
 * ### Example
 *
 * {@example common/pipes/ts/i18n_pipe.ts region='I18nPluralPipeComponent'}
 *
 * @publicApi
 */
class I18nPluralPipe {
  constructor(_localization) {
    this._localization = _localization;
  }
  /**
   * @param value the number to be formatted
   * @param pluralMap an object that mimics the ICU format, see
   * https://unicode-org.github.io/icu/userguide/format_parse/messages/.
   * @param locale a `string` defining the locale to use (uses the current {@link LOCALE_ID} by
   * default).
   */
  transform(value, pluralMap, locale) {
    if (value == null) return '';
    if (typeof pluralMap !== 'object' || pluralMap === null) {
      throw invalidPipeArgumentError(I18nPluralPipe, pluralMap);
    }
    const key = getPluralCategory(value, Object.keys(pluralMap), this._localization, locale);
    return pluralMap[key].replace(_INTERPOLATION_REGEXP, value.toString());
  }
  static {
    this.ɵfac = function I18nPluralPipe_Factory(t) {
      return new (t || I18nPluralPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgLocalization, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "i18nPlural",
      type: I18nPluralPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](I18nPluralPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'i18nPlural',
      standalone: true
    }]
  }], () => [{
    type: NgLocalization
  }], null);
})();

/**
 * @ngModule CommonModule
 * @description
 *
 * Generic selector that displays the string that matches the current value.
 *
 * If none of the keys of the `mapping` match the `value`, then the content
 * of the `other` key is returned when present, otherwise an empty string is returned.
 *
 * @usageNotes
 *
 * ### Example
 *
 * {@example common/pipes/ts/i18n_pipe.ts region='I18nSelectPipeComponent'}
 *
 * @publicApi
 */
class I18nSelectPipe {
  /**
   * @param value a string to be internationalized.
   * @param mapping an object that indicates the text that should be displayed
   * for different values of the provided `value`.
   */
  transform(value, mapping) {
    if (value == null) return '';
    if (typeof mapping !== 'object' || typeof value !== 'string') {
      throw invalidPipeArgumentError(I18nSelectPipe, mapping);
    }
    if (mapping.hasOwnProperty(value)) {
      return mapping[value];
    }
    if (mapping.hasOwnProperty('other')) {
      return mapping['other'];
    }
    return '';
  }
  static {
    this.ɵfac = function I18nSelectPipe_Factory(t) {
      return new (t || I18nSelectPipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "i18nSelect",
      type: I18nSelectPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](I18nSelectPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'i18nSelect',
      standalone: true
    }]
  }], null, null);
})();

/**
 * @ngModule CommonModule
 * @description
 *
 * Converts a value into its JSON-format representation.  Useful for debugging.
 *
 * @usageNotes
 *
 * The following component uses a JSON pipe to convert an object
 * to JSON format, and displays the string in both formats for comparison.
 *
 * {@example common/pipes/ts/json_pipe.ts region='JsonPipe'}
 *
 * @publicApi
 */
class JsonPipe {
  /**
   * @param value A value of any type to convert into a JSON-format string.
   */
  transform(value) {
    return JSON.stringify(value, null, 2);
  }
  static {
    this.ɵfac = function JsonPipe_Factory(t) {
      return new (t || JsonPipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "json",
      type: JsonPipe,
      pure: false,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](JsonPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'json',
      pure: false,
      standalone: true
    }]
  }], null, null);
})();
function makeKeyValuePair(key, value) {
  return {
    key: key,
    value: value
  };
}
/**
 * @ngModule CommonModule
 * @description
 *
 * Transforms Object or Map into an array of key value pairs.
 *
 * The output array will be ordered by keys.
 * By default the comparator will be by Unicode point value.
 * You can optionally pass a compareFn if your keys are complex types.
 *
 * @usageNotes
 * ### Examples
 *
 * This examples show how an Object or a Map can be iterated by ngFor with the use of this
 * keyvalue pipe.
 *
 * {@example common/pipes/ts/keyvalue_pipe.ts region='KeyValuePipe'}
 *
 * @publicApi
 */
class KeyValuePipe {
  constructor(differs) {
    this.differs = differs;
    this.keyValues = [];
    this.compareFn = defaultComparator;
  }
  transform(input, compareFn = defaultComparator) {
    if (!input || !(input instanceof Map) && typeof input !== 'object') {
      return null;
    }
    // make a differ for whatever type we've been passed in
    this.differ ??= this.differs.find(input).create();
    const differChanges = this.differ.diff(input);
    const compareFnChanged = compareFn !== this.compareFn;
    if (differChanges) {
      this.keyValues = [];
      differChanges.forEachItem(r => {
        this.keyValues.push(makeKeyValuePair(r.key, r.currentValue));
      });
    }
    if (differChanges || compareFnChanged) {
      this.keyValues.sort(compareFn);
      this.compareFn = compareFn;
    }
    return this.keyValues;
  }
  static {
    this.ɵfac = function KeyValuePipe_Factory(t) {
      return new (t || KeyValuePipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "keyvalue",
      type: KeyValuePipe,
      pure: false,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](KeyValuePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'keyvalue',
      pure: false,
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.KeyValueDiffers
  }], null);
})();
function defaultComparator(keyValueA, keyValueB) {
  const a = keyValueA.key;
  const b = keyValueB.key;
  // if same exit with 0;
  if (a === b) return 0;
  // make sure that undefined are at the end of the sort.
  if (a === undefined) return 1;
  if (b === undefined) return -1;
  // make sure that nulls are at the end of the sort.
  if (a === null) return 1;
  if (b === null) return -1;
  if (typeof a == 'string' && typeof b == 'string') {
    return a < b ? -1 : 1;
  }
  if (typeof a == 'number' && typeof b == 'number') {
    return a - b;
  }
  if (typeof a == 'boolean' && typeof b == 'boolean') {
    return a < b ? -1 : 1;
  }
  // `a` and `b` are of different types. Compare their string values.
  const aString = String(a);
  const bString = String(b);
  return aString == bString ? 0 : aString < bString ? -1 : 1;
}

/**
 * @ngModule CommonModule
 * @description
 *
 * Formats a value according to digit options and locale rules.
 * Locale determines group sizing and separator,
 * decimal point character, and other locale-specific configurations.
 *
 * @see {@link formatNumber}
 *
 * @usageNotes
 *
 * ### digitsInfo
 *
 * The value's decimal representation is specified by the `digitsInfo`
 * parameter, written in the following format:<br>
 *
 * ```
 * {minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}
 * ```
 *
 *  - `minIntegerDigits`:
 * The minimum number of integer digits before the decimal point.
 * Default is 1.
 *
 * - `minFractionDigits`:
 * The minimum number of digits after the decimal point.
 * Default is 0.
 *
 *  - `maxFractionDigits`:
 * The maximum number of digits after the decimal point.
 * Default is 3.
 *
 * If the formatted value is truncated it will be rounded using the "to-nearest" method:
 *
 * ```
 * {{3.6 | number: '1.0-0'}}
 * <!--will output '4'-->
 *
 * {{-3.6 | number:'1.0-0'}}
 * <!--will output '-4'-->
 * ```
 *
 * ### locale
 *
 * `locale` will format a value according to locale rules.
 * Locale determines group sizing and separator,
 * decimal point character, and other locale-specific configurations.
 *
 * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
 *
 * See [Setting your app locale](guide/i18n-common-locale-id).
 *
 * ### Example
 *
 * The following code shows how the pipe transforms values
 * according to various format specifications,
 * where the caller's default locale is `en-US`.
 *
 * <code-example path="common/pipes/ts/number_pipe.ts" region='NumberPipe'></code-example>
 *
 * @publicApi
 */
class DecimalPipe {
  constructor(_locale) {
    this._locale = _locale;
  }
  /**
   * @param value The value to be formatted.
   * @param digitsInfo Sets digit and decimal representation.
   * [See more](#digitsinfo).
   * @param locale Specifies what locale format rules to use.
   * [See more](#locale).
   */
  transform(value, digitsInfo, locale) {
    if (!isValue(value)) return null;
    locale ||= this._locale;
    try {
      const num = strToNumber(value);
      return formatNumber(num, locale, digitsInfo);
    } catch (error) {
      throw invalidPipeArgumentError(DecimalPipe, error.message);
    }
  }
  static {
    this.ɵfac = function DecimalPipe_Factory(t) {
      return new (t || DecimalPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "number",
      type: DecimalPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DecimalPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'number',
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }], null);
})();
/**
 * @ngModule CommonModule
 * @description
 *
 * Transforms a number to a percentage
 * string, formatted according to locale rules that determine group sizing and
 * separator, decimal-point character, and other locale-specific
 * configurations.
 *
 * @see {@link formatPercent}
 *
 * @usageNotes
 * The following code shows how the pipe transforms numbers
 * into text strings, according to various format specifications,
 * where the caller's default locale is `en-US`.
 *
 * <code-example path="common/pipes/ts/percent_pipe.ts" region='PercentPipe'></code-example>
 *
 * @publicApi
 */
class PercentPipe {
  constructor(_locale) {
    this._locale = _locale;
  }
  /**
   *
   * @param value The number to be formatted as a percentage.
   * @param digitsInfo Decimal representation options, specified by a string
   * in the following format:<br>
   * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>.
   *   - `minIntegerDigits`: The minimum number of integer digits before the decimal point.
   * Default is `1`.
   *   - `minFractionDigits`: The minimum number of digits after the decimal point.
   * Default is `0`.
   *   - `maxFractionDigits`: The maximum number of digits after the decimal point.
   * Default is `0`.
   * @param locale A locale code for the locale format rules to use.
   * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
   * See [Setting your app locale](guide/i18n-common-locale-id).
   */
  transform(value, digitsInfo, locale) {
    if (!isValue(value)) return null;
    locale ||= this._locale;
    try {
      const num = strToNumber(value);
      return formatPercent(num, locale, digitsInfo);
    } catch (error) {
      throw invalidPipeArgumentError(PercentPipe, error.message);
    }
  }
  static {
    this.ɵfac = function PercentPipe_Factory(t) {
      return new (t || PercentPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "percent",
      type: PercentPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PercentPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'percent',
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }], null);
})();
/**
 * @ngModule CommonModule
 * @description
 *
 * Transforms a number to a currency string, formatted according to locale rules
 * that determine group sizing and separator, decimal-point character,
 * and other locale-specific configurations.
 *
 *
 * @see {@link getCurrencySymbol}
 * @see {@link formatCurrency}
 *
 * @usageNotes
 * The following code shows how the pipe transforms numbers
 * into text strings, according to various format specifications,
 * where the caller's default locale is `en-US`.
 *
 * <code-example path="common/pipes/ts/currency_pipe.ts" region='CurrencyPipe'></code-example>
 *
 * @publicApi
 */
class CurrencyPipe {
  constructor(_locale, _defaultCurrencyCode = 'USD') {
    this._locale = _locale;
    this._defaultCurrencyCode = _defaultCurrencyCode;
  }
  /**
   *
   * @param value The number to be formatted as currency.
   * @param currencyCode The [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code,
   * such as `USD` for the US dollar and `EUR` for the euro. The default currency code can be
   * configured using the `DEFAULT_CURRENCY_CODE` injection token.
   * @param display The format for the currency indicator. One of the following:
   *   - `code`: Show the code (such as `USD`).
   *   - `symbol`(default): Show the symbol (such as `$`).
   *   - `symbol-narrow`: Use the narrow symbol for locales that have two symbols for their
   * currency.
   * For example, the Canadian dollar CAD has the symbol `CA$` and the symbol-narrow `$`. If the
   * locale has no narrow symbol, uses the standard symbol for the locale.
   *   - String: Use the given string value instead of a code or a symbol.
   * For example, an empty string will suppress the currency & symbol.
   *   - Boolean (marked deprecated in v5): `true` for symbol and false for `code`.
   *
   * @param digitsInfo Decimal representation options, specified by a string
   * in the following format:<br>
   * <code>{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}</code>.
   *   - `minIntegerDigits`: The minimum number of integer digits before the decimal point.
   * Default is `1`.
   *   - `minFractionDigits`: The minimum number of digits after the decimal point.
   * Default is `2`.
   *   - `maxFractionDigits`: The maximum number of digits after the decimal point.
   * Default is `2`.
   * If not provided, the number will be formatted with the proper amount of digits,
   * depending on what the [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) specifies.
   * For example, the Canadian dollar has 2 digits, whereas the Chilean peso has none.
   * @param locale A locale code for the locale format rules to use.
   * When not supplied, uses the value of `LOCALE_ID`, which is `en-US` by default.
   * See [Setting your app locale](guide/i18n-common-locale-id).
   */
  transform(value, currencyCode = this._defaultCurrencyCode, display = 'symbol', digitsInfo, locale) {
    if (!isValue(value)) return null;
    locale ||= this._locale;
    if (typeof display === 'boolean') {
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && console && console.warn) {
        console.warn(`Warning: the currency pipe has been changed in Angular v5. The symbolDisplay option (third parameter) is now a string instead of a boolean. The accepted values are "code", "symbol" or "symbol-narrow".`);
      }
      display = display ? 'symbol' : 'code';
    }
    let currency = currencyCode || this._defaultCurrencyCode;
    if (display !== 'code') {
      if (display === 'symbol' || display === 'symbol-narrow') {
        currency = getCurrencySymbol(currency, display === 'symbol' ? 'wide' : 'narrow', locale);
      } else {
        currency = display;
      }
    }
    try {
      const num = strToNumber(value);
      return formatCurrency(num, locale, currency, currencyCode, digitsInfo);
    } catch (error) {
      throw invalidPipeArgumentError(CurrencyPipe, error.message);
    }
  }
  static {
    this.ɵfac = function CurrencyPipe_Factory(t) {
      return new (t || CurrencyPipe)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID, 16), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_CURRENCY_CODE, 16));
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "currency",
      type: CurrencyPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CurrencyPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'currency',
      standalone: true
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.DEFAULT_CURRENCY_CODE]
    }]
  }], null);
})();
function isValue(value) {
  return !(value == null || value === '' || value !== value);
}
/**
 * Transforms a string into a number (if needed).
 */
function strToNumber(value) {
  // Convert strings to numbers
  if (typeof value === 'string' && !isNaN(Number(value) - parseFloat(value))) {
    return Number(value);
  }
  if (typeof value !== 'number') {
    throw new Error(`${value} is not a number`);
  }
  return value;
}

/**
 * @ngModule CommonModule
 * @description
 *
 * Creates a new `Array` or `String` containing a subset (slice) of the elements.
 *
 * @usageNotes
 *
 * All behavior is based on the expected behavior of the JavaScript API `Array.prototype.slice()`
 * and `String.prototype.slice()`.
 *
 * When operating on an `Array`, the returned `Array` is always a copy even when all
 * the elements are being returned.
 *
 * When operating on a blank value, the pipe returns the blank value.
 *
 * ### List Example
 *
 * This `ngFor` example:
 *
 * {@example common/pipes/ts/slice_pipe.ts region='SlicePipe_list'}
 *
 * produces the following:
 *
 * ```html
 * <li>b</li>
 * <li>c</li>
 * ```
 *
 * ### String Examples
 *
 * {@example common/pipes/ts/slice_pipe.ts region='SlicePipe_string'}
 *
 * @publicApi
 */
class SlicePipe {
  transform(value, start, end) {
    if (value == null) return null;
    if (!this.supports(value)) {
      throw invalidPipeArgumentError(SlicePipe, value);
    }
    return value.slice(start, end);
  }
  supports(obj) {
    return typeof obj === 'string' || Array.isArray(obj);
  }
  static {
    this.ɵfac = function SlicePipe_Factory(t) {
      return new (t || SlicePipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
      name: "slice",
      type: SlicePipe,
      pure: false,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlicePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'slice',
      pure: false,
      standalone: true
    }]
  }], null, null);
})();

/**
 * @module
 * @description
 * This module provides a set of common Pipes.
 */
/**
 * A collection of Angular pipes that are likely to be used in each and every application.
 */
const COMMON_PIPES = [AsyncPipe, UpperCasePipe, LowerCasePipe, JsonPipe, SlicePipe, DecimalPipe, PercentPipe, TitleCasePipe, CurrencyPipe, DatePipe, I18nPluralPipe, I18nSelectPipe, KeyValuePipe];

// Note: This does not contain the location providers,
// as they need some platform specific implementations to work.
/**
 * Exports all the basic Angular directives and pipes,
 * such as `NgIf`, `NgForOf`, `DecimalPipe`, and so on.
 * Re-exported by `BrowserModule`, which is included automatically in the root
 * `AppModule` when you create a new app with the CLI `new` command.
 *
 * @publicApi
 */
class CommonModule {
  static {
    this.ɵfac = function CommonModule_Factory(t) {
      return new (t || CommonModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: CommonModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CommonModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [COMMON_DIRECTIVES, COMMON_PIPES],
      exports: [COMMON_DIRECTIVES, COMMON_PIPES]
    }]
  }], null, null);
})();
const PLATFORM_BROWSER_ID = 'browser';
const PLATFORM_SERVER_ID = 'server';
const PLATFORM_WORKER_APP_ID = 'browserWorkerApp';
const PLATFORM_WORKER_UI_ID = 'browserWorkerUi';
/**
 * Returns whether a platform id represents a browser platform.
 * @publicApi
 */
function isPlatformBrowser(platformId) {
  return platformId === PLATFORM_BROWSER_ID;
}
/**
 * Returns whether a platform id represents a server platform.
 * @publicApi
 */
function isPlatformServer(platformId) {
  return platformId === PLATFORM_SERVER_ID;
}
/**
 * Returns whether a platform id represents a web worker app platform.
 * @publicApi
 * @deprecated This function serves no purpose since the removal of the Webworker platform. It will
 *     always return `false`.
 */
function isPlatformWorkerApp(platformId) {
  return platformId === PLATFORM_WORKER_APP_ID;
}
/**
 * Returns whether a platform id represents a web worker UI platform.
 * @publicApi
 * @deprecated This function serves no purpose since the removal of the Webworker platform. It will
 *     always return `false`.
 */
function isPlatformWorkerUi(platformId) {
  return platformId === PLATFORM_WORKER_UI_ID;
}

/**
 * @module
 * @description
 * Entry point for all public APIs of the common package.
 */
/**
 * @publicApi
 */
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('17.3.12');

/**
 * Defines a scroll position manager. Implemented by `BrowserViewportScroller`.
 *
 * @publicApi
 */
class ViewportScroller {
  // De-sugared tree-shakable injection
  // See #23917
  /** @nocollapse */
  static {
    this.ɵprov = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"])({
      token: ViewportScroller,
      providedIn: 'root',
      factory: () => isPlatformBrowser((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID)) ? new BrowserViewportScroller((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT), window) : new NullViewportScroller()
    });
  }
}
/**
 * Manages the scroll position for a browser window.
 */
class BrowserViewportScroller {
  constructor(document, window) {
    this.document = document;
    this.window = window;
    this.offset = () => [0, 0];
  }
  /**
   * Configures the top offset used when scrolling to an anchor.
   * @param offset A position in screen coordinates (a tuple with x and y values)
   * or a function that returns the top offset position.
   *
   */
  setOffset(offset) {
    if (Array.isArray(offset)) {
      this.offset = () => offset;
    } else {
      this.offset = offset;
    }
  }
  /**
   * Retrieves the current scroll position.
   * @returns The position in screen coordinates.
   */
  getScrollPosition() {
    return [this.window.scrollX, this.window.scrollY];
  }
  /**
   * Sets the scroll position.
   * @param position The new position in screen coordinates.
   */
  scrollToPosition(position) {
    this.window.scrollTo(position[0], position[1]);
  }
  /**
   * Scrolls to an element and attempts to focus the element.
   *
   * Note that the function name here is misleading in that the target string may be an ID for a
   * non-anchor element.
   *
   * @param target The ID of an element or name of the anchor.
   *
   * @see https://html.spec.whatwg.org/#the-indicated-part-of-the-document
   * @see https://html.spec.whatwg.org/#scroll-to-fragid
   */
  scrollToAnchor(target) {
    const elSelected = findAnchorFromDocument(this.document, target);
    if (elSelected) {
      this.scrollToElement(elSelected);
      // After scrolling to the element, the spec dictates that we follow the focus steps for the
      // target. Rather than following the robust steps, simply attempt focus.
      //
      // @see https://html.spec.whatwg.org/#get-the-focusable-area
      // @see https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/focus
      // @see https://html.spec.whatwg.org/#focusable-area
      elSelected.focus();
    }
  }
  /**
   * Disables automatic scroll restoration provided by the browser.
   */
  setHistoryScrollRestoration(scrollRestoration) {
    this.window.history.scrollRestoration = scrollRestoration;
  }
  /**
   * Scrolls to an element using the native offset and the specified offset set on this scroller.
   *
   * The offset can be used when we know that there is a floating header and scrolling naively to an
   * element (ex: `scrollIntoView`) leaves the element hidden behind the floating header.
   */
  scrollToElement(el) {
    const rect = el.getBoundingClientRect();
    const left = rect.left + this.window.pageXOffset;
    const top = rect.top + this.window.pageYOffset;
    const offset = this.offset();
    this.window.scrollTo(left - offset[0], top - offset[1]);
  }
}
function findAnchorFromDocument(document, target) {
  const documentResult = document.getElementById(target) || document.getElementsByName(target)[0];
  if (documentResult) {
    return documentResult;
  }
  // `getElementById` and `getElementsByName` won't pierce through the shadow DOM so we
  // have to traverse the DOM manually and do the lookup through the shadow roots.
  if (typeof document.createTreeWalker === 'function' && document.body && typeof document.body.attachShadow === 'function') {
    const treeWalker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
    let currentNode = treeWalker.currentNode;
    while (currentNode) {
      const shadowRoot = currentNode.shadowRoot;
      if (shadowRoot) {
        // Note that `ShadowRoot` doesn't support `getElementsByName`
        // so we have to fall back to `querySelector`.
        const result = shadowRoot.getElementById(target) || shadowRoot.querySelector(`[name="${target}"]`);
        if (result) {
          return result;
        }
      }
      currentNode = treeWalker.nextNode();
    }
  }
  return null;
}
/**
 * Provides an empty implementation of the viewport scroller.
 */
class NullViewportScroller {
  /**
   * Empty implementation
   */
  setOffset(offset) {}
  /**
   * Empty implementation
   */
  getScrollPosition() {
    return [0, 0];
  }
  /**
   * Empty implementation
   */
  scrollToPosition(position) {}
  /**
   * Empty implementation
   */
  scrollToAnchor(anchor) {}
  /**
   * Empty implementation
   */
  setHistoryScrollRestoration(scrollRestoration) {}
}

/**
 * A wrapper around the `XMLHttpRequest` constructor.
 *
 * @publicApi
 */
class XhrFactory {}

/**
 * Value (out of 100) of the requested quality for placeholder images.
 */
const PLACEHOLDER_QUALITY = '20';

// Converts a string that represents a URL into a URL class instance.
function getUrl(src, win) {
  // Don't use a base URL is the URL is absolute.
  return isAbsoluteUrl(src) ? new URL(src) : new URL(src, win.location.href);
}
// Checks whether a URL is absolute (i.e. starts with `http://` or `https://`).
function isAbsoluteUrl(src) {
  return /^https?:\/\//.test(src);
}
// Given a URL, extract the hostname part.
// If a URL is a relative one - the URL is returned as is.
function extractHostname(url) {
  return isAbsoluteUrl(url) ? new URL(url).hostname : url;
}
function isValidPath(path) {
  const isString = typeof path === 'string';
  if (!isString || path.trim() === '') {
    return false;
  }
  // Calling new URL() will throw if the path string is malformed
  try {
    const url = new URL(path);
    return true;
  } catch {
    return false;
  }
}
function normalizePath(path) {
  return path.endsWith('/') ? path.slice(0, -1) : path;
}
function normalizeSrc(src) {
  return src.startsWith('/') ? src.slice(1) : src;
}

/**
 * Noop image loader that does no transformation to the original src and just returns it as is.
 * This loader is used as a default one if more specific logic is not provided in an app config.
 *
 * @see {@link ImageLoader}
 * @see {@link NgOptimizedImage}
 */
const noopImageLoader = config => config.src;
/**
 * Injection token that configures the image loader function.
 *
 * @see {@link ImageLoader}
 * @see {@link NgOptimizedImage}
 * @publicApi
 */
const IMAGE_LOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'ImageLoader' : '', {
  providedIn: 'root',
  factory: () => noopImageLoader
});
/**
 * Internal helper function that makes it easier to introduce custom image loaders for the
 * `NgOptimizedImage` directive. It is enough to specify a URL builder function to obtain full DI
 * configuration for a given loader: a DI token corresponding to the actual loader function, plus DI
 * tokens managing preconnect check functionality.
 * @param buildUrlFn a function returning a full URL based on loader's configuration
 * @param exampleUrls example of full URLs for a given loader (used in error messages)
 * @returns a set of DI providers corresponding to the configured image loader
 */
function createImageLoader(buildUrlFn, exampleUrls) {
  return function provideImageLoader(path) {
    if (!isValidPath(path)) {
      throwInvalidPathError(path, exampleUrls || []);
    }
    // The trailing / is stripped (if provided) to make URL construction (concatenation) easier in
    // the individual loader functions.
    path = normalizePath(path);
    const loaderFn = config => {
      if (isAbsoluteUrl(config.src)) {
        // Image loader functions expect an image file name (e.g. `my-image.png`)
        // or a relative path + a file name (e.g. `/a/b/c/my-image.png`) as an input,
        // so the final absolute URL can be constructed.
        // When an absolute URL is provided instead - the loader can not
        // build a final URL, thus the error is thrown to indicate that.
        throwUnexpectedAbsoluteUrlError(path, config.src);
      }
      return buildUrlFn(path, {
        ...config,
        src: normalizeSrc(config.src)
      });
    };
    const providers = [{
      provide: IMAGE_LOADER,
      useValue: loaderFn
    }];
    return providers;
  };
}
function throwInvalidPathError(path, exampleUrls) {
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, ngDevMode && `Image loader has detected an invalid path (\`${path}\`). ` + `To fix this, supply a path using one of the following formats: ${exampleUrls.join(' or ')}`);
}
function throwUnexpectedAbsoluteUrlError(path, url) {
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, ngDevMode && `Image loader has detected a \`<img>\` tag with an invalid \`ngSrc\` attribute: ${url}. ` + `This image loader expects \`ngSrc\` to be a relative URL - ` + `however the provided value is an absolute URL. ` + `To fix this, provide \`ngSrc\` as a path relative to the base URL ` + `configured for this loader (\`${path}\`).`);
}

/**
 * Function that generates an ImageLoader for [Cloudflare Image
 * Resizing](https://developers.cloudflare.com/images/image-resizing/) and turns it into an Angular
 * provider. Note: Cloudflare has multiple image products - this provider is specifically for
 * Cloudflare Image Resizing; it will not work with Cloudflare Images or Cloudflare Polish.
 *
 * @param path Your domain name, e.g. https://mysite.com
 * @returns Provider that provides an ImageLoader function
 *
 * @publicApi
 */
const provideCloudflareLoader = createImageLoader(createCloudflareUrl, ngDevMode ? ['https://<ZONE>/cdn-cgi/image/<OPTIONS>/<SOURCE-IMAGE>'] : undefined);
function createCloudflareUrl(path, config) {
  let params = `format=auto`;
  if (config.width) {
    params += `,width=${config.width}`;
  }
  // When requesting a placeholder image we ask for a low quality image to reduce the load time.
  if (config.isPlaceholder) {
    params += `,quality=${PLACEHOLDER_QUALITY}`;
  }
  // Cloudflare image URLs format:
  // https://developers.cloudflare.com/images/image-resizing/url-format/
  return `${path}/cdn-cgi/image/${params}/${config.src}`;
}

/**
 * Name and URL tester for Cloudinary.
 */
const cloudinaryLoaderInfo = {
  name: 'Cloudinary',
  testUrl: isCloudinaryUrl
};
const CLOUDINARY_LOADER_REGEX = /https?\:\/\/[^\/]+\.cloudinary\.com\/.+/;
/**
 * Tests whether a URL is from Cloudinary CDN.
 */
function isCloudinaryUrl(url) {
  return CLOUDINARY_LOADER_REGEX.test(url);
}
/**
 * Function that generates an ImageLoader for Cloudinary and turns it into an Angular provider.
 *
 * @param path Base URL of your Cloudinary images
 * This URL should match one of the following formats:
 * https://res.cloudinary.com/mysite
 * https://mysite.cloudinary.com
 * https://subdomain.mysite.com
 * @returns Set of providers to configure the Cloudinary loader.
 *
 * @publicApi
 */
const provideCloudinaryLoader = createImageLoader(createCloudinaryUrl, ngDevMode ? ['https://res.cloudinary.com/mysite', 'https://mysite.cloudinary.com', 'https://subdomain.mysite.com'] : undefined);
function createCloudinaryUrl(path, config) {
  // Cloudinary image URLformat:
  // https://cloudinary.com/documentation/image_transformations#transformation_url_structure
  // Example of a Cloudinary image URL:
  // https://res.cloudinary.com/mysite/image/upload/c_scale,f_auto,q_auto,w_600/marketing/tile-topics-m.png
  // For a placeholder image, we use the lowest image setting available to reduce the load time
  // else we use the auto size
  const quality = config.isPlaceholder ? 'q_auto:low' : 'q_auto';
  let params = `f_auto,${quality}`;
  if (config.width) {
    params += `,w_${config.width}`;
  }
  return `${path}/image/upload/${params}/${config.src}`;
}

/**
 * Name and URL tester for ImageKit.
 */
const imageKitLoaderInfo = {
  name: 'ImageKit',
  testUrl: isImageKitUrl
};
const IMAGE_KIT_LOADER_REGEX = /https?\:\/\/[^\/]+\.imagekit\.io\/.+/;
/**
 * Tests whether a URL is from ImageKit CDN.
 */
function isImageKitUrl(url) {
  return IMAGE_KIT_LOADER_REGEX.test(url);
}
/**
 * Function that generates an ImageLoader for ImageKit and turns it into an Angular provider.
 *
 * @param path Base URL of your ImageKit images
 * This URL should match one of the following formats:
 * https://ik.imagekit.io/myaccount
 * https://subdomain.mysite.com
 * @returns Set of providers to configure the ImageKit loader.
 *
 * @publicApi
 */
const provideImageKitLoader = createImageLoader(createImagekitUrl, ngDevMode ? ['https://ik.imagekit.io/mysite', 'https://subdomain.mysite.com'] : undefined);
function createImagekitUrl(path, config) {
  // Example of an ImageKit image URL:
  // https://ik.imagekit.io/demo/tr:w-300,h-300/medium_cafe_B1iTdD0C.jpg
  const {
    src,
    width
  } = config;
  const params = [];
  if (width) {
    params.push(`w-${width}`);
  }
  // When requesting a placeholder image we ask for a low quality image to reduce the load time.
  if (config.isPlaceholder) {
    params.push(`q-${PLACEHOLDER_QUALITY}`);
  }
  const urlSegments = params.length ? [path, `tr:${params.join(',')}`, src] : [path, src];
  const url = new URL(urlSegments.join('/'));
  return url.href;
}

/**
 * Name and URL tester for Imgix.
 */
const imgixLoaderInfo = {
  name: 'Imgix',
  testUrl: isImgixUrl
};
const IMGIX_LOADER_REGEX = /https?\:\/\/[^\/]+\.imgix\.net\/.+/;
/**
 * Tests whether a URL is from Imgix CDN.
 */
function isImgixUrl(url) {
  return IMGIX_LOADER_REGEX.test(url);
}
/**
 * Function that generates an ImageLoader for Imgix and turns it into an Angular provider.
 *
 * @param path path to the desired Imgix origin,
 * e.g. https://somepath.imgix.net or https://images.mysite.com
 * @returns Set of providers to configure the Imgix loader.
 *
 * @publicApi
 */
const provideImgixLoader = createImageLoader(createImgixUrl, ngDevMode ? ['https://somepath.imgix.net/'] : undefined);
function createImgixUrl(path, config) {
  const url = new URL(`${path}/${config.src}`);
  // This setting ensures the smallest allowable format is set.
  url.searchParams.set('auto', 'format');
  if (config.width) {
    url.searchParams.set('w', config.width.toString());
  }
  // When requesting a placeholder image we ask a low quality image to reduce the load time.
  if (config.isPlaceholder) {
    url.searchParams.set('q', PLACEHOLDER_QUALITY);
  }
  return url.href;
}

/**
 * Name and URL tester for Netlify.
 */
const netlifyLoaderInfo = {
  name: 'Netlify',
  testUrl: isNetlifyUrl
};
const NETLIFY_LOADER_REGEX = /https?\:\/\/[^\/]+\.netlify\.app\/.+/;
/**
 * Tests whether a URL is from a Netlify site. This won't catch sites with a custom domain,
 * but it's a good start for sites in development. This is only used to warn users who haven't
 * configured an image loader.
 */
function isNetlifyUrl(url) {
  return NETLIFY_LOADER_REGEX.test(url);
}
/**
 * Function that generates an ImageLoader for Netlify and turns it into an Angular provider.
 *
 * @param path optional URL of the desired Netlify site. Defaults to the current site.
 * @returns Set of providers to configure the Netlify loader.
 *
 * @publicApi
 */
function provideNetlifyLoader(path) {
  if (path && !isValidPath(path)) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, ngDevMode && `Image loader has detected an invalid path (\`${path}\`). ` + `To fix this, supply either the full URL to the Netlify site, or leave it empty to use the current site.`);
  }
  if (path) {
    const url = new URL(path);
    path = url.origin;
  }
  const loaderFn = config => {
    return createNetlifyUrl(config, path);
  };
  const providers = [{
    provide: IMAGE_LOADER,
    useValue: loaderFn
  }];
  return providers;
}
const validParams = new Map([['height', 'h'], ['fit', 'fit'], ['quality', 'q'], ['q', 'q'], ['position', 'position']]);
function createNetlifyUrl(config, path) {
  // Note: `path` can be undefined, in which case we use a fake one to construct a `URL` instance.
  const url = new URL(path ?? 'https://a/');
  url.pathname = '/.netlify/images';
  if (!isAbsoluteUrl(config.src) && !config.src.startsWith('/')) {
    config.src = '/' + config.src;
  }
  url.searchParams.set('url', config.src);
  if (config.width) {
    url.searchParams.set('w', config.width.toString());
  }
  // When requesting a placeholder image we ask for a low quality image to reduce the load time.
  // If the quality is specified in the loader config - always use provided value.
  const configQuality = config.loaderParams?.['quality'] ?? config.loaderParams?.['q'];
  if (config.isPlaceholder && !configQuality) {
    url.searchParams.set('q', PLACEHOLDER_QUALITY);
  }
  for (const [param, value] of Object.entries(config.loaderParams ?? {})) {
    if (validParams.has(param)) {
      url.searchParams.set(validParams.get(param), value.toString());
    } else {
      if (ngDevMode) {
        console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2959 /* RuntimeErrorCode.INVALID_LOADER_ARGUMENTS */, `The Netlify image loader has detected an \`<img>\` tag with the unsupported attribute "\`${param}\`".`));
      }
    }
  }
  // The "a" hostname is used for relative URLs, so we can remove it from the final URL.
  return url.hostname === 'a' ? url.href.replace(url.origin, '') : url.href;
}

// Assembles directive details string, useful for error messages.
function imgDirectiveDetails(ngSrc, includeNgSrc = true) {
  const ngSrcInfo = includeNgSrc ? `(activated on an <img> element with the \`ngSrc="${ngSrc}"\`) ` : '';
  return `The NgOptimizedImage directive ${ngSrcInfo}has detected that`;
}

/**
 * Asserts that the application is in development mode. Throws an error if the application is in
 * production mode. This assert can be used to make sure that there is no dev-mode code invoked in
 * the prod mode accidentally.
 */
function assertDevMode(checkName) {
  if (!ngDevMode) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2958 /* RuntimeErrorCode.UNEXPECTED_DEV_MODE_CHECK_IN_PROD_MODE */, `Unexpected invocation of the ${checkName} in the prod mode. ` + `Please make sure that the prod mode is enabled for production builds.`);
  }
}

/**
 * Observer that detects whether an image with `NgOptimizedImage`
 * is treated as a Largest Contentful Paint (LCP) element. If so,
 * asserts that the image has the `priority` attribute.
 *
 * Note: this is a dev-mode only class and it does not appear in prod bundles,
 * thus there is no `ngDevMode` use in the code.
 *
 * Based on https://web.dev/lcp/#measure-lcp-in-javascript.
 */
class LCPImageObserver {
  constructor() {
    // Map of full image URLs -> original `ngSrc` values.
    this.images = new Map();
    this.window = null;
    this.observer = null;
    assertDevMode('LCP checker');
    const win = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT).defaultView;
    if (typeof win !== 'undefined' && typeof PerformanceObserver !== 'undefined') {
      this.window = win;
      this.observer = this.initPerformanceObserver();
    }
  }
  /**
   * Inits PerformanceObserver and subscribes to LCP events.
   * Based on https://web.dev/lcp/#measure-lcp-in-javascript
   */
  initPerformanceObserver() {
    const observer = new PerformanceObserver(entryList => {
      const entries = entryList.getEntries();
      if (entries.length === 0) return;
      // We use the latest entry produced by the `PerformanceObserver` as the best
      // signal on which element is actually an LCP one. As an example, the first image to load on
      // a page, by virtue of being the only thing on the page so far, is often a LCP candidate
      // and gets reported by PerformanceObserver, but isn't necessarily the LCP element.
      const lcpElement = entries[entries.length - 1];
      // Cast to `any` due to missing `element` on the `LargestContentfulPaint` type of entry.
      // See https://developer.mozilla.org/en-US/docs/Web/API/LargestContentfulPaint
      const imgSrc = lcpElement.element?.src ?? '';
      // Exclude `data:` and `blob:` URLs, since they are not supported by the directive.
      if (imgSrc.startsWith('data:') || imgSrc.startsWith('blob:')) return;
      const img = this.images.get(imgSrc);
      if (!img) return;
      if (!img.priority && !img.alreadyWarnedPriority) {
        img.alreadyWarnedPriority = true;
        logMissingPriorityError(imgSrc);
      }
      if (img.modified && !img.alreadyWarnedModified) {
        img.alreadyWarnedModified = true;
        logModifiedWarning(imgSrc);
      }
    });
    observer.observe({
      type: 'largest-contentful-paint',
      buffered: true
    });
    return observer;
  }
  registerImage(rewrittenSrc, originalNgSrc, isPriority) {
    if (!this.observer) return;
    const newObservedImageState = {
      priority: isPriority,
      modified: false,
      alreadyWarnedModified: false,
      alreadyWarnedPriority: false
    };
    this.images.set(getUrl(rewrittenSrc, this.window).href, newObservedImageState);
  }
  unregisterImage(rewrittenSrc) {
    if (!this.observer) return;
    this.images.delete(getUrl(rewrittenSrc, this.window).href);
  }
  updateImage(originalSrc, newSrc) {
    const originalUrl = getUrl(originalSrc, this.window).href;
    const img = this.images.get(originalUrl);
    if (img) {
      img.modified = true;
      this.images.set(getUrl(newSrc, this.window).href, img);
      this.images.delete(originalUrl);
    }
  }
  ngOnDestroy() {
    if (!this.observer) return;
    this.observer.disconnect();
    this.images.clear();
  }
  static {
    this.ɵfac = function LCPImageObserver_Factory(t) {
      return new (t || LCPImageObserver)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: LCPImageObserver,
      factory: LCPImageObserver.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LCPImageObserver, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();
function logMissingPriorityError(ngSrc) {
  const directiveDetails = imgDirectiveDetails(ngSrc);
  console.error((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2955 /* RuntimeErrorCode.LCP_IMG_MISSING_PRIORITY */, `${directiveDetails} this image is the Largest Contentful Paint (LCP) ` + `element but was not marked "priority". This image should be marked ` + `"priority" in order to prioritize its loading. ` + `To fix this, add the "priority" attribute.`));
}
function logModifiedWarning(ngSrc) {
  const directiveDetails = imgDirectiveDetails(ngSrc);
  console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2964 /* RuntimeErrorCode.LCP_IMG_NGSRC_MODIFIED */, `${directiveDetails} this image is the Largest Contentful Paint (LCP) ` + `element and has had its "ngSrc" attribute modified. This can cause ` + `slower loading performance. It is recommended not to modify the "ngSrc" ` + `property on any image which could be the LCP element.`));
}

// Set of origins that are always excluded from the preconnect checks.
const INTERNAL_PRECONNECT_CHECK_BLOCKLIST = new Set(['localhost', '127.0.0.1', '0.0.0.0']);
/**
 * Injection token to configure which origins should be excluded
 * from the preconnect checks. It can either be a single string or an array of strings
 * to represent a group of origins, for example:
 *
 * ```typescript
 *  {provide: PRECONNECT_CHECK_BLOCKLIST, useValue: 'https://your-domain.com'}
 * ```
 *
 * or:
 *
 * ```typescript
 *  {provide: PRECONNECT_CHECK_BLOCKLIST,
 *   useValue: ['https://your-domain-1.com', 'https://your-domain-2.com']}
 * ```
 *
 * @publicApi
 */
const PRECONNECT_CHECK_BLOCKLIST = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'PRECONNECT_CHECK_BLOCKLIST' : '');
/**
 * Contains the logic to detect whether an image, marked with the "priority" attribute
 * has a corresponding `<link rel="preconnect">` tag in the `document.head`.
 *
 * Note: this is a dev-mode only class, which should not appear in prod bundles,
 * thus there is no `ngDevMode` use in the code.
 */
class PreconnectLinkChecker {
  constructor() {
    this.document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT);
    /**
     * Set of <link rel="preconnect"> tags found on this page.
     * The `null` value indicates that there was no DOM query operation performed.
     */
    this.preconnectLinks = null;
    /*
     * Keep track of all already seen origin URLs to avoid repeating the same check.
     */
    this.alreadySeen = new Set();
    this.window = null;
    this.blocklist = new Set(INTERNAL_PRECONNECT_CHECK_BLOCKLIST);
    assertDevMode('preconnect link checker');
    const win = this.document.defaultView;
    if (typeof win !== 'undefined') {
      this.window = win;
    }
    const blocklist = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PRECONNECT_CHECK_BLOCKLIST, {
      optional: true
    });
    if (blocklist) {
      this.populateBlocklist(blocklist);
    }
  }
  populateBlocklist(origins) {
    if (Array.isArray(origins)) {
      deepForEach(origins, origin => {
        this.blocklist.add(extractHostname(origin));
      });
    } else {
      this.blocklist.add(extractHostname(origins));
    }
  }
  /**
   * Checks that a preconnect resource hint exists in the head for the
   * given src.
   *
   * @param rewrittenSrc src formatted with loader
   * @param originalNgSrc ngSrc value
   */
  assertPreconnect(rewrittenSrc, originalNgSrc) {
    if (!this.window) return;
    const imgUrl = getUrl(rewrittenSrc, this.window);
    if (this.blocklist.has(imgUrl.hostname) || this.alreadySeen.has(imgUrl.origin)) return;
    // Register this origin as seen, so we don't check it again later.
    this.alreadySeen.add(imgUrl.origin);
    // Note: we query for preconnect links only *once* and cache the results
    // for the entire lifespan of an application, since it's unlikely that the
    // list would change frequently. This allows to make sure there are no
    // performance implications of making extra DOM lookups for each image.
    this.preconnectLinks ??= this.queryPreconnectLinks();
    if (!this.preconnectLinks.has(imgUrl.origin)) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2956 /* RuntimeErrorCode.PRIORITY_IMG_MISSING_PRECONNECT_TAG */, `${imgDirectiveDetails(originalNgSrc)} there is no preconnect tag present for this ` + `image. Preconnecting to the origin(s) that serve priority images ensures that these ` + `images are delivered as soon as possible. To fix this, please add the following ` + `element into the <head> of the document:\n` + `  <link rel="preconnect" href="${imgUrl.origin}">`));
    }
  }
  queryPreconnectLinks() {
    const preconnectUrls = new Set();
    const selector = 'link[rel=preconnect]';
    const links = Array.from(this.document.querySelectorAll(selector));
    for (let link of links) {
      const url = getUrl(link.href, this.window);
      preconnectUrls.add(url.origin);
    }
    return preconnectUrls;
  }
  ngOnDestroy() {
    this.preconnectLinks?.clear();
    this.alreadySeen.clear();
  }
  static {
    this.ɵfac = function PreconnectLinkChecker_Factory(t) {
      return new (t || PreconnectLinkChecker)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: PreconnectLinkChecker,
      factory: PreconnectLinkChecker.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PreconnectLinkChecker, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();
/**
 * Invokes a callback for each element in the array. Also invokes a callback
 * recursively for each nested array.
 */
function deepForEach(input, fn) {
  for (let value of input) {
    Array.isArray(value) ? deepForEach(value, fn) : fn(value);
  }
}

/**
 * In SSR scenarios, a preload `<link>` element is generated for priority images.
 * Having a large number of preload tags may negatively affect the performance,
 * so we warn developers (by throwing an error) if the number of preloaded images
 * is above a certain threshold. This const specifies this threshold.
 */
const DEFAULT_PRELOADED_IMAGES_LIMIT = 5;
/**
 * Helps to keep track of priority images that already have a corresponding
 * preload tag (to avoid generating multiple preload tags with the same URL).
 *
 * This Set tracks the original src passed into the `ngSrc` input not the src after it has been
 * run through the specified `IMAGE_LOADER`.
 */
const PRELOADED_IMAGES = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('NG_OPTIMIZED_PRELOADED_IMAGES', {
  providedIn: 'root',
  factory: () => new Set()
});

/**
 * @description Contains the logic needed to track and add preload link tags to the `<head>` tag. It
 * will also track what images have already had preload link tags added so as to not duplicate link
 * tags.
 *
 * In dev mode this service will validate that the number of preloaded images does not exceed the
 * configured default preloaded images limit: {@link DEFAULT_PRELOADED_IMAGES_LIMIT}.
 */
class PreloadLinkCreator {
  constructor() {
    this.preloadedImages = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PRELOADED_IMAGES);
    this.document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DOCUMENT);
  }
  /**
   * @description Add a preload `<link>` to the `<head>` of the `index.html` that is served from the
   * server while using Angular Universal and SSR to kick off image loads for high priority images.
   *
   * The `sizes` (passed in from the user) and `srcset` (parsed and formatted from `ngSrcset`)
   * properties used to set the corresponding attributes, `imagesizes` and `imagesrcset`
   * respectively, on the preload `<link>` tag so that the correctly sized image is preloaded from
   * the CDN.
   *
   * {@link https://web.dev/preload-responsive-images/#imagesrcset-and-imagesizes}
   *
   * @param renderer The `Renderer2` passed in from the directive
   * @param src The original src of the image that is set on the `ngSrc` input.
   * @param srcset The parsed and formatted srcset created from the `ngSrcset` input
   * @param sizes The value of the `sizes` attribute passed in to the `<img>` tag
   */
  createPreloadLinkTag(renderer, src, srcset, sizes) {
    if (ngDevMode) {
      if (this.preloadedImages.size >= DEFAULT_PRELOADED_IMAGES_LIMIT) {
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2961 /* RuntimeErrorCode.TOO_MANY_PRELOADED_IMAGES */, ngDevMode && `The \`NgOptimizedImage\` directive has detected that more than ` + `${DEFAULT_PRELOADED_IMAGES_LIMIT} images were marked as priority. ` + `This might negatively affect an overall performance of the page. ` + `To fix this, remove the "priority" attribute from images with less priority.`);
      }
    }
    if (this.preloadedImages.has(src)) {
      return;
    }
    this.preloadedImages.add(src);
    const preload = renderer.createElement('link');
    renderer.setAttribute(preload, 'as', 'image');
    renderer.setAttribute(preload, 'href', src);
    renderer.setAttribute(preload, 'rel', 'preload');
    renderer.setAttribute(preload, 'fetchpriority', 'high');
    if (sizes) {
      renderer.setAttribute(preload, 'imageSizes', sizes);
    }
    if (srcset) {
      renderer.setAttribute(preload, 'imageSrcset', srcset);
    }
    renderer.appendChild(this.document.head, preload);
  }
  static {
    this.ɵfac = function PreloadLinkCreator_Factory(t) {
      return new (t || PreloadLinkCreator)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: PreloadLinkCreator,
      factory: PreloadLinkCreator.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PreloadLinkCreator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * When a Base64-encoded image is passed as an input to the `NgOptimizedImage` directive,
 * an error is thrown. The image content (as a string) might be very long, thus making
 * it hard to read an error message if the entire string is included. This const defines
 * the number of characters that should be included into the error message. The rest
 * of the content is truncated.
 */
const BASE64_IMG_MAX_LENGTH_IN_ERROR = 50;
/**
 * RegExpr to determine whether a src in a srcset is using width descriptors.
 * Should match something like: "100w, 200w".
 */
const VALID_WIDTH_DESCRIPTOR_SRCSET = /^((\s*\d+w\s*(,|$)){1,})$/;
/**
 * RegExpr to determine whether a src in a srcset is using density descriptors.
 * Should match something like: "1x, 2x, 50x". Also supports decimals like "1.5x, 1.50x".
 */
const VALID_DENSITY_DESCRIPTOR_SRCSET = /^((\s*\d+(\.\d+)?x\s*(,|$)){1,})$/;
/**
 * Srcset values with a density descriptor higher than this value will actively
 * throw an error. Such densities are not permitted as they cause image sizes
 * to be unreasonably large and slow down LCP.
 */
const ABSOLUTE_SRCSET_DENSITY_CAP = 3;
/**
 * Used only in error message text to communicate best practices, as we will
 * only throw based on the slightly more conservative ABSOLUTE_SRCSET_DENSITY_CAP.
 */
const RECOMMENDED_SRCSET_DENSITY_CAP = 2;
/**
 * Used in generating automatic density-based srcsets
 */
const DENSITY_SRCSET_MULTIPLIERS = [1, 2];
/**
 * Used to determine which breakpoints to use on full-width images
 */
const VIEWPORT_BREAKPOINT_CUTOFF = 640;
/**
 * Used to determine whether two aspect ratios are similar in value.
 */
const ASPECT_RATIO_TOLERANCE = 0.1;
/**
 * Used to determine whether the image has been requested at an overly
 * large size compared to the actual rendered image size (after taking
 * into account a typical device pixel ratio). In pixels.
 */
const OVERSIZED_IMAGE_TOLERANCE = 1000;
/**
 * Used to limit automatic srcset generation of very large sources for
 * fixed-size images. In pixels.
 */
const FIXED_SRCSET_WIDTH_LIMIT = 1920;
const FIXED_SRCSET_HEIGHT_LIMIT = 1080;
/**
 * Default blur radius of the CSS filter used on placeholder images, in pixels
 */
const PLACEHOLDER_BLUR_AMOUNT = 15;
/**
 * Used to warn or error when the user provides an overly large dataURL for the placeholder
 * attribute.
 * Character count of Base64 images is 1 character per byte, and base64 encoding is approximately
 * 33% larger than base images, so 4000 characters is around 3KB on disk and 10000 characters is
 * around 7.7KB. Experimentally, 4000 characters is about 20x20px in PNG or medium-quality JPEG
 * format, and 10,000 is around 50x50px, but there's quite a bit of variation depending on how the
 * image is saved.
 */
const DATA_URL_WARN_LIMIT = 4000;
const DATA_URL_ERROR_LIMIT = 10000;
/** Info about built-in loaders we can test for. */
const BUILT_IN_LOADERS = [imgixLoaderInfo, imageKitLoaderInfo, cloudinaryLoaderInfo, netlifyLoaderInfo];
/**
 * Directive that improves image loading performance by enforcing best practices.
 *
 * `NgOptimizedImage` ensures that the loading of the Largest Contentful Paint (LCP) image is
 * prioritized by:
 * - Automatically setting the `fetchpriority` attribute on the `<img>` tag
 * - Lazy loading non-priority images by default
 * - Automatically generating a preconnect link tag in the document head
 *
 * In addition, the directive:
 * - Generates appropriate asset URLs if a corresponding `ImageLoader` function is provided
 * - Automatically generates a srcset
 * - Requires that `width` and `height` are set
 * - Warns if `width` or `height` have been set incorrectly
 * - Warns if the image will be visually distorted when rendered
 *
 * @usageNotes
 * The `NgOptimizedImage` directive is marked as [standalone](guide/standalone-components) and can
 * be imported directly.
 *
 * Follow the steps below to enable and use the directive:
 * 1. Import it into the necessary NgModule or a standalone Component.
 * 2. Optionally provide an `ImageLoader` if you use an image hosting service.
 * 3. Update the necessary `<img>` tags in templates and replace `src` attributes with `ngSrc`.
 * Using a `ngSrc` allows the directive to control when the `src` gets set, which triggers an image
 * download.
 *
 * Step 1: import the `NgOptimizedImage` directive.
 *
 * ```typescript
 * import { NgOptimizedImage } from '@angular/common';
 *
 * // Include it into the necessary NgModule
 * @NgModule({
 *   imports: [NgOptimizedImage],
 * })
 * class AppModule {}
 *
 * // ... or a standalone Component
 * @Component({
 *   standalone: true
 *   imports: [NgOptimizedImage],
 * })
 * class MyStandaloneComponent {}
 * ```
 *
 * Step 2: configure a loader.
 *
 * To use the **default loader**: no additional code changes are necessary. The URL returned by the
 * generic loader will always match the value of "src". In other words, this loader applies no
 * transformations to the resource URL and the value of the `ngSrc` attribute will be used as is.
 *
 * To use an existing loader for a **third-party image service**: add the provider factory for your
 * chosen service to the `providers` array. In the example below, the Imgix loader is used:
 *
 * ```typescript
 * import {provideImgixLoader} from '@angular/common';
 *
 * // Call the function and add the result to the `providers` array:
 * providers: [
 *   provideImgixLoader("https://my.base.url/"),
 * ],
 * ```
 *
 * The `NgOptimizedImage` directive provides the following functions:
 * - `provideCloudflareLoader`
 * - `provideCloudinaryLoader`
 * - `provideImageKitLoader`
 * - `provideImgixLoader`
 *
 * If you use a different image provider, you can create a custom loader function as described
 * below.
 *
 * To use a **custom loader**: provide your loader function as a value for the `IMAGE_LOADER` DI
 * token.
 *
 * ```typescript
 * import {IMAGE_LOADER, ImageLoaderConfig} from '@angular/common';
 *
 * // Configure the loader using the `IMAGE_LOADER` token.
 * providers: [
 *   {
 *      provide: IMAGE_LOADER,
 *      useValue: (config: ImageLoaderConfig) => {
 *        return `https://example.com/${config.src}-${config.width}.jpg}`;
 *      }
 *   },
 * ],
 * ```
 *
 * Step 3: update `<img>` tags in templates to use `ngSrc` instead of `src`.
 *
 * ```
 * <img ngSrc="logo.png" width="200" height="100">
 * ```
 *
 * @publicApi
 */
class NgOptimizedImage {
  constructor() {
    this.imageLoader = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(IMAGE_LOADER);
    this.config = processConfig((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵIMAGE_CONFIG"]));
    this.renderer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2);
    this.imgElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this.injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this.isServer = isPlatformServer((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID));
    this.preloadLinkCreator = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(PreloadLinkCreator);
    // a LCP image observer - should be injected only in the dev mode
    this.lcpObserver = ngDevMode ? this.injector.get(LCPImageObserver) : null;
    /**
     * Calculate the rewritten `src` once and store it.
     * This is needed to avoid repetitive calculations and make sure the directive cleanup in the
     * `ngOnDestroy` does not rely on the `IMAGE_LOADER` logic (which in turn can rely on some other
     * instance that might be already destroyed).
     */
    this._renderedSrc = null;
    /**
     * Indicates whether this image should have a high priority.
     */
    this.priority = false;
    /**
     * Disables automatic srcset generation for this image.
     */
    this.disableOptimizedSrcset = false;
    /**
     * Sets the image to "fill mode", which eliminates the height/width requirement and adds
     * styles such that the image fills its containing element.
     */
    this.fill = false;
  }
  /** @nodoc */
  ngOnInit() {
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵperformanceMarkFeature"])('NgOptimizedImage');
    if (ngDevMode) {
      const ngZone = this.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
      assertNonEmptyInput(this, 'ngSrc', this.ngSrc);
      assertValidNgSrcset(this, this.ngSrcset);
      assertNoConflictingSrc(this);
      if (this.ngSrcset) {
        assertNoConflictingSrcset(this);
      }
      assertNotBase64Image(this);
      assertNotBlobUrl(this);
      if (this.fill) {
        assertEmptyWidthAndHeight(this);
        // This leaves the Angular zone to avoid triggering unnecessary change detection cycles when
        // `load` tasks are invoked on images.
        ngZone.runOutsideAngular(() => assertNonZeroRenderedHeight(this, this.imgElement, this.renderer));
      } else {
        assertNonEmptyWidthAndHeight(this);
        if (this.height !== undefined) {
          assertGreaterThanZero(this, this.height, 'height');
        }
        if (this.width !== undefined) {
          assertGreaterThanZero(this, this.width, 'width');
        }
        // Only check for distorted images when not in fill mode, where
        // images may be intentionally stretched, cropped or letterboxed.
        ngZone.runOutsideAngular(() => assertNoImageDistortion(this, this.imgElement, this.renderer));
      }
      assertValidLoadingInput(this);
      if (!this.ngSrcset) {
        assertNoComplexSizes(this);
      }
      assertValidPlaceholder(this, this.imageLoader);
      assertNotMissingBuiltInLoader(this.ngSrc, this.imageLoader);
      assertNoNgSrcsetWithoutLoader(this, this.imageLoader);
      assertNoLoaderParamsWithoutLoader(this, this.imageLoader);
      if (this.lcpObserver !== null) {
        const ngZone = this.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
        ngZone.runOutsideAngular(() => {
          this.lcpObserver.registerImage(this.getRewrittenSrc(), this.ngSrc, this.priority);
        });
      }
      if (this.priority) {
        const checker = this.injector.get(PreconnectLinkChecker);
        checker.assertPreconnect(this.getRewrittenSrc(), this.ngSrc);
      }
    }
    if (this.placeholder) {
      this.removePlaceholderOnLoad(this.imgElement);
    }
    this.setHostAttributes();
  }
  setHostAttributes() {
    // Must set width/height explicitly in case they are bound (in which case they will
    // only be reflected and not found by the browser)
    if (this.fill) {
      this.sizes ||= '100vw';
    } else {
      this.setHostAttribute('width', this.width.toString());
      this.setHostAttribute('height', this.height.toString());
    }
    this.setHostAttribute('loading', this.getLoadingBehavior());
    this.setHostAttribute('fetchpriority', this.getFetchPriority());
    // The `data-ng-img` attribute flags an image as using the directive, to allow
    // for analysis of the directive's performance.
    this.setHostAttribute('ng-img', 'true');
    // The `src` and `srcset` attributes should be set last since other attributes
    // could affect the image's loading behavior.
    const rewrittenSrcset = this.updateSrcAndSrcset();
    if (this.sizes) {
      this.setHostAttribute('sizes', this.sizes);
    }
    if (this.isServer && this.priority) {
      this.preloadLinkCreator.createPreloadLinkTag(this.renderer, this.getRewrittenSrc(), rewrittenSrcset, this.sizes);
    }
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (ngDevMode) {
      assertNoPostInitInputChange(this, changes, ['ngSrcset', 'width', 'height', 'priority', 'fill', 'loading', 'sizes', 'loaderParams', 'disableOptimizedSrcset']);
    }
    if (changes['ngSrc'] && !changes['ngSrc'].isFirstChange()) {
      const oldSrc = this._renderedSrc;
      this.updateSrcAndSrcset(true);
      const newSrc = this._renderedSrc;
      if (this.lcpObserver !== null && oldSrc && newSrc && oldSrc !== newSrc) {
        const ngZone = this.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
        ngZone.runOutsideAngular(() => {
          this.lcpObserver?.updateImage(oldSrc, newSrc);
        });
      }
    }
  }
  callImageLoader(configWithoutCustomParams) {
    let augmentedConfig = configWithoutCustomParams;
    if (this.loaderParams) {
      augmentedConfig.loaderParams = this.loaderParams;
    }
    return this.imageLoader(augmentedConfig);
  }
  getLoadingBehavior() {
    if (!this.priority && this.loading !== undefined) {
      return this.loading;
    }
    return this.priority ? 'eager' : 'lazy';
  }
  getFetchPriority() {
    return this.priority ? 'high' : 'auto';
  }
  getRewrittenSrc() {
    // ImageLoaderConfig supports setting a width property. However, we're not setting width here
    // because if the developer uses rendered width instead of intrinsic width in the HTML width
    // attribute, the image requested may be too small for 2x+ screens.
    if (!this._renderedSrc) {
      const imgConfig = {
        src: this.ngSrc
      };
      // Cache calculated image src to reuse it later in the code.
      this._renderedSrc = this.callImageLoader(imgConfig);
    }
    return this._renderedSrc;
  }
  getRewrittenSrcset() {
    const widthSrcSet = VALID_WIDTH_DESCRIPTOR_SRCSET.test(this.ngSrcset);
    const finalSrcs = this.ngSrcset.split(',').filter(src => src !== '').map(srcStr => {
      srcStr = srcStr.trim();
      const width = widthSrcSet ? parseFloat(srcStr) : parseFloat(srcStr) * this.width;
      return `${this.callImageLoader({
        src: this.ngSrc,
        width
      })} ${srcStr}`;
    });
    return finalSrcs.join(', ');
  }
  getAutomaticSrcset() {
    if (this.sizes) {
      return this.getResponsiveSrcset();
    } else {
      return this.getFixedSrcset();
    }
  }
  getResponsiveSrcset() {
    const {
      breakpoints
    } = this.config;
    let filteredBreakpoints = breakpoints;
    if (this.sizes?.trim() === '100vw') {
      // Since this is a full-screen-width image, our srcset only needs to include
      // breakpoints with full viewport widths.
      filteredBreakpoints = breakpoints.filter(bp => bp >= VIEWPORT_BREAKPOINT_CUTOFF);
    }
    const finalSrcs = filteredBreakpoints.map(bp => `${this.callImageLoader({
      src: this.ngSrc,
      width: bp
    })} ${bp}w`);
    return finalSrcs.join(', ');
  }
  updateSrcAndSrcset(forceSrcRecalc = false) {
    if (forceSrcRecalc) {
      // Reset cached value, so that the followup `getRewrittenSrc()` call
      // will recalculate it and update the cache.
      this._renderedSrc = null;
    }
    const rewrittenSrc = this.getRewrittenSrc();
    this.setHostAttribute('src', rewrittenSrc);
    let rewrittenSrcset = undefined;
    if (this.ngSrcset) {
      rewrittenSrcset = this.getRewrittenSrcset();
    } else if (this.shouldGenerateAutomaticSrcset()) {
      rewrittenSrcset = this.getAutomaticSrcset();
    }
    if (rewrittenSrcset) {
      this.setHostAttribute('srcset', rewrittenSrcset);
    }
    return rewrittenSrcset;
  }
  getFixedSrcset() {
    const finalSrcs = DENSITY_SRCSET_MULTIPLIERS.map(multiplier => `${this.callImageLoader({
      src: this.ngSrc,
      width: this.width * multiplier
    })} ${multiplier}x`);
    return finalSrcs.join(', ');
  }
  shouldGenerateAutomaticSrcset() {
    let oversizedImage = false;
    if (!this.sizes) {
      oversizedImage = this.width > FIXED_SRCSET_WIDTH_LIMIT || this.height > FIXED_SRCSET_HEIGHT_LIMIT;
    }
    return !this.disableOptimizedSrcset && !this.srcset && this.imageLoader !== noopImageLoader && !oversizedImage;
  }
  /**
   * Returns an image url formatted for use with the CSS background-image property. Expects one of:
   * * A base64 encoded image, which is wrapped and passed through.
   * * A boolean. If true, calls the image loader to generate a small placeholder url.
   */
  generatePlaceholder(placeholderInput) {
    const {
      placeholderResolution
    } = this.config;
    if (placeholderInput === true) {
      return `url(${this.callImageLoader({
        src: this.ngSrc,
        width: placeholderResolution,
        isPlaceholder: true
      })})`;
    } else if (typeof placeholderInput === 'string' && placeholderInput.startsWith('data:')) {
      return `url(${placeholderInput})`;
    }
    return null;
  }
  /**
   * Determines if blur should be applied, based on an optional boolean
   * property `blur` within the optional configuration object `placeholderConfig`.
   */
  shouldBlurPlaceholder(placeholderConfig) {
    if (!placeholderConfig || !placeholderConfig.hasOwnProperty('blur')) {
      return true;
    }
    return Boolean(placeholderConfig.blur);
  }
  removePlaceholderOnLoad(img) {
    const callback = () => {
      const changeDetectorRef = this.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
      removeLoadListenerFn();
      removeErrorListenerFn();
      this.placeholder = false;
      changeDetectorRef.markForCheck();
    };
    const removeLoadListenerFn = this.renderer.listen(img, 'load', callback);
    const removeErrorListenerFn = this.renderer.listen(img, 'error', callback);
  }
  /** @nodoc */
  ngOnDestroy() {
    if (ngDevMode) {
      if (!this.priority && this._renderedSrc !== null && this.lcpObserver !== null) {
        this.lcpObserver.unregisterImage(this._renderedSrc);
      }
    }
  }
  setHostAttribute(name, value) {
    this.renderer.setAttribute(this.imgElement, name, value);
  }
  static {
    this.ɵfac = function NgOptimizedImage_Factory(t) {
      return new (t || NgOptimizedImage)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgOptimizedImage,
      selectors: [["img", "ngSrc", ""]],
      hostVars: 18,
      hostBindings: function NgOptimizedImage_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("position", ctx.fill ? "absolute" : null)("width", ctx.fill ? "100%" : null)("height", ctx.fill ? "100%" : null)("inset", ctx.fill ? "0" : null)("background-size", ctx.placeholder ? "cover" : null)("background-position", ctx.placeholder ? "50% 50%" : null)("background-repeat", ctx.placeholder ? "no-repeat" : null)("background-image", ctx.placeholder ? ctx.generatePlaceholder(ctx.placeholder) : null)("filter", ctx.placeholder && ctx.shouldBlurPlaceholder(ctx.placeholderConfig) ? "blur(15px)" : null);
        }
      },
      inputs: {
        ngSrc: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "ngSrc", "ngSrc", unwrapSafeUrl],
        ngSrcset: "ngSrcset",
        sizes: "sizes",
        width: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "width", "width", _angular_core__WEBPACK_IMPORTED_MODULE_0__.numberAttribute],
        height: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "height", "height", _angular_core__WEBPACK_IMPORTED_MODULE_0__.numberAttribute],
        loading: "loading",
        priority: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "priority", "priority", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute],
        loaderParams: "loaderParams",
        disableOptimizedSrcset: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "disableOptimizedSrcset", "disableOptimizedSrcset", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute],
        fill: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "fill", "fill", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute],
        placeholder: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "placeholder", "placeholder", booleanOrDataUrlAttribute],
        placeholderConfig: "placeholderConfig",
        src: "src",
        srcset: "srcset"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgOptimizedImage, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      standalone: true,
      selector: 'img[ngSrc]',
      host: {
        '[style.position]': 'fill ? "absolute" : null',
        '[style.width]': 'fill ? "100%" : null',
        '[style.height]': 'fill ? "100%" : null',
        '[style.inset]': 'fill ? "0" : null',
        '[style.background-size]': 'placeholder ? "cover" : null',
        '[style.background-position]': 'placeholder ? "50% 50%" : null',
        '[style.background-repeat]': 'placeholder ? "no-repeat" : null',
        '[style.background-image]': 'placeholder ? generatePlaceholder(placeholder) : null',
        '[style.filter]': `placeholder && shouldBlurPlaceholder(placeholderConfig) ? "blur(${PLACEHOLDER_BLUR_AMOUNT}px)" : null`
      }
    }]
  }], null, {
    ngSrc: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true,
        transform: unwrapSafeUrl
      }]
    }],
    ngSrcset: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    sizes: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    width: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.numberAttribute
      }]
    }],
    height: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.numberAttribute
      }]
    }],
    loading: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    priority: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    loaderParams: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disableOptimizedSrcset: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    fill: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    placeholder: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: booleanOrDataUrlAttribute
      }]
    }],
    placeholderConfig: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    src: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    srcset: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/***** Helpers *****/
/**
 * Sorts provided config breakpoints and uses defaults.
 */
function processConfig(config) {
  let sortedBreakpoints = {};
  if (config.breakpoints) {
    sortedBreakpoints.breakpoints = config.breakpoints.sort((a, b) => a - b);
  }
  return Object.assign({}, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵIMAGE_CONFIG_DEFAULTS"], config, sortedBreakpoints);
}
/***** Assert functions *****/
/**
 * Verifies that there is no `src` set on a host element.
 */
function assertNoConflictingSrc(dir) {
  if (dir.src) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2950 /* RuntimeErrorCode.UNEXPECTED_SRC_ATTR */, `${imgDirectiveDetails(dir.ngSrc)} both \`src\` and \`ngSrc\` have been set. ` + `Supplying both of these attributes breaks lazy loading. ` + `The NgOptimizedImage directive sets \`src\` itself based on the value of \`ngSrc\`. ` + `To fix this, please remove the \`src\` attribute.`);
  }
}
/**
 * Verifies that there is no `srcset` set on a host element.
 */
function assertNoConflictingSrcset(dir) {
  if (dir.srcset) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2951 /* RuntimeErrorCode.UNEXPECTED_SRCSET_ATTR */, `${imgDirectiveDetails(dir.ngSrc)} both \`srcset\` and \`ngSrcset\` have been set. ` + `Supplying both of these attributes breaks lazy loading. ` + `The NgOptimizedImage directive sets \`srcset\` itself based on the value of ` + `\`ngSrcset\`. To fix this, please remove the \`srcset\` attribute.`);
  }
}
/**
 * Verifies that the `ngSrc` is not a Base64-encoded image.
 */
function assertNotBase64Image(dir) {
  let ngSrc = dir.ngSrc.trim();
  if (ngSrc.startsWith('data:')) {
    if (ngSrc.length > BASE64_IMG_MAX_LENGTH_IN_ERROR) {
      ngSrc = ngSrc.substring(0, BASE64_IMG_MAX_LENGTH_IN_ERROR) + '...';
    }
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc, false)} \`ngSrc\` is a Base64-encoded string ` + `(${ngSrc}). NgOptimizedImage does not support Base64-encoded strings. ` + `To fix this, disable the NgOptimizedImage directive for this element ` + `by removing \`ngSrc\` and using a standard \`src\` attribute instead.`);
  }
}
/**
 * Verifies that the 'sizes' only includes responsive values.
 */
function assertNoComplexSizes(dir) {
  let sizes = dir.sizes;
  if (sizes?.match(/((\)|,)\s|^)\d+px/)) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc, false)} \`sizes\` was set to a string including ` + `pixel values. For automatic \`srcset\` generation, \`sizes\` must only include responsive ` + `values, such as \`sizes="50vw"\` or \`sizes="(min-width: 768px) 50vw, 100vw"\`. ` + `To fix this, modify the \`sizes\` attribute, or provide your own \`ngSrcset\` value directly.`);
  }
}
function assertValidPlaceholder(dir, imageLoader) {
  assertNoPlaceholderConfigWithoutPlaceholder(dir);
  assertNoRelativePlaceholderWithoutLoader(dir, imageLoader);
  assertNoOversizedDataUrl(dir);
}
/**
 * Verifies that placeholderConfig isn't being used without placeholder
 */
function assertNoPlaceholderConfigWithoutPlaceholder(dir) {
  if (dir.placeholderConfig && !dir.placeholder) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc, false)} \`placeholderConfig\` options were provided for an ` + `image that does not use the \`placeholder\` attribute, and will have no effect.`);
  }
}
/**
 * Warns if a relative URL placeholder is specified, but no loader is present to provide the small
 * image.
 */
function assertNoRelativePlaceholderWithoutLoader(dir, imageLoader) {
  if (dir.placeholder === true && imageLoader === noopImageLoader) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2963 /* RuntimeErrorCode.MISSING_NECESSARY_LOADER */, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to true but ` + `no image loader is configured (i.e. the default one is being used), ` + `which would result in the same image being used for the primary image and its placeholder. ` + `To fix this, provide a loader or remove the \`placeholder\` attribute from the image.`);
  }
}
/**
 * Warns or throws an error if an oversized dataURL placeholder is provided.
 */
function assertNoOversizedDataUrl(dir) {
  if (dir.placeholder && typeof dir.placeholder === 'string' && dir.placeholder.startsWith('data:')) {
    if (dir.placeholder.length > DATA_URL_ERROR_LIMIT) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2965 /* RuntimeErrorCode.OVERSIZED_PLACEHOLDER */, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to a data URL which is longer ` + `than ${DATA_URL_ERROR_LIMIT} characters. This is strongly discouraged, as large inline placeholders ` + `directly increase the bundle size of Angular and hurt page load performance. To fix this, generate ` + `a smaller data URL placeholder.`);
    }
    if (dir.placeholder.length > DATA_URL_WARN_LIMIT) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2965 /* RuntimeErrorCode.OVERSIZED_PLACEHOLDER */, `${imgDirectiveDetails(dir.ngSrc)} the \`placeholder\` attribute is set to a data URL which is longer ` + `than ${DATA_URL_WARN_LIMIT} characters. This is discouraged, as large inline placeholders ` + `directly increase the bundle size of Angular and hurt page load performance. For better loading performance, ` + `generate a smaller data URL placeholder.`));
    }
  }
}
/**
 * Verifies that the `ngSrc` is not a Blob URL.
 */
function assertNotBlobUrl(dir) {
  const ngSrc = dir.ngSrc.trim();
  if (ngSrc.startsWith('blob:')) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} \`ngSrc\` was set to a blob URL (${ngSrc}). ` + `Blob URLs are not supported by the NgOptimizedImage directive. ` + `To fix this, disable the NgOptimizedImage directive for this element ` + `by removing \`ngSrc\` and using a regular \`src\` attribute instead.`);
  }
}
/**
 * Verifies that the input is set to a non-empty string.
 */
function assertNonEmptyInput(dir, name, value) {
  const isString = typeof value === 'string';
  const isEmptyString = isString && value.trim() === '';
  if (!isString || isEmptyString) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} \`${name}\` has an invalid value ` + `(\`${value}\`). To fix this, change the value to a non-empty string.`);
  }
}
/**
 * Verifies that the `ngSrcset` is in a valid format, e.g. "100w, 200w" or "1x, 2x".
 */
function assertValidNgSrcset(dir, value) {
  if (value == null) return;
  assertNonEmptyInput(dir, 'ngSrcset', value);
  const stringVal = value;
  const isValidWidthDescriptor = VALID_WIDTH_DESCRIPTOR_SRCSET.test(stringVal);
  const isValidDensityDescriptor = VALID_DENSITY_DESCRIPTOR_SRCSET.test(stringVal);
  if (isValidDensityDescriptor) {
    assertUnderDensityCap(dir, stringVal);
  }
  const isValidSrcset = isValidWidthDescriptor || isValidDensityDescriptor;
  if (!isValidSrcset) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} \`ngSrcset\` has an invalid value (\`${value}\`). ` + `To fix this, supply \`ngSrcset\` using a comma-separated list of one or more width ` + `descriptors (e.g. "100w, 200w") or density descriptors (e.g. "1x, 2x").`);
  }
}
function assertUnderDensityCap(dir, value) {
  const underDensityCap = value.split(',').every(num => num === '' || parseFloat(num) <= ABSOLUTE_SRCSET_DENSITY_CAP);
  if (!underDensityCap) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` contains an unsupported image density:` + `\`${value}\`. NgOptimizedImage generally recommends a max image density of ` + `${RECOMMENDED_SRCSET_DENSITY_CAP}x but supports image densities up to ` + `${ABSOLUTE_SRCSET_DENSITY_CAP}x. The human eye cannot distinguish between image densities ` + `greater than ${RECOMMENDED_SRCSET_DENSITY_CAP}x - which makes them unnecessary for ` + `most use cases. Images that will be pinch-zoomed are typically the primary use case for ` + `${ABSOLUTE_SRCSET_DENSITY_CAP}x images. Please remove the high density descriptor and try again.`);
  }
}
/**
 * Creates a `RuntimeError` instance to represent a situation when an input is set after
 * the directive has initialized.
 */
function postInitInputChangeError(dir, inputName) {
  let reason;
  if (inputName === 'width' || inputName === 'height') {
    reason = `Changing \`${inputName}\` may result in different attribute value ` + `applied to the underlying image element and cause layout shifts on a page.`;
  } else {
    reason = `Changing the \`${inputName}\` would have no effect on the underlying ` + `image element, because the resource loading has already occurred.`;
  }
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2953 /* RuntimeErrorCode.UNEXPECTED_INPUT_CHANGE */, `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` was updated after initialization. ` + `The NgOptimizedImage directive will not react to this input change. ${reason} ` + `To fix this, either switch \`${inputName}\` to a static value ` + `or wrap the image element in an *ngIf that is gated on the necessary value.`);
}
/**
 * Verify that none of the listed inputs has changed.
 */
function assertNoPostInitInputChange(dir, changes, inputs) {
  inputs.forEach(input => {
    const isUpdated = changes.hasOwnProperty(input);
    if (isUpdated && !changes[input].isFirstChange()) {
      if (input === 'ngSrc') {
        // When the `ngSrc` input changes, we detect that only in the
        // `ngOnChanges` hook, thus the `ngSrc` is already set. We use
        // `ngSrc` in the error message, so we use a previous value, but
        // not the updated one in it.
        dir = {
          ngSrc: changes[input].previousValue
        };
      }
      throw postInitInputChangeError(dir, input);
    }
  });
}
/**
 * Verifies that a specified input is a number greater than 0.
 */
function assertGreaterThanZero(dir, inputValue, inputName) {
  const validNumber = typeof inputValue === 'number' && inputValue > 0;
  const validString = typeof inputValue === 'string' && /^\d+$/.test(inputValue.trim()) && parseInt(inputValue) > 0;
  if (!validNumber && !validString) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} \`${inputName}\` has an invalid value. ` + `To fix this, provide \`${inputName}\` as a number greater than 0.`);
  }
}
/**
 * Verifies that the rendered image is not visually distorted. Effectively this is checking:
 * - Whether the "width" and "height" attributes reflect the actual dimensions of the image.
 * - Whether image styling is "correct" (see below for a longer explanation).
 */
function assertNoImageDistortion(dir, img, renderer) {
  const removeLoadListenerFn = renderer.listen(img, 'load', () => {
    removeLoadListenerFn();
    removeErrorListenerFn();
    const computedStyle = window.getComputedStyle(img);
    let renderedWidth = parseFloat(computedStyle.getPropertyValue('width'));
    let renderedHeight = parseFloat(computedStyle.getPropertyValue('height'));
    const boxSizing = computedStyle.getPropertyValue('box-sizing');
    if (boxSizing === 'border-box') {
      const paddingTop = computedStyle.getPropertyValue('padding-top');
      const paddingRight = computedStyle.getPropertyValue('padding-right');
      const paddingBottom = computedStyle.getPropertyValue('padding-bottom');
      const paddingLeft = computedStyle.getPropertyValue('padding-left');
      renderedWidth -= parseFloat(paddingRight) + parseFloat(paddingLeft);
      renderedHeight -= parseFloat(paddingTop) + parseFloat(paddingBottom);
    }
    const renderedAspectRatio = renderedWidth / renderedHeight;
    const nonZeroRenderedDimensions = renderedWidth !== 0 && renderedHeight !== 0;
    const intrinsicWidth = img.naturalWidth;
    const intrinsicHeight = img.naturalHeight;
    const intrinsicAspectRatio = intrinsicWidth / intrinsicHeight;
    const suppliedWidth = dir.width;
    const suppliedHeight = dir.height;
    const suppliedAspectRatio = suppliedWidth / suppliedHeight;
    // Tolerance is used to account for the impact of subpixel rendering.
    // Due to subpixel rendering, the rendered, intrinsic, and supplied
    // aspect ratios of a correctly configured image may not exactly match.
    // For example, a `width=4030 height=3020` image might have a rendered
    // size of "1062w, 796.48h". (An aspect ratio of 1.334... vs. 1.333...)
    const inaccurateDimensions = Math.abs(suppliedAspectRatio - intrinsicAspectRatio) > ASPECT_RATIO_TOLERANCE;
    const stylingDistortion = nonZeroRenderedDimensions && Math.abs(intrinsicAspectRatio - renderedAspectRatio) > ASPECT_RATIO_TOLERANCE;
    if (inaccurateDimensions) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the image does not match ` + `the aspect ratio indicated by the width and height attributes. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` + `(aspect-ratio: ${round(intrinsicAspectRatio)}). \nSupplied width and height attributes: ` + `${suppliedWidth}w x ${suppliedHeight}h (aspect-ratio: ${round(suppliedAspectRatio)}). ` + `\nTo fix this, update the width and height attributes.`));
    } else if (stylingDistortion) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the aspect ratio of the rendered image ` + `does not match the image's intrinsic aspect ratio. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h ` + `(aspect-ratio: ${round(intrinsicAspectRatio)}). \nRendered image size: ` + `${renderedWidth}w x ${renderedHeight}h (aspect-ratio: ` + `${round(renderedAspectRatio)}). \nThis issue can occur if "width" and "height" ` + `attributes are added to an image without updating the corresponding ` + `image styling. To fix this, adjust image styling. In most cases, ` + `adding "height: auto" or "width: auto" to the image styling will fix ` + `this issue.`));
    } else if (!dir.ngSrcset && nonZeroRenderedDimensions) {
      // If `ngSrcset` hasn't been set, sanity check the intrinsic size.
      const recommendedWidth = RECOMMENDED_SRCSET_DENSITY_CAP * renderedWidth;
      const recommendedHeight = RECOMMENDED_SRCSET_DENSITY_CAP * renderedHeight;
      const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;
      const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;
      if (oversizedWidth || oversizedHeight) {
        console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2960 /* RuntimeErrorCode.OVERSIZED_IMAGE */, `${imgDirectiveDetails(dir.ngSrc)} the intrinsic image is significantly ` + `larger than necessary. ` + `\nRendered image size: ${renderedWidth}w x ${renderedHeight}h. ` + `\nIntrinsic image size: ${intrinsicWidth}w x ${intrinsicHeight}h. ` + `\nRecommended intrinsic image size: ${recommendedWidth}w x ${recommendedHeight}h. ` + `\nNote: Recommended intrinsic image size is calculated assuming a maximum DPR of ` + `${RECOMMENDED_SRCSET_DENSITY_CAP}. To improve loading time, resize the image ` + `or consider using the "ngSrcset" and "sizes" attributes.`));
      }
    }
  });
  // We only listen to the `error` event to remove the `load` event listener because it will not be
  // fired if the image fails to load. This is done to prevent memory leaks in development mode
  // because image elements aren't garbage-collected properly. It happens because zone.js stores the
  // event listener directly on the element and closures capture `dir`.
  const removeErrorListenerFn = renderer.listen(img, 'error', () => {
    removeLoadListenerFn();
    removeErrorListenerFn();
  });
}
/**
 * Verifies that a specified input is set.
 */
function assertNonEmptyWidthAndHeight(dir) {
  let missingAttributes = [];
  if (dir.width === undefined) missingAttributes.push('width');
  if (dir.height === undefined) missingAttributes.push('height');
  if (missingAttributes.length > 0) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2954 /* RuntimeErrorCode.REQUIRED_INPUT_MISSING */, `${imgDirectiveDetails(dir.ngSrc)} these required attributes ` + `are missing: ${missingAttributes.map(attr => `"${attr}"`).join(', ')}. ` + `Including "width" and "height" attributes will prevent image-related layout shifts. ` + `To fix this, include "width" and "height" attributes on the image tag or turn on ` + `"fill" mode with the \`fill\` attribute.`);
  }
}
/**
 * Verifies that width and height are not set. Used in fill mode, where those attributes don't make
 * sense.
 */
function assertEmptyWidthAndHeight(dir) {
  if (dir.width || dir.height) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the attributes \`height\` and/or \`width\` are present ` + `along with the \`fill\` attribute. Because \`fill\` mode causes an image to fill its containing ` + `element, the size attributes have no effect and should be removed.`);
  }
}
/**
 * Verifies that the rendered image has a nonzero height. If the image is in fill mode, provides
 * guidance that this can be caused by the containing element's CSS position property.
 */
function assertNonZeroRenderedHeight(dir, img, renderer) {
  const removeLoadListenerFn = renderer.listen(img, 'load', () => {
    removeLoadListenerFn();
    removeErrorListenerFn();
    const renderedHeight = img.clientHeight;
    if (dir.fill && renderedHeight === 0) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the height of the fill-mode image is zero. ` + `This is likely because the containing element does not have the CSS 'position' ` + `property set to one of the following: "relative", "fixed", or "absolute". ` + `To fix this problem, make sure the container element has the CSS 'position' ` + `property defined and the height of the element is not zero.`));
    }
  });
  // See comments in the `assertNoImageDistortion`.
  const removeErrorListenerFn = renderer.listen(img, 'error', () => {
    removeLoadListenerFn();
    removeErrorListenerFn();
  });
}
/**
 * Verifies that the `loading` attribute is set to a valid input &
 * is not used on priority images.
 */
function assertValidLoadingInput(dir) {
  if (dir.loading && dir.priority) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute ` + `was used on an image that was marked "priority". ` + `Setting \`loading\` on priority images is not allowed ` + `because these images will always be eagerly loaded. ` + `To fix this, remove the “loading” attribute from the priority image.`);
  }
  const validInputs = ['auto', 'eager', 'lazy'];
  if (typeof dir.loading === 'string' && !validInputs.includes(dir.loading)) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](2952 /* RuntimeErrorCode.INVALID_INPUT */, `${imgDirectiveDetails(dir.ngSrc)} the \`loading\` attribute ` + `has an invalid value (\`${dir.loading}\`). ` + `To fix this, provide a valid value ("lazy", "eager", or "auto").`);
  }
}
/**
 * Warns if NOT using a loader (falling back to the generic loader) and
 * the image appears to be hosted on one of the image CDNs for which
 * we do have a built-in image loader. Suggests switching to the
 * built-in loader.
 *
 * @param ngSrc Value of the ngSrc attribute
 * @param imageLoader ImageLoader provided
 */
function assertNotMissingBuiltInLoader(ngSrc, imageLoader) {
  if (imageLoader === noopImageLoader) {
    let builtInLoaderName = '';
    for (const loader of BUILT_IN_LOADERS) {
      if (loader.testUrl(ngSrc)) {
        builtInLoaderName = loader.name;
        break;
      }
    }
    if (builtInLoaderName) {
      console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2962 /* RuntimeErrorCode.MISSING_BUILTIN_LOADER */, `NgOptimizedImage: It looks like your images may be hosted on the ` + `${builtInLoaderName} CDN, but your app is not using Angular's ` + `built-in loader for that CDN. We recommend switching to use ` + `the built-in by calling \`provide${builtInLoaderName}Loader()\` ` + `in your \`providers\` and passing it your instance's base URL. ` + `If you don't want to use the built-in loader, define a custom ` + `loader function using IMAGE_LOADER to silence this warning.`));
    }
  }
}
/**
 * Warns if ngSrcset is present and no loader is configured (i.e. the default one is being used).
 */
function assertNoNgSrcsetWithoutLoader(dir, imageLoader) {
  if (dir.ngSrcset && imageLoader === noopImageLoader) {
    console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2963 /* RuntimeErrorCode.MISSING_NECESSARY_LOADER */, `${imgDirectiveDetails(dir.ngSrc)} the \`ngSrcset\` attribute is present but ` + `no image loader is configured (i.e. the default one is being used), ` + `which would result in the same image being used for all configured sizes. ` + `To fix this, provide a loader or remove the \`ngSrcset\` attribute from the image.`));
  }
}
/**
 * Warns if loaderParams is present and no loader is configured (i.e. the default one is being
 * used).
 */
function assertNoLoaderParamsWithoutLoader(dir, imageLoader) {
  if (dir.loaderParams && imageLoader === noopImageLoader) {
    console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵformatRuntimeError"])(2963 /* RuntimeErrorCode.MISSING_NECESSARY_LOADER */, `${imgDirectiveDetails(dir.ngSrc)} the \`loaderParams\` attribute is present but ` + `no image loader is configured (i.e. the default one is being used), ` + `which means that the loaderParams data will not be consumed and will not affect the URL. ` + `To fix this, provide a custom loader or remove the \`loaderParams\` attribute from the image.`));
  }
}
function round(input) {
  return Number.isInteger(input) ? input : input.toFixed(2);
}
// Transform function to handle SafeValue input for ngSrc. This doesn't do any sanitization,
// as that is not needed for img.src and img.srcset. This transform is purely for compatibility.
function unwrapSafeUrl(value) {
  if (typeof value === 'string') {
    return value;
  }
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵunwrapSafeValue"])(value);
}
// Transform function to handle inputs which may be booleans, strings, or string representations
// of boolean values. Used for the placeholder attribute.
function booleanOrDataUrlAttribute(value) {
  if (typeof value === 'string' && value.startsWith(`data:`)) {
    return value;
  }
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute)(value);
}

/**
 * @module
 * @description
 * Entry point for all public APIs of the common package.
 */

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */
// This file only reexports content of the `src` folder. Keep it that way.

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 46443:
/*!********************************************************!*\
  !*** ./node_modules/@angular/common/fesm2022/http.mjs ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   FetchBackend: () => (/* binding */ FetchBackend),
/* harmony export */   HTTP_INTERCEPTORS: () => (/* binding */ HTTP_INTERCEPTORS),
/* harmony export */   HttpBackend: () => (/* binding */ HttpBackend),
/* harmony export */   HttpClient: () => (/* binding */ HttpClient),
/* harmony export */   HttpClientJsonpModule: () => (/* binding */ HttpClientJsonpModule),
/* harmony export */   HttpClientModule: () => (/* binding */ HttpClientModule),
/* harmony export */   HttpClientXsrfModule: () => (/* binding */ HttpClientXsrfModule),
/* harmony export */   HttpContext: () => (/* binding */ HttpContext),
/* harmony export */   HttpContextToken: () => (/* binding */ HttpContextToken),
/* harmony export */   HttpErrorResponse: () => (/* binding */ HttpErrorResponse),
/* harmony export */   HttpEventType: () => (/* binding */ HttpEventType),
/* harmony export */   HttpFeatureKind: () => (/* binding */ HttpFeatureKind),
/* harmony export */   HttpHandler: () => (/* binding */ HttpHandler),
/* harmony export */   HttpHeaderResponse: () => (/* binding */ HttpHeaderResponse),
/* harmony export */   HttpHeaders: () => (/* binding */ HttpHeaders),
/* harmony export */   HttpParams: () => (/* binding */ HttpParams),
/* harmony export */   HttpRequest: () => (/* binding */ HttpRequest),
/* harmony export */   HttpResponse: () => (/* binding */ HttpResponse),
/* harmony export */   HttpResponseBase: () => (/* binding */ HttpResponseBase),
/* harmony export */   HttpStatusCode: () => (/* binding */ HttpStatusCode),
/* harmony export */   HttpUrlEncodingCodec: () => (/* binding */ HttpUrlEncodingCodec),
/* harmony export */   HttpXhrBackend: () => (/* binding */ HttpXhrBackend),
/* harmony export */   HttpXsrfTokenExtractor: () => (/* binding */ HttpXsrfTokenExtractor),
/* harmony export */   JsonpClientBackend: () => (/* binding */ JsonpClientBackend),
/* harmony export */   JsonpInterceptor: () => (/* binding */ JsonpInterceptor),
/* harmony export */   provideHttpClient: () => (/* binding */ provideHttpClient),
/* harmony export */   withFetch: () => (/* binding */ withFetch),
/* harmony export */   withInterceptors: () => (/* binding */ withInterceptors),
/* harmony export */   withInterceptorsFromDi: () => (/* binding */ withInterceptorsFromDi),
/* harmony export */   withJsonpSupport: () => (/* binding */ withJsonpSupport),
/* harmony export */   withNoXsrfProtection: () => (/* binding */ withNoXsrfProtection),
/* harmony export */   withRequestsMadeViaParent: () => (/* binding */ withRequestsMadeViaParent),
/* harmony export */   withXsrfConfiguration: () => (/* binding */ withXsrfConfiguration),
/* harmony export */   "ɵHTTP_ROOT_INTERCEPTOR_FNS": () => (/* binding */ HTTP_ROOT_INTERCEPTOR_FNS),
/* harmony export */   "ɵHttpInterceptingHandler": () => (/* binding */ HttpInterceptorHandler),
/* harmony export */   "ɵHttpInterceptorHandler": () => (/* binding */ HttpInterceptorHandler),
/* harmony export */   "ɵPRIMARY_HTTP_BACKEND": () => (/* binding */ PRIMARY_HTTP_BACKEND),
/* harmony export */   "ɵwithHttpTransferCache": () => (/* binding */ withHttpTransferCache)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 95429);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 89475);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @angular/common */ 60316);

/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */








/**
 * Transforms an `HttpRequest` into a stream of `HttpEvent`s, one of which will likely be a
 * `HttpResponse`.
 *
 * `HttpHandler` is injectable. When injected, the handler instance dispatches requests to the
 * first interceptor in the chain, which dispatches to the second, etc, eventually reaching the
 * `HttpBackend`.
 *
 * In an `HttpInterceptor`, the `HttpHandler` parameter is the next interceptor in the chain.
 *
 * @publicApi
 */
class HttpHandler {}
/**
 * A final `HttpHandler` which will dispatch the request via browser HTTP APIs to a backend.
 *
 * Interceptors sit between the `HttpClient` interface and the `HttpBackend`.
 *
 * When injected, `HttpBackend` dispatches requests directly to the backend, without going
 * through the interceptor chain.
 *
 * @publicApi
 */
class HttpBackend {}

/**
 * Represents the header configuration options for an HTTP request.
 * Instances are immutable. Modifying methods return a cloned
 * instance with the change. The original object is never changed.
 *
 * @publicApi
 */
class HttpHeaders {
  /**  Constructs a new HTTP header object with the given values.*/
  constructor(headers) {
    /**
     * Internal map of lowercased header names to the normalized
     * form of the name (the form seen first).
     */
    this.normalizedNames = new Map();
    /**
     * Queued updates to be materialized the next initialization.
     */
    this.lazyUpdate = null;
    if (!headers) {
      this.headers = new Map();
    } else if (typeof headers === 'string') {
      this.lazyInit = () => {
        this.headers = new Map();
        headers.split('\n').forEach(line => {
          const index = line.indexOf(':');
          if (index > 0) {
            const name = line.slice(0, index);
            const key = name.toLowerCase();
            const value = line.slice(index + 1).trim();
            this.maybeSetNormalizedName(name, key);
            if (this.headers.has(key)) {
              this.headers.get(key).push(value);
            } else {
              this.headers.set(key, [value]);
            }
          }
        });
      };
    } else if (typeof Headers !== 'undefined' && headers instanceof Headers) {
      this.headers = new Map();
      headers.forEach((values, name) => {
        this.setHeaderEntries(name, values);
      });
    } else {
      this.lazyInit = () => {
        if (typeof ngDevMode === 'undefined' || ngDevMode) {
          assertValidHeaders(headers);
        }
        this.headers = new Map();
        Object.entries(headers).forEach(([name, values]) => {
          this.setHeaderEntries(name, values);
        });
      };
    }
  }
  /**
   * Checks for existence of a given header.
   *
   * @param name The header name to check for existence.
   *
   * @returns True if the header exists, false otherwise.
   */
  has(name) {
    this.init();
    return this.headers.has(name.toLowerCase());
  }
  /**
   * Retrieves the first value of a given header.
   *
   * @param name The header name.
   *
   * @returns The value string if the header exists, null otherwise
   */
  get(name) {
    this.init();
    const values = this.headers.get(name.toLowerCase());
    return values && values.length > 0 ? values[0] : null;
  }
  /**
   * Retrieves the names of the headers.
   *
   * @returns A list of header names.
   */
  keys() {
    this.init();
    return Array.from(this.normalizedNames.values());
  }
  /**
   * Retrieves a list of values for a given header.
   *
   * @param name The header name from which to retrieve values.
   *
   * @returns A string of values if the header exists, null otherwise.
   */
  getAll(name) {
    this.init();
    return this.headers.get(name.toLowerCase()) || null;
  }
  /**
   * Appends a new value to the existing set of values for a header
   * and returns them in a clone of the original instance.
   *
   * @param name The header name for which to append the values.
   * @param value The value to append.
   *
   * @returns A clone of the HTTP headers object with the value appended to the given header.
   */
  append(name, value) {
    return this.clone({
      name,
      value,
      op: 'a'
    });
  }
  /**
   * Sets or modifies a value for a given header in a clone of the original instance.
   * If the header already exists, its value is replaced with the given value
   * in the returned object.
   *
   * @param name The header name.
   * @param value The value or values to set or override for the given header.
   *
   * @returns A clone of the HTTP headers object with the newly set header value.
   */
  set(name, value) {
    return this.clone({
      name,
      value,
      op: 's'
    });
  }
  /**
   * Deletes values for a given header in a clone of the original instance.
   *
   * @param name The header name.
   * @param value The value or values to delete for the given header.
   *
   * @returns A clone of the HTTP headers object with the given value deleted.
   */
  delete(name, value) {
    return this.clone({
      name,
      value,
      op: 'd'
    });
  }
  maybeSetNormalizedName(name, lcName) {
    if (!this.normalizedNames.has(lcName)) {
      this.normalizedNames.set(lcName, name);
    }
  }
  init() {
    if (!!this.lazyInit) {
      if (this.lazyInit instanceof HttpHeaders) {
        this.copyFrom(this.lazyInit);
      } else {
        this.lazyInit();
      }
      this.lazyInit = null;
      if (!!this.lazyUpdate) {
        this.lazyUpdate.forEach(update => this.applyUpdate(update));
        this.lazyUpdate = null;
      }
    }
  }
  copyFrom(other) {
    other.init();
    Array.from(other.headers.keys()).forEach(key => {
      this.headers.set(key, other.headers.get(key));
      this.normalizedNames.set(key, other.normalizedNames.get(key));
    });
  }
  clone(update) {
    const clone = new HttpHeaders();
    clone.lazyInit = !!this.lazyInit && this.lazyInit instanceof HttpHeaders ? this.lazyInit : this;
    clone.lazyUpdate = (this.lazyUpdate || []).concat([update]);
    return clone;
  }
  applyUpdate(update) {
    const key = update.name.toLowerCase();
    switch (update.op) {
      case 'a':
      case 's':
        let value = update.value;
        if (typeof value === 'string') {
          value = [value];
        }
        if (value.length === 0) {
          return;
        }
        this.maybeSetNormalizedName(update.name, key);
        const base = (update.op === 'a' ? this.headers.get(key) : undefined) || [];
        base.push(...value);
        this.headers.set(key, base);
        break;
      case 'd':
        const toDelete = update.value;
        if (!toDelete) {
          this.headers.delete(key);
          this.normalizedNames.delete(key);
        } else {
          let existing = this.headers.get(key);
          if (!existing) {
            return;
          }
          existing = existing.filter(value => toDelete.indexOf(value) === -1);
          if (existing.length === 0) {
            this.headers.delete(key);
            this.normalizedNames.delete(key);
          } else {
            this.headers.set(key, existing);
          }
        }
        break;
    }
  }
  setHeaderEntries(name, values) {
    const headerValues = (Array.isArray(values) ? values : [values]).map(value => value.toString());
    const key = name.toLowerCase();
    this.headers.set(key, headerValues);
    this.maybeSetNormalizedName(name, key);
  }
  /**
   * @internal
   */
  forEach(fn) {
    this.init();
    Array.from(this.normalizedNames.keys()).forEach(key => fn(this.normalizedNames.get(key), this.headers.get(key)));
  }
}
/**
 * Verifies that the headers object has the right shape: the values
 * must be either strings, numbers or arrays. Throws an error if an invalid
 * header value is present.
 */
function assertValidHeaders(headers) {
  for (const [key, value] of Object.entries(headers)) {
    if (!(typeof value === 'string' || typeof value === 'number') && !Array.isArray(value)) {
      throw new Error(`Unexpected value of the \`${key}\` header provided. ` + `Expecting either a string, a number or an array, but got: \`${value}\`.`);
    }
  }
}

/**
 * Provides encoding and decoding of URL parameter and query-string values.
 *
 * Serializes and parses URL parameter keys and values to encode and decode them.
 * If you pass URL query parameters without encoding,
 * the query parameters can be misinterpreted at the receiving end.
 *
 *
 * @publicApi
 */
class HttpUrlEncodingCodec {
  /**
   * Encodes a key name for a URL parameter or query-string.
   * @param key The key name.
   * @returns The encoded key name.
   */
  encodeKey(key) {
    return standardEncoding(key);
  }
  /**
   * Encodes the value of a URL parameter or query-string.
   * @param value The value.
   * @returns The encoded value.
   */
  encodeValue(value) {
    return standardEncoding(value);
  }
  /**
   * Decodes an encoded URL parameter or query-string key.
   * @param key The encoded key name.
   * @returns The decoded key name.
   */
  decodeKey(key) {
    return decodeURIComponent(key);
  }
  /**
   * Decodes an encoded URL parameter or query-string value.
   * @param value The encoded value.
   * @returns The decoded value.
   */
  decodeValue(value) {
    return decodeURIComponent(value);
  }
}
function paramParser(rawParams, codec) {
  const map = new Map();
  if (rawParams.length > 0) {
    // The `window.location.search` can be used while creating an instance of the `HttpParams` class
    // (e.g. `new HttpParams({ fromString: window.location.search })`). The `window.location.search`
    // may start with the `?` char, so we strip it if it's present.
    const params = rawParams.replace(/^\?/, '').split('&');
    params.forEach(param => {
      const eqIdx = param.indexOf('=');
      const [key, val] = eqIdx == -1 ? [codec.decodeKey(param), ''] : [codec.decodeKey(param.slice(0, eqIdx)), codec.decodeValue(param.slice(eqIdx + 1))];
      const list = map.get(key) || [];
      list.push(val);
      map.set(key, list);
    });
  }
  return map;
}
/**
 * Encode input string with standard encodeURIComponent and then un-encode specific characters.
 */
const STANDARD_ENCODING_REGEX = /%(\d[a-f0-9])/gi;
const STANDARD_ENCODING_REPLACEMENTS = {
  '40': '@',
  '3A': ':',
  '24': '$',
  '2C': ',',
  '3B': ';',
  '3D': '=',
  '3F': '?',
  '2F': '/'
};
function standardEncoding(v) {
  return encodeURIComponent(v).replace(STANDARD_ENCODING_REGEX, (s, t) => STANDARD_ENCODING_REPLACEMENTS[t] ?? s);
}
function valueToString(value) {
  return `${value}`;
}
/**
 * An HTTP request/response body that represents serialized parameters,
 * per the MIME type `application/x-www-form-urlencoded`.
 *
 * This class is immutable; all mutation operations return a new instance.
 *
 * @publicApi
 */
class HttpParams {
  constructor(options = {}) {
    this.updates = null;
    this.cloneFrom = null;
    this.encoder = options.encoder || new HttpUrlEncodingCodec();
    if (!!options.fromString) {
      if (!!options.fromObject) {
        throw new Error(`Cannot specify both fromString and fromObject.`);
      }
      this.map = paramParser(options.fromString, this.encoder);
    } else if (!!options.fromObject) {
      this.map = new Map();
      Object.keys(options.fromObject).forEach(key => {
        const value = options.fromObject[key];
        // convert the values to strings
        const values = Array.isArray(value) ? value.map(valueToString) : [valueToString(value)];
        this.map.set(key, values);
      });
    } else {
      this.map = null;
    }
  }
  /**
   * Reports whether the body includes one or more values for a given parameter.
   * @param param The parameter name.
   * @returns True if the parameter has one or more values,
   * false if it has no value or is not present.
   */
  has(param) {
    this.init();
    return this.map.has(param);
  }
  /**
   * Retrieves the first value for a parameter.
   * @param param The parameter name.
   * @returns The first value of the given parameter,
   * or `null` if the parameter is not present.
   */
  get(param) {
    this.init();
    const res = this.map.get(param);
    return !!res ? res[0] : null;
  }
  /**
   * Retrieves all values for a  parameter.
   * @param param The parameter name.
   * @returns All values in a string array,
   * or `null` if the parameter not present.
   */
  getAll(param) {
    this.init();
    return this.map.get(param) || null;
  }
  /**
   * Retrieves all the parameters for this body.
   * @returns The parameter names in a string array.
   */
  keys() {
    this.init();
    return Array.from(this.map.keys());
  }
  /**
   * Appends a new value to existing values for a parameter.
   * @param param The parameter name.
   * @param value The new value to add.
   * @return A new body with the appended value.
   */
  append(param, value) {
    return this.clone({
      param,
      value,
      op: 'a'
    });
  }
  /**
   * Constructs a new body with appended values for the given parameter name.
   * @param params parameters and values
   * @return A new body with the new value.
   */
  appendAll(params) {
    const updates = [];
    Object.keys(params).forEach(param => {
      const value = params[param];
      if (Array.isArray(value)) {
        value.forEach(_value => {
          updates.push({
            param,
            value: _value,
            op: 'a'
          });
        });
      } else {
        updates.push({
          param,
          value: value,
          op: 'a'
        });
      }
    });
    return this.clone(updates);
  }
  /**
   * Replaces the value for a parameter.
   * @param param The parameter name.
   * @param value The new value.
   * @return A new body with the new value.
   */
  set(param, value) {
    return this.clone({
      param,
      value,
      op: 's'
    });
  }
  /**
   * Removes a given value or all values from a parameter.
   * @param param The parameter name.
   * @param value The value to remove, if provided.
   * @return A new body with the given value removed, or with all values
   * removed if no value is specified.
   */
  delete(param, value) {
    return this.clone({
      param,
      value,
      op: 'd'
    });
  }
  /**
   * Serializes the body to an encoded string, where key-value pairs (separated by `=`) are
   * separated by `&`s.
   */
  toString() {
    this.init();
    return this.keys().map(key => {
      const eKey = this.encoder.encodeKey(key);
      // `a: ['1']` produces `'a=1'`
      // `b: []` produces `''`
      // `c: ['1', '2']` produces `'c=1&c=2'`
      return this.map.get(key).map(value => eKey + '=' + this.encoder.encodeValue(value)).join('&');
    })
    // filter out empty values because `b: []` produces `''`
    // which results in `a=1&&c=1&c=2` instead of `a=1&c=1&c=2` if we don't
    .filter(param => param !== '').join('&');
  }
  clone(update) {
    const clone = new HttpParams({
      encoder: this.encoder
    });
    clone.cloneFrom = this.cloneFrom || this;
    clone.updates = (this.updates || []).concat(update);
    return clone;
  }
  init() {
    if (this.map === null) {
      this.map = new Map();
    }
    if (this.cloneFrom !== null) {
      this.cloneFrom.init();
      this.cloneFrom.keys().forEach(key => this.map.set(key, this.cloneFrom.map.get(key)));
      this.updates.forEach(update => {
        switch (update.op) {
          case 'a':
          case 's':
            const base = (update.op === 'a' ? this.map.get(update.param) : undefined) || [];
            base.push(valueToString(update.value));
            this.map.set(update.param, base);
            break;
          case 'd':
            if (update.value !== undefined) {
              let base = this.map.get(update.param) || [];
              const idx = base.indexOf(valueToString(update.value));
              if (idx !== -1) {
                base.splice(idx, 1);
              }
              if (base.length > 0) {
                this.map.set(update.param, base);
              } else {
                this.map.delete(update.param);
              }
            } else {
              this.map.delete(update.param);
              break;
            }
        }
      });
      this.cloneFrom = this.updates = null;
    }
  }
}

/**
 * A token used to manipulate and access values stored in `HttpContext`.
 *
 * @publicApi
 */
class HttpContextToken {
  constructor(defaultValue) {
    this.defaultValue = defaultValue;
  }
}
/**
 * Http context stores arbitrary user defined values and ensures type safety without
 * actually knowing the types. It is backed by a `Map` and guarantees that keys do not clash.
 *
 * This context is mutable and is shared between cloned requests unless explicitly specified.
 *
 * @usageNotes
 *
 * ### Usage Example
 *
 * ```typescript
 * // inside cache.interceptors.ts
 * export const IS_CACHE_ENABLED = new HttpContextToken<boolean>(() => false);
 *
 * export class CacheInterceptor implements HttpInterceptor {
 *
 *   intercept(req: HttpRequest<any>, delegate: HttpHandler): Observable<HttpEvent<any>> {
 *     if (req.context.get(IS_CACHE_ENABLED) === true) {
 *       return ...;
 *     }
 *     return delegate.handle(req);
 *   }
 * }
 *
 * // inside a service
 *
 * this.httpClient.get('/api/weather', {
 *   context: new HttpContext().set(IS_CACHE_ENABLED, true)
 * }).subscribe(...);
 * ```
 *
 * @publicApi
 */
class HttpContext {
  constructor() {
    this.map = new Map();
  }
  /**
   * Store a value in the context. If a value is already present it will be overwritten.
   *
   * @param token The reference to an instance of `HttpContextToken`.
   * @param value The value to store.
   *
   * @returns A reference to itself for easy chaining.
   */
  set(token, value) {
    this.map.set(token, value);
    return this;
  }
  /**
   * Retrieve the value associated with the given token.
   *
   * @param token The reference to an instance of `HttpContextToken`.
   *
   * @returns The stored value or default if one is defined.
   */
  get(token) {
    if (!this.map.has(token)) {
      this.map.set(token, token.defaultValue());
    }
    return this.map.get(token);
  }
  /**
   * Delete the value associated with the given token.
   *
   * @param token The reference to an instance of `HttpContextToken`.
   *
   * @returns A reference to itself for easy chaining.
   */
  delete(token) {
    this.map.delete(token);
    return this;
  }
  /**
   * Checks for existence of a given token.
   *
   * @param token The reference to an instance of `HttpContextToken`.
   *
   * @returns True if the token exists, false otherwise.
   */
  has(token) {
    return this.map.has(token);
  }
  /**
   * @returns a list of tokens currently stored in the context.
   */
  keys() {
    return this.map.keys();
  }
}

/**
 * Determine whether the given HTTP method may include a body.
 */
function mightHaveBody(method) {
  switch (method) {
    case 'DELETE':
    case 'GET':
    case 'HEAD':
    case 'OPTIONS':
    case 'JSONP':
      return false;
    default:
      return true;
  }
}
/**
 * Safely assert whether the given value is an ArrayBuffer.
 *
 * In some execution environments ArrayBuffer is not defined.
 */
function isArrayBuffer(value) {
  return typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer;
}
/**
 * Safely assert whether the given value is a Blob.
 *
 * In some execution environments Blob is not defined.
 */
function isBlob(value) {
  return typeof Blob !== 'undefined' && value instanceof Blob;
}
/**
 * Safely assert whether the given value is a FormData instance.
 *
 * In some execution environments FormData is not defined.
 */
function isFormData(value) {
  return typeof FormData !== 'undefined' && value instanceof FormData;
}
/**
 * Safely assert whether the given value is a URLSearchParams instance.
 *
 * In some execution environments URLSearchParams is not defined.
 */
function isUrlSearchParams(value) {
  return typeof URLSearchParams !== 'undefined' && value instanceof URLSearchParams;
}
/**
 * An outgoing HTTP request with an optional typed body.
 *
 * `HttpRequest` represents an outgoing request, including URL, method,
 * headers, body, and other request configuration options. Instances should be
 * assumed to be immutable. To modify a `HttpRequest`, the `clone`
 * method should be used.
 *
 * @publicApi
 */
class HttpRequest {
  constructor(method, url, third, fourth) {
    this.url = url;
    /**
     * The request body, or `null` if one isn't set.
     *
     * Bodies are not enforced to be immutable, as they can include a reference to any
     * user-defined data type. However, interceptors should take care to preserve
     * idempotence by treating them as such.
     */
    this.body = null;
    /**
     * Whether this request should be made in a way that exposes progress events.
     *
     * Progress events are expensive (change detection runs on each event) and so
     * they should only be requested if the consumer intends to monitor them.
     *
     * Note: The `FetchBackend` doesn't support progress report on uploads.
     */
    this.reportProgress = false;
    /**
     * Whether this request should be sent with outgoing credentials (cookies).
     */
    this.withCredentials = false;
    /**
     * The expected response type of the server.
     *
     * This is used to parse the response appropriately before returning it to
     * the requestee.
     */
    this.responseType = 'json';
    this.method = method.toUpperCase();
    // Next, need to figure out which argument holds the HttpRequestInit
    // options, if any.
    let options;
    // Check whether a body argument is expected. The only valid way to omit
    // the body argument is to use a known no-body method like GET.
    if (mightHaveBody(this.method) || !!fourth) {
      // Body is the third argument, options are the fourth.
      this.body = third !== undefined ? third : null;
      options = fourth;
    } else {
      // No body required, options are the third argument. The body stays null.
      options = third;
    }
    // If options have been passed, interpret them.
    if (options) {
      // Normalize reportProgress and withCredentials.
      this.reportProgress = !!options.reportProgress;
      this.withCredentials = !!options.withCredentials;
      // Override default response type of 'json' if one is provided.
      if (!!options.responseType) {
        this.responseType = options.responseType;
      }
      // Override headers if they're provided.
      if (!!options.headers) {
        this.headers = options.headers;
      }
      if (!!options.context) {
        this.context = options.context;
      }
      if (!!options.params) {
        this.params = options.params;
      }
      // We do want to assign transferCache even if it's falsy (false is valid value)
      this.transferCache = options.transferCache;
    }
    // If no headers have been passed in, construct a new HttpHeaders instance.
    this.headers ??= new HttpHeaders();
    // If no context have been passed in, construct a new HttpContext instance.
    this.context ??= new HttpContext();
    // If no parameters have been passed in, construct a new HttpUrlEncodedParams instance.
    if (!this.params) {
      this.params = new HttpParams();
      this.urlWithParams = url;
    } else {
      // Encode the parameters to a string in preparation for inclusion in the URL.
      const params = this.params.toString();
      if (params.length === 0) {
        // No parameters, the visible URL is just the URL given at creation time.
        this.urlWithParams = url;
      } else {
        // Does the URL already have query parameters? Look for '?'.
        const qIdx = url.indexOf('?');
        // There are 3 cases to handle:
        // 1) No existing parameters -> append '?' followed by params.
        // 2) '?' exists and is followed by existing query string ->
        //    append '&' followed by params.
        // 3) '?' exists at the end of the url -> append params directly.
        // This basically amounts to determining the character, if any, with
        // which to join the URL and parameters.
        const sep = qIdx === -1 ? '?' : qIdx < url.length - 1 ? '&' : '';
        this.urlWithParams = url + sep + params;
      }
    }
  }
  /**
   * Transform the free-form body into a serialized format suitable for
   * transmission to the server.
   */
  serializeBody() {
    // If no body is present, no need to serialize it.
    if (this.body === null) {
      return null;
    }
    // Check whether the body is already in a serialized form. If so,
    // it can just be returned directly.
    if (typeof this.body === 'string' || isArrayBuffer(this.body) || isBlob(this.body) || isFormData(this.body) || isUrlSearchParams(this.body)) {
      return this.body;
    }
    // Check whether the body is an instance of HttpUrlEncodedParams.
    if (this.body instanceof HttpParams) {
      return this.body.toString();
    }
    // Check whether the body is an object or array, and serialize with JSON if so.
    if (typeof this.body === 'object' || typeof this.body === 'boolean' || Array.isArray(this.body)) {
      return JSON.stringify(this.body);
    }
    // Fall back on toString() for everything else.
    return this.body.toString();
  }
  /**
   * Examine the body and attempt to infer an appropriate MIME type
   * for it.
   *
   * If no such type can be inferred, this method will return `null`.
   */
  detectContentTypeHeader() {
    // An empty body has no content type.
    if (this.body === null) {
      return null;
    }
    // FormData bodies rely on the browser's content type assignment.
    if (isFormData(this.body)) {
      return null;
    }
    // Blobs usually have their own content type. If it doesn't, then
    // no type can be inferred.
    if (isBlob(this.body)) {
      return this.body.type || null;
    }
    // Array buffers have unknown contents and thus no type can be inferred.
    if (isArrayBuffer(this.body)) {
      return null;
    }
    // Technically, strings could be a form of JSON data, but it's safe enough
    // to assume they're plain strings.
    if (typeof this.body === 'string') {
      return 'text/plain';
    }
    // `HttpUrlEncodedParams` has its own content-type.
    if (this.body instanceof HttpParams) {
      return 'application/x-www-form-urlencoded;charset=UTF-8';
    }
    // Arrays, objects, boolean and numbers will be encoded as JSON.
    if (typeof this.body === 'object' || typeof this.body === 'number' || typeof this.body === 'boolean') {
      return 'application/json';
    }
    // No type could be inferred.
    return null;
  }
  clone(update = {}) {
    // For method, url, and responseType, take the current value unless
    // it is overridden in the update hash.
    const method = update.method || this.method;
    const url = update.url || this.url;
    const responseType = update.responseType || this.responseType;
    // Carefully handle the transferCache to differentiate between
    // `false` and `undefined` in the update args.
    const transferCache = update.transferCache ?? this.transferCache;
    // The body is somewhat special - a `null` value in update.body means
    // whatever current body is present is being overridden with an empty
    // body, whereas an `undefined` value in update.body implies no
    // override.
    const body = update.body !== undefined ? update.body : this.body;
    // Carefully handle the boolean options to differentiate between
    // `false` and `undefined` in the update args.
    const withCredentials = update.withCredentials ?? this.withCredentials;
    const reportProgress = update.reportProgress ?? this.reportProgress;
    // Headers and params may be appended to if `setHeaders` or
    // `setParams` are used.
    let headers = update.headers || this.headers;
    let params = update.params || this.params;
    // Pass on context if needed
    const context = update.context ?? this.context;
    // Check whether the caller has asked to add headers.
    if (update.setHeaders !== undefined) {
      // Set every requested header.
      headers = Object.keys(update.setHeaders).reduce((headers, name) => headers.set(name, update.setHeaders[name]), headers);
    }
    // Check whether the caller has asked to set params.
    if (update.setParams) {
      // Set every requested param.
      params = Object.keys(update.setParams).reduce((params, param) => params.set(param, update.setParams[param]), params);
    }
    // Finally, construct the new HttpRequest using the pieces from above.
    return new HttpRequest(method, url, body, {
      params,
      headers,
      context,
      reportProgress,
      responseType,
      withCredentials,
      transferCache
    });
  }
}

/**
 * Type enumeration for the different kinds of `HttpEvent`.
 *
 * @publicApi
 */
var HttpEventType;
(function (HttpEventType) {
  /**
   * The request was sent out over the wire.
   */
  HttpEventType[HttpEventType["Sent"] = 0] = "Sent";
  /**
   * An upload progress event was received.
   *
   * Note: The `FetchBackend` doesn't support progress report on uploads.
   */
  HttpEventType[HttpEventType["UploadProgress"] = 1] = "UploadProgress";
  /**
   * The response status code and headers were received.
   */
  HttpEventType[HttpEventType["ResponseHeader"] = 2] = "ResponseHeader";
  /**
   * A download progress event was received.
   */
  HttpEventType[HttpEventType["DownloadProgress"] = 3] = "DownloadProgress";
  /**
   * The full response including the body was received.
   */
  HttpEventType[HttpEventType["Response"] = 4] = "Response";
  /**
   * A custom event from an interceptor or a backend.
   */
  HttpEventType[HttpEventType["User"] = 5] = "User";
})(HttpEventType || (HttpEventType = {}));
/**
 * Base class for both `HttpResponse` and `HttpHeaderResponse`.
 *
 * @publicApi
 */
class HttpResponseBase {
  /**
   * Super-constructor for all responses.
   *
   * The single parameter accepted is an initialization hash. Any properties
   * of the response passed there will override the default values.
   */
  constructor(init, defaultStatus = HttpStatusCode.Ok, defaultStatusText = 'OK') {
    // If the hash has values passed, use them to initialize the response.
    // Otherwise use the default values.
    this.headers = init.headers || new HttpHeaders();
    this.status = init.status !== undefined ? init.status : defaultStatus;
    this.statusText = init.statusText || defaultStatusText;
    this.url = init.url || null;
    // Cache the ok value to avoid defining a getter.
    this.ok = this.status >= 200 && this.status < 300;
  }
}
/**
 * A partial HTTP response which only includes the status and header data,
 * but no response body.
 *
 * `HttpHeaderResponse` is a `HttpEvent` available on the response
 * event stream, only when progress events are requested.
 *
 * @publicApi
 */
class HttpHeaderResponse extends HttpResponseBase {
  /**
   * Create a new `HttpHeaderResponse` with the given parameters.
   */
  constructor(init = {}) {
    super(init);
    this.type = HttpEventType.ResponseHeader;
  }
  /**
   * Copy this `HttpHeaderResponse`, overriding its contents with the
   * given parameter hash.
   */
  clone(update = {}) {
    // Perform a straightforward initialization of the new HttpHeaderResponse,
    // overriding the current parameters with new ones if given.
    return new HttpHeaderResponse({
      headers: update.headers || this.headers,
      status: update.status !== undefined ? update.status : this.status,
      statusText: update.statusText || this.statusText,
      url: update.url || this.url || undefined
    });
  }
}
/**
 * A full HTTP response, including a typed response body (which may be `null`
 * if one was not returned).
 *
 * `HttpResponse` is a `HttpEvent` available on the response event
 * stream.
 *
 * @publicApi
 */
class HttpResponse extends HttpResponseBase {
  /**
   * Construct a new `HttpResponse`.
   */
  constructor(init = {}) {
    super(init);
    this.type = HttpEventType.Response;
    this.body = init.body !== undefined ? init.body : null;
  }
  clone(update = {}) {
    return new HttpResponse({
      body: update.body !== undefined ? update.body : this.body,
      headers: update.headers || this.headers,
      status: update.status !== undefined ? update.status : this.status,
      statusText: update.statusText || this.statusText,
      url: update.url || this.url || undefined
    });
  }
}
/**
 * A response that represents an error or failure, either from a
 * non-successful HTTP status, an error while executing the request,
 * or some other failure which occurred during the parsing of the response.
 *
 * Any error returned on the `Observable` response stream will be
 * wrapped in an `HttpErrorResponse` to provide additional context about
 * the state of the HTTP layer when the error occurred. The error property
 * will contain either a wrapped Error object or the error response returned
 * from the server.
 *
 * @publicApi
 */
class HttpErrorResponse extends HttpResponseBase {
  constructor(init) {
    // Initialize with a default status of 0 / Unknown Error.
    super(init, 0, 'Unknown Error');
    this.name = 'HttpErrorResponse';
    /**
     * Errors are never okay, even when the status code is in the 2xx success range.
     */
    this.ok = false;
    // If the response was successful, then this was a parse error. Otherwise, it was
    // a protocol-level failure of some sort. Either the request failed in transit
    // or the server returned an unsuccessful status code.
    if (this.status >= 200 && this.status < 300) {
      this.message = `Http failure during parsing for ${init.url || '(unknown url)'}`;
    } else {
      this.message = `Http failure response for ${init.url || '(unknown url)'}: ${init.status} ${init.statusText}`;
    }
    this.error = init.error || null;
  }
}
/**
 * Http status codes.
 * As per https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml
 * @publicApi
 */
var HttpStatusCode;
(function (HttpStatusCode) {
  HttpStatusCode[HttpStatusCode["Continue"] = 100] = "Continue";
  HttpStatusCode[HttpStatusCode["SwitchingProtocols"] = 101] = "SwitchingProtocols";
  HttpStatusCode[HttpStatusCode["Processing"] = 102] = "Processing";
  HttpStatusCode[HttpStatusCode["EarlyHints"] = 103] = "EarlyHints";
  HttpStatusCode[HttpStatusCode["Ok"] = 200] = "Ok";
  HttpStatusCode[HttpStatusCode["Created"] = 201] = "Created";
  HttpStatusCode[HttpStatusCode["Accepted"] = 202] = "Accepted";
  HttpStatusCode[HttpStatusCode["NonAuthoritativeInformation"] = 203] = "NonAuthoritativeInformation";
  HttpStatusCode[HttpStatusCode["NoContent"] = 204] = "NoContent";
  HttpStatusCode[HttpStatusCode["ResetContent"] = 205] = "ResetContent";
  HttpStatusCode[HttpStatusCode["PartialContent"] = 206] = "PartialContent";
  HttpStatusCode[HttpStatusCode["MultiStatus"] = 207] = "MultiStatus";
  HttpStatusCode[HttpStatusCode["AlreadyReported"] = 208] = "AlreadyReported";
  HttpStatusCode[HttpStatusCode["ImUsed"] = 226] = "ImUsed";
  HttpStatusCode[HttpStatusCode["MultipleChoices"] = 300] = "MultipleChoices";
  HttpStatusCode[HttpStatusCode["MovedPermanently"] = 301] = "MovedPermanently";
  HttpStatusCode[HttpStatusCode["Found"] = 302] = "Found";
  HttpStatusCode[HttpStatusCode["SeeOther"] = 303] = "SeeOther";
  HttpStatusCode[HttpStatusCode["NotModified"] = 304] = "NotModified";
  HttpStatusCode[HttpStatusCode["UseProxy"] = 305] = "UseProxy";
  HttpStatusCode[HttpStatusCode["Unused"] = 306] = "Unused";
  HttpStatusCode[HttpStatusCode["TemporaryRedirect"] = 307] = "TemporaryRedirect";
  HttpStatusCode[HttpStatusCode["PermanentRedirect"] = 308] = "PermanentRedirect";
  HttpStatusCode[HttpStatusCode["BadRequest"] = 400] = "BadRequest";
  HttpStatusCode[HttpStatusCode["Unauthorized"] = 401] = "Unauthorized";
  HttpStatusCode[HttpStatusCode["PaymentRequired"] = 402] = "PaymentRequired";
  HttpStatusCode[HttpStatusCode["Forbidden"] = 403] = "Forbidden";
  HttpStatusCode[HttpStatusCode["NotFound"] = 404] = "NotFound";
  HttpStatusCode[HttpStatusCode["MethodNotAllowed"] = 405] = "MethodNotAllowed";
  HttpStatusCode[HttpStatusCode["NotAcceptable"] = 406] = "NotAcceptable";
  HttpStatusCode[HttpStatusCode["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired";
  HttpStatusCode[HttpStatusCode["RequestTimeout"] = 408] = "RequestTimeout";
  HttpStatusCode[HttpStatusCode["Conflict"] = 409] = "Conflict";
  HttpStatusCode[HttpStatusCode["Gone"] = 410] = "Gone";
  HttpStatusCode[HttpStatusCode["LengthRequired"] = 411] = "LengthRequired";
  HttpStatusCode[HttpStatusCode["PreconditionFailed"] = 412] = "PreconditionFailed";
  HttpStatusCode[HttpStatusCode["PayloadTooLarge"] = 413] = "PayloadTooLarge";
  HttpStatusCode[HttpStatusCode["UriTooLong"] = 414] = "UriTooLong";
  HttpStatusCode[HttpStatusCode["UnsupportedMediaType"] = 415] = "UnsupportedMediaType";
  HttpStatusCode[HttpStatusCode["RangeNotSatisfiable"] = 416] = "RangeNotSatisfiable";
  HttpStatusCode[HttpStatusCode["ExpectationFailed"] = 417] = "ExpectationFailed";
  HttpStatusCode[HttpStatusCode["ImATeapot"] = 418] = "ImATeapot";
  HttpStatusCode[HttpStatusCode["MisdirectedRequest"] = 421] = "MisdirectedRequest";
  HttpStatusCode[HttpStatusCode["UnprocessableEntity"] = 422] = "UnprocessableEntity";
  HttpStatusCode[HttpStatusCode["Locked"] = 423] = "Locked";
  HttpStatusCode[HttpStatusCode["FailedDependency"] = 424] = "FailedDependency";
  HttpStatusCode[HttpStatusCode["TooEarly"] = 425] = "TooEarly";
  HttpStatusCode[HttpStatusCode["UpgradeRequired"] = 426] = "UpgradeRequired";
  HttpStatusCode[HttpStatusCode["PreconditionRequired"] = 428] = "PreconditionRequired";
  HttpStatusCode[HttpStatusCode["TooManyRequests"] = 429] = "TooManyRequests";
  HttpStatusCode[HttpStatusCode["RequestHeaderFieldsTooLarge"] = 431] = "RequestHeaderFieldsTooLarge";
  HttpStatusCode[HttpStatusCode["UnavailableForLegalReasons"] = 451] = "UnavailableForLegalReasons";
  HttpStatusCode[HttpStatusCode["InternalServerError"] = 500] = "InternalServerError";
  HttpStatusCode[HttpStatusCode["NotImplemented"] = 501] = "NotImplemented";
  HttpStatusCode[HttpStatusCode["BadGateway"] = 502] = "BadGateway";
  HttpStatusCode[HttpStatusCode["ServiceUnavailable"] = 503] = "ServiceUnavailable";
  HttpStatusCode[HttpStatusCode["GatewayTimeout"] = 504] = "GatewayTimeout";
  HttpStatusCode[HttpStatusCode["HttpVersionNotSupported"] = 505] = "HttpVersionNotSupported";
  HttpStatusCode[HttpStatusCode["VariantAlsoNegotiates"] = 506] = "VariantAlsoNegotiates";
  HttpStatusCode[HttpStatusCode["InsufficientStorage"] = 507] = "InsufficientStorage";
  HttpStatusCode[HttpStatusCode["LoopDetected"] = 508] = "LoopDetected";
  HttpStatusCode[HttpStatusCode["NotExtended"] = 510] = "NotExtended";
  HttpStatusCode[HttpStatusCode["NetworkAuthenticationRequired"] = 511] = "NetworkAuthenticationRequired";
})(HttpStatusCode || (HttpStatusCode = {}));

/**
 * Constructs an instance of `HttpRequestOptions<T>` from a source `HttpMethodOptions` and
 * the given `body`. This function clones the object and adds the body.
 *
 * Note that the `responseType` *options* value is a String that identifies the
 * single data type of the response.
 * A single overload version of the method handles each response type.
 * The value of `responseType` cannot be a union, as the combined signature could imply.
 *
 */
function addBody(options, body) {
  return {
    body,
    headers: options.headers,
    context: options.context,
    observe: options.observe,
    params: options.params,
    reportProgress: options.reportProgress,
    responseType: options.responseType,
    withCredentials: options.withCredentials,
    transferCache: options.transferCache
  };
}
/**
 * Performs HTTP requests.
 * This service is available as an injectable class, with methods to perform HTTP requests.
 * Each request method has multiple signatures, and the return type varies based on
 * the signature that is called (mainly the values of `observe` and `responseType`).
 *
 * Note that the `responseType` *options* value is a String that identifies the
 * single data type of the response.
 * A single overload version of the method handles each response type.
 * The value of `responseType` cannot be a union, as the combined signature could imply.

 *
 * @usageNotes
 * Sample HTTP requests for the [Tour of Heroes](/tutorial/tour-of-heroes/toh-pt0) application.
 *
 * ### HTTP Request Example
 *
 * ```
 *  // GET heroes whose name contains search term
 * searchHeroes(term: string): observable<Hero[]>{
 *
 *  const params = new HttpParams({fromString: 'name=term'});
 *    return this.httpClient.request('GET', this.heroesUrl, {responseType:'json', params});
 * }
 * ```
 *
 * Alternatively, the parameter string can be used without invoking HttpParams
 * by directly joining to the URL.
 * ```
 * this.httpClient.request('GET', this.heroesUrl + '?' + 'name=term', {responseType:'json'});
 * ```
 *
 *
 * ### JSONP Example
 * ```
 * requestJsonp(url, callback = 'callback') {
 *  return this.httpClient.jsonp(this.heroesURL, callback);
 * }
 * ```
 *
 * ### PATCH Example
 * ```
 * // PATCH one of the heroes' name
 * patchHero (id: number, heroName: string): Observable<{}> {
 * const url = `${this.heroesUrl}/${id}`;   // PATCH api/heroes/42
 *  return this.httpClient.patch(url, {name: heroName}, httpOptions)
 *    .pipe(catchError(this.handleError('patchHero')));
 * }
 * ```
 *
 * @see [HTTP Guide](guide/understanding-communicating-with-http)
 * @see [HTTP Request](api/common/http/HttpRequest)
 *
 * @publicApi
 */
class HttpClient {
  constructor(handler) {
    this.handler = handler;
  }
  /**
   * Constructs an observable for a generic HTTP request that, when subscribed,
   * fires the request through the chain of registered interceptors and on to the
   * server.
   *
   * You can pass an `HttpRequest` directly as the only parameter. In this case,
   * the call returns an observable of the raw `HttpEvent` stream.
   *
   * Alternatively you can pass an HTTP method as the first parameter,
   * a URL string as the second, and an options hash containing the request body as the third.
   * See `addBody()`. In this case, the specified `responseType` and `observe` options determine the
   * type of returned observable.
   *   * The `responseType` value determines how a successful response body is parsed.
   *   * If `responseType` is the default `json`, you can pass a type interface for the resulting
   * object as a type parameter to the call.
   *
   * The `observe` value determines the return type, according to what you are interested in
   * observing.
   *   * An `observe` value of events returns an observable of the raw `HttpEvent` stream, including
   * progress events by default.
   *   * An `observe` value of response returns an observable of `HttpResponse<T>`,
   * where the `T` parameter depends on the `responseType` and any optionally provided type
   * parameter.
   *   * An `observe` value of body returns an observable of `<T>` with the same `T` body type.
   *
   */
  request(first, url, options = {}) {
    let req;
    // First, check whether the primary argument is an instance of `HttpRequest`.
    if (first instanceof HttpRequest) {
      // It is. The other arguments must be undefined (per the signatures) and can be
      // ignored.
      req = first;
    } else {
      // It's a string, so it represents a URL. Construct a request based on it,
      // and incorporate the remaining arguments (assuming `GET` unless a method is
      // provided.
      // Figure out the headers.
      let headers = undefined;
      if (options.headers instanceof HttpHeaders) {
        headers = options.headers;
      } else {
        headers = new HttpHeaders(options.headers);
      }
      // Sort out parameters.
      let params = undefined;
      if (!!options.params) {
        if (options.params instanceof HttpParams) {
          params = options.params;
        } else {
          params = new HttpParams({
            fromObject: options.params
          });
        }
      }
      // Construct the request.
      req = new HttpRequest(first, url, options.body !== undefined ? options.body : null, {
        headers,
        context: options.context,
        params,
        reportProgress: options.reportProgress,
        // By default, JSON is assumed to be returned for all calls.
        responseType: options.responseType || 'json',
        withCredentials: options.withCredentials,
        transferCache: options.transferCache
      });
    }
    // Start with an Observable.of() the initial request, and run the handler (which
    // includes all interceptors) inside a concatMap(). This way, the handler runs
    // inside an Observable chain, which causes interceptors to be re-run on every
    // subscription (this also makes retries re-run the handler, including interceptors).
    const events$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.of)(req).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.concatMap)(req => this.handler.handle(req)));
    // If coming via the API signature which accepts a previously constructed HttpRequest,
    // the only option is to get the event stream. Otherwise, return the event stream if
    // that is what was requested.
    if (first instanceof HttpRequest || options.observe === 'events') {
      return events$;
    }
    // The requested stream contains either the full response or the body. In either
    // case, the first step is to filter the event stream to extract a stream of
    // responses(s).
    const res$ = events$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.filter)(event => event instanceof HttpResponse));
    // Decide which stream to return.
    switch (options.observe || 'body') {
      case 'body':
        // The requested stream is the body. Map the response stream to the response
        // body. This could be done more simply, but a misbehaving interceptor might
        // transform the response body into a different format and ignore the requested
        // responseType. Guard against this by validating that the response is of the
        // requested type.
        switch (req.responseType) {
          case 'arraybuffer':
            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(res => {
              // Validate that the body is an ArrayBuffer.
              if (res.body !== null && !(res.body instanceof ArrayBuffer)) {
                throw new Error('Response is not an ArrayBuffer.');
              }
              return res.body;
            }));
          case 'blob':
            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(res => {
              // Validate that the body is a Blob.
              if (res.body !== null && !(res.body instanceof Blob)) {
                throw new Error('Response is not a Blob.');
              }
              return res.body;
            }));
          case 'text':
            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(res => {
              // Validate that the body is a string.
              if (res.body !== null && typeof res.body !== 'string') {
                throw new Error('Response is not a string.');
              }
              return res.body;
            }));
          case 'json':
          default:
            // No validation needed for JSON responses, as they can be of any type.
            return res$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(res => res.body));
        }
      case 'response':
        // The response stream was requested directly, so return it.
        return res$;
      default:
        // Guard against new future observe types being added.
        throw new Error(`Unreachable: unhandled observe type ${options.observe}}`);
    }
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `DELETE` request to execute on the server. See the individual overloads for
   * details on the return type.
   *
   * @param url     The endpoint URL.
   * @param options The HTTP options to send with the request.
   *
   */
  delete(url, options = {}) {
    return this.request('DELETE', url, options);
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `GET` request to execute on the server. See the individual overloads for
   * details on the return type.
   */
  get(url, options = {}) {
    return this.request('GET', url, options);
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `HEAD` request to execute on the server. The `HEAD` method returns
   * meta information about the resource without transferring the
   * resource itself. See the individual overloads for
   * details on the return type.
   */
  head(url, options = {}) {
    return this.request('HEAD', url, options);
  }
  /**
   * Constructs an `Observable` that, when subscribed, causes a request with the special method
   * `JSONP` to be dispatched via the interceptor pipeline.
   * The [JSONP pattern](https://en.wikipedia.org/wiki/JSONP) works around limitations of certain
   * API endpoints that don't support newer,
   * and preferable [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) protocol.
   * JSONP treats the endpoint API as a JavaScript file and tricks the browser to process the
   * requests even if the API endpoint is not located on the same domain (origin) as the client-side
   * application making the request.
   * The endpoint API must support JSONP callback for JSONP requests to work.
   * The resource API returns the JSON response wrapped in a callback function.
   * You can pass the callback function name as one of the query parameters.
   * Note that JSONP requests can only be used with `GET` requests.
   *
   * @param url The resource URL.
   * @param callbackParam The callback function name.
   *
   */
  jsonp(url, callbackParam) {
    return this.request('JSONP', url, {
      params: new HttpParams().append(callbackParam, 'JSONP_CALLBACK'),
      observe: 'body',
      responseType: 'json'
    });
  }
  /**
   * Constructs an `Observable` that, when subscribed, causes the configured
   * `OPTIONS` request to execute on the server. This method allows the client
   * to determine the supported HTTP methods and other capabilities of an endpoint,
   * without implying a resource action. See the individual overloads for
   * details on the return type.
   */
  options(url, options = {}) {
    return this.request('OPTIONS', url, options);
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `PATCH` request to execute on the server. See the individual overloads for
   * details on the return type.
   */
  patch(url, body, options = {}) {
    return this.request('PATCH', url, addBody(options, body));
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `POST` request to execute on the server. The server responds with the location of
   * the replaced resource. See the individual overloads for
   * details on the return type.
   */
  post(url, body, options = {}) {
    return this.request('POST', url, addBody(options, body));
  }
  /**
   * Constructs an observable that, when subscribed, causes the configured
   * `PUT` request to execute on the server. The `PUT` method replaces an existing resource
   * with a new set of values.
   * See the individual overloads for details on the return type.
   */
  put(url, body, options = {}) {
    return this.request('PUT', url, addBody(options, body));
  }
  static {
    this.ɵfac = function HttpClient_Factory(t) {
      return new (t || HttpClient)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](HttpHandler));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: HttpClient,
      factory: HttpClient.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpClient, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: HttpHandler
  }], null);
})();
const XSSI_PREFIX$1 = /^\)\]\}',?\n/;
const REQUEST_URL_HEADER = `X-Request-URL`;
/**
 * Determine an appropriate URL for the response, by checking either
 * response url or the X-Request-URL header.
 */
function getResponseUrl$1(response) {
  if (response.url) {
    return response.url;
  }
  // stored as lowercase in the map
  const xRequestUrl = REQUEST_URL_HEADER.toLocaleLowerCase();
  return response.headers.get(xRequestUrl);
}
/**
 * Uses `fetch` to send requests to a backend server.
 *
 * This `FetchBackend` requires the support of the
 * [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) which is available on all
 * supported browsers and on Node.js v18 or later.
 *
 * @see {@link HttpHandler}
 *
 * @publicApi
 */
class FetchBackend {
  constructor() {
    // We need to bind the native fetch to its context or it will throw an "illegal invocation"
    this.fetchImpl = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(FetchFactory, {
      optional: true
    })?.fetch ?? fetch.bind(globalThis);
    this.ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__.NgZone);
  }
  handle(request) {
    return new rxjs__WEBPACK_IMPORTED_MODULE_6__.Observable(observer => {
      const aborter = new AbortController();
      this.doRequest(request, aborter.signal, observer).then(noop, error => observer.error(new HttpErrorResponse({
        error
      })));
      return () => aborter.abort();
    });
  }
  doRequest(request, signal, observer) {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      const init = _this.createRequestInit(request);
      let response;
      try {
        const fetchPromise = _this.fetchImpl(request.urlWithParams, {
          signal,
          ...init
        });
        // Make sure Zone.js doesn't trigger false-positive unhandled promise
        // error in case the Promise is rejected synchronously. See function
        // description for additional information.
        silenceSuperfluousUnhandledPromiseRejection(fetchPromise);
        // Send the `Sent` event before awaiting the response.
        observer.next({
          type: HttpEventType.Sent
        });
        response = yield fetchPromise;
      } catch (error) {
        observer.error(new HttpErrorResponse({
          error,
          status: error.status ?? 0,
          statusText: error.statusText,
          url: request.urlWithParams,
          headers: error.headers
        }));
        return;
      }
      const headers = new HttpHeaders(response.headers);
      const statusText = response.statusText;
      const url = getResponseUrl$1(response) ?? request.urlWithParams;
      let status = response.status;
      let body = null;
      if (request.reportProgress) {
        observer.next(new HttpHeaderResponse({
          headers,
          status,
          statusText,
          url
        }));
      }
      if (response.body) {
        // Read Progress
        const contentLength = response.headers.get('content-length');
        const chunks = [];
        const reader = response.body.getReader();
        let receivedLength = 0;
        let decoder;
        let partialText;
        // We have to check whether the Zone is defined in the global scope because this may be called
        // when the zone is nooped.
        const reqZone = typeof Zone !== 'undefined' && Zone.current;
        // Perform response processing outside of Angular zone to
        // ensure no excessive change detection runs are executed
        // Here calling the async ReadableStreamDefaultReader.read() is responsible for triggering CD
        yield _this.ngZone.runOutsideAngular(/*#__PURE__*/(0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
          while (true) {
            const {
              done,
              value
            } = yield reader.read();
            if (done) {
              break;
            }
            chunks.push(value);
            receivedLength += value.length;
            if (request.reportProgress) {
              partialText = request.responseType === 'text' ? (partialText ?? '') + (decoder ??= new TextDecoder()).decode(value, {
                stream: true
              }) : undefined;
              const reportProgress = () => observer.next({
                type: HttpEventType.DownloadProgress,
                total: contentLength ? +contentLength : undefined,
                loaded: receivedLength,
                partialText
              });
              reqZone ? reqZone.run(reportProgress) : reportProgress();
            }
          }
        }));
        // Combine all chunks.
        const chunksAll = _this.concatChunks(chunks, receivedLength);
        try {
          const contentType = response.headers.get('Content-Type') ?? '';
          body = _this.parseBody(request, chunksAll, contentType);
        } catch (error) {
          // Body loading or parsing failed
          observer.error(new HttpErrorResponse({
            error,
            headers: new HttpHeaders(response.headers),
            status: response.status,
            statusText: response.statusText,
            url: getResponseUrl$1(response) ?? request.urlWithParams
          }));
          return;
        }
      }
      // Same behavior as the XhrBackend
      if (status === 0) {
        status = body ? HttpStatusCode.Ok : 0;
      }
      // ok determines whether the response will be transmitted on the event or
      // error channel. Unsuccessful status codes (not 2xx) will always be errors,
      // but a successful status code can still result in an error if the user
      // asked for JSON data and the body cannot be parsed as such.
      const ok = status >= 200 && status < 300;
      if (ok) {
        observer.next(new HttpResponse({
          body,
          headers,
          status,
          statusText,
          url
        }));
        // The full body has been received and delivered, no further events
        // are possible. This request is complete.
        observer.complete();
      } else {
        observer.error(new HttpErrorResponse({
          error: body,
          headers,
          status,
          statusText,
          url
        }));
      }
    })();
  }
  parseBody(request, binContent, contentType) {
    switch (request.responseType) {
      case 'json':
        // stripping the XSSI when present
        const text = new TextDecoder().decode(binContent).replace(XSSI_PREFIX$1, '');
        return text === '' ? null : JSON.parse(text);
      case 'text':
        return new TextDecoder().decode(binContent);
      case 'blob':
        return new Blob([binContent], {
          type: contentType
        });
      case 'arraybuffer':
        return binContent.buffer;
    }
  }
  createRequestInit(req) {
    // We could share some of this logic with the XhrBackend
    const headers = {};
    const credentials = req.withCredentials ? 'include' : undefined;
    // Setting all the requested headers.
    req.headers.forEach((name, values) => headers[name] = values.join(','));
    // Add an Accept header if one isn't present already.
    headers['Accept'] ??= 'application/json, text/plain, */*';
    // Auto-detect the Content-Type header if one isn't present already.
    if (!headers['Content-Type']) {
      const detectedType = req.detectContentTypeHeader();
      // Sometimes Content-Type detection fails.
      if (detectedType !== null) {
        headers['Content-Type'] = detectedType;
      }
    }
    return {
      body: req.serializeBody(),
      method: req.method,
      headers,
      credentials
    };
  }
  concatChunks(chunks, totalLength) {
    const chunksAll = new Uint8Array(totalLength);
    let position = 0;
    for (const chunk of chunks) {
      chunksAll.set(chunk, position);
      position += chunk.length;
    }
    return chunksAll;
  }
  static {
    this.ɵfac = function FetchBackend_Factory(t) {
      return new (t || FetchBackend)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: FetchBackend,
      factory: FetchBackend.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](FetchBackend, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], null, null);
})();
/**
 * Abstract class to provide a mocked implementation of `fetch()`
 */
class FetchFactory {}
function noop() {}
/**
 * Zone.js treats a rejected promise that has not yet been awaited
 * as an unhandled error. This function adds a noop `.then` to make
 * sure that Zone.js doesn't throw an error if the Promise is rejected
 * synchronously.
 */
function silenceSuperfluousUnhandledPromiseRejection(promise) {
  promise.then(noop, noop);
}
function interceptorChainEndFn(req, finalHandlerFn) {
  return finalHandlerFn(req);
}
/**
 * Constructs a `ChainedInterceptorFn` which adapts a legacy `HttpInterceptor` to the
 * `ChainedInterceptorFn` interface.
 */
function adaptLegacyInterceptorToChain(chainTailFn, interceptor) {
  return (initialRequest, finalHandlerFn) => interceptor.intercept(initialRequest, {
    handle: downstreamRequest => chainTailFn(downstreamRequest, finalHandlerFn)
  });
}
/**
 * Constructs a `ChainedInterceptorFn` which wraps and invokes a functional interceptor in the given
 * injector.
 */
function chainedInterceptorFn(chainTailFn, interceptorFn, injector) {
  // clang-format off
  return (initialRequest, finalHandlerFn) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.runInInjectionContext)(injector, () => interceptorFn(initialRequest, downstreamRequest => chainTailFn(downstreamRequest, finalHandlerFn)));
  // clang-format on
}
/**
 * A multi-provider token that represents the array of registered
 * `HttpInterceptor` objects.
 *
 * @publicApi
 */
const HTTP_INTERCEPTORS = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'HTTP_INTERCEPTORS' : '');
/**
 * A multi-provided token of `HttpInterceptorFn`s.
 */
const HTTP_INTERCEPTOR_FNS = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'HTTP_INTERCEPTOR_FNS' : '');
/**
 * A multi-provided token of `HttpInterceptorFn`s that are only set in root.
 */
const HTTP_ROOT_INTERCEPTOR_FNS = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'HTTP_ROOT_INTERCEPTOR_FNS' : '');
/**
 * A provider to set a global primary http backend. If set, it will override the default one
 */
const PRIMARY_HTTP_BACKEND = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'PRIMARY_HTTP_BACKEND' : '');
/**
 * Creates an `HttpInterceptorFn` which lazily initializes an interceptor chain from the legacy
 * class-based interceptors and runs the request through it.
 */
function legacyInterceptorFnFactory() {
  let chain = null;
  return (req, handler) => {
    if (chain === null) {
      const interceptors = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(HTTP_INTERCEPTORS, {
        optional: true
      }) ?? [];
      // Note: interceptors are wrapped right-to-left so that final execution order is
      // left-to-right. That is, if `interceptors` is the array `[a, b, c]`, we want to
      // produce a chain that is conceptually `c(b(a(end)))`, which we build from the inside
      // out.
      chain = interceptors.reduceRight(adaptLegacyInterceptorToChain, interceptorChainEndFn);
    }
    const pendingTasks = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵPendingTasks"]);
    const taskId = pendingTasks.add();
    return chain(req, handler).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.finalize)(() => pendingTasks.remove(taskId)));
  };
}
let fetchBackendWarningDisplayed = false;
/** Internal function to reset the flag in tests */
function resetFetchBackendWarningFlag() {
  fetchBackendWarningDisplayed = false;
}
class HttpInterceptorHandler extends HttpHandler {
  constructor(backend, injector) {
    super();
    this.backend = backend;
    this.injector = injector;
    this.chain = null;
    this.pendingTasks = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵPendingTasks"]);
    // Check if there is a preferred HTTP backend configured and use it if that's the case.
    // This is needed to enable `FetchBackend` globally for all HttpClient's when `withFetch`
    // is used.
    const primaryHttpBackend = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(PRIMARY_HTTP_BACKEND, {
      optional: true
    });
    this.backend = primaryHttpBackend ?? backend;
    // We strongly recommend using fetch backend for HTTP calls when SSR is used
    // for an application. The logic below checks if that's the case and produces
    // a warning otherwise.
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !fetchBackendWarningDisplayed) {
      const isServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_8__.isPlatformServer)(injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_5__.PLATFORM_ID));
      if (isServer && !(this.backend instanceof FetchBackend)) {
        fetchBackendWarningDisplayed = true;
        injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵConsole"]).warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵformatRuntimeError"])(2801 /* RuntimeErrorCode.NOT_USING_FETCH_BACKEND_IN_SSR */, 'Angular detected that `HttpClient` is not configured ' + "to use `fetch` APIs. It's strongly recommended to " + 'enable `fetch` for applications that use Server-Side Rendering ' + 'for better performance and compatibility. ' + 'To enable `fetch`, add the `withFetch()` to the `provideHttpClient()` ' + 'call at the root of the application.'));
      }
    }
  }
  handle(initialRequest) {
    if (this.chain === null) {
      const dedupedInterceptorFns = Array.from(new Set([...this.injector.get(HTTP_INTERCEPTOR_FNS), ...this.injector.get(HTTP_ROOT_INTERCEPTOR_FNS, [])]));
      // Note: interceptors are wrapped right-to-left so that final execution order is
      // left-to-right. That is, if `dedupedInterceptorFns` is the array `[a, b, c]`, we want to
      // produce a chain that is conceptually `c(b(a(end)))`, which we build from the inside
      // out.
      this.chain = dedupedInterceptorFns.reduceRight((nextSequencedFn, interceptorFn) => chainedInterceptorFn(nextSequencedFn, interceptorFn, this.injector), interceptorChainEndFn);
    }
    const taskId = this.pendingTasks.add();
    return this.chain(initialRequest, downstreamRequest => this.backend.handle(downstreamRequest)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.finalize)(() => this.pendingTasks.remove(taskId)));
  }
  static {
    this.ɵfac = function HttpInterceptorHandler_Factory(t) {
      return new (t || HttpInterceptorHandler)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](HttpBackend), _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: HttpInterceptorHandler,
      factory: HttpInterceptorHandler.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpInterceptorHandler, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: HttpBackend
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector
  }], null);
})();

// Every request made through JSONP needs a callback name that's unique across the
// whole page. Each request is assigned an id and the callback name is constructed
// from that. The next id to be assigned is tracked in a global variable here that
// is shared among all applications on the page.
let nextRequestId = 0;
/**
 * When a pending <script> is unsubscribed we'll move it to this document, so it won't be
 * executed.
 */
let foreignDocument;
// Error text given when a JSONP script is injected, but doesn't invoke the callback
// passed in its URL.
const JSONP_ERR_NO_CALLBACK = 'JSONP injected script did not invoke callback.';
// Error text given when a request is passed to the JsonpClientBackend that doesn't
// have a request method JSONP.
const JSONP_ERR_WRONG_METHOD = 'JSONP requests must use JSONP request method.';
const JSONP_ERR_WRONG_RESPONSE_TYPE = 'JSONP requests must use Json response type.';
// Error text given when a request is passed to the JsonpClientBackend that has
// headers set
const JSONP_ERR_HEADERS_NOT_SUPPORTED = 'JSONP requests do not support headers.';
/**
 * DI token/abstract type representing a map of JSONP callbacks.
 *
 * In the browser, this should always be the `window` object.
 *
 *
 */
class JsonpCallbackContext {}
/**
 * Factory function that determines where to store JSONP callbacks.
 *
 * Ordinarily JSONP callbacks are stored on the `window` object, but this may not exist
 * in test environments. In that case, callbacks are stored on an anonymous object instead.
 *
 *
 */
function jsonpCallbackContext() {
  if (typeof window === 'object') {
    return window;
  }
  return {};
}
/**
 * Processes an `HttpRequest` with the JSONP method,
 * by performing JSONP style requests.
 * @see {@link HttpHandler}
 * @see {@link HttpXhrBackend}
 *
 * @publicApi
 */
class JsonpClientBackend {
  constructor(callbackMap, document) {
    this.callbackMap = callbackMap;
    this.document = document;
    /**
     * A resolved promise that can be used to schedule microtasks in the event handlers.
     */
    this.resolvedPromise = Promise.resolve();
  }
  /**
   * Get the name of the next callback method, by incrementing the global `nextRequestId`.
   */
  nextCallback() {
    return `ng_jsonp_callback_${nextRequestId++}`;
  }
  /**
   * Processes a JSONP request and returns an event stream of the results.
   * @param req The request object.
   * @returns An observable of the response events.
   *
   */
  handle(req) {
    // Firstly, check both the method and response type. If either doesn't match
    // then the request was improperly routed here and cannot be handled.
    if (req.method !== 'JSONP') {
      throw new Error(JSONP_ERR_WRONG_METHOD);
    } else if (req.responseType !== 'json') {
      throw new Error(JSONP_ERR_WRONG_RESPONSE_TYPE);
    }
    // Check the request headers. JSONP doesn't support headers and
    // cannot set any that were supplied.
    if (req.headers.keys().length > 0) {
      throw new Error(JSONP_ERR_HEADERS_NOT_SUPPORTED);
    }
    // Everything else happens inside the Observable boundary.
    return new rxjs__WEBPACK_IMPORTED_MODULE_6__.Observable(observer => {
      // The first step to make a request is to generate the callback name, and replace the
      // callback placeholder in the URL with the name. Care has to be taken here to ensure
      // a trailing &, if matched, gets inserted back into the URL in the correct place.
      const callback = this.nextCallback();
      const url = req.urlWithParams.replace(/=JSONP_CALLBACK(&|$)/, `=${callback}$1`);
      // Construct the <script> tag and point it at the URL.
      const node = this.document.createElement('script');
      node.src = url;
      // A JSONP request requires waiting for multiple callbacks. These variables
      // are closed over and track state across those callbacks.
      // The response object, if one has been received, or null otherwise.
      let body = null;
      // Whether the response callback has been called.
      let finished = false;
      // Set the response callback in this.callbackMap (which will be the window
      // object in the browser. The script being loaded via the <script> tag will
      // eventually call this callback.
      this.callbackMap[callback] = data => {
        // Data has been received from the JSONP script. Firstly, delete this callback.
        delete this.callbackMap[callback];
        // Set state to indicate data was received.
        body = data;
        finished = true;
      };
      // cleanup() is a utility closure that removes the <script> from the page and
      // the response callback from the window. This logic is used in both the
      // success, error, and cancellation paths, so it's extracted out for convenience.
      const cleanup = () => {
        // Remove the <script> tag if it's still on the page.
        if (node.parentNode) {
          node.parentNode.removeChild(node);
        }
        // Remove the response callback from the callbackMap (window object in the
        // browser).
        delete this.callbackMap[callback];
      };
      // onLoad() is the success callback which runs after the response callback
      // if the JSONP script loads successfully. The event itself is unimportant.
      // If something went wrong, onLoad() may run without the response callback
      // having been invoked.
      const onLoad = event => {
        // We wrap it in an extra Promise, to ensure the microtask
        // is scheduled after the loaded endpoint has executed any potential microtask itself,
        // which is not guaranteed in Internet Explorer and EdgeHTML. See issue #39496
        this.resolvedPromise.then(() => {
          // Cleanup the page.
          cleanup();
          // Check whether the response callback has run.
          if (!finished) {
            // It hasn't, something went wrong with the request. Return an error via
            // the Observable error path. All JSONP errors have status 0.
            observer.error(new HttpErrorResponse({
              url,
              status: 0,
              statusText: 'JSONP Error',
              error: new Error(JSONP_ERR_NO_CALLBACK)
            }));
            return;
          }
          // Success. body either contains the response body or null if none was
          // returned.
          observer.next(new HttpResponse({
            body,
            status: HttpStatusCode.Ok,
            statusText: 'OK',
            url
          }));
          // Complete the stream, the response is over.
          observer.complete();
        });
      };
      // onError() is the error callback, which runs if the script returned generates
      // a Javascript error. It emits the error via the Observable error channel as
      // a HttpErrorResponse.
      const onError = error => {
        cleanup();
        // Wrap the error in a HttpErrorResponse.
        observer.error(new HttpErrorResponse({
          error,
          status: 0,
          statusText: 'JSONP Error',
          url
        }));
      };
      // Subscribe to both the success (load) and error events on the <script> tag,
      // and add it to the page.
      node.addEventListener('load', onLoad);
      node.addEventListener('error', onError);
      this.document.body.appendChild(node);
      // The request has now been successfully sent.
      observer.next({
        type: HttpEventType.Sent
      });
      // Cancellation handler.
      return () => {
        if (!finished) {
          this.removeListeners(node);
        }
        // And finally, clean up the page.
        cleanup();
      };
    });
  }
  removeListeners(script) {
    // Issue #34818
    // Changing <script>'s ownerDocument will prevent it from execution.
    // https://html.spec.whatwg.org/multipage/scripting.html#execute-the-script-block
    foreignDocument ??= this.document.implementation.createHTMLDocument();
    foreignDocument.adoptNode(script);
  }
  static {
    this.ɵfac = function JsonpClientBackend_Factory(t) {
      return new (t || JsonpClientBackend)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](JsonpCallbackContext), _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: JsonpClientBackend,
      factory: JsonpClientBackend.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](JsonpClientBackend, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: JsonpCallbackContext
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT]
    }]
  }], null);
})();
/**
 * Identifies requests with the method JSONP and shifts them to the `JsonpClientBackend`.
 */
function jsonpInterceptorFn(req, next) {
  if (req.method === 'JSONP') {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(JsonpClientBackend).handle(req);
  }
  // Fall through for normal HTTP requests.
  return next(req);
}
/**
 * Identifies requests with the method JSONP and
 * shifts them to the `JsonpClientBackend`.
 *
 * @see {@link HttpInterceptor}
 *
 * @publicApi
 */
class JsonpInterceptor {
  constructor(injector) {
    this.injector = injector;
  }
  /**
   * Identifies and handles a given JSONP request.
   * @param initialRequest The outgoing request object to handle.
   * @param next The next interceptor in the chain, or the backend
   * if no interceptors remain in the chain.
   * @returns An observable of the event stream.
   */
  intercept(initialRequest, next) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.runInInjectionContext)(this.injector, () => jsonpInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
  }
  static {
    this.ɵfac = function JsonpInterceptor_Factory(t) {
      return new (t || JsonpInterceptor)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: JsonpInterceptor,
      factory: JsonpInterceptor.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](JsonpInterceptor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector
  }], null);
})();
const XSSI_PREFIX = /^\)\]\}',?\n/;
/**
 * Determine an appropriate URL for the response, by checking either
 * XMLHttpRequest.responseURL or the X-Request-URL header.
 */
function getResponseUrl(xhr) {
  if ('responseURL' in xhr && xhr.responseURL) {
    return xhr.responseURL;
  }
  if (/^X-Request-URL:/m.test(xhr.getAllResponseHeaders())) {
    return xhr.getResponseHeader('X-Request-URL');
  }
  return null;
}
/**
 * Uses `XMLHttpRequest` to send requests to a backend server.
 * @see {@link HttpHandler}
 * @see {@link JsonpClientBackend}
 *
 * @publicApi
 */
class HttpXhrBackend {
  constructor(xhrFactory) {
    this.xhrFactory = xhrFactory;
  }
  /**
   * Processes a request and returns a stream of response events.
   * @param req The request object.
   * @returns An observable of the response events.
   */
  handle(req) {
    // Quick check to give a better error message when a user attempts to use
    // HttpClient.jsonp() without installing the HttpClientJsonpModule
    if (req.method === 'JSONP') {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵRuntimeError"](-2800 /* RuntimeErrorCode.MISSING_JSONP_MODULE */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot make a JSONP request without JSONP support. To fix the problem, either add the \`withJsonpSupport()\` call (if \`provideHttpClient()\` is used) or import the \`HttpClientJsonpModule\` in the root NgModule.`);
    }
    // Check whether this factory has a special function to load an XHR implementation
    // for various non-browser environments. We currently limit it to only `ServerXhr`
    // class, which needs to load an XHR implementation.
    const xhrFactory = this.xhrFactory;
    const source = xhrFactory.ɵloadImpl ? (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.from)(xhrFactory.ɵloadImpl()) : (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.of)(null);
    return source.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.switchMap)(() => {
      // Everything happens on Observable subscription.
      return new rxjs__WEBPACK_IMPORTED_MODULE_6__.Observable(observer => {
        // Start by setting up the XHR object with request method, URL, and withCredentials
        // flag.
        const xhr = xhrFactory.build();
        xhr.open(req.method, req.urlWithParams);
        if (req.withCredentials) {
          xhr.withCredentials = true;
        }
        // Add all the requested headers.
        req.headers.forEach((name, values) => xhr.setRequestHeader(name, values.join(',')));
        // Add an Accept header if one isn't present already.
        if (!req.headers.has('Accept')) {
          xhr.setRequestHeader('Accept', 'application/json, text/plain, */*');
        }
        // Auto-detect the Content-Type header if one isn't present already.
        if (!req.headers.has('Content-Type')) {
          const detectedType = req.detectContentTypeHeader();
          // Sometimes Content-Type detection fails.
          if (detectedType !== null) {
            xhr.setRequestHeader('Content-Type', detectedType);
          }
        }
        // Set the responseType if one was requested.
        if (req.responseType) {
          const responseType = req.responseType.toLowerCase();
          // JSON responses need to be processed as text. This is because if the server
          // returns an XSSI-prefixed JSON response, the browser will fail to parse it,
          // xhr.response will be null, and xhr.responseText cannot be accessed to
          // retrieve the prefixed JSON data in order to strip the prefix. Thus, all JSON
          // is parsed by first requesting text and then applying JSON.parse.
          xhr.responseType = responseType !== 'json' ? responseType : 'text';
        }
        // Serialize the request body if one is present. If not, this will be set to null.
        const reqBody = req.serializeBody();
        // If progress events are enabled, response headers will be delivered
        // in two events - the HttpHeaderResponse event and the full HttpResponse
        // event. However, since response headers don't change in between these
        // two events, it doesn't make sense to parse them twice. So headerResponse
        // caches the data extracted from the response whenever it's first parsed,
        // to ensure parsing isn't duplicated.
        let headerResponse = null;
        // partialFromXhr extracts the HttpHeaderResponse from the current XMLHttpRequest
        // state, and memoizes it into headerResponse.
        const partialFromXhr = () => {
          if (headerResponse !== null) {
            return headerResponse;
          }
          const statusText = xhr.statusText || 'OK';
          // Parse headers from XMLHttpRequest - this step is lazy.
          const headers = new HttpHeaders(xhr.getAllResponseHeaders());
          // Read the response URL from the XMLHttpResponse instance and fall back on the
          // request URL.
          const url = getResponseUrl(xhr) || req.url;
          // Construct the HttpHeaderResponse and memoize it.
          headerResponse = new HttpHeaderResponse({
            headers,
            status: xhr.status,
            statusText,
            url
          });
          return headerResponse;
        };
        // Next, a few closures are defined for the various events which XMLHttpRequest can
        // emit. This allows them to be unregistered as event listeners later.
        // First up is the load event, which represents a response being fully available.
        const onLoad = () => {
          // Read response state from the memoized partial data.
          let {
            headers,
            status,
            statusText,
            url
          } = partialFromXhr();
          // The body will be read out if present.
          let body = null;
          if (status !== HttpStatusCode.NoContent) {
            // Use XMLHttpRequest.response if set, responseText otherwise.
            body = typeof xhr.response === 'undefined' ? xhr.responseText : xhr.response;
          }
          // Normalize another potential bug (this one comes from CORS).
          if (status === 0) {
            status = !!body ? HttpStatusCode.Ok : 0;
          }
          // ok determines whether the response will be transmitted on the event or
          // error channel. Unsuccessful status codes (not 2xx) will always be errors,
          // but a successful status code can still result in an error if the user
          // asked for JSON data and the body cannot be parsed as such.
          let ok = status >= 200 && status < 300;
          // Check whether the body needs to be parsed as JSON (in many cases the browser
          // will have done that already).
          if (req.responseType === 'json' && typeof body === 'string') {
            // Save the original body, before attempting XSSI prefix stripping.
            const originalBody = body;
            body = body.replace(XSSI_PREFIX, '');
            try {
              // Attempt the parse. If it fails, a parse error should be delivered to the
              // user.
              body = body !== '' ? JSON.parse(body) : null;
            } catch (error) {
              // Since the JSON.parse failed, it's reasonable to assume this might not have
              // been a JSON response. Restore the original body (including any XSSI prefix)
              // to deliver a better error response.
              body = originalBody;
              // If this was an error request to begin with, leave it as a string, it
              // probably just isn't JSON. Otherwise, deliver the parsing error to the user.
              if (ok) {
                // Even though the response status was 2xx, this is still an error.
                ok = false;
                // The parse error contains the text of the body that failed to parse.
                body = {
                  error,
                  text: body
                };
              }
            }
          }
          if (ok) {
            // A successful response is delivered on the event stream.
            observer.next(new HttpResponse({
              body,
              headers,
              status,
              statusText,
              url: url || undefined
            }));
            // The full body has been received and delivered, no further events
            // are possible. This request is complete.
            observer.complete();
          } else {
            // An unsuccessful request is delivered on the error channel.
            observer.error(new HttpErrorResponse({
              // The error in this case is the response body (error from the server).
              error: body,
              headers,
              status,
              statusText,
              url: url || undefined
            }));
          }
        };
        // The onError callback is called when something goes wrong at the network level.
        // Connection timeout, DNS error, offline, etc. These are actual errors, and are
        // transmitted on the error channel.
        const onError = error => {
          const {
            url
          } = partialFromXhr();
          const res = new HttpErrorResponse({
            error,
            status: xhr.status || 0,
            statusText: xhr.statusText || 'Unknown Error',
            url: url || undefined
          });
          observer.error(res);
        };
        // The sentHeaders flag tracks whether the HttpResponseHeaders event
        // has been sent on the stream. This is necessary to track if progress
        // is enabled since the event will be sent on only the first download
        // progress event.
        let sentHeaders = false;
        // The download progress event handler, which is only registered if
        // progress events are enabled.
        const onDownProgress = event => {
          // Send the HttpResponseHeaders event if it hasn't been sent already.
          if (!sentHeaders) {
            observer.next(partialFromXhr());
            sentHeaders = true;
          }
          // Start building the download progress event to deliver on the response
          // event stream.
          let progressEvent = {
            type: HttpEventType.DownloadProgress,
            loaded: event.loaded
          };
          // Set the total number of bytes in the event if it's available.
          if (event.lengthComputable) {
            progressEvent.total = event.total;
          }
          // If the request was for text content and a partial response is
          // available on XMLHttpRequest, include it in the progress event
          // to allow for streaming reads.
          if (req.responseType === 'text' && !!xhr.responseText) {
            progressEvent.partialText = xhr.responseText;
          }
          // Finally, fire the event.
          observer.next(progressEvent);
        };
        // The upload progress event handler, which is only registered if
        // progress events are enabled.
        const onUpProgress = event => {
          // Upload progress events are simpler. Begin building the progress
          // event.
          let progress = {
            type: HttpEventType.UploadProgress,
            loaded: event.loaded
          };
          // If the total number of bytes being uploaded is available, include
          // it.
          if (event.lengthComputable) {
            progress.total = event.total;
          }
          // Send the event.
          observer.next(progress);
        };
        // By default, register for load and error events.
        xhr.addEventListener('load', onLoad);
        xhr.addEventListener('error', onError);
        xhr.addEventListener('timeout', onError);
        xhr.addEventListener('abort', onError);
        // Progress events are only enabled if requested.
        if (req.reportProgress) {
          // Download progress is always enabled if requested.
          xhr.addEventListener('progress', onDownProgress);
          // Upload progress depends on whether there is a body to upload.
          if (reqBody !== null && xhr.upload) {
            xhr.upload.addEventListener('progress', onUpProgress);
          }
        }
        // Fire the request, and notify the event stream that it was fired.
        xhr.send(reqBody);
        observer.next({
          type: HttpEventType.Sent
        });
        // This is the return from the Observable function, which is the
        // request cancellation handler.
        return () => {
          // On a cancellation, remove all registered event listeners.
          xhr.removeEventListener('error', onError);
          xhr.removeEventListener('abort', onError);
          xhr.removeEventListener('load', onLoad);
          xhr.removeEventListener('timeout', onError);
          if (req.reportProgress) {
            xhr.removeEventListener('progress', onDownProgress);
            if (reqBody !== null && xhr.upload) {
              xhr.upload.removeEventListener('progress', onUpProgress);
            }
          }
          // Finally, abort the in-flight request.
          if (xhr.readyState !== xhr.DONE) {
            xhr.abort();
          }
        };
      });
    }));
  }
  static {
    this.ɵfac = function HttpXhrBackend_Factory(t) {
      return new (t || HttpXhrBackend)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_8__.XhrFactory));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: HttpXhrBackend,
      factory: HttpXhrBackend.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpXhrBackend, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: _angular_common__WEBPACK_IMPORTED_MODULE_8__.XhrFactory
  }], null);
})();
const XSRF_ENABLED = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'XSRF_ENABLED' : '');
const XSRF_DEFAULT_COOKIE_NAME = 'XSRF-TOKEN';
const XSRF_COOKIE_NAME = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'XSRF_COOKIE_NAME' : '', {
  providedIn: 'root',
  factory: () => XSRF_DEFAULT_COOKIE_NAME
});
const XSRF_DEFAULT_HEADER_NAME = 'X-XSRF-TOKEN';
const XSRF_HEADER_NAME = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'XSRF_HEADER_NAME' : '', {
  providedIn: 'root',
  factory: () => XSRF_DEFAULT_HEADER_NAME
});
/**
 * Retrieves the current XSRF token to use with the next outgoing request.
 *
 * @publicApi
 */
class HttpXsrfTokenExtractor {}
/**
 * `HttpXsrfTokenExtractor` which retrieves the token from a cookie.
 */
class HttpXsrfCookieExtractor {
  constructor(doc, platform, cookieName) {
    this.doc = doc;
    this.platform = platform;
    this.cookieName = cookieName;
    this.lastCookieString = '';
    this.lastToken = null;
    /**
     * @internal for testing
     */
    this.parseCount = 0;
  }
  getToken() {
    if (this.platform === 'server') {
      return null;
    }
    const cookieString = this.doc.cookie || '';
    if (cookieString !== this.lastCookieString) {
      this.parseCount++;
      this.lastToken = (0,_angular_common__WEBPACK_IMPORTED_MODULE_8__["ɵparseCookieValue"])(cookieString, this.cookieName);
      this.lastCookieString = cookieString;
    }
    return this.lastToken;
  }
  static {
    this.ɵfac = function HttpXsrfCookieExtractor_Factory(t) {
      return new (t || HttpXsrfCookieExtractor)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_5__.PLATFORM_ID), _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](XSRF_COOKIE_NAME));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: HttpXsrfCookieExtractor,
      factory: HttpXsrfCookieExtractor.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpXsrfCookieExtractor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_5__.PLATFORM_ID]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Inject,
      args: [XSRF_COOKIE_NAME]
    }]
  }], null);
})();
function xsrfInterceptorFn(req, next) {
  const lcUrl = req.url.toLowerCase();
  // Skip both non-mutating requests and absolute URLs.
  // Non-mutating requests don't require a token, and absolute URLs require special handling
  // anyway as the cookie set
  // on our origin is not the same as the token expected by another origin.
  if (!(0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(XSRF_ENABLED) || req.method === 'GET' || req.method === 'HEAD' || lcUrl.startsWith('http://') || lcUrl.startsWith('https://')) {
    return next(req);
  }
  const token = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(HttpXsrfTokenExtractor).getToken();
  const headerName = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(XSRF_HEADER_NAME);
  // Be careful not to overwrite an existing header of the same name.
  if (token != null && !req.headers.has(headerName)) {
    req = req.clone({
      headers: req.headers.set(headerName, token)
    });
  }
  return next(req);
}
/**
 * `HttpInterceptor` which adds an XSRF token to eligible outgoing requests.
 */
class HttpXsrfInterceptor {
  constructor(injector) {
    this.injector = injector;
  }
  intercept(initialRequest, next) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.runInInjectionContext)(this.injector, () => xsrfInterceptorFn(initialRequest, downstreamRequest => next.handle(downstreamRequest)));
  }
  static {
    this.ɵfac = function HttpXsrfInterceptor_Factory(t) {
      return new (t || HttpXsrfInterceptor)(_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjectable"]({
      token: HttpXsrfInterceptor,
      factory: HttpXsrfInterceptor.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpXsrfInterceptor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.Injectable
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.EnvironmentInjector
  }], null);
})();

/**
 * Identifies a particular kind of `HttpFeature`.
 *
 * @publicApi
 */
var HttpFeatureKind;
(function (HttpFeatureKind) {
  HttpFeatureKind[HttpFeatureKind["Interceptors"] = 0] = "Interceptors";
  HttpFeatureKind[HttpFeatureKind["LegacyInterceptors"] = 1] = "LegacyInterceptors";
  HttpFeatureKind[HttpFeatureKind["CustomXsrfConfiguration"] = 2] = "CustomXsrfConfiguration";
  HttpFeatureKind[HttpFeatureKind["NoXsrfProtection"] = 3] = "NoXsrfProtection";
  HttpFeatureKind[HttpFeatureKind["JsonpSupport"] = 4] = "JsonpSupport";
  HttpFeatureKind[HttpFeatureKind["RequestsMadeViaParent"] = 5] = "RequestsMadeViaParent";
  HttpFeatureKind[HttpFeatureKind["Fetch"] = 6] = "Fetch";
})(HttpFeatureKind || (HttpFeatureKind = {}));
function makeHttpFeature(kind, providers) {
  return {
    ɵkind: kind,
    ɵproviders: providers
  };
}
/**
 * Configures Angular's `HttpClient` service to be available for injection.
 *
 * By default, `HttpClient` will be configured for injection with its default options for XSRF
 * protection of outgoing requests. Additional configuration options can be provided by passing
 * feature functions to `provideHttpClient`. For example, HTTP interceptors can be added using the
 * `withInterceptors(...)` feature.
 *
 * <div class="alert is-helpful">
 *
 * It's strongly recommended to enable
 * [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) for applications that use
 * Server-Side Rendering for better performance and compatibility. To enable `fetch`, add
 * `withFetch()` feature to the `provideHttpClient()` call at the root of the application:
 *
 * ```
 * provideHttpClient(withFetch());
 * ```
 *
 * </div>
 *
 * @see {@link withInterceptors}
 * @see {@link withInterceptorsFromDi}
 * @see {@link withXsrfConfiguration}
 * @see {@link withNoXsrfProtection}
 * @see {@link withJsonpSupport}
 * @see {@link withRequestsMadeViaParent}
 * @see {@link withFetch}
 */
function provideHttpClient(...features) {
  if (ngDevMode) {
    const featureKinds = new Set(features.map(f => f.ɵkind));
    if (featureKinds.has(HttpFeatureKind.NoXsrfProtection) && featureKinds.has(HttpFeatureKind.CustomXsrfConfiguration)) {
      throw new Error(ngDevMode ? `Configuration error: found both withXsrfConfiguration() and withNoXsrfProtection() in the same call to provideHttpClient(), which is a contradiction.` : '');
    }
  }
  const providers = [HttpClient, HttpXhrBackend, HttpInterceptorHandler, {
    provide: HttpHandler,
    useExisting: HttpInterceptorHandler
  }, {
    provide: HttpBackend,
    useExisting: HttpXhrBackend
  }, {
    provide: HTTP_INTERCEPTOR_FNS,
    useValue: xsrfInterceptorFn,
    multi: true
  }, {
    provide: XSRF_ENABLED,
    useValue: true
  }, {
    provide: HttpXsrfTokenExtractor,
    useClass: HttpXsrfCookieExtractor
  }];
  for (const feature of features) {
    providers.push(...feature.ɵproviders);
  }
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.makeEnvironmentProviders)(providers);
}
/**
 * Adds one or more functional-style HTTP interceptors to the configuration of the `HttpClient`
 * instance.
 *
 * @see {@link HttpInterceptorFn}
 * @see {@link provideHttpClient}
 * @publicApi
 */
function withInterceptors(interceptorFns) {
  return makeHttpFeature(HttpFeatureKind.Interceptors, interceptorFns.map(interceptorFn => {
    return {
      provide: HTTP_INTERCEPTOR_FNS,
      useValue: interceptorFn,
      multi: true
    };
  }));
}
const LEGACY_INTERCEPTOR_FN = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'LEGACY_INTERCEPTOR_FN' : '');
/**
 * Includes class-based interceptors configured using a multi-provider in the current injector into
 * the configured `HttpClient` instance.
 *
 * Prefer `withInterceptors` and functional interceptors instead, as support for DI-provided
 * interceptors may be phased out in a later release.
 *
 * @see {@link HttpInterceptor}
 * @see {@link HTTP_INTERCEPTORS}
 * @see {@link provideHttpClient}
 */
function withInterceptorsFromDi() {
  // Note: the legacy interceptor function is provided here via an intermediate token
  // (`LEGACY_INTERCEPTOR_FN`), using a pattern which guarantees that if these providers are
  // included multiple times, all of the multi-provider entries will have the same instance of the
  // interceptor function. That way, the `HttpINterceptorHandler` will dedup them and legacy
  // interceptors will not run multiple times.
  return makeHttpFeature(HttpFeatureKind.LegacyInterceptors, [{
    provide: LEGACY_INTERCEPTOR_FN,
    useFactory: legacyInterceptorFnFactory
  }, {
    provide: HTTP_INTERCEPTOR_FNS,
    useExisting: LEGACY_INTERCEPTOR_FN,
    multi: true
  }]);
}
/**
 * Customizes the XSRF protection for the configuration of the current `HttpClient` instance.
 *
 * This feature is incompatible with the `withNoXsrfProtection` feature.
 *
 * @see {@link provideHttpClient}
 */
function withXsrfConfiguration({
  cookieName,
  headerName
}) {
  const providers = [];
  if (cookieName !== undefined) {
    providers.push({
      provide: XSRF_COOKIE_NAME,
      useValue: cookieName
    });
  }
  if (headerName !== undefined) {
    providers.push({
      provide: XSRF_HEADER_NAME,
      useValue: headerName
    });
  }
  return makeHttpFeature(HttpFeatureKind.CustomXsrfConfiguration, providers);
}
/**
 * Disables XSRF protection in the configuration of the current `HttpClient` instance.
 *
 * This feature is incompatible with the `withXsrfConfiguration` feature.
 *
 * @see {@link provideHttpClient}
 */
function withNoXsrfProtection() {
  return makeHttpFeature(HttpFeatureKind.NoXsrfProtection, [{
    provide: XSRF_ENABLED,
    useValue: false
  }]);
}
/**
 * Add JSONP support to the configuration of the current `HttpClient` instance.
 *
 * @see {@link provideHttpClient}
 */
function withJsonpSupport() {
  return makeHttpFeature(HttpFeatureKind.JsonpSupport, [JsonpClientBackend, {
    provide: JsonpCallbackContext,
    useFactory: jsonpCallbackContext
  }, {
    provide: HTTP_INTERCEPTOR_FNS,
    useValue: jsonpInterceptorFn,
    multi: true
  }]);
}
/**
 * Configures the current `HttpClient` instance to make requests via the parent injector's
 * `HttpClient` instead of directly.
 *
 * By default, `provideHttpClient` configures `HttpClient` in its injector to be an independent
 * instance. For example, even if `HttpClient` is configured in the parent injector with
 * one or more interceptors, they will not intercept requests made via this instance.
 *
 * With this option enabled, once the request has passed through the current injector's
 * interceptors, it will be delegated to the parent injector's `HttpClient` chain instead of
 * dispatched directly, and interceptors in the parent configuration will be applied to the request.
 *
 * If there are several `HttpClient` instances in the injector hierarchy, it's possible for
 * `withRequestsMadeViaParent` to be used at multiple levels, which will cause the request to
 * "bubble up" until either reaching the root level or an `HttpClient` which was not configured with
 * this option.
 *
 * @see {@link provideHttpClient}
 * @developerPreview
 */
function withRequestsMadeViaParent() {
  return makeHttpFeature(HttpFeatureKind.RequestsMadeViaParent, [{
    provide: HttpBackend,
    useFactory: () => {
      const handlerFromParent = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(HttpHandler, {
        skipSelf: true,
        optional: true
      });
      if (ngDevMode && handlerFromParent === null) {
        throw new Error('withRequestsMadeViaParent() can only be used when the parent injector also configures HttpClient');
      }
      return handlerFromParent;
    }
  }]);
}
/**
 * Configures the current `HttpClient` instance to make requests using the fetch API.
 *
 * This `FetchBackend` requires the support of the Fetch API which is available on all evergreen
 * browsers and on NodeJS from v18 onward.
 *
 * Note: The Fetch API doesn't support progress report on uploads.
 *
 * @publicApi
 */
function withFetch() {
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && typeof fetch !== 'function') {
    // TODO: Create a runtime error
    // TODO: Use ENVIRONMENT_INITIALIZER to contextualize the error message (browser or server)
    throw new Error('The `withFetch` feature of HttpClient requires the `fetch` API to be available. ' + 'If you run the code in a Node environment, make sure you use Node v18.10 or later.');
  }
  return makeHttpFeature(HttpFeatureKind.Fetch, [FetchBackend, {
    provide: HttpBackend,
    useExisting: FetchBackend
  }, {
    provide: PRIMARY_HTTP_BACKEND,
    useExisting: FetchBackend
  }]);
}

/**
 * Configures XSRF protection support for outgoing requests.
 *
 * For a server that supports a cookie-based XSRF protection system,
 * use directly to configure XSRF protection with the correct
 * cookie and header names.
 *
 * If no names are supplied, the default cookie name is `XSRF-TOKEN`
 * and the default header name is `X-XSRF-TOKEN`.
 *
 * @publicApi
 */
class HttpClientXsrfModule {
  /**
   * Disable the default XSRF protection.
   */
  static disable() {
    return {
      ngModule: HttpClientXsrfModule,
      providers: [withNoXsrfProtection().ɵproviders]
    };
  }
  /**
   * Configure XSRF protection.
   * @param options An object that can specify either or both
   * cookie name or header name.
   * - Cookie name default is `XSRF-TOKEN`.
   * - Header name default is `X-XSRF-TOKEN`.
   *
   */
  static withOptions(options = {}) {
    return {
      ngModule: HttpClientXsrfModule,
      providers: withXsrfConfiguration(options).ɵproviders
    };
  }
  static {
    this.ɵfac = function HttpClientXsrfModule_Factory(t) {
      return new (t || HttpClientXsrfModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineNgModule"]({
      type: HttpClientXsrfModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjector"]({
      providers: [HttpXsrfInterceptor, {
        provide: HTTP_INTERCEPTORS,
        useExisting: HttpXsrfInterceptor,
        multi: true
      }, {
        provide: HttpXsrfTokenExtractor,
        useClass: HttpXsrfCookieExtractor
      }, withXsrfConfiguration({
        cookieName: XSRF_DEFAULT_COOKIE_NAME,
        headerName: XSRF_DEFAULT_HEADER_NAME
      }).ɵproviders, {
        provide: XSRF_ENABLED,
        useValue: true
      }]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpClientXsrfModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.NgModule,
    args: [{
      providers: [HttpXsrfInterceptor, {
        provide: HTTP_INTERCEPTORS,
        useExisting: HttpXsrfInterceptor,
        multi: true
      }, {
        provide: HttpXsrfTokenExtractor,
        useClass: HttpXsrfCookieExtractor
      }, withXsrfConfiguration({
        cookieName: XSRF_DEFAULT_COOKIE_NAME,
        headerName: XSRF_DEFAULT_HEADER_NAME
      }).ɵproviders, {
        provide: XSRF_ENABLED,
        useValue: true
      }]
    }]
  }], null, null);
})();
/**
 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
 * with supporting services for XSRF. Automatically imported by `HttpClientModule`.
 *
 * You can add interceptors to the chain behind `HttpClient` by binding them to the
 * multiprovider for built-in [DI token](guide/glossary#di-token) `HTTP_INTERCEPTORS`.
 *
 * @publicApi
 */
class HttpClientModule {
  static {
    this.ɵfac = function HttpClientModule_Factory(t) {
      return new (t || HttpClientModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineNgModule"]({
      type: HttpClientModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjector"]({
      providers: [provideHttpClient(withInterceptorsFromDi())]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpClientModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.NgModule,
    args: [{
      /**
       * Configures the [dependency injector](guide/glossary#injector) where it is imported
       * with supporting services for HTTP communications.
       */
      providers: [provideHttpClient(withInterceptorsFromDi())]
    }]
  }], null, null);
})();
/**
 * Configures the [dependency injector](guide/glossary#injector) for `HttpClient`
 * with supporting services for JSONP.
 * Without this module, Jsonp requests reach the backend
 * with method JSONP, where they are rejected.
 *
 * @publicApi
 */
class HttpClientJsonpModule {
  static {
    this.ɵfac = function HttpClientJsonpModule_Factory(t) {
      return new (t || HttpClientJsonpModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineNgModule"]({
      type: HttpClientJsonpModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵɵdefineInjector"]({
      providers: [withJsonpSupport().ɵproviders]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵsetClassMetadata"](HttpClientJsonpModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_5__.NgModule,
    args: [{
      providers: [withJsonpSupport().ɵproviders]
    }]
  }], null, null);
})();

/**
 * Keys within cached response data structure.
 */
const BODY = 'b';
const HEADERS = 'h';
const STATUS = 's';
const STATUS_TEXT = 'st';
const URL = 'u';
const RESPONSE_TYPE = 'rt';
const CACHE_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_5__.InjectionToken(ngDevMode ? 'HTTP_TRANSFER_STATE_CACHE_OPTIONS' : '');
/**
 * A list of allowed HTTP methods to cache.
 */
const ALLOWED_METHODS = ['GET', 'HEAD'];
function transferCacheInterceptorFn(req, next) {
  const {
    isCacheActive,
    ...globalOptions
  } = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(CACHE_OPTIONS);
  const {
    transferCache: requestOptions,
    method: requestMethod
  } = req;
  // In the following situations we do not want to cache the request
  if (!isCacheActive ||
  // POST requests are allowed either globally or at request level
  requestMethod === 'POST' && !globalOptions.includePostRequests && !requestOptions || requestMethod !== 'POST' && !ALLOWED_METHODS.includes(requestMethod) || requestOptions === false ||
  //
  globalOptions.filter?.(req) === false) {
    return next(req);
  }
  const transferState = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__.TransferState);
  const storeKey = makeCacheKey(req);
  const response = transferState.get(storeKey, null);
  let headersToInclude = globalOptions.includeHeaders;
  if (typeof requestOptions === 'object' && requestOptions.includeHeaders) {
    // Request-specific config takes precedence over the global config.
    headersToInclude = requestOptions.includeHeaders;
  }
  if (response) {
    const {
      [BODY]: undecodedBody,
      [RESPONSE_TYPE]: responseType,
      [HEADERS]: httpHeaders,
      [STATUS]: status,
      [STATUS_TEXT]: statusText,
      [URL]: url
    } = response;
    // Request found in cache. Respond using it.
    let body = undecodedBody;
    switch (responseType) {
      case 'arraybuffer':
        body = new TextEncoder().encode(undecodedBody).buffer;
        break;
      case 'blob':
        body = new Blob([undecodedBody]);
        break;
    }
    // We want to warn users accessing a header provided from the cache
    // That HttpTransferCache alters the headers
    // The warning will be logged a single time by HttpHeaders instance
    let headers = new HttpHeaders(httpHeaders);
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      // Append extra logic in dev mode to produce a warning when a header
      // that was not transferred to the client is accessed in the code via `get`
      // and `has` calls.
      headers = appendMissingHeadersDetection(req.url, headers, headersToInclude ?? []);
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.of)(new HttpResponse({
      body,
      headers,
      status,
      statusText,
      url
    }));
  }
  const isServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_8__.isPlatformServer)((0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__.PLATFORM_ID));
  // Request not found in cache. Make the request and cache it if on the server.
  return next(req).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.tap)(event => {
    if (event instanceof HttpResponse && isServer) {
      transferState.set(storeKey, {
        [BODY]: event.body,
        [HEADERS]: getFilteredHeaders(event.headers, headersToInclude),
        [STATUS]: event.status,
        [STATUS_TEXT]: event.statusText,
        [URL]: event.url || '',
        [RESPONSE_TYPE]: req.responseType
      });
    }
  }));
}
function getFilteredHeaders(headers, includeHeaders) {
  if (!includeHeaders) {
    return {};
  }
  const headersMap = {};
  for (const key of includeHeaders) {
    const values = headers.getAll(key);
    if (values !== null) {
      headersMap[key] = values;
    }
  }
  return headersMap;
}
function sortAndConcatParams(params) {
  return [...params.keys()].sort().map(k => `${k}=${params.getAll(k)}`).join('&');
}
function makeCacheKey(request) {
  // make the params encoded same as a url so it's easy to identify
  const {
    params,
    method,
    responseType,
    url
  } = request;
  const encodedParams = sortAndConcatParams(params);
  let serializedBody = request.serializeBody();
  if (serializedBody instanceof URLSearchParams) {
    serializedBody = sortAndConcatParams(serializedBody);
  } else if (typeof serializedBody !== 'string') {
    serializedBody = '';
  }
  const key = [method, responseType, url, serializedBody, encodedParams].join('|');
  const hash = generateHash(key);
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.makeStateKey)(hash);
}
/**
 * A method that returns a hash representation of a string using a variant of DJB2 hash
 * algorithm.
 *
 * This is the same hashing logic that is used to generate component ids.
 */
function generateHash(value) {
  let hash = 0;
  for (const char of value) {
    hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;
  }
  // Force positive number hash.
  // 2147483647 = equivalent of Integer.MAX_VALUE.
  hash += 2147483647 + 1;
  return hash.toString();
}
/**
 * Returns the DI providers needed to enable HTTP transfer cache.
 *
 * By default, when using server rendering, requests are performed twice: once on the server and
 * other one on the browser.
 *
 * When these providers are added, requests performed on the server are cached and reused during the
 * bootstrapping of the application in the browser thus avoiding duplicate requests and reducing
 * load time.
 *
 */
function withHttpTransferCache(cacheOptions) {
  return [{
    provide: CACHE_OPTIONS,
    useFactory: () => {
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵperformanceMarkFeature"])('NgHttpTransferCache');
      return {
        isCacheActive: true,
        ...cacheOptions
      };
    }
  }, {
    provide: HTTP_ROOT_INTERCEPTOR_FNS,
    useValue: transferCacheInterceptorFn,
    multi: true,
    deps: [_angular_core__WEBPACK_IMPORTED_MODULE_5__.TransferState, CACHE_OPTIONS]
  }, {
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_5__.APP_BOOTSTRAP_LISTENER,
    multi: true,
    useFactory: () => {
      const appRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_5__.ApplicationRef);
      const cacheState = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__.inject)(CACHE_OPTIONS);
      return () => {
        (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵwhenStable"])(appRef).then(() => {
          cacheState.isCacheActive = false;
        });
      };
    }
  }];
}
/**
 * This function will add a proxy to an HttpHeader to intercept calls to get/has
 * and log a warning if the header entry requested has been removed
 */
function appendMissingHeadersDetection(url, headers, headersToInclude) {
  const warningProduced = new Set();
  return new Proxy(headers, {
    get(target, prop) {
      const value = Reflect.get(target, prop);
      const methods = new Set(['get', 'has', 'getAll']);
      if (typeof value !== 'function' || !methods.has(prop)) {
        return value;
      }
      return headerName => {
        // We log when the key has been removed and a warning hasn't been produced for the header
        const key = (prop + ':' + headerName).toLowerCase(); // e.g. `get:cache-control`
        if (!headersToInclude.includes(headerName) && !warningProduced.has(key)) {
          warningProduced.add(key);
          const truncatedUrl = (0,_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵtruncateMiddle"])(url);
          // TODO: create Error guide for this warning
          console.warn((0,_angular_core__WEBPACK_IMPORTED_MODULE_5__["ɵformatRuntimeError"])(2802 /* RuntimeErrorCode.HEADERS_ALTERED_BY_TRANSFER_CACHE */, `Angular detected that the \`${headerName}\` header is accessed, but the value of the header ` + `was not transferred from the server to the client by the HttpTransferCache. ` + `To include the value of the \`${headerName}\` header for the \`${truncatedUrl}\` request, ` + `use the \`includeHeaders\` list. The \`includeHeaders\` can be defined either ` + `on a request level by adding the \`transferCache\` parameter, or on an application ` + `level by adding the \`httpCacheTransfer.includeHeaders\` argument to the ` + `\`provideClientHydration()\` call. `));
        }
        // invoking the original method
        return value.apply(target, [headerName]);
      };
    }
  });
}

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 41565:
/*!*****************************************************!*\
  !*** ./node_modules/@angular/common/locales/es.mjs ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * @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
 */
// THIS CODE IS GENERATED - DO NOT MODIFY.
const u = undefined;
function plural(val) {
  const n = val,
    i = Math.floor(Math.abs(val)),
    v = val.toString().replace(/^[^.]*\.?/, '').length,
    e = parseInt(val.toString().replace(/^[^e]*(e([-+]?\d+))?/, '$2')) || 0;
  if (n === 1) return 1;
  if (e === 0 && !(i === 0) && i % 1000000 === 0 && v === 0 || !(e >= 0 && e <= 5)) return 4;
  return 5;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (["es", [["a. m.", "p. m."], u, u], u, [["D", "L", "M", "X", "J", "V", "S"], ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], ["DO", "LU", "MA", "MI", "JU", "VI", "SA"]], u, [["E", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sept", "oct", "nov", "dic"], ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]], u, [["a. C.", "d. C."], u, ["antes de Cristo", "después de Cristo"]], 1, [6, 0], ["d/M/yy", "d MMM y", "d 'de' MMMM 'de' y", "EEEE, d 'de' MMMM 'de' y"], ["H:mm", "H:mm:ss", "H:mm:ss z", "H:mm:ss (zzzz)"], ["{1}, {0}", u, u, u], [",", ".", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0 %", "#,##0.00 ¤", "#E0"], "EUR", "€", "euro", {
  "AUD": [u, "$"],
  "BRL": [u, "R$"],
  "BYN": [u, "р."],
  "CAD": [u, "$"],
  "CNY": [u, "¥"],
  "EGP": [],
  "ESP": ["₧"],
  "GBP": [u, "£"],
  "HKD": [u, "$"],
  "ILS": [u, "₪"],
  "INR": [u, "₹"],
  "JPY": [u, "¥"],
  "KRW": [u, "₩"],
  "MXN": [u, "$"],
  "NZD": [u, "$"],
  "PHP": [u, "₱"],
  "RON": [u, "L"],
  "THB": ["฿"],
  "TWD": [u, "NT$"],
  "USD": ["US$", "$"],
  "XAF": [],
  "XCD": [u, "$"],
  "XOF": []
}, "ltr", plural]);

/***/ }),

/***/ 37580:
/*!******************************************************!*\
  !*** ./node_modules/@angular/core/fesm2022/core.mjs ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ANIMATION_MODULE_TYPE: () => (/* binding */ ANIMATION_MODULE_TYPE),
/* harmony export */   APP_BOOTSTRAP_LISTENER: () => (/* binding */ APP_BOOTSTRAP_LISTENER),
/* harmony export */   APP_ID: () => (/* binding */ APP_ID),
/* harmony export */   APP_INITIALIZER: () => (/* binding */ APP_INITIALIZER),
/* harmony export */   AfterRenderPhase: () => (/* binding */ AfterRenderPhase),
/* harmony export */   ApplicationInitStatus: () => (/* binding */ ApplicationInitStatus),
/* harmony export */   ApplicationModule: () => (/* binding */ ApplicationModule),
/* harmony export */   ApplicationRef: () => (/* binding */ ApplicationRef),
/* harmony export */   Attribute: () => (/* binding */ Attribute),
/* harmony export */   COMPILER_OPTIONS: () => (/* binding */ COMPILER_OPTIONS),
/* harmony export */   CSP_NONCE: () => (/* binding */ CSP_NONCE),
/* harmony export */   CUSTOM_ELEMENTS_SCHEMA: () => (/* binding */ CUSTOM_ELEMENTS_SCHEMA),
/* harmony export */   ChangeDetectionStrategy: () => (/* binding */ ChangeDetectionStrategy),
/* harmony export */   ChangeDetectorRef: () => (/* binding */ ChangeDetectorRef),
/* harmony export */   Compiler: () => (/* binding */ Compiler),
/* harmony export */   CompilerFactory: () => (/* binding */ CompilerFactory),
/* harmony export */   Component: () => (/* binding */ Component),
/* harmony export */   ComponentFactory: () => (/* binding */ ComponentFactory$1),
/* harmony export */   ComponentFactoryResolver: () => (/* binding */ ComponentFactoryResolver$1),
/* harmony export */   ComponentRef: () => (/* binding */ ComponentRef$1),
/* harmony export */   ContentChild: () => (/* binding */ ContentChild),
/* harmony export */   ContentChildren: () => (/* binding */ ContentChildren),
/* harmony export */   DEFAULT_CURRENCY_CODE: () => (/* binding */ DEFAULT_CURRENCY_CODE),
/* harmony export */   DebugElement: () => (/* binding */ DebugElement),
/* harmony export */   DebugEventListener: () => (/* binding */ DebugEventListener),
/* harmony export */   DebugNode: () => (/* binding */ DebugNode),
/* harmony export */   DefaultIterableDiffer: () => (/* binding */ DefaultIterableDiffer),
/* harmony export */   DestroyRef: () => (/* binding */ DestroyRef),
/* harmony export */   Directive: () => (/* binding */ Directive),
/* harmony export */   ENVIRONMENT_INITIALIZER: () => (/* binding */ ENVIRONMENT_INITIALIZER),
/* harmony export */   ElementRef: () => (/* binding */ ElementRef),
/* harmony export */   EmbeddedViewRef: () => (/* binding */ EmbeddedViewRef),
/* harmony export */   EnvironmentInjector: () => (/* binding */ EnvironmentInjector),
/* harmony export */   ErrorHandler: () => (/* binding */ ErrorHandler),
/* harmony export */   EventEmitter: () => (/* binding */ EventEmitter),
/* harmony export */   Host: () => (/* binding */ Host),
/* harmony export */   HostAttributeToken: () => (/* binding */ HostAttributeToken),
/* harmony export */   HostBinding: () => (/* binding */ HostBinding),
/* harmony export */   HostListener: () => (/* binding */ HostListener),
/* harmony export */   INJECTOR: () => (/* binding */ INJECTOR$1),
/* harmony export */   Inject: () => (/* binding */ Inject),
/* harmony export */   InjectFlags: () => (/* binding */ InjectFlags),
/* harmony export */   Injectable: () => (/* binding */ Injectable),
/* harmony export */   InjectionToken: () => (/* binding */ InjectionToken),
/* harmony export */   Injector: () => (/* binding */ Injector),
/* harmony export */   Input: () => (/* binding */ Input),
/* harmony export */   IterableDiffers: () => (/* binding */ IterableDiffers),
/* harmony export */   KeyValueDiffers: () => (/* binding */ KeyValueDiffers),
/* harmony export */   LOCALE_ID: () => (/* binding */ LOCALE_ID),
/* harmony export */   MissingTranslationStrategy: () => (/* binding */ MissingTranslationStrategy),
/* harmony export */   ModuleWithComponentFactories: () => (/* binding */ ModuleWithComponentFactories),
/* harmony export */   NO_ERRORS_SCHEMA: () => (/* binding */ NO_ERRORS_SCHEMA),
/* harmony export */   NgModule: () => (/* binding */ NgModule),
/* harmony export */   NgModuleFactory: () => (/* binding */ NgModuleFactory$1),
/* harmony export */   NgModuleRef: () => (/* binding */ NgModuleRef$1),
/* harmony export */   NgProbeToken: () => (/* binding */ NgProbeToken),
/* harmony export */   NgZone: () => (/* binding */ NgZone),
/* harmony export */   Optional: () => (/* binding */ Optional),
/* harmony export */   Output: () => (/* binding */ Output),
/* harmony export */   OutputEmitterRef: () => (/* binding */ OutputEmitterRef),
/* harmony export */   PACKAGE_ROOT_URL: () => (/* binding */ PACKAGE_ROOT_URL),
/* harmony export */   PLATFORM_ID: () => (/* binding */ PLATFORM_ID),
/* harmony export */   PLATFORM_INITIALIZER: () => (/* binding */ PLATFORM_INITIALIZER),
/* harmony export */   Pipe: () => (/* binding */ Pipe),
/* harmony export */   PlatformRef: () => (/* binding */ PlatformRef),
/* harmony export */   Query: () => (/* binding */ Query),
/* harmony export */   QueryList: () => (/* binding */ QueryList),
/* harmony export */   Renderer2: () => (/* binding */ Renderer2),
/* harmony export */   RendererFactory2: () => (/* binding */ RendererFactory2),
/* harmony export */   RendererStyleFlags2: () => (/* binding */ RendererStyleFlags2),
/* harmony export */   Sanitizer: () => (/* binding */ Sanitizer),
/* harmony export */   SecurityContext: () => (/* binding */ SecurityContext),
/* harmony export */   Self: () => (/* binding */ Self),
/* harmony export */   SimpleChange: () => (/* binding */ SimpleChange),
/* harmony export */   SkipSelf: () => (/* binding */ SkipSelf),
/* harmony export */   TRANSLATIONS: () => (/* binding */ TRANSLATIONS),
/* harmony export */   TRANSLATIONS_FORMAT: () => (/* binding */ TRANSLATIONS_FORMAT),
/* harmony export */   TemplateRef: () => (/* binding */ TemplateRef),
/* harmony export */   Testability: () => (/* binding */ Testability),
/* harmony export */   TestabilityRegistry: () => (/* binding */ TestabilityRegistry),
/* harmony export */   TransferState: () => (/* binding */ TransferState),
/* harmony export */   Type: () => (/* binding */ Type),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   Version: () => (/* binding */ Version),
/* harmony export */   ViewChild: () => (/* binding */ ViewChild),
/* harmony export */   ViewChildren: () => (/* binding */ ViewChildren),
/* harmony export */   ViewContainerRef: () => (/* binding */ ViewContainerRef),
/* harmony export */   ViewEncapsulation: () => (/* binding */ ViewEncapsulation$1),
/* harmony export */   ViewRef: () => (/* binding */ ViewRef),
/* harmony export */   afterNextRender: () => (/* binding */ afterNextRender),
/* harmony export */   afterRender: () => (/* binding */ afterRender),
/* harmony export */   asNativeElements: () => (/* binding */ asNativeElements),
/* harmony export */   assertInInjectionContext: () => (/* binding */ assertInInjectionContext),
/* harmony export */   assertNotInReactiveContext: () => (/* binding */ assertNotInReactiveContext),
/* harmony export */   assertPlatform: () => (/* binding */ assertPlatform),
/* harmony export */   booleanAttribute: () => (/* binding */ booleanAttribute),
/* harmony export */   computed: () => (/* binding */ computed),
/* harmony export */   contentChild: () => (/* binding */ contentChild),
/* harmony export */   contentChildren: () => (/* binding */ contentChildren),
/* harmony export */   createComponent: () => (/* binding */ createComponent),
/* harmony export */   createEnvironmentInjector: () => (/* binding */ createEnvironmentInjector),
/* harmony export */   createNgModule: () => (/* binding */ createNgModule),
/* harmony export */   createNgModuleRef: () => (/* binding */ createNgModuleRef),
/* harmony export */   createPlatform: () => (/* binding */ createPlatform),
/* harmony export */   createPlatformFactory: () => (/* binding */ createPlatformFactory),
/* harmony export */   defineInjectable: () => (/* binding */ defineInjectable),
/* harmony export */   destroyPlatform: () => (/* binding */ destroyPlatform),
/* harmony export */   effect: () => (/* binding */ effect),
/* harmony export */   enableProdMode: () => (/* binding */ enableProdMode),
/* harmony export */   forwardRef: () => (/* binding */ forwardRef),
/* harmony export */   getDebugNode: () => (/* binding */ getDebugNode),
/* harmony export */   getModuleFactory: () => (/* binding */ getModuleFactory),
/* harmony export */   getNgModuleById: () => (/* binding */ getNgModuleById),
/* harmony export */   getPlatform: () => (/* binding */ getPlatform),
/* harmony export */   importProvidersFrom: () => (/* binding */ importProvidersFrom),
/* harmony export */   inject: () => (/* binding */ inject),
/* harmony export */   input: () => (/* binding */ input),
/* harmony export */   isDevMode: () => (/* binding */ isDevMode),
/* harmony export */   isSignal: () => (/* binding */ isSignal),
/* harmony export */   isStandalone: () => (/* binding */ isStandalone),
/* harmony export */   makeEnvironmentProviders: () => (/* binding */ makeEnvironmentProviders),
/* harmony export */   makeStateKey: () => (/* binding */ makeStateKey),
/* harmony export */   mergeApplicationConfig: () => (/* binding */ mergeApplicationConfig),
/* harmony export */   model: () => (/* binding */ model),
/* harmony export */   numberAttribute: () => (/* binding */ numberAttribute),
/* harmony export */   output: () => (/* binding */ output),
/* harmony export */   platformCore: () => (/* binding */ platformCore),
/* harmony export */   provideZoneChangeDetection: () => (/* binding */ provideZoneChangeDetection),
/* harmony export */   reflectComponentType: () => (/* binding */ reflectComponentType),
/* harmony export */   resolveForwardRef: () => (/* binding */ resolveForwardRef),
/* harmony export */   runInInjectionContext: () => (/* binding */ runInInjectionContext),
/* harmony export */   setTestabilityGetter: () => (/* binding */ setTestabilityGetter),
/* harmony export */   signal: () => (/* binding */ signal),
/* harmony export */   untracked: () => (/* binding */ untracked),
/* harmony export */   viewChild: () => (/* binding */ viewChild),
/* harmony export */   viewChildren: () => (/* binding */ viewChildren),
/* harmony export */   "ɵALLOW_MULTIPLE_PLATFORMS": () => (/* binding */ ALLOW_MULTIPLE_PLATFORMS),
/* harmony export */   "ɵAfterRenderEventManager": () => (/* binding */ AfterRenderEventManager),
/* harmony export */   "ɵCONTAINER_HEADER_OFFSET": () => (/* binding */ CONTAINER_HEADER_OFFSET),
/* harmony export */   "ɵChangeDetectionScheduler": () => (/* binding */ ChangeDetectionScheduler),
/* harmony export */   "ɵComponentFactory": () => (/* binding */ ComponentFactory$1),
/* harmony export */   "ɵConsole": () => (/* binding */ Console),
/* harmony export */   "ɵDEFAULT_LOCALE_ID": () => (/* binding */ DEFAULT_LOCALE_ID),
/* harmony export */   "ɵDEFER_BLOCK_CONFIG": () => (/* binding */ DEFER_BLOCK_CONFIG),
/* harmony export */   "ɵDEFER_BLOCK_DEPENDENCY_INTERCEPTOR": () => (/* binding */ DEFER_BLOCK_DEPENDENCY_INTERCEPTOR),
/* harmony export */   "ɵDeferBlockBehavior": () => (/* binding */ DeferBlockBehavior),
/* harmony export */   "ɵDeferBlockState": () => (/* binding */ DeferBlockState),
/* harmony export */   "ɵEffectScheduler": () => (/* binding */ EffectScheduler),
/* harmony export */   "ɵIMAGE_CONFIG": () => (/* binding */ IMAGE_CONFIG),
/* harmony export */   "ɵIMAGE_CONFIG_DEFAULTS": () => (/* binding */ IMAGE_CONFIG_DEFAULTS),
/* harmony export */   "ɵINJECTOR_SCOPE": () => (/* binding */ INJECTOR_SCOPE),
/* harmony export */   "ɵINPUT_SIGNAL_BRAND_WRITE_TYPE": () => (/* binding */ ɵINPUT_SIGNAL_BRAND_WRITE_TYPE),
/* harmony export */   "ɵIS_HYDRATION_DOM_REUSE_ENABLED": () => (/* binding */ IS_HYDRATION_DOM_REUSE_ENABLED),
/* harmony export */   "ɵLContext": () => (/* binding */ LContext),
/* harmony export */   "ɵLifecycleHooksFeature": () => (/* binding */ LifecycleHooksFeature),
/* harmony export */   "ɵLocaleDataIndex": () => (/* binding */ LocaleDataIndex),
/* harmony export */   "ɵNG_COMP_DEF": () => (/* binding */ NG_COMP_DEF),
/* harmony export */   "ɵNG_DIR_DEF": () => (/* binding */ NG_DIR_DEF),
/* harmony export */   "ɵNG_ELEMENT_ID": () => (/* binding */ NG_ELEMENT_ID),
/* harmony export */   "ɵNG_INJ_DEF": () => (/* binding */ NG_INJ_DEF),
/* harmony export */   "ɵNG_MOD_DEF": () => (/* binding */ NG_MOD_DEF),
/* harmony export */   "ɵNG_PIPE_DEF": () => (/* binding */ NG_PIPE_DEF),
/* harmony export */   "ɵNG_PROV_DEF": () => (/* binding */ NG_PROV_DEF),
/* harmony export */   "ɵNOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR": () => (/* binding */ NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR),
/* harmony export */   "ɵNO_CHANGE": () => (/* binding */ NO_CHANGE),
/* harmony export */   "ɵNgModuleFactory": () => (/* binding */ NgModuleFactory),
/* harmony export */   "ɵNoopNgZone": () => (/* binding */ NoopNgZone),
/* harmony export */   "ɵPendingTasks": () => (/* binding */ PendingTasks),
/* harmony export */   "ɵReflectionCapabilities": () => (/* binding */ ReflectionCapabilities),
/* harmony export */   "ɵRender3ComponentFactory": () => (/* binding */ ComponentFactory),
/* harmony export */   "ɵRender3ComponentRef": () => (/* binding */ ComponentRef),
/* harmony export */   "ɵRender3NgModuleRef": () => (/* binding */ NgModuleRef),
/* harmony export */   "ɵRuntimeError": () => (/* binding */ RuntimeError),
/* harmony export */   "ɵSSR_CONTENT_INTEGRITY_MARKER": () => (/* binding */ SSR_CONTENT_INTEGRITY_MARKER),
/* harmony export */   "ɵTESTABILITY": () => (/* binding */ TESTABILITY),
/* harmony export */   "ɵTESTABILITY_GETTER": () => (/* binding */ TESTABILITY_GETTER),
/* harmony export */   "ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT": () => (/* binding */ USE_RUNTIME_DEPS_TRACKER_FOR_JIT),
/* harmony export */   "ɵViewRef": () => (/* binding */ ViewRef$1),
/* harmony export */   "ɵXSS_SECURITY_URL": () => (/* binding */ XSS_SECURITY_URL),
/* harmony export */   "ɵ_sanitizeHtml": () => (/* binding */ _sanitizeHtml),
/* harmony export */   "ɵ_sanitizeUrl": () => (/* binding */ _sanitizeUrl),
/* harmony export */   "ɵallowSanitizationBypassAndThrow": () => (/* binding */ allowSanitizationBypassAndThrow),
/* harmony export */   "ɵannotateForHydration": () => (/* binding */ annotateForHydration),
/* harmony export */   "ɵbypassSanitizationTrustHtml": () => (/* binding */ bypassSanitizationTrustHtml),
/* harmony export */   "ɵbypassSanitizationTrustResourceUrl": () => (/* binding */ bypassSanitizationTrustResourceUrl),
/* harmony export */   "ɵbypassSanitizationTrustScript": () => (/* binding */ bypassSanitizationTrustScript),
/* harmony export */   "ɵbypassSanitizationTrustStyle": () => (/* binding */ bypassSanitizationTrustStyle),
/* harmony export */   "ɵbypassSanitizationTrustUrl": () => (/* binding */ bypassSanitizationTrustUrl),
/* harmony export */   "ɵclearResolutionOfComponentResourcesQueue": () => (/* binding */ clearResolutionOfComponentResourcesQueue),
/* harmony export */   "ɵcompileComponent": () => (/* binding */ compileComponent),
/* harmony export */   "ɵcompileDirective": () => (/* binding */ compileDirective),
/* harmony export */   "ɵcompileNgModule": () => (/* binding */ compileNgModule),
/* harmony export */   "ɵcompileNgModuleDefs": () => (/* binding */ compileNgModuleDefs),
/* harmony export */   "ɵcompileNgModuleFactory": () => (/* binding */ compileNgModuleFactory),
/* harmony export */   "ɵcompilePipe": () => (/* binding */ compilePipe),
/* harmony export */   "ɵconvertToBitFlags": () => (/* binding */ convertToBitFlags),
/* harmony export */   "ɵcreateInjector": () => (/* binding */ createInjector),
/* harmony export */   "ɵdefaultIterableDiffers": () => (/* binding */ defaultIterableDiffers),
/* harmony export */   "ɵdefaultKeyValueDiffers": () => (/* binding */ defaultKeyValueDiffers),
/* harmony export */   "ɵdepsTracker": () => (/* binding */ depsTracker),
/* harmony export */   "ɵdetectChangesInViewIfRequired": () => (/* binding */ detectChangesInViewIfRequired),
/* harmony export */   "ɵdevModeEqual": () => (/* binding */ devModeEqual),
/* harmony export */   "ɵfindLocaleData": () => (/* binding */ findLocaleData),
/* harmony export */   "ɵflushModuleScopingQueueAsMuchAsPossible": () => (/* binding */ flushModuleScopingQueueAsMuchAsPossible),
/* harmony export */   "ɵformatRuntimeError": () => (/* binding */ formatRuntimeError),
/* harmony export */   "ɵgenerateStandaloneInDeclarationsError": () => (/* binding */ generateStandaloneInDeclarationsError),
/* harmony export */   "ɵgetAsyncClassMetadataFn": () => (/* binding */ getAsyncClassMetadataFn),
/* harmony export */   "ɵgetDebugNode": () => (/* binding */ getDebugNode),
/* harmony export */   "ɵgetDeferBlocks": () => (/* binding */ getDeferBlocks),
/* harmony export */   "ɵgetDirectives": () => (/* binding */ getDirectives),
/* harmony export */   "ɵgetEnsureDirtyViewsAreAlwaysReachable": () => (/* binding */ getEnsureDirtyViewsAreAlwaysReachable),
/* harmony export */   "ɵgetHostElement": () => (/* binding */ getHostElement),
/* harmony export */   "ɵgetInjectableDef": () => (/* binding */ getInjectableDef),
/* harmony export */   "ɵgetLContext": () => (/* binding */ getLContext),
/* harmony export */   "ɵgetLocaleCurrencyCode": () => (/* binding */ getLocaleCurrencyCode),
/* harmony export */   "ɵgetLocalePluralCase": () => (/* binding */ getLocalePluralCase),
/* harmony export */   "ɵgetOutputDestroyRef": () => (/* binding */ getOutputDestroyRef),
/* harmony export */   "ɵgetSanitizationBypassType": () => (/* binding */ getSanitizationBypassType),
/* harmony export */   "ɵgetUnknownElementStrictMode": () => (/* binding */ ɵgetUnknownElementStrictMode),
/* harmony export */   "ɵgetUnknownPropertyStrictMode": () => (/* binding */ ɵgetUnknownPropertyStrictMode),
/* harmony export */   "ɵglobal": () => (/* binding */ _global),
/* harmony export */   "ɵinjectChangeDetectorRef": () => (/* binding */ injectChangeDetectorRef),
/* harmony export */   "ɵinternalAfterNextRender": () => (/* binding */ internalAfterNextRender),
/* harmony export */   "ɵinternalCreateApplication": () => (/* binding */ internalCreateApplication),
/* harmony export */   "ɵisBoundToModule": () => (/* binding */ isBoundToModule),
/* harmony export */   "ɵisComponentDefPendingResolution": () => (/* binding */ isComponentDefPendingResolution),
/* harmony export */   "ɵisEnvironmentProviders": () => (/* binding */ isEnvironmentProviders),
/* harmony export */   "ɵisInjectable": () => (/* binding */ isInjectable),
/* harmony export */   "ɵisNgModule": () => (/* binding */ isNgModule),
/* harmony export */   "ɵisPromise": () => (/* binding */ isPromise),
/* harmony export */   "ɵisSubscribable": () => (/* binding */ isSubscribable),
/* harmony export */   "ɵnoSideEffects": () => (/* binding */ noSideEffects),
/* harmony export */   "ɵpatchComponentDefWithScope": () => (/* binding */ patchComponentDefWithScope),
/* harmony export */   "ɵperformanceMarkFeature": () => (/* binding */ performanceMarkFeature),
/* harmony export */   "ɵprovideZonelessChangeDetection": () => (/* binding */ provideZonelessChangeDetection),
/* harmony export */   "ɵqueueStateUpdate": () => (/* binding */ queueStateUpdate),
/* harmony export */   "ɵreadHydrationInfo": () => (/* binding */ readHydrationInfo),
/* harmony export */   "ɵregisterLocaleData": () => (/* binding */ registerLocaleData),
/* harmony export */   "ɵrenderDeferBlockState": () => (/* binding */ renderDeferBlockState),
/* harmony export */   "ɵresetCompiledComponents": () => (/* binding */ resetCompiledComponents),
/* harmony export */   "ɵresetJitOptions": () => (/* binding */ resetJitOptions),
/* harmony export */   "ɵresolveComponentResources": () => (/* binding */ resolveComponentResources),
/* harmony export */   "ɵrestoreComponentResolutionQueue": () => (/* binding */ restoreComponentResolutionQueue),
/* harmony export */   "ɵsetAllowDuplicateNgModuleIdsForTest": () => (/* binding */ setAllowDuplicateNgModuleIdsForTest),
/* harmony export */   "ɵsetAlternateWeakRefImpl": () => (/* binding */ setAlternateWeakRefImpl),
/* harmony export */   "ɵsetClassDebugInfo": () => (/* binding */ ɵsetClassDebugInfo),
/* harmony export */   "ɵsetClassMetadata": () => (/* binding */ setClassMetadata),
/* harmony export */   "ɵsetClassMetadataAsync": () => (/* binding */ setClassMetadataAsync),
/* harmony export */   "ɵsetCurrentInjector": () => (/* binding */ setCurrentInjector),
/* harmony export */   "ɵsetDocument": () => (/* binding */ setDocument),
/* harmony export */   "ɵsetEnsureDirtyViewsAreAlwaysReachable": () => (/* binding */ setEnsureDirtyViewsAreAlwaysReachable),
/* harmony export */   "ɵsetInjectorProfilerContext": () => (/* binding */ setInjectorProfilerContext),
/* harmony export */   "ɵsetLocaleId": () => (/* binding */ setLocaleId),
/* harmony export */   "ɵsetUnknownElementStrictMode": () => (/* binding */ ɵsetUnknownElementStrictMode),
/* harmony export */   "ɵsetUnknownPropertyStrictMode": () => (/* binding */ ɵsetUnknownPropertyStrictMode),
/* harmony export */   "ɵstore": () => (/* binding */ store),
/* harmony export */   "ɵstringify": () => (/* binding */ stringify),
/* harmony export */   "ɵtransitiveScopesFor": () => (/* binding */ transitiveScopesFor),
/* harmony export */   "ɵtriggerResourceLoading": () => (/* binding */ triggerResourceLoading),
/* harmony export */   "ɵtruncateMiddle": () => (/* binding */ truncateMiddle),
/* harmony export */   "ɵunregisterLocaleData": () => (/* binding */ unregisterAllLocaleData),
/* harmony export */   "ɵunwrapSafeValue": () => (/* binding */ unwrapSafeValue),
/* harmony export */   "ɵunwrapWritableSignal": () => (/* binding */ ɵunwrapWritableSignal),
/* harmony export */   "ɵwhenStable": () => (/* binding */ whenStable),
/* harmony export */   "ɵwithDomHydration": () => (/* binding */ withDomHydration),
/* harmony export */   "ɵwithI18nHydration": () => (/* binding */ withI18nHydration),
/* harmony export */   "ɵɵCopyDefinitionFeature": () => (/* binding */ ɵɵCopyDefinitionFeature),
/* harmony export */   "ɵɵFactoryTarget": () => (/* binding */ FactoryTarget),
/* harmony export */   "ɵɵHostDirectivesFeature": () => (/* binding */ ɵɵHostDirectivesFeature),
/* harmony export */   "ɵɵInheritDefinitionFeature": () => (/* binding */ ɵɵInheritDefinitionFeature),
/* harmony export */   "ɵɵInputFlags": () => (/* binding */ InputFlags),
/* harmony export */   "ɵɵInputTransformsFeature": () => (/* binding */ ɵɵInputTransformsFeature),
/* harmony export */   "ɵɵNgOnChangesFeature": () => (/* binding */ ɵɵNgOnChangesFeature),
/* harmony export */   "ɵɵProvidersFeature": () => (/* binding */ ɵɵProvidersFeature),
/* harmony export */   "ɵɵStandaloneFeature": () => (/* binding */ ɵɵStandaloneFeature),
/* harmony export */   "ɵɵadvance": () => (/* binding */ ɵɵadvance),
/* harmony export */   "ɵɵattribute": () => (/* binding */ ɵɵattribute),
/* harmony export */   "ɵɵattributeInterpolate1": () => (/* binding */ ɵɵattributeInterpolate1),
/* harmony export */   "ɵɵattributeInterpolate2": () => (/* binding */ ɵɵattributeInterpolate2),
/* harmony export */   "ɵɵattributeInterpolate3": () => (/* binding */ ɵɵattributeInterpolate3),
/* harmony export */   "ɵɵattributeInterpolate4": () => (/* binding */ ɵɵattributeInterpolate4),
/* harmony export */   "ɵɵattributeInterpolate5": () => (/* binding */ ɵɵattributeInterpolate5),
/* harmony export */   "ɵɵattributeInterpolate6": () => (/* binding */ ɵɵattributeInterpolate6),
/* harmony export */   "ɵɵattributeInterpolate7": () => (/* binding */ ɵɵattributeInterpolate7),
/* harmony export */   "ɵɵattributeInterpolate8": () => (/* binding */ ɵɵattributeInterpolate8),
/* harmony export */   "ɵɵattributeInterpolateV": () => (/* binding */ ɵɵattributeInterpolateV),
/* harmony export */   "ɵɵclassMap": () => (/* binding */ ɵɵclassMap),
/* harmony export */   "ɵɵclassMapInterpolate1": () => (/* binding */ ɵɵclassMapInterpolate1),
/* harmony export */   "ɵɵclassMapInterpolate2": () => (/* binding */ ɵɵclassMapInterpolate2),
/* harmony export */   "ɵɵclassMapInterpolate3": () => (/* binding */ ɵɵclassMapInterpolate3),
/* harmony export */   "ɵɵclassMapInterpolate4": () => (/* binding */ ɵɵclassMapInterpolate4),
/* harmony export */   "ɵɵclassMapInterpolate5": () => (/* binding */ ɵɵclassMapInterpolate5),
/* harmony export */   "ɵɵclassMapInterpolate6": () => (/* binding */ ɵɵclassMapInterpolate6),
/* harmony export */   "ɵɵclassMapInterpolate7": () => (/* binding */ ɵɵclassMapInterpolate7),
/* harmony export */   "ɵɵclassMapInterpolate8": () => (/* binding */ ɵɵclassMapInterpolate8),
/* harmony export */   "ɵɵclassMapInterpolateV": () => (/* binding */ ɵɵclassMapInterpolateV),
/* harmony export */   "ɵɵclassProp": () => (/* binding */ ɵɵclassProp),
/* harmony export */   "ɵɵcomponentInstance": () => (/* binding */ ɵɵcomponentInstance),
/* harmony export */   "ɵɵconditional": () => (/* binding */ ɵɵconditional),
/* harmony export */   "ɵɵcontentQuery": () => (/* binding */ ɵɵcontentQuery),
/* harmony export */   "ɵɵcontentQuerySignal": () => (/* binding */ ɵɵcontentQuerySignal),
/* harmony export */   "ɵɵdefer": () => (/* binding */ ɵɵdefer),
/* harmony export */   "ɵɵdeferEnableTimerScheduling": () => (/* binding */ ɵɵdeferEnableTimerScheduling),
/* harmony export */   "ɵɵdeferOnHover": () => (/* binding */ ɵɵdeferOnHover),
/* harmony export */   "ɵɵdeferOnIdle": () => (/* binding */ ɵɵdeferOnIdle),
/* harmony export */   "ɵɵdeferOnImmediate": () => (/* binding */ ɵɵdeferOnImmediate),
/* harmony export */   "ɵɵdeferOnInteraction": () => (/* binding */ ɵɵdeferOnInteraction),
/* harmony export */   "ɵɵdeferOnTimer": () => (/* binding */ ɵɵdeferOnTimer),
/* harmony export */   "ɵɵdeferOnViewport": () => (/* binding */ ɵɵdeferOnViewport),
/* harmony export */   "ɵɵdeferPrefetchOnHover": () => (/* binding */ ɵɵdeferPrefetchOnHover),
/* harmony export */   "ɵɵdeferPrefetchOnIdle": () => (/* binding */ ɵɵdeferPrefetchOnIdle),
/* harmony export */   "ɵɵdeferPrefetchOnImmediate": () => (/* binding */ ɵɵdeferPrefetchOnImmediate),
/* harmony export */   "ɵɵdeferPrefetchOnInteraction": () => (/* binding */ ɵɵdeferPrefetchOnInteraction),
/* harmony export */   "ɵɵdeferPrefetchOnTimer": () => (/* binding */ ɵɵdeferPrefetchOnTimer),
/* harmony export */   "ɵɵdeferPrefetchOnViewport": () => (/* binding */ ɵɵdeferPrefetchOnViewport),
/* harmony export */   "ɵɵdeferPrefetchWhen": () => (/* binding */ ɵɵdeferPrefetchWhen),
/* harmony export */   "ɵɵdeferWhen": () => (/* binding */ ɵɵdeferWhen),
/* harmony export */   "ɵɵdefineComponent": () => (/* binding */ ɵɵdefineComponent),
/* harmony export */   "ɵɵdefineDirective": () => (/* binding */ ɵɵdefineDirective),
/* harmony export */   "ɵɵdefineInjectable": () => (/* binding */ ɵɵdefineInjectable),
/* harmony export */   "ɵɵdefineInjector": () => (/* binding */ ɵɵdefineInjector),
/* harmony export */   "ɵɵdefineNgModule": () => (/* binding */ ɵɵdefineNgModule),
/* harmony export */   "ɵɵdefinePipe": () => (/* binding */ ɵɵdefinePipe),
/* harmony export */   "ɵɵdirectiveInject": () => (/* binding */ ɵɵdirectiveInject),
/* harmony export */   "ɵɵdisableBindings": () => (/* binding */ ɵɵdisableBindings),
/* harmony export */   "ɵɵelement": () => (/* binding */ ɵɵelement),
/* harmony export */   "ɵɵelementContainer": () => (/* binding */ ɵɵelementContainer),
/* harmony export */   "ɵɵelementContainerEnd": () => (/* binding */ ɵɵelementContainerEnd),
/* harmony export */   "ɵɵelementContainerStart": () => (/* binding */ ɵɵelementContainerStart),
/* harmony export */   "ɵɵelementEnd": () => (/* binding */ ɵɵelementEnd),
/* harmony export */   "ɵɵelementStart": () => (/* binding */ ɵɵelementStart),
/* harmony export */   "ɵɵenableBindings": () => (/* binding */ ɵɵenableBindings),
/* harmony export */   "ɵɵgetComponentDepsFactory": () => (/* binding */ ɵɵgetComponentDepsFactory),
/* harmony export */   "ɵɵgetCurrentView": () => (/* binding */ ɵɵgetCurrentView),
/* harmony export */   "ɵɵgetInheritedFactory": () => (/* binding */ ɵɵgetInheritedFactory),
/* harmony export */   "ɵɵhostProperty": () => (/* binding */ ɵɵhostProperty),
/* harmony export */   "ɵɵi18n": () => (/* binding */ ɵɵi18n),
/* harmony export */   "ɵɵi18nApply": () => (/* binding */ ɵɵi18nApply),
/* harmony export */   "ɵɵi18nAttributes": () => (/* binding */ ɵɵi18nAttributes),
/* harmony export */   "ɵɵi18nEnd": () => (/* binding */ ɵɵi18nEnd),
/* harmony export */   "ɵɵi18nExp": () => (/* binding */ ɵɵi18nExp),
/* harmony export */   "ɵɵi18nPostprocess": () => (/* binding */ ɵɵi18nPostprocess),
/* harmony export */   "ɵɵi18nStart": () => (/* binding */ ɵɵi18nStart),
/* harmony export */   "ɵɵinject": () => (/* binding */ ɵɵinject),
/* harmony export */   "ɵɵinjectAttribute": () => (/* binding */ ɵɵinjectAttribute),
/* harmony export */   "ɵɵinvalidFactory": () => (/* binding */ ɵɵinvalidFactory),
/* harmony export */   "ɵɵinvalidFactoryDep": () => (/* binding */ ɵɵinvalidFactoryDep),
/* harmony export */   "ɵɵlistener": () => (/* binding */ ɵɵlistener),
/* harmony export */   "ɵɵloadQuery": () => (/* binding */ ɵɵloadQuery),
/* harmony export */   "ɵɵnamespaceHTML": () => (/* binding */ ɵɵnamespaceHTML),
/* harmony export */   "ɵɵnamespaceMathML": () => (/* binding */ ɵɵnamespaceMathML),
/* harmony export */   "ɵɵnamespaceSVG": () => (/* binding */ ɵɵnamespaceSVG),
/* harmony export */   "ɵɵnextContext": () => (/* binding */ ɵɵnextContext),
/* harmony export */   "ɵɵngDeclareClassMetadata": () => (/* binding */ ɵɵngDeclareClassMetadata),
/* harmony export */   "ɵɵngDeclareComponent": () => (/* binding */ ɵɵngDeclareComponent),
/* harmony export */   "ɵɵngDeclareDirective": () => (/* binding */ ɵɵngDeclareDirective),
/* harmony export */   "ɵɵngDeclareFactory": () => (/* binding */ ɵɵngDeclareFactory),
/* harmony export */   "ɵɵngDeclareInjectable": () => (/* binding */ ɵɵngDeclareInjectable),
/* harmony export */   "ɵɵngDeclareInjector": () => (/* binding */ ɵɵngDeclareInjector),
/* harmony export */   "ɵɵngDeclareNgModule": () => (/* binding */ ɵɵngDeclareNgModule),
/* harmony export */   "ɵɵngDeclarePipe": () => (/* binding */ ɵɵngDeclarePipe),
/* harmony export */   "ɵɵpipe": () => (/* binding */ ɵɵpipe),
/* harmony export */   "ɵɵpipeBind1": () => (/* binding */ ɵɵpipeBind1),
/* harmony export */   "ɵɵpipeBind2": () => (/* binding */ ɵɵpipeBind2),
/* harmony export */   "ɵɵpipeBind3": () => (/* binding */ ɵɵpipeBind3),
/* harmony export */   "ɵɵpipeBind4": () => (/* binding */ ɵɵpipeBind4),
/* harmony export */   "ɵɵpipeBindV": () => (/* binding */ ɵɵpipeBindV),
/* harmony export */   "ɵɵprojection": () => (/* binding */ ɵɵprojection),
/* harmony export */   "ɵɵprojectionDef": () => (/* binding */ ɵɵprojectionDef),
/* harmony export */   "ɵɵproperty": () => (/* binding */ ɵɵproperty),
/* harmony export */   "ɵɵpropertyInterpolate": () => (/* binding */ ɵɵpropertyInterpolate),
/* harmony export */   "ɵɵpropertyInterpolate1": () => (/* binding */ ɵɵpropertyInterpolate1),
/* harmony export */   "ɵɵpropertyInterpolate2": () => (/* binding */ ɵɵpropertyInterpolate2),
/* harmony export */   "ɵɵpropertyInterpolate3": () => (/* binding */ ɵɵpropertyInterpolate3),
/* harmony export */   "ɵɵpropertyInterpolate4": () => (/* binding */ ɵɵpropertyInterpolate4),
/* harmony export */   "ɵɵpropertyInterpolate5": () => (/* binding */ ɵɵpropertyInterpolate5),
/* harmony export */   "ɵɵpropertyInterpolate6": () => (/* binding */ ɵɵpropertyInterpolate6),
/* harmony export */   "ɵɵpropertyInterpolate7": () => (/* binding */ ɵɵpropertyInterpolate7),
/* harmony export */   "ɵɵpropertyInterpolate8": () => (/* binding */ ɵɵpropertyInterpolate8),
/* harmony export */   "ɵɵpropertyInterpolateV": () => (/* binding */ ɵɵpropertyInterpolateV),
/* harmony export */   "ɵɵpureFunction0": () => (/* binding */ ɵɵpureFunction0),
/* harmony export */   "ɵɵpureFunction1": () => (/* binding */ ɵɵpureFunction1),
/* harmony export */   "ɵɵpureFunction2": () => (/* binding */ ɵɵpureFunction2),
/* harmony export */   "ɵɵpureFunction3": () => (/* binding */ ɵɵpureFunction3),
/* harmony export */   "ɵɵpureFunction4": () => (/* binding */ ɵɵpureFunction4),
/* harmony export */   "ɵɵpureFunction5": () => (/* binding */ ɵɵpureFunction5),
/* harmony export */   "ɵɵpureFunction6": () => (/* binding */ ɵɵpureFunction6),
/* harmony export */   "ɵɵpureFunction7": () => (/* binding */ ɵɵpureFunction7),
/* harmony export */   "ɵɵpureFunction8": () => (/* binding */ ɵɵpureFunction8),
/* harmony export */   "ɵɵpureFunctionV": () => (/* binding */ ɵɵpureFunctionV),
/* harmony export */   "ɵɵqueryAdvance": () => (/* binding */ ɵɵqueryAdvance),
/* harmony export */   "ɵɵqueryRefresh": () => (/* binding */ ɵɵqueryRefresh),
/* harmony export */   "ɵɵreference": () => (/* binding */ ɵɵreference),
/* harmony export */   "ɵɵregisterNgModuleType": () => (/* binding */ registerNgModuleType),
/* harmony export */   "ɵɵrepeater": () => (/* binding */ ɵɵrepeater),
/* harmony export */   "ɵɵrepeaterCreate": () => (/* binding */ ɵɵrepeaterCreate),
/* harmony export */   "ɵɵrepeaterTrackByIdentity": () => (/* binding */ ɵɵrepeaterTrackByIdentity),
/* harmony export */   "ɵɵrepeaterTrackByIndex": () => (/* binding */ ɵɵrepeaterTrackByIndex),
/* harmony export */   "ɵɵresetView": () => (/* binding */ ɵɵresetView),
/* harmony export */   "ɵɵresolveBody": () => (/* binding */ ɵɵresolveBody),
/* harmony export */   "ɵɵresolveDocument": () => (/* binding */ ɵɵresolveDocument),
/* harmony export */   "ɵɵresolveWindow": () => (/* binding */ ɵɵresolveWindow),
/* harmony export */   "ɵɵrestoreView": () => (/* binding */ ɵɵrestoreView),
/* harmony export */   "ɵɵsanitizeHtml": () => (/* binding */ ɵɵsanitizeHtml),
/* harmony export */   "ɵɵsanitizeResourceUrl": () => (/* binding */ ɵɵsanitizeResourceUrl),
/* harmony export */   "ɵɵsanitizeScript": () => (/* binding */ ɵɵsanitizeScript),
/* harmony export */   "ɵɵsanitizeStyle": () => (/* binding */ ɵɵsanitizeStyle),
/* harmony export */   "ɵɵsanitizeUrl": () => (/* binding */ ɵɵsanitizeUrl),
/* harmony export */   "ɵɵsanitizeUrlOrResourceUrl": () => (/* binding */ ɵɵsanitizeUrlOrResourceUrl),
/* harmony export */   "ɵɵsetComponentScope": () => (/* binding */ ɵɵsetComponentScope),
/* harmony export */   "ɵɵsetNgModuleScope": () => (/* binding */ ɵɵsetNgModuleScope),
/* harmony export */   "ɵɵstyleMap": () => (/* binding */ ɵɵstyleMap),
/* harmony export */   "ɵɵstyleMapInterpolate1": () => (/* binding */ ɵɵstyleMapInterpolate1),
/* harmony export */   "ɵɵstyleMapInterpolate2": () => (/* binding */ ɵɵstyleMapInterpolate2),
/* harmony export */   "ɵɵstyleMapInterpolate3": () => (/* binding */ ɵɵstyleMapInterpolate3),
/* harmony export */   "ɵɵstyleMapInterpolate4": () => (/* binding */ ɵɵstyleMapInterpolate4),
/* harmony export */   "ɵɵstyleMapInterpolate5": () => (/* binding */ ɵɵstyleMapInterpolate5),
/* harmony export */   "ɵɵstyleMapInterpolate6": () => (/* binding */ ɵɵstyleMapInterpolate6),
/* harmony export */   "ɵɵstyleMapInterpolate7": () => (/* binding */ ɵɵstyleMapInterpolate7),
/* harmony export */   "ɵɵstyleMapInterpolate8": () => (/* binding */ ɵɵstyleMapInterpolate8),
/* harmony export */   "ɵɵstyleMapInterpolateV": () => (/* binding */ ɵɵstyleMapInterpolateV),
/* harmony export */   "ɵɵstyleProp": () => (/* binding */ ɵɵstyleProp),
/* harmony export */   "ɵɵstylePropInterpolate1": () => (/* binding */ ɵɵstylePropInterpolate1),
/* harmony export */   "ɵɵstylePropInterpolate2": () => (/* binding */ ɵɵstylePropInterpolate2),
/* harmony export */   "ɵɵstylePropInterpolate3": () => (/* binding */ ɵɵstylePropInterpolate3),
/* harmony export */   "ɵɵstylePropInterpolate4": () => (/* binding */ ɵɵstylePropInterpolate4),
/* harmony export */   "ɵɵstylePropInterpolate5": () => (/* binding */ ɵɵstylePropInterpolate5),
/* harmony export */   "ɵɵstylePropInterpolate6": () => (/* binding */ ɵɵstylePropInterpolate6),
/* harmony export */   "ɵɵstylePropInterpolate7": () => (/* binding */ ɵɵstylePropInterpolate7),
/* harmony export */   "ɵɵstylePropInterpolate8": () => (/* binding */ ɵɵstylePropInterpolate8),
/* harmony export */   "ɵɵstylePropInterpolateV": () => (/* binding */ ɵɵstylePropInterpolateV),
/* harmony export */   "ɵɵsyntheticHostListener": () => (/* binding */ ɵɵsyntheticHostListener),
/* harmony export */   "ɵɵsyntheticHostProperty": () => (/* binding */ ɵɵsyntheticHostProperty),
/* harmony export */   "ɵɵtemplate": () => (/* binding */ ɵɵtemplate),
/* harmony export */   "ɵɵtemplateRefExtractor": () => (/* binding */ ɵɵtemplateRefExtractor),
/* harmony export */   "ɵɵtext": () => (/* binding */ ɵɵtext),
/* harmony export */   "ɵɵtextInterpolate": () => (/* binding */ ɵɵtextInterpolate),
/* harmony export */   "ɵɵtextInterpolate1": () => (/* binding */ ɵɵtextInterpolate1),
/* harmony export */   "ɵɵtextInterpolate2": () => (/* binding */ ɵɵtextInterpolate2),
/* harmony export */   "ɵɵtextInterpolate3": () => (/* binding */ ɵɵtextInterpolate3),
/* harmony export */   "ɵɵtextInterpolate4": () => (/* binding */ ɵɵtextInterpolate4),
/* harmony export */   "ɵɵtextInterpolate5": () => (/* binding */ ɵɵtextInterpolate5),
/* harmony export */   "ɵɵtextInterpolate6": () => (/* binding */ ɵɵtextInterpolate6),
/* harmony export */   "ɵɵtextInterpolate7": () => (/* binding */ ɵɵtextInterpolate7),
/* harmony export */   "ɵɵtextInterpolate8": () => (/* binding */ ɵɵtextInterpolate8),
/* harmony export */   "ɵɵtextInterpolateV": () => (/* binding */ ɵɵtextInterpolateV),
/* harmony export */   "ɵɵtrustConstantHtml": () => (/* binding */ ɵɵtrustConstantHtml),
/* harmony export */   "ɵɵtrustConstantResourceUrl": () => (/* binding */ ɵɵtrustConstantResourceUrl),
/* harmony export */   "ɵɵtwoWayBindingSet": () => (/* binding */ ɵɵtwoWayBindingSet),
/* harmony export */   "ɵɵtwoWayListener": () => (/* binding */ ɵɵtwoWayListener),
/* harmony export */   "ɵɵtwoWayProperty": () => (/* binding */ ɵɵtwoWayProperty),
/* harmony export */   "ɵɵvalidateIframeAttribute": () => (/* binding */ ɵɵvalidateIframeAttribute),
/* harmony export */   "ɵɵviewQuery": () => (/* binding */ ɵɵviewQuery),
/* harmony export */   "ɵɵviewQuerySignal": () => (/* binding */ ɵɵviewQuerySignal)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core/primitives/signals */ 85689);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 2510);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 2435);

/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */





/**
 * Base URL for the error details page.
 *
 * Keep this constant in sync across:
 *  - packages/compiler-cli/src/ngtsc/diagnostics/src/error_details_base_url.ts
 *  - packages/core/src/error_details_base_url.ts
 */
const ERROR_DETAILS_PAGE_BASE_URL = 'https://angular.io/errors';
/**
 * URL for the XSS security documentation.
 */
const XSS_SECURITY_URL = 'https://g.co/ng/security#xss';

/**
 * Class that represents a runtime error.
 * Formats and outputs the error message in a consistent way.
 *
 * Example:
 * ```
 *  throw new RuntimeError(
 *    RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED,
 *    ngDevMode && 'Injector has already been destroyed.');
 * ```
 *
 * Note: the `message` argument contains a descriptive error message as a string in development
 * mode (when the `ngDevMode` is defined). In production mode (after tree-shaking pass), the
 * `message` argument becomes `false`, thus we account for it in the typings and the runtime
 * logic.
 */
class RuntimeError extends Error {
  constructor(code, message) {
    super(formatRuntimeError(code, message));
    this.code = code;
  }
}
/**
 * Called to format a runtime error.
 * See additional info on the `message` argument type in the `RuntimeError` class description.
 */
function formatRuntimeError(code, message) {
  // Error code might be a negative number, which is a special marker that instructs the logic to
  // generate a link to the error details page on angular.io.
  // We also prepend `0` to non-compile-time errors.
  const fullCode = `NG0${Math.abs(code)}`;
  let errorMessage = `${fullCode}${message ? ': ' + message : ''}`;
  if (ngDevMode && code < 0) {
    const addPeriodSeparator = !errorMessage.match(/[.,;!?\n]$/);
    const separator = addPeriodSeparator ? '.' : '';
    errorMessage = `${errorMessage}${separator} Find more at ${ERROR_DETAILS_PAGE_BASE_URL}/${fullCode}`;
  }
  return errorMessage;
}
const REQUIRED_UNSET_VALUE = /* @__PURE__ */Symbol('InputSignalNode#UNSET');
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const INPUT_SIGNAL_NODE = /* @__PURE__ */(() => {
  return {
    ..._angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL_NODE,
    transformFn: undefined,
    applyValueToInputSignal(node, value) {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.signalSetFn)(node, value);
    }
  };
})();
const ɵINPUT_SIGNAL_BRAND_READ_TYPE = /* @__PURE__ */Symbol();
const ɵINPUT_SIGNAL_BRAND_WRITE_TYPE = /* @__PURE__ */Symbol();
/**
 * Creates an input signal.
 *
 * @param initialValue The initial value.
 *   Can be set to {@link REQUIRED_UNSET_VALUE} for required inputs.
 * @param options Additional options for the input. e.g. a transform, or an alias.
 */
function createInputSignal(initialValue, options) {
  const node = Object.create(INPUT_SIGNAL_NODE);
  node.value = initialValue;
  // Perf note: Always set `transformFn` here to ensure that `node` always
  // has the same v8 class shape, allowing monomorphic reads on input signals.
  node.transformFn = options?.transform;
  function inputValueFn() {
    // Record that someone looked at this signal.
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.producerAccessed)(node);
    if (node.value === REQUIRED_UNSET_VALUE) {
      throw new RuntimeError(-950 /* RuntimeErrorCode.REQUIRED_INPUT_NO_VALUE */, ngDevMode && 'Input is required but no value is available yet.');
    }
    return node.value;
  }
  inputValueFn[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL] = node;
  if (ngDevMode) {
    inputValueFn.toString = () => `[Input Signal: ${inputValueFn()}]`;
  }
  return inputValueFn;
}

/**
 * Convince closure compiler that the wrapped function has no side-effects.
 *
 * Closure compiler always assumes that `toString` has no side-effects. We use this quirk to
 * allow us to execute a function but have closure compiler mark the call as no-side-effects.
 * It is important that the return value for the `noSideEffects` function be assigned
 * to something which is retained otherwise the call to `noSideEffects` will be removed by closure
 * compiler.
 */
function noSideEffects(fn) {
  return {
    toString: fn
  }.toString();
}
const ANNOTATIONS = '__annotations__';
const PARAMETERS = '__parameters__';
const PROP_METADATA = '__prop__metadata__';
/**
 * @suppress {globalThis}
 */
function makeDecorator(name, props, parentClass, additionalProcessing, typeFn) {
  return noSideEffects(() => {
    const metaCtor = makeMetadataCtor(props);
    function DecoratorFactory(...args) {
      if (this instanceof DecoratorFactory) {
        metaCtor.call(this, ...args);
        return this;
      }
      const annotationInstance = new DecoratorFactory(...args);
      return function TypeDecorator(cls) {
        if (typeFn) typeFn(cls, ...args);
        // Use of Object.defineProperty is important since it creates non-enumerable property which
        // prevents the property is copied during subclassing.
        const annotations = cls.hasOwnProperty(ANNOTATIONS) ? cls[ANNOTATIONS] : Object.defineProperty(cls, ANNOTATIONS, {
          value: []
        })[ANNOTATIONS];
        annotations.push(annotationInstance);
        if (additionalProcessing) additionalProcessing(cls);
        return cls;
      };
    }
    if (parentClass) {
      DecoratorFactory.prototype = Object.create(parentClass.prototype);
    }
    DecoratorFactory.prototype.ngMetadataName = name;
    DecoratorFactory.annotationCls = DecoratorFactory;
    return DecoratorFactory;
  });
}
function makeMetadataCtor(props) {
  return function ctor(...args) {
    if (props) {
      const values = props(...args);
      for (const propName in values) {
        this[propName] = values[propName];
      }
    }
  };
}
function makeParamDecorator(name, props, parentClass) {
  return noSideEffects(() => {
    const metaCtor = makeMetadataCtor(props);
    function ParamDecoratorFactory(...args) {
      if (this instanceof ParamDecoratorFactory) {
        metaCtor.apply(this, args);
        return this;
      }
      const annotationInstance = new ParamDecoratorFactory(...args);
      ParamDecorator.annotation = annotationInstance;
      return ParamDecorator;
      function ParamDecorator(cls, unusedKey, index) {
        // Use of Object.defineProperty is important since it creates non-enumerable property which
        // prevents the property is copied during subclassing.
        const parameters = cls.hasOwnProperty(PARAMETERS) ? cls[PARAMETERS] : Object.defineProperty(cls, PARAMETERS, {
          value: []
        })[PARAMETERS];
        // there might be gaps if some in between parameters do not have annotations.
        // we pad with nulls.
        while (parameters.length <= index) {
          parameters.push(null);
        }
        (parameters[index] = parameters[index] || []).push(annotationInstance);
        return cls;
      }
    }
    if (parentClass) {
      ParamDecoratorFactory.prototype = Object.create(parentClass.prototype);
    }
    ParamDecoratorFactory.prototype.ngMetadataName = name;
    ParamDecoratorFactory.annotationCls = ParamDecoratorFactory;
    return ParamDecoratorFactory;
  });
}
function makePropDecorator(name, props, parentClass, additionalProcessing) {
  return noSideEffects(() => {
    const metaCtor = makeMetadataCtor(props);
    function PropDecoratorFactory(...args) {
      if (this instanceof PropDecoratorFactory) {
        metaCtor.apply(this, args);
        return this;
      }
      const decoratorInstance = new PropDecoratorFactory(...args);
      function PropDecorator(target, name) {
        // target is undefined with standard decorators. This case is not supported and will throw
        // if this decorator is used in JIT mode with standard decorators.
        if (target === undefined) {
          throw new Error('Standard Angular field decorators are not supported in JIT mode.');
        }
        const constructor = target.constructor;
        // Use of Object.defineProperty is important because it creates a non-enumerable property
        // which prevents the property from being copied during subclassing.
        const meta = constructor.hasOwnProperty(PROP_METADATA) ? constructor[PROP_METADATA] : Object.defineProperty(constructor, PROP_METADATA, {
          value: {}
        })[PROP_METADATA];
        meta[name] = meta.hasOwnProperty(name) && meta[name] || [];
        meta[name].unshift(decoratorInstance);
        if (additionalProcessing) additionalProcessing(target, name, ...args);
      }
      return PropDecorator;
    }
    if (parentClass) {
      PropDecoratorFactory.prototype = Object.create(parentClass.prototype);
    }
    PropDecoratorFactory.prototype.ngMetadataName = name;
    PropDecoratorFactory.annotationCls = PropDecoratorFactory;
    return PropDecoratorFactory;
  });
}
const _global = globalThis;
function ngDevModeResetPerfCounters() {
  const locationString = typeof location !== 'undefined' ? location.toString() : '';
  const newCounters = {
    namedConstructors: locationString.indexOf('ngDevMode=namedConstructors') != -1,
    firstCreatePass: 0,
    tNode: 0,
    tView: 0,
    rendererCreateTextNode: 0,
    rendererSetText: 0,
    rendererCreateElement: 0,
    rendererAddEventListener: 0,
    rendererSetAttribute: 0,
    rendererRemoveAttribute: 0,
    rendererSetProperty: 0,
    rendererSetClassName: 0,
    rendererAddClass: 0,
    rendererRemoveClass: 0,
    rendererSetStyle: 0,
    rendererRemoveStyle: 0,
    rendererDestroy: 0,
    rendererDestroyNode: 0,
    rendererMoveNode: 0,
    rendererRemoveNode: 0,
    rendererAppendChild: 0,
    rendererInsertBefore: 0,
    rendererCreateComment: 0,
    hydratedNodes: 0,
    hydratedComponents: 0,
    dehydratedViewsRemoved: 0,
    dehydratedViewsCleanupRuns: 0,
    componentsSkippedHydration: 0
  };
  // Make sure to refer to ngDevMode as ['ngDevMode'] for closure.
  const allowNgDevModeTrue = locationString.indexOf('ngDevMode=false') === -1;
  if (!allowNgDevModeTrue) {
    _global['ngDevMode'] = false;
  } else {
    if (typeof _global['ngDevMode'] !== 'object') {
      _global['ngDevMode'] = {};
    }
    Object.assign(_global['ngDevMode'], newCounters);
  }
  return newCounters;
}
/**
 * This function checks to see if the `ngDevMode` has been set. If yes,
 * then we honor it, otherwise we default to dev mode with additional checks.
 *
 * The idea is that unless we are doing production build where we explicitly
 * set `ngDevMode == false` we should be helping the developer by providing
 * as much early warning and errors as possible.
 *
 * `ɵɵdefineComponent` is guaranteed to have been called before any component template functions
 * (and thus Ivy instructions), so a single initialization there is sufficient to ensure ngDevMode
 * is defined for the entire instruction set.
 *
 * When checking `ngDevMode` on toplevel, always init it before referencing it
 * (e.g. `((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode())`), otherwise you can
 *  get a `ReferenceError` like in https://github.com/angular/angular/issues/31595.
 *
 * Details on possible values for `ngDevMode` can be found on its docstring.
 *
 * NOTE:
 * - changes to the `ngDevMode` name must be synced with `compiler-cli/src/tooling.ts`.
 */
function initNgDevMode() {
  // The below checks are to ensure that calling `initNgDevMode` multiple times does not
  // reset the counters.
  // If the `ngDevMode` is not an object, then it means we have not created the perf counters
  // yet.
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    if (typeof ngDevMode !== 'object' || Object.keys(ngDevMode).length === 0) {
      ngDevModeResetPerfCounters();
    }
    return typeof ngDevMode !== 'undefined' && !!ngDevMode;
  }
  return false;
}
function getClosureSafeProperty(objWithPropertyToExtract) {
  for (let key in objWithPropertyToExtract) {
    if (objWithPropertyToExtract[key] === getClosureSafeProperty) {
      return key;
    }
  }
  throw Error('Could not find renamed property on target object.');
}
/**
 * Sets properties on a target object from a source object, but only if
 * the property doesn't already exist on the target object.
 * @param target The target to set properties on
 * @param source The source of the property keys and values to set
 */
function fillProperties(target, source) {
  for (const key in source) {
    if (source.hasOwnProperty(key) && !target.hasOwnProperty(key)) {
      target[key] = source[key];
    }
  }
}
function stringify(token) {
  if (typeof token === 'string') {
    return token;
  }
  if (Array.isArray(token)) {
    return '[' + token.map(stringify).join(', ') + ']';
  }
  if (token == null) {
    return '' + token;
  }
  if (token.overriddenName) {
    return `${token.overriddenName}`;
  }
  if (token.name) {
    return `${token.name}`;
  }
  const res = token.toString();
  if (res == null) {
    return '' + res;
  }
  const newLineIndex = res.indexOf('\n');
  return newLineIndex === -1 ? res : res.substring(0, newLineIndex);
}
/**
 * Concatenates two strings with separator, allocating new strings only when necessary.
 *
 * @param before before string.
 * @param separator separator string.
 * @param after after string.
 * @returns concatenated string.
 */
function concatStringsWithSpace(before, after) {
  return before == null || before === '' ? after === null ? '' : after : after == null || after === '' ? before : before + ' ' + after;
}
/**
 * Ellipses the string in the middle when longer than the max length
 *
 * @param string
 * @param maxLength of the output string
 * @returns ellipsed string with ... in the middle
 */
function truncateMiddle(str, maxLength = 100) {
  if (!str || maxLength < 1 || str.length <= maxLength) return str;
  if (maxLength == 1) return str.substring(0, 1) + '...';
  const halfLimit = Math.round(maxLength / 2);
  return str.substring(0, halfLimit) + '...' + str.substring(str.length - halfLimit);
}
const __forward_ref__ = getClosureSafeProperty({
  __forward_ref__: getClosureSafeProperty
});
/**
 * Allows to refer to references which are not yet defined.
 *
 * For instance, `forwardRef` is used when the `token` which we need to refer to for the purposes of
 * DI is declared, but not yet defined. It is also used when the `token` which we use when creating
 * a query is not yet defined.
 *
 * `forwardRef` is also used to break circularities in standalone components imports.
 *
 * @usageNotes
 * ### Circular dependency example
 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='forward_ref'}
 *
 * ### Circular standalone reference import example
 * ```ts
 * @Component({
 *   standalone: true,
 *   imports: [ChildComponent],
 *   selector: 'app-parent',
 *   template: `<app-child [hideParent]="hideParent"></app-child>`,
 * })
 * export class ParentComponent {
 *   @Input() hideParent: boolean;
 * }
 *
 *
 * @Component({
 *   standalone: true,
 *   imports: [CommonModule, forwardRef(() => ParentComponent)],
 *   selector: 'app-child',
 *   template: `<app-parent *ngIf="!hideParent"></app-parent>`,
 * })
 * export class ChildComponent {
 *   @Input() hideParent: boolean;
 * }
 * ```
 *
 * @publicApi
 */
function forwardRef(forwardRefFn) {
  forwardRefFn.__forward_ref__ = forwardRef;
  forwardRefFn.toString = function () {
    return stringify(this());
  };
  return forwardRefFn;
}
/**
 * Lazily retrieves the reference value from a forwardRef.
 *
 * Acts as the identity function when given a non-forward-ref value.
 *
 * @usageNotes
 * ### Example
 *
 * {@example core/di/ts/forward_ref/forward_ref_spec.ts region='resolve_forward_ref'}
 *
 * @see {@link forwardRef}
 * @publicApi
 */
function resolveForwardRef(type) {
  return isForwardRef(type) ? type() : type;
}
/** Checks whether a function is wrapped by a `forwardRef`. */
function isForwardRef(fn) {
  return typeof fn === 'function' && fn.hasOwnProperty(__forward_ref__) && fn.__forward_ref__ === forwardRef;
}

// The functions in this file verify that the assumptions we are making
function assertNumber(actual, msg) {
  if (!(typeof actual === 'number')) {
    throwError(msg, typeof actual, 'number', '===');
  }
}
function assertNumberInRange(actual, minInclusive, maxInclusive) {
  assertNumber(actual, 'Expected a number');
  assertLessThanOrEqual(actual, maxInclusive, 'Expected number to be less than or equal to');
  assertGreaterThanOrEqual(actual, minInclusive, 'Expected number to be greater than or equal to');
}
function assertString(actual, msg) {
  if (!(typeof actual === 'string')) {
    throwError(msg, actual === null ? 'null' : typeof actual, 'string', '===');
  }
}
function assertFunction(actual, msg) {
  if (!(typeof actual === 'function')) {
    throwError(msg, actual === null ? 'null' : typeof actual, 'function', '===');
  }
}
function assertEqual(actual, expected, msg) {
  if (!(actual == expected)) {
    throwError(msg, actual, expected, '==');
  }
}
function assertNotEqual(actual, expected, msg) {
  if (!(actual != expected)) {
    throwError(msg, actual, expected, '!=');
  }
}
function assertSame(actual, expected, msg) {
  if (!(actual === expected)) {
    throwError(msg, actual, expected, '===');
  }
}
function assertNotSame(actual, expected, msg) {
  if (!(actual !== expected)) {
    throwError(msg, actual, expected, '!==');
  }
}
function assertLessThan(actual, expected, msg) {
  if (!(actual < expected)) {
    throwError(msg, actual, expected, '<');
  }
}
function assertLessThanOrEqual(actual, expected, msg) {
  if (!(actual <= expected)) {
    throwError(msg, actual, expected, '<=');
  }
}
function assertGreaterThan(actual, expected, msg) {
  if (!(actual > expected)) {
    throwError(msg, actual, expected, '>');
  }
}
function assertGreaterThanOrEqual(actual, expected, msg) {
  if (!(actual >= expected)) {
    throwError(msg, actual, expected, '>=');
  }
}
function assertNotDefined(actual, msg) {
  if (actual != null) {
    throwError(msg, actual, null, '==');
  }
}
function assertDefined(actual, msg) {
  if (actual == null) {
    throwError(msg, actual, null, '!=');
  }
}
function throwError(msg, actual, expected, comparison) {
  throw new Error(`ASSERTION ERROR: ${msg}` + (comparison == null ? '' : ` [Expected=> ${expected} ${comparison} ${actual} <=Actual]`));
}
function assertDomNode(node) {
  if (!(node instanceof Node)) {
    throwError(`The provided value must be an instance of a DOM Node but got ${stringify(node)}`);
  }
}
function assertElement(node) {
  if (!(node instanceof Element)) {
    throwError(`The provided value must be an element but got ${stringify(node)}`);
  }
}
function assertIndexInRange(arr, index) {
  assertDefined(arr, 'Array must be defined.');
  const maxLen = arr.length;
  if (index < 0 || index >= maxLen) {
    throwError(`Index expected to be less than ${maxLen} but got ${index}`);
  }
}
function assertOneOf(value, ...validValues) {
  if (validValues.indexOf(value) !== -1) return true;
  throwError(`Expected value to be one of ${JSON.stringify(validValues)} but was ${JSON.stringify(value)}.`);
}
function assertNotReactive(fn) {
  if ((0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.getActiveConsumer)() !== null) {
    throwError(`${fn}() should never be called in a reactive context.`);
  }
}

/**
 * Construct an injectable definition which defines how a token will be constructed by the DI
 * system, and in which injectors (if any) it will be available.
 *
 * This should be assigned to a static `ɵprov` field on a type, which will then be an
 * `InjectableType`.
 *
 * Options:
 * * `providedIn` determines which injectors will include the injectable, by either associating it
 *   with an `@NgModule` or other `InjectorType`, or by specifying that this injectable should be
 *   provided in the `'root'` injector, which will be the application-level injector in most apps.
 * * `factory` gives the zero argument function which will create an instance of the injectable.
 *   The factory can call [`inject`](api/core/inject) to access the `Injector` and request injection
 * of dependencies.
 *
 * @codeGenApi
 * @publicApi This instruction has been emitted by ViewEngine for some time and is deployed to npm.
 */
function ɵɵdefineInjectable(opts) {
  return {
    token: opts.token,
    providedIn: opts.providedIn || null,
    factory: opts.factory,
    value: undefined
  };
}
/**
 * @deprecated in v8, delete after v10. This API should be used only by generated code, and that
 * code should now use ɵɵdefineInjectable instead.
 * @publicApi
 */
const defineInjectable = ɵɵdefineInjectable;
/**
 * Construct an `InjectorDef` which configures an injector.
 *
 * This should be assigned to a static injector def (`ɵinj`) field on a type, which will then be an
 * `InjectorType`.
 *
 * Options:
 *
 * * `providers`: an optional array of providers to add to the injector. Each provider must
 *   either have a factory or point to a type which has a `ɵprov` static property (the
 *   type must be an `InjectableType`).
 * * `imports`: an optional array of imports of other `InjectorType`s or `InjectorTypeWithModule`s
 *   whose providers will also be added to the injector. Locally provided types will override
 *   providers from imports.
 *
 * @codeGenApi
 */
function ɵɵdefineInjector(options) {
  return {
    providers: options.providers || [],
    imports: options.imports || []
  };
}
/**
 * Read the injectable def (`ɵprov`) for `type` in a way which is immune to accidentally reading
 * inherited value.
 *
 * @param type A type which may have its own (non-inherited) `ɵprov`.
 */
function getInjectableDef(type) {
  return getOwnDefinition(type, NG_PROV_DEF) || getOwnDefinition(type, NG_INJECTABLE_DEF);
}
function isInjectable(type) {
  return getInjectableDef(type) !== null;
}
/**
 * Return definition only if it is defined directly on `type` and is not inherited from a base
 * class of `type`.
 */
function getOwnDefinition(type, field) {
  return type.hasOwnProperty(field) ? type[field] : null;
}
/**
 * Read the injectable def (`ɵprov`) for `type` or read the `ɵprov` from one of its ancestors.
 *
 * @param type A type which may have `ɵprov`, via inheritance.
 *
 * @deprecated Will be removed in a future version of Angular, where an error will occur in the
 *     scenario if we find the `ɵprov` on an ancestor only.
 */
function getInheritedInjectableDef(type) {
  const def = type && (type[NG_PROV_DEF] || type[NG_INJECTABLE_DEF]);
  if (def) {
    ngDevMode && console.warn(`DEPRECATED: DI is instantiating a token "${type.name}" that inherits its @Injectable decorator but does not provide one itself.\n` + `This will become an error in a future version of Angular. Please add @Injectable() to the "${type.name}" class.`);
    return def;
  } else {
    return null;
  }
}
/**
 * Read the injector def type in a way which is immune to accidentally reading inherited value.
 *
 * @param type type which may have an injector def (`ɵinj`)
 */
function getInjectorDef(type) {
  return type && (type.hasOwnProperty(NG_INJ_DEF) || type.hasOwnProperty(NG_INJECTOR_DEF)) ? type[NG_INJ_DEF] : null;
}
const NG_PROV_DEF = getClosureSafeProperty({
  ɵprov: getClosureSafeProperty
});
const NG_INJ_DEF = getClosureSafeProperty({
  ɵinj: getClosureSafeProperty
});
// We need to keep these around so we can read off old defs if new defs are unavailable
const NG_INJECTABLE_DEF = getClosureSafeProperty({
  ngInjectableDef: getClosureSafeProperty
});
const NG_INJECTOR_DEF = getClosureSafeProperty({
  ngInjectorDef: getClosureSafeProperty
});

/**
 * Creates a token that can be used in a DI Provider.
 *
 * Use an `InjectionToken` whenever the type you are injecting is not reified (does not have a
 * runtime representation) such as when injecting an interface, callable type, array or
 * parameterized type.
 *
 * `InjectionToken` is parameterized on `T` which is the type of object which will be returned by
 * the `Injector`. This provides an additional level of type safety.
 *
 * <div class="alert is-helpful">
 *
 * **Important Note**: Ensure that you use the same instance of the `InjectionToken` in both the
 * provider and the injection call. Creating a new instance of `InjectionToken` in different places,
 * even with the same description, will be treated as different tokens by Angular's DI system,
 * leading to a `NullInjectorError`.
 *
 * </div>
 *
 * <code-example format="typescript" language="typescript" path="injection-token/src/main.ts"
 * region="InjectionToken"></code-example>
 *
 * When creating an `InjectionToken`, you can optionally specify a factory function which returns
 * (possibly by creating) a default value of the parameterized type `T`. This sets up the
 * `InjectionToken` using this factory as a provider as if it was defined explicitly in the
 * application's root injector. If the factory function, which takes zero arguments, needs to inject
 * dependencies, it can do so using the [`inject`](api/core/inject) function.
 * As you can see in the Tree-shakable InjectionToken example below.
 *
 * Additionally, if a `factory` is specified you can also specify the `providedIn` option, which
 * overrides the above behavior and marks the token as belonging to a particular `@NgModule` (note:
 * this option is now deprecated). As mentioned above, `'root'` is the default value for
 * `providedIn`.
 *
 * The `providedIn: NgModule` and `providedIn: 'any'` options are deprecated.
 *
 * @usageNotes
 * ### Basic Examples
 *
 * ### Plain InjectionToken
 *
 * {@example core/di/ts/injector_spec.ts region='InjectionToken'}
 *
 * ### Tree-shakable InjectionToken
 *
 * {@example core/di/ts/injector_spec.ts region='ShakableInjectionToken'}
 *
 * @publicApi
 */
class InjectionToken {
  /**
   * @param _desc   Description for the token,
   *                used only for debugging purposes,
   *                it should but does not need to be unique
   * @param options Options for the token's usage, as described above
   */
  constructor(_desc, options) {
    this._desc = _desc;
    /** @internal */
    this.ngMetadataName = 'InjectionToken';
    this.ɵprov = undefined;
    if (typeof options == 'number') {
      (typeof ngDevMode === 'undefined' || ngDevMode) && assertLessThan(options, 0, 'Only negative numbers are supported here');
      // This is a special hack to assign __NG_ELEMENT_ID__ to this instance.
      // See `InjectorMarkers`
      this.__NG_ELEMENT_ID__ = options;
    } else if (options !== undefined) {
      this.ɵprov = ɵɵdefineInjectable({
        token: this,
        providedIn: options.providedIn || 'root',
        factory: options.factory
      });
    }
  }
  /**
   * @internal
   */
  get multi() {
    return this;
  }
  toString() {
    return `InjectionToken ${this._desc}`;
  }
}
let _injectorProfilerContext;
function getInjectorProfilerContext() {
  !ngDevMode && throwError('getInjectorProfilerContext should never be called in production mode');
  return _injectorProfilerContext;
}
function setInjectorProfilerContext(context) {
  !ngDevMode && throwError('setInjectorProfilerContext should never be called in production mode');
  const previous = _injectorProfilerContext;
  _injectorProfilerContext = context;
  return previous;
}
let injectorProfilerCallback = null;
/**
 * Sets the callback function which will be invoked during certain DI events within the
 * runtime (for example: injecting services, creating injectable instances, configuring providers)
 *
 * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
 * The contract of the function might be changed in any release and/or the function can be removed
 * completely.
 *
 * @param profiler function provided by the caller or null value to disable profiling.
 */
const setInjectorProfiler = injectorProfiler => {
  !ngDevMode && throwError('setInjectorProfiler should never be called in production mode');
  injectorProfilerCallback = injectorProfiler;
};
/**
 * Injector profiler function which emits on DI events executed by the runtime.
 *
 * @param event InjectorProfilerEvent corresponding to the DI event being emitted
 */
function injectorProfiler(event) {
  !ngDevMode && throwError('Injector profiler should never be called in production mode');
  if (injectorProfilerCallback != null /* both `null` and `undefined` */) {
    injectorProfilerCallback(event);
  }
}
/**
 * Emits an InjectorProfilerEventType.ProviderConfigured to the injector profiler. The data in the
 * emitted event includes the raw provider, as well as the token that provider is providing.
 *
 * @param eventProvider A provider object
 */
function emitProviderConfiguredEvent(eventProvider, isViewProvider = false) {
  !ngDevMode && throwError('Injector profiler should never be called in production mode');
  let token;
  // if the provider is a TypeProvider (typeof provider is function) then the token is the
  // provider itself
  if (typeof eventProvider === 'function') {
    token = eventProvider;
  }
  // if the provider is an injection token, then the token is the injection token.
  else if (eventProvider instanceof InjectionToken) {
    token = eventProvider;
  }
  // in all other cases we can access the token via the `provide` property of the provider
  else {
    token = resolveForwardRef(eventProvider.provide);
  }
  let provider = eventProvider;
  // Injection tokens may define their own default provider which gets attached to the token itself
  // as `ɵprov`. In this case, we want to emit the provider that is attached to the token, not the
  // token itself.
  if (eventProvider instanceof InjectionToken) {
    provider = eventProvider.ɵprov || eventProvider;
  }
  injectorProfiler({
    type: 2 /* InjectorProfilerEventType.ProviderConfigured */,
    context: getInjectorProfilerContext(),
    providerRecord: {
      token,
      provider,
      isViewProvider
    }
  });
}
/**
 * Emits an event to the injector profiler with the instance that was created. Note that
 * the injector associated with this emission can be accessed by using getDebugInjectContext()
 *
 * @param instance an object created by an injector
 */
function emitInstanceCreatedByInjectorEvent(instance) {
  !ngDevMode && throwError('Injector profiler should never be called in production mode');
  injectorProfiler({
    type: 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */,
    context: getInjectorProfilerContext(),
    instance: {
      value: instance
    }
  });
}
/**
 * @param token DI token associated with injected service
 * @param value the instance of the injected service (i.e the result of `inject(token)`)
 * @param flags the flags that the token was injected with
 */
function emitInjectEvent(token, value, flags) {
  !ngDevMode && throwError('Injector profiler should never be called in production mode');
  injectorProfiler({
    type: 0 /* InjectorProfilerEventType.Inject */,
    context: getInjectorProfilerContext(),
    service: {
      token,
      value,
      flags
    }
  });
}
function runInInjectorProfilerContext(injector, token, callback) {
  !ngDevMode && throwError('runInInjectorProfilerContext should never be called in production mode');
  const prevInjectContext = setInjectorProfilerContext({
    injector,
    token
  });
  try {
    callback();
  } finally {
    setInjectorProfilerContext(prevInjectContext);
  }
}
function isEnvironmentProviders(value) {
  return value && !!value.ɵproviders;
}
const NG_COMP_DEF = getClosureSafeProperty({
  ɵcmp: getClosureSafeProperty
});
const NG_DIR_DEF = getClosureSafeProperty({
  ɵdir: getClosureSafeProperty
});
const NG_PIPE_DEF = getClosureSafeProperty({
  ɵpipe: getClosureSafeProperty
});
const NG_MOD_DEF = getClosureSafeProperty({
  ɵmod: getClosureSafeProperty
});
const NG_FACTORY_DEF = getClosureSafeProperty({
  ɵfac: getClosureSafeProperty
});
/**
 * If a directive is diPublic, bloomAdd sets a property on the type with this constant as
 * the key and the directive's unique ID as the value. This allows us to map directives to their
 * bloom filter bit for DI.
 */
// TODO(misko): This is wrong. The NG_ELEMENT_ID should never be minified.
const NG_ELEMENT_ID = getClosureSafeProperty({
  __NG_ELEMENT_ID__: getClosureSafeProperty
});
/**
 * The `NG_ENV_ID` field on a DI token indicates special processing in the `EnvironmentInjector`:
 * getting such tokens from the `EnvironmentInjector` will bypass the standard DI resolution
 * strategy and instead will return implementation produced by the `NG_ENV_ID` factory function.
 *
 * This particular retrieval of DI tokens is mostly done to eliminate circular dependencies and
 * improve tree-shaking.
 */
const NG_ENV_ID = getClosureSafeProperty({
  __NG_ENV_ID__: getClosureSafeProperty
});

/**
 * Used for stringify render output in Ivy.
 * Important! This function is very performance-sensitive and we should
 * be extra careful not to introduce megamorphic reads in it.
 * Check `core/test/render3/perf/render_stringify` for benchmarks and alternate implementations.
 */
function renderStringify(value) {
  if (typeof value === 'string') return value;
  if (value == null) return '';
  // Use `String` so that it invokes the `toString` method of the value. Note that this
  // appears to be faster than calling `value.toString` (see `render_stringify` benchmark).
  return String(value);
}
/**
 * Used to stringify a value so that it can be displayed in an error message.
 *
 * Important! This function contains a megamorphic read and should only be
 * used for error messages.
 */
function stringifyForError(value) {
  if (typeof value === 'function') return value.name || value.toString();
  if (typeof value === 'object' && value != null && typeof value.type === 'function') {
    return value.type.name || value.type.toString();
  }
  return renderStringify(value);
}
/**
 * Used to stringify a `Type` and including the file path and line number in which it is defined, if
 * possible, for better debugging experience.
 *
 * Important! This function contains a megamorphic read and should only be used for error messages.
 */
function debugStringifyTypeForError(type) {
  // TODO(pmvald): Do some refactoring so that we can use getComponentDef here without creating
  // circular deps.
  let componentDef = type[NG_COMP_DEF] || null;
  if (componentDef !== null && componentDef.debugInfo) {
    return stringifyTypeFromDebugInfo(componentDef.debugInfo);
  }
  return stringifyForError(type);
}
// TODO(pmvald): Do some refactoring so that we can use the type ClassDebugInfo for the param
// debugInfo here without creating circular deps.
function stringifyTypeFromDebugInfo(debugInfo) {
  if (!debugInfo.filePath || !debugInfo.lineNumber) {
    return debugInfo.className;
  } else {
    return `${debugInfo.className} (at ${debugInfo.filePath}:${debugInfo.lineNumber})`;
  }
}

/** Called when directives inject each other (creating a circular dependency) */
function throwCyclicDependencyError(token, path) {
  const depPath = path ? `. Dependency path: ${path.join(' > ')} > ${token}` : '';
  throw new RuntimeError(-200 /* RuntimeErrorCode.CYCLIC_DI_DEPENDENCY */, ngDevMode ? `Circular dependency in DI detected for ${token}${depPath}` : token);
}
function throwMixedMultiProviderError() {
  throw new Error(`Cannot mix multi providers and regular providers`);
}
function throwInvalidProviderError(ngModuleType, providers, provider) {
  if (ngModuleType && providers) {
    const providerDetail = providers.map(v => v == provider ? '?' + provider + '?' : '...');
    throw new Error(`Invalid provider for the NgModule '${stringify(ngModuleType)}' - only instances of Provider and Type are allowed, got: [${providerDetail.join(', ')}]`);
  } else if (isEnvironmentProviders(provider)) {
    if (provider.ɵfromNgModule) {
      throw new RuntimeError(207 /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */, `Invalid providers from 'importProvidersFrom' present in a non-environment injector. 'importProvidersFrom' can't be used for component providers.`);
    } else {
      throw new RuntimeError(207 /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */, `Invalid providers present in a non-environment injector. 'EnvironmentProviders' can't be used for component providers.`);
    }
  } else {
    throw new Error('Invalid provider');
  }
}
/** Throws an error when a token is not found in DI. */
function throwProviderNotFoundError(token, injectorName) {
  const errorMessage = ngDevMode && `No provider for ${stringifyForError(token)} found${injectorName ? ` in ${injectorName}` : ''}`;
  throw new RuntimeError(-201 /* RuntimeErrorCode.PROVIDER_NOT_FOUND */, errorMessage);
}

/**
 * Injection flags for DI.
 *
 * @publicApi
 * @deprecated use an options object for [`inject`](api/core/inject) instead.
 */
var InjectFlags;
(function (InjectFlags) {
  // TODO(alxhub): make this 'const' (and remove `InternalInjectFlags` enum) when ngc no longer
  // writes exports of it into ngfactory files.
  /** Check self and check parent injector if needed */
  InjectFlags[InjectFlags["Default"] = 0] = "Default";
  /**
   * Specifies that an injector should retrieve a dependency from any injector until reaching the
   * host element of the current component. (Only used with Element Injector)
   */
  InjectFlags[InjectFlags["Host"] = 1] = "Host";
  /** Don't ascend to ancestors of the node requesting injection. */
  InjectFlags[InjectFlags["Self"] = 2] = "Self";
  /** Skip the node that is requesting injection. */
  InjectFlags[InjectFlags["SkipSelf"] = 4] = "SkipSelf";
  /** Inject `defaultValue` instead if token not found. */
  InjectFlags[InjectFlags["Optional"] = 8] = "Optional";
})(InjectFlags || (InjectFlags = {}));

/**
 * Current implementation of inject.
 *
 * By default, it is `injectInjectorOnly`, which makes it `Injector`-only aware. It can be changed
 * to `directiveInject`, which brings in the `NodeInjector` system of ivy. It is designed this
 * way for two reasons:
 *  1. `Injector` should not depend on ivy logic.
 *  2. To maintain tree shake-ability we don't want to bring in unnecessary code.
 */
let _injectImplementation;
function getInjectImplementation() {
  return _injectImplementation;
}
/**
 * Sets the current inject implementation.
 */
function setInjectImplementation(impl) {
  const previous = _injectImplementation;
  _injectImplementation = impl;
  return previous;
}
/**
 * Injects `root` tokens in limp mode.
 *
 * If no injector exists, we can still inject tree-shakable providers which have `providedIn` set to
 * `"root"`. This is known as the limp mode injection. In such case the value is stored in the
 * injectable definition.
 */
function injectRootLimpMode(token, notFoundValue, flags) {
  const injectableDef = getInjectableDef(token);
  if (injectableDef && injectableDef.providedIn == 'root') {
    return injectableDef.value === undefined ? injectableDef.value = injectableDef.factory() : injectableDef.value;
  }
  if (flags & InjectFlags.Optional) return null;
  if (notFoundValue !== undefined) return notFoundValue;
  throwProviderNotFoundError(token, 'Injector');
}
/**
 * Assert that `_injectImplementation` is not `fn`.
 *
 * This is useful, to prevent infinite recursion.
 *
 * @param fn Function which it should not equal to
 */
function assertInjectImplementationNotEqual(fn) {
  ngDevMode && assertNotEqual(_injectImplementation, fn, 'Calling ɵɵinject would cause infinite recursion');
}
const _THROW_IF_NOT_FOUND = {};
const THROW_IF_NOT_FOUND = _THROW_IF_NOT_FOUND;
/*
 * Name of a property (that we patch onto DI decorator), which is used as an annotation of which
 * InjectFlag this decorator represents. This allows to avoid direct references to the DI decorators
 * in the code, thus making them tree-shakable.
 */
const DI_DECORATOR_FLAG = '__NG_DI_FLAG__';
const NG_TEMP_TOKEN_PATH = 'ngTempTokenPath';
const NG_TOKEN_PATH = 'ngTokenPath';
const NEW_LINE = /\n/gm;
const NO_NEW_LINE = 'ɵ';
const SOURCE = '__source';
/**
 * Current injector value used by `inject`.
 * - `undefined`: it is an error to call `inject`
 * - `null`: `inject` can be called but there is no injector (limp-mode).
 * - Injector instance: Use the injector for resolution.
 */
let _currentInjector = undefined;
function getCurrentInjector() {
  return _currentInjector;
}
function setCurrentInjector(injector) {
  const former = _currentInjector;
  _currentInjector = injector;
  return former;
}
function injectInjectorOnly(token, flags = InjectFlags.Default) {
  if (_currentInjector === undefined) {
    throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode && `inject() must be called from an injection context such as a constructor, a factory function, a field initializer, or a function used with \`runInInjectionContext\`.`);
  } else if (_currentInjector === null) {
    return injectRootLimpMode(token, undefined, flags);
  } else {
    const value = _currentInjector.get(token, flags & InjectFlags.Optional ? null : undefined, flags);
    ngDevMode && emitInjectEvent(token, value, flags);
    return value;
  }
}
function ɵɵinject(token, flags = InjectFlags.Default) {
  return (getInjectImplementation() || injectInjectorOnly)(resolveForwardRef(token), flags);
}
/**
 * Throws an error indicating that a factory function could not be generated by the compiler for a
 * particular class.
 *
 * The name of the class is not mentioned here, but will be in the generated factory function name
 * and thus in the stack trace.
 *
 * @codeGenApi
 */
function ɵɵinvalidFactoryDep(index) {
  throw new RuntimeError(202 /* RuntimeErrorCode.INVALID_FACTORY_DEPENDENCY */, ngDevMode && `This constructor is not compatible with Angular Dependency Injection because its dependency at index ${index} of the parameter list is invalid.
This can happen if the dependency type is a primitive like a string or if an ancestor of this class is missing an Angular decorator.

Please check that 1) the type for the parameter at index ${index} is correct and 2) the correct Angular decorators are defined for this class and its ancestors.`);
}
/**
 * Injects a token from the currently active injector.
 * `inject` is only supported in an [injection context](/guide/dependency-injection-context). It can
 * be used during:
 * - Construction (via the `constructor`) of a class being instantiated by the DI system, such
 * as an `@Injectable` or `@Component`.
 * - In the initializer for fields of such classes.
 * - In the factory function specified for `useFactory` of a `Provider` or an `@Injectable`.
 * - In the `factory` function specified for an `InjectionToken`.
 * - In a stackframe of a function call in a DI context
 *
 * @param token A token that represents a dependency that should be injected.
 * @param flags Optional flags that control how injection is executed.
 * The flags correspond to injection strategies that can be specified with
 * parameter decorators `@Host`, `@Self`, `@SkipSelf`, and `@Optional`.
 * @returns the injected value if operation is successful, `null` otherwise.
 * @throws if called outside of a supported context.
 *
 * @usageNotes
 * In practice the `inject()` calls are allowed in a constructor, a constructor parameter and a
 * field initializer:
 *
 * ```typescript
 * @Injectable({providedIn: 'root'})
 * export class Car {
 *   radio: Radio|undefined;
 *   // OK: field initializer
 *   spareTyre = inject(Tyre);
 *
 *   constructor() {
 *     // OK: constructor body
 *     this.radio = inject(Radio);
 *   }
 * }
 * ```
 *
 * It is also legal to call `inject` from a provider's factory:
 *
 * ```typescript
 * providers: [
 *   {provide: Car, useFactory: () => {
 *     // OK: a class factory
 *     const engine = inject(Engine);
 *     return new Car(engine);
 *   }}
 * ]
 * ```
 *
 * Calls to the `inject()` function outside of the class creation context will result in error. Most
 * notably, calls to `inject()` are disallowed after a class instance was created, in methods
 * (including lifecycle hooks):
 *
 * ```typescript
 * @Component({ ... })
 * export class CarComponent {
 *   ngOnInit() {
 *     // ERROR: too late, the component instance was already created
 *     const engine = inject(Engine);
 *     engine.start();
 *   }
 * }
 * ```
 *
 * @publicApi
 */
function inject(token, flags = InjectFlags.Default) {
  // The `as any` here _shouldn't_ be necessary, but without it JSCompiler
  // throws a disambiguation  error due to the multiple signatures.
  return ɵɵinject(token, convertToBitFlags(flags));
}
// Converts object-based DI flags (`InjectOptions`) to bit flags (`InjectFlags`).
function convertToBitFlags(flags) {
  if (typeof flags === 'undefined' || typeof flags === 'number') {
    return flags;
  }
  // While TypeScript doesn't accept it without a cast, bitwise OR with false-y values in
  // JavaScript is a no-op. We can use that for a very codesize-efficient conversion from
  // `InjectOptions` to `InjectFlags`.
  return 0 /* InternalInjectFlags.Default */ | (
  // comment to force a line break in the formatter
  flags.optional && 8 /* InternalInjectFlags.Optional */) | (flags.host && 1 /* InternalInjectFlags.Host */) | (flags.self && 2 /* InternalInjectFlags.Self */) | (flags.skipSelf && 4 /* InternalInjectFlags.SkipSelf */);
}
function injectArgs(types) {
  const args = [];
  for (let i = 0; i < types.length; i++) {
    const arg = resolveForwardRef(types[i]);
    if (Array.isArray(arg)) {
      if (arg.length === 0) {
        throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && 'Arguments array must have arguments.');
      }
      let type = undefined;
      let flags = InjectFlags.Default;
      for (let j = 0; j < arg.length; j++) {
        const meta = arg[j];
        const flag = getInjectFlag(meta);
        if (typeof flag === 'number') {
          // Special case when we handle @Inject decorator.
          if (flag === -1 /* DecoratorFlags.Inject */) {
            type = meta.token;
          } else {
            flags |= flag;
          }
        } else {
          type = meta;
        }
      }
      args.push(ɵɵinject(type, flags));
    } else {
      args.push(ɵɵinject(arg));
    }
  }
  return args;
}
/**
 * Attaches a given InjectFlag to a given decorator using monkey-patching.
 * Since DI decorators can be used in providers `deps` array (when provider is configured using
 * `useFactory`) without initialization (e.g. `Host`) and as an instance (e.g. `new Host()`), we
 * attach the flag to make it available both as a static property and as a field on decorator
 * instance.
 *
 * @param decorator Provided DI decorator.
 * @param flag InjectFlag that should be applied.
 */
function attachInjectFlag(decorator, flag) {
  decorator[DI_DECORATOR_FLAG] = flag;
  decorator.prototype[DI_DECORATOR_FLAG] = flag;
  return decorator;
}
/**
 * Reads monkey-patched property that contains InjectFlag attached to a decorator.
 *
 * @param token Token that may contain monkey-patched DI flags property.
 */
function getInjectFlag(token) {
  return token[DI_DECORATOR_FLAG];
}
function catchInjectorError(e, token, injectorErrorName, source) {
  const tokenPath = e[NG_TEMP_TOKEN_PATH];
  if (token[SOURCE]) {
    tokenPath.unshift(token[SOURCE]);
  }
  e.message = formatError('\n' + e.message, tokenPath, injectorErrorName, source);
  e[NG_TOKEN_PATH] = tokenPath;
  e[NG_TEMP_TOKEN_PATH] = null;
  throw e;
}
function formatError(text, obj, injectorErrorName, source = null) {
  text = text && text.charAt(0) === '\n' && text.charAt(1) == NO_NEW_LINE ? text.slice(2) : text;
  let context = stringify(obj);
  if (Array.isArray(obj)) {
    context = obj.map(stringify).join(' -> ');
  } else if (typeof obj === 'object') {
    let parts = [];
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        let value = obj[key];
        parts.push(key + ':' + (typeof value === 'string' ? JSON.stringify(value) : stringify(value)));
      }
    }
    context = `{${parts.join(', ')}}`;
  }
  return `${injectorErrorName}${source ? '(' + source + ')' : ''}[${context}]: ${text.replace(NEW_LINE, '\n  ')}`;
}

/**
 * Inject decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Inject = attachInjectFlag(
// Disable tslint because `DecoratorFlags` is a const enum which gets inlined.
// tslint:disable-next-line: no-toplevel-property-access
makeParamDecorator('Inject', token => ({
  token
})), -1 /* DecoratorFlags.Inject */);
/**
 * Optional decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Optional =
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
// tslint:disable-next-line: no-toplevel-property-access
attachInjectFlag(makeParamDecorator('Optional'), 8 /* InternalInjectFlags.Optional */);
/**
 * Self decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Self =
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
// tslint:disable-next-line: no-toplevel-property-access
attachInjectFlag(makeParamDecorator('Self'), 2 /* InternalInjectFlags.Self */);
/**
 * `SkipSelf` decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const SkipSelf =
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
// tslint:disable-next-line: no-toplevel-property-access
attachInjectFlag(makeParamDecorator('SkipSelf'), 4 /* InternalInjectFlags.SkipSelf */);
/**
 * Host decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Host =
// Disable tslint because `InternalInjectFlags` is a const enum which gets inlined.
// tslint:disable-next-line: no-toplevel-property-access
attachInjectFlag(makeParamDecorator('Host'), 1 /* InternalInjectFlags.Host */);
function getFactoryDef(type, throwNotFound) {
  const hasFactoryDef = type.hasOwnProperty(NG_FACTORY_DEF);
  if (!hasFactoryDef && throwNotFound === true && ngDevMode) {
    throw new Error(`Type ${stringify(type)} does not have 'ɵfac' property.`);
  }
  return hasFactoryDef ? type[NG_FACTORY_DEF] : null;
}

/**
 * Determines if the contents of two arrays is identical
 *
 * @param a first array
 * @param b second array
 * @param identityAccessor Optional function for extracting stable object identity from a value in
 *     the array.
 */
function arrayEquals(a, b, identityAccessor) {
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; i++) {
    let valueA = a[i];
    let valueB = b[i];
    if (identityAccessor) {
      valueA = identityAccessor(valueA);
      valueB = identityAccessor(valueB);
    }
    if (valueB !== valueA) {
      return false;
    }
  }
  return true;
}
/**
 * Flattens an array.
 */
function flatten(list) {
  return list.flat(Number.POSITIVE_INFINITY);
}
function deepForEach(input, fn) {
  input.forEach(value => Array.isArray(value) ? deepForEach(value, fn) : fn(value));
}
function addToArray(arr, index, value) {
  // perf: array.push is faster than array.splice!
  if (index >= arr.length) {
    arr.push(value);
  } else {
    arr.splice(index, 0, value);
  }
}
function removeFromArray(arr, index) {
  // perf: array.pop is faster than array.splice!
  if (index >= arr.length - 1) {
    return arr.pop();
  } else {
    return arr.splice(index, 1)[0];
  }
}
function newArray(size, value) {
  const list = [];
  for (let i = 0; i < size; i++) {
    list.push(value);
  }
  return list;
}
/**
 * Remove item from array (Same as `Array.splice()` but faster.)
 *
 * `Array.splice()` is not as fast because it has to allocate an array for the elements which were
 * removed. This causes memory pressure and slows down code when most of the time we don't
 * care about the deleted items array.
 *
 * https://jsperf.com/fast-array-splice (About 20x faster)
 *
 * @param array Array to splice
 * @param index Index of element in array to remove.
 * @param count Number of items to remove.
 */
function arraySplice(array, index, count) {
  const length = array.length - count;
  while (index < length) {
    array[index] = array[index + count];
    index++;
  }
  while (count--) {
    array.pop(); // shrink the array
  }
}
/**
 * Same as `Array.splice(index, 0, value)` but faster.
 *
 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
 * removed. This causes memory pressure and slows down code when most of the time we don't
 * care about the deleted items array.
 *
 * @param array Array to splice.
 * @param index Index in array where the `value` should be added.
 * @param value Value to add to array.
 */
function arrayInsert(array, index, value) {
  ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
  let end = array.length;
  while (end > index) {
    const previousEnd = end - 1;
    array[end] = array[previousEnd];
    end = previousEnd;
  }
  array[index] = value;
}
/**
 * Same as `Array.splice2(index, 0, value1, value2)` but faster.
 *
 * `Array.splice()` is not fast because it has to allocate an array for the elements which were
 * removed. This causes memory pressure and slows down code when most of the time we don't
 * care about the deleted items array.
 *
 * @param array Array to splice.
 * @param index Index in array where the `value` should be added.
 * @param value1 Value to add to array.
 * @param value2 Value to add to array.
 */
function arrayInsert2(array, index, value1, value2) {
  ngDevMode && assertLessThanOrEqual(index, array.length, 'Can\'t insert past array end.');
  let end = array.length;
  if (end == index) {
    // inserting at the end.
    array.push(value1, value2);
  } else if (end === 1) {
    // corner case when we have less items in array than we have items to insert.
    array.push(value2, array[0]);
    array[0] = value1;
  } else {
    end--;
    array.push(array[end - 1], array[end]);
    while (end > index) {
      const previousEnd = end - 2;
      array[end] = array[previousEnd];
      end--;
    }
    array[index] = value1;
    array[index + 1] = value2;
  }
}
/**
 * Get an index of an `value` in a sorted `array`.
 *
 * NOTE:
 * - This uses binary search algorithm for fast removals.
 *
 * @param array A sorted array to binary search.
 * @param value The value to look for.
 * @returns index of the value.
 *   - positive index if value found.
 *   - negative index if value not found. (`~index` to get the value where it should have been
 *     located)
 */
function arrayIndexOfSorted(array, value) {
  return _arrayIndexOfSorted(array, value, 0);
}
/**
 * Set a `value` for a `key`.
 *
 * @param keyValueArray to modify.
 * @param key The key to locate or create.
 * @param value The value to set for a `key`.
 * @returns index (always even) of where the value vas set.
 */
function keyValueArraySet(keyValueArray, key, value) {
  let index = keyValueArrayIndexOf(keyValueArray, key);
  if (index >= 0) {
    // if we found it set it.
    keyValueArray[index | 1] = value;
  } else {
    index = ~index;
    arrayInsert2(keyValueArray, index, key, value);
  }
  return index;
}
/**
 * Retrieve a `value` for a `key` (on `undefined` if not found.)
 *
 * @param keyValueArray to search.
 * @param key The key to locate.
 * @return The `value` stored at the `key` location or `undefined if not found.
 */
function keyValueArrayGet(keyValueArray, key) {
  const index = keyValueArrayIndexOf(keyValueArray, key);
  if (index >= 0) {
    // if we found it retrieve it.
    return keyValueArray[index | 1];
  }
  return undefined;
}
/**
 * Retrieve a `key` index value in the array or `-1` if not found.
 *
 * @param keyValueArray to search.
 * @param key The key to locate.
 * @returns index of where the key is (or should have been.)
 *   - positive (even) index if key found.
 *   - negative index if key not found. (`~index` (even) to get the index where it should have
 *     been inserted.)
 */
function keyValueArrayIndexOf(keyValueArray, key) {
  return _arrayIndexOfSorted(keyValueArray, key, 1);
}
/**
 * Delete a `key` (and `value`) from the `KeyValueArray`.
 *
 * @param keyValueArray to modify.
 * @param key The key to locate or delete (if exist).
 * @returns index of where the key was (or should have been.)
 *   - positive (even) index if key found and deleted.
 *   - negative index if key not found. (`~index` (even) to get the index where it should have
 *     been.)
 */
function keyValueArrayDelete(keyValueArray, key) {
  const index = keyValueArrayIndexOf(keyValueArray, key);
  if (index >= 0) {
    // if we found it remove it.
    arraySplice(keyValueArray, index, 2);
  }
  return index;
}
/**
 * INTERNAL: Get an index of an `value` in a sorted `array` by grouping search by `shift`.
 *
 * NOTE:
 * - This uses binary search algorithm for fast removals.
 *
 * @param array A sorted array to binary search.
 * @param value The value to look for.
 * @param shift grouping shift.
 *   - `0` means look at every location
 *   - `1` means only look at every other (even) location (the odd locations are to be ignored as
 *         they are values.)
 * @returns index of the value.
 *   - positive index if value found.
 *   - negative index if value not found. (`~index` to get the value where it should have been
 * inserted)
 */
function _arrayIndexOfSorted(array, value, shift) {
  ngDevMode && assertEqual(Array.isArray(array), true, 'Expecting an array');
  let start = 0;
  let end = array.length >> shift;
  while (end !== start) {
    const middle = start + (end - start >> 1); // find the middle.
    const current = array[middle << shift];
    if (value === current) {
      return middle << shift;
    } else if (current > value) {
      end = middle;
    } else {
      start = middle + 1; // We already searched middle so make it non-inclusive by adding 1
    }
  }
  return ~(end << shift);
}

/**
 * This file contains reuseable "empty" symbols that can be used as default return values
 * in different parts of the rendering code. Because the same symbols are returned, this
 * allows for identity checks against these values to be consistently used by the framework
 * code.
 */
const EMPTY_OBJ = {};
const EMPTY_ARRAY = [];
// freezing the values prevents any code from accidentally inserting new values in
if ((typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode()) {
  // These property accesses can be ignored because ngDevMode will be set to false
  // when optimizing code and the whole if statement will be dropped.
  // tslint:disable-next-line:no-toplevel-property-access
  Object.freeze(EMPTY_OBJ);
  // tslint:disable-next-line:no-toplevel-property-access
  Object.freeze(EMPTY_ARRAY);
}

/**
 * A multi-provider token for initialization functions that will run upon construction of an
 * environment injector.
 *
 * @publicApi
 */
const ENVIRONMENT_INITIALIZER = new InjectionToken(ngDevMode ? 'ENVIRONMENT_INITIALIZER' : '');

/**
 * An InjectionToken that gets the current `Injector` for `createInjector()`-style injectors.
 *
 * Requesting this token instead of `Injector` allows `StaticInjector` to be tree-shaken from a
 * project.
 *
 * @publicApi
 */
const INJECTOR$1 = new InjectionToken(ngDevMode ? 'INJECTOR' : '',
// Disable tslint because this is const enum which gets inlined not top level prop access.
// tslint:disable-next-line: no-toplevel-property-access
-1 /* InjectorMarkers.Injector */);
const INJECTOR_DEF_TYPES = new InjectionToken(ngDevMode ? 'INJECTOR_DEF_TYPES' : '');
class NullInjector {
  get(token, notFoundValue = THROW_IF_NOT_FOUND) {
    if (notFoundValue === THROW_IF_NOT_FOUND) {
      const error = new Error(`NullInjectorError: No provider for ${stringify(token)}!`);
      error.name = 'NullInjectorError';
      throw error;
    }
    return notFoundValue;
  }
}

/**
 * The strategy that the default change detector uses to detect changes.
 * When set, takes effect the next time change detection is triggered.
 *
 * @see [Change detection usage](/api/core/ChangeDetectorRef?tab=usage-notes)
 *
 * @publicApi
 */
var ChangeDetectionStrategy;
(function (ChangeDetectionStrategy) {
  /**
   * Use the `CheckOnce` strategy, meaning that automatic change detection is deactivated
   * until reactivated by setting the strategy to `Default` (`CheckAlways`).
   * Change detection can still be explicitly invoked.
   * This strategy applies to all child directives and cannot be overridden.
   */
  ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush";
  /**
   * Use the default `CheckAlways` strategy, in which change detection is automatic until
   * explicitly deactivated.
   */
  ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default";
})(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}));

/**
 * Defines the CSS styles encapsulation policies for the {@link Component} decorator's
 * `encapsulation` option.
 *
 * See {@link Component#encapsulation encapsulation}.
 *
 * @usageNotes
 * ### Example
 *
 * {@example core/ts/metadata/encapsulation.ts region='longform'}
 *
 * @publicApi
 */
var ViewEncapsulation$1;
(function (ViewEncapsulation) {
  // TODO: consider making `ViewEncapsulation` a `const enum` instead. See
  // https://github.com/angular/angular/issues/44119 for additional information.
  /**
   * Emulates a native Shadow DOM encapsulation behavior by adding a specific attribute to the
   * component's host element and applying the same attribute to all the CSS selectors provided
   * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls}.
   *
   * This is the default option.
   */
  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
  // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
  /**
   * Doesn't provide any sort of CSS style encapsulation, meaning that all the styles provided
   * via {@link Component#styles styles} or {@link Component#styleUrls styleUrls} are applicable
   * to any HTML element of the application regardless of their host Component.
   */
  ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
  /**
   * Uses the browser's native Shadow DOM API to encapsulate CSS styles, meaning that it creates
   * a ShadowRoot for the component's host element which is then used to encapsulate
   * all the Component's styling.
   */
  ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation$1 || (ViewEncapsulation$1 = {}));

/** Flags describing an input for a directive. */
var InputFlags;
(function (InputFlags) {
  InputFlags[InputFlags["None"] = 0] = "None";
  InputFlags[InputFlags["SignalBased"] = 1] = "SignalBased";
  InputFlags[InputFlags["HasDecoratorInputTransform"] = 2] = "HasDecoratorInputTransform";
})(InputFlags || (InputFlags = {}));

/**
 * Returns an index of `classToSearch` in `className` taking token boundaries into account.
 *
 * `classIndexOf('AB A', 'A', 0)` will be 3 (not 0 since `AB!==A`)
 *
 * @param className A string containing classes (whitespace separated)
 * @param classToSearch A class name to locate
 * @param startingIndex Starting location of search
 * @returns an index of the located class (or -1 if not found)
 */
function classIndexOf(className, classToSearch, startingIndex) {
  ngDevMode && assertNotEqual(classToSearch, '', 'can not look for "" string.');
  let end = className.length;
  while (true) {
    const foundIndex = className.indexOf(classToSearch, startingIndex);
    if (foundIndex === -1) return foundIndex;
    if (foundIndex === 0 || className.charCodeAt(foundIndex - 1) <= 32 /* CharCode.SPACE */) {
      // Ensure that it has leading whitespace
      const length = classToSearch.length;
      if (foundIndex + length === end || className.charCodeAt(foundIndex + length) <= 32 /* CharCode.SPACE */) {
        // Ensure that it has trailing whitespace
        return foundIndex;
      }
    }
    // False positive, keep searching from where we left off.
    startingIndex = foundIndex + 1;
  }
}

/**
 * Assigns all attribute values to the provided element via the inferred renderer.
 *
 * This function accepts two forms of attribute entries:
 *
 * default: (key, value):
 *  attrs = [key1, value1, key2, value2]
 *
 * namespaced: (NAMESPACE_MARKER, uri, name, value)
 *  attrs = [NAMESPACE_MARKER, uri, name, value, NAMESPACE_MARKER, uri, name, value]
 *
 * The `attrs` array can contain a mix of both the default and namespaced entries.
 * The "default" values are set without a marker, but if the function comes across
 * a marker value then it will attempt to set a namespaced value. If the marker is
 * not of a namespaced value then the function will quit and return the index value
 * where it stopped during the iteration of the attrs array.
 *
 * See [AttributeMarker] to understand what the namespace marker value is.
 *
 * Note that this instruction does not support assigning style and class values to
 * an element. See `elementStart` and `elementHostAttrs` to learn how styling values
 * are applied to an element.
 * @param renderer The renderer to be used
 * @param native The element that the attributes will be assigned to
 * @param attrs The attribute array of values that will be assigned to the element
 * @returns the index value that was last accessed in the attributes array
 */
function setUpAttributes(renderer, native, attrs) {
  let i = 0;
  while (i < attrs.length) {
    const value = attrs[i];
    if (typeof value === 'number') {
      // only namespaces are supported. Other value types (such as style/class
      // entries) are not supported in this function.
      if (value !== 0 /* AttributeMarker.NamespaceURI */) {
        break;
      }
      // we just landed on the marker value ... therefore
      // we should skip to the next entry
      i++;
      const namespaceURI = attrs[i++];
      const attrName = attrs[i++];
      const attrVal = attrs[i++];
      ngDevMode && ngDevMode.rendererSetAttribute++;
      renderer.setAttribute(native, attrName, attrVal, namespaceURI);
    } else {
      // attrName is string;
      const attrName = value;
      const attrVal = attrs[++i];
      // Standard attributes
      ngDevMode && ngDevMode.rendererSetAttribute++;
      if (isAnimationProp(attrName)) {
        renderer.setProperty(native, attrName, attrVal);
      } else {
        renderer.setAttribute(native, attrName, attrVal);
      }
      i++;
    }
  }
  // another piece of code may iterate over the same attributes array. Therefore
  // it may be helpful to return the exact spot where the attributes array exited
  // whether by running into an unsupported marker or if all the static values were
  // iterated over.
  return i;
}
/**
 * Test whether the given value is a marker that indicates that the following
 * attribute values in a `TAttributes` array are only the names of attributes,
 * and not name-value pairs.
 * @param marker The attribute marker to test.
 * @returns true if the marker is a "name-only" marker (e.g. `Bindings`, `Template` or `I18n`).
 */
function isNameOnlyAttributeMarker(marker) {
  return marker === 3 /* AttributeMarker.Bindings */ || marker === 4 /* AttributeMarker.Template */ || marker === 6 /* AttributeMarker.I18n */;
}
function isAnimationProp(name) {
  // Perf note: accessing charCodeAt to check for the first character of a string is faster as
  // compared to accessing a character at index 0 (ex. name[0]). The main reason for this is that
  // charCodeAt doesn't allocate memory to return a substring.
  return name.charCodeAt(0) === 64 /* CharCode.AT_SIGN */;
}
/**
 * Merges `src` `TAttributes` into `dst` `TAttributes` removing any duplicates in the process.
 *
 * This merge function keeps the order of attrs same.
 *
 * @param dst Location of where the merged `TAttributes` should end up.
 * @param src `TAttributes` which should be appended to `dst`
 */
function mergeHostAttrs(dst, src) {
  if (src === null || src.length === 0) {
    // do nothing
  } else if (dst === null || dst.length === 0) {
    // We have source, but dst is empty, just make a copy.
    dst = src.slice();
  } else {
    let srcMarker = -1 /* AttributeMarker.ImplicitAttributes */;
    for (let i = 0; i < src.length; i++) {
      const item = src[i];
      if (typeof item === 'number') {
        srcMarker = item;
      } else {
        if (srcMarker === 0 /* AttributeMarker.NamespaceURI */) {
          // Case where we need to consume `key1`, `key2`, `value` items.
        } else if (srcMarker === -1 /* AttributeMarker.ImplicitAttributes */ || srcMarker === 2 /* AttributeMarker.Styles */) {
          // Case where we have to consume `key1` and `value` only.
          mergeHostAttribute(dst, srcMarker, item, null, src[++i]);
        } else {
          // Case where we have to consume `key1` only.
          mergeHostAttribute(dst, srcMarker, item, null, null);
        }
      }
    }
  }
  return dst;
}
/**
 * Append `key`/`value` to existing `TAttributes` taking region marker and duplicates into account.
 *
 * @param dst `TAttributes` to append to.
 * @param marker Region where the `key`/`value` should be added.
 * @param key1 Key to add to `TAttributes`
 * @param key2 Key to add to `TAttributes` (in case of `AttributeMarker.NamespaceURI`)
 * @param value Value to add or to overwrite to `TAttributes` Only used if `marker` is not Class.
 */
function mergeHostAttribute(dst, marker, key1, key2, value) {
  let i = 0;
  // Assume that new markers will be inserted at the end.
  let markerInsertPosition = dst.length;
  // scan until correct type.
  if (marker === -1 /* AttributeMarker.ImplicitAttributes */) {
    markerInsertPosition = -1;
  } else {
    while (i < dst.length) {
      const dstValue = dst[i++];
      if (typeof dstValue === 'number') {
        if (dstValue === marker) {
          markerInsertPosition = -1;
          break;
        } else if (dstValue > marker) {
          // We need to save this as we want the markers to be inserted in specific order.
          markerInsertPosition = i - 1;
          break;
        }
      }
    }
  }
  // search until you find place of insertion
  while (i < dst.length) {
    const item = dst[i];
    if (typeof item === 'number') {
      // since `i` started as the index after the marker, we did not find it if we are at the next
      // marker
      break;
    } else if (item === key1) {
      // We already have same token
      if (key2 === null) {
        if (value !== null) {
          dst[i + 1] = value;
        }
        return;
      } else if (key2 === dst[i + 1]) {
        dst[i + 2] = value;
        return;
      }
    }
    // Increment counter.
    i++;
    if (key2 !== null) i++;
    if (value !== null) i++;
  }
  // insert at location.
  if (markerInsertPosition !== -1) {
    dst.splice(markerInsertPosition, 0, marker);
    i = markerInsertPosition + 1;
  }
  dst.splice(i++, 0, key1);
  if (key2 !== null) {
    dst.splice(i++, 0, key2);
  }
  if (value !== null) {
    dst.splice(i++, 0, value);
  }
}
const NG_TEMPLATE_SELECTOR = 'ng-template';
/**
 * Search the `TAttributes` to see if it contains `cssClassToMatch` (case insensitive)
 *
 * @param tNode static data of the node to match
 * @param attrs `TAttributes` to search through.
 * @param cssClassToMatch class to match (lowercase)
 * @param isProjectionMode Whether or not class matching should look into the attribute `class` in
 *    addition to the `AttributeMarker.Classes`.
 */
function isCssClassMatching(tNode, attrs, cssClassToMatch, isProjectionMode) {
  ngDevMode && assertEqual(cssClassToMatch, cssClassToMatch.toLowerCase(), 'Class name expected to be lowercase.');
  let i = 0;
  if (isProjectionMode) {
    for (; i < attrs.length && typeof attrs[i] === 'string'; i += 2) {
      // Search for an implicit `class` attribute and check if its value matches `cssClassToMatch`.
      if (attrs[i] === 'class' && classIndexOf(attrs[i + 1].toLowerCase(), cssClassToMatch, 0) !== -1) {
        return true;
      }
    }
  } else if (isInlineTemplate(tNode)) {
    // Matching directives (i.e. when not matching for projection mode) should not consider the
    // class bindings that are present on inline templates, as those class bindings only target
    // the root node of the template, not the template itself.
    return false;
  }
  // Resume the search for classes after the `Classes` marker.
  i = attrs.indexOf(1 /* AttributeMarker.Classes */, i);
  if (i > -1) {
    // We found the classes section. Start searching for the class.
    let item;
    while (++i < attrs.length && typeof (item = attrs[i]) === 'string') {
      if (item.toLowerCase() === cssClassToMatch) {
        return true;
      }
    }
  }
  return false;
}
/**
 * Checks whether the `tNode` represents an inline template (e.g. `*ngFor`).
 *
 * @param tNode current TNode
 */
function isInlineTemplate(tNode) {
  return tNode.type === 4 /* TNodeType.Container */ && tNode.value !== NG_TEMPLATE_SELECTOR;
}
/**
 * Function that checks whether a given tNode matches tag-based selector and has a valid type.
 *
 * Matching can be performed in 2 modes: projection mode (when we project nodes) and regular
 * directive matching mode:
 * - in the "directive matching" mode we do _not_ take TContainer's tagName into account if it is
 * different from NG_TEMPLATE_SELECTOR (value different from NG_TEMPLATE_SELECTOR indicates that a
 * tag name was extracted from * syntax so we would match the same directive twice);
 * - in the "projection" mode, we use a tag name potentially extracted from the * syntax processing
 * (applicable to TNodeType.Container only).
 */
function hasTagAndTypeMatch(tNode, currentSelector, isProjectionMode) {
  const tagNameToCompare = tNode.type === 4 /* TNodeType.Container */ && !isProjectionMode ? NG_TEMPLATE_SELECTOR : tNode.value;
  return currentSelector === tagNameToCompare;
}
/**
 * A utility function to match an Ivy node static data against a simple CSS selector
 *
 * @param tNode static data of the node to match
 * @param selector The selector to try matching against the node.
 * @param isProjectionMode if `true` we are matching for content projection, otherwise we are doing
 * directive matching.
 * @returns true if node matches the selector.
 */
function isNodeMatchingSelector(tNode, selector, isProjectionMode) {
  ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
  let mode = 4 /* SelectorFlags.ELEMENT */;
  const nodeAttrs = tNode.attrs;
  // Find the index of first attribute that has no value, only a name.
  const nameOnlyMarkerIdx = nodeAttrs !== null ? getNameOnlyMarkerIndex(nodeAttrs) : 0;
  // When processing ":not" selectors, we skip to the next ":not" if the
  // current one doesn't match
  let skipToNextSelector = false;
  for (let i = 0; i < selector.length; i++) {
    const current = selector[i];
    if (typeof current === 'number') {
      // If we finish processing a :not selector and it hasn't failed, return false
      if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
        return false;
      }
      // If we are skipping to the next :not() and this mode flag is positive,
      // it's a part of the current :not() selector, and we should keep skipping
      if (skipToNextSelector && isPositive(current)) continue;
      skipToNextSelector = false;
      mode = current | mode & 1 /* SelectorFlags.NOT */;
      continue;
    }
    if (skipToNextSelector) continue;
    if (mode & 4 /* SelectorFlags.ELEMENT */) {
      mode = 2 /* SelectorFlags.ATTRIBUTE */ | mode & 1 /* SelectorFlags.NOT */;
      if (current !== '' && !hasTagAndTypeMatch(tNode, current, isProjectionMode) || current === '' && selector.length === 1) {
        if (isPositive(mode)) return false;
        skipToNextSelector = true;
      }
    } else if (mode & 8 /* SelectorFlags.CLASS */) {
      if (nodeAttrs === null || !isCssClassMatching(tNode, nodeAttrs, current, isProjectionMode)) {
        if (isPositive(mode)) return false;
        skipToNextSelector = true;
      }
    } else {
      const selectorAttrValue = selector[++i];
      const attrIndexInNode = findAttrIndexInNode(current, nodeAttrs, isInlineTemplate(tNode), isProjectionMode);
      if (attrIndexInNode === -1) {
        if (isPositive(mode)) return false;
        skipToNextSelector = true;
        continue;
      }
      if (selectorAttrValue !== '') {
        let nodeAttrValue;
        if (attrIndexInNode > nameOnlyMarkerIdx) {
          nodeAttrValue = '';
        } else {
          ngDevMode && assertNotEqual(nodeAttrs[attrIndexInNode], 0 /* AttributeMarker.NamespaceURI */, 'We do not match directives on namespaced attributes');
          // we lowercase the attribute value to be able to match
          // selectors without case-sensitivity
          // (selectors are already in lowercase when generated)
          nodeAttrValue = nodeAttrs[attrIndexInNode + 1].toLowerCase();
        }
        if (mode & 2 /* SelectorFlags.ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
          if (isPositive(mode)) return false;
          skipToNextSelector = true;
        }
      }
    }
  }
  return isPositive(mode) || skipToNextSelector;
}
function isPositive(mode) {
  return (mode & 1 /* SelectorFlags.NOT */) === 0;
}
/**
 * Examines the attribute's definition array for a node to find the index of the
 * attribute that matches the given `name`.
 *
 * NOTE: This will not match namespaced attributes.
 *
 * Attribute matching depends upon `isInlineTemplate` and `isProjectionMode`.
 * The following table summarizes which types of attributes we attempt to match:
 *
 * ===========================================================================================================
 * Modes                   | Normal Attributes | Bindings Attributes | Template Attributes | I18n
 * Attributes
 * ===========================================================================================================
 * Inline + Projection     | YES               | YES                 | NO                  | YES
 * -----------------------------------------------------------------------------------------------------------
 * Inline + Directive      | NO                | NO                  | YES                 | NO
 * -----------------------------------------------------------------------------------------------------------
 * Non-inline + Projection | YES               | YES                 | NO                  | YES
 * -----------------------------------------------------------------------------------------------------------
 * Non-inline + Directive  | YES               | YES                 | NO                  | YES
 * ===========================================================================================================
 *
 * @param name the name of the attribute to find
 * @param attrs the attribute array to examine
 * @param isInlineTemplate true if the node being matched is an inline template (e.g. `*ngFor`)
 * rather than a manually expanded template node (e.g `<ng-template>`).
 * @param isProjectionMode true if we are matching against content projection otherwise we are
 * matching against directives.
 */
function findAttrIndexInNode(name, attrs, isInlineTemplate, isProjectionMode) {
  if (attrs === null) return -1;
  let i = 0;
  if (isProjectionMode || !isInlineTemplate) {
    let bindingsMode = false;
    while (i < attrs.length) {
      const maybeAttrName = attrs[i];
      if (maybeAttrName === name) {
        return i;
      } else if (maybeAttrName === 3 /* AttributeMarker.Bindings */ || maybeAttrName === 6 /* AttributeMarker.I18n */) {
        bindingsMode = true;
      } else if (maybeAttrName === 1 /* AttributeMarker.Classes */ || maybeAttrName === 2 /* AttributeMarker.Styles */) {
        let value = attrs[++i];
        // We should skip classes here because we have a separate mechanism for
        // matching classes in projection mode.
        while (typeof value === 'string') {
          value = attrs[++i];
        }
        continue;
      } else if (maybeAttrName === 4 /* AttributeMarker.Template */) {
        // We do not care about Template attributes in this scenario.
        break;
      } else if (maybeAttrName === 0 /* AttributeMarker.NamespaceURI */) {
        // Skip the whole namespaced attribute and value. This is by design.
        i += 4;
        continue;
      }
      // In binding mode there are only names, rather than name-value pairs.
      i += bindingsMode ? 1 : 2;
    }
    // We did not match the attribute
    return -1;
  } else {
    return matchTemplateAttribute(attrs, name);
  }
}
function isNodeMatchingSelectorList(tNode, selector, isProjectionMode = false) {
  for (let i = 0; i < selector.length; i++) {
    if (isNodeMatchingSelector(tNode, selector[i], isProjectionMode)) {
      return true;
    }
  }
  return false;
}
function getProjectAsAttrValue(tNode) {
  const nodeAttrs = tNode.attrs;
  if (nodeAttrs != null) {
    const ngProjectAsAttrIdx = nodeAttrs.indexOf(5 /* AttributeMarker.ProjectAs */);
    // only check for ngProjectAs in attribute names, don't accidentally match attribute's value
    // (attribute names are stored at even indexes)
    if ((ngProjectAsAttrIdx & 1) === 0) {
      return nodeAttrs[ngProjectAsAttrIdx + 1];
    }
  }
  return null;
}
function getNameOnlyMarkerIndex(nodeAttrs) {
  for (let i = 0; i < nodeAttrs.length; i++) {
    const nodeAttr = nodeAttrs[i];
    if (isNameOnlyAttributeMarker(nodeAttr)) {
      return i;
    }
  }
  return nodeAttrs.length;
}
function matchTemplateAttribute(attrs, name) {
  let i = attrs.indexOf(4 /* AttributeMarker.Template */);
  if (i > -1) {
    i++;
    while (i < attrs.length) {
      const attr = attrs[i];
      // Return in case we checked all template attrs and are switching to the next section in the
      // attrs array (that starts with a number that represents an attribute marker).
      if (typeof attr === 'number') return -1;
      if (attr === name) return i;
      i++;
    }
  }
  return -1;
}
/**
 * Checks whether a selector is inside a CssSelectorList
 * @param selector Selector to be checked.
 * @param list List in which to look for the selector.
 */
function isSelectorInSelectorList(selector, list) {
  selectorListLoop: for (let i = 0; i < list.length; i++) {
    const currentSelectorInList = list[i];
    if (selector.length !== currentSelectorInList.length) {
      continue;
    }
    for (let j = 0; j < selector.length; j++) {
      if (selector[j] !== currentSelectorInList[j]) {
        continue selectorListLoop;
      }
    }
    return true;
  }
  return false;
}
function maybeWrapInNotSelector(isNegativeMode, chunk) {
  return isNegativeMode ? ':not(' + chunk.trim() + ')' : chunk;
}
function stringifyCSSSelector(selector) {
  let result = selector[0];
  let i = 1;
  let mode = 2 /* SelectorFlags.ATTRIBUTE */;
  let currentChunk = '';
  let isNegativeMode = false;
  while (i < selector.length) {
    let valueOrMarker = selector[i];
    if (typeof valueOrMarker === 'string') {
      if (mode & 2 /* SelectorFlags.ATTRIBUTE */) {
        const attrValue = selector[++i];
        currentChunk += '[' + valueOrMarker + (attrValue.length > 0 ? '="' + attrValue + '"' : '') + ']';
      } else if (mode & 8 /* SelectorFlags.CLASS */) {
        currentChunk += '.' + valueOrMarker;
      } else if (mode & 4 /* SelectorFlags.ELEMENT */) {
        currentChunk += ' ' + valueOrMarker;
      }
    } else {
      //
      // Append current chunk to the final result in case we come across SelectorFlag, which
      // indicates that the previous section of a selector is over. We need to accumulate content
      // between flags to make sure we wrap the chunk later in :not() selector if needed, e.g.
      // ```
      //  ['', Flags.CLASS, '.classA', Flags.CLASS | Flags.NOT, '.classB', '.classC']
      // ```
      // should be transformed to `.classA :not(.classB .classC)`.
      //
      // Note: for negative selector part, we accumulate content between flags until we find the
      // next negative flag. This is needed to support a case where `:not()` rule contains more than
      // one chunk, e.g. the following selector:
      // ```
      //  ['', Flags.ELEMENT | Flags.NOT, 'p', Flags.CLASS, 'foo', Flags.CLASS | Flags.NOT, 'bar']
      // ```
      // should be stringified to `:not(p.foo) :not(.bar)`
      //
      if (currentChunk !== '' && !isPositive(valueOrMarker)) {
        result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
        currentChunk = '';
      }
      mode = valueOrMarker;
      // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
      // mode is maintained for remaining chunks of a selector.
      isNegativeMode = isNegativeMode || !isPositive(mode);
    }
    i++;
  }
  if (currentChunk !== '') {
    result += maybeWrapInNotSelector(isNegativeMode, currentChunk);
  }
  return result;
}
/**
 * Generates string representation of CSS selector in parsed form.
 *
 * ComponentDef and DirectiveDef are generated with the selector in parsed form to avoid doing
 * additional parsing at runtime (for example, for directive matching). However in some cases (for
 * example, while bootstrapping a component), a string version of the selector is required to query
 * for the host element on the page. This function takes the parsed form of a selector and returns
 * its string representation.
 *
 * @param selectorList selector in parsed form
 * @returns string representation of a given selector
 */
function stringifyCSSSelectorList(selectorList) {
  return selectorList.map(stringifyCSSSelector).join(',');
}
/**
 * Extracts attributes and classes information from a given CSS selector.
 *
 * This function is used while creating a component dynamically. In this case, the host element
 * (that is created dynamically) should contain attributes and classes specified in component's CSS
 * selector.
 *
 * @param selector CSS selector in parsed form (in a form of array)
 * @returns object with `attrs` and `classes` fields that contain extracted information
 */
function extractAttrsAndClassesFromSelector(selector) {
  const attrs = [];
  const classes = [];
  let i = 1;
  let mode = 2 /* SelectorFlags.ATTRIBUTE */;
  while (i < selector.length) {
    let valueOrMarker = selector[i];
    if (typeof valueOrMarker === 'string') {
      if (mode === 2 /* SelectorFlags.ATTRIBUTE */) {
        if (valueOrMarker !== '') {
          attrs.push(valueOrMarker, selector[++i]);
        }
      } else if (mode === 8 /* SelectorFlags.CLASS */) {
        classes.push(valueOrMarker);
      }
    } else {
      // According to CssSelector spec, once we come across `SelectorFlags.NOT` flag, the negative
      // mode is maintained for remaining chunks of a selector. Since attributes and classes are
      // extracted only for "positive" part of the selector, we can stop here.
      if (!isPositive(mode)) break;
      mode = valueOrMarker;
    }
    i++;
  }
  return {
    attrs,
    classes
  };
}

/**
 * Create a component definition object.
 *
 *
 * # Example
 * ```
 * class MyComponent {
 *   // Generated by Angular Template Compiler
 *   // [Symbol] syntax will not be supported by TypeScript until v2.7
 *   static ɵcmp = defineComponent({
 *     ...
 *   });
 * }
 * ```
 * @codeGenApi
 */
function ɵɵdefineComponent(componentDefinition) {
  return noSideEffects(() => {
    // Initialize ngDevMode. This must be the first statement in ɵɵdefineComponent.
    // See the `initNgDevMode` docstring for more information.
    (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
    const baseDef = getNgDirectiveDef(componentDefinition);
    const def = {
      ...baseDef,
      decls: componentDefinition.decls,
      vars: componentDefinition.vars,
      template: componentDefinition.template,
      consts: componentDefinition.consts || null,
      ngContentSelectors: componentDefinition.ngContentSelectors,
      onPush: componentDefinition.changeDetection === ChangeDetectionStrategy.OnPush,
      directiveDefs: null,
      // assigned in noSideEffects
      pipeDefs: null,
      // assigned in noSideEffects
      dependencies: baseDef.standalone && componentDefinition.dependencies || null,
      getStandaloneInjector: null,
      signals: componentDefinition.signals ?? false,
      data: componentDefinition.data || {},
      encapsulation: componentDefinition.encapsulation || ViewEncapsulation$1.Emulated,
      styles: componentDefinition.styles || EMPTY_ARRAY,
      _: null,
      schemas: componentDefinition.schemas || null,
      tView: null,
      id: ''
    };
    initFeatures(def);
    const dependencies = componentDefinition.dependencies;
    def.directiveDefs = extractDefListOrFactory(dependencies, /* pipeDef */false);
    def.pipeDefs = extractDefListOrFactory(dependencies, /* pipeDef */true);
    def.id = getComponentId(def);
    return def;
  });
}
function extractDirectiveDef(type) {
  return getComponentDef(type) || getDirectiveDef(type);
}
function nonNull(value) {
  return value !== null;
}
/**
 * @codeGenApi
 */
function ɵɵdefineNgModule(def) {
  return noSideEffects(() => {
    const res = {
      type: def.type,
      bootstrap: def.bootstrap || EMPTY_ARRAY,
      declarations: def.declarations || EMPTY_ARRAY,
      imports: def.imports || EMPTY_ARRAY,
      exports: def.exports || EMPTY_ARRAY,
      transitiveCompileScopes: null,
      schemas: def.schemas || null,
      id: def.id || null
    };
    return res;
  });
}
function parseAndConvertBindingsForDefinition(obj, declaredInputs) {
  if (obj == null) return EMPTY_OBJ;
  const newLookup = {};
  for (const minifiedKey in obj) {
    if (obj.hasOwnProperty(minifiedKey)) {
      const value = obj[minifiedKey];
      let publicName;
      let declaredName;
      let inputFlags = InputFlags.None;
      if (Array.isArray(value)) {
        inputFlags = value[0];
        publicName = value[1];
        declaredName = value[2] ?? publicName; // declared name might not be set to save bytes.
      } else {
        publicName = value;
        declaredName = value;
      }
      // For inputs, capture the declared name, or if some flags are set.
      if (declaredInputs) {
        // Perf note: An array is only allocated for the input if there are flags.
        newLookup[publicName] = inputFlags !== InputFlags.None ? [minifiedKey, inputFlags] : minifiedKey;
        declaredInputs[publicName] = declaredName;
      } else {
        newLookup[publicName] = minifiedKey;
      }
    }
  }
  return newLookup;
}
/**
 * Create a directive definition object.
 *
 * # Example
 * ```ts
 * class MyDirective {
 *   // Generated by Angular Template Compiler
 *   // [Symbol] syntax will not be supported by TypeScript until v2.7
 *   static ɵdir = ɵɵdefineDirective({
 *     ...
 *   });
 * }
 * ```
 *
 * @codeGenApi
 */
function ɵɵdefineDirective(directiveDefinition) {
  return noSideEffects(() => {
    const def = getNgDirectiveDef(directiveDefinition);
    initFeatures(def);
    return def;
  });
}
/**
 * Create a pipe definition object.
 *
 * # Example
 * ```
 * class MyPipe implements PipeTransform {
 *   // Generated by Angular Template Compiler
 *   static ɵpipe = definePipe({
 *     ...
 *   });
 * }
 * ```
 * @param pipeDef Pipe definition generated by the compiler
 *
 * @codeGenApi
 */
function ɵɵdefinePipe(pipeDef) {
  return {
    type: pipeDef.type,
    name: pipeDef.name,
    factory: null,
    pure: pipeDef.pure !== false,
    standalone: pipeDef.standalone === true,
    onDestroy: pipeDef.type.prototype.ngOnDestroy || null
  };
}
/**
 * The following getter methods retrieve the definition from the type. Currently the retrieval
 * honors inheritance, but in the future we may change the rule to require that definitions are
 * explicit. This would require some sort of migration strategy.
 */
function getComponentDef(type) {
  return type[NG_COMP_DEF] || null;
}
function getDirectiveDef(type) {
  return type[NG_DIR_DEF] || null;
}
function getPipeDef$1(type) {
  return type[NG_PIPE_DEF] || null;
}
/**
 * Checks whether a given Component, Directive or Pipe is marked as standalone.
 * This will return false if passed anything other than a Component, Directive, or Pipe class
 * See [this guide](/guide/standalone-components) for additional information:
 *
 * @param type A reference to a Component, Directive or Pipe.
 * @publicApi
 */
function isStandalone(type) {
  const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
  return def !== null ? def.standalone : false;
}
function getNgModuleDef(type, throwNotFound) {
  const ngModuleDef = type[NG_MOD_DEF] || null;
  if (!ngModuleDef && throwNotFound === true) {
    throw new Error(`Type ${stringify(type)} does not have 'ɵmod' property.`);
  }
  return ngModuleDef;
}
function getNgDirectiveDef(directiveDefinition) {
  const declaredInputs = {};
  return {
    type: directiveDefinition.type,
    providersResolver: null,
    factory: null,
    hostBindings: directiveDefinition.hostBindings || null,
    hostVars: directiveDefinition.hostVars || 0,
    hostAttrs: directiveDefinition.hostAttrs || null,
    contentQueries: directiveDefinition.contentQueries || null,
    declaredInputs: declaredInputs,
    inputTransforms: null,
    inputConfig: directiveDefinition.inputs || EMPTY_OBJ,
    exportAs: directiveDefinition.exportAs || null,
    standalone: directiveDefinition.standalone === true,
    signals: directiveDefinition.signals === true,
    selectors: directiveDefinition.selectors || EMPTY_ARRAY,
    viewQuery: directiveDefinition.viewQuery || null,
    features: directiveDefinition.features || null,
    setInput: null,
    findHostDirectiveDefs: null,
    hostDirectives: null,
    inputs: parseAndConvertBindingsForDefinition(directiveDefinition.inputs, declaredInputs),
    outputs: parseAndConvertBindingsForDefinition(directiveDefinition.outputs),
    debugInfo: null
  };
}
function initFeatures(definition) {
  definition.features?.forEach(fn => fn(definition));
}
function extractDefListOrFactory(dependencies, pipeDef) {
  if (!dependencies) {
    return null;
  }
  const defExtractor = pipeDef ? getPipeDef$1 : extractDirectiveDef;
  return () => (typeof dependencies === 'function' ? dependencies() : dependencies).map(dep => defExtractor(dep)).filter(nonNull);
}
/**
 * A map that contains the generated component IDs and type.
 */
const GENERATED_COMP_IDS = new Map();
/**
 * A method can returns a component ID from the component definition using a variant of DJB2 hash
 * algorithm.
 */
function getComponentId(componentDef) {
  let hash = 0;
  // We cannot rely solely on the component selector as the same selector can be used in different
  // modules.
  //
  // `componentDef.style` is not used, due to it causing inconsistencies. Ex: when server
  // component styles has no sourcemaps and browsers do.
  //
  // Example:
  // https://github.com/angular/components/blob/d9f82c8f95309e77a6d82fd574c65871e91354c2/src/material/core/option/option.ts#L248
  // https://github.com/angular/components/blob/285f46dc2b4c5b127d356cb7c4714b221f03ce50/src/material/legacy-core/option/option.ts#L32
  const hashSelectors = [componentDef.selectors, componentDef.ngContentSelectors, componentDef.hostVars, componentDef.hostAttrs, componentDef.consts, componentDef.vars, componentDef.decls, componentDef.encapsulation, componentDef.standalone, componentDef.signals, componentDef.exportAs, JSON.stringify(componentDef.inputs), JSON.stringify(componentDef.outputs),
  // We cannot use 'componentDef.type.name' as the name of the symbol will change and will not
  // match in the server and browser bundles.
  Object.getOwnPropertyNames(componentDef.type.prototype), !!componentDef.contentQueries, !!componentDef.viewQuery].join('|');
  for (const char of hashSelectors) {
    hash = Math.imul(31, hash) + char.charCodeAt(0) << 0;
  }
  // Force positive number hash.
  // 2147483647 = equivalent of Integer.MAX_VALUE.
  hash += 2147483647 + 1;
  const compId = 'c' + hash;
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    if (GENERATED_COMP_IDS.has(compId)) {
      const previousCompDefType = GENERATED_COMP_IDS.get(compId);
      if (previousCompDefType !== componentDef.type) {
        console.warn(formatRuntimeError(-912 /* RuntimeErrorCode.COMPONENT_ID_COLLISION */, `Component ID generation collision detected. Components '${previousCompDefType.name}' and '${componentDef.type.name}' with selector '${stringifyCSSSelectorList(componentDef.selectors)}' generated the same component ID. To fix this, you can change the selector of one of those components or add an extra host attribute to force a different ID.`));
      }
    } else {
      GENERATED_COMP_IDS.set(compId, componentDef.type);
    }
  }
  return compId;
}

/**
 * Wrap an array of `Provider`s into `EnvironmentProviders`, preventing them from being accidentally
 * referenced in `@Component` in a component injector.
 */
function makeEnvironmentProviders(providers) {
  return {
    ɵproviders: providers
  };
}
/**
 * Collects providers from all NgModules and standalone components, including transitively imported
 * ones.
 *
 * Providers extracted via `importProvidersFrom` are only usable in an application injector or
 * another environment injector (such as a route injector). They should not be used in component
 * providers.
 *
 * More information about standalone components can be found in [this
 * guide](guide/standalone-components).
 *
 * @usageNotes
 * The results of the `importProvidersFrom` call can be used in the `bootstrapApplication` call:
 *
 * ```typescript
 * await bootstrapApplication(RootComponent, {
 *   providers: [
 *     importProvidersFrom(NgModuleOne, NgModuleTwo)
 *   ]
 * });
 * ```
 *
 * You can also use the `importProvidersFrom` results in the `providers` field of a route, when a
 * standalone component is used:
 *
 * ```typescript
 * export const ROUTES: Route[] = [
 *   {
 *     path: 'foo',
 *     providers: [
 *       importProvidersFrom(NgModuleOne, NgModuleTwo)
 *     ],
 *     component: YourStandaloneComponent
 *   }
 * ];
 * ```
 *
 * @returns Collected providers from the specified list of types.
 * @publicApi
 */
function importProvidersFrom(...sources) {
  return {
    ɵproviders: internalImportProvidersFrom(true, sources),
    ɵfromNgModule: true
  };
}
function internalImportProvidersFrom(checkForStandaloneCmp, ...sources) {
  const providersOut = [];
  const dedup = new Set(); // already seen types
  let injectorTypesWithProviders;
  const collectProviders = provider => {
    providersOut.push(provider);
  };
  deepForEach(sources, source => {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && checkForStandaloneCmp) {
      const cmpDef = getComponentDef(source);
      if (cmpDef?.standalone) {
        throw new RuntimeError(800 /* RuntimeErrorCode.IMPORT_PROVIDERS_FROM_STANDALONE */, `Importing providers supports NgModule or ModuleWithProviders but got a standalone component "${stringifyForError(source)}"`);
      }
    }
    // Narrow `source` to access the internal type analogue for `ModuleWithProviders`.
    const internalSource = source;
    if (walkProviderTree(internalSource, collectProviders, [], dedup)) {
      injectorTypesWithProviders ||= [];
      injectorTypesWithProviders.push(internalSource);
    }
  });
  // Collect all providers from `ModuleWithProviders` types.
  if (injectorTypesWithProviders !== undefined) {
    processInjectorTypesWithProviders(injectorTypesWithProviders, collectProviders);
  }
  return providersOut;
}
/**
 * Collects all providers from the list of `ModuleWithProviders` and appends them to the provided
 * array.
 */
function processInjectorTypesWithProviders(typesWithProviders, visitor) {
  for (let i = 0; i < typesWithProviders.length; i++) {
    const {
      ngModule,
      providers
    } = typesWithProviders[i];
    deepForEachProvider(providers, provider => {
      ngDevMode && validateProvider(provider, providers || EMPTY_ARRAY, ngModule);
      visitor(provider, ngModule);
    });
  }
}
/**
 * The logic visits an `InjectorType`, an `InjectorTypeWithProviders`, or a standalone
 * `ComponentType`, and all of its transitive providers and collects providers.
 *
 * If an `InjectorTypeWithProviders` that declares providers besides the type is specified,
 * the function will return "true" to indicate that the providers of the type definition need
 * to be processed. This allows us to process providers of injector types after all imports of
 * an injector definition are processed. (following View Engine semantics: see FW-1349)
 */
function walkProviderTree(container, visitor, parents, dedup) {
  container = resolveForwardRef(container);
  if (!container) return false;
  // The actual type which had the definition. Usually `container`, but may be an unwrapped type
  // from `InjectorTypeWithProviders`.
  let defType = null;
  let injDef = getInjectorDef(container);
  const cmpDef = !injDef && getComponentDef(container);
  if (!injDef && !cmpDef) {
    // `container` is not an injector type or a component type. It might be:
    //  * An `InjectorTypeWithProviders` that wraps an injector type.
    //  * A standalone directive or pipe that got pulled in from a standalone component's
    //    dependencies.
    // Try to unwrap it as an `InjectorTypeWithProviders` first.
    const ngModule = container.ngModule;
    injDef = getInjectorDef(ngModule);
    if (injDef) {
      defType = ngModule;
    } else {
      // Not a component or injector type, so ignore it.
      return false;
    }
  } else if (cmpDef && !cmpDef.standalone) {
    return false;
  } else {
    defType = container;
  }
  // Check for circular dependencies.
  if (ngDevMode && parents.indexOf(defType) !== -1) {
    const defName = stringify(defType);
    const path = parents.map(stringify);
    throwCyclicDependencyError(defName, path);
  }
  // Check for multiple imports of the same module
  const isDuplicate = dedup.has(defType);
  if (cmpDef) {
    if (isDuplicate) {
      // This component definition has already been processed.
      return false;
    }
    dedup.add(defType);
    if (cmpDef.dependencies) {
      const deps = typeof cmpDef.dependencies === 'function' ? cmpDef.dependencies() : cmpDef.dependencies;
      for (const dep of deps) {
        walkProviderTree(dep, visitor, parents, dedup);
      }
    }
  } else if (injDef) {
    // First, include providers from any imports.
    if (injDef.imports != null && !isDuplicate) {
      // Before processing defType's imports, add it to the set of parents. This way, if it ends
      // up deeply importing itself, this can be detected.
      ngDevMode && parents.push(defType);
      // Add it to the set of dedups. This way we can detect multiple imports of the same module
      dedup.add(defType);
      let importTypesWithProviders;
      try {
        deepForEach(injDef.imports, imported => {
          if (walkProviderTree(imported, visitor, parents, dedup)) {
            importTypesWithProviders ||= [];
            // If the processed import is an injector type with providers, we store it in the
            // list of import types with providers, so that we can process those afterwards.
            importTypesWithProviders.push(imported);
          }
        });
      } finally {
        // Remove it from the parents set when finished.
        ngDevMode && parents.pop();
      }
      // Imports which are declared with providers (TypeWithProviders) need to be processed
      // after all imported modules are processed. This is similar to how View Engine
      // processes/merges module imports in the metadata resolver. See: FW-1349.
      if (importTypesWithProviders !== undefined) {
        processInjectorTypesWithProviders(importTypesWithProviders, visitor);
      }
    }
    if (!isDuplicate) {
      // Track the InjectorType and add a provider for it.
      // It's important that this is done after the def's imports.
      const factory = getFactoryDef(defType) || (() => new defType());
      // Append extra providers to make more info available for consumers (to retrieve an injector
      // type), as well as internally (to calculate an injection scope correctly and eagerly
      // instantiate a `defType` when an injector is created).
      // Provider to create `defType` using its factory.
      visitor({
        provide: defType,
        useFactory: factory,
        deps: EMPTY_ARRAY
      }, defType);
      // Make this `defType` available to an internal logic that calculates injector scope.
      visitor({
        provide: INJECTOR_DEF_TYPES,
        useValue: defType,
        multi: true
      }, defType);
      // Provider to eagerly instantiate `defType` via `INJECTOR_INITIALIZER`.
      visitor({
        provide: ENVIRONMENT_INITIALIZER,
        useValue: () => ɵɵinject(defType),
        multi: true
      }, defType);
    }
    // Next, include providers listed on the definition itself.
    const defProviders = injDef.providers;
    if (defProviders != null && !isDuplicate) {
      const injectorType = container;
      deepForEachProvider(defProviders, provider => {
        ngDevMode && validateProvider(provider, defProviders, injectorType);
        visitor(provider, injectorType);
      });
    }
  } else {
    // Should not happen, but just in case.
    return false;
  }
  return defType !== container && container.providers !== undefined;
}
function validateProvider(provider, providers, containerType) {
  if (isTypeProvider(provider) || isValueProvider(provider) || isFactoryProvider(provider) || isExistingProvider(provider)) {
    return;
  }
  // Here we expect the provider to be a `useClass` provider (by elimination).
  const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
  if (!classRef) {
    throwInvalidProviderError(containerType, providers, provider);
  }
}
function deepForEachProvider(providers, fn) {
  for (let provider of providers) {
    if (isEnvironmentProviders(provider)) {
      provider = provider.ɵproviders;
    }
    if (Array.isArray(provider)) {
      deepForEachProvider(provider, fn);
    } else {
      fn(provider);
    }
  }
}
const USE_VALUE$1 = getClosureSafeProperty({
  provide: String,
  useValue: getClosureSafeProperty
});
function isValueProvider(value) {
  return value !== null && typeof value == 'object' && USE_VALUE$1 in value;
}
function isExistingProvider(value) {
  return !!(value && value.useExisting);
}
function isFactoryProvider(value) {
  return !!(value && value.useFactory);
}
function isTypeProvider(value) {
  return typeof value === 'function';
}
function isClassProvider(value) {
  return !!value.useClass;
}

/**
 * An internal token whose presence in an injector indicates that the injector should treat itself
 * as a root scoped injector when processing requests for unknown tokens which may indicate
 * they are provided in the root scope.
 */
const INJECTOR_SCOPE = new InjectionToken(ngDevMode ? 'Set Injector scope.' : '');

/**
 * Marker which indicates that a value has not yet been created from the factory function.
 */
const NOT_YET = {};
/**
 * Marker which indicates that the factory function for a token is in the process of being called.
 *
 * If the injector is asked to inject a token with its value set to CIRCULAR, that indicates
 * injection of a dependency has recursively attempted to inject the original token, and there is
 * a circular dependency among the providers.
 */
const CIRCULAR = {};
/**
 * A lazily initialized NullInjector.
 */
let NULL_INJECTOR = undefined;
function getNullInjector() {
  if (NULL_INJECTOR === undefined) {
    NULL_INJECTOR = new NullInjector();
  }
  return NULL_INJECTOR;
}
/**
 * An `Injector` that's part of the environment injector hierarchy, which exists outside of the
 * component tree.
 */
class EnvironmentInjector {}
class R3Injector extends EnvironmentInjector {
  /**
   * Flag indicating that this injector was previously destroyed.
   */
  get destroyed() {
    return this._destroyed;
  }
  constructor(providers, parent, source, scopes) {
    super();
    this.parent = parent;
    this.source = source;
    this.scopes = scopes;
    /**
     * Map of tokens to records which contain the instances of those tokens.
     * - `null` value implies that we don't have the record. Used by tree-shakable injectors
     * to prevent further searches.
     */
    this.records = new Map();
    /**
     * Set of values instantiated by this injector which contain `ngOnDestroy` lifecycle hooks.
     */
    this._ngOnDestroyHooks = new Set();
    this._onDestroyHooks = [];
    this._destroyed = false;
    // Start off by creating Records for every provider.
    forEachSingleProvider(providers, provider => this.processProvider(provider));
    // Make sure the INJECTOR token provides this injector.
    this.records.set(INJECTOR$1, makeRecord(undefined, this));
    // And `EnvironmentInjector` if the current injector is supposed to be env-scoped.
    if (scopes.has('environment')) {
      this.records.set(EnvironmentInjector, makeRecord(undefined, this));
    }
    // Detect whether this injector has the APP_ROOT_SCOPE token and thus should provide
    // any injectable scoped to APP_ROOT_SCOPE.
    const record = this.records.get(INJECTOR_SCOPE);
    if (record != null && typeof record.value === 'string') {
      this.scopes.add(record.value);
    }
    this.injectorDefTypes = new Set(this.get(INJECTOR_DEF_TYPES, EMPTY_ARRAY, InjectFlags.Self));
  }
  /**
   * Destroy the injector and release references to every instance or provider associated with it.
   *
   * Also calls the `OnDestroy` lifecycle hooks of every instance that was created for which a
   * hook was found.
   */
  destroy() {
    this.assertNotDestroyed();
    // Set destroyed = true first, in case lifecycle hooks re-enter destroy().
    this._destroyed = true;
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      // Call all the lifecycle hooks.
      for (const service of this._ngOnDestroyHooks) {
        service.ngOnDestroy();
      }
      const onDestroyHooks = this._onDestroyHooks;
      // Reset the _onDestroyHooks array before iterating over it to prevent hooks that unregister
      // themselves from mutating the array during iteration.
      this._onDestroyHooks = [];
      for (const hook of onDestroyHooks) {
        hook();
      }
    } finally {
      // Release all references.
      this.records.clear();
      this._ngOnDestroyHooks.clear();
      this.injectorDefTypes.clear();
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
  onDestroy(callback) {
    this.assertNotDestroyed();
    this._onDestroyHooks.push(callback);
    return () => this.removeOnDestroy(callback);
  }
  runInContext(fn) {
    this.assertNotDestroyed();
    const previousInjector = setCurrentInjector(this);
    const previousInjectImplementation = setInjectImplementation(undefined);
    let prevInjectContext;
    if (ngDevMode) {
      prevInjectContext = setInjectorProfilerContext({
        injector: this,
        token: null
      });
    }
    try {
      return fn();
    } finally {
      setCurrentInjector(previousInjector);
      setInjectImplementation(previousInjectImplementation);
      ngDevMode && setInjectorProfilerContext(prevInjectContext);
    }
  }
  get(token, notFoundValue = THROW_IF_NOT_FOUND, flags = InjectFlags.Default) {
    this.assertNotDestroyed();
    if (token.hasOwnProperty(NG_ENV_ID)) {
      return token[NG_ENV_ID](this);
    }
    flags = convertToBitFlags(flags);
    // Set the injection context.
    let prevInjectContext;
    if (ngDevMode) {
      prevInjectContext = setInjectorProfilerContext({
        injector: this,
        token: token
      });
    }
    const previousInjector = setCurrentInjector(this);
    const previousInjectImplementation = setInjectImplementation(undefined);
    try {
      // Check for the SkipSelf flag.
      if (!(flags & InjectFlags.SkipSelf)) {
        // SkipSelf isn't set, check if the record belongs to this injector.
        let record = this.records.get(token);
        if (record === undefined) {
          // No record, but maybe the token is scoped to this injector. Look for an injectable
          // def with a scope matching this injector.
          const def = couldBeInjectableType(token) && getInjectableDef(token);
          if (def && this.injectableDefInScope(def)) {
            // Found an injectable def and it's scoped to this injector. Pretend as if it was here
            // all along.
            if (ngDevMode) {
              runInInjectorProfilerContext(this, token, () => {
                emitProviderConfiguredEvent(token);
              });
            }
            record = makeRecord(injectableDefOrInjectorDefFactory(token), NOT_YET);
          } else {
            record = null;
          }
          this.records.set(token, record);
        }
        // If a record was found, get the instance for it and return it.
        if (record != null /* NOT null || undefined */) {
          return this.hydrate(token, record);
        }
      }
      // Select the next injector based on the Self flag - if self is set, the next injector is
      // the NullInjector, otherwise it's the parent.
      const nextInjector = !(flags & InjectFlags.Self) ? this.parent : getNullInjector();
      // Set the notFoundValue based on the Optional flag - if optional is set and notFoundValue
      // is undefined, the value is null, otherwise it's the notFoundValue.
      notFoundValue = flags & InjectFlags.Optional && notFoundValue === THROW_IF_NOT_FOUND ? null : notFoundValue;
      return nextInjector.get(token, notFoundValue);
    } catch (e) {
      if (e.name === 'NullInjectorError') {
        const path = e[NG_TEMP_TOKEN_PATH] = e[NG_TEMP_TOKEN_PATH] || [];
        path.unshift(stringify(token));
        if (previousInjector) {
          // We still have a parent injector, keep throwing
          throw e;
        } else {
          // Format & throw the final error message when we don't have any previous injector
          return catchInjectorError(e, token, 'R3InjectorError', this.source);
        }
      } else {
        throw e;
      }
    } finally {
      // Lastly, restore the previous injection context.
      setInjectImplementation(previousInjectImplementation);
      setCurrentInjector(previousInjector);
      ngDevMode && setInjectorProfilerContext(prevInjectContext);
    }
  }
  /** @internal */
  resolveInjectorInitializers() {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    const previousInjector = setCurrentInjector(this);
    const previousInjectImplementation = setInjectImplementation(undefined);
    let prevInjectContext;
    if (ngDevMode) {
      prevInjectContext = setInjectorProfilerContext({
        injector: this,
        token: null
      });
    }
    try {
      const initializers = this.get(ENVIRONMENT_INITIALIZER, EMPTY_ARRAY, InjectFlags.Self);
      if (ngDevMode && !Array.isArray(initializers)) {
        throw new RuntimeError(-209 /* RuntimeErrorCode.INVALID_MULTI_PROVIDER */, 'Unexpected type of the `ENVIRONMENT_INITIALIZER` token value ' + `(expected an array, but got ${typeof initializers}). ` + 'Please check that the `ENVIRONMENT_INITIALIZER` token is configured as a ' + '`multi: true` provider.');
      }
      for (const initializer of initializers) {
        initializer();
      }
    } finally {
      setCurrentInjector(previousInjector);
      setInjectImplementation(previousInjectImplementation);
      ngDevMode && setInjectorProfilerContext(prevInjectContext);
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
  toString() {
    const tokens = [];
    const records = this.records;
    for (const token of records.keys()) {
      tokens.push(stringify(token));
    }
    return `R3Injector[${tokens.join(', ')}]`;
  }
  assertNotDestroyed() {
    if (this._destroyed) {
      throw new RuntimeError(205 /* RuntimeErrorCode.INJECTOR_ALREADY_DESTROYED */, ngDevMode && 'Injector has already been destroyed.');
    }
  }
  /**
   * Process a `SingleProvider` and add it.
   */
  processProvider(provider) {
    // Determine the token from the provider. Either it's its own token, or has a {provide: ...}
    // property.
    provider = resolveForwardRef(provider);
    let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider && provider.provide);
    // Construct a `Record` for the provider.
    const record = providerToRecord(provider);
    if (ngDevMode) {
      runInInjectorProfilerContext(this, token, () => {
        // Emit InjectorProfilerEventType.Create if provider is a value provider because
        // these are the only providers that do not go through the value hydration logic
        // where this event would normally be emitted from.
        if (isValueProvider(provider)) {
          emitInstanceCreatedByInjectorEvent(provider.useValue);
        }
        emitProviderConfiguredEvent(provider);
      });
    }
    if (!isTypeProvider(provider) && provider.multi === true) {
      // If the provider indicates that it's a multi-provider, process it specially.
      // First check whether it's been defined already.
      let multiRecord = this.records.get(token);
      if (multiRecord) {
        // It has. Throw a nice error if
        if (ngDevMode && multiRecord.multi === undefined) {
          throwMixedMultiProviderError();
        }
      } else {
        multiRecord = makeRecord(undefined, NOT_YET, true);
        multiRecord.factory = () => injectArgs(multiRecord.multi);
        this.records.set(token, multiRecord);
      }
      token = provider;
      multiRecord.multi.push(provider);
    } else {
      if (ngDevMode) {
        const existing = this.records.get(token);
        if (existing && existing.multi !== undefined) {
          throwMixedMultiProviderError();
        }
      }
    }
    this.records.set(token, record);
  }
  hydrate(token, record) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      if (ngDevMode && record.value === CIRCULAR) {
        throwCyclicDependencyError(stringify(token));
      } else if (record.value === NOT_YET) {
        record.value = CIRCULAR;
        if (ngDevMode) {
          runInInjectorProfilerContext(this, token, () => {
            record.value = record.factory();
            emitInstanceCreatedByInjectorEvent(record.value);
          });
        } else {
          record.value = record.factory();
        }
      }
      if (typeof record.value === 'object' && record.value && hasOnDestroy(record.value)) {
        this._ngOnDestroyHooks.add(record.value);
      }
      return record.value;
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
  injectableDefInScope(def) {
    if (!def.providedIn) {
      return false;
    }
    const providedIn = resolveForwardRef(def.providedIn);
    if (typeof providedIn === 'string') {
      return providedIn === 'any' || this.scopes.has(providedIn);
    } else {
      return this.injectorDefTypes.has(providedIn);
    }
  }
  removeOnDestroy(callback) {
    const destroyCBIdx = this._onDestroyHooks.indexOf(callback);
    if (destroyCBIdx !== -1) {
      this._onDestroyHooks.splice(destroyCBIdx, 1);
    }
  }
}
function injectableDefOrInjectorDefFactory(token) {
  // Most tokens will have an injectable def directly on them, which specifies a factory directly.
  const injectableDef = getInjectableDef(token);
  const factory = injectableDef !== null ? injectableDef.factory : getFactoryDef(token);
  if (factory !== null) {
    return factory;
  }
  // InjectionTokens should have an injectable def (ɵprov) and thus should be handled above.
  // If it's missing that, it's an error.
  if (token instanceof InjectionToken) {
    throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode && `Token ${stringify(token)} is missing a ɵprov definition.`);
  }
  // Undecorated types can sometimes be created if they have no constructor arguments.
  if (token instanceof Function) {
    return getUndecoratedInjectableFactory(token);
  }
  // There was no way to resolve a factory for this token.
  throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode && 'unreachable');
}
function getUndecoratedInjectableFactory(token) {
  // If the token has parameters then it has dependencies that we cannot resolve implicitly.
  const paramLength = token.length;
  if (paramLength > 0) {
    throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode && `Can't resolve all parameters for ${stringify(token)}: (${newArray(paramLength, '?').join(', ')}).`);
  }
  // The constructor function appears to have no parameters.
  // This might be because it inherits from a super-class. In which case, use an injectable
  // def from an ancestor if there is one.
  // Otherwise this really is a simple class with no dependencies, so return a factory that
  // just instantiates the zero-arg constructor.
  const inheritedInjectableDef = getInheritedInjectableDef(token);
  if (inheritedInjectableDef !== null) {
    return () => inheritedInjectableDef.factory(token);
  } else {
    return () => new token();
  }
}
function providerToRecord(provider) {
  if (isValueProvider(provider)) {
    return makeRecord(undefined, provider.useValue);
  } else {
    const factory = providerToFactory(provider);
    return makeRecord(factory, NOT_YET);
  }
}
/**
 * Converts a `SingleProvider` into a factory function.
 *
 * @param provider provider to convert to factory
 */
function providerToFactory(provider, ngModuleType, providers) {
  let factory = undefined;
  if (ngDevMode && isEnvironmentProviders(provider)) {
    throwInvalidProviderError(undefined, providers, provider);
  }
  if (isTypeProvider(provider)) {
    const unwrappedProvider = resolveForwardRef(provider);
    return getFactoryDef(unwrappedProvider) || injectableDefOrInjectorDefFactory(unwrappedProvider);
  } else {
    if (isValueProvider(provider)) {
      factory = () => resolveForwardRef(provider.useValue);
    } else if (isFactoryProvider(provider)) {
      factory = () => provider.useFactory(...injectArgs(provider.deps || []));
    } else if (isExistingProvider(provider)) {
      factory = () => ɵɵinject(resolveForwardRef(provider.useExisting));
    } else {
      const classRef = resolveForwardRef(provider && (provider.useClass || provider.provide));
      if (ngDevMode && !classRef) {
        throwInvalidProviderError(ngModuleType, providers, provider);
      }
      if (hasDeps(provider)) {
        factory = () => new classRef(...injectArgs(provider.deps));
      } else {
        return getFactoryDef(classRef) || injectableDefOrInjectorDefFactory(classRef);
      }
    }
  }
  return factory;
}
function makeRecord(factory, value, multi = false) {
  return {
    factory: factory,
    value: value,
    multi: multi ? [] : undefined
  };
}
function hasDeps(value) {
  return !!value.deps;
}
function hasOnDestroy(value) {
  return value !== null && typeof value === 'object' && typeof value.ngOnDestroy === 'function';
}
function couldBeInjectableType(value) {
  return typeof value === 'function' || typeof value === 'object' && value instanceof InjectionToken;
}
function forEachSingleProvider(providers, fn) {
  for (const provider of providers) {
    if (Array.isArray(provider)) {
      forEachSingleProvider(provider, fn);
    } else if (provider && isEnvironmentProviders(provider)) {
      forEachSingleProvider(provider.ɵproviders, fn);
    } else {
      fn(provider);
    }
  }
}

/**
 * Runs the given function in the [context](guide/dependency-injection-context) of the given
 * `Injector`.
 *
 * Within the function's stack frame, [`inject`](api/core/inject) can be used to inject dependencies
 * from the given `Injector`. Note that `inject` is only usable synchronously, and cannot be used in
 * any asynchronous callbacks or after any `await` points.
 *
 * @param injector the injector which will satisfy calls to [`inject`](api/core/inject) while `fn`
 *     is executing
 * @param fn the closure to be run in the context of `injector`
 * @returns the return value of the function, if any
 * @publicApi
 */
function runInInjectionContext(injector, fn) {
  if (injector instanceof R3Injector) {
    injector.assertNotDestroyed();
  }
  let prevInjectorProfilerContext;
  if (ngDevMode) {
    prevInjectorProfilerContext = setInjectorProfilerContext({
      injector,
      token: null
    });
  }
  const prevInjector = setCurrentInjector(injector);
  const previousInjectImplementation = setInjectImplementation(undefined);
  try {
    return fn();
  } finally {
    setCurrentInjector(prevInjector);
    ngDevMode && setInjectorProfilerContext(prevInjectorProfilerContext);
    setInjectImplementation(previousInjectImplementation);
  }
}
/**
 * Whether the current stack frame is inside an injection context.
 */
function isInInjectionContext() {
  return getInjectImplementation() !== undefined || getCurrentInjector() != null;
}
/**
 * Asserts that the current stack frame is within an [injection
 * context](guide/dependency-injection-context) and has access to `inject`.
 *
 * @param debugFn a reference to the function making the assertion (used for the error message).
 *
 * @publicApi
 */
function assertInInjectionContext(debugFn) {
  // Taking a `Function` instead of a string name here prevents the unminified name of the function
  // from being retained in the bundle regardless of minification.
  if (!isInInjectionContext()) {
    throw new RuntimeError(-203 /* RuntimeErrorCode.MISSING_INJECTION_CONTEXT */, ngDevMode && debugFn.name + '() can only be used within an injection context such as a constructor, a factory function, a field initializer, or a function used with `runInInjectionContext`');
  }
}
var FactoryTarget;
(function (FactoryTarget) {
  FactoryTarget[FactoryTarget["Directive"] = 0] = "Directive";
  FactoryTarget[FactoryTarget["Component"] = 1] = "Component";
  FactoryTarget[FactoryTarget["Injectable"] = 2] = "Injectable";
  FactoryTarget[FactoryTarget["Pipe"] = 3] = "Pipe";
  FactoryTarget[FactoryTarget["NgModule"] = 4] = "NgModule";
})(FactoryTarget || (FactoryTarget = {}));
var R3TemplateDependencyKind;
(function (R3TemplateDependencyKind) {
  R3TemplateDependencyKind[R3TemplateDependencyKind["Directive"] = 0] = "Directive";
  R3TemplateDependencyKind[R3TemplateDependencyKind["Pipe"] = 1] = "Pipe";
  R3TemplateDependencyKind[R3TemplateDependencyKind["NgModule"] = 2] = "NgModule";
})(R3TemplateDependencyKind || (R3TemplateDependencyKind = {}));
var ViewEncapsulation;
(function (ViewEncapsulation) {
  ViewEncapsulation[ViewEncapsulation["Emulated"] = 0] = "Emulated";
  // Historically the 1 value was for `Native` encapsulation which has been removed as of v11.
  ViewEncapsulation[ViewEncapsulation["None"] = 2] = "None";
  ViewEncapsulation[ViewEncapsulation["ShadowDom"] = 3] = "ShadowDom";
})(ViewEncapsulation || (ViewEncapsulation = {}));
function getCompilerFacade(request) {
  const globalNg = _global['ng'];
  if (globalNg && globalNg.ɵcompilerFacade) {
    return globalNg.ɵcompilerFacade;
  }
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    // Log the type as an error so that a developer can easily navigate to the type from the
    // console.
    console.error(`JIT compilation failed for ${request.kind}`, request.type);
    let message = `The ${request.kind} '${request.type.name}' needs to be compiled using the JIT compiler, but '@angular/compiler' is not available.\n\n`;
    if (request.usage === 1 /* JitCompilerUsage.PartialDeclaration */) {
      message += `The ${request.kind} is part of a library that has been partially compiled.\n`;
      message += `However, the Angular Linker has not processed the library such that JIT compilation is used as fallback.\n`;
      message += '\n';
      message += `Ideally, the library is processed using the Angular Linker to become fully AOT compiled.\n`;
    } else {
      message += `JIT compilation is discouraged for production use-cases! Consider using AOT mode instead.\n`;
    }
    message += `Alternatively, the JIT compiler should be loaded by bootstrapping using '@angular/platform-browser-dynamic' or '@angular/platform-server',\n`;
    message += `or manually provide the compiler with 'import "@angular/compiler";' before bootstrapping.`;
    throw new Error(message);
  } else {
    throw new Error('JIT compiler unavailable');
  }
}

/**
 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
 *
 * This should be kept up to date with the public exports of @angular/core.
 */
const angularCoreDiEnv = {
  'ɵɵdefineInjectable': ɵɵdefineInjectable,
  'ɵɵdefineInjector': ɵɵdefineInjector,
  'ɵɵinject': ɵɵinject,
  'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
  'resolveForwardRef': resolveForwardRef
};

/**
 * @description
 *
 * Represents a type that a Component or other object is instances of.
 *
 * An example of a `Type` is `MyCustomComponent` class, which in JavaScript is represented by
 * the `MyCustomComponent` constructor function.
 *
 * @publicApi
 */
const Type = Function;
function isType(v) {
  return typeof v === 'function';
}

/*
 * #########################
 * Attention: These Regular expressions have to hold even if the code is minified!
 * ##########################
 */
/**
 * Regular expression that detects pass-through constructors for ES5 output. This Regex
 * intends to capture the common delegation pattern emitted by TypeScript and Babel. Also
 * it intends to capture the pattern where existing constructors have been downleveled from
 * ES2015 to ES5 using TypeScript w/ downlevel iteration. e.g.
 *
 * ```
 *   function MyClass() {
 *     var _this = _super.apply(this, arguments) || this;
 * ```
 *
 * downleveled to ES5 with `downlevelIteration` for TypeScript < 4.2:
 * ```
 *   function MyClass() {
 *     var _this = _super.apply(this, __spread(arguments)) || this;
 * ```
 *
 * or downleveled to ES5 with `downlevelIteration` for TypeScript >= 4.2:
 * ```
 *   function MyClass() {
 *     var _this = _super.apply(this, __spreadArray([], __read(arguments), false)) || this;
 * ```
 *
 * More details can be found in: https://github.com/angular/angular/issues/38453.
 */
const ES5_DELEGATE_CTOR = /^function\s+\S+\(\)\s*{[\s\S]+\.apply\(this,\s*(arguments|(?:[^()]+\(\[\],)?[^()]+\(arguments\).*)\)/;
/** Regular expression that detects ES2015 classes which extend from other classes. */
const ES2015_INHERITED_CLASS = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{/;
/**
 * Regular expression that detects ES2015 classes which extend from other classes and
 * have an explicit constructor defined.
 */
const ES2015_INHERITED_CLASS_WITH_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(/;
/**
 * Regular expression that detects ES2015 classes which extend from other classes
 * and inherit a constructor.
 */
const ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR = /^class\s+[A-Za-z\d$_]*\s*extends\s+[^{]+{[\s\S]*constructor\s*\(\)\s*{[^}]*super\(\.\.\.arguments\)/;
/**
 * Determine whether a stringified type is a class which delegates its constructor
 * to its parent.
 *
 * This is not trivial since compiled code can actually contain a constructor function
 * even if the original source code did not. For instance, when the child class contains
 * an initialized instance property.
 */
function isDelegateCtor(typeStr) {
  return ES5_DELEGATE_CTOR.test(typeStr) || ES2015_INHERITED_CLASS_WITH_DELEGATE_CTOR.test(typeStr) || ES2015_INHERITED_CLASS.test(typeStr) && !ES2015_INHERITED_CLASS_WITH_CTOR.test(typeStr);
}
class ReflectionCapabilities {
  constructor(reflect) {
    this._reflect = reflect || _global['Reflect'];
  }
  factory(t) {
    return (...args) => new t(...args);
  }
  /** @internal */
  _zipTypesAndAnnotations(paramTypes, paramAnnotations) {
    let result;
    if (typeof paramTypes === 'undefined') {
      result = newArray(paramAnnotations.length);
    } else {
      result = newArray(paramTypes.length);
    }
    for (let i = 0; i < result.length; i++) {
      // TS outputs Object for parameters without types, while Traceur omits
      // the annotations. For now we preserve the Traceur behavior to aid
      // migration, but this can be revisited.
      if (typeof paramTypes === 'undefined') {
        result[i] = [];
      } else if (paramTypes[i] && paramTypes[i] != Object) {
        result[i] = [paramTypes[i]];
      } else {
        result[i] = [];
      }
      if (paramAnnotations && paramAnnotations[i] != null) {
        result[i] = result[i].concat(paramAnnotations[i]);
      }
    }
    return result;
  }
  _ownParameters(type, parentCtor) {
    const typeStr = type.toString();
    // If we have no decorators, we only have function.length as metadata.
    // In that case, to detect whether a child class declared an own constructor or not,
    // we need to look inside of that constructor to check whether it is
    // just calling the parent.
    // This also helps to work around for https://github.com/Microsoft/TypeScript/issues/12439
    // that sets 'design:paramtypes' to []
    // if a class inherits from another class but has no ctor declared itself.
    if (isDelegateCtor(typeStr)) {
      return null;
    }
    // Prefer the direct API.
    if (type.parameters && type.parameters !== parentCtor.parameters) {
      return type.parameters;
    }
    // API of tsickle for lowering decorators to properties on the class.
    const tsickleCtorParams = type.ctorParameters;
    if (tsickleCtorParams && tsickleCtorParams !== parentCtor.ctorParameters) {
      // Newer tsickle uses a function closure
      // Retain the non-function case for compatibility with older tsickle
      const ctorParameters = typeof tsickleCtorParams === 'function' ? tsickleCtorParams() : tsickleCtorParams;
      const paramTypes = ctorParameters.map(ctorParam => ctorParam && ctorParam.type);
      const paramAnnotations = ctorParameters.map(ctorParam => ctorParam && convertTsickleDecoratorIntoMetadata(ctorParam.decorators));
      return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
    }
    // API for metadata created by invoking the decorators.
    const paramAnnotations = type.hasOwnProperty(PARAMETERS) && type[PARAMETERS];
    const paramTypes = this._reflect && this._reflect.getOwnMetadata && this._reflect.getOwnMetadata('design:paramtypes', type);
    if (paramTypes || paramAnnotations) {
      return this._zipTypesAndAnnotations(paramTypes, paramAnnotations);
    }
    // If a class has no decorators, at least create metadata
    // based on function.length.
    // Note: We know that this is a real constructor as we checked
    // the content of the constructor above.
    return newArray(type.length);
  }
  parameters(type) {
    // Note: only report metadata if we have at least one class decorator
    // to stay in sync with the static reflector.
    if (!isType(type)) {
      return [];
    }
    const parentCtor = getParentCtor(type);
    let parameters = this._ownParameters(type, parentCtor);
    if (!parameters && parentCtor !== Object) {
      parameters = this.parameters(parentCtor);
    }
    return parameters || [];
  }
  _ownAnnotations(typeOrFunc, parentCtor) {
    // Prefer the direct API.
    if (typeOrFunc.annotations && typeOrFunc.annotations !== parentCtor.annotations) {
      let annotations = typeOrFunc.annotations;
      if (typeof annotations === 'function' && annotations.annotations) {
        annotations = annotations.annotations;
      }
      return annotations;
    }
    // API of tsickle for lowering decorators to properties on the class.
    if (typeOrFunc.decorators && typeOrFunc.decorators !== parentCtor.decorators) {
      return convertTsickleDecoratorIntoMetadata(typeOrFunc.decorators);
    }
    // API for metadata created by invoking the decorators.
    if (typeOrFunc.hasOwnProperty(ANNOTATIONS)) {
      return typeOrFunc[ANNOTATIONS];
    }
    return null;
  }
  annotations(typeOrFunc) {
    if (!isType(typeOrFunc)) {
      return [];
    }
    const parentCtor = getParentCtor(typeOrFunc);
    const ownAnnotations = this._ownAnnotations(typeOrFunc, parentCtor) || [];
    const parentAnnotations = parentCtor !== Object ? this.annotations(parentCtor) : [];
    return parentAnnotations.concat(ownAnnotations);
  }
  _ownPropMetadata(typeOrFunc, parentCtor) {
    // Prefer the direct API.
    if (typeOrFunc.propMetadata && typeOrFunc.propMetadata !== parentCtor.propMetadata) {
      let propMetadata = typeOrFunc.propMetadata;
      if (typeof propMetadata === 'function' && propMetadata.propMetadata) {
        propMetadata = propMetadata.propMetadata;
      }
      return propMetadata;
    }
    // API of tsickle for lowering decorators to properties on the class.
    if (typeOrFunc.propDecorators && typeOrFunc.propDecorators !== parentCtor.propDecorators) {
      const propDecorators = typeOrFunc.propDecorators;
      const propMetadata = {};
      Object.keys(propDecorators).forEach(prop => {
        propMetadata[prop] = convertTsickleDecoratorIntoMetadata(propDecorators[prop]);
      });
      return propMetadata;
    }
    // API for metadata created by invoking the decorators.
    if (typeOrFunc.hasOwnProperty(PROP_METADATA)) {
      return typeOrFunc[PROP_METADATA];
    }
    return null;
  }
  propMetadata(typeOrFunc) {
    if (!isType(typeOrFunc)) {
      return {};
    }
    const parentCtor = getParentCtor(typeOrFunc);
    const propMetadata = {};
    if (parentCtor !== Object) {
      const parentPropMetadata = this.propMetadata(parentCtor);
      Object.keys(parentPropMetadata).forEach(propName => {
        propMetadata[propName] = parentPropMetadata[propName];
      });
    }
    const ownPropMetadata = this._ownPropMetadata(typeOrFunc, parentCtor);
    if (ownPropMetadata) {
      Object.keys(ownPropMetadata).forEach(propName => {
        const decorators = [];
        if (propMetadata.hasOwnProperty(propName)) {
          decorators.push(...propMetadata[propName]);
        }
        decorators.push(...ownPropMetadata[propName]);
        propMetadata[propName] = decorators;
      });
    }
    return propMetadata;
  }
  ownPropMetadata(typeOrFunc) {
    if (!isType(typeOrFunc)) {
      return {};
    }
    return this._ownPropMetadata(typeOrFunc, getParentCtor(typeOrFunc)) || {};
  }
  hasLifecycleHook(type, lcProperty) {
    return type instanceof Type && lcProperty in type.prototype;
  }
}
function convertTsickleDecoratorIntoMetadata(decoratorInvocations) {
  if (!decoratorInvocations) {
    return [];
  }
  return decoratorInvocations.map(decoratorInvocation => {
    const decoratorType = decoratorInvocation.type;
    const annotationCls = decoratorType.annotationCls;
    const annotationArgs = decoratorInvocation.args ? decoratorInvocation.args : [];
    return new annotationCls(...annotationArgs);
  });
}
function getParentCtor(ctor) {
  const parentProto = ctor.prototype ? Object.getPrototypeOf(ctor.prototype) : null;
  const parentCtor = parentProto ? parentProto.constructor : null;
  // Note: We always use `Object` as the null value
  // to simplify checking later on.
  return parentCtor || Object;
}

// Below are constants for LView indices to help us look up LView members
// without having to remember the specific indices.
// Uglify will inline these when minifying so there shouldn't be a cost.
const HOST = 0;
const TVIEW = 1;
// Shared with LContainer
const FLAGS = 2;
const PARENT = 3;
const NEXT = 4;
const T_HOST = 5;
// End shared with LContainer
const HYDRATION = 6;
const CLEANUP = 7;
const CONTEXT = 8;
const INJECTOR = 9;
const ENVIRONMENT = 10;
const RENDERER = 11;
const CHILD_HEAD = 12;
const CHILD_TAIL = 13;
// FIXME(misko): Investigate if the three declarations aren't all same thing.
const DECLARATION_VIEW = 14;
const DECLARATION_COMPONENT_VIEW = 15;
const DECLARATION_LCONTAINER = 16;
const PREORDER_HOOK_FLAGS = 17;
const QUERIES = 18;
const ID = 19;
const EMBEDDED_VIEW_INJECTOR = 20;
const ON_DESTROY_HOOKS = 21;
const EFFECTS_TO_SCHEDULE = 22;
const REACTIVE_TEMPLATE_CONSUMER = 23;
/**
 * Size of LView's header. Necessary to adjust for it when setting slots.
 *
 * IMPORTANT: `HEADER_OFFSET` should only be referred to the in the `ɵɵ*` instructions to translate
 * instruction index into `LView` index. All other indexes should be in the `LView` index space and
 * there should be no need to refer to `HEADER_OFFSET` anywhere else.
 */
const HEADER_OFFSET = 25;

/**
 * Special location which allows easy identification of type. If we have an array which was
 * retrieved from the `LView` and that array has `true` at `TYPE` location, we know it is
 * `LContainer`.
 */
const TYPE = 1;
/**
 * Below are constants for LContainer indices to help us look up LContainer members
 * without having to remember the specific indices.
 * Uglify will inline these when minifying so there shouldn't be a cost.
 */
// FLAGS, PARENT, NEXT, and T_HOST are indices 2, 3, 4, and 5
// As we already have these constants in LView, we don't need to re-create them.
const DEHYDRATED_VIEWS = 6;
const NATIVE = 7;
const VIEW_REFS = 8;
const MOVED_VIEWS = 9;
/**
 * Size of LContainer's header. Represents the index after which all views in the
 * container will be inserted. We need to keep a record of current views so we know
 * which views are already in the DOM (and don't need to be re-added) and so we can
 * remove views from the DOM when they are no longer required.
 */
const CONTAINER_HEADER_OFFSET = 10;
/** Flags associated with an LContainer (saved in LContainer[FLAGS]) */
var LContainerFlags;
(function (LContainerFlags) {
  LContainerFlags[LContainerFlags["None"] = 0] = "None";
  /**
   * Flag to signify that this `LContainer` may have transplanted views which need to be change
   * detected. (see: `LView[DECLARATION_COMPONENT_VIEW])`.
   *
   * This flag, once set, is never unset for the `LContainer`.
   */
  LContainerFlags[LContainerFlags["HasTransplantedViews"] = 2] = "HasTransplantedViews";
})(LContainerFlags || (LContainerFlags = {}));

/**
 * True if `value` is `LView`.
 * @param value wrapped value of `RNode`, `LView`, `LContainer`
 */
function isLView(value) {
  return Array.isArray(value) && typeof value[TYPE] === 'object';
}
/**
 * True if `value` is `LContainer`.
 * @param value wrapped value of `RNode`, `LView`, `LContainer`
 */
function isLContainer(value) {
  return Array.isArray(value) && value[TYPE] === true;
}
function isContentQueryHost(tNode) {
  return (tNode.flags & 4 /* TNodeFlags.hasContentQuery */) !== 0;
}
function isComponentHost(tNode) {
  return tNode.componentOffset > -1;
}
function isDirectiveHost(tNode) {
  return (tNode.flags & 1 /* TNodeFlags.isDirectiveHost */) === 1 /* TNodeFlags.isDirectiveHost */;
}
function isComponentDef(def) {
  return !!def.template;
}
function isRootView(target) {
  return (target[FLAGS] & 512 /* LViewFlags.IsRoot */) !== 0;
}
function isProjectionTNode(tNode) {
  return (tNode.type & 16 /* TNodeType.Projection */) === 16 /* TNodeType.Projection */;
}
function hasI18n(lView) {
  return (lView[FLAGS] & 32 /* LViewFlags.HasI18n */) === 32 /* LViewFlags.HasI18n */;
}
function isDestroyed(lView) {
  return (lView[FLAGS] & 256 /* LViewFlags.Destroyed */) === 256 /* LViewFlags.Destroyed */;
}

// [Assert functions do not constraint type when they are guarded by a truthy
// expression.](https://github.com/microsoft/TypeScript/issues/37295)
function assertTNodeForLView(tNode, lView) {
  assertTNodeForTView(tNode, lView[TVIEW]);
}
function assertTNodeForTView(tNode, tView) {
  assertTNode(tNode);
  const tData = tView.data;
  for (let i = HEADER_OFFSET; i < tData.length; i++) {
    if (tData[i] === tNode) {
      return;
    }
  }
  throwError('This TNode does not belong to this TView.');
}
function assertTNode(tNode) {
  assertDefined(tNode, 'TNode must be defined');
  if (!(tNode && typeof tNode === 'object' && tNode.hasOwnProperty('directiveStylingLast'))) {
    throwError('Not of type TNode, got: ' + tNode);
  }
}
function assertTIcu(tIcu) {
  assertDefined(tIcu, 'Expected TIcu to be defined');
  if (!(typeof tIcu.currentCaseLViewIndex === 'number')) {
    throwError('Object is not of TIcu type.');
  }
}
function assertComponentType(actual, msg = 'Type passed in is not ComponentType, it does not have \'ɵcmp\' property.') {
  if (!getComponentDef(actual)) {
    throwError(msg);
  }
}
function assertNgModuleType(actual, msg = 'Type passed in is not NgModuleType, it does not have \'ɵmod\' property.') {
  if (!getNgModuleDef(actual)) {
    throwError(msg);
  }
}
function assertCurrentTNodeIsParent(isParent) {
  assertEqual(isParent, true, 'currentTNode should be a parent');
}
function assertHasParent(tNode) {
  assertDefined(tNode, 'currentTNode should exist!');
  assertDefined(tNode.parent, 'currentTNode should have a parent');
}
function assertLContainer(value) {
  assertDefined(value, 'LContainer must be defined');
  assertEqual(isLContainer(value), true, 'Expecting LContainer');
}
function assertLViewOrUndefined(value) {
  value && assertEqual(isLView(value), true, 'Expecting LView or undefined or null');
}
function assertLView(value) {
  assertDefined(value, 'LView must be defined');
  assertEqual(isLView(value), true, 'Expecting LView');
}
function assertFirstCreatePass(tView, errMessage) {
  assertEqual(tView.firstCreatePass, true, errMessage || 'Should only be called in first create pass.');
}
function assertFirstUpdatePass(tView, errMessage) {
  assertEqual(tView.firstUpdatePass, true, errMessage || 'Should only be called in first update pass.');
}
/**
 * This is a basic sanity check that an object is probably a directive def. DirectiveDef is
 * an interface, so we can't do a direct instanceof check.
 */
function assertDirectiveDef(obj) {
  if (obj.type === undefined || obj.selectors == undefined || obj.inputs === undefined) {
    throwError(`Expected a DirectiveDef/ComponentDef and this object does not seem to have the expected shape.`);
  }
}
function assertIndexInDeclRange(tView, index) {
  assertBetween(HEADER_OFFSET, tView.bindingStartIndex, index);
}
function assertIndexInExpandoRange(lView, index) {
  const tView = lView[1];
  assertBetween(tView.expandoStartIndex, lView.length, index);
}
function assertBetween(lower, upper, index) {
  if (!(lower <= index && index < upper)) {
    throwError(`Index out of range (expecting ${lower} <= ${index} < ${upper})`);
  }
}
function assertProjectionSlots(lView, errMessage) {
  assertDefined(lView[DECLARATION_COMPONENT_VIEW], 'Component views should exist.');
  assertDefined(lView[DECLARATION_COMPONENT_VIEW][T_HOST].projection, errMessage || 'Components with projection nodes (<ng-content>) must have projection slots defined.');
}
function assertParentView(lView, errMessage) {
  assertDefined(lView, errMessage || 'Component views should always have a parent view (component\'s host view)');
}
function assertNoDuplicateDirectives(directives) {
  // The array needs at least two elements in order to have duplicates.
  if (directives.length < 2) {
    return;
  }
  const seenDirectives = new Set();
  for (const current of directives) {
    if (seenDirectives.has(current)) {
      throw new RuntimeError(309 /* RuntimeErrorCode.DUPLICATE_DIRECTIVE */, `Directive ${current.type.name} matches multiple times on the same element. ` + `Directives can only match an element once.`);
    }
    seenDirectives.add(current);
  }
}
/**
 * This is a basic sanity check that the `injectorIndex` seems to point to what looks like a
 * NodeInjector data structure.
 *
 * @param lView `LView` which should be checked.
 * @param injectorIndex index into the `LView` where the `NodeInjector` is expected.
 */
function assertNodeInjector(lView, injectorIndex) {
  assertIndexInExpandoRange(lView, injectorIndex);
  assertIndexInExpandoRange(lView, injectorIndex + 8 /* NodeInjectorOffset.PARENT */);
  assertNumber(lView[injectorIndex + 0], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 1], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 2], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 3], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 4], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 5], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 6], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 7], 'injectorIndex should point to a bloom filter');
  assertNumber(lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */], 'injectorIndex should point to parent injector');
}

/**
 * Represents a basic change from a previous to a new value for a single
 * property on a directive instance. Passed as a value in a
 * {@link SimpleChanges} object to the `ngOnChanges` hook.
 *
 * @see {@link OnChanges}
 *
 * @publicApi
 */
class SimpleChange {
  constructor(previousValue, currentValue, firstChange) {
    this.previousValue = previousValue;
    this.currentValue = currentValue;
    this.firstChange = firstChange;
  }
  /**
   * Check whether the new value is the first value assigned.
   */
  isFirstChange() {
    return this.firstChange;
  }
}
function applyValueToInputField(instance, inputSignalNode, privateName, value) {
  if (inputSignalNode !== null) {
    inputSignalNode.applyValueToInputSignal(inputSignalNode, value);
  } else {
    instance[privateName] = value;
  }
}

/**
 * The NgOnChangesFeature decorates a component with support for the ngOnChanges
 * lifecycle hook, so it should be included in any component that implements
 * that hook.
 *
 * If the component or directive uses inheritance, the NgOnChangesFeature MUST
 * be included as a feature AFTER {@link InheritDefinitionFeature}, otherwise
 * inherited properties will not be propagated to the ngOnChanges lifecycle
 * hook.
 *
 * Example usage:
 *
 * ```
 * static ɵcmp = defineComponent({
 *   ...
 *   inputs: {name: 'publicName'},
 *   features: [NgOnChangesFeature]
 * });
 * ```
 *
 * @codeGenApi
 */
function ɵɵNgOnChangesFeature() {
  return NgOnChangesFeatureImpl;
}
function NgOnChangesFeatureImpl(definition) {
  if (definition.type.prototype.ngOnChanges) {
    definition.setInput = ngOnChangesSetInput;
  }
  return rememberChangeHistoryAndInvokeOnChangesHook;
}
// This option ensures that the ngOnChanges lifecycle hook will be inherited
// from superclasses (in InheritDefinitionFeature).
/** @nocollapse */
// tslint:disable-next-line:no-toplevel-property-access
ɵɵNgOnChangesFeature.ngInherit = true;
/**
 * This is a synthetic lifecycle hook which gets inserted into `TView.preOrderHooks` to simulate
 * `ngOnChanges`.
 *
 * The hook reads the `NgSimpleChangesStore` data from the component instance and if changes are
 * found it invokes `ngOnChanges` on the component instance.
 *
 * @param this Component instance. Because this function gets inserted into `TView.preOrderHooks`,
 *     it is guaranteed to be called with component instance.
 */
function rememberChangeHistoryAndInvokeOnChangesHook() {
  const simpleChangesStore = getSimpleChangesStore(this);
  const current = simpleChangesStore?.current;
  if (current) {
    const previous = simpleChangesStore.previous;
    if (previous === EMPTY_OBJ) {
      simpleChangesStore.previous = current;
    } else {
      // New changes are copied to the previous store, so that we don't lose history for inputs
      // which were not changed this time
      for (let key in current) {
        previous[key] = current[key];
      }
    }
    simpleChangesStore.current = null;
    this.ngOnChanges(current);
  }
}
function ngOnChangesSetInput(instance, inputSignalNode, value, publicName, privateName) {
  const declaredName = this.declaredInputs[publicName];
  ngDevMode && assertString(declaredName, 'Name of input in ngOnChanges has to be a string');
  const simpleChangesStore = getSimpleChangesStore(instance) || setSimpleChangesStore(instance, {
    previous: EMPTY_OBJ,
    current: null
  });
  const current = simpleChangesStore.current || (simpleChangesStore.current = {});
  const previous = simpleChangesStore.previous;
  const previousChange = previous[declaredName];
  current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
  applyValueToInputField(instance, inputSignalNode, privateName, value);
}
const SIMPLE_CHANGES_STORE = '__ngSimpleChanges__';
function getSimpleChangesStore(instance) {
  return instance[SIMPLE_CHANGES_STORE] || null;
}
function setSimpleChangesStore(instance, store) {
  return instance[SIMPLE_CHANGES_STORE] = store;
}
let profilerCallback = null;
/**
 * Sets the callback function which will be invoked before and after performing certain actions at
 * runtime (for example, before and after running change detection).
 *
 * Warning: this function is *INTERNAL* and should not be relied upon in application's code.
 * The contract of the function might be changed in any release and/or the function can be removed
 * completely.
 *
 * @param profiler function provided by the caller or null value to disable profiling.
 */
const setProfiler = profiler => {
  profilerCallback = profiler;
};
/**
 * Profiler function which wraps user code executed by the runtime.
 *
 * @param event ProfilerEvent corresponding to the execution context
 * @param instance component instance
 * @param hookOrListener lifecycle hook function or output listener. The value depends on the
 *  execution context
 * @returns
 */
const profiler = function (event, instance, hookOrListener) {
  if (profilerCallback != null /* both `null` and `undefined` */) {
    profilerCallback(event, instance, hookOrListener);
  }
};
const SVG_NAMESPACE = 'svg';
const MATH_ML_NAMESPACE = 'math';

// TODO(atscott): flip default internally ASAP and externally for v18 (#52928)
let _ensureDirtyViewsAreAlwaysReachable = false;
function getEnsureDirtyViewsAreAlwaysReachable() {
  return _ensureDirtyViewsAreAlwaysReachable;
}
function setEnsureDirtyViewsAreAlwaysReachable(v) {
  _ensureDirtyViewsAreAlwaysReachable = v;
}

/**
 * For efficiency reasons we often put several different data types (`RNode`, `LView`, `LContainer`)
 * in same location in `LView`. This is because we don't want to pre-allocate space for it
 * because the storage is sparse. This file contains utilities for dealing with such data types.
 *
 * How do we know what is stored at a given location in `LView`.
 * - `Array.isArray(value) === false` => `RNode` (The normal storage value)
 * - `Array.isArray(value) === true` => then the `value[0]` represents the wrapped value.
 *   - `typeof value[TYPE] === 'object'` => `LView`
 *      - This happens when we have a component at a given location
 *   - `typeof value[TYPE] === true` => `LContainer`
 *      - This happens when we have `LContainer` binding at a given location.
 *
 *
 * NOTE: it is assumed that `Array.isArray` and `typeof` operations are very efficient.
 */
/**
 * Returns `RNode`.
 * @param value wrapped value of `RNode`, `LView`, `LContainer`
 */
function unwrapRNode(value) {
  while (Array.isArray(value)) {
    value = value[HOST];
  }
  return value;
}
/**
 * Returns `LView` or `null` if not found.
 * @param value wrapped value of `RNode`, `LView`, `LContainer`
 */
function unwrapLView(value) {
  while (Array.isArray(value)) {
    // This check is same as `isLView()` but we don't call at as we don't want to call
    // `Array.isArray()` twice and give JITer more work for inlining.
    if (typeof value[TYPE] === 'object') return value;
    value = value[HOST];
  }
  return null;
}
/**
 * Retrieves an element value from the provided `viewData`, by unwrapping
 * from any containers, component views, or style contexts.
 */
function getNativeByIndex(index, lView) {
  ngDevMode && assertIndexInRange(lView, index);
  ngDevMode && assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Expected to be past HEADER_OFFSET');
  return unwrapRNode(lView[index]);
}
/**
 * Retrieve an `RNode` for a given `TNode` and `LView`.
 *
 * This function guarantees in dev mode to retrieve a non-null `RNode`.
 *
 * @param tNode
 * @param lView
 */
function getNativeByTNode(tNode, lView) {
  ngDevMode && assertTNodeForLView(tNode, lView);
  ngDevMode && assertIndexInRange(lView, tNode.index);
  const node = unwrapRNode(lView[tNode.index]);
  return node;
}
/**
 * Retrieve an `RNode` or `null` for a given `TNode` and `LView`.
 *
 * Some `TNode`s don't have associated `RNode`s. For example `Projection`
 *
 * @param tNode
 * @param lView
 */
function getNativeByTNodeOrNull(tNode, lView) {
  const index = tNode === null ? -1 : tNode.index;
  if (index !== -1) {
    ngDevMode && assertTNodeForLView(tNode, lView);
    const node = unwrapRNode(lView[index]);
    return node;
  }
  return null;
}
// fixme(misko): The return Type should be `TNode|null`
function getTNode(tView, index) {
  ngDevMode && assertGreaterThan(index, -1, 'wrong index for TNode');
  ngDevMode && assertLessThan(index, tView.data.length, 'wrong index for TNode');
  const tNode = tView.data[index];
  ngDevMode && tNode !== null && assertTNode(tNode);
  return tNode;
}
/** Retrieves a value from any `LView` or `TData`. */
function load(view, index) {
  ngDevMode && assertIndexInRange(view, index);
  return view[index];
}
function getComponentLViewByIndex(nodeIndex, hostView) {
  // Could be an LView or an LContainer. If LContainer, unwrap to find LView.
  ngDevMode && assertIndexInRange(hostView, nodeIndex);
  const slotValue = hostView[nodeIndex];
  const lView = isLView(slotValue) ? slotValue : slotValue[HOST];
  return lView;
}
/** Checks whether a given view is in creation mode */
function isCreationMode(view) {
  return (view[FLAGS] & 4 /* LViewFlags.CreationMode */) === 4 /* LViewFlags.CreationMode */;
}
/**
 * Returns a boolean for whether the view is attached to the change detection tree.
 *
 * Note: This determines whether a view should be checked, not whether it's inserted
 * into a container. For that, you'll want `viewAttachedToContainer` below.
 */
function viewAttachedToChangeDetector(view) {
  return (view[FLAGS] & 128 /* LViewFlags.Attached */) === 128 /* LViewFlags.Attached */;
}
/** Returns a boolean for whether the view is attached to a container. */
function viewAttachedToContainer(view) {
  return isLContainer(view[PARENT]);
}
function getConstant(consts, index) {
  if (index === null || index === undefined) return null;
  ngDevMode && assertIndexInRange(consts, index);
  return consts[index];
}
/**
 * Resets the pre-order hook flags of the view.
 * @param lView the LView on which the flags are reset
 */
function resetPreOrderHookFlags(lView) {
  lView[PREORDER_HOOK_FLAGS] = 0;
}
/**
 * Adds the `RefreshView` flag from the lView and updates HAS_CHILD_VIEWS_TO_REFRESH flag of
 * parents.
 */
function markViewForRefresh(lView) {
  if (lView[FLAGS] & 1024 /* LViewFlags.RefreshView */) {
    return;
  }
  lView[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
  if (viewAttachedToChangeDetector(lView)) {
    markAncestorsForTraversal(lView);
  }
}
/**
 * Walks up the LView hierarchy.
 * @param nestingLevel Number of times to walk up in hierarchy.
 * @param currentView View from which to start the lookup.
 */
function walkUpViews(nestingLevel, currentView) {
  while (nestingLevel > 0) {
    ngDevMode && assertDefined(currentView[DECLARATION_VIEW], 'Declaration view should be defined if nesting level is greater than 0.');
    currentView = currentView[DECLARATION_VIEW];
    nestingLevel--;
  }
  return currentView;
}
function requiresRefreshOrTraversal(lView) {
  return !!(lView[FLAGS] & (1024 /* LViewFlags.RefreshView */ | 8192 /* LViewFlags.HasChildViewsToRefresh */) || lView[REACTIVE_TEMPLATE_CONSUMER]?.dirty);
}
/**
 * Updates the `HasChildViewsToRefresh` flag on the parents of the `LView` as well as the
 * parents above.
 */
function updateAncestorTraversalFlagsOnAttach(lView) {
  lView[ENVIRONMENT].changeDetectionScheduler?.notify(1 /* NotificationType.AfterRenderHooks */);
  // TODO(atscott): Simplify if...else cases once getEnsureDirtyViewsAreAlwaysReachable is always
  // `true`. When we attach a view that's marked `Dirty`, we should ensure that it is reached during
  // the next CD traversal so we add the `RefreshView` flag and mark ancestors accordingly.
  if (requiresRefreshOrTraversal(lView)) {
    markAncestorsForTraversal(lView);
  } else if (lView[FLAGS] & 64 /* LViewFlags.Dirty */) {
    if (getEnsureDirtyViewsAreAlwaysReachable()) {
      lView[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
      markAncestorsForTraversal(lView);
    } else {
      lView[ENVIRONMENT].changeDetectionScheduler?.notify();
    }
  }
}
/**
 * Ensures views above the given `lView` are traversed during change detection even when they are
 * not dirty.
 *
 * This is done by setting the `HAS_CHILD_VIEWS_TO_REFRESH` flag up to the root, stopping when the
 * flag is already `true` or the `lView` is detached.
 */
function markAncestorsForTraversal(lView) {
  lView[ENVIRONMENT].changeDetectionScheduler?.notify();
  let parent = getLViewParent(lView);
  while (parent !== null) {
    // We stop adding markers to the ancestors once we reach one that already has the marker. This
    // is to avoid needlessly traversing all the way to the root when the marker already exists.
    if (parent[FLAGS] & 8192 /* LViewFlags.HasChildViewsToRefresh */) {
      break;
    }
    parent[FLAGS] |= 8192 /* LViewFlags.HasChildViewsToRefresh */;
    if (!viewAttachedToChangeDetector(parent)) {
      break;
    }
    parent = getLViewParent(parent);
  }
}
/**
 * Stores a LView-specific destroy callback.
 */
function storeLViewOnDestroy(lView, onDestroyCallback) {
  if ((lView[FLAGS] & 256 /* LViewFlags.Destroyed */) === 256 /* LViewFlags.Destroyed */) {
    throw new RuntimeError(911 /* RuntimeErrorCode.VIEW_ALREADY_DESTROYED */, ngDevMode && 'View has already been destroyed.');
  }
  if (lView[ON_DESTROY_HOOKS] === null) {
    lView[ON_DESTROY_HOOKS] = [];
  }
  lView[ON_DESTROY_HOOKS].push(onDestroyCallback);
}
/**
 * Removes previously registered LView-specific destroy callback.
 */
function removeLViewOnDestroy(lView, onDestroyCallback) {
  if (lView[ON_DESTROY_HOOKS] === null) return;
  const destroyCBIdx = lView[ON_DESTROY_HOOKS].indexOf(onDestroyCallback);
  if (destroyCBIdx !== -1) {
    lView[ON_DESTROY_HOOKS].splice(destroyCBIdx, 1);
  }
}
/**
 * Gets the parent LView of the passed LView, if the PARENT is an LContainer, will get the parent of
 * that LContainer, which is an LView
 * @param lView the lView whose parent to get
 */
function getLViewParent(lView) {
  ngDevMode && assertLView(lView);
  const parent = lView[PARENT];
  return isLContainer(parent) ? parent[PARENT] : parent;
}
const instructionState = {
  lFrame: createLFrame(null),
  bindingsEnabled: true,
  skipHydrationRootTNode: null
};
/**
 * In this mode, any changes in bindings will throw an ExpressionChangedAfterChecked error.
 *
 * Necessary to support ChangeDetectorRef.checkNoChanges().
 *
 * The `checkNoChanges` function is invoked only in ngDevMode=true and verifies that no unintended
 * changes exist in the change detector or its children.
 */
let _isInCheckNoChangesMode = false;
/**
 * Returns true if the instruction state stack is empty.
 *
 * Intended to be called from tests only (tree shaken otherwise).
 */
function specOnlyIsInstructionStateEmpty() {
  return instructionState.lFrame.parent === null;
}
function getElementDepthCount() {
  return instructionState.lFrame.elementDepthCount;
}
function increaseElementDepthCount() {
  instructionState.lFrame.elementDepthCount++;
}
function decreaseElementDepthCount() {
  instructionState.lFrame.elementDepthCount--;
}
function getBindingsEnabled() {
  return instructionState.bindingsEnabled;
}
/**
 * Returns true if currently inside a skip hydration block.
 * @returns boolean
 */
function isInSkipHydrationBlock$1() {
  return instructionState.skipHydrationRootTNode !== null;
}
/**
 * Returns true if this is the root TNode of the skip hydration block.
 * @param tNode the current TNode
 * @returns boolean
 */
function isSkipHydrationRootTNode(tNode) {
  return instructionState.skipHydrationRootTNode === tNode;
}
/**
 * Enables directive matching on elements.
 *
 *  * Example:
 * ```
 * <my-comp my-directive>
 *   Should match component / directive.
 * </my-comp>
 * <div ngNonBindable>
 *   <!-- ɵɵdisableBindings() -->
 *   <my-comp my-directive>
 *     Should not match component / directive because we are in ngNonBindable.
 *   </my-comp>
 *   <!-- ɵɵenableBindings() -->
 * </div>
 * ```
 *
 * @codeGenApi
 */
function ɵɵenableBindings() {
  instructionState.bindingsEnabled = true;
}
/**
 * Sets a flag to specify that the TNode is in a skip hydration block.
 * @param tNode the current TNode
 */
function enterSkipHydrationBlock(tNode) {
  instructionState.skipHydrationRootTNode = tNode;
}
/**
 * Disables directive matching on element.
 *
 *  * Example:
 * ```
 * <my-comp my-directive>
 *   Should match component / directive.
 * </my-comp>
 * <div ngNonBindable>
 *   <!-- ɵɵdisableBindings() -->
 *   <my-comp my-directive>
 *     Should not match component / directive because we are in ngNonBindable.
 *   </my-comp>
 *   <!-- ɵɵenableBindings() -->
 * </div>
 * ```
 *
 * @codeGenApi
 */
function ɵɵdisableBindings() {
  instructionState.bindingsEnabled = false;
}
/**
 * Clears the root skip hydration node when leaving a skip hydration block.
 */
function leaveSkipHydrationBlock() {
  instructionState.skipHydrationRootTNode = null;
}
/**
 * Return the current `LView`.
 */
function getLView() {
  return instructionState.lFrame.lView;
}
/**
 * Return the current `TView`.
 */
function getTView() {
  return instructionState.lFrame.tView;
}
/**
 * Restores `contextViewData` to the given OpaqueViewState instance.
 *
 * Used in conjunction with the getCurrentView() instruction to save a snapshot
 * of the current view and restore it when listeners are invoked. This allows
 * walking the declaration view tree in listeners to get vars from parent views.
 *
 * @param viewToRestore The OpaqueViewState instance to restore.
 * @returns Context of the restored OpaqueViewState instance.
 *
 * @codeGenApi
 */
function ɵɵrestoreView(viewToRestore) {
  instructionState.lFrame.contextLView = viewToRestore;
  return viewToRestore[CONTEXT];
}
/**
 * Clears the view set in `ɵɵrestoreView` from memory. Returns the passed in
 * value so that it can be used as a return value of an instruction.
 *
 * @codeGenApi
 */
function ɵɵresetView(value) {
  instructionState.lFrame.contextLView = null;
  return value;
}
function getCurrentTNode() {
  let currentTNode = getCurrentTNodePlaceholderOk();
  while (currentTNode !== null && currentTNode.type === 64 /* TNodeType.Placeholder */) {
    currentTNode = currentTNode.parent;
  }
  return currentTNode;
}
function getCurrentTNodePlaceholderOk() {
  return instructionState.lFrame.currentTNode;
}
function getCurrentParentTNode() {
  const lFrame = instructionState.lFrame;
  const currentTNode = lFrame.currentTNode;
  return lFrame.isParent ? currentTNode : currentTNode.parent;
}
function setCurrentTNode(tNode, isParent) {
  ngDevMode && tNode && assertTNodeForTView(tNode, instructionState.lFrame.tView);
  const lFrame = instructionState.lFrame;
  lFrame.currentTNode = tNode;
  lFrame.isParent = isParent;
}
function isCurrentTNodeParent() {
  return instructionState.lFrame.isParent;
}
function setCurrentTNodeAsNotParent() {
  instructionState.lFrame.isParent = false;
}
function getContextLView() {
  const contextLView = instructionState.lFrame.contextLView;
  ngDevMode && assertDefined(contextLView, 'contextLView must be defined.');
  return contextLView;
}
function isInCheckNoChangesMode() {
  !ngDevMode && throwError('Must never be called in production mode');
  return _isInCheckNoChangesMode;
}
function setIsInCheckNoChangesMode(mode) {
  !ngDevMode && throwError('Must never be called in production mode');
  _isInCheckNoChangesMode = mode;
}
// top level variables should not be exported for performance reasons (PERF_NOTES.md)
function getBindingRoot() {
  const lFrame = instructionState.lFrame;
  let index = lFrame.bindingRootIndex;
  if (index === -1) {
    index = lFrame.bindingRootIndex = lFrame.tView.bindingStartIndex;
  }
  return index;
}
function getBindingIndex() {
  return instructionState.lFrame.bindingIndex;
}
function setBindingIndex(value) {
  return instructionState.lFrame.bindingIndex = value;
}
function nextBindingIndex() {
  return instructionState.lFrame.bindingIndex++;
}
function incrementBindingIndex(count) {
  const lFrame = instructionState.lFrame;
  const index = lFrame.bindingIndex;
  lFrame.bindingIndex = lFrame.bindingIndex + count;
  return index;
}
function isInI18nBlock() {
  return instructionState.lFrame.inI18n;
}
function setInI18nBlock(isInI18nBlock) {
  instructionState.lFrame.inI18n = isInI18nBlock;
}
/**
 * Set a new binding root index so that host template functions can execute.
 *
 * Bindings inside the host template are 0 index. But because we don't know ahead of time
 * how many host bindings we have we can't pre-compute them. For this reason they are all
 * 0 index and we just shift the root so that they match next available location in the LView.
 *
 * @param bindingRootIndex Root index for `hostBindings`
 * @param currentDirectiveIndex `TData[currentDirectiveIndex]` will point to the current directive
 *        whose `hostBindings` are being processed.
 */
function setBindingRootForHostBindings(bindingRootIndex, currentDirectiveIndex) {
  const lFrame = instructionState.lFrame;
  lFrame.bindingIndex = lFrame.bindingRootIndex = bindingRootIndex;
  setCurrentDirectiveIndex(currentDirectiveIndex);
}
/**
 * When host binding is executing this points to the directive index.
 * `TView.data[getCurrentDirectiveIndex()]` is `DirectiveDef`
 * `LView[getCurrentDirectiveIndex()]` is directive instance.
 */
function getCurrentDirectiveIndex() {
  return instructionState.lFrame.currentDirectiveIndex;
}
/**
 * Sets an index of a directive whose `hostBindings` are being processed.
 *
 * @param currentDirectiveIndex `TData` index where current directive instance can be found.
 */
function setCurrentDirectiveIndex(currentDirectiveIndex) {
  instructionState.lFrame.currentDirectiveIndex = currentDirectiveIndex;
}
/**
 * Retrieve the current `DirectiveDef` which is active when `hostBindings` instruction is being
 * executed.
 *
 * @param tData Current `TData` where the `DirectiveDef` will be looked up at.
 */
function getCurrentDirectiveDef(tData) {
  const currentDirectiveIndex = instructionState.lFrame.currentDirectiveIndex;
  return currentDirectiveIndex === -1 ? null : tData[currentDirectiveIndex];
}
function getCurrentQueryIndex() {
  return instructionState.lFrame.currentQueryIndex;
}
function setCurrentQueryIndex(value) {
  instructionState.lFrame.currentQueryIndex = value;
}
/**
 * Returns a `TNode` of the location where the current `LView` is declared at.
 *
 * @param lView an `LView` that we want to find parent `TNode` for.
 */
function getDeclarationTNode(lView) {
  const tView = lView[TVIEW];
  // Return the declaration parent for embedded views
  if (tView.type === 2 /* TViewType.Embedded */) {
    ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');
    return tView.declTNode;
  }
  // Components don't have `TView.declTNode` because each instance of component could be
  // inserted in different location, hence `TView.declTNode` is meaningless.
  // Falling back to `T_HOST` in case we cross component boundary.
  if (tView.type === 1 /* TViewType.Component */) {
    return lView[T_HOST];
  }
  // Remaining TNode type is `TViewType.Root` which doesn't have a parent TNode.
  return null;
}
/**
 * This is a light weight version of the `enterView` which is needed by the DI system.
 *
 * @param lView `LView` location of the DI context.
 * @param tNode `TNode` for DI context
 * @param flags DI context flags. if `SkipSelf` flag is set than we walk up the declaration
 *     tree from `tNode`  until we find parent declared `TElementNode`.
 * @returns `true` if we have successfully entered DI associated with `tNode` (or with declared
 *     `TNode` if `flags` has  `SkipSelf`). Failing to enter DI implies that no associated
 *     `NodeInjector` can be found and we should instead use `ModuleInjector`.
 *     - If `true` than this call must be fallowed by `leaveDI`
 *     - If `false` than this call failed and we should NOT call `leaveDI`
 */
function enterDI(lView, tNode, flags) {
  ngDevMode && assertLViewOrUndefined(lView);
  if (flags & InjectFlags.SkipSelf) {
    ngDevMode && assertTNodeForTView(tNode, lView[TVIEW]);
    let parentTNode = tNode;
    let parentLView = lView;
    while (true) {
      ngDevMode && assertDefined(parentTNode, 'Parent TNode should be defined');
      parentTNode = parentTNode.parent;
      if (parentTNode === null && !(flags & InjectFlags.Host)) {
        parentTNode = getDeclarationTNode(parentLView);
        if (parentTNode === null) break;
        // In this case, a parent exists and is definitely an element. So it will definitely
        // have an existing lView as the declaration view, which is why we can assume it's defined.
        ngDevMode && assertDefined(parentLView, 'Parent LView should be defined');
        parentLView = parentLView[DECLARATION_VIEW];
        // In Ivy there are Comment nodes that correspond to ngIf and NgFor embedded directives
        // We want to skip those and look only at Elements and ElementContainers to ensure
        // we're looking at true parent nodes, and not content or other types.
        if (parentTNode.type & (2 /* TNodeType.Element */ | 8 /* TNodeType.ElementContainer */)) {
          break;
        }
      } else {
        break;
      }
    }
    if (parentTNode === null) {
      // If we failed to find a parent TNode this means that we should use module injector.
      return false;
    } else {
      tNode = parentTNode;
      lView = parentLView;
    }
  }
  ngDevMode && assertTNodeForLView(tNode, lView);
  const lFrame = instructionState.lFrame = allocLFrame();
  lFrame.currentTNode = tNode;
  lFrame.lView = lView;
  return true;
}
/**
 * Swap the current lView with a new lView.
 *
 * For performance reasons we store the lView in the top level of the module.
 * This way we minimize the number of properties to read. Whenever a new view
 * is entered we have to store the lView for later, and when the view is
 * exited the state has to be restored
 *
 * @param newView New lView to become active
 * @returns the previously active lView;
 */
function enterView(newView) {
  ngDevMode && assertNotEqual(newView[0], newView[1], '????');
  ngDevMode && assertLViewOrUndefined(newView);
  const newLFrame = allocLFrame();
  if (ngDevMode) {
    assertEqual(newLFrame.isParent, true, 'Expected clean LFrame');
    assertEqual(newLFrame.lView, null, 'Expected clean LFrame');
    assertEqual(newLFrame.tView, null, 'Expected clean LFrame');
    assertEqual(newLFrame.selectedIndex, -1, 'Expected clean LFrame');
    assertEqual(newLFrame.elementDepthCount, 0, 'Expected clean LFrame');
    assertEqual(newLFrame.currentDirectiveIndex, -1, 'Expected clean LFrame');
    assertEqual(newLFrame.currentNamespace, null, 'Expected clean LFrame');
    assertEqual(newLFrame.bindingRootIndex, -1, 'Expected clean LFrame');
    assertEqual(newLFrame.currentQueryIndex, 0, 'Expected clean LFrame');
  }
  const tView = newView[TVIEW];
  instructionState.lFrame = newLFrame;
  ngDevMode && tView.firstChild && assertTNodeForTView(tView.firstChild, tView);
  newLFrame.currentTNode = tView.firstChild;
  newLFrame.lView = newView;
  newLFrame.tView = tView;
  newLFrame.contextLView = newView;
  newLFrame.bindingIndex = tView.bindingStartIndex;
  newLFrame.inI18n = false;
}
/**
 * Allocates next free LFrame. This function tries to reuse the `LFrame`s to lower memory pressure.
 */
function allocLFrame() {
  const currentLFrame = instructionState.lFrame;
  const childLFrame = currentLFrame === null ? null : currentLFrame.child;
  const newLFrame = childLFrame === null ? createLFrame(currentLFrame) : childLFrame;
  return newLFrame;
}
function createLFrame(parent) {
  const lFrame = {
    currentTNode: null,
    isParent: true,
    lView: null,
    tView: null,
    selectedIndex: -1,
    contextLView: null,
    elementDepthCount: 0,
    currentNamespace: null,
    currentDirectiveIndex: -1,
    bindingRootIndex: -1,
    bindingIndex: -1,
    currentQueryIndex: 0,
    parent: parent,
    child: null,
    inI18n: false
  };
  parent !== null && (parent.child = lFrame); // link the new LFrame for reuse.
  return lFrame;
}
/**
 * A lightweight version of leave which is used with DI.
 *
 * This function only resets `currentTNode` and `LView` as those are the only properties
 * used with DI (`enterDI()`).
 *
 * NOTE: This function is reexported as `leaveDI`. However `leaveDI` has return type of `void` where
 * as `leaveViewLight` has `LFrame`. This is so that `leaveViewLight` can be used in `leaveView`.
 */
function leaveViewLight() {
  const oldLFrame = instructionState.lFrame;
  instructionState.lFrame = oldLFrame.parent;
  oldLFrame.currentTNode = null;
  oldLFrame.lView = null;
  return oldLFrame;
}
/**
 * This is a lightweight version of the `leaveView` which is needed by the DI system.
 *
 * NOTE: this function is an alias so that we can change the type of the function to have `void`
 * return type.
 */
const leaveDI = leaveViewLight;
/**
 * Leave the current `LView`
 *
 * This pops the `LFrame` with the associated `LView` from the stack.
 *
 * IMPORTANT: We must zero out the `LFrame` values here otherwise they will be retained. This is
 * because for performance reasons we don't release `LFrame` but rather keep it for next use.
 */
function leaveView() {
  const oldLFrame = leaveViewLight();
  oldLFrame.isParent = true;
  oldLFrame.tView = null;
  oldLFrame.selectedIndex = -1;
  oldLFrame.contextLView = null;
  oldLFrame.elementDepthCount = 0;
  oldLFrame.currentDirectiveIndex = -1;
  oldLFrame.currentNamespace = null;
  oldLFrame.bindingRootIndex = -1;
  oldLFrame.bindingIndex = -1;
  oldLFrame.currentQueryIndex = 0;
}
function nextContextImpl(level) {
  const contextLView = instructionState.lFrame.contextLView = walkUpViews(level, instructionState.lFrame.contextLView);
  return contextLView[CONTEXT];
}
/**
 * Gets the currently selected element index.
 *
 * Used with {@link property} instruction (and more in the future) to identify the index in the
 * current `LView` to act on.
 */
function getSelectedIndex() {
  return instructionState.lFrame.selectedIndex;
}
/**
 * Sets the most recent index passed to {@link select}
 *
 * Used with {@link property} instruction (and more in the future) to identify the index in the
 * current `LView` to act on.
 *
 * (Note that if an "exit function" was set earlier (via `setElementExitFn()`) then that will be
 * run if and when the provided `index` value is different from the current selected index value.)
 */
function setSelectedIndex(index) {
  ngDevMode && index !== -1 && assertGreaterThanOrEqual(index, HEADER_OFFSET, 'Index must be past HEADER_OFFSET (or -1).');
  ngDevMode && assertLessThan(index, instructionState.lFrame.lView.length, 'Can\'t set index passed end of LView');
  instructionState.lFrame.selectedIndex = index;
}
/**
 * Gets the `tNode` that represents currently selected element.
 */
function getSelectedTNode() {
  const lFrame = instructionState.lFrame;
  return getTNode(lFrame.tView, lFrame.selectedIndex);
}
/**
 * Sets the namespace used to create elements to `'http://www.w3.org/2000/svg'` in global state.
 *
 * @codeGenApi
 */
function ɵɵnamespaceSVG() {
  instructionState.lFrame.currentNamespace = SVG_NAMESPACE;
}
/**
 * Sets the namespace used to create elements to `'http://www.w3.org/1998/MathML/'` in global state.
 *
 * @codeGenApi
 */
function ɵɵnamespaceMathML() {
  instructionState.lFrame.currentNamespace = MATH_ML_NAMESPACE;
}
/**
 * Sets the namespace used to create elements to `null`, which forces element creation to use
 * `createElement` rather than `createElementNS`.
 *
 * @codeGenApi
 */
function ɵɵnamespaceHTML() {
  namespaceHTMLInternal();
}
/**
 * Sets the namespace used to create elements to `null`, which forces element creation to use
 * `createElement` rather than `createElementNS`.
 */
function namespaceHTMLInternal() {
  instructionState.lFrame.currentNamespace = null;
}
function getNamespace$1() {
  return instructionState.lFrame.currentNamespace;
}
let _wasLastNodeCreated = true;
/**
 * Retrieves a global flag that indicates whether the most recent DOM node
 * was created or hydrated.
 */
function wasLastNodeCreated() {
  return _wasLastNodeCreated;
}
/**
 * Sets a global flag to indicate whether the most recent DOM node
 * was created or hydrated.
 */
function lastNodeWasCreated(flag) {
  _wasLastNodeCreated = flag;
}

/**
 * Adds all directive lifecycle hooks from the given `DirectiveDef` to the given `TView`.
 *
 * Must be run *only* on the first template pass.
 *
 * Sets up the pre-order hooks on the provided `tView`,
 * see {@link HookData} for details about the data structure.
 *
 * @param directiveIndex The index of the directive in LView
 * @param directiveDef The definition containing the hooks to setup in tView
 * @param tView The current TView
 */
function registerPreOrderHooks(directiveIndex, directiveDef, tView) {
  ngDevMode && assertFirstCreatePass(tView);
  const {
    ngOnChanges,
    ngOnInit,
    ngDoCheck
  } = directiveDef.type.prototype;
  if (ngOnChanges) {
    const wrappedOnChanges = NgOnChangesFeatureImpl(directiveDef);
    (tView.preOrderHooks ??= []).push(directiveIndex, wrappedOnChanges);
    (tView.preOrderCheckHooks ??= []).push(directiveIndex, wrappedOnChanges);
  }
  if (ngOnInit) {
    (tView.preOrderHooks ??= []).push(0 - directiveIndex, ngOnInit);
  }
  if (ngDoCheck) {
    (tView.preOrderHooks ??= []).push(directiveIndex, ngDoCheck);
    (tView.preOrderCheckHooks ??= []).push(directiveIndex, ngDoCheck);
  }
}
/**
 *
 * Loops through the directives on the provided `tNode` and queues hooks to be
 * run that are not initialization hooks.
 *
 * Should be executed during `elementEnd()` and similar to
 * preserve hook execution order. Content, view, and destroy hooks for projected
 * components and directives must be called *before* their hosts.
 *
 * Sets up the content, view, and destroy hooks on the provided `tView`,
 * see {@link HookData} for details about the data structure.
 *
 * NOTE: This does not set up `onChanges`, `onInit` or `doCheck`, those are set up
 * separately at `elementStart`.
 *
 * @param tView The current TView
 * @param tNode The TNode whose directives are to be searched for hooks to queue
 */
function registerPostOrderHooks(tView, tNode) {
  ngDevMode && assertFirstCreatePass(tView);
  // It's necessary to loop through the directives at elementEnd() (rather than processing in
  // directiveCreate) so we can preserve the current hook order. Content, view, and destroy
  // hooks for projected components and directives must be called *before* their hosts.
  for (let i = tNode.directiveStart, end = tNode.directiveEnd; i < end; i++) {
    const directiveDef = tView.data[i];
    ngDevMode && assertDefined(directiveDef, 'Expecting DirectiveDef');
    const lifecycleHooks = directiveDef.type.prototype;
    const {
      ngAfterContentInit,
      ngAfterContentChecked,
      ngAfterViewInit,
      ngAfterViewChecked,
      ngOnDestroy
    } = lifecycleHooks;
    if (ngAfterContentInit) {
      (tView.contentHooks ??= []).push(-i, ngAfterContentInit);
    }
    if (ngAfterContentChecked) {
      (tView.contentHooks ??= []).push(i, ngAfterContentChecked);
      (tView.contentCheckHooks ??= []).push(i, ngAfterContentChecked);
    }
    if (ngAfterViewInit) {
      (tView.viewHooks ??= []).push(-i, ngAfterViewInit);
    }
    if (ngAfterViewChecked) {
      (tView.viewHooks ??= []).push(i, ngAfterViewChecked);
      (tView.viewCheckHooks ??= []).push(i, ngAfterViewChecked);
    }
    if (ngOnDestroy != null) {
      (tView.destroyHooks ??= []).push(i, ngOnDestroy);
    }
  }
}
/**
 * Executing hooks requires complex logic as we need to deal with 2 constraints.
 *
 * 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only
 * once, across many change detection cycles. This must be true even if some hooks throw, or if
 * some recursively trigger a change detection cycle.
 * To solve that, it is required to track the state of the execution of these init hooks.
 * This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
 * and the index within that phase. They can be seen as a cursor in the following structure:
 * [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
 * They are stored as flags in LView[FLAGS].
 *
 * 2. Pre-order hooks can be executed in batches, because of the select instruction.
 * To be able to pause and resume their execution, we also need some state about the hook's array
 * that is being processed:
 * - the index of the next hook to be executed
 * - the number of init hooks already found in the processed part of the  array
 * They are stored as flags in LView[PREORDER_HOOK_FLAGS].
 */
/**
 * Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
 * executed once. This is a light version of executeInitAndCheckPreOrderHooks where we can skip read
 * / write of the init-hooks related flags.
 * @param lView The LView where hooks are defined
 * @param hooks Hooks to be run
 * @param nodeIndex 3 cases depending on the value:
 * - undefined: all hooks from the array should be executed (post-order case)
 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
 * flushing the remaining hooks)
 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
 * case, when executing select(number))
 */
function executeCheckHooks(lView, hooks, nodeIndex) {
  callHooks(lView, hooks, 3 /* InitPhaseState.InitPhaseCompleted */, nodeIndex);
}
/**
 * Executes post-order init and check hooks (one of AfterContentInit, AfterContentChecked,
 * AfterViewInit, AfterViewChecked) given a view where there are pending init hooks to be executed.
 * @param lView The LView where hooks are defined
 * @param hooks Hooks to be run
 * @param initPhase A phase for which hooks should be run
 * @param nodeIndex 3 cases depending on the value:
 * - undefined: all hooks from the array should be executed (post-order case)
 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
 * flushing the remaining hooks)
 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
 * case, when executing select(number))
 */
function executeInitAndCheckHooks(lView, hooks, initPhase, nodeIndex) {
  ngDevMode && assertNotEqual(initPhase, 3 /* InitPhaseState.InitPhaseCompleted */, 'Init pre-order hooks should not be called more than once');
  if ((lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === initPhase) {
    callHooks(lView, hooks, initPhase, nodeIndex);
  }
}
function incrementInitPhaseFlags(lView, initPhase) {
  ngDevMode && assertNotEqual(initPhase, 3 /* InitPhaseState.InitPhaseCompleted */, 'Init hooks phase should not be incremented after all init hooks have been run.');
  let flags = lView[FLAGS];
  if ((flags & 3 /* LViewFlags.InitPhaseStateMask */) === initPhase) {
    flags &= 16383 /* LViewFlags.IndexWithinInitPhaseReset */;
    flags += 1 /* LViewFlags.InitPhaseStateIncrementer */;
    lView[FLAGS] = flags;
  }
}
/**
 * Calls lifecycle hooks with their contexts, skipping init hooks if it's not
 * the first LView pass
 *
 * @param currentView The current view
 * @param arr The array in which the hooks are found
 * @param initPhaseState the current state of the init phase
 * @param currentNodeIndex 3 cases depending on the value:
 * - undefined: all hooks from the array should be executed (post-order case)
 * - null: execute hooks only from the saved index until the end of the array (pre-order case, when
 * flushing the remaining hooks)
 * - number: execute hooks only from the saved index until that node index exclusive (pre-order
 * case, when executing select(number))
 */
function callHooks(currentView, arr, initPhase, currentNodeIndex) {
  ngDevMode && assertEqual(isInCheckNoChangesMode(), false, 'Hooks should never be run when in check no changes mode.');
  const startIndex = currentNodeIndex !== undefined ? currentView[PREORDER_HOOK_FLAGS] & 65535 /* PreOrderHookFlags.IndexOfTheNextPreOrderHookMaskMask */ : 0;
  const nodeIndexLimit = currentNodeIndex != null ? currentNodeIndex : -1;
  const max = arr.length - 1; // Stop the loop at length - 1, because we look for the hook at i + 1
  let lastNodeIndexFound = 0;
  for (let i = startIndex; i < max; i++) {
    const hook = arr[i + 1];
    if (typeof hook === 'number') {
      lastNodeIndexFound = arr[i];
      if (currentNodeIndex != null && lastNodeIndexFound >= currentNodeIndex) {
        break;
      }
    } else {
      const isInitHook = arr[i] < 0;
      if (isInitHook) {
        currentView[PREORDER_HOOK_FLAGS] += 65536 /* PreOrderHookFlags.NumberOfInitHooksCalledIncrementer */;
      }
      if (lastNodeIndexFound < nodeIndexLimit || nodeIndexLimit == -1) {
        callHook(currentView, initPhase, arr, i);
        currentView[PREORDER_HOOK_FLAGS] = (currentView[PREORDER_HOOK_FLAGS] & 4294901760 /* PreOrderHookFlags.NumberOfInitHooksCalledMask */) + i + 2;
      }
      i++;
    }
  }
}
/**
 * Executes a single lifecycle hook, making sure that:
 * - it is called in the non-reactive context;
 * - profiling data are registered.
 */
function callHookInternal(directive, hook) {
  profiler(4 /* ProfilerEvent.LifecycleHookStart */, directive, hook);
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    hook.call(directive);
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    profiler(5 /* ProfilerEvent.LifecycleHookEnd */, directive, hook);
  }
}
/**
 * Execute one hook against the current `LView`.
 *
 * @param currentView The current view
 * @param initPhaseState the current state of the init phase
 * @param arr The array in which the hooks are found
 * @param i The current index within the hook data array
 */
function callHook(currentView, initPhase, arr, i) {
  const isInitHook = arr[i] < 0;
  const hook = arr[i + 1];
  const directiveIndex = isInitHook ? -arr[i] : arr[i];
  const directive = currentView[directiveIndex];
  if (isInitHook) {
    const indexWithintInitPhase = currentView[FLAGS] >> 14 /* LViewFlags.IndexWithinInitPhaseShift */;
    // The init phase state must be always checked here as it may have been recursively updated.
    if (indexWithintInitPhase < currentView[PREORDER_HOOK_FLAGS] >> 16 /* PreOrderHookFlags.NumberOfInitHooksCalledShift */ && (currentView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === initPhase) {
      currentView[FLAGS] += 16384 /* LViewFlags.IndexWithinInitPhaseIncrementer */;
      callHookInternal(directive, hook);
    }
  } else {
    callHookInternal(directive, hook);
  }
}
const NO_PARENT_INJECTOR = -1;
/**
 * Each injector is saved in 9 contiguous slots in `LView` and 9 contiguous slots in
 * `TView.data`. This allows us to store information about the current node's tokens (which
 * can be shared in `TView`) as well as the tokens of its ancestor nodes (which cannot be
 * shared, so they live in `LView`).
 *
 * Each of these slots (aside from the last slot) contains a bloom filter. This bloom filter
 * determines whether a directive is available on the associated node or not. This prevents us
 * from searching the directives array at this level unless it's probable the directive is in it.
 *
 * See: https://en.wikipedia.org/wiki/Bloom_filter for more about bloom filters.
 *
 * Because all injectors have been flattened into `LView` and `TViewData`, they cannot typed
 * using interfaces as they were previously. The start index of each `LInjector` and `TInjector`
 * will differ based on where it is flattened into the main array, so it's not possible to know
 * the indices ahead of time and save their types here. The interfaces are still included here
 * for documentation purposes.
 *
 * export interface LInjector extends Array<any> {
 *
 *    // Cumulative bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
 *    [0]: number;
 *
 *    // Cumulative bloom for directive IDs 32-63
 *    [1]: number;
 *
 *    // Cumulative bloom for directive IDs 64-95
 *    [2]: number;
 *
 *    // Cumulative bloom for directive IDs 96-127
 *    [3]: number;
 *
 *    // Cumulative bloom for directive IDs 128-159
 *    [4]: number;
 *
 *    // Cumulative bloom for directive IDs 160 - 191
 *    [5]: number;
 *
 *    // Cumulative bloom for directive IDs 192 - 223
 *    [6]: number;
 *
 *    // Cumulative bloom for directive IDs 224 - 255
 *    [7]: number;
 *
 *    // We need to store a reference to the injector's parent so DI can keep looking up
 *    // the injector tree until it finds the dependency it's looking for.
 *    [PARENT_INJECTOR]: number;
 * }
 *
 * export interface TInjector extends Array<any> {
 *
 *    // Shared node bloom for directive IDs 0-31  (IDs are % BLOOM_SIZE)
 *    [0]: number;
 *
 *    // Shared node bloom for directive IDs 32-63
 *    [1]: number;
 *
 *    // Shared node bloom for directive IDs 64-95
 *    [2]: number;
 *
 *    // Shared node bloom for directive IDs 96-127
 *    [3]: number;
 *
 *    // Shared node bloom for directive IDs 128-159
 *    [4]: number;
 *
 *    // Shared node bloom for directive IDs 160 - 191
 *    [5]: number;
 *
 *    // Shared node bloom for directive IDs 192 - 223
 *    [6]: number;
 *
 *    // Shared node bloom for directive IDs 224 - 255
 *    [7]: number;
 *
 *    // Necessary to find directive indices for a particular node.
 *    [TNODE]: TElementNode|TElementContainerNode|TContainerNode;
 *  }
 */
/**
 * Factory for creating instances of injectors in the NodeInjector.
 *
 * This factory is complicated by the fact that it can resolve `multi` factories as well.
 *
 * NOTE: Some of the fields are optional which means that this class has two hidden classes.
 * - One without `multi` support (most common)
 * - One with `multi` values, (rare).
 *
 * Since VMs can cache up to 4 inline hidden classes this is OK.
 *
 * - Single factory: Only `resolving` and `factory` is defined.
 * - `providers` factory: `componentProviders` is a number and `index = -1`.
 * - `viewProviders` factory: `componentProviders` is a number and `index` points to `providers`.
 */
class NodeInjectorFactory {
  constructor(
  /**
   * Factory to invoke in order to create a new instance.
   */
  factory,
  /**
   * Set to `true` if the token is declared in `viewProviders` (or if it is component).
   */
  isViewProvider, injectImplementation) {
    this.factory = factory;
    /**
     * Marker set to true during factory invocation to see if we get into recursive loop.
     * Recursive loop causes an error to be displayed.
     */
    this.resolving = false;
    ngDevMode && assertDefined(factory, 'Factory not specified');
    ngDevMode && assertEqual(typeof factory, 'function', 'Expected factory function.');
    this.canSeeViewProviders = isViewProvider;
    this.injectImpl = injectImplementation;
  }
}
function isFactory(obj) {
  return obj instanceof NodeInjectorFactory;
}

/**
 * Converts `TNodeType` into human readable text.
 * Make sure this matches with `TNodeType`
 */
function toTNodeTypeAsString(tNodeType) {
  let text = '';
  tNodeType & 1 /* TNodeType.Text */ && (text += '|Text');
  tNodeType & 2 /* TNodeType.Element */ && (text += '|Element');
  tNodeType & 4 /* TNodeType.Container */ && (text += '|Container');
  tNodeType & 8 /* TNodeType.ElementContainer */ && (text += '|ElementContainer');
  tNodeType & 16 /* TNodeType.Projection */ && (text += '|Projection');
  tNodeType & 32 /* TNodeType.Icu */ && (text += '|IcuContainer');
  tNodeType & 64 /* TNodeType.Placeholder */ && (text += '|Placeholder');
  return text.length > 0 ? text.substring(1) : text;
}
/**
 * Helper function to detect if a given value matches a `TNode` shape.
 *
 * The logic uses the `insertBeforeIndex` and its possible values as
 * a way to differentiate a TNode shape from other types of objects
 * within the `TView.data`. This is not a perfect check, but it can
 * be a reasonable differentiator, since we control the shapes of objects
 * within `TView.data`.
 */
function isTNodeShape(value) {
  return value != null && typeof value === 'object' && (value.insertBeforeIndex === null || typeof value.insertBeforeIndex === 'number' || Array.isArray(value.insertBeforeIndex));
}
/**
 * Returns `true` if the `TNode` has a directive which has `@Input()` for `class` binding.
 *
 * ```
 * <div my-dir [class]="exp"></div>
 * ```
 * and
 * ```
 * @Directive({
 * })
 * class MyDirective {
 *   @Input()
 *   class: string;
 * }
 * ```
 *
 * In the above case it is necessary to write the reconciled styling information into the
 * directive's input.
 *
 * @param tNode
 */
function hasClassInput(tNode) {
  return (tNode.flags & 8 /* TNodeFlags.hasClassInput */) !== 0;
}
/**
 * Returns `true` if the `TNode` has a directive which has `@Input()` for `style` binding.
 *
 * ```
 * <div my-dir [style]="exp"></div>
 * ```
 * and
 * ```
 * @Directive({
 * })
 * class MyDirective {
 *   @Input()
 *   class: string;
 * }
 * ```
 *
 * In the above case it is necessary to write the reconciled styling information into the
 * directive's input.
 *
 * @param tNode
 */
function hasStyleInput(tNode) {
  return (tNode.flags & 16 /* TNodeFlags.hasStyleInput */) !== 0;
}
function assertTNodeType(tNode, expectedTypes, message) {
  assertDefined(tNode, 'should be called with a TNode');
  if ((tNode.type & expectedTypes) === 0) {
    throwError(message || `Expected [${toTNodeTypeAsString(expectedTypes)}] but got ${toTNodeTypeAsString(tNode.type)}.`);
  }
}
function assertPureTNodeType(type) {
  if (!(type === 2 /* TNodeType.Element */ ||
  //
  type === 1 /* TNodeType.Text */ ||
  //
  type === 4 /* TNodeType.Container */ ||
  //
  type === 8 /* TNodeType.ElementContainer */ ||
  //
  type === 32 /* TNodeType.Icu */ ||
  //
  type === 16 /* TNodeType.Projection */ ||
  //
  type === 64 /* TNodeType.Placeholder */)) {
    throwError(`Expected TNodeType to have only a single type selected, but got ${toTNodeTypeAsString(type)}.`);
  }
}

/// Parent Injector Utils ///////////////////////////////////////////////////////////////
function hasParentInjector(parentLocation) {
  return parentLocation !== NO_PARENT_INJECTOR;
}
function getParentInjectorIndex(parentLocation) {
  if (ngDevMode) {
    assertNumber(parentLocation, 'Number expected');
    assertNotEqual(parentLocation, -1, 'Not a valid state.');
    const parentInjectorIndex = parentLocation & 32767 /* RelativeInjectorLocationFlags.InjectorIndexMask */;
    assertGreaterThan(parentInjectorIndex, HEADER_OFFSET, 'Parent injector must be pointing past HEADER_OFFSET.');
  }
  return parentLocation & 32767 /* RelativeInjectorLocationFlags.InjectorIndexMask */;
}
function getParentInjectorViewOffset(parentLocation) {
  return parentLocation >> 16 /* RelativeInjectorLocationFlags.ViewOffsetShift */;
}
/**
 * Unwraps a parent injector location number to find the view offset from the current injector,
 * then walks up the declaration view tree until the view is found that contains the parent
 * injector.
 *
 * @param location The location of the parent injector, which contains the view offset
 * @param startView The LView instance from which to start walking up the view tree
 * @returns The LView instance that contains the parent injector
 */
function getParentInjectorView(location, startView) {
  let viewOffset = getParentInjectorViewOffset(location);
  let parentView = startView;
  // For most cases, the parent injector can be found on the host node (e.g. for component
  // or container), but we must keep the loop here to support the rarer case of deeply nested
  // <ng-template> tags or inline views, where the parent injector might live many views
  // above the child injector.
  while (viewOffset > 0) {
    parentView = parentView[DECLARATION_VIEW];
    viewOffset--;
  }
  return parentView;
}

/**
 * Defines if the call to `inject` should include `viewProviders` in its resolution.
 *
 * This is set to true when we try to instantiate a component. This value is reset in
 * `getNodeInjectable` to a value which matches the declaration location of the token about to be
 * instantiated. This is done so that if we are injecting a token which was declared outside of
 * `viewProviders` we don't accidentally pull `viewProviders` in.
 *
 * Example:
 *
 * ```
 * @Injectable()
 * class MyService {
 *   constructor(public value: String) {}
 * }
 *
 * @Component({
 *   providers: [
 *     MyService,
 *     {provide: String, value: 'providers' }
 *   ]
 *   viewProviders: [
 *     {provide: String, value: 'viewProviders'}
 *   ]
 * })
 * class MyComponent {
 *   constructor(myService: MyService, value: String) {
 *     // We expect that Component can see into `viewProviders`.
 *     expect(value).toEqual('viewProviders');
 *     // `MyService` was not declared in `viewProviders` hence it can't see it.
 *     expect(myService.value).toEqual('providers');
 *   }
 * }
 *
 * ```
 */
let includeViewProviders = true;
function setIncludeViewProviders(v) {
  const oldValue = includeViewProviders;
  includeViewProviders = v;
  return oldValue;
}
/**
 * The number of slots in each bloom filter (used by DI). The larger this number, the fewer
 * directives that will share slots, and thus, the fewer false positives when checking for
 * the existence of a directive.
 */
const BLOOM_SIZE = 256;
const BLOOM_MASK = BLOOM_SIZE - 1;
/**
 * The number of bits that is represented by a single bloom bucket. JS bit operations are 32 bits,
 * so each bucket represents 32 distinct tokens which accounts for log2(32) = 5 bits of a bloom hash
 * number.
 */
const BLOOM_BUCKET_BITS = 5;
/** Counter used to generate unique IDs for directives. */
let nextNgElementId = 0;
/** Value used when something wasn't found by an injector. */
const NOT_FOUND = {};
/**
 * Registers this directive as present in its node's injector by flipping the directive's
 * corresponding bit in the injector's bloom filter.
 *
 * @param injectorIndex The index of the node injector where this token should be registered
 * @param tView The TView for the injector's bloom filters
 * @param type The directive token to register
 */
function bloomAdd(injectorIndex, tView, type) {
  ngDevMode && assertEqual(tView.firstCreatePass, true, 'expected firstCreatePass to be true');
  let id;
  if (typeof type === 'string') {
    id = type.charCodeAt(0) || 0;
  } else if (type.hasOwnProperty(NG_ELEMENT_ID)) {
    id = type[NG_ELEMENT_ID];
  }
  // Set a unique ID on the directive type, so if something tries to inject the directive,
  // we can easily retrieve the ID and hash it into the bloom bit that should be checked.
  if (id == null) {
    id = type[NG_ELEMENT_ID] = nextNgElementId++;
  }
  // We only have BLOOM_SIZE (256) slots in our bloom filter (8 buckets * 32 bits each),
  // so all unique IDs must be modulo-ed into a number from 0 - 255 to fit into the filter.
  const bloomHash = id & BLOOM_MASK;
  // Create a mask that targets the specific bit associated with the directive.
  // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
  // to bit positions 0 - 31 in a 32 bit integer.
  const mask = 1 << bloomHash;
  // Each bloom bucket in `tData` represents `BLOOM_BUCKET_BITS` number of bits of `bloomHash`.
  // Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset that the mask
  // should be written to.
  tView.data[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)] |= mask;
}
/**
 * Creates (or gets an existing) injector for a given element or container.
 *
 * @param tNode for which an injector should be retrieved / created.
 * @param lView View where the node is stored
 * @returns Node injector
 */
function getOrCreateNodeInjectorForNode(tNode, lView) {
  const existingInjectorIndex = getInjectorIndex(tNode, lView);
  if (existingInjectorIndex !== -1) {
    return existingInjectorIndex;
  }
  const tView = lView[TVIEW];
  if (tView.firstCreatePass) {
    tNode.injectorIndex = lView.length;
    insertBloom(tView.data, tNode); // foundation for node bloom
    insertBloom(lView, null); // foundation for cumulative bloom
    insertBloom(tView.blueprint, null);
  }
  const parentLoc = getParentInjectorLocation(tNode, lView);
  const injectorIndex = tNode.injectorIndex;
  // If a parent injector can't be found, its location is set to -1.
  // In that case, we don't need to set up a cumulative bloom
  if (hasParentInjector(parentLoc)) {
    const parentIndex = getParentInjectorIndex(parentLoc);
    const parentLView = getParentInjectorView(parentLoc, lView);
    const parentData = parentLView[TVIEW].data;
    // Creates a cumulative bloom filter that merges the parent's bloom filter
    // and its own cumulative bloom (which contains tokens for all ancestors)
    for (let i = 0; i < 8 /* NodeInjectorOffset.BLOOM_SIZE */; i++) {
      lView[injectorIndex + i] = parentLView[parentIndex + i] | parentData[parentIndex + i];
    }
  }
  lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */] = parentLoc;
  return injectorIndex;
}
function insertBloom(arr, footer) {
  arr.push(0, 0, 0, 0, 0, 0, 0, 0, footer);
}
function getInjectorIndex(tNode, lView) {
  if (tNode.injectorIndex === -1 ||
  // If the injector index is the same as its parent's injector index, then the index has been
  // copied down from the parent node. No injector has been created yet on this node.
  tNode.parent && tNode.parent.injectorIndex === tNode.injectorIndex ||
  // After the first template pass, the injector index might exist but the parent values
  // might not have been calculated yet for this instance
  lView[tNode.injectorIndex + 8 /* NodeInjectorOffset.PARENT */] === null) {
    return -1;
  } else {
    ngDevMode && assertIndexInRange(lView, tNode.injectorIndex);
    return tNode.injectorIndex;
  }
}
/**
 * Finds the index of the parent injector, with a view offset if applicable. Used to set the
 * parent injector initially.
 *
 * @returns Returns a number that is the combination of the number of LViews that we have to go up
 * to find the LView containing the parent inject AND the index of the injector within that LView.
 */
function getParentInjectorLocation(tNode, lView) {
  if (tNode.parent && tNode.parent.injectorIndex !== -1) {
    // If we have a parent `TNode` and there is an injector associated with it we are done, because
    // the parent injector is within the current `LView`.
    return tNode.parent.injectorIndex; // ViewOffset is 0
  }
  // When parent injector location is computed it may be outside of the current view. (ie it could
  // be pointing to a declared parent location). This variable stores number of declaration parents
  // we need to walk up in order to find the parent injector location.
  let declarationViewOffset = 0;
  let parentTNode = null;
  let lViewCursor = lView;
  // The parent injector is not in the current `LView`. We will have to walk the declared parent
  // `LView` hierarchy and look for it. If we walk of the top, that means that there is no parent
  // `NodeInjector`.
  while (lViewCursor !== null) {
    parentTNode = getTNodeFromLView(lViewCursor);
    if (parentTNode === null) {
      // If we have no parent, than we are done.
      return NO_PARENT_INJECTOR;
    }
    ngDevMode && parentTNode && assertTNodeForLView(parentTNode, lViewCursor[DECLARATION_VIEW]);
    // Every iteration of the loop requires that we go to the declared parent.
    declarationViewOffset++;
    lViewCursor = lViewCursor[DECLARATION_VIEW];
    if (parentTNode.injectorIndex !== -1) {
      // We found a NodeInjector which points to something.
      return parentTNode.injectorIndex | declarationViewOffset << 16 /* RelativeInjectorLocationFlags.ViewOffsetShift */;
    }
  }
  return NO_PARENT_INJECTOR;
}
/**
 * Makes a type or an injection token public to the DI system by adding it to an
 * injector's bloom filter.
 *
 * @param di The node injector in which a directive will be added
 * @param token The type or the injection token to be made public
 */
function diPublicInInjector(injectorIndex, tView, token) {
  bloomAdd(injectorIndex, tView, token);
}
/**
 * Inject static attribute value into directive constructor.
 *
 * This method is used with `factory` functions which are generated as part of
 * `defineDirective` or `defineComponent`. The method retrieves the static value
 * of an attribute. (Dynamic attributes are not supported since they are not resolved
 *  at the time of injection and can change over time.)
 *
 * # Example
 * Given:
 * ```
 * @Component(...)
 * class MyComponent {
 *   constructor(@Attribute('title') title: string) { ... }
 * }
 * ```
 * When instantiated with
 * ```
 * <my-component title="Hello"></my-component>
 * ```
 *
 * Then factory method generated is:
 * ```
 * MyComponent.ɵcmp = defineComponent({
 *   factory: () => new MyComponent(injectAttribute('title'))
 *   ...
 * })
 * ```
 *
 * @publicApi
 */
function injectAttributeImpl(tNode, attrNameToInject) {
  ngDevMode && assertTNodeType(tNode, 12 /* TNodeType.AnyContainer */ | 3 /* TNodeType.AnyRNode */);
  ngDevMode && assertDefined(tNode, 'expecting tNode');
  if (attrNameToInject === 'class') {
    return tNode.classes;
  }
  if (attrNameToInject === 'style') {
    return tNode.styles;
  }
  const attrs = tNode.attrs;
  if (attrs) {
    const attrsLength = attrs.length;
    let i = 0;
    while (i < attrsLength) {
      const value = attrs[i];
      // If we hit a `Bindings` or `Template` marker then we are done.
      if (isNameOnlyAttributeMarker(value)) break;
      // Skip namespaced attributes
      if (value === 0 /* AttributeMarker.NamespaceURI */) {
        // we skip the next two values
        // as namespaced attributes looks like
        // [..., AttributeMarker.NamespaceURI, 'http://someuri.com/test', 'test:exist',
        // 'existValue', ...]
        i = i + 2;
      } else if (typeof value === 'number') {
        // Skip to the first value of the marked attribute.
        i++;
        while (i < attrsLength && typeof attrs[i] === 'string') {
          i++;
        }
      } else if (value === attrNameToInject) {
        return attrs[i + 1];
      } else {
        i = i + 2;
      }
    }
  }
  return null;
}
function notFoundValueOrThrow(notFoundValue, token, flags) {
  if (flags & InjectFlags.Optional || notFoundValue !== undefined) {
    return notFoundValue;
  } else {
    throwProviderNotFoundError(token, 'NodeInjector');
  }
}
/**
 * Returns the value associated to the given token from the ModuleInjector or throws exception
 *
 * @param lView The `LView` that contains the `tNode`
 * @param token The token to look for
 * @param flags Injection flags
 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
 * @returns the value from the injector or throws an exception
 */
function lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue) {
  if (flags & InjectFlags.Optional && notFoundValue === undefined) {
    // This must be set or the NullInjector will throw for optional deps
    notFoundValue = null;
  }
  if ((flags & (InjectFlags.Self | InjectFlags.Host)) === 0) {
    const moduleInjector = lView[INJECTOR];
    // switch to `injectInjectorOnly` implementation for module injector, since module injector
    // should not have access to Component/Directive DI scope (that may happen through
    // `directiveInject` implementation)
    const previousInjectImplementation = setInjectImplementation(undefined);
    try {
      if (moduleInjector) {
        return moduleInjector.get(token, notFoundValue, flags & InjectFlags.Optional);
      } else {
        return injectRootLimpMode(token, notFoundValue, flags & InjectFlags.Optional);
      }
    } finally {
      setInjectImplementation(previousInjectImplementation);
    }
  }
  return notFoundValueOrThrow(notFoundValue, token, flags);
}
/**
 * Returns the value associated to the given token from the NodeInjectors => ModuleInjector.
 *
 * Look for the injector providing the token by walking up the node injector tree and then
 * the module injector tree.
 *
 * This function patches `token` with `__NG_ELEMENT_ID__` which contains the id for the bloom
 * filter. `-1` is reserved for injecting `Injector` (implemented by `NodeInjector`)
 *
 * @param tNode The Node where the search for the injector should start
 * @param lView The `LView` that contains the `tNode`
 * @param token The token to look for
 * @param flags Injection flags
 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
 */
function getOrCreateInjectable(tNode, lView, token, flags = InjectFlags.Default, notFoundValue) {
  if (tNode !== null) {
    // If the view or any of its ancestors have an embedded
    // view injector, we have to look it up there first.
    if (lView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */ &&
    // The token must be present on the current node injector when the `Self`
    // flag is set, so the lookup on embedded view injector(s) can be skipped.
    !(flags & InjectFlags.Self)) {
      const embeddedInjectorValue = lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, NOT_FOUND);
      if (embeddedInjectorValue !== NOT_FOUND) {
        return embeddedInjectorValue;
      }
    }
    // Otherwise try the node injector.
    const value = lookupTokenUsingNodeInjector(tNode, lView, token, flags, NOT_FOUND);
    if (value !== NOT_FOUND) {
      return value;
    }
  }
  // Finally, fall back to the module injector.
  return lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
}
/**
 * Returns the value associated to the given token from the node injector.
 *
 * @param tNode The Node where the search for the injector should start
 * @param lView The `LView` that contains the `tNode`
 * @param token The token to look for
 * @param flags Injection flags
 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
 */
function lookupTokenUsingNodeInjector(tNode, lView, token, flags, notFoundValue) {
  const bloomHash = bloomHashBitOrFactory(token);
  // If the ID stored here is a function, this is a special object like ElementRef or TemplateRef
  // so just call the factory function to create it.
  if (typeof bloomHash === 'function') {
    if (!enterDI(lView, tNode, flags)) {
      // Failed to enter DI, try module injector instead. If a token is injected with the @Host
      // flag, the module injector is not searched for that token in Ivy.
      return flags & InjectFlags.Host ? notFoundValueOrThrow(notFoundValue, token, flags) : lookupTokenUsingModuleInjector(lView, token, flags, notFoundValue);
    }
    try {
      let value;
      if (ngDevMode) {
        runInInjectorProfilerContext(new NodeInjector(getCurrentTNode(), getLView()), token, () => {
          value = bloomHash(flags);
          if (value != null) {
            emitInstanceCreatedByInjectorEvent(value);
          }
        });
      } else {
        value = bloomHash(flags);
      }
      if (value == null && !(flags & InjectFlags.Optional)) {
        throwProviderNotFoundError(token);
      } else {
        return value;
      }
    } finally {
      leaveDI();
    }
  } else if (typeof bloomHash === 'number') {
    // A reference to the previous injector TView that was found while climbing the element
    // injector tree. This is used to know if viewProviders can be accessed on the current
    // injector.
    let previousTView = null;
    let injectorIndex = getInjectorIndex(tNode, lView);
    let parentLocation = NO_PARENT_INJECTOR;
    let hostTElementNode = flags & InjectFlags.Host ? lView[DECLARATION_COMPONENT_VIEW][T_HOST] : null;
    // If we should skip this injector, or if there is no injector on this node, start by
    // searching the parent injector.
    if (injectorIndex === -1 || flags & InjectFlags.SkipSelf) {
      parentLocation = injectorIndex === -1 ? getParentInjectorLocation(tNode, lView) : lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */];
      if (parentLocation === NO_PARENT_INJECTOR || !shouldSearchParent(flags, false)) {
        injectorIndex = -1;
      } else {
        previousTView = lView[TVIEW];
        injectorIndex = getParentInjectorIndex(parentLocation);
        lView = getParentInjectorView(parentLocation, lView);
      }
    }
    // Traverse up the injector tree until we find a potential match or until we know there
    // *isn't* a match.
    while (injectorIndex !== -1) {
      ngDevMode && assertNodeInjector(lView, injectorIndex);
      // Check the current injector. If it matches, see if it contains token.
      const tView = lView[TVIEW];
      ngDevMode && assertTNodeForLView(tView.data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */], lView);
      if (bloomHasToken(bloomHash, injectorIndex, tView.data)) {
        // At this point, we have an injector which *may* contain the token, so we step through
        // the providers and directives associated with the injector's corresponding node to get
        // the instance.
        const instance = searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode);
        if (instance !== NOT_FOUND) {
          return instance;
        }
      }
      parentLocation = lView[injectorIndex + 8 /* NodeInjectorOffset.PARENT */];
      if (parentLocation !== NO_PARENT_INJECTOR && shouldSearchParent(flags, lView[TVIEW].data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */] === hostTElementNode) && bloomHasToken(bloomHash, injectorIndex, lView)) {
        // The def wasn't found anywhere on this node, so it was a false positive.
        // Traverse up the tree and continue searching.
        previousTView = tView;
        injectorIndex = getParentInjectorIndex(parentLocation);
        lView = getParentInjectorView(parentLocation, lView);
      } else {
        // If we should not search parent OR If the ancestor bloom filter value does not have the
        // bit corresponding to the directive we can give up on traversing up to find the specific
        // injector.
        injectorIndex = -1;
      }
    }
  }
  return notFoundValue;
}
function searchTokensOnInjector(injectorIndex, lView, token, previousTView, flags, hostTElementNode) {
  const currentTView = lView[TVIEW];
  const tNode = currentTView.data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */];
  // First, we need to determine if view providers can be accessed by the starting element.
  // There are two possibilities
  const canAccessViewProviders = previousTView == null ?
  // 1) This is the first invocation `previousTView == null` which means that we are at the
  // `TNode` of where injector is starting to look. In such a case the only time we are allowed
  // to look into the ViewProviders is if:
  // - we are on a component
  // - AND the injector set `includeViewProviders` to true (implying that the token can see
  // ViewProviders because it is the Component or a Service which itself was declared in
  // ViewProviders)
  isComponentHost(tNode) && includeViewProviders :
  // 2) `previousTView != null` which means that we are now walking across the parent nodes.
  // In such a case we are only allowed to look into the ViewProviders if:
  // - We just crossed from child View to Parent View `previousTView != currentTView`
  // - AND the parent TNode is an Element.
  // This means that we just came from the Component's View and therefore are allowed to see
  // into the ViewProviders.
  previousTView != currentTView && (tNode.type & 3 /* TNodeType.AnyRNode */) !== 0;
  // This special case happens when there is a @host on the inject and when we are searching
  // on the host element node.
  const isHostSpecialCase = flags & InjectFlags.Host && hostTElementNode === tNode;
  const injectableIdx = locateDirectiveOrProvider(tNode, currentTView, token, canAccessViewProviders, isHostSpecialCase);
  if (injectableIdx !== null) {
    return getNodeInjectable(lView, currentTView, injectableIdx, tNode);
  } else {
    return NOT_FOUND;
  }
}
/**
 * Searches for the given token among the node's directives and providers.
 *
 * @param tNode TNode on which directives are present.
 * @param tView The tView we are currently processing
 * @param token Provider token or type of a directive to look for.
 * @param canAccessViewProviders Whether view providers should be considered.
 * @param isHostSpecialCase Whether the host special case applies.
 * @returns Index of a found directive or provider, or null when none found.
 */
function locateDirectiveOrProvider(tNode, tView, token, canAccessViewProviders, isHostSpecialCase) {
  const nodeProviderIndexes = tNode.providerIndexes;
  const tInjectables = tView.data;
  const injectablesStart = nodeProviderIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
  const directivesStart = tNode.directiveStart;
  const directiveEnd = tNode.directiveEnd;
  const cptViewProvidersCount = nodeProviderIndexes >> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */;
  const startingIndex = canAccessViewProviders ? injectablesStart : injectablesStart + cptViewProvidersCount;
  // When the host special case applies, only the viewProviders and the component are visible
  const endIndex = isHostSpecialCase ? injectablesStart + cptViewProvidersCount : directiveEnd;
  for (let i = startingIndex; i < endIndex; i++) {
    const providerTokenOrDef = tInjectables[i];
    if (i < directivesStart && token === providerTokenOrDef || i >= directivesStart && providerTokenOrDef.type === token) {
      return i;
    }
  }
  if (isHostSpecialCase) {
    const dirDef = tInjectables[directivesStart];
    if (dirDef && isComponentDef(dirDef) && dirDef.type === token) {
      return directivesStart;
    }
  }
  return null;
}
/**
 * Retrieve or instantiate the injectable from the `LView` at particular `index`.
 *
 * This function checks to see if the value has already been instantiated and if so returns the
 * cached `injectable`. Otherwise if it detects that the value is still a factory it
 * instantiates the `injectable` and caches the value.
 */
function getNodeInjectable(lView, tView, index, tNode) {
  let value = lView[index];
  const tData = tView.data;
  if (isFactory(value)) {
    const factory = value;
    if (factory.resolving) {
      throwCyclicDependencyError(stringifyForError(tData[index]));
    }
    const previousIncludeViewProviders = setIncludeViewProviders(factory.canSeeViewProviders);
    factory.resolving = true;
    let prevInjectContext;
    if (ngDevMode) {
      // tData indexes mirror the concrete instances in its corresponding LView.
      // lView[index] here is either the injectable instace itself or a factory,
      // therefore tData[index] is the constructor of that injectable or a
      // definition object that contains the constructor in a `.type` field.
      const token = tData[index].type || tData[index];
      const injector = new NodeInjector(tNode, lView);
      prevInjectContext = setInjectorProfilerContext({
        injector,
        token
      });
    }
    const previousInjectImplementation = factory.injectImpl ? setInjectImplementation(factory.injectImpl) : null;
    const success = enterDI(lView, tNode, InjectFlags.Default);
    ngDevMode && assertEqual(success, true, 'Because flags do not contain \`SkipSelf\' we expect this to always succeed.');
    try {
      value = lView[index] = factory.factory(undefined, tData, lView, tNode);
      ngDevMode && emitInstanceCreatedByInjectorEvent(value);
      // This code path is hit for both directives and providers.
      // For perf reasons, we want to avoid searching for hooks on providers.
      // It does no harm to try (the hooks just won't exist), but the extra
      // checks are unnecessary and this is a hot path. So we check to see
      // if the index of the dependency is in the directive range for this
      // tNode. If it's not, we know it's a provider and skip hook registration.
      if (tView.firstCreatePass && index >= tNode.directiveStart) {
        ngDevMode && assertDirectiveDef(tData[index]);
        registerPreOrderHooks(index, tData[index], tView);
      }
    } finally {
      ngDevMode && setInjectorProfilerContext(prevInjectContext);
      previousInjectImplementation !== null && setInjectImplementation(previousInjectImplementation);
      setIncludeViewProviders(previousIncludeViewProviders);
      factory.resolving = false;
      leaveDI();
    }
  }
  return value;
}
/**
 * Returns the bit in an injector's bloom filter that should be used to determine whether or not
 * the directive might be provided by the injector.
 *
 * When a directive is public, it is added to the bloom filter and given a unique ID that can be
 * retrieved on the Type. When the directive isn't public or the token is not a directive `null`
 * is returned as the node injector can not possibly provide that token.
 *
 * @param token the injection token
 * @returns the matching bit to check in the bloom filter or `null` if the token is not known.
 *   When the returned value is negative then it represents special values such as `Injector`.
 */
function bloomHashBitOrFactory(token) {
  ngDevMode && assertDefined(token, 'token must be defined');
  if (typeof token === 'string') {
    return token.charCodeAt(0) || 0;
  }
  const tokenId =
  // First check with `hasOwnProperty` so we don't get an inherited ID.
  token.hasOwnProperty(NG_ELEMENT_ID) ? token[NG_ELEMENT_ID] : undefined;
  // Negative token IDs are used for special objects such as `Injector`
  if (typeof tokenId === 'number') {
    if (tokenId >= 0) {
      return tokenId & BLOOM_MASK;
    } else {
      ngDevMode && assertEqual(tokenId, -1 /* InjectorMarkers.Injector */, 'Expecting to get Special Injector Id');
      return createNodeInjector;
    }
  } else {
    return tokenId;
  }
}
function bloomHasToken(bloomHash, injectorIndex, injectorView) {
  // Create a mask that targets the specific bit associated with the directive we're looking for.
  // JS bit operations are 32 bits, so this will be a number between 2^0 and 2^31, corresponding
  // to bit positions 0 - 31 in a 32 bit integer.
  const mask = 1 << bloomHash;
  // Each bloom bucket in `injectorView` represents `BLOOM_BUCKET_BITS` number of bits of
  // `bloomHash`. Any bits in `bloomHash` beyond `BLOOM_BUCKET_BITS` indicate the bucket offset
  // that should be used.
  const value = injectorView[injectorIndex + (bloomHash >> BLOOM_BUCKET_BITS)];
  // If the bloom filter value has the bit corresponding to the directive's bloomBit flipped on,
  // this injector is a potential match.
  return !!(value & mask);
}
/** Returns true if flags prevent parent injector from being searched for tokens */
function shouldSearchParent(flags, isFirstHostTNode) {
  return !(flags & InjectFlags.Self) && !(flags & InjectFlags.Host && isFirstHostTNode);
}
function getNodeInjectorLView(nodeInjector) {
  return nodeInjector._lView;
}
function getNodeInjectorTNode(nodeInjector) {
  return nodeInjector._tNode;
}
class NodeInjector {
  constructor(_tNode, _lView) {
    this._tNode = _tNode;
    this._lView = _lView;
  }
  get(token, notFoundValue, flags) {
    return getOrCreateInjectable(this._tNode, this._lView, token, convertToBitFlags(flags), notFoundValue);
  }
}
/** Creates a `NodeInjector` for the current node. */
function createNodeInjector() {
  return new NodeInjector(getCurrentTNode(), getLView());
}
/**
 * @codeGenApi
 */
function ɵɵgetInheritedFactory(type) {
  return noSideEffects(() => {
    const ownConstructor = type.prototype.constructor;
    const ownFactory = ownConstructor[NG_FACTORY_DEF] || getFactoryOf(ownConstructor);
    const objectPrototype = Object.prototype;
    let parent = Object.getPrototypeOf(type.prototype).constructor;
    // Go up the prototype until we hit `Object`.
    while (parent && parent !== objectPrototype) {
      const factory = parent[NG_FACTORY_DEF] || getFactoryOf(parent);
      // If we hit something that has a factory and the factory isn't the same as the type,
      // we've found the inherited factory. Note the check that the factory isn't the type's
      // own factory is redundant in most cases, but if the user has custom decorators on the
      // class, this lookup will start one level down in the prototype chain, causing us to
      // find the own factory first and potentially triggering an infinite loop downstream.
      if (factory && factory !== ownFactory) {
        return factory;
      }
      parent = Object.getPrototypeOf(parent);
    }
    // There is no factory defined. Either this was improper usage of inheritance
    // (no Angular decorator on the superclass) or there is no constructor at all
    // in the inheritance chain. Since the two cases cannot be distinguished, the
    // latter has to be assumed.
    return t => new t();
  });
}
function getFactoryOf(type) {
  if (isForwardRef(type)) {
    return () => {
      const factory = getFactoryOf(resolveForwardRef(type));
      return factory && factory();
    };
  }
  return getFactoryDef(type);
}
/**
 * Returns a value from the closest embedded or node injector.
 *
 * @param tNode The Node where the search for the injector should start
 * @param lView The `LView` that contains the `tNode`
 * @param token The token to look for
 * @param flags Injection flags
 * @param notFoundValue The value to return when the injection flags is `InjectFlags.Optional`
 * @returns the value from the injector, `null` when not found, or `notFoundValue` if provided
 */
function lookupTokenUsingEmbeddedInjector(tNode, lView, token, flags, notFoundValue) {
  let currentTNode = tNode;
  let currentLView = lView;
  // When an LView with an embedded view injector is inserted, it'll likely be interlaced with
  // nodes who may have injectors (e.g. node injector -> embedded view injector -> node injector).
  // Since the bloom filters for the node injectors have already been constructed and we don't
  // have a way of extracting the records from an injector, the only way to maintain the correct
  // hierarchy when resolving the value is to walk it node-by-node while attempting to resolve
  // the token at each level.
  while (currentTNode !== null && currentLView !== null && currentLView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */ && !(currentLView[FLAGS] & 512 /* LViewFlags.IsRoot */)) {
    ngDevMode && assertTNodeForLView(currentTNode, currentLView);
    // Note that this lookup on the node injector is using the `Self` flag, because
    // we don't want the node injector to look at any parent injectors since we
    // may hit the embedded view injector first.
    const nodeInjectorValue = lookupTokenUsingNodeInjector(currentTNode, currentLView, token, flags | InjectFlags.Self, NOT_FOUND);
    if (nodeInjectorValue !== NOT_FOUND) {
      return nodeInjectorValue;
    }
    // Has an explicit type due to a TS bug: https://github.com/microsoft/TypeScript/issues/33191
    let parentTNode = currentTNode.parent;
    // `TNode.parent` includes the parent within the current view only. If it doesn't exist,
    // it means that we've hit the view boundary and we need to go up to the next view.
    if (!parentTNode) {
      // Before we go to the next LView, check if the token exists on the current embedded injector.
      const embeddedViewInjector = currentLView[EMBEDDED_VIEW_INJECTOR];
      if (embeddedViewInjector) {
        const embeddedViewInjectorValue = embeddedViewInjector.get(token, NOT_FOUND, flags);
        if (embeddedViewInjectorValue !== NOT_FOUND) {
          return embeddedViewInjectorValue;
        }
      }
      // Otherwise keep going up the tree.
      parentTNode = getTNodeFromLView(currentLView);
      currentLView = currentLView[DECLARATION_VIEW];
    }
    currentTNode = parentTNode;
  }
  return notFoundValue;
}
/** Gets the TNode associated with an LView inside of the declaration view. */
function getTNodeFromLView(lView) {
  const tView = lView[TVIEW];
  const tViewType = tView.type;
  // The parent pointer differs based on `TView.type`.
  if (tViewType === 2 /* TViewType.Embedded */) {
    ngDevMode && assertDefined(tView.declTNode, 'Embedded TNodes should have declaration parents.');
    return tView.declTNode;
  } else if (tViewType === 1 /* TViewType.Component */) {
    // Components don't have `TView.declTNode` because each instance of component could be
    // inserted in different location, hence `TView.declTNode` is meaningless.
    return lView[T_HOST];
  }
  return null;
}

/**
 * Facade for the attribute injection from DI.
 *
 * @codeGenApi
 */
function ɵɵinjectAttribute(attrNameToInject) {
  return injectAttributeImpl(getCurrentTNode(), attrNameToInject);
}

/**
 * Attribute decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Attribute = makeParamDecorator('Attribute', attributeName => ({
  attributeName,
  __NG_ELEMENT_ID__: () => ɵɵinjectAttribute(attributeName)
}));
let _reflect = null;
function getReflect() {
  return _reflect = _reflect || new ReflectionCapabilities();
}
function reflectDependencies(type) {
  return convertDependencies(getReflect().parameters(type));
}
function convertDependencies(deps) {
  return deps.map(dep => reflectDependency(dep));
}
function reflectDependency(dep) {
  const meta = {
    token: null,
    attribute: null,
    host: false,
    optional: false,
    self: false,
    skipSelf: false
  };
  if (Array.isArray(dep) && dep.length > 0) {
    for (let j = 0; j < dep.length; j++) {
      const param = dep[j];
      if (param === undefined) {
        // param may be undefined if type of dep is not set by ngtsc
        continue;
      }
      const proto = Object.getPrototypeOf(param);
      if (param instanceof Optional || proto.ngMetadataName === 'Optional') {
        meta.optional = true;
      } else if (param instanceof SkipSelf || proto.ngMetadataName === 'SkipSelf') {
        meta.skipSelf = true;
      } else if (param instanceof Self || proto.ngMetadataName === 'Self') {
        meta.self = true;
      } else if (param instanceof Host || proto.ngMetadataName === 'Host') {
        meta.host = true;
      } else if (param instanceof Inject) {
        meta.token = param.token;
      } else if (param instanceof Attribute) {
        if (param.attributeName === undefined) {
          throw new RuntimeError(204 /* RuntimeErrorCode.INVALID_INJECTION_TOKEN */, ngDevMode && `Attribute name must be defined.`);
        }
        meta.attribute = param.attributeName;
      } else {
        meta.token = param;
      }
    }
  } else if (dep === undefined || Array.isArray(dep) && dep.length === 0) {
    meta.token = null;
  } else {
    meta.token = dep;
  }
  return meta;
}

/**
 * Compile an Angular injectable according to its `Injectable` metadata, and patch the resulting
 * injectable def (`ɵprov`) onto the injectable type.
 */
function compileInjectable(type, meta) {
  let ngInjectableDef = null;
  let ngFactoryDef = null;
  // if NG_PROV_DEF is already defined on this class then don't overwrite it
  if (!type.hasOwnProperty(NG_PROV_DEF)) {
    Object.defineProperty(type, NG_PROV_DEF, {
      get: () => {
        if (ngInjectableDef === null) {
          const compiler = getCompilerFacade({
            usage: 0 /* JitCompilerUsage.Decorator */,
            kind: 'injectable',
            type
          });
          ngInjectableDef = compiler.compileInjectable(angularCoreDiEnv, `ng:///${type.name}/ɵprov.js`, getInjectableMetadata(type, meta));
        }
        return ngInjectableDef;
      }
    });
  }
  // if NG_FACTORY_DEF is already defined on this class then don't overwrite it
  if (!type.hasOwnProperty(NG_FACTORY_DEF)) {
    Object.defineProperty(type, NG_FACTORY_DEF, {
      get: () => {
        if (ngFactoryDef === null) {
          const compiler = getCompilerFacade({
            usage: 0 /* JitCompilerUsage.Decorator */,
            kind: 'injectable',
            type
          });
          ngFactoryDef = compiler.compileFactory(angularCoreDiEnv, `ng:///${type.name}/ɵfac.js`, {
            name: type.name,
            type,
            typeArgumentCount: 0,
            // In JIT mode types are not available nor used.
            deps: reflectDependencies(type),
            target: compiler.FactoryTarget.Injectable
          });
        }
        return ngFactoryDef;
      },
      // Leave this configurable so that the factories from directives or pipes can take precedence.
      configurable: true
    });
  }
}
const USE_VALUE = getClosureSafeProperty({
  provide: String,
  useValue: getClosureSafeProperty
});
function isUseClassProvider(meta) {
  return meta.useClass !== undefined;
}
function isUseValueProvider(meta) {
  return USE_VALUE in meta;
}
function isUseFactoryProvider(meta) {
  return meta.useFactory !== undefined;
}
function isUseExistingProvider(meta) {
  return meta.useExisting !== undefined;
}
function getInjectableMetadata(type, srcMeta) {
  // Allow the compilation of a class with a `@Injectable()` decorator without parameters
  const meta = srcMeta || {
    providedIn: null
  };
  const compilerMeta = {
    name: type.name,
    type: type,
    typeArgumentCount: 0,
    providedIn: meta.providedIn
  };
  if ((isUseClassProvider(meta) || isUseFactoryProvider(meta)) && meta.deps !== undefined) {
    compilerMeta.deps = convertDependencies(meta.deps);
  }
  // Check to see if the user explicitly provided a `useXxxx` property.
  if (isUseClassProvider(meta)) {
    compilerMeta.useClass = meta.useClass;
  } else if (isUseValueProvider(meta)) {
    compilerMeta.useValue = meta.useValue;
  } else if (isUseFactoryProvider(meta)) {
    compilerMeta.useFactory = meta.useFactory;
  } else if (isUseExistingProvider(meta)) {
    compilerMeta.useExisting = meta.useExisting;
  }
  return compilerMeta;
}

/**
 * Injectable decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Injectable = makeDecorator('Injectable', undefined, undefined, undefined, (type, meta) => compileInjectable(type, meta));

/**
 * Create a new `Injector` which is configured using a `defType` of `InjectorType<any>`s.
 */
function createInjector(defType, parent = null, additionalProviders = null, name) {
  const injector = createInjectorWithoutInjectorInstances(defType, parent, additionalProviders, name);
  injector.resolveInjectorInitializers();
  return injector;
}
/**
 * Creates a new injector without eagerly resolving its injector types. Can be used in places
 * where resolving the injector types immediately can lead to an infinite loop. The injector types
 * should be resolved at a later point by calling `_resolveInjectorDefTypes`.
 */
function createInjectorWithoutInjectorInstances(defType, parent = null, additionalProviders = null, name, scopes = new Set()) {
  const providers = [additionalProviders || EMPTY_ARRAY, importProvidersFrom(defType)];
  name = name || (typeof defType === 'object' ? undefined : stringify(defType));
  return new R3Injector(providers, parent || getNullInjector(), name || null, scopes);
}

/**
 * Concrete injectors implement this interface. Injectors are configured
 * with [providers](guide/dependency-injection-providers) that associate
 * dependencies of various types with [injection tokens](guide/dependency-injection-providers).
 *
 * @see [DI Providers](guide/dependency-injection-providers).
 * @see {@link StaticProvider}
 *
 * @usageNotes
 *
 *  The following example creates a service injector instance.
 *
 * {@example core/di/ts/provider_spec.ts region='ConstructorProvider'}
 *
 * ### Usage example
 *
 * {@example core/di/ts/injector_spec.ts region='Injector'}
 *
 * `Injector` returns itself when given `Injector` as a token:
 *
 * {@example core/di/ts/injector_spec.ts region='injectInjector'}
 *
 * @publicApi
 */
class Injector {
  static {
    this.THROW_IF_NOT_FOUND = THROW_IF_NOT_FOUND;
  }
  static {
    this.NULL = /* @__PURE__ */new NullInjector();
  }
  static create(options, parent) {
    if (Array.isArray(options)) {
      return createInjector({
        name: ''
      }, parent, options, '');
    } else {
      const name = options.name ?? '';
      return createInjector({
        name
      }, options.parent, options.providers, name);
    }
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: Injector,
      providedIn: 'any',
      factory: () => ɵɵinject(INJECTOR$1)
    });
  }
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = -1 /* InjectorMarkers.Injector */;
  }
}

/*!
 * @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
 */
/**
 * Creates a token that can be used to inject static attributes of the host node.
 *
 * @usageNotes
 * ### Injecting an attribute that is known to exist
 * ```typescript
 * @Directive()
 * class MyDir {
 *   attr: string = inject(new HostAttributeToken('some-attr'));
 * }
 * ```
 *
 * ### Optionally injecting an attribute
 * ```typescript
 * @Directive()
 * class MyDir {
 *   attr: string | null = inject(new HostAttributeToken('some-attr'), {optional: true});
 * }
 * ```
 * @publicApi
 */
class HostAttributeToken {
  constructor(attributeName) {
    this.attributeName = attributeName;
    /** @internal */
    this.__NG_ELEMENT_ID__ = () => ɵɵinjectAttribute(this.attributeName);
  }
  toString() {
    return `HostAttributeToken ${this.attributeName}`;
  }
}

/**
 * @module
 * @description
 * The `di` module provides dependency injection container services.
 */

/**
 * This file should not be necessary because node resolution should just default to `./di/index`!
 *
 * However it does not seem to work and it breaks:
 *  - //packages/animations/browser/test:test_web_chromium-local
 *  - //packages/compiler-cli/test:extract_i18n
 *  - //packages/compiler-cli/test:ngc
 *  - //packages/compiler-cli/test:perform_watch
 *  - //packages/compiler-cli/test/diagnostics:check_types
 *  - //packages/compiler-cli/test/transformers:test
 *  - //packages/compiler/test:test
 *  - //tools/public_api_guard:core_api
 *
 * Remove this file once the above is solved or wait until `ngc` is deleted and then it should be
 * safe to delete this file.
 */

const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
function wrappedError(message, originalError) {
  const msg = `${message} caused by: ${originalError instanceof Error ? originalError.message : originalError}`;
  const error = Error(msg);
  error[ERROR_ORIGINAL_ERROR] = originalError;
  return error;
}
function getOriginalError(error) {
  return error[ERROR_ORIGINAL_ERROR];
}

/**
 * Provides a hook for centralized exception handling.
 *
 * The default implementation of `ErrorHandler` prints error messages to the `console`. To
 * intercept error handling, write a custom exception handler that replaces this default as
 * appropriate for your app.
 *
 * @usageNotes
 * ### Example
 *
 * ```
 * class MyErrorHandler implements ErrorHandler {
 *   handleError(error) {
 *     // do something with the exception
 *   }
 * }
 *
 * @NgModule({
 *   providers: [{provide: ErrorHandler, useClass: MyErrorHandler}]
 * })
 * class MyModule {}
 * ```
 *
 * @publicApi
 */
class ErrorHandler {
  constructor() {
    /**
     * @internal
     */
    this._console = console;
  }
  handleError(error) {
    const originalError = this._findOriginalError(error);
    this._console.error('ERROR', error);
    if (originalError) {
      this._console.error('ORIGINAL ERROR', originalError);
    }
  }
  /** @internal */
  _findOriginalError(error) {
    let e = error && getOriginalError(error);
    while (e && getOriginalError(e)) {
      e = getOriginalError(e);
    }
    return e || null;
  }
}
/**
 * `InjectionToken` used to configure how to call the `ErrorHandler`.
 *
 * `NgZone` is provided by default today so the default (and only) implementation for this
 * is calling `ErrorHandler.handleError` outside of the Angular zone.
 */
const INTERNAL_APPLICATION_ERROR_HANDLER = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'internal error handler' : '', {
  providedIn: 'root',
  factory: () => {
    const userErrorHandler = inject(ErrorHandler);
    return userErrorHandler.handleError.bind(undefined);
  }
});

/**
 * `DestroyRef` lets you set callbacks to run for any cleanup or destruction behavior.
 * The scope of this destruction depends on where `DestroyRef` is injected. If `DestroyRef`
 * is injected in a component or directive, the callbacks run when that component or
 * directive is destroyed. Otherwise the callbacks run when a corresponding injector is destroyed.
 *
 * @publicApi
 */
class DestroyRef {
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = injectDestroyRef;
  }
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ENV_ID__ = injector => injector;
  }
}
class NodeInjectorDestroyRef extends DestroyRef {
  constructor(_lView) {
    super();
    this._lView = _lView;
  }
  onDestroy(callback) {
    storeLViewOnDestroy(this._lView, callback);
    return () => removeLViewOnDestroy(this._lView, callback);
  }
}
function injectDestroyRef() {
  return new NodeInjectorDestroyRef(getLView());
}

/**
 * An `OutputEmitterRef` is created by the `output()` function and can be
 * used to emit values to consumers of your directive or component.
 *
 * Consumers of your directive/component can bind to the output and
 * subscribe to changes via the bound event syntax. For example:
 *
 * ```html
 * <my-comp (valueChange)="processNewValue($event)" />
 * ```
 *
 * @developerPreview
 */
class OutputEmitterRef {
  constructor() {
    this.destroyed = false;
    this.listeners = null;
    this.errorHandler = inject(ErrorHandler, {
      optional: true
    });
    /** @internal */
    this.destroyRef = inject(DestroyRef);
    // Clean-up all listeners and mark as destroyed upon destroy.
    this.destroyRef.onDestroy(() => {
      this.destroyed = true;
      this.listeners = null;
    });
  }
  subscribe(callback) {
    if (this.destroyed) {
      throw new RuntimeError(953 /* RuntimeErrorCode.OUTPUT_REF_DESTROYED */, ngDevMode && 'Unexpected subscription to destroyed `OutputRef`. ' + 'The owning directive/component is destroyed.');
    }
    (this.listeners ??= []).push(callback);
    return {
      unsubscribe: () => {
        const idx = this.listeners?.indexOf(callback);
        if (idx !== undefined && idx !== -1) {
          this.listeners?.splice(idx, 1);
        }
      }
    };
  }
  /** Emits a new value to the output. */
  emit(value) {
    if (this.destroyed) {
      throw new RuntimeError(953 /* RuntimeErrorCode.OUTPUT_REF_DESTROYED */, ngDevMode && 'Unexpected emit for destroyed `OutputRef`. ' + 'The owning directive/component is destroyed.');
    }
    if (this.listeners === null) {
      return;
    }
    const previousConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      for (const listenerFn of this.listeners) {
        try {
          listenerFn(value);
        } catch (err) {
          this.errorHandler?.handleError(err);
        }
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(previousConsumer);
    }
  }
}
/** Gets the owning `DestroyRef` for the given output. */
function getOutputDestroyRef(ref) {
  return ref.destroyRef;
}

/**
 * The `output` function allows declaration of Angular outputs in
 * directives and components.
 *
 * You can use outputs to emit values to parent directives and component.
 * Parents can subscribe to changes via:
 *
 * - template event bindings. For example, `(myOutput)="doSomething($event)"`
 * - programmatic subscription by using `OutputRef#subscribe`.
 *
 * @usageNotes
 *
 * To use `output()`, import the function from `@angular/core`.
 *
 * ```
 * import {output} from '@angular/core`;
 * ```
 *
 * Inside your component, introduce a new class member and initialize
 * it with a call to `output`.
 *
 * ```ts
 * @Directive({
 *   ...
 * })
 * export class MyDir {
 *   nameChange = output<string>();    // OutputEmitterRef<string>
 *   onClick    = output();            // OutputEmitterRef<void>
 * }
 * ```
 *
 * You can emit values to consumers of your directive, by using
 * the `emit` method from `OutputEmitterRef`.
 *
 * ```ts
 * updateName(newName: string): void {
 *   this.nameChange.emit(newName);
 * }
 * ```
 *
 * @developerPreview
 * @initializerApiFunction {"showTypesInSignaturePreview": true}
 */
function output(opts) {
  ngDevMode && assertInInjectionContext(output);
  return new OutputEmitterRef();
}
function inputFunction(initialValue, opts) {
  ngDevMode && assertInInjectionContext(input);
  return createInputSignal(initialValue, opts);
}
function inputRequiredFunction(opts) {
  ngDevMode && assertInInjectionContext(input);
  return createInputSignal(REQUIRED_UNSET_VALUE, opts);
}
/**
 * The `input` function allows declaration of Angular inputs in directives
 * and components.
 *
 * There are two variants of inputs that can be declared:
 *
 *   1. **Optional inputs** with an initial value.
 *   2. **Required inputs** that consumers need to set.
 *
 * By default, the `input` function will declare optional inputs that
 * always have an initial value. Required inputs can be declared
 * using the `input.required()` function.
 *
 * Inputs are signals. The values of an input are exposed as a `Signal`.
 * The signal always holds the latest value of the input that is bound
 * from the parent.
 *
 * @usageNotes
 * To use signal-based inputs, import `input` from `@angular/core`.
 *
 * ```
 * import {input} from '@angular/core`;
 * ```
 *
 * Inside your component, introduce a new class member and initialize
 * it with a call to `input` or `input.required`.
 *
 * ```ts
 * @Component({
 *   ...
 * })
 * export class UserProfileComponent {
 *   firstName = input<string>();             // Signal<string|undefined>
 *   lastName  = input.required<string>();    // Signal<string>
 *   age       = input(0)                     // Signal<number>
 * }
 * ```
 *
 * Inside your component template, you can display values of the inputs
 * by calling the signal.
 *
 * ```html
 * <span>{{firstName()}}</span>
 * ```
 *
 * @developerPreview
 * @initializerApiFunction
 */
const input = (() => {
  // Note: This may be considered a side-effect, but nothing will depend on
  // this assignment, unless this `input` constant export is accessed. It's a
  // self-contained side effect that is local to the user facing`input` export.
  inputFunction.required = inputRequiredFunction;
  return inputFunction;
})();

/**
 * Creates an ElementRef from the most recent node.
 *
 * @returns The ElementRef instance to use
 */
function injectElementRef() {
  return createElementRef(getCurrentTNode(), getLView());
}
/**
 * Creates an ElementRef given a node.
 *
 * @param tNode The node for which you'd like an ElementRef
 * @param lView The view to which the node belongs
 * @returns The ElementRef instance to use
 */
function createElementRef(tNode, lView) {
  return new ElementRef(getNativeByTNode(tNode, lView));
}
/**
 * A wrapper around a native element inside of a View.
 *
 * An `ElementRef` is backed by a render-specific element. In the browser, this is usually a DOM
 * element.
 *
 * @security Permitting direct access to the DOM can make your application more vulnerable to
 * XSS attacks. Carefully review any use of `ElementRef` in your code. For more detail, see the
 * [Security Guide](https://g.co/ng/security).
 *
 * @publicApi
 */
// Note: We don't expose things like `Injector`, `ViewContainer`, ... here,
// i.e. users have to ask for what they need. With that, we can build better analysis tools
// and could do better codegen in the future.
class ElementRef {
  constructor(nativeElement) {
    this.nativeElement = nativeElement;
  }
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = injectElementRef;
  }
}
/**
 * Unwraps `ElementRef` and return the `nativeElement`.
 *
 * @param value value to unwrap
 * @returns `nativeElement` if `ElementRef` otherwise returns value as is.
 */
function unwrapElementRef(value) {
  return value instanceof ElementRef ? value.nativeElement : value;
}
class EventEmitter_ extends rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject {
  constructor(isAsync = false) {
    super();
    this.destroyRef = undefined;
    this.__isAsync = isAsync;
    // Attempt to retrieve a `DestroyRef` optionally.
    // For backwards compatibility reasons, this cannot be required
    if (isInInjectionContext()) {
      this.destroyRef = inject(DestroyRef, {
        optional: true
      }) ?? undefined;
    }
  }
  emit(value) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      super.next(value);
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
  subscribe(observerOrNext, error, complete) {
    let nextFn = observerOrNext;
    let errorFn = error || (() => null);
    let completeFn = complete;
    if (observerOrNext && typeof observerOrNext === 'object') {
      const observer = observerOrNext;
      nextFn = observer.next?.bind(observer);
      errorFn = observer.error?.bind(observer);
      completeFn = observer.complete?.bind(observer);
    }
    if (this.__isAsync) {
      errorFn = _wrapInTimeout(errorFn);
      if (nextFn) {
        nextFn = _wrapInTimeout(nextFn);
      }
      if (completeFn) {
        completeFn = _wrapInTimeout(completeFn);
      }
    }
    const sink = super.subscribe({
      next: nextFn,
      error: errorFn,
      complete: completeFn
    });
    if (observerOrNext instanceof rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription) {
      observerOrNext.add(sink);
    }
    return sink;
  }
}
function _wrapInTimeout(fn) {
  return value => {
    setTimeout(fn, undefined, value);
  };
}
/**
 * @publicApi
 */
const EventEmitter = EventEmitter_;
function symbolIterator() {
  // @ts-expect-error accessing a private member
  return this._results[Symbol.iterator]();
}
/**
 * An unmodifiable list of items that Angular keeps up to date when the state
 * of the application changes.
 *
 * The type of object that {@link ViewChildren}, {@link ContentChildren}, and {@link QueryList}
 * provide.
 *
 * Implements an iterable interface, therefore it can be used in both ES6
 * javascript `for (var i of items)` loops as well as in Angular templates with
 * `*ngFor="let i of myList"`.
 *
 * Changes can be observed by subscribing to the changes `Observable`.
 *
 * NOTE: In the future this class will implement an `Observable` interface.
 *
 * @usageNotes
 * ### Example
 * ```typescript
 * @Component({...})
 * class Container {
 *   @ViewChildren(Item) items:QueryList<Item>;
 * }
 * ```
 *
 * @publicApi
 */
class QueryList {
  static {
    Symbol.iterator;
  }
  /**
   * Returns `Observable` of `QueryList` notifying the subscriber of changes.
   */
  get changes() {
    return this._changes ??= new EventEmitter();
  }
  /**
   * @param emitDistinctChangesOnly Whether `QueryList.changes` should fire only when actual change
   *     has occurred. Or if it should fire when query is recomputed. (recomputing could resolve in
   *     the same result)
   */
  constructor(_emitDistinctChangesOnly = false) {
    this._emitDistinctChangesOnly = _emitDistinctChangesOnly;
    this.dirty = true;
    this._onDirty = undefined;
    this._results = [];
    this._changesDetected = false;
    this._changes = undefined;
    this.length = 0;
    this.first = undefined;
    this.last = undefined;
    // This function should be declared on the prototype, but doing so there will cause the class
    // declaration to have side-effects and become not tree-shakable. For this reason we do it in
    // the constructor.
    // [Symbol.iterator](): Iterator<T> { ... }
    const proto = QueryList.prototype;
    if (!proto[Symbol.iterator]) proto[Symbol.iterator] = symbolIterator;
  }
  /**
   * Returns the QueryList entry at `index`.
   */
  get(index) {
    return this._results[index];
  }
  /**
   * See
   * [Array.map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
   */
  map(fn) {
    return this._results.map(fn);
  }
  filter(fn) {
    return this._results.filter(fn);
  }
  /**
   * See
   * [Array.find](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find)
   */
  find(fn) {
    return this._results.find(fn);
  }
  /**
   * See
   * [Array.reduce](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce)
   */
  reduce(fn, init) {
    return this._results.reduce(fn, init);
  }
  /**
   * See
   * [Array.forEach](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach)
   */
  forEach(fn) {
    this._results.forEach(fn);
  }
  /**
   * See
   * [Array.some](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some)
   */
  some(fn) {
    return this._results.some(fn);
  }
  /**
   * Returns a copy of the internal results list as an Array.
   */
  toArray() {
    return this._results.slice();
  }
  toString() {
    return this._results.toString();
  }
  /**
   * Updates the stored data of the query list, and resets the `dirty` flag to `false`, so that
   * on change detection, it will not notify of changes to the queries, unless a new change
   * occurs.
   *
   * @param resultsTree The query results to store
   * @param identityAccessor Optional function for extracting stable object identity from a value
   *    in the array. This function is executed for each element of the query result list while
   *    comparing current query list with the new one (provided as a first argument of the `reset`
   *    function) to detect if the lists are different. If the function is not provided, elements
   *    are compared as is (without any pre-processing).
   */
  reset(resultsTree, identityAccessor) {
    this.dirty = false;
    const newResultFlat = flatten(resultsTree);
    if (this._changesDetected = !arrayEquals(this._results, newResultFlat, identityAccessor)) {
      this._results = newResultFlat;
      this.length = newResultFlat.length;
      this.last = newResultFlat[this.length - 1];
      this.first = newResultFlat[0];
    }
  }
  /**
   * Triggers a change event by emitting on the `changes` {@link EventEmitter}.
   */
  notifyOnChanges() {
    if (this._changes !== undefined && (this._changesDetected || !this._emitDistinctChangesOnly)) this._changes.emit(this);
  }
  /** @internal */
  onDirty(cb) {
    this._onDirty = cb;
  }
  /** internal */
  setDirty() {
    this.dirty = true;
    this._onDirty?.();
  }
  /** internal */
  destroy() {
    if (this._changes !== undefined) {
      this._changes.complete();
      this._changes.unsubscribe();
    }
  }
}

/**
 * The name of an attribute that can be added to the hydration boundary node
 * (component host node) to disable hydration for the content within that boundary.
 */
const SKIP_HYDRATION_ATTR_NAME = 'ngSkipHydration';
/** Lowercase name of the `ngSkipHydration` attribute used for case-insensitive comparisons. */
const SKIP_HYDRATION_ATTR_NAME_LOWER_CASE = 'ngskiphydration';
/**
 * Helper function to check if a given TNode has the 'ngSkipHydration' attribute.
 */
function hasSkipHydrationAttrOnTNode(tNode) {
  const attrs = tNode.mergedAttrs;
  if (attrs === null) return false;
  // only ever look at the attribute name and skip the values
  for (let i = 0; i < attrs.length; i += 2) {
    const value = attrs[i];
    // This is a marker, which means that the static attributes section is over,
    // so we can exit early.
    if (typeof value === 'number') return false;
    if (typeof value === 'string' && value.toLowerCase() === SKIP_HYDRATION_ATTR_NAME_LOWER_CASE) {
      return true;
    }
  }
  return false;
}
/**
 * Helper function to check if a given RElement has the 'ngSkipHydration' attribute.
 */
function hasSkipHydrationAttrOnRElement(rNode) {
  return rNode.hasAttribute(SKIP_HYDRATION_ATTR_NAME);
}
/**
 * Checks whether a TNode has a flag to indicate that it's a part of
 * a skip hydration block.
 */
function hasInSkipHydrationBlockFlag(tNode) {
  return (tNode.flags & 128 /* TNodeFlags.inSkipHydrationBlock */) === 128 /* TNodeFlags.inSkipHydrationBlock */;
}
/**
 * Helper function that determines if a given node is within a skip hydration block
 * by navigating up the TNode tree to see if any parent nodes have skip hydration
 * attribute.
 */
function isInSkipHydrationBlock(tNode) {
  if (hasInSkipHydrationBlockFlag(tNode)) {
    return true;
  }
  let currentTNode = tNode.parent;
  while (currentTNode) {
    if (hasInSkipHydrationBlockFlag(tNode) || hasSkipHydrationAttrOnTNode(currentTNode)) {
      return true;
    }
    currentTNode = currentTNode.parent;
  }
  return false;
}

// Keeps track of the currently-active LViews.
const TRACKED_LVIEWS = new Map();
// Used for generating unique IDs for LViews.
let uniqueIdCounter = 0;
/** Gets a unique ID that can be assigned to an LView. */
function getUniqueLViewId() {
  return uniqueIdCounter++;
}
/** Starts tracking an LView. */
function registerLView(lView) {
  ngDevMode && assertNumber(lView[ID], 'LView must have an ID in order to be registered');
  TRACKED_LVIEWS.set(lView[ID], lView);
}
/** Gets an LView by its unique ID. */
function getLViewById(id) {
  ngDevMode && assertNumber(id, 'ID used for LView lookup must be a number');
  return TRACKED_LVIEWS.get(id) || null;
}
/** Stops tracking an LView. */
function unregisterLView(lView) {
  ngDevMode && assertNumber(lView[ID], 'Cannot stop tracking an LView that does not have an ID');
  TRACKED_LVIEWS.delete(lView[ID]);
}

/**
 * The internal view context which is specific to a given DOM element, directive or
 * component instance. Each value in here (besides the LView and element node details)
 * can be present, null or undefined. If undefined then it implies the value has not been
 * looked up yet, otherwise, if null, then a lookup was executed and nothing was found.
 *
 * Each value will get filled when the respective value is examined within the getContext
 * function. The component, element and each directive instance will share the same instance
 * of the context.
 */
class LContext {
  /** Component's parent view data. */
  get lView() {
    return getLViewById(this.lViewId);
  }
  constructor(
  /**
   * ID of the component's parent view data.
   */
  lViewId,
  /**
   * The index instance of the node.
   */
  nodeIndex,
  /**
   * The instance of the DOM node that is attached to the lNode.
   */
  native) {
    this.lViewId = lViewId;
    this.nodeIndex = nodeIndex;
    this.native = native;
  }
}

/**
 * Returns the matching `LContext` data for a given DOM node, directive or component instance.
 *
 * This function will examine the provided DOM element, component, or directive instance\'s
 * monkey-patched property to derive the `LContext` data. Once called then the monkey-patched
 * value will be that of the newly created `LContext`.
 *
 * If the monkey-patched value is the `LView` instance then the context value for that
 * target will be created and the monkey-patch reference will be updated. Therefore when this
 * function is called it may mutate the provided element\'s, component\'s or any of the associated
 * directive\'s monkey-patch values.
 *
 * If the monkey-patch value is not detected then the code will walk up the DOM until an element
 * is found which contains a monkey-patch reference. When that occurs then the provided element
 * will be updated with a new context (which is then returned). If the monkey-patch value is not
 * detected for a component/directive instance then it will throw an error (all components and
 * directives should be automatically monkey-patched by ivy).
 *
 * @param target Component, Directive or DOM Node.
 */
function getLContext(target) {
  let mpValue = readPatchedData(target);
  if (mpValue) {
    // only when it's an array is it considered an LView instance
    // ... otherwise it's an already constructed LContext instance
    if (isLView(mpValue)) {
      const lView = mpValue;
      let nodeIndex;
      let component = undefined;
      let directives = undefined;
      if (isComponentInstance(target)) {
        nodeIndex = findViaComponent(lView, target);
        if (nodeIndex == -1) {
          throw new Error('The provided component was not found in the application');
        }
        component = target;
      } else if (isDirectiveInstance(target)) {
        nodeIndex = findViaDirective(lView, target);
        if (nodeIndex == -1) {
          throw new Error('The provided directive was not found in the application');
        }
        directives = getDirectivesAtNodeIndex(nodeIndex, lView);
      } else {
        nodeIndex = findViaNativeElement(lView, target);
        if (nodeIndex == -1) {
          return null;
        }
      }
      // the goal is not to fill the entire context full of data because the lookups
      // are expensive. Instead, only the target data (the element, component, container, ICU
      // expression or directive details) are filled into the context. If called multiple times
      // with different target values then the missing target data will be filled in.
      const native = unwrapRNode(lView[nodeIndex]);
      const existingCtx = readPatchedData(native);
      const context = existingCtx && !Array.isArray(existingCtx) ? existingCtx : createLContext(lView, nodeIndex, native);
      // only when the component has been discovered then update the monkey-patch
      if (component && context.component === undefined) {
        context.component = component;
        attachPatchData(context.component, context);
      }
      // only when the directives have been discovered then update the monkey-patch
      if (directives && context.directives === undefined) {
        context.directives = directives;
        for (let i = 0; i < directives.length; i++) {
          attachPatchData(directives[i], context);
        }
      }
      attachPatchData(context.native, context);
      mpValue = context;
    }
  } else {
    const rElement = target;
    ngDevMode && assertDomNode(rElement);
    // if the context is not found then we need to traverse upwards up the DOM
    // to find the nearest element that has already been monkey patched with data
    let parent = rElement;
    while (parent = parent.parentNode) {
      const parentContext = readPatchedData(parent);
      if (parentContext) {
        const lView = Array.isArray(parentContext) ? parentContext : parentContext.lView;
        // the edge of the app was also reached here through another means
        // (maybe because the DOM was changed manually).
        if (!lView) {
          return null;
        }
        const index = findViaNativeElement(lView, rElement);
        if (index >= 0) {
          const native = unwrapRNode(lView[index]);
          const context = createLContext(lView, index, native);
          attachPatchData(native, context);
          mpValue = context;
          break;
        }
      }
    }
  }
  return mpValue || null;
}
/**
 * Creates an empty instance of a `LContext` context
 */
function createLContext(lView, nodeIndex, native) {
  return new LContext(lView[ID], nodeIndex, native);
}
/**
 * Takes a component instance and returns the view for that component.
 *
 * @param componentInstance
 * @returns The component's view
 */
function getComponentViewByInstance(componentInstance) {
  let patchedData = readPatchedData(componentInstance);
  let lView;
  if (isLView(patchedData)) {
    const contextLView = patchedData;
    const nodeIndex = findViaComponent(contextLView, componentInstance);
    lView = getComponentLViewByIndex(nodeIndex, contextLView);
    const context = createLContext(contextLView, nodeIndex, lView[HOST]);
    context.component = componentInstance;
    attachPatchData(componentInstance, context);
    attachPatchData(context.native, context);
  } else {
    const context = patchedData;
    const contextLView = context.lView;
    ngDevMode && assertLView(contextLView);
    lView = getComponentLViewByIndex(context.nodeIndex, contextLView);
  }
  return lView;
}
/**
 * This property will be monkey-patched on elements, components and directives.
 */
const MONKEY_PATCH_KEY_NAME = '__ngContext__';
/**
 * Assigns the given data to the given target (which could be a component,
 * directive or DOM node instance) using monkey-patching.
 */
function attachPatchData(target, data) {
  ngDevMode && assertDefined(target, 'Target expected');
  // Only attach the ID of the view in order to avoid memory leaks (see #41047). We only do this
  // for `LView`, because we have control over when an `LView` is created and destroyed, whereas
  // we can't know when to remove an `LContext`.
  if (isLView(data)) {
    target[MONKEY_PATCH_KEY_NAME] = data[ID];
    registerLView(data);
  } else {
    target[MONKEY_PATCH_KEY_NAME] = data;
  }
}
/**
 * Returns the monkey-patch value data present on the target (which could be
 * a component, directive or a DOM node).
 */
function readPatchedData(target) {
  ngDevMode && assertDefined(target, 'Target expected');
  const data = target[MONKEY_PATCH_KEY_NAME];
  return typeof data === 'number' ? getLViewById(data) : data || null;
}
function readPatchedLView(target) {
  const value = readPatchedData(target);
  if (value) {
    return isLView(value) ? value : value.lView;
  }
  return null;
}
function isComponentInstance(instance) {
  return instance && instance.constructor && instance.constructor.ɵcmp;
}
function isDirectiveInstance(instance) {
  return instance && instance.constructor && instance.constructor.ɵdir;
}
/**
 * Locates the element within the given LView and returns the matching index
 */
function findViaNativeElement(lView, target) {
  const tView = lView[TVIEW];
  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
    if (unwrapRNode(lView[i]) === target) {
      return i;
    }
  }
  return -1;
}
/**
 * Locates the next tNode (child, sibling or parent).
 */
function traverseNextElement(tNode) {
  if (tNode.child) {
    return tNode.child;
  } else if (tNode.next) {
    return tNode.next;
  } else {
    // Let's take the following template: <div><span>text</span></div><component/>
    // After checking the text node, we need to find the next parent that has a "next" TNode,
    // in this case the parent `div`, so that we can find the component.
    while (tNode.parent && !tNode.parent.next) {
      tNode = tNode.parent;
    }
    return tNode.parent && tNode.parent.next;
  }
}
/**
 * Locates the component within the given LView and returns the matching index
 */
function findViaComponent(lView, componentInstance) {
  const componentIndices = lView[TVIEW].components;
  if (componentIndices) {
    for (let i = 0; i < componentIndices.length; i++) {
      const elementComponentIndex = componentIndices[i];
      const componentView = getComponentLViewByIndex(elementComponentIndex, lView);
      if (componentView[CONTEXT] === componentInstance) {
        return elementComponentIndex;
      }
    }
  } else {
    const rootComponentView = getComponentLViewByIndex(HEADER_OFFSET, lView);
    const rootComponent = rootComponentView[CONTEXT];
    if (rootComponent === componentInstance) {
      // we are dealing with the root element here therefore we know that the
      // element is the very first element after the HEADER data in the lView
      return HEADER_OFFSET;
    }
  }
  return -1;
}
/**
 * Locates the directive within the given LView and returns the matching index
 */
function findViaDirective(lView, directiveInstance) {
  // if a directive is monkey patched then it will (by default)
  // have a reference to the LView of the current view. The
  // element bound to the directive being search lives somewhere
  // in the view data. We loop through the nodes and check their
  // list of directives for the instance.
  let tNode = lView[TVIEW].firstChild;
  while (tNode) {
    const directiveIndexStart = tNode.directiveStart;
    const directiveIndexEnd = tNode.directiveEnd;
    for (let i = directiveIndexStart; i < directiveIndexEnd; i++) {
      if (lView[i] === directiveInstance) {
        return tNode.index;
      }
    }
    tNode = traverseNextElement(tNode);
  }
  return -1;
}
/**
 * Returns a list of directives applied to a node at a specific index. The list includes
 * directives matched by selector and any host directives, but it excludes components.
 * Use `getComponentAtNodeIndex` to find the component applied to a node.
 *
 * @param nodeIndex The node index
 * @param lView The target view data
 */
function getDirectivesAtNodeIndex(nodeIndex, lView) {
  const tNode = lView[TVIEW].data[nodeIndex];
  if (tNode.directiveStart === 0) return EMPTY_ARRAY;
  const results = [];
  for (let i = tNode.directiveStart; i < tNode.directiveEnd; i++) {
    const directiveInstance = lView[i];
    if (!isComponentInstance(directiveInstance)) {
      results.push(directiveInstance);
    }
  }
  return results;
}
function getComponentAtNodeIndex(nodeIndex, lView) {
  const tNode = lView[TVIEW].data[nodeIndex];
  const {
    directiveStart,
    componentOffset
  } = tNode;
  return componentOffset > -1 ? lView[directiveStart + componentOffset] : null;
}
/**
 * Returns a map of local references (local reference name => element or directive instance) that
 * exist on a given element.
 */
function discoverLocalRefs(lView, nodeIndex) {
  const tNode = lView[TVIEW].data[nodeIndex];
  if (tNode && tNode.localNames) {
    const result = {};
    let localIndex = tNode.index + 1;
    for (let i = 0; i < tNode.localNames.length; i += 2) {
      result[tNode.localNames[i]] = lView[localIndex];
      localIndex++;
    }
    return result;
  }
  return null;
}

/**
 * Retrieve the root view from any component or `LView` by walking the parent `LView` until
 * reaching the root `LView`.
 *
 * @param componentOrLView any component or `LView`
 */
function getRootView(componentOrLView) {
  ngDevMode && assertDefined(componentOrLView, 'component');
  let lView = isLView(componentOrLView) ? componentOrLView : readPatchedLView(componentOrLView);
  while (lView && !(lView[FLAGS] & 512 /* LViewFlags.IsRoot */)) {
    lView = getLViewParent(lView);
  }
  ngDevMode && assertLView(lView);
  return lView;
}
/**
 * Returns the context information associated with the application where the target is situated. It
 * does this by walking the parent views until it gets to the root view, then getting the context
 * off of that.
 *
 * @param viewOrComponent the `LView` or component to get the root context for.
 */
function getRootContext(viewOrComponent) {
  const rootView = getRootView(viewOrComponent);
  ngDevMode && assertDefined(rootView[CONTEXT], 'Root view has no context. Perhaps it is disconnected?');
  return rootView[CONTEXT];
}
/**
 * Gets the first `LContainer` in the LView or `null` if none exists.
 */
function getFirstLContainer(lView) {
  return getNearestLContainer(lView[CHILD_HEAD]);
}
/**
 * Gets the next `LContainer` that is a sibling of the given container.
 */
function getNextLContainer(container) {
  return getNearestLContainer(container[NEXT]);
}
function getNearestLContainer(viewOrContainer) {
  while (viewOrContainer !== null && !isLContainer(viewOrContainer)) {
    viewOrContainer = viewOrContainer[NEXT];
  }
  return viewOrContainer;
}

/**
 * Retrieves the component instance associated with a given DOM element.
 *
 * @usageNotes
 * Given the following DOM structure:
 *
 * ```html
 * <app-root>
 *   <div>
 *     <child-comp></child-comp>
 *   </div>
 * </app-root>
 * ```
 *
 * Calling `getComponent` on `<child-comp>` will return the instance of `ChildComponent`
 * associated with this DOM element.
 *
 * Calling the function on `<app-root>` will return the `MyApp` instance.
 *
 *
 * @param element DOM element from which the component should be retrieved.
 * @returns Component instance associated with the element or `null` if there
 *    is no component associated with it.
 *
 * @publicApi
 * @globalApi ng
 */
function getComponent$1(element) {
  ngDevMode && assertDomElement(element);
  const context = getLContext(element);
  if (context === null) return null;
  if (context.component === undefined) {
    const lView = context.lView;
    if (lView === null) {
      return null;
    }
    context.component = getComponentAtNodeIndex(context.nodeIndex, lView);
  }
  return context.component;
}
/**
 * If inside an embedded view (e.g. `*ngIf` or `*ngFor`), retrieves the context of the embedded
 * view that the element is part of. Otherwise retrieves the instance of the component whose view
 * owns the element (in this case, the result is the same as calling `getOwningComponent`).
 *
 * @param element Element for which to get the surrounding component instance.
 * @returns Instance of the component that is around the element or null if the element isn't
 *    inside any component.
 *
 * @publicApi
 * @globalApi ng
 */
function getContext(element) {
  assertDomElement(element);
  const context = getLContext(element);
  const lView = context ? context.lView : null;
  return lView === null ? null : lView[CONTEXT];
}
/**
 * Retrieves the component instance whose view contains the DOM element.
 *
 * For example, if `<child-comp>` is used in the template of `<app-comp>`
 * (i.e. a `ViewChild` of `<app-comp>`), calling `getOwningComponent` on `<child-comp>`
 * would return `<app-comp>`.
 *
 * @param elementOrDir DOM element, component or directive instance
 *    for which to retrieve the root components.
 * @returns Component instance whose view owns the DOM element or null if the element is not
 *    part of a component view.
 *
 * @publicApi
 * @globalApi ng
 */
function getOwningComponent(elementOrDir) {
  const context = getLContext(elementOrDir);
  let lView = context ? context.lView : null;
  if (lView === null) return null;
  let parent;
  while (lView[TVIEW].type === 2 /* TViewType.Embedded */ && (parent = getLViewParent(lView))) {
    lView = parent;
  }
  return lView[FLAGS] & 512 /* LViewFlags.IsRoot */ ? null : lView[CONTEXT];
}
/**
 * Retrieves all root components associated with a DOM element, directive or component instance.
 * Root components are those which have been bootstrapped by Angular.
 *
 * @param elementOrDir DOM element, component or directive instance
 *    for which to retrieve the root components.
 * @returns Root components associated with the target object.
 *
 * @publicApi
 * @globalApi ng
 */
function getRootComponents(elementOrDir) {
  const lView = readPatchedLView(elementOrDir);
  return lView !== null ? [getRootContext(lView)] : [];
}
/**
 * Retrieves an `Injector` associated with an element, component or directive instance.
 *
 * @param elementOrDir DOM element, component or directive instance for which to
 *    retrieve the injector.
 * @returns Injector associated with the element, component or directive instance.
 *
 * @publicApi
 * @globalApi ng
 */
function getInjector(elementOrDir) {
  const context = getLContext(elementOrDir);
  const lView = context ? context.lView : null;
  if (lView === null) return Injector.NULL;
  const tNode = lView[TVIEW].data[context.nodeIndex];
  return new NodeInjector(tNode, lView);
}
/**
 * Retrieve a set of injection tokens at a given DOM node.
 *
 * @param element Element for which the injection tokens should be retrieved.
 */
function getInjectionTokens(element) {
  const context = getLContext(element);
  const lView = context ? context.lView : null;
  if (lView === null) return [];
  const tView = lView[TVIEW];
  const tNode = tView.data[context.nodeIndex];
  const providerTokens = [];
  const startIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
  const endIndex = tNode.directiveEnd;
  for (let i = startIndex; i < endIndex; i++) {
    let value = tView.data[i];
    if (isDirectiveDefHack(value)) {
      // The fact that we sometimes store Type and sometimes DirectiveDef in this location is a
      // design flaw.  We should always store same type so that we can be monomorphic. The issue
      // is that for Components/Directives we store the def instead the type. The correct behavior
      // is that we should always be storing injectable type in this location.
      value = value.type;
    }
    providerTokens.push(value);
  }
  return providerTokens;
}
/**
 * Retrieves directive instances associated with a given DOM node. Does not include
 * component instances.
 *
 * @usageNotes
 * Given the following DOM structure:
 *
 * ```html
 * <app-root>
 *   <button my-button></button>
 *   <my-comp></my-comp>
 * </app-root>
 * ```
 *
 * Calling `getDirectives` on `<button>` will return an array with an instance of the `MyButton`
 * directive that is associated with the DOM node.
 *
 * Calling `getDirectives` on `<my-comp>` will return an empty array.
 *
 * @param node DOM node for which to get the directives.
 * @returns Array of directives associated with the node.
 *
 * @publicApi
 * @globalApi ng
 */
function getDirectives(node) {
  // Skip text nodes because we can't have directives associated with them.
  if (node instanceof Text) {
    return [];
  }
  const context = getLContext(node);
  const lView = context ? context.lView : null;
  if (lView === null) {
    return [];
  }
  const tView = lView[TVIEW];
  const nodeIndex = context.nodeIndex;
  if (!tView?.data[nodeIndex]) {
    return [];
  }
  if (context.directives === undefined) {
    context.directives = getDirectivesAtNodeIndex(nodeIndex, lView);
  }
  // The `directives` in this case are a named array called `LComponentView`. Clone the
  // result so we don't expose an internal data structure in the user's console.
  return context.directives === null ? [] : [...context.directives];
}
/**
 * Returns the debug (partial) metadata for a particular directive or component instance.
 * The function accepts an instance of a directive or component and returns the corresponding
 * metadata.
 *
 * @param directiveOrComponentInstance Instance of a directive or component
 * @returns metadata of the passed directive or component
 *
 * @publicApi
 * @globalApi ng
 */
function getDirectiveMetadata$1(directiveOrComponentInstance) {
  const {
    constructor
  } = directiveOrComponentInstance;
  if (!constructor) {
    throw new Error('Unable to find the instance constructor');
  }
  // In case a component inherits from a directive, we may have component and directive metadata
  // To ensure we don't get the metadata of the directive, we want to call `getComponentDef` first.
  const componentDef = getComponentDef(constructor);
  if (componentDef) {
    const inputs = extractInputDebugMetadata(componentDef.inputs);
    return {
      inputs,
      outputs: componentDef.outputs,
      encapsulation: componentDef.encapsulation,
      changeDetection: componentDef.onPush ? ChangeDetectionStrategy.OnPush : ChangeDetectionStrategy.Default
    };
  }
  const directiveDef = getDirectiveDef(constructor);
  if (directiveDef) {
    const inputs = extractInputDebugMetadata(directiveDef.inputs);
    return {
      inputs,
      outputs: directiveDef.outputs
    };
  }
  return null;
}
/**
 * Retrieve map of local references.
 *
 * The references are retrieved as a map of local reference name to element or directive instance.
 *
 * @param target DOM element, component or directive instance for which to retrieve
 *    the local references.
 */
function getLocalRefs(target) {
  const context = getLContext(target);
  if (context === null) return {};
  if (context.localRefs === undefined) {
    const lView = context.lView;
    if (lView === null) {
      return {};
    }
    context.localRefs = discoverLocalRefs(lView, context.nodeIndex);
  }
  return context.localRefs || {};
}
/**
 * Retrieves the host element of a component or directive instance.
 * The host element is the DOM element that matched the selector of the directive.
 *
 * @param componentOrDirective Component or directive instance for which the host
 *     element should be retrieved.
 * @returns Host element of the target.
 *
 * @publicApi
 * @globalApi ng
 */
function getHostElement(componentOrDirective) {
  return getLContext(componentOrDirective).native;
}
/**
 * Retrieves the rendered text for a given component.
 *
 * This function retrieves the host element of a component and
 * and then returns the `textContent` for that element. This implies
 * that the text returned will include re-projected content of
 * the component as well.
 *
 * @param component The component to return the content text for.
 */
function getRenderedText(component) {
  const hostElement = getHostElement(component);
  return hostElement.textContent || '';
}
/**
 * Retrieves a list of event listeners associated with a DOM element. The list does include host
 * listeners, but it does not include event listeners defined outside of the Angular context
 * (e.g. through `addEventListener`).
 *
 * @usageNotes
 * Given the following DOM structure:
 *
 * ```html
 * <app-root>
 *   <div (click)="doSomething()"></div>
 * </app-root>
 * ```
 *
 * Calling `getListeners` on `<div>` will return an object that looks as follows:
 *
 * ```ts
 * {
 *   name: 'click',
 *   element: <div>,
 *   callback: () => doSomething(),
 *   useCapture: false
 * }
 * ```
 *
 * @param element Element for which the DOM listeners should be retrieved.
 * @returns Array of event listeners on the DOM element.
 *
 * @publicApi
 * @globalApi ng
 */
function getListeners(element) {
  ngDevMode && assertDomElement(element);
  const lContext = getLContext(element);
  const lView = lContext === null ? null : lContext.lView;
  if (lView === null) return [];
  const tView = lView[TVIEW];
  const lCleanup = lView[CLEANUP];
  const tCleanup = tView.cleanup;
  const listeners = [];
  if (tCleanup && lCleanup) {
    for (let i = 0; i < tCleanup.length;) {
      const firstParam = tCleanup[i++];
      const secondParam = tCleanup[i++];
      if (typeof firstParam === 'string') {
        const name = firstParam;
        const listenerElement = unwrapRNode(lView[secondParam]);
        const callback = lCleanup[tCleanup[i++]];
        const useCaptureOrIndx = tCleanup[i++];
        // if useCaptureOrIndx is boolean then report it as is.
        // if useCaptureOrIndx is positive number then it in unsubscribe method
        // if useCaptureOrIndx is negative number then it is a Subscription
        const type = typeof useCaptureOrIndx === 'boolean' || useCaptureOrIndx >= 0 ? 'dom' : 'output';
        const useCapture = typeof useCaptureOrIndx === 'boolean' ? useCaptureOrIndx : false;
        if (element == listenerElement) {
          listeners.push({
            element,
            name,
            callback,
            useCapture,
            type
          });
        }
      }
    }
  }
  listeners.sort(sortListeners);
  return listeners;
}
function sortListeners(a, b) {
  if (a.name == b.name) return 0;
  return a.name < b.name ? -1 : 1;
}
/**
 * This function should not exist because it is megamorphic and only mostly correct.
 *
 * See call site for more info.
 */
function isDirectiveDefHack(obj) {
  return obj.type !== undefined && obj.declaredInputs !== undefined && obj.findHostDirectiveDefs !== undefined;
}
/**
 * Retrieve the component `LView` from component/element.
 *
 * NOTE: `LView` is a private and should not be leaked outside.
 *       Don't export this method to `ng.*` on window.
 *
 * @param target DOM element or component instance for which to retrieve the LView.
 */
function getComponentLView(target) {
  const lContext = getLContext(target);
  const nodeIndx = lContext.nodeIndex;
  const lView = lContext.lView;
  ngDevMode && assertLView(lView);
  const componentLView = lView[nodeIndx];
  ngDevMode && assertLView(componentLView);
  return componentLView;
}
/** Asserts that a value is a DOM Element. */
function assertDomElement(value) {
  if (typeof Element !== 'undefined' && !(value instanceof Element)) {
    throw new Error('Expecting instance of DOM Element');
  }
}
/**
 * A directive definition holds additional metadata using bitwise flags to indicate
 * for example whether it is signal based.
 *
 * This information needs to be separate from the `publicName -> minifiedName`
 * mappings for backwards compatibility.
 */
function extractInputDebugMetadata(inputs) {
  const res = {};
  for (const key in inputs) {
    if (!inputs.hasOwnProperty(key)) {
      continue;
    }
    const value = inputs[key];
    if (value === undefined) {
      continue;
    }
    let minifiedName;
    if (Array.isArray(value)) {
      minifiedName = value[0];
      // flags are not used for now.
      // TODO: Consider exposing flag information in discovery.
    } else {
      minifiedName = value;
    }
    res[key] = minifiedName;
  }
  return res;
}

/**
 * Most of the use of `document` in Angular is from within the DI system so it is possible to simply
 * inject the `DOCUMENT` token and are done.
 *
 * Ivy is special because it does not rely upon the DI and must get hold of the document some other
 * way.
 *
 * The solution is to define `getDocument()` and `setDocument()` top-level functions for ivy.
 * Wherever ivy needs the global document, it calls `getDocument()` instead.
 *
 * When running ivy outside of a browser environment, it is necessary to call `setDocument()` to
 * tell ivy what the global `document` is.
 *
 * Angular does this for us in each of the standard platforms (`Browser` and `Server`)
 * by calling `setDocument()` when providing the `DOCUMENT` token.
 */
let DOCUMENT = undefined;
/**
 * Tell ivy what the `document` is for this platform.
 *
 * It is only necessary to call this if the current platform is not a browser.
 *
 * @param document The object representing the global `document` in this environment.
 */
function setDocument(document) {
  DOCUMENT = document;
}
/**
 * Access the object that represents the `document` for this platform.
 *
 * Ivy calls this whenever it needs to access the `document` object.
 * For example to create the renderer or to do sanitization.
 */
function getDocument() {
  if (DOCUMENT !== undefined) {
    return DOCUMENT;
  } else if (typeof document !== 'undefined') {
    return document;
  }
  throw new RuntimeError(210 /* RuntimeErrorCode.MISSING_DOCUMENT */, (typeof ngDevMode === 'undefined' || ngDevMode) && `The document object is not available in this context. Make sure the DOCUMENT injection token is provided.`);
  // No "document" can be found. This should only happen if we are running ivy outside Angular and
  // the current platform is not a browser. Since this is not a supported scenario at the moment
  // this should not happen in Angular apps.
  // Once we support running ivy outside of Angular we will need to publish `setDocument()` as a
  // public API.
}

/**
 * A [DI token](guide/glossary#di-token "DI token definition") representing a string ID, used
 * primarily for prefixing application attributes and CSS styles when
 * {@link ViewEncapsulation#Emulated} is being used.
 *
 * The token is needed in cases when multiple applications are bootstrapped on a page
 * (for example, using `bootstrapApplication` calls). In this case, ensure that those applications
 * have different `APP_ID` value setup. For example:
 *
 * ```
 * bootstrapApplication(ComponentA, {
 *   providers: [
 *     { provide: APP_ID, useValue: 'app-a' },
 *     // ... other providers ...
 *   ]
 * });
 *
 * bootstrapApplication(ComponentB, {
 *   providers: [
 *     { provide: APP_ID, useValue: 'app-b' },
 *     // ... other providers ...
 *   ]
 * });
 * ```
 *
 * By default, when there is only one application bootstrapped, you don't need to provide the
 * `APP_ID` token (the `ng` will be used as an app ID).
 *
 * @publicApi
 */
const APP_ID = new InjectionToken(ngDevMode ? 'AppId' : '', {
  providedIn: 'root',
  factory: () => DEFAULT_APP_ID
});
/** Default value of the `APP_ID` token. */
const DEFAULT_APP_ID = 'ng';
/**
 * A function that is executed when a platform is initialized.
 * @publicApi
 */
const PLATFORM_INITIALIZER = new InjectionToken(ngDevMode ? 'Platform Initializer' : '');
/**
 * A token that indicates an opaque platform ID.
 * @publicApi
 */
const PLATFORM_ID = new InjectionToken(ngDevMode ? 'Platform ID' : '', {
  providedIn: 'platform',
  factory: () => 'unknown' // set a default platform name, when none set explicitly
});
/**
 * A [DI token](guide/glossary#di-token "DI token definition") that indicates the root directory of
 * the application
 * @publicApi
 * @deprecated
 */
const PACKAGE_ROOT_URL = new InjectionToken(ngDevMode ? 'Application Packages Root URL' : '');
// We keep this token here, rather than the animations package, so that modules that only care
// about which animations module is loaded (e.g. the CDK) can retrieve it without having to
// include extra dependencies. See #44970 for more context.
/**
 * A [DI token](api/core/InjectionToken) that indicates which animations
 * module has been loaded.
 * @publicApi
 */
const ANIMATION_MODULE_TYPE = new InjectionToken(ngDevMode ? 'AnimationModuleType' : '');
// TODO(crisbeto): link to CSP guide here.
/**
 * Token used to configure the [Content Security Policy](https://web.dev/strict-csp/) nonce that
 * Angular will apply when inserting inline styles. If not provided, Angular will look up its value
 * from the `ngCspNonce` attribute of the application root node.
 *
 * @publicApi
 */
const CSP_NONCE = new InjectionToken(ngDevMode ? 'CSP nonce' : '', {
  providedIn: 'root',
  factory: () => {
    // Ideally we wouldn't have to use `querySelector` here since we know that the nonce will be on
    // the root node, but because the token value is used in renderers, it has to be available
    // *very* early in the bootstrapping process. This should be a fairly shallow search, because
    // the app won't have been added to the DOM yet. Some approaches that were considered:
    // 1. Find the root node through `ApplicationRef.components[i].location` - normally this would
    // be enough for our purposes, but the token is injected very early so the `components` array
    // isn't populated yet.
    // 2. Find the root `LView` through the current `LView` - renderers are a prerequisite to
    // creating the `LView`. This means that no `LView` will have been entered when this factory is
    // invoked for the root component.
    // 3. Have the token factory return `() => string` which is invoked when a nonce is requested -
    // the slightly later execution does allow us to get an `LView` reference, but the fact that
    // it is a function means that it could be executed at *any* time (including immediately) which
    // may lead to weird bugs.
    // 4. Have the `ComponentFactory` read the attribute and provide it to the injector under the
    // hood - has the same problem as #1 and #2 in that the renderer is used to query for the root
    // node and the nonce value needs to be available when the renderer is created.
    return getDocument().body?.querySelector('[ngCspNonce]')?.getAttribute('ngCspNonce') || null;
  }
});
const IMAGE_CONFIG_DEFAULTS = {
  breakpoints: [16, 32, 48, 64, 96, 128, 256, 384, 640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  placeholderResolution: 30,
  disableImageSizeWarning: false,
  disableImageLazyLoadWarning: false
};
/**
 * Injection token that configures the image optimized image functionality.
 * See {@link ImageConfig} for additional information about parameters that
 * can be used.
 *
 * @see {@link NgOptimizedImage}
 * @see {@link ImageConfig}
 * @publicApi
 */
const IMAGE_CONFIG = new InjectionToken(ngDevMode ? 'ImageConfig' : '', {
  providedIn: 'root',
  factory: () => IMAGE_CONFIG_DEFAULTS
});

/**
 * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
 *
 * Example:
 *
 * ```
 * const COUNTER_KEY = makeStateKey<number>('counter');
 * let value = 10;
 *
 * transferState.set(COUNTER_KEY, value);
 * ```
 *
 * @publicApi
 */
function makeStateKey(key) {
  return key;
}
function initTransferState() {
  const transferState = new TransferState();
  if (inject(PLATFORM_ID) === 'browser') {
    transferState.store = retrieveTransferredState(getDocument(), inject(APP_ID));
  }
  return transferState;
}
/**
 * A key value store that is transferred from the application on the server side to the application
 * on the client side.
 *
 * The `TransferState` is available as an injectable token.
 * On the client, just inject this token using DI and use it, it will be lazily initialized.
 * On the server it's already included if `renderApplication` function is used. Otherwise, import
 * the `ServerTransferStateModule` module to make the `TransferState` available.
 *
 * The values in the store are serialized/deserialized using JSON.stringify/JSON.parse. So only
 * boolean, number, string, null and non-class objects will be serialized and deserialized in a
 * non-lossy manner.
 *
 * @publicApi
 */
class TransferState {
  constructor() {
    /** @internal */
    this.store = {};
    this.onSerializeCallbacks = {};
  }
  /** @nocollapse */
  static {
    this.ɵprov = /** @pureOrBreakMyCode */ɵɵdefineInjectable({
      token: TransferState,
      providedIn: 'root',
      factory: initTransferState
    });
  }
  /**
   * Get the value corresponding to a key. Return `defaultValue` if key is not found.
   */
  get(key, defaultValue) {
    return this.store[key] !== undefined ? this.store[key] : defaultValue;
  }
  /**
   * Set the value corresponding to a key.
   */
  set(key, value) {
    this.store[key] = value;
  }
  /**
   * Remove a key from the store.
   */
  remove(key) {
    delete this.store[key];
  }
  /**
   * Test whether a key exists in the store.
   */
  hasKey(key) {
    return this.store.hasOwnProperty(key);
  }
  /**
   * Indicates whether the state is empty.
   */
  get isEmpty() {
    return Object.keys(this.store).length === 0;
  }
  /**
   * Register a callback to provide the value for a key when `toJson` is called.
   */
  onSerialize(key, callback) {
    this.onSerializeCallbacks[key] = callback;
  }
  /**
   * Serialize the current state of the store to JSON.
   */
  toJson() {
    // Call the onSerialize callbacks and put those values into the store.
    for (const key in this.onSerializeCallbacks) {
      if (this.onSerializeCallbacks.hasOwnProperty(key)) {
        try {
          this.store[key] = this.onSerializeCallbacks[key]();
        } catch (e) {
          console.warn('Exception in onSerialize callback: ', e);
        }
      }
    }
    // Escape script tag to avoid break out of <script> tag in serialized output.
    // Encoding of `<` is the same behaviour as G3 script_builders.
    return JSON.stringify(this.store).replace(/</g, '\\u003C');
  }
}
function retrieveTransferredState(doc, appId) {
  // Locate the script tag with the JSON data transferred from the server.
  // The id of the script tag is set to the Angular appId + 'state'.
  const script = doc.getElementById(appId + '-state');
  if (script?.textContent) {
    try {
      // Avoid using any here as it triggers lint errors in google3 (any is not allowed).
      // Decoding of `<` is done of the box by browsers and node.js, same behaviour as G3
      // script_builders.
      return JSON.parse(script.textContent);
    } catch (e) {
      console.warn('Exception while restoring TransferState for app ' + appId, e);
    }
  }
  return {};
}

/** Encodes that the node lookup should start from the host node of this component. */
const REFERENCE_NODE_HOST = 'h';
/** Encodes that the node lookup should start from the document body node. */
const REFERENCE_NODE_BODY = 'b';
/**
 * Describes navigation steps that the runtime logic need to perform,
 * starting from a given (known) element.
 */
var NodeNavigationStep;
(function (NodeNavigationStep) {
  NodeNavigationStep["FirstChild"] = "f";
  NodeNavigationStep["NextSibling"] = "n";
})(NodeNavigationStep || (NodeNavigationStep = {}));
/**
 * Keys within serialized view data structure to represent various
 * parts. See the `SerializedView` interface below for additional information.
 */
const ELEMENT_CONTAINERS = 'e';
const TEMPLATES = 't';
const CONTAINERS = 'c';
const MULTIPLIER = 'x';
const NUM_ROOT_NODES = 'r';
const TEMPLATE_ID = 'i'; // as it's also an "id"
const NODES = 'n';
const DISCONNECTED_NODES = 'd';

/**
 * The name of the key used in the TransferState collection,
 * where hydration information is located.
 */
const TRANSFER_STATE_TOKEN_ID = '__nghData__';
/**
 * Lookup key used to reference DOM hydration data (ngh) in `TransferState`.
 */
const NGH_DATA_KEY = makeStateKey(TRANSFER_STATE_TOKEN_ID);
/**
 * The name of the attribute that would be added to host component
 * nodes and contain a reference to a particular slot in transferred
 * state that contains the necessary hydration info for this component.
 */
const NGH_ATTR_NAME = 'ngh';
/**
 * Marker used in a comment node to ensure hydration content integrity
 */
const SSR_CONTENT_INTEGRITY_MARKER = 'nghm';
/**
 * Reference to a function that reads `ngh` attribute value from a given RNode
 * and retrieves hydration information from the TransferState using that value
 * as an index. Returns `null` by default, when hydration is not enabled.
 *
 * @param rNode Component's host element.
 * @param injector Injector that this component has access to.
 * @param isRootView Specifies whether we trying to read hydration info for the root view.
 */
let _retrieveHydrationInfoImpl = () => null;
function retrieveHydrationInfoImpl(rNode, injector, isRootView = false) {
  let nghAttrValue = rNode.getAttribute(NGH_ATTR_NAME);
  if (nghAttrValue == null) return null;
  // For cases when a root component also acts as an anchor node for a ViewContainerRef
  // (for example, when ViewContainerRef is injected in a root component), there is a need
  // to serialize information about the component itself, as well as an LContainer that
  // represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
  // (1) hydration info for the root component itself and (2) hydration info for the
  // ViewContainerRef instance (an LContainer). Each piece of information is included into
  // the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
  // Since we only have 1 root element, we encode both bits of info into a single string:
  // ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
  // and 25 is the `ngh` for a root view which holds LContainer).
  const [componentViewNgh, rootViewNgh] = nghAttrValue.split('|');
  nghAttrValue = isRootView ? rootViewNgh : componentViewNgh;
  if (!nghAttrValue) return null;
  // We've read one of the ngh ids, keep the remaining one, so that
  // we can set it back on the DOM element.
  const rootNgh = rootViewNgh ? `|${rootViewNgh}` : '';
  const remainingNgh = isRootView ? componentViewNgh : rootNgh;
  let data = {};
  // An element might have an empty `ngh` attribute value (e.g. `<comp ngh="" />`),
  // which means that no special annotations are required. Do not attempt to read
  // from the TransferState in this case.
  if (nghAttrValue !== '') {
    const transferState = injector.get(TransferState, null, {
      optional: true
    });
    if (transferState !== null) {
      const nghData = transferState.get(NGH_DATA_KEY, []);
      // The nghAttrValue is always a number referencing an index
      // in the hydration TransferState data.
      data = nghData[Number(nghAttrValue)];
      // If the `ngh` attribute exists and has a non-empty value,
      // the hydration info *must* be present in the TransferState.
      // If there is no data for some reasons, this is an error.
      ngDevMode && assertDefined(data, 'Unable to retrieve hydration info from the TransferState.');
    }
  }
  const dehydratedView = {
    data,
    firstChild: rNode.firstChild ?? null
  };
  if (isRootView) {
    // If there is hydration info present for the root view, it means that there was
    // a ViewContainerRef injected in the root component. The root component host element
    // acted as an anchor node in this scenario. As a result, the DOM nodes that represent
    // embedded views in this ViewContainerRef are located as siblings to the host node,
    // i.e. `<app-root /><#VIEW1><#VIEW2>...<!--container-->`. In this case, the current
    // node becomes the first child of this root view and the next sibling is the first
    // element in the DOM segment.
    dehydratedView.firstChild = rNode;
    // We use `0` here, since this is the slot (right after the HEADER_OFFSET)
    // where a component LView or an LContainer is located in a root LView.
    setSegmentHead(dehydratedView, 0, rNode.nextSibling);
  }
  if (remainingNgh) {
    // If we have only used one of the ngh ids, store the remaining one
    // back on this RNode.
    rNode.setAttribute(NGH_ATTR_NAME, remainingNgh);
  } else {
    // The `ngh` attribute is cleared from the DOM node now
    // that the data has been retrieved for all indices.
    rNode.removeAttribute(NGH_ATTR_NAME);
  }
  // Note: don't check whether this node was claimed for hydration,
  // because this node might've been previously claimed while processing
  // template instructions.
  ngDevMode && markRNodeAsClaimedByHydration(rNode, /* checkIfAlreadyClaimed */false);
  ngDevMode && ngDevMode.hydratedComponents++;
  return dehydratedView;
}
/**
 * Sets the implementation for the `retrieveHydrationInfo` function.
 */
function enableRetrieveHydrationInfoImpl() {
  _retrieveHydrationInfoImpl = retrieveHydrationInfoImpl;
}
/**
 * Retrieves hydration info by reading the value from the `ngh` attribute
 * and accessing a corresponding slot in TransferState storage.
 */
function retrieveHydrationInfo(rNode, injector, isRootView = false) {
  return _retrieveHydrationInfoImpl(rNode, injector, isRootView);
}
/**
 * Retrieves the necessary object from a given ViewRef to serialize:
 *  - an LView for component views
 *  - an LContainer for cases when component acts as a ViewContainerRef anchor
 *  - `null` in case of an embedded view
 */
function getLNodeForHydration(viewRef) {
  // Reading an internal field from `ViewRef` instance.
  let lView = viewRef._lView;
  const tView = lView[TVIEW];
  // A registered ViewRef might represent an instance of an
  // embedded view, in which case we do not need to annotate it.
  if (tView.type === 2 /* TViewType.Embedded */) {
    return null;
  }
  // Check if it's a root view and if so, retrieve component's
  // LView from the first slot after the header.
  if (isRootView(lView)) {
    lView = lView[HEADER_OFFSET];
  }
  return lView;
}
function getTextNodeContent(node) {
  return node.textContent?.replace(/\s/gm, '');
}
/**
 * Restores text nodes and separators into the DOM that were lost during SSR
 * serialization. The hydration process replaces empty text nodes and text
 * nodes that are immediately adjacent to other text nodes with comment nodes
 * that this method filters on to restore those missing nodes that the
 * hydration process is expecting to be present.
 *
 * @param node The app's root HTML Element
 */
function processTextNodeMarkersBeforeHydration(node) {
  const doc = getDocument();
  const commentNodesIterator = doc.createNodeIterator(node, NodeFilter.SHOW_COMMENT, {
    acceptNode(node) {
      const content = getTextNodeContent(node);
      const isTextNodeMarker = content === "ngetn" /* TextNodeMarker.EmptyNode */ || content === "ngtns" /* TextNodeMarker.Separator */;
      return isTextNodeMarker ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_REJECT;
    }
  });
  let currentNode;
  // We cannot modify the DOM while using the commentIterator,
  // because it throws off the iterator state.
  // So we collect all marker nodes first and then follow up with
  // applying the changes to the DOM: either inserting an empty node
  // or just removing the marker if it was used as a separator.
  const nodes = [];
  while (currentNode = commentNodesIterator.nextNode()) {
    nodes.push(currentNode);
  }
  for (const node of nodes) {
    if (node.textContent === "ngetn" /* TextNodeMarker.EmptyNode */) {
      node.replaceWith(doc.createTextNode(''));
    } else {
      node.remove();
    }
  }
}
/**
 * Internal type that represents a claimed node.
 * Only used in dev mode.
 */
var HydrationStatus;
(function (HydrationStatus) {
  HydrationStatus["Hydrated"] = "hydrated";
  HydrationStatus["Skipped"] = "skipped";
  HydrationStatus["Mismatched"] = "mismatched";
})(HydrationStatus || (HydrationStatus = {}));
// clang-format on
const HYDRATION_INFO_KEY = '__ngDebugHydrationInfo__';
function patchHydrationInfo(node, info) {
  node[HYDRATION_INFO_KEY] = info;
}
function readHydrationInfo(node) {
  return node[HYDRATION_INFO_KEY] ?? null;
}
/**
 * Marks a node as "claimed" by hydration process.
 * This is needed to make assessments in tests whether
 * the hydration process handled all nodes.
 */
function markRNodeAsClaimedByHydration(node, checkIfAlreadyClaimed = true) {
  if (!ngDevMode) {
    throw new Error('Calling `markRNodeAsClaimedByHydration` in prod mode ' + 'is not supported and likely a mistake.');
  }
  if (checkIfAlreadyClaimed && isRNodeClaimedForHydration(node)) {
    throw new Error('Trying to claim a node, which was claimed already.');
  }
  patchHydrationInfo(node, {
    status: HydrationStatus.Hydrated
  });
  ngDevMode.hydratedNodes++;
}
function markRNodeAsSkippedByHydration(node) {
  if (!ngDevMode) {
    throw new Error('Calling `markRNodeAsSkippedByHydration` in prod mode ' + 'is not supported and likely a mistake.');
  }
  patchHydrationInfo(node, {
    status: HydrationStatus.Skipped
  });
  ngDevMode.componentsSkippedHydration++;
}
function markRNodeAsHavingHydrationMismatch(node, expectedNodeDetails = null, actualNodeDetails = null) {
  if (!ngDevMode) {
    throw new Error('Calling `markRNodeAsMismatchedByHydration` in prod mode ' + 'is not supported and likely a mistake.');
  }
  // The RNode can be a standard HTMLElement (not an Angular component or directive)
  // The devtools component tree only displays Angular components & directives
  // Therefore we attach the debug info to the closest component/directive
  while (node && !getComponent$1(node)) {
    node = node?.parentNode;
  }
  if (node) {
    patchHydrationInfo(node, {
      status: HydrationStatus.Mismatched,
      expectedNodeDetails,
      actualNodeDetails
    });
  }
}
function isRNodeClaimedForHydration(node) {
  return readHydrationInfo(node)?.status === HydrationStatus.Hydrated;
}
function setSegmentHead(hydrationInfo, index, node) {
  hydrationInfo.segmentHeads ??= {};
  hydrationInfo.segmentHeads[index] = node;
}
function getSegmentHead(hydrationInfo, index) {
  return hydrationInfo.segmentHeads?.[index] ?? null;
}
/**
 * Returns the size of an <ng-container>, using either the information
 * serialized in `ELEMENT_CONTAINERS` (element container size) or by
 * computing the sum of root nodes in all dehydrated views in a given
 * container (in case this `<ng-container>` was also used as a view
 * container host node, e.g. <ng-container *ngIf>).
 */
function getNgContainerSize(hydrationInfo, index) {
  const data = hydrationInfo.data;
  let size = data[ELEMENT_CONTAINERS]?.[index] ?? null;
  // If there is no serialized information available in the `ELEMENT_CONTAINERS` slot,
  // check if we have info about view containers at this location (e.g.
  // `<ng-container *ngIf>`) and use container size as a number of root nodes in this
  // element container.
  if (size === null && data[CONTAINERS]?.[index]) {
    size = calcSerializedContainerSize(hydrationInfo, index);
  }
  return size;
}
function getSerializedContainerViews(hydrationInfo, index) {
  return hydrationInfo.data[CONTAINERS]?.[index] ?? null;
}
/**
 * Computes the size of a serialized container (the number of root nodes)
 * by calculating the sum of root nodes in all dehydrated views in this container.
 */
function calcSerializedContainerSize(hydrationInfo, index) {
  const views = getSerializedContainerViews(hydrationInfo, index) ?? [];
  let numNodes = 0;
  for (let view of views) {
    numNodes += view[NUM_ROOT_NODES] * (view[MULTIPLIER] ?? 1);
  }
  return numNodes;
}
/**
 * Checks whether a node is annotated as "disconnected", i.e. not present
 * in the DOM at serialization time. We should not attempt hydration for
 * such nodes and instead, use a regular "creation mode".
 */
function isDisconnectedNode$1(hydrationInfo, index) {
  // Check if we are processing disconnected info for the first time.
  if (typeof hydrationInfo.disconnectedNodes === 'undefined') {
    const nodeIds = hydrationInfo.data[DISCONNECTED_NODES];
    hydrationInfo.disconnectedNodes = nodeIds ? new Set(nodeIds) : null;
  }
  return !!hydrationInfo.disconnectedNodes?.has(index);
}

/**
 * Internal token that specifies whether DOM reuse logic
 * during hydration is enabled.
 */
const IS_HYDRATION_DOM_REUSE_ENABLED = new InjectionToken(typeof ngDevMode === 'undefined' || !!ngDevMode ? 'IS_HYDRATION_DOM_REUSE_ENABLED' : '');
// By default (in client rendering mode), we remove all the contents
// of the host element and render an application after that.
const PRESERVE_HOST_CONTENT_DEFAULT = false;
/**
 * Internal token that indicates whether host element content should be
 * retained during the bootstrap.
 */
const PRESERVE_HOST_CONTENT = new InjectionToken(typeof ngDevMode === 'undefined' || !!ngDevMode ? 'PRESERVE_HOST_CONTENT' : '', {
  providedIn: 'root',
  factory: () => PRESERVE_HOST_CONTENT_DEFAULT
});
/**
 * Internal token that indicates whether hydration support for i18n
 * is enabled.
 */
const IS_I18N_HYDRATION_ENABLED = new InjectionToken(typeof ngDevMode === 'undefined' || !!ngDevMode ? 'IS_I18N_HYDRATION_ENABLED' : '');

/**
 * @fileoverview
 * A module to facilitate use of a Trusted Types policy internally within
 * Angular. It lazily constructs the Trusted Types policy, providing helper
 * utilities for promoting strings to Trusted Types. When Trusted Types are not
 * available, strings are used as a fallback.
 * @security All use of this module is security-sensitive and should go through
 * security review.
 */
/**
 * The Trusted Types policy, or null if Trusted Types are not
 * enabled/supported, or undefined if the policy has not been created yet.
 */
let policy$1;
/**
 * Returns the Trusted Types policy, or null if Trusted Types are not
 * enabled/supported. The first call to this function will create the policy.
 */
function getPolicy$1() {
  if (policy$1 === undefined) {
    policy$1 = null;
    if (_global.trustedTypes) {
      try {
        policy$1 = _global.trustedTypes.createPolicy('angular', {
          createHTML: s => s,
          createScript: s => s,
          createScriptURL: s => s
        });
      } catch {
        // trustedTypes.createPolicy throws if called with a name that is
        // already registered, even in report-only mode. Until the API changes,
        // catch the error not to break the applications functionally. In such
        // cases, the code will fall back to using strings.
      }
    }
  }
  return policy$1;
}
/**
 * Unsafely promote a string to a TrustedHTML, falling back to strings when
 * Trusted Types are not available.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that the
 * provided string will never cause an XSS vulnerability if used in a context
 * that will be interpreted as HTML by a browser, e.g. when assigning to
 * element.innerHTML.
 */
function trustedHTMLFromString(html) {
  return getPolicy$1()?.createHTML(html) || html;
}
/**
 * Unsafely promote a string to a TrustedScript, falling back to strings when
 * Trusted Types are not available.
 * @security In particular, it must be assured that the provided string will
 * never cause an XSS vulnerability if used in a context that will be
 * interpreted and executed as a script by a browser, e.g. when calling eval.
 */
function trustedScriptFromString(script) {
  return getPolicy$1()?.createScript(script) || script;
}
/**
 * Unsafely promote a string to a TrustedScriptURL, falling back to strings
 * when Trusted Types are not available.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that the
 * provided string will never cause an XSS vulnerability if used in a context
 * that will cause a browser to load and execute a resource, e.g. when
 * assigning to script.src.
 */
function trustedScriptURLFromString(url) {
  return getPolicy$1()?.createScriptURL(url) || url;
}
/**
 * Unsafely call the Function constructor with the given string arguments. It
 * is only available in development mode, and should be stripped out of
 * production code.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that it
 * is only called from development code, as use in production code can lead to
 * XSS vulnerabilities.
 */
function newTrustedFunctionForDev(...args) {
  if (typeof ngDevMode === 'undefined') {
    throw new Error('newTrustedFunctionForDev should never be called in production');
  }
  if (!_global.trustedTypes) {
    // In environments that don't support Trusted Types, fall back to the most
    // straightforward implementation:
    return new Function(...args);
  }
  // Chrome currently does not support passing TrustedScript to the Function
  // constructor. The following implements the workaround proposed on the page
  // below, where the Chromium bug is also referenced:
  // https://github.com/w3c/webappsec-trusted-types/wiki/Trusted-Types-for-function-constructor
  const fnArgs = args.slice(0, -1).join(',');
  const fnBody = args[args.length - 1];
  const body = `(function anonymous(${fnArgs}
) { ${fnBody}
})`;
  // Using eval directly confuses the compiler and prevents this module from
  // being stripped out of JS binaries even if not used. The global['eval']
  // indirection fixes that.
  const fn = _global['eval'](trustedScriptFromString(body));
  if (fn.bind === undefined) {
    // Workaround for a browser bug that only exists in Chrome 83, where passing
    // a TrustedScript to eval just returns the TrustedScript back without
    // evaluating it. In that case, fall back to the most straightforward
    // implementation:
    return new Function(...args);
  }
  // To completely mimic the behavior of calling "new Function", two more
  // things need to happen:
  // 1. Stringifying the resulting function should return its source code
  fn.toString = () => body;
  // 2. When calling the resulting function, `this` should refer to `global`
  return fn.bind(_global);
  // When Trusted Types support in Function constructors is widely available,
  // the implementation of this function can be simplified to:
  // return new Function(...args.map(a => trustedScriptFromString(a)));
}

/**
 * @fileoverview
 * A module to facilitate use of a Trusted Types policy internally within
 * Angular specifically for bypassSecurityTrust* and custom sanitizers. It
 * lazily constructs the Trusted Types policy, providing helper utilities for
 * promoting strings to Trusted Types. When Trusted Types are not available,
 * strings are used as a fallback.
 * @security All use of this module is security-sensitive and should go through
 * security review.
 */
/**
 * The Trusted Types policy, or null if Trusted Types are not
 * enabled/supported, or undefined if the policy has not been created yet.
 */
let policy;
/**
 * Returns the Trusted Types policy, or null if Trusted Types are not
 * enabled/supported. The first call to this function will create the policy.
 */
function getPolicy() {
  if (policy === undefined) {
    policy = null;
    if (_global.trustedTypes) {
      try {
        policy = _global.trustedTypes.createPolicy('angular#unsafe-bypass', {
          createHTML: s => s,
          createScript: s => s,
          createScriptURL: s => s
        });
      } catch {
        // trustedTypes.createPolicy throws if called with a name that is
        // already registered, even in report-only mode. Until the API changes,
        // catch the error not to break the applications functionally. In such
        // cases, the code will fall back to using strings.
      }
    }
  }
  return policy;
}
/**
 * Unsafely promote a string to a TrustedHTML, falling back to strings when
 * Trusted Types are not available.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that it
 * is only passed strings that come directly from custom sanitizers or the
 * bypassSecurityTrust* functions.
 */
function trustedHTMLFromStringBypass(html) {
  return getPolicy()?.createHTML(html) || html;
}
/**
 * Unsafely promote a string to a TrustedScript, falling back to strings when
 * Trusted Types are not available.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that it
 * is only passed strings that come directly from custom sanitizers or the
 * bypassSecurityTrust* functions.
 */
function trustedScriptFromStringBypass(script) {
  return getPolicy()?.createScript(script) || script;
}
/**
 * Unsafely promote a string to a TrustedScriptURL, falling back to strings
 * when Trusted Types are not available.
 * @security This is a security-sensitive function; any use of this function
 * must go through security review. In particular, it must be assured that it
 * is only passed strings that come directly from custom sanitizers or the
 * bypassSecurityTrust* functions.
 */
function trustedScriptURLFromStringBypass(url) {
  return getPolicy()?.createScriptURL(url) || url;
}
class SafeValueImpl {
  constructor(changingThisBreaksApplicationSecurity) {
    this.changingThisBreaksApplicationSecurity = changingThisBreaksApplicationSecurity;
  }
  toString() {
    return `SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity}` + ` (see ${XSS_SECURITY_URL})`;
  }
}
class SafeHtmlImpl extends SafeValueImpl {
  getTypeName() {
    return "HTML" /* BypassType.Html */;
  }
}
class SafeStyleImpl extends SafeValueImpl {
  getTypeName() {
    return "Style" /* BypassType.Style */;
  }
}
class SafeScriptImpl extends SafeValueImpl {
  getTypeName() {
    return "Script" /* BypassType.Script */;
  }
}
class SafeUrlImpl extends SafeValueImpl {
  getTypeName() {
    return "URL" /* BypassType.Url */;
  }
}
class SafeResourceUrlImpl extends SafeValueImpl {
  getTypeName() {
    return "ResourceURL" /* BypassType.ResourceUrl */;
  }
}
function unwrapSafeValue(value) {
  return value instanceof SafeValueImpl ? value.changingThisBreaksApplicationSecurity : value;
}
function allowSanitizationBypassAndThrow(value, type) {
  const actualType = getSanitizationBypassType(value);
  if (actualType != null && actualType !== type) {
    // Allow ResourceURLs in URL contexts, they are strictly more trusted.
    if (actualType === "ResourceURL" /* BypassType.ResourceUrl */ && type === "URL" /* BypassType.Url */) return true;
    throw new Error(`Required a safe ${type}, got a ${actualType} (see ${XSS_SECURITY_URL})`);
  }
  return actualType === type;
}
function getSanitizationBypassType(value) {
  return value instanceof SafeValueImpl && value.getTypeName() || null;
}
/**
 * Mark `html` string as trusted.
 *
 * This function wraps the trusted string in `String` and brands it in a way which makes it
 * recognizable to {@link htmlSanitizer} to be trusted implicitly.
 *
 * @param trustedHtml `html` string which needs to be implicitly trusted.
 * @returns a `html` which has been branded to be implicitly trusted.
 */
function bypassSanitizationTrustHtml(trustedHtml) {
  return new SafeHtmlImpl(trustedHtml);
}
/**
 * Mark `style` string as trusted.
 *
 * This function wraps the trusted string in `String` and brands it in a way which makes it
 * recognizable to {@link styleSanitizer} to be trusted implicitly.
 *
 * @param trustedStyle `style` string which needs to be implicitly trusted.
 * @returns a `style` hich has been branded to be implicitly trusted.
 */
function bypassSanitizationTrustStyle(trustedStyle) {
  return new SafeStyleImpl(trustedStyle);
}
/**
 * Mark `script` string as trusted.
 *
 * This function wraps the trusted string in `String` and brands it in a way which makes it
 * recognizable to {@link scriptSanitizer} to be trusted implicitly.
 *
 * @param trustedScript `script` string which needs to be implicitly trusted.
 * @returns a `script` which has been branded to be implicitly trusted.
 */
function bypassSanitizationTrustScript(trustedScript) {
  return new SafeScriptImpl(trustedScript);
}
/**
 * Mark `url` string as trusted.
 *
 * This function wraps the trusted string in `String` and brands it in a way which makes it
 * recognizable to {@link urlSanitizer} to be trusted implicitly.
 *
 * @param trustedUrl `url` string which needs to be implicitly trusted.
 * @returns a `url`  which has been branded to be implicitly trusted.
 */
function bypassSanitizationTrustUrl(trustedUrl) {
  return new SafeUrlImpl(trustedUrl);
}
/**
 * Mark `url` string as trusted.
 *
 * This function wraps the trusted string in `String` and brands it in a way which makes it
 * recognizable to {@link resourceUrlSanitizer} to be trusted implicitly.
 *
 * @param trustedResourceUrl `url` string which needs to be implicitly trusted.
 * @returns a `url` which has been branded to be implicitly trusted.
 */
function bypassSanitizationTrustResourceUrl(trustedResourceUrl) {
  return new SafeResourceUrlImpl(trustedResourceUrl);
}

/**
 * This helper is used to get hold of an inert tree of DOM elements containing dirty HTML
 * that needs sanitizing.
 * Depending upon browser support we use one of two strategies for doing this.
 * Default: DOMParser strategy
 * Fallback: InertDocument strategy
 */
function getInertBodyHelper(defaultDoc) {
  const inertDocumentHelper = new InertDocumentHelper(defaultDoc);
  return isDOMParserAvailable() ? new DOMParserHelper(inertDocumentHelper) : inertDocumentHelper;
}
/**
 * Uses DOMParser to create and fill an inert body element.
 * This is the default strategy used in browsers that support it.
 */
class DOMParserHelper {
  constructor(inertDocumentHelper) {
    this.inertDocumentHelper = inertDocumentHelper;
  }
  getInertBodyElement(html) {
    // We add these extra elements to ensure that the rest of the content is parsed as expected
    // e.g. leading whitespace is maintained and tags like `<meta>` do not get hoisted to the
    // `<head>` tag. Note that the `<body>` tag is closed implicitly to prevent unclosed tags
    // in `html` from consuming the otherwise explicit `</body>` tag.
    html = '<body><remove></remove>' + html;
    try {
      const body = new window.DOMParser().parseFromString(trustedHTMLFromString(html), 'text/html').body;
      if (body === null) {
        // In some browsers (e.g. Mozilla/5.0 iPad AppleWebKit Mobile) the `body` property only
        // becomes available in the following tick of the JS engine. In that case we fall back to
        // the `inertDocumentHelper` instead.
        return this.inertDocumentHelper.getInertBodyElement(html);
      }
      body.removeChild(body.firstChild);
      return body;
    } catch {
      return null;
    }
  }
}
/**
 * Use an HTML5 `template` element to create and fill an inert DOM element.
 * This is the fallback strategy if the browser does not support DOMParser.
 */
class InertDocumentHelper {
  constructor(defaultDoc) {
    this.defaultDoc = defaultDoc;
    this.inertDocument = this.defaultDoc.implementation.createHTMLDocument('sanitization-inert');
  }
  getInertBodyElement(html) {
    const templateEl = this.inertDocument.createElement('template');
    templateEl.innerHTML = trustedHTMLFromString(html);
    return templateEl;
  }
}
/**
 * We need to determine whether the DOMParser exists in the global context and
 * supports parsing HTML; HTML parsing support is not as wide as other formats, see
 * https://developer.mozilla.org/en-US/docs/Web/API/DOMParser#Browser_compatibility.
 *
 * @suppress {uselessCode}
 */
function isDOMParserAvailable() {
  try {
    return !!new window.DOMParser().parseFromString(trustedHTMLFromString(''), 'text/html');
  } catch {
    return false;
  }
}

/**
 * A pattern that recognizes URLs that are safe wrt. XSS in URL navigation
 * contexts.
 *
 * This regular expression matches a subset of URLs that will not cause script
 * execution if used in URL context within a HTML document. Specifically, this
 * regular expression matches if:
 * (1) Either a protocol that is not javascript:, and that has valid characters
 *     (alphanumeric or [+-.]).
 * (2) or no protocol.  A protocol must be followed by a colon. The below
 *     allows that by allowing colons only after one of the characters [/?#].
 *     A colon after a hash (#) must be in the fragment.
 *     Otherwise, a colon after a (?) must be in a query.
 *     Otherwise, a colon after a single solidus (/) must be in a path.
 *     Otherwise, a colon after a double solidus (//) must be in the authority
 *     (before port).
 *
 * The pattern disallows &, used in HTML entity declarations before
 * one of the characters in [/?#]. This disallows HTML entities used in the
 * protocol name, which should never happen, e.g. "h&#116;tp" for "http".
 * It also disallows HTML entities in the first path part of a relative path,
 * e.g. "foo&lt;bar/baz".  Our existing escaping functions should not produce
 * that. More importantly, it disallows masking of a colon,
 * e.g. "javascript&#58;...".
 *
 * This regular expression was taken from the Closure sanitization library.
 */
const SAFE_URL_PATTERN = /^(?!javascript:)(?:[a-z0-9+.-]+:|[^&:\/?#]*(?:[\/?#]|$))/i;
function _sanitizeUrl(url) {
  url = String(url);
  if (url.match(SAFE_URL_PATTERN)) return url;
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    console.warn(`WARNING: sanitizing unsafe URL value ${url} (see ${XSS_SECURITY_URL})`);
  }
  return 'unsafe:' + url;
}
function tagSet(tags) {
  const res = {};
  for (const t of tags.split(',')) res[t] = true;
  return res;
}
function merge(...sets) {
  const res = {};
  for (const s of sets) {
    for (const v in s) {
      if (s.hasOwnProperty(v)) res[v] = true;
    }
  }
  return res;
}
// Good source of info about elements and attributes
// https://html.spec.whatwg.org/#semantics
// https://simon.html5.org/html-elements
// Safe Void Elements - HTML5
// https://html.spec.whatwg.org/#void-elements
const VOID_ELEMENTS = tagSet('area,br,col,hr,img,wbr');
// Elements that you can, intentionally, leave open (and which close themselves)
// https://html.spec.whatwg.org/#optional-tags
const OPTIONAL_END_TAG_BLOCK_ELEMENTS = tagSet('colgroup,dd,dt,li,p,tbody,td,tfoot,th,thead,tr');
const OPTIONAL_END_TAG_INLINE_ELEMENTS = tagSet('rp,rt');
const OPTIONAL_END_TAG_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, OPTIONAL_END_TAG_BLOCK_ELEMENTS);
// Safe Block Elements - HTML5
const BLOCK_ELEMENTS = merge(OPTIONAL_END_TAG_BLOCK_ELEMENTS, tagSet('address,article,' + 'aside,blockquote,caption,center,del,details,dialog,dir,div,dl,figure,figcaption,footer,h1,h2,h3,h4,h5,' + 'h6,header,hgroup,hr,ins,main,map,menu,nav,ol,pre,section,summary,table,ul'));
// Inline Elements - HTML5
const INLINE_ELEMENTS = merge(OPTIONAL_END_TAG_INLINE_ELEMENTS, tagSet('a,abbr,acronym,audio,b,' + 'bdi,bdo,big,br,cite,code,del,dfn,em,font,i,img,ins,kbd,label,map,mark,picture,q,ruby,rp,rt,s,' + 'samp,small,source,span,strike,strong,sub,sup,time,track,tt,u,var,video'));
const VALID_ELEMENTS = merge(VOID_ELEMENTS, BLOCK_ELEMENTS, INLINE_ELEMENTS, OPTIONAL_END_TAG_ELEMENTS);
// Attributes that have href and hence need to be sanitized
const URI_ATTRS = tagSet('background,cite,href,itemtype,longdesc,poster,src,xlink:href');
const HTML_ATTRS = tagSet('abbr,accesskey,align,alt,autoplay,axis,bgcolor,border,cellpadding,cellspacing,class,clear,color,cols,colspan,' + 'compact,controls,coords,datetime,default,dir,download,face,headers,height,hidden,hreflang,hspace,' + 'ismap,itemscope,itemprop,kind,label,lang,language,loop,media,muted,nohref,nowrap,open,preload,rel,rev,role,rows,rowspan,rules,' + 'scope,scrolling,shape,size,sizes,span,srclang,srcset,start,summary,tabindex,target,title,translate,type,usemap,' + 'valign,value,vspace,width');
// Accessibility attributes as per WAI-ARIA 1.1 (W3C Working Draft 14 December 2018)
const ARIA_ATTRS = tagSet('aria-activedescendant,aria-atomic,aria-autocomplete,aria-busy,aria-checked,aria-colcount,aria-colindex,' + 'aria-colspan,aria-controls,aria-current,aria-describedby,aria-details,aria-disabled,aria-dropeffect,' + 'aria-errormessage,aria-expanded,aria-flowto,aria-grabbed,aria-haspopup,aria-hidden,aria-invalid,' + 'aria-keyshortcuts,aria-label,aria-labelledby,aria-level,aria-live,aria-modal,aria-multiline,' + 'aria-multiselectable,aria-orientation,aria-owns,aria-placeholder,aria-posinset,aria-pressed,aria-readonly,' + 'aria-relevant,aria-required,aria-roledescription,aria-rowcount,aria-rowindex,aria-rowspan,aria-selected,' + 'aria-setsize,aria-sort,aria-valuemax,aria-valuemin,aria-valuenow,aria-valuetext');
// NB: This currently consciously doesn't support SVG. SVG sanitization has had several security
// issues in the past, so it seems safer to leave it out if possible. If support for binding SVG via
// innerHTML is required, SVG attributes should be added here.
// NB: Sanitization does not allow <form> elements or other active elements (<button> etc). Those
// can be sanitized, but they increase security surface area without a legitimate use case, so they
// are left out here.
const VALID_ATTRS = merge(URI_ATTRS, HTML_ATTRS, ARIA_ATTRS);
// Elements whose content should not be traversed/preserved, if the elements themselves are invalid.
//
// Typically, `<invalid>Some content</invalid>` would traverse (and in this case preserve)
// `Some content`, but strip `invalid-element` opening/closing tags. For some elements, though, we
// don't want to preserve the content, if the elements themselves are going to be removed.
const SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS = tagSet('script,style,template');
/**
 * SanitizingHtmlSerializer serializes a DOM fragment, stripping out any unsafe elements and unsafe
 * attributes.
 */
class SanitizingHtmlSerializer {
  constructor() {
    // Explicitly track if something was stripped, to avoid accidentally warning of sanitization just
    // because characters were re-encoded.
    this.sanitizedSomething = false;
    this.buf = [];
  }
  sanitizeChildren(el) {
    // This cannot use a TreeWalker, as it has to run on Angular's various DOM adapters.
    // However this code never accesses properties off of `document` before deleting its contents
    // again, so it shouldn't be vulnerable to DOM clobbering.
    let current = el.firstChild;
    let traverseContent = true;
    let parentNodes = [];
    while (current) {
      if (current.nodeType === Node.ELEMENT_NODE) {
        traverseContent = this.startElement(current);
      } else if (current.nodeType === Node.TEXT_NODE) {
        this.chars(current.nodeValue);
      } else {
        // Strip non-element, non-text nodes.
        this.sanitizedSomething = true;
      }
      if (traverseContent && current.firstChild) {
        // Push current node to the parent stack before entering its content.
        parentNodes.push(current);
        current = getFirstChild(current);
        continue;
      }
      while (current) {
        // Leaving the element.
        // Walk up and to the right, closing tags as we go.
        if (current.nodeType === Node.ELEMENT_NODE) {
          this.endElement(current);
        }
        let next = getNextSibling(current);
        if (next) {
          current = next;
          break;
        }
        // There was no next sibling, walk up to the parent node (extract it from the stack).
        current = parentNodes.pop();
      }
    }
    return this.buf.join('');
  }
  /**
   * Sanitizes an opening element tag (if valid) and returns whether the element's contents should
   * be traversed. Element content must always be traversed (even if the element itself is not
   * valid/safe), unless the element is one of `SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS`.
   *
   * @param element The element to sanitize.
   * @return True if the element's contents should be traversed.
   */
  startElement(element) {
    const tagName = getNodeName(element).toLowerCase();
    if (!VALID_ELEMENTS.hasOwnProperty(tagName)) {
      this.sanitizedSomething = true;
      return !SKIP_TRAVERSING_CONTENT_IF_INVALID_ELEMENTS.hasOwnProperty(tagName);
    }
    this.buf.push('<');
    this.buf.push(tagName);
    const elAttrs = element.attributes;
    for (let i = 0; i < elAttrs.length; i++) {
      const elAttr = elAttrs.item(i);
      const attrName = elAttr.name;
      const lower = attrName.toLowerCase();
      if (!VALID_ATTRS.hasOwnProperty(lower)) {
        this.sanitizedSomething = true;
        continue;
      }
      let value = elAttr.value;
      // TODO(martinprobst): Special case image URIs for data:image/...
      if (URI_ATTRS[lower]) value = _sanitizeUrl(value);
      this.buf.push(' ', attrName, '="', encodeEntities(value), '"');
    }
    this.buf.push('>');
    return true;
  }
  endElement(current) {
    const tagName = getNodeName(current).toLowerCase();
    if (VALID_ELEMENTS.hasOwnProperty(tagName) && !VOID_ELEMENTS.hasOwnProperty(tagName)) {
      this.buf.push('</');
      this.buf.push(tagName);
      this.buf.push('>');
    }
  }
  chars(chars) {
    this.buf.push(encodeEntities(chars));
  }
}
/**
 * Verifies whether a given child node is a descendant of a given parent node.
 * It may not be the case when properties like `.firstChild` are clobbered and
 * accessing `.firstChild` results in an unexpected node returned.
 */
function isClobberedElement(parentNode, childNode) {
  return (parentNode.compareDocumentPosition(childNode) & Node.DOCUMENT_POSITION_CONTAINED_BY) !== Node.DOCUMENT_POSITION_CONTAINED_BY;
}
/**
 * Retrieves next sibling node and makes sure that there is no
 * clobbering of the `nextSibling` property happening.
 */
function getNextSibling(node) {
  const nextSibling = node.nextSibling;
  // Make sure there is no `nextSibling` clobbering: navigating to
  // the next sibling and going back to the previous one should result
  // in the original node.
  if (nextSibling && node !== nextSibling.previousSibling) {
    throw clobberedElementError(nextSibling);
  }
  return nextSibling;
}
/**
 * Retrieves first child node and makes sure that there is no
 * clobbering of the `firstChild` property happening.
 */
function getFirstChild(node) {
  const firstChild = node.firstChild;
  if (firstChild && isClobberedElement(node, firstChild)) {
    throw clobberedElementError(firstChild);
  }
  return firstChild;
}
/** Gets a reasonable nodeName, even for clobbered nodes. */
function getNodeName(node) {
  const nodeName = node.nodeName;
  // If the property is clobbered, assume it is an `HTMLFormElement`.
  return typeof nodeName === 'string' ? nodeName : 'FORM';
}
function clobberedElementError(node) {
  return new Error(`Failed to sanitize html because the element is clobbered: ${node.outerHTML}`);
}
// Regular Expressions for parsing tags and attributes
const SURROGATE_PAIR_REGEXP = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
// ! to ~ is the ASCII range.
const NON_ALPHANUMERIC_REGEXP = /([^\#-~ |!])/g;
/**
 * Escapes all potentially dangerous characters, so that the
 * resulting string can be safely inserted into attribute or
 * element text.
 * @param value
 */
function encodeEntities(value) {
  return value.replace(/&/g, '&amp;').replace(SURROGATE_PAIR_REGEXP, function (match) {
    const hi = match.charCodeAt(0);
    const low = match.charCodeAt(1);
    return '&#' + ((hi - 0xD800) * 0x400 + (low - 0xDC00) + 0x10000) + ';';
  }).replace(NON_ALPHANUMERIC_REGEXP, function (match) {
    return '&#' + match.charCodeAt(0) + ';';
  }).replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
let inertBodyHelper;
/**
 * Sanitizes the given unsafe, untrusted HTML fragment, and returns HTML text that is safe to add to
 * the DOM in a browser environment.
 */
function _sanitizeHtml(defaultDoc, unsafeHtmlInput) {
  let inertBodyElement = null;
  try {
    inertBodyHelper = inertBodyHelper || getInertBodyHelper(defaultDoc);
    // Make sure unsafeHtml is actually a string (TypeScript types are not enforced at runtime).
    let unsafeHtml = unsafeHtmlInput ? String(unsafeHtmlInput) : '';
    inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
    // mXSS protection. Repeatedly parse the document to make sure it stabilizes, so that a browser
    // trying to auto-correct incorrect HTML cannot cause formerly inert HTML to become dangerous.
    let mXSSAttempts = 5;
    let parsedHtml = unsafeHtml;
    do {
      if (mXSSAttempts === 0) {
        throw new Error('Failed to sanitize html because the input is unstable');
      }
      mXSSAttempts--;
      unsafeHtml = parsedHtml;
      parsedHtml = inertBodyElement.innerHTML;
      inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeHtml);
    } while (unsafeHtml !== parsedHtml);
    const sanitizer = new SanitizingHtmlSerializer();
    const safeHtml = sanitizer.sanitizeChildren(getTemplateContent(inertBodyElement) || inertBodyElement);
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && sanitizer.sanitizedSomething) {
      console.warn(`WARNING: sanitizing HTML stripped some content, see ${XSS_SECURITY_URL}`);
    }
    return trustedHTMLFromString(safeHtml);
  } finally {
    // In case anything goes wrong, clear out inertElement to reset the entire DOM structure.
    if (inertBodyElement) {
      const parent = getTemplateContent(inertBodyElement) || inertBodyElement;
      while (parent.firstChild) {
        parent.removeChild(parent.firstChild);
      }
    }
  }
}
function getTemplateContent(el) {
  return 'content' in el /** Microsoft/TypeScript#21517 */ && isTemplateElement(el) ? el.content : null;
}
function isTemplateElement(el) {
  return el.nodeType === Node.ELEMENT_NODE && el.nodeName === 'TEMPLATE';
}

/**
 * A SecurityContext marks a location that has dangerous security implications, e.g. a DOM property
 * like `innerHTML` that could cause Cross Site Scripting (XSS) security bugs when improperly
 * handled.
 *
 * See DomSanitizer for more details on security in Angular applications.
 *
 * @publicApi
 */
var SecurityContext;
(function (SecurityContext) {
  SecurityContext[SecurityContext["NONE"] = 0] = "NONE";
  SecurityContext[SecurityContext["HTML"] = 1] = "HTML";
  SecurityContext[SecurityContext["STYLE"] = 2] = "STYLE";
  SecurityContext[SecurityContext["SCRIPT"] = 3] = "SCRIPT";
  SecurityContext[SecurityContext["URL"] = 4] = "URL";
  SecurityContext[SecurityContext["RESOURCE_URL"] = 5] = "RESOURCE_URL";
})(SecurityContext || (SecurityContext = {}));

/**
 * An `html` sanitizer which converts untrusted `html` **string** into trusted string by removing
 * dangerous content.
 *
 * This method parses the `html` and locates potentially dangerous content (such as urls and
 * javascript) and removes it.
 *
 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustHtml}.
 *
 * @param unsafeHtml untrusted `html`, typically from the user.
 * @returns `html` string which is safe to display to user, because all of the dangerous javascript
 * and urls have been removed.
 *
 * @codeGenApi
 */
function ɵɵsanitizeHtml(unsafeHtml) {
  const sanitizer = getSanitizer();
  if (sanitizer) {
    return trustedHTMLFromStringBypass(sanitizer.sanitize(SecurityContext.HTML, unsafeHtml) || '');
  }
  if (allowSanitizationBypassAndThrow(unsafeHtml, "HTML" /* BypassType.Html */)) {
    return trustedHTMLFromStringBypass(unwrapSafeValue(unsafeHtml));
  }
  return _sanitizeHtml(getDocument(), renderStringify(unsafeHtml));
}
/**
 * A `style` sanitizer which converts untrusted `style` **string** into trusted string by removing
 * dangerous content.
 *
 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustStyle}.
 *
 * @param unsafeStyle untrusted `style`, typically from the user.
 * @returns `style` string which is safe to bind to the `style` properties.
 *
 * @codeGenApi
 */
function ɵɵsanitizeStyle(unsafeStyle) {
  const sanitizer = getSanitizer();
  if (sanitizer) {
    return sanitizer.sanitize(SecurityContext.STYLE, unsafeStyle) || '';
  }
  if (allowSanitizationBypassAndThrow(unsafeStyle, "Style" /* BypassType.Style */)) {
    return unwrapSafeValue(unsafeStyle);
  }
  return renderStringify(unsafeStyle);
}
/**
 * A `url` sanitizer which converts untrusted `url` **string** into trusted string by removing
 * dangerous
 * content.
 *
 * This method parses the `url` and locates potentially dangerous content (such as javascript) and
 * removes it.
 *
 * It is possible to mark a string as trusted by calling {@link bypassSanitizationTrustUrl}.
 *
 * @param unsafeUrl untrusted `url`, typically from the user.
 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
 * all of the dangerous javascript has been removed.
 *
 * @codeGenApi
 */
function ɵɵsanitizeUrl(unsafeUrl) {
  const sanitizer = getSanitizer();
  if (sanitizer) {
    return sanitizer.sanitize(SecurityContext.URL, unsafeUrl) || '';
  }
  if (allowSanitizationBypassAndThrow(unsafeUrl, "URL" /* BypassType.Url */)) {
    return unwrapSafeValue(unsafeUrl);
  }
  return _sanitizeUrl(renderStringify(unsafeUrl));
}
/**
 * A `url` sanitizer which only lets trusted `url`s through.
 *
 * This passes only `url`s marked trusted by calling {@link bypassSanitizationTrustResourceUrl}.
 *
 * @param unsafeResourceUrl untrusted `url`, typically from the user.
 * @returns `url` string which is safe to bind to the `src` properties such as `<img src>`, because
 * only trusted `url`s have been allowed to pass.
 *
 * @codeGenApi
 */
function ɵɵsanitizeResourceUrl(unsafeResourceUrl) {
  const sanitizer = getSanitizer();
  if (sanitizer) {
    return trustedScriptURLFromStringBypass(sanitizer.sanitize(SecurityContext.RESOURCE_URL, unsafeResourceUrl) || '');
  }
  if (allowSanitizationBypassAndThrow(unsafeResourceUrl, "ResourceURL" /* BypassType.ResourceUrl */)) {
    return trustedScriptURLFromStringBypass(unwrapSafeValue(unsafeResourceUrl));
  }
  throw new RuntimeError(904 /* RuntimeErrorCode.UNSAFE_VALUE_IN_RESOURCE_URL */, ngDevMode && `unsafe value used in a resource URL context (see ${XSS_SECURITY_URL})`);
}
/**
 * A `script` sanitizer which only lets trusted javascript through.
 *
 * This passes only `script`s marked trusted by calling {@link
 * bypassSanitizationTrustScript}.
 *
 * @param unsafeScript untrusted `script`, typically from the user.
 * @returns `url` string which is safe to bind to the `<script>` element such as `<img src>`,
 * because only trusted `scripts` have been allowed to pass.
 *
 * @codeGenApi
 */
function ɵɵsanitizeScript(unsafeScript) {
  const sanitizer = getSanitizer();
  if (sanitizer) {
    return trustedScriptFromStringBypass(sanitizer.sanitize(SecurityContext.SCRIPT, unsafeScript) || '');
  }
  if (allowSanitizationBypassAndThrow(unsafeScript, "Script" /* BypassType.Script */)) {
    return trustedScriptFromStringBypass(unwrapSafeValue(unsafeScript));
  }
  throw new RuntimeError(905 /* RuntimeErrorCode.UNSAFE_VALUE_IN_SCRIPT */, ngDevMode && 'unsafe value used in a script context');
}
/**
 * A template tag function for promoting the associated constant literal to a
 * TrustedHTML. Interpolation is explicitly not allowed.
 *
 * @param html constant template literal containing trusted HTML.
 * @returns TrustedHTML wrapping `html`.
 *
 * @security This is a security-sensitive function and should only be used to
 * convert constant values of attributes and properties found in
 * application-provided Angular templates to TrustedHTML.
 *
 * @codeGenApi
 */
function ɵɵtrustConstantHtml(html) {
  // The following runtime check ensures that the function was called as a
  // template tag (e.g. ɵɵtrustConstantHtml`content`), without any interpolation
  // (e.g. not ɵɵtrustConstantHtml`content ${variable}`). A TemplateStringsArray
  // is an array with a `raw` property that is also an array. The associated
  // template literal has no interpolation if and only if the length of the
  // TemplateStringsArray is 1.
  if (ngDevMode && (!Array.isArray(html) || !Array.isArray(html.raw) || html.length !== 1)) {
    throw new Error(`Unexpected interpolation in trusted HTML constant: ${html.join('?')}`);
  }
  return trustedHTMLFromString(html[0]);
}
/**
 * A template tag function for promoting the associated constant literal to a
 * TrustedScriptURL. Interpolation is explicitly not allowed.
 *
 * @param url constant template literal containing a trusted script URL.
 * @returns TrustedScriptURL wrapping `url`.
 *
 * @security This is a security-sensitive function and should only be used to
 * convert constant values of attributes and properties found in
 * application-provided Angular templates to TrustedScriptURL.
 *
 * @codeGenApi
 */
function ɵɵtrustConstantResourceUrl(url) {
  // The following runtime check ensures that the function was called as a
  // template tag (e.g. ɵɵtrustConstantResourceUrl`content`), without any
  // interpolation (e.g. not ɵɵtrustConstantResourceUrl`content ${variable}`). A
  // TemplateStringsArray is an array with a `raw` property that is also an
  // array. The associated template literal has no interpolation if and only if
  // the length of the TemplateStringsArray is 1.
  if (ngDevMode && (!Array.isArray(url) || !Array.isArray(url.raw) || url.length !== 1)) {
    throw new Error(`Unexpected interpolation in trusted URL constant: ${url.join('?')}`);
  }
  return trustedScriptURLFromString(url[0]);
}
/**
 * Detects which sanitizer to use for URL property, based on tag name and prop name.
 *
 * The rules are based on the RESOURCE_URL context config from
 * `packages/compiler/src/schema/dom_security_schema.ts`.
 * If tag and prop names don't match Resource URL schema, use URL sanitizer.
 */
function getUrlSanitizer(tag, prop) {
  if (prop === 'src' && (tag === 'embed' || tag === 'frame' || tag === 'iframe' || tag === 'media' || tag === 'script') || prop === 'href' && (tag === 'base' || tag === 'link')) {
    return ɵɵsanitizeResourceUrl;
  }
  return ɵɵsanitizeUrl;
}
/**
 * Sanitizes URL, selecting sanitizer function based on tag and property names.
 *
 * This function is used in case we can't define security context at compile time, when only prop
 * name is available. This happens when we generate host bindings for Directives/Components. The
 * host element is unknown at compile time, so we defer calculation of specific sanitizer to
 * runtime.
 *
 * @param unsafeUrl untrusted `url`, typically from the user.
 * @param tag target element tag name.
 * @param prop name of the property that contains the value.
 * @returns `url` string which is safe to bind.
 *
 * @codeGenApi
 */
function ɵɵsanitizeUrlOrResourceUrl(unsafeUrl, tag, prop) {
  return getUrlSanitizer(tag, prop)(unsafeUrl);
}
function validateAgainstEventProperties(name) {
  if (name.toLowerCase().startsWith('on')) {
    const errorMessage = `Binding to event property '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...` + `\nIf '${name}' is a directive input, make sure the directive is imported by the` + ` current module.`;
    throw new RuntimeError(306 /* RuntimeErrorCode.INVALID_EVENT_BINDING */, errorMessage);
  }
}
function validateAgainstEventAttributes(name) {
  if (name.toLowerCase().startsWith('on')) {
    const errorMessage = `Binding to event attribute '${name}' is disallowed for security reasons, ` + `please use (${name.slice(2)})=...`;
    throw new RuntimeError(306 /* RuntimeErrorCode.INVALID_EVENT_BINDING */, errorMessage);
  }
}
function getSanitizer() {
  const lView = getLView();
  return lView && lView[ENVIRONMENT].sanitizer;
}

/**
 * Disallowed strings in the comment.
 *
 * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
 */
const COMMENT_DISALLOWED = /^>|^->|<!--|-->|--!>|<!-$/g;
/**
 * Delimiter in the disallowed strings which needs to be wrapped with zero with character.
 */
const COMMENT_DELIMITER = /(<|>)/g;
const COMMENT_DELIMITER_ESCAPED = '\u200B$1\u200B';
/**
 * Escape the content of comment strings so that it can be safely inserted into a comment node.
 *
 * The issue is that HTML does not specify any way to escape comment end text inside the comment.
 * Consider: `<!-- The way you close a comment is with ">", and "->" at the beginning or by "-->" or
 * "--!>" at the end. -->`. Above the `"-->"` is meant to be text not an end to the comment. This
 * can be created programmatically through DOM APIs. (`<!--` are also disallowed.)
 *
 * see: https://html.spec.whatwg.org/multipage/syntax.html#comments
 *
 * ```
 * div.innerHTML = div.innerHTML
 * ```
 *
 * One would expect that the above code would be safe to do, but it turns out that because comment
 * text is not escaped, the comment may contain text which will prematurely close the comment
 * opening up the application for XSS attack. (In SSR we programmatically create comment nodes which
 * may contain such text and expect them to be safe.)
 *
 * This function escapes the comment text by looking for comment delimiters (`<` and `>`) and
 * surrounding them with `_>_` where the `_` is a zero width space `\u200B`. The result is that if a
 * comment contains any of the comment start/end delimiters (such as `<!--`, `-->` or `--!>`) the
 * text it will render normally but it will not cause the HTML parser to close/open the comment.
 *
 * @param value text to make safe for comment node by escaping the comment open/close character
 *     sequence.
 */
function escapeCommentText(value) {
  return value.replace(COMMENT_DISALLOWED, text => text.replace(COMMENT_DELIMITER, COMMENT_DELIMITER_ESCAPED));
}
function normalizeDebugBindingName(name) {
  // Attribute names with `$` (eg `x-y$`) are valid per spec, but unsupported by some browsers
  name = camelCaseToDashCase(name.replace(/[$@]/g, '_'));
  return `ng-reflect-${name}`;
}
const CAMEL_CASE_REGEXP = /([A-Z])/g;
function camelCaseToDashCase(input) {
  return input.replace(CAMEL_CASE_REGEXP, (...m) => '-' + m[1].toLowerCase());
}
function normalizeDebugBindingValue(value) {
  try {
    // Limit the size of the value as otherwise the DOM just gets polluted.
    return value != null ? value.toString().slice(0, 30) : value;
  } catch (e) {
    return '[ERROR] Exception while trying to serialize the value';
  }
}

/**
 * Defines a schema that allows an NgModule to contain the following:
 * - Non-Angular elements named with dash case (`-`).
 * - Element properties named with dash case (`-`).
 * Dash case is the naming convention for custom elements.
 *
 * @publicApi
 */
const CUSTOM_ELEMENTS_SCHEMA = {
  name: 'custom-elements'
};
/**
 * Defines a schema that allows any property on any element.
 *
 * This schema allows you to ignore the errors related to any unknown elements or properties in a
 * template. The usage of this schema is generally discouraged because it prevents useful validation
 * and may hide real errors in your template. Consider using the `CUSTOM_ELEMENTS_SCHEMA` instead.
 *
 * @publicApi
 */
const NO_ERRORS_SCHEMA = {
  name: 'no-errors-schema'
};
let shouldThrowErrorOnUnknownElement = false;
/**
 * Sets a strict mode for JIT-compiled components to throw an error on unknown elements,
 * instead of just logging the error.
 * (for AOT-compiled ones this check happens at build time).
 */
function ɵsetUnknownElementStrictMode(shouldThrow) {
  shouldThrowErrorOnUnknownElement = shouldThrow;
}
/**
 * Gets the current value of the strict mode.
 */
function ɵgetUnknownElementStrictMode() {
  return shouldThrowErrorOnUnknownElement;
}
let shouldThrowErrorOnUnknownProperty = false;
/**
 * Sets a strict mode for JIT-compiled components to throw an error on unknown properties,
 * instead of just logging the error.
 * (for AOT-compiled ones this check happens at build time).
 */
function ɵsetUnknownPropertyStrictMode(shouldThrow) {
  shouldThrowErrorOnUnknownProperty = shouldThrow;
}
/**
 * Gets the current value of the strict mode.
 */
function ɵgetUnknownPropertyStrictMode() {
  return shouldThrowErrorOnUnknownProperty;
}
/**
 * Validates that the element is known at runtime and produces
 * an error if it's not the case.
 * This check is relevant for JIT-compiled components (for AOT-compiled
 * ones this check happens at build time).
 *
 * The element is considered known if either:
 * - it's a known HTML element
 * - it's a known custom element
 * - the element matches any directive
 * - the element is allowed by one of the schemas
 *
 * @param element Element to validate
 * @param lView An `LView` that represents a current component that is being rendered
 * @param tagName Name of the tag to check
 * @param schemas Array of schemas
 * @param hasDirectives Boolean indicating that the element matches any directive
 */
function validateElementIsKnown(element, lView, tagName, schemas, hasDirectives) {
  // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
  // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
  // defined as an array (as an empty array in case `schemas` field is not defined) and we should
  // execute the check below.
  if (schemas === null) return;
  // If the element matches any directive, it's considered as valid.
  if (!hasDirectives && tagName !== null) {
    // The element is unknown if it's an instance of HTMLUnknownElement, or it isn't registered
    // as a custom element. Note that unknown elements with a dash in their name won't be instances
    // of HTMLUnknownElement in browsers that support web components.
    const isUnknown =
    // Note that we can't check for `typeof HTMLUnknownElement === 'function'` because
    // Domino doesn't expose HTMLUnknownElement globally.
    typeof HTMLUnknownElement !== 'undefined' && HTMLUnknownElement && element instanceof HTMLUnknownElement || typeof customElements !== 'undefined' && tagName.indexOf('-') > -1 && !customElements.get(tagName);
    if (isUnknown && !matchingSchemas(schemas, tagName)) {
      const isHostStandalone = isHostComponentStandalone(lView);
      const templateLocation = getTemplateLocationDetails(lView);
      const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
      let message = `'${tagName}' is not a known element${templateLocation}:\n`;
      message += `1. If '${tagName}' is an Angular component, then verify that it is ${isHostStandalone ? 'included in the \'@Component.imports\' of this component' : 'a part of an @NgModule where this component is declared'}.\n`;
      if (tagName && tagName.indexOf('-') > -1) {
        message += `2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the ${schemas} of this component to suppress this message.`;
      } else {
        message += `2. To allow any element add 'NO_ERRORS_SCHEMA' to the ${schemas} of this component.`;
      }
      if (shouldThrowErrorOnUnknownElement) {
        throw new RuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message);
      } else {
        console.error(formatRuntimeError(304 /* RuntimeErrorCode.UNKNOWN_ELEMENT */, message));
      }
    }
  }
}
/**
 * Validates that the property of the element is known at runtime and returns
 * false if it's not the case.
 * This check is relevant for JIT-compiled components (for AOT-compiled
 * ones this check happens at build time).
 *
 * The property is considered known if either:
 * - it's a known property of the element
 * - the element is allowed by one of the schemas
 * - the property is used for animations
 *
 * @param element Element to validate
 * @param propName Name of the property to check
 * @param tagName Name of the tag hosting the property
 * @param schemas Array of schemas
 */
function isPropertyValid(element, propName, tagName, schemas) {
  // If `schemas` is set to `null`, that's an indication that this Component was compiled in AOT
  // mode where this check happens at compile time. In JIT mode, `schemas` is always present and
  // defined as an array (as an empty array in case `schemas` field is not defined) and we should
  // execute the check below.
  if (schemas === null) return true;
  // The property is considered valid if the element matches the schema, it exists on the element,
  // or it is synthetic.
  if (matchingSchemas(schemas, tagName) || propName in element || isAnimationProp(propName)) {
    return true;
  }
  // Note: `typeof Node` returns 'function' in most browsers, but is undefined with domino.
  return typeof Node === 'undefined' || Node === null || !(element instanceof Node);
}
/**
 * Logs or throws an error that a property is not supported on an element.
 *
 * @param propName Name of the invalid property
 * @param tagName Name of the tag hosting the property
 * @param nodeType Type of the node hosting the property
 * @param lView An `LView` that represents a current component
 */
function handleUnknownPropertyError(propName, tagName, nodeType, lView) {
  // Special-case a situation when a structural directive is applied to
  // an `<ng-template>` element, for example: `<ng-template *ngIf="true">`.
  // In this case the compiler generates the `ɵɵtemplate` instruction with
  // the `null` as the tagName. The directive matching logic at runtime relies
  // on this effect (see `isInlineTemplate`), thus using the 'ng-template' as
  // a default value of the `tNode.value` is not feasible at this moment.
  if (!tagName && nodeType === 4 /* TNodeType.Container */) {
    tagName = 'ng-template';
  }
  const isHostStandalone = isHostComponentStandalone(lView);
  const templateLocation = getTemplateLocationDetails(lView);
  let message = `Can't bind to '${propName}' since it isn't a known property of '${tagName}'${templateLocation}.`;
  const schemas = `'${isHostStandalone ? '@Component' : '@NgModule'}.schemas'`;
  const importLocation = isHostStandalone ? 'included in the \'@Component.imports\' of this component' : 'a part of an @NgModule where this component is declared';
  if (KNOWN_CONTROL_FLOW_DIRECTIVES.has(propName)) {
    // Most likely this is a control flow directive (such as `*ngIf`) used in
    // a template, but the directive or the `CommonModule` is not imported.
    const correspondingImport = KNOWN_CONTROL_FLOW_DIRECTIVES.get(propName);
    message += `\nIf the '${propName}' is an Angular control flow directive, ` + `please make sure that either the '${correspondingImport}' directive or the 'CommonModule' is ${importLocation}.`;
  } else {
    // May be an Angular component, which is not imported/declared?
    message += `\n1. If '${tagName}' is an Angular component and it has the ` + `'${propName}' input, then verify that it is ${importLocation}.`;
    // May be a Web Component?
    if (tagName && tagName.indexOf('-') > -1) {
      message += `\n2. If '${tagName}' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' ` + `to the ${schemas} of this component to suppress this message.`;
      message += `\n3. To allow any property add 'NO_ERRORS_SCHEMA' to ` + `the ${schemas} of this component.`;
    } else {
      // If it's expected, the error can be suppressed by the `NO_ERRORS_SCHEMA` schema.
      message += `\n2. To allow any property add 'NO_ERRORS_SCHEMA' to ` + `the ${schemas} of this component.`;
    }
  }
  reportUnknownPropertyError(message);
}
function reportUnknownPropertyError(message) {
  if (shouldThrowErrorOnUnknownProperty) {
    throw new RuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message);
  } else {
    console.error(formatRuntimeError(303 /* RuntimeErrorCode.UNKNOWN_BINDING */, message));
  }
}
/**
 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
 * be too slow for production mode and also it relies on the constructor function being available.
 *
 * Gets a reference to the host component def (where a current component is declared).
 *
 * @param lView An `LView` that represents a current component that is being rendered.
 */
function getDeclarationComponentDef(lView) {
  !ngDevMode && throwError('Must never be called in production mode');
  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
  const context = declarationLView[CONTEXT];
  // Unable to obtain a context.
  if (!context) return null;
  return context.constructor ? getComponentDef(context.constructor) : null;
}
/**
 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
 * be too slow for production mode.
 *
 * Checks if the current component is declared inside of a standalone component template.
 *
 * @param lView An `LView` that represents a current component that is being rendered.
 */
function isHostComponentStandalone(lView) {
  !ngDevMode && throwError('Must never be called in production mode');
  const componentDef = getDeclarationComponentDef(lView);
  // Treat host component as non-standalone if we can't obtain the def.
  return !!componentDef?.standalone;
}
/**
 * WARNING: this is a **dev-mode only** function (thus should always be guarded by the `ngDevMode`)
 * and must **not** be used in production bundles. The function makes megamorphic reads, which might
 * be too slow for production mode.
 *
 * Constructs a string describing the location of the host component template. The function is used
 * in dev mode to produce error messages.
 *
 * @param lView An `LView` that represents a current component that is being rendered.
 */
function getTemplateLocationDetails(lView) {
  !ngDevMode && throwError('Must never be called in production mode');
  const hostComponentDef = getDeclarationComponentDef(lView);
  const componentClassName = hostComponentDef?.type?.name;
  return componentClassName ? ` (used in the '${componentClassName}' component template)` : '';
}
/**
 * The set of known control flow directives and their corresponding imports.
 * We use this set to produce a more precises error message with a note
 * that the `CommonModule` should also be included.
 */
const KNOWN_CONTROL_FLOW_DIRECTIVES = new Map([['ngIf', 'NgIf'], ['ngFor', 'NgFor'], ['ngSwitchCase', 'NgSwitchCase'], ['ngSwitchDefault', 'NgSwitchDefault']]);
/**
 * Returns true if the tag name is allowed by specified schemas.
 * @param schemas Array of schemas
 * @param tagName Name of the tag
 */
function matchingSchemas(schemas, tagName) {
  if (schemas !== null) {
    for (let i = 0; i < schemas.length; i++) {
      const schema = schemas[i];
      if (schema === NO_ERRORS_SCHEMA || schema === CUSTOM_ELEMENTS_SCHEMA && tagName && tagName.indexOf('-') > -1) {
        return true;
      }
    }
  }
  return false;
}

/**
 *
 * @codeGenApi
 */
function ɵɵresolveWindow(element) {
  return element.ownerDocument.defaultView;
}
/**
 *
 * @codeGenApi
 */
function ɵɵresolveDocument(element) {
  return element.ownerDocument;
}
/**
 *
 * @codeGenApi
 */
function ɵɵresolveBody(element) {
  return element.ownerDocument.body;
}
/**
 * The special delimiter we use to separate property names, prefixes, and suffixes
 * in property binding metadata. See storeBindingMetadata().
 *
 * We intentionally use the Unicode "REPLACEMENT CHARACTER" (U+FFFD) as a delimiter
 * because it is a very uncommon character that is unlikely to be part of a user's
 * property names or interpolation strings. If it is in fact used in a property
 * binding, DebugElement.properties will not return the correct value for that
 * binding. However, there should be no runtime effect for real applications.
 *
 * This character is typically rendered as a question mark inside of a diamond.
 * See https://en.wikipedia.org/wiki/Specials_(Unicode_block)
 *
 */
const INTERPOLATION_DELIMITER = `�`;
/**
 * Unwrap a value which might be behind a closure (for forward declaration reasons).
 */
function maybeUnwrapFn(value) {
  if (value instanceof Function) {
    return value();
  } else {
    return value;
  }
}
/**
 * Detects whether the code is invoked in a browser.
 * Later on, this check should be replaced with a tree-shakable
 * flag (e.g. `!isServer`).
 */
function isPlatformBrowser(injector) {
  return (injector ?? inject(Injector)).get(PLATFORM_ID) === 'browser';
}

/**
 * The max length of the string representation of a value in an error message
 */
const VALUE_STRING_LENGTH_LIMIT = 200;
/** Verifies that a given type is a Standalone Component. */
function assertStandaloneComponentType(type) {
  assertComponentDef(type);
  const componentDef = getComponentDef(type);
  if (!componentDef.standalone) {
    throw new RuntimeError(907 /* RuntimeErrorCode.TYPE_IS_NOT_STANDALONE */, `The ${stringifyForError(type)} component is not marked as standalone, ` + `but Angular expects to have a standalone component here. ` + `Please make sure the ${stringifyForError(type)} component has ` + `the \`standalone: true\` flag in the decorator.`);
  }
}
/** Verifies whether a given type is a component */
function assertComponentDef(type) {
  if (!getComponentDef(type)) {
    throw new RuntimeError(906 /* RuntimeErrorCode.MISSING_GENERATED_DEF */, `The ${stringifyForError(type)} is not an Angular component, ` + `make sure it has the \`@Component\` decorator.`);
  }
}
/** Called when there are multiple component selectors that match a given node */
function throwMultipleComponentError(tNode, first, second) {
  throw new RuntimeError(-300 /* RuntimeErrorCode.MULTIPLE_COMPONENTS_MATCH */, `Multiple components match node with tagname ${tNode.value}: ` + `${stringifyForError(first)} and ` + `${stringifyForError(second)}`);
}
/** Throws an ExpressionChangedAfterChecked error if checkNoChanges mode is on. */
function throwErrorIfNoChangesMode(creationMode, oldValue, currValue, propName, lView) {
  const hostComponentDef = getDeclarationComponentDef(lView);
  const componentClassName = hostComponentDef?.type?.name;
  const field = propName ? ` for '${propName}'` : '';
  let msg = `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value${field}: '${formatValue(oldValue)}'. Current value: '${formatValue(currValue)}'.${componentClassName ? ` Expression location: ${componentClassName} component` : ''}`;
  if (creationMode) {
    msg += ` It seems like the view has been created after its parent and its children have been dirty checked.` + ` Has it been created in a change detection hook?`;
  }
  throw new RuntimeError(-100 /* RuntimeErrorCode.EXPRESSION_CHANGED_AFTER_CHECKED */, msg);
}
function formatValue(value) {
  let strValue = String(value);
  // JSON.stringify will throw on circular references
  try {
    if (Array.isArray(value) || strValue === '[object Object]') {
      strValue = JSON.stringify(value);
    }
  } catch (error) {}
  return strValue.length > VALUE_STRING_LENGTH_LIMIT ? strValue.substring(0, VALUE_STRING_LENGTH_LIMIT) + '…' : strValue;
}
function constructDetailsForInterpolation(lView, rootIndex, expressionIndex, meta, changedValue) {
  const [propName, prefix, ...chunks] = meta.split(INTERPOLATION_DELIMITER);
  let oldValue = prefix,
    newValue = prefix;
  for (let i = 0; i < chunks.length; i++) {
    const slotIdx = rootIndex + i;
    oldValue += `${lView[slotIdx]}${chunks[i]}`;
    newValue += `${slotIdx === expressionIndex ? changedValue : lView[slotIdx]}${chunks[i]}`;
  }
  return {
    propName,
    oldValue,
    newValue
  };
}
/**
 * Constructs an object that contains details for the ExpressionChangedAfterItHasBeenCheckedError:
 * - property name (for property bindings or interpolations)
 * - old and new values, enriched using information from metadata
 *
 * More information on the metadata storage format can be found in `storePropertyBindingMetadata`
 * function description.
 */
function getExpressionChangedErrorDetails(lView, bindingIndex, oldValue, newValue) {
  const tData = lView[TVIEW].data;
  const metadata = tData[bindingIndex];
  if (typeof metadata === 'string') {
    // metadata for property interpolation
    if (metadata.indexOf(INTERPOLATION_DELIMITER) > -1) {
      return constructDetailsForInterpolation(lView, bindingIndex, bindingIndex, metadata, newValue);
    }
    // metadata for property binding
    return {
      propName: metadata,
      oldValue,
      newValue
    };
  }
  // metadata is not available for this expression, check if this expression is a part of the
  // property interpolation by going from the current binding index left and look for a string that
  // contains INTERPOLATION_DELIMITER, the layout in tView.data for this case will look like this:
  // [..., 'id�Prefix � and � suffix', null, null, null, ...]
  if (metadata === null) {
    let idx = bindingIndex - 1;
    while (typeof tData[idx] !== 'string' && tData[idx + 1] === null) {
      idx--;
    }
    const meta = tData[idx];
    if (typeof meta === 'string') {
      const matches = meta.match(new RegExp(INTERPOLATION_DELIMITER, 'g'));
      // first interpolation delimiter separates property name from interpolation parts (in case of
      // property interpolations), so we subtract one from total number of found delimiters
      if (matches && matches.length - 1 > bindingIndex - idx) {
        return constructDetailsForInterpolation(lView, idx, bindingIndex, meta, newValue);
      }
    }
  }
  return {
    propName: undefined,
    oldValue,
    newValue
  };
}

/**
 * Flags for renderer-specific style modifiers.
 * @publicApi
 */
var RendererStyleFlags2;
(function (RendererStyleFlags2) {
  // TODO(misko): This needs to be refactored into a separate file so that it can be imported from
  // `node_manipulation.ts` Currently doing the import cause resolution order to change and fails
  // the tests. The work around is to have hard coded value in `node_manipulation.ts` for now.
  /**
   * Marks a style as important.
   */
  RendererStyleFlags2[RendererStyleFlags2["Important"] = 1] = "Important";
  /**
   * Marks a style as using dash case naming (this-is-dash-case).
   */
  RendererStyleFlags2[RendererStyleFlags2["DashCase"] = 2] = "DashCase";
})(RendererStyleFlags2 || (RendererStyleFlags2 = {}));
let _icuContainerIterate;
/**
 * Iterator which provides ability to visit all of the `TIcuContainerNode` root `RNode`s.
 */
function icuContainerIterate(tIcuContainerNode, lView) {
  return _icuContainerIterate(tIcuContainerNode, lView);
}
/**
 * Ensures that `IcuContainerVisitor`'s implementation is present.
 *
 * This function is invoked when i18n instruction comes across an ICU. The purpose is to allow the
 * bundler to tree shake ICU logic and only load it if ICU instruction is executed.
 */
function ensureIcuContainerVisitorLoaded(loader) {
  if (_icuContainerIterate === undefined) {
    // Do not inline this function. We want to keep `ensureIcuContainerVisitorLoaded` light, so it
    // can be inlined into call-site.
    _icuContainerIterate = loader();
  }
}

/**
 * NOTE: for performance reasons, the possible actions are inlined within the function instead of
 * being passed as an argument.
 */
function applyToElementOrContainer(action, renderer, parent, lNodeToHandle, beforeNode) {
  // If this slot was allocated for a text node dynamically created by i18n, the text node itself
  // won't be created until i18nApply() in the update block, so this node should be skipped.
  // For more info, see "ICU expressions should work inside an ngTemplateOutlet inside an ngFor"
  // in `i18n_spec.ts`.
  if (lNodeToHandle != null) {
    let lContainer;
    let isComponent = false;
    // We are expecting an RNode, but in the case of a component or LContainer the `RNode` is
    // wrapped in an array which needs to be unwrapped. We need to know if it is a component and if
    // it has LContainer so that we can process all of those cases appropriately.
    if (isLContainer(lNodeToHandle)) {
      lContainer = lNodeToHandle;
    } else if (isLView(lNodeToHandle)) {
      isComponent = true;
      ngDevMode && assertDefined(lNodeToHandle[HOST], 'HOST must be defined for a component LView');
      lNodeToHandle = lNodeToHandle[HOST];
    }
    const rNode = unwrapRNode(lNodeToHandle);
    if (action === 0 /* WalkTNodeTreeAction.Create */ && parent !== null) {
      if (beforeNode == null) {
        nativeAppendChild(renderer, parent, rNode);
      } else {
        nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
      }
    } else if (action === 1 /* WalkTNodeTreeAction.Insert */ && parent !== null) {
      nativeInsertBefore(renderer, parent, rNode, beforeNode || null, true);
    } else if (action === 2 /* WalkTNodeTreeAction.Detach */) {
      nativeRemoveNode(renderer, rNode, isComponent);
    } else if (action === 3 /* WalkTNodeTreeAction.Destroy */) {
      ngDevMode && ngDevMode.rendererDestroyNode++;
      renderer.destroyNode(rNode);
    }
    if (lContainer != null) {
      applyContainer(renderer, action, lContainer, parent, beforeNode);
    }
  }
}
function createTextNode(renderer, value) {
  ngDevMode && ngDevMode.rendererCreateTextNode++;
  ngDevMode && ngDevMode.rendererSetText++;
  return renderer.createText(value);
}
function updateTextNode(renderer, rNode, value) {
  ngDevMode && ngDevMode.rendererSetText++;
  renderer.setValue(rNode, value);
}
function createCommentNode(renderer, value) {
  ngDevMode && ngDevMode.rendererCreateComment++;
  return renderer.createComment(escapeCommentText(value));
}
/**
 * Creates a native element from a tag name, using a renderer.
 * @param renderer A renderer to use
 * @param name the tag name
 * @param namespace Optional namespace for element.
 * @returns the element created
 */
function createElementNode(renderer, name, namespace) {
  ngDevMode && ngDevMode.rendererCreateElement++;
  return renderer.createElement(name, namespace);
}
/**
 * Removes all DOM elements associated with a view.
 *
 * Because some root nodes of the view may be containers, we sometimes need
 * to propagate deeply into the nested containers to remove all elements in the
 * views beneath it.
 *
 * @param tView The `TView' of the `LView` from which elements should be added or removed
 * @param lView The view from which elements should be added or removed
 */
function removeViewFromDOM(tView, lView) {
  detachViewFromDOM(tView, lView);
  lView[HOST] = null;
  lView[T_HOST] = null;
}
/**
 * Adds all DOM elements associated with a view.
 *
 * Because some root nodes of the view may be containers, we sometimes need
 * to propagate deeply into the nested containers to add all elements in the
 * views beneath it.
 *
 * @param tView The `TView' of the `LView` from which elements should be added or removed
 * @param parentTNode The `TNode` where the `LView` should be attached to.
 * @param renderer Current renderer to use for DOM manipulations.
 * @param lView The view from which elements should be added or removed
 * @param parentNativeNode The parent `RElement` where it should be inserted into.
 * @param beforeNode The node before which elements should be added, if insert mode
 */
function addViewToDOM(tView, parentTNode, renderer, lView, parentNativeNode, beforeNode) {
  lView[HOST] = parentNativeNode;
  lView[T_HOST] = parentTNode;
  applyView(tView, lView, renderer, 1 /* WalkTNodeTreeAction.Insert */, parentNativeNode, beforeNode);
}
/**
 * Detach a `LView` from the DOM by detaching its nodes.
 *
 * @param tView The `TView' of the `LView` to be detached
 * @param lView the `LView` to be detached.
 */
function detachViewFromDOM(tView, lView) {
  // When we remove a view from the DOM, we need to rerun afterRender hooks
  // We don't necessarily needs to run change detection. DOM removal only requires
  // change detection if animations are enabled (this notification is handled by animations).
  lView[ENVIRONMENT].changeDetectionScheduler?.notify(1 /* NotificationType.AfterRenderHooks */);
  applyView(tView, lView, lView[RENDERER], 2 /* WalkTNodeTreeAction.Detach */, null, null);
}
/**
 * Traverses down and up the tree of views and containers to remove listeners and
 * call onDestroy callbacks.
 *
 * Notes:
 *  - Because it's used for onDestroy calls, it needs to be bottom-up.
 *  - Must process containers instead of their views to avoid splicing
 *  when views are destroyed and re-added.
 *  - Using a while loop because it's faster than recursion
 *  - Destroy only called on movement to sibling or movement to parent (laterally or up)
 *
 *  @param rootView The view to destroy
 */
function destroyViewTree(rootView) {
  // If the view has no children, we can clean it up and return early.
  let lViewOrLContainer = rootView[CHILD_HEAD];
  if (!lViewOrLContainer) {
    return cleanUpView(rootView[TVIEW], rootView);
  }
  while (lViewOrLContainer) {
    let next = null;
    if (isLView(lViewOrLContainer)) {
      // If LView, traverse down to child.
      next = lViewOrLContainer[CHILD_HEAD];
    } else {
      ngDevMode && assertLContainer(lViewOrLContainer);
      // If container, traverse down to its first LView.
      const firstView = lViewOrLContainer[CONTAINER_HEADER_OFFSET];
      if (firstView) next = firstView;
    }
    if (!next) {
      // Only clean up view when moving to the side or up, as destroy hooks
      // should be called in order from the bottom up.
      while (lViewOrLContainer && !lViewOrLContainer[NEXT] && lViewOrLContainer !== rootView) {
        if (isLView(lViewOrLContainer)) {
          cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
        }
        lViewOrLContainer = lViewOrLContainer[PARENT];
      }
      if (lViewOrLContainer === null) lViewOrLContainer = rootView;
      if (isLView(lViewOrLContainer)) {
        cleanUpView(lViewOrLContainer[TVIEW], lViewOrLContainer);
      }
      next = lViewOrLContainer && lViewOrLContainer[NEXT];
    }
    lViewOrLContainer = next;
  }
}
/**
 * Inserts a view into a container.
 *
 * This adds the view to the container's array of active views in the correct
 * position. It also adds the view's elements to the DOM if the container isn't a
 * root node of another view (in that case, the view's elements will be added when
 * the container's parent view is added later).
 *
 * @param tView The `TView' of the `LView` to insert
 * @param lView The view to insert
 * @param lContainer The container into which the view should be inserted
 * @param index Which index in the container to insert the child view into
 */
function insertView(tView, lView, lContainer, index) {
  ngDevMode && assertLView(lView);
  ngDevMode && assertLContainer(lContainer);
  const indexInContainer = CONTAINER_HEADER_OFFSET + index;
  const containerLength = lContainer.length;
  if (index > 0) {
    // This is a new view, we need to add it to the children.
    lContainer[indexInContainer - 1][NEXT] = lView;
  }
  if (index < containerLength - CONTAINER_HEADER_OFFSET) {
    lView[NEXT] = lContainer[indexInContainer];
    addToArray(lContainer, CONTAINER_HEADER_OFFSET + index, lView);
  } else {
    lContainer.push(lView);
    lView[NEXT] = null;
  }
  lView[PARENT] = lContainer;
  // track views where declaration and insertion points are different
  const declarationLContainer = lView[DECLARATION_LCONTAINER];
  if (declarationLContainer !== null && lContainer !== declarationLContainer) {
    trackMovedView(declarationLContainer, lView);
  }
  // notify query that a new view has been added
  const lQueries = lView[QUERIES];
  if (lQueries !== null) {
    lQueries.insertView(tView);
  }
  updateAncestorTraversalFlagsOnAttach(lView);
  // Sets the attached flag
  lView[FLAGS] |= 128 /* LViewFlags.Attached */;
}
/**
 * Track views created from the declaration container (TemplateRef) and inserted into a
 * different LContainer.
 */
function trackMovedView(declarationContainer, lView) {
  ngDevMode && assertDefined(lView, 'LView required');
  ngDevMode && assertLContainer(declarationContainer);
  const movedViews = declarationContainer[MOVED_VIEWS];
  const insertedLContainer = lView[PARENT];
  ngDevMode && assertLContainer(insertedLContainer);
  const insertedComponentLView = insertedLContainer[PARENT][DECLARATION_COMPONENT_VIEW];
  ngDevMode && assertDefined(insertedComponentLView, 'Missing insertedComponentLView');
  const declaredComponentLView = lView[DECLARATION_COMPONENT_VIEW];
  ngDevMode && assertDefined(declaredComponentLView, 'Missing declaredComponentLView');
  if (declaredComponentLView !== insertedComponentLView) {
    // At this point the declaration-component is not same as insertion-component; this means that
    // this is a transplanted view. Mark the declared lView as having transplanted views so that
    // those views can participate in CD.
    declarationContainer[FLAGS] |= LContainerFlags.HasTransplantedViews;
  }
  if (movedViews === null) {
    declarationContainer[MOVED_VIEWS] = [lView];
  } else {
    movedViews.push(lView);
  }
}
function detachMovedView(declarationContainer, lView) {
  ngDevMode && assertLContainer(declarationContainer);
  ngDevMode && assertDefined(declarationContainer[MOVED_VIEWS], 'A projected view should belong to a non-empty projected views collection');
  const movedViews = declarationContainer[MOVED_VIEWS];
  const declarationViewIndex = movedViews.indexOf(lView);
  ngDevMode && assertLContainer(lView[PARENT]);
  movedViews.splice(declarationViewIndex, 1);
}
/**
 * Detaches a view from a container.
 *
 * This method removes the view from the container's array of active views. It also
 * removes the view's elements from the DOM.
 *
 * @param lContainer The container from which to detach a view
 * @param removeIndex The index of the view to detach
 * @returns Detached LView instance.
 */
function detachView(lContainer, removeIndex) {
  if (lContainer.length <= CONTAINER_HEADER_OFFSET) return;
  const indexInContainer = CONTAINER_HEADER_OFFSET + removeIndex;
  const viewToDetach = lContainer[indexInContainer];
  if (viewToDetach) {
    const declarationLContainer = viewToDetach[DECLARATION_LCONTAINER];
    if (declarationLContainer !== null && declarationLContainer !== lContainer) {
      detachMovedView(declarationLContainer, viewToDetach);
    }
    if (removeIndex > 0) {
      lContainer[indexInContainer - 1][NEXT] = viewToDetach[NEXT];
    }
    const removedLView = removeFromArray(lContainer, CONTAINER_HEADER_OFFSET + removeIndex);
    removeViewFromDOM(viewToDetach[TVIEW], viewToDetach);
    // notify query that a view has been removed
    const lQueries = removedLView[QUERIES];
    if (lQueries !== null) {
      lQueries.detachView(removedLView[TVIEW]);
    }
    viewToDetach[PARENT] = null;
    viewToDetach[NEXT] = null;
    // Unsets the attached flag
    viewToDetach[FLAGS] &= ~128 /* LViewFlags.Attached */;
  }
  return viewToDetach;
}
/**
 * A standalone function which destroys an LView,
 * conducting clean up (e.g. removing listeners, calling onDestroys).
 *
 * @param tView The `TView' of the `LView` to be destroyed
 * @param lView The view to be destroyed.
 */
function destroyLView(tView, lView) {
  if (!(lView[FLAGS] & 256 /* LViewFlags.Destroyed */)) {
    const renderer = lView[RENDERER];
    if (renderer.destroyNode) {
      applyView(tView, lView, renderer, 3 /* WalkTNodeTreeAction.Destroy */, null, null);
    }
    destroyViewTree(lView);
  }
}
/**
 * Calls onDestroys hooks for all directives and pipes in a given view and then removes all
 * listeners. Listeners are removed as the last step so events delivered in the onDestroys hooks
 * can be propagated to @Output listeners.
 *
 * @param tView `TView` for the `LView` to clean up.
 * @param lView The LView to clean up
 */
function cleanUpView(tView, lView) {
  if (lView[FLAGS] & 256 /* LViewFlags.Destroyed */) {
    return;
  }
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    // Usually the Attached flag is removed when the view is detached from its parent, however
    // if it's a root view, the flag won't be unset hence why we're also removing on destroy.
    lView[FLAGS] &= ~128 /* LViewFlags.Attached */;
    // Mark the LView as destroyed *before* executing the onDestroy hooks. An onDestroy hook
    // runs arbitrary user code, which could include its own `viewRef.destroy()` (or similar). If
    // We don't flag the view as destroyed before the hooks, this could lead to an infinite loop.
    // This also aligns with the ViewEngine behavior. It also means that the onDestroy hook is
    // really more of an "afterDestroy" hook if you think about it.
    lView[FLAGS] |= 256 /* LViewFlags.Destroyed */;
    lView[REACTIVE_TEMPLATE_CONSUMER] && (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.consumerDestroy)(lView[REACTIVE_TEMPLATE_CONSUMER]);
    executeOnDestroys(tView, lView);
    processCleanups(tView, lView);
    // For component views only, the local renderer is destroyed at clean up time.
    if (lView[TVIEW].type === 1 /* TViewType.Component */) {
      ngDevMode && ngDevMode.rendererDestroy++;
      lView[RENDERER].destroy();
    }
    const declarationContainer = lView[DECLARATION_LCONTAINER];
    // we are dealing with an embedded view that is still inserted into a container
    if (declarationContainer !== null && isLContainer(lView[PARENT])) {
      // and this is a projected view
      if (declarationContainer !== lView[PARENT]) {
        detachMovedView(declarationContainer, lView);
      }
      // For embedded views still attached to a container: remove query result from this view.
      const lQueries = lView[QUERIES];
      if (lQueries !== null) {
        lQueries.detachView(tView);
      }
    }
    // Unregister the view once everything else has been cleaned up.
    unregisterLView(lView);
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}
/** Removes listeners and unsubscribes from output subscriptions */
function processCleanups(tView, lView) {
  ngDevMode && assertNotReactive(processCleanups.name);
  const tCleanup = tView.cleanup;
  const lCleanup = lView[CLEANUP];
  if (tCleanup !== null) {
    for (let i = 0; i < tCleanup.length - 1; i += 2) {
      if (typeof tCleanup[i] === 'string') {
        // This is a native DOM listener. It will occupy 4 entries in the TCleanup array (hence i +=
        // 2 at the end of this block).
        const targetIdx = tCleanup[i + 3];
        ngDevMode && assertNumber(targetIdx, 'cleanup target must be a number');
        if (targetIdx >= 0) {
          // Destroy anything whose teardown is a function call (e.g. QueryList, ModelSignal).
          lCleanup[targetIdx]();
        } else {
          // Subscription
          lCleanup[-targetIdx].unsubscribe();
        }
        i += 2;
      } else {
        // This is a cleanup function that is grouped with the index of its context
        const context = lCleanup[tCleanup[i + 1]];
        tCleanup[i].call(context);
      }
    }
  }
  if (lCleanup !== null) {
    lView[CLEANUP] = null;
  }
  const destroyHooks = lView[ON_DESTROY_HOOKS];
  if (destroyHooks !== null) {
    // Reset the ON_DESTROY_HOOKS array before iterating over it to prevent hooks that unregister
    // themselves from mutating the array during iteration.
    lView[ON_DESTROY_HOOKS] = null;
    for (let i = 0; i < destroyHooks.length; i++) {
      const destroyHooksFn = destroyHooks[i];
      ngDevMode && assertFunction(destroyHooksFn, 'Expecting destroy hook to be a function.');
      destroyHooksFn();
    }
  }
}
/** Calls onDestroy hooks for this view */
function executeOnDestroys(tView, lView) {
  ngDevMode && assertNotReactive(executeOnDestroys.name);
  let destroyHooks;
  if (tView != null && (destroyHooks = tView.destroyHooks) != null) {
    for (let i = 0; i < destroyHooks.length; i += 2) {
      const context = lView[destroyHooks[i]];
      // Only call the destroy hook if the context has been requested.
      if (!(context instanceof NodeInjectorFactory)) {
        const toCall = destroyHooks[i + 1];
        if (Array.isArray(toCall)) {
          for (let j = 0; j < toCall.length; j += 2) {
            const callContext = context[toCall[j]];
            const hook = toCall[j + 1];
            profiler(4 /* ProfilerEvent.LifecycleHookStart */, callContext, hook);
            try {
              hook.call(callContext);
            } finally {
              profiler(5 /* ProfilerEvent.LifecycleHookEnd */, callContext, hook);
            }
          }
        } else {
          profiler(4 /* ProfilerEvent.LifecycleHookStart */, context, toCall);
          try {
            toCall.call(context);
          } finally {
            profiler(5 /* ProfilerEvent.LifecycleHookEnd */, context, toCall);
          }
        }
      }
    }
  }
}
/**
 * Returns a native element if a node can be inserted into the given parent.
 *
 * There are two reasons why we may not be able to insert a element immediately.
 * - Projection: When creating a child content element of a component, we have to skip the
 *   insertion because the content of a component will be projected.
 *   `<component><content>delayed due to projection</content></component>`
 * - Parent container is disconnected: This can happen when we are inserting a view into
 *   parent container, which itself is disconnected. For example the parent container is part
 *   of a View which has not be inserted or is made for projection but has not been inserted
 *   into destination.
 *
 * @param tView: Current `TView`.
 * @param tNode: `TNode` for which we wish to retrieve render parent.
 * @param lView: Current `LView`.
 */
function getParentRElement(tView, tNode, lView) {
  return getClosestRElement(tView, tNode.parent, lView);
}
/**
 * Get closest `RElement` or `null` if it can't be found.
 *
 * If `TNode` is `TNodeType.Element` => return `RElement` at `LView[tNode.index]` location.
 * If `TNode` is `TNodeType.ElementContainer|IcuContain` => return the parent (recursively).
 * If `TNode` is `null` then return host `RElement`:
 *   - return `null` if projection
 *   - return `null` if parent container is disconnected (we have no parent.)
 *
 * @param tView: Current `TView`.
 * @param tNode: `TNode` for which we wish to retrieve `RElement` (or `null` if host element is
 *     needed).
 * @param lView: Current `LView`.
 * @returns `null` if the `RElement` can't be determined at this time (no parent / projection)
 */
function getClosestRElement(tView, tNode, lView) {
  let parentTNode = tNode;
  // Skip over element and ICU containers as those are represented by a comment node and
  // can't be used as a render parent.
  while (parentTNode !== null && parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */)) {
    tNode = parentTNode;
    parentTNode = tNode.parent;
  }
  // If the parent tNode is null, then we are inserting across views: either into an embedded view
  // or a component view.
  if (parentTNode === null) {
    // We are inserting a root element of the component view into the component host element and
    // it should always be eager.
    return lView[HOST];
  } else {
    ngDevMode && assertTNodeType(parentTNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
    const {
      componentOffset
    } = parentTNode;
    if (componentOffset > -1) {
      ngDevMode && assertTNodeForLView(parentTNode, lView);
      const {
        encapsulation
      } = tView.data[parentTNode.directiveStart + componentOffset];
      // We've got a parent which is an element in the current view. We just need to verify if the
      // parent element is not a component. Component's content nodes are not inserted immediately
      // because they will be projected, and so doing insert at this point would be wasteful.
      // Since the projection would then move it to its final destination. Note that we can't
      // make this assumption when using the Shadow DOM, because the native projection placeholders
      // (<content> or <slot>) have to be in place as elements are being inserted.
      if (encapsulation === ViewEncapsulation$1.None || encapsulation === ViewEncapsulation$1.Emulated) {
        return null;
      }
    }
    return getNativeByTNode(parentTNode, lView);
  }
}
/**
 * Inserts a native node before another native node for a given parent.
 * This is a utility function that can be used when native nodes were determined.
 */
function nativeInsertBefore(renderer, parent, child, beforeNode, isMove) {
  ngDevMode && ngDevMode.rendererInsertBefore++;
  renderer.insertBefore(parent, child, beforeNode, isMove);
}
function nativeAppendChild(renderer, parent, child) {
  ngDevMode && ngDevMode.rendererAppendChild++;
  ngDevMode && assertDefined(parent, 'parent node must be defined');
  renderer.appendChild(parent, child);
}
function nativeAppendOrInsertBefore(renderer, parent, child, beforeNode, isMove) {
  if (beforeNode !== null) {
    nativeInsertBefore(renderer, parent, child, beforeNode, isMove);
  } else {
    nativeAppendChild(renderer, parent, child);
  }
}
/** Removes a node from the DOM given its native parent. */
function nativeRemoveChild(renderer, parent, child, isHostElement) {
  renderer.removeChild(parent, child, isHostElement);
}
/** Checks if an element is a `<template>` node. */
function isTemplateNode(node) {
  return node.tagName === 'TEMPLATE' && node.content !== undefined;
}
/**
 * Returns a native parent of a given native node.
 */
function nativeParentNode(renderer, node) {
  return renderer.parentNode(node);
}
/**
 * Returns a native sibling of a given native node.
 */
function nativeNextSibling(renderer, node) {
  return renderer.nextSibling(node);
}
/**
 * Find a node in front of which `currentTNode` should be inserted.
 *
 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
 * takes `TNode.insertBeforeIndex` into account if i18n code has been invoked.
 *
 * @param parentTNode parent `TNode`
 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
 * @param lView current `LView`
 */
function getInsertInFrontOfRNode(parentTNode, currentTNode, lView) {
  return _getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView);
}
/**
 * Find a node in front of which `currentTNode` should be inserted. (Does not take i18n into
 * account)
 *
 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
 * does not take `TNode.insertBeforeIndex` into account.
 *
 * @param parentTNode parent `TNode`
 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
 * @param lView current `LView`
 */
function getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView) {
  if (parentTNode.type & (8 /* TNodeType.ElementContainer */ | 32 /* TNodeType.Icu */)) {
    return getNativeByTNode(parentTNode, lView);
  }
  return null;
}
/**
 * Tree shakable boundary for `getInsertInFrontOfRNodeWithI18n` function.
 *
 * This function will only be set if i18n code runs.
 */
let _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithNoI18n;
/**
 * Tree shakable boundary for `processI18nInsertBefore` function.
 *
 * This function will only be set if i18n code runs.
 */
let _processI18nInsertBefore;
function setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore) {
  _getInsertInFrontOfRNodeWithI18n = getInsertInFrontOfRNodeWithI18n;
  _processI18nInsertBefore = processI18nInsertBefore;
}
/**
 * Appends the `child` native node (or a collection of nodes) to the `parent`.
 *
 * @param tView The `TView' to be appended
 * @param lView The current LView
 * @param childRNode The native child (or children) that should be appended
 * @param childTNode The TNode of the child element
 */
function appendChild(tView, lView, childRNode, childTNode) {
  const parentRNode = getParentRElement(tView, childTNode, lView);
  const renderer = lView[RENDERER];
  const parentTNode = childTNode.parent || lView[T_HOST];
  const anchorNode = getInsertInFrontOfRNode(parentTNode, childTNode, lView);
  if (parentRNode != null) {
    if (Array.isArray(childRNode)) {
      for (let i = 0; i < childRNode.length; i++) {
        nativeAppendOrInsertBefore(renderer, parentRNode, childRNode[i], anchorNode, false);
      }
    } else {
      nativeAppendOrInsertBefore(renderer, parentRNode, childRNode, anchorNode, false);
    }
  }
  _processI18nInsertBefore !== undefined && _processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRNode);
}
/**
 * Returns the first native node for a given LView, starting from the provided TNode.
 *
 * Native nodes are returned in the order in which those appear in the native tree (DOM).
 */
function getFirstNativeNode(lView, tNode) {
  if (tNode !== null) {
    ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 32 /* TNodeType.Icu */ | 16 /* TNodeType.Projection */);
    const tNodeType = tNode.type;
    if (tNodeType & 3 /* TNodeType.AnyRNode */) {
      return getNativeByTNode(tNode, lView);
    } else if (tNodeType & 4 /* TNodeType.Container */) {
      return getBeforeNodeForView(-1, lView[tNode.index]);
    } else if (tNodeType & 8 /* TNodeType.ElementContainer */) {
      const elIcuContainerChild = tNode.child;
      if (elIcuContainerChild !== null) {
        return getFirstNativeNode(lView, elIcuContainerChild);
      } else {
        const rNodeOrLContainer = lView[tNode.index];
        if (isLContainer(rNodeOrLContainer)) {
          return getBeforeNodeForView(-1, rNodeOrLContainer);
        } else {
          return unwrapRNode(rNodeOrLContainer);
        }
      }
    } else if (tNodeType & 32 /* TNodeType.Icu */) {
      let nextRNode = icuContainerIterate(tNode, lView);
      let rNode = nextRNode();
      // If the ICU container has no nodes, than we use the ICU anchor as the node.
      return rNode || unwrapRNode(lView[tNode.index]);
    } else {
      const projectionNodes = getProjectionNodes(lView, tNode);
      if (projectionNodes !== null) {
        if (Array.isArray(projectionNodes)) {
          return projectionNodes[0];
        }
        const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
        ngDevMode && assertParentView(parentView);
        return getFirstNativeNode(parentView, projectionNodes);
      } else {
        return getFirstNativeNode(lView, tNode.next);
      }
    }
  }
  return null;
}
function getProjectionNodes(lView, tNode) {
  if (tNode !== null) {
    const componentView = lView[DECLARATION_COMPONENT_VIEW];
    const componentHost = componentView[T_HOST];
    const slotIdx = tNode.projection;
    ngDevMode && assertProjectionSlots(lView);
    return componentHost.projection[slotIdx];
  }
  return null;
}
function getBeforeNodeForView(viewIndexInContainer, lContainer) {
  const nextViewIndex = CONTAINER_HEADER_OFFSET + viewIndexInContainer + 1;
  if (nextViewIndex < lContainer.length) {
    const lView = lContainer[nextViewIndex];
    const firstTNodeOfView = lView[TVIEW].firstChild;
    if (firstTNodeOfView !== null) {
      return getFirstNativeNode(lView, firstTNodeOfView);
    }
  }
  return lContainer[NATIVE];
}
/**
 * Removes a native node itself using a given renderer. To remove the node we are looking up its
 * parent from the native tree as not all platforms / browsers support the equivalent of
 * node.remove().
 *
 * @param renderer A renderer to be used
 * @param rNode The native node that should be removed
 * @param isHostElement A flag indicating if a node to be removed is a host of a component.
 */
function nativeRemoveNode(renderer, rNode, isHostElement) {
  ngDevMode && ngDevMode.rendererRemoveNode++;
  const nativeParent = nativeParentNode(renderer, rNode);
  if (nativeParent) {
    nativeRemoveChild(renderer, nativeParent, rNode, isHostElement);
  }
}
/**
 * Clears the contents of a given RElement.
 *
 * @param rElement the native RElement to be cleared
 */
function clearElementContents(rElement) {
  rElement.textContent = '';
}
/**
 * Performs the operation of `action` on the node. Typically this involves inserting or removing
 * nodes on the LView or projection boundary.
 */
function applyNodes(renderer, action, tNode, lView, parentRElement, beforeNode, isProjection) {
  while (tNode != null) {
    ngDevMode && assertTNodeForLView(tNode, lView);
    ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
    const rawSlotValue = lView[tNode.index];
    const tNodeType = tNode.type;
    if (isProjection) {
      if (action === 0 /* WalkTNodeTreeAction.Create */) {
        rawSlotValue && attachPatchData(unwrapRNode(rawSlotValue), lView);
        tNode.flags |= 2 /* TNodeFlags.isProjected */;
      }
    }
    if ((tNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
      if (tNodeType & 8 /* TNodeType.ElementContainer */) {
        applyNodes(renderer, action, tNode.child, lView, parentRElement, beforeNode, false);
        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
      } else if (tNodeType & 32 /* TNodeType.Icu */) {
        const nextRNode = icuContainerIterate(tNode, lView);
        let rNode;
        while (rNode = nextRNode()) {
          applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
        }
        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
      } else if (tNodeType & 16 /* TNodeType.Projection */) {
        applyProjectionRecursive(renderer, action, lView, tNode, parentRElement, beforeNode);
      } else {
        ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */);
        applyToElementOrContainer(action, renderer, parentRElement, rawSlotValue, beforeNode);
      }
    }
    tNode = isProjection ? tNode.projectionNext : tNode.next;
  }
}
function applyView(tView, lView, renderer, action, parentRElement, beforeNode) {
  applyNodes(renderer, action, tView.firstChild, lView, parentRElement, beforeNode, false);
}
/**
 * `applyProjection` performs operation on the projection.
 *
 * Inserting a projection requires us to locate the projected nodes from the parent component. The
 * complication is that those nodes themselves could be re-projected from their parent component.
 *
 * @param tView The `TView` of `LView` which needs to be inserted, detached, destroyed
 * @param lView The `LView` which needs to be inserted, detached, destroyed.
 * @param tProjectionNode node to project
 */
function applyProjection(tView, lView, tProjectionNode) {
  const renderer = lView[RENDERER];
  const parentRNode = getParentRElement(tView, tProjectionNode, lView);
  const parentTNode = tProjectionNode.parent || lView[T_HOST];
  let beforeNode = getInsertInFrontOfRNode(parentTNode, tProjectionNode, lView);
  applyProjectionRecursive(renderer, 0 /* WalkTNodeTreeAction.Create */, lView, tProjectionNode, parentRNode, beforeNode);
}
/**
 * `applyProjectionRecursive` performs operation on the projection specified by `action` (insert,
 * detach, destroy)
 *
 * Inserting a projection requires us to locate the projected nodes from the parent component. The
 * complication is that those nodes themselves could be re-projected from their parent component.
 *
 * @param renderer Render to use
 * @param action action to perform (insert, detach, destroy)
 * @param lView The LView which needs to be inserted, detached, destroyed.
 * @param tProjectionNode node to project
 * @param parentRElement parent DOM element for insertion/removal.
 * @param beforeNode Before which node the insertions should happen.
 */
function applyProjectionRecursive(renderer, action, lView, tProjectionNode, parentRElement, beforeNode) {
  const componentLView = lView[DECLARATION_COMPONENT_VIEW];
  const componentNode = componentLView[T_HOST];
  ngDevMode && assertEqual(typeof tProjectionNode.projection, 'number', 'expecting projection index');
  const nodeToProjectOrRNodes = componentNode.projection[tProjectionNode.projection];
  if (Array.isArray(nodeToProjectOrRNodes)) {
    // This should not exist, it is a bit of a hack. When we bootstrap a top level node and we
    // need to support passing projectable nodes, so we cheat and put them in the TNode
    // of the Host TView. (Yes we put instance info at the T Level). We can get away with it
    // because we know that TView is not shared and therefore it will not be a problem.
    // This should be refactored and cleaned up.
    for (let i = 0; i < nodeToProjectOrRNodes.length; i++) {
      const rNode = nodeToProjectOrRNodes[i];
      applyToElementOrContainer(action, renderer, parentRElement, rNode, beforeNode);
    }
  } else {
    let nodeToProject = nodeToProjectOrRNodes;
    const projectedComponentLView = componentLView[PARENT];
    // If a parent <ng-content> is located within a skip hydration block,
    // annotate an actual node that is being projected with the same flag too.
    if (hasInSkipHydrationBlockFlag(tProjectionNode)) {
      nodeToProject.flags |= 128 /* TNodeFlags.inSkipHydrationBlock */;
    }
    applyNodes(renderer, action, nodeToProject, projectedComponentLView, parentRElement, beforeNode, true);
  }
}
/**
 * `applyContainer` performs an operation on the container and its views as specified by
 * `action` (insert, detach, destroy)
 *
 * Inserting a Container is complicated by the fact that the container may have Views which
 * themselves have containers or projections.
 *
 * @param renderer Renderer to use
 * @param action action to perform (insert, detach, destroy)
 * @param lContainer The LContainer which needs to be inserted, detached, destroyed.
 * @param parentRElement parent DOM element for insertion/removal.
 * @param beforeNode Before which node the insertions should happen.
 */
function applyContainer(renderer, action, lContainer, parentRElement, beforeNode) {
  ngDevMode && assertLContainer(lContainer);
  const anchor = lContainer[NATIVE]; // LContainer has its own before node.
  const native = unwrapRNode(lContainer);
  // An LContainer can be created dynamically on any node by injecting ViewContainerRef.
  // Asking for a ViewContainerRef on an element will result in a creation of a separate anchor
  // node (comment in the DOM) that will be different from the LContainer's host node. In this
  // particular case we need to execute action on 2 nodes:
  // - container's host node (this is done in the executeActionOnElementOrContainer)
  // - container's host node (this is done here)
  if (anchor !== native) {
    // This is very strange to me (Misko). I would expect that the native is same as anchor. I
    // don't see a reason why they should be different, but they are.
    //
    // If they are we need to process the second anchor as well.
    applyToElementOrContainer(action, renderer, parentRElement, anchor, beforeNode);
  }
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
    const lView = lContainer[i];
    applyView(lView[TVIEW], lView, renderer, action, parentRElement, anchor);
  }
}
/**
 * Writes class/style to element.
 *
 * @param renderer Renderer to use.
 * @param isClassBased `true` if it should be written to `class` (`false` to write to `style`)
 * @param rNode The Node to write to.
 * @param prop Property to write to. This would be the class/style name.
 * @param value Value to write. If `null`/`undefined`/`false` this is considered a remove (set/add
 *        otherwise).
 */
function applyStyling(renderer, isClassBased, rNode, prop, value) {
  if (isClassBased) {
    // We actually want JS true/false here because any truthy value should add the class
    if (!value) {
      ngDevMode && ngDevMode.rendererRemoveClass++;
      renderer.removeClass(rNode, prop);
    } else {
      ngDevMode && ngDevMode.rendererAddClass++;
      renderer.addClass(rNode, prop);
    }
  } else {
    let flags = prop.indexOf('-') === -1 ? undefined : RendererStyleFlags2.DashCase;
    if (value == null /** || value === undefined */) {
      ngDevMode && ngDevMode.rendererRemoveStyle++;
      renderer.removeStyle(rNode, prop, flags);
    } else {
      // A value is important if it ends with `!important`. The style
      // parser strips any semicolons at the end of the value.
      const isImportant = typeof value === 'string' ? value.endsWith('!important') : false;
      if (isImportant) {
        // !important has to be stripped from the value for it to be valid.
        value = value.slice(0, -10);
        flags |= RendererStyleFlags2.Important;
      }
      ngDevMode && ngDevMode.rendererSetStyle++;
      renderer.setStyle(rNode, prop, value, flags);
    }
  }
}
/**
 * Write `cssText` to `RElement`.
 *
 * This function does direct write without any reconciliation. Used for writing initial values, so
 * that static styling values do not pull in the style parser.
 *
 * @param renderer Renderer to use
 * @param element The element which needs to be updated.
 * @param newValue The new class list to write.
 */
function writeDirectStyle(renderer, element, newValue) {
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
  renderer.setAttribute(element, 'style', newValue);
  ngDevMode && ngDevMode.rendererSetStyle++;
}
/**
 * Write `className` to `RElement`.
 *
 * This function does direct write without any reconciliation. Used for writing initial values, so
 * that static styling values do not pull in the style parser.
 *
 * @param renderer Renderer to use
 * @param element The element which needs to be updated.
 * @param newValue The new class list to write.
 */
function writeDirectClass(renderer, element, newValue) {
  ngDevMode && assertString(newValue, '\'newValue\' should be a string');
  if (newValue === '') {
    // There are tests in `google3` which expect `element.getAttribute('class')` to be `null`.
    renderer.removeAttribute(element, 'class');
  } else {
    renderer.setAttribute(element, 'class', newValue);
  }
  ngDevMode && ngDevMode.rendererSetClassName++;
}
/** Sets up the static DOM attributes on an `RNode`. */
function setupStaticAttributes(renderer, element, tNode) {
  const {
    mergedAttrs,
    classes,
    styles
  } = tNode;
  if (mergedAttrs !== null) {
    setUpAttributes(renderer, element, mergedAttrs);
  }
  if (classes !== null) {
    writeDirectClass(renderer, element, classes);
  }
  if (styles !== null) {
    writeDirectStyle(renderer, element, styles);
  }
}

/** A special value which designates that a value has not changed. */
const NO_CHANGE = typeof ngDevMode === 'undefined' || ngDevMode ? {
  __brand__: 'NO_CHANGE'
} : {};

/**
 * Advances to an element for later binding instructions.
 *
 * Used in conjunction with instructions like {@link property} to act on elements with specified
 * indices, for example those created with {@link element} or {@link elementStart}.
 *
 * ```ts
 * (rf: RenderFlags, ctx: any) => {
 *   if (rf & 1) {
 *     text(0, 'Hello');
 *     text(1, 'Goodbye')
 *     element(2, 'div');
 *   }
 *   if (rf & 2) {
 *     advance(2); // Advance twice to the <div>.
 *     property('title', 'test');
 *   }
 *  }
 * ```
 * @param delta Number of elements to advance forwards by.
 *
 * @codeGenApi
 */
function ɵɵadvance(delta = 1) {
  ngDevMode && assertGreaterThan(delta, 0, 'Can only advance forward');
  selectIndexInternal(getTView(), getLView(), getSelectedIndex() + delta, !!ngDevMode && isInCheckNoChangesMode());
}
function selectIndexInternal(tView, lView, index, checkNoChangesMode) {
  ngDevMode && assertIndexInDeclRange(lView[TVIEW], index);
  // Flush the initial hooks for elements in the view that have been added up to this point.
  // PERF WARNING: do NOT extract this to a separate function without running benchmarks
  if (!checkNoChangesMode) {
    const hooksInitPhaseCompleted = (lView[FLAGS] & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
    if (hooksInitPhaseCompleted) {
      const preOrderCheckHooks = tView.preOrderCheckHooks;
      if (preOrderCheckHooks !== null) {
        executeCheckHooks(lView, preOrderCheckHooks, index);
      }
    } else {
      const preOrderHooks = tView.preOrderHooks;
      if (preOrderHooks !== null) {
        executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, index);
      }
    }
  }
  // We must set the selected index *after* running the hooks, because hooks may have side-effects
  // that cause other template functions to run, thus updating the selected index, which is global
  // state. If we run `setSelectedIndex` *before* we run the hooks, in some cases the selected index
  // will be altered by the time we leave the `ɵɵadvance` instruction.
  setSelectedIndex(index);
}
function ɵɵdirectiveInject(token, flags = InjectFlags.Default) {
  const lView = getLView();
  // Fall back to inject() if view hasn't been created. This situation can happen in tests
  // if inject utilities are used before bootstrapping.
  if (lView === null) {
    // Verify that we will not get into infinite loop.
    ngDevMode && assertInjectImplementationNotEqual(ɵɵdirectiveInject);
    return ɵɵinject(token, flags);
  }
  const tNode = getCurrentTNode();
  const value = getOrCreateInjectable(tNode, lView, resolveForwardRef(token), flags);
  ngDevMode && emitInjectEvent(token, value, flags);
  return value;
}
/**
 * Throws an error indicating that a factory function could not be generated by the compiler for a
 * particular class.
 *
 * This instruction allows the actual error message to be optimized away when ngDevMode is turned
 * off, saving bytes of generated code while still providing a good experience in dev mode.
 *
 * The name of the class is not mentioned here, but will be in the generated factory function name
 * and thus in the stack trace.
 *
 * @codeGenApi
 */
function ɵɵinvalidFactory() {
  const msg = ngDevMode ? `This constructor was not compatible with Dependency Injection.` : 'invalid';
  throw new Error(msg);
}
function writeToDirectiveInput(def, instance, publicName, privateName, flags, value) {
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    // If we know we are dealing with a signal input, we cache its reference
    // in a tree-shakable way. The input signal node can then be used for
    // value transform execution or actual value updates without introducing
    // additional megamorphic accesses for accessing the instance field.
    let inputSignalNode = null;
    if ((flags & InputFlags.SignalBased) !== 0) {
      const field = instance[privateName];
      inputSignalNode = field[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL];
    }
    // If there is a signal node and a transform, run it before potentially
    // delegating to features like `NgOnChanges`.
    if (inputSignalNode !== null && inputSignalNode.transformFn !== undefined) {
      value = inputSignalNode.transformFn(value);
    }
    // If there is a decorator input transform, run it.
    if ((flags & InputFlags.HasDecoratorInputTransform) !== 0) {
      value = def.inputTransforms[privateName].call(instance, value);
    }
    if (def.setInput !== null) {
      def.setInput(instance, inputSignalNode, value, publicName, privateName);
    } else {
      applyValueToInputField(instance, inputSignalNode, privateName, value);
    }
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}

/**
 * Invoke `HostBindingsFunction`s for view.
 *
 * This methods executes `TView.hostBindingOpCodes`. It is used to execute the
 * `HostBindingsFunction`s associated with the current `LView`.
 *
 * @param tView Current `TView`.
 * @param lView Current `LView`.
 */
function processHostBindingOpCodes(tView, lView) {
  const hostBindingOpCodes = tView.hostBindingOpCodes;
  if (hostBindingOpCodes === null) return;
  try {
    for (let i = 0; i < hostBindingOpCodes.length; i++) {
      const opCode = hostBindingOpCodes[i];
      if (opCode < 0) {
        // Negative numbers are element indexes.
        setSelectedIndex(~opCode);
      } else {
        // Positive numbers are NumberTuple which store bindingRootIndex and directiveIndex.
        const directiveIdx = opCode;
        const bindingRootIndx = hostBindingOpCodes[++i];
        const hostBindingFn = hostBindingOpCodes[++i];
        setBindingRootForHostBindings(bindingRootIndx, directiveIdx);
        const context = lView[directiveIdx];
        hostBindingFn(2 /* RenderFlags.Update */, context);
      }
    }
  } finally {
    setSelectedIndex(-1);
  }
}
function createLView(parentLView, tView, context, flags, host, tHostNode, environment, renderer, injector, embeddedViewInjector, hydrationInfo) {
  const lView = tView.blueprint.slice();
  lView[HOST] = host;
  lView[FLAGS] = flags | 4 /* LViewFlags.CreationMode */ | 128 /* LViewFlags.Attached */ | 8 /* LViewFlags.FirstLViewPass */ | 64 /* LViewFlags.Dirty */;
  if (embeddedViewInjector !== null || parentLView && parentLView[FLAGS] & 2048 /* LViewFlags.HasEmbeddedViewInjector */) {
    lView[FLAGS] |= 2048 /* LViewFlags.HasEmbeddedViewInjector */;
  }
  resetPreOrderHookFlags(lView);
  ngDevMode && tView.declTNode && parentLView && assertTNodeForLView(tView.declTNode, parentLView);
  lView[PARENT] = lView[DECLARATION_VIEW] = parentLView;
  lView[CONTEXT] = context;
  lView[ENVIRONMENT] = environment || parentLView && parentLView[ENVIRONMENT];
  ngDevMode && assertDefined(lView[ENVIRONMENT], 'LViewEnvironment is required');
  lView[RENDERER] = renderer || parentLView && parentLView[RENDERER];
  ngDevMode && assertDefined(lView[RENDERER], 'Renderer is required');
  lView[INJECTOR] = injector || parentLView && parentLView[INJECTOR] || null;
  lView[T_HOST] = tHostNode;
  lView[ID] = getUniqueLViewId();
  lView[HYDRATION] = hydrationInfo;
  lView[EMBEDDED_VIEW_INJECTOR] = embeddedViewInjector;
  ngDevMode && assertEqual(tView.type == 2 /* TViewType.Embedded */ ? parentLView !== null : true, true, 'Embedded views must have parentLView');
  lView[DECLARATION_COMPONENT_VIEW] = tView.type == 2 /* TViewType.Embedded */ ? parentLView[DECLARATION_COMPONENT_VIEW] : lView;
  return lView;
}
function getOrCreateTNode(tView, index, type, name, attrs) {
  ngDevMode && index !== 0 &&
  // 0 are bogus nodes and they are OK. See `createContainerRef` in
  // `view_engine_compatibility` for additional context.
  assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.');
  // Keep this function short, so that the VM will inline it.
  ngDevMode && assertPureTNodeType(type);
  let tNode = tView.data[index];
  if (tNode === null) {
    tNode = createTNodeAtIndex(tView, index, type, name, attrs);
    if (isInI18nBlock()) {
      // If we are in i18n block then all elements should be pre declared through `Placeholder`
      // See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
      // If the `TNode` was not pre-declared than it means it was not mentioned which means it was
      // removed, so we mark it as detached.
      tNode.flags |= 32 /* TNodeFlags.isDetached */;
    }
  } else if (tNode.type & 64 /* TNodeType.Placeholder */) {
    tNode.type = type;
    tNode.value = name;
    tNode.attrs = attrs;
    const parent = getCurrentParentTNode();
    tNode.injectorIndex = parent === null ? -1 : parent.injectorIndex;
    ngDevMode && assertTNodeForTView(tNode, tView);
    ngDevMode && assertEqual(index, tNode.index, 'Expecting same index');
  }
  setCurrentTNode(tNode, true);
  return tNode;
}
function createTNodeAtIndex(tView, index, type, name, attrs) {
  const currentTNode = getCurrentTNodePlaceholderOk();
  const isParent = isCurrentTNodeParent();
  const parent = isParent ? currentTNode : currentTNode && currentTNode.parent;
  // Parents cannot cross component boundaries because components will be used in multiple places.
  const tNode = tView.data[index] = createTNode(tView, parent, type, index, name, attrs);
  // Assign a pointer to the first child node of a given view. The first node is not always the one
  // at index 0, in case of i18n, index 0 can be the instruction `i18nStart` and the first node has
  // the index 1 or more, so we can't just check node index.
  if (tView.firstChild === null) {
    tView.firstChild = tNode;
  }
  if (currentTNode !== null) {
    if (isParent) {
      // FIXME(misko): This logic looks unnecessarily complicated. Could we simplify?
      if (currentTNode.child == null && tNode.parent !== null) {
        // We are in the same view, which means we are adding content node to the parent view.
        currentTNode.child = tNode;
      }
    } else {
      if (currentTNode.next === null) {
        // In the case of i18n the `currentTNode` may already be linked, in which case we don't want
        // to break the links which i18n created.
        currentTNode.next = tNode;
        tNode.prev = currentTNode;
      }
    }
  }
  return tNode;
}
/**
 * When elements are created dynamically after a view blueprint is created (e.g. through
 * i18nApply()), we need to adjust the blueprint for future
 * template passes.
 *
 * @param tView `TView` associated with `LView`
 * @param lView The `LView` containing the blueprint to adjust
 * @param numSlotsToAlloc The number of slots to alloc in the LView, should be >0
 * @param initialValue Initial value to store in blueprint
 */
function allocExpando(tView, lView, numSlotsToAlloc, initialValue) {
  if (numSlotsToAlloc === 0) return -1;
  if (ngDevMode) {
    assertFirstCreatePass(tView);
    assertSame(tView, lView[TVIEW], '`LView` must be associated with `TView`!');
    assertEqual(tView.data.length, lView.length, 'Expecting LView to be same size as TView');
    assertEqual(tView.data.length, tView.blueprint.length, 'Expecting Blueprint to be same size as TView');
    assertFirstUpdatePass(tView);
  }
  const allocIdx = lView.length;
  for (let i = 0; i < numSlotsToAlloc; i++) {
    lView.push(initialValue);
    tView.blueprint.push(initialValue);
    tView.data.push(null);
  }
  return allocIdx;
}
function executeTemplate(tView, lView, templateFn, rf, context) {
  const prevSelectedIndex = getSelectedIndex();
  const isUpdatePhase = rf & 2 /* RenderFlags.Update */;
  try {
    setSelectedIndex(-1);
    if (isUpdatePhase && lView.length > HEADER_OFFSET) {
      // When we're updating, inherently select 0 so we don't
      // have to generate that instruction for most update blocks.
      selectIndexInternal(tView, lView, HEADER_OFFSET, !!ngDevMode && isInCheckNoChangesMode());
    }
    const preHookType = isUpdatePhase ? 2 /* ProfilerEvent.TemplateUpdateStart */ : 0 /* ProfilerEvent.TemplateCreateStart */;
    profiler(preHookType, context);
    templateFn(rf, context);
  } finally {
    setSelectedIndex(prevSelectedIndex);
    const postHookType = isUpdatePhase ? 3 /* ProfilerEvent.TemplateUpdateEnd */ : 1 /* ProfilerEvent.TemplateCreateEnd */;
    profiler(postHookType, context);
  }
}
//////////////////////////
//// Element
//////////////////////////
function executeContentQueries(tView, tNode, lView) {
  if (isContentQueryHost(tNode)) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      const start = tNode.directiveStart;
      const end = tNode.directiveEnd;
      for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
        const def = tView.data[directiveIndex];
        if (def.contentQueries) {
          const directiveInstance = lView[directiveIndex];
          ngDevMode && assertDefined(directiveIndex, 'Incorrect reference to a directive defining a content query');
          def.contentQueries(1 /* RenderFlags.Create */, directiveInstance, directiveIndex);
        }
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
}
/**
 * Creates directive instances.
 */
function createDirectivesInstances(tView, lView, tNode) {
  if (!getBindingsEnabled()) return;
  instantiateAllDirectives(tView, lView, tNode, getNativeByTNode(tNode, lView));
  if ((tNode.flags & 64 /* TNodeFlags.hasHostBindings */) === 64 /* TNodeFlags.hasHostBindings */) {
    invokeDirectivesHostBindings(tView, lView, tNode);
  }
}
/**
 * Takes a list of local names and indices and pushes the resolved local variable values
 * to LView in the same order as they are loaded in the template with load().
 */
function saveResolvedLocalsInData(viewData, tNode, localRefExtractor = getNativeByTNode) {
  const localNames = tNode.localNames;
  if (localNames !== null) {
    let localIndex = tNode.index + 1;
    for (let i = 0; i < localNames.length; i += 2) {
      const index = localNames[i + 1];
      const value = index === -1 ? localRefExtractor(tNode, viewData) : viewData[index];
      viewData[localIndex++] = value;
    }
  }
}
/**
 * Gets TView from a template function or creates a new TView
 * if it doesn't already exist.
 *
 * @param def ComponentDef
 * @returns TView
 */
function getOrCreateComponentTView(def) {
  const tView = def.tView;
  // Create a TView if there isn't one, or recreate it if the first create pass didn't
  // complete successfully since we can't know for sure whether it's in a usable shape.
  if (tView === null || tView.incompleteFirstPass) {
    // Declaration node here is null since this function is called when we dynamically create a
    // component and hence there is no declaration.
    const declTNode = null;
    return def.tView = createTView(1 /* TViewType.Component */, declTNode, def.template, def.decls, def.vars, def.directiveDefs, def.pipeDefs, def.viewQuery, def.schemas, def.consts, def.id);
  }
  return tView;
}
/**
 * Creates a TView instance
 *
 * @param type Type of `TView`.
 * @param declTNode Declaration location of this `TView`.
 * @param templateFn Template function
 * @param decls The number of nodes, local refs, and pipes in this template
 * @param directives Registry of directives for this view
 * @param pipes Registry of pipes for this view
 * @param viewQuery View queries for this view
 * @param schemas Schemas for this view
 * @param consts Constants for this view
 */
function createTView(type, declTNode, templateFn, decls, vars, directives, pipes, viewQuery, schemas, constsOrFactory, ssrId) {
  ngDevMode && ngDevMode.tView++;
  const bindingStartIndex = HEADER_OFFSET + decls;
  // This length does not yet contain host bindings from child directives because at this point,
  // we don't know which directives are active on this template. As soon as a directive is matched
  // that has a host binding, we will update the blueprint with that def's hostVars count.
  const initialViewLength = bindingStartIndex + vars;
  const blueprint = createViewBlueprint(bindingStartIndex, initialViewLength);
  const consts = typeof constsOrFactory === 'function' ? constsOrFactory() : constsOrFactory;
  const tView = blueprint[TVIEW] = {
    type: type,
    blueprint: blueprint,
    template: templateFn,
    queries: null,
    viewQuery: viewQuery,
    declTNode: declTNode,
    data: blueprint.slice().fill(null, bindingStartIndex),
    bindingStartIndex: bindingStartIndex,
    expandoStartIndex: initialViewLength,
    hostBindingOpCodes: null,
    firstCreatePass: true,
    firstUpdatePass: true,
    staticViewQueries: false,
    staticContentQueries: false,
    preOrderHooks: null,
    preOrderCheckHooks: null,
    contentHooks: null,
    contentCheckHooks: null,
    viewHooks: null,
    viewCheckHooks: null,
    destroyHooks: null,
    cleanup: null,
    contentQueries: null,
    components: null,
    directiveRegistry: typeof directives === 'function' ? directives() : directives,
    pipeRegistry: typeof pipes === 'function' ? pipes() : pipes,
    firstChild: null,
    schemas: schemas,
    consts: consts,
    incompleteFirstPass: false,
    ssrId
  };
  if (ngDevMode) {
    // For performance reasons it is important that the tView retains the same shape during runtime.
    // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
    // prevent class transitions.
    Object.seal(tView);
  }
  return tView;
}
function createViewBlueprint(bindingStartIndex, initialViewLength) {
  const blueprint = [];
  for (let i = 0; i < initialViewLength; i++) {
    blueprint.push(i < bindingStartIndex ? null : NO_CHANGE);
  }
  return blueprint;
}
/**
 * Locates the host native element, used for bootstrapping existing nodes into rendering pipeline.
 *
 * @param renderer the renderer used to locate the element.
 * @param elementOrSelector Render element or CSS selector to locate the element.
 * @param encapsulation View Encapsulation defined for component that requests host element.
 * @param injector Root view injector instance.
 */
function locateHostElement(renderer, elementOrSelector, encapsulation, injector) {
  // Note: we use default value for the `PRESERVE_HOST_CONTENT` here even though it's a
  // tree-shakable one (providedIn:'root'). This code path can be triggered during dynamic
  // component creation (after calling ViewContainerRef.createComponent) when an injector
  // instance can be provided. The injector instance might be disconnected from the main DI
  // tree, thus the `PRESERVE_HOST_CONTENT` would not be able to instantiate. In this case, the
  // default value will be used.
  const preserveHostContent = injector.get(PRESERVE_HOST_CONTENT, PRESERVE_HOST_CONTENT_DEFAULT);
  // When using native Shadow DOM, do not clear host element to allow native slot
  // projection.
  const preserveContent = preserveHostContent || encapsulation === ViewEncapsulation$1.ShadowDom;
  const rootElement = renderer.selectRootElement(elementOrSelector, preserveContent);
  applyRootElementTransform(rootElement);
  return rootElement;
}
/**
 * Applies any root element transformations that are needed. If hydration is enabled,
 * this will process corrupted text nodes.
 *
 * @param rootElement the app root HTML Element
 */
function applyRootElementTransform(rootElement) {
  _applyRootElementTransformImpl(rootElement);
}
/**
 * Reference to a function that applies transformations to the root HTML element
 * of an app. When hydration is enabled, this processes any corrupt text nodes
 * so they are properly hydratable on the client.
 *
 * @param rootElement the app root HTML Element
 */
let _applyRootElementTransformImpl = () => null;
/**
 * Processes text node markers before hydration begins. This replaces any special comment
 * nodes that were added prior to serialization are swapped out to restore proper text
 * nodes before hydration.
 *
 * @param rootElement the app root HTML Element
 */
function applyRootElementTransformImpl(rootElement) {
  if (hasSkipHydrationAttrOnRElement(rootElement)) {
    // Handle a situation when the `ngSkipHydration` attribute is applied
    // to the root node of an application. In this case, we should clear
    // the contents and render everything from scratch.
    clearElementContents(rootElement);
  } else {
    processTextNodeMarkersBeforeHydration(rootElement);
  }
}
/**
 * Sets the implementation for the `applyRootElementTransform` function.
 */
function enableApplyRootElementTransformImpl() {
  _applyRootElementTransformImpl = applyRootElementTransformImpl;
}
/**
 * Saves context for this cleanup function in LView.cleanupInstances.
 *
 * On the first template pass, saves in TView:
 * - Cleanup function
 * - Index of context we just saved in LView.cleanupInstances
 */
function storeCleanupWithContext(tView, lView, context, cleanupFn) {
  const lCleanup = getOrCreateLViewCleanup(lView);
  // Historically the `storeCleanupWithContext` was used to register both framework-level and
  // user-defined cleanup callbacks, but over time those two types of cleanups were separated.
  // This dev mode checks assures that user-level cleanup callbacks are _not_ stored in data
  // structures reserved for framework-specific hooks.
  ngDevMode && assertDefined(context, 'Cleanup context is mandatory when registering framework-level destroy hooks');
  lCleanup.push(context);
  if (tView.firstCreatePass) {
    getOrCreateTViewCleanup(tView).push(cleanupFn, lCleanup.length - 1);
  } else {
    // Make sure that no new framework-level cleanup functions are registered after the first
    // template pass is done (and TView data structures are meant to fully constructed).
    if (ngDevMode) {
      Object.freeze(getOrCreateTViewCleanup(tView));
    }
  }
}
function createTNode(tView, tParent, type, index, value, attrs) {
  ngDevMode && index !== 0 &&
  // 0 are bogus nodes and they are OK. See `createContainerRef` in
  // `view_engine_compatibility` for additional context.
  assertGreaterThanOrEqual(index, HEADER_OFFSET, 'TNodes can\'t be in the LView header.');
  ngDevMode && assertNotSame(attrs, undefined, '\'undefined\' is not valid value for \'attrs\'');
  ngDevMode && ngDevMode.tNode++;
  ngDevMode && tParent && assertTNodeForTView(tParent, tView);
  let injectorIndex = tParent ? tParent.injectorIndex : -1;
  let flags = 0;
  if (isInSkipHydrationBlock$1()) {
    flags |= 128 /* TNodeFlags.inSkipHydrationBlock */;
  }
  const tNode = {
    type,
    index,
    insertBeforeIndex: null,
    injectorIndex,
    directiveStart: -1,
    directiveEnd: -1,
    directiveStylingLast: -1,
    componentOffset: -1,
    propertyBindings: null,
    flags,
    providerIndexes: 0,
    value: value,
    attrs: attrs,
    mergedAttrs: null,
    localNames: null,
    initialInputs: undefined,
    inputs: null,
    outputs: null,
    tView: null,
    next: null,
    prev: null,
    projectionNext: null,
    child: null,
    parent: tParent,
    projection: null,
    styles: null,
    stylesWithoutHost: null,
    residualStyles: undefined,
    classes: null,
    classesWithoutHost: null,
    residualClasses: undefined,
    classBindings: 0,
    styleBindings: 0
  };
  if (ngDevMode) {
    // For performance reasons it is important that the tNode retains the same shape during runtime.
    // (To make sure that all of the code is monomorphic.) For this reason we seal the object to
    // prevent class transitions.
    Object.seal(tNode);
  }
  return tNode;
}
function captureNodeBindings(mode, aliasMap, directiveIndex, bindingsResult, hostDirectiveAliasMap) {
  for (let publicName in aliasMap) {
    if (!aliasMap.hasOwnProperty(publicName)) {
      continue;
    }
    const value = aliasMap[publicName];
    if (value === undefined) {
      continue;
    }
    bindingsResult ??= {};
    let internalName;
    let inputFlags = InputFlags.None;
    // For inputs, the value might be an array capturing additional
    // input flags.
    if (Array.isArray(value)) {
      internalName = value[0];
      inputFlags = value[1];
    } else {
      internalName = value;
    }
    // If there are no host directive mappings, we want to remap using the alias map from the
    // definition itself. If there is an alias map, it has two functions:
    // 1. It serves as an allowlist of bindings that are exposed by the host directives. Only the
    // ones inside the host directive map will be exposed on the host.
    // 2. The public name of the property is aliased using the host directive alias map, rather
    // than the alias map from the definition.
    let finalPublicName = publicName;
    if (hostDirectiveAliasMap !== null) {
      // If there is no mapping, it's not part of the allowlist and this input/output
      // is not captured and should be ignored.
      if (!hostDirectiveAliasMap.hasOwnProperty(publicName)) {
        continue;
      }
      finalPublicName = hostDirectiveAliasMap[publicName];
    }
    if (mode === 0 /* CaptureNodeBindingMode.Inputs */) {
      addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName, inputFlags);
    } else {
      addPropertyBinding(bindingsResult, directiveIndex, finalPublicName, internalName);
    }
  }
  return bindingsResult;
}
function addPropertyBinding(bindings, directiveIndex, publicName, internalName, inputFlags) {
  let values;
  if (bindings.hasOwnProperty(publicName)) {
    (values = bindings[publicName]).push(directiveIndex, internalName);
  } else {
    values = bindings[publicName] = [directiveIndex, internalName];
  }
  if (inputFlags !== undefined) {
    values.push(inputFlags);
  }
}
/**
 * Initializes data structures required to work with directive inputs and outputs.
 * Initialization is done for all directives matched on a given TNode.
 */
function initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefinitionMap) {
  ngDevMode && assertFirstCreatePass(tView);
  const start = tNode.directiveStart;
  const end = tNode.directiveEnd;
  const tViewData = tView.data;
  const tNodeAttrs = tNode.attrs;
  const inputsFromAttrs = [];
  let inputsStore = null;
  let outputsStore = null;
  for (let directiveIndex = start; directiveIndex < end; directiveIndex++) {
    const directiveDef = tViewData[directiveIndex];
    const aliasData = hostDirectiveDefinitionMap ? hostDirectiveDefinitionMap.get(directiveDef) : null;
    const aliasedInputs = aliasData ? aliasData.inputs : null;
    const aliasedOutputs = aliasData ? aliasData.outputs : null;
    inputsStore = captureNodeBindings(0 /* CaptureNodeBindingMode.Inputs */, directiveDef.inputs, directiveIndex, inputsStore, aliasedInputs);
    outputsStore = captureNodeBindings(1 /* CaptureNodeBindingMode.Outputs */, directiveDef.outputs, directiveIndex, outputsStore, aliasedOutputs);
    // Do not use unbound attributes as inputs to structural directives, since structural
    // directive inputs can only be set using microsyntax (e.g. `<div *dir="exp">`).
    // TODO(FW-1930): microsyntax expressions may also contain unbound/static attributes, which
    // should be set for inline templates.
    const initialInputs = inputsStore !== null && tNodeAttrs !== null && !isInlineTemplate(tNode) ? generateInitialInputs(inputsStore, directiveIndex, tNodeAttrs) : null;
    inputsFromAttrs.push(initialInputs);
  }
  if (inputsStore !== null) {
    if (inputsStore.hasOwnProperty('class')) {
      tNode.flags |= 8 /* TNodeFlags.hasClassInput */;
    }
    if (inputsStore.hasOwnProperty('style')) {
      tNode.flags |= 16 /* TNodeFlags.hasStyleInput */;
    }
  }
  tNode.initialInputs = inputsFromAttrs;
  tNode.inputs = inputsStore;
  tNode.outputs = outputsStore;
}
/**
 * Mapping between attributes names that don't correspond to their element property names.
 *
 * Performance note: this function is written as a series of if checks (instead of, say, a property
 * object lookup) for performance reasons - the series of `if` checks seems to be the fastest way of
 * mapping property names. Do NOT change without benchmarking.
 *
 * Note: this mapping has to be kept in sync with the equally named mapping in the template
 * type-checking machinery of ngtsc.
 */
function mapPropName(name) {
  if (name === 'class') return 'className';
  if (name === 'for') return 'htmlFor';
  if (name === 'formaction') return 'formAction';
  if (name === 'innerHtml') return 'innerHTML';
  if (name === 'readonly') return 'readOnly';
  if (name === 'tabindex') return 'tabIndex';
  return name;
}
function elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, nativeOnly) {
  ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
  const element = getNativeByTNode(tNode, lView);
  let inputData = tNode.inputs;
  let dataValue;
  if (!nativeOnly && inputData != null && (dataValue = inputData[propName])) {
    setInputsForProperty(tView, lView, dataValue, propName, value);
    if (isComponentHost(tNode)) markDirtyIfOnPush(lView, tNode.index);
    if (ngDevMode) {
      setNgReflectProperties(lView, element, tNode.type, dataValue, value);
    }
  } else if (tNode.type & 3 /* TNodeType.AnyRNode */) {
    propName = mapPropName(propName);
    if (ngDevMode) {
      validateAgainstEventProperties(propName);
      if (!isPropertyValid(element, propName, tNode.value, tView.schemas)) {
        handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
      }
      ngDevMode.rendererSetProperty++;
    }
    // It is assumed that the sanitizer is only added when the compiler determines that the
    // property is risky, so sanitization can be done without further checks.
    value = sanitizer != null ? sanitizer(value, tNode.value || '', propName) : value;
    renderer.setProperty(element, propName, value);
  } else if (tNode.type & 12 /* TNodeType.AnyContainer */) {
    // If the node is a container and the property didn't
    // match any of the inputs or schemas we should throw.
    if (ngDevMode && !matchingSchemas(tView.schemas, tNode.value)) {
      handleUnknownPropertyError(propName, tNode.value, tNode.type, lView);
    }
  }
}
/** If node is an OnPush component, marks its LView dirty. */
function markDirtyIfOnPush(lView, viewIndex) {
  ngDevMode && assertLView(lView);
  const childComponentLView = getComponentLViewByIndex(viewIndex, lView);
  if (!(childComponentLView[FLAGS] & 16 /* LViewFlags.CheckAlways */)) {
    childComponentLView[FLAGS] |= 64 /* LViewFlags.Dirty */;
  }
}
function setNgReflectProperty(lView, element, type, attrName, value) {
  const renderer = lView[RENDERER];
  attrName = normalizeDebugBindingName(attrName);
  const debugValue = normalizeDebugBindingValue(value);
  if (type & 3 /* TNodeType.AnyRNode */) {
    if (value == null) {
      renderer.removeAttribute(element, attrName);
    } else {
      renderer.setAttribute(element, attrName, debugValue);
    }
  } else {
    const textContent = escapeCommentText(`bindings=${JSON.stringify({
      [attrName]: debugValue
    }, null, 2)}`);
    renderer.setValue(element, textContent);
  }
}
function setNgReflectProperties(lView, element, type, dataValue, value) {
  if (type & (3 /* TNodeType.AnyRNode */ | 4 /* TNodeType.Container */)) {
    /**
     * dataValue is an array containing runtime input or output names for the directives:
     * i+0: directive instance index
     * i+1: privateName
     *
     * e.g. [0, 'change', 'change-minified']
     * we want to set the reflected property with the privateName: dataValue[i+1]
     */
    for (let i = 0; i < dataValue.length; i += 3) {
      setNgReflectProperty(lView, element, type, dataValue[i + 1], value);
    }
  }
}
/**
 * Resolve the matched directives on a node.
 */
function resolveDirectives(tView, lView, tNode, localRefs) {
  // Please make sure to have explicit type for `exportsMap`. Inferred type triggers bug in
  // tsickle.
  ngDevMode && assertFirstCreatePass(tView);
  if (getBindingsEnabled()) {
    const exportsMap = localRefs === null ? null : {
      '': -1
    };
    const matchResult = findDirectiveDefMatches(tView, tNode);
    let directiveDefs;
    let hostDirectiveDefs;
    if (matchResult === null) {
      directiveDefs = hostDirectiveDefs = null;
    } else {
      [directiveDefs, hostDirectiveDefs] = matchResult;
    }
    if (directiveDefs !== null) {
      initializeDirectives(tView, lView, tNode, directiveDefs, exportsMap, hostDirectiveDefs);
    }
    if (exportsMap) cacheMatchingLocalNames(tNode, localRefs, exportsMap);
  }
  // Merge the template attrs last so that they have the highest priority.
  tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, tNode.attrs);
}
/** Initializes the data structures necessary for a list of directives to be instantiated. */
function initializeDirectives(tView, lView, tNode, directives, exportsMap, hostDirectiveDefs) {
  ngDevMode && assertFirstCreatePass(tView);
  // Publishes the directive types to DI so they can be injected. Needs to
  // happen in a separate pass before the TNode flags have been initialized.
  for (let i = 0; i < directives.length; i++) {
    diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, directives[i].type);
  }
  initTNodeFlags(tNode, tView.data.length, directives.length);
  // When the same token is provided by several directives on the same node, some rules apply in
  // the viewEngine:
  // - viewProviders have priority over providers
  // - the last directive in NgModule.declarations has priority over the previous one
  // So to match these rules, the order in which providers are added in the arrays is very
  // important.
  for (let i = 0; i < directives.length; i++) {
    const def = directives[i];
    if (def.providersResolver) def.providersResolver(def);
  }
  let preOrderHooksFound = false;
  let preOrderCheckHooksFound = false;
  let directiveIdx = allocExpando(tView, lView, directives.length, null);
  ngDevMode && assertSame(directiveIdx, tNode.directiveStart, 'TNode.directiveStart should point to just allocated space');
  for (let i = 0; i < directives.length; i++) {
    const def = directives[i];
    // Merge the attrs in the order of matches. This assumes that the first directive is the
    // component itself, so that the component has the least priority.
    tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
    configureViewWithDirective(tView, tNode, lView, directiveIdx, def);
    saveNameToExportMap(directiveIdx, def, exportsMap);
    if (def.contentQueries !== null) tNode.flags |= 4 /* TNodeFlags.hasContentQuery */;
    if (def.hostBindings !== null || def.hostAttrs !== null || def.hostVars !== 0) tNode.flags |= 64 /* TNodeFlags.hasHostBindings */;
    const lifeCycleHooks = def.type.prototype;
    // Only push a node index into the preOrderHooks array if this is the first
    // pre-order hook found on this node.
    if (!preOrderHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngOnInit || lifeCycleHooks.ngDoCheck)) {
      // We will push the actual hook function into this array later during dir instantiation.
      // We cannot do it now because we must ensure hooks are registered in the same
      // order that directives are created (i.e. injection order).
      (tView.preOrderHooks ??= []).push(tNode.index);
      preOrderHooksFound = true;
    }
    if (!preOrderCheckHooksFound && (lifeCycleHooks.ngOnChanges || lifeCycleHooks.ngDoCheck)) {
      (tView.preOrderCheckHooks ??= []).push(tNode.index);
      preOrderCheckHooksFound = true;
    }
    directiveIdx++;
  }
  initializeInputAndOutputAliases(tView, tNode, hostDirectiveDefs);
}
/**
 * Add `hostBindings` to the `TView.hostBindingOpCodes`.
 *
 * @param tView `TView` to which the `hostBindings` should be added.
 * @param tNode `TNode` the element which contains the directive
 * @param directiveIdx Directive index in view.
 * @param directiveVarsIdx Where will the directive's vars be stored
 * @param def `ComponentDef`/`DirectiveDef`, which contains the `hostVars`/`hostBindings` to add.
 */
function registerHostBindingOpCodes(tView, tNode, directiveIdx, directiveVarsIdx, def) {
  ngDevMode && assertFirstCreatePass(tView);
  const hostBindings = def.hostBindings;
  if (hostBindings) {
    let hostBindingOpCodes = tView.hostBindingOpCodes;
    if (hostBindingOpCodes === null) {
      hostBindingOpCodes = tView.hostBindingOpCodes = [];
    }
    const elementIndx = ~tNode.index;
    if (lastSelectedElementIdx(hostBindingOpCodes) != elementIndx) {
      // Conditionally add select element so that we are more efficient in execution.
      // NOTE: this is strictly not necessary and it trades code size for runtime perf.
      // (We could just always add it.)
      hostBindingOpCodes.push(elementIndx);
    }
    hostBindingOpCodes.push(directiveIdx, directiveVarsIdx, hostBindings);
  }
}
/**
 * Returns the last selected element index in the `HostBindingOpCodes`
 *
 * For perf reasons we don't need to update the selected element index in `HostBindingOpCodes` only
 * if it changes. This method returns the last index (or '0' if not found.)
 *
 * Selected element index are only the ones which are negative.
 */
function lastSelectedElementIdx(hostBindingOpCodes) {
  let i = hostBindingOpCodes.length;
  while (i > 0) {
    const value = hostBindingOpCodes[--i];
    if (typeof value === 'number' && value < 0) {
      return value;
    }
  }
  return 0;
}
/**
 * Instantiate all the directives that were previously resolved on the current node.
 */
function instantiateAllDirectives(tView, lView, tNode, native) {
  const start = tNode.directiveStart;
  const end = tNode.directiveEnd;
  // The component view needs to be created before creating the node injector
  // since it is used to inject some special symbols like `ChangeDetectorRef`.
  if (isComponentHost(tNode)) {
    ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
    addComponentLogic(lView, tNode, tView.data[start + tNode.componentOffset]);
  }
  if (!tView.firstCreatePass) {
    getOrCreateNodeInjectorForNode(tNode, lView);
  }
  attachPatchData(native, lView);
  const initialInputs = tNode.initialInputs;
  for (let i = start; i < end; i++) {
    const def = tView.data[i];
    const directive = getNodeInjectable(lView, tView, i, tNode);
    attachPatchData(directive, lView);
    if (initialInputs !== null) {
      setInputsFromAttrs(lView, i - start, directive, def, tNode, initialInputs);
    }
    if (isComponentDef(def)) {
      const componentView = getComponentLViewByIndex(tNode.index, lView);
      componentView[CONTEXT] = getNodeInjectable(lView, tView, i, tNode);
    }
  }
}
function invokeDirectivesHostBindings(tView, lView, tNode) {
  const start = tNode.directiveStart;
  const end = tNode.directiveEnd;
  const elementIndex = tNode.index;
  const currentDirectiveIndex = getCurrentDirectiveIndex();
  try {
    setSelectedIndex(elementIndex);
    for (let dirIndex = start; dirIndex < end; dirIndex++) {
      const def = tView.data[dirIndex];
      const directive = lView[dirIndex];
      setCurrentDirectiveIndex(dirIndex);
      if (def.hostBindings !== null || def.hostVars !== 0 || def.hostAttrs !== null) {
        invokeHostBindingsInCreationMode(def, directive);
      }
    }
  } finally {
    setSelectedIndex(-1);
    setCurrentDirectiveIndex(currentDirectiveIndex);
  }
}
/**
 * Invoke the host bindings in creation mode.
 *
 * @param def `DirectiveDef` which may contain the `hostBindings` function.
 * @param directive Instance of directive.
 */
function invokeHostBindingsInCreationMode(def, directive) {
  if (def.hostBindings !== null) {
    def.hostBindings(1 /* RenderFlags.Create */, directive);
  }
}
/**
 * Matches the current node against all available selectors.
 * If a component is matched (at most one), it is returned in first position in the array.
 */
function findDirectiveDefMatches(tView, tNode) {
  ngDevMode && assertFirstCreatePass(tView);
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
  const registry = tView.directiveRegistry;
  let matches = null;
  let hostDirectiveDefs = null;
  if (registry) {
    for (let i = 0; i < registry.length; i++) {
      const def = registry[i];
      if (isNodeMatchingSelectorList(tNode, def.selectors, /* isProjectionMode */false)) {
        matches || (matches = []);
        if (isComponentDef(def)) {
          if (ngDevMode) {
            assertTNodeType(tNode, 2 /* TNodeType.Element */, `"${tNode.value}" tags cannot be used as component hosts. ` + `Please use a different tag to activate the ${stringify(def.type)} component.`);
            if (isComponentHost(tNode)) {
              throwMultipleComponentError(tNode, matches.find(isComponentDef).type, def.type);
            }
          }
          // Components are inserted at the front of the matches array so that their lifecycle
          // hooks run before any directive lifecycle hooks. This appears to be for ViewEngine
          // compatibility. This logic doesn't make sense with host directives, because it
          // would allow the host directives to undo any overrides the host may have made.
          // To handle this case, the host directives of components are inserted at the beginning
          // of the array, followed by the component. As such, the insertion order is as follows:
          // 1. Host directives belonging to the selector-matched component.
          // 2. Selector-matched component.
          // 3. Host directives belonging to selector-matched directives.
          // 4. Selector-matched directives.
          if (def.findHostDirectiveDefs !== null) {
            const hostDirectiveMatches = [];
            hostDirectiveDefs = hostDirectiveDefs || new Map();
            def.findHostDirectiveDefs(def, hostDirectiveMatches, hostDirectiveDefs);
            // Add all host directives declared on this component, followed by the component itself.
            // Host directives should execute first so the host has a chance to override changes
            // to the DOM made by them.
            matches.unshift(...hostDirectiveMatches, def);
            // Component is offset starting from the beginning of the host directives array.
            const componentOffset = hostDirectiveMatches.length;
            markAsComponentHost(tView, tNode, componentOffset);
          } else {
            // No host directives on this component, just add the
            // component def to the beginning of the matches.
            matches.unshift(def);
            markAsComponentHost(tView, tNode, 0);
          }
        } else {
          // Append any host directives to the matches first.
          hostDirectiveDefs = hostDirectiveDefs || new Map();
          def.findHostDirectiveDefs?.(def, matches, hostDirectiveDefs);
          matches.push(def);
        }
      }
    }
  }
  ngDevMode && matches !== null && assertNoDuplicateDirectives(matches);
  return matches === null ? null : [matches, hostDirectiveDefs];
}
/**
 * Marks a given TNode as a component's host. This consists of:
 * - setting the component offset on the TNode.
 * - storing index of component's host element so it will be queued for view refresh during CD.
 */
function markAsComponentHost(tView, hostTNode, componentOffset) {
  ngDevMode && assertFirstCreatePass(tView);
  ngDevMode && assertGreaterThan(componentOffset, -1, 'componentOffset must be great than -1');
  hostTNode.componentOffset = componentOffset;
  (tView.components ??= []).push(hostTNode.index);
}
/** Caches local names and their matching directive indices for query and template lookups. */
function cacheMatchingLocalNames(tNode, localRefs, exportsMap) {
  if (localRefs) {
    const localNames = tNode.localNames = [];
    // Local names must be stored in tNode in the same order that localRefs are defined
    // in the template to ensure the data is loaded in the same slots as their refs
    // in the template (for template queries).
    for (let i = 0; i < localRefs.length; i += 2) {
      const index = exportsMap[localRefs[i + 1]];
      if (index == null) throw new RuntimeError(-301 /* RuntimeErrorCode.EXPORT_NOT_FOUND */, ngDevMode && `Export of name '${localRefs[i + 1]}' not found!`);
      localNames.push(localRefs[i], index);
    }
  }
}
/**
 * Builds up an export map as directives are created, so local refs can be quickly mapped
 * to their directive instances.
 */
function saveNameToExportMap(directiveIdx, def, exportsMap) {
  if (exportsMap) {
    if (def.exportAs) {
      for (let i = 0; i < def.exportAs.length; i++) {
        exportsMap[def.exportAs[i]] = directiveIdx;
      }
    }
    if (isComponentDef(def)) exportsMap[''] = directiveIdx;
  }
}
/**
 * Initializes the flags on the current node, setting all indices to the initial index,
 * the directive count to 0, and adding the isComponent flag.
 * @param index the initial index
 */
function initTNodeFlags(tNode, index, numberOfDirectives) {
  ngDevMode && assertNotEqual(numberOfDirectives, tNode.directiveEnd - tNode.directiveStart, 'Reached the max number of directives');
  tNode.flags |= 1 /* TNodeFlags.isDirectiveHost */;
  // When the first directive is created on a node, save the index
  tNode.directiveStart = index;
  tNode.directiveEnd = index + numberOfDirectives;
  tNode.providerIndexes = index;
}
/**
 * Setup directive for instantiation.
 *
 * We need to create a `NodeInjectorFactory` which is then inserted in both the `Blueprint` as well
 * as `LView`. `TView` gets the `DirectiveDef`.
 *
 * @param tView `TView`
 * @param tNode `TNode`
 * @param lView `LView`
 * @param directiveIndex Index where the directive will be stored in the Expando.
 * @param def `DirectiveDef`
 */
function configureViewWithDirective(tView, tNode, lView, directiveIndex, def) {
  ngDevMode && assertGreaterThanOrEqual(directiveIndex, HEADER_OFFSET, 'Must be in Expando section');
  tView.data[directiveIndex] = def;
  const directiveFactory = def.factory || (def.factory = getFactoryDef(def.type, true));
  // Even though `directiveFactory` will already be using `ɵɵdirectiveInject` in its generated code,
  // we also want to support `inject()` directly from the directive constructor context so we set
  // `ɵɵdirectiveInject` as the inject implementation here too.
  const nodeInjectorFactory = new NodeInjectorFactory(directiveFactory, isComponentDef(def), ɵɵdirectiveInject);
  tView.blueprint[directiveIndex] = nodeInjectorFactory;
  lView[directiveIndex] = nodeInjectorFactory;
  registerHostBindingOpCodes(tView, tNode, directiveIndex, allocExpando(tView, lView, def.hostVars, NO_CHANGE), def);
}
function addComponentLogic(lView, hostTNode, def) {
  const native = getNativeByTNode(hostTNode, lView);
  const tView = getOrCreateComponentTView(def);
  // Only component views should be added to the view tree directly. Embedded views are
  // accessed through their containers because they may be removed / re-added later.
  const rendererFactory = lView[ENVIRONMENT].rendererFactory;
  let lViewFlags = 16 /* LViewFlags.CheckAlways */;
  if (def.signals) {
    lViewFlags = 4096 /* LViewFlags.SignalView */;
  } else if (def.onPush) {
    lViewFlags = 64 /* LViewFlags.Dirty */;
  }
  const componentView = addToViewTree(lView, createLView(lView, tView, null, lViewFlags, native, hostTNode, null, rendererFactory.createRenderer(native, def), null, null, null));
  // Component view will always be created before any injected LContainers,
  // so this is a regular element, wrap it with the component view
  lView[hostTNode.index] = componentView;
}
function elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace) {
  if (ngDevMode) {
    assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
    validateAgainstEventAttributes(name);
    assertTNodeType(tNode, 2 /* TNodeType.Element */, `Attempted to set attribute \`${name}\` on a container node. ` + `Host bindings are not valid on ng-container or ng-template.`);
  }
  const element = getNativeByTNode(tNode, lView);
  setElementAttribute(lView[RENDERER], element, namespace, tNode.value, name, value, sanitizer);
}
function setElementAttribute(renderer, element, namespace, tagName, name, value, sanitizer) {
  if (value == null) {
    ngDevMode && ngDevMode.rendererRemoveAttribute++;
    renderer.removeAttribute(element, name, namespace);
  } else {
    ngDevMode && ngDevMode.rendererSetAttribute++;
    const strValue = sanitizer == null ? renderStringify(value) : sanitizer(value, tagName || '', name);
    renderer.setAttribute(element, name, strValue, namespace);
  }
}
/**
 * Sets initial input properties on directive instances from attribute data
 *
 * @param lView Current LView that is being processed.
 * @param directiveIndex Index of the directive in directives array
 * @param instance Instance of the directive on which to set the initial inputs
 * @param def The directive def that contains the list of inputs
 * @param tNode The static data for this node
 */
function setInputsFromAttrs(lView, directiveIndex, instance, def, tNode, initialInputData) {
  const initialInputs = initialInputData[directiveIndex];
  if (initialInputs !== null) {
    for (let i = 0; i < initialInputs.length;) {
      const publicName = initialInputs[i++];
      const privateName = initialInputs[i++];
      const flags = initialInputs[i++];
      const value = initialInputs[i++];
      writeToDirectiveInput(def, instance, publicName, privateName, flags, value);
      if (ngDevMode) {
        const nativeElement = getNativeByTNode(tNode, lView);
        setNgReflectProperty(lView, nativeElement, tNode.type, privateName, value);
      }
    }
  }
}
/**
 * Generates initialInputData for a node and stores it in the template's static storage
 * so subsequent template invocations don't have to recalculate it.
 *
 * initialInputData is an array containing values that need to be set as input properties
 * for directives on this node, but only once on creation. We need this array to support
 * the case where you set an @Input property of a directive using attribute-like syntax.
 * e.g. if you have a `name` @Input, you can set it once like this:
 *
 * <my-component name="Bess"></my-component>
 *
 * @param inputs Input alias map that was generated from the directive def inputs.
 * @param directiveIndex Index of the directive that is currently being processed.
 * @param attrs Static attrs on this node.
 */
function generateInitialInputs(inputs, directiveIndex, attrs) {
  let inputsToStore = null;
  let i = 0;
  while (i < attrs.length) {
    const attrName = attrs[i];
    if (attrName === 0 /* AttributeMarker.NamespaceURI */) {
      // We do not allow inputs on namespaced attributes.
      i += 4;
      continue;
    } else if (attrName === 5 /* AttributeMarker.ProjectAs */) {
      // Skip over the `ngProjectAs` value.
      i += 2;
      continue;
    }
    // If we hit any other attribute markers, we're done anyway. None of those are valid inputs.
    if (typeof attrName === 'number') break;
    if (inputs.hasOwnProperty(attrName)) {
      if (inputsToStore === null) inputsToStore = [];
      // Find the input's public name from the input store. Note that we can be found easier
      // through the directive def, but we want to do it using the inputs store so that it can
      // account for host directive aliases.
      const inputConfig = inputs[attrName];
      for (let j = 0; j < inputConfig.length; j += 3) {
        if (inputConfig[j] === directiveIndex) {
          inputsToStore.push(attrName, inputConfig[j + 1], inputConfig[j + 2], attrs[i + 1]);
          // A directive can't have multiple inputs with the same name so we can break here.
          break;
        }
      }
    }
    i += 2;
  }
  return inputsToStore;
}
//////////////////////////
//// ViewContainer & View
//////////////////////////
/**
 * Creates a LContainer, either from a container instruction, or for a ViewContainerRef.
 *
 * @param hostNative The host element for the LContainer
 * @param hostTNode The host TNode for the LContainer
 * @param currentView The parent view of the LContainer
 * @param native The native comment element
 * @param isForViewContainerRef Optional a flag indicating the ViewContainerRef case
 * @returns LContainer
 */
function createLContainer(hostNative, currentView, native, tNode) {
  ngDevMode && assertLView(currentView);
  const lContainer = [hostNative,
  // host native
  true,
  // Boolean `true` in this position signifies that this is an `LContainer`
  0,
  // flags
  currentView,
  // parent
  null,
  // next
  tNode,
  // t_host
  null,
  // dehydrated views
  native,
  // native,
  null,
  // view refs
  null // moved views
  ];
  ngDevMode && assertEqual(lContainer.length, CONTAINER_HEADER_OFFSET, 'Should allocate correct number of slots for LContainer header.');
  return lContainer;
}
/** Refreshes all content queries declared by directives in a given view */
function refreshContentQueries(tView, lView) {
  const contentQueries = tView.contentQueries;
  if (contentQueries !== null) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      for (let i = 0; i < contentQueries.length; i += 2) {
        const queryStartIdx = contentQueries[i];
        const directiveDefIdx = contentQueries[i + 1];
        if (directiveDefIdx !== -1) {
          const directiveDef = tView.data[directiveDefIdx];
          ngDevMode && assertDefined(directiveDef, 'DirectiveDef not found.');
          ngDevMode && assertDefined(directiveDef.contentQueries, 'contentQueries function should be defined');
          setCurrentQueryIndex(queryStartIdx);
          directiveDef.contentQueries(2 /* RenderFlags.Update */, lView[directiveDefIdx], directiveDefIdx);
        }
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
}
/**
 * Adds LView or LContainer to the end of the current view tree.
 *
 * This structure will be used to traverse through nested views to remove listeners
 * and call onDestroy callbacks.
 *
 * @param lView The view where LView or LContainer should be added
 * @param adjustedHostIndex Index of the view's host node in LView[], adjusted for header
 * @param lViewOrLContainer The LView or LContainer to add to the view tree
 * @returns The state passed in
 */
function addToViewTree(lView, lViewOrLContainer) {
  // TODO(benlesh/misko): This implementation is incorrect, because it always adds the LContainer
  // to the end of the queue, which means if the developer retrieves the LContainers from RNodes out
  // of order, the change detection will run out of order, as the act of retrieving the the
  // LContainer from the RNode is what adds it to the queue.
  if (lView[CHILD_HEAD]) {
    lView[CHILD_TAIL][NEXT] = lViewOrLContainer;
  } else {
    lView[CHILD_HEAD] = lViewOrLContainer;
  }
  lView[CHILD_TAIL] = lViewOrLContainer;
  return lViewOrLContainer;
}
///////////////////////////////
//// Change detection
///////////////////////////////
function executeViewQueryFn(flags, viewQueryFn, component) {
  ngDevMode && assertDefined(viewQueryFn, 'View queries function to execute must be defined.');
  setCurrentQueryIndex(0);
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    viewQueryFn(flags, component);
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}
///////////////////////////////
//// Bindings & interpolations
///////////////////////////////
/**
 * Stores meta-data for a property binding to be used by TestBed's `DebugElement.properties`.
 *
 * In order to support TestBed's `DebugElement.properties` we need to save, for each binding:
 * - a bound property name;
 * - a static parts of interpolated strings;
 *
 * A given property metadata is saved at the binding's index in the `TView.data` (in other words, a
 * property binding metadata will be stored in `TView.data` at the same index as a bound value in
 * `LView`). Metadata are represented as `INTERPOLATION_DELIMITER`-delimited string with the
 * following format:
 * - `propertyName` for bound properties;
 * - `propertyName�prefix�interpolation_static_part1�..interpolation_static_partN�suffix` for
 * interpolated properties.
 *
 * @param tData `TData` where meta-data will be saved;
 * @param tNode `TNode` that is a target of the binding;
 * @param propertyName bound property name;
 * @param bindingIndex binding index in `LView`
 * @param interpolationParts static interpolation parts (for property interpolations)
 */
function storePropertyBindingMetadata(tData, tNode, propertyName, bindingIndex, ...interpolationParts) {
  // Binding meta-data are stored only the first time a given property instruction is processed.
  // Since we don't have a concept of the "first update pass" we need to check for presence of the
  // binding meta-data to decide if one should be stored (or if was stored already).
  if (tData[bindingIndex] === null) {
    if (tNode.inputs == null || !tNode.inputs[propertyName]) {
      const propBindingIdxs = tNode.propertyBindings || (tNode.propertyBindings = []);
      propBindingIdxs.push(bindingIndex);
      let bindingMetadata = propertyName;
      if (interpolationParts.length > 0) {
        bindingMetadata += INTERPOLATION_DELIMITER + interpolationParts.join(INTERPOLATION_DELIMITER);
      }
      tData[bindingIndex] = bindingMetadata;
    }
  }
}
function getOrCreateLViewCleanup(view) {
  // top level variables should not be exported for performance reasons (PERF_NOTES.md)
  return view[CLEANUP] || (view[CLEANUP] = []);
}
function getOrCreateTViewCleanup(tView) {
  return tView.cleanup || (tView.cleanup = []);
}
/**
 * There are cases where the sub component's renderer needs to be included
 * instead of the current renderer (see the componentSyntheticHost* instructions).
 */
function loadComponentRenderer(currentDef, tNode, lView) {
  // TODO(FW-2043): the `currentDef` is null when host bindings are invoked while creating root
  // component (see packages/core/src/render3/component.ts). This is not consistent with the process
  // of creating inner components, when current directive index is available in the state. In order
  // to avoid relying on current def being `null` (thus special-casing root component creation), the
  // process of creating root component should be unified with the process of creating inner
  // components.
  if (currentDef === null || isComponentDef(currentDef)) {
    lView = unwrapLView(lView[tNode.index]);
  }
  return lView[RENDERER];
}
/** Handles an error thrown in an LView. */
function handleError(lView, error) {
  const injector = lView[INJECTOR];
  const errorHandler = injector ? injector.get(ErrorHandler, null) : null;
  errorHandler && errorHandler.handleError(error);
}
/**
 * Set the inputs of directives at the current node to corresponding value.
 *
 * @param tView The current TView
 * @param lView the `LView` which contains the directives.
 * @param inputs mapping between the public "input" name and privately-known,
 *        possibly minified, property names to write to.
 * @param value Value to set.
 */
function setInputsForProperty(tView, lView, inputs, publicName, value) {
  for (let i = 0; i < inputs.length;) {
    const index = inputs[i++];
    const privateName = inputs[i++];
    const flags = inputs[i++];
    const instance = lView[index];
    ngDevMode && assertIndexInRange(lView, index);
    const def = tView.data[index];
    writeToDirectiveInput(def, instance, publicName, privateName, flags, value);
  }
}
/**
 * Updates a text binding at a given index in a given LView.
 */
function textBindingInternal(lView, index, value) {
  ngDevMode && assertString(value, 'Value should be a string');
  ngDevMode && assertNotSame(value, NO_CHANGE, 'value should not be NO_CHANGE');
  ngDevMode && assertIndexInRange(lView, index);
  const element = getNativeByIndex(index, lView);
  ngDevMode && assertDefined(element, 'native element should exist');
  updateTextNode(lView[RENDERER], element, value);
}
function renderComponent(hostLView, componentHostIdx) {
  ngDevMode && assertEqual(isCreationMode(hostLView), true, 'Should be run in creation mode');
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
  const componentTView = componentView[TVIEW];
  syncViewWithBlueprint(componentTView, componentView);
  const hostRNode = componentView[HOST];
  // Populate an LView with hydration info retrieved from the DOM via TransferState.
  if (hostRNode !== null && componentView[HYDRATION] === null) {
    componentView[HYDRATION] = retrieveHydrationInfo(hostRNode, componentView[INJECTOR]);
  }
  renderView(componentTView, componentView, componentView[CONTEXT]);
}
/**
 * Syncs an LView instance with its blueprint if they have gotten out of sync.
 *
 * Typically, blueprints and their view instances should always be in sync, so the loop here
 * will be skipped. However, consider this case of two components side-by-side:
 *
 * App template:
 * ```
 * <comp></comp>
 * <comp></comp>
 * ```
 *
 * The following will happen:
 * 1. App template begins processing.
 * 2. First <comp> is matched as a component and its LView is created.
 * 3. Second <comp> is matched as a component and its LView is created.
 * 4. App template completes processing, so it's time to check child templates.
 * 5. First <comp> template is checked. It has a directive, so its def is pushed to blueprint.
 * 6. Second <comp> template is checked. Its blueprint has been updated by the first
 * <comp> template, but its LView was created before this update, so it is out of sync.
 *
 * Note that embedded views inside ngFor loops will never be out of sync because these views
 * are processed as soon as they are created.
 *
 * @param tView The `TView` that contains the blueprint for syncing
 * @param lView The view to sync
 */
function syncViewWithBlueprint(tView, lView) {
  for (let i = lView.length; i < tView.blueprint.length; i++) {
    lView.push(tView.blueprint[i]);
  }
}
/**
 * Processes a view in the creation mode. This includes a number of steps in a specific order:
 * - creating view query functions (if any);
 * - executing a template function in the creation mode;
 * - updating static queries (if any);
 * - creating child components defined in a given view.
 */
function renderView(tView, lView, context) {
  ngDevMode && assertEqual(isCreationMode(lView), true, 'Should be run in creation mode');
  ngDevMode && assertNotReactive(renderView.name);
  enterView(lView);
  try {
    const viewQuery = tView.viewQuery;
    if (viewQuery !== null) {
      executeViewQueryFn(1 /* RenderFlags.Create */, viewQuery, context);
    }
    // Execute a template associated with this view, if it exists. A template function might not be
    // defined for the root component views.
    const templateFn = tView.template;
    if (templateFn !== null) {
      executeTemplate(tView, lView, templateFn, 1 /* RenderFlags.Create */, context);
    }
    // This needs to be set before children are processed to support recursive components.
    // This must be set to false immediately after the first creation run because in an
    // ngFor loop, all the views will be created together before update mode runs and turns
    // off firstCreatePass. If we don't set it here, instances will perform directive
    // matching, etc again and again.
    if (tView.firstCreatePass) {
      tView.firstCreatePass = false;
    }
    // Mark all queries active in this view as dirty. This is necessary for signal-based queries to
    // have a clear marking point where we can read query results atomically (for a given view).
    lView[QUERIES]?.finishViewCreation(tView);
    // We resolve content queries specifically marked as `static` in creation mode. Dynamic
    // content queries are resolved during change detection (i.e. update mode), after embedded
    // views are refreshed (see block above).
    if (tView.staticContentQueries) {
      refreshContentQueries(tView, lView);
    }
    // We must materialize query results before child components are processed
    // in case a child component has projected a container. The LContainer needs
    // to exist so the embedded views are properly attached by the container.
    if (tView.staticViewQueries) {
      executeViewQueryFn(2 /* RenderFlags.Update */, tView.viewQuery, context);
    }
    // Render child component views.
    const components = tView.components;
    if (components !== null) {
      renderChildComponents(lView, components);
    }
  } catch (error) {
    // If we didn't manage to get past the first template pass due to
    // an error, mark the view as corrupted so we can try to recover.
    if (tView.firstCreatePass) {
      tView.incompleteFirstPass = true;
      tView.firstCreatePass = false;
    }
    throw error;
  } finally {
    lView[FLAGS] &= ~4 /* LViewFlags.CreationMode */;
    leaveView();
  }
}
/** Renders child components in the current view (creation mode). */
function renderChildComponents(hostLView, components) {
  for (let i = 0; i < components.length; i++) {
    renderComponent(hostLView, components[i]);
  }
}
function createAndRenderEmbeddedLView(declarationLView, templateTNode, context, options) {
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    const embeddedTView = templateTNode.tView;
    ngDevMode && assertDefined(embeddedTView, 'TView must be defined for a template node.');
    ngDevMode && assertTNodeForLView(templateTNode, declarationLView);
    // Embedded views follow the change detection strategy of the view they're declared in.
    const isSignalView = declarationLView[FLAGS] & 4096 /* LViewFlags.SignalView */;
    const viewFlags = isSignalView ? 4096 /* LViewFlags.SignalView */ : 16 /* LViewFlags.CheckAlways */;
    const embeddedLView = createLView(declarationLView, embeddedTView, context, viewFlags, null, templateTNode, null, null, options?.injector ?? null, options?.embeddedViewInjector ?? null, options?.dehydratedView ?? null);
    const declarationLContainer = declarationLView[templateTNode.index];
    ngDevMode && assertLContainer(declarationLContainer);
    embeddedLView[DECLARATION_LCONTAINER] = declarationLContainer;
    const declarationViewLQueries = declarationLView[QUERIES];
    if (declarationViewLQueries !== null) {
      embeddedLView[QUERIES] = declarationViewLQueries.createEmbeddedView(embeddedTView);
    }
    // execute creation mode of a view
    renderView(embeddedTView, embeddedLView, context);
    return embeddedLView;
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}
function getLViewFromLContainer(lContainer, index) {
  const adjustedIndex = CONTAINER_HEADER_OFFSET + index;
  // avoid reading past the array boundaries
  if (adjustedIndex < lContainer.length) {
    const lView = lContainer[adjustedIndex];
    ngDevMode && assertLView(lView);
    return lView;
  }
  return undefined;
}
/**
 * Returns whether an elements that belong to a view should be
 * inserted into the DOM. For client-only cases, DOM elements are
 * always inserted. For hydration cases, we check whether serialized
 * info is available for a view and the view is not in a "skip hydration"
 * block (in which case view contents was re-created, thus needing insertion).
 */
function shouldAddViewToDom(tNode, dehydratedView) {
  return !dehydratedView || dehydratedView.firstChild === null || hasInSkipHydrationBlockFlag(tNode);
}
function addLViewToLContainer(lContainer, lView, index, addToDOM = true) {
  const tView = lView[TVIEW];
  // Insert into the view tree so the new view can be change-detected
  insertView(tView, lView, lContainer, index);
  // Insert elements that belong to this view into the DOM tree
  if (addToDOM) {
    const beforeNode = getBeforeNodeForView(index, lContainer);
    const renderer = lView[RENDERER];
    const parentRNode = nativeParentNode(renderer, lContainer[NATIVE]);
    if (parentRNode !== null) {
      addViewToDOM(tView, lContainer[T_HOST], renderer, lView, parentRNode, beforeNode);
    }
  }
  // When in hydration mode, reset the pointer to the first child in
  // the dehydrated view. This indicates that the view was hydrated and
  // further attaching/detaching should work with this view as normal.
  const hydrationInfo = lView[HYDRATION];
  if (hydrationInfo !== null && hydrationInfo.firstChild !== null) {
    hydrationInfo.firstChild = null;
  }
}
function removeLViewFromLContainer(lContainer, index) {
  const lView = detachView(lContainer, index);
  if (lView !== undefined) {
    destroyLView(lView[TVIEW], lView);
  }
  return lView;
}
function collectNativeNodes(tView, lView, tNode, result, isProjection = false) {
  while (tNode !== null) {
    ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 16 /* TNodeType.Projection */ | 32 /* TNodeType.Icu */);
    const lNode = lView[tNode.index];
    if (lNode !== null) {
      result.push(unwrapRNode(lNode));
    }
    // A given lNode can represent either a native node or a LContainer (when it is a host of a
    // ViewContainerRef). When we find a LContainer we need to descend into it to collect root nodes
    // from the views in this container.
    if (isLContainer(lNode)) {
      collectNativeNodesInLContainer(lNode, result);
    }
    const tNodeType = tNode.type;
    if (tNodeType & 8 /* TNodeType.ElementContainer */) {
      collectNativeNodes(tView, lView, tNode.child, result);
    } else if (tNodeType & 32 /* TNodeType.Icu */) {
      const nextRNode = icuContainerIterate(tNode, lView);
      let rNode;
      while (rNode = nextRNode()) {
        result.push(rNode);
      }
    } else if (tNodeType & 16 /* TNodeType.Projection */) {
      const nodesInSlot = getProjectionNodes(lView, tNode);
      if (Array.isArray(nodesInSlot)) {
        result.push(...nodesInSlot);
      } else {
        const parentView = getLViewParent(lView[DECLARATION_COMPONENT_VIEW]);
        ngDevMode && assertParentView(parentView);
        collectNativeNodes(parentView[TVIEW], parentView, nodesInSlot, result, true);
      }
    }
    tNode = isProjection ? tNode.projectionNext : tNode.next;
  }
  return result;
}
/**
 * Collects all root nodes in all views in a given LContainer.
 */
function collectNativeNodesInLContainer(lContainer, result) {
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
    const lViewInAContainer = lContainer[i];
    const lViewFirstChildTNode = lViewInAContainer[TVIEW].firstChild;
    if (lViewFirstChildTNode !== null) {
      collectNativeNodes(lViewInAContainer[TVIEW], lViewInAContainer, lViewFirstChildTNode, result);
    }
  }
  // When an LContainer is created, the anchor (comment) node is:
  // - (1) either reused in case of an ElementContainer (<ng-container>)
  // - (2) or a new comment node is created
  // In the first case, the anchor comment node would be added to the final
  // list by the code in the `collectNativeNodes` function
  // (see the `result.push(unwrapRNode(lNode))` line), but the second
  // case requires extra handling: the anchor node needs to be added to the
  // final list manually. See additional information in the `createAnchorNode`
  // function in the `view_container_ref.ts`.
  //
  // In the first case, the same reference would be stored in the `NATIVE`
  // and `HOST` slots in an LContainer. Otherwise, this is the second case and
  // we should add an element to the final list.
  if (lContainer[NATIVE] !== lContainer[HOST]) {
    result.push(lContainer[NATIVE]);
  }
}
let freeConsumers = [];
/**
 * Create a new template consumer pointing at the specified LView.
 * Sometimes, a previously created consumer may be reused, in order to save on allocations. In that
 * case, the LView will be updated.
 */
function getOrBorrowReactiveLViewConsumer(lView) {
  return lView[REACTIVE_TEMPLATE_CONSUMER] ?? borrowReactiveLViewConsumer(lView);
}
function borrowReactiveLViewConsumer(lView) {
  const consumer = freeConsumers.pop() ?? Object.create(REACTIVE_LVIEW_CONSUMER_NODE);
  consumer.lView = lView;
  return consumer;
}
function maybeReturnReactiveLViewConsumer(consumer) {
  if (consumer.lView[REACTIVE_TEMPLATE_CONSUMER] === consumer) {
    // The consumer got committed.
    return;
  }
  consumer.lView = null;
  freeConsumers.push(consumer);
}
const REACTIVE_LVIEW_CONSUMER_NODE = {
  ..._angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.REACTIVE_NODE,
  consumerIsAlwaysLive: true,
  consumerMarkedDirty: node => {
    markAncestorsForTraversal(node.lView);
  },
  consumerOnSignalRead() {
    this.lView[REACTIVE_TEMPLATE_CONSUMER] = this;
  }
};

/**
 * The maximum number of times the change detection traversal will rerun before throwing an error.
 */
const MAXIMUM_REFRESH_RERUNS = 100;
function detectChangesInternal(lView, notifyErrorHandler = true, mode = 0 /* ChangeDetectionMode.Global */) {
  const environment = lView[ENVIRONMENT];
  const rendererFactory = environment.rendererFactory;
  // Check no changes mode is a dev only mode used to verify that bindings have not changed
  // since they were assigned. We do not want to invoke renderer factory functions in that mode
  // to avoid any possible side-effects.
  const checkNoChangesMode = !!ngDevMode && isInCheckNoChangesMode();
  if (!checkNoChangesMode) {
    rendererFactory.begin?.();
  }
  try {
    detectChangesInViewWhileDirty(lView, mode);
  } catch (error) {
    if (notifyErrorHandler) {
      handleError(lView, error);
    }
    throw error;
  } finally {
    if (!checkNoChangesMode) {
      rendererFactory.end?.();
      // One final flush of the effects queue to catch any effects created in `ngAfterViewInit` or
      // other post-order hooks.
      environment.inlineEffectRunner?.flush();
    }
  }
}
function detectChangesInViewWhileDirty(lView, mode) {
  detectChangesInView$1(lView, mode);
  let retries = 0;
  // If after running change detection, this view still needs to be refreshed or there are
  // descendants views that need to be refreshed due to re-dirtying during the change detection
  // run, detect changes on the view again. We run change detection in `Targeted` mode to only
  // refresh views with the `RefreshView` flag.
  while (requiresRefreshOrTraversal(lView)) {
    if (retries === MAXIMUM_REFRESH_RERUNS) {
      throw new RuntimeError(103 /* RuntimeErrorCode.INFINITE_CHANGE_DETECTION */, ngDevMode && 'Infinite change detection while trying to refresh views. ' + 'There may be components which each cause the other to require a refresh, ' + 'causing an infinite loop.');
    }
    retries++;
    // Even if this view is detached, we still detect changes in targeted mode because this was
    // the root of the change detection run.
    detectChangesInView$1(lView, 1 /* ChangeDetectionMode.Targeted */);
  }
}
function checkNoChangesInternal(lView, notifyErrorHandler = true) {
  setIsInCheckNoChangesMode(true);
  try {
    detectChangesInternal(lView, notifyErrorHandler);
  } finally {
    setIsInCheckNoChangesMode(false);
  }
}
/**
 * Processes a view in update mode. This includes a number of steps in a specific order:
 * - executing a template function in update mode;
 * - executing hooks;
 * - refreshing queries;
 * - setting host bindings;
 * - refreshing child (embedded and component) views.
 */
function refreshView(tView, lView, templateFn, context) {
  ngDevMode && assertEqual(isCreationMode(lView), false, 'Should be run in update mode');
  const flags = lView[FLAGS];
  if ((flags & 256 /* LViewFlags.Destroyed */) === 256 /* LViewFlags.Destroyed */) return;
  // Check no changes mode is a dev only mode used to verify that bindings have not changed
  // since they were assigned. We do not want to execute lifecycle hooks in that mode.
  const isInCheckNoChangesPass = ngDevMode && isInCheckNoChangesMode();
  !isInCheckNoChangesPass && lView[ENVIRONMENT].inlineEffectRunner?.flush();
  // Start component reactive context
  // - We might already be in a reactive context if this is an embedded view of the host.
  // - We might be descending into a view that needs a consumer.
  enterView(lView);
  let prevConsumer = null;
  let currentConsumer = null;
  if (!isInCheckNoChangesPass && viewShouldHaveReactiveConsumer(tView)) {
    currentConsumer = getOrBorrowReactiveLViewConsumer(lView);
    prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.consumerBeforeComputation)(currentConsumer);
  }
  try {
    resetPreOrderHookFlags(lView);
    setBindingIndex(tView.bindingStartIndex);
    if (templateFn !== null) {
      executeTemplate(tView, lView, templateFn, 2 /* RenderFlags.Update */, context);
    }
    const hooksInitPhaseCompleted = (flags & 3 /* LViewFlags.InitPhaseStateMask */) === 3 /* InitPhaseState.InitPhaseCompleted */;
    // execute pre-order hooks (OnInit, OnChanges, DoCheck)
    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
    if (!isInCheckNoChangesPass) {
      if (hooksInitPhaseCompleted) {
        const preOrderCheckHooks = tView.preOrderCheckHooks;
        if (preOrderCheckHooks !== null) {
          executeCheckHooks(lView, preOrderCheckHooks, null);
        }
      } else {
        const preOrderHooks = tView.preOrderHooks;
        if (preOrderHooks !== null) {
          executeInitAndCheckHooks(lView, preOrderHooks, 0 /* InitPhaseState.OnInitHooksToBeRun */, null);
        }
        incrementInitPhaseFlags(lView, 0 /* InitPhaseState.OnInitHooksToBeRun */);
      }
    }
    // First mark transplanted views that are declared in this lView as needing a refresh at their
    // insertion points. This is needed to avoid the situation where the template is defined in this
    // `LView` but its declaration appears after the insertion component.
    markTransplantedViewsForRefresh(lView);
    detectChangesInEmbeddedViews(lView, 0 /* ChangeDetectionMode.Global */);
    // Content query results must be refreshed before content hooks are called.
    if (tView.contentQueries !== null) {
      refreshContentQueries(tView, lView);
    }
    // execute content hooks (AfterContentInit, AfterContentChecked)
    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
    if (!isInCheckNoChangesPass) {
      if (hooksInitPhaseCompleted) {
        const contentCheckHooks = tView.contentCheckHooks;
        if (contentCheckHooks !== null) {
          executeCheckHooks(lView, contentCheckHooks);
        }
      } else {
        const contentHooks = tView.contentHooks;
        if (contentHooks !== null) {
          executeInitAndCheckHooks(lView, contentHooks, 1 /* InitPhaseState.AfterContentInitHooksToBeRun */);
        }
        incrementInitPhaseFlags(lView, 1 /* InitPhaseState.AfterContentInitHooksToBeRun */);
      }
    }
    processHostBindingOpCodes(tView, lView);
    // Refresh child component views.
    const components = tView.components;
    if (components !== null) {
      detectChangesInChildComponents(lView, components, 0 /* ChangeDetectionMode.Global */);
    }
    // View queries must execute after refreshing child components because a template in this view
    // could be inserted in a child component. If the view query executes before child component
    // refresh, the template might not yet be inserted.
    const viewQuery = tView.viewQuery;
    if (viewQuery !== null) {
      executeViewQueryFn(2 /* RenderFlags.Update */, viewQuery, context);
    }
    // execute view hooks (AfterViewInit, AfterViewChecked)
    // PERF WARNING: do NOT extract this to a separate function without running benchmarks
    if (!isInCheckNoChangesPass) {
      if (hooksInitPhaseCompleted) {
        const viewCheckHooks = tView.viewCheckHooks;
        if (viewCheckHooks !== null) {
          executeCheckHooks(lView, viewCheckHooks);
        }
      } else {
        const viewHooks = tView.viewHooks;
        if (viewHooks !== null) {
          executeInitAndCheckHooks(lView, viewHooks, 2 /* InitPhaseState.AfterViewInitHooksToBeRun */);
        }
        incrementInitPhaseFlags(lView, 2 /* InitPhaseState.AfterViewInitHooksToBeRun */);
      }
    }
    if (tView.firstUpdatePass === true) {
      // We need to make sure that we only flip the flag on successful `refreshView` only
      // Don't do this in `finally` block.
      // If we did this in `finally` block then an exception could block the execution of styling
      // instructions which in turn would be unable to insert themselves into the styling linked
      // list. The result of this would be that if the exception would not be throw on subsequent CD
      // the styling would be unable to process it data and reflect to the DOM.
      tView.firstUpdatePass = false;
    }
    // Schedule any effects that are waiting on the update pass of this view.
    if (lView[EFFECTS_TO_SCHEDULE]) {
      for (const notifyEffect of lView[EFFECTS_TO_SCHEDULE]) {
        notifyEffect();
      }
      // Once they've been run, we can drop the array.
      lView[EFFECTS_TO_SCHEDULE] = null;
    }
    // Do not reset the dirty state when running in check no changes mode. We don't want components
    // to behave differently depending on whether check no changes is enabled or not. For example:
    // Marking an OnPush component as dirty from within the `ngAfterViewInit` hook in order to
    // refresh a `NgClass` binding should work. If we would reset the dirty state in the check
    // no changes cycle, the component would be not be dirty for the next update pass. This would
    // be different in production mode where the component dirty state is not reset.
    if (!isInCheckNoChangesPass) {
      lView[FLAGS] &= ~(64 /* LViewFlags.Dirty */ | 8 /* LViewFlags.FirstLViewPass */);
    }
  } catch (e) {
    // If refreshing a view causes an error, we need to remark the ancestors as needing traversal
    // because the error might have caused a situation where views below the current location are
    // dirty but will be unreachable because the "has dirty children" flag in the ancestors has been
    // cleared during change detection and we failed to run to completion.
    markAncestorsForTraversal(lView);
    throw e;
  } finally {
    if (currentConsumer !== null) {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.consumerAfterComputation)(currentConsumer, prevConsumer);
      maybeReturnReactiveLViewConsumer(currentConsumer);
    }
    leaveView();
  }
}
/**
 * Indicates if the view should get its own reactive consumer node.
 *
 * In the current design, all embedded views share a consumer with the component view. This allows
 * us to refresh at the component level rather than at a per-view level. In addition, root views get
 * their own reactive node because root component will have a host view that executes the
 * component's host bindings. This needs to be tracked in a consumer as well.
 *
 * To get a more granular change detection than per-component, all we would just need to update the
 * condition here so that a given view gets a reactive consumer which can become dirty independently
 * from its parent component. For example embedded views for signal components could be created with
 * a new type "SignalEmbeddedView" and the condition here wouldn't even need updating in order to
 * get granular per-view change detection for signal components.
 */
function viewShouldHaveReactiveConsumer(tView) {
  return tView.type !== 2 /* TViewType.Embedded */;
}
/**
 * Goes over embedded views (ones created through ViewContainerRef APIs) and refreshes
 * them by executing an associated template function.
 */
function detectChangesInEmbeddedViews(lView, mode) {
  for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
    for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
      const embeddedLView = lContainer[i];
      detectChangesInViewIfAttached(embeddedLView, mode);
    }
  }
}
/**
 * Mark transplanted views as needing to be refreshed at their insertion points.
 *
 * @param lView The `LView` that may have transplanted views.
 */
function markTransplantedViewsForRefresh(lView) {
  for (let lContainer = getFirstLContainer(lView); lContainer !== null; lContainer = getNextLContainer(lContainer)) {
    if (!(lContainer[FLAGS] & LContainerFlags.HasTransplantedViews)) continue;
    const movedViews = lContainer[MOVED_VIEWS];
    ngDevMode && assertDefined(movedViews, 'Transplanted View flags set but missing MOVED_VIEWS');
    for (let i = 0; i < movedViews.length; i++) {
      const movedLView = movedViews[i];
      const insertionLContainer = movedLView[PARENT];
      ngDevMode && assertLContainer(insertionLContainer);
      markViewForRefresh(movedLView);
    }
  }
}
/**
 * Detects changes in a component by entering the component view and processing its bindings,
 * queries, etc. if it is CheckAlways, OnPush and Dirty, etc.
 *
 * @param componentHostIdx  Element index in LView[] (adjusted for HEADER_OFFSET)
 */
function detectChangesInComponent(hostLView, componentHostIdx, mode) {
  ngDevMode && assertEqual(isCreationMode(hostLView), false, 'Should be run in update mode');
  const componentView = getComponentLViewByIndex(componentHostIdx, hostLView);
  detectChangesInViewIfAttached(componentView, mode);
}
/**
 * Visits a view as part of change detection traversal.
 *
 * If the view is detached, no additional traversal happens.
 */
function detectChangesInViewIfAttached(lView, mode) {
  if (!viewAttachedToChangeDetector(lView)) {
    return;
  }
  detectChangesInView$1(lView, mode);
}
/**
 * Visits a view as part of change detection traversal.
 *
 * The view is refreshed if:
 * - If the view is CheckAlways or Dirty and ChangeDetectionMode is `Global`
 * - If the view has the `RefreshView` flag
 *
 * The view is not refreshed, but descendants are traversed in `ChangeDetectionMode.Targeted` if the
 * view HasChildViewsToRefresh flag is set.
 */
function detectChangesInView$1(lView, mode) {
  const isInCheckNoChangesPass = ngDevMode && isInCheckNoChangesMode();
  const tView = lView[TVIEW];
  const flags = lView[FLAGS];
  const consumer = lView[REACTIVE_TEMPLATE_CONSUMER];
  // Refresh CheckAlways views in Global mode.
  let shouldRefreshView = !!(mode === 0 /* ChangeDetectionMode.Global */ && flags & 16 /* LViewFlags.CheckAlways */);
  // Refresh Dirty views in Global mode, as long as we're not in checkNoChanges.
  // CheckNoChanges never worked with `OnPush` components because the `Dirty` flag was
  // cleared before checkNoChanges ran. Because there is now a loop for to check for
  // backwards views, it gives an opportunity for `OnPush` components to be marked `Dirty`
  // before the CheckNoChanges pass. We don't want existing errors that are hidden by the
  // current CheckNoChanges bug to surface when making unrelated changes.
  shouldRefreshView ||= !!(flags & 64 /* LViewFlags.Dirty */ && mode === 0 /* ChangeDetectionMode.Global */ && !isInCheckNoChangesPass);
  // Always refresh views marked for refresh, regardless of mode.
  shouldRefreshView ||= !!(flags & 1024 /* LViewFlags.RefreshView */);
  // Refresh views when they have a dirty reactive consumer, regardless of mode.
  shouldRefreshView ||= !!(consumer?.dirty && (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.consumerPollProducersForChange)(consumer));
  // Mark the Flags and `ReactiveNode` as not dirty before refreshing the component, so that they
  // can be re-dirtied during the refresh process.
  if (consumer) {
    consumer.dirty = false;
  }
  lView[FLAGS] &= ~(8192 /* LViewFlags.HasChildViewsToRefresh */ | 1024 /* LViewFlags.RefreshView */);
  if (shouldRefreshView) {
    refreshView(tView, lView, tView.template, lView[CONTEXT]);
  } else if (flags & 8192 /* LViewFlags.HasChildViewsToRefresh */) {
    detectChangesInEmbeddedViews(lView, 1 /* ChangeDetectionMode.Targeted */);
    const components = tView.components;
    if (components !== null) {
      detectChangesInChildComponents(lView, components, 1 /* ChangeDetectionMode.Targeted */);
    }
  }
}
/** Refreshes child components in the current view (update mode). */
function detectChangesInChildComponents(hostLView, components, mode) {
  for (let i = 0; i < components.length; i++) {
    detectChangesInComponent(hostLView, components[i], mode);
  }
}

/**
 * Marks current view and all ancestors dirty.
 *
 * Returns the root view because it is found as a byproduct of marking the view tree
 * dirty, and can be used by methods that consume markViewDirty() to easily schedule
 * change detection. Otherwise, such methods would need to traverse up the view tree
 * an additional time to get the root view and schedule a tick on it.
 *
 * @param lView The starting LView to mark dirty
 * @returns the root LView
 */
function markViewDirty(lView) {
  lView[ENVIRONMENT].changeDetectionScheduler?.notify();
  while (lView) {
    lView[FLAGS] |= 64 /* LViewFlags.Dirty */;
    const parent = getLViewParent(lView);
    // Stop traversing up as soon as you find a root view that wasn't attached to any container
    if (isRootView(lView) && !parent) {
      return lView;
    }
    // continue otherwise
    lView = parent;
  }
  return null;
}
class ViewRef$1 {
  get rootNodes() {
    const lView = this._lView;
    const tView = lView[TVIEW];
    return collectNativeNodes(tView, lView, tView.firstChild, []);
  }
  constructor(
  /**
   * This represents `LView` associated with the component when ViewRef is a ChangeDetectorRef.
   *
   * When ViewRef is created for a dynamic component, this also represents the `LView` for the
   * component.
   *
   * For a "regular" ViewRef created for an embedded view, this is the `LView` for the embedded
   * view.
   *
   * @internal
   */
  _lView,
  /**
   * This represents the `LView` associated with the point where `ChangeDetectorRef` was
   * requested.
   *
   * This may be different from `_lView` if the `_cdRefInjectingView` is an embedded view.
   */
  _cdRefInjectingView, notifyErrorHandler = true) {
    this._lView = _lView;
    this._cdRefInjectingView = _cdRefInjectingView;
    this.notifyErrorHandler = notifyErrorHandler;
    this._appRef = null;
    this._attachedToViewContainer = false;
  }
  get context() {
    return this._lView[CONTEXT];
  }
  /**
   * @deprecated Replacing the full context object is not supported. Modify the context
   *   directly, or consider using a `Proxy` if you need to replace the full object.
   * // TODO(devversion): Remove this.
   */
  set context(value) {
    if (ngDevMode) {
      // Note: We have a warning message here because the `@deprecated` JSDoc will not be picked
      // up for assignments on the setter. We want to let users know about the deprecated usage.
      console.warn('Angular: Replacing the `context` object of an `EmbeddedViewRef` is deprecated.');
    }
    this._lView[CONTEXT] = value;
  }
  get destroyed() {
    return (this._lView[FLAGS] & 256 /* LViewFlags.Destroyed */) === 256 /* LViewFlags.Destroyed */;
  }
  destroy() {
    if (this._appRef) {
      this._appRef.detachView(this);
    } else if (this._attachedToViewContainer) {
      const parent = this._lView[PARENT];
      if (isLContainer(parent)) {
        const viewRefs = parent[VIEW_REFS];
        const index = viewRefs ? viewRefs.indexOf(this) : -1;
        if (index > -1) {
          ngDevMode && assertEqual(index, parent.indexOf(this._lView) - CONTAINER_HEADER_OFFSET, 'An attached view should be in the same position within its container as its ViewRef in the VIEW_REFS array.');
          detachView(parent, index);
          removeFromArray(viewRefs, index);
        }
      }
      this._attachedToViewContainer = false;
    }
    destroyLView(this._lView[TVIEW], this._lView);
  }
  onDestroy(callback) {
    storeLViewOnDestroy(this._lView, callback);
  }
  /**
   * Marks a view and all of its ancestors dirty.
   *
   * This can be used to ensure an {@link ChangeDetectionStrategy#OnPush} component is
   * checked when it needs to be re-rendered but the two normal triggers haven't marked it
   * dirty (i.e. inputs haven't changed and events haven't fired in the view).
   *
   * <!-- TODO: Add a link to a chapter on OnPush components -->
   *
   * @usageNotes
   * ### Example
   *
   * ```typescript
   * @Component({
   *   selector: 'app-root',
   *   template: `Number of ticks: {{numberOfTicks}}`
   *   changeDetection: ChangeDetectionStrategy.OnPush,
   * })
   * class AppComponent {
   *   numberOfTicks = 0;
   *
   *   constructor(private ref: ChangeDetectorRef) {
   *     setInterval(() => {
   *       this.numberOfTicks++;
   *       // the following is required, otherwise the view will not be updated
   *       this.ref.markForCheck();
   *     }, 1000);
   *   }
   * }
   * ```
   */
  markForCheck() {
    markViewDirty(this._cdRefInjectingView || this._lView);
  }
  /**
   * Detaches the view from the change detection tree.
   *
   * Detached views will not be checked during change detection runs until they are
   * re-attached, even if they are dirty. `detach` can be used in combination with
   * {@link ChangeDetectorRef#detectChanges} to implement local change
   * detection checks.
   *
   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
   * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
   *
   * @usageNotes
   * ### Example
   *
   * The following example defines a component with a large list of readonly data.
   * Imagine the data changes constantly, many times per second. For performance reasons,
   * we want to check and update the list every five seconds. We can do that by detaching
   * the component's change detector and doing a local check every five seconds.
   *
   * ```typescript
   * class DataProvider {
   *   // in a real application the returned data will be different every time
   *   get data() {
   *     return [1,2,3,4,5];
   *   }
   * }
   *
   * @Component({
   *   selector: 'giant-list',
   *   template: `
   *     <li *ngFor="let d of dataProvider.data">Data {{d}}</li>
   *   `,
   * })
   * class GiantList {
   *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {
   *     ref.detach();
   *     setInterval(() => {
   *       this.ref.detectChanges();
   *     }, 5000);
   *   }
   * }
   *
   * @Component({
   *   selector: 'app',
   *   providers: [DataProvider],
   *   template: `
   *     <giant-list><giant-list>
   *   `,
   * })
   * class App {
   * }
   * ```
   */
  detach() {
    this._lView[FLAGS] &= ~128 /* LViewFlags.Attached */;
  }
  /**
   * Re-attaches a view to the change detection tree.
   *
   * This can be used to re-attach views that were previously detached from the tree
   * using {@link ChangeDetectorRef#detach}. Views are attached to the tree by default.
   *
   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
   *
   * @usageNotes
   * ### Example
   *
   * The following example creates a component displaying `live` data. The component will detach
   * its change detector from the main change detector tree when the component's live property
   * is set to false.
   *
   * ```typescript
   * class DataProvider {
   *   data = 1;
   *
   *   constructor() {
   *     setInterval(() => {
   *       this.data = this.data * 2;
   *     }, 500);
   *   }
   * }
   *
   * @Component({
   *   selector: 'live-data',
   *   inputs: ['live'],
   *   template: 'Data: {{dataProvider.data}}'
   * })
   * class LiveData {
   *   constructor(private ref: ChangeDetectorRef, private dataProvider: DataProvider) {}
   *
   *   set live(value) {
   *     if (value) {
   *       this.ref.reattach();
   *     } else {
   *       this.ref.detach();
   *     }
   *   }
   * }
   *
   * @Component({
   *   selector: 'app-root',
   *   providers: [DataProvider],
   *   template: `
   *     Live Update: <input type="checkbox" [(ngModel)]="live">
   *     <live-data [live]="live"><live-data>
   *   `,
   * })
   * class AppComponent {
   *   live = true;
   * }
   * ```
   */
  reattach() {
    updateAncestorTraversalFlagsOnAttach(this._lView);
    this._lView[FLAGS] |= 128 /* LViewFlags.Attached */;
  }
  /**
   * Checks the view and its children.
   *
   * This can also be used in combination with {@link ChangeDetectorRef#detach} to implement
   * local change detection checks.
   *
   * <!-- TODO: Add a link to a chapter on detach/reattach/local digest -->
   * <!-- TODO: Add a live demo once ref.detectChanges is merged into master -->
   *
   * @usageNotes
   * ### Example
   *
   * The following example defines a component with a large list of readonly data.
   * Imagine, the data changes constantly, many times per second. For performance reasons,
   * we want to check and update the list every five seconds.
   *
   * We can do that by detaching the component's change detector and doing a local change detection
   * check every five seconds.
   *
   * See {@link ChangeDetectorRef#detach} for more information.
   */
  detectChanges() {
    // Add `RefreshView` flag to ensure this view is refreshed if not already dirty.
    // `RefreshView` flag is used intentionally over `Dirty` because it gets cleared before
    // executing any of the actual refresh code while the `Dirty` flag doesn't get cleared
    // until the end of the refresh. Using `RefreshView` prevents creating a potential difference
    // in the state of the LViewFlags during template execution.
    this._lView[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
    detectChangesInternal(this._lView, this.notifyErrorHandler);
  }
  /**
   * Checks the change detector and its children, and throws if any changes are detected.
   *
   * This is used in development mode to verify that running change detection doesn't
   * introduce other changes.
   */
  checkNoChanges() {
    if (ngDevMode) {
      checkNoChangesInternal(this._lView, this.notifyErrorHandler);
    }
  }
  attachToViewContainerRef() {
    if (this._appRef) {
      throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached directly to the ApplicationRef!');
    }
    this._attachedToViewContainer = true;
  }
  detachFromAppRef() {
    this._appRef = null;
    detachViewFromDOM(this._lView[TVIEW], this._lView);
  }
  attachToAppRef(appRef) {
    if (this._attachedToViewContainer) {
      throw new RuntimeError(902 /* RuntimeErrorCode.VIEW_ALREADY_ATTACHED */, ngDevMode && 'This view is already attached to a ViewContainer!');
    }
    this._appRef = appRef;
    updateAncestorTraversalFlagsOnAttach(this._lView);
  }
}

/**
 * Represents an embedded template that can be used to instantiate embedded views.
 * To instantiate embedded views based on a template, use the `ViewContainerRef`
 * method `createEmbeddedView()`.
 *
 * Access a `TemplateRef` instance by placing a directive on an `<ng-template>`
 * element (or directive prefixed with `*`). The `TemplateRef` for the embedded view
 * is injected into the constructor of the directive,
 * using the `TemplateRef` token.
 *
 * You can also use a `Query` to find a `TemplateRef` associated with
 * a component or a directive.
 *
 * @see {@link ViewContainerRef}
 * @see [Navigate the Component Tree with DI](guide/dependency-injection-navtree)
 *
 * @publicApi
 */
class TemplateRef {
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = injectTemplateRef;
  }
}
const ViewEngineTemplateRef = TemplateRef;
// TODO(alxhub): combine interface and implementation. Currently this is challenging since something
// in g3 depends on them being separate.
const R3TemplateRef = class TemplateRef extends ViewEngineTemplateRef {
  constructor(_declarationLView, _declarationTContainer, elementRef) {
    super();
    this._declarationLView = _declarationLView;
    this._declarationTContainer = _declarationTContainer;
    this.elementRef = elementRef;
  }
  /**
   * Returns an `ssrId` associated with a TView, which was used to
   * create this instance of the `TemplateRef`.
   *
   * @internal
   */
  get ssrId() {
    return this._declarationTContainer.tView?.ssrId || null;
  }
  createEmbeddedView(context, injector) {
    return this.createEmbeddedViewImpl(context, injector);
  }
  /**
   * @internal
   */
  createEmbeddedViewImpl(context, injector, dehydratedView) {
    const embeddedLView = createAndRenderEmbeddedLView(this._declarationLView, this._declarationTContainer, context, {
      embeddedViewInjector: injector,
      dehydratedView
    });
    return new ViewRef$1(embeddedLView);
  }
};
/**
 * Creates a TemplateRef given a node.
 *
 * @returns The TemplateRef instance to use
 */
function injectTemplateRef() {
  return createTemplateRef(getCurrentTNode(), getLView());
}
/**
 * Creates a TemplateRef and stores it on the injector.
 *
 * @param hostTNode The node on which a TemplateRef is requested
 * @param hostLView The `LView` to which the node belongs
 * @returns The TemplateRef instance or null if we can't create a TemplateRef on a given node type
 */
function createTemplateRef(hostTNode, hostLView) {
  if (hostTNode.type & 4 /* TNodeType.Container */) {
    ngDevMode && assertDefined(hostTNode.tView, 'TView must be allocated');
    return new R3TemplateRef(hostLView, hostTNode, createElementRef(hostTNode, hostLView));
  }
  return null;
}
const AT_THIS_LOCATION = '<-- AT THIS LOCATION';
/**
 * Retrieves a user friendly string for a given TNodeType for use in
 * friendly error messages
 *
 * @param tNodeType
 * @returns
 */
function getFriendlyStringFromTNodeType(tNodeType) {
  switch (tNodeType) {
    case 4 /* TNodeType.Container */:
      return 'view container';
    case 2 /* TNodeType.Element */:
      return 'element';
    case 8 /* TNodeType.ElementContainer */:
      return 'ng-container';
    case 32 /* TNodeType.Icu */:
      return 'icu';
    case 64 /* TNodeType.Placeholder */:
      return 'i18n';
    case 16 /* TNodeType.Projection */:
      return 'projection';
    case 1 /* TNodeType.Text */:
      return 'text';
    default:
      // This should not happen as we cover all possible TNode types above.
      return '<unknown>';
  }
}
/**
 * Validates that provided nodes match during the hydration process.
 */
function validateMatchingNode(node, nodeType, tagName, lView, tNode, isViewContainerAnchor = false) {
  if (!node || node.nodeType !== nodeType || node.nodeType === Node.ELEMENT_NODE && node.tagName.toLowerCase() !== tagName?.toLowerCase()) {
    const expectedNode = shortRNodeDescription(nodeType, tagName, null);
    let header = `During hydration Angular expected ${expectedNode} but `;
    const hostComponentDef = getDeclarationComponentDef(lView);
    const componentClassName = hostComponentDef?.type?.name;
    const expectedDom = describeExpectedDom(lView, tNode, isViewContainerAnchor);
    const expected = `Angular expected this DOM:\n\n${expectedDom}\n\n`;
    let actual = '';
    const componentHostElement = unwrapRNode(lView[HOST]);
    if (!node) {
      // No node found during hydration.
      header += `the node was not found.\n\n`;
      // Since the node is missing, we use the closest node to attach the error to
      markRNodeAsHavingHydrationMismatch(componentHostElement, expectedDom);
    } else {
      const actualNode = shortRNodeDescription(node.nodeType, node.tagName ?? null, node.textContent ?? null);
      header += `found ${actualNode}.\n\n`;
      const actualDom = describeDomFromNode(node);
      actual = `Actual DOM is:\n\n${actualDom}\n\n`;
      // DevTools only report hydration issues on the component level, so we attach extra debug
      // info to a component host element to make it available to DevTools.
      markRNodeAsHavingHydrationMismatch(componentHostElement, expectedDom, actualDom);
    }
    const footer = getHydrationErrorFooter(componentClassName);
    const message = header + expected + actual + getHydrationAttributeNote() + footer;
    throw new RuntimeError(-500 /* RuntimeErrorCode.HYDRATION_NODE_MISMATCH */, message);
  }
}
/**
 * Validates that a given node has sibling nodes
 */
function validateSiblingNodeExists(node) {
  validateNodeExists(node);
  if (!node.nextSibling) {
    const header = 'During hydration Angular expected more sibling nodes to be present.\n\n';
    const actual = `Actual DOM is:\n\n${describeDomFromNode(node)}\n\n`;
    const footer = getHydrationErrorFooter();
    const message = header + actual + footer;
    markRNodeAsHavingHydrationMismatch(node, '', actual);
    throw new RuntimeError(-501 /* RuntimeErrorCode.HYDRATION_MISSING_SIBLINGS */, message);
  }
}
/**
 * Validates that a node exists or throws
 */
function validateNodeExists(node, lView = null, tNode = null) {
  if (!node) {
    const header = 'During hydration, Angular expected an element to be present at this location.\n\n';
    let expected = '';
    let footer = '';
    if (lView !== null && tNode !== null) {
      expected = describeExpectedDom(lView, tNode, false);
      footer = getHydrationErrorFooter();
      // Since the node is missing, we use the closest node to attach the error to
      markRNodeAsHavingHydrationMismatch(unwrapRNode(lView[HOST]), expected, '');
    }
    throw new RuntimeError(-502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, `${header}${expected}\n\n${footer}`);
  }
}
/**
 * Builds the hydration error message when a node is not found
 *
 * @param lView the LView where the node exists
 * @param tNode the TNode
 */
function nodeNotFoundError(lView, tNode) {
  const header = 'During serialization, Angular was unable to find an element in the DOM:\n\n';
  const expected = `${describeExpectedDom(lView, tNode, false)}\n\n`;
  const footer = getHydrationErrorFooter();
  throw new RuntimeError(-502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + expected + footer);
}
/**
 * Builds a hydration error message when a node is not found at a path location
 *
 * @param host the Host Node
 * @param path the path to the node
 */
function nodeNotFoundAtPathError(host, path) {
  const header = `During hydration Angular was unable to locate a node ` + `using the "${path}" path, starting from the ${describeRNode(host)} node.\n\n`;
  const footer = getHydrationErrorFooter();
  markRNodeAsHavingHydrationMismatch(host);
  throw new RuntimeError(-502 /* RuntimeErrorCode.HYDRATION_MISSING_NODE */, header + footer);
}
/**
 * Builds the hydration error message in the case that dom nodes are created outside of
 * the Angular context and are being used as projected nodes
 *
 * @param lView the LView
 * @param tNode the TNode
 * @returns an error
 */
function unsupportedProjectionOfDomNodes(rNode) {
  const header = 'During serialization, Angular detected DOM nodes ' + 'that were created outside of Angular context and provided as projectable nodes ' + '(likely via `ViewContainerRef.createComponent` or `createComponent` APIs). ' + 'Hydration is not supported for such cases, consider refactoring the code to avoid ' + 'this pattern or using `ngSkipHydration` on the host element of the component.\n\n';
  const actual = `${describeDomFromNode(rNode)}\n\n`;
  const message = header + actual + getHydrationAttributeNote();
  return new RuntimeError(-503 /* RuntimeErrorCode.UNSUPPORTED_PROJECTION_DOM_NODES */, message);
}
/**
 * Builds the hydration error message in the case that ngSkipHydration was used on a
 * node that is not a component host element or host binding
 *
 * @param rNode the HTML Element
 * @returns an error
 */
function invalidSkipHydrationHost(rNode) {
  const header = 'The `ngSkipHydration` flag is applied on a node ' + 'that doesn\'t act as a component host. Hydration can be ' + 'skipped only on per-component basis.\n\n';
  const actual = `${describeDomFromNode(rNode)}\n\n`;
  const footer = 'Please move the `ngSkipHydration` attribute to the component host element.\n\n';
  const message = header + actual + footer;
  return new RuntimeError(-504 /* RuntimeErrorCode.INVALID_SKIP_HYDRATION_HOST */, message);
}
// Stringification methods
/**
 * Stringifies a given TNode's attributes
 *
 * @param tNode a provided TNode
 * @returns string
 */
function stringifyTNodeAttrs(tNode) {
  const results = [];
  if (tNode.attrs) {
    for (let i = 0; i < tNode.attrs.length;) {
      const attrName = tNode.attrs[i++];
      // Once we reach the first flag, we know that the list of
      // attributes is over.
      if (typeof attrName == 'number') {
        break;
      }
      const attrValue = tNode.attrs[i++];
      results.push(`${attrName}="${shorten(attrValue)}"`);
    }
  }
  return results.join(' ');
}
/**
 * The list of internal attributes that should be filtered out while
 * producing an error message.
 */
const internalAttrs = new Set(['ngh', 'ng-version', 'ng-server-context']);
/**
 * Stringifies an HTML Element's attributes
 *
 * @param rNode an HTML Element
 * @returns string
 */
function stringifyRNodeAttrs(rNode) {
  const results = [];
  for (let i = 0; i < rNode.attributes.length; i++) {
    const attr = rNode.attributes[i];
    if (internalAttrs.has(attr.name)) continue;
    results.push(`${attr.name}="${shorten(attr.value)}"`);
  }
  return results.join(' ');
}
// Methods for Describing the DOM
/**
 * Converts a tNode to a helpful readable string value for use in error messages
 *
 * @param tNode a given TNode
 * @param innerContent the content of the node
 * @returns string
 */
function describeTNode(tNode, innerContent = '…') {
  switch (tNode.type) {
    case 1 /* TNodeType.Text */:
      const content = tNode.value ? `(${tNode.value})` : '';
      return `#text${content}`;
    case 2 /* TNodeType.Element */:
      const attrs = stringifyTNodeAttrs(tNode);
      const tag = tNode.value.toLowerCase();
      return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
    case 8 /* TNodeType.ElementContainer */:
      return '<!-- ng-container -->';
    case 4 /* TNodeType.Container */:
      return '<!-- container -->';
    default:
      const typeAsString = getFriendlyStringFromTNodeType(tNode.type);
      return `#node(${typeAsString})`;
  }
}
/**
 * Converts an RNode to a helpful readable string value for use in error messages
 *
 * @param rNode a given RNode
 * @param innerContent the content of the node
 * @returns string
 */
function describeRNode(rNode, innerContent = '…') {
  const node = rNode;
  switch (node.nodeType) {
    case Node.ELEMENT_NODE:
      const tag = node.tagName.toLowerCase();
      const attrs = stringifyRNodeAttrs(node);
      return `<${tag}${attrs ? ' ' + attrs : ''}>${innerContent}</${tag}>`;
    case Node.TEXT_NODE:
      const content = node.textContent ? shorten(node.textContent) : '';
      return `#text${content ? `(${content})` : ''}`;
    case Node.COMMENT_NODE:
      return `<!-- ${shorten(node.textContent ?? '')} -->`;
    default:
      return `#node(${node.nodeType})`;
  }
}
/**
 * Builds the string containing the expected DOM present given the LView and TNode
 * values for a readable error message
 *
 * @param lView the lView containing the DOM
 * @param tNode the tNode
 * @param isViewContainerAnchor boolean
 * @returns string
 */
function describeExpectedDom(lView, tNode, isViewContainerAnchor) {
  const spacer = '  ';
  let content = '';
  if (tNode.prev) {
    content += spacer + '…\n';
    content += spacer + describeTNode(tNode.prev) + '\n';
  } else if (tNode.type && tNode.type & 12 /* TNodeType.AnyContainer */) {
    content += spacer + '…\n';
  }
  if (isViewContainerAnchor) {
    content += spacer + describeTNode(tNode) + '\n';
    content += spacer + `<!-- container -->  ${AT_THIS_LOCATION}\n`;
  } else {
    content += spacer + describeTNode(tNode) + `  ${AT_THIS_LOCATION}\n`;
  }
  content += spacer + '…\n';
  const parentRNode = tNode.type ? getParentRElement(lView[TVIEW], tNode, lView) : null;
  if (parentRNode) {
    content = describeRNode(parentRNode, '\n' + content);
  }
  return content;
}
/**
 * Builds the string containing the DOM present around a given RNode for a
 * readable error message
 *
 * @param node the RNode
 * @returns string
 */
function describeDomFromNode(node) {
  const spacer = '  ';
  let content = '';
  const currentNode = node;
  if (currentNode.previousSibling) {
    content += spacer + '…\n';
    content += spacer + describeRNode(currentNode.previousSibling) + '\n';
  }
  content += spacer + describeRNode(currentNode) + `  ${AT_THIS_LOCATION}\n`;
  if (node.nextSibling) {
    content += spacer + '…\n';
  }
  if (node.parentNode) {
    content = describeRNode(currentNode.parentNode, '\n' + content);
  }
  return content;
}
/**
 * Shortens the description of a given RNode by its type for readability
 *
 * @param nodeType the type of node
 * @param tagName the node tag name
 * @param textContent the text content in the node
 * @returns string
 */
function shortRNodeDescription(nodeType, tagName, textContent) {
  switch (nodeType) {
    case Node.ELEMENT_NODE:
      return `<${tagName.toLowerCase()}>`;
    case Node.TEXT_NODE:
      const content = textContent ? ` (with the "${shorten(textContent)}" content)` : '';
      return `a text node${content}`;
    case Node.COMMENT_NODE:
      return 'a comment node';
    default:
      return `#node(nodeType=${nodeType})`;
  }
}
/**
 * Builds the footer hydration error message
 *
 * @param componentClassName the name of the component class
 * @returns string
 */
function getHydrationErrorFooter(componentClassName) {
  const componentInfo = componentClassName ? `the "${componentClassName}"` : 'corresponding';
  return `To fix this problem:\n` + `  * check ${componentInfo} component for hydration-related issues\n` + `  * check to see if your template has valid HTML structure\n` + `  * or skip hydration by adding the \`ngSkipHydration\` attribute ` + `to its host node in a template\n\n`;
}
/**
 * An attribute related note for hydration errors
 */
function getHydrationAttributeNote() {
  return 'Note: attributes are only displayed to better represent the DOM' + ' but have no effect on hydration mismatches.\n\n';
}
// Node string utility functions
/**
 * Strips all newlines out of a given string
 *
 * @param input a string to be cleared of new line characters
 * @returns
 */
function stripNewlines(input) {
  return input.replace(/\s+/gm, '');
}
/**
 * Reduces a string down to a maximum length of characters with ellipsis for readability
 *
 * @param input a string input
 * @param maxLength a maximum length in characters
 * @returns string
 */
function shorten(input, maxLength = 50) {
  if (!input) {
    return '';
  }
  input = stripNewlines(input);
  return input.length > maxLength ? `${input.substring(0, maxLength - 1)}…` : input;
}

/**
 * Removes all dehydrated views from a given LContainer:
 * both in internal data structure, as well as removing
 * corresponding DOM nodes that belong to that dehydrated view.
 */
function removeDehydratedViews(lContainer) {
  const views = lContainer[DEHYDRATED_VIEWS] ?? [];
  const parentLView = lContainer[PARENT];
  const renderer = parentLView[RENDERER];
  for (const view of views) {
    removeDehydratedView(view, renderer);
    ngDevMode && ngDevMode.dehydratedViewsRemoved++;
  }
  // Reset the value to an empty array to indicate that no
  // further processing of dehydrated views is needed for
  // this view container (i.e. do not trigger the lookup process
  // once again in case a `ViewContainerRef` is created later).
  lContainer[DEHYDRATED_VIEWS] = EMPTY_ARRAY;
}
/**
 * Helper function to remove all nodes from a dehydrated view.
 */
function removeDehydratedView(dehydratedView, renderer) {
  let nodesRemoved = 0;
  let currentRNode = dehydratedView.firstChild;
  if (currentRNode) {
    const numNodes = dehydratedView.data[NUM_ROOT_NODES];
    while (nodesRemoved < numNodes) {
      ngDevMode && validateSiblingNodeExists(currentRNode);
      const nextSibling = currentRNode.nextSibling;
      nativeRemoveNode(renderer, currentRNode, false);
      currentRNode = nextSibling;
      nodesRemoved++;
    }
  }
}
/**
 * Walks over all views within this LContainer invokes dehydrated views
 * cleanup function for each one.
 */
function cleanupLContainer(lContainer) {
  removeDehydratedViews(lContainer);
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
    cleanupLView(lContainer[i]);
  }
}
/**
 * Removes any remaining dehydrated i18n nodes from a given LView,
 * both in internal data structure, as well as removing the
 * corresponding DOM nodes.
 */
function cleanupDehydratedI18nNodes(lView) {
  const i18nNodes = lView[HYDRATION]?.i18nNodes;
  if (i18nNodes) {
    const renderer = lView[RENDERER];
    for (const node of i18nNodes.values()) {
      nativeRemoveNode(renderer, node, false);
    }
    lView[HYDRATION].i18nNodes = undefined;
  }
}
/**
 * Walks over `LContainer`s and components registered within
 * this LView and invokes dehydrated views cleanup function for each one.
 */
function cleanupLView(lView) {
  cleanupDehydratedI18nNodes(lView);
  const tView = lView[TVIEW];
  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
    if (isLContainer(lView[i])) {
      const lContainer = lView[i];
      cleanupLContainer(lContainer);
    } else if (isLView(lView[i])) {
      // This is a component, enter the `cleanupLView` recursively.
      cleanupLView(lView[i]);
    }
  }
}
/**
 * Walks over all views registered within the ApplicationRef and removes
 * all dehydrated views from all `LContainer`s along the way.
 */
function cleanupDehydratedViews(appRef) {
  const viewRefs = appRef._views;
  for (const viewRef of viewRefs) {
    const lNode = getLNodeForHydration(viewRef);
    // An `lView` might be `null` if a `ViewRef` represents
    // an embedded view (not a component view).
    if (lNode !== null && lNode[HOST] !== null) {
      if (isLView(lNode)) {
        cleanupLView(lNode);
      } else {
        // Cleanup in the root component view
        const componentLView = lNode[HOST];
        cleanupLView(componentLView);
        // Cleanup in all views within this view container
        cleanupLContainer(lNode);
      }
      ngDevMode && ngDevMode.dehydratedViewsCleanupRuns++;
    }
  }
}

/**
 * Regexp that extracts a reference node information from the compressed node location.
 * The reference node is represented as either:
 *  - a number which points to an LView slot
 *  - the `b` char which indicates that the lookup should start from the `document.body`
 *  - the `h` char to start lookup from the component host node (`lView[HOST]`)
 */
const REF_EXTRACTOR_REGEXP = new RegExp(`^(\\d+)*(${REFERENCE_NODE_BODY}|${REFERENCE_NODE_HOST})*(.*)`);
/**
 * Helper function that takes a reference node location and a set of navigation steps
 * (from the reference node) to a target node and outputs a string that represents
 * a location.
 *
 * For example, given: referenceNode = 'b' (body) and path = ['firstChild', 'firstChild',
 * 'nextSibling'], the function returns: `bf2n`.
 */
function compressNodeLocation(referenceNode, path) {
  const result = [referenceNode];
  for (const segment of path) {
    const lastIdx = result.length - 1;
    if (lastIdx > 0 && result[lastIdx - 1] === segment) {
      // An empty string in a count slot represents 1 occurrence of an instruction.
      const value = result[lastIdx] || 1;
      result[lastIdx] = value + 1;
    } else {
      // Adding a new segment to the path.
      // Using an empty string in a counter field to avoid encoding `1`s
      // into the path, since they are implicit (e.g. `f1n1` vs `fn`), so
      // it's enough to have a single char in this case.
      result.push(segment, '');
    }
  }
  return result.join('');
}
/**
 * Helper function that reverts the `compressNodeLocation` and transforms a given
 * string into an array where at 0th position there is a reference node info and
 * after that it contains information (in pairs) about a navigation step and the
 * number of repetitions.
 *
 * For example, the path like 'bf2n' will be transformed to:
 * ['b', 'firstChild', 2, 'nextSibling', 1].
 *
 * This information is later consumed by the code that navigates the DOM to find
 * a given node by its location.
 */
function decompressNodeLocation(path) {
  const matches = path.match(REF_EXTRACTOR_REGEXP);
  const [_, refNodeId, refNodeName, rest] = matches;
  // If a reference node is represented by an index, transform it to a number.
  const ref = refNodeId ? parseInt(refNodeId, 10) : refNodeName;
  const steps = [];
  // Match all segments in a path.
  for (const [_, step, count] of rest.matchAll(/(f|n)(\d*)/g)) {
    const repeat = parseInt(count, 10) || 1;
    steps.push(step, repeat);
  }
  return [ref, ...steps];
}

/** Whether current TNode is a first node in an <ng-container>. */
function isFirstElementInNgContainer(tNode) {
  return !tNode.prev && tNode.parent?.type === 8 /* TNodeType.ElementContainer */;
}
/** Returns an instruction index (subtracting HEADER_OFFSET). */
function getNoOffsetIndex(tNode) {
  return tNode.index - HEADER_OFFSET;
}
/**
 * Check whether a given node exists, but is disconnected from the DOM.
 *
 * Note: we leverage the fact that we have this information available in the DOM emulation
 * layer (in Domino) for now. Longer-term solution should not rely on the DOM emulation and
 * only use internal data structures and state to compute this information.
 */
function isDisconnectedNode(tNode, lView) {
  return !(tNode.type & 16 /* TNodeType.Projection */) && !!lView[tNode.index] && !unwrapRNode(lView[tNode.index])?.isConnected;
}
/**
 * Locate a node in an i18n tree that corresponds to a given instruction index.
 *
 * @param hydrationInfo The hydration annotation data
 * @param noOffsetIndex the instruction index
 * @returns an RNode that corresponds to the instruction index
 */
function locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex) {
  const i18nNodes = hydrationInfo.i18nNodes;
  if (i18nNodes) {
    const native = i18nNodes.get(noOffsetIndex);
    if (native) {
      i18nNodes.delete(noOffsetIndex);
    }
    return native;
  }
  return null;
}
/**
 * Locate a node in DOM tree that corresponds to a given TNode.
 *
 * @param hydrationInfo The hydration annotation data
 * @param tView the current tView
 * @param lView the current lView
 * @param tNode the current tNode
 * @returns an RNode that represents a given tNode
 */
function locateNextRNode(hydrationInfo, tView, lView, tNode) {
  const noOffsetIndex = getNoOffsetIndex(tNode);
  let native = locateI18nRNodeByIndex(hydrationInfo, noOffsetIndex);
  if (!native) {
    const nodes = hydrationInfo.data[NODES];
    if (nodes?.[noOffsetIndex]) {
      // We know the exact location of the node.
      native = locateRNodeByPath(nodes[noOffsetIndex], lView);
    } else if (tView.firstChild === tNode) {
      // We create a first node in this view, so we use a reference
      // to the first child in this DOM segment.
      native = hydrationInfo.firstChild;
    } else {
      // Locate a node based on a previous sibling or a parent node.
      const previousTNodeParent = tNode.prev === null;
      const previousTNode = tNode.prev ?? tNode.parent;
      ngDevMode && assertDefined(previousTNode, 'Unexpected state: current TNode does not have a connection ' + 'to the previous node or a parent node.');
      if (isFirstElementInNgContainer(tNode)) {
        const noOffsetParentIndex = getNoOffsetIndex(tNode.parent);
        native = getSegmentHead(hydrationInfo, noOffsetParentIndex);
      } else {
        let previousRElement = getNativeByTNode(previousTNode, lView);
        if (previousTNodeParent) {
          native = previousRElement.firstChild;
        } else {
          // If the previous node is an element, but it also has container info,
          // this means that we are processing a node like `<div #vcrTarget>`, which is
          // represented in the DOM as `<div></div>...<!--container-->`.
          // In this case, there are nodes *after* this element and we need to skip
          // all of them to reach an element that we are looking for.
          const noOffsetPrevSiblingIndex = getNoOffsetIndex(previousTNode);
          const segmentHead = getSegmentHead(hydrationInfo, noOffsetPrevSiblingIndex);
          if (previousTNode.type === 2 /* TNodeType.Element */ && segmentHead) {
            const numRootNodesToSkip = calcSerializedContainerSize(hydrationInfo, noOffsetPrevSiblingIndex);
            // `+1` stands for an anchor comment node after all the views in this container.
            const nodesToSkip = numRootNodesToSkip + 1;
            // First node after this segment.
            native = siblingAfter(nodesToSkip, segmentHead);
          } else {
            native = previousRElement.nextSibling;
          }
        }
      }
    }
  }
  return native;
}
/**
 * Skips over a specified number of nodes and returns the next sibling node after that.
 */
function siblingAfter(skip, from) {
  let currentNode = from;
  for (let i = 0; i < skip; i++) {
    ngDevMode && validateSiblingNodeExists(currentNode);
    currentNode = currentNode.nextSibling;
  }
  return currentNode;
}
/**
 * Helper function to produce a string representation of the navigation steps
 * (in terms of `nextSibling` and `firstChild` navigations). Used in error
 * messages in dev mode.
 */
function stringifyNavigationInstructions(instructions) {
  const container = [];
  for (let i = 0; i < instructions.length; i += 2) {
    const step = instructions[i];
    const repeat = instructions[i + 1];
    for (let r = 0; r < repeat; r++) {
      container.push(step === NodeNavigationStep.FirstChild ? 'firstChild' : 'nextSibling');
    }
  }
  return container.join('.');
}
/**
 * Helper function that navigates from a starting point node (the `from` node)
 * using provided set of navigation instructions (within `path` argument).
 */
function navigateToNode(from, instructions) {
  let node = from;
  for (let i = 0; i < instructions.length; i += 2) {
    const step = instructions[i];
    const repeat = instructions[i + 1];
    for (let r = 0; r < repeat; r++) {
      if (ngDevMode && !node) {
        throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
      }
      switch (step) {
        case NodeNavigationStep.FirstChild:
          node = node.firstChild;
          break;
        case NodeNavigationStep.NextSibling:
          node = node.nextSibling;
          break;
      }
    }
  }
  if (ngDevMode && !node) {
    throw nodeNotFoundAtPathError(from, stringifyNavigationInstructions(instructions));
  }
  return node;
}
/**
 * Locates an RNode given a set of navigation instructions (which also contains
 * a starting point node info).
 */
function locateRNodeByPath(path, lView) {
  const [referenceNode, ...navigationInstructions] = decompressNodeLocation(path);
  let ref;
  if (referenceNode === REFERENCE_NODE_HOST) {
    ref = lView[DECLARATION_COMPONENT_VIEW][HOST];
  } else if (referenceNode === REFERENCE_NODE_BODY) {
    ref = ɵɵresolveBody(lView[DECLARATION_COMPONENT_VIEW][HOST]);
  } else {
    const parentElementId = Number(referenceNode);
    ref = unwrapRNode(lView[parentElementId + HEADER_OFFSET]);
  }
  return navigateToNode(ref, navigationInstructions);
}
/**
 * Generate a list of DOM navigation operations to get from node `start` to node `finish`.
 *
 * Note: assumes that node `start` occurs before node `finish` in an in-order traversal of the DOM
 * tree. That is, we should be able to get from `start` to `finish` purely by using `.firstChild`
 * and `.nextSibling` operations.
 */
function navigateBetween(start, finish) {
  if (start === finish) {
    return [];
  } else if (start.parentElement == null || finish.parentElement == null) {
    return null;
  } else if (start.parentElement === finish.parentElement) {
    return navigateBetweenSiblings(start, finish);
  } else {
    // `finish` is a child of its parent, so the parent will always have a child.
    const parent = finish.parentElement;
    const parentPath = navigateBetween(start, parent);
    const childPath = navigateBetween(parent.firstChild, finish);
    if (!parentPath || !childPath) return null;
    return [
    // First navigate to `finish`'s parent
    ...parentPath,
    // Then to its first child.
    NodeNavigationStep.FirstChild,
    // And finally from that node to `finish` (maybe a no-op if we're already there).
    ...childPath];
  }
}
/**
 * Calculates a path between 2 sibling nodes (generates a number of `NextSibling` navigations).
 * Returns `null` if no such path exists between the given nodes.
 */
function navigateBetweenSiblings(start, finish) {
  const nav = [];
  let node = null;
  for (node = start; node != null && node !== finish; node = node.nextSibling) {
    nav.push(NodeNavigationStep.NextSibling);
  }
  // If the `node` becomes `null` or `undefined` at the end, that means that we
  // didn't find the `end` node, thus return `null` (which would trigger serialization
  // error to be produced).
  return node == null ? null : nav;
}
/**
 * Calculates a path between 2 nodes in terms of `nextSibling` and `firstChild`
 * navigations:
 * - the `from` node is a known node, used as an starting point for the lookup
 *   (the `fromNodeName` argument is a string representation of the node).
 * - the `to` node is a node that the runtime logic would be looking up,
 *   using the path generated by this function.
 */
function calcPathBetween(from, to, fromNodeName) {
  const path = navigateBetween(from, to);
  return path === null ? null : compressNodeLocation(fromNodeName, path);
}
/**
 * Invoked at serialization time (on the server) when a set of navigation
 * instructions needs to be generated for a TNode.
 */
function calcPathForNode(tNode, lView) {
  let parentTNode = tNode.parent;
  let parentIndex;
  let parentRNode;
  let referenceNodeName;
  // Skip over all parent nodes that are disconnected from the DOM, such nodes
  // can not be used as anchors.
  //
  // This might happen in certain content projection-based use-cases, where
  // a content of an element is projected and used, when a parent element
  // itself remains detached from DOM. In this scenario we try to find a parent
  // element that is attached to DOM and can act as an anchor instead.
  while (parentTNode !== null && isDisconnectedNode(parentTNode, lView)) {
    parentTNode = parentTNode.parent;
  }
  if (parentTNode === null || !(parentTNode.type & 3 /* TNodeType.AnyRNode */)) {
    // If there is no parent TNode or a parent TNode does not represent an RNode
    // (i.e. not a DOM node), use component host element as a reference node.
    parentIndex = referenceNodeName = REFERENCE_NODE_HOST;
    parentRNode = lView[DECLARATION_COMPONENT_VIEW][HOST];
  } else {
    // Use parent TNode as a reference node.
    parentIndex = parentTNode.index;
    parentRNode = unwrapRNode(lView[parentIndex]);
    referenceNodeName = renderStringify(parentIndex - HEADER_OFFSET);
  }
  let rNode = unwrapRNode(lView[tNode.index]);
  if (tNode.type & 12 /* TNodeType.AnyContainer */) {
    // For <ng-container> nodes, instead of serializing a reference
    // to the anchor comment node, serialize a location of the first
    // DOM element. Paired with the container size (serialized as a part
    // of `ngh.containers`), it should give enough information for runtime
    // to hydrate nodes in this container.
    const firstRNode = getFirstNativeNode(lView, tNode);
    // If container is not empty, use a reference to the first element,
    // otherwise, rNode would point to an anchor comment node.
    if (firstRNode) {
      rNode = firstRNode;
    }
  }
  let path = calcPathBetween(parentRNode, rNode, referenceNodeName);
  if (path === null && parentRNode !== rNode) {
    // Searching for a path between elements within a host node failed.
    // Trying to find a path to an element starting from the `document.body` instead.
    //
    // Important note: this type of reference is relatively unstable, since Angular
    // may not be able to control parts of the page that the runtime logic navigates
    // through. This is mostly needed to cover "portals" use-case (like menus, dialog boxes,
    // etc), where nodes are content-projected (including direct DOM manipulations) outside
    // of the host node. The better solution is to provide APIs to work with "portals",
    // at which point this code path would not be needed.
    const body = parentRNode.ownerDocument.body;
    path = calcPathBetween(body, rNode, REFERENCE_NODE_BODY);
    if (path === null) {
      // If the path is still empty, it's likely that this node is detached and
      // won't be found during hydration.
      throw nodeNotFoundError(lView, tNode);
    }
  }
  return path;
}

/**
 * Given a current DOM node and a serialized information about the views
 * in a container, walks over the DOM structure, collecting the list of
 * dehydrated views.
 */
function locateDehydratedViewsInContainer(currentRNode, serializedViews) {
  const dehydratedViews = [];
  for (const serializedView of serializedViews) {
    // Repeats a view multiple times as needed, based on the serialized information
    // (for example, for *ngFor-produced views).
    for (let i = 0; i < (serializedView[MULTIPLIER] ?? 1); i++) {
      const view = {
        data: serializedView,
        firstChild: null
      };
      if (serializedView[NUM_ROOT_NODES] > 0) {
        // Keep reference to the first node in this view,
        // so it can be accessed while invoking template instructions.
        view.firstChild = currentRNode;
        // Move over to the next node after this view, which can
        // either be a first node of the next view or an anchor comment
        // node after the last view in a container.
        currentRNode = siblingAfter(serializedView[NUM_ROOT_NODES], currentRNode);
      }
      dehydratedViews.push(view);
    }
  }
  return [currentRNode, dehydratedViews];
}
/**
 * Reference to a function that searches for a matching dehydrated views
 * stored on a given lContainer.
 * Returns `null` by default, when hydration is not enabled.
 */
let _findMatchingDehydratedViewImpl = () => null;
/**
 * Retrieves the next dehydrated view from the LContainer and verifies that
 * it matches a given template id (from the TView that was used to create this
 * instance of a view). If the id doesn't match, that means that we are in an
 * unexpected state and can not complete the reconciliation process. Thus,
 * all dehydrated views from this LContainer are removed (including corresponding
 * DOM nodes) and the rendering is performed as if there were no dehydrated views
 * in this container.
 */
function findMatchingDehydratedViewImpl(lContainer, template) {
  const views = lContainer[DEHYDRATED_VIEWS];
  if (!template || views === null || views.length === 0) {
    return null;
  }
  const view = views[0];
  // Verify whether the first dehydrated view in the container matches
  // the template id passed to this function (that originated from a TView
  // that was used to create an instance of an embedded or component views.
  if (view.data[TEMPLATE_ID] === template) {
    // If the template id matches - extract the first view and return it.
    return views.shift();
  } else {
    // Otherwise, we are at the state when reconciliation can not be completed,
    // thus we remove all dehydrated views within this container (remove them
    // from internal data structures as well as delete associated elements from
    // the DOM tree).
    removeDehydratedViews(lContainer);
    return null;
  }
}
function enableFindMatchingDehydratedViewImpl() {
  _findMatchingDehydratedViewImpl = findMatchingDehydratedViewImpl;
}
function findMatchingDehydratedView(lContainer, template) {
  return _findMatchingDehydratedViewImpl(lContainer, template);
}

/**
 * Injectable that is notified when an `LView` is made aware of changes to application state.
 */
class ChangeDetectionScheduler {}

/**
 * Represents a component created by a `ComponentFactory`.
 * Provides access to the component instance and related objects,
 * and provides the means of destroying the instance.
 *
 * @publicApi
 */
class ComponentRef$1 {}
/**
 * Base class for a factory that can create a component dynamically.
 * Instantiate a factory for a given type of component with `resolveComponentFactory()`.
 * Use the resulting `ComponentFactory.create()` method to create a component of that type.
 *
 * @publicApi
 *
 * @deprecated Angular no longer requires Component factories. Please use other APIs where
 *     Component class can be used directly.
 */
class ComponentFactory$1 {}
function noComponentFactoryError(component) {
  const error = Error(`No component factory found for ${stringify(component)}.`);
  error[ERROR_COMPONENT] = component;
  return error;
}
const ERROR_COMPONENT = 'ngComponent';
function getComponent(error) {
  return error[ERROR_COMPONENT];
}
class _NullComponentFactoryResolver {
  resolveComponentFactory(component) {
    throw noComponentFactoryError(component);
  }
}
/**
 * A simple registry that maps `Components` to generated `ComponentFactory` classes
 * that can be used to create instances of components.
 * Use to obtain the factory for a given component type,
 * then use the factory's `create()` method to create a component of that type.
 *
 * Note: since v13, dynamic component creation via
 * [`ViewContainerRef.createComponent`](api/core/ViewContainerRef#createComponent)
 * does **not** require resolving component factory: component class can be used directly.
 *
 * @publicApi
 *
 * @deprecated Angular no longer requires Component factories. Please use other APIs where
 *     Component class can be used directly.
 */
class ComponentFactoryResolver$1 {
  static {
    this.NULL = /* @__PURE__ */new _NullComponentFactoryResolver();
  }
}

/**
 * Creates and initializes a custom renderer that implements the `Renderer2` base class.
 *
 * @publicApi
 */
class RendererFactory2 {}
/**
 * Extend this base class to implement custom rendering. By default, Angular
 * renders a template into DOM. You can use custom rendering to intercept
 * rendering calls, or to render to something other than DOM.
 *
 * Create your custom renderer using `RendererFactory2`.
 *
 * Use a custom renderer to bypass Angular's templating and
 * make custom UI changes that can't be expressed declaratively.
 * For example if you need to set a property or an attribute whose name is
 * not statically known, use the `setProperty()` or
 * `setAttribute()` method.
 *
 * @publicApi
 */
class Renderer2 {
  constructor() {
    /**
     * If null or undefined, the view engine won't call it.
     * This is used as a performance optimization for production mode.
     */
    this.destroyNode = null;
  }
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = () => injectRenderer2();
  }
}
/** Injects a Renderer2 for the current component. */
function injectRenderer2() {
  // We need the Renderer to be based on the component that it's being injected into, however since
  // DI happens before we've entered its view, `getLView` will return the parent view instead.
  const lView = getLView();
  const tNode = getCurrentTNode();
  const nodeAtIndex = getComponentLViewByIndex(tNode.index, lView);
  return (isLView(nodeAtIndex) ? nodeAtIndex : lView)[RENDERER];
}

/**
 * Sanitizer is used by the views to sanitize potentially dangerous values.
 *
 * @publicApi
 */
class Sanitizer {
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: Sanitizer,
      providedIn: 'root',
      factory: () => null
    });
  }
}

// This default value is when checking the hierarchy for a token.
//
// It means both:
// - the token is not provided by the current injector,
// - only the element injectors should be checked (ie do not check module injectors
//
//          mod1
//         /
//       el1   mod2
//         \  /
//         el2
//
// When requesting el2.injector.get(token), we should check in the following order and return the
// first found value:
// - el2.injector.get(token, default)
// - el1.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) -> do not check the module
// - mod2.injector.get(token, default)
const NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR = {};

/**
 * Asserts that the current stack frame is not within a reactive context. Useful
 * to disallow certain code from running inside a reactive context (see {@link toSignal}).
 *
 * @param debugFn a reference to the function making the assertion (used for the error message).
 *
 * @publicApi
 */
function assertNotInReactiveContext(debugFn, extraContext) {
  // Taking a `Function` instead of a string name here prevents the un-minified name of the function
  // from being retained in the bundle regardless of minification.
  if ((0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.getActiveConsumer)() !== null) {
    throw new RuntimeError(-602 /* RuntimeErrorCode.ASSERTION_NOT_INSIDE_REACTIVE_CONTEXT */, ngDevMode && `${debugFn.name}() cannot be called from within a reactive context.${extraContext ? ` ${extraContext}` : ''}`);
  }
}
const markedFeatures = new Set();
// tslint:disable:ban
/**
 * A guarded `performance.mark` for feature marking.
 *
 * This method exists because while all supported browser and node.js version supported by Angular
 * support performance.mark API. This is not the case for other environments such as JSDOM and
 * Cloudflare workers.
 */
function performanceMarkFeature(feature) {
  if (markedFeatures.has(feature)) {
    return;
  }
  markedFeatures.add(feature);
  performance?.mark?.('mark_feature_usage', {
    detail: {
      feature
    }
  });
}
function noop(...args) {
  // Do nothing.
}
function getNativeRequestAnimationFrame() {
  // Note: the `getNativeRequestAnimationFrame` is used in the `NgZone` class, but we cannot use the
  // `inject` function. The `NgZone` instance may be created manually, and thus the injection
  // context will be unavailable. This might be enough to check whether `requestAnimationFrame` is
  // available because otherwise, we'll fall back to `setTimeout`.
  const isBrowser = typeof _global['requestAnimationFrame'] === 'function';
  // Note: `requestAnimationFrame` is unavailable when the code runs in the Node.js environment. We
  // use `setTimeout` because no changes are required other than checking if the current platform is
  // the browser. `setTimeout` is a well-established API that is available in both environments.
  // `requestAnimationFrame` is used in the browser to coalesce event tasks since event tasks are
  // usually executed within the same rendering frame (but this is more implementation details of
  // browsers).
  let nativeRequestAnimationFrame = _global[isBrowser ? 'requestAnimationFrame' : 'setTimeout'];
  let nativeCancelAnimationFrame = _global[isBrowser ? 'cancelAnimationFrame' : 'clearTimeout'];
  if (typeof Zone !== 'undefined' && nativeRequestAnimationFrame && nativeCancelAnimationFrame) {
    // Note: zone.js sets original implementations on patched APIs behind the
    // `__zone_symbol__OriginalDelegate` key (see `attachOriginToPatched`). Given the following
    // example: `window.requestAnimationFrame.__zone_symbol__OriginalDelegate`; this would return an
    // unpatched implementation of the `requestAnimationFrame`, which isn't intercepted by the
    // Angular zone. We use the unpatched implementation to avoid another change detection when
    // coalescing tasks.
    const unpatchedRequestAnimationFrame = nativeRequestAnimationFrame[Zone.__symbol__('OriginalDelegate')];
    if (unpatchedRequestAnimationFrame) {
      nativeRequestAnimationFrame = unpatchedRequestAnimationFrame;
    }
    const unpatchedCancelAnimationFrame = nativeCancelAnimationFrame[Zone.__symbol__('OriginalDelegate')];
    if (unpatchedCancelAnimationFrame) {
      nativeCancelAnimationFrame = unpatchedCancelAnimationFrame;
    }
  }
  return {
    nativeRequestAnimationFrame,
    nativeCancelAnimationFrame
  };
}
class AsyncStackTaggingZoneSpec {
  constructor(namePrefix, consoleAsyncStackTaggingImpl = console) {
    this.name = 'asyncStackTagging for ' + namePrefix;
    this.createTask = consoleAsyncStackTaggingImpl?.createTask ?? (() => null);
  }
  onScheduleTask(delegate, _current, target, task) {
    task.consoleTask = this.createTask(`Zone - ${task.source || task.type}`);
    return delegate.scheduleTask(target, task);
  }
  onInvokeTask(delegate, _currentZone, targetZone, task, applyThis, applyArgs) {
    let ret;
    if (task.consoleTask) {
      ret = task.consoleTask.run(() => delegate.invokeTask(targetZone, task, applyThis, applyArgs));
    } else {
      ret = delegate.invokeTask(targetZone, task, applyThis, applyArgs);
    }
    return ret;
  }
}

/**
 * An injectable service for executing work inside or outside of the Angular zone.
 *
 * The most common use of this service is to optimize performance when starting a work consisting of
 * one or more asynchronous tasks that don't require UI updates or error handling to be handled by
 * Angular. Such tasks can be kicked off via {@link #runOutsideAngular} and if needed, these tasks
 * can reenter the Angular zone via {@link #run}.
 *
 * <!-- TODO: add/fix links to:
 *   - docs explaining zones and the use of zones in Angular and change-detection
 *   - link to runOutsideAngular/run (throughout this file!)
 *   -->
 *
 * @usageNotes
 * ### Example
 *
 * ```
 * import {Component, NgZone} from '@angular/core';
 * import {NgIf} from '@angular/common';
 *
 * @Component({
 *   selector: 'ng-zone-demo',
 *   template: `
 *     <h2>Demo: NgZone</h2>
 *
 *     <p>Progress: {{progress}}%</p>
 *     <p *ngIf="progress >= 100">Done processing {{label}} of Angular zone!</p>
 *
 *     <button (click)="processWithinAngularZone()">Process within Angular zone</button>
 *     <button (click)="processOutsideOfAngularZone()">Process outside of Angular zone</button>
 *   `,
 * })
 * export class NgZoneDemo {
 *   progress: number = 0;
 *   label: string;
 *
 *   constructor(private _ngZone: NgZone) {}
 *
 *   // Loop inside the Angular zone
 *   // so the UI DOES refresh after each setTimeout cycle
 *   processWithinAngularZone() {
 *     this.label = 'inside';
 *     this.progress = 0;
 *     this._increaseProgress(() => console.log('Inside Done!'));
 *   }
 *
 *   // Loop outside of the Angular zone
 *   // so the UI DOES NOT refresh after each setTimeout cycle
 *   processOutsideOfAngularZone() {
 *     this.label = 'outside';
 *     this.progress = 0;
 *     this._ngZone.runOutsideAngular(() => {
 *       this._increaseProgress(() => {
 *         // reenter the Angular zone and display done
 *         this._ngZone.run(() => { console.log('Outside Done!'); });
 *       });
 *     });
 *   }
 *
 *   _increaseProgress(doneCallback: () => void) {
 *     this.progress += 1;
 *     console.log(`Current progress: ${this.progress}%`);
 *
 *     if (this.progress < 100) {
 *       window.setTimeout(() => this._increaseProgress(doneCallback), 10);
 *     } else {
 *       doneCallback();
 *     }
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class NgZone {
  constructor({
    enableLongStackTrace = false,
    shouldCoalesceEventChangeDetection = false,
    shouldCoalesceRunChangeDetection = false
  }) {
    this.hasPendingMacrotasks = false;
    this.hasPendingMicrotasks = false;
    /**
     * Whether there are no outstanding microtasks or macrotasks.
     */
    this.isStable = true;
    /**
     * Notifies when code enters Angular Zone. This gets fired first on VM Turn.
     */
    this.onUnstable = new EventEmitter(false);
    /**
     * Notifies when there is no more microtasks enqueued in the current VM Turn.
     * This is a hint for Angular to do change detection, which may enqueue more microtasks.
     * For this reason this event can fire multiple times per VM Turn.
     */
    this.onMicrotaskEmpty = new EventEmitter(false);
    /**
     * Notifies when the last `onMicrotaskEmpty` has run and there are no more microtasks, which
     * implies we are about to relinquish VM turn.
     * This event gets called just once.
     */
    this.onStable = new EventEmitter(false);
    /**
     * Notifies that an error has been delivered.
     */
    this.onError = new EventEmitter(false);
    if (typeof Zone == 'undefined') {
      throw new RuntimeError(908 /* RuntimeErrorCode.MISSING_ZONEJS */, ngDevMode && `In this configuration Angular requires Zone.js`);
    }
    Zone.assertZonePatched();
    const self = this;
    self._nesting = 0;
    self._outer = self._inner = Zone.current;
    // AsyncStackTaggingZoneSpec provides `linked stack traces` to show
    // where the async operation is scheduled. For more details, refer
    // to this article, https://developer.chrome.com/blog/devtools-better-angular-debugging/
    // And we only import this AsyncStackTaggingZoneSpec in development mode,
    // in the production mode, the AsyncStackTaggingZoneSpec will be tree shaken away.
    if (ngDevMode) {
      self._inner = self._inner.fork(new AsyncStackTaggingZoneSpec('Angular'));
    }
    if (Zone['TaskTrackingZoneSpec']) {
      self._inner = self._inner.fork(new Zone['TaskTrackingZoneSpec']());
    }
    if (enableLongStackTrace && Zone['longStackTraceZoneSpec']) {
      self._inner = self._inner.fork(Zone['longStackTraceZoneSpec']);
    }
    // if shouldCoalesceRunChangeDetection is true, all tasks including event tasks will be
    // coalesced, so shouldCoalesceEventChangeDetection option is not necessary and can be skipped.
    self.shouldCoalesceEventChangeDetection = !shouldCoalesceRunChangeDetection && shouldCoalesceEventChangeDetection;
    self.shouldCoalesceRunChangeDetection = shouldCoalesceRunChangeDetection;
    self.lastRequestAnimationFrameId = -1;
    self.nativeRequestAnimationFrame = getNativeRequestAnimationFrame().nativeRequestAnimationFrame;
    forkInnerZoneWithAngularBehavior(self);
  }
  /**
    This method checks whether the method call happens within an Angular Zone instance.
  */
  static isInAngularZone() {
    // Zone needs to be checked, because this method might be called even when NoopNgZone is used.
    return typeof Zone !== 'undefined' && Zone.current.get('isAngularZone') === true;
  }
  /**
    Assures that the method is called within the Angular Zone, otherwise throws an error.
  */
  static assertInAngularZone() {
    if (!NgZone.isInAngularZone()) {
      throw new RuntimeError(909 /* RuntimeErrorCode.UNEXPECTED_ZONE_STATE */, ngDevMode && 'Expected to be in Angular Zone, but it is not!');
    }
  }
  /**
    Assures that the method is called outside of the Angular Zone, otherwise throws an error.
  */
  static assertNotInAngularZone() {
    if (NgZone.isInAngularZone()) {
      throw new RuntimeError(909 /* RuntimeErrorCode.UNEXPECTED_ZONE_STATE */, ngDevMode && 'Expected to not be in Angular Zone, but it is!');
    }
  }
  /**
   * Executes the `fn` function synchronously within the Angular zone and returns value returned by
   * the function.
   *
   * Running functions via `run` allows you to reenter Angular zone from a task that was executed
   * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
   *
   * Any future tasks or microtasks scheduled from within this function will continue executing from
   * within the Angular zone.
   *
   * If a synchronous error happens it will be rethrown and not reported via `onError`.
   */
  run(fn, applyThis, applyArgs) {
    return this._inner.run(fn, applyThis, applyArgs);
  }
  /**
   * Executes the `fn` function synchronously within the Angular zone as a task and returns value
   * returned by the function.
   *
   * Running functions via `run` allows you to reenter Angular zone from a task that was executed
   * outside of the Angular zone (typically started via {@link #runOutsideAngular}).
   *
   * Any future tasks or microtasks scheduled from within this function will continue executing from
   * within the Angular zone.
   *
   * If a synchronous error happens it will be rethrown and not reported via `onError`.
   */
  runTask(fn, applyThis, applyArgs, name) {
    const zone = this._inner;
    const task = zone.scheduleEventTask('NgZoneEvent: ' + name, fn, EMPTY_PAYLOAD, noop, noop);
    try {
      return zone.runTask(task, applyThis, applyArgs);
    } finally {
      zone.cancelTask(task);
    }
  }
  /**
   * Same as `run`, except that synchronous errors are caught and forwarded via `onError` and not
   * rethrown.
   */
  runGuarded(fn, applyThis, applyArgs) {
    return this._inner.runGuarded(fn, applyThis, applyArgs);
  }
  /**
   * Executes the `fn` function synchronously in Angular's parent zone and returns value returned by
   * the function.
   *
   * Running functions via {@link #runOutsideAngular} allows you to escape Angular's zone and do
   * work that
   * doesn't trigger Angular change-detection or is subject to Angular's error handling.
   *
   * Any future tasks or microtasks scheduled from within this function will continue executing from
   * outside of the Angular zone.
   *
   * Use {@link #run} to reenter the Angular zone and do work that updates the application model.
   */
  runOutsideAngular(fn) {
    return this._outer.run(fn);
  }
}
const EMPTY_PAYLOAD = {};
function checkStable(zone) {
  // TODO: @JiaLiPassion, should check zone.isCheckStableRunning to prevent
  // re-entry. The case is:
  //
  // @Component({...})
  // export class AppComponent {
  // constructor(private ngZone: NgZone) {
  //   this.ngZone.onStable.subscribe(() => {
  //     this.ngZone.run(() => console.log('stable'););
  //   });
  // }
  //
  // The onStable subscriber run another function inside ngZone
  // which causes `checkStable()` re-entry.
  // But this fix causes some issues in g3, so this fix will be
  // launched in another PR.
  if (zone._nesting == 0 && !zone.hasPendingMicrotasks && !zone.isStable) {
    try {
      zone._nesting++;
      zone.onMicrotaskEmpty.emit(null);
    } finally {
      zone._nesting--;
      if (!zone.hasPendingMicrotasks) {
        try {
          zone.runOutsideAngular(() => zone.onStable.emit(null));
        } finally {
          zone.isStable = true;
        }
      }
    }
  }
}
function delayChangeDetectionForEvents(zone) {
  /**
   * We also need to check _nesting here
   * Consider the following case with shouldCoalesceRunChangeDetection = true
   *
   * ngZone.run(() => {});
   * ngZone.run(() => {});
   *
   * We want the two `ngZone.run()` only trigger one change detection
   * when shouldCoalesceRunChangeDetection is true.
   * And because in this case, change detection run in async way(requestAnimationFrame),
   * so we also need to check the _nesting here to prevent multiple
   * change detections.
   */
  if (zone.isCheckStableRunning || zone.lastRequestAnimationFrameId !== -1) {
    return;
  }
  zone.lastRequestAnimationFrameId = zone.nativeRequestAnimationFrame.call(_global, () => {
    // This is a work around for https://github.com/angular/angular/issues/36839.
    // The core issue is that when event coalescing is enabled it is possible for microtasks
    // to get flushed too early (As is the case with `Promise.then`) between the
    // coalescing eventTasks.
    //
    // To workaround this we schedule a "fake" eventTask before we process the
    // coalescing eventTasks. The benefit of this is that the "fake" container eventTask
    //  will prevent the microtasks queue from getting drained in between the coalescing
    // eventTask execution.
    if (!zone.fakeTopEventTask) {
      zone.fakeTopEventTask = Zone.root.scheduleEventTask('fakeTopEventTask', () => {
        zone.lastRequestAnimationFrameId = -1;
        updateMicroTaskStatus(zone);
        zone.isCheckStableRunning = true;
        checkStable(zone);
        zone.isCheckStableRunning = false;
      }, undefined, () => {}, () => {});
    }
    zone.fakeTopEventTask.invoke();
  });
  updateMicroTaskStatus(zone);
}
function forkInnerZoneWithAngularBehavior(zone) {
  const delayChangeDetectionForEventsDelegate = () => {
    delayChangeDetectionForEvents(zone);
  };
  zone._inner = zone._inner.fork({
    name: 'angular',
    properties: {
      'isAngularZone': true
    },
    onInvokeTask: (delegate, current, target, task, applyThis, applyArgs) => {
      if (shouldBeIgnoredByZone(applyArgs)) {
        return delegate.invokeTask(target, task, applyThis, applyArgs);
      }
      try {
        onEnter(zone);
        return delegate.invokeTask(target, task, applyThis, applyArgs);
      } finally {
        if (zone.shouldCoalesceEventChangeDetection && task.type === 'eventTask' || zone.shouldCoalesceRunChangeDetection) {
          delayChangeDetectionForEventsDelegate();
        }
        onLeave(zone);
      }
    },
    onInvoke: (delegate, current, target, callback, applyThis, applyArgs, source) => {
      try {
        onEnter(zone);
        return delegate.invoke(target, callback, applyThis, applyArgs, source);
      } finally {
        if (zone.shouldCoalesceRunChangeDetection) {
          delayChangeDetectionForEventsDelegate();
        }
        onLeave(zone);
      }
    },
    onHasTask: (delegate, current, target, hasTaskState) => {
      delegate.hasTask(target, hasTaskState);
      if (current === target) {
        // We are only interested in hasTask events which originate from our zone
        // (A child hasTask event is not interesting to us)
        if (hasTaskState.change == 'microTask') {
          zone._hasPendingMicrotasks = hasTaskState.microTask;
          updateMicroTaskStatus(zone);
          checkStable(zone);
        } else if (hasTaskState.change == 'macroTask') {
          zone.hasPendingMacrotasks = hasTaskState.macroTask;
        }
      }
    },
    onHandleError: (delegate, current, target, error) => {
      delegate.handleError(target, error);
      zone.runOutsideAngular(() => zone.onError.emit(error));
      return false;
    }
  });
}
function updateMicroTaskStatus(zone) {
  if (zone._hasPendingMicrotasks || (zone.shouldCoalesceEventChangeDetection || zone.shouldCoalesceRunChangeDetection) && zone.lastRequestAnimationFrameId !== -1) {
    zone.hasPendingMicrotasks = true;
  } else {
    zone.hasPendingMicrotasks = false;
  }
}
function onEnter(zone) {
  zone._nesting++;
  if (zone.isStable) {
    zone.isStable = false;
    zone.onUnstable.emit(null);
  }
}
function onLeave(zone) {
  zone._nesting--;
  checkStable(zone);
}
/**
 * Provides a noop implementation of `NgZone` which does nothing. This zone requires explicit calls
 * to framework to perform rendering.
 */
class NoopNgZone {
  constructor() {
    this.hasPendingMicrotasks = false;
    this.hasPendingMacrotasks = false;
    this.isStable = true;
    this.onUnstable = new EventEmitter();
    this.onMicrotaskEmpty = new EventEmitter();
    this.onStable = new EventEmitter();
    this.onError = new EventEmitter();
  }
  run(fn, applyThis, applyArgs) {
    return fn.apply(applyThis, applyArgs);
  }
  runGuarded(fn, applyThis, applyArgs) {
    return fn.apply(applyThis, applyArgs);
  }
  runOutsideAngular(fn) {
    return fn();
  }
  runTask(fn, applyThis, applyArgs, name) {
    return fn.apply(applyThis, applyArgs);
  }
}
function shouldBeIgnoredByZone(applyArgs) {
  if (!Array.isArray(applyArgs)) {
    return false;
  }
  // We should only ever get 1 arg passed through to invokeTask.
  // Short circuit here incase that behavior changes.
  if (applyArgs.length !== 1) {
    return false;
  }
  // Prevent triggering change detection when the __ignore_ng_zone__ flag is detected.
  return applyArgs[0].data?.['__ignore_ng_zone__'] === true;
}
function getNgZone(ngZoneToUse = 'zone.js', options) {
  if (ngZoneToUse === 'noop') {
    return new NoopNgZone();
  }
  if (ngZoneToUse === 'zone.js') {
    return new NgZone(options);
  }
  return ngZoneToUse;
}

/**
 * The phase to run an `afterRender` or `afterNextRender` callback in.
 *
 * Callbacks in the same phase run in the order they are registered. Phases run in the
 * following order after each render:
 *
 *   1. `AfterRenderPhase.EarlyRead`
 *   2. `AfterRenderPhase.Write`
 *   3. `AfterRenderPhase.MixedReadWrite`
 *   4. `AfterRenderPhase.Read`
 *
 * Angular is unable to verify or enforce that phases are used correctly, and instead
 * relies on each developer to follow the guidelines documented for each value and
 * carefully choose the appropriate one, refactoring their code if necessary. By doing
 * so, Angular is better able to minimize the performance degradation associated with
 * manual DOM access, ensuring the best experience for the end users of your application
 * or library.
 *
 * @developerPreview
 */
var AfterRenderPhase;
(function (AfterRenderPhase) {
  /**
   * Use `AfterRenderPhase.EarlyRead` for callbacks that only need to **read** from the
   * DOM before a subsequent `AfterRenderPhase.Write` callback, for example to perform
   * custom layout that the browser doesn't natively support. **Never** use this phase
   * for callbacks that can write to the DOM or when `AfterRenderPhase.Read` is adequate.
   *
   * <div class="alert is-important">
   *
   * Using this value can degrade performance.
   * Instead, prefer using built-in browser functionality when possible.
   *
   * </div>
   */
  AfterRenderPhase[AfterRenderPhase["EarlyRead"] = 0] = "EarlyRead";
  /**
   * Use `AfterRenderPhase.Write` for callbacks that only **write** to the DOM. **Never**
   * use this phase for callbacks that can read from the DOM.
   */
  AfterRenderPhase[AfterRenderPhase["Write"] = 1] = "Write";
  /**
   * Use `AfterRenderPhase.MixedReadWrite` for callbacks that read from or write to the
   * DOM, that haven't been refactored to use a different phase. **Never** use this phase
   * for callbacks that can use a different phase instead.
   *
   * <div class="alert is-critical">
   *
   * Using this value can **significantly** degrade performance.
   * Instead, prefer refactoring into multiple callbacks using a more specific phase.
   *
   * </div>
   */
  AfterRenderPhase[AfterRenderPhase["MixedReadWrite"] = 2] = "MixedReadWrite";
  /**
   * Use `AfterRenderPhase.Read` for callbacks that only **read** from the DOM. **Never**
   * use this phase for callbacks that can write to the DOM.
   */
  AfterRenderPhase[AfterRenderPhase["Read"] = 3] = "Read";
})(AfterRenderPhase || (AfterRenderPhase = {}));
/** `AfterRenderRef` that does nothing. */
const NOOP_AFTER_RENDER_REF = {
  destroy() {}
};
/**
 * Register a callback to run once before any userspace `afterRender` or
 * `afterNextRender` callbacks.
 *
 * This function should almost always be used instead of `afterRender` or
 * `afterNextRender` for implementing framework functionality. Consider:
 *
 *   1.) `AfterRenderPhase.EarlyRead` is intended to be used for implementing
 *       custom layout. If the framework itself mutates the DOM after *any*
 *       `AfterRenderPhase.EarlyRead` callbacks are run, the phase can no
 *       longer reliably serve its purpose.
 *
 *   2.) Importing `afterRender` in the framework can reduce the ability for it
 *       to be tree-shaken, and the framework shouldn't need much of the behavior.
 */
function internalAfterNextRender(callback, options) {
  const injector = options?.injector ?? inject(Injector);
  // Similarly to the public `afterNextRender` function, an internal one
  // is only invoked in a browser as long as the runOnServer option is not set.
  if (!options?.runOnServer && !isPlatformBrowser(injector)) return;
  const afterRenderEventManager = injector.get(AfterRenderEventManager);
  afterRenderEventManager.internalCallbacks.push(callback);
}
/**
 * Register a callback to be invoked each time the application
 * finishes rendering.
 *
 * <div class="alert is-critical">
 *
 * You should always explicitly specify a non-default [phase](api/core/AfterRenderPhase), or you
 * risk significant performance degradation.
 *
 * </div>
 *
 * Note that the callback will run
 * - in the order it was registered
 * - once per render
 * - on browser platforms only
 *
 * <div class="alert is-important">
 *
 * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
 * You must use caution when directly reading or writing the DOM and layout.
 *
 * </div>
 *
 * @param callback A callback function to register
 *
 * @usageNotes
 *
 * Use `afterRender` to read or write the DOM after each render.
 *
 * ### Example
 * ```ts
 * @Component({
 *   selector: 'my-cmp',
 *   template: `<span #content>{{ ... }}</span>`,
 * })
 * export class MyComponent {
 *   @ViewChild('content') contentRef: ElementRef;
 *
 *   constructor() {
 *     afterRender(() => {
 *       console.log('content height: ' + this.contentRef.nativeElement.scrollHeight);
 *     }, {phase: AfterRenderPhase.Read});
 *   }
 * }
 * ```
 *
 * @developerPreview
 */
function afterRender(callback, options) {
  ngDevMode && assertNotInReactiveContext(afterRender, 'Call `afterRender` outside of a reactive context. For example, schedule the render ' + 'callback inside the component constructor`.');
  !options && assertInInjectionContext(afterRender);
  const injector = options?.injector ?? inject(Injector);
  if (!isPlatformBrowser(injector)) {
    return NOOP_AFTER_RENDER_REF;
  }
  performanceMarkFeature('NgAfterRender');
  const afterRenderEventManager = injector.get(AfterRenderEventManager);
  // Lazily initialize the handler implementation, if necessary. This is so that it can be
  // tree-shaken if `afterRender` and `afterNextRender` aren't used.
  const callbackHandler = afterRenderEventManager.handler ??= new AfterRenderCallbackHandlerImpl();
  const phase = options?.phase ?? AfterRenderPhase.MixedReadWrite;
  const destroy = () => {
    callbackHandler.unregister(instance);
    unregisterFn();
  };
  const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
  const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, callback));
  callbackHandler.register(instance);
  return {
    destroy
  };
}
/**
 * Register a callback to be invoked the next time the application
 * finishes rendering.
 *
 * <div class="alert is-critical">
 *
 * You should always explicitly specify a non-default [phase](api/core/AfterRenderPhase), or you
 * risk significant performance degradation.
 *
 * </div>
 *
 * Note that the callback will run
 * - in the order it was registered
 * - on browser platforms only
 *
 * <div class="alert is-important">
 *
 * Components are not guaranteed to be [hydrated](guide/hydration) before the callback runs.
 * You must use caution when directly reading or writing the DOM and layout.
 *
 * </div>
 *
 * @param callback A callback function to register
 *
 * @usageNotes
 *
 * Use `afterNextRender` to read or write the DOM once,
 * for example to initialize a non-Angular library.
 *
 * ### Example
 * ```ts
 * @Component({
 *   selector: 'my-chart-cmp',
 *   template: `<div #chart>{{ ... }}</div>`,
 * })
 * export class MyChartCmp {
 *   @ViewChild('chart') chartRef: ElementRef;
 *   chart: MyChart|null;
 *
 *   constructor() {
 *     afterNextRender(() => {
 *       this.chart = new MyChart(this.chartRef.nativeElement);
 *     }, {phase: AfterRenderPhase.Write});
 *   }
 * }
 * ```
 *
 * @developerPreview
 */
function afterNextRender(callback, options) {
  !options && assertInInjectionContext(afterNextRender);
  const injector = options?.injector ?? inject(Injector);
  if (!isPlatformBrowser(injector)) {
    return NOOP_AFTER_RENDER_REF;
  }
  performanceMarkFeature('NgAfterNextRender');
  const afterRenderEventManager = injector.get(AfterRenderEventManager);
  // Lazily initialize the handler implementation, if necessary. This is so that it can be
  // tree-shaken if `afterRender` and `afterNextRender` aren't used.
  const callbackHandler = afterRenderEventManager.handler ??= new AfterRenderCallbackHandlerImpl();
  const phase = options?.phase ?? AfterRenderPhase.MixedReadWrite;
  const destroy = () => {
    callbackHandler.unregister(instance);
    unregisterFn();
  };
  const unregisterFn = injector.get(DestroyRef).onDestroy(destroy);
  const instance = runInInjectionContext(injector, () => new AfterRenderCallback(phase, () => {
    destroy();
    callback();
  }));
  callbackHandler.register(instance);
  return {
    destroy
  };
}
/**
 * A wrapper around a function to be used as an after render callback.
 */
class AfterRenderCallback {
  constructor(phase, callbackFn) {
    this.phase = phase;
    this.callbackFn = callbackFn;
    this.zone = inject(NgZone);
    this.errorHandler = inject(ErrorHandler, {
      optional: true
    });
    // Registering a callback will notify the scheduler.
    inject(ChangeDetectionScheduler, {
      optional: true
    })?.notify(1 /* NotificationType.AfterRenderHooks */);
  }
  invoke() {
    try {
      this.zone.runOutsideAngular(this.callbackFn);
    } catch (err) {
      this.errorHandler?.handleError(err);
    }
  }
}
/**
 * Core functionality for `afterRender` and `afterNextRender`. Kept separate from
 * `AfterRenderEventManager` for tree-shaking.
 */
class AfterRenderCallbackHandlerImpl {
  constructor() {
    this.executingCallbacks = false;
    this.buckets = {
      // Note: the order of these keys controls the order the phases are run.
      [AfterRenderPhase.EarlyRead]: new Set(),
      [AfterRenderPhase.Write]: new Set(),
      [AfterRenderPhase.MixedReadWrite]: new Set(),
      [AfterRenderPhase.Read]: new Set()
    };
    this.deferredCallbacks = new Set();
  }
  register(callback) {
    // If we're currently running callbacks, new callbacks should be deferred
    // until the next render operation.
    const target = this.executingCallbacks ? this.deferredCallbacks : this.buckets[callback.phase];
    target.add(callback);
  }
  unregister(callback) {
    this.buckets[callback.phase].delete(callback);
    this.deferredCallbacks.delete(callback);
  }
  execute() {
    this.executingCallbacks = true;
    for (const bucket of Object.values(this.buckets)) {
      for (const callback of bucket) {
        callback.invoke();
      }
    }
    this.executingCallbacks = false;
    for (const callback of this.deferredCallbacks) {
      this.buckets[callback.phase].add(callback);
    }
    this.deferredCallbacks.clear();
  }
  destroy() {
    for (const bucket of Object.values(this.buckets)) {
      bucket.clear();
    }
    this.deferredCallbacks.clear();
  }
}
/**
 * Implements core timing for `afterRender` and `afterNextRender` events.
 * Delegates to an optional `AfterRenderCallbackHandler` for implementation.
 */
class AfterRenderEventManager {
  constructor() {
    /* @internal */
    this.handler = null;
    /* @internal */
    this.internalCallbacks = [];
  }
  /**
   * Executes internal and user-provided callbacks.
   */
  execute() {
    this.executeInternalCallbacks();
    this.handler?.execute();
  }
  executeInternalCallbacks() {
    // Note: internal callbacks power `internalAfterNextRender`. Since internal callbacks
    // are fairly trivial, they are kept separate so that `AfterRenderCallbackHandlerImpl`
    // can still be tree-shaken unless used by the application.
    const callbacks = [...this.internalCallbacks];
    this.internalCallbacks.length = 0;
    for (const callback of callbacks) {
      callback();
    }
  }
  ngOnDestroy() {
    this.handler?.destroy();
    this.handler = null;
    this.internalCallbacks.length = 0;
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: AfterRenderEventManager,
      providedIn: 'root',
      factory: () => new AfterRenderEventManager()
    });
  }
}
function isModuleWithProviders(value) {
  return value.ngModule !== undefined;
}
function isNgModule(value) {
  return !!getNgModuleDef(value);
}
function isPipe(value) {
  return !!getPipeDef$1(value);
}
function isDirective(value) {
  return !!getDirectiveDef(value);
}
function isComponent(value) {
  return !!getComponentDef(value);
}
function getDependencyTypeForError(type) {
  if (getComponentDef(type)) return 'component';
  if (getDirectiveDef(type)) return 'directive';
  if (getPipeDef$1(type)) return 'pipe';
  return 'type';
}
function verifyStandaloneImport(depType, importingType) {
  if (isForwardRef(depType)) {
    depType = resolveForwardRef(depType);
    if (!depType) {
      throw new Error(`Expected forwardRef function, imported from "${stringifyForError(importingType)}", to return a standalone entity or NgModule but got "${stringifyForError(depType) || depType}".`);
    }
  }
  if (getNgModuleDef(depType) == null) {
    const def = getComponentDef(depType) || getDirectiveDef(depType) || getPipeDef$1(depType);
    if (def != null) {
      // if a component, directive or pipe is imported make sure that it is standalone
      if (!def.standalone) {
        throw new Error(`The "${stringifyForError(depType)}" ${getDependencyTypeForError(depType)}, imported from "${stringifyForError(importingType)}", is not standalone. Did you forget to add the standalone: true flag?`);
      }
    } else {
      // it can be either a module with provider or an unknown (not annotated) type
      if (isModuleWithProviders(depType)) {
        throw new Error(`A module with providers was imported from "${stringifyForError(importingType)}". Modules with providers are not supported in standalone components imports.`);
      } else {
        throw new Error(`The "${stringifyForError(depType)}" type, imported from "${stringifyForError(importingType)}", must be a standalone component / directive / pipe or an NgModule. Did you forget to add the required @Component / @Directive / @Pipe or @NgModule annotation?`);
      }
    }
  }
}

/**
 * Indicates whether to use the runtime dependency tracker for scope calculation in JIT compilation.
 * The value "false" means the old code path based on patching scope info into the types will be
 * used.
 *
 * @deprecated For migration purposes only, to be removed soon.
 */
const USE_RUNTIME_DEPS_TRACKER_FOR_JIT = true;
/**
 * An implementation of DepsTrackerApi which will be used for JIT and local compilation.
 */
class DepsTracker {
  constructor() {
    this.ownerNgModule = new Map();
    this.ngModulesWithSomeUnresolvedDecls = new Set();
    this.ngModulesScopeCache = new Map();
    this.standaloneComponentsScopeCache = new Map();
  }
  /**
   * Attempts to resolve ng module's forward ref declarations as much as possible and add them to
   * the `ownerNgModule` map. This method normally should be called after the initial parsing when
   * all the forward refs are resolved (e.g., when trying to render a component)
   */
  resolveNgModulesDecls() {
    if (this.ngModulesWithSomeUnresolvedDecls.size === 0) {
      return;
    }
    for (const moduleType of this.ngModulesWithSomeUnresolvedDecls) {
      const def = getNgModuleDef(moduleType);
      if (def?.declarations) {
        for (const decl of maybeUnwrapFn(def.declarations)) {
          if (isComponent(decl)) {
            this.ownerNgModule.set(decl, moduleType);
          }
        }
      }
    }
    this.ngModulesWithSomeUnresolvedDecls.clear();
  }
  /** @override */
  getComponentDependencies(type, rawImports) {
    this.resolveNgModulesDecls();
    const def = getComponentDef(type);
    if (def === null) {
      throw new Error(`Attempting to get component dependencies for a type that is not a component: ${type}`);
    }
    if (def.standalone) {
      const scope = this.getStandaloneComponentScope(type, rawImports);
      if (scope.compilation.isPoisoned) {
        return {
          dependencies: []
        };
      }
      return {
        dependencies: [...scope.compilation.directives, ...scope.compilation.pipes, ...scope.compilation.ngModules]
      };
    } else {
      if (!this.ownerNgModule.has(type)) {
        // This component is orphan! No need to handle the error since the component rendering
        // pipeline (e.g., view_container_ref) will check for this error based on configs.
        return {
          dependencies: []
        };
      }
      const scope = this.getNgModuleScope(this.ownerNgModule.get(type));
      if (scope.compilation.isPoisoned) {
        return {
          dependencies: []
        };
      }
      return {
        dependencies: [...scope.compilation.directives, ...scope.compilation.pipes]
      };
    }
  }
  /**
   * @override
   * This implementation does not make use of param scopeInfo since it assumes the scope info is
   * already added to the type itself through methods like {@link ɵɵsetNgModuleScope}
   */
  registerNgModule(type, scopeInfo) {
    if (!isNgModule(type)) {
      throw new Error(`Attempting to register a Type which is not NgModule as NgModule: ${type}`);
    }
    // Lazily process the NgModules later when needed.
    this.ngModulesWithSomeUnresolvedDecls.add(type);
  }
  /** @override */
  clearScopeCacheFor(type) {
    this.ngModulesScopeCache.delete(type);
    this.standaloneComponentsScopeCache.delete(type);
  }
  /** @override */
  getNgModuleScope(type) {
    if (this.ngModulesScopeCache.has(type)) {
      return this.ngModulesScopeCache.get(type);
    }
    const scope = this.computeNgModuleScope(type);
    this.ngModulesScopeCache.set(type, scope);
    return scope;
  }
  /** Compute NgModule scope afresh. */
  computeNgModuleScope(type) {
    const def = getNgModuleDef(type, true);
    const scope = {
      exported: {
        directives: new Set(),
        pipes: new Set()
      },
      compilation: {
        directives: new Set(),
        pipes: new Set()
      }
    };
    // Analyzing imports
    for (const imported of maybeUnwrapFn(def.imports)) {
      if (isNgModule(imported)) {
        const importedScope = this.getNgModuleScope(imported);
        // When this module imports another, the imported module's exported directives and pipes
        // are added to the compilation scope of this module.
        addSet(importedScope.exported.directives, scope.compilation.directives);
        addSet(importedScope.exported.pipes, scope.compilation.pipes);
      } else if (isStandalone(imported)) {
        if (isDirective(imported) || isComponent(imported)) {
          scope.compilation.directives.add(imported);
        } else if (isPipe(imported)) {
          scope.compilation.pipes.add(imported);
        } else {
          // The standalone thing is neither a component nor a directive nor a pipe ... (what?)
          throw new RuntimeError(1000 /* RuntimeErrorCode.RUNTIME_DEPS_INVALID_IMPORTED_TYPE */, 'The standalone imported type is neither a component nor a directive nor a pipe');
        }
      } else {
        // The import is neither a module nor a module-with-providers nor a standalone thing. This
        // is going to be an error. So we short circuit.
        scope.compilation.isPoisoned = true;
        break;
      }
    }
    // Analyzing declarations
    if (!scope.compilation.isPoisoned) {
      for (const decl of maybeUnwrapFn(def.declarations)) {
        // Cannot declare another NgModule or a standalone thing
        if (isNgModule(decl) || isStandalone(decl)) {
          scope.compilation.isPoisoned = true;
          break;
        }
        if (isPipe(decl)) {
          scope.compilation.pipes.add(decl);
        } else {
          // decl is either a directive or a component. The component may not yet have the ɵcmp due
          // to async compilation.
          scope.compilation.directives.add(decl);
        }
      }
    }
    // Analyzing exports
    for (const exported of maybeUnwrapFn(def.exports)) {
      if (isNgModule(exported)) {
        // When this module exports another, the exported module's exported directives and pipes
        // are added to both the compilation and exported scopes of this module.
        const exportedScope = this.getNgModuleScope(exported);
        // Based on the current logic there is no way to have poisoned exported scope. So no need to
        // check for it.
        addSet(exportedScope.exported.directives, scope.exported.directives);
        addSet(exportedScope.exported.pipes, scope.exported.pipes);
        // Some test toolings which run in JIT mode depend on this behavior that the exported scope
        // should also be present in the compilation scope, even though AoT does not support this
        // and it is also in odds with NgModule metadata definitions. Without this some tests in
        // Google will fail.
        addSet(exportedScope.exported.directives, scope.compilation.directives);
        addSet(exportedScope.exported.pipes, scope.compilation.pipes);
      } else if (isPipe(exported)) {
        scope.exported.pipes.add(exported);
      } else {
        scope.exported.directives.add(exported);
      }
    }
    return scope;
  }
  /** @override */
  getStandaloneComponentScope(type, rawImports) {
    if (this.standaloneComponentsScopeCache.has(type)) {
      return this.standaloneComponentsScopeCache.get(type);
    }
    const ans = this.computeStandaloneComponentScope(type, rawImports);
    this.standaloneComponentsScopeCache.set(type, ans);
    return ans;
  }
  computeStandaloneComponentScope(type, rawImports) {
    const ans = {
      compilation: {
        // Standalone components are always able to self-reference.
        directives: new Set([type]),
        pipes: new Set(),
        ngModules: new Set()
      }
    };
    for (const rawImport of flatten(rawImports ?? [])) {
      const imported = resolveForwardRef(rawImport);
      try {
        verifyStandaloneImport(imported, type);
      } catch (e) {
        // Short-circuit if an import is not valid
        ans.compilation.isPoisoned = true;
        return ans;
      }
      if (isNgModule(imported)) {
        ans.compilation.ngModules.add(imported);
        const importedScope = this.getNgModuleScope(imported);
        // Short-circuit if an imported NgModule has corrupted exported scope.
        if (importedScope.exported.isPoisoned) {
          ans.compilation.isPoisoned = true;
          return ans;
        }
        addSet(importedScope.exported.directives, ans.compilation.directives);
        addSet(importedScope.exported.pipes, ans.compilation.pipes);
      } else if (isPipe(imported)) {
        ans.compilation.pipes.add(imported);
      } else if (isDirective(imported) || isComponent(imported)) {
        ans.compilation.directives.add(imported);
      } else {
        // The imported thing is not module/pipe/directive/component, so we error and short-circuit
        // here
        ans.compilation.isPoisoned = true;
        return ans;
      }
    }
    return ans;
  }
  /** @override */
  isOrphanComponent(cmp) {
    const def = getComponentDef(cmp);
    if (!def || def.standalone) {
      return false;
    }
    this.resolveNgModulesDecls();
    return !this.ownerNgModule.has(cmp);
  }
}
function addSet(sourceSet, targetSet) {
  for (const m of sourceSet) {
    targetSet.add(m);
  }
}
/** The deps tracker to be used in the current Angular app in dev mode. */
const depsTracker = new DepsTracker();
const TEST_ONLY = {
  DepsTracker
};

/**
 * Compute the static styling (class/style) from `TAttributes`.
 *
 * This function should be called during `firstCreatePass` only.
 *
 * @param tNode The `TNode` into which the styling information should be loaded.
 * @param attrs `TAttributes` containing the styling information.
 * @param writeToHost Where should the resulting static styles be written?
 *   - `false` Write to `TNode.stylesWithoutHost` / `TNode.classesWithoutHost`
 *   - `true` Write to `TNode.styles` / `TNode.classes`
 */
function computeStaticStyling(tNode, attrs, writeToHost) {
  ngDevMode && assertFirstCreatePass(getTView(), 'Expecting to be called in first template pass only');
  let styles = writeToHost ? tNode.styles : null;
  let classes = writeToHost ? tNode.classes : null;
  let mode = 0;
  if (attrs !== null) {
    for (let i = 0; i < attrs.length; i++) {
      const value = attrs[i];
      if (typeof value === 'number') {
        mode = value;
      } else if (mode == 1 /* AttributeMarker.Classes */) {
        classes = concatStringsWithSpace(classes, value);
      } else if (mode == 2 /* AttributeMarker.Styles */) {
        const style = value;
        const styleValue = attrs[++i];
        styles = concatStringsWithSpace(styles, style + ': ' + styleValue + ';');
      }
    }
  }
  writeToHost ? tNode.styles = styles : tNode.stylesWithoutHost = styles;
  writeToHost ? tNode.classes = classes : tNode.classesWithoutHost = classes;
}
class ComponentFactoryResolver extends ComponentFactoryResolver$1 {
  /**
   * @param ngModule The NgModuleRef to which all resolved factories are bound.
   */
  constructor(ngModule) {
    super();
    this.ngModule = ngModule;
  }
  resolveComponentFactory(component) {
    ngDevMode && assertComponentType(component);
    const componentDef = getComponentDef(component);
    return new ComponentFactory(componentDef, this.ngModule);
  }
}
function toRefArray(map) {
  const array = [];
  for (const publicName in map) {
    if (!map.hasOwnProperty(publicName)) {
      continue;
    }
    const value = map[publicName];
    if (value === undefined) {
      continue;
    }
    array.push({
      propName: Array.isArray(value) ? value[0] : value,
      templateName: publicName
    });
  }
  return array;
}
function getNamespace(elementName) {
  const name = elementName.toLowerCase();
  return name === 'svg' ? SVG_NAMESPACE : name === 'math' ? MATH_ML_NAMESPACE : null;
}
/**
 * Injector that looks up a value using a specific injector, before falling back to the module
 * injector. Used primarily when creating components or embedded views dynamically.
 */
class ChainedInjector {
  constructor(injector, parentInjector) {
    this.injector = injector;
    this.parentInjector = parentInjector;
  }
  get(token, notFoundValue, flags) {
    flags = convertToBitFlags(flags);
    const value = this.injector.get(token, NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR, flags);
    if (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR || notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR) {
      // Return the value from the root element injector when
      // - it provides it
      //   (value !== NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
      // - the module injector should not be checked
      //   (notFoundValue === NOT_FOUND_CHECK_ONLY_ELEMENT_INJECTOR)
      return value;
    }
    return this.parentInjector.get(token, notFoundValue, flags);
  }
}
/**
 * ComponentFactory interface implementation.
 */
class ComponentFactory extends ComponentFactory$1 {
  get inputs() {
    const componentDef = this.componentDef;
    const inputTransforms = componentDef.inputTransforms;
    const refArray = toRefArray(componentDef.inputs);
    if (inputTransforms !== null) {
      for (const input of refArray) {
        if (inputTransforms.hasOwnProperty(input.propName)) {
          input.transform = inputTransforms[input.propName];
        }
      }
    }
    return refArray;
  }
  get outputs() {
    return toRefArray(this.componentDef.outputs);
  }
  /**
   * @param componentDef The component definition.
   * @param ngModule The NgModuleRef to which the factory is bound.
   */
  constructor(componentDef, ngModule) {
    super();
    this.componentDef = componentDef;
    this.ngModule = ngModule;
    this.componentType = componentDef.type;
    this.selector = stringifyCSSSelectorList(componentDef.selectors);
    this.ngContentSelectors = componentDef.ngContentSelectors ? componentDef.ngContentSelectors : [];
    this.isBoundToModule = !!ngModule;
  }
  create(injector, projectableNodes, rootSelectorOrNode, environmentInjector) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      // Check if the component is orphan
      if (ngDevMode && (typeof ngJitMode === 'undefined' || ngJitMode) && this.componentDef.debugInfo?.forbidOrphanRendering) {
        if (depsTracker.isOrphanComponent(this.componentType)) {
          throw new RuntimeError(1001 /* RuntimeErrorCode.RUNTIME_DEPS_ORPHAN_COMPONENT */, `Orphan component found! Trying to render the component ${debugStringifyTypeForError(this.componentType)} without first loading the NgModule that declares it. It is recommended to make this component standalone in order to avoid this error. If this is not possible now, import the component's NgModule in the appropriate NgModule, or the standalone component in which you are trying to render this component. If this is a lazy import, load the NgModule lazily as well and use its module injector.`);
        }
      }
      environmentInjector = environmentInjector || this.ngModule;
      let realEnvironmentInjector = environmentInjector instanceof EnvironmentInjector ? environmentInjector : environmentInjector?.injector;
      if (realEnvironmentInjector && this.componentDef.getStandaloneInjector !== null) {
        realEnvironmentInjector = this.componentDef.getStandaloneInjector(realEnvironmentInjector) || realEnvironmentInjector;
      }
      const rootViewInjector = realEnvironmentInjector ? new ChainedInjector(injector, realEnvironmentInjector) : injector;
      const rendererFactory = rootViewInjector.get(RendererFactory2, null);
      if (rendererFactory === null) {
        throw new RuntimeError(407 /* RuntimeErrorCode.RENDERER_NOT_FOUND */, ngDevMode && 'Angular was not able to inject a renderer (RendererFactory2). ' + 'Likely this is due to a broken DI hierarchy. ' + 'Make sure that any injector used to create this component has a correct parent.');
      }
      const sanitizer = rootViewInjector.get(Sanitizer, null);
      const afterRenderEventManager = rootViewInjector.get(AfterRenderEventManager, null);
      const changeDetectionScheduler = rootViewInjector.get(ChangeDetectionScheduler, null);
      const environment = {
        rendererFactory,
        sanitizer,
        // We don't use inline effects (yet).
        inlineEffectRunner: null,
        afterRenderEventManager,
        changeDetectionScheduler
      };
      const hostRenderer = rendererFactory.createRenderer(null, this.componentDef);
      // Determine a tag name used for creating host elements when this component is created
      // dynamically. Default to 'div' if this component did not specify any tag name in its
      // selector.
      const elementName = this.componentDef.selectors[0][0] || 'div';
      const hostRNode = rootSelectorOrNode ? locateHostElement(hostRenderer, rootSelectorOrNode, this.componentDef.encapsulation, rootViewInjector) : createElementNode(hostRenderer, elementName, getNamespace(elementName));
      let rootFlags = 512 /* LViewFlags.IsRoot */;
      if (this.componentDef.signals) {
        rootFlags |= 4096 /* LViewFlags.SignalView */;
      } else if (!this.componentDef.onPush) {
        rootFlags |= 16 /* LViewFlags.CheckAlways */;
      }
      let hydrationInfo = null;
      if (hostRNode !== null) {
        hydrationInfo = retrieveHydrationInfo(hostRNode, rootViewInjector, true /* isRootView */);
      }
      // Create the root view. Uses empty TView and ContentTemplate.
      const rootTView = createTView(0 /* TViewType.Root */, null, null, 1, 0, null, null, null, null, null, null);
      const rootLView = createLView(null, rootTView, null, rootFlags, null, null, environment, hostRenderer, rootViewInjector, null, hydrationInfo);
      // rootView is the parent when bootstrapping
      // TODO(misko): it looks like we are entering view here but we don't really need to as
      // `renderView` does that. However as the code is written it is needed because
      // `createRootComponentView` and `createRootComponent` both read global state. Fixing those
      // issues would allow us to drop this.
      enterView(rootLView);
      let component;
      let tElementNode;
      try {
        const rootComponentDef = this.componentDef;
        let rootDirectives;
        let hostDirectiveDefs = null;
        if (rootComponentDef.findHostDirectiveDefs) {
          rootDirectives = [];
          hostDirectiveDefs = new Map();
          rootComponentDef.findHostDirectiveDefs(rootComponentDef, rootDirectives, hostDirectiveDefs);
          rootDirectives.push(rootComponentDef);
          ngDevMode && assertNoDuplicateDirectives(rootDirectives);
        } else {
          rootDirectives = [rootComponentDef];
        }
        const hostTNode = createRootComponentTNode(rootLView, hostRNode);
        const componentView = createRootComponentView(hostTNode, hostRNode, rootComponentDef, rootDirectives, rootLView, environment, hostRenderer);
        tElementNode = getTNode(rootTView, HEADER_OFFSET);
        // TODO(crisbeto): in practice `hostRNode` should always be defined, but there are some
        // tests where the renderer is mocked out and `undefined` is returned. We should update the
        // tests so that this check can be removed.
        if (hostRNode) {
          setRootNodeAttributes(hostRenderer, rootComponentDef, hostRNode, rootSelectorOrNode);
        }
        if (projectableNodes !== undefined) {
          projectNodes(tElementNode, this.ngContentSelectors, projectableNodes);
        }
        // TODO: should LifecycleHooksFeature and other host features be generated by the compiler
        // and executed here? Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
        component = createRootComponent(componentView, rootComponentDef, rootDirectives, hostDirectiveDefs, rootLView, [LifecycleHooksFeature]);
        renderView(rootTView, rootLView, null);
      } finally {
        leaveView();
      }
      return new ComponentRef(this.componentType, component, createElementRef(tElementNode, rootLView), rootLView, tElementNode);
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
}
/**
 * Represents an instance of a Component created via a {@link ComponentFactory}.
 *
 * `ComponentRef` provides access to the Component Instance as well other objects related to this
 * Component Instance and allows you to destroy the Component Instance via the {@link #destroy}
 * method.
 *
 */
class ComponentRef extends ComponentRef$1 {
  constructor(componentType, instance, location, _rootLView, _tNode) {
    super();
    this.location = location;
    this._rootLView = _rootLView;
    this._tNode = _tNode;
    this.previousInputValues = null;
    this.instance = instance;
    this.hostView = this.changeDetectorRef = new ViewRef$1(_rootLView, undefined, /* _cdRefInjectingView */false);
    this.componentType = componentType;
  }
  setInput(name, value) {
    const inputData = this._tNode.inputs;
    let dataValue;
    if (inputData !== null && (dataValue = inputData[name])) {
      this.previousInputValues ??= new Map();
      // Do not set the input if it is the same as the last value
      // This behavior matches `bindingUpdated` when binding inputs in templates.
      if (this.previousInputValues.has(name) && Object.is(this.previousInputValues.get(name), value)) {
        return;
      }
      const lView = this._rootLView;
      setInputsForProperty(lView[TVIEW], lView, dataValue, name, value);
      this.previousInputValues.set(name, value);
      const childComponentLView = getComponentLViewByIndex(this._tNode.index, lView);
      markViewDirty(childComponentLView);
    } else {
      if (ngDevMode) {
        const cmpNameForError = stringifyForError(this.componentType);
        let message = `Can't set value of the '${name}' input on the '${cmpNameForError}' component. `;
        message += `Make sure that the '${name}' property is annotated with @Input() or a mapped @Input('${name}') exists.`;
        reportUnknownPropertyError(message);
      }
    }
  }
  get injector() {
    return new NodeInjector(this._tNode, this._rootLView);
  }
  destroy() {
    this.hostView.destroy();
  }
  onDestroy(callback) {
    this.hostView.onDestroy(callback);
  }
}
/** Creates a TNode that can be used to instantiate a root component. */
function createRootComponentTNode(lView, rNode) {
  const tView = lView[TVIEW];
  const index = HEADER_OFFSET;
  ngDevMode && assertIndexInRange(lView, index);
  lView[index] = rNode;
  // '#host' is added here as we don't know the real host DOM name (we don't want to read it) and at
  // the same time we want to communicate the debug `TNode` that this is a special `TNode`
  // representing a host element.
  return getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, '#host', null);
}
/**
 * Creates the root component view and the root component node.
 *
 * @param hostRNode Render host element.
 * @param rootComponentDef ComponentDef
 * @param rootView The parent view where the host node is stored
 * @param rendererFactory Factory to be used for creating child renderers.
 * @param hostRenderer The current renderer
 * @param sanitizer The sanitizer, if provided
 *
 * @returns Component view created
 */
function createRootComponentView(tNode, hostRNode, rootComponentDef, rootDirectives, rootView, environment, hostRenderer) {
  const tView = rootView[TVIEW];
  applyRootComponentStyling(rootDirectives, tNode, hostRNode, hostRenderer);
  // Hydration info is on the host element and needs to be retrieved
  // and passed to the component LView.
  let hydrationInfo = null;
  if (hostRNode !== null) {
    hydrationInfo = retrieveHydrationInfo(hostRNode, rootView[INJECTOR]);
  }
  const viewRenderer = environment.rendererFactory.createRenderer(hostRNode, rootComponentDef);
  let lViewFlags = 16 /* LViewFlags.CheckAlways */;
  if (rootComponentDef.signals) {
    lViewFlags = 4096 /* LViewFlags.SignalView */;
  } else if (rootComponentDef.onPush) {
    lViewFlags = 64 /* LViewFlags.Dirty */;
  }
  const componentView = createLView(rootView, getOrCreateComponentTView(rootComponentDef), null, lViewFlags, rootView[tNode.index], tNode, environment, viewRenderer, null, null, hydrationInfo);
  if (tView.firstCreatePass) {
    markAsComponentHost(tView, tNode, rootDirectives.length - 1);
  }
  addToViewTree(rootView, componentView);
  // Store component view at node index, with node as the HOST
  return rootView[tNode.index] = componentView;
}
/** Sets up the styling information on a root component. */
function applyRootComponentStyling(rootDirectives, tNode, rNode, hostRenderer) {
  for (const def of rootDirectives) {
    tNode.mergedAttrs = mergeHostAttrs(tNode.mergedAttrs, def.hostAttrs);
  }
  if (tNode.mergedAttrs !== null) {
    computeStaticStyling(tNode, tNode.mergedAttrs, true);
    if (rNode !== null) {
      setupStaticAttributes(hostRenderer, rNode, tNode);
    }
  }
}
/**
 * Creates a root component and sets it up with features and host bindings.Shared by
 * renderComponent() and ViewContainerRef.createComponent().
 */
function createRootComponent(componentView, rootComponentDef, rootDirectives, hostDirectiveDefs, rootLView, hostFeatures) {
  const rootTNode = getCurrentTNode();
  ngDevMode && assertDefined(rootTNode, 'tNode should have been already created');
  const tView = rootLView[TVIEW];
  const native = getNativeByTNode(rootTNode, rootLView);
  initializeDirectives(tView, rootLView, rootTNode, rootDirectives, null, hostDirectiveDefs);
  for (let i = 0; i < rootDirectives.length; i++) {
    const directiveIndex = rootTNode.directiveStart + i;
    const directiveInstance = getNodeInjectable(rootLView, tView, directiveIndex, rootTNode);
    attachPatchData(directiveInstance, rootLView);
  }
  invokeDirectivesHostBindings(tView, rootLView, rootTNode);
  if (native) {
    attachPatchData(native, rootLView);
  }
  // We're guaranteed for the `componentOffset` to be positive here
  // since a root component always matches a component def.
  ngDevMode && assertGreaterThan(rootTNode.componentOffset, -1, 'componentOffset must be great than -1');
  const component = getNodeInjectable(rootLView, tView, rootTNode.directiveStart + rootTNode.componentOffset, rootTNode);
  componentView[CONTEXT] = rootLView[CONTEXT] = component;
  if (hostFeatures !== null) {
    for (const feature of hostFeatures) {
      feature(component, rootComponentDef);
    }
  }
  // We want to generate an empty QueryList for root content queries for backwards
  // compatibility with ViewEngine.
  executeContentQueries(tView, rootTNode, rootLView);
  return component;
}
/** Sets the static attributes on a root component. */
function setRootNodeAttributes(hostRenderer, componentDef, hostRNode, rootSelectorOrNode) {
  if (rootSelectorOrNode) {
    // The placeholder will be replaced with the actual version at build time.
    setUpAttributes(hostRenderer, hostRNode, ['ng-version', '17.3.12']);
  } else {
    // If host element is created as a part of this function call (i.e. `rootSelectorOrNode`
    // is not defined), also apply attributes and classes extracted from component selector.
    // Extract attributes and classes from the first selector only to match VE behavior.
    const {
      attrs,
      classes
    } = extractAttrsAndClassesFromSelector(componentDef.selectors[0]);
    if (attrs) {
      setUpAttributes(hostRenderer, hostRNode, attrs);
    }
    if (classes && classes.length > 0) {
      writeDirectClass(hostRenderer, hostRNode, classes.join(' '));
    }
  }
}
/** Projects the `projectableNodes` that were specified when creating a root component. */
function projectNodes(tNode, ngContentSelectors, projectableNodes) {
  const projection = tNode.projection = [];
  for (let i = 0; i < ngContentSelectors.length; i++) {
    const nodesforSlot = projectableNodes[i];
    // Projectable nodes can be passed as array of arrays or an array of iterables (ngUpgrade
    // case). Here we do normalize passed data structure to be an array of arrays to avoid
    // complex checks down the line.
    // We also normalize the length of the passed in projectable nodes (to match the number of
    // <ng-container> slots defined by a component).
    projection.push(nodesforSlot != null ? Array.from(nodesforSlot) : null);
  }
}
/**
 * Used to enable lifecycle hooks on the root component.
 *
 * Include this feature when calling `renderComponent` if the root component
 * you are rendering has lifecycle hooks defined. Otherwise, the hooks won't
 * be called properly.
 *
 * Example:
 *
 * ```
 * renderComponent(AppComponent, {hostFeatures: [LifecycleHooksFeature]});
 * ```
 */
function LifecycleHooksFeature() {
  const tNode = getCurrentTNode();
  ngDevMode && assertDefined(tNode, 'TNode is required');
  registerPostOrderHooks(getLView()[TVIEW], tNode);
}

/**
 * Represents a container where one or more views can be attached to a component.
 *
 * Can contain *host views* (created by instantiating a
 * component with the `createComponent()` method), and *embedded views*
 * (created by instantiating a `TemplateRef` with the `createEmbeddedView()` method).
 *
 * A view container instance can contain other view containers,
 * creating a [view hierarchy](guide/glossary#view-hierarchy).
 *
 * @usageNotes
 *
 * The example below demonstrates how the `createComponent` function can be used
 * to create an instance of a ComponentRef dynamically and attach it to an ApplicationRef,
 * so that it gets included into change detection cycles.
 *
 * Note: the example uses standalone components, but the function can also be used for
 * non-standalone components (declared in an NgModule) as well.
 *
 * ```typescript
 * @Component({
 *   standalone: true,
 *   selector: 'dynamic',
 *   template: `<span>This is a content of a dynamic component.</span>`,
 * })
 * class DynamicComponent {
 *   vcr = inject(ViewContainerRef);
 * }
 *
 * @Component({
 *   standalone: true,
 *   selector: 'app',
 *   template: `<main>Hi! This is the main content.</main>`,
 * })
 * class AppComponent {
 *   vcr = inject(ViewContainerRef);
 *
 *   ngAfterViewInit() {
 *     const compRef = this.vcr.createComponent(DynamicComponent);
 *     compRef.changeDetectorRef.detectChanges();
 *   }
 * }
 * ```
 *
 * @see {@link ComponentRef}
 * @see {@link EmbeddedViewRef}
 *
 * @publicApi
 */
class ViewContainerRef {
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = injectViewContainerRef;
  }
}
/**
 * Creates a ViewContainerRef and stores it on the injector. Or, if the ViewContainerRef
 * already exists, retrieves the existing ViewContainerRef.
 *
 * @returns The ViewContainerRef instance to use
 */
function injectViewContainerRef() {
  const previousTNode = getCurrentTNode();
  return createContainerRef(previousTNode, getLView());
}
const VE_ViewContainerRef = ViewContainerRef;
// TODO(alxhub): cleaning up this indirection triggers a subtle bug in Closure in g3. Once the fix
// for that lands, this can be cleaned up.
const R3ViewContainerRef = class ViewContainerRef extends VE_ViewContainerRef {
  constructor(_lContainer, _hostTNode, _hostLView) {
    super();
    this._lContainer = _lContainer;
    this._hostTNode = _hostTNode;
    this._hostLView = _hostLView;
  }
  get element() {
    return createElementRef(this._hostTNode, this._hostLView);
  }
  get injector() {
    return new NodeInjector(this._hostTNode, this._hostLView);
  }
  /** @deprecated No replacement */
  get parentInjector() {
    const parentLocation = getParentInjectorLocation(this._hostTNode, this._hostLView);
    if (hasParentInjector(parentLocation)) {
      const parentView = getParentInjectorView(parentLocation, this._hostLView);
      const injectorIndex = getParentInjectorIndex(parentLocation);
      ngDevMode && assertNodeInjector(parentView, injectorIndex);
      const parentTNode = parentView[TVIEW].data[injectorIndex + 8 /* NodeInjectorOffset.TNODE */];
      return new NodeInjector(parentTNode, parentView);
    } else {
      return new NodeInjector(null, this._hostLView);
    }
  }
  clear() {
    while (this.length > 0) {
      this.remove(this.length - 1);
    }
  }
  get(index) {
    const viewRefs = getViewRefs(this._lContainer);
    return viewRefs !== null && viewRefs[index] || null;
  }
  get length() {
    return this._lContainer.length - CONTAINER_HEADER_OFFSET;
  }
  createEmbeddedView(templateRef, context, indexOrOptions) {
    let index;
    let injector;
    if (typeof indexOrOptions === 'number') {
      index = indexOrOptions;
    } else if (indexOrOptions != null) {
      index = indexOrOptions.index;
      injector = indexOrOptions.injector;
    }
    const dehydratedView = findMatchingDehydratedView(this._lContainer, templateRef.ssrId);
    const viewRef = templateRef.createEmbeddedViewImpl(context || {}, injector, dehydratedView);
    this.insertImpl(viewRef, index, shouldAddViewToDom(this._hostTNode, dehydratedView));
    return viewRef;
  }
  createComponent(componentFactoryOrType, indexOrOptions, injector, projectableNodes, environmentInjector) {
    const isComponentFactory = componentFactoryOrType && !isType(componentFactoryOrType);
    let index;
    // This function supports 2 signatures and we need to handle options correctly for both:
    //   1. When first argument is a Component type. This signature also requires extra
    //      options to be provided as object (more ergonomic option).
    //   2. First argument is a Component factory. In this case extra options are represented as
    //      positional arguments. This signature is less ergonomic and will be deprecated.
    if (isComponentFactory) {
      if (ngDevMode) {
        assertEqual(typeof indexOrOptions !== 'object', true, 'It looks like Component factory was provided as the first argument ' + 'and an options object as the second argument. This combination of arguments ' + 'is incompatible. You can either change the first argument to provide Component ' + 'type or change the second argument to be a number (representing an index at ' + 'which to insert the new component\'s host view into this container)');
      }
      index = indexOrOptions;
    } else {
      if (ngDevMode) {
        assertDefined(getComponentDef(componentFactoryOrType), `Provided Component class doesn't contain Component definition. ` + `Please check whether provided class has @Component decorator.`);
        assertEqual(typeof indexOrOptions !== 'number', true, 'It looks like Component type was provided as the first argument ' + 'and a number (representing an index at which to insert the new component\'s ' + 'host view into this container as the second argument. This combination of arguments ' + 'is incompatible. Please use an object as the second argument instead.');
      }
      const options = indexOrOptions || {};
      if (ngDevMode && options.environmentInjector && options.ngModuleRef) {
        throwError(`Cannot pass both environmentInjector and ngModuleRef options to createComponent().`);
      }
      index = options.index;
      injector = options.injector;
      projectableNodes = options.projectableNodes;
      environmentInjector = options.environmentInjector || options.ngModuleRef;
    }
    const componentFactory = isComponentFactory ? componentFactoryOrType : new ComponentFactory(getComponentDef(componentFactoryOrType));
    const contextInjector = injector || this.parentInjector;
    // If an `NgModuleRef` is not provided explicitly, try retrieving it from the DI tree.
    if (!environmentInjector && componentFactory.ngModule == null) {
      // For the `ComponentFactory` case, entering this logic is very unlikely, since we expect that
      // an instance of a `ComponentFactory`, resolved via `ComponentFactoryResolver` would have an
      // `ngModule` field. This is possible in some test scenarios and potentially in some JIT-based
      // use-cases. For the `ComponentFactory` case we preserve backwards-compatibility and try
      // using a provided injector first, then fall back to the parent injector of this
      // `ViewContainerRef` instance.
      //
      // For the factory-less case, it's critical to establish a connection with the module
      // injector tree (by retrieving an instance of an `NgModuleRef` and accessing its injector),
      // so that a component can use DI tokens provided in MgModules. For this reason, we can not
      // rely on the provided injector, since it might be detached from the DI tree (for example, if
      // it was created via `Injector.create` without specifying a parent injector, or if an
      // injector is retrieved from an `NgModuleRef` created via `createNgModule` using an
      // NgModule outside of a module tree). Instead, we always use `ViewContainerRef`'s parent
      // injector, which is normally connected to the DI tree, which includes module injector
      // subtree.
      const _injector = isComponentFactory ? contextInjector : this.parentInjector;
      // DO NOT REFACTOR. The code here used to have a `injector.get(NgModuleRef, null) ||
      // undefined` expression which seems to cause internal google apps to fail. This is documented
      // in the following internal bug issue: go/b/142967802
      const result = _injector.get(EnvironmentInjector, null);
      if (result) {
        environmentInjector = result;
      }
    }
    const componentDef = getComponentDef(componentFactory.componentType ?? {});
    const dehydratedView = findMatchingDehydratedView(this._lContainer, componentDef?.id ?? null);
    const rNode = dehydratedView?.firstChild ?? null;
    const componentRef = componentFactory.create(contextInjector, projectableNodes, rNode, environmentInjector);
    this.insertImpl(componentRef.hostView, index, shouldAddViewToDom(this._hostTNode, dehydratedView));
    return componentRef;
  }
  insert(viewRef, index) {
    return this.insertImpl(viewRef, index, true);
  }
  insertImpl(viewRef, index, addToDOM) {
    const lView = viewRef._lView;
    if (ngDevMode && viewRef.destroyed) {
      throw new Error('Cannot insert a destroyed View in a ViewContainer!');
    }
    if (viewAttachedToContainer(lView)) {
      // If view is already attached, detach it first so we clean up references appropriately.
      const prevIdx = this.indexOf(viewRef);
      // A view might be attached either to this or a different container. The `prevIdx` for
      // those cases will be:
      // equal to -1 for views attached to this ViewContainerRef
      // >= 0 for views attached to a different ViewContainerRef
      if (prevIdx !== -1) {
        this.detach(prevIdx);
      } else {
        const prevLContainer = lView[PARENT];
        ngDevMode && assertEqual(isLContainer(prevLContainer), true, 'An attached view should have its PARENT point to a container.');
        // We need to re-create a R3ViewContainerRef instance since those are not stored on
        // LView (nor anywhere else).
        const prevVCRef = new R3ViewContainerRef(prevLContainer, prevLContainer[T_HOST], prevLContainer[PARENT]);
        prevVCRef.detach(prevVCRef.indexOf(viewRef));
      }
    }
    // Logical operation of adding `LView` to `LContainer`
    const adjustedIdx = this._adjustIndex(index);
    const lContainer = this._lContainer;
    addLViewToLContainer(lContainer, lView, adjustedIdx, addToDOM);
    viewRef.attachToViewContainerRef();
    addToArray(getOrCreateViewRefs(lContainer), adjustedIdx, viewRef);
    return viewRef;
  }
  move(viewRef, newIndex) {
    if (ngDevMode && viewRef.destroyed) {
      throw new Error('Cannot move a destroyed View in a ViewContainer!');
    }
    return this.insert(viewRef, newIndex);
  }
  indexOf(viewRef) {
    const viewRefsArr = getViewRefs(this._lContainer);
    return viewRefsArr !== null ? viewRefsArr.indexOf(viewRef) : -1;
  }
  remove(index) {
    const adjustedIdx = this._adjustIndex(index, -1);
    const detachedView = detachView(this._lContainer, adjustedIdx);
    if (detachedView) {
      // Before destroying the view, remove it from the container's array of `ViewRef`s.
      // This ensures the view container length is updated before calling
      // `destroyLView`, which could recursively call view container methods that
      // rely on an accurate container length.
      // (e.g. a method on this view container being called by a child directive's OnDestroy
      // lifecycle hook)
      removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx);
      destroyLView(detachedView[TVIEW], detachedView);
    }
  }
  detach(index) {
    const adjustedIdx = this._adjustIndex(index, -1);
    const view = detachView(this._lContainer, adjustedIdx);
    const wasDetached = view && removeFromArray(getOrCreateViewRefs(this._lContainer), adjustedIdx) != null;
    return wasDetached ? new ViewRef$1(view) : null;
  }
  _adjustIndex(index, shift = 0) {
    if (index == null) {
      return this.length + shift;
    }
    if (ngDevMode) {
      assertGreaterThan(index, -1, `ViewRef index must be positive, got ${index}`);
      // +1 because it's legal to insert at the end.
      assertLessThan(index, this.length + 1 + shift, 'index');
    }
    return index;
  }
};
function getViewRefs(lContainer) {
  return lContainer[VIEW_REFS];
}
function getOrCreateViewRefs(lContainer) {
  return lContainer[VIEW_REFS] || (lContainer[VIEW_REFS] = []);
}
/**
 * Creates a ViewContainerRef and stores it on the injector.
 *
 * @param hostTNode The node that is requesting a ViewContainerRef
 * @param hostLView The view to which the node belongs
 * @returns The ViewContainerRef instance to use
 */
function createContainerRef(hostTNode, hostLView) {
  ngDevMode && assertTNodeType(hostTNode, 12 /* TNodeType.AnyContainer */ | 3 /* TNodeType.AnyRNode */);
  let lContainer;
  const slotValue = hostLView[hostTNode.index];
  if (isLContainer(slotValue)) {
    // If the host is a container, we don't need to create a new LContainer
    lContainer = slotValue;
  } else {
    // An LContainer anchor can not be `null`, but we set it here temporarily
    // and update to the actual value later in this function (see
    // `_locateOrCreateAnchorNode`).
    lContainer = createLContainer(slotValue, hostLView, null, hostTNode);
    hostLView[hostTNode.index] = lContainer;
    addToViewTree(hostLView, lContainer);
  }
  _locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue);
  return new R3ViewContainerRef(lContainer, hostTNode, hostLView);
}
/**
 * Creates and inserts a comment node that acts as an anchor for a view container.
 *
 * If the host is a regular element, we have to insert a comment node manually which will
 * be used as an anchor when inserting elements. In this specific case we use low-level DOM
 * manipulation to insert it.
 */
function insertAnchorNode(hostLView, hostTNode) {
  const renderer = hostLView[RENDERER];
  ngDevMode && ngDevMode.rendererCreateComment++;
  const commentNode = renderer.createComment(ngDevMode ? 'container' : '');
  const hostNative = getNativeByTNode(hostTNode, hostLView);
  const parentOfHostNative = nativeParentNode(renderer, hostNative);
  nativeInsertBefore(renderer, parentOfHostNative, commentNode, nativeNextSibling(renderer, hostNative), false);
  return commentNode;
}
let _locateOrCreateAnchorNode = createAnchorNode;
let _populateDehydratedViewsInLContainer = () => false; // noop by default
/**
 * Looks up dehydrated views that belong to a given LContainer and populates
 * this information into the `LContainer[DEHYDRATED_VIEWS]` slot. When running
 * in client-only mode, this function is a noop.
 *
 * @param lContainer LContainer that should be populated.
 * @param tNode Corresponding TNode.
 * @param hostLView LView that hosts LContainer.
 * @returns a boolean flag that indicates whether a populating operation
 *   was successful. The operation might be unsuccessful in case is has completed
 *   previously, we are rendering in client-only mode or this content is located
 *   in a skip hydration section.
 */
function populateDehydratedViewsInLContainer(lContainer, tNode, hostLView) {
  return _populateDehydratedViewsInLContainer(lContainer, tNode, hostLView);
}
/**
 * Regular creation mode: an anchor is created and
 * assigned to the `lContainer[NATIVE]` slot.
 */
function createAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
  // We already have a native element (anchor) set, return.
  if (lContainer[NATIVE]) return;
  let commentNode;
  // If the host is an element container, the native host element is guaranteed to be a
  // comment and we can reuse that comment as anchor element for the new LContainer.
  // The comment node in question is already part of the DOM structure so we don't need to append
  // it again.
  if (hostTNode.type & 8 /* TNodeType.ElementContainer */) {
    commentNode = unwrapRNode(slotValue);
  } else {
    commentNode = insertAnchorNode(hostLView, hostTNode);
  }
  lContainer[NATIVE] = commentNode;
}
/**
 * Hydration logic that looks up all dehydrated views in this container
 * and puts them into `lContainer[DEHYDRATED_VIEWS]` slot.
 *
 * @returns a boolean flag that indicates whether a populating operation
 *   was successful. The operation might be unsuccessful in case is has completed
 *   previously, we are rendering in client-only mode or this content is located
 *   in a skip hydration section.
 */
function populateDehydratedViewsInLContainerImpl(lContainer, tNode, hostLView) {
  // We already have a native element (anchor) set and the process
  // of finding dehydrated views happened (so the `lContainer[DEHYDRATED_VIEWS]`
  // is not null), exit early.
  if (lContainer[NATIVE] && lContainer[DEHYDRATED_VIEWS]) {
    return true;
  }
  const hydrationInfo = hostLView[HYDRATION];
  const noOffsetIndex = tNode.index - HEADER_OFFSET;
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock(tNode) || isDisconnectedNode$1(hydrationInfo, noOffsetIndex);
  // Regular creation mode.
  if (isNodeCreationMode) {
    return false;
  }
  // Hydration mode, looking up an anchor node and dehydrated views in DOM.
  const currentRNode = getSegmentHead(hydrationInfo, noOffsetIndex);
  const serializedViews = hydrationInfo.data[CONTAINERS]?.[noOffsetIndex];
  ngDevMode && assertDefined(serializedViews, 'Unexpected state: no hydration info available for a given TNode, ' + 'which represents a view container.');
  const [commentNode, dehydratedViews] = locateDehydratedViewsInContainer(currentRNode, serializedViews);
  if (ngDevMode) {
    validateMatchingNode(commentNode, Node.COMMENT_NODE, null, hostLView, tNode, true);
    // Do not throw in case this node is already claimed (thus `false` as a second
    // argument). If this container is created based on an `<ng-template>`, the comment
    // node would be already claimed from the `template` instruction. If an element acts
    // as an anchor (e.g. <div #vcRef>), a separate comment node would be created/located,
    // so we need to claim it here.
    markRNodeAsClaimedByHydration(commentNode, false);
  }
  lContainer[NATIVE] = commentNode;
  lContainer[DEHYDRATED_VIEWS] = dehydratedViews;
  return true;
}
function locateOrCreateAnchorNode(lContainer, hostLView, hostTNode, slotValue) {
  if (!_populateDehydratedViewsInLContainer(lContainer, hostTNode, hostLView)) {
    // Populating dehydrated views operation returned `false`, which indicates
    // that the logic was running in client-only mode, this an anchor comment
    // node should be created for this container.
    createAnchorNode(lContainer, hostLView, hostTNode, slotValue);
  }
}
function enableLocateOrCreateContainerRefImpl() {
  _locateOrCreateAnchorNode = locateOrCreateAnchorNode;
  _populateDehydratedViewsInLContainer = populateDehydratedViewsInLContainerImpl;
}
class LQuery_ {
  constructor(queryList) {
    this.queryList = queryList;
    this.matches = null;
  }
  clone() {
    return new LQuery_(this.queryList);
  }
  setDirty() {
    this.queryList.setDirty();
  }
}
class LQueries_ {
  constructor(queries = []) {
    this.queries = queries;
  }
  createEmbeddedView(tView) {
    const tQueries = tView.queries;
    if (tQueries !== null) {
      const noOfInheritedQueries = tView.contentQueries !== null ? tView.contentQueries[0] : tQueries.length;
      const viewLQueries = [];
      // An embedded view has queries propagated from a declaration view at the beginning of the
      // TQueries collection and up until a first content query declared in the embedded view. Only
      // propagated LQueries are created at this point (LQuery corresponding to declared content
      // queries will be instantiated from the content query instructions for each directive).
      for (let i = 0; i < noOfInheritedQueries; i++) {
        const tQuery = tQueries.getByIndex(i);
        const parentLQuery = this.queries[tQuery.indexInDeclarationView];
        viewLQueries.push(parentLQuery.clone());
      }
      return new LQueries_(viewLQueries);
    }
    return null;
  }
  insertView(tView) {
    this.dirtyQueriesWithMatches(tView);
  }
  detachView(tView) {
    this.dirtyQueriesWithMatches(tView);
  }
  finishViewCreation(tView) {
    this.dirtyQueriesWithMatches(tView);
  }
  dirtyQueriesWithMatches(tView) {
    for (let i = 0; i < this.queries.length; i++) {
      if (getTQuery(tView, i).matches !== null) {
        this.queries[i].setDirty();
      }
    }
  }
}
class TQueryMetadata_ {
  constructor(predicate, flags, read = null) {
    this.flags = flags;
    this.read = read;
    // Compiler might not be able to pre-optimize and split multiple selectors.
    if (typeof predicate === 'string') {
      this.predicate = splitQueryMultiSelectors(predicate);
    } else {
      this.predicate = predicate;
    }
  }
}
class TQueries_ {
  constructor(queries = []) {
    this.queries = queries;
  }
  elementStart(tView, tNode) {
    ngDevMode && assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
    for (let i = 0; i < this.queries.length; i++) {
      this.queries[i].elementStart(tView, tNode);
    }
  }
  elementEnd(tNode) {
    for (let i = 0; i < this.queries.length; i++) {
      this.queries[i].elementEnd(tNode);
    }
  }
  embeddedTView(tNode) {
    let queriesForTemplateRef = null;
    for (let i = 0; i < this.length; i++) {
      const childQueryIndex = queriesForTemplateRef !== null ? queriesForTemplateRef.length : 0;
      const tqueryClone = this.getByIndex(i).embeddedTView(tNode, childQueryIndex);
      if (tqueryClone) {
        tqueryClone.indexInDeclarationView = i;
        if (queriesForTemplateRef !== null) {
          queriesForTemplateRef.push(tqueryClone);
        } else {
          queriesForTemplateRef = [tqueryClone];
        }
      }
    }
    return queriesForTemplateRef !== null ? new TQueries_(queriesForTemplateRef) : null;
  }
  template(tView, tNode) {
    ngDevMode && assertFirstCreatePass(tView, 'Queries should collect results on the first template pass only');
    for (let i = 0; i < this.queries.length; i++) {
      this.queries[i].template(tView, tNode);
    }
  }
  getByIndex(index) {
    ngDevMode && assertIndexInRange(this.queries, index);
    return this.queries[index];
  }
  get length() {
    return this.queries.length;
  }
  track(tquery) {
    this.queries.push(tquery);
  }
}
class TQuery_ {
  constructor(metadata, nodeIndex = -1) {
    this.metadata = metadata;
    this.matches = null;
    this.indexInDeclarationView = -1;
    this.crossesNgTemplate = false;
    /**
     * A flag indicating if a given query still applies to nodes it is crossing. We use this flag
     * (alongside with _declarationNodeIndex) to know when to stop applying content queries to
     * elements in a template.
     */
    this._appliesToNextNode = true;
    this._declarationNodeIndex = nodeIndex;
  }
  elementStart(tView, tNode) {
    if (this.isApplyingToNode(tNode)) {
      this.matchTNode(tView, tNode);
    }
  }
  elementEnd(tNode) {
    if (this._declarationNodeIndex === tNode.index) {
      this._appliesToNextNode = false;
    }
  }
  template(tView, tNode) {
    this.elementStart(tView, tNode);
  }
  embeddedTView(tNode, childQueryIndex) {
    if (this.isApplyingToNode(tNode)) {
      this.crossesNgTemplate = true;
      // A marker indicating a `<ng-template>` element (a placeholder for query results from
      // embedded views created based on this `<ng-template>`).
      this.addMatch(-tNode.index, childQueryIndex);
      return new TQuery_(this.metadata);
    }
    return null;
  }
  isApplyingToNode(tNode) {
    if (this._appliesToNextNode && (this.metadata.flags & 1 /* QueryFlags.descendants */) !== 1 /* QueryFlags.descendants */) {
      const declarationNodeIdx = this._declarationNodeIndex;
      let parent = tNode.parent;
      // Determine if a given TNode is a "direct" child of a node on which a content query was
      // declared (only direct children of query's host node can match with the descendants: false
      // option). There are 3 main use-case / conditions to consider here:
      // - <needs-target><i #target></i></needs-target>: here <i #target> parent node is a query
      // host node;
      // - <needs-target><ng-template [ngIf]="true"><i #target></i></ng-template></needs-target>:
      // here <i #target> parent node is null;
      // - <needs-target><ng-container><i #target></i></ng-container></needs-target>: here we need
      // to go past `<ng-container>` to determine <i #target> parent node (but we shouldn't traverse
      // up past the query's host node!).
      while (parent !== null && parent.type & 8 /* TNodeType.ElementContainer */ && parent.index !== declarationNodeIdx) {
        parent = parent.parent;
      }
      return declarationNodeIdx === (parent !== null ? parent.index : -1);
    }
    return this._appliesToNextNode;
  }
  matchTNode(tView, tNode) {
    const predicate = this.metadata.predicate;
    if (Array.isArray(predicate)) {
      for (let i = 0; i < predicate.length; i++) {
        const name = predicate[i];
        this.matchTNodeWithReadOption(tView, tNode, getIdxOfMatchingSelector(tNode, name));
        // Also try matching the name to a provider since strings can be used as DI tokens too.
        this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, name, false, false));
      }
    } else {
      if (predicate === TemplateRef) {
        if (tNode.type & 4 /* TNodeType.Container */) {
          this.matchTNodeWithReadOption(tView, tNode, -1);
        }
      } else {
        this.matchTNodeWithReadOption(tView, tNode, locateDirectiveOrProvider(tNode, tView, predicate, false, false));
      }
    }
  }
  matchTNodeWithReadOption(tView, tNode, nodeMatchIdx) {
    if (nodeMatchIdx !== null) {
      const read = this.metadata.read;
      if (read !== null) {
        if (read === ElementRef || read === ViewContainerRef || read === TemplateRef && tNode.type & 4 /* TNodeType.Container */) {
          this.addMatch(tNode.index, -2);
        } else {
          const directiveOrProviderIdx = locateDirectiveOrProvider(tNode, tView, read, false, false);
          if (directiveOrProviderIdx !== null) {
            this.addMatch(tNode.index, directiveOrProviderIdx);
          }
        }
      } else {
        this.addMatch(tNode.index, nodeMatchIdx);
      }
    }
  }
  addMatch(tNodeIdx, matchIdx) {
    if (this.matches === null) {
      this.matches = [tNodeIdx, matchIdx];
    } else {
      this.matches.push(tNodeIdx, matchIdx);
    }
  }
}
/**
 * Iterates over local names for a given node and returns directive index
 * (or -1 if a local name points to an element).
 *
 * @param tNode static data of a node to check
 * @param selector selector to match
 * @returns directive index, -1 or null if a selector didn't match any of the local names
 */
function getIdxOfMatchingSelector(tNode, selector) {
  const localNames = tNode.localNames;
  if (localNames !== null) {
    for (let i = 0; i < localNames.length; i += 2) {
      if (localNames[i] === selector) {
        return localNames[i + 1];
      }
    }
  }
  return null;
}
function createResultByTNodeType(tNode, currentView) {
  if (tNode.type & (3 /* TNodeType.AnyRNode */ | 8 /* TNodeType.ElementContainer */)) {
    return createElementRef(tNode, currentView);
  } else if (tNode.type & 4 /* TNodeType.Container */) {
    return createTemplateRef(tNode, currentView);
  }
  return null;
}
function createResultForNode(lView, tNode, matchingIdx, read) {
  if (matchingIdx === -1) {
    // if read token and / or strategy is not specified, detect it using appropriate tNode type
    return createResultByTNodeType(tNode, lView);
  } else if (matchingIdx === -2) {
    // read a special token from a node injector
    return createSpecialToken(lView, tNode, read);
  } else {
    // read a token
    return getNodeInjectable(lView, lView[TVIEW], matchingIdx, tNode);
  }
}
function createSpecialToken(lView, tNode, read) {
  if (read === ElementRef) {
    return createElementRef(tNode, lView);
  } else if (read === TemplateRef) {
    return createTemplateRef(tNode, lView);
  } else if (read === ViewContainerRef) {
    ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
    return createContainerRef(tNode, lView);
  } else {
    ngDevMode && throwError(`Special token to read should be one of ElementRef, TemplateRef or ViewContainerRef but got ${stringify(read)}.`);
  }
}
/**
 * A helper function that creates query results for a given view. This function is meant to do the
 * processing once and only once for a given view instance (a set of results for a given view
 * doesn't change).
 */
function materializeViewResults(tView, lView, tQuery, queryIndex) {
  const lQuery = lView[QUERIES].queries[queryIndex];
  if (lQuery.matches === null) {
    const tViewData = tView.data;
    const tQueryMatches = tQuery.matches;
    const result = [];
    for (let i = 0; tQueryMatches !== null && i < tQueryMatches.length; i += 2) {
      const matchedNodeIdx = tQueryMatches[i];
      if (matchedNodeIdx < 0) {
        // we at the <ng-template> marker which might have results in views created based on this
        // <ng-template> - those results will be in separate views though, so here we just leave
        // null as a placeholder
        result.push(null);
      } else {
        ngDevMode && assertIndexInRange(tViewData, matchedNodeIdx);
        const tNode = tViewData[matchedNodeIdx];
        result.push(createResultForNode(lView, tNode, tQueryMatches[i + 1], tQuery.metadata.read));
      }
    }
    lQuery.matches = result;
  }
  return lQuery.matches;
}
/**
 * A helper function that collects (already materialized) query results from a tree of views,
 * starting with a provided LView.
 */
function collectQueryResults(tView, lView, queryIndex, result) {
  const tQuery = tView.queries.getByIndex(queryIndex);
  const tQueryMatches = tQuery.matches;
  if (tQueryMatches !== null) {
    const lViewResults = materializeViewResults(tView, lView, tQuery, queryIndex);
    for (let i = 0; i < tQueryMatches.length; i += 2) {
      const tNodeIdx = tQueryMatches[i];
      if (tNodeIdx > 0) {
        result.push(lViewResults[i / 2]);
      } else {
        const childQueryIndex = tQueryMatches[i + 1];
        const declarationLContainer = lView[-tNodeIdx];
        ngDevMode && assertLContainer(declarationLContainer);
        // collect matches for views inserted in this container
        for (let i = CONTAINER_HEADER_OFFSET; i < declarationLContainer.length; i++) {
          const embeddedLView = declarationLContainer[i];
          if (embeddedLView[DECLARATION_LCONTAINER] === embeddedLView[PARENT]) {
            collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
          }
        }
        // collect matches for views created from this declaration container and inserted into
        // different containers
        if (declarationLContainer[MOVED_VIEWS] !== null) {
          const embeddedLViews = declarationLContainer[MOVED_VIEWS];
          for (let i = 0; i < embeddedLViews.length; i++) {
            const embeddedLView = embeddedLViews[i];
            collectQueryResults(embeddedLView[TVIEW], embeddedLView, childQueryIndex, result);
          }
        }
      }
    }
  }
  return result;
}
function loadQueryInternal(lView, queryIndex) {
  ngDevMode && assertDefined(lView[QUERIES], 'LQueries should be defined when trying to load a query');
  ngDevMode && assertIndexInRange(lView[QUERIES].queries, queryIndex);
  return lView[QUERIES].queries[queryIndex].queryList;
}
/**
 * Creates a new instance of LQuery and returns its index in the collection of LQuery objects.
 *
 * @returns index in the collection of LQuery objects
 */
function createLQuery(tView, lView, flags) {
  const queryList = new QueryList((flags & 4 /* QueryFlags.emitDistinctChangesOnly */) === 4 /* QueryFlags.emitDistinctChangesOnly */);
  storeCleanupWithContext(tView, lView, queryList, queryList.destroy);
  const lQueries = (lView[QUERIES] ??= new LQueries_()).queries;
  return lQueries.push(new LQuery_(queryList)) - 1;
}
function createViewQuery(predicate, flags, read) {
  ngDevMode && assertNumber(flags, 'Expecting flags');
  const tView = getTView();
  if (tView.firstCreatePass) {
    createTQuery(tView, new TQueryMetadata_(predicate, flags, read), -1);
    if ((flags & 2 /* QueryFlags.isStatic */) === 2 /* QueryFlags.isStatic */) {
      tView.staticViewQueries = true;
    }
  }
  return createLQuery(tView, getLView(), flags);
}
function createContentQuery(directiveIndex, predicate, flags, read) {
  ngDevMode && assertNumber(flags, 'Expecting flags');
  const tView = getTView();
  if (tView.firstCreatePass) {
    const tNode = getCurrentTNode();
    createTQuery(tView, new TQueryMetadata_(predicate, flags, read), tNode.index);
    saveContentQueryAndDirectiveIndex(tView, directiveIndex);
    if ((flags & 2 /* QueryFlags.isStatic */) === 2 /* QueryFlags.isStatic */) {
      tView.staticContentQueries = true;
    }
  }
  return createLQuery(tView, getLView(), flags);
}
/** Splits multiple selectors in the locator. */
function splitQueryMultiSelectors(locator) {
  return locator.split(',').map(s => s.trim());
}
function createTQuery(tView, metadata, nodeIndex) {
  if (tView.queries === null) tView.queries = new TQueries_();
  tView.queries.track(new TQuery_(metadata, nodeIndex));
}
function saveContentQueryAndDirectiveIndex(tView, directiveIndex) {
  const tViewContentQueries = tView.contentQueries || (tView.contentQueries = []);
  const lastSavedDirectiveIndex = tViewContentQueries.length ? tViewContentQueries[tViewContentQueries.length - 1] : -1;
  if (directiveIndex !== lastSavedDirectiveIndex) {
    tViewContentQueries.push(tView.queries.length - 1, directiveIndex);
  }
}
function getTQuery(tView, index) {
  ngDevMode && assertDefined(tView.queries, 'TQueries must be defined to retrieve a TQuery');
  return tView.queries.getByIndex(index);
}
/**
 * A helper function collecting results from all the views where a given query was active.
 * @param lView
 * @param queryIndex
 */
function getQueryResults(lView, queryIndex) {
  const tView = lView[TVIEW];
  const tQuery = getTQuery(tView, queryIndex);
  return tQuery.crossesNgTemplate ? collectQueryResults(tView, lView, queryIndex, []) : materializeViewResults(tView, lView, tQuery, queryIndex);
}

/**
 * Checks if the given `value` is a reactive `Signal`.
 */
function isSignal(value) {
  return typeof value === 'function' && value[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL] !== undefined;
}

/** Symbol used distinguish `WritableSignal` from other non-writable signals and functions. */
const ɵWRITABLE_SIGNAL = /* @__PURE__ */Symbol('WRITABLE_SIGNAL');
/**
 * Utility function used during template type checking to extract the value from a `WritableSignal`.
 * @codeGenApi
 */
function ɵunwrapWritableSignal(value) {
  // Note: the function uses `WRITABLE_SIGNAL` as a brand instead of `WritableSignal<T>`,
  // because the latter incorrectly unwraps non-signal getter functions.
  return null;
}
/**
 * Create a `Signal` that can be set or updated directly.
 */
function signal(initialValue, options) {
  performanceMarkFeature('NgSignals');
  const signalFn = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.createSignal)(initialValue);
  const node = signalFn[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL];
  if (options?.equal) {
    node.equal = options.equal;
  }
  signalFn.set = newValue => (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.signalSetFn)(node, newValue);
  signalFn.update = updateFn => (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.signalUpdateFn)(node, updateFn);
  signalFn.asReadonly = signalAsReadonlyFn.bind(signalFn);
  if (ngDevMode) {
    signalFn.toString = () => `[Signal: ${signalFn()}]`;
  }
  return signalFn;
}
function signalAsReadonlyFn() {
  const node = this[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL];
  if (node.readonlyFn === undefined) {
    const readonlyFn = () => this();
    readonlyFn[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL] = node;
    node.readonlyFn = readonlyFn;
  }
  return node.readonlyFn;
}
/**
 * Checks if the given `value` is a writeable signal.
 */
function isWritableSignal(value) {
  return isSignal(value) && typeof value.set === 'function';
}

/**
 * A signal factory function in charge of creating a new computed signal capturing query
 * results. This centralized creation function is used by all types of queries (child / children,
 * required / optional).
 *
 * @param firstOnly indicates if all or only the first result should be returned
 * @param required indicates if at least one result is required
 * @returns a read-only signal with query results
 */
function createQuerySignalFn(firstOnly, required) {
  let node;
  const signalFn = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.createComputed)(() => {
    // A dedicated signal that increments its value every time a query changes its dirty status. By
    // using this signal we can implement a query as computed and avoid creation of a specialized
    // reactive node type. Please note that a query gets marked dirty under the following
    // circumstances:
    // - a view (where a query is active) finished its first creation pass;
    // - a new view is inserted / deleted and it impacts query results.
    node._dirtyCounter();
    const value = refreshSignalQuery(node, firstOnly);
    if (required && value === undefined) {
      throw new RuntimeError(-951 /* RuntimeErrorCode.REQUIRED_QUERY_NO_VALUE */, ngDevMode && 'Child query result is required but no value is available.');
    }
    return value;
  });
  node = signalFn[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL];
  node._dirtyCounter = signal(0);
  node._flatValue = undefined;
  if (ngDevMode) {
    signalFn.toString = () => `[Query Signal]`;
  }
  return signalFn;
}
function createSingleResultOptionalQuerySignalFn() {
  return createQuerySignalFn(/* firstOnly */true, /* required */false);
}
function createSingleResultRequiredQuerySignalFn() {
  return createQuerySignalFn(/* firstOnly */true, /* required */true);
}
function createMultiResultQuerySignalFn() {
  return createQuerySignalFn(/* firstOnly */false, /* required */false);
}
function bindQueryToSignal(target, queryIndex) {
  const node = target[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL];
  node._lView = getLView();
  node._queryIndex = queryIndex;
  node._queryList = loadQueryInternal(node._lView, queryIndex);
  node._queryList.onDirty(() => node._dirtyCounter.update(v => v + 1));
}
function refreshSignalQuery(node, firstOnly) {
  const lView = node._lView;
  const queryIndex = node._queryIndex;
  // There are 2 conditions under which we want to return "empty" results instead of the ones
  // collected by a query:
  //
  // 1) a given query wasn't created yet (this is a period of time between the directive creation
  // and execution of the query creation function) - in this case a query doesn't exist yet and we
  // don't have any results to return.
  //
  // 2) we are in the process of constructing a view (the first
  // creation pass didn't finish) and a query might have partial results, but we don't want to
  // return those - instead we do delay results collection until all nodes had a chance of matching
  // and we can present consistent, "atomic" (on a view level) results.
  if (lView === undefined || queryIndex === undefined || lView[FLAGS] & 4 /* LViewFlags.CreationMode */) {
    return firstOnly ? undefined : EMPTY_ARRAY;
  }
  const queryList = loadQueryInternal(lView, queryIndex);
  const results = getQueryResults(lView, queryIndex);
  queryList.reset(results, unwrapElementRef);
  if (firstOnly) {
    return queryList.first;
  } else {
    // TODO: remove access to the private _changesDetected field by abstracting / removing usage of
    // QueryList in the signal-based queries (perf follow-up)
    const resultChanged = queryList._changesDetected;
    if (resultChanged || node._flatValue === undefined) {
      return node._flatValue = queryList.toArray();
    }
    return node._flatValue;
  }
}
function viewChildFn(locator, opts) {
  ngDevMode && assertInInjectionContext(viewChild);
  return createSingleResultOptionalQuerySignalFn();
}
function viewChildRequiredFn(locator, opts) {
  ngDevMode && assertInInjectionContext(viewChild);
  return createSingleResultRequiredQuerySignalFn();
}
/**
 * Initializes a view child query.
 *
 * Consider using `viewChild.required` for queries that should always match.
 *
 * @usageNotes
 * Create a child query in your component by declaring a
 * class field and initializing it with the `viewChild()` function.
 *
 * ```ts
 * @Component({template: '<div #el></div><my-component #cmp />'})
 * export class TestComponent {
 *   divEl = viewChild<ElementRef>('el');                   // Signal<ElementRef|undefined>
 *   divElRequired = viewChild.required<ElementRef>('el');  // Signal<ElementRef>
 *   cmp = viewChild(MyComponent);                          // Signal<MyComponent|undefined>
 *   cmpRequired = viewChild.required(MyComponent);         // Signal<MyComponent>
 * }
 * ```
 *
 * @developerPreview
 * @initializerApiFunction
 */
const viewChild = (() => {
  // Note: This may be considered a side-effect, but nothing will depend on
  // this assignment, unless this `viewChild` constant export is accessed. It's a
  // self-contained side effect that is local to the user facing `viewChild` export.
  viewChildFn.required = viewChildRequiredFn;
  return viewChildFn;
})();
/**
 * Initializes a view children query.
 *
 * Query results are represented as a signal of a read-only collection containing all matched
 * elements.
 *
 * @usageNotes
 * Create a children query in your component by declaring a
 * class field and initializing it with the `viewChildren()` function.
 *
 * ```ts
 * @Component({...})
 * export class TestComponent {
 *   divEls = viewChildren<ElementRef>('el');   // Signal<ReadonlyArray<ElementRef>>
 * }
 * ```
 *
 * @initializerApiFunction
 * @developerPreview
 */
function viewChildren(locator, opts) {
  ngDevMode && assertInInjectionContext(viewChildren);
  return createMultiResultQuerySignalFn();
}
function contentChildFn(locator, opts) {
  ngDevMode && assertInInjectionContext(contentChild);
  return createSingleResultOptionalQuerySignalFn();
}
function contentChildRequiredFn(locator, opts) {
  ngDevMode && assertInInjectionContext(contentChildren);
  return createSingleResultRequiredQuerySignalFn();
}
/**
 * Initializes a content child query. Consider using `contentChild.required` for queries that should
 * always match.
 *
 * @usageNotes
 * Create a child query in your component by declaring a
 * class field and initializing it with the `contentChild()` function.
 *
 * ```ts
 * @Component({...})
 * export class TestComponent {
 *   headerEl = contentChild<ElementRef>('h');                    // Signal<ElementRef|undefined>
 *   headerElElRequired = contentChild.required<ElementRef>('h'); // Signal<ElementRef>
 *   header = contentChild(MyHeader);                             // Signal<MyHeader|undefined>
 *   headerRequired = contentChild.required(MyHeader);            // Signal<MyHeader>
 * }
 * ```
 *
 * @initializerApiFunction
 * @developerPreview
 */
const contentChild = (() => {
  // Note: This may be considered a side-effect, but nothing will depend on
  // this assignment, unless this `viewChild` constant export is accessed. It's a
  // self-contained side effect that is local to the user facing `viewChild` export.
  contentChildFn.required = contentChildRequiredFn;
  return contentChildFn;
})();
/**
 * Initializes a content children query.
 *
 * Query results are represented as a signal of a read-only collection containing all matched
 * elements.
 *
 * @usageNotes
 * Create a children query in your component by declaring a
 * class field and initializing it with the `contentChildren()` function.
 *
 * ```ts
 * @Component({...})
 * export class TestComponent {
 *   headerEl = contentChildren<ElementRef>('h');   // Signal<ReadonlyArray<ElementRef>>
 * }
 * ```
 *
 * @initializerApiFunction
 * @developerPreview
 */
function contentChildren(locator, opts) {
  return createMultiResultQuerySignalFn();
}

/**
 * Creates a model signal.
 *
 * @param initialValue The initial value.
 *   Can be set to {@link REQUIRED_UNSET_VALUE} for required model signals.
 * @param options Additional options for the model.
 */
function createModelSignal(initialValue) {
  const node = Object.create(INPUT_SIGNAL_NODE);
  const emitterRef = new OutputEmitterRef();
  node.value = initialValue;
  function getter() {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.producerAccessed)(node);
    assertModelSet(node.value);
    return node.value;
  }
  getter[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL] = node;
  getter.asReadonly = signalAsReadonlyFn.bind(getter);
  // TODO: Should we throw an error when updating a destroyed model?
  getter.set = newValue => {
    if (!node.equal(node.value, newValue)) {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.signalSetFn)(node, newValue);
      emitterRef.emit(newValue);
    }
  };
  getter.update = updateFn => {
    assertModelSet(node.value);
    getter.set(updateFn(node.value));
  };
  getter.subscribe = emitterRef.subscribe.bind(emitterRef);
  getter.destroyRef = emitterRef.destroyRef;
  if (ngDevMode) {
    getter.toString = () => `[Model Signal: ${getter()}]`;
  }
  return getter;
}
/** Asserts that a model's value is set. */
function assertModelSet(value) {
  if (value === REQUIRED_UNSET_VALUE) {
    throw new RuntimeError(-952 /* RuntimeErrorCode.REQUIRED_MODEL_NO_VALUE */, ngDevMode && 'Model is required but no value is available yet.');
  }
}
function modelFunction(initialValue) {
  ngDevMode && assertInInjectionContext(model);
  return createModelSignal(initialValue);
}
function modelRequiredFunction() {
  ngDevMode && assertInInjectionContext(model);
  return createModelSignal(REQUIRED_UNSET_VALUE);
}
/**
 * `model` declares a writeable signal that is exposed as an input/output
 * pair on the containing directive.
 *
 * The input name is taken either from the class member or from the `alias` option.
 * The output name is generated by taking the input name and appending `Change`.
 *
 * @usageNotes
 *
 * To use `model()`, import the function from `@angular/core`.
 *
 * ```
 * import {model} from '@angular/core`;
 * ```
 *
 * Inside your component, introduce a new class member and initialize
 * it with a call to `model` or `model.required`.
 *
 * ```ts
 * @Directive({
 *   ...
 * })
 * export class MyDir {
 *   firstName = model<string>();            // ModelSignal<string|undefined>
 *   lastName  = model.required<string>();   // ModelSignal<string>
 *   age       = model(0);                   // ModelSignal<number>
 * }
 * ```
 *
 * Inside your component template, you can display the value of a `model`
 * by calling the signal.
 *
 * ```html
 * <span>{{firstName()}}</span>
 * ```
 *
 * Updating the `model` is equivalent to updating a writable signal.
 *
 * ```ts
 * updateName(newFirstName: string): void {
 *   this.firstName.set(newFirstName);
 * }
 * ```
 *
 * @developerPreview
 * @initializerApiFunction
 */
const model = (() => {
  // Note: This may be considered a side-effect, but nothing will depend on
  // this assignment, unless this `model` constant export is accessed. It's a
  // self-contained side effect that is local to the user facing `model` export.
  modelFunction.required = modelRequiredFunction;
  return modelFunction;
})();

// Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not
// explicitly set.
const emitDistinctChangesOnlyDefaultValue = true;
/**
 * Base class for query metadata.
 *
 * @see {@link ContentChildren}
 * @see {@link ContentChild}
 * @see {@link ViewChildren}
 * @see {@link ViewChild}
 *
 * @publicApi
 */
class Query {}
/**
 * ContentChildren decorator and metadata.
 *
 *
 * @Annotation
 * @publicApi
 */
const ContentChildren = makePropDecorator('ContentChildren', (selector, opts = {}) => ({
  selector,
  first: false,
  isViewQuery: false,
  descendants: false,
  emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
  ...opts
}), Query);
/**
 * ContentChild decorator and metadata.
 *
 *
 * @Annotation
 *
 * @publicApi
 */
const ContentChild = makePropDecorator('ContentChild', (selector, opts = {}) => ({
  selector,
  first: true,
  isViewQuery: false,
  descendants: true,
  ...opts
}), Query);
/**
 * ViewChildren decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const ViewChildren = makePropDecorator('ViewChildren', (selector, opts = {}) => ({
  selector,
  first: false,
  isViewQuery: true,
  descendants: true,
  emitDistinctChangesOnly: emitDistinctChangesOnlyDefaultValue,
  ...opts
}), Query);
/**
 * ViewChild decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const ViewChild = makePropDecorator('ViewChild', (selector, opts) => ({
  selector,
  first: true,
  isViewQuery: true,
  descendants: true,
  ...opts
}), Query);

/**
 * Used to resolve resource URLs on `@Component` when used with JIT compilation.
 *
 * Example:
 * ```
 * @Component({
 *   selector: 'my-comp',
 *   templateUrl: 'my-comp.html', // This requires asynchronous resolution
 * })
 * class MyComponent{
 * }
 *
 * // Calling `renderComponent` will fail because `renderComponent` is a synchronous process
 * // and `MyComponent`'s `@Component.templateUrl` needs to be resolved asynchronously.
 *
 * // Calling `resolveComponentResources()` will resolve `@Component.templateUrl` into
 * // `@Component.template`, which allows `renderComponent` to proceed in a synchronous manner.
 *
 * // Use browser's `fetch()` function as the default resource resolution strategy.
 * resolveComponentResources(fetch).then(() => {
 *   // After resolution all URLs have been converted into `template` strings.
 *   renderComponent(MyComponent);
 * });
 *
 * ```
 *
 * NOTE: In AOT the resolution happens during compilation, and so there should be no need
 * to call this method outside JIT mode.
 *
 * @param resourceResolver a function which is responsible for returning a `Promise` to the
 * contents of the resolved URL. Browser's `fetch()` method is a good default implementation.
 */
function resolveComponentResources(resourceResolver) {
  // Store all promises which are fetching the resources.
  const componentResolved = [];
  // Cache so that we don't fetch the same resource more than once.
  const urlMap = new Map();
  function cachedResourceResolve(url) {
    let promise = urlMap.get(url);
    if (!promise) {
      const resp = resourceResolver(url);
      urlMap.set(url, promise = resp.then(unwrapResponse));
    }
    return promise;
  }
  componentResourceResolutionQueue.forEach((component, type) => {
    const promises = [];
    if (component.templateUrl) {
      promises.push(cachedResourceResolve(component.templateUrl).then(template => {
        component.template = template;
      }));
    }
    const styles = typeof component.styles === 'string' ? [component.styles] : component.styles || [];
    component.styles = styles;
    if (component.styleUrl && component.styleUrls?.length) {
      throw new Error('@Component cannot define both `styleUrl` and `styleUrls`. ' + 'Use `styleUrl` if the component has one stylesheet, or `styleUrls` if it has multiple');
    } else if (component.styleUrls?.length) {
      const styleOffset = component.styles.length;
      const styleUrls = component.styleUrls;
      component.styleUrls.forEach((styleUrl, index) => {
        styles.push(''); // pre-allocate array.
        promises.push(cachedResourceResolve(styleUrl).then(style => {
          styles[styleOffset + index] = style;
          styleUrls.splice(styleUrls.indexOf(styleUrl), 1);
          if (styleUrls.length == 0) {
            component.styleUrls = undefined;
          }
        }));
      });
    } else if (component.styleUrl) {
      promises.push(cachedResourceResolve(component.styleUrl).then(style => {
        styles.push(style);
        component.styleUrl = undefined;
      }));
    }
    const fullyResolved = Promise.all(promises).then(() => componentDefResolved(type));
    componentResolved.push(fullyResolved);
  });
  clearResolutionOfComponentResourcesQueue();
  return Promise.all(componentResolved).then(() => undefined);
}
let componentResourceResolutionQueue = new Map();
// Track when existing ɵcmp for a Type is waiting on resources.
const componentDefPendingResolution = new Set();
function maybeQueueResolutionOfComponentResources(type, metadata) {
  if (componentNeedsResolution(metadata)) {
    componentResourceResolutionQueue.set(type, metadata);
    componentDefPendingResolution.add(type);
  }
}
function isComponentDefPendingResolution(type) {
  return componentDefPendingResolution.has(type);
}
function componentNeedsResolution(component) {
  return !!(component.templateUrl && !component.hasOwnProperty('template') || component.styleUrls && component.styleUrls.length || component.styleUrl);
}
function clearResolutionOfComponentResourcesQueue() {
  const old = componentResourceResolutionQueue;
  componentResourceResolutionQueue = new Map();
  return old;
}
function restoreComponentResolutionQueue(queue) {
  componentDefPendingResolution.clear();
  queue.forEach((_, type) => componentDefPendingResolution.add(type));
  componentResourceResolutionQueue = queue;
}
function isComponentResourceResolutionQueueEmpty() {
  return componentResourceResolutionQueue.size === 0;
}
function unwrapResponse(response) {
  return typeof response == 'string' ? response : response.text();
}
function componentDefResolved(type) {
  componentDefPendingResolution.delete(type);
}

/**
 * Map of module-id to the corresponding NgModule.
 */
const modules = new Map();
/**
 * Whether to check for duplicate NgModule registrations.
 *
 * This can be disabled for testing.
 */
let checkForDuplicateNgModules = true;
function assertSameOrNotExisting(id, type, incoming) {
  if (type && type !== incoming && checkForDuplicateNgModules) {
    throw new Error(`Duplicate module registered for ${id} - ${stringify(type)} vs ${stringify(type.name)}`);
  }
}
/**
 * Adds the given NgModule type to Angular's NgModule registry.
 *
 * This is generated as a side-effect of NgModule compilation. Note that the `id` is passed in
 * explicitly and not read from the NgModule definition. This is for two reasons: it avoids a
 * megamorphic read, and in JIT there's a chicken-and-egg problem where the NgModule may not be
 * fully resolved when it's registered.
 *
 * @codeGenApi
 */
function registerNgModuleType(ngModuleType, id) {
  const existing = modules.get(id) || null;
  assertSameOrNotExisting(id, existing, ngModuleType);
  modules.set(id, ngModuleType);
}
function clearModulesForTest() {
  modules.clear();
}
function getRegisteredNgModuleType(id) {
  return modules.get(id);
}
/**
 * Control whether the NgModule registration system enforces that each NgModule type registered has
 * a unique id.
 *
 * This is useful for testing as the NgModule registry cannot be properly reset between tests with
 * Angular's current API.
 */
function setAllowDuplicateNgModuleIdsForTest(allowDuplicates) {
  checkForDuplicateNgModules = !allowDuplicates;
}

/**
 * Validation function invoked at runtime for each binding that might potentially
 * represent a security-sensitive attribute of an <iframe>.
 * See `IFRAME_SECURITY_SENSITIVE_ATTRS` in the
 * `packages/compiler/src/schema/dom_security_schema.ts` script for the full list
 * of such attributes.
 *
 * @codeGenApi
 */
function ɵɵvalidateIframeAttribute(attrValue, tagName, attrName) {
  const lView = getLView();
  const tNode = getSelectedTNode();
  const element = getNativeByTNode(tNode, lView);
  // Restrict any dynamic bindings of security-sensitive attributes/properties
  // on an <iframe> for security reasons.
  if (tNode.type === 2 /* TNodeType.Element */ && tagName.toLowerCase() === 'iframe') {
    const iframe = element;
    // Unset previously applied `src` and `srcdoc` if we come across a situation when
    // a security-sensitive attribute is set later via an attribute/property binding.
    iframe.src = '';
    iframe.srcdoc = trustedHTMLFromString('');
    // Also remove the <iframe> from the document.
    nativeRemoveNode(lView[RENDERER], iframe);
    const errorMessage = ngDevMode && `Angular has detected that the \`${attrName}\` was applied ` + `as a binding to an <iframe>${getTemplateLocationDetails(lView)}. ` + `For security reasons, the \`${attrName}\` can be set on an <iframe> ` + `as a static attribute only. \n` + `To fix this, switch the \`${attrName}\` binding to a static attribute ` + `in a template or in host bindings section.`;
    throw new RuntimeError(-910 /* RuntimeErrorCode.UNSAFE_IFRAME_ATTRS */, errorMessage);
  }
  return attrValue;
}
function getSuperType(type) {
  return Object.getPrototypeOf(type.prototype).constructor;
}
/**
 * Merges the definition from a super class to a sub class.
 * @param definition The definition that is a SubClass of another directive of component
 *
 * @codeGenApi
 */
function ɵɵInheritDefinitionFeature(definition) {
  let superType = getSuperType(definition.type);
  let shouldInheritFields = true;
  const inheritanceChain = [definition];
  while (superType) {
    let superDef = undefined;
    if (isComponentDef(definition)) {
      // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
      superDef = superType.ɵcmp || superType.ɵdir;
    } else {
      if (superType.ɵcmp) {
        throw new RuntimeError(903 /* RuntimeErrorCode.INVALID_INHERITANCE */, ngDevMode && `Directives cannot inherit Components. Directive ${stringifyForError(definition.type)} is attempting to extend component ${stringifyForError(superType)}`);
      }
      // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
      superDef = superType.ɵdir;
    }
    if (superDef) {
      if (shouldInheritFields) {
        inheritanceChain.push(superDef);
        // Some fields in the definition may be empty, if there were no values to put in them that
        // would've justified object creation. Unwrap them if necessary.
        const writeableDef = definition;
        writeableDef.inputs = maybeUnwrapEmpty(definition.inputs);
        writeableDef.inputTransforms = maybeUnwrapEmpty(definition.inputTransforms);
        writeableDef.declaredInputs = maybeUnwrapEmpty(definition.declaredInputs);
        writeableDef.outputs = maybeUnwrapEmpty(definition.outputs);
        // Merge hostBindings
        const superHostBindings = superDef.hostBindings;
        superHostBindings && inheritHostBindings(definition, superHostBindings);
        // Merge queries
        const superViewQuery = superDef.viewQuery;
        const superContentQueries = superDef.contentQueries;
        superViewQuery && inheritViewQuery(definition, superViewQuery);
        superContentQueries && inheritContentQueries(definition, superContentQueries);
        // Merge inputs and outputs
        mergeInputsWithTransforms(definition, superDef);
        fillProperties(definition.outputs, superDef.outputs);
        // Merge animations metadata.
        // If `superDef` is a Component, the `data` field is present (defaults to an empty object).
        if (isComponentDef(superDef) && superDef.data.animation) {
          // If super def is a Component, the `definition` is also a Component, since Directives can
          // not inherit Components (we throw an error above and cannot reach this code).
          const defData = definition.data;
          defData.animation = (defData.animation || []).concat(superDef.data.animation);
        }
      }
      // Run parent features
      const features = superDef.features;
      if (features) {
        for (let i = 0; i < features.length; i++) {
          const feature = features[i];
          if (feature && feature.ngInherit) {
            feature(definition);
          }
          // If `InheritDefinitionFeature` is a part of the current `superDef`, it means that this
          // def already has all the necessary information inherited from its super class(es), so we
          // can stop merging fields from super classes. However we need to iterate through the
          // prototype chain to look for classes that might contain other "features" (like
          // NgOnChanges), which we should invoke for the original `definition`. We set the
          // `shouldInheritFields` flag to indicate that, essentially skipping fields inheritance
          // logic and only invoking functions from the "features" list.
          if (feature === ɵɵInheritDefinitionFeature) {
            shouldInheritFields = false;
          }
        }
      }
    }
    superType = Object.getPrototypeOf(superType);
  }
  mergeHostAttrsAcrossInheritance(inheritanceChain);
}
function mergeInputsWithTransforms(target, source) {
  for (const key in source.inputs) {
    if (!source.inputs.hasOwnProperty(key)) {
      continue;
    }
    if (target.inputs.hasOwnProperty(key)) {
      continue;
    }
    const value = source.inputs[key];
    if (value === undefined) {
      continue;
    }
    target.inputs[key] = value;
    target.declaredInputs[key] = source.declaredInputs[key];
    // If the input is inherited, and we have a transform for it, we also inherit it.
    // Note that transforms should not be inherited if the input has its own metadata
    // in the `source` directive itself already (i.e. the input is re-declared/overridden).
    if (source.inputTransforms !== null) {
      // Note: transforms are stored with their minified names.
      // Perf: only access the minified name when there are source transforms.
      const minifiedName = Array.isArray(value) ? value[0] : value;
      if (!source.inputTransforms.hasOwnProperty(minifiedName)) {
        continue;
      }
      target.inputTransforms ??= {};
      target.inputTransforms[minifiedName] = source.inputTransforms[minifiedName];
    }
  }
}
/**
 * Merge the `hostAttrs` and `hostVars` from the inherited parent to the base class.
 *
 * @param inheritanceChain A list of `WritableDefs` starting at the top most type and listing
 * sub-types in order. For each type take the `hostAttrs` and `hostVars` and merge it with the child
 * type.
 */
function mergeHostAttrsAcrossInheritance(inheritanceChain) {
  let hostVars = 0;
  let hostAttrs = null;
  // We process the inheritance order from the base to the leaves here.
  for (let i = inheritanceChain.length - 1; i >= 0; i--) {
    const def = inheritanceChain[i];
    // For each `hostVars`, we need to add the superclass amount.
    def.hostVars = hostVars += def.hostVars;
    // for each `hostAttrs` we need to merge it with superclass.
    def.hostAttrs = mergeHostAttrs(def.hostAttrs, hostAttrs = mergeHostAttrs(hostAttrs, def.hostAttrs));
  }
}
function maybeUnwrapEmpty(value) {
  if (value === EMPTY_OBJ) {
    return {};
  } else if (value === EMPTY_ARRAY) {
    return [];
  } else {
    return value;
  }
}
function inheritViewQuery(definition, superViewQuery) {
  const prevViewQuery = definition.viewQuery;
  if (prevViewQuery) {
    definition.viewQuery = (rf, ctx) => {
      superViewQuery(rf, ctx);
      prevViewQuery(rf, ctx);
    };
  } else {
    definition.viewQuery = superViewQuery;
  }
}
function inheritContentQueries(definition, superContentQueries) {
  const prevContentQueries = definition.contentQueries;
  if (prevContentQueries) {
    definition.contentQueries = (rf, ctx, directiveIndex) => {
      superContentQueries(rf, ctx, directiveIndex);
      prevContentQueries(rf, ctx, directiveIndex);
    };
  } else {
    definition.contentQueries = superContentQueries;
  }
}
function inheritHostBindings(definition, superHostBindings) {
  const prevHostBindings = definition.hostBindings;
  if (prevHostBindings) {
    definition.hostBindings = (rf, ctx) => {
      superHostBindings(rf, ctx);
      prevHostBindings(rf, ctx);
    };
  } else {
    definition.hostBindings = superHostBindings;
  }
}

/**
 * Fields which exist on either directive or component definitions, and need to be copied from
 * parent to child classes by the `ɵɵCopyDefinitionFeature`.
 */
const COPY_DIRECTIVE_FIELDS = [
// The child class should use the providers of its parent.
'providersResolver'
// Not listed here are any fields which are handled by the `ɵɵInheritDefinitionFeature`, such
// as inputs, outputs, and host binding functions.
];
/**
 * Fields which exist only on component definitions, and need to be copied from parent to child
 * classes by the `ɵɵCopyDefinitionFeature`.
 *
 * The type here allows any field of `ComponentDef` which is not also a property of `DirectiveDef`,
 * since those should go in `COPY_DIRECTIVE_FIELDS` above.
 */
const COPY_COMPONENT_FIELDS = [
// The child class should use the template function of its parent, including all template
// semantics.
'template', 'decls', 'consts', 'vars', 'onPush', 'ngContentSelectors',
// The child class should use the CSS styles of its parent, including all styling semantics.
'styles', 'encapsulation',
// The child class should be checked by the runtime in the same way as its parent.
'schemas'];
/**
 * Copies the fields not handled by the `ɵɵInheritDefinitionFeature` from the supertype of a
 * definition.
 *
 * This exists primarily to support ngcc migration of an existing View Engine pattern, where an
 * entire decorator is inherited from a parent to a child class. When ngcc detects this case, it
 * generates a skeleton definition on the child class, and applies this feature.
 *
 * The `ɵɵCopyDefinitionFeature` then copies any needed fields from the parent class' definition,
 * including things like the component template function.
 *
 * @param definition The definition of a child class which inherits from a parent class with its
 * own definition.
 *
 * @codeGenApi
 */
function ɵɵCopyDefinitionFeature(definition) {
  let superType = getSuperType(definition.type);
  let superDef = undefined;
  if (isComponentDef(definition)) {
    // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
    superDef = superType.ɵcmp;
  } else {
    // Don't use getComponentDef/getDirectiveDef. This logic relies on inheritance.
    superDef = superType.ɵdir;
  }
  // Needed because `definition` fields are readonly.
  const defAny = definition;
  // Copy over any fields that apply to either directives or components.
  for (const field of COPY_DIRECTIVE_FIELDS) {
    defAny[field] = superDef[field];
  }
  if (isComponentDef(superDef)) {
    // Copy over any component-specific fields.
    for (const field of COPY_COMPONENT_FIELDS) {
      defAny[field] = superDef[field];
    }
  }
}

/**
 * This feature adds the host directives behavior to a directive definition by patching a
 * function onto it. The expectation is that the runtime will invoke the function during
 * directive matching.
 *
 * For example:
 * ```ts
 * class ComponentWithHostDirective {
 *   static ɵcmp = defineComponent({
 *    type: ComponentWithHostDirective,
 *    features: [ɵɵHostDirectivesFeature([
 *      SimpleHostDirective,
 *      {directive: AdvancedHostDirective, inputs: ['foo: alias'], outputs: ['bar']},
 *    ])]
 *  });
 * }
 * ```
 *
 * @codeGenApi
 */
function ɵɵHostDirectivesFeature(rawHostDirectives) {
  const feature = definition => {
    const resolved = (Array.isArray(rawHostDirectives) ? rawHostDirectives : rawHostDirectives()).map(dir => {
      return typeof dir === 'function' ? {
        directive: resolveForwardRef(dir),
        inputs: EMPTY_OBJ,
        outputs: EMPTY_OBJ
      } : {
        directive: resolveForwardRef(dir.directive),
        inputs: bindingArrayToMap(dir.inputs),
        outputs: bindingArrayToMap(dir.outputs)
      };
    });
    if (definition.hostDirectives === null) {
      definition.findHostDirectiveDefs = findHostDirectiveDefs;
      definition.hostDirectives = resolved;
    } else {
      definition.hostDirectives.unshift(...resolved);
    }
  };
  feature.ngInherit = true;
  return feature;
}
function findHostDirectiveDefs(currentDef, matchedDefs, hostDirectiveDefs) {
  if (currentDef.hostDirectives !== null) {
    for (const hostDirectiveConfig of currentDef.hostDirectives) {
      const hostDirectiveDef = getDirectiveDef(hostDirectiveConfig.directive);
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        validateHostDirective(hostDirectiveConfig, hostDirectiveDef);
      }
      // We need to patch the `declaredInputs` so that
      // `ngOnChanges` can map the properties correctly.
      patchDeclaredInputs(hostDirectiveDef.declaredInputs, hostDirectiveConfig.inputs);
      // Host directives execute before the host so that its host bindings can be overwritten.
      findHostDirectiveDefs(hostDirectiveDef, matchedDefs, hostDirectiveDefs);
      hostDirectiveDefs.set(hostDirectiveDef, hostDirectiveConfig);
      matchedDefs.push(hostDirectiveDef);
    }
  }
}
/**
 * Converts an array in the form of `['publicName', 'alias', 'otherPublicName', 'otherAlias']` into
 * a map in the form of `{publicName: 'alias', otherPublicName: 'otherAlias'}`.
 */
function bindingArrayToMap(bindings) {
  if (bindings === undefined || bindings.length === 0) {
    return EMPTY_OBJ;
  }
  const result = {};
  for (let i = 0; i < bindings.length; i += 2) {
    result[bindings[i]] = bindings[i + 1];
  }
  return result;
}
/**
 * `ngOnChanges` has some leftover legacy ViewEngine behavior where the keys inside the
 * `SimpleChanges` event refer to the *declared* name of the input, not its public name or its
 * minified name. E.g. in `@Input('alias') foo: string`, the name in the `SimpleChanges` object
 * will always be `foo`, and not `alias` or the minified name of `foo` in apps using property
 * minification.
 *
 * This is achieved through the `DirectiveDef.declaredInputs` map that is constructed when the
 * definition is declared. When a property is written to the directive instance, the
 * `NgOnChangesFeature` will try to remap the property name being written to using the
 * `declaredInputs`.
 *
 * Since the host directive input remapping happens during directive matching, `declaredInputs`
 * won't contain the new alias that the input is available under. This function addresses the
 * issue by patching the host directive aliases to the `declaredInputs`. There is *not* a risk of
 * this patching accidentally introducing new inputs to the host directive, because `declaredInputs`
 * is used *only* by the `NgOnChangesFeature` when determining what name is used in the
 * `SimpleChanges` object which won't be reached if an input doesn't exist.
 */
function patchDeclaredInputs(declaredInputs, exposedInputs) {
  for (const publicName in exposedInputs) {
    if (exposedInputs.hasOwnProperty(publicName)) {
      const remappedPublicName = exposedInputs[publicName];
      const privateName = declaredInputs[publicName];
      // We *technically* shouldn't be able to hit this case because we can't have multiple
      // inputs on the same property and we have validations against conflicting aliases in
      // `validateMappings`. If we somehow did, it would lead to `ngOnChanges` being invoked
      // with the wrong name so we have a non-user-friendly assertion here just in case.
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && declaredInputs.hasOwnProperty(remappedPublicName)) {
        assertEqual(declaredInputs[remappedPublicName], declaredInputs[publicName], `Conflicting host directive input alias ${publicName}.`);
      }
      declaredInputs[remappedPublicName] = privateName;
    }
  }
}
/**
 * Verifies that the host directive has been configured correctly.
 * @param hostDirectiveConfig Host directive configuration object.
 * @param directiveDef Directive definition of the host directive.
 */
function validateHostDirective(hostDirectiveConfig, directiveDef) {
  const type = hostDirectiveConfig.directive;
  if (directiveDef === null) {
    if (getComponentDef(type) !== null) {
      throw new RuntimeError(310 /* RuntimeErrorCode.HOST_DIRECTIVE_COMPONENT */, `Host directive ${type.name} cannot be a component.`);
    }
    throw new RuntimeError(307 /* RuntimeErrorCode.HOST_DIRECTIVE_UNRESOLVABLE */, `Could not resolve metadata for host directive ${type.name}. ` + `Make sure that the ${type.name} class is annotated with an @Directive decorator.`);
  }
  if (!directiveDef.standalone) {
    throw new RuntimeError(308 /* RuntimeErrorCode.HOST_DIRECTIVE_NOT_STANDALONE */, `Host directive ${directiveDef.type.name} must be standalone.`);
  }
  validateMappings('input', directiveDef, hostDirectiveConfig.inputs);
  validateMappings('output', directiveDef, hostDirectiveConfig.outputs);
}
/**
 * Checks that the host directive inputs/outputs configuration is valid.
 * @param bindingType Kind of binding that is being validated. Used in the error message.
 * @param def Definition of the host directive that is being validated against.
 * @param hostDirectiveBindings Host directive mapping object that shold be validated.
 */
function validateMappings(bindingType, def, hostDirectiveBindings) {
  const className = def.type.name;
  const bindings = bindingType === 'input' ? def.inputs : def.outputs;
  for (const publicName in hostDirectiveBindings) {
    if (hostDirectiveBindings.hasOwnProperty(publicName)) {
      if (!bindings.hasOwnProperty(publicName)) {
        throw new RuntimeError(311 /* RuntimeErrorCode.HOST_DIRECTIVE_UNDEFINED_BINDING */, `Directive ${className} does not have an ${bindingType} with a public name of ${publicName}.`);
      }
      const remappedPublicName = hostDirectiveBindings[publicName];
      if (bindings.hasOwnProperty(remappedPublicName) && remappedPublicName !== publicName) {
        throw new RuntimeError(312 /* RuntimeErrorCode.HOST_DIRECTIVE_CONFLICTING_ALIAS */, `Cannot alias ${bindingType} ${publicName} of host directive ${className} to ${remappedPublicName}, because it already has a different ${bindingType} with the same public name.`);
      }
    }
  }
}

/**
 * Decorates the directive definition with support for input transform functions.
 *
 * If the directive uses inheritance, the feature should be included before the
 * `InheritDefinitionFeature` to ensure that the `inputTransforms` field is populated.
 *
 * @codeGenApi
 */
function ɵɵInputTransformsFeature(definition) {
  const inputs = definition.inputConfig;
  const inputTransforms = {};
  for (const minifiedKey in inputs) {
    if (inputs.hasOwnProperty(minifiedKey)) {
      // Note: the private names are used for the keys, rather than the public ones, because public
      // names can be re-aliased in host directives which would invalidate the lookup.
      const value = inputs[minifiedKey];
      if (Array.isArray(value) && value[3]) {
        inputTransforms[minifiedKey] = value[3];
      }
    }
  }
  definition.inputTransforms = inputTransforms;
}

/**
 * Represents an instance of an `NgModule` created by an `NgModuleFactory`.
 * Provides access to the `NgModule` instance and related objects.
 *
 * @publicApi
 */
class NgModuleRef$1 {}
/**
 * @publicApi
 *
 * @deprecated
 * This class was mostly used as a part of ViewEngine-based JIT API and is no longer needed in Ivy
 * JIT mode. See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes)
 * for additional context. Angular provides APIs that accept NgModule classes directly (such as
 * [PlatformRef.bootstrapModule](api/core/PlatformRef#bootstrapModule) and
 * [createNgModule](api/core/createNgModule)), consider switching to those APIs instead of
 * using factory-based ones.
 */
class NgModuleFactory$1 {}

/**
 * Returns a new NgModuleRef instance based on the NgModule class and parent injector provided.
 *
 * @param ngModule NgModule class.
 * @param parentInjector Optional injector instance to use as a parent for the module injector. If
 *     not provided, `NullInjector` will be used instead.
 * @returns NgModuleRef that represents an NgModule instance.
 *
 * @publicApi
 */
function createNgModule(ngModule, parentInjector) {
  return new NgModuleRef(ngModule, parentInjector ?? null, []);
}
/**
 * The `createNgModule` function alias for backwards-compatibility.
 * Please avoid using it directly and use `createNgModule` instead.
 *
 * @deprecated Use `createNgModule` instead.
 */
const createNgModuleRef = createNgModule;
class NgModuleRef extends NgModuleRef$1 {
  constructor(ngModuleType, _parent, additionalProviders) {
    super();
    this._parent = _parent;
    // tslint:disable-next-line:require-internal-with-underscore
    this._bootstrapComponents = [];
    this.destroyCbs = [];
    // When bootstrapping a module we have a dependency graph that looks like this:
    // ApplicationRef -> ComponentFactoryResolver -> NgModuleRef. The problem is that if the
    // module being resolved tries to inject the ComponentFactoryResolver, it'll create a
    // circular dependency which will result in a runtime error, because the injector doesn't
    // exist yet. We work around the issue by creating the ComponentFactoryResolver ourselves
    // and providing it, rather than letting the injector resolve it.
    this.componentFactoryResolver = new ComponentFactoryResolver(this);
    const ngModuleDef = getNgModuleDef(ngModuleType);
    ngDevMode && assertDefined(ngModuleDef, `NgModule '${stringify(ngModuleType)}' is not a subtype of 'NgModuleType'.`);
    this._bootstrapComponents = maybeUnwrapFn(ngModuleDef.bootstrap);
    this._r3Injector = createInjectorWithoutInjectorInstances(ngModuleType, _parent, [{
      provide: NgModuleRef$1,
      useValue: this
    }, {
      provide: ComponentFactoryResolver$1,
      useValue: this.componentFactoryResolver
    }, ...additionalProviders], stringify(ngModuleType), new Set(['environment']));
    // We need to resolve the injector types separately from the injector creation, because
    // the module might be trying to use this ref in its constructor for DI which will cause a
    // circular error that will eventually error out, because the injector isn't created yet.
    this._r3Injector.resolveInjectorInitializers();
    this.instance = this._r3Injector.get(ngModuleType);
  }
  get injector() {
    return this._r3Injector;
  }
  destroy() {
    ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
    const injector = this._r3Injector;
    !injector.destroyed && injector.destroy();
    this.destroyCbs.forEach(fn => fn());
    this.destroyCbs = null;
  }
  onDestroy(callback) {
    ngDevMode && assertDefined(this.destroyCbs, 'NgModule already destroyed');
    this.destroyCbs.push(callback);
  }
}
class NgModuleFactory extends NgModuleFactory$1 {
  constructor(moduleType) {
    super();
    this.moduleType = moduleType;
  }
  create(parentInjector) {
    return new NgModuleRef(this.moduleType, parentInjector, []);
  }
}
function createNgModuleRefWithProviders(moduleType, parentInjector, additionalProviders) {
  return new NgModuleRef(moduleType, parentInjector, additionalProviders);
}
class EnvironmentNgModuleRefAdapter extends NgModuleRef$1 {
  constructor(config) {
    super();
    this.componentFactoryResolver = new ComponentFactoryResolver(this);
    this.instance = null;
    const injector = new R3Injector([...config.providers, {
      provide: NgModuleRef$1,
      useValue: this
    }, {
      provide: ComponentFactoryResolver$1,
      useValue: this.componentFactoryResolver
    }], config.parent || getNullInjector(), config.debugName, new Set(['environment']));
    this.injector = injector;
    if (config.runEnvironmentInitializers) {
      injector.resolveInjectorInitializers();
    }
  }
  destroy() {
    this.injector.destroy();
  }
  onDestroy(callback) {
    this.injector.onDestroy(callback);
  }
}
/**
 * Create a new environment injector.
 *
 * Learn more about environment injectors in
 * [this guide](guide/standalone-components#environment-injectors).
 *
 * @param providers An array of providers.
 * @param parent A parent environment injector.
 * @param debugName An optional name for this injector instance, which will be used in error
 *     messages.
 *
 * @publicApi
 */
function createEnvironmentInjector(providers, parent, debugName = null) {
  const adapter = new EnvironmentNgModuleRefAdapter({
    providers,
    parent,
    debugName,
    runEnvironmentInitializers: true
  });
  return adapter.injector;
}

/**
 * A service used by the framework to create and cache injector instances.
 *
 * This service is used to create a single injector instance for each defer
 * block definition, to avoid creating an injector for each defer block instance
 * of a certain type.
 */
class CachedInjectorService {
  constructor() {
    this.cachedInjectors = new Map();
  }
  getOrCreateInjector(key, parentInjector, providers, debugName) {
    if (!this.cachedInjectors.has(key)) {
      const injector = providers.length > 0 ? createEnvironmentInjector(providers, parentInjector, debugName) : null;
      this.cachedInjectors.set(key, injector);
    }
    return this.cachedInjectors.get(key);
  }
  ngOnDestroy() {
    try {
      for (const injector of this.cachedInjectors.values()) {
        if (injector !== null) {
          injector.destroy();
        }
      }
    } finally {
      this.cachedInjectors.clear();
    }
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: CachedInjectorService,
      providedIn: 'environment',
      factory: () => new CachedInjectorService()
    });
  }
}

/**
 * The name of a field that Angular monkey-patches onto a component
 * class to store a function that loads defer-loadable dependencies
 * and applies metadata to a class.
 */
const ASYNC_COMPONENT_METADATA_FN = '__ngAsyncComponentMetadataFn__';
/**
 * If a given component has unresolved async metadata - returns a reference
 * to a function that applies component metadata after resolving defer-loadable
 * dependencies. Otherwise - this function returns `null`.
 */
function getAsyncClassMetadataFn(type) {
  const componentClass = type; // cast to `any`, so that we can read a monkey-patched field
  return componentClass[ASYNC_COMPONENT_METADATA_FN] ?? null;
}
/**
 * Handles the process of applying metadata info to a component class in case
 * component template has defer blocks (thus some dependencies became deferrable).
 *
 * @param type Component class where metadata should be added
 * @param dependencyLoaderFn Function that loads dependencies
 * @param metadataSetterFn Function that forms a scope in which the `setClassMetadata` is invoked
 */
function setClassMetadataAsync(type, dependencyLoaderFn, metadataSetterFn) {
  const componentClass = type; // cast to `any`, so that we can monkey-patch it
  componentClass[ASYNC_COMPONENT_METADATA_FN] = () => Promise.all(dependencyLoaderFn()).then(dependencies => {
    metadataSetterFn(...dependencies);
    // Metadata is now set, reset field value to indicate that this component
    // can by used/compiled synchronously.
    componentClass[ASYNC_COMPONENT_METADATA_FN] = null;
    return dependencies;
  });
  return componentClass[ASYNC_COMPONENT_METADATA_FN];
}
/**
 * Adds decorator, constructor, and property metadata to a given type via static metadata fields
 * on the type.
 *
 * These metadata fields can later be read with Angular's `ReflectionCapabilities` API.
 *
 * Calls to `setClassMetadata` can be guarded by ngDevMode, resulting in the metadata assignments
 * being tree-shaken away during production builds.
 */
function setClassMetadata(type, decorators, ctorParameters, propDecorators) {
  return noSideEffects(() => {
    const clazz = type;
    if (decorators !== null) {
      if (clazz.hasOwnProperty('decorators') && clazz.decorators !== undefined) {
        clazz.decorators.push(...decorators);
      } else {
        clazz.decorators = decorators;
      }
    }
    if (ctorParameters !== null) {
      // Rather than merging, clobber the existing parameters. If other projects exist which
      // use tsickle-style annotations and reflect over them in the same way, this could
      // cause issues, but that is vanishingly unlikely.
      clazz.ctorParameters = ctorParameters;
    }
    if (propDecorators !== null) {
      // The property decorator objects are merged as it is possible different fields have
      // different decorator types. Decorators on individual fields are not merged, as it's
      // also incredibly unlikely that a field will be decorated both with an Angular
      // decorator and a non-Angular decorator that's also been downleveled.
      if (clazz.hasOwnProperty('propDecorators') && clazz.propDecorators !== undefined) {
        clazz.propDecorators = {
          ...clazz.propDecorators,
          ...propDecorators
        };
      } else {
        clazz.propDecorators = propDecorators;
      }
    }
  });
}

/*
 * This file exists to support compilation of @angular/core in Ivy mode.
 *
 * When the Angular compiler processes a compilation unit, it normally writes imports to
 * @angular/core. When compiling the core package itself this strategy isn't usable. Instead, the
 * compiler writes imports to this file.
 *
 * Only a subset of such imports are supported - core is not allowed to declare components or pipes.
 * A check in ngtsc's `R3SymbolsImportRewriter` validates this condition. The rewriter is only used
 * when compiling @angular/core and is responsible for translating an external name (prefixed with
 * ɵ) to the internal symbol name as exported below.
 *
 * The below symbols are used for @Injectable and @NgModule compilation.
 */
/**
 * The existence of this constant (in this particular file) informs the Angular compiler that the
 * current program is actually @angular/core, which needs to be compiled specially.
 */
const ITS_JUST_ANGULAR = true;

/**
 * *Internal* service that keeps track of pending tasks happening in the system.
 *
 * This information is needed to make sure that the serialization on the server
 * is delayed until all tasks in the queue (such as an initial navigation or a
 * pending HTTP request) are completed.
 *
 * Pending tasks continue to contribute to the stableness of `ApplicationRef`
 * throughout the lifetime of the application.
 */
class PendingTasks {
  constructor() {
    this.taskId = 0;
    this.pendingTasks = new Set();
    this.hasPendingTasks = new rxjs__WEBPACK_IMPORTED_MODULE_4__.BehaviorSubject(false);
  }
  get _hasPendingTasks() {
    return this.hasPendingTasks.value;
  }
  add() {
    if (!this._hasPendingTasks) {
      this.hasPendingTasks.next(true);
    }
    const taskId = this.taskId++;
    this.pendingTasks.add(taskId);
    return taskId;
  }
  remove(taskId) {
    this.pendingTasks.delete(taskId);
    if (this.pendingTasks.size === 0 && this._hasPendingTasks) {
      this.hasPendingTasks.next(false);
    }
  }
  ngOnDestroy() {
    this.pendingTasks.clear();
    if (this._hasPendingTasks) {
      this.hasPendingTasks.next(false);
    }
  }
  static {
    this.ɵfac = function PendingTasks_Factory(t) {
      return new (t || PendingTasks)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: PendingTasks,
      factory: PendingTasks.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PendingTasks, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function isIterable(obj) {
  return obj !== null && typeof obj === 'object' && obj[Symbol.iterator] !== undefined;
}
function isListLikeIterable(obj) {
  if (!isJsObject(obj)) return false;
  return Array.isArray(obj) || !(obj instanceof Map) &&
  // JS Map are iterables but return entries as [k, v]
  Symbol.iterator in obj; // JS Iterable have a Symbol.iterator prop
}
function areIterablesEqual(a, b, comparator) {
  const iterator1 = a[Symbol.iterator]();
  const iterator2 = b[Symbol.iterator]();
  while (true) {
    const item1 = iterator1.next();
    const item2 = iterator2.next();
    if (item1.done && item2.done) return true;
    if (item1.done || item2.done) return false;
    if (!comparator(item1.value, item2.value)) return false;
  }
}
function iterateListLike(obj, fn) {
  if (Array.isArray(obj)) {
    for (let i = 0; i < obj.length; i++) {
      fn(obj[i]);
    }
  } else {
    const iterator = obj[Symbol.iterator]();
    let item;
    while (!(item = iterator.next()).done) {
      fn(item.value);
    }
  }
}
function isJsObject(o) {
  return o !== null && (typeof o === 'function' || typeof o === 'object');
}
function devModeEqual(a, b) {
  const isListLikeIterableA = isListLikeIterable(a);
  const isListLikeIterableB = isListLikeIterable(b);
  if (isListLikeIterableA && isListLikeIterableB) {
    return areIterablesEqual(a, b, devModeEqual);
  } else {
    const isAObject = a && (typeof a === 'object' || typeof a === 'function');
    const isBObject = b && (typeof b === 'object' || typeof b === 'function');
    if (!isListLikeIterableA && isAObject && !isListLikeIterableB && isBObject) {
      return true;
    } else {
      return Object.is(a, b);
    }
  }
}

// TODO(misko): consider inlining
/** Updates binding and returns the value. */
function updateBinding(lView, bindingIndex, value) {
  return lView[bindingIndex] = value;
}
/** Gets the current binding value. */
function getBinding(lView, bindingIndex) {
  ngDevMode && assertIndexInRange(lView, bindingIndex);
  ngDevMode && assertNotSame(lView[bindingIndex], NO_CHANGE, 'Stored value should never be NO_CHANGE.');
  return lView[bindingIndex];
}
/**
 * Updates binding if changed, then returns whether it was updated.
 *
 * This function also checks the `CheckNoChangesMode` and throws if changes are made.
 * Some changes (Objects/iterables) during `CheckNoChangesMode` are exempt to comply with VE
 * behavior.
 *
 * @param lView current `LView`
 * @param bindingIndex The binding in the `LView` to check
 * @param value New value to check against `lView[bindingIndex]`
 * @returns `true` if the bindings has changed. (Throws if binding has changed during
 *          `CheckNoChangesMode`)
 */
function bindingUpdated(lView, bindingIndex, value) {
  ngDevMode && assertNotSame(value, NO_CHANGE, 'Incoming value should never be NO_CHANGE.');
  ngDevMode && assertLessThan(bindingIndex, lView.length, `Slot should have been initialized to NO_CHANGE`);
  const oldValue = lView[bindingIndex];
  if (Object.is(oldValue, value)) {
    return false;
  } else {
    if (ngDevMode && isInCheckNoChangesMode()) {
      // View engine didn't report undefined values as changed on the first checkNoChanges pass
      // (before the change detection was run).
      const oldValueToCompare = oldValue !== NO_CHANGE ? oldValue : undefined;
      if (!devModeEqual(oldValueToCompare, value)) {
        const details = getExpressionChangedErrorDetails(lView, bindingIndex, oldValueToCompare, value);
        throwErrorIfNoChangesMode(oldValue === NO_CHANGE, details.oldValue, details.newValue, details.propName, lView);
      }
      // There was a change, but the `devModeEqual` decided that the change is exempt from an error.
      // For this reason we exit as if no change. The early exit is needed to prevent the changed
      // value to be written into `LView` (If we would write the new value that we would not see it
      // as change on next CD.)
      return false;
    }
    lView[bindingIndex] = value;
    return true;
  }
}
/** Updates 2 bindings if changed, then returns whether either was updated. */
function bindingUpdated2(lView, bindingIndex, exp1, exp2) {
  const different = bindingUpdated(lView, bindingIndex, exp1);
  return bindingUpdated(lView, bindingIndex + 1, exp2) || different;
}
/** Updates 3 bindings if changed, then returns whether any was updated. */
function bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) {
  const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
  return bindingUpdated(lView, bindingIndex + 2, exp3) || different;
}
/** Updates 4 bindings if changed, then returns whether any was updated. */
function bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) {
  const different = bindingUpdated2(lView, bindingIndex, exp1, exp2);
  return bindingUpdated2(lView, bindingIndex + 2, exp3, exp4) || different;
}

/**
 * Checks whether a TNode is considered detached, i.e. not present in the
 * translated i18n template. We should not attempt hydration for such nodes
 * and instead, use a regular "creation mode".
 */
function isDetachedByI18n(tNode) {
  return (tNode.flags & 32 /* TNodeFlags.isDetached */) === 32 /* TNodeFlags.isDetached */;
}
function templateFirstCreatePass(index, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) {
  ngDevMode && assertFirstCreatePass(tView);
  ngDevMode && ngDevMode.firstCreatePass++;
  const tViewConsts = tView.consts;
  // TODO(pk): refactor getOrCreateTNode to have the "create" only version
  const tNode = getOrCreateTNode(tView, index, 4 /* TNodeType.Container */, tagName || null, getConstant(tViewConsts, attrsIndex));
  resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
  registerPostOrderHooks(tView, tNode);
  const embeddedTView = tNode.tView = createTView(2 /* TViewType.Embedded */, tNode, templateFn, decls, vars, tView.directiveRegistry, tView.pipeRegistry, null, tView.schemas, tViewConsts, null /* ssrId */);
  if (tView.queries !== null) {
    tView.queries.template(tView, tNode);
    embeddedTView.queries = tView.queries.embeddedTView(tNode);
  }
  return tNode;
}
/**
 * Creates an LContainer for an ng-template (dynamically-inserted view), e.g.
 *
 * <ng-template #foo>
 *    <div></div>
 * </ng-template>
 *
 * @param index The index of the container in the data array
 * @param templateFn Inline template
 * @param decls The number of nodes, local refs, and pipes for this template
 * @param vars The number of bindings for this template
 * @param tagName The name of the container element, if applicable
 * @param attrsIndex Index of template attributes in the `consts` array.
 * @param localRefs Index of the local references in the `consts` array.
 * @param localRefExtractor A function which extracts local-refs values from the template.
 *        Defaults to the current element associated with the local-ref.
 *
 * @codeGenApi
 */
function ɵɵtemplate(index, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex, localRefExtractor) {
  const lView = getLView();
  const tView = getTView();
  const adjustedIndex = index + HEADER_OFFSET;
  const tNode = tView.firstCreatePass ? templateFirstCreatePass(adjustedIndex, tView, lView, templateFn, decls, vars, tagName, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
  setCurrentTNode(tNode, false);
  const comment = _locateOrCreateContainerAnchor(tView, lView, tNode, index);
  if (wasLastNodeCreated()) {
    appendChild(tView, lView, comment, tNode);
  }
  attachPatchData(comment, lView);
  const lContainer = createLContainer(comment, lView, comment, tNode);
  lView[adjustedIndex] = lContainer;
  addToViewTree(lView, lContainer);
  // If hydration is enabled, looks up dehydrated views in the DOM
  // using hydration annotation info and stores those views on LContainer.
  // In client-only mode, this function is a noop.
  populateDehydratedViewsInLContainer(lContainer, tNode, lView);
  if (isDirectiveHost(tNode)) {
    createDirectivesInstances(tView, lView, tNode);
  }
  if (localRefsIndex != null) {
    saveResolvedLocalsInData(lView, tNode, localRefExtractor);
  }
  return ɵɵtemplate;
}
let _locateOrCreateContainerAnchor = createContainerAnchorImpl;
/**
 * Regular creation mode for LContainers and their anchor (comment) nodes.
 */
function createContainerAnchorImpl(tView, lView, tNode, index) {
  lastNodeWasCreated(true);
  return lView[RENDERER].createComment(ngDevMode ? 'container' : '');
}
/**
 * Enables hydration code path (to lookup existing elements in DOM)
 * in addition to the regular creation mode for LContainers and their
 * anchor (comment) nodes.
 */
function locateOrCreateContainerAnchorImpl(tView, lView, tNode, index) {
  const hydrationInfo = lView[HYDRATION];
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
  lastNodeWasCreated(isNodeCreationMode);
  // Regular creation mode.
  if (isNodeCreationMode) {
    return createContainerAnchorImpl(tView, lView, tNode, index);
  }
  const ssrId = hydrationInfo.data[TEMPLATES]?.[index] ?? null;
  // Apply `ssrId` value to the underlying TView if it was not previously set.
  //
  // There might be situations when the same component is present in a template
  // multiple times and some instances are opted-out of using hydration via
  // `ngSkipHydration` attribute. In this scenario, at the time a TView is created,
  // the `ssrId` might be `null` (if the first component is opted-out of hydration).
  // The code below makes sure that the `ssrId` is applied to the TView if it's still
  // `null` and verifies we never try to override it with a different value.
  if (ssrId !== null && tNode.tView !== null) {
    if (tNode.tView.ssrId === null) {
      tNode.tView.ssrId = ssrId;
    } else {
      ngDevMode && assertEqual(tNode.tView.ssrId, ssrId, 'Unexpected value of the `ssrId` for this TView');
    }
  }
  // Hydration mode, looking up existing elements in DOM.
  const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
  ngDevMode && validateNodeExists(currentRNode, lView, tNode);
  setSegmentHead(hydrationInfo, index, currentRNode);
  const viewContainerSize = calcSerializedContainerSize(hydrationInfo, index);
  const comment = siblingAfter(viewContainerSize, currentRNode);
  if (ngDevMode) {
    validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
    markRNodeAsClaimedByHydration(comment);
  }
  return comment;
}
function enableLocateOrCreateContainerAnchorImpl() {
  _locateOrCreateContainerAnchor = locateOrCreateContainerAnchorImpl;
}

/**
 * Describes the state of defer block dependency loading.
 */
var DeferDependenciesLoadingState;
(function (DeferDependenciesLoadingState) {
  /** Initial state, dependency loading is not yet triggered */
  DeferDependenciesLoadingState[DeferDependenciesLoadingState["NOT_STARTED"] = 0] = "NOT_STARTED";
  /** Dependency loading is in progress */
  DeferDependenciesLoadingState[DeferDependenciesLoadingState["IN_PROGRESS"] = 1] = "IN_PROGRESS";
  /** Dependency loading has completed successfully */
  DeferDependenciesLoadingState[DeferDependenciesLoadingState["COMPLETE"] = 2] = "COMPLETE";
  /** Dependency loading has failed */
  DeferDependenciesLoadingState[DeferDependenciesLoadingState["FAILED"] = 3] = "FAILED";
})(DeferDependenciesLoadingState || (DeferDependenciesLoadingState = {}));
/** Slot index where `minimum` parameter value is stored. */
const MINIMUM_SLOT = 0;
/** Slot index where `after` parameter value is stored. */
const LOADING_AFTER_SLOT = 1;
/**
 * Describes the current state of this defer block instance.
 *
 * @publicApi
 * @developerPreview
 */
var DeferBlockState;
(function (DeferBlockState) {
  /** The placeholder block content is rendered */
  DeferBlockState[DeferBlockState["Placeholder"] = 0] = "Placeholder";
  /** The loading block content is rendered */
  DeferBlockState[DeferBlockState["Loading"] = 1] = "Loading";
  /** The main content block content is rendered */
  DeferBlockState[DeferBlockState["Complete"] = 2] = "Complete";
  /** The error block content is rendered */
  DeferBlockState[DeferBlockState["Error"] = 3] = "Error";
})(DeferBlockState || (DeferBlockState = {}));
/**
 * Describes the initial state of this defer block instance.
 *
 * Note: this state is internal only and *must* be represented
 * with a number lower than any value in the `DeferBlockState` enum.
 */
var DeferBlockInternalState;
(function (DeferBlockInternalState) {
  /** Initial state. Nothing is rendered yet. */
  DeferBlockInternalState[DeferBlockInternalState["Initial"] = -1] = "Initial";
})(DeferBlockInternalState || (DeferBlockInternalState = {}));
const NEXT_DEFER_BLOCK_STATE = 0;
// Note: it's *important* to keep the state in this slot, because this slot
// is used by runtime logic to differentiate between LViews, LContainers and
// other types (see `isLView` and `isLContainer` functions). In case of defer
// blocks, this slot would always be a number.
const DEFER_BLOCK_STATE = 1;
const STATE_IS_FROZEN_UNTIL = 2;
const LOADING_AFTER_CLEANUP_FN = 3;
const TRIGGER_CLEANUP_FNS = 4;
const PREFETCH_TRIGGER_CLEANUP_FNS = 5;
/**
 * Options for configuring defer blocks behavior.
 * @publicApi
 * @developerPreview
 */
var DeferBlockBehavior;
(function (DeferBlockBehavior) {
  /**
   * Manual triggering mode for defer blocks. Provides control over when defer blocks render
   * and which state they render.
   */
  DeferBlockBehavior[DeferBlockBehavior["Manual"] = 0] = "Manual";
  /**
   * Playthrough mode for defer blocks. This mode behaves like defer blocks would in a browser.
   * This is the default behavior in test environments.
   */
  DeferBlockBehavior[DeferBlockBehavior["Playthrough"] = 1] = "Playthrough";
})(DeferBlockBehavior || (DeferBlockBehavior = {}));

/*!
 * @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
 */
/**
 * Registers a cleanup function associated with a prefetching trigger
 * or a regular trigger of a defer block.
 */
function storeTriggerCleanupFn(type, lDetails, cleanupFn) {
  const key = type === 1 /* TriggerType.Prefetch */ ? PREFETCH_TRIGGER_CLEANUP_FNS : TRIGGER_CLEANUP_FNS;
  if (lDetails[key] === null) {
    lDetails[key] = [];
  }
  lDetails[key].push(cleanupFn);
}
/**
 * Invokes registered cleanup functions either for prefetch or for regular triggers.
 */
function invokeTriggerCleanupFns(type, lDetails) {
  const key = type === 1 /* TriggerType.Prefetch */ ? PREFETCH_TRIGGER_CLEANUP_FNS : TRIGGER_CLEANUP_FNS;
  const cleanupFns = lDetails[key];
  if (cleanupFns !== null) {
    for (const cleanupFn of cleanupFns) {
      cleanupFn();
    }
    lDetails[key] = null;
  }
}
/**
 * Invokes registered cleanup functions for both prefetch and regular triggers.
 */
function invokeAllTriggerCleanupFns(lDetails) {
  invokeTriggerCleanupFns(1 /* TriggerType.Prefetch */, lDetails);
  invokeTriggerCleanupFns(0 /* TriggerType.Regular */, lDetails);
}

// Public API for Zone

/**
 * Calculates a data slot index for defer block info (either static or
 * instance-specific), given an index of a defer instruction.
 */
function getDeferBlockDataIndex(deferBlockIndex) {
  // Instance state is located at the *next* position
  // after the defer block slot in an LView or TView.data.
  return deferBlockIndex + 1;
}
/** Retrieves a defer block state from an LView, given a TNode that represents a block. */
function getLDeferBlockDetails(lView, tNode) {
  const tView = lView[TVIEW];
  const slotIndex = getDeferBlockDataIndex(tNode.index);
  ngDevMode && assertIndexInDeclRange(tView, slotIndex);
  return lView[slotIndex];
}
/** Stores a defer block instance state in LView. */
function setLDeferBlockDetails(lView, deferBlockIndex, lDetails) {
  const tView = lView[TVIEW];
  const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
  ngDevMode && assertIndexInDeclRange(tView, slotIndex);
  lView[slotIndex] = lDetails;
}
/** Retrieves static info about a defer block, given a TView and a TNode that represents a block. */
function getTDeferBlockDetails(tView, tNode) {
  const slotIndex = getDeferBlockDataIndex(tNode.index);
  ngDevMode && assertIndexInDeclRange(tView, slotIndex);
  return tView.data[slotIndex];
}
/** Stores a defer block static info in `TView.data`. */
function setTDeferBlockDetails(tView, deferBlockIndex, deferBlockConfig) {
  const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
  ngDevMode && assertIndexInDeclRange(tView, slotIndex);
  tView.data[slotIndex] = deferBlockConfig;
}
function getTemplateIndexForState(newState, hostLView, tNode) {
  const tView = hostLView[TVIEW];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  switch (newState) {
    case DeferBlockState.Complete:
      return tDetails.primaryTmplIndex;
    case DeferBlockState.Loading:
      return tDetails.loadingTmplIndex;
    case DeferBlockState.Error:
      return tDetails.errorTmplIndex;
    case DeferBlockState.Placeholder:
      return tDetails.placeholderTmplIndex;
    default:
      ngDevMode && throwError(`Unexpected defer block state: ${newState}`);
      return null;
  }
}
/**
 * Returns a minimum amount of time that a given state should be rendered for,
 * taking into account `minimum` parameter value. If the `minimum` value is
 * not specified - returns `null`.
 */
function getMinimumDurationForState(tDetails, currentState) {
  if (currentState === DeferBlockState.Placeholder) {
    return tDetails.placeholderBlockConfig?.[MINIMUM_SLOT] ?? null;
  } else if (currentState === DeferBlockState.Loading) {
    return tDetails.loadingBlockConfig?.[MINIMUM_SLOT] ?? null;
  }
  return null;
}
/** Retrieves the value of the `after` parameter on the @loading block. */
function getLoadingBlockAfter(tDetails) {
  return tDetails.loadingBlockConfig?.[LOADING_AFTER_SLOT] ?? null;
}
/**
 * Adds downloaded dependencies into a directive or a pipe registry,
 * making sure that a dependency doesn't yet exist in the registry.
 */
function addDepsToRegistry(currentDeps, newDeps) {
  if (!currentDeps || currentDeps.length === 0) {
    return newDeps;
  }
  const currentDepSet = new Set(currentDeps);
  for (const dep of newDeps) {
    currentDepSet.add(dep);
  }
  // If `currentDeps` is the same length, there were no new deps and can
  // return the original array.
  return currentDeps.length === currentDepSet.size ? currentDeps : Array.from(currentDepSet);
}
/** Retrieves a TNode that represents main content of a defer block. */
function getPrimaryBlockTNode(tView, tDetails) {
  const adjustedIndex = tDetails.primaryTmplIndex + HEADER_OFFSET;
  return getTNode(tView, adjustedIndex);
}
/**
 * Asserts whether all dependencies for a defer block are loaded.
 * Always run this function (in dev mode) before rendering a defer
 * block in completed state.
 */
function assertDeferredDependenciesLoaded(tDetails) {
  assertEqual(tDetails.loadingState, DeferDependenciesLoadingState.COMPLETE, 'Expecting all deferred dependencies to be loaded.');
}
/**
 * Determines if a given value matches the expected structure of a defer block
 *
 * We can safely rely on the primaryTmplIndex because every defer block requires
 * that a primary template exists. All the other template options are optional.
 */
function isTDeferBlockDetails(value) {
  return value !== null && typeof value === 'object' && typeof value.primaryTmplIndex === 'number';
}

/*!
 * @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
 */
/** Configuration object used to register passive and capturing events. */
const eventListenerOptions = {
  passive: true,
  capture: true
};
/** Keeps track of the currently-registered `on hover` triggers. */
const hoverTriggers = new WeakMap();
/** Keeps track of the currently-registered `on interaction` triggers. */
const interactionTriggers = new WeakMap();
/** Currently-registered `viewport` triggers. */
const viewportTriggers = new WeakMap();
/** Names of the events considered as interaction events. */
const interactionEventNames = ['click', 'keydown'];
/** Names of the events considered as hover events. */
const hoverEventNames = ['mouseenter', 'focusin'];
/** `IntersectionObserver` used to observe `viewport` triggers. */
let intersectionObserver = null;
/** Number of elements currently observed with `viewport` triggers. */
let observedViewportElements = 0;
/** Object keeping track of registered callbacks for a deferred block trigger. */
class DeferEventEntry {
  constructor() {
    this.callbacks = new Set();
    this.listener = () => {
      for (const callback of this.callbacks) {
        callback();
      }
    };
  }
}
/**
 * Registers an interaction trigger.
 * @param trigger Element that is the trigger.
 * @param callback Callback to be invoked when the trigger is interacted with.
 */
function onInteraction(trigger, callback) {
  let entry = interactionTriggers.get(trigger);
  // If this is the first entry for this element, add the listeners.
  if (!entry) {
    // Note that managing events centrally like this lends itself well to using global
    // event delegation. It currently does delegation at the element level, rather than the
    // document level, because:
    // 1. Global delegation is the most effective when there are a lot of events being registered
    // at the same time. Deferred blocks are unlikely to be used in such a way.
    // 2. Matching events to their target isn't free. For each `click` and `keydown` event we
    // would have look through all the triggers and check if the target either is the element
    // itself or it's contained within the element. Given that `click` and `keydown` are some
    // of the most common events, this may end up introducing a lot of runtime overhead.
    // 3. We're still registering only two events per element, no matter how many deferred blocks
    // are referencing it.
    entry = new DeferEventEntry();
    interactionTriggers.set(trigger, entry);
    for (const name of interactionEventNames) {
      trigger.addEventListener(name, entry.listener, eventListenerOptions);
    }
  }
  entry.callbacks.add(callback);
  return () => {
    const {
      callbacks,
      listener
    } = entry;
    callbacks.delete(callback);
    if (callbacks.size === 0) {
      interactionTriggers.delete(trigger);
      for (const name of interactionEventNames) {
        trigger.removeEventListener(name, listener, eventListenerOptions);
      }
    }
  };
}
/**
 * Registers a hover trigger.
 * @param trigger Element that is the trigger.
 * @param callback Callback to be invoked when the trigger is hovered over.
 */
function onHover(trigger, callback) {
  let entry = hoverTriggers.get(trigger);
  // If this is the first entry for this element, add the listener.
  if (!entry) {
    entry = new DeferEventEntry();
    hoverTriggers.set(trigger, entry);
    for (const name of hoverEventNames) {
      trigger.addEventListener(name, entry.listener, eventListenerOptions);
    }
  }
  entry.callbacks.add(callback);
  return () => {
    const {
      callbacks,
      listener
    } = entry;
    callbacks.delete(callback);
    if (callbacks.size === 0) {
      for (const name of hoverEventNames) {
        trigger.removeEventListener(name, listener, eventListenerOptions);
      }
      hoverTriggers.delete(trigger);
    }
  };
}
/**
 * Registers a viewport trigger.
 * @param trigger Element that is the trigger.
 * @param callback Callback to be invoked when the trigger comes into the viewport.
 * @param injector Injector that can be used by the trigger to resolve DI tokens.
 */
function onViewport(trigger, callback, injector) {
  const ngZone = injector.get(NgZone);
  let entry = viewportTriggers.get(trigger);
  intersectionObserver = intersectionObserver || ngZone.runOutsideAngular(() => {
    return new IntersectionObserver(entries => {
      for (const current of entries) {
        // Only invoke the callbacks if the specific element is intersecting.
        if (current.isIntersecting && viewportTriggers.has(current.target)) {
          ngZone.run(viewportTriggers.get(current.target).listener);
        }
      }
    });
  });
  if (!entry) {
    entry = new DeferEventEntry();
    ngZone.runOutsideAngular(() => intersectionObserver.observe(trigger));
    viewportTriggers.set(trigger, entry);
    observedViewportElements++;
  }
  entry.callbacks.add(callback);
  return () => {
    // It's possible that a different cleanup callback fully removed this element already.
    if (!viewportTriggers.has(trigger)) {
      return;
    }
    entry.callbacks.delete(callback);
    if (entry.callbacks.size === 0) {
      intersectionObserver?.unobserve(trigger);
      viewportTriggers.delete(trigger);
      observedViewportElements--;
    }
    if (observedViewportElements === 0) {
      intersectionObserver?.disconnect();
      intersectionObserver = null;
    }
  };
}
/**
 * Helper function to get the LView in which a deferred block's trigger is rendered.
 * @param deferredHostLView LView in which the deferred block is defined.
 * @param deferredTNode TNode defining the deferred block.
 * @param walkUpTimes Number of times to go up in the view hierarchy to find the trigger's view.
 *   A negative value means that the trigger is inside the block's placeholder, while an undefined
 *   value means that the trigger is in the same LView as the deferred block.
 */
function getTriggerLView(deferredHostLView, deferredTNode, walkUpTimes) {
  // The trigger is in the same view, we don't need to traverse.
  if (walkUpTimes == null) {
    return deferredHostLView;
  }
  // A positive value or zero means that the trigger is in a parent view.
  if (walkUpTimes >= 0) {
    return walkUpViews(walkUpTimes, deferredHostLView);
  }
  // If the value is negative, it means that the trigger is inside the placeholder.
  const deferredContainer = deferredHostLView[deferredTNode.index];
  ngDevMode && assertLContainer(deferredContainer);
  const triggerLView = deferredContainer[CONTAINER_HEADER_OFFSET] ?? null;
  // We need to null check, because the placeholder might not have been rendered yet.
  if (ngDevMode && triggerLView !== null) {
    const lDetails = getLDeferBlockDetails(deferredHostLView, deferredTNode);
    const renderedState = lDetails[DEFER_BLOCK_STATE];
    assertEqual(renderedState, DeferBlockState.Placeholder, 'Expected a placeholder to be rendered in this defer block.');
    assertLView(triggerLView);
  }
  return triggerLView;
}
/**
 * Gets the element that a deferred block's trigger is pointing to.
 * @param triggerLView LView in which the trigger is defined.
 * @param triggerIndex Index at which the trigger element should've been rendered.
 */
function getTriggerElement(triggerLView, triggerIndex) {
  const element = getNativeByIndex(HEADER_OFFSET + triggerIndex, triggerLView);
  ngDevMode && assertElement(element);
  return element;
}
/**
 * Registers a DOM-node based trigger.
 * @param initialLView LView in which the defer block is rendered.
 * @param tNode TNode representing the defer block.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to go up/down in the view hierarchy to find the trigger.
 * @param registerFn Function that will register the DOM events.
 * @param callback Callback to be invoked when the trigger receives the event that should render
 *     the deferred block.
 * @param type Trigger type to distinguish between regular and prefetch triggers.
 */
function registerDomTrigger(initialLView, tNode, triggerIndex, walkUpTimes, registerFn, callback, type) {
  const injector = initialLView[INJECTOR];
  function pollDomTrigger() {
    // If the initial view was destroyed, we don't need to do anything.
    if (isDestroyed(initialLView)) {
      return;
    }
    const lDetails = getLDeferBlockDetails(initialLView, tNode);
    const renderedState = lDetails[DEFER_BLOCK_STATE];
    // If the block was loaded before the trigger was resolved, we don't need to do anything.
    if (renderedState !== DeferBlockInternalState.Initial && renderedState !== DeferBlockState.Placeholder) {
      return;
    }
    const triggerLView = getTriggerLView(initialLView, tNode, walkUpTimes);
    // Keep polling until we resolve the trigger's LView.
    if (!triggerLView) {
      internalAfterNextRender(pollDomTrigger, {
        injector
      });
      return;
    }
    // It's possible that the trigger's view was destroyed before we resolved the trigger element.
    if (isDestroyed(triggerLView)) {
      return;
    }
    const element = getTriggerElement(triggerLView, triggerIndex);
    const cleanup = registerFn(element, () => {
      if (initialLView !== triggerLView) {
        removeLViewOnDestroy(triggerLView, cleanup);
      }
      callback();
    }, injector);
    // The trigger and deferred block might be in different LViews.
    // For the main LView the cleanup would happen as a part of
    // `storeTriggerCleanupFn` logic. For trigger LView we register
    // a cleanup function there to remove event handlers in case an
    // LView gets destroyed before a trigger is invoked.
    if (initialLView !== triggerLView) {
      storeLViewOnDestroy(triggerLView, cleanup);
    }
    storeTriggerCleanupFn(type, lDetails, cleanup);
  }
  // Begin polling for the trigger.
  internalAfterNextRender(pollDomTrigger, {
    injector
  });
}

/**
 * Helper function to schedule a callback to be invoked when a browser becomes idle.
 *
 * @param callback A function to be invoked when a browser becomes idle.
 * @param lView LView that hosts an instance of a defer block.
 */
function onIdle(callback, lView) {
  const injector = lView[INJECTOR];
  const scheduler = injector.get(IdleScheduler);
  const cleanupFn = () => scheduler.remove(callback);
  scheduler.add(callback);
  return cleanupFn;
}
/**
 * Use shims for the `requestIdleCallback` and `cancelIdleCallback` functions for
 * environments where those functions are not available (e.g. Node.js and Safari).
 *
 * Note: we wrap the `requestIdleCallback` call into a function, so that it can be
 * overridden/mocked in test environment and picked up by the runtime code.
 */
const _requestIdleCallback = () => typeof requestIdleCallback !== 'undefined' ? requestIdleCallback : setTimeout;
const _cancelIdleCallback = () => typeof requestIdleCallback !== 'undefined' ? cancelIdleCallback : clearTimeout;
/**
 * Helper service to schedule `requestIdleCallback`s for batches of defer blocks,
 * to avoid calling `requestIdleCallback` for each defer block (e.g. if
 * defer blocks are defined inside a for loop).
 */
class IdleScheduler {
  constructor() {
    // Indicates whether current callbacks are being invoked.
    this.executingCallbacks = false;
    // Currently scheduled idle callback id.
    this.idleId = null;
    // Set of callbacks to be invoked next.
    this.current = new Set();
    // Set of callbacks collected while invoking current set of callbacks.
    // Those callbacks are scheduled for the next idle period.
    this.deferred = new Set();
    this.ngZone = inject(NgZone);
    this.requestIdleCallbackFn = _requestIdleCallback().bind(globalThis);
    this.cancelIdleCallbackFn = _cancelIdleCallback().bind(globalThis);
  }
  add(callback) {
    const target = this.executingCallbacks ? this.deferred : this.current;
    target.add(callback);
    if (this.idleId === null) {
      this.scheduleIdleCallback();
    }
  }
  remove(callback) {
    const {
      current,
      deferred
    } = this;
    current.delete(callback);
    deferred.delete(callback);
    // If the last callback was removed and there is a pending
    // idle callback - cancel it.
    if (current.size === 0 && deferred.size === 0) {
      this.cancelIdleCallback();
    }
  }
  scheduleIdleCallback() {
    const callback = () => {
      this.cancelIdleCallback();
      this.executingCallbacks = true;
      for (const callback of this.current) {
        callback();
      }
      this.current.clear();
      this.executingCallbacks = false;
      // If there are any callbacks added during an invocation
      // of the current ones - make them "current" and schedule
      // a new idle callback.
      if (this.deferred.size > 0) {
        for (const callback of this.deferred) {
          this.current.add(callback);
        }
        this.deferred.clear();
        this.scheduleIdleCallback();
      }
    };
    // Ensure that the callback runs in the NgZone since
    // the `requestIdleCallback` is not currently patched by Zone.js.
    this.idleId = this.requestIdleCallbackFn(() => this.ngZone.run(callback));
  }
  cancelIdleCallback() {
    if (this.idleId !== null) {
      this.cancelIdleCallbackFn(this.idleId);
      this.idleId = null;
    }
  }
  ngOnDestroy() {
    this.cancelIdleCallback();
    this.current.clear();
    this.deferred.clear();
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: IdleScheduler,
      providedIn: 'root',
      factory: () => new IdleScheduler()
    });
  }
}

/**
 * Returns a function that captures a provided delay.
 * Invoking the returned function schedules a trigger.
 */
function onTimer(delay) {
  return (callback, lView) => scheduleTimerTrigger(delay, callback, lView);
}
/**
 * Schedules a callback to be invoked after a given timeout.
 *
 * @param delay A number of ms to wait until firing a callback.
 * @param callback A function to be invoked after a timeout.
 * @param lView LView that hosts an instance of a defer block.
 */
function scheduleTimerTrigger(delay, callback, lView) {
  const injector = lView[INJECTOR];
  const scheduler = injector.get(TimerScheduler);
  const cleanupFn = () => scheduler.remove(callback);
  scheduler.add(delay, callback);
  return cleanupFn;
}
/**
 * Helper service to schedule `setTimeout`s for batches of defer blocks,
 * to avoid calling `setTimeout` for each defer block (e.g. if defer blocks
 * are created inside a for loop).
 */
class TimerScheduler {
  constructor() {
    // Indicates whether current callbacks are being invoked.
    this.executingCallbacks = false;
    // Currently scheduled `setTimeout` id.
    this.timeoutId = null;
    // When currently scheduled timer would fire.
    this.invokeTimerAt = null;
    // List of callbacks to be invoked.
    // For each callback we also store a timestamp on when the callback
    // should be invoked. We store timestamps and callback functions
    // in a flat array to avoid creating new objects for each entry.
    // [timestamp1, callback1, timestamp2, callback2, ...]
    this.current = [];
    // List of callbacks collected while invoking current set of callbacks.
    // Those callbacks are added to the "current" queue at the end of
    // the current callback invocation. The shape of this list is the same
    // as the shape of the `current` list.
    this.deferred = [];
  }
  add(delay, callback) {
    const target = this.executingCallbacks ? this.deferred : this.current;
    this.addToQueue(target, Date.now() + delay, callback);
    this.scheduleTimer();
  }
  remove(callback) {
    const {
      current,
      deferred
    } = this;
    const callbackIndex = this.removeFromQueue(current, callback);
    if (callbackIndex === -1) {
      // Try cleaning up deferred queue only in case
      // we didn't find a callback in the "current" queue.
      this.removeFromQueue(deferred, callback);
    }
    // If the last callback was removed and there is a pending timeout - cancel it.
    if (current.length === 0 && deferred.length === 0) {
      this.clearTimeout();
    }
  }
  addToQueue(target, invokeAt, callback) {
    let insertAtIndex = target.length;
    for (let i = 0; i < target.length; i += 2) {
      const invokeQueuedCallbackAt = target[i];
      if (invokeQueuedCallbackAt > invokeAt) {
        // We've reached a first timer that is scheduled
        // for a later time than what we are trying to insert.
        // This is the location at which we need to insert,
        // no need to iterate further.
        insertAtIndex = i;
        break;
      }
    }
    arrayInsert2(target, insertAtIndex, invokeAt, callback);
  }
  removeFromQueue(target, callback) {
    let index = -1;
    for (let i = 0; i < target.length; i += 2) {
      const queuedCallback = target[i + 1];
      if (queuedCallback === callback) {
        index = i;
        break;
      }
    }
    if (index > -1) {
      // Remove 2 elements: a timestamp slot and
      // the following slot with a callback function.
      arraySplice(target, index, 2);
    }
    return index;
  }
  scheduleTimer() {
    const callback = () => {
      this.clearTimeout();
      this.executingCallbacks = true;
      // Clone the current state of the queue, since it might be altered
      // as we invoke callbacks.
      const current = [...this.current];
      // Invoke callbacks that were scheduled to run before the current time.
      const now = Date.now();
      for (let i = 0; i < current.length; i += 2) {
        const invokeAt = current[i];
        const callback = current[i + 1];
        if (invokeAt <= now) {
          callback();
        } else {
          // We've reached a timer that should not be invoked yet.
          break;
        }
      }
      // The state of the queue might've changed after callbacks invocation,
      // run the cleanup logic based on the *current* state of the queue.
      let lastCallbackIndex = -1;
      for (let i = 0; i < this.current.length; i += 2) {
        const invokeAt = this.current[i];
        if (invokeAt <= now) {
          // Add +1 to account for a callback function that
          // goes after the timestamp in events array.
          lastCallbackIndex = i + 1;
        } else {
          // We've reached a timer that should not be invoked yet.
          break;
        }
      }
      if (lastCallbackIndex >= 0) {
        arraySplice(this.current, 0, lastCallbackIndex + 1);
      }
      this.executingCallbacks = false;
      // If there are any callbacks added during an invocation
      // of the current ones - move them over to the "current"
      // queue.
      if (this.deferred.length > 0) {
        for (let i = 0; i < this.deferred.length; i += 2) {
          const invokeAt = this.deferred[i];
          const callback = this.deferred[i + 1];
          this.addToQueue(this.current, invokeAt, callback);
        }
        this.deferred.length = 0;
      }
      this.scheduleTimer();
    };
    // Avoid running timer callbacks more than once per
    // average frame duration. This is needed for better
    // batching and to avoid kicking off excessive change
    // detection cycles.
    const FRAME_DURATION_MS = 16; // 1000ms / 60fps
    if (this.current.length > 0) {
      const now = Date.now();
      // First element in the queue points at the timestamp
      // of the first (earliest) event.
      const invokeAt = this.current[0];
      if (this.timeoutId === null ||
      // Reschedule a timer in case a queue contains an item with
      // an earlier timestamp and the delta is more than an average
      // frame duration.
      this.invokeTimerAt && this.invokeTimerAt - invokeAt > FRAME_DURATION_MS) {
        // There was a timeout already, but an earlier event was added
        // into the queue. In this case we drop an old timer and setup
        // a new one with an updated (smaller) timeout.
        this.clearTimeout();
        const timeout = Math.max(invokeAt - now, FRAME_DURATION_MS);
        this.invokeTimerAt = invokeAt;
        this.timeoutId = setTimeout(callback, timeout);
      }
    }
  }
  clearTimeout() {
    if (this.timeoutId !== null) {
      clearTimeout(this.timeoutId);
      this.timeoutId = null;
    }
  }
  ngOnDestroy() {
    this.clearTimeout();
    this.current.length = 0;
    this.deferred.length = 0;
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: TimerScheduler,
      providedIn: 'root',
      factory: () => new TimerScheduler()
    });
  }
}

/**
 * **INTERNAL**, avoid referencing it in application code.
 * *
 * Injector token that allows to provide `DeferBlockDependencyInterceptor` class
 * implementation.
 *
 * This token is only injected in devMode
 */
const DEFER_BLOCK_DEPENDENCY_INTERCEPTOR = new InjectionToken('DEFER_BLOCK_DEPENDENCY_INTERCEPTOR');
/**
 * **INTERNAL**, token used for configuring defer block behavior.
 */
const DEFER_BLOCK_CONFIG = new InjectionToken(ngDevMode ? 'DEFER_BLOCK_CONFIG' : '');
/**
 * Returns whether defer blocks should be triggered.
 *
 * Currently, defer blocks are not triggered on the server,
 * only placeholder content is rendered (if provided).
 */
function shouldTriggerDeferBlock(injector) {
  const config = injector.get(DEFER_BLOCK_CONFIG, null, {
    optional: true
  });
  if (config?.behavior === DeferBlockBehavior.Manual) {
    return false;
  }
  return isPlatformBrowser(injector);
}
/**
 * Reference to the timer-based scheduler implementation of defer block state
 * rendering method. It's used to make timer-based scheduling tree-shakable.
 * If `minimum` or `after` parameters are used, compiler generates an extra
 * argument for the `ɵɵdefer` instruction, which references a timer-based
 * implementation.
 */
let applyDeferBlockStateWithSchedulingImpl = null;
/**
 * Enables timer-related scheduling if `after` or `minimum` parameters are setup
 * on the `@loading` or `@placeholder` blocks.
 */
function ɵɵdeferEnableTimerScheduling(tView, tDetails, placeholderConfigIndex, loadingConfigIndex) {
  const tViewConsts = tView.consts;
  if (placeholderConfigIndex != null) {
    tDetails.placeholderBlockConfig = getConstant(tViewConsts, placeholderConfigIndex);
  }
  if (loadingConfigIndex != null) {
    tDetails.loadingBlockConfig = getConstant(tViewConsts, loadingConfigIndex);
  }
  // Enable implementation that supports timer-based scheduling.
  if (applyDeferBlockStateWithSchedulingImpl === null) {
    applyDeferBlockStateWithSchedulingImpl = applyDeferBlockStateWithScheduling;
  }
}
/**
 * Creates runtime data structures for defer blocks.
 *
 * @param index Index of the `defer` instruction.
 * @param primaryTmplIndex Index of the template with the primary block content.
 * @param dependencyResolverFn Function that contains dependencies for this defer block.
 * @param loadingTmplIndex Index of the template with the loading block content.
 * @param placeholderTmplIndex Index of the template with the placeholder block content.
 * @param errorTmplIndex Index of the template with the error block content.
 * @param loadingConfigIndex Index in the constants array of the configuration of the loading.
 *     block.
 * @param placeholderConfigIndex Index in the constants array of the configuration of the
 *     placeholder block.
 * @param enableTimerScheduling Function that enables timer-related scheduling if `after`
 *     or `minimum` parameters are setup on the `@loading` or `@placeholder` blocks.
 *
 * @codeGenApi
 */
function ɵɵdefer(index, primaryTmplIndex, dependencyResolverFn, loadingTmplIndex, placeholderTmplIndex, errorTmplIndex, loadingConfigIndex, placeholderConfigIndex, enableTimerScheduling) {
  const lView = getLView();
  const tView = getTView();
  const adjustedIndex = index + HEADER_OFFSET;
  ɵɵtemplate(index, null, 0, 0);
  if (tView.firstCreatePass) {
    performanceMarkFeature('NgDefer');
    const tDetails = {
      primaryTmplIndex,
      loadingTmplIndex: loadingTmplIndex ?? null,
      placeholderTmplIndex: placeholderTmplIndex ?? null,
      errorTmplIndex: errorTmplIndex ?? null,
      placeholderBlockConfig: null,
      loadingBlockConfig: null,
      dependencyResolverFn: dependencyResolverFn ?? null,
      loadingState: DeferDependenciesLoadingState.NOT_STARTED,
      loadingPromise: null,
      providers: null
    };
    enableTimerScheduling?.(tView, tDetails, placeholderConfigIndex, loadingConfigIndex);
    setTDeferBlockDetails(tView, adjustedIndex, tDetails);
  }
  const tNode = getCurrentTNode();
  const lContainer = lView[adjustedIndex];
  // If hydration is enabled, looks up dehydrated views in the DOM
  // using hydration annotation info and stores those views on LContainer.
  // In client-only mode, this function is a noop.
  populateDehydratedViewsInLContainer(lContainer, tNode, lView);
  // Init instance-specific defer details and store it.
  const lDetails = [null,
  // NEXT_DEFER_BLOCK_STATE
  DeferBlockInternalState.Initial,
  // DEFER_BLOCK_STATE
  null,
  // STATE_IS_FROZEN_UNTIL
  null,
  // LOADING_AFTER_CLEANUP_FN
  null,
  // TRIGGER_CLEANUP_FNS
  null // PREFETCH_TRIGGER_CLEANUP_FNS
  ];
  setLDeferBlockDetails(lView, adjustedIndex, lDetails);
  const cleanupTriggersFn = () => invokeAllTriggerCleanupFns(lDetails);
  // When defer block is triggered - unsubscribe from LView destroy cleanup.
  storeTriggerCleanupFn(0 /* TriggerType.Regular */, lDetails, () => removeLViewOnDestroy(lView, cleanupTriggersFn));
  storeLViewOnDestroy(lView, cleanupTriggersFn);
}
/**
 * Loads defer block dependencies when a trigger value becomes truthy.
 * @codeGenApi
 */
function ɵɵdeferWhen(rawValue) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, rawValue)) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      const value = Boolean(rawValue); // handle truthy or falsy values
      const tNode = getSelectedTNode();
      const lDetails = getLDeferBlockDetails(lView, tNode);
      const renderedState = lDetails[DEFER_BLOCK_STATE];
      if (value === false && renderedState === DeferBlockInternalState.Initial) {
        // If nothing is rendered yet, render a placeholder (if defined).
        renderPlaceholder(lView, tNode);
      } else if (value === true && (renderedState === DeferBlockInternalState.Initial || renderedState === DeferBlockState.Placeholder)) {
        // The `when` condition has changed to `true`, trigger defer block loading
        // if the block is either in initial (nothing is rendered) or a placeholder
        // state.
        triggerDeferBlock(lView, tNode);
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
}
/**
 * Prefetches the deferred content when a value becomes truthy.
 * @codeGenApi
 */
function ɵɵdeferPrefetchWhen(rawValue) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, rawValue)) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      const value = Boolean(rawValue); // handle truthy or falsy values
      const tView = lView[TVIEW];
      const tNode = getSelectedTNode();
      const tDetails = getTDeferBlockDetails(tView, tNode);
      if (value === true && tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
        // If loading has not been started yet, trigger it now.
        triggerPrefetching(tDetails, lView, tNode);
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
}
/**
 * Sets up logic to handle the `on idle` deferred trigger.
 * @codeGenApi
 */
function ɵɵdeferOnIdle() {
  scheduleDelayedTrigger(onIdle);
}
/**
 * Sets up logic to handle the `prefetch on idle` deferred trigger.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnIdle() {
  scheduleDelayedPrefetching(onIdle);
}
/**
 * Sets up logic to handle the `on immediate` deferred trigger.
 * @codeGenApi
 */
function ɵɵdeferOnImmediate() {
  const lView = getLView();
  const tNode = getCurrentTNode();
  const tView = lView[TVIEW];
  const injector = lView[INJECTOR];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  // Render placeholder block only if loading template is not present and we're on
  // the client to avoid content flickering, since it would be immediately replaced
  // by the loading block.
  if (!shouldTriggerDeferBlock(injector) || tDetails.loadingTmplIndex === null) {
    renderPlaceholder(lView, tNode);
  }
  triggerDeferBlock(lView, tNode);
}
/**
 * Sets up logic to handle the `prefetch on immediate` deferred trigger.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnImmediate() {
  const lView = getLView();
  const tNode = getCurrentTNode();
  const tView = lView[TVIEW];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
    triggerResourceLoading(tDetails, lView, tNode);
  }
}
/**
 * Creates runtime data structures for the `on timer` deferred trigger.
 * @param delay Amount of time to wait before loading the content.
 * @codeGenApi
 */
function ɵɵdeferOnTimer(delay) {
  scheduleDelayedTrigger(onTimer(delay));
}
/**
 * Creates runtime data structures for the `prefetch on timer` deferred trigger.
 * @param delay Amount of time to wait before prefetching the content.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnTimer(delay) {
  scheduleDelayedPrefetching(onTimer(delay));
}
/**
 * Creates runtime data structures for the `on hover` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferOnHover(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  renderPlaceholder(lView, tNode);
  registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onHover, () => triggerDeferBlock(lView, tNode), 0 /* TriggerType.Regular */);
}
/**
 * Creates runtime data structures for the `prefetch on hover` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnHover(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  const tView = lView[TVIEW];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
    registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onHover, () => triggerPrefetching(tDetails, lView, tNode), 1 /* TriggerType.Prefetch */);
  }
}
/**
 * Creates runtime data structures for the `on interaction` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferOnInteraction(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  renderPlaceholder(lView, tNode);
  registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onInteraction, () => triggerDeferBlock(lView, tNode), 0 /* TriggerType.Regular */);
}
/**
 * Creates runtime data structures for the `prefetch on interaction` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnInteraction(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  const tView = lView[TVIEW];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
    registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onInteraction, () => triggerPrefetching(tDetails, lView, tNode), 1 /* TriggerType.Prefetch */);
  }
}
/**
 * Creates runtime data structures for the `on viewport` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferOnViewport(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  renderPlaceholder(lView, tNode);
  registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewport, () => triggerDeferBlock(lView, tNode), 0 /* TriggerType.Regular */);
}
/**
 * Creates runtime data structures for the `prefetch on viewport` deferred trigger.
 * @param triggerIndex Index at which to find the trigger element.
 * @param walkUpTimes Number of times to walk up/down the tree hierarchy to find the trigger.
 * @codeGenApi
 */
function ɵɵdeferPrefetchOnViewport(triggerIndex, walkUpTimes) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  const tView = lView[TVIEW];
  const tDetails = getTDeferBlockDetails(tView, tNode);
  if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
    registerDomTrigger(lView, tNode, triggerIndex, walkUpTimes, onViewport, () => triggerPrefetching(tDetails, lView, tNode), 1 /* TriggerType.Prefetch */);
  }
}
/********** Helper functions **********/
/**
 * Schedules triggering of a defer block for `on idle` and `on timer` conditions.
 */
function scheduleDelayedTrigger(scheduleFn) {
  const lView = getLView();
  const tNode = getCurrentTNode();
  renderPlaceholder(lView, tNode);
  // Only trigger the scheduled trigger on the browser
  // since we don't want to delay the server response.
  if (isPlatformBrowser(lView[INJECTOR])) {
    const cleanupFn = scheduleFn(() => triggerDeferBlock(lView, tNode), lView);
    const lDetails = getLDeferBlockDetails(lView, tNode);
    storeTriggerCleanupFn(0 /* TriggerType.Regular */, lDetails, cleanupFn);
  }
}
/**
 * Schedules prefetching for `on idle` and `on timer` triggers.
 *
 * @param scheduleFn A function that does the scheduling.
 */
function scheduleDelayedPrefetching(scheduleFn) {
  const lView = getLView();
  // Only trigger the scheduled trigger on the browser
  // since we don't want to delay the server response.
  if (isPlatformBrowser(lView[INJECTOR])) {
    const tNode = getCurrentTNode();
    const tView = lView[TVIEW];
    const tDetails = getTDeferBlockDetails(tView, tNode);
    if (tDetails.loadingState === DeferDependenciesLoadingState.NOT_STARTED) {
      const lDetails = getLDeferBlockDetails(lView, tNode);
      const prefetch = () => triggerPrefetching(tDetails, lView, tNode);
      const cleanupFn = scheduleFn(prefetch, lView);
      storeTriggerCleanupFn(1 /* TriggerType.Prefetch */, lDetails, cleanupFn);
    }
  }
}
/**
 * Transitions a defer block to the new state. Updates the  necessary
 * data structures and renders corresponding block.
 *
 * @param newState New state that should be applied to the defer block.
 * @param tNode TNode that represents a defer block.
 * @param lContainer Represents an instance of a defer block.
 * @param skipTimerScheduling Indicates that `@loading` and `@placeholder` block
 *   should be rendered immediately, even if they have `after` or `minimum` config
 *   options setup. This flag to needed for testing APIs to transition defer block
 *   between states via `DeferFixture.render` method.
 */
function renderDeferBlockState(newState, tNode, lContainer, skipTimerScheduling = false) {
  const hostLView = lContainer[PARENT];
  const hostTView = hostLView[TVIEW];
  // Check if this view is not destroyed. Since the loading process was async,
  // the view might end up being destroyed by the time rendering happens.
  if (isDestroyed(hostLView)) return;
  // Make sure this TNode belongs to TView that represents host LView.
  ngDevMode && assertTNodeForLView(tNode, hostLView);
  const lDetails = getLDeferBlockDetails(hostLView, tNode);
  ngDevMode && assertDefined(lDetails, 'Expected a defer block state defined');
  const currentState = lDetails[DEFER_BLOCK_STATE];
  if (isValidStateChange(currentState, newState) && isValidStateChange(lDetails[NEXT_DEFER_BLOCK_STATE] ?? -1, newState)) {
    const injector = hostLView[INJECTOR];
    const tDetails = getTDeferBlockDetails(hostTView, tNode);
    // Skips scheduling on the server since it can delay the server response.
    const needsScheduling = !skipTimerScheduling && isPlatformBrowser(injector) && (getLoadingBlockAfter(tDetails) !== null || getMinimumDurationForState(tDetails, DeferBlockState.Loading) !== null || getMinimumDurationForState(tDetails, DeferBlockState.Placeholder));
    if (ngDevMode && needsScheduling) {
      assertDefined(applyDeferBlockStateWithSchedulingImpl, 'Expected scheduling function to be defined');
    }
    const applyStateFn = needsScheduling ? applyDeferBlockStateWithSchedulingImpl : applyDeferBlockState;
    try {
      applyStateFn(newState, lDetails, lContainer, tNode, hostLView);
    } catch (error) {
      handleError(hostLView, error);
    }
  }
}
/**
 * Detects whether an injector is an instance of a `ChainedInjector`,
 * created based on the `OutletInjector`.
 */
function isRouterOutletInjector(currentInjector) {
  return currentInjector instanceof ChainedInjector && typeof currentInjector.injector.__ngOutletInjector === 'function';
}
/**
 * Creates an instance of the `OutletInjector` using a private factory
 * function available on the `OutletInjector` class.
 *
 * @param parentOutletInjector Parent OutletInjector, which should be used
 *                             to produce a new instance.
 * @param parentInjector An Injector, which should be used as a parent one
 *                       for a newly created `OutletInjector` instance.
 */
function createRouterOutletInjector(parentOutletInjector, parentInjector) {
  const outletInjector = parentOutletInjector.injector;
  return outletInjector.__ngOutletInjector(parentInjector);
}
/**
 * Applies changes to the DOM to reflect a given state.
 */
function applyDeferBlockState(newState, lDetails, lContainer, tNode, hostLView) {
  const stateTmplIndex = getTemplateIndexForState(newState, hostLView, tNode);
  if (stateTmplIndex !== null) {
    lDetails[DEFER_BLOCK_STATE] = newState;
    const hostTView = hostLView[TVIEW];
    const adjustedIndex = stateTmplIndex + HEADER_OFFSET;
    const activeBlockTNode = getTNode(hostTView, adjustedIndex);
    // There is only 1 view that can be present in an LContainer that
    // represents a defer block, so always refer to the first one.
    const viewIndex = 0;
    removeLViewFromLContainer(lContainer, viewIndex);
    let injector;
    if (newState === DeferBlockState.Complete) {
      // When we render a defer block in completed state, there might be
      // newly loaded standalone components used within the block, which may
      // import NgModules with providers. In order to make those providers
      // available for components declared in that NgModule, we create an instance
      // of environment injector to host those providers and pass this injector
      // to the logic that creates a view.
      const tDetails = getTDeferBlockDetails(hostTView, tNode);
      const providers = tDetails.providers;
      if (providers && providers.length > 0) {
        const parentInjector = hostLView[INJECTOR];
        // Note: we have a special case for Router's `OutletInjector`,
        // since it's not an instance of the `EnvironmentInjector`, so
        // we can't inject it. Once the `OutletInjector` is replaced
        // with the `EnvironmentInjector` in Router's code, this special
        // handling can be removed.
        const isParentOutletInjector = isRouterOutletInjector(parentInjector);
        const parentEnvInjector = isParentOutletInjector ? parentInjector : parentInjector.get(EnvironmentInjector);
        injector = parentEnvInjector.get(CachedInjectorService).getOrCreateInjector(tDetails, parentEnvInjector, providers, ngDevMode ? 'DeferBlock Injector' : '');
        // Note: this is a continuation of the special case for Router's `OutletInjector`.
        // Since the `OutletInjector` handles `ActivatedRoute` and `ChildrenOutletContexts`
        // dynamically (i.e. their values are not really stored statically in an injector),
        // we need to "wrap" a defer injector into another `OutletInjector`, so we retain
        // the dynamic resolution of the mentioned tokens.
        if (isParentOutletInjector) {
          injector = createRouterOutletInjector(parentInjector, injector);
        }
      }
    }
    const dehydratedView = findMatchingDehydratedView(lContainer, activeBlockTNode.tView.ssrId);
    const embeddedLView = createAndRenderEmbeddedLView(hostLView, activeBlockTNode, null, {
      dehydratedView,
      injector
    });
    addLViewToLContainer(lContainer, embeddedLView, viewIndex, shouldAddViewToDom(activeBlockTNode, dehydratedView));
    markViewDirty(embeddedLView);
  }
}
/**
 * Extends the `applyDeferBlockState` with timer-based scheduling.
 * This function becomes available on a page if there are defer blocks
 * that use `after` or `minimum` parameters in the `@loading` or
 * `@placeholder` blocks.
 */
function applyDeferBlockStateWithScheduling(newState, lDetails, lContainer, tNode, hostLView) {
  const now = Date.now();
  const hostTView = hostLView[TVIEW];
  const tDetails = getTDeferBlockDetails(hostTView, tNode);
  if (lDetails[STATE_IS_FROZEN_UNTIL] === null || lDetails[STATE_IS_FROZEN_UNTIL] <= now) {
    lDetails[STATE_IS_FROZEN_UNTIL] = null;
    const loadingAfter = getLoadingBlockAfter(tDetails);
    const inLoadingAfterPhase = lDetails[LOADING_AFTER_CLEANUP_FN] !== null;
    if (newState === DeferBlockState.Loading && loadingAfter !== null && !inLoadingAfterPhase) {
      // Trying to render loading, but it has an `after` config,
      // so schedule an update action after a timeout.
      lDetails[NEXT_DEFER_BLOCK_STATE] = newState;
      const cleanupFn = scheduleDeferBlockUpdate(loadingAfter, lDetails, tNode, lContainer, hostLView);
      lDetails[LOADING_AFTER_CLEANUP_FN] = cleanupFn;
    } else {
      // If we transition to a complete or an error state and there is a pending
      // operation to render loading after a timeout - invoke a cleanup operation,
      // which stops the timer.
      if (newState > DeferBlockState.Loading && inLoadingAfterPhase) {
        lDetails[LOADING_AFTER_CLEANUP_FN]();
        lDetails[LOADING_AFTER_CLEANUP_FN] = null;
        lDetails[NEXT_DEFER_BLOCK_STATE] = null;
      }
      applyDeferBlockState(newState, lDetails, lContainer, tNode, hostLView);
      const duration = getMinimumDurationForState(tDetails, newState);
      if (duration !== null) {
        lDetails[STATE_IS_FROZEN_UNTIL] = now + duration;
        scheduleDeferBlockUpdate(duration, lDetails, tNode, lContainer, hostLView);
      }
    }
  } else {
    // We are still rendering the previous state.
    // Update the `NEXT_DEFER_BLOCK_STATE`, which would be
    // picked up once it's time to transition to the next state.
    lDetails[NEXT_DEFER_BLOCK_STATE] = newState;
  }
}
/**
 * Schedules an update operation after a specified timeout.
 */
function scheduleDeferBlockUpdate(timeout, lDetails, tNode, lContainer, hostLView) {
  const callback = () => {
    const nextState = lDetails[NEXT_DEFER_BLOCK_STATE];
    lDetails[STATE_IS_FROZEN_UNTIL] = null;
    lDetails[NEXT_DEFER_BLOCK_STATE] = null;
    if (nextState !== null) {
      renderDeferBlockState(nextState, tNode, lContainer);
    }
  };
  return scheduleTimerTrigger(timeout, callback, hostLView);
}
/**
 * Checks whether we can transition to the next state.
 *
 * We transition to the next state if the previous state was represented
 * with a number that is less than the next state. For example, if the current
 * state is "loading" (represented as `1`), we should not show a placeholder
 * (represented as `0`), but we can show a completed state (represented as `2`)
 * or an error state (represented as `3`).
 */
function isValidStateChange(currentState, newState) {
  return currentState < newState;
}
/**
 * Trigger prefetching of dependencies for a defer block.
 *
 * @param tDetails Static information about this defer block.
 * @param lView LView of a host view.
 */
function triggerPrefetching(tDetails, lView, tNode) {
  if (lView[INJECTOR] && shouldTriggerDeferBlock(lView[INJECTOR])) {
    triggerResourceLoading(tDetails, lView, tNode);
  }
}
/**
 * Trigger loading of defer block dependencies if the process hasn't started yet.
 *
 * @param tDetails Static information about this defer block.
 * @param lView LView of a host view.
 */
function triggerResourceLoading(tDetails, lView, tNode) {
  const injector = lView[INJECTOR];
  const tView = lView[TVIEW];
  if (tDetails.loadingState !== DeferDependenciesLoadingState.NOT_STARTED) {
    // If the loading status is different from initial one, it means that
    // the loading of dependencies is in progress and there is nothing to do
    // in this function. All details can be obtained from the `tDetails` object.
    return tDetails.loadingPromise ?? Promise.resolve();
  }
  const lDetails = getLDeferBlockDetails(lView, tNode);
  const primaryBlockTNode = getPrimaryBlockTNode(tView, tDetails);
  // Switch from NOT_STARTED -> IN_PROGRESS state.
  tDetails.loadingState = DeferDependenciesLoadingState.IN_PROGRESS;
  // Prefetching is triggered, cleanup all registered prefetch triggers.
  invokeTriggerCleanupFns(1 /* TriggerType.Prefetch */, lDetails);
  let dependenciesFn = tDetails.dependencyResolverFn;
  if (ngDevMode) {
    // Check if dependency function interceptor is configured.
    const deferDependencyInterceptor = injector.get(DEFER_BLOCK_DEPENDENCY_INTERCEPTOR, null, {
      optional: true
    });
    if (deferDependencyInterceptor) {
      dependenciesFn = deferDependencyInterceptor.intercept(dependenciesFn);
    }
  }
  // Indicate that an application is not stable and has a pending task.
  const pendingTasks = injector.get(PendingTasks);
  const taskId = pendingTasks.add();
  // The `dependenciesFn` might be `null` when all dependencies within
  // a given defer block were eagerly referenced elsewhere in a file,
  // thus no dynamic `import()`s were produced.
  if (!dependenciesFn) {
    tDetails.loadingPromise = Promise.resolve().then(() => {
      tDetails.loadingPromise = null;
      tDetails.loadingState = DeferDependenciesLoadingState.COMPLETE;
      pendingTasks.remove(taskId);
    });
    return tDetails.loadingPromise;
  }
  // Start downloading of defer block dependencies.
  tDetails.loadingPromise = Promise.allSettled(dependenciesFn()).then(results => {
    let failed = false;
    const directiveDefs = [];
    const pipeDefs = [];
    for (const result of results) {
      if (result.status === 'fulfilled') {
        const dependency = result.value;
        const directiveDef = getComponentDef(dependency) || getDirectiveDef(dependency);
        if (directiveDef) {
          directiveDefs.push(directiveDef);
        } else {
          const pipeDef = getPipeDef$1(dependency);
          if (pipeDef) {
            pipeDefs.push(pipeDef);
          }
        }
      } else {
        failed = true;
        break;
      }
    }
    // Loading is completed, we no longer need the loading Promise
    // and a pending task should also be removed.
    tDetails.loadingPromise = null;
    pendingTasks.remove(taskId);
    if (failed) {
      tDetails.loadingState = DeferDependenciesLoadingState.FAILED;
      if (tDetails.errorTmplIndex === null) {
        const templateLocation = getTemplateLocationDetails(lView);
        const error = new RuntimeError(750 /* RuntimeErrorCode.DEFER_LOADING_FAILED */, ngDevMode && 'Loading dependencies for `@defer` block failed, ' + `but no \`@error\` block was configured${templateLocation}. ` + 'Consider using the `@error` block to render an error state.');
        handleError(lView, error);
      }
    } else {
      tDetails.loadingState = DeferDependenciesLoadingState.COMPLETE;
      // Update directive and pipe registries to add newly downloaded dependencies.
      const primaryBlockTView = primaryBlockTNode.tView;
      if (directiveDefs.length > 0) {
        primaryBlockTView.directiveRegistry = addDepsToRegistry(primaryBlockTView.directiveRegistry, directiveDefs);
        // Extract providers from all NgModules imported by standalone components
        // used within this defer block.
        const directiveTypes = directiveDefs.map(def => def.type);
        const providers = internalImportProvidersFrom(false, ...directiveTypes);
        tDetails.providers = providers;
      }
      if (pipeDefs.length > 0) {
        primaryBlockTView.pipeRegistry = addDepsToRegistry(primaryBlockTView.pipeRegistry, pipeDefs);
      }
    }
  });
  return tDetails.loadingPromise;
}
/** Utility function to render placeholder content (if present) */
function renderPlaceholder(lView, tNode) {
  const lContainer = lView[tNode.index];
  ngDevMode && assertLContainer(lContainer);
  renderDeferBlockState(DeferBlockState.Placeholder, tNode, lContainer);
}
/**
 * Subscribes to the "loading" Promise and renders corresponding defer sub-block,
 * based on the loading results.
 *
 * @param lContainer Represents an instance of a defer block.
 * @param tNode Represents defer block info shared across all instances.
 */
function renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer) {
  ngDevMode && assertDefined(tDetails.loadingPromise, 'Expected loading Promise to exist on this defer block');
  tDetails.loadingPromise.then(() => {
    if (tDetails.loadingState === DeferDependenciesLoadingState.COMPLETE) {
      ngDevMode && assertDeferredDependenciesLoaded(tDetails);
      // Everything is loaded, show the primary block content
      renderDeferBlockState(DeferBlockState.Complete, tNode, lContainer);
    } else if (tDetails.loadingState === DeferDependenciesLoadingState.FAILED) {
      renderDeferBlockState(DeferBlockState.Error, tNode, lContainer);
    }
  });
}
/**
 * Attempts to trigger loading of defer block dependencies.
 * If the block is already in a loading, completed or an error state -
 * no additional actions are taken.
 */
function triggerDeferBlock(lView, tNode) {
  const tView = lView[TVIEW];
  const lContainer = lView[tNode.index];
  const injector = lView[INJECTOR];
  ngDevMode && assertLContainer(lContainer);
  if (!shouldTriggerDeferBlock(injector)) return;
  const lDetails = getLDeferBlockDetails(lView, tNode);
  const tDetails = getTDeferBlockDetails(tView, tNode);
  // Defer block is triggered, cleanup all registered trigger functions.
  invokeAllTriggerCleanupFns(lDetails);
  switch (tDetails.loadingState) {
    case DeferDependenciesLoadingState.NOT_STARTED:
      renderDeferBlockState(DeferBlockState.Loading, tNode, lContainer);
      triggerResourceLoading(tDetails, lView, tNode);
      // The `loadingState` might have changed to "loading".
      if (tDetails.loadingState === DeferDependenciesLoadingState.IN_PROGRESS) {
        renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer);
      }
      break;
    case DeferDependenciesLoadingState.IN_PROGRESS:
      renderDeferBlockState(DeferBlockState.Loading, tNode, lContainer);
      renderDeferStateAfterResourceLoading(tDetails, tNode, lContainer);
      break;
    case DeferDependenciesLoadingState.COMPLETE:
      ngDevMode && assertDeferredDependenciesLoaded(tDetails);
      renderDeferBlockState(DeferBlockState.Complete, tNode, lContainer);
      break;
    case DeferDependenciesLoadingState.FAILED:
      renderDeferBlockState(DeferBlockState.Error, tNode, lContainer);
      break;
    default:
      if (ngDevMode) {
        throwError('Unknown defer block state');
      }
  }
}

/**
 * Updates the value of or removes a bound attribute on an Element.
 *
 * Used in the case of `[attr.title]="value"`
 *
 * @param name name The name of the attribute.
 * @param value value The attribute is removed when value is `null` or `undefined`.
 *                  Otherwise the attribute value is set to the stringified value.
 * @param sanitizer An optional function used to sanitize the value.
 * @param namespace Optional namespace to use when setting the attribute.
 *
 * @codeGenApi
 */
function ɵɵattribute(name, value, sanitizer, namespace) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, value)) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, name, value, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, 'attr.' + name, bindingIndex);
  }
  return ɵɵattribute;
}

/**
 * Create interpolation bindings with a variable number of expressions.
 *
 * If there are 1 to 8 expressions `interpolation1()` to `interpolation8()` should be used instead.
 * Those are faster because there is no need to create an array of expressions and iterate over it.
 *
 * `values`:
 * - has static text at even indexes,
 * - has evaluated expressions at odd indexes.
 *
 * Returns the concatenated string when any of the arguments changes, `NO_CHANGE` otherwise.
 */
function interpolationV(lView, values) {
  ngDevMode && assertLessThan(2, values.length, 'should have at least 3 values');
  ngDevMode && assertEqual(values.length % 2, 1, 'should have an odd number of values');
  let isBindingUpdated = false;
  let bindingIndex = getBindingIndex();
  for (let i = 1; i < values.length; i += 2) {
    // Check if bindings (odd indexes) have changed
    isBindingUpdated = bindingUpdated(lView, bindingIndex++, values[i]) || isBindingUpdated;
  }
  setBindingIndex(bindingIndex);
  if (!isBindingUpdated) {
    return NO_CHANGE;
  }
  // Build the updated content
  let content = values[0];
  for (let i = 1; i < values.length; i += 2) {
    content += renderStringify(values[i]) + values[i + 1];
  }
  return content;
}
/**
 * Creates an interpolation binding with 1 expression.
 *
 * @param prefix static value used for concatenation only.
 * @param v0 value checked for change.
 * @param suffix static value used for concatenation only.
 */
function interpolation1(lView, prefix, v0, suffix) {
  const different = bindingUpdated(lView, nextBindingIndex(), v0);
  return different ? prefix + renderStringify(v0) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 2 expressions.
 */
function interpolation2(lView, prefix, v0, i0, v1, suffix) {
  const bindingIndex = getBindingIndex();
  const different = bindingUpdated2(lView, bindingIndex, v0, v1);
  incrementBindingIndex(2);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 3 expressions.
 */
function interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix) {
  const bindingIndex = getBindingIndex();
  const different = bindingUpdated3(lView, bindingIndex, v0, v1, v2);
  incrementBindingIndex(3);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + suffix : NO_CHANGE;
}
/**
 * Create an interpolation binding with 4 expressions.
 */
function interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
  const bindingIndex = getBindingIndex();
  const different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
  incrementBindingIndex(4);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 5 expressions.
 */
function interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
  const bindingIndex = getBindingIndex();
  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
  different = bindingUpdated(lView, bindingIndex + 4, v4) || different;
  incrementBindingIndex(5);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 6 expressions.
 */
function interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
  const bindingIndex = getBindingIndex();
  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
  different = bindingUpdated2(lView, bindingIndex + 4, v4, v5) || different;
  incrementBindingIndex(6);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 7 expressions.
 */
function interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
  const bindingIndex = getBindingIndex();
  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
  different = bindingUpdated3(lView, bindingIndex + 4, v4, v5, v6) || different;
  incrementBindingIndex(7);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + renderStringify(v6) + suffix : NO_CHANGE;
}
/**
 * Creates an interpolation binding with 8 expressions.
 */
function interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
  const bindingIndex = getBindingIndex();
  let different = bindingUpdated4(lView, bindingIndex, v0, v1, v2, v3);
  different = bindingUpdated4(lView, bindingIndex + 4, v4, v5, v6, v7) || different;
  incrementBindingIndex(8);
  return different ? prefix + renderStringify(v0) + i0 + renderStringify(v1) + i1 + renderStringify(v2) + i2 + renderStringify(v3) + i3 + renderStringify(v4) + i4 + renderStringify(v5) + i5 + renderStringify(v6) + i6 + renderStringify(v7) + suffix : NO_CHANGE;
}

/**
 *
 * Update an interpolated attribute on an element with single bound value surrounded by text.
 *
 * Used when the value passed to a property has 1 interpolated value in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate1('title', 'prefix', v0, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate1(attrName, prefix, v0, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 1, prefix, suffix);
  }
  return ɵɵattributeInterpolate1;
}
/**
 *
 * Update an interpolated attribute on an element with 2 bound values surrounded by text.
 *
 * Used when the value passed to a property has 2 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate2(attrName, prefix, v0, i0, v1, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 2, prefix, i0, suffix);
  }
  return ɵɵattributeInterpolate2;
}
/**
 *
 * Update an interpolated attribute on an element with 3 bound values surrounded by text.
 *
 * Used when the value passed to a property has 3 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate3(
 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate3(attrName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 3, prefix, i0, i1, suffix);
  }
  return ɵɵattributeInterpolate3;
}
/**
 *
 * Update an interpolated attribute on an element with 4 bound values surrounded by text.
 *
 * Used when the value passed to a property has 4 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate4(
 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate4(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
  }
  return ɵɵattributeInterpolate4;
}
/**
 *
 * Update an interpolated attribute on an element with 5 bound values surrounded by text.
 *
 * Used when the value passed to a property has 5 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate5(
 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate5(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
  }
  return ɵɵattributeInterpolate5;
}
/**
 *
 * Update an interpolated attribute on an element with 6 bound values surrounded by text.
 *
 * Used when the value passed to a property has 6 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate6(
 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate6(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
  }
  return ɵɵattributeInterpolate6;
}
/**
 *
 * Update an interpolated attribute on an element with 7 bound values surrounded by text.
 *
 * Used when the value passed to a property has 7 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate7(
 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate7(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
  }
  return ɵɵattributeInterpolate7;
}
/**
 *
 * Update an interpolated attribute on an element with 8 bound values surrounded by text.
 *
 * Used when the value passed to a property has 8 interpolated values in it:
 *
 * ```html
 * <div attr.title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolate8(
 *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
 * ```
 *
 * @param attrName The name of the attribute to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param i6 Static value used for concatenation only.
 * @param v7 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolate8(attrName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer, namespace) {
  const lView = getLView();
  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolatedValue, sanitizer, namespace);
    ngDevMode && storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
  }
  return ɵɵattributeInterpolate8;
}
/**
 * Update an interpolated attribute on an element with 9 or more bound values surrounded by text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div
 *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵattributeInterpolateV(
 *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
 *  'suffix']);
 * ```
 *
 * @param attrName The name of the attribute to update.
 * @param values The collection of values and the strings in-between those values, beginning with
 * a string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵattributeInterpolateV(attrName, values, sanitizer, namespace) {
  const lView = getLView();
  const interpolated = interpolationV(lView, values);
  if (interpolated !== NO_CHANGE) {
    const tNode = getSelectedTNode();
    elementAttributeInternal(tNode, lView, attrName, interpolated, sanitizer, namespace);
    if (ngDevMode) {
      const interpolationInBetween = [values[0]]; // prefix
      for (let i = 2; i < values.length; i += 2) {
        interpolationInBetween.push(values[i]);
      }
      storePropertyBindingMetadata(getTView().data, tNode, 'attr.' + attrName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
    }
  }
  return ɵɵattributeInterpolateV;
}
function toTStylingRange(prev, next) {
  ngDevMode && assertNumberInRange(prev, 0, 32767 /* StylingRange.UNSIGNED_MASK */);
  ngDevMode && assertNumberInRange(next, 0, 32767 /* StylingRange.UNSIGNED_MASK */);
  return prev << 17 /* StylingRange.PREV_SHIFT */ | next << 2 /* StylingRange.NEXT_SHIFT */;
}
function getTStylingRangePrev(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return tStylingRange >> 17 /* StylingRange.PREV_SHIFT */ & 32767 /* StylingRange.UNSIGNED_MASK */;
}
function getTStylingRangePrevDuplicate(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return (tStylingRange & 2 /* StylingRange.PREV_DUPLICATE */) == 2 /* StylingRange.PREV_DUPLICATE */;
}
function setTStylingRangePrev(tStylingRange, previous) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  ngDevMode && assertNumberInRange(previous, 0, 32767 /* StylingRange.UNSIGNED_MASK */);
  return tStylingRange & ~4294836224 /* StylingRange.PREV_MASK */ | previous << 17 /* StylingRange.PREV_SHIFT */;
}
function setTStylingRangePrevDuplicate(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return tStylingRange | 2 /* StylingRange.PREV_DUPLICATE */;
}
function getTStylingRangeNext(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return (tStylingRange & 131068 /* StylingRange.NEXT_MASK */) >> 2 /* StylingRange.NEXT_SHIFT */;
}
function setTStylingRangeNext(tStylingRange, next) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  ngDevMode && assertNumberInRange(next, 0, 32767 /* StylingRange.UNSIGNED_MASK */);
  return tStylingRange & ~131068 /* StylingRange.NEXT_MASK */ |
  //
  next << 2 /* StylingRange.NEXT_SHIFT */;
}
function getTStylingRangeNextDuplicate(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return (tStylingRange & 1 /* StylingRange.NEXT_DUPLICATE */) === 1 /* StylingRange.NEXT_DUPLICATE */;
}
function setTStylingRangeNextDuplicate(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  return tStylingRange | 1 /* StylingRange.NEXT_DUPLICATE */;
}
function getTStylingRangeTail(tStylingRange) {
  ngDevMode && assertNumber(tStylingRange, 'expected number');
  const next = getTStylingRangeNext(tStylingRange);
  return next === 0 ? getTStylingRangePrev(tStylingRange) : next;
}

/**
 * NOTE: The word `styling` is used interchangeably as style or class styling.
 *
 * This file contains code to link styling instructions together so that they can be replayed in
 * priority order. The file exists because Ivy styling instruction execution order does not match
 * that of the priority order. The purpose of this code is to create a linked list so that the
 * instructions can be traversed in priority order when computing the styles.
 *
 * Assume we are dealing with the following code:
 * ```
 * @Component({
 *   template: `
 *     <my-cmp [style]=" {color: '#001'} "
 *             [style.color]=" #002 "
 *             dir-style-color-1
 *             dir-style-color-2> `
 * })
 * class ExampleComponent {
 *   static ngComp = ... {
 *     ...
 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
 *     ɵɵstyleMap({color: '#001'});
 *     ɵɵstyleProp('color', '#002');
 *     ...
 *   }
 * }
 *
 * @Directive({
 *   selector: `[dir-style-color-1]',
 * })
 * class Style1Directive {
 *   @HostBinding('style') style = {color: '#005'};
 *   @HostBinding('style.color') color = '#006';
 *
 *   static ngDir = ... {
 *     ...
 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
 *     ɵɵstyleMap({color: '#005'});
 *     ɵɵstyleProp('color', '#006');
 *     ...
 *   }
 * }
 *
 * @Directive({
 *   selector: `[dir-style-color-2]',
 * })
 * class Style2Directive {
 *   @HostBinding('style') style = {color: '#007'};
 *   @HostBinding('style.color') color = '#008';
 *
 *   static ngDir = ... {
 *     ...
 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
 *     ɵɵstyleMap({color: '#007'});
 *     ɵɵstyleProp('color', '#008');
 *     ...
 *   }
 * }
 *
 * @Directive({
 *   selector: `my-cmp',
 * })
 * class MyComponent {
 *   @HostBinding('style') style = {color: '#003'};
 *   @HostBinding('style.color') color = '#004';
 *
 *   static ngComp = ... {
 *     ...
 *     // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
 *     ɵɵstyleMap({color: '#003'});
 *     ɵɵstyleProp('color', '#004');
 *     ...
 *   }
 * }
 * ```
 *
 * The Order of instruction execution is:
 *
 * NOTE: the comment binding location is for illustrative purposes only.
 *
 * ```
 * // Template: (ExampleComponent)
 *     ɵɵstyleMap({color: '#001'});   // Binding index: 10
 *     ɵɵstyleProp('color', '#002');  // Binding index: 12
 * // MyComponent
 *     ɵɵstyleMap({color: '#003'});   // Binding index: 20
 *     ɵɵstyleProp('color', '#004');  // Binding index: 22
 * // Style1Directive
 *     ɵɵstyleMap({color: '#005'});   // Binding index: 24
 *     ɵɵstyleProp('color', '#006');  // Binding index: 26
 * // Style2Directive
 *     ɵɵstyleMap({color: '#007'});   // Binding index: 28
 *     ɵɵstyleProp('color', '#008');  // Binding index: 30
 * ```
 *
 * The correct priority order of concatenation is:
 *
 * ```
 * // MyComponent
 *     ɵɵstyleMap({color: '#003'});   // Binding index: 20
 *     ɵɵstyleProp('color', '#004');  // Binding index: 22
 * // Style1Directive
 *     ɵɵstyleMap({color: '#005'});   // Binding index: 24
 *     ɵɵstyleProp('color', '#006');  // Binding index: 26
 * // Style2Directive
 *     ɵɵstyleMap({color: '#007'});   // Binding index: 28
 *     ɵɵstyleProp('color', '#008');  // Binding index: 30
 * // Template: (ExampleComponent)
 *     ɵɵstyleMap({color: '#001'});   // Binding index: 10
 *     ɵɵstyleProp('color', '#002');  // Binding index: 12
 * ```
 *
 * What color should be rendered?
 *
 * Once the items are correctly sorted in the list, the answer is simply the last item in the
 * concatenation list which is `#002`.
 *
 * To do so we keep a linked list of all of the bindings which pertain to this element.
 * Notice that the bindings are inserted in the order of execution, but the `TView.data` allows
 * us to traverse them in the order of priority.
 *
 * |Idx|`TView.data`|`LView`          | Notes
 * |---|------------|-----------------|--------------
 * |...|            |                 |
 * |10 |`null`      |`{color: '#001'}`| `ɵɵstyleMap('color', {color: '#001'})`
 * |11 |`30 | 12`   | ...             |
 * |12 |`color`     |`'#002'`         | `ɵɵstyleProp('color', '#002')`
 * |13 |`10 | 0`    | ...             |
 * |...|            |                 |
 * |20 |`null`      |`{color: '#003'}`| `ɵɵstyleMap('color', {color: '#003'})`
 * |21 |`0 | 22`    | ...             |
 * |22 |`color`     |`'#004'`         | `ɵɵstyleProp('color', '#004')`
 * |23 |`20 | 24`   | ...             |
 * |24 |`null`      |`{color: '#005'}`| `ɵɵstyleMap('color', {color: '#005'})`
 * |25 |`22 | 26`   | ...             |
 * |26 |`color`     |`'#006'`         | `ɵɵstyleProp('color', '#006')`
 * |27 |`24 | 28`   | ...             |
 * |28 |`null`      |`{color: '#007'}`| `ɵɵstyleMap('color', {color: '#007'})`
 * |29 |`26 | 30`   | ...             |
 * |30 |`color`     |`'#008'`         | `ɵɵstyleProp('color', '#008')`
 * |31 |`28 | 10`   | ...             |
 *
 * The above data structure allows us to re-concatenate the styling no matter which data binding
 * changes.
 *
 * NOTE: in addition to keeping track of next/previous index the `TView.data` also stores prev/next
 * duplicate bit. The duplicate bit if true says there either is a binding with the same name or
 * there is a map (which may contain the name). This information is useful in knowing if other
 * styles with higher priority need to be searched for overwrites.
 *
 * NOTE: See `should support example in 'tnode_linked_list.ts' documentation` in
 * `tnode_linked_list_spec.ts` for working example.
 */
let __unused_const_as_closure_does_not_like_standalone_comment_blocks__;
/**
 * Insert new `tStyleValue` at `TData` and link existing style bindings such that we maintain linked
 * list of styles and compute the duplicate flag.
 *
 * Note: this function is executed during `firstUpdatePass` only to populate the `TView.data`.
 *
 * The function works by keeping track of `tStylingRange` which contains two pointers pointing to
 * the head/tail of the template portion of the styles.
 *  - if `isHost === false` (we are template) then insertion is at tail of `TStylingRange`
 *  - if `isHost === true` (we are host binding) then insertion is at head of `TStylingRange`
 *
 * @param tData The `TData` to insert into.
 * @param tNode `TNode` associated with the styling element.
 * @param tStylingKey See `TStylingKey`.
 * @param index location of where `tStyleValue` should be stored (and linked into list.)
 * @param isHostBinding `true` if the insertion is for a `hostBinding`. (insertion is in front of
 *               template.)
 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
 *                       `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
 */
function insertTStylingBinding(tData, tNode, tStylingKeyWithStatic, index, isHostBinding, isClassBinding) {
  ngDevMode && assertFirstUpdatePass(getTView());
  let tBindings = isClassBinding ? tNode.classBindings : tNode.styleBindings;
  let tmplHead = getTStylingRangePrev(tBindings);
  let tmplTail = getTStylingRangeNext(tBindings);
  tData[index] = tStylingKeyWithStatic;
  let isKeyDuplicateOfStatic = false;
  let tStylingKey;
  if (Array.isArray(tStylingKeyWithStatic)) {
    // We are case when the `TStylingKey` contains static fields as well.
    const staticKeyValueArray = tStylingKeyWithStatic;
    tStylingKey = staticKeyValueArray[1]; // unwrap.
    // We need to check if our key is present in the static so that we can mark it as duplicate.
    if (tStylingKey === null || keyValueArrayIndexOf(staticKeyValueArray, tStylingKey) > 0) {
      // tStylingKey is present in the statics, need to mark it as duplicate.
      isKeyDuplicateOfStatic = true;
    }
  } else {
    tStylingKey = tStylingKeyWithStatic;
  }
  if (isHostBinding) {
    // We are inserting host bindings
    // If we don't have template bindings then `tail` is 0.
    const hasTemplateBindings = tmplTail !== 0;
    // This is important to know because that means that the `head` can't point to the first
    // template bindings (there are none.) Instead the head points to the tail of the template.
    if (hasTemplateBindings) {
      // template head's "prev" will point to last host binding or to 0 if no host bindings yet
      const previousNode = getTStylingRangePrev(tData[tmplHead + 1]);
      tData[index + 1] = toTStylingRange(previousNode, tmplHead);
      // if a host binding has already been registered, we need to update the next of that host
      // binding to point to this one
      if (previousNode !== 0) {
        // We need to update the template-tail value to point to us.
        tData[previousNode + 1] = setTStylingRangeNext(tData[previousNode + 1], index);
      }
      // The "previous" of the template binding head should point to this host binding
      tData[tmplHead + 1] = setTStylingRangePrev(tData[tmplHead + 1], index);
    } else {
      tData[index + 1] = toTStylingRange(tmplHead, 0);
      // if a host binding has already been registered, we need to update the next of that host
      // binding to point to this one
      if (tmplHead !== 0) {
        // We need to update the template-tail value to point to us.
        tData[tmplHead + 1] = setTStylingRangeNext(tData[tmplHead + 1], index);
      }
      // if we don't have template, the head points to template-tail, and needs to be advanced.
      tmplHead = index;
    }
  } else {
    // We are inserting in template section.
    // We need to set this binding's "previous" to the current template tail
    tData[index + 1] = toTStylingRange(tmplTail, 0);
    ngDevMode && assertEqual(tmplHead !== 0 && tmplTail === 0, false, 'Adding template bindings after hostBindings is not allowed.');
    if (tmplHead === 0) {
      tmplHead = index;
    } else {
      // We need to update the previous value "next" to point to this binding
      tData[tmplTail + 1] = setTStylingRangeNext(tData[tmplTail + 1], index);
    }
    tmplTail = index;
  }
  // Now we need to update / compute the duplicates.
  // Starting with our location search towards head (least priority)
  if (isKeyDuplicateOfStatic) {
    tData[index + 1] = setTStylingRangePrevDuplicate(tData[index + 1]);
  }
  markDuplicates(tData, tStylingKey, index, true);
  markDuplicates(tData, tStylingKey, index, false);
  markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding);
  tBindings = toTStylingRange(tmplHead, tmplTail);
  if (isClassBinding) {
    tNode.classBindings = tBindings;
  } else {
    tNode.styleBindings = tBindings;
  }
}
/**
 * Look into the residual styling to see if the current `tStylingKey` is duplicate of residual.
 *
 * @param tNode `TNode` where the residual is stored.
 * @param tStylingKey `TStylingKey` to store.
 * @param tData `TData` associated with the current `LView`.
 * @param index location of where `tStyleValue` should be stored (and linked into list.)
 * @param isClassBinding True if the associated `tStylingKey` as a `class` styling.
 *                       `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
 */
function markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding) {
  const residual = isClassBinding ? tNode.residualClasses : tNode.residualStyles;
  if (residual != null /* or undefined */ && typeof tStylingKey == 'string' && keyValueArrayIndexOf(residual, tStylingKey) >= 0) {
    // We have duplicate in the residual so mark ourselves as duplicate.
    tData[index + 1] = setTStylingRangeNextDuplicate(tData[index + 1]);
  }
}
/**
 * Marks `TStyleValue`s as duplicates if another style binding in the list has the same
 * `TStyleValue`.
 *
 * NOTE: this function is intended to be called twice once with `isPrevDir` set to `true` and once
 * with it set to `false` to search both the previous as well as next items in the list.
 *
 * No duplicate case
 * ```
 *   [style.color]
 *   [style.width.px] <<- index
 *   [style.height.px]
 * ```
 *
 * In the above case adding `[style.width.px]` to the existing `[style.color]` produces no
 * duplicates because `width` is not found in any other part of the linked list.
 *
 * Duplicate case
 * ```
 *   [style.color]
 *   [style.width.em]
 *   [style.width.px] <<- index
 * ```
 * In the above case adding `[style.width.px]` will produce a duplicate with `[style.width.em]`
 * because `width` is found in the chain.
 *
 * Map case 1
 * ```
 *   [style.width.px]
 *   [style.color]
 *   [style]  <<- index
 * ```
 * In the above case adding `[style]` will produce a duplicate with any other bindings because
 * `[style]` is a Map and as such is fully dynamic and could produce `color` or `width`.
 *
 * Map case 2
 * ```
 *   [style]
 *   [style.width.px]
 *   [style.color]  <<- index
 * ```
 * In the above case adding `[style.color]` will produce a duplicate because there is already a
 * `[style]` binding which is a Map and as such is fully dynamic and could produce `color` or
 * `width`.
 *
 * NOTE: Once `[style]` (Map) is added into the system all things are mapped as duplicates.
 * NOTE: We use `style` as example, but same logic is applied to `class`es as well.
 *
 * @param tData `TData` where the linked list is stored.
 * @param tStylingKey `TStylingKeyPrimitive` which contains the value to compare to other keys in
 *        the linked list.
 * @param index Starting location in the linked list to search from
 * @param isPrevDir Direction.
 *        - `true` for previous (lower priority);
 *        - `false` for next (higher priority).
 */
function markDuplicates(tData, tStylingKey, index, isPrevDir) {
  const tStylingAtIndex = tData[index + 1];
  const isMap = tStylingKey === null;
  let cursor = isPrevDir ? getTStylingRangePrev(tStylingAtIndex) : getTStylingRangeNext(tStylingAtIndex);
  let foundDuplicate = false;
  // We keep iterating as long as we have a cursor
  // AND either:
  // - we found what we are looking for, OR
  // - we are a map in which case we have to continue searching even after we find what we were
  //   looking for since we are a wild card and everything needs to be flipped to duplicate.
  while (cursor !== 0 && (foundDuplicate === false || isMap)) {
    ngDevMode && assertIndexInRange(tData, cursor);
    const tStylingValueAtCursor = tData[cursor];
    const tStyleRangeAtCursor = tData[cursor + 1];
    if (isStylingMatch(tStylingValueAtCursor, tStylingKey)) {
      foundDuplicate = true;
      tData[cursor + 1] = isPrevDir ? setTStylingRangeNextDuplicate(tStyleRangeAtCursor) : setTStylingRangePrevDuplicate(tStyleRangeAtCursor);
    }
    cursor = isPrevDir ? getTStylingRangePrev(tStyleRangeAtCursor) : getTStylingRangeNext(tStyleRangeAtCursor);
  }
  if (foundDuplicate) {
    // if we found a duplicate, than mark ourselves.
    tData[index + 1] = isPrevDir ? setTStylingRangePrevDuplicate(tStylingAtIndex) : setTStylingRangeNextDuplicate(tStylingAtIndex);
  }
}
/**
 * Determines if two `TStylingKey`s are a match.
 *
 * When computing whether a binding contains a duplicate, we need to compare if the instruction
 * `TStylingKey` has a match.
 *
 * Here are examples of `TStylingKey`s which match given `tStylingKeyCursor` is:
 * - `color`
 *    - `color`    // Match another color
 *    - `null`     // That means that `tStylingKey` is a `classMap`/`styleMap` instruction
 *    - `['', 'color', 'other', true]` // wrapped `color` so match
 *    - `['', null, 'other', true]`       // wrapped `null` so match
 *    - `['', 'width', 'color', 'value']` // wrapped static value contains a match on `'color'`
 * - `null`       // `tStylingKeyCursor` always match as it is `classMap`/`styleMap` instruction
 *
 * @param tStylingKeyCursor
 * @param tStylingKey
 */
function isStylingMatch(tStylingKeyCursor, tStylingKey) {
  ngDevMode && assertNotEqual(Array.isArray(tStylingKey), true, 'Expected that \'tStylingKey\' has been unwrapped');
  if (tStylingKeyCursor === null ||
  // If the cursor is `null` it means that we have map at that
  // location so we must assume that we have a match.
  tStylingKey == null ||
  // If `tStylingKey` is `null` then it is a map therefor assume that it
  // contains a match.
  (Array.isArray(tStylingKeyCursor) ? tStylingKeyCursor[1] : tStylingKeyCursor) === tStylingKey // If the keys match explicitly than we are a match.
  ) {
    return true;
  } else if (Array.isArray(tStylingKeyCursor) && typeof tStylingKey === 'string') {
    // if we did not find a match, but `tStylingKeyCursor` is `KeyValueArray` that means cursor has
    // statics and we need to check those as well.
    return keyValueArrayIndexOf(tStylingKeyCursor, tStylingKey) >= 0; // see if we are matching the key
  }
  return false;
}

// Global state of the parser. (This makes parser non-reentrant, but that is not an issue)
const parserState = {
  textEnd: 0,
  key: 0,
  keyEnd: 0,
  value: 0,
  valueEnd: 0
};
/**
 * Retrieves the last parsed `key` of style.
 * @param text the text to substring the key from.
 */
function getLastParsedKey(text) {
  return text.substring(parserState.key, parserState.keyEnd);
}
/**
 * Retrieves the last parsed `value` of style.
 * @param text the text to substring the key from.
 */
function getLastParsedValue(text) {
  return text.substring(parserState.value, parserState.valueEnd);
}
/**
 * Initializes `className` string for parsing and parses the first token.
 *
 * This function is intended to be used in this format:
 * ```
 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
 *   const key = getLastParsedKey();
 *   ...
 * }
 * ```
 * @param text `className` to parse
 * @returns index where the next invocation of `parseClassNameNext` should resume.
 */
function parseClassName(text) {
  resetParserState(text);
  return parseClassNameNext(text, consumeWhitespace(text, 0, parserState.textEnd));
}
/**
 * Parses next `className` token.
 *
 * This function is intended to be used in this format:
 * ```
 * for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
 *   const key = getLastParsedKey();
 *   ...
 * }
 * ```
 *
 * @param text `className` to parse
 * @param index where the parsing should resume.
 * @returns index where the next invocation of `parseClassNameNext` should resume.
 */
function parseClassNameNext(text, index) {
  const end = parserState.textEnd;
  if (end === index) {
    return -1;
  }
  index = parserState.keyEnd = consumeClassToken(text, parserState.key = index, end);
  return consumeWhitespace(text, index, end);
}
/**
 * Initializes `cssText` string for parsing and parses the first key/values.
 *
 * This function is intended to be used in this format:
 * ```
 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
 *   const key = getLastParsedKey();
 *   const value = getLastParsedValue();
 *   ...
 * }
 * ```
 * @param text `cssText` to parse
 * @returns index where the next invocation of `parseStyleNext` should resume.
 */
function parseStyle(text) {
  resetParserState(text);
  return parseStyleNext(text, consumeWhitespace(text, 0, parserState.textEnd));
}
/**
 * Parses the next `cssText` key/values.
 *
 * This function is intended to be used in this format:
 * ```
 * for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i))) {
 *   const key = getLastParsedKey();
 *   const value = getLastParsedValue();
 *   ...
 * }
 *
 * @param text `cssText` to parse
 * @param index where the parsing should resume.
 * @returns index where the next invocation of `parseStyleNext` should resume.
 */
function parseStyleNext(text, startIndex) {
  const end = parserState.textEnd;
  let index = parserState.key = consumeWhitespace(text, startIndex, end);
  if (end === index) {
    // we reached an end so just quit
    return -1;
  }
  index = parserState.keyEnd = consumeStyleKey(text, index, end);
  index = consumeSeparator(text, index, end, 58 /* CharCode.COLON */);
  index = parserState.value = consumeWhitespace(text, index, end);
  index = parserState.valueEnd = consumeStyleValue(text, index, end);
  return consumeSeparator(text, index, end, 59 /* CharCode.SEMI_COLON */);
}
/**
 * Reset the global state of the styling parser.
 * @param text The styling text to parse.
 */
function resetParserState(text) {
  parserState.key = 0;
  parserState.keyEnd = 0;
  parserState.value = 0;
  parserState.valueEnd = 0;
  parserState.textEnd = text.length;
}
/**
 * Returns index of next non-whitespace character.
 *
 * @param text Text to scan
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index of next non-whitespace character (May be the same as `start` if no whitespace at
 *          that location.)
 */
function consumeWhitespace(text, startIndex, endIndex) {
  while (startIndex < endIndex && text.charCodeAt(startIndex) <= 32 /* CharCode.SPACE */) {
    startIndex++;
  }
  return startIndex;
}
/**
 * Returns index of last char in class token.
 *
 * @param text Text to scan
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index after last char in class token.
 */
function consumeClassToken(text, startIndex, endIndex) {
  while (startIndex < endIndex && text.charCodeAt(startIndex) > 32 /* CharCode.SPACE */) {
    startIndex++;
  }
  return startIndex;
}
/**
 * Consumes all of the characters belonging to style key and token.
 *
 * @param text Text to scan
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index after last style key character.
 */
function consumeStyleKey(text, startIndex, endIndex) {
  let ch;
  while (startIndex < endIndex && ((ch = text.charCodeAt(startIndex)) === 45 /* CharCode.DASH */ || ch === 95 /* CharCode.UNDERSCORE */ || (ch & -33 /* CharCode.UPPER_CASE */) >= 65 /* CharCode.A */ && (ch & -33 /* CharCode.UPPER_CASE */) <= 90 /* CharCode.Z */ || ch >= 48 /* CharCode.ZERO */ && ch <= 57 /* CharCode.NINE */)) {
    startIndex++;
  }
  return startIndex;
}
/**
 * Consumes all whitespace and the separator `:` after the style key.
 *
 * @param text Text to scan
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index after separator and surrounding whitespace.
 */
function consumeSeparator(text, startIndex, endIndex, separator) {
  startIndex = consumeWhitespace(text, startIndex, endIndex);
  if (startIndex < endIndex) {
    if (ngDevMode && text.charCodeAt(startIndex) !== separator) {
      malformedStyleError(text, String.fromCharCode(separator), startIndex);
    }
    startIndex++;
  }
  return startIndex;
}
/**
 * Consumes style value honoring `url()` and `""` text.
 *
 * @param text Text to scan
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index after last style value character.
 */
function consumeStyleValue(text, startIndex, endIndex) {
  let ch1 = -1; // 1st previous character
  let ch2 = -1; // 2nd previous character
  let ch3 = -1; // 3rd previous character
  let i = startIndex;
  let lastChIndex = i;
  while (i < endIndex) {
    const ch = text.charCodeAt(i++);
    if (ch === 59 /* CharCode.SEMI_COLON */) {
      return lastChIndex;
    } else if (ch === 34 /* CharCode.DOUBLE_QUOTE */ || ch === 39 /* CharCode.SINGLE_QUOTE */) {
      lastChIndex = i = consumeQuotedText(text, ch, i, endIndex);
    } else if (startIndex === i - 4 &&
    // We have seen only 4 characters so far "URL(" (Ignore "foo_URL()")
    ch3 === 85 /* CharCode.U */ && ch2 === 82 /* CharCode.R */ && ch1 === 76 /* CharCode.L */ && ch === 40 /* CharCode.OPEN_PAREN */) {
      lastChIndex = i = consumeQuotedText(text, 41 /* CharCode.CLOSE_PAREN */, i, endIndex);
    } else if (ch > 32 /* CharCode.SPACE */) {
      // if we have a non-whitespace character then capture its location
      lastChIndex = i;
    }
    ch3 = ch2;
    ch2 = ch1;
    ch1 = ch & -33 /* CharCode.UPPER_CASE */;
  }
  return lastChIndex;
}
/**
 * Consumes all of the quoted characters.
 *
 * @param text Text to scan
 * @param quoteCharCode CharCode of either `"` or `'` quote or `)` for `url(...)`.
 * @param startIndex Starting index of character where the scan should start.
 * @param endIndex Ending index of character where the scan should end.
 * @returns Index after quoted characters.
 */
function consumeQuotedText(text, quoteCharCode, startIndex, endIndex) {
  let ch1 = -1; // 1st previous character
  let index = startIndex;
  while (index < endIndex) {
    const ch = text.charCodeAt(index++);
    if (ch == quoteCharCode && ch1 !== 92 /* CharCode.BACK_SLASH */) {
      return index;
    }
    if (ch == 92 /* CharCode.BACK_SLASH */ && ch1 === 92 /* CharCode.BACK_SLASH */) {
      // two back slashes cancel each other out. For example `"\\"` should properly end the
      // quotation. (It should not assume that the last `"` is escaped.)
      ch1 = 0;
    } else {
      ch1 = ch;
    }
  }
  throw ngDevMode ? malformedStyleError(text, String.fromCharCode(quoteCharCode), endIndex) : new Error();
}
function malformedStyleError(text, expecting, index) {
  ngDevMode && assertEqual(typeof text === 'string', true, 'String expected here');
  throw throwError(`Malformed style at location ${index} in string '` + text.substring(0, index) + '[>>' + text.substring(index, index + 1) + '<<]' + text.slice(index + 1) + `'. Expecting '${expecting}'.`);
}

/**
 * Update a property on a selected element.
 *
 * Operates on the element selected by index via the {@link select} instruction.
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled
 *
 * @param propName Name of property. Because it is going to DOM, this is not subject to
 *        renaming as part of minification.
 * @param value New value to write.
 * @param sanitizer An optional function used to sanitize the value.
 * @returns This function returns itself so that it may be chained
 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
 *
 * @codeGenApi
 */
function ɵɵproperty(propName, value, sanitizer) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, value)) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
  }
  return ɵɵproperty;
}
/**
 * Given `<div style="..." my-dir>` and `MyDir` with `@Input('style')` we need to write to
 * directive input.
 */
function setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased) {
  const inputs = tNode.inputs;
  const property = isClassBased ? 'class' : 'style';
  // We support both 'class' and `className` hence the fallback.
  setInputsForProperty(tView, lView, inputs[property], property, value);
}

/**
 * Update a style binding on an element with the provided value.
 *
 * If the style value is falsy then it will be removed from the element
 * (or assigned a different value depending if there are any styles placed
 * on the element with `styleMap` or any static styles that are
 * present from when the element was created with `styling`).
 *
 * Note that the styling element is updated as part of `stylingApply`.
 *
 * @param prop A valid CSS property.
 * @param value New value to write (`null` or an empty string to remove).
 * @param suffix Optional suffix. Used with scalar values to add unit such as `px`.
 *
 * Note that this will apply the provided style value to the host element if this function is called
 * within a host binding function.
 *
 * @codeGenApi
 */
function ɵɵstyleProp(prop, value, suffix) {
  checkStylingProperty(prop, value, suffix, false);
  return ɵɵstyleProp;
}
/**
 * Update a class binding on an element with the provided value.
 *
 * This instruction is meant to handle the `[class.foo]="exp"` case and,
 * therefore, the class binding itself must already be allocated using
 * `styling` within the creation block.
 *
 * @param prop A valid CSS class (only one).
 * @param value A true/false value which will turn the class on or off.
 *
 * Note that this will apply the provided class value to the host element if this function
 * is called within a host binding function.
 *
 * @codeGenApi
 */
function ɵɵclassProp(className, value) {
  checkStylingProperty(className, value, null, true);
  return ɵɵclassProp;
}
/**
 * Update style bindings using an object literal on an element.
 *
 * This instruction is meant to apply styling via the `[style]="exp"` template bindings.
 * When styles are applied to the element they will then be updated with respect to
 * any styles/classes set via `styleProp`. If any styles are set to falsy
 * then they will be removed from the element.
 *
 * Note that the styling instruction will not be applied until `stylingApply` is called.
 *
 * @param styles A key/value style map of the styles that will be applied to the given element.
 *        Any missing styles (that have already been applied to the element beforehand) will be
 *        removed (unset) from the element's styling.
 *
 * Note that this will apply the provided styleMap value to the host element if this function
 * is called within a host binding.
 *
 * @codeGenApi
 */
function ɵɵstyleMap(styles) {
  checkStylingMap(styleKeyValueArraySet, styleStringParser, styles, false);
}
/**
 * Parse text as style and add values to KeyValueArray.
 *
 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
 * needed. It is only referenced from `ɵɵstyleMap`.
 *
 * @param keyValueArray KeyValueArray to add parsed values to.
 * @param text text to parse.
 */
function styleStringParser(keyValueArray, text) {
  for (let i = parseStyle(text); i >= 0; i = parseStyleNext(text, i)) {
    styleKeyValueArraySet(keyValueArray, getLastParsedKey(text), getLastParsedValue(text));
  }
}
/**
 * Update class bindings using an object literal or class-string on an element.
 *
 * This instruction is meant to apply styling via the `[class]="exp"` template bindings.
 * When classes are applied to the element they will then be updated with
 * respect to any styles/classes set via `classProp`. If any
 * classes are set to falsy then they will be removed from the element.
 *
 * Note that the styling instruction will not be applied until `stylingApply` is called.
 * Note that this will the provided classMap value to the host element if this function is called
 * within a host binding.
 *
 * @param classes A key/value map or string of CSS classes that will be added to the
 *        given element. Any missing classes (that have already been applied to the element
 *        beforehand) will be removed (unset) from the element's list of CSS classes.
 *
 * @codeGenApi
 */
function ɵɵclassMap(classes) {
  checkStylingMap(classKeyValueArraySet, classStringParser, classes, true);
}
/**
 * Parse text as class and add values to KeyValueArray.
 *
 * This code is pulled out to a separate function so that it can be tree shaken away if it is not
 * needed. It is only referenced from `ɵɵclassMap`.
 *
 * @param keyValueArray KeyValueArray to add parsed values to.
 * @param text text to parse.
 */
function classStringParser(keyValueArray, text) {
  for (let i = parseClassName(text); i >= 0; i = parseClassNameNext(text, i)) {
    keyValueArraySet(keyValueArray, getLastParsedKey(text), true);
  }
}
/**
 * Common code between `ɵɵclassProp` and `ɵɵstyleProp`.
 *
 * @param prop property name.
 * @param value binding value.
 * @param suffix suffix for the property (e.g. `em` or `px`)
 * @param isClassBased `true` if `class` change (`false` if `style`)
 */
function checkStylingProperty(prop, value, suffix, isClassBased) {
  const lView = getLView();
  const tView = getTView();
  // Styling instructions use 2 slots per binding.
  // 1. one for the value / TStylingKey
  // 2. one for the intermittent-value / TStylingRange
  const bindingIndex = incrementBindingIndex(2);
  if (tView.firstUpdatePass) {
    stylingFirstUpdatePass(tView, prop, bindingIndex, isClassBased);
  }
  if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
    const tNode = tView.data[getSelectedIndex()];
    updateStyling(tView, tNode, lView, lView[RENDERER], prop, lView[bindingIndex + 1] = normalizeSuffix(value, suffix), isClassBased, bindingIndex);
  }
}
/**
 * Common code between `ɵɵclassMap` and `ɵɵstyleMap`.
 *
 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
 *        function so that `style` can be processed. This is done for tree shaking purposes.
 * @param stringParser Parser used to parse `value` if `string`. (Passed in as `style` and `class`
 *        have different parsers.)
 * @param value bound value from application
 * @param isClassBased `true` if `class` change (`false` if `style`)
 */
function checkStylingMap(keyValueArraySet, stringParser, value, isClassBased) {
  const tView = getTView();
  const bindingIndex = incrementBindingIndex(2);
  if (tView.firstUpdatePass) {
    stylingFirstUpdatePass(tView, null, bindingIndex, isClassBased);
  }
  const lView = getLView();
  if (value !== NO_CHANGE && bindingUpdated(lView, bindingIndex, value)) {
    // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
    // if so as not to read unnecessarily.
    const tNode = tView.data[getSelectedIndex()];
    if (hasStylingInputShadow(tNode, isClassBased) && !isInHostBindings(tView, bindingIndex)) {
      if (ngDevMode) {
        // verify that if we are shadowing then `TData` is appropriately marked so that we skip
        // processing this binding in styling resolution.
        const tStylingKey = tView.data[bindingIndex];
        assertEqual(Array.isArray(tStylingKey) ? tStylingKey[1] : tStylingKey, false, 'Styling linked list shadow input should be marked as \'false\'');
      }
      // VE does not concatenate the static portion like we are doing here.
      // Instead VE just ignores the static completely if dynamic binding is present.
      // Because of locality we have already set the static portion because we don't know if there
      // is a dynamic portion until later. If we would ignore the static portion it would look like
      // the binding has removed it. This would confuse `[ngStyle]`/`[ngClass]` to do the wrong
      // thing as it would think that the static portion was removed. For this reason we
      // concatenate it so that `[ngStyle]`/`[ngClass]`  can continue to work on changed.
      let staticPrefix = isClassBased ? tNode.classesWithoutHost : tNode.stylesWithoutHost;
      ngDevMode && isClassBased === false && staticPrefix !== null && assertEqual(staticPrefix.endsWith(';'), true, 'Expecting static portion to end with \';\'');
      if (staticPrefix !== null) {
        // We want to make sure that falsy values of `value` become empty strings.
        value = concatStringsWithSpace(staticPrefix, value ? value : '');
      }
      // Given `<div [style] my-dir>` such that `my-dir` has `@Input('style')`.
      // This takes over the `[style]` binding. (Same for `[class]`)
      setDirectiveInputsWhichShadowsStyling(tView, tNode, lView, value, isClassBased);
    } else {
      updateStylingMap(tView, tNode, lView, lView[RENDERER], lView[bindingIndex + 1], lView[bindingIndex + 1] = toStylingKeyValueArray(keyValueArraySet, stringParser, value), isClassBased, bindingIndex);
    }
  }
}
/**
 * Determines when the binding is in `hostBindings` section
 *
 * @param tView Current `TView`
 * @param bindingIndex index of binding which we would like if it is in `hostBindings`
 */
function isInHostBindings(tView, bindingIndex) {
  // All host bindings are placed after the expando section.
  return bindingIndex >= tView.expandoStartIndex;
}
/**
 * Collects the necessary information to insert the binding into a linked list of style bindings
 * using `insertTStylingBinding`.
 *
 * @param tView `TView` where the binding linked list will be stored.
 * @param tStylingKey Property/key of the binding.
 * @param bindingIndex Index of binding associated with the `prop`
 * @param isClassBased `true` if `class` change (`false` if `style`)
 */
function stylingFirstUpdatePass(tView, tStylingKey, bindingIndex, isClassBased) {
  ngDevMode && assertFirstUpdatePass(tView);
  const tData = tView.data;
  if (tData[bindingIndex + 1] === null) {
    // The above check is necessary because we don't clear first update pass until first successful
    // (no exception) template execution. This prevents the styling instruction from double adding
    // itself to the list.
    // `getSelectedIndex()` should be here (rather than in instruction) so that it is guarded by the
    // if so as not to read unnecessarily.
    const tNode = tData[getSelectedIndex()];
    ngDevMode && assertDefined(tNode, 'TNode expected');
    const isHostBindings = isInHostBindings(tView, bindingIndex);
    if (hasStylingInputShadow(tNode, isClassBased) && tStylingKey === null && !isHostBindings) {
      // `tStylingKey === null` implies that we are either `[style]` or `[class]` binding.
      // If there is a directive which uses `@Input('style')` or `@Input('class')` than
      // we need to neutralize this binding since that directive is shadowing it.
      // We turn this into a noop by setting the key to `false`
      tStylingKey = false;
    }
    tStylingKey = wrapInStaticStylingKey(tData, tNode, tStylingKey, isClassBased);
    insertTStylingBinding(tData, tNode, tStylingKey, bindingIndex, isHostBindings, isClassBased);
  }
}
/**
 * Adds static styling information to the binding if applicable.
 *
 * The linked list of styles not only stores the list and keys, but also stores static styling
 * information on some of the keys. This function determines if the key should contain the styling
 * information and computes it.
 *
 * See `TStylingStatic` for more details.
 *
 * @param tData `TData` where the linked list is stored.
 * @param tNode `TNode` for which the styling is being computed.
 * @param stylingKey `TStylingKeyPrimitive` which may need to be wrapped into `TStylingKey`
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function wrapInStaticStylingKey(tData, tNode, stylingKey, isClassBased) {
  const hostDirectiveDef = getCurrentDirectiveDef(tData);
  let residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
  if (hostDirectiveDef === null) {
    // We are in template node.
    // If template node already had styling instruction then it has already collected the static
    // styling and there is no need to collect them again. We know that we are the first styling
    // instruction because the `TNode.*Bindings` points to 0 (nothing has been inserted yet).
    const isFirstStylingInstructionInTemplate = (isClassBased ? tNode.classBindings : tNode.styleBindings) === 0;
    if (isFirstStylingInstructionInTemplate) {
      // It would be nice to be able to get the statics from `mergeAttrs`, however, at this point
      // they are already merged and it would not be possible to figure which property belongs where
      // in the priority.
      stylingKey = collectStylingFromDirectives(null, tData, tNode, stylingKey, isClassBased);
      stylingKey = collectStylingFromTAttrs(stylingKey, tNode.attrs, isClassBased);
      // We know that if we have styling binding in template we can't have residual.
      residual = null;
    }
  } else {
    // We are in host binding node and there was no binding instruction in template node.
    // This means that we need to compute the residual.
    const directiveStylingLast = tNode.directiveStylingLast;
    const isFirstStylingInstructionInHostBinding = directiveStylingLast === -1 || tData[directiveStylingLast] !== hostDirectiveDef;
    if (isFirstStylingInstructionInHostBinding) {
      stylingKey = collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased);
      if (residual === null) {
        // - If `null` than either:
        //    - Template styling instruction already ran and it has consumed the static
        //      styling into its `TStylingKey` and so there is no need to update residual. Instead
        //      we need to update the `TStylingKey` associated with the first template node
        //      instruction. OR
        //    - Some other styling instruction ran and determined that there are no residuals
        let templateStylingKey = getTemplateHeadTStylingKey(tData, tNode, isClassBased);
        if (templateStylingKey !== undefined && Array.isArray(templateStylingKey)) {
          // Only recompute if `templateStylingKey` had static values. (If no static value found
          // then there is nothing to do since this operation can only produce less static keys, not
          // more.)
          templateStylingKey = collectStylingFromDirectives(null, tData, tNode, templateStylingKey[1] /* unwrap previous statics */, isClassBased);
          templateStylingKey = collectStylingFromTAttrs(templateStylingKey, tNode.attrs, isClassBased);
          setTemplateHeadTStylingKey(tData, tNode, isClassBased, templateStylingKey);
        }
      } else {
        // We only need to recompute residual if it is not `null`.
        // - If existing residual (implies there was no template styling). This means that some of
        //   the statics may have moved from the residual to the `stylingKey` and so we have to
        //   recompute.
        // - If `undefined` this is the first time we are running.
        residual = collectResidual(tData, tNode, isClassBased);
      }
    }
  }
  if (residual !== undefined) {
    isClassBased ? tNode.residualClasses = residual : tNode.residualStyles = residual;
  }
  return stylingKey;
}
/**
 * Retrieve the `TStylingKey` for the template styling instruction.
 *
 * This is needed since `hostBinding` styling instructions are inserted after the template
 * instruction. While the template instruction needs to update the residual in `TNode` the
 * `hostBinding` instructions need to update the `TStylingKey` of the template instruction because
 * the template instruction is downstream from the `hostBindings` instructions.
 *
 * @param tData `TData` where the linked list is stored.
 * @param tNode `TNode` for which the styling is being computed.
 * @param isClassBased `true` if `class` (`false` if `style`)
 * @return `TStylingKey` if found or `undefined` if not found.
 */
function getTemplateHeadTStylingKey(tData, tNode, isClassBased) {
  const bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
  if (getTStylingRangeNext(bindings) === 0) {
    // There does not seem to be a styling instruction in the `template`.
    return undefined;
  }
  return tData[getTStylingRangePrev(bindings)];
}
/**
 * Update the `TStylingKey` of the first template instruction in `TNode`.
 *
 * Logically `hostBindings` styling instructions are of lower priority than that of the template.
 * However, they execute after the template styling instructions. This means that they get inserted
 * in front of the template styling instructions.
 *
 * If we have a template styling instruction and a new `hostBindings` styling instruction is
 * executed it means that it may need to steal static fields from the template instruction. This
 * method allows us to update the first template instruction `TStylingKey` with a new value.
 *
 * Assume:
 * ```
 * <div my-dir style="color: red" [style.color]="tmplExp"></div>
 *
 * @Directive({
 *   host: {
 *     'style': 'width: 100px',
 *     '[style.color]': 'dirExp',
 *   }
 * })
 * class MyDir {}
 * ```
 *
 * when `[style.color]="tmplExp"` executes it creates this data structure.
 * ```
 *  ['', 'color', 'color', 'red', 'width', '100px'],
 * ```
 *
 * The reason for this is that the template instruction does not know if there are styling
 * instructions and must assume that there are none and must collect all of the static styling.
 * (both
 * `color' and 'width`)
 *
 * When `'[style.color]': 'dirExp',` executes we need to insert a new data into the linked list.
 * ```
 *  ['', 'color', 'width', '100px'],  // newly inserted
 *  ['', 'color', 'color', 'red', 'width', '100px'], // this is wrong
 * ```
 *
 * Notice that the template statics is now wrong as it incorrectly contains `width` so we need to
 * update it like so:
 * ```
 *  ['', 'color', 'width', '100px'],
 *  ['', 'color', 'color', 'red'],    // UPDATE
 * ```
 *
 * @param tData `TData` where the linked list is stored.
 * @param tNode `TNode` for which the styling is being computed.
 * @param isClassBased `true` if `class` (`false` if `style`)
 * @param tStylingKey New `TStylingKey` which is replacing the old one.
 */
function setTemplateHeadTStylingKey(tData, tNode, isClassBased, tStylingKey) {
  const bindings = isClassBased ? tNode.classBindings : tNode.styleBindings;
  ngDevMode && assertNotEqual(getTStylingRangeNext(bindings), 0, 'Expecting to have at least one template styling binding.');
  tData[getTStylingRangePrev(bindings)] = tStylingKey;
}
/**
 * Collect all static values after the current `TNode.directiveStylingLast` index.
 *
 * Collect the remaining styling information which has not yet been collected by an existing
 * styling instruction.
 *
 * @param tData `TData` where the `DirectiveDefs` are stored.
 * @param tNode `TNode` which contains the directive range.
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function collectResidual(tData, tNode, isClassBased) {
  let residual = undefined;
  const directiveEnd = tNode.directiveEnd;
  ngDevMode && assertNotEqual(tNode.directiveStylingLast, -1, 'By the time this function gets called at least one hostBindings-node styling instruction must have executed.');
  // We add `1 + tNode.directiveStart` because we need to skip the current directive (as we are
  // collecting things after the last `hostBindings` directive which had a styling instruction.)
  for (let i = 1 + tNode.directiveStylingLast; i < directiveEnd; i++) {
    const attrs = tData[i].hostAttrs;
    residual = collectStylingFromTAttrs(residual, attrs, isClassBased);
  }
  return collectStylingFromTAttrs(residual, tNode.attrs, isClassBased);
}
/**
 * Collect the static styling information with lower priority than `hostDirectiveDef`.
 *
 * (This is opposite of residual styling.)
 *
 * @param hostDirectiveDef `DirectiveDef` for which we want to collect lower priority static
 *        styling. (Or `null` if template styling)
 * @param tData `TData` where the linked list is stored.
 * @param tNode `TNode` for which the styling is being computed.
 * @param stylingKey Existing `TStylingKey` to update or wrap.
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function collectStylingFromDirectives(hostDirectiveDef, tData, tNode, stylingKey, isClassBased) {
  // We need to loop because there can be directives which have `hostAttrs` but don't have
  // `hostBindings` so this loop catches up to the current directive..
  let currentDirective = null;
  const directiveEnd = tNode.directiveEnd;
  let directiveStylingLast = tNode.directiveStylingLast;
  if (directiveStylingLast === -1) {
    directiveStylingLast = tNode.directiveStart;
  } else {
    directiveStylingLast++;
  }
  while (directiveStylingLast < directiveEnd) {
    currentDirective = tData[directiveStylingLast];
    ngDevMode && assertDefined(currentDirective, 'expected to be defined');
    stylingKey = collectStylingFromTAttrs(stylingKey, currentDirective.hostAttrs, isClassBased);
    if (currentDirective === hostDirectiveDef) break;
    directiveStylingLast++;
  }
  if (hostDirectiveDef !== null) {
    // we only advance the styling cursor if we are collecting data from host bindings.
    // Template executes before host bindings and so if we would update the index,
    // host bindings would not get their statics.
    tNode.directiveStylingLast = directiveStylingLast;
  }
  return stylingKey;
}
/**
 * Convert `TAttrs` into `TStylingStatic`.
 *
 * @param stylingKey existing `TStylingKey` to update or wrap.
 * @param attrs `TAttributes` to process.
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function collectStylingFromTAttrs(stylingKey, attrs, isClassBased) {
  const desiredMarker = isClassBased ? 1 /* AttributeMarker.Classes */ : 2 /* AttributeMarker.Styles */;
  let currentMarker = -1 /* AttributeMarker.ImplicitAttributes */;
  if (attrs !== null) {
    for (let i = 0; i < attrs.length; i++) {
      const item = attrs[i];
      if (typeof item === 'number') {
        currentMarker = item;
      } else {
        if (currentMarker === desiredMarker) {
          if (!Array.isArray(stylingKey)) {
            stylingKey = stylingKey === undefined ? [] : ['', stylingKey];
          }
          keyValueArraySet(stylingKey, item, isClassBased ? true : attrs[++i]);
        }
      }
    }
  }
  return stylingKey === undefined ? null : stylingKey;
}
/**
 * Convert user input to `KeyValueArray`.
 *
 * This function takes user input which could be `string`, Object literal, or iterable and converts
 * it into a consistent representation. The output of this is `KeyValueArray` (which is an array
 * where
 * even indexes contain keys and odd indexes contain values for those keys).
 *
 * The advantage of converting to `KeyValueArray` is that we can perform diff in an input
 * independent
 * way.
 * (ie we can compare `foo bar` to `['bar', 'baz'] and determine a set of changes which need to be
 * applied)
 *
 * The fact that `KeyValueArray` is sorted is very important because it allows us to compute the
 * difference in linear fashion without the need to allocate any additional data.
 *
 * For example if we kept this as a `Map` we would have to iterate over previous `Map` to determine
 * which values need to be deleted, over the new `Map` to determine additions, and we would have to
 * keep additional `Map` to keep track of duplicates or items which have not yet been visited.
 *
 * @param keyValueArraySet (See `keyValueArraySet` in "util/array_utils") Gets passed in as a
 *        function so that `style` can be processed. This is done
 *        for tree shaking purposes.
 * @param stringParser The parser is passed in so that it will be tree shakable. See
 *        `styleStringParser` and `classStringParser`
 * @param value The value to parse/convert to `KeyValueArray`
 */
function toStylingKeyValueArray(keyValueArraySet, stringParser, value) {
  if (value == null /*|| value === undefined */ || value === '') return EMPTY_ARRAY;
  const styleKeyValueArray = [];
  const unwrappedValue = unwrapSafeValue(value);
  if (Array.isArray(unwrappedValue)) {
    for (let i = 0; i < unwrappedValue.length; i++) {
      keyValueArraySet(styleKeyValueArray, unwrappedValue[i], true);
    }
  } else if (typeof unwrappedValue === 'object') {
    for (const key in unwrappedValue) {
      if (unwrappedValue.hasOwnProperty(key)) {
        keyValueArraySet(styleKeyValueArray, key, unwrappedValue[key]);
      }
    }
  } else if (typeof unwrappedValue === 'string') {
    stringParser(styleKeyValueArray, unwrappedValue);
  } else {
    ngDevMode && throwError('Unsupported styling type ' + typeof unwrappedValue + ': ' + unwrappedValue);
  }
  return styleKeyValueArray;
}
/**
 * Set a `value` for a `key`.
 *
 * See: `keyValueArraySet` for details
 *
 * @param keyValueArray KeyValueArray to add to.
 * @param key Style key to add.
 * @param value The value to set.
 */
function styleKeyValueArraySet(keyValueArray, key, value) {
  keyValueArraySet(keyValueArray, key, unwrapSafeValue(value));
}
/**
 * Class-binding-specific function for setting the `value` for a `key`.
 *
 * See: `keyValueArraySet` for details
 *
 * @param keyValueArray KeyValueArray to add to.
 * @param key Style key to add.
 * @param value The value to set.
 */
function classKeyValueArraySet(keyValueArray, key, value) {
  // We use `classList.add` to eventually add the CSS classes to the DOM node. Any value passed into
  // `add` is stringified and added to the `class` attribute, e.g. even null, undefined or numbers
  // will be added. Stringify the key here so that our internal data structure matches the value in
  // the DOM. The only exceptions are empty strings and strings that contain spaces for which
  // the browser throws an error. We ignore such values, because the error is somewhat cryptic.
  const stringKey = String(key);
  if (stringKey !== '' && !stringKey.includes(' ')) {
    keyValueArraySet(keyValueArray, stringKey, value);
  }
}
/**
 * Update map based styling.
 *
 * Map based styling could be anything which contains more than one binding. For example `string`,
 * or object literal. Dealing with all of these types would complicate the logic so
 * instead this function expects that the complex input is first converted into normalized
 * `KeyValueArray`. The advantage of normalization is that we get the values sorted, which makes it
 * very cheap to compute deltas between the previous and current value.
 *
 * @param tView Associated `TView.data` contains the linked list of binding priorities.
 * @param tNode `TNode` where the binding is located.
 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
 * @param renderer Renderer to use if any updates.
 * @param oldKeyValueArray Previous value represented as `KeyValueArray`
 * @param newKeyValueArray Current value represented as `KeyValueArray`
 * @param isClassBased `true` if `class` (`false` if `style`)
 * @param bindingIndex Binding index of the binding.
 */
function updateStylingMap(tView, tNode, lView, renderer, oldKeyValueArray, newKeyValueArray, isClassBased, bindingIndex) {
  if (oldKeyValueArray === NO_CHANGE) {
    // On first execution the oldKeyValueArray is NO_CHANGE => treat it as empty KeyValueArray.
    oldKeyValueArray = EMPTY_ARRAY;
  }
  let oldIndex = 0;
  let newIndex = 0;
  let oldKey = 0 < oldKeyValueArray.length ? oldKeyValueArray[0] : null;
  let newKey = 0 < newKeyValueArray.length ? newKeyValueArray[0] : null;
  while (oldKey !== null || newKey !== null) {
    ngDevMode && assertLessThan(oldIndex, 999, 'Are we stuck in infinite loop?');
    ngDevMode && assertLessThan(newIndex, 999, 'Are we stuck in infinite loop?');
    const oldValue = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex + 1] : undefined;
    const newValue = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex + 1] : undefined;
    let setKey = null;
    let setValue = undefined;
    if (oldKey === newKey) {
      // UPDATE: Keys are equal => new value is overwriting old value.
      oldIndex += 2;
      newIndex += 2;
      if (oldValue !== newValue) {
        setKey = newKey;
        setValue = newValue;
      }
    } else if (newKey === null || oldKey !== null && oldKey < newKey) {
      // DELETE: oldKey key is missing or we did not find the oldKey in the newValue
      // (because the keyValueArray is sorted and `newKey` is found later alphabetically).
      // `"background" < "color"` so we need to delete `"background"` because it is not found in the
      // new array.
      oldIndex += 2;
      setKey = oldKey;
    } else {
      // CREATE: newKey's is earlier alphabetically than oldKey's (or no oldKey) => we have new key.
      // `"color" > "background"` so we need to add `color` because it is in new array but not in
      // old array.
      ngDevMode && assertDefined(newKey, 'Expecting to have a valid key');
      newIndex += 2;
      setKey = newKey;
      setValue = newValue;
    }
    if (setKey !== null) {
      updateStyling(tView, tNode, lView, renderer, setKey, setValue, isClassBased, bindingIndex);
    }
    oldKey = oldIndex < oldKeyValueArray.length ? oldKeyValueArray[oldIndex] : null;
    newKey = newIndex < newKeyValueArray.length ? newKeyValueArray[newIndex] : null;
  }
}
/**
 * Update a simple (property name) styling.
 *
 * This function takes `prop` and updates the DOM to that value. The function takes the binding
 * value as well as binding priority into consideration to determine which value should be written
 * to DOM. (For example it may be determined that there is a higher priority overwrite which blocks
 * the DOM write, or if the value goes to `undefined` a lower priority overwrite may be consulted.)
 *
 * @param tView Associated `TView.data` contains the linked list of binding priorities.
 * @param tNode `TNode` where the binding is located.
 * @param lView `LView` contains the values associated with other styling binding at this `TNode`.
 * @param renderer Renderer to use if any updates.
 * @param prop Either style property name or a class name.
 * @param value Either style value for `prop` or `true`/`false` if `prop` is class.
 * @param isClassBased `true` if `class` (`false` if `style`)
 * @param bindingIndex Binding index of the binding.
 */
function updateStyling(tView, tNode, lView, renderer, prop, value, isClassBased, bindingIndex) {
  if (!(tNode.type & 3 /* TNodeType.AnyRNode */)) {
    // It is possible to have styling on non-elements (such as ng-container).
    // This is rare, but it does happen. In such a case, just ignore the binding.
    return;
  }
  const tData = tView.data;
  const tRange = tData[bindingIndex + 1];
  const higherPriorityValue = getTStylingRangeNextDuplicate(tRange) ? findStylingValue(tData, tNode, lView, prop, getTStylingRangeNext(tRange), isClassBased) : undefined;
  if (!isStylingValuePresent(higherPriorityValue)) {
    // We don't have a next duplicate, or we did not find a duplicate value.
    if (!isStylingValuePresent(value)) {
      // We should delete current value or restore to lower priority value.
      if (getTStylingRangePrevDuplicate(tRange)) {
        // We have a possible prev duplicate, let's retrieve it.
        value = findStylingValue(tData, null, lView, prop, bindingIndex, isClassBased);
      }
    }
    const rNode = getNativeByIndex(getSelectedIndex(), lView);
    applyStyling(renderer, isClassBased, rNode, prop, value);
  }
}
/**
 * Search for styling value with higher priority which is overwriting current value, or a
 * value of lower priority to which we should fall back if the value is `undefined`.
 *
 * When value is being applied at a location, related values need to be consulted.
 * - If there is a higher priority binding, we should be using that one instead.
 *   For example `<div  [style]="{color:exp1}" [style.color]="exp2">` change to `exp1`
 *   requires that we check `exp2` to see if it is set to value other than `undefined`.
 * - If there is a lower priority binding and we are changing to `undefined`
 *   For example `<div  [style]="{color:exp1}" [style.color]="exp2">` change to `exp2` to
 *   `undefined` requires that we check `exp1` (and static values) and use that as new value.
 *
 * NOTE: The styling stores two values.
 * 1. The raw value which came from the application is stored at `index + 0` location. (This value
 *    is used for dirty checking).
 * 2. The normalized value is stored at `index + 1`.
 *
 * @param tData `TData` used for traversing the priority.
 * @param tNode `TNode` to use for resolving static styling. Also controls search direction.
 *   - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
 *      If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
 *   - `null` search prev and go all the way to end. Return last value where
 *     `isStylingValuePresent(value)` is true.
 * @param lView `LView` used for retrieving the actual values.
 * @param prop Property which we are interested in.
 * @param index Starting index in the linked list of styling bindings where the search should start.
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function findStylingValue(tData, tNode, lView, prop, index, isClassBased) {
  // `TNode` to use for resolving static styling. Also controls search direction.
  //   - `TNode` search next and quit as soon as `isStylingValuePresent(value)` is true.
  //      If no value found consult `tNode.residualStyle`/`tNode.residualClass` for default value.
  //   - `null` search prev and go all the way to end. Return last value where
  //     `isStylingValuePresent(value)` is true.
  const isPrevDirection = tNode === null;
  let value = undefined;
  while (index > 0) {
    const rawKey = tData[index];
    const containsStatics = Array.isArray(rawKey);
    // Unwrap the key if we contain static values.
    const key = containsStatics ? rawKey[1] : rawKey;
    const isStylingMap = key === null;
    let valueAtLViewIndex = lView[index + 1];
    if (valueAtLViewIndex === NO_CHANGE) {
      // In firstUpdatePass the styling instructions create a linked list of styling.
      // On subsequent passes it is possible for a styling instruction to try to read a binding
      // which
      // has not yet executed. In that case we will find `NO_CHANGE` and we should assume that
      // we have `undefined` (or empty array in case of styling-map instruction) instead. This
      // allows the resolution to apply the value (which may later be overwritten when the
      // binding actually executes.)
      valueAtLViewIndex = isStylingMap ? EMPTY_ARRAY : undefined;
    }
    let currentValue = isStylingMap ? keyValueArrayGet(valueAtLViewIndex, prop) : key === prop ? valueAtLViewIndex : undefined;
    if (containsStatics && !isStylingValuePresent(currentValue)) {
      currentValue = keyValueArrayGet(rawKey, prop);
    }
    if (isStylingValuePresent(currentValue)) {
      value = currentValue;
      if (isPrevDirection) {
        return value;
      }
    }
    const tRange = tData[index + 1];
    index = isPrevDirection ? getTStylingRangePrev(tRange) : getTStylingRangeNext(tRange);
  }
  if (tNode !== null) {
    // in case where we are going in next direction AND we did not find anything, we need to
    // consult residual styling
    let residual = isClassBased ? tNode.residualClasses : tNode.residualStyles;
    if (residual != null /** OR residual !=== undefined */) {
      value = keyValueArrayGet(residual, prop);
    }
  }
  return value;
}
/**
 * Determines if the binding value should be used (or if the value is 'undefined' and hence priority
 * resolution should be used.)
 *
 * @param value Binding style value.
 */
function isStylingValuePresent(value) {
  // Currently only `undefined` value is considered non-binding. That is `undefined` says I don't
  // have an opinion as to what this binding should be and you should consult other bindings by
  // priority to determine the valid value.
  // This is extracted into a single function so that we have a single place to control this.
  return value !== undefined;
}
/**
 * Normalizes and/or adds a suffix to the value.
 *
 * If value is `null`/`undefined` no suffix is added
 * @param value
 * @param suffix
 */
function normalizeSuffix(value, suffix) {
  if (value == null || value === '') {
    // do nothing
    // Do not add the suffix if the value is going to be empty.
    // As it produce invalid CSS, which the browsers will automatically omit but Domino will not.
    // Example: `"left": "px;"` instead of `"left": ""`.
  } else if (typeof suffix === 'string') {
    value = value + suffix;
  } else if (typeof value === 'object') {
    value = stringify(unwrapSafeValue(value));
  }
  return value;
}
/**
 * Tests if the `TNode` has input shadow.
 *
 * An input shadow is when a directive steals (shadows) the input by using `@Input('style')` or
 * `@Input('class')` as input.
 *
 * @param tNode `TNode` which we would like to see if it has shadow.
 * @param isClassBased `true` if `class` (`false` if `style`)
 */
function hasStylingInputShadow(tNode, isClassBased) {
  return (tNode.flags & (isClassBased ? 8 /* TNodeFlags.hasClassInput */ : 16 /* TNodeFlags.hasStyleInput */)) !== 0;
}

/**
 *
 * Update an interpolated class on an element with single bound value surrounded by text.
 *
 * Used when the value passed to a property has 1 interpolated value in it:
 *
 * ```html
 * <div class="prefix{{v0}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate1('prefix', v0, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate1(prefix, v0, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 2 bound values surrounded by text.
 *
 * Used when the value passed to a property has 2 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate2('prefix', v0, '-', v1, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate2(prefix, v0, i0, v1, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 3 bound values surrounded by text.
 *
 * Used when the value passed to a property has 3 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate3(
 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 4 bound values surrounded by text.
 *
 * Used when the value passed to a property has 4 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate4(
 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 5 bound values surrounded by text.
 *
 * Used when the value passed to a property has 5 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate5(
 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 6 bound values surrounded by text.
 *
 * Used when the value passed to a property has 6 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate6(
 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 7 bound values surrounded by text.
 *
 * Used when the value passed to a property has 7 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate7(
 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 *
 * Update an interpolated class on an element with 8 bound values surrounded by text.
 *
 * Used when the value passed to a property has 8 interpolated values in it:
 *
 * ```html
 * <div class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolate8(
 *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param i6 Static value used for concatenation only.
 * @param v7 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵclassMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}
/**
 * Update an interpolated class on an element with 9 or more bound values surrounded by text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div
 *  class="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵclassMapInterpolateV(
 *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
 *  'suffix']);
 * ```
 *.
 * @param values The collection of values and the strings in-between those values, beginning with
 * a string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
 * @codeGenApi
 */
function ɵɵclassMapInterpolateV(values) {
  const lView = getLView();
  const interpolatedValue = interpolationV(lView, values);
  checkStylingMap(keyValueArraySet, classStringParser, interpolatedValue, true);
}

/*!
 * @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
 */
/**
 * Instruction that returns the component instance in which the current instruction is executing.
 * This is a constant-time version of `nextContent` for the case where we know that we need the
 * component instance specifically, rather than the context of a particular template.
 *
 * @codeGenApi
 */
function ɵɵcomponentInstance() {
  const instance = getLView()[DECLARATION_COMPONENT_VIEW][CONTEXT];
  ngDevMode && assertDefined(instance, 'Expected component instance to be defined');
  return instance;
}

/**
 * A type representing the live collection to be reconciled with any new (incoming) collection. This
 * is an adapter class that makes it possible to work with different internal data structures,
 * regardless of the actual values of the incoming collection.
 */
class LiveCollection {
  destroy(item) {
    // noop by default
  }
  updateValue(index, value) {
    // noop by default
  }
  // operations below could be implemented on top of the operations defined so far, but having
  // them explicitly allow clear expression of intent and potentially more performant
  // implementations
  swap(index1, index2) {
    const startIdx = Math.min(index1, index2);
    const endIdx = Math.max(index1, index2);
    const endItem = this.detach(endIdx);
    if (endIdx - startIdx > 1) {
      const startItem = this.detach(startIdx);
      this.attach(startIdx, endItem);
      this.attach(endIdx, startItem);
    } else {
      this.attach(startIdx, endItem);
    }
  }
  move(prevIndex, newIdx) {
    this.attach(newIdx, this.detach(prevIndex));
  }
}
function valuesMatching(liveIdx, liveValue, newIdx, newValue, trackBy) {
  if (liveIdx === newIdx && Object.is(liveValue, newValue)) {
    // matching and no value identity to update
    return 1;
  } else if (Object.is(trackBy(liveIdx, liveValue), trackBy(newIdx, newValue))) {
    // matching but requires value identity update
    return -1;
  }
  return 0;
}
/**
 * The live collection reconciliation algorithm that perform various in-place operations, so it
 * reflects the content of the new (incoming) collection.
 *
 * The reconciliation algorithm has 2 code paths:
 * - "fast" path that don't require any memory allocation;
 * - "slow" path that requires additional memory allocation for intermediate data structures used to
 * collect additional information about the live collection.
 * It might happen that the algorithm switches between the two modes in question in a single
 * reconciliation path - generally it tries to stay on the "fast" path as much as possible.
 *
 * The overall complexity of the algorithm is O(n + m) for speed and O(n) for memory (where n is the
 * length of the live collection and m is the length of the incoming collection). Given the problem
 * at hand the complexity / performance constraints makes it impossible to perform the absolute
 * minimum of operation to reconcile the 2 collections. The algorithm makes different tradeoffs to
 * stay within reasonable performance bounds and may apply sub-optimal number of operations in
 * certain situations.
 *
 * @param liveCollection the current, live collection;
 * @param newCollection the new, incoming collection;
 * @param trackByFn key generation function that determines equality between items in the life and
 *     incoming collection;
 */
function reconcile(liveCollection, newCollection, trackByFn) {
  let detachedItems = undefined;
  let liveKeysInTheFuture = undefined;
  let liveStartIdx = 0;
  let liveEndIdx = liveCollection.length - 1;
  if (Array.isArray(newCollection)) {
    let newEndIdx = newCollection.length - 1;
    while (liveStartIdx <= liveEndIdx && liveStartIdx <= newEndIdx) {
      // compare from the beginning
      const liveStartValue = liveCollection.at(liveStartIdx);
      const newStartValue = newCollection[liveStartIdx];
      const isStartMatching = valuesMatching(liveStartIdx, liveStartValue, liveStartIdx, newStartValue, trackByFn);
      if (isStartMatching !== 0) {
        if (isStartMatching < 0) {
          liveCollection.updateValue(liveStartIdx, newStartValue);
        }
        liveStartIdx++;
        continue;
      }
      // compare from the end
      // TODO(perf): do _all_ the matching from the end
      const liveEndValue = liveCollection.at(liveEndIdx);
      const newEndValue = newCollection[newEndIdx];
      const isEndMatching = valuesMatching(liveEndIdx, liveEndValue, newEndIdx, newEndValue, trackByFn);
      if (isEndMatching !== 0) {
        if (isEndMatching < 0) {
          liveCollection.updateValue(liveEndIdx, newEndValue);
        }
        liveEndIdx--;
        newEndIdx--;
        continue;
      }
      // Detect swap and moves:
      const liveStartKey = trackByFn(liveStartIdx, liveStartValue);
      const liveEndKey = trackByFn(liveEndIdx, liveEndValue);
      const newStartKey = trackByFn(liveStartIdx, newStartValue);
      if (Object.is(newStartKey, liveEndKey)) {
        const newEndKey = trackByFn(newEndIdx, newEndValue);
        // detect swap on both ends;
        if (Object.is(newEndKey, liveStartKey)) {
          liveCollection.swap(liveStartIdx, liveEndIdx);
          liveCollection.updateValue(liveEndIdx, newEndValue);
          newEndIdx--;
          liveEndIdx--;
        } else {
          // the new item is the same as the live item with the end pointer - this is a move forward
          // to an earlier index;
          liveCollection.move(liveEndIdx, liveStartIdx);
        }
        liveCollection.updateValue(liveStartIdx, newStartValue);
        liveStartIdx++;
        continue;
      }
      // Fallback to the slow path: we need to learn more about the content of the live and new
      // collections.
      detachedItems ??= new UniqueValueMultiKeyMap();
      liveKeysInTheFuture ??= initLiveItemsInTheFuture(liveCollection, liveStartIdx, liveEndIdx, trackByFn);
      // Check if I'm inserting a previously detached item: if so, attach it here
      if (attachPreviouslyDetached(liveCollection, detachedItems, liveStartIdx, newStartKey)) {
        liveCollection.updateValue(liveStartIdx, newStartValue);
        liveStartIdx++;
        liveEndIdx++;
      } else if (!liveKeysInTheFuture.has(newStartKey)) {
        // Check if we seen a new item that doesn't exist in the old collection and must be INSERTED
        const newItem = liveCollection.create(liveStartIdx, newCollection[liveStartIdx]);
        liveCollection.attach(liveStartIdx, newItem);
        liveStartIdx++;
        liveEndIdx++;
      } else {
        // We know that the new item exists later on in old collection but we don't know its index
        // and as the consequence can't move it (don't know where to find it). Detach the old item,
        // hoping that it unlocks the fast path again.
        detachedItems.set(liveStartKey, liveCollection.detach(liveStartIdx));
        liveEndIdx--;
      }
    }
    // Final cleanup steps:
    // - more items in the new collection => insert
    while (liveStartIdx <= newEndIdx) {
      createOrAttach(liveCollection, detachedItems, trackByFn, liveStartIdx, newCollection[liveStartIdx]);
      liveStartIdx++;
    }
  } else if (newCollection != null) {
    // iterable - immediately fallback to the slow path
    const newCollectionIterator = newCollection[Symbol.iterator]();
    let newIterationResult = newCollectionIterator.next();
    while (!newIterationResult.done && liveStartIdx <= liveEndIdx) {
      const liveValue = liveCollection.at(liveStartIdx);
      const newValue = newIterationResult.value;
      const isStartMatching = valuesMatching(liveStartIdx, liveValue, liveStartIdx, newValue, trackByFn);
      if (isStartMatching !== 0) {
        // found a match - move on, but update value
        if (isStartMatching < 0) {
          liveCollection.updateValue(liveStartIdx, newValue);
        }
        liveStartIdx++;
        newIterationResult = newCollectionIterator.next();
      } else {
        detachedItems ??= new UniqueValueMultiKeyMap();
        liveKeysInTheFuture ??= initLiveItemsInTheFuture(liveCollection, liveStartIdx, liveEndIdx, trackByFn);
        // Check if I'm inserting a previously detached item: if so, attach it here
        const newKey = trackByFn(liveStartIdx, newValue);
        if (attachPreviouslyDetached(liveCollection, detachedItems, liveStartIdx, newKey)) {
          liveCollection.updateValue(liveStartIdx, newValue);
          liveStartIdx++;
          liveEndIdx++;
          newIterationResult = newCollectionIterator.next();
        } else if (!liveKeysInTheFuture.has(newKey)) {
          liveCollection.attach(liveStartIdx, liveCollection.create(liveStartIdx, newValue));
          liveStartIdx++;
          liveEndIdx++;
          newIterationResult = newCollectionIterator.next();
        } else {
          // it is a move forward - detach the current item without advancing in collections
          const liveKey = trackByFn(liveStartIdx, liveValue);
          detachedItems.set(liveKey, liveCollection.detach(liveStartIdx));
          liveEndIdx--;
        }
      }
    }
    // this is a new item as we run out of the items in the old collection - create or attach a
    // previously detached one
    while (!newIterationResult.done) {
      createOrAttach(liveCollection, detachedItems, trackByFn, liveCollection.length, newIterationResult.value);
      newIterationResult = newCollectionIterator.next();
    }
  }
  // Cleanups common to the array and iterable:
  // - more items in the live collection => delete starting from the end;
  while (liveStartIdx <= liveEndIdx) {
    liveCollection.destroy(liveCollection.detach(liveEndIdx--));
  }
  // - destroy items that were detached but never attached again.
  detachedItems?.forEach(item => {
    liveCollection.destroy(item);
  });
}
function attachPreviouslyDetached(prevCollection, detachedItems, index, key) {
  if (detachedItems !== undefined && detachedItems.has(key)) {
    prevCollection.attach(index, detachedItems.get(key));
    detachedItems.delete(key);
    return true;
  }
  return false;
}
function createOrAttach(liveCollection, detachedItems, trackByFn, index, value) {
  if (!attachPreviouslyDetached(liveCollection, detachedItems, index, trackByFn(index, value))) {
    const newItem = liveCollection.create(index, value);
    liveCollection.attach(index, newItem);
  } else {
    liveCollection.updateValue(index, value);
  }
}
function initLiveItemsInTheFuture(liveCollection, start, end, trackByFn) {
  const keys = new Set();
  for (let i = start; i <= end; i++) {
    keys.add(trackByFn(i, liveCollection.at(i)));
  }
  return keys;
}
/**
 * A specific, partial implementation of the Map interface with the following characteristics:
 * - allows multiple values for a given key;
 * - maintain FIFO order for multiple values corresponding to a given key;
 * - assumes that all values are unique.
 *
 * The implementation aims at having the minimal overhead for cases where keys are _not_ duplicated
 * (the most common case in the list reconciliation algorithm). To achieve this, the first value for
 * a given key is stored in a regular map. Then, when more values are set for a given key, we
 * maintain a form of linked list in a separate map. To maintain this linked list we assume that all
 * values (in the entire collection) are unique.
 */
class UniqueValueMultiKeyMap {
  constructor() {
    // A map from a key to the first value corresponding to this key.
    this.kvMap = new Map();
    // A map that acts as a linked list of values - each value maps to the next value in this "linked
    // list" (this only works if values are unique). Allocated lazily to avoid memory consumption when
    // there are no duplicated values.
    this._vMap = undefined;
  }
  has(key) {
    return this.kvMap.has(key);
  }
  delete(key) {
    if (!this.has(key)) return false;
    const value = this.kvMap.get(key);
    if (this._vMap !== undefined && this._vMap.has(value)) {
      this.kvMap.set(key, this._vMap.get(value));
      this._vMap.delete(value);
    } else {
      this.kvMap.delete(key);
    }
    return true;
  }
  get(key) {
    return this.kvMap.get(key);
  }
  set(key, value) {
    if (this.kvMap.has(key)) {
      let prevValue = this.kvMap.get(key);
      ngDevMode && assertNotSame(prevValue, value, `Detected a duplicated value ${value} for the key ${key}`);
      if (this._vMap === undefined) {
        this._vMap = new Map();
      }
      const vMap = this._vMap;
      while (vMap.has(prevValue)) {
        prevValue = vMap.get(prevValue);
      }
      vMap.set(prevValue, value);
    } else {
      this.kvMap.set(key, value);
    }
  }
  forEach(cb) {
    for (let [key, value] of this.kvMap) {
      cb(value, key);
      if (this._vMap !== undefined) {
        const vMap = this._vMap;
        while (vMap.has(value)) {
          value = vMap.get(value);
          cb(value, key);
        }
      }
    }
  }
}

/**
 * The conditional instruction represents the basic building block on the runtime side to support
 * built-in "if" and "switch". On the high level this instruction is responsible for adding and
 * removing views selected by a conditional expression.
 *
 * @param containerIndex index of a container in a host view (indexed from HEADER_OFFSET) where
 *     conditional views should be inserted.
 * @param matchingTemplateIndex index of a template TNode representing a conditional view to be
 *     inserted; -1 represents a special case when there is no view to insert.
 * @codeGenApi
 */
function ɵɵconditional(containerIndex, matchingTemplateIndex, value) {
  performanceMarkFeature('NgControlFlow');
  const hostLView = getLView();
  const bindingIndex = nextBindingIndex();
  const lContainer = getLContainer(hostLView, HEADER_OFFSET + containerIndex);
  const viewInContainerIdx = 0;
  if (bindingUpdated(hostLView, bindingIndex, matchingTemplateIndex)) {
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      // The index of the view to show changed - remove the previously displayed one
      // (it is a noop if there are no active views in a container).
      removeLViewFromLContainer(lContainer, viewInContainerIdx);
      // Index -1 is a special case where none of the conditions evaluates to
      // a truthy value and as the consequence we've got no view to show.
      if (matchingTemplateIndex !== -1) {
        const templateTNode = getExistingTNode(hostLView[TVIEW], HEADER_OFFSET + matchingTemplateIndex);
        const dehydratedView = findMatchingDehydratedView(lContainer, templateTNode.tView.ssrId);
        const embeddedLView = createAndRenderEmbeddedLView(hostLView, templateTNode, value, {
          dehydratedView
        });
        addLViewToLContainer(lContainer, embeddedLView, viewInContainerIdx, shouldAddViewToDom(templateTNode, dehydratedView));
      }
    } finally {
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  } else {
    // We might keep displaying the same template but the actual value of the expression could have
    // changed - re-bind in context.
    const lView = getLViewFromLContainer(lContainer, viewInContainerIdx);
    if (lView !== undefined) {
      lView[CONTEXT] = value;
    }
  }
}
class RepeaterContext {
  constructor(lContainer, $implicit, $index) {
    this.lContainer = lContainer;
    this.$implicit = $implicit;
    this.$index = $index;
  }
  get $count() {
    return this.lContainer.length - CONTAINER_HEADER_OFFSET;
  }
}
/**
 * A built-in trackBy function used for situations where users specified collection index as a
 * tracking expression. Having this function body in the runtime avoids unnecessary code generation.
 *
 * @param index
 * @returns
 */
function ɵɵrepeaterTrackByIndex(index) {
  return index;
}
/**
 * A built-in trackBy function used for situations where users specified collection item reference
 * as a tracking expression. Having this function body in the runtime avoids unnecessary code
 * generation.
 *
 * @param index
 * @returns
 */
function ɵɵrepeaterTrackByIdentity(_, value) {
  return value;
}
class RepeaterMetadata {
  constructor(hasEmptyBlock, trackByFn, liveCollection) {
    this.hasEmptyBlock = hasEmptyBlock;
    this.trackByFn = trackByFn;
    this.liveCollection = liveCollection;
  }
}
/**
 * The repeaterCreate instruction runs in the creation part of the template pass and initializes
 * internal data structures required by the update pass of the built-in repeater logic. Repeater
 * metadata are allocated in the data part of LView with the following layout:
 * - LView[HEADER_OFFSET + index] - metadata
 * - LView[HEADER_OFFSET + index + 1] - reference to a template function rendering an item
 * - LView[HEADER_OFFSET + index + 2] - optional reference to a template function rendering an empty
 * block
 *
 * @param index Index at which to store the metadata of the repeater.
 * @param templateFn Reference to the template of the main repeater block.
 * @param decls The number of nodes, local refs, and pipes for the main block.
 * @param vars The number of bindings for the main block.
 * @param tagName The name of the container element, if applicable
 * @param attrsIndex Index of template attributes in the `consts` array.
 * @param trackByFn Reference to the tracking function.
 * @param trackByUsesComponentInstance Whether the tracking function has any references to the
 *  component instance. If it doesn't, we can avoid rebinding it.
 * @param emptyTemplateFn Reference to the template function of the empty block.
 * @param emptyDecls The number of nodes, local refs, and pipes for the empty block.
 * @param emptyVars The number of bindings for the empty block.
 * @param emptyTagName The name of the empty block container element, if applicable
 * @param emptyAttrsIndex Index of the empty block template attributes in the `consts` array.
 *
 * @codeGenApi
 */
function ɵɵrepeaterCreate(index, templateFn, decls, vars, tagName, attrsIndex, trackByFn, trackByUsesComponentInstance, emptyTemplateFn, emptyDecls, emptyVars, emptyTagName, emptyAttrsIndex) {
  performanceMarkFeature('NgControlFlow');
  ngDevMode && assertFunction(trackByFn, `A track expression must be a function, was ${typeof trackByFn} instead.`);
  const hasEmptyBlock = emptyTemplateFn !== undefined;
  const hostLView = getLView();
  const boundTrackBy = trackByUsesComponentInstance ?
  // We only want to bind when necessary, because it produces a
  // new function. For pure functions it's not necessary.
  trackByFn.bind(hostLView[DECLARATION_COMPONENT_VIEW][CONTEXT]) : trackByFn;
  const metadata = new RepeaterMetadata(hasEmptyBlock, boundTrackBy);
  hostLView[HEADER_OFFSET + index] = metadata;
  ɵɵtemplate(index + 1, templateFn, decls, vars, tagName, attrsIndex);
  if (hasEmptyBlock) {
    ngDevMode && assertDefined(emptyDecls, 'Missing number of declarations for the empty repeater block.');
    ngDevMode && assertDefined(emptyVars, 'Missing number of bindings for the empty repeater block.');
    ɵɵtemplate(index + 2, emptyTemplateFn, emptyDecls, emptyVars, emptyTagName, emptyAttrsIndex);
  }
}
class LiveCollectionLContainerImpl extends LiveCollection {
  constructor(lContainer, hostLView, templateTNode) {
    super();
    this.lContainer = lContainer;
    this.hostLView = hostLView;
    this.templateTNode = templateTNode;
    /**
     Property indicating if indexes in the repeater context need to be updated following the live
     collection changes. Index updates are necessary if and only if views are inserted / removed in
     the middle of LContainer. Adds and removals at the end don't require index updates.
    */
    this.needsIndexUpdate = false;
  }
  get length() {
    return this.lContainer.length - CONTAINER_HEADER_OFFSET;
  }
  at(index) {
    return this.getLView(index)[CONTEXT].$implicit;
  }
  attach(index, lView) {
    const dehydratedView = lView[HYDRATION];
    this.needsIndexUpdate ||= index !== this.length;
    addLViewToLContainer(this.lContainer, lView, index, shouldAddViewToDom(this.templateTNode, dehydratedView));
  }
  detach(index) {
    this.needsIndexUpdate ||= index !== this.length - 1;
    return detachExistingView(this.lContainer, index);
  }
  create(index, value) {
    const dehydratedView = findMatchingDehydratedView(this.lContainer, this.templateTNode.tView.ssrId);
    const embeddedLView = createAndRenderEmbeddedLView(this.hostLView, this.templateTNode, new RepeaterContext(this.lContainer, value, index), {
      dehydratedView
    });
    return embeddedLView;
  }
  destroy(lView) {
    destroyLView(lView[TVIEW], lView);
  }
  updateValue(index, value) {
    this.getLView(index)[CONTEXT].$implicit = value;
  }
  reset() {
    this.needsIndexUpdate = false;
  }
  updateIndexes() {
    if (this.needsIndexUpdate) {
      for (let i = 0; i < this.length; i++) {
        this.getLView(i)[CONTEXT].$index = i;
      }
    }
  }
  getLView(index) {
    return getExistingLViewFromLContainer(this.lContainer, index);
  }
}
/**
 * The repeater instruction does update-time diffing of a provided collection (against the
 * collection seen previously) and maps changes in the collection to views structure (by adding,
 * removing or moving views as needed).
 * @param collection - the collection instance to be checked for changes
 * @codeGenApi
 */
function ɵɵrepeater(collection) {
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  const metadataSlotIdx = getSelectedIndex();
  try {
    const hostLView = getLView();
    const hostTView = hostLView[TVIEW];
    const metadata = hostLView[metadataSlotIdx];
    if (metadata.liveCollection === undefined) {
      const containerIndex = metadataSlotIdx + 1;
      const lContainer = getLContainer(hostLView, containerIndex);
      const itemTemplateTNode = getExistingTNode(hostTView, containerIndex);
      metadata.liveCollection = new LiveCollectionLContainerImpl(lContainer, hostLView, itemTemplateTNode);
    } else {
      metadata.liveCollection.reset();
    }
    const liveCollection = metadata.liveCollection;
    reconcile(liveCollection, collection, metadata.trackByFn);
    // moves in the container might caused context's index to get out of order, re-adjust if needed
    liveCollection.updateIndexes();
    // handle empty blocks
    if (metadata.hasEmptyBlock) {
      const bindingIndex = nextBindingIndex();
      const isCollectionEmpty = liveCollection.length === 0;
      if (bindingUpdated(hostLView, bindingIndex, isCollectionEmpty)) {
        const emptyTemplateIndex = metadataSlotIdx + 2;
        const lContainerForEmpty = getLContainer(hostLView, emptyTemplateIndex);
        if (isCollectionEmpty) {
          const emptyTemplateTNode = getExistingTNode(hostTView, emptyTemplateIndex);
          const dehydratedView = findMatchingDehydratedView(lContainerForEmpty, emptyTemplateTNode.tView.ssrId);
          const embeddedLView = createAndRenderEmbeddedLView(hostLView, emptyTemplateTNode, undefined, {
            dehydratedView
          });
          addLViewToLContainer(lContainerForEmpty, embeddedLView, 0, shouldAddViewToDom(emptyTemplateTNode, dehydratedView));
        } else {
          removeLViewFromLContainer(lContainerForEmpty, 0);
        }
      }
    }
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}
function getLContainer(lView, index) {
  const lContainer = lView[index];
  ngDevMode && assertLContainer(lContainer);
  return lContainer;
}
function detachExistingView(lContainer, index) {
  const existingLView = detachView(lContainer, index);
  ngDevMode && assertLView(existingLView);
  return existingLView;
}
function getExistingLViewFromLContainer(lContainer, index) {
  const existingLView = getLViewFromLContainer(lContainer, index);
  ngDevMode && assertLView(existingLView);
  return existingLView;
}
function getExistingTNode(tView, index) {
  const tNode = getTNode(tView, index);
  ngDevMode && assertTNode(tNode);
  return tNode;
}
function elementStartFirstCreatePass(index, tView, lView, name, attrsIndex, localRefsIndex) {
  ngDevMode && assertFirstCreatePass(tView);
  ngDevMode && ngDevMode.firstCreatePass++;
  const tViewConsts = tView.consts;
  const attrs = getConstant(tViewConsts, attrsIndex);
  const tNode = getOrCreateTNode(tView, index, 2 /* TNodeType.Element */, name, attrs);
  resolveDirectives(tView, lView, tNode, getConstant(tViewConsts, localRefsIndex));
  if (tNode.attrs !== null) {
    computeStaticStyling(tNode, tNode.attrs, false);
  }
  if (tNode.mergedAttrs !== null) {
    computeStaticStyling(tNode, tNode.mergedAttrs, true);
  }
  if (tView.queries !== null) {
    tView.queries.elementStart(tView, tNode);
  }
  return tNode;
}
/**
 * Create DOM element. The instruction must later be followed by `elementEnd()` call.
 *
 * @param index Index of the element in the LView array
 * @param name Name of the DOM Node
 * @param attrsIndex Index of the element's attributes in the `consts` array.
 * @param localRefsIndex Index of the element's local references in the `consts` array.
 * @returns This function returns itself so that it may be chained.
 *
 * Attributes and localRefs are passed as an array of strings where elements with an even index
 * hold an attribute name and elements with an odd index hold an attribute value, ex.:
 * ['id', 'warning5', 'class', 'alert']
 *
 * @codeGenApi
 */
function ɵɵelementStart(index, name, attrsIndex, localRefsIndex) {
  const lView = getLView();
  const tView = getTView();
  const adjustedIndex = HEADER_OFFSET + index;
  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'elements should be created before any bindings');
  ngDevMode && assertIndexInRange(lView, adjustedIndex);
  const renderer = lView[RENDERER];
  const tNode = tView.firstCreatePass ? elementStartFirstCreatePass(adjustedIndex, tView, lView, name, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
  const native = _locateOrCreateElementNode(tView, lView, tNode, renderer, name, index);
  lView[adjustedIndex] = native;
  const hasDirectives = isDirectiveHost(tNode);
  if (ngDevMode && tView.firstCreatePass) {
    validateElementIsKnown(native, lView, tNode.value, tView.schemas, hasDirectives);
  }
  setCurrentTNode(tNode, true);
  setupStaticAttributes(renderer, native, tNode);
  if (!isDetachedByI18n(tNode) && wasLastNodeCreated()) {
    // In the i18n case, the translation may have removed this element, so only add it if it is not
    // detached. See `TNodeType.Placeholder` and `LFrame.inI18n` for more context.
    appendChild(tView, lView, native, tNode);
  }
  // any immediate children of a component or template container must be pre-emptively
  // monkey-patched with the component view data so that the element can be inspected
  // later on using any element discovery utility methods (see `element_discovery.ts`)
  if (getElementDepthCount() === 0) {
    attachPatchData(native, lView);
  }
  increaseElementDepthCount();
  if (hasDirectives) {
    createDirectivesInstances(tView, lView, tNode);
    executeContentQueries(tView, tNode, lView);
  }
  if (localRefsIndex !== null) {
    saveResolvedLocalsInData(lView, tNode);
  }
  return ɵɵelementStart;
}
/**
 * Mark the end of the element.
 * @returns This function returns itself so that it may be chained.
 *
 * @codeGenApi
 */
function ɵɵelementEnd() {
  let currentTNode = getCurrentTNode();
  ngDevMode && assertDefined(currentTNode, 'No parent node to close.');
  if (isCurrentTNodeParent()) {
    setCurrentTNodeAsNotParent();
  } else {
    ngDevMode && assertHasParent(getCurrentTNode());
    currentTNode = currentTNode.parent;
    setCurrentTNode(currentTNode, false);
  }
  const tNode = currentTNode;
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */);
  if (isSkipHydrationRootTNode(tNode)) {
    leaveSkipHydrationBlock();
  }
  decreaseElementDepthCount();
  const tView = getTView();
  if (tView.firstCreatePass) {
    registerPostOrderHooks(tView, currentTNode);
    if (isContentQueryHost(currentTNode)) {
      tView.queries.elementEnd(currentTNode);
    }
  }
  if (tNode.classesWithoutHost != null && hasClassInput(tNode)) {
    setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.classesWithoutHost, true);
  }
  if (tNode.stylesWithoutHost != null && hasStyleInput(tNode)) {
    setDirectiveInputsWhichShadowsStyling(tView, tNode, getLView(), tNode.stylesWithoutHost, false);
  }
  return ɵɵelementEnd;
}
/**
 * Creates an empty element using {@link elementStart} and {@link elementEnd}
 *
 * @param index Index of the element in the data array
 * @param name Name of the DOM Node
 * @param attrsIndex Index of the element's attributes in the `consts` array.
 * @param localRefsIndex Index of the element's local references in the `consts` array.
 * @returns This function returns itself so that it may be chained.
 *
 * @codeGenApi
 */
function ɵɵelement(index, name, attrsIndex, localRefsIndex) {
  ɵɵelementStart(index, name, attrsIndex, localRefsIndex);
  ɵɵelementEnd();
  return ɵɵelement;
}
let _locateOrCreateElementNode = (tView, lView, tNode, renderer, name, index) => {
  lastNodeWasCreated(true);
  return createElementNode(renderer, name, getNamespace$1());
};
/**
 * Enables hydration code path (to lookup existing elements in DOM)
 * in addition to the regular creation mode of element nodes.
 */
function locateOrCreateElementNodeImpl(tView, lView, tNode, renderer, name, index) {
  const hydrationInfo = lView[HYDRATION];
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
  lastNodeWasCreated(isNodeCreationMode);
  // Regular creation mode.
  if (isNodeCreationMode) {
    return createElementNode(renderer, name, getNamespace$1());
  }
  // Hydration mode, looking up an existing element in DOM.
  const native = locateNextRNode(hydrationInfo, tView, lView, tNode);
  ngDevMode && validateMatchingNode(native, Node.ELEMENT_NODE, name, lView, tNode);
  ngDevMode && markRNodeAsClaimedByHydration(native);
  // This element might also be an anchor of a view container.
  if (getSerializedContainerViews(hydrationInfo, index)) {
    // Important note: this element acts as an anchor, but it's **not** a part
    // of the embedded view, so we start the segment **after** this element, taking
    // a reference to the next sibling. For example, the following template:
    // `<div #vcrTarget>` is represented in the DOM as `<div></div>...<!--container-->`,
    // so while processing a `<div>` instruction, point to the next sibling as a
    // start of a segment.
    ngDevMode && validateNodeExists(native.nextSibling, lView, tNode);
    setSegmentHead(hydrationInfo, index, native.nextSibling);
  }
  // Checks if the skip hydration attribute is present during hydration so we know to
  // skip attempting to hydrate this block. We check both TNode and RElement for an
  // attribute: the RElement case is needed for i18n cases, when we add it to host
  // elements during the annotation phase (after all internal data structures are setup).
  if (hydrationInfo && (hasSkipHydrationAttrOnTNode(tNode) || hasSkipHydrationAttrOnRElement(native))) {
    if (isComponentHost(tNode)) {
      enterSkipHydrationBlock(tNode);
      // Since this isn't hydratable, we need to empty the node
      // so there's no duplicate content after render
      clearElementContents(native);
      ngDevMode && markRNodeAsSkippedByHydration(native);
    } else if (ngDevMode) {
      // If this is not a component host, throw an error.
      // Hydration can be skipped on per-component basis only.
      throw invalidSkipHydrationHost(native);
    }
  }
  return native;
}
function enableLocateOrCreateElementNodeImpl() {
  _locateOrCreateElementNode = locateOrCreateElementNodeImpl;
}
function elementContainerStartFirstCreatePass(index, tView, lView, attrsIndex, localRefsIndex) {
  ngDevMode && ngDevMode.firstCreatePass++;
  const tViewConsts = tView.consts;
  const attrs = getConstant(tViewConsts, attrsIndex);
  const tNode = getOrCreateTNode(tView, index, 8 /* TNodeType.ElementContainer */, 'ng-container', attrs);
  // While ng-container doesn't necessarily support styling, we use the style context to identify
  // and execute directives on the ng-container.
  if (attrs !== null) {
    computeStaticStyling(tNode, attrs, true);
  }
  const localRefs = getConstant(tViewConsts, localRefsIndex);
  resolveDirectives(tView, lView, tNode, localRefs);
  if (tView.queries !== null) {
    tView.queries.elementStart(tView, tNode);
  }
  return tNode;
}
/**
 * Creates a logical container for other nodes (<ng-container>) backed by a comment node in the DOM.
 * The instruction must later be followed by `elementContainerEnd()` call.
 *
 * @param index Index of the element in the LView array
 * @param attrsIndex Index of the container attributes in the `consts` array.
 * @param localRefsIndex Index of the container's local references in the `consts` array.
 * @returns This function returns itself so that it may be chained.
 *
 * Even if this instruction accepts a set of attributes no actual attribute values are propagated to
 * the DOM (as a comment node can't have attributes). Attributes are here only for directive
 * matching purposes and setting initial inputs of directives.
 *
 * @codeGenApi
 */
function ɵɵelementContainerStart(index, attrsIndex, localRefsIndex) {
  const lView = getLView();
  const tView = getTView();
  const adjustedIndex = index + HEADER_OFFSET;
  ngDevMode && assertIndexInRange(lView, adjustedIndex);
  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'element containers should be created before any bindings');
  const tNode = tView.firstCreatePass ? elementContainerStartFirstCreatePass(adjustedIndex, tView, lView, attrsIndex, localRefsIndex) : tView.data[adjustedIndex];
  setCurrentTNode(tNode, true);
  const comment = _locateOrCreateElementContainerNode(tView, lView, tNode, index);
  lView[adjustedIndex] = comment;
  if (wasLastNodeCreated()) {
    appendChild(tView, lView, comment, tNode);
  }
  attachPatchData(comment, lView);
  if (isDirectiveHost(tNode)) {
    createDirectivesInstances(tView, lView, tNode);
    executeContentQueries(tView, tNode, lView);
  }
  if (localRefsIndex != null) {
    saveResolvedLocalsInData(lView, tNode);
  }
  return ɵɵelementContainerStart;
}
/**
 * Mark the end of the <ng-container>.
 * @returns This function returns itself so that it may be chained.
 *
 * @codeGenApi
 */
function ɵɵelementContainerEnd() {
  let currentTNode = getCurrentTNode();
  const tView = getTView();
  if (isCurrentTNodeParent()) {
    setCurrentTNodeAsNotParent();
  } else {
    ngDevMode && assertHasParent(currentTNode);
    currentTNode = currentTNode.parent;
    setCurrentTNode(currentTNode, false);
  }
  ngDevMode && assertTNodeType(currentTNode, 8 /* TNodeType.ElementContainer */);
  if (tView.firstCreatePass) {
    registerPostOrderHooks(tView, currentTNode);
    if (isContentQueryHost(currentTNode)) {
      tView.queries.elementEnd(currentTNode);
    }
  }
  return ɵɵelementContainerEnd;
}
/**
 * Creates an empty logical container using {@link elementContainerStart}
 * and {@link elementContainerEnd}
 *
 * @param index Index of the element in the LView array
 * @param attrsIndex Index of the container attributes in the `consts` array.
 * @param localRefsIndex Index of the container's local references in the `consts` array.
 * @returns This function returns itself so that it may be chained.
 *
 * @codeGenApi
 */
function ɵɵelementContainer(index, attrsIndex, localRefsIndex) {
  ɵɵelementContainerStart(index, attrsIndex, localRefsIndex);
  ɵɵelementContainerEnd();
  return ɵɵelementContainer;
}
let _locateOrCreateElementContainerNode = (tView, lView, tNode, index) => {
  lastNodeWasCreated(true);
  return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
};
/**
 * Enables hydration code path (to lookup existing elements in DOM)
 * in addition to the regular creation mode of comment nodes that
 * represent <ng-container>'s anchor.
 */
function locateOrCreateElementContainerNode(tView, lView, tNode, index) {
  let comment;
  const hydrationInfo = lView[HYDRATION];
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode);
  lastNodeWasCreated(isNodeCreationMode);
  // Regular creation mode.
  if (isNodeCreationMode) {
    return createCommentNode(lView[RENDERER], ngDevMode ? 'ng-container' : '');
  }
  // Hydration mode, looking up existing elements in DOM.
  const currentRNode = locateNextRNode(hydrationInfo, tView, lView, tNode);
  ngDevMode && validateNodeExists(currentRNode, lView, tNode);
  const ngContainerSize = getNgContainerSize(hydrationInfo, index);
  ngDevMode && assertNumber(ngContainerSize, 'Unexpected state: hydrating an <ng-container>, ' + 'but no hydration info is available.');
  setSegmentHead(hydrationInfo, index, currentRNode);
  comment = siblingAfter(ngContainerSize, currentRNode);
  if (ngDevMode) {
    validateMatchingNode(comment, Node.COMMENT_NODE, null, lView, tNode);
    markRNodeAsClaimedByHydration(comment);
  }
  return comment;
}
function enableLocateOrCreateElementContainerNodeImpl() {
  _locateOrCreateElementContainerNode = locateOrCreateElementContainerNode;
}

/**
 * Returns the current OpaqueViewState instance.
 *
 * Used in conjunction with the restoreView() instruction to save a snapshot
 * of the current view and restore it when listeners are invoked. This allows
 * walking the declaration view tree in listeners to get vars from parent views.
 *
 * @codeGenApi
 */
function ɵɵgetCurrentView() {
  return getLView();
}

/**
 * Update a property on a host element. Only applies to native node properties, not inputs.
 *
 * Operates on the element selected by index via the {@link select} instruction.
 *
 * @param propName Name of property. Because it is going to DOM, this is not subject to
 *        renaming as part of minification.
 * @param value New value to write.
 * @param sanitizer An optional function used to sanitize the value.
 * @returns This function returns itself so that it may be chained
 * (e.g. `property('name', ctx.name)('title', ctx.title)`)
 *
 * @codeGenApi
 */
function ɵɵhostProperty(propName, value, sanitizer) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, value)) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, true);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
  }
  return ɵɵhostProperty;
}
/**
 * Updates a synthetic host binding (e.g. `[@foo]`) on a component or directive.
 *
 * This instruction is for compatibility purposes and is designed to ensure that a
 * synthetic host binding (e.g. `@HostBinding('@foo')`) properly gets rendered in
 * the component's renderer. Normally all host bindings are evaluated with the parent
 * component's renderer, but, in the case of animation @triggers, they need to be
 * evaluated with the sub component's renderer (because that's where the animation
 * triggers are defined).
 *
 * Do not use this instruction as a replacement for `elementProperty`. This instruction
 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
 *
 * @param index The index of the element to update in the data array
 * @param propName Name of property. Because it is going to DOM, this is not subject to
 *        renaming as part of minification.
 * @param value New value to write.
 * @param sanitizer An optional function used to sanitize the value.
 *
 * @codeGenApi
 */
function ɵɵsyntheticHostProperty(propName, value, sanitizer) {
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, value)) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    const currentDef = getCurrentDirectiveDef(tView.data);
    const renderer = loadComponentRenderer(currentDef, tNode, lView);
    elementPropertyInternal(tView, tNode, lView, propName, value, renderer, sanitizer, true);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
  }
  return ɵɵsyntheticHostProperty;
}

/**
 * NOTE: changes to the `ngI18nClosureMode` name must be synced with `compiler-cli/src/tooling.ts`.
 */
if (typeof ngI18nClosureMode === 'undefined') {
  // These property accesses can be ignored because ngI18nClosureMode will be set to false
  // when optimizing code and the whole if statement will be dropped.
  // Make sure to refer to ngI18nClosureMode as ['ngI18nClosureMode'] for closure.
  // NOTE: we need to have it in IIFE so that the tree-shaker is happy.
  (function () {
    // tslint:disable-next-line:no-toplevel-property-access
    _global['ngI18nClosureMode'] =
    // TODO(FW-1250): validate that this actually, you know, works.
    // tslint:disable-next-line:no-toplevel-property-access
    typeof goog !== 'undefined' && typeof goog.getMsg === 'function';
  })();
}

// THIS CODE IS GENERATED - DO NOT MODIFY.
const u = undefined;
function plural(val) {
  const n = val,
    i = Math.floor(Math.abs(val)),
    v = val.toString().replace(/^[^.]*\.?/, '').length;
  if (i === 1 && v === 0) return 1;
  return 5;
}
var localeEn = ["en", [["a", "p"], ["AM", "PM"], u], [["AM", "PM"], u, u], [["S", "M", "T", "W", "T", "F", "S"], ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]], u, [["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"], ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]], u, [["B", "A"], ["BC", "AD"], ["Before Christ", "Anno Domini"]], 0, [6, 0], ["M/d/yy", "MMM d, y", "MMMM d, y", "EEEE, MMMM d, y"], ["h:mm a", "h:mm:ss a", "h:mm:ss a z", "h:mm:ss a zzzz"], ["{1}, {0}", u, "{1} 'at' {0}", u], [".", ",", ";", "%", "+", "-", "E", "×", "‰", "∞", "NaN", ":"], ["#,##0.###", "#,##0%", "¤#,##0.00", "#E0"], "USD", "$", "US Dollar", {}, "ltr", plural];

/**
 * This const is used to store the locale data registered with `registerLocaleData`
 */
let LOCALE_DATA = {};
/**
 * Register locale data to be used internally by Angular. See the
 * ["I18n guide"](guide/i18n-common-format-data-locale) to know how to import additional locale
 * data.
 *
 * The signature `registerLocaleData(data: any, extraData?: any)` is deprecated since v5.1
 */
function registerLocaleData(data, localeId, extraData) {
  if (typeof localeId !== 'string') {
    extraData = localeId;
    localeId = data[LocaleDataIndex.LocaleId];
  }
  localeId = localeId.toLowerCase().replace(/_/g, '-');
  LOCALE_DATA[localeId] = data;
  if (extraData) {
    LOCALE_DATA[localeId][LocaleDataIndex.ExtraData] = extraData;
  }
}
/**
 * Finds the locale data for a given locale.
 *
 * @param locale The locale code.
 * @returns The locale data.
 * @see [Internationalization (i18n) Guide](https://angular.io/guide/i18n-overview)
 */
function findLocaleData(locale) {
  const normalizedLocale = normalizeLocale(locale);
  let match = getLocaleData(normalizedLocale);
  if (match) {
    return match;
  }
  // let's try to find a parent locale
  const parentLocale = normalizedLocale.split('-')[0];
  match = getLocaleData(parentLocale);
  if (match) {
    return match;
  }
  if (parentLocale === 'en') {
    return localeEn;
  }
  throw new RuntimeError(701 /* RuntimeErrorCode.MISSING_LOCALE_DATA */, ngDevMode && `Missing locale data for the locale "${locale}".`);
}
/**
 * Retrieves the default currency code for the given locale.
 *
 * The default is defined as the first currency which is still in use.
 *
 * @param locale The code of the locale whose currency code we want.
 * @returns The code of the default currency for the given locale.
 *
 */
function getLocaleCurrencyCode(locale) {
  const data = findLocaleData(locale);
  return data[LocaleDataIndex.CurrencyCode] || null;
}
/**
 * Retrieves the plural function used by ICU expressions to determine the plural case to use
 * for a given locale.
 * @param locale A locale code for the locale format rules to use.
 * @returns The plural function for the locale.
 * @see {@link NgPlural}
 * @see [Internationalization (i18n) Guide](/guide/i18n-overview)
 */
function getLocalePluralCase(locale) {
  const data = findLocaleData(locale);
  return data[LocaleDataIndex.PluralCase];
}
/**
 * Helper function to get the given `normalizedLocale` from `LOCALE_DATA`
 * or from the global `ng.common.locale`.
 */
function getLocaleData(normalizedLocale) {
  if (!(normalizedLocale in LOCALE_DATA)) {
    LOCALE_DATA[normalizedLocale] = _global.ng && _global.ng.common && _global.ng.common.locales && _global.ng.common.locales[normalizedLocale];
  }
  return LOCALE_DATA[normalizedLocale];
}
/**
 * Helper function to remove all the locale data from `LOCALE_DATA`.
 */
function unregisterAllLocaleData() {
  LOCALE_DATA = {};
}
/**
 * Index of each type of locale data from the locale data array
 */
var LocaleDataIndex;
(function (LocaleDataIndex) {
  LocaleDataIndex[LocaleDataIndex["LocaleId"] = 0] = "LocaleId";
  LocaleDataIndex[LocaleDataIndex["DayPeriodsFormat"] = 1] = "DayPeriodsFormat";
  LocaleDataIndex[LocaleDataIndex["DayPeriodsStandalone"] = 2] = "DayPeriodsStandalone";
  LocaleDataIndex[LocaleDataIndex["DaysFormat"] = 3] = "DaysFormat";
  LocaleDataIndex[LocaleDataIndex["DaysStandalone"] = 4] = "DaysStandalone";
  LocaleDataIndex[LocaleDataIndex["MonthsFormat"] = 5] = "MonthsFormat";
  LocaleDataIndex[LocaleDataIndex["MonthsStandalone"] = 6] = "MonthsStandalone";
  LocaleDataIndex[LocaleDataIndex["Eras"] = 7] = "Eras";
  LocaleDataIndex[LocaleDataIndex["FirstDayOfWeek"] = 8] = "FirstDayOfWeek";
  LocaleDataIndex[LocaleDataIndex["WeekendRange"] = 9] = "WeekendRange";
  LocaleDataIndex[LocaleDataIndex["DateFormat"] = 10] = "DateFormat";
  LocaleDataIndex[LocaleDataIndex["TimeFormat"] = 11] = "TimeFormat";
  LocaleDataIndex[LocaleDataIndex["DateTimeFormat"] = 12] = "DateTimeFormat";
  LocaleDataIndex[LocaleDataIndex["NumberSymbols"] = 13] = "NumberSymbols";
  LocaleDataIndex[LocaleDataIndex["NumberFormats"] = 14] = "NumberFormats";
  LocaleDataIndex[LocaleDataIndex["CurrencyCode"] = 15] = "CurrencyCode";
  LocaleDataIndex[LocaleDataIndex["CurrencySymbol"] = 16] = "CurrencySymbol";
  LocaleDataIndex[LocaleDataIndex["CurrencyName"] = 17] = "CurrencyName";
  LocaleDataIndex[LocaleDataIndex["Currencies"] = 18] = "Currencies";
  LocaleDataIndex[LocaleDataIndex["Directionality"] = 19] = "Directionality";
  LocaleDataIndex[LocaleDataIndex["PluralCase"] = 20] = "PluralCase";
  LocaleDataIndex[LocaleDataIndex["ExtraData"] = 21] = "ExtraData";
})(LocaleDataIndex || (LocaleDataIndex = {}));
/**
 * Returns the canonical form of a locale name - lowercase with `_` replaced with `-`.
 */
function normalizeLocale(locale) {
  return locale.toLowerCase().replace(/_/g, '-');
}
const pluralMapping = ['zero', 'one', 'two', 'few', 'many'];
/**
 * Returns the plural case based on the locale
 */
function getPluralCase(value, locale) {
  const plural = getLocalePluralCase(locale)(parseInt(value, 10));
  const result = pluralMapping[plural];
  return result !== undefined ? result : 'other';
}
/**
 * The locale id that the application is using by default (for translations and ICU expressions).
 */
const DEFAULT_LOCALE_ID = 'en-US';
/**
 * USD currency code that the application uses by default for CurrencyPipe when no
 * DEFAULT_CURRENCY_CODE is provided.
 */
const USD_CURRENCY_CODE = 'USD';

/**
 * Marks that the next string is an element name.
 *
 * See `I18nMutateOpCodes` documentation.
 */
const ELEMENT_MARKER = {
  marker: 'element'
};
/**
 * Marks that the next string is comment text need for ICU.
 *
 * See `I18nMutateOpCodes` documentation.
 */
const ICU_MARKER = {
  marker: 'ICU'
};
/**
 * See `I18nCreateOpCodes`
 */
var I18nCreateOpCode;
(function (I18nCreateOpCode) {
  /**
   * Number of bits to shift index so that it can be combined with the `APPEND_EAGERLY` and
   * `COMMENT`.
   */
  I18nCreateOpCode[I18nCreateOpCode["SHIFT"] = 2] = "SHIFT";
  /**
   * Should the node be appended to parent immediately after creation.
   */
  I18nCreateOpCode[I18nCreateOpCode["APPEND_EAGERLY"] = 1] = "APPEND_EAGERLY";
  /**
   * If set the node should be comment (rather than a text) node.
   */
  I18nCreateOpCode[I18nCreateOpCode["COMMENT"] = 2] = "COMMENT";
})(I18nCreateOpCode || (I18nCreateOpCode = {}));

/**
 * The locale id that the application is currently using (for translations and ICU expressions).
 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
 * but is now defined as a global value.
 */
let LOCALE_ID$1 = DEFAULT_LOCALE_ID;
/**
 * Sets the locale id that will be used for translations and ICU expressions.
 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
 * but is now defined as a global value.
 *
 * @param localeId
 */
function setLocaleId(localeId) {
  ngDevMode && assertDefined(localeId, `Expected localeId to be defined`);
  if (typeof localeId === 'string') {
    LOCALE_ID$1 = localeId.toLowerCase().replace(/_/g, '-');
  }
}
/**
 * Gets the locale id that will be used for translations and ICU expressions.
 * This is the ivy version of `LOCALE_ID` that was defined as an injection token for the view engine
 * but is now defined as a global value.
 */
function getLocaleId() {
  return LOCALE_ID$1;
}

/**
 * Find a node in front of which `currentTNode` should be inserted (takes i18n into account).
 *
 * This method determines the `RNode` in front of which we should insert the `currentRNode`. This
 * takes `TNode.insertBeforeIndex` into account.
 *
 * @param parentTNode parent `TNode`
 * @param currentTNode current `TNode` (The node which we would like to insert into the DOM)
 * @param lView current `LView`
 */
function getInsertInFrontOfRNodeWithI18n(parentTNode, currentTNode, lView) {
  const tNodeInsertBeforeIndex = currentTNode.insertBeforeIndex;
  const insertBeforeIndex = Array.isArray(tNodeInsertBeforeIndex) ? tNodeInsertBeforeIndex[0] : tNodeInsertBeforeIndex;
  if (insertBeforeIndex === null) {
    return getInsertInFrontOfRNodeWithNoI18n(parentTNode, currentTNode, lView);
  } else {
    ngDevMode && assertIndexInRange(lView, insertBeforeIndex);
    return unwrapRNode(lView[insertBeforeIndex]);
  }
}
/**
 * Process `TNode.insertBeforeIndex` by adding i18n text nodes.
 *
 * See `TNode.insertBeforeIndex`
 */
function processI18nInsertBefore(renderer, childTNode, lView, childRNode, parentRElement) {
  const tNodeInsertBeforeIndex = childTNode.insertBeforeIndex;
  if (Array.isArray(tNodeInsertBeforeIndex)) {
    // An array indicates that there are i18n nodes that need to be added as children of this
    // `childRNode`. These i18n nodes were created before this `childRNode` was available and so
    // only now can be added. The first element of the array is the normal index where we should
    // insert the `childRNode`. Additional elements are the extra nodes to be added as children of
    // `childRNode`.
    ngDevMode && assertDomNode(childRNode);
    let i18nParent = childRNode;
    let anchorRNode = null;
    if (!(childTNode.type & 3 /* TNodeType.AnyRNode */)) {
      anchorRNode = i18nParent;
      i18nParent = parentRElement;
    }
    if (i18nParent !== null && childTNode.componentOffset === -1) {
      for (let i = 1; i < tNodeInsertBeforeIndex.length; i++) {
        // No need to `unwrapRNode` because all of the indexes point to i18n text nodes.
        // see `assertDomNode` below.
        const i18nChild = lView[tNodeInsertBeforeIndex[i]];
        nativeInsertBefore(renderer, i18nParent, i18nChild, anchorRNode, false);
      }
    }
  }
}

/**
 * Add `tNode` to `previousTNodes` list and update relevant `TNode`s in `previousTNodes` list
 * `tNode.insertBeforeIndex`.
 *
 * Things to keep in mind:
 * 1. All i18n text nodes are encoded as `TNodeType.Element` and are created eagerly by the
 *    `ɵɵi18nStart` instruction.
 * 2. All `TNodeType.Placeholder` `TNodes` are elements which will be created later by
 *    `ɵɵelementStart` instruction.
 * 3. `ɵɵelementStart` instruction will create `TNode`s in the ascending `TNode.index` order. (So a
 *    smaller index `TNode` is guaranteed to be created before a larger one)
 *
 * We use the above three invariants to determine `TNode.insertBeforeIndex`.
 *
 * In an ideal world `TNode.insertBeforeIndex` would always be `TNode.next.index`. However,
 * this will not work because `TNode.next.index` may be larger than `TNode.index` which means that
 * the next node is not yet created and therefore we can't insert in front of it.
 *
 * Rule1: `TNode.insertBeforeIndex = null` if `TNode.next === null` (Initial condition, as we don't
 *        know if there will be further `TNode`s inserted after.)
 * Rule2: If `previousTNode` is created after the `tNode` being inserted, then
 *        `previousTNode.insertBeforeNode = tNode.index` (So when a new `tNode` is added we check
 *        previous to see if we can update its `insertBeforeTNode`)
 *
 * See `TNode.insertBeforeIndex` for more context.
 *
 * @param previousTNodes A list of previous TNodes so that we can easily traverse `TNode`s in
 *     reverse order. (If `TNode` would have `previous` this would not be necessary.)
 * @param newTNode A TNode to add to the `previousTNodes` list.
 */
function addTNodeAndUpdateInsertBeforeIndex(previousTNodes, newTNode) {
  // Start with Rule1
  ngDevMode && assertEqual(newTNode.insertBeforeIndex, null, 'We expect that insertBeforeIndex is not set');
  previousTNodes.push(newTNode);
  if (previousTNodes.length > 1) {
    for (let i = previousTNodes.length - 2; i >= 0; i--) {
      const existingTNode = previousTNodes[i];
      // Text nodes are created eagerly and so they don't need their `indexBeforeIndex` updated.
      // It is safe to ignore them.
      if (!isI18nText(existingTNode)) {
        if (isNewTNodeCreatedBefore(existingTNode, newTNode) && getInsertBeforeIndex(existingTNode) === null) {
          // If it was created before us in time, (and it does not yet have `insertBeforeIndex`)
          // then add the `insertBeforeIndex`.
          setInsertBeforeIndex(existingTNode, newTNode.index);
        }
      }
    }
  }
}
function isI18nText(tNode) {
  return !(tNode.type & 64 /* TNodeType.Placeholder */);
}
function isNewTNodeCreatedBefore(existingTNode, newTNode) {
  return isI18nText(newTNode) || existingTNode.index > newTNode.index;
}
function getInsertBeforeIndex(tNode) {
  const index = tNode.insertBeforeIndex;
  return Array.isArray(index) ? index[0] : index;
}
function setInsertBeforeIndex(tNode, value) {
  const index = tNode.insertBeforeIndex;
  if (Array.isArray(index)) {
    // Array is stored if we have to insert child nodes. See `TNode.insertBeforeIndex`
    index[0] = value;
  } else {
    setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore);
    tNode.insertBeforeIndex = value;
  }
}

/**
 * Retrieve `TIcu` at a given `index`.
 *
 * The `TIcu` can be stored either directly (if it is nested ICU) OR
 * it is stored inside tho `TIcuContainer` if it is top level ICU.
 *
 * The reason for this is that the top level ICU need a `TNode` so that they are part of the render
 * tree, but nested ICU's have no TNode, because we don't know ahead of time if the nested ICU is
 * expressed (parent ICU may have selected a case which does not contain it.)
 *
 * @param tView Current `TView`.
 * @param index Index where the value should be read from.
 */
function getTIcu(tView, index) {
  const value = tView.data[index];
  if (value === null || typeof value === 'string') return null;
  if (ngDevMode && !(value.hasOwnProperty('tView') || value.hasOwnProperty('currentCaseLViewIndex'))) {
    throwError('We expect to get \'null\'|\'TIcu\'|\'TIcuContainer\', but got: ' + value);
  }
  // Here the `value.hasOwnProperty('currentCaseLViewIndex')` is a polymorphic read as it can be
  // either TIcu or TIcuContainerNode. This is not ideal, but we still think it is OK because it
  // will be just two cases which fits into the browser inline cache (inline cache can take up to
  // 4)
  const tIcu = value.hasOwnProperty('currentCaseLViewIndex') ? value : value.value;
  ngDevMode && assertTIcu(tIcu);
  return tIcu;
}
/**
 * Store `TIcu` at a give `index`.
 *
 * The `TIcu` can be stored either directly (if it is nested ICU) OR
 * it is stored inside tho `TIcuContainer` if it is top level ICU.
 *
 * The reason for this is that the top level ICU need a `TNode` so that they are part of the render
 * tree, but nested ICU's have no TNode, because we don't know ahead of time if the nested ICU is
 * expressed (parent ICU may have selected a case which does not contain it.)
 *
 * @param tView Current `TView`.
 * @param index Index where the value should be stored at in `Tview.data`
 * @param tIcu The TIcu to store.
 */
function setTIcu(tView, index, tIcu) {
  const tNode = tView.data[index];
  ngDevMode && assertEqual(tNode === null || tNode.hasOwnProperty('tView'), true, 'We expect to get \'null\'|\'TIcuContainer\'');
  if (tNode === null) {
    tView.data[index] = tIcu;
  } else {
    ngDevMode && assertTNodeType(tNode, 32 /* TNodeType.Icu */);
    tNode.value = tIcu;
  }
}
/**
 * Set `TNode.insertBeforeIndex` taking the `Array` into account.
 *
 * See `TNode.insertBeforeIndex`
 */
function setTNodeInsertBeforeIndex(tNode, index) {
  ngDevMode && assertTNode(tNode);
  let insertBeforeIndex = tNode.insertBeforeIndex;
  if (insertBeforeIndex === null) {
    setI18nHandling(getInsertInFrontOfRNodeWithI18n, processI18nInsertBefore);
    insertBeforeIndex = tNode.insertBeforeIndex = [null /* may be updated to number later */, index];
  } else {
    assertEqual(Array.isArray(insertBeforeIndex), true, 'Expecting array here');
    insertBeforeIndex.push(index);
  }
}
/**
 * Create `TNode.type=TNodeType.Placeholder` node.
 *
 * See `TNodeType.Placeholder` for more information.
 */
function createTNodePlaceholder(tView, previousTNodes, index) {
  const tNode = createTNodeAtIndex(tView, index, 64 /* TNodeType.Placeholder */, null, null);
  addTNodeAndUpdateInsertBeforeIndex(previousTNodes, tNode);
  return tNode;
}
/**
 * Returns current ICU case.
 *
 * ICU cases are stored as index into the `TIcu.cases`.
 * At times it is necessary to communicate that the ICU case just switched and that next ICU update
 * should update all bindings regardless of the mask. In such a case the we store negative numbers
 * for cases which have just been switched. This function removes the negative flag.
 */
function getCurrentICUCaseIndex(tIcu, lView) {
  const currentCase = lView[tIcu.currentCaseLViewIndex];
  return currentCase === null ? currentCase : currentCase < 0 ? ~currentCase : currentCase;
}
function getParentFromIcuCreateOpCode(mergedCode) {
  return mergedCode >>> 17 /* IcuCreateOpCode.SHIFT_PARENT */;
}
function getRefFromIcuCreateOpCode(mergedCode) {
  return (mergedCode & 131070 /* IcuCreateOpCode.MASK_REF */) >>> 1 /* IcuCreateOpCode.SHIFT_REF */;
}
function getInstructionFromIcuCreateOpCode(mergedCode) {
  return mergedCode & 1 /* IcuCreateOpCode.MASK_INSTRUCTION */;
}
function icuCreateOpCode(opCode, parentIdx, refIdx) {
  ngDevMode && assertGreaterThanOrEqual(parentIdx, 0, 'Missing parent index');
  ngDevMode && assertGreaterThan(refIdx, 0, 'Missing ref index');
  return opCode | parentIdx << 17 /* IcuCreateOpCode.SHIFT_PARENT */ | refIdx << 1 /* IcuCreateOpCode.SHIFT_REF */;
}

/**
 * Keep track of which input bindings in `ɵɵi18nExp` have changed.
 *
 * This is used to efficiently update expressions in i18n only when the corresponding input has
 * changed.
 *
 * 1) Each bit represents which of the `ɵɵi18nExp` has changed.
 * 2) There are 32 bits allowed in JS.
 * 3) Bit 32 is special as it is shared for all changes past 32. (In other words if you have more
 * than 32 `ɵɵi18nExp` then all changes past 32nd `ɵɵi18nExp` will be mapped to same bit. This means
 * that we may end up changing more than we need to. But i18n expressions with 32 bindings is rare
 * so in practice it should not be an issue.)
 */
let changeMask = 0b0;
/**
 * Keeps track of which bit needs to be updated in `changeMask`
 *
 * This value gets incremented on every call to `ɵɵi18nExp`
 */
let changeMaskCounter = 0;
/**
 * Keep track of which input bindings in `ɵɵi18nExp` have changed.
 *
 * `setMaskBit` gets invoked by each call to `ɵɵi18nExp`.
 *
 * @param hasChange did `ɵɵi18nExp` detect a change.
 */
function setMaskBit(hasChange) {
  if (hasChange) {
    changeMask = changeMask | 1 << Math.min(changeMaskCounter, 31);
  }
  changeMaskCounter++;
}
function applyI18n(tView, lView, index) {
  if (changeMaskCounter > 0) {
    ngDevMode && assertDefined(tView, `tView should be defined`);
    const tI18n = tView.data[index];
    // When `index` points to an `ɵɵi18nAttributes` then we have an array otherwise `TI18n`
    const updateOpCodes = Array.isArray(tI18n) ? tI18n : tI18n.update;
    const bindingsStartIndex = getBindingIndex() - changeMaskCounter - 1;
    applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, changeMask);
  }
  // Reset changeMask & maskBit to default for the next update cycle
  changeMask = 0b0;
  changeMaskCounter = 0;
}
function createNodeWithoutHydration(lView, textOrName, nodeType) {
  const renderer = lView[RENDERER];
  switch (nodeType) {
    case Node.COMMENT_NODE:
      return createCommentNode(renderer, textOrName);
    case Node.TEXT_NODE:
      return createTextNode(renderer, textOrName);
    case Node.ELEMENT_NODE:
      return createElementNode(renderer, textOrName, null);
  }
}
let _locateOrCreateNode = (lView, index, textOrName, nodeType) => {
  lastNodeWasCreated(true);
  return createNodeWithoutHydration(lView, textOrName, nodeType);
};
function locateOrCreateNodeImpl(lView, index, textOrName, nodeType) {
  // TODO: Add support for hydration
  lastNodeWasCreated(true);
  return createNodeWithoutHydration(lView, textOrName, nodeType);
}
function enableLocateOrCreateI18nNodeImpl() {
  _locateOrCreateNode = locateOrCreateNodeImpl;
}
/**
 * Apply `I18nCreateOpCodes` op-codes as stored in `TI18n.create`.
 *
 * Creates text (and comment) nodes which are internationalized.
 *
 * @param lView Current lView
 * @param createOpCodes Set of op-codes to apply
 * @param parentRNode Parent node (so that direct children can be added eagerly) or `null` if it is
 *     a root node.
 * @param insertInFrontOf DOM node that should be used as an anchor.
 */
function applyCreateOpCodes(lView, createOpCodes, parentRNode, insertInFrontOf) {
  const renderer = lView[RENDERER];
  for (let i = 0; i < createOpCodes.length; i++) {
    const opCode = createOpCodes[i++];
    const text = createOpCodes[i];
    const isComment = (opCode & I18nCreateOpCode.COMMENT) === I18nCreateOpCode.COMMENT;
    const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
    const index = opCode >>> I18nCreateOpCode.SHIFT;
    let rNode = lView[index];
    let lastNodeWasCreated = false;
    if (rNode === null) {
      // We only create new DOM nodes if they don't already exist: If ICU switches case back to a
      // case which was already instantiated, no need to create new DOM nodes.
      rNode = lView[index] = _locateOrCreateNode(lView, index, text, isComment ? Node.COMMENT_NODE : Node.TEXT_NODE);
      lastNodeWasCreated = wasLastNodeCreated();
    }
    if (appendNow && parentRNode !== null && lastNodeWasCreated) {
      nativeInsertBefore(renderer, parentRNode, rNode, insertInFrontOf, false);
    }
  }
}
/**
 * Apply `I18nMutateOpCodes` OpCodes.
 *
 * @param tView Current `TView`
 * @param mutableOpCodes Mutable OpCodes to process
 * @param lView Current `LView`
 * @param anchorRNode place where the i18n node should be inserted.
 */
function applyMutableOpCodes(tView, mutableOpCodes, lView, anchorRNode) {
  ngDevMode && assertDomNode(anchorRNode);
  const renderer = lView[RENDERER];
  // `rootIdx` represents the node into which all inserts happen.
  let rootIdx = null;
  // `rootRNode` represents the real node into which we insert. This can be different from
  // `lView[rootIdx]` if we have projection.
  //  - null we don't have a parent (as can be the case in when we are inserting into a root of
  //    LView which has no parent.)
  //  - `RElement` The element representing the root after taking projection into account.
  let rootRNode;
  for (let i = 0; i < mutableOpCodes.length; i++) {
    const opCode = mutableOpCodes[i];
    if (typeof opCode == 'string') {
      const textNodeIndex = mutableOpCodes[++i];
      if (lView[textNodeIndex] === null) {
        ngDevMode && ngDevMode.rendererCreateTextNode++;
        ngDevMode && assertIndexInRange(lView, textNodeIndex);
        lView[textNodeIndex] = _locateOrCreateNode(lView, textNodeIndex, opCode, Node.TEXT_NODE);
      }
    } else if (typeof opCode == 'number') {
      switch (opCode & 1 /* IcuCreateOpCode.MASK_INSTRUCTION */) {
        case 0 /* IcuCreateOpCode.AppendChild */:
          const parentIdx = getParentFromIcuCreateOpCode(opCode);
          if (rootIdx === null) {
            // The first operation should save the `rootIdx` because the first operation
            // must insert into the root. (Only subsequent operations can insert into a dynamic
            // parent)
            rootIdx = parentIdx;
            rootRNode = nativeParentNode(renderer, anchorRNode);
          }
          let insertInFrontOf;
          let parentRNode;
          if (parentIdx === rootIdx) {
            insertInFrontOf = anchorRNode;
            parentRNode = rootRNode;
          } else {
            insertInFrontOf = null;
            parentRNode = unwrapRNode(lView[parentIdx]);
          }
          // FIXME(misko): Refactor with `processI18nText`
          if (parentRNode !== null) {
            // This can happen if the `LView` we are adding to is not attached to a parent `LView`.
            // In such a case there is no "root" we can attach to. This is fine, as we still need to
            // create the elements. When the `LView` gets later added to a parent these "root" nodes
            // get picked up and added.
            ngDevMode && assertDomNode(parentRNode);
            const refIdx = getRefFromIcuCreateOpCode(opCode);
            ngDevMode && assertGreaterThan(refIdx, HEADER_OFFSET, 'Missing ref');
            // `unwrapRNode` is not needed here as all of these point to RNodes as part of the i18n
            // which can't have components.
            const child = lView[refIdx];
            ngDevMode && assertDomNode(child);
            nativeInsertBefore(renderer, parentRNode, child, insertInFrontOf, false);
            const tIcu = getTIcu(tView, refIdx);
            if (tIcu !== null && typeof tIcu === 'object') {
              // If we just added a comment node which has ICU then that ICU may have already been
              // rendered and therefore we need to re-add it here.
              ngDevMode && assertTIcu(tIcu);
              const caseIndex = getCurrentICUCaseIndex(tIcu, lView);
              if (caseIndex !== null) {
                applyMutableOpCodes(tView, tIcu.create[caseIndex], lView, lView[tIcu.anchorIdx]);
              }
            }
          }
          break;
        case 1 /* IcuCreateOpCode.Attr */:
          const elementNodeIndex = opCode >>> 1 /* IcuCreateOpCode.SHIFT_REF */;
          const attrName = mutableOpCodes[++i];
          const attrValue = mutableOpCodes[++i];
          // This code is used for ICU expressions only, since we don't support
          // directives/components in ICUs, we don't need to worry about inputs here
          setElementAttribute(renderer, getNativeByIndex(elementNodeIndex, lView), null, null, attrName, attrValue, null);
          break;
        default:
          if (ngDevMode) {
            throw new RuntimeError(700 /* RuntimeErrorCode.INVALID_I18N_STRUCTURE */, `Unable to determine the type of mutate operation for "${opCode}"`);
          }
      }
    } else {
      switch (opCode) {
        case ICU_MARKER:
          const commentValue = mutableOpCodes[++i];
          const commentNodeIndex = mutableOpCodes[++i];
          if (lView[commentNodeIndex] === null) {
            ngDevMode && assertEqual(typeof commentValue, 'string', `Expected "${commentValue}" to be a comment node value`);
            ngDevMode && ngDevMode.rendererCreateComment++;
            ngDevMode && assertIndexInExpandoRange(lView, commentNodeIndex);
            const commentRNode = lView[commentNodeIndex] = _locateOrCreateNode(lView, commentNodeIndex, commentValue, Node.COMMENT_NODE);
            // FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
            attachPatchData(commentRNode, lView);
          }
          break;
        case ELEMENT_MARKER:
          const tagName = mutableOpCodes[++i];
          const elementNodeIndex = mutableOpCodes[++i];
          if (lView[elementNodeIndex] === null) {
            ngDevMode && assertEqual(typeof tagName, 'string', `Expected "${tagName}" to be an element node tag name`);
            ngDevMode && ngDevMode.rendererCreateElement++;
            ngDevMode && assertIndexInExpandoRange(lView, elementNodeIndex);
            const elementRNode = lView[elementNodeIndex] = _locateOrCreateNode(lView, elementNodeIndex, tagName, Node.ELEMENT_NODE);
            // FIXME(misko): Attaching patch data is only needed for the root (Also add tests)
            attachPatchData(elementRNode, lView);
          }
          break;
        default:
          ngDevMode && throwError(`Unable to determine the type of mutate operation for "${opCode}"`);
      }
    }
  }
}
/**
 * Apply `I18nUpdateOpCodes` OpCodes
 *
 * @param tView Current `TView`
 * @param lView Current `LView`
 * @param updateOpCodes OpCodes to process
 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
 * @param changeMask Each bit corresponds to a `ɵɵi18nExp` (Counting backwards from
 *     `bindingsStartIndex`)
 */
function applyUpdateOpCodes(tView, lView, updateOpCodes, bindingsStartIndex, changeMask) {
  for (let i = 0; i < updateOpCodes.length; i++) {
    // bit code to check if we should apply the next update
    const checkBit = updateOpCodes[i];
    // Number of opCodes to skip until next set of update codes
    const skipCodes = updateOpCodes[++i];
    if (checkBit & changeMask) {
      // The value has been updated since last checked
      let value = '';
      for (let j = i + 1; j <= i + skipCodes; j++) {
        const opCode = updateOpCodes[j];
        if (typeof opCode == 'string') {
          value += opCode;
        } else if (typeof opCode == 'number') {
          if (opCode < 0) {
            // Negative opCode represent `i18nExp` values offset.
            value += renderStringify(lView[bindingsStartIndex - opCode]);
          } else {
            const nodeIndex = opCode >>> 2 /* I18nUpdateOpCode.SHIFT_REF */;
            switch (opCode & 3 /* I18nUpdateOpCode.MASK_OPCODE */) {
              case 1 /* I18nUpdateOpCode.Attr */:
                const propName = updateOpCodes[++j];
                const sanitizeFn = updateOpCodes[++j];
                const tNodeOrTagName = tView.data[nodeIndex];
                ngDevMode && assertDefined(tNodeOrTagName, 'Experting TNode or string');
                if (typeof tNodeOrTagName === 'string') {
                  // IF we don't have a `TNode`, then we are an element in ICU (as ICU content does
                  // not have TNode), in which case we know that there are no directives, and hence
                  // we use attribute setting.
                  setElementAttribute(lView[RENDERER], lView[nodeIndex], null, tNodeOrTagName, propName, value, sanitizeFn);
                } else {
                  elementPropertyInternal(tView, tNodeOrTagName, lView, propName, value, lView[RENDERER], sanitizeFn, false);
                }
                break;
              case 0 /* I18nUpdateOpCode.Text */:
                const rText = lView[nodeIndex];
                rText !== null && updateTextNode(lView[RENDERER], rText, value);
                break;
              case 2 /* I18nUpdateOpCode.IcuSwitch */:
                applyIcuSwitchCase(tView, getTIcu(tView, nodeIndex), lView, value);
                break;
              case 3 /* I18nUpdateOpCode.IcuUpdate */:
                applyIcuUpdateCase(tView, getTIcu(tView, nodeIndex), bindingsStartIndex, lView);
                break;
            }
          }
        }
      }
    } else {
      const opCode = updateOpCodes[i + 1];
      if (opCode > 0 && (opCode & 3 /* I18nUpdateOpCode.MASK_OPCODE */) === 3 /* I18nUpdateOpCode.IcuUpdate */) {
        // Special case for the `icuUpdateCase`. It could be that the mask did not match, but
        // we still need to execute `icuUpdateCase` because the case has changed recently due to
        // previous `icuSwitchCase` instruction. (`icuSwitchCase` and `icuUpdateCase` always come in
        // pairs.)
        const nodeIndex = opCode >>> 2 /* I18nUpdateOpCode.SHIFT_REF */;
        const tIcu = getTIcu(tView, nodeIndex);
        const currentIndex = lView[tIcu.currentCaseLViewIndex];
        if (currentIndex < 0) {
          applyIcuUpdateCase(tView, tIcu, bindingsStartIndex, lView);
        }
      }
    }
    i += skipCodes;
  }
}
/**
 * Apply OpCodes associated with updating an existing ICU.
 *
 * @param tView Current `TView`
 * @param tIcu Current `TIcu`
 * @param bindingsStartIndex Location of the first `ɵɵi18nApply`
 * @param lView Current `LView`
 */
function applyIcuUpdateCase(tView, tIcu, bindingsStartIndex, lView) {
  ngDevMode && assertIndexInRange(lView, tIcu.currentCaseLViewIndex);
  let activeCaseIndex = lView[tIcu.currentCaseLViewIndex];
  if (activeCaseIndex !== null) {
    let mask = changeMask;
    if (activeCaseIndex < 0) {
      // Clear the flag.
      // Negative number means that the ICU was freshly created and we need to force the update.
      activeCaseIndex = lView[tIcu.currentCaseLViewIndex] = ~activeCaseIndex;
      // -1 is same as all bits on, which simulates creation since it marks all bits dirty
      mask = -1;
    }
    applyUpdateOpCodes(tView, lView, tIcu.update[activeCaseIndex], bindingsStartIndex, mask);
  }
}
/**
 * Apply OpCodes associated with switching a case on ICU.
 *
 * This involves tearing down existing case and than building up a new case.
 *
 * @param tView Current `TView`
 * @param tIcu Current `TIcu`
 * @param lView Current `LView`
 * @param value Value of the case to update to.
 */
function applyIcuSwitchCase(tView, tIcu, lView, value) {
  // Rebuild a new case for this ICU
  const caseIndex = getCaseIndex(tIcu, value);
  let activeCaseIndex = getCurrentICUCaseIndex(tIcu, lView);
  if (activeCaseIndex !== caseIndex) {
    applyIcuSwitchCaseRemove(tView, tIcu, lView);
    lView[tIcu.currentCaseLViewIndex] = caseIndex === null ? null : ~caseIndex;
    if (caseIndex !== null) {
      // Add the nodes for the new case
      const anchorRNode = lView[tIcu.anchorIdx];
      if (anchorRNode) {
        ngDevMode && assertDomNode(anchorRNode);
        applyMutableOpCodes(tView, tIcu.create[caseIndex], lView, anchorRNode);
      }
    }
  }
}
/**
 * Apply OpCodes associated with tearing ICU case.
 *
 * This involves tearing down existing case and than building up a new case.
 *
 * @param tView Current `TView`
 * @param tIcu Current `TIcu`
 * @param lView Current `LView`
 */
function applyIcuSwitchCaseRemove(tView, tIcu, lView) {
  let activeCaseIndex = getCurrentICUCaseIndex(tIcu, lView);
  if (activeCaseIndex !== null) {
    const removeCodes = tIcu.remove[activeCaseIndex];
    for (let i = 0; i < removeCodes.length; i++) {
      const nodeOrIcuIndex = removeCodes[i];
      if (nodeOrIcuIndex > 0) {
        // Positive numbers are `RNode`s.
        const rNode = getNativeByIndex(nodeOrIcuIndex, lView);
        rNode !== null && nativeRemoveNode(lView[RENDERER], rNode);
      } else {
        // Negative numbers are ICUs
        applyIcuSwitchCaseRemove(tView, getTIcu(tView, ~nodeOrIcuIndex), lView);
      }
    }
  }
}
/**
 * Returns the index of the current case of an ICU expression depending on the main binding value
 *
 * @param icuExpression
 * @param bindingValue The value of the main binding used by this ICU expression
 */
function getCaseIndex(icuExpression, bindingValue) {
  let index = icuExpression.cases.indexOf(bindingValue);
  if (index === -1) {
    switch (icuExpression.type) {
      case 1 /* IcuType.plural */:
        {
          const resolvedCase = getPluralCase(bindingValue, getLocaleId());
          index = icuExpression.cases.indexOf(resolvedCase);
          if (index === -1 && resolvedCase !== 'other') {
            index = icuExpression.cases.indexOf('other');
          }
          break;
        }
      case 0 /* IcuType.select */:
        {
          index = icuExpression.cases.indexOf('other');
          break;
        }
    }
  }
  return index === -1 ? null : index;
}
function loadIcuContainerVisitor() {
  const _stack = [];
  let _index = -1;
  let _lView;
  let _removes;
  /**
   * Retrieves a set of root nodes from `TIcu.remove`. Used by `TNodeType.ICUContainer`
   * to determine which root belong to the ICU.
   *
   * Example of usage.
   * ```
   * const nextRNode = icuContainerIteratorStart(tIcuContainerNode, lView);
   * let rNode: RNode|null;
   * while(rNode = nextRNode()) {
   *   console.log(rNode);
   * }
   * ```
   *
   * @param tIcuContainerNode Current `TIcuContainerNode`
   * @param lView `LView` where the `RNode`s should be looked up.
   */
  function icuContainerIteratorStart(tIcuContainerNode, lView) {
    _lView = lView;
    while (_stack.length) _stack.pop();
    ngDevMode && assertTNodeForLView(tIcuContainerNode, lView);
    enterIcu(tIcuContainerNode.value, lView);
    return icuContainerIteratorNext;
  }
  function enterIcu(tIcu, lView) {
    _index = 0;
    const currentCase = getCurrentICUCaseIndex(tIcu, lView);
    if (currentCase !== null) {
      ngDevMode && assertNumberInRange(currentCase, 0, tIcu.cases.length - 1);
      _removes = tIcu.remove[currentCase];
    } else {
      _removes = EMPTY_ARRAY;
    }
  }
  function icuContainerIteratorNext() {
    if (_index < _removes.length) {
      const removeOpCode = _removes[_index++];
      ngDevMode && assertNumber(removeOpCode, 'Expecting OpCode number');
      if (removeOpCode > 0) {
        const rNode = _lView[removeOpCode];
        ngDevMode && assertDomNode(rNode);
        return rNode;
      } else {
        _stack.push(_index, _removes);
        // ICUs are represented by negative indices
        const tIcuIndex = ~removeOpCode;
        const tIcu = _lView[TVIEW].data[tIcuIndex];
        ngDevMode && assertTIcu(tIcu);
        enterIcu(tIcu, _lView);
        return icuContainerIteratorNext();
      }
    } else {
      if (_stack.length === 0) {
        return null;
      } else {
        _removes = _stack.pop();
        _index = _stack.pop();
        return icuContainerIteratorNext();
      }
    }
  }
  return icuContainerIteratorStart;
}

/**
 * Converts `I18nCreateOpCodes` array into a human readable format.
 *
 * This function is attached to the `I18nCreateOpCodes.debug` property if `ngDevMode` is enabled.
 * This function provides a human readable view of the opcodes. This is useful when debugging the
 * application as well as writing more readable tests.
 *
 * @param this `I18nCreateOpCodes` if attached as a method.
 * @param opcodes `I18nCreateOpCodes` if invoked as a function.
 */
function i18nCreateOpCodesToString(opcodes) {
  const createOpCodes = opcodes || (Array.isArray(this) ? this : []);
  let lines = [];
  for (let i = 0; i < createOpCodes.length; i++) {
    const opCode = createOpCodes[i++];
    const text = createOpCodes[i];
    const isComment = (opCode & I18nCreateOpCode.COMMENT) === I18nCreateOpCode.COMMENT;
    const appendNow = (opCode & I18nCreateOpCode.APPEND_EAGERLY) === I18nCreateOpCode.APPEND_EAGERLY;
    const index = opCode >>> I18nCreateOpCode.SHIFT;
    lines.push(`lView[${index}] = document.${isComment ? 'createComment' : 'createText'}(${JSON.stringify(text)});`);
    if (appendNow) {
      lines.push(`parent.appendChild(lView[${index}]);`);
    }
  }
  return lines;
}
/**
 * Converts `I18nUpdateOpCodes` array into a human readable format.
 *
 * This function is attached to the `I18nUpdateOpCodes.debug` property if `ngDevMode` is enabled.
 * This function provides a human readable view of the opcodes. This is useful when debugging the
 * application as well as writing more readable tests.
 *
 * @param this `I18nUpdateOpCodes` if attached as a method.
 * @param opcodes `I18nUpdateOpCodes` if invoked as a function.
 */
function i18nUpdateOpCodesToString(opcodes) {
  const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
  let lines = [];
  function consumeOpCode(value) {
    const ref = value >>> 2 /* I18nUpdateOpCode.SHIFT_REF */;
    const opCode = value & 3 /* I18nUpdateOpCode.MASK_OPCODE */;
    switch (opCode) {
      case 0 /* I18nUpdateOpCode.Text */:
        return `(lView[${ref}] as Text).textContent = $$$`;
      case 1 /* I18nUpdateOpCode.Attr */:
        const attrName = parser.consumeString();
        const sanitizationFn = parser.consumeFunction();
        const value = sanitizationFn ? `(${sanitizationFn})($$$)` : '$$$';
        return `(lView[${ref}] as Element).setAttribute('${attrName}', ${value})`;
      case 2 /* I18nUpdateOpCode.IcuSwitch */:
        return `icuSwitchCase(${ref}, $$$)`;
      case 3 /* I18nUpdateOpCode.IcuUpdate */:
        return `icuUpdateCase(${ref})`;
    }
    throw new Error('unexpected OpCode');
  }
  while (parser.hasMore()) {
    let mask = parser.consumeNumber();
    let size = parser.consumeNumber();
    const end = parser.i + size;
    const statements = [];
    let statement = '';
    while (parser.i < end) {
      let value = parser.consumeNumberOrString();
      if (typeof value === 'string') {
        statement += value;
      } else if (value < 0) {
        // Negative numbers are ref indexes
        // Here `i` refers to current binding index. It is to signify that the value is relative,
        // rather than absolute.
        statement += '${lView[i' + value + ']}';
      } else {
        // Positive numbers are operations.
        const opCodeText = consumeOpCode(value);
        statements.push(opCodeText.replace('$$$', '`' + statement + '`') + ';');
        statement = '';
      }
    }
    lines.push(`if (mask & 0b${mask.toString(2)}) { ${statements.join(' ')} }`);
  }
  return lines;
}
/**
 * Converts `I18nCreateOpCodes` array into a human readable format.
 *
 * This function is attached to the `I18nCreateOpCodes.debug` if `ngDevMode` is enabled. This
 * function provides a human readable view of the opcodes. This is useful when debugging the
 * application as well as writing more readable tests.
 *
 * @param this `I18nCreateOpCodes` if attached as a method.
 * @param opcodes `I18nCreateOpCodes` if invoked as a function.
 */
function icuCreateOpCodesToString(opcodes) {
  const parser = new OpCodeParser(opcodes || (Array.isArray(this) ? this : []));
  let lines = [];
  function consumeOpCode(opCode) {
    const parent = getParentFromIcuCreateOpCode(opCode);
    const ref = getRefFromIcuCreateOpCode(opCode);
    switch (getInstructionFromIcuCreateOpCode(opCode)) {
      case 0 /* IcuCreateOpCode.AppendChild */:
        return `(lView[${parent}] as Element).appendChild(lView[${lastRef}])`;
      case 1 /* IcuCreateOpCode.Attr */:
        return `(lView[${ref}] as Element).setAttribute("${parser.consumeString()}", "${parser.consumeString()}")`;
    }
    throw new Error('Unexpected OpCode: ' + getInstructionFromIcuCreateOpCode(opCode));
  }
  let lastRef = -1;
  while (parser.hasMore()) {
    let value = parser.consumeNumberStringOrMarker();
    if (value === ICU_MARKER) {
      const text = parser.consumeString();
      lastRef = parser.consumeNumber();
      lines.push(`lView[${lastRef}] = document.createComment("${text}")`);
    } else if (value === ELEMENT_MARKER) {
      const text = parser.consumeString();
      lastRef = parser.consumeNumber();
      lines.push(`lView[${lastRef}] = document.createElement("${text}")`);
    } else if (typeof value === 'string') {
      lastRef = parser.consumeNumber();
      lines.push(`lView[${lastRef}] = document.createTextNode("${value}")`);
    } else if (typeof value === 'number') {
      const line = consumeOpCode(value);
      line && lines.push(line);
    } else {
      throw new Error('Unexpected value');
    }
  }
  return lines;
}
/**
 * Converts `I18nRemoveOpCodes` array into a human readable format.
 *
 * This function is attached to the `I18nRemoveOpCodes.debug` if `ngDevMode` is enabled. This
 * function provides a human readable view of the opcodes. This is useful when debugging the
 * application as well as writing more readable tests.
 *
 * @param this `I18nRemoveOpCodes` if attached as a method.
 * @param opcodes `I18nRemoveOpCodes` if invoked as a function.
 */
function i18nRemoveOpCodesToString(opcodes) {
  const removeCodes = opcodes || (Array.isArray(this) ? this : []);
  let lines = [];
  for (let i = 0; i < removeCodes.length; i++) {
    const nodeOrIcuIndex = removeCodes[i];
    if (nodeOrIcuIndex > 0) {
      // Positive numbers are `RNode`s.
      lines.push(`remove(lView[${nodeOrIcuIndex}])`);
    } else {
      // Negative numbers are ICUs
      lines.push(`removeNestedICU(${~nodeOrIcuIndex})`);
    }
  }
  return lines;
}
class OpCodeParser {
  constructor(codes) {
    this.i = 0;
    this.codes = codes;
  }
  hasMore() {
    return this.i < this.codes.length;
  }
  consumeNumber() {
    let value = this.codes[this.i++];
    assertNumber(value, 'expecting number in OpCode');
    return value;
  }
  consumeString() {
    let value = this.codes[this.i++];
    assertString(value, 'expecting string in OpCode');
    return value;
  }
  consumeFunction() {
    let value = this.codes[this.i++];
    if (value === null || typeof value === 'function') {
      return value;
    }
    throw new Error('expecting function in OpCode');
  }
  consumeNumberOrString() {
    let value = this.codes[this.i++];
    if (typeof value === 'string') {
      return value;
    }
    assertNumber(value, 'expecting number or string in OpCode');
    return value;
  }
  consumeNumberStringOrMarker() {
    let value = this.codes[this.i++];
    if (typeof value === 'string' || typeof value === 'number' || value == ICU_MARKER || value == ELEMENT_MARKER) {
      return value;
    }
    assertNumber(value, 'expecting number, string, ICU_MARKER or ELEMENT_MARKER in OpCode');
    return value;
  }
}
const BINDING_REGEXP = /�(\d+):?\d*�/gi;
const ICU_REGEXP = /({\s*�\d+:?\d*�\s*,\s*\S{6}\s*,[\s\S]*})/gi;
const NESTED_ICU = /�(\d+)�/;
const ICU_BLOCK_REGEXP = /^\s*(�\d+:?\d*�)\s*,\s*(select|plural)\s*,/;
const MARKER = `�`;
const SUBTEMPLATE_REGEXP = /�\/?\*(\d+:\d+)�/gi;
const PH_REGEXP = /�(\/?[#*]\d+):?\d*�/gi;
/**
 * Angular uses the special entity &ngsp; as a placeholder for non-removable space.
 * It's replaced by the 0xE500 PUA (Private Use Areas) unicode character and later on replaced by a
 * space.
 * We are re-implementing the same idea since translations might contain this special character.
 */
const NGSP_UNICODE_REGEXP = /\uE500/g;
function replaceNgsp(value) {
  return value.replace(NGSP_UNICODE_REGEXP, ' ');
}
/**
 * Patch a `debug` property getter on top of the existing object.
 *
 * NOTE: always call this method with `ngDevMode && attachDebugObject(...)`
 *
 * @param obj Object to patch
 * @param debugGetter Getter returning a value to patch
 */
function attachDebugGetter(obj, debugGetter) {
  if (ngDevMode) {
    Object.defineProperty(obj, 'debug', {
      get: debugGetter,
      enumerable: false
    });
  } else {
    throw new Error('This method should be guarded with `ngDevMode` so that it can be tree shaken in production!');
  }
}
/**
 * Create dynamic nodes from i18n translation block.
 *
 * - Text nodes are created synchronously
 * - TNodes are linked into tree lazily
 *
 * @param tView Current `TView`
 * @parentTNodeIndex index to the parent TNode of this i18n block
 * @param lView Current `LView`
 * @param index Index of `ɵɵi18nStart` instruction.
 * @param message Message to translate.
 * @param subTemplateIndex Index into the sub template of message translation. (ie in case of
 *     `ngIf`) (-1 otherwise)
 */
function i18nStartFirstCreatePass(tView, parentTNodeIndex, lView, index, message, subTemplateIndex) {
  const rootTNode = getCurrentParentTNode();
  const createOpCodes = [];
  const updateOpCodes = [];
  const existingTNodeStack = [[]];
  const astStack = [[]];
  if (ngDevMode) {
    attachDebugGetter(createOpCodes, i18nCreateOpCodesToString);
    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
  }
  message = getTranslationForTemplate(message, subTemplateIndex);
  const msgParts = replaceNgsp(message).split(PH_REGEXP);
  for (let i = 0; i < msgParts.length; i++) {
    let value = msgParts[i];
    if ((i & 1) === 0) {
      // Even indexes are text (including bindings & ICU expressions)
      const parts = i18nParseTextIntoPartsAndICU(value);
      for (let j = 0; j < parts.length; j++) {
        let part = parts[j];
        if ((j & 1) === 0) {
          // `j` is odd therefore `part` is string
          const text = part;
          ngDevMode && assertString(text, 'Parsed ICU part should be string');
          if (text !== '') {
            i18nStartFirstCreatePassProcessTextNode(astStack[0], tView, rootTNode, existingTNodeStack[0], createOpCodes, updateOpCodes, lView, text);
          }
        } else {
          // `j` is Even therefor `part` is an `ICUExpression`
          const icuExpression = part;
          // Verify that ICU expression has the right shape. Translations might contain invalid
          // constructions (while original messages were correct), so ICU parsing at runtime may
          // not succeed (thus `icuExpression` remains a string).
          // Note: we intentionally retain the error here by not using `ngDevMode`, because
          // the value can change based on the locale and users aren't guaranteed to hit
          // an invalid string while they're developing.
          if (typeof icuExpression !== 'object') {
            throw new Error(`Unable to parse ICU expression in "${message}" message.`);
          }
          const icuContainerTNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodeStack[0], lView, createOpCodes, ngDevMode ? `ICU ${index}:${icuExpression.mainBinding}` : '', true);
          const icuNodeIndex = icuContainerTNode.index;
          ngDevMode && assertGreaterThanOrEqual(icuNodeIndex, HEADER_OFFSET, 'Index must be in absolute LView offset');
          icuStart(astStack[0], tView, lView, updateOpCodes, parentTNodeIndex, icuExpression, icuNodeIndex);
        }
      }
    } else {
      // Odd indexes are placeholders (elements and sub-templates)
      // At this point value is something like: '/#1:2' (originally coming from '�/#1:2�')
      const isClosing = value.charCodeAt(0) === 47 /* CharCode.SLASH */;
      const type = value.charCodeAt(isClosing ? 1 : 0);
      ngDevMode && assertOneOf(type, 42 /* CharCode.STAR */, 35 /* CharCode.HASH */);
      const index = HEADER_OFFSET + Number.parseInt(value.substring(isClosing ? 2 : 1));
      if (isClosing) {
        existingTNodeStack.shift();
        astStack.shift();
        setCurrentTNode(getCurrentParentTNode(), false);
      } else {
        const tNode = createTNodePlaceholder(tView, existingTNodeStack[0], index);
        existingTNodeStack.unshift([]);
        setCurrentTNode(tNode, true);
        const placeholderNode = {
          kind: 2 /* I18nNodeKind.PLACEHOLDER */,
          index,
          children: [],
          type: type === 35 /* CharCode.HASH */ ? 0 /* I18nPlaceholderType.ELEMENT */ : 1 /* I18nPlaceholderType.SUBTEMPLATE */
        };
        astStack[0].push(placeholderNode);
        astStack.unshift(placeholderNode.children);
      }
    }
  }
  tView.data[index] = {
    create: createOpCodes,
    update: updateOpCodes,
    ast: astStack[0]
  };
}
/**
 * Allocate space in i18n Range add create OpCode instruction to create a text or comment node.
 *
 * @param tView Current `TView` needed to allocate space in i18n range.
 * @param rootTNode Root `TNode` of the i18n block. This node determines if the new TNode will be
 *     added as part of the `i18nStart` instruction or as part of the `TNode.insertBeforeIndex`.
 * @param existingTNodes internal state for `addTNodeAndUpdateInsertBeforeIndex`.
 * @param lView Current `LView` needed to allocate space in i18n range.
 * @param createOpCodes Array storing `I18nCreateOpCodes` where new opCodes will be added.
 * @param text Text to be added when the `Text` or `Comment` node will be created.
 * @param isICU true if a `Comment` node for ICU (instead of `Text`) node should be created.
 */
function createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, text, isICU) {
  const i18nNodeIdx = allocExpando(tView, lView, 1, null);
  let opCode = i18nNodeIdx << I18nCreateOpCode.SHIFT;
  let parentTNode = getCurrentParentTNode();
  if (rootTNode === parentTNode) {
    // FIXME(misko): A null `parentTNode` should represent when we fall of the `LView` boundary.
    // (there is no parent), but in some circumstances (because we are inconsistent about how we set
    // `previousOrParentTNode`) it could point to `rootTNode` So this is a work around.
    parentTNode = null;
  }
  if (parentTNode === null) {
    // If we don't have a parent that means that we can eagerly add nodes.
    // If we have a parent than these nodes can't be added now (as the parent has not been created
    // yet) and instead the `parentTNode` is responsible for adding it. See
    // `TNode.insertBeforeIndex`
    opCode |= I18nCreateOpCode.APPEND_EAGERLY;
  }
  if (isICU) {
    opCode |= I18nCreateOpCode.COMMENT;
    ensureIcuContainerVisitorLoaded(loadIcuContainerVisitor);
  }
  createOpCodes.push(opCode, text === null ? '' : text);
  // We store `{{?}}` so that when looking at debug `TNodeType.template` we can see where the
  // bindings are.
  const tNode = createTNodeAtIndex(tView, i18nNodeIdx, isICU ? 32 /* TNodeType.Icu */ : 1 /* TNodeType.Text */, text === null ? ngDevMode ? '{{?}}' : '' : text, null);
  addTNodeAndUpdateInsertBeforeIndex(existingTNodes, tNode);
  const tNodeIdx = tNode.index;
  setCurrentTNode(tNode, false /* Text nodes are self closing */);
  if (parentTNode !== null && rootTNode !== parentTNode) {
    // We are a child of deeper node (rather than a direct child of `i18nStart` instruction.)
    // We have to make sure to add ourselves to the parent.
    setTNodeInsertBeforeIndex(parentTNode, tNodeIdx);
  }
  return tNode;
}
/**
 * Processes text node in i18n block.
 *
 * Text nodes can have:
 * - Create instruction in `createOpCodes` for creating the text node.
 * - Allocate spec for text node in i18n range of `LView`
 * - If contains binding:
 *    - bindings => allocate space in i18n range of `LView` to store the binding value.
 *    - populate `updateOpCodes` with update instructions.
 *
 * @param tView Current `TView`
 * @param rootTNode Root `TNode` of the i18n block. This node determines if the new TNode will
 *     be added as part of the `i18nStart` instruction or as part of the
 *     `TNode.insertBeforeIndex`.
 * @param existingTNodes internal state for `addTNodeAndUpdateInsertBeforeIndex`.
 * @param createOpCodes Location where the creation OpCodes will be stored.
 * @param lView Current `LView`
 * @param text The translated text (which may contain binding)
 */
function i18nStartFirstCreatePassProcessTextNode(ast, tView, rootTNode, existingTNodes, createOpCodes, updateOpCodes, lView, text) {
  const hasBinding = text.match(BINDING_REGEXP);
  const tNode = createTNodeAndAddOpCode(tView, rootTNode, existingTNodes, lView, createOpCodes, hasBinding ? null : text, false);
  const index = tNode.index;
  if (hasBinding) {
    generateBindingUpdateOpCodes(updateOpCodes, text, index, null, 0, null);
  }
  ast.push({
    kind: 0 /* I18nNodeKind.TEXT */,
    index
  });
}
/**
 * See `i18nAttributes` above.
 */
function i18nAttributesFirstPass(tView, index, values) {
  const previousElement = getCurrentTNode();
  const previousElementIndex = previousElement.index;
  const updateOpCodes = [];
  if (ngDevMode) {
    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
  }
  if (tView.firstCreatePass && tView.data[index] === null) {
    for (let i = 0; i < values.length; i += 2) {
      const attrName = values[i];
      const message = values[i + 1];
      if (message !== '') {
        // Check if attribute value contains an ICU and throw an error if that's the case.
        // ICUs in element attributes are not supported.
        // Note: we intentionally retain the error here by not using `ngDevMode`, because
        // the `value` can change based on the locale and users aren't guaranteed to hit
        // an invalid string while they're developing.
        if (ICU_REGEXP.test(message)) {
          throw new Error(`ICU expressions are not supported in attributes. Message: "${message}".`);
        }
        // i18n attributes that hit this code path are guaranteed to have bindings, because
        // the compiler treats static i18n attributes as regular attribute bindings.
        // Since this may not be the first i18n attribute on this element we need to pass in how
        // many previous bindings there have already been.
        generateBindingUpdateOpCodes(updateOpCodes, message, previousElementIndex, attrName, countBindings(updateOpCodes), null);
      }
    }
    tView.data[index] = updateOpCodes;
  }
}
/**
 * Generate the OpCodes to update the bindings of a string.
 *
 * @param updateOpCodes Place where the update opcodes will be stored.
 * @param str The string containing the bindings.
 * @param destinationNode Index of the destination node which will receive the binding.
 * @param attrName Name of the attribute, if the string belongs to an attribute.
 * @param sanitizeFn Sanitization function used to sanitize the string after update, if necessary.
 * @param bindingStart The lView index of the next expression that can be bound via an opCode.
 * @returns The mask value for these bindings
 */
function generateBindingUpdateOpCodes(updateOpCodes, str, destinationNode, attrName, bindingStart, sanitizeFn) {
  ngDevMode && assertGreaterThanOrEqual(destinationNode, HEADER_OFFSET, 'Index must be in absolute LView offset');
  const maskIndex = updateOpCodes.length; // Location of mask
  const sizeIndex = maskIndex + 1; // location of size for skipping
  updateOpCodes.push(null, null); // Alloc space for mask and size
  const startIndex = maskIndex + 2; // location of first allocation.
  if (ngDevMode) {
    attachDebugGetter(updateOpCodes, i18nUpdateOpCodesToString);
  }
  const textParts = str.split(BINDING_REGEXP);
  let mask = 0;
  for (let j = 0; j < textParts.length; j++) {
    const textValue = textParts[j];
    if (j & 1) {
      // Odd indexes are bindings
      const bindingIndex = bindingStart + parseInt(textValue, 10);
      updateOpCodes.push(-1 - bindingIndex);
      mask = mask | toMaskBit(bindingIndex);
    } else if (textValue !== '') {
      // Even indexes are text
      updateOpCodes.push(textValue);
    }
  }
  updateOpCodes.push(destinationNode << 2 /* I18nUpdateOpCode.SHIFT_REF */ | (attrName ? 1 /* I18nUpdateOpCode.Attr */ : 0 /* I18nUpdateOpCode.Text */));
  if (attrName) {
    updateOpCodes.push(attrName, sanitizeFn);
  }
  updateOpCodes[maskIndex] = mask;
  updateOpCodes[sizeIndex] = updateOpCodes.length - startIndex;
  return mask;
}
/**
 * Count the number of bindings in the given `opCodes`.
 *
 * It could be possible to speed this up, by passing the number of bindings found back from
 * `generateBindingUpdateOpCodes()` to `i18nAttributesFirstPass()` but this would then require more
 * complexity in the code and/or transient objects to be created.
 *
 * Since this function is only called once when the template is instantiated, is trivial in the
 * first instance (since `opCodes` will be an empty array), and it is not common for elements to
 * contain multiple i18n bound attributes, it seems like this is a reasonable compromise.
 */
function countBindings(opCodes) {
  let count = 0;
  for (let i = 0; i < opCodes.length; i++) {
    const opCode = opCodes[i];
    // Bindings are negative numbers.
    if (typeof opCode === 'number' && opCode < 0) {
      count++;
    }
  }
  return count;
}
/**
 * Convert binding index to mask bit.
 *
 * Each index represents a single bit on the bit-mask. Because bit-mask only has 32 bits, we make
 * the 32nd bit share all masks for all bindings higher than 32. Since it is extremely rare to
 * have more than 32 bindings this will be hit very rarely. The downside of hitting this corner
 * case is that we will execute binding code more often than necessary. (penalty of performance)
 */
function toMaskBit(bindingIndex) {
  return 1 << Math.min(bindingIndex, 31);
}
function isRootTemplateMessage(subTemplateIndex) {
  return subTemplateIndex === -1;
}
/**
 * Removes everything inside the sub-templates of a message.
 */
function removeInnerTemplateTranslation(message) {
  let match;
  let res = '';
  let index = 0;
  let inTemplate = false;
  let tagMatched;
  while ((match = SUBTEMPLATE_REGEXP.exec(message)) !== null) {
    if (!inTemplate) {
      res += message.substring(index, match.index + match[0].length);
      tagMatched = match[1];
      inTemplate = true;
    } else {
      if (match[0] === `${MARKER}/*${tagMatched}${MARKER}`) {
        index = match.index;
        inTemplate = false;
      }
    }
  }
  ngDevMode && assertEqual(inTemplate, false, `Tag mismatch: unable to find the end of the sub-template in the translation "${message}"`);
  res += message.slice(index);
  return res;
}
/**
 * Extracts a part of a message and removes the rest.
 *
 * This method is used for extracting a part of the message associated with a template. A
 * translated message can span multiple templates.
 *
 * Example:
 * ```
 * <div i18n>Translate <span *ngIf>me</span>!</div>
 * ```
 *
 * @param message The message to crop
 * @param subTemplateIndex Index of the sub-template to extract. If undefined it returns the
 * external template and removes all sub-templates.
 */
function getTranslationForTemplate(message, subTemplateIndex) {
  if (isRootTemplateMessage(subTemplateIndex)) {
    // We want the root template message, ignore all sub-templates
    return removeInnerTemplateTranslation(message);
  } else {
    // We want a specific sub-template
    const start = message.indexOf(`:${subTemplateIndex}${MARKER}`) + 2 + subTemplateIndex.toString().length;
    const end = message.search(new RegExp(`${MARKER}\\/\\*\\d+:${subTemplateIndex}${MARKER}`));
    return removeInnerTemplateTranslation(message.substring(start, end));
  }
}
/**
 * Generate the OpCodes for ICU expressions.
 *
 * @param icuExpression
 * @param index Index where the anchor is stored and an optional `TIcuContainerNode`
 *   - `lView[anchorIdx]` points to a `Comment` node representing the anchor for the ICU.
 *   - `tView.data[anchorIdx]` points to the `TIcuContainerNode` if ICU is root (`null` otherwise)
 */
function icuStart(ast, tView, lView, updateOpCodes, parentIdx, icuExpression, anchorIdx) {
  ngDevMode && assertDefined(icuExpression, 'ICU expression must be defined');
  let bindingMask = 0;
  const tIcu = {
    type: icuExpression.type,
    currentCaseLViewIndex: allocExpando(tView, lView, 1, null),
    anchorIdx,
    cases: [],
    create: [],
    remove: [],
    update: []
  };
  addUpdateIcuSwitch(updateOpCodes, icuExpression, anchorIdx);
  setTIcu(tView, anchorIdx, tIcu);
  const values = icuExpression.values;
  const cases = [];
  for (let i = 0; i < values.length; i++) {
    // Each value is an array of strings & other ICU expressions
    const valueArr = values[i];
    const nestedIcus = [];
    for (let j = 0; j < valueArr.length; j++) {
      const value = valueArr[j];
      if (typeof value !== 'string') {
        // It is an nested ICU expression
        const icuIndex = nestedIcus.push(value) - 1;
        // Replace nested ICU expression by a comment node
        valueArr[j] = `<!--�${icuIndex}�-->`;
      }
    }
    const caseAst = [];
    cases.push(caseAst);
    bindingMask = parseIcuCase(caseAst, tView, tIcu, lView, updateOpCodes, parentIdx, icuExpression.cases[i], valueArr.join(''), nestedIcus) | bindingMask;
  }
  if (bindingMask) {
    addUpdateIcuUpdate(updateOpCodes, bindingMask, anchorIdx);
  }
  ast.push({
    kind: 3 /* I18nNodeKind.ICU */,
    index: anchorIdx,
    cases,
    currentCaseLViewIndex: tIcu.currentCaseLViewIndex
  });
}
/**
 * Parses text containing an ICU expression and produces a JSON object for it.
 * Original code from closure library, modified for Angular.
 *
 * @param pattern Text containing an ICU expression that needs to be parsed.
 *
 */
function parseICUBlock(pattern) {
  const cases = [];
  const values = [];
  let icuType = 1 /* IcuType.plural */;
  let mainBinding = 0;
  pattern = pattern.replace(ICU_BLOCK_REGEXP, function (str, binding, type) {
    if (type === 'select') {
      icuType = 0 /* IcuType.select */;
    } else {
      icuType = 1 /* IcuType.plural */;
    }
    mainBinding = parseInt(binding.slice(1), 10);
    return '';
  });
  const parts = i18nParseTextIntoPartsAndICU(pattern);
  // Looking for (key block)+ sequence. One of the keys has to be "other".
  for (let pos = 0; pos < parts.length;) {
    let key = parts[pos++].trim();
    if (icuType === 1 /* IcuType.plural */) {
      // Key can be "=x", we just want "x"
      key = key.replace(/\s*(?:=)?(\w+)\s*/, '$1');
    }
    if (key.length) {
      cases.push(key);
    }
    const blocks = i18nParseTextIntoPartsAndICU(parts[pos++]);
    if (cases.length > values.length) {
      values.push(blocks);
    }
  }
  // TODO(ocombe): support ICU expressions in attributes, see #21615
  return {
    type: icuType,
    mainBinding: mainBinding,
    cases,
    values
  };
}
/**
 * Breaks pattern into strings and top level {...} blocks.
 * Can be used to break a message into text and ICU expressions, or to break an ICU expression
 * into keys and cases. Original code from closure library, modified for Angular.
 *
 * @param pattern (sub)Pattern to be broken.
 * @returns An `Array<string|IcuExpression>` where:
 *   - odd positions: `string` => text between ICU expressions
 *   - even positions: `ICUExpression` => ICU expression parsed into `ICUExpression` record.
 */
function i18nParseTextIntoPartsAndICU(pattern) {
  if (!pattern) {
    return [];
  }
  let prevPos = 0;
  const braceStack = [];
  const results = [];
  const braces = /[{}]/g;
  // lastIndex doesn't get set to 0 so we have to.
  braces.lastIndex = 0;
  let match;
  while (match = braces.exec(pattern)) {
    const pos = match.index;
    if (match[0] == '}') {
      braceStack.pop();
      if (braceStack.length == 0) {
        // End of the block.
        const block = pattern.substring(prevPos, pos);
        if (ICU_BLOCK_REGEXP.test(block)) {
          results.push(parseICUBlock(block));
        } else {
          results.push(block);
        }
        prevPos = pos + 1;
      }
    } else {
      if (braceStack.length == 0) {
        const substring = pattern.substring(prevPos, pos);
        results.push(substring);
        prevPos = pos + 1;
      }
      braceStack.push('{');
    }
  }
  const substring = pattern.substring(prevPos);
  results.push(substring);
  return results;
}
/**
 * Parses a node, its children and its siblings, and generates the mutate & update OpCodes.
 *
 */
function parseIcuCase(ast, tView, tIcu, lView, updateOpCodes, parentIdx, caseName, unsafeCaseHtml, nestedIcus) {
  const create = [];
  const remove = [];
  const update = [];
  if (ngDevMode) {
    attachDebugGetter(create, icuCreateOpCodesToString);
    attachDebugGetter(remove, i18nRemoveOpCodesToString);
    attachDebugGetter(update, i18nUpdateOpCodesToString);
  }
  tIcu.cases.push(caseName);
  tIcu.create.push(create);
  tIcu.remove.push(remove);
  tIcu.update.push(update);
  const inertBodyHelper = getInertBodyHelper(getDocument());
  const inertBodyElement = inertBodyHelper.getInertBodyElement(unsafeCaseHtml);
  ngDevMode && assertDefined(inertBodyElement, 'Unable to generate inert body element');
  const inertRootNode = getTemplateContent(inertBodyElement) || inertBodyElement;
  if (inertRootNode) {
    return walkIcuTree(ast, tView, tIcu, lView, updateOpCodes, create, remove, update, inertRootNode, parentIdx, nestedIcus, 0);
  } else {
    return 0;
  }
}
function walkIcuTree(ast, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, parentNode, parentIdx, nestedIcus, depth) {
  let bindingMask = 0;
  let currentNode = parentNode.firstChild;
  while (currentNode) {
    const newIndex = allocExpando(tView, lView, 1, null);
    switch (currentNode.nodeType) {
      case Node.ELEMENT_NODE:
        const element = currentNode;
        const tagName = element.tagName.toLowerCase();
        if (VALID_ELEMENTS.hasOwnProperty(tagName)) {
          addCreateNodeAndAppend(create, ELEMENT_MARKER, tagName, parentIdx, newIndex);
          tView.data[newIndex] = tagName;
          const elAttrs = element.attributes;
          for (let i = 0; i < elAttrs.length; i++) {
            const attr = elAttrs.item(i);
            const lowerAttrName = attr.name.toLowerCase();
            const hasBinding = !!attr.value.match(BINDING_REGEXP);
            // we assume the input string is safe, unless it's using a binding
            if (hasBinding) {
              if (VALID_ATTRS.hasOwnProperty(lowerAttrName)) {
                if (URI_ATTRS[lowerAttrName]) {
                  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, _sanitizeUrl);
                } else {
                  generateBindingUpdateOpCodes(update, attr.value, newIndex, attr.name, 0, null);
                }
              } else {
                ngDevMode && console.warn(`WARNING: ignoring unsafe attribute value ` + `${lowerAttrName} on element ${tagName} ` + `(see ${XSS_SECURITY_URL})`);
              }
            } else {
              addCreateAttribute(create, newIndex, attr);
            }
          }
          const elementNode = {
            kind: 1 /* I18nNodeKind.ELEMENT */,
            index: newIndex,
            children: []
          };
          ast.push(elementNode);
          // Parse the children of this node (if any)
          bindingMask = walkIcuTree(elementNode.children, tView, tIcu, lView, sharedUpdateOpCodes, create, remove, update, currentNode, newIndex, nestedIcus, depth + 1) | bindingMask;
          addRemoveNode(remove, newIndex, depth);
        }
        break;
      case Node.TEXT_NODE:
        const value = currentNode.textContent || '';
        const hasBinding = value.match(BINDING_REGEXP);
        addCreateNodeAndAppend(create, null, hasBinding ? '' : value, parentIdx, newIndex);
        addRemoveNode(remove, newIndex, depth);
        if (hasBinding) {
          bindingMask = generateBindingUpdateOpCodes(update, value, newIndex, null, 0, null) | bindingMask;
        }
        ast.push({
          kind: 0 /* I18nNodeKind.TEXT */,
          index: newIndex
        });
        break;
      case Node.COMMENT_NODE:
        // Check if the comment node is a placeholder for a nested ICU
        const isNestedIcu = NESTED_ICU.exec(currentNode.textContent || '');
        if (isNestedIcu) {
          const nestedIcuIndex = parseInt(isNestedIcu[1], 10);
          const icuExpression = nestedIcus[nestedIcuIndex];
          // Create the comment node that will anchor the ICU expression
          addCreateNodeAndAppend(create, ICU_MARKER, ngDevMode ? `nested ICU ${nestedIcuIndex}` : '', parentIdx, newIndex);
          icuStart(ast, tView, lView, sharedUpdateOpCodes, parentIdx, icuExpression, newIndex);
          addRemoveNestedIcu(remove, newIndex, depth);
        }
        break;
    }
    currentNode = currentNode.nextSibling;
  }
  return bindingMask;
}
function addRemoveNode(remove, index, depth) {
  if (depth === 0) {
    remove.push(index);
  }
}
function addRemoveNestedIcu(remove, index, depth) {
  if (depth === 0) {
    remove.push(~index); // remove ICU at `index`
    remove.push(index); // remove ICU comment at `index`
  }
}
function addUpdateIcuSwitch(update, icuExpression, index) {
  update.push(toMaskBit(icuExpression.mainBinding), 2, -1 - icuExpression.mainBinding, index << 2 /* I18nUpdateOpCode.SHIFT_REF */ | 2 /* I18nUpdateOpCode.IcuSwitch */);
}
function addUpdateIcuUpdate(update, bindingMask, index) {
  update.push(bindingMask, 1, index << 2 /* I18nUpdateOpCode.SHIFT_REF */ | 3 /* I18nUpdateOpCode.IcuUpdate */);
}
function addCreateNodeAndAppend(create, marker, text, appendToParentIdx, createAtIdx) {
  if (marker !== null) {
    create.push(marker);
  }
  create.push(text, createAtIdx, icuCreateOpCode(0 /* IcuCreateOpCode.AppendChild */, appendToParentIdx, createAtIdx));
}
function addCreateAttribute(create, newIndex, attr) {
  create.push(newIndex << 1 /* IcuCreateOpCode.SHIFT_REF */ | 1 /* IcuCreateOpCode.Attr */, attr.name, attr.value);
}

// i18nPostprocess consts
const ROOT_TEMPLATE_ID = 0;
const PP_MULTI_VALUE_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]/;
const PP_PLACEHOLDERS_REGEXP = /\[(�.+?�?)\]|(�\/?\*\d+:\d+�)/g;
const PP_ICU_VARS_REGEXP = /({\s*)(VAR_(PLURAL|SELECT)(_\d+)?)(\s*,)/g;
const PP_ICU_PLACEHOLDERS_REGEXP = /{([A-Z0-9_]+)}/g;
const PP_ICUS_REGEXP = /�I18N_EXP_(ICU(_\d+)?)�/g;
const PP_CLOSE_TEMPLATE_REGEXP = /\/\*/;
const PP_TEMPLATE_ID_REGEXP = /\d+\:(\d+)/;
/**
 * Handles message string post-processing for internationalization.
 *
 * Handles message string post-processing by transforming it from intermediate
 * format (that might contain some markers that we need to replace) to the final
 * form, consumable by i18nStart instruction. Post processing steps include:
 *
 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
 * 2. Replace all ICU vars (like "VAR_PLURAL")
 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
 *    in case multiple ICUs have the same placeholder name
 *
 * @param message Raw translation string for post processing
 * @param replacements Set of replacements that should be applied
 *
 * @returns Transformed string that can be consumed by i18nStart instruction
 *
 * @codeGenApi
 */
function i18nPostprocess(message, replacements = {}) {
  /**
   * Step 1: resolve all multi-value placeholders like [�#5�|�*1:1��#2:1�|�#4:1�]
   *
   * Note: due to the way we process nested templates (BFS), multi-value placeholders are typically
   * grouped by templates, for example: [�#5�|�#6�|�#1:1�|�#3:2�] where �#5� and �#6� belong to root
   * template, �#1:1� belong to nested template with index 1 and �#1:2� - nested template with index
   * 3. However in real templates the order might be different: i.e. �#1:1� and/or �#3:2� may go in
   * front of �#6�. The post processing step restores the right order by keeping track of the
   * template id stack and looks for placeholders that belong to the currently active template.
   */
  let result = message;
  if (PP_MULTI_VALUE_PLACEHOLDERS_REGEXP.test(message)) {
    const matches = {};
    const templateIdsStack = [ROOT_TEMPLATE_ID];
    result = result.replace(PP_PLACEHOLDERS_REGEXP, (m, phs, tmpl) => {
      const content = phs || tmpl;
      const placeholders = matches[content] || [];
      if (!placeholders.length) {
        content.split('|').forEach(placeholder => {
          const match = placeholder.match(PP_TEMPLATE_ID_REGEXP);
          const templateId = match ? parseInt(match[1], 10) : ROOT_TEMPLATE_ID;
          const isCloseTemplateTag = PP_CLOSE_TEMPLATE_REGEXP.test(placeholder);
          placeholders.push([templateId, isCloseTemplateTag, placeholder]);
        });
        matches[content] = placeholders;
      }
      if (!placeholders.length) {
        throw new Error(`i18n postprocess: unmatched placeholder - ${content}`);
      }
      const currentTemplateId = templateIdsStack[templateIdsStack.length - 1];
      let idx = 0;
      // find placeholder index that matches current template id
      for (let i = 0; i < placeholders.length; i++) {
        if (placeholders[i][0] === currentTemplateId) {
          idx = i;
          break;
        }
      }
      // update template id stack based on the current tag extracted
      const [templateId, isCloseTemplateTag, placeholder] = placeholders[idx];
      if (isCloseTemplateTag) {
        templateIdsStack.pop();
      } else if (currentTemplateId !== templateId) {
        templateIdsStack.push(templateId);
      }
      // remove processed tag from the list
      placeholders.splice(idx, 1);
      return placeholder;
    });
  }
  // return current result if no replacements specified
  if (!Object.keys(replacements).length) {
    return result;
  }
  /**
   * Step 2: replace all ICU vars (like "VAR_PLURAL")
   */
  result = result.replace(PP_ICU_VARS_REGEXP, (match, start, key, _type, _idx, end) => {
    return replacements.hasOwnProperty(key) ? `${start}${replacements[key]}${end}` : match;
  });
  /**
   * Step 3: replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
   */
  result = result.replace(PP_ICU_PLACEHOLDERS_REGEXP, (match, key) => {
    return replacements.hasOwnProperty(key) ? replacements[key] : match;
  });
  /**
   * Step 4: replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�) in case
   * multiple ICUs have the same placeholder name
   */
  result = result.replace(PP_ICUS_REGEXP, (match, key) => {
    if (replacements.hasOwnProperty(key)) {
      const list = replacements[key];
      if (!list.length) {
        throw new Error(`i18n postprocess: unmatched ICU - ${match} with key: ${key}`);
      }
      return list.shift();
    }
    return match;
  });
  return result;
}

/**
 * Marks a block of text as translatable.
 *
 * The instructions `i18nStart` and `i18nEnd` mark the translation block in the template.
 * The translation `message` is the value which is locale specific. The translation string may
 * contain placeholders which associate inner elements and sub-templates within the translation.
 *
 * The translation `message` placeholders are:
 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
 *   interpolated into. The placeholder `index` points to the expression binding index. An optional
 *   `block` that matches the sub-template in which it was declared.
 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
 *   and end of DOM element that were embedded in the original translation block. The placeholder
 *   `index` points to the element index in the template instructions set. An optional `block` that
 *   matches the sub-template in which it was declared.
 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
 *   split up and translated separately in each angular template function. The `index` points to the
 *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
 *
 * @param index A unique index of the translation in the static block.
 * @param messageIndex An index of the translation message from the `def.consts` array.
 * @param subTemplateIndex Optional sub-template index in the `message`.
 *
 * @codeGenApi
 */
function ɵɵi18nStart(index, messageIndex, subTemplateIndex = -1) {
  const tView = getTView();
  const lView = getLView();
  const adjustedIndex = HEADER_OFFSET + index;
  ngDevMode && assertDefined(tView, `tView should be defined`);
  const message = getConstant(tView.consts, messageIndex);
  const parentTNode = getCurrentParentTNode();
  if (tView.firstCreatePass) {
    i18nStartFirstCreatePass(tView, parentTNode === null ? 0 : parentTNode.index, lView, adjustedIndex, message, subTemplateIndex);
  }
  // Set a flag that this LView has i18n blocks.
  // The flag is later used to determine whether this component should
  // be hydrated (currently hydration is not supported for i18n blocks).
  if (tView.type === 2 /* TViewType.Embedded */) {
    // Annotate host component's LView (not embedded view's LView),
    // since hydration can be skipped on per-component basis only.
    const componentLView = lView[DECLARATION_COMPONENT_VIEW];
    componentLView[FLAGS] |= 32 /* LViewFlags.HasI18n */;
  } else {
    lView[FLAGS] |= 32 /* LViewFlags.HasI18n */;
  }
  const tI18n = tView.data[adjustedIndex];
  const sameViewParentTNode = parentTNode === lView[T_HOST] ? null : parentTNode;
  const parentRNode = getClosestRElement(tView, sameViewParentTNode, lView);
  // If `parentTNode` is an `ElementContainer` than it has `<!--ng-container--->`.
  // When we do inserts we have to make sure to insert in front of `<!--ng-container--->`.
  const insertInFrontOf = parentTNode && parentTNode.type & 8 /* TNodeType.ElementContainer */ ? lView[parentTNode.index] : null;
  applyCreateOpCodes(lView, tI18n.create, parentRNode, insertInFrontOf);
  setInI18nBlock(true);
}
/**
 * Translates a translation block marked by `i18nStart` and `i18nEnd`. It inserts the text/ICU nodes
 * into the render tree, moves the placeholder nodes and removes the deleted nodes.
 *
 * @codeGenApi
 */
function ɵɵi18nEnd() {
  setInI18nBlock(false);
}
/**
 *
 * Use this instruction to create a translation block that doesn't contain any placeholder.
 * It calls both {@link i18nStart} and {@link i18nEnd} in one instruction.
 *
 * The translation `message` is the value which is locale specific. The translation string may
 * contain placeholders which associate inner elements and sub-templates within the translation.
 *
 * The translation `message` placeholders are:
 * - `�{index}(:{block})�`: *Binding Placeholder*: Marks a location where an expression will be
 *   interpolated into. The placeholder `index` points to the expression binding index. An optional
 *   `block` that matches the sub-template in which it was declared.
 * - `�#{index}(:{block})�`/`�/#{index}(:{block})�`: *Element Placeholder*:  Marks the beginning
 *   and end of DOM element that were embedded in the original translation block. The placeholder
 *   `index` points to the element index in the template instructions set. An optional `block` that
 *   matches the sub-template in which it was declared.
 * - `�*{index}:{block}�`/`�/*{index}:{block}�`: *Sub-template Placeholder*: Sub-templates must be
 *   split up and translated separately in each angular template function. The `index` points to the
 *   `template` instruction index. A `block` that matches the sub-template in which it was declared.
 *
 * @param index A unique index of the translation in the static block.
 * @param messageIndex An index of the translation message from the `def.consts` array.
 * @param subTemplateIndex Optional sub-template index in the `message`.
 *
 * @codeGenApi
 */
function ɵɵi18n(index, messageIndex, subTemplateIndex) {
  ɵɵi18nStart(index, messageIndex, subTemplateIndex);
  ɵɵi18nEnd();
}
/**
 * Marks a list of attributes as translatable.
 *
 * @param index A unique index in the static block
 * @param values
 *
 * @codeGenApi
 */
function ɵɵi18nAttributes(index, attrsIndex) {
  const tView = getTView();
  ngDevMode && assertDefined(tView, `tView should be defined`);
  const attrs = getConstant(tView.consts, attrsIndex);
  i18nAttributesFirstPass(tView, index + HEADER_OFFSET, attrs);
}
/**
 * Stores the values of the bindings during each update cycle in order to determine if we need to
 * update the translated nodes.
 *
 * @param value The binding's value
 * @returns This function returns itself so that it may be chained
 * (e.g. `i18nExp(ctx.name)(ctx.title)`)
 *
 * @codeGenApi
 */
function ɵɵi18nExp(value) {
  const lView = getLView();
  setMaskBit(bindingUpdated(lView, nextBindingIndex(), value));
  return ɵɵi18nExp;
}
/**
 * Updates a translation block or an i18n attribute when the bindings have changed.
 *
 * @param index Index of either {@link i18nStart} (translation block) or {@link i18nAttributes}
 * (i18n attribute) on which it should update the content.
 *
 * @codeGenApi
 */
function ɵɵi18nApply(index) {
  applyI18n(getTView(), getLView(), index + HEADER_OFFSET);
}
/**
 * Handles message string post-processing for internationalization.
 *
 * Handles message string post-processing by transforming it from intermediate
 * format (that might contain some markers that we need to replace) to the final
 * form, consumable by i18nStart instruction. Post processing steps include:
 *
 * 1. Resolve all multi-value cases (like [�*1:1��#2:1�|�#4:1�|�5�])
 * 2. Replace all ICU vars (like "VAR_PLURAL")
 * 3. Replace all placeholders used inside ICUs in a form of {PLACEHOLDER}
 * 4. Replace all ICU references with corresponding values (like �ICU_EXP_ICU_1�)
 *    in case multiple ICUs have the same placeholder name
 *
 * @param message Raw translation string for post processing
 * @param replacements Set of replacements that should be applied
 *
 * @returns Transformed string that can be consumed by i18nStart instruction
 *
 * @codeGenApi
 */
function ɵɵi18nPostprocess(message, replacements = {}) {
  return i18nPostprocess(message, replacements);
}

/**
 * Adds an event listener to the current node.
 *
 * If an output exists on one of the node's directives, it also subscribes to the output
 * and saves the subscription for later cleanup.
 *
 * @param eventName Name of the event
 * @param listenerFn The function to be called when event emits
 * @param useCapture Whether or not to use capture in event listener - this argument is a reminder
 *     from the Renderer3 infrastructure and should be removed from the instruction arguments
 * @param eventTargetResolver Function that returns global target information in case this listener
 * should be attached to a global object like window, document or body
 *
 * @codeGenApi
 */
function ɵɵlistener(eventName, listenerFn, useCapture, eventTargetResolver) {
  const lView = getLView();
  const tView = getTView();
  const tNode = getCurrentTNode();
  listenerInternal(tView, lView, lView[RENDERER], tNode, eventName, listenerFn, eventTargetResolver);
  return ɵɵlistener;
}
/**
 * Registers a synthetic host listener (e.g. `(@foo.start)`) on a component or directive.
 *
 * This instruction is for compatibility purposes and is designed to ensure that a
 * synthetic host listener (e.g. `@HostListener('@foo.start')`) properly gets rendered
 * in the component's renderer. Normally all host listeners are evaluated with the
 * parent component's renderer, but, in the case of animation @triggers, they need
 * to be evaluated with the sub component's renderer (because that's where the
 * animation triggers are defined).
 *
 * Do not use this instruction as a replacement for `listener`. This instruction
 * only exists to ensure compatibility with the ViewEngine's host binding behavior.
 *
 * @param eventName Name of the event
 * @param listenerFn The function to be called when event emits
 * @param useCapture Whether or not to use capture in event listener
 * @param eventTargetResolver Function that returns global target information in case this listener
 * should be attached to a global object like window, document or body
 *
 * @codeGenApi
 */
function ɵɵsyntheticHostListener(eventName, listenerFn) {
  const tNode = getCurrentTNode();
  const lView = getLView();
  const tView = getTView();
  const currentDef = getCurrentDirectiveDef(tView.data);
  const renderer = loadComponentRenderer(currentDef, tNode, lView);
  listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn);
  return ɵɵsyntheticHostListener;
}
/**
 * A utility function that checks if a given element has already an event handler registered for an
 * event with a specified name. The TView.cleanup data structure is used to find out which events
 * are registered for a given element.
 */
function findExistingListener(tView, lView, eventName, tNodeIdx) {
  const tCleanup = tView.cleanup;
  if (tCleanup != null) {
    for (let i = 0; i < tCleanup.length - 1; i += 2) {
      const cleanupEventName = tCleanup[i];
      if (cleanupEventName === eventName && tCleanup[i + 1] === tNodeIdx) {
        // We have found a matching event name on the same node but it might not have been
        // registered yet, so we must explicitly verify entries in the LView cleanup data
        // structures.
        const lCleanup = lView[CLEANUP];
        const listenerIdxInLCleanup = tCleanup[i + 2];
        return lCleanup.length > listenerIdxInLCleanup ? lCleanup[listenerIdxInLCleanup] : null;
      }
      // TView.cleanup can have a mix of 4-elements entries (for event handler cleanups) or
      // 2-element entries (for directive and queries destroy hooks). As such we can encounter
      // blocks of 4 or 2 items in the tView.cleanup and this is why we iterate over 2 elements
      // first and jump another 2 elements if we detect listeners cleanup (4 elements). Also check
      // documentation of TView.cleanup for more details of this data structure layout.
      if (typeof cleanupEventName === 'string') {
        i += 2;
      }
    }
  }
  return null;
}
function listenerInternal(tView, lView, renderer, tNode, eventName, listenerFn, eventTargetResolver) {
  const isTNodeDirectiveHost = isDirectiveHost(tNode);
  const firstCreatePass = tView.firstCreatePass;
  const tCleanup = firstCreatePass && getOrCreateTViewCleanup(tView);
  const context = lView[CONTEXT];
  // When the ɵɵlistener instruction was generated and is executed we know that there is either a
  // native listener or a directive output on this element. As such we we know that we will have to
  // register a listener and store its cleanup function on LView.
  const lCleanup = getOrCreateLViewCleanup(lView);
  ngDevMode && assertTNodeType(tNode, 3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */);
  let processOutputs = true;
  // Adding a native event listener is applicable when:
  // - The corresponding TNode represents a DOM element.
  // - The event target has a resolver (usually resulting in a global object,
  //   such as `window` or `document`).
  if (tNode.type & 3 /* TNodeType.AnyRNode */ || eventTargetResolver) {
    const native = getNativeByTNode(tNode, lView);
    const target = eventTargetResolver ? eventTargetResolver(native) : native;
    const lCleanupIndex = lCleanup.length;
    const idxOrTargetGetter = eventTargetResolver ? _lView => eventTargetResolver(unwrapRNode(_lView[tNode.index])) : tNode.index;
    // In order to match current behavior, native DOM event listeners must be added for all
    // events (including outputs).
    // There might be cases where multiple directives on the same element try to register an event
    // handler function for the same event. In this situation we want to avoid registration of
    // several native listeners as each registration would be intercepted by NgZone and
    // trigger change detection. This would mean that a single user action would result in several
    // change detections being invoked. To avoid this situation we want to have only one call to
    // native handler registration (for the same element and same type of event).
    //
    // In order to have just one native event handler in presence of multiple handler functions,
    // we just register a first handler function as a native event listener and then chain
    // (coalesce) other handler functions on top of the first native handler function.
    let existingListener = null;
    // Please note that the coalescing described here doesn't happen for events specifying an
    // alternative target (ex. (document:click)) - this is to keep backward compatibility with the
    // view engine.
    // Also, we don't have to search for existing listeners is there are no directives
    // matching on a given node as we can't register multiple event handlers for the same event in
    // a template (this would mean having duplicate attributes).
    if (!eventTargetResolver && isTNodeDirectiveHost) {
      existingListener = findExistingListener(tView, lView, eventName, tNode.index);
    }
    if (existingListener !== null) {
      // Attach a new listener to coalesced listeners list, maintaining the order in which
      // listeners are registered. For performance reasons, we keep a reference to the last
      // listener in that list (in `__ngLastListenerFn__` field), so we can avoid going through
      // the entire set each time we need to add a new listener.
      const lastListenerFn = existingListener.__ngLastListenerFn__ || existingListener;
      lastListenerFn.__ngNextListenerFn__ = listenerFn;
      existingListener.__ngLastListenerFn__ = listenerFn;
      processOutputs = false;
    } else {
      listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
      const cleanupFn = renderer.listen(target, eventName, listenerFn);
      ngDevMode && ngDevMode.rendererAddEventListener++;
      lCleanup.push(listenerFn, cleanupFn);
      tCleanup && tCleanup.push(eventName, idxOrTargetGetter, lCleanupIndex, lCleanupIndex + 1);
    }
  } else {
    // Even if there is no native listener to add, we still need to wrap the listener so that OnPush
    // ancestors are marked dirty when an event occurs.
    listenerFn = wrapListener(tNode, lView, context, listenerFn, false /** preventDefault */);
  }
  // subscribe to directive outputs
  const outputs = tNode.outputs;
  let props;
  if (processOutputs && outputs !== null && (props = outputs[eventName])) {
    const propsLength = props.length;
    if (propsLength) {
      for (let i = 0; i < propsLength; i += 2) {
        const index = props[i];
        ngDevMode && assertIndexInRange(lView, index);
        const minifiedName = props[i + 1];
        const directiveInstance = lView[index];
        const output = directiveInstance[minifiedName];
        if (ngDevMode && !isOutputSubscribable(output)) {
          throw new Error(`@Output ${minifiedName} not initialized in '${directiveInstance.constructor.name}'.`);
        }
        const subscription = output.subscribe(listenerFn);
        const idx = lCleanup.length;
        lCleanup.push(listenerFn, subscription);
        tCleanup && tCleanup.push(eventName, tNode.index, idx, -(idx + 1));
      }
    }
  }
}
function executeListenerWithErrorHandling(lView, context, listenerFn, e) {
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  try {
    profiler(6 /* ProfilerEvent.OutputStart */, context, listenerFn);
    // Only explicitly returning false from a listener should preventDefault
    return listenerFn(e) !== false;
  } catch (error) {
    handleError(lView, error);
    return false;
  } finally {
    profiler(7 /* ProfilerEvent.OutputEnd */, context, listenerFn);
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}
/**
 * Wraps an event listener with a function that marks ancestors dirty and prevents default behavior,
 * if applicable.
 *
 * @param tNode The TNode associated with this listener
 * @param lView The LView that contains this listener
 * @param listenerFn The listener function to call
 * @param wrapWithPreventDefault Whether or not to prevent default behavior
 * (the procedural renderer does this already, so in those cases, we should skip)
 */
function wrapListener(tNode, lView, context, listenerFn, wrapWithPreventDefault) {
  // Note: we are performing most of the work in the listener function itself
  // to optimize listener registration.
  return function wrapListenerIn_markDirtyAndPreventDefault(e) {
    // Ivy uses `Function` as a special token that allows us to unwrap the function
    // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`.
    if (e === Function) {
      return listenerFn;
    }
    // In order to be backwards compatible with View Engine, events on component host nodes
    // must also mark the component view itself dirty (i.e. the view that it owns).
    const startView = tNode.componentOffset > -1 ? getComponentLViewByIndex(tNode.index, lView) : lView;
    markViewDirty(startView);
    let result = executeListenerWithErrorHandling(lView, context, listenerFn, e);
    // A just-invoked listener function might have coalesced listeners so we need to check for
    // their presence and invoke as needed.
    let nextListenerFn = wrapListenerIn_markDirtyAndPreventDefault.__ngNextListenerFn__;
    while (nextListenerFn) {
      // We should prevent default if any of the listeners explicitly return false
      result = executeListenerWithErrorHandling(lView, context, nextListenerFn, e) && result;
      nextListenerFn = nextListenerFn.__ngNextListenerFn__;
    }
    if (wrapWithPreventDefault && result === false) {
      e.preventDefault();
    }
    return result;
  };
}
/**
 * Whether the given value represents a subscribable output.
 *
 * For example, an `EventEmitter, a `Subject`, an `Observable` or an
 * `OutputEmitter`.
 */
function isOutputSubscribable(value) {
  return value != null && typeof value.subscribe === 'function';
}

/**
 * Retrieves a context at the level specified and saves it as the global, contextViewData.
 * Will get the next level up if level is not specified.
 *
 * This is used to save contexts of parent views so they can be bound in embedded views, or
 * in conjunction with reference() to bind a ref from a parent view.
 *
 * @param level The relative level of the view from which to grab context compared to contextVewData
 * @returns context
 *
 * @codeGenApi
 */
function ɵɵnextContext(level = 1) {
  return nextContextImpl(level);
}

/**
 * Checks a given node against matching projection slots and returns the
 * determined slot index. Returns "null" if no slot matched the given node.
 *
 * This function takes into account the parsed ngProjectAs selector from the
 * node's attributes. If present, it will check whether the ngProjectAs selector
 * matches any of the projection slot selectors.
 */
function matchingProjectionSlotIndex(tNode, projectionSlots) {
  let wildcardNgContentIndex = null;
  const ngProjectAsAttrVal = getProjectAsAttrValue(tNode);
  for (let i = 0; i < projectionSlots.length; i++) {
    const slotValue = projectionSlots[i];
    // The last wildcard projection slot should match all nodes which aren't matching
    // any selector. This is necessary to be backwards compatible with view engine.
    if (slotValue === '*') {
      wildcardNgContentIndex = i;
      continue;
    }
    // If we ran into an `ngProjectAs` attribute, we should match its parsed selector
    // to the list of selectors, otherwise we fall back to matching against the node.
    if (ngProjectAsAttrVal === null ? isNodeMatchingSelectorList(tNode, slotValue, /* isProjectionMode */true) : isSelectorInSelectorList(ngProjectAsAttrVal, slotValue)) {
      return i; // first matching selector "captures" a given node
    }
  }
  return wildcardNgContentIndex;
}
/**
 * Instruction to distribute projectable nodes among <ng-content> occurrences in a given template.
 * It takes all the selectors from the entire component's template and decides where
 * each projected node belongs (it re-distributes nodes among "buckets" where each "bucket" is
 * backed by a selector).
 *
 * This function requires CSS selectors to be provided in 2 forms: parsed (by a compiler) and text,
 * un-parsed form.
 *
 * The parsed form is needed for efficient matching of a node against a given CSS selector.
 * The un-parsed, textual form is needed for support of the ngProjectAs attribute.
 *
 * Having a CSS selector in 2 different formats is not ideal, but alternatives have even more
 * drawbacks:
 * - having only a textual form would require runtime parsing of CSS selectors;
 * - we can't have only a parsed as we can't re-construct textual form from it (as entered by a
 * template author).
 *
 * @param projectionSlots? A collection of projection slots. A projection slot can be based
 *        on a parsed CSS selectors or set to the wildcard selector ("*") in order to match
 *        all nodes which do not match any selector. If not specified, a single wildcard
 *        selector projection slot will be defined.
 *
 * @codeGenApi
 */
function ɵɵprojectionDef(projectionSlots) {
  const componentNode = getLView()[DECLARATION_COMPONENT_VIEW][T_HOST];
  if (!componentNode.projection) {
    // If no explicit projection slots are defined, fall back to a single
    // projection slot with the wildcard selector.
    const numProjectionSlots = projectionSlots ? projectionSlots.length : 1;
    const projectionHeads = componentNode.projection = newArray(numProjectionSlots, null);
    const tails = projectionHeads.slice();
    let componentChild = componentNode.child;
    while (componentChild !== null) {
      const slotIndex = projectionSlots ? matchingProjectionSlotIndex(componentChild, projectionSlots) : 0;
      if (slotIndex !== null) {
        if (tails[slotIndex]) {
          tails[slotIndex].projectionNext = componentChild;
        } else {
          projectionHeads[slotIndex] = componentChild;
        }
        tails[slotIndex] = componentChild;
      }
      componentChild = componentChild.next;
    }
  }
}
/**
 * Inserts previously re-distributed projected nodes. This instruction must be preceded by a call
 * to the projectionDef instruction.
 *
 * @param nodeIndex
 * @param selectorIndex:
 *        - 0 when the selector is `*` (or unspecified as this is the default value),
 *        - 1 based index of the selector from the {@link projectionDef}
 *
 * @codeGenApi
 */
function ɵɵprojection(nodeIndex, selectorIndex = 0, attrs) {
  const lView = getLView();
  const tView = getTView();
  const tProjectionNode = getOrCreateTNode(tView, HEADER_OFFSET + nodeIndex, 16 /* TNodeType.Projection */, null, attrs || null);
  // We can't use viewData[HOST_NODE] because projection nodes can be nested in embedded views.
  if (tProjectionNode.projection === null) tProjectionNode.projection = selectorIndex;
  // `<ng-content>` has no content
  setCurrentTNodeAsNotParent();
  const hydrationInfo = lView[HYDRATION];
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1();
  if (isNodeCreationMode && (tProjectionNode.flags & 32 /* TNodeFlags.isDetached */) !== 32 /* TNodeFlags.isDetached */) {
    // re-distribution of projectable nodes is stored on a component's view level
    applyProjection(tView, lView, tProjectionNode);
  }
}

/**
 *
 * Update an interpolated property on an element with a lone bound value
 *
 * Used when the value passed to a property has 1 interpolated value in it, an no additional text
 * surrounds that interpolated value:
 *
 * ```html
 * <div title="{{v0}}"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate('title', v0);
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate(propName, v0, sanitizer) {
  ɵɵpropertyInterpolate1(propName, '', v0, '', sanitizer);
  return ɵɵpropertyInterpolate;
}
/**
 *
 * Update an interpolated property on an element with single bound value surrounded by text.
 *
 * Used when the value passed to a property has 1 interpolated value in it:
 *
 * ```html
 * <div title="prefix{{v0}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate1('title', 'prefix', v0, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate1(propName, prefix, v0, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 1, prefix, suffix);
  }
  return ɵɵpropertyInterpolate1;
}
/**
 *
 * Update an interpolated property on an element with 2 bound values surrounded by text.
 *
 * Used when the value passed to a property has 2 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate2('title', 'prefix', v0, '-', v1, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate2(propName, prefix, v0, i0, v1, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 2, prefix, i0, suffix);
  }
  return ɵɵpropertyInterpolate2;
}
/**
 *
 * Update an interpolated property on an element with 3 bound values surrounded by text.
 *
 * Used when the value passed to a property has 3 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate3(
 * 'title', 'prefix', v0, '-', v1, '-', v2, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate3(propName, prefix, v0, i0, v1, i1, v2, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 3, prefix, i0, i1, suffix);
  }
  return ɵɵpropertyInterpolate3;
}
/**
 *
 * Update an interpolated property on an element with 4 bound values surrounded by text.
 *
 * Used when the value passed to a property has 4 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate4(
 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate4(propName, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 4, prefix, i0, i1, i2, suffix);
  }
  return ɵɵpropertyInterpolate4;
}
/**
 *
 * Update an interpolated property on an element with 5 bound values surrounded by text.
 *
 * Used when the value passed to a property has 5 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate5(
 * 'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate5(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 5, prefix, i0, i1, i2, i3, suffix);
  }
  return ɵɵpropertyInterpolate5;
}
/**
 *
 * Update an interpolated property on an element with 6 bound values surrounded by text.
 *
 * Used when the value passed to a property has 6 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate6(
 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate6(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 6, prefix, i0, i1, i2, i3, i4, suffix);
  }
  return ɵɵpropertyInterpolate6;
}
/**
 *
 * Update an interpolated property on an element with 7 bound values surrounded by text.
 *
 * Used when the value passed to a property has 7 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate7(
 *    'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate7(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 7, prefix, i0, i1, i2, i3, i4, i5, suffix);
  }
  return ɵɵpropertyInterpolate7;
}
/**
 *
 * Update an interpolated property on an element with 8 bound values surrounded by text.
 *
 * Used when the value passed to a property has 8 interpolated values in it:
 *
 * ```html
 * <div title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolate8(
 *  'title', 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param i6 Static value used for concatenation only.
 * @param v7 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolate8(propName, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - 8, prefix, i0, i1, i2, i3, i4, i5, i6, suffix);
  }
  return ɵɵpropertyInterpolate8;
}
/**
 * Update an interpolated property on an element with 9 or more bound values surrounded by text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div
 *  title="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix"></div>
 * ```
 *
 * Its compiled representation is::
 *
 * ```ts
 * ɵɵpropertyInterpolateV(
 *  'title', ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
 *  'suffix']);
 * ```
 *
 * If the property name also exists as an input property on one of the element's directives,
 * the component property will be set instead of the element property. This check must
 * be conducted at runtime so child components that add new `@Inputs` don't have to be re-compiled.
 *
 * @param propName The name of the property to update.
 * @param values The collection of values and the strings in between those values, beginning with a
 * string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
 * @param sanitizer An optional sanitizer function
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵpropertyInterpolateV(propName, values, sanitizer) {
  const lView = getLView();
  const interpolatedValue = interpolationV(lView, values);
  if (interpolatedValue !== NO_CHANGE) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, interpolatedValue, lView[RENDERER], sanitizer, false);
    if (ngDevMode) {
      const interpolationInBetween = [values[0]]; // prefix
      for (let i = 2; i < values.length; i += 2) {
        interpolationInBetween.push(values[i]);
      }
      storePropertyBindingMetadata(tView.data, tNode, propName, getBindingIndex() - interpolationInBetween.length + 1, ...interpolationInBetween);
    }
  }
  return ɵɵpropertyInterpolateV;
}

/**
 * Registers a QueryList, associated with a content query, for later refresh (part of a view
 * refresh).
 *
 * @param directiveIndex Current directive index
 * @param predicate The type for which the query will search
 * @param flags Flags associated with the query
 * @param read What to save in the query
 * @returns QueryList<T>
 *
 * @codeGenApi
 */
function ɵɵcontentQuery(directiveIndex, predicate, flags, read) {
  createContentQuery(directiveIndex, predicate, flags, read);
}
/**
 * Creates a new view query by initializing internal data structures.
 *
 * @param predicate The type for which the query will search
 * @param flags Flags associated with the query
 * @param read What to save in the query
 *
 * @codeGenApi
 */
function ɵɵviewQuery(predicate, flags, read) {
  createViewQuery(predicate, flags, read);
}
/**
 * Refreshes a query by combining matches from all active views and removing matches from deleted
 * views.
 *
 * @returns `true` if a query got dirty during change detection or if this is a static query
 * resolving in creation mode, `false` otherwise.
 *
 * @codeGenApi
 */
function ɵɵqueryRefresh(queryList) {
  const lView = getLView();
  const tView = getTView();
  const queryIndex = getCurrentQueryIndex();
  setCurrentQueryIndex(queryIndex + 1);
  const tQuery = getTQuery(tView, queryIndex);
  if (queryList.dirty && isCreationMode(lView) === ((tQuery.metadata.flags & 2 /* QueryFlags.isStatic */) === 2 /* QueryFlags.isStatic */)) {
    if (tQuery.matches === null) {
      queryList.reset([]);
    } else {
      const result = getQueryResults(lView, queryIndex);
      queryList.reset(result, unwrapElementRef);
      queryList.notifyOnChanges();
    }
    return true;
  }
  return false;
}
/**
 * Loads a QueryList corresponding to the current view or content query.
 *
 * @codeGenApi
 */
function ɵɵloadQuery() {
  return loadQueryInternal(getLView(), getCurrentQueryIndex());
}

/**
 * Creates a new content query and binds it to a signal created by an authoring function.
 *
 * @param directiveIndex Current directive index
 * @param target The target signal to which the query should be bound
 * @param predicate The type for which the query will search
 * @param flags Flags associated with the query
 * @param read What to save in the query
 *
 * @codeGenApi
 */
function ɵɵcontentQuerySignal(directiveIndex, target, predicate, flags, read) {
  bindQueryToSignal(target, createContentQuery(directiveIndex, predicate, flags, read));
}
/**
 * Creates a new view query by initializing internal data structures and binding a new query to the
 * target signal.
 *
 * @param target The target signal to assign the query results to.
 * @param predicate The type or label that should match a given query
 * @param flags Flags associated with the query
 * @param read What to save in the query
 *
 * @codeGenApi
 */
function ɵɵviewQuerySignal(target, predicate, flags, read) {
  bindQueryToSignal(target, createViewQuery(predicate, flags, read));
}
/**
 * Advances the current query index by a specified offset.
 *
 * Adjusting the current query index is necessary in cases where a given directive has a mix of
 * zone-based and signal-based queries. The signal-based queries don't require tracking of the
 * current index (those are refreshed on demand and not during change detection) so this instruction
 * is only necessary for backward-compatibility.
 *
 * @param index offset to apply to the current query index (defaults to 1)
 *
 * @codeGenApi
 */
function ɵɵqueryAdvance(indexOffset = 1) {
  setCurrentQueryIndex(getCurrentQueryIndex() + indexOffset);
}

/** Store a value in the `data` at a given `index`. */
function store(tView, lView, index, value) {
  // We don't store any static data for local variables, so the first time
  // we see the template, we should store as null to avoid a sparse array
  if (index >= tView.data.length) {
    tView.data[index] = null;
    tView.blueprint[index] = null;
  }
  lView[index] = value;
}
/**
 * Retrieves a local reference from the current contextViewData.
 *
 * If the reference to retrieve is in a parent view, this instruction is used in conjunction
 * with a nextContext() call, which walks up the tree and updates the contextViewData instance.
 *
 * @param index The index of the local ref in contextViewData.
 *
 * @codeGenApi
 */
function ɵɵreference(index) {
  const contextLView = getContextLView();
  return load(contextLView, HEADER_OFFSET + index);
}

/**
 *
 * Update an interpolated style on an element with single bound value surrounded by text.
 *
 * Used when the value passed to a property has 1 interpolated value in it:
 *
 * ```html
 * <div style="key: {{v0}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate1('key: ', v0, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate1(prefix, v0, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 2 bound values surrounded by text.
 *
 * Used when the value passed to a property has 2 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate2('key: ', v0, '; key1: ', v1, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate2(prefix, v0, i0, v1, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 3 bound values surrounded by text.
 *
 * Used when the value passed to a property has 3 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key2: {{v1}}; key2: {{v2}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate3(
 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 4 bound values surrounded by text.
 *
 * Used when the value passed to a property has 4 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate4(
 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 5 bound values surrounded by text.
 *
 * Used when the value passed to a property has 5 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate5(
 *     'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 6 bound values surrounded by text.
 *
 * Used when the value passed to a property has 6 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}};
 *             key5: {{v5}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate6(
 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
 *    'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 7 bound values surrounded by text.
 *
 * Used when the value passed to a property has 7 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
 *             key6: {{v6}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate7(
 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
 *    '; key6: ', v6, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 *
 * Update an interpolated style on an element with 8 bound values surrounded by text.
 *
 * Used when the value passed to a property has 8 interpolated values in it:
 *
 * ```html
 * <div style="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
 *             key6: {{v6}}; key7: {{v7}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolate8(
 *    'key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
 *    '; key6: ', v6, '; key7: ', v7, 'suffix');
 * ```
 *
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param i6 Static value used for concatenation only.
 * @param v7 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @codeGenApi
 */
function ɵɵstyleMapInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
  const lView = getLView();
  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  ɵɵstyleMap(interpolatedValue);
}
/**
 * Update an interpolated style on an element with 9 or more bound values surrounded by text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div
 *  class="key: {{v0}}; key1: {{v1}}; key2: {{v2}}; key3: {{v3}}; key4: {{v4}}; key5: {{v5}};
 *         key6: {{v6}}; key7: {{v7}}; key8: {{v8}}; key9: {{v9}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstyleMapInterpolateV(
 *    ['key: ', v0, '; key1: ', v1, '; key2: ', v2, '; key3: ', v3, '; key4: ', v4, '; key5: ', v5,
 *     '; key6: ', v6, '; key7: ', v7, '; key8: ', v8, '; key9: ', v9, 'suffix']);
 * ```
 *.
 * @param values The collection of values and the strings in-between those values, beginning with
 * a string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '; key2: ', value1, '; key2: ', value2, ..., value99, 'suffix']`)
 * @codeGenApi
 */
function ɵɵstyleMapInterpolateV(values) {
  const lView = getLView();
  const interpolatedValue = interpolationV(lView, values);
  ɵɵstyleMap(interpolatedValue);
}

/**
 *
 * Update an interpolated style property on an element with single bound value surrounded by text.
 *
 * Used when the value passed to a property has 1 interpolated value in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate1(0, 'prefix', v0, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate1(prop, prefix, v0, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation1(lView, prefix, v0, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate1;
}
/**
 *
 * Update an interpolated style property on an element with 2 bound values surrounded by text.
 *
 * Used when the value passed to a property has 2 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate2(0, 'prefix', v0, '-', v1, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate2(prop, prefix, v0, i0, v1, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation2(lView, prefix, v0, i0, v1, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate2;
}
/**
 *
 * Update an interpolated style property on an element with 3 bound values surrounded by text.
 *
 * Used when the value passed to a property has 3 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate3(0, 'prefix', v0, '-', v1, '-', v2, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate3(prop, prefix, v0, i0, v1, i1, v2, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate3;
}
/**
 *
 * Update an interpolated style property on an element with 4 bound values surrounded by text.
 *
 * Used when the value passed to a property has 4 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate4(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate4(prop, prefix, v0, i0, v1, i1, v2, i2, v3, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate4;
}
/**
 *
 * Update an interpolated style property on an element with 5 bound values surrounded by text.
 *
 * Used when the value passed to a property has 5 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate5(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate5(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate5;
}
/**
 *
 * Update an interpolated style property on an element with 6 bound values surrounded by text.
 *
 * Used when the value passed to a property has 6 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate6(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate6(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate6;
}
/**
 *
 * Update an interpolated style property on an element with 7 bound values surrounded by text.
 *
 * Used when the value passed to a property has 7 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate7(
 *    0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate7(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate7;
}
/**
 *
 * Update an interpolated style property on an element with 8 bound values surrounded by text.
 *
 * Used when the value passed to a property has 8 interpolated values in it:
 *
 * ```html
 * <div style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix"></div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolate8(0, 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6,
 * '-', v7, 'suffix');
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`.
 * @param prefix Static value used for concatenation only.
 * @param v0 Value checked for change.
 * @param i0 Static value used for concatenation only.
 * @param v1 Value checked for change.
 * @param i1 Static value used for concatenation only.
 * @param v2 Value checked for change.
 * @param i2 Static value used for concatenation only.
 * @param v3 Value checked for change.
 * @param i3 Static value used for concatenation only.
 * @param v4 Value checked for change.
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change.
 * @param i5 Static value used for concatenation only.
 * @param v6 Value checked for change.
 * @param i6 Static value used for concatenation only.
 * @param v7 Value checked for change.
 * @param suffix Static value used for concatenation only.
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolate8(prop, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolate8;
}
/**
 * Update an interpolated style property on an element with 9 or more bound values surrounded by
 * text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div
 *  style.color="prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix">
 * </div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵstylePropInterpolateV(
 *  0, ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
 *  'suffix']);
 * ```
 *
 * @param styleIndex Index of style to update. This index value refers to the
 *        index of the style in the style bindings array that was passed into
 *        `styling`..
 * @param values The collection of values and the strings in-between those values, beginning with
 * a string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
 * @param valueSuffix Optional suffix. Used with scalar values to add unit such as `px`.
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵstylePropInterpolateV(prop, values, valueSuffix) {
  const lView = getLView();
  const interpolatedValue = interpolationV(lView, values);
  checkStylingProperty(prop, interpolatedValue, valueSuffix, false);
  return ɵɵstylePropInterpolateV;
}

/**
 * Create static text node
 *
 * @param index Index of the node in the data array
 * @param value Static string value to write.
 *
 * @codeGenApi
 */
function ɵɵtext(index, value = '') {
  const lView = getLView();
  const tView = getTView();
  const adjustedIndex = index + HEADER_OFFSET;
  ngDevMode && assertEqual(getBindingIndex(), tView.bindingStartIndex, 'text nodes should be created before any bindings');
  ngDevMode && assertIndexInRange(lView, adjustedIndex);
  const tNode = tView.firstCreatePass ? getOrCreateTNode(tView, adjustedIndex, 1 /* TNodeType.Text */, value, null) : tView.data[adjustedIndex];
  const textNative = _locateOrCreateTextNode(tView, lView, tNode, value, index);
  lView[adjustedIndex] = textNative;
  if (wasLastNodeCreated()) {
    appendChild(tView, lView, textNative, tNode);
  }
  // Text nodes are self closing.
  setCurrentTNode(tNode, false);
}
let _locateOrCreateTextNode = (tView, lView, tNode, value, index) => {
  lastNodeWasCreated(true);
  return createTextNode(lView[RENDERER], value);
};
/**
 * Enables hydration code path (to lookup existing elements in DOM)
 * in addition to the regular creation mode of text nodes.
 */
function locateOrCreateTextNodeImpl(tView, lView, tNode, value, index) {
  const hydrationInfo = lView[HYDRATION];
  const isNodeCreationMode = !hydrationInfo || isInSkipHydrationBlock$1() || isDetachedByI18n(tNode) || isDisconnectedNode$1(hydrationInfo, index);
  lastNodeWasCreated(isNodeCreationMode);
  // Regular creation mode.
  if (isNodeCreationMode) {
    return createTextNode(lView[RENDERER], value);
  }
  // Hydration mode, looking up an existing element in DOM.
  const textNative = locateNextRNode(hydrationInfo, tView, lView, tNode);
  ngDevMode && validateMatchingNode(textNative, Node.TEXT_NODE, null, lView, tNode);
  ngDevMode && markRNodeAsClaimedByHydration(textNative);
  return textNative;
}
function enableLocateOrCreateTextNodeImpl() {
  _locateOrCreateTextNode = locateOrCreateTextNodeImpl;
}

/**
 *
 * Update text content with a lone bound value
 *
 * Used when a text node has 1 interpolated value in it, an no additional text
 * surrounds that interpolated value:
 *
 * ```html
 * <div>{{v0}}</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate(v0);
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate(v0) {
  ɵɵtextInterpolate1('', v0, '');
  return ɵɵtextInterpolate;
}
/**
 *
 * Update text content with single bound value surrounded by other text.
 *
 * Used when a text node has 1 interpolated value in it:
 *
 * ```html
 * <div>prefix{{v0}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate1('prefix', v0, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate1(prefix, v0, suffix) {
  const lView = getLView();
  const interpolated = interpolation1(lView, prefix, v0, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate1;
}
/**
 *
 * Update text content with 2 bound values surrounded by other text.
 *
 * Used when a text node has 2 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate2('prefix', v0, '-', v1, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate2(prefix, v0, i0, v1, suffix) {
  const lView = getLView();
  const interpolated = interpolation2(lView, prefix, v0, i0, v1, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate2;
}
/**
 *
 * Update text content with 3 bound values surrounded by other text.
 *
 * Used when a text node has 3 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate3(
 * 'prefix', v0, '-', v1, '-', v2, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate3(prefix, v0, i0, v1, i1, v2, suffix) {
  const lView = getLView();
  const interpolated = interpolation3(lView, prefix, v0, i0, v1, i1, v2, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate3;
}
/**
 *
 * Update text content with 4 bound values surrounded by other text.
 *
 * Used when a text node has 4 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate4(
 * 'prefix', v0, '-', v1, '-', v2, '-', v3, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see ɵɵtextInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate4(prefix, v0, i0, v1, i1, v2, i2, v3, suffix) {
  const lView = getLView();
  const interpolated = interpolation4(lView, prefix, v0, i0, v1, i1, v2, i2, v3, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate4;
}
/**
 *
 * Update text content with 5 bound values surrounded by other text.
 *
 * Used when a text node has 5 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate5(
 * 'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate5(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix) {
  const lView = getLView();
  const interpolated = interpolation5(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate5;
}
/**
 *
 * Update text content with 6 bound values surrounded by other text.
 *
 * Used when a text node has 6 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate6(
 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, 'suffix');
 * ```
 *
 * @param i4 Static value used for concatenation only.
 * @param v5 Value checked for change. @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate6(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix) {
  const lView = getLView();
  const interpolated = interpolation6(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate6;
}
/**
 *
 * Update text content with 7 bound values surrounded by other text.
 *
 * Used when a text node has 7 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate7(
 *    'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate7(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix) {
  const lView = getLView();
  const interpolated = interpolation7(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate7;
}
/**
 *
 * Update text content with 8 bound values surrounded by other text.
 *
 * Used when a text node has 8 interpolated values in it:
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolate8(
 *  'prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, 'suffix');
 * ```
 * @returns itself, so that it may be chained.
 * @see textInterpolateV
 * @codeGenApi
 */
function ɵɵtextInterpolate8(prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix) {
  const lView = getLView();
  const interpolated = interpolation8(lView, prefix, v0, i0, v1, i1, v2, i2, v3, i3, v4, i4, v5, i5, v6, i6, v7, suffix);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolate8;
}
/**
 * Update text content with 9 or more bound values other surrounded by text.
 *
 * Used when the number of interpolated values exceeds 8.
 *
 * ```html
 * <div>prefix{{v0}}-{{v1}}-{{v2}}-{{v3}}-{{v4}}-{{v5}}-{{v6}}-{{v7}}-{{v8}}-{{v9}}suffix</div>
 * ```
 *
 * Its compiled representation is:
 *
 * ```ts
 * ɵɵtextInterpolateV(
 *  ['prefix', v0, '-', v1, '-', v2, '-', v3, '-', v4, '-', v5, '-', v6, '-', v7, '-', v9,
 *  'suffix']);
 * ```
 *.
 * @param values The collection of values and the strings in between those values, beginning with
 * a string prefix and ending with a string suffix.
 * (e.g. `['prefix', value0, '-', value1, '-', value2, ..., value99, 'suffix']`)
 *
 * @returns itself, so that it may be chained.
 * @codeGenApi
 */
function ɵɵtextInterpolateV(values) {
  const lView = getLView();
  const interpolated = interpolationV(lView, values);
  if (interpolated !== NO_CHANGE) {
    textBindingInternal(lView, getSelectedIndex(), interpolated);
  }
  return ɵɵtextInterpolateV;
}

/*!
 * @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
 */
/**
 * Update a two-way bound property on a selected element.
 *
 * Operates on the element selected by index via the {@link select} instruction.
 *
 * @param propName Name of property.
 * @param value New value to write.
 * @param sanitizer An optional function used to sanitize the value.
 * @returns This function returns itself so that it may be chained
 * (e.g. `twoWayProperty('name', ctx.name)('title', ctx.title)`)
 *
 * @codeGenApi
 */
function ɵɵtwoWayProperty(propName, value, sanitizer) {
  // TODO(crisbeto): perf impact of re-evaluating this on each change detection?
  if (isWritableSignal(value)) {
    value = value();
  }
  const lView = getLView();
  const bindingIndex = nextBindingIndex();
  if (bindingUpdated(lView, bindingIndex, value)) {
    const tView = getTView();
    const tNode = getSelectedTNode();
    elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false);
    ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex);
  }
  return ɵɵtwoWayProperty;
}
/**
 * Function used inside two-way listeners to conditionally set the value of the bound expression.
 *
 * @param target Field on which to set the value.
 * @param value Value to be set to the field.
 *
 * @codeGenApi
 */
function ɵɵtwoWayBindingSet(target, value) {
  const canWrite = isWritableSignal(target);
  canWrite && target.set(value);
  return canWrite;
}
/**
 * Adds an event listener that updates a two-way binding to the current node.
 *
 * @param eventName Name of the event.
 * @param listenerFn The function to be called when event emits.
 *
 * @codeGenApi
 */
function ɵɵtwoWayListener(eventName, listenerFn) {
  const lView = getLView();
  const tView = getTView();
  const tNode = getCurrentTNode();
  listenerInternal(tView, lView, lView[RENDERER], tNode, eventName, listenerFn);
  return ɵɵtwoWayListener;
}

/*
 * This file re-exports all symbols contained in this directory.
 *
 * Why is this file not `index.ts`?
 *
 * There seems to be an inconsistent path resolution of an `index.ts` file
 * when only the parent directory is referenced. This could be due to the
 * node module resolution configuration differing from rollup and/or typescript.
 *
 * With commit
 * https://github.com/angular/angular/commit/d5e3f2c64bd13ce83e7c70788b7fc514ca4a9918
 * the `instructions.ts` file was moved to `instructions/instructions.ts` and an
 * `index.ts` file was used to re-export everything. Having had file names that were
 * importing from `instructions' directly (not the from the sub file or the `index.ts`
 * file) caused strange CI issues. `index.ts` had to be renamed to `all.ts` for this
 * to work.
 *
 * Jira Issue = FW-1184
 */

/**
 * Resolves the providers which are defined in the DirectiveDef.
 *
 * When inserting the tokens and the factories in their respective arrays, we can assume that
 * this method is called first for the component (if any), and then for other directives on the same
 * node.
 * As a consequence,the providers are always processed in that order:
 * 1) The view providers of the component
 * 2) The providers of the component
 * 3) The providers of the other directives
 * This matches the structure of the injectables arrays of a view (for each node).
 * So the tokens and the factories can be pushed at the end of the arrays, except
 * in one case for multi providers.
 *
 * @param def the directive definition
 * @param providers: Array of `providers`.
 * @param viewProviders: Array of `viewProviders`.
 */
function providersResolver(def, providers, viewProviders) {
  const tView = getTView();
  if (tView.firstCreatePass) {
    const isComponent = isComponentDef(def);
    // The list of view providers is processed first, and the flags are updated
    resolveProvider(viewProviders, tView.data, tView.blueprint, isComponent, true);
    // Then, the list of providers is processed, and the flags are updated
    resolveProvider(providers, tView.data, tView.blueprint, isComponent, false);
  }
}
/**
 * Resolves a provider and publishes it to the DI system.
 */
function resolveProvider(provider, tInjectables, lInjectablesBlueprint, isComponent, isViewProvider) {
  provider = resolveForwardRef(provider);
  if (Array.isArray(provider)) {
    // Recursively call `resolveProvider`
    // Recursion is OK in this case because this code will not be in hot-path once we implement
    // cloning of the initial state.
    for (let i = 0; i < provider.length; i++) {
      resolveProvider(provider[i], tInjectables, lInjectablesBlueprint, isComponent, isViewProvider);
    }
  } else {
    const tView = getTView();
    const lView = getLView();
    const tNode = getCurrentTNode();
    let token = isTypeProvider(provider) ? provider : resolveForwardRef(provider.provide);
    const providerFactory = providerToFactory(provider);
    if (ngDevMode) {
      const injector = new NodeInjector(tNode, lView);
      runInInjectorProfilerContext(injector, token, () => {
        emitProviderConfiguredEvent(provider, isViewProvider);
      });
    }
    const beginIndex = tNode.providerIndexes & 1048575 /* TNodeProviderIndexes.ProvidersStartIndexMask */;
    const endIndex = tNode.directiveStart;
    const cptViewProvidersCount = tNode.providerIndexes >> 20 /* TNodeProviderIndexes.CptViewProvidersCountShift */;
    if (isTypeProvider(provider) || !provider.multi) {
      // Single provider case: the factory is created and pushed immediately
      const factory = new NodeInjectorFactory(providerFactory, isViewProvider, ɵɵdirectiveInject);
      const existingFactoryIndex = indexOf(token, tInjectables, isViewProvider ? beginIndex : beginIndex + cptViewProvidersCount, endIndex);
      if (existingFactoryIndex === -1) {
        diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
        registerDestroyHooksIfSupported(tView, provider, tInjectables.length);
        tInjectables.push(token);
        tNode.directiveStart++;
        tNode.directiveEnd++;
        if (isViewProvider) {
          tNode.providerIndexes += 1048576 /* TNodeProviderIndexes.CptViewProvidersCountShifter */;
        }
        lInjectablesBlueprint.push(factory);
        lView.push(factory);
      } else {
        lInjectablesBlueprint[existingFactoryIndex] = factory;
        lView[existingFactoryIndex] = factory;
      }
    } else {
      // Multi provider case:
      // We create a multi factory which is going to aggregate all the values.
      // Since the output of such a factory depends on content or view injection,
      // we create two of them, which are linked together.
      //
      // The first one (for view providers) is always in the first block of the injectables array,
      // and the second one (for providers) is always in the second block.
      // This is important because view providers have higher priority. When a multi token
      // is being looked up, the view providers should be found first.
      // Note that it is not possible to have a multi factory in the third block (directive block).
      //
      // The algorithm to process multi providers is as follows:
      // 1) If the multi provider comes from the `viewProviders` of the component:
      //   a) If the special view providers factory doesn't exist, it is created and pushed.
      //   b) Else, the multi provider is added to the existing multi factory.
      // 2) If the multi provider comes from the `providers` of the component or of another
      // directive:
      //   a) If the multi factory doesn't exist, it is created and provider pushed into it.
      //      It is also linked to the multi factory for view providers, if it exists.
      //   b) Else, the multi provider is added to the existing multi factory.
      const existingProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex + cptViewProvidersCount, endIndex);
      const existingViewProvidersFactoryIndex = indexOf(token, tInjectables, beginIndex, beginIndex + cptViewProvidersCount);
      const doesProvidersFactoryExist = existingProvidersFactoryIndex >= 0 && lInjectablesBlueprint[existingProvidersFactoryIndex];
      const doesViewProvidersFactoryExist = existingViewProvidersFactoryIndex >= 0 && lInjectablesBlueprint[existingViewProvidersFactoryIndex];
      if (isViewProvider && !doesViewProvidersFactoryExist || !isViewProvider && !doesProvidersFactoryExist) {
        // Cases 1.a and 2.a
        diPublicInInjector(getOrCreateNodeInjectorForNode(tNode, lView), tView, token);
        const factory = multiFactory(isViewProvider ? multiViewProvidersFactoryResolver : multiProvidersFactoryResolver, lInjectablesBlueprint.length, isViewProvider, isComponent, providerFactory);
        if (!isViewProvider && doesViewProvidersFactoryExist) {
          lInjectablesBlueprint[existingViewProvidersFactoryIndex].providerFactory = factory;
        }
        registerDestroyHooksIfSupported(tView, provider, tInjectables.length, 0);
        tInjectables.push(token);
        tNode.directiveStart++;
        tNode.directiveEnd++;
        if (isViewProvider) {
          tNode.providerIndexes += 1048576 /* TNodeProviderIndexes.CptViewProvidersCountShifter */;
        }
        lInjectablesBlueprint.push(factory);
        lView.push(factory);
      } else {
        // Cases 1.b and 2.b
        const indexInFactory = multiFactoryAdd(lInjectablesBlueprint[isViewProvider ? existingViewProvidersFactoryIndex : existingProvidersFactoryIndex], providerFactory, !isViewProvider && isComponent);
        registerDestroyHooksIfSupported(tView, provider, existingProvidersFactoryIndex > -1 ? existingProvidersFactoryIndex : existingViewProvidersFactoryIndex, indexInFactory);
      }
      if (!isViewProvider && isComponent && doesViewProvidersFactoryExist) {
        lInjectablesBlueprint[existingViewProvidersFactoryIndex].componentProviders++;
      }
    }
  }
}
/**
 * Registers the `ngOnDestroy` hook of a provider, if the provider supports destroy hooks.
 * @param tView `TView` in which to register the hook.
 * @param provider Provider whose hook should be registered.
 * @param contextIndex Index under which to find the context for the hook when it's being invoked.
 * @param indexInFactory Only required for `multi` providers. Index of the provider in the multi
 * provider factory.
 */
function registerDestroyHooksIfSupported(tView, provider, contextIndex, indexInFactory) {
  const providerIsTypeProvider = isTypeProvider(provider);
  const providerIsClassProvider = isClassProvider(provider);
  if (providerIsTypeProvider || providerIsClassProvider) {
    // Resolve forward references as `useClass` can hold a forward reference.
    const classToken = providerIsClassProvider ? resolveForwardRef(provider.useClass) : provider;
    const prototype = classToken.prototype;
    const ngOnDestroy = prototype.ngOnDestroy;
    if (ngOnDestroy) {
      const hooks = tView.destroyHooks || (tView.destroyHooks = []);
      if (!providerIsTypeProvider && provider.multi) {
        ngDevMode && assertDefined(indexInFactory, 'indexInFactory when registering multi factory destroy hook');
        const existingCallbacksIndex = hooks.indexOf(contextIndex);
        if (existingCallbacksIndex === -1) {
          hooks.push(contextIndex, [indexInFactory, ngOnDestroy]);
        } else {
          hooks[existingCallbacksIndex + 1].push(indexInFactory, ngOnDestroy);
        }
      } else {
        hooks.push(contextIndex, ngOnDestroy);
      }
    }
  }
}
/**
 * Add a factory in a multi factory.
 * @returns Index at which the factory was inserted.
 */
function multiFactoryAdd(multiFactory, factory, isComponentProvider) {
  if (isComponentProvider) {
    multiFactory.componentProviders++;
  }
  return multiFactory.multi.push(factory) - 1;
}
/**
 * Returns the index of item in the array, but only in the begin to end range.
 */
function indexOf(item, arr, begin, end) {
  for (let i = begin; i < end; i++) {
    if (arr[i] === item) return i;
  }
  return -1;
}
/**
 * Use this with `multi` `providers`.
 */
function multiProvidersFactoryResolver(_, tData, lData, tNode) {
  return multiResolve(this.multi, []);
}
/**
 * Use this with `multi` `viewProviders`.
 *
 * This factory knows how to concatenate itself with the existing `multi` `providers`.
 */
function multiViewProvidersFactoryResolver(_, tData, lView, tNode) {
  const factories = this.multi;
  let result;
  if (this.providerFactory) {
    const componentCount = this.providerFactory.componentProviders;
    const multiProviders = getNodeInjectable(lView, lView[TVIEW], this.providerFactory.index, tNode);
    // Copy the section of the array which contains `multi` `providers` from the component
    result = multiProviders.slice(0, componentCount);
    // Insert the `viewProvider` instances.
    multiResolve(factories, result);
    // Copy the section of the array which contains `multi` `providers` from other directives
    for (let i = componentCount; i < multiProviders.length; i++) {
      result.push(multiProviders[i]);
    }
  } else {
    result = [];
    // Insert the `viewProvider` instances.
    multiResolve(factories, result);
  }
  return result;
}
/**
 * Maps an array of factories into an array of values.
 */
function multiResolve(factories, result) {
  for (let i = 0; i < factories.length; i++) {
    const factory = factories[i];
    result.push(factory());
  }
  return result;
}
/**
 * Creates a multi factory.
 */
function multiFactory(factoryFn, index, isViewProvider, isComponent, f) {
  const factory = new NodeInjectorFactory(factoryFn, isViewProvider, ɵɵdirectiveInject);
  factory.multi = [];
  factory.index = index;
  factory.componentProviders = 0;
  multiFactoryAdd(factory, f, isComponent && !isViewProvider);
  return factory;
}

/**
 * This feature resolves the providers of a directive (or component),
 * and publish them into the DI system, making it visible to others for injection.
 *
 * For example:
 * ```ts
 * class ComponentWithProviders {
 *   constructor(private greeter: GreeterDE) {}
 *
 *   static ɵcmp = defineComponent({
 *     type: ComponentWithProviders,
 *     selectors: [['component-with-providers']],
 *    factory: () => new ComponentWithProviders(directiveInject(GreeterDE as any)),
 *    decls: 1,
 *    vars: 1,
 *    template: function(fs: RenderFlags, ctx: ComponentWithProviders) {
 *      if (fs & RenderFlags.Create) {
 *        ɵɵtext(0);
 *      }
 *      if (fs & RenderFlags.Update) {
 *        ɵɵtextInterpolate(ctx.greeter.greet());
 *      }
 *    },
 *    features: [ɵɵProvidersFeature([GreeterDE])]
 *  });
 * }
 * ```
 *
 * @param definition
 *
 * @codeGenApi
 */
function ɵɵProvidersFeature(providers, viewProviders = []) {
  return definition => {
    definition.providersResolver = (def, processProvidersFn) => {
      return providersResolver(def,
      //
      processProvidersFn ? processProvidersFn(providers) : providers,
      //
      viewProviders);
    };
  };
}

/**
 * A service used by the framework to create instances of standalone injectors. Those injectors are
 * created on demand in case of dynamic component instantiation and contain ambient providers
 * collected from the imports graph rooted at a given standalone component.
 */
class StandaloneService {
  constructor(_injector) {
    this._injector = _injector;
    this.cachedInjectors = new Map();
  }
  getOrCreateStandaloneInjector(componentDef) {
    if (!componentDef.standalone) {
      return null;
    }
    if (!this.cachedInjectors.has(componentDef)) {
      const providers = internalImportProvidersFrom(false, componentDef.type);
      const standaloneInjector = providers.length > 0 ? createEnvironmentInjector([providers], this._injector, `Standalone[${componentDef.type.name}]`) : null;
      this.cachedInjectors.set(componentDef, standaloneInjector);
    }
    return this.cachedInjectors.get(componentDef);
  }
  ngOnDestroy() {
    try {
      for (const injector of this.cachedInjectors.values()) {
        if (injector !== null) {
          injector.destroy();
        }
      }
    } finally {
      this.cachedInjectors.clear();
    }
  }
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: StandaloneService,
      providedIn: 'environment',
      factory: () => new StandaloneService(ɵɵinject(EnvironmentInjector))
    });
  }
}
/**
 * A feature that acts as a setup code for the {@link StandaloneService}.
 *
 * The most important responsibility of this feature is to expose the "getStandaloneInjector"
 * function (an entry points to a standalone injector creation) on a component definition object. We
 * go through the features infrastructure to make sure that the standalone injector creation logic
 * is tree-shakable and not included in applications that don't use standalone components.
 *
 * @codeGenApi
 */
function ɵɵStandaloneFeature(definition) {
  performanceMarkFeature('NgStandalone');
  definition.getStandaloneInjector = parentInjector => {
    return parentInjector.get(StandaloneService).getOrCreateStandaloneInjector(definition);
  };
}

/**
 * Generated next to NgModules to monkey-patch directive and pipe references onto a component's
 * definition, when generating a direct reference in the component file would otherwise create an
 * import cycle.
 *
 * See [this explanation](https://hackmd.io/Odw80D0pR6yfsOjg_7XCJg?view) for more details.
 *
 * @codeGenApi
 */
function ɵɵsetComponentScope(type, directives, pipes) {
  const def = type.ɵcmp;
  def.directiveDefs = extractDefListOrFactory(directives, /* pipeDef */false);
  def.pipeDefs = extractDefListOrFactory(pipes, /* pipeDef */true);
}
/**
 * Adds the module metadata that is necessary to compute the module's transitive scope to an
 * existing module definition.
 *
 * Scope metadata of modules is not used in production builds, so calls to this function can be
 * marked pure to tree-shake it from the bundle, allowing for all referenced declarations
 * to become eligible for tree-shaking as well.
 *
 * @codeGenApi
 */
function ɵɵsetNgModuleScope(type, scope) {
  return noSideEffects(() => {
    const ngModuleDef = getNgModuleDef(type, true);
    ngModuleDef.declarations = convertToTypeArray(scope.declarations || EMPTY_ARRAY);
    ngModuleDef.imports = convertToTypeArray(scope.imports || EMPTY_ARRAY);
    ngModuleDef.exports = convertToTypeArray(scope.exports || EMPTY_ARRAY);
    if (scope.bootstrap) {
      // This only happens in local compilation mode.
      ngModuleDef.bootstrap = convertToTypeArray(scope.bootstrap);
    }
    depsTracker.registerNgModule(type, scope);
  });
}
function convertToTypeArray(values) {
  if (typeof values === 'function') {
    return values;
  }
  const flattenValues = flatten(values);
  if (flattenValues.some(isForwardRef)) {
    return () => flattenValues.map(resolveForwardRef).map(maybeUnwrapModuleWithProviders);
  } else {
    return flattenValues.map(maybeUnwrapModuleWithProviders);
  }
}
function maybeUnwrapModuleWithProviders(value) {
  return isModuleWithProviders(value) ? value.ngModule : value;
}

/**
 * Bindings for pure functions are stored after regular bindings.
 *
 * |-------decls------|---------vars---------|                 |----- hostVars (dir1) ------|
 * ------------------------------------------------------------------------------------------
 * | nodes/refs/pipes | bindings | fn slots  | injector | dir1 | host bindings | host slots |
 * ------------------------------------------------------------------------------------------
 *                    ^                      ^
 *      TView.bindingStartIndex      TView.expandoStartIndex
 *
 * Pure function instructions are given an offset from the binding root. Adding the offset to the
 * binding root gives the first index where the bindings are stored. In component views, the binding
 * root is the bindingStartIndex. In host bindings, the binding root is the expandoStartIndex +
 * any directive instances + any hostVars in directives evaluated before it.
 *
 * See VIEW_DATA.md for more information about host binding resolution.
 */
/**
 * If the value hasn't been saved, calls the pure function to store and return the
 * value. If it has been saved, returns the saved value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn Function that returns a value
 * @param thisArg Optional calling context of pureFn
 * @returns value
 *
 * @codeGenApi
 */
function ɵɵpureFunction0(slotOffset, pureFn, thisArg) {
  const bindingIndex = getBindingRoot() + slotOffset;
  const lView = getLView();
  return lView[bindingIndex] === NO_CHANGE ? updateBinding(lView, bindingIndex, thisArg ? pureFn.call(thisArg) : pureFn()) : getBinding(lView, bindingIndex);
}
/**
 * If the value of the provided exp has changed, calls the pure function to return
 * an updated value. Or if the value has not changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn Function that returns an updated value
 * @param exp Updated expression value
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction1(slotOffset, pureFn, exp, thisArg) {
  return pureFunction1Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp, thisArg);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction2(slotOffset, pureFn, exp1, exp2, thisArg) {
  return pureFunction2Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, thisArg);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction3(slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
  return pureFunction3Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, thisArg);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction4(slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
  return pureFunction4Internal(getLView(), getBindingRoot(), slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param exp5
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction5(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, thisArg) {
  const bindingIndex = getBindingRoot() + slotOffset;
  const lView = getLView();
  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
  return bindingUpdated(lView, bindingIndex + 4, exp5) || different ? updateBinding(lView, bindingIndex + 5, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5) : pureFn(exp1, exp2, exp3, exp4, exp5)) : getBinding(lView, bindingIndex + 5);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param exp5
 * @param exp6
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction6(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, thisArg) {
  const bindingIndex = getBindingRoot() + slotOffset;
  const lView = getLView();
  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
  return bindingUpdated2(lView, bindingIndex + 4, exp5, exp6) || different ? updateBinding(lView, bindingIndex + 6, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6)) : getBinding(lView, bindingIndex + 6);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param exp5
 * @param exp6
 * @param exp7
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction7(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, thisArg) {
  const bindingIndex = getBindingRoot() + slotOffset;
  const lView = getLView();
  let different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
  return bindingUpdated3(lView, bindingIndex + 4, exp5, exp6, exp7) || different ? updateBinding(lView, bindingIndex + 7, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7)) : getBinding(lView, bindingIndex + 7);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param exp5
 * @param exp6
 * @param exp7
 * @param exp8
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunction8(slotOffset, pureFn, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8, thisArg) {
  const bindingIndex = getBindingRoot() + slotOffset;
  const lView = getLView();
  const different = bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4);
  return bindingUpdated4(lView, bindingIndex + 4, exp5, exp6, exp7, exp8) || different ? updateBinding(lView, bindingIndex + 8, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8) : pureFn(exp1, exp2, exp3, exp4, exp5, exp6, exp7, exp8)) : getBinding(lView, bindingIndex + 8);
}
/**
 * pureFunction instruction that can support any number of bindings.
 *
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn A pure function that takes binding values and builds an object or array
 * containing those values.
 * @param exps An array of binding values
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 * @codeGenApi
 */
function ɵɵpureFunctionV(slotOffset, pureFn, exps, thisArg) {
  return pureFunctionVInternal(getLView(), getBindingRoot(), slotOffset, pureFn, exps, thisArg);
}
/**
 * Results of a pure function invocation are stored in LView in a dedicated slot that is initialized
 * to NO_CHANGE. In rare situations a pure pipe might throw an exception on the very first
 * invocation and not produce any valid results. In this case LView would keep holding the NO_CHANGE
 * value. The NO_CHANGE is not something that we can use in expressions / bindings thus we convert
 * it to `undefined`.
 */
function getPureFunctionReturnValue(lView, returnValueIndex) {
  ngDevMode && assertIndexInRange(lView, returnValueIndex);
  const lastReturnValue = lView[returnValueIndex];
  return lastReturnValue === NO_CHANGE ? undefined : lastReturnValue;
}
/**
 * If the value of the provided exp has changed, calls the pure function to return
 * an updated value. Or if the value has not changed, returns cached value.
 *
 * @param lView LView in which the function is being executed.
 * @param bindingRoot Binding root index.
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn Function that returns an updated value
 * @param exp Updated expression value
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 */
function pureFunction1Internal(lView, bindingRoot, slotOffset, pureFn, exp, thisArg) {
  const bindingIndex = bindingRoot + slotOffset;
  return bindingUpdated(lView, bindingIndex, exp) ? updateBinding(lView, bindingIndex + 1, thisArg ? pureFn.call(thisArg, exp) : pureFn(exp)) : getPureFunctionReturnValue(lView, bindingIndex + 1);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param lView LView in which the function is being executed.
 * @param bindingRoot Binding root index.
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 */
function pureFunction2Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, thisArg) {
  const bindingIndex = bindingRoot + slotOffset;
  return bindingUpdated2(lView, bindingIndex, exp1, exp2) ? updateBinding(lView, bindingIndex + 2, thisArg ? pureFn.call(thisArg, exp1, exp2) : pureFn(exp1, exp2)) : getPureFunctionReturnValue(lView, bindingIndex + 2);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param lView LView in which the function is being executed.
 * @param bindingRoot Binding root index.
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 */
function pureFunction3Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, thisArg) {
  const bindingIndex = bindingRoot + slotOffset;
  return bindingUpdated3(lView, bindingIndex, exp1, exp2, exp3) ? updateBinding(lView, bindingIndex + 3, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3) : pureFn(exp1, exp2, exp3)) : getPureFunctionReturnValue(lView, bindingIndex + 3);
}
/**
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param lView LView in which the function is being executed.
 * @param bindingRoot Binding root index.
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn
 * @param exp1
 * @param exp2
 * @param exp3
 * @param exp4
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 *
 */
function pureFunction4Internal(lView, bindingRoot, slotOffset, pureFn, exp1, exp2, exp3, exp4, thisArg) {
  const bindingIndex = bindingRoot + slotOffset;
  return bindingUpdated4(lView, bindingIndex, exp1, exp2, exp3, exp4) ? updateBinding(lView, bindingIndex + 4, thisArg ? pureFn.call(thisArg, exp1, exp2, exp3, exp4) : pureFn(exp1, exp2, exp3, exp4)) : getPureFunctionReturnValue(lView, bindingIndex + 4);
}
/**
 * pureFunction instruction that can support any number of bindings.
 *
 * If the value of any provided exp has changed, calls the pure function to return
 * an updated value. Or if no values have changed, returns cached value.
 *
 * @param lView LView in which the function is being executed.
 * @param bindingRoot Binding root index.
 * @param slotOffset the offset from binding root to the reserved slot
 * @param pureFn A pure function that takes binding values and builds an object or array
 * containing those values.
 * @param exps An array of binding values
 * @param thisArg Optional calling context of pureFn
 * @returns Updated or cached value
 */
function pureFunctionVInternal(lView, bindingRoot, slotOffset, pureFn, exps, thisArg) {
  let bindingIndex = bindingRoot + slotOffset;
  let different = false;
  for (let i = 0; i < exps.length; i++) {
    bindingUpdated(lView, bindingIndex++, exps[i]) && (different = true);
  }
  return different ? updateBinding(lView, bindingIndex, pureFn.apply(thisArg, exps)) : getPureFunctionReturnValue(lView, bindingIndex);
}

/**
 * Create a pipe.
 *
 * @param index Pipe index where the pipe will be stored.
 * @param pipeName The name of the pipe
 * @returns T the instance of the pipe.
 *
 * @codeGenApi
 */
function ɵɵpipe(index, pipeName) {
  const tView = getTView();
  let pipeDef;
  const adjustedIndex = index + HEADER_OFFSET;
  if (tView.firstCreatePass) {
    // The `getPipeDef` throws if a pipe with a given name is not found
    // (so we use non-null assertion below).
    pipeDef = getPipeDef(pipeName, tView.pipeRegistry);
    tView.data[adjustedIndex] = pipeDef;
    if (pipeDef.onDestroy) {
      (tView.destroyHooks ??= []).push(adjustedIndex, pipeDef.onDestroy);
    }
  } else {
    pipeDef = tView.data[adjustedIndex];
  }
  const pipeFactory = pipeDef.factory || (pipeDef.factory = getFactoryDef(pipeDef.type, true));
  let previousInjectorProfilerContext;
  if (ngDevMode) {
    previousInjectorProfilerContext = setInjectorProfilerContext({
      injector: new NodeInjector(getCurrentTNode(), getLView()),
      token: pipeDef.type
    });
  }
  const previousInjectImplementation = setInjectImplementation(ɵɵdirectiveInject);
  try {
    // DI for pipes is supposed to behave like directives when placed on a component
    // host node, which means that we have to disable access to `viewProviders`.
    const previousIncludeViewProviders = setIncludeViewProviders(false);
    const pipeInstance = pipeFactory();
    setIncludeViewProviders(previousIncludeViewProviders);
    store(tView, getLView(), adjustedIndex, pipeInstance);
    return pipeInstance;
  } finally {
    // we have to restore the injector implementation in finally, just in case the creation of the
    // pipe throws an error.
    setInjectImplementation(previousInjectImplementation);
    ngDevMode && setInjectorProfilerContext(previousInjectorProfilerContext);
  }
}
/**
 * Searches the pipe registry for a pipe with the given name. If one is found,
 * returns the pipe. Otherwise, an error is thrown because the pipe cannot be resolved.
 *
 * @param name Name of pipe to resolve
 * @param registry Full list of available pipes
 * @returns Matching PipeDef
 */
function getPipeDef(name, registry) {
  if (registry) {
    if (ngDevMode) {
      const pipes = registry.filter(pipe => pipe.name === name);
      // TODO: Throw an error in the next major
      if (pipes.length > 1) {
        console.warn(formatRuntimeError(313 /* RuntimeErrorCode.MULTIPLE_MATCHING_PIPES */, getMultipleMatchingPipesMessage(name)));
      }
    }
    for (let i = registry.length - 1; i >= 0; i--) {
      const pipeDef = registry[i];
      if (name === pipeDef.name) {
        return pipeDef;
      }
    }
  }
  if (ngDevMode) {
    throw new RuntimeError(-302 /* RuntimeErrorCode.PIPE_NOT_FOUND */, getPipeNotFoundErrorMessage(name));
  }
  return;
}
/**
 * Generates a helpful error message for the user when multiple pipes match the name.
 *
 * @param name Name of the pipe
 * @returns The error message
 */
function getMultipleMatchingPipesMessage(name) {
  const lView = getLView();
  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
  const context = declarationLView[CONTEXT];
  const hostIsStandalone = isHostComponentStandalone(lView);
  const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
  const verifyMessage = `check ${hostIsStandalone ? '\'@Component.imports\' of this component' : 'the imports of this module'}`;
  const errorMessage = `Multiple pipes match the name \`${name}\`${componentInfoMessage}. ${verifyMessage}`;
  return errorMessage;
}
/**
 * Generates a helpful error message for the user when a pipe is not found.
 *
 * @param name Name of the missing pipe
 * @returns The error message
 */
function getPipeNotFoundErrorMessage(name) {
  const lView = getLView();
  const declarationLView = lView[DECLARATION_COMPONENT_VIEW];
  const context = declarationLView[CONTEXT];
  const hostIsStandalone = isHostComponentStandalone(lView);
  const componentInfoMessage = context ? ` in the '${context.constructor.name}' component` : '';
  const verifyMessage = `Verify that it is ${hostIsStandalone ? 'included in the \'@Component.imports\' of this component' : 'declared or imported in this module'}`;
  const errorMessage = `The pipe '${name}' could not be found${componentInfoMessage}. ${verifyMessage}`;
  return errorMessage;
}
/**
 * Invokes a pipe with 1 arguments.
 *
 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
 * the pipe only when an input to the pipe changes.
 *
 * @param index Pipe index where the pipe was stored on creation.
 * @param offset the binding offset
 * @param v1 1st argument to {@link PipeTransform#transform}.
 *
 * @codeGenApi
 */
function ɵɵpipeBind1(index, offset, v1) {
  const adjustedIndex = index + HEADER_OFFSET;
  const lView = getLView();
  const pipeInstance = load(lView, adjustedIndex);
  return isPure(lView, adjustedIndex) ? pureFunction1Internal(lView, getBindingRoot(), offset, pipeInstance.transform, v1, pipeInstance) : pipeInstance.transform(v1);
}
/**
 * Invokes a pipe with 2 arguments.
 *
 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
 * the pipe only when an input to the pipe changes.
 *
 * @param index Pipe index where the pipe was stored on creation.
 * @param slotOffset the offset in the reserved slot space
 * @param v1 1st argument to {@link PipeTransform#transform}.
 * @param v2 2nd argument to {@link PipeTransform#transform}.
 *
 * @codeGenApi
 */
function ɵɵpipeBind2(index, slotOffset, v1, v2) {
  const adjustedIndex = index + HEADER_OFFSET;
  const lView = getLView();
  const pipeInstance = load(lView, adjustedIndex);
  return isPure(lView, adjustedIndex) ? pureFunction2Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, pipeInstance) : pipeInstance.transform(v1, v2);
}
/**
 * Invokes a pipe with 3 arguments.
 *
 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
 * the pipe only when an input to the pipe changes.
 *
 * @param index Pipe index where the pipe was stored on creation.
 * @param slotOffset the offset in the reserved slot space
 * @param v1 1st argument to {@link PipeTransform#transform}.
 * @param v2 2nd argument to {@link PipeTransform#transform}.
 * @param v3 4rd argument to {@link PipeTransform#transform}.
 *
 * @codeGenApi
 */
function ɵɵpipeBind3(index, slotOffset, v1, v2, v3) {
  const adjustedIndex = index + HEADER_OFFSET;
  const lView = getLView();
  const pipeInstance = load(lView, adjustedIndex);
  return isPure(lView, adjustedIndex) ? pureFunction3Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, pipeInstance) : pipeInstance.transform(v1, v2, v3);
}
/**
 * Invokes a pipe with 4 arguments.
 *
 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
 * the pipe only when an input to the pipe changes.
 *
 * @param index Pipe index where the pipe was stored on creation.
 * @param slotOffset the offset in the reserved slot space
 * @param v1 1st argument to {@link PipeTransform#transform}.
 * @param v2 2nd argument to {@link PipeTransform#transform}.
 * @param v3 3rd argument to {@link PipeTransform#transform}.
 * @param v4 4th argument to {@link PipeTransform#transform}.
 *
 * @codeGenApi
 */
function ɵɵpipeBind4(index, slotOffset, v1, v2, v3, v4) {
  const adjustedIndex = index + HEADER_OFFSET;
  const lView = getLView();
  const pipeInstance = load(lView, adjustedIndex);
  return isPure(lView, adjustedIndex) ? pureFunction4Internal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, v1, v2, v3, v4, pipeInstance) : pipeInstance.transform(v1, v2, v3, v4);
}
/**
 * Invokes a pipe with variable number of arguments.
 *
 * This instruction acts as a guard to {@link PipeTransform#transform} invoking
 * the pipe only when an input to the pipe changes.
 *
 * @param index Pipe index where the pipe was stored on creation.
 * @param slotOffset the offset in the reserved slot space
 * @param values Array of arguments to pass to {@link PipeTransform#transform} method.
 *
 * @codeGenApi
 */
function ɵɵpipeBindV(index, slotOffset, values) {
  const adjustedIndex = index + HEADER_OFFSET;
  const lView = getLView();
  const pipeInstance = load(lView, adjustedIndex);
  return isPure(lView, adjustedIndex) ? pureFunctionVInternal(lView, getBindingRoot(), slotOffset, pipeInstance.transform, values, pipeInstance) : pipeInstance.transform.apply(pipeInstance, values);
}
function isPure(lView, index) {
  return lView[TVIEW].data[index].pure;
}

/**
 * Retrieves `TemplateRef` instance from `Injector` when a local reference is placed on the
 * `<ng-template>` element.
 *
 * @codeGenApi
 */
function ɵɵtemplateRefExtractor(tNode, lView) {
  return createTemplateRef(tNode, lView);
}
function ɵɵgetComponentDepsFactory(type, rawImports) {
  return () => {
    try {
      return depsTracker.getComponentDependencies(type, rawImports).dependencies;
    } catch (e) {
      console.error(`Computing dependencies in local compilation mode for the component "${type.name}" failed with the exception:`, e);
      throw e;
    }
  };
}

/**
 * Sets the debug info for an Angular class.
 *
 * This runtime is guarded by ngDevMode flag.
 */
function ɵsetClassDebugInfo(type, debugInfo) {
  const def = getComponentDef(type);
  if (def !== null) {
    def.debugInfo = debugInfo;
  }
}

/**
 * A mapping of the @angular/core API surface used in generated expressions to the actual symbols.
 *
 * This should be kept up to date with the public exports of @angular/core.
 */
const angularCoreEnv = (() => ({
  'ɵɵattribute': ɵɵattribute,
  'ɵɵattributeInterpolate1': ɵɵattributeInterpolate1,
  'ɵɵattributeInterpolate2': ɵɵattributeInterpolate2,
  'ɵɵattributeInterpolate3': ɵɵattributeInterpolate3,
  'ɵɵattributeInterpolate4': ɵɵattributeInterpolate4,
  'ɵɵattributeInterpolate5': ɵɵattributeInterpolate5,
  'ɵɵattributeInterpolate6': ɵɵattributeInterpolate6,
  'ɵɵattributeInterpolate7': ɵɵattributeInterpolate7,
  'ɵɵattributeInterpolate8': ɵɵattributeInterpolate8,
  'ɵɵattributeInterpolateV': ɵɵattributeInterpolateV,
  'ɵɵdefineComponent': ɵɵdefineComponent,
  'ɵɵdefineDirective': ɵɵdefineDirective,
  'ɵɵdefineInjectable': ɵɵdefineInjectable,
  'ɵɵdefineInjector': ɵɵdefineInjector,
  'ɵɵdefineNgModule': ɵɵdefineNgModule,
  'ɵɵdefinePipe': ɵɵdefinePipe,
  'ɵɵdirectiveInject': ɵɵdirectiveInject,
  'ɵɵgetInheritedFactory': ɵɵgetInheritedFactory,
  'ɵɵinject': ɵɵinject,
  'ɵɵinjectAttribute': ɵɵinjectAttribute,
  'ɵɵinvalidFactory': ɵɵinvalidFactory,
  'ɵɵinvalidFactoryDep': ɵɵinvalidFactoryDep,
  'ɵɵtemplateRefExtractor': ɵɵtemplateRefExtractor,
  'ɵɵresetView': ɵɵresetView,
  'ɵɵHostDirectivesFeature': ɵɵHostDirectivesFeature,
  'ɵɵNgOnChangesFeature': ɵɵNgOnChangesFeature,
  'ɵɵProvidersFeature': ɵɵProvidersFeature,
  'ɵɵCopyDefinitionFeature': ɵɵCopyDefinitionFeature,
  'ɵɵInheritDefinitionFeature': ɵɵInheritDefinitionFeature,
  'ɵɵInputTransformsFeature': ɵɵInputTransformsFeature,
  'ɵɵStandaloneFeature': ɵɵStandaloneFeature,
  'ɵɵnextContext': ɵɵnextContext,
  'ɵɵnamespaceHTML': ɵɵnamespaceHTML,
  'ɵɵnamespaceMathML': ɵɵnamespaceMathML,
  'ɵɵnamespaceSVG': ɵɵnamespaceSVG,
  'ɵɵenableBindings': ɵɵenableBindings,
  'ɵɵdisableBindings': ɵɵdisableBindings,
  'ɵɵelementStart': ɵɵelementStart,
  'ɵɵelementEnd': ɵɵelementEnd,
  'ɵɵelement': ɵɵelement,
  'ɵɵelementContainerStart': ɵɵelementContainerStart,
  'ɵɵelementContainerEnd': ɵɵelementContainerEnd,
  'ɵɵelementContainer': ɵɵelementContainer,
  'ɵɵpureFunction0': ɵɵpureFunction0,
  'ɵɵpureFunction1': ɵɵpureFunction1,
  'ɵɵpureFunction2': ɵɵpureFunction2,
  'ɵɵpureFunction3': ɵɵpureFunction3,
  'ɵɵpureFunction4': ɵɵpureFunction4,
  'ɵɵpureFunction5': ɵɵpureFunction5,
  'ɵɵpureFunction6': ɵɵpureFunction6,
  'ɵɵpureFunction7': ɵɵpureFunction7,
  'ɵɵpureFunction8': ɵɵpureFunction8,
  'ɵɵpureFunctionV': ɵɵpureFunctionV,
  'ɵɵgetCurrentView': ɵɵgetCurrentView,
  'ɵɵrestoreView': ɵɵrestoreView,
  'ɵɵlistener': ɵɵlistener,
  'ɵɵprojection': ɵɵprojection,
  'ɵɵsyntheticHostProperty': ɵɵsyntheticHostProperty,
  'ɵɵsyntheticHostListener': ɵɵsyntheticHostListener,
  'ɵɵpipeBind1': ɵɵpipeBind1,
  'ɵɵpipeBind2': ɵɵpipeBind2,
  'ɵɵpipeBind3': ɵɵpipeBind3,
  'ɵɵpipeBind4': ɵɵpipeBind4,
  'ɵɵpipeBindV': ɵɵpipeBindV,
  'ɵɵprojectionDef': ɵɵprojectionDef,
  'ɵɵhostProperty': ɵɵhostProperty,
  'ɵɵproperty': ɵɵproperty,
  'ɵɵpropertyInterpolate': ɵɵpropertyInterpolate,
  'ɵɵpropertyInterpolate1': ɵɵpropertyInterpolate1,
  'ɵɵpropertyInterpolate2': ɵɵpropertyInterpolate2,
  'ɵɵpropertyInterpolate3': ɵɵpropertyInterpolate3,
  'ɵɵpropertyInterpolate4': ɵɵpropertyInterpolate4,
  'ɵɵpropertyInterpolate5': ɵɵpropertyInterpolate5,
  'ɵɵpropertyInterpolate6': ɵɵpropertyInterpolate6,
  'ɵɵpropertyInterpolate7': ɵɵpropertyInterpolate7,
  'ɵɵpropertyInterpolate8': ɵɵpropertyInterpolate8,
  'ɵɵpropertyInterpolateV': ɵɵpropertyInterpolateV,
  'ɵɵpipe': ɵɵpipe,
  'ɵɵqueryRefresh': ɵɵqueryRefresh,
  'ɵɵqueryAdvance': ɵɵqueryAdvance,
  'ɵɵviewQuery': ɵɵviewQuery,
  'ɵɵviewQuerySignal': ɵɵviewQuerySignal,
  'ɵɵloadQuery': ɵɵloadQuery,
  'ɵɵcontentQuery': ɵɵcontentQuery,
  'ɵɵcontentQuerySignal': ɵɵcontentQuerySignal,
  'ɵɵreference': ɵɵreference,
  'ɵɵclassMap': ɵɵclassMap,
  'ɵɵclassMapInterpolate1': ɵɵclassMapInterpolate1,
  'ɵɵclassMapInterpolate2': ɵɵclassMapInterpolate2,
  'ɵɵclassMapInterpolate3': ɵɵclassMapInterpolate3,
  'ɵɵclassMapInterpolate4': ɵɵclassMapInterpolate4,
  'ɵɵclassMapInterpolate5': ɵɵclassMapInterpolate5,
  'ɵɵclassMapInterpolate6': ɵɵclassMapInterpolate6,
  'ɵɵclassMapInterpolate7': ɵɵclassMapInterpolate7,
  'ɵɵclassMapInterpolate8': ɵɵclassMapInterpolate8,
  'ɵɵclassMapInterpolateV': ɵɵclassMapInterpolateV,
  'ɵɵstyleMap': ɵɵstyleMap,
  'ɵɵstyleMapInterpolate1': ɵɵstyleMapInterpolate1,
  'ɵɵstyleMapInterpolate2': ɵɵstyleMapInterpolate2,
  'ɵɵstyleMapInterpolate3': ɵɵstyleMapInterpolate3,
  'ɵɵstyleMapInterpolate4': ɵɵstyleMapInterpolate4,
  'ɵɵstyleMapInterpolate5': ɵɵstyleMapInterpolate5,
  'ɵɵstyleMapInterpolate6': ɵɵstyleMapInterpolate6,
  'ɵɵstyleMapInterpolate7': ɵɵstyleMapInterpolate7,
  'ɵɵstyleMapInterpolate8': ɵɵstyleMapInterpolate8,
  'ɵɵstyleMapInterpolateV': ɵɵstyleMapInterpolateV,
  'ɵɵstyleProp': ɵɵstyleProp,
  'ɵɵstylePropInterpolate1': ɵɵstylePropInterpolate1,
  'ɵɵstylePropInterpolate2': ɵɵstylePropInterpolate2,
  'ɵɵstylePropInterpolate3': ɵɵstylePropInterpolate3,
  'ɵɵstylePropInterpolate4': ɵɵstylePropInterpolate4,
  'ɵɵstylePropInterpolate5': ɵɵstylePropInterpolate5,
  'ɵɵstylePropInterpolate6': ɵɵstylePropInterpolate6,
  'ɵɵstylePropInterpolate7': ɵɵstylePropInterpolate7,
  'ɵɵstylePropInterpolate8': ɵɵstylePropInterpolate8,
  'ɵɵstylePropInterpolateV': ɵɵstylePropInterpolateV,
  'ɵɵclassProp': ɵɵclassProp,
  'ɵɵadvance': ɵɵadvance,
  'ɵɵtemplate': ɵɵtemplate,
  'ɵɵconditional': ɵɵconditional,
  'ɵɵdefer': ɵɵdefer,
  'ɵɵdeferWhen': ɵɵdeferWhen,
  'ɵɵdeferOnIdle': ɵɵdeferOnIdle,
  'ɵɵdeferOnImmediate': ɵɵdeferOnImmediate,
  'ɵɵdeferOnTimer': ɵɵdeferOnTimer,
  'ɵɵdeferOnHover': ɵɵdeferOnHover,
  'ɵɵdeferOnInteraction': ɵɵdeferOnInteraction,
  'ɵɵdeferOnViewport': ɵɵdeferOnViewport,
  'ɵɵdeferPrefetchWhen': ɵɵdeferPrefetchWhen,
  'ɵɵdeferPrefetchOnIdle': ɵɵdeferPrefetchOnIdle,
  'ɵɵdeferPrefetchOnImmediate': ɵɵdeferPrefetchOnImmediate,
  'ɵɵdeferPrefetchOnTimer': ɵɵdeferPrefetchOnTimer,
  'ɵɵdeferPrefetchOnHover': ɵɵdeferPrefetchOnHover,
  'ɵɵdeferPrefetchOnInteraction': ɵɵdeferPrefetchOnInteraction,
  'ɵɵdeferPrefetchOnViewport': ɵɵdeferPrefetchOnViewport,
  'ɵɵdeferEnableTimerScheduling': ɵɵdeferEnableTimerScheduling,
  'ɵɵrepeater': ɵɵrepeater,
  'ɵɵrepeaterCreate': ɵɵrepeaterCreate,
  'ɵɵrepeaterTrackByIndex': ɵɵrepeaterTrackByIndex,
  'ɵɵrepeaterTrackByIdentity': ɵɵrepeaterTrackByIdentity,
  'ɵɵcomponentInstance': ɵɵcomponentInstance,
  'ɵɵtext': ɵɵtext,
  'ɵɵtextInterpolate': ɵɵtextInterpolate,
  'ɵɵtextInterpolate1': ɵɵtextInterpolate1,
  'ɵɵtextInterpolate2': ɵɵtextInterpolate2,
  'ɵɵtextInterpolate3': ɵɵtextInterpolate3,
  'ɵɵtextInterpolate4': ɵɵtextInterpolate4,
  'ɵɵtextInterpolate5': ɵɵtextInterpolate5,
  'ɵɵtextInterpolate6': ɵɵtextInterpolate6,
  'ɵɵtextInterpolate7': ɵɵtextInterpolate7,
  'ɵɵtextInterpolate8': ɵɵtextInterpolate8,
  'ɵɵtextInterpolateV': ɵɵtextInterpolateV,
  'ɵɵi18n': ɵɵi18n,
  'ɵɵi18nAttributes': ɵɵi18nAttributes,
  'ɵɵi18nExp': ɵɵi18nExp,
  'ɵɵi18nStart': ɵɵi18nStart,
  'ɵɵi18nEnd': ɵɵi18nEnd,
  'ɵɵi18nApply': ɵɵi18nApply,
  'ɵɵi18nPostprocess': ɵɵi18nPostprocess,
  'ɵɵresolveWindow': ɵɵresolveWindow,
  'ɵɵresolveDocument': ɵɵresolveDocument,
  'ɵɵresolveBody': ɵɵresolveBody,
  'ɵɵsetComponentScope': ɵɵsetComponentScope,
  'ɵɵsetNgModuleScope': ɵɵsetNgModuleScope,
  'ɵɵregisterNgModuleType': registerNgModuleType,
  'ɵɵgetComponentDepsFactory': ɵɵgetComponentDepsFactory,
  'ɵsetClassDebugInfo': ɵsetClassDebugInfo,
  'ɵɵsanitizeHtml': ɵɵsanitizeHtml,
  'ɵɵsanitizeStyle': ɵɵsanitizeStyle,
  'ɵɵsanitizeResourceUrl': ɵɵsanitizeResourceUrl,
  'ɵɵsanitizeScript': ɵɵsanitizeScript,
  'ɵɵsanitizeUrl': ɵɵsanitizeUrl,
  'ɵɵsanitizeUrlOrResourceUrl': ɵɵsanitizeUrlOrResourceUrl,
  'ɵɵtrustConstantHtml': ɵɵtrustConstantHtml,
  'ɵɵtrustConstantResourceUrl': ɵɵtrustConstantResourceUrl,
  'ɵɵvalidateIframeAttribute': ɵɵvalidateIframeAttribute,
  'forwardRef': forwardRef,
  'resolveForwardRef': resolveForwardRef,
  'ɵɵtwoWayProperty': ɵɵtwoWayProperty,
  'ɵɵtwoWayBindingSet': ɵɵtwoWayBindingSet,
  'ɵɵtwoWayListener': ɵɵtwoWayListener,
  'ɵɵInputFlags': InputFlags
}))();
let jitOptions = null;
function setJitOptions(options) {
  if (jitOptions !== null) {
    if (options.defaultEncapsulation !== jitOptions.defaultEncapsulation) {
      ngDevMode && console.error('Provided value for `defaultEncapsulation` can not be changed once it has been set.');
      return;
    }
    if (options.preserveWhitespaces !== jitOptions.preserveWhitespaces) {
      ngDevMode && console.error('Provided value for `preserveWhitespaces` can not be changed once it has been set.');
      return;
    }
  }
  jitOptions = options;
}
function getJitOptions() {
  return jitOptions;
}
function resetJitOptions() {
  jitOptions = null;
}
function patchModuleCompilation() {
  // Does nothing, but exists as a target for patching.
}
const moduleQueue = [];
/**
 * Enqueues moduleDef to be checked later to see if scope can be set on its
 * component declarations.
 */
function enqueueModuleForDelayedScoping(moduleType, ngModule) {
  moduleQueue.push({
    moduleType,
    ngModule
  });
}
let flushingModuleQueue = false;
/**
 * Loops over queued module definitions, if a given module definition has all of its
 * declarations resolved, it dequeues that module definition and sets the scope on
 * its declarations.
 */
function flushModuleScopingQueueAsMuchAsPossible() {
  if (!flushingModuleQueue) {
    flushingModuleQueue = true;
    try {
      for (let i = moduleQueue.length - 1; i >= 0; i--) {
        const {
          moduleType,
          ngModule
        } = moduleQueue[i];
        if (ngModule.declarations && ngModule.declarations.every(isResolvedDeclaration)) {
          // dequeue
          moduleQueue.splice(i, 1);
          setScopeOnDeclaredComponents(moduleType, ngModule);
        }
      }
    } finally {
      flushingModuleQueue = false;
    }
  }
}
/**
 * Returns truthy if a declaration has resolved. If the declaration happens to be
 * an array of declarations, it will recurse to check each declaration in that array
 * (which may also be arrays).
 */
function isResolvedDeclaration(declaration) {
  if (Array.isArray(declaration)) {
    return declaration.every(isResolvedDeclaration);
  }
  return !!resolveForwardRef(declaration);
}
/**
 * Compiles a module in JIT mode.
 *
 * This function automatically gets called when a class has a `@NgModule` decorator.
 */
function compileNgModule(moduleType, ngModule = {}) {
  patchModuleCompilation();
  compileNgModuleDefs(moduleType, ngModule);
  if (ngModule.id !== undefined) {
    registerNgModuleType(moduleType, ngModule.id);
  }
  // Because we don't know if all declarations have resolved yet at the moment the
  // NgModule decorator is executing, we're enqueueing the setting of module scope
  // on its declarations to be run at a later time when all declarations for the module,
  // including forward refs, have resolved.
  enqueueModuleForDelayedScoping(moduleType, ngModule);
}
/**
 * Compiles and adds the `ɵmod`, `ɵfac` and `ɵinj` properties to the module class.
 *
 * It's possible to compile a module via this API which will allow duplicate declarations in its
 * root.
 */
function compileNgModuleDefs(moduleType, ngModule, allowDuplicateDeclarationsInRoot = false) {
  ngDevMode && assertDefined(moduleType, 'Required value moduleType');
  ngDevMode && assertDefined(ngModule, 'Required value ngModule');
  const declarations = flatten(ngModule.declarations || EMPTY_ARRAY);
  let ngModuleDef = null;
  Object.defineProperty(moduleType, NG_MOD_DEF, {
    configurable: true,
    get: () => {
      if (ngModuleDef === null) {
        if (ngDevMode && ngModule.imports && ngModule.imports.indexOf(moduleType) > -1) {
          // We need to assert this immediately, because allowing it to continue will cause it to
          // go into an infinite loop before we've reached the point where we throw all the errors.
          throw new Error(`'${stringifyForError(moduleType)}' module can't import itself`);
        }
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'NgModule',
          type: moduleType
        });
        ngModuleDef = compiler.compileNgModule(angularCoreEnv, `ng:///${moduleType.name}/ɵmod.js`, {
          type: moduleType,
          bootstrap: flatten(ngModule.bootstrap || EMPTY_ARRAY).map(resolveForwardRef),
          declarations: declarations.map(resolveForwardRef),
          imports: flatten(ngModule.imports || EMPTY_ARRAY).map(resolveForwardRef).map(expandModuleWithProviders),
          exports: flatten(ngModule.exports || EMPTY_ARRAY).map(resolveForwardRef).map(expandModuleWithProviders),
          schemas: ngModule.schemas ? flatten(ngModule.schemas) : null,
          id: ngModule.id || null
        });
        // Set `schemas` on ngModuleDef to an empty array in JIT mode to indicate that runtime
        // should verify that there are no unknown elements in a template. In AOT mode, that check
        // happens at compile time and `schemas` information is not present on Component and Module
        // defs after compilation (so the check doesn't happen the second time at runtime).
        if (!ngModuleDef.schemas) {
          ngModuleDef.schemas = [];
        }
      }
      return ngModuleDef;
    }
  });
  let ngFactoryDef = null;
  Object.defineProperty(moduleType, NG_FACTORY_DEF, {
    get: () => {
      if (ngFactoryDef === null) {
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'NgModule',
          type: moduleType
        });
        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${moduleType.name}/ɵfac.js`, {
          name: moduleType.name,
          type: moduleType,
          deps: reflectDependencies(moduleType),
          target: compiler.FactoryTarget.NgModule,
          typeArgumentCount: 0
        });
      }
      return ngFactoryDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
  let ngInjectorDef = null;
  Object.defineProperty(moduleType, NG_INJ_DEF, {
    get: () => {
      if (ngInjectorDef === null) {
        ngDevMode && verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot);
        const meta = {
          name: moduleType.name,
          type: moduleType,
          providers: ngModule.providers || EMPTY_ARRAY,
          imports: [(ngModule.imports || EMPTY_ARRAY).map(resolveForwardRef), (ngModule.exports || EMPTY_ARRAY).map(resolveForwardRef)]
        };
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'NgModule',
          type: moduleType
        });
        ngInjectorDef = compiler.compileInjector(angularCoreEnv, `ng:///${moduleType.name}/ɵinj.js`, meta);
      }
      return ngInjectorDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
}
function generateStandaloneInDeclarationsError(type, location) {
  const prefix = `Unexpected "${stringifyForError(type)}" found in the "declarations" array of the`;
  const suffix = `"${stringifyForError(type)}" is marked as standalone and can't be declared ` + 'in any NgModule - did you intend to import it instead (by adding it to the "imports" array)?';
  return `${prefix} ${location}, ${suffix}`;
}
function verifySemanticsOfNgModuleDef(moduleType, allowDuplicateDeclarationsInRoot, importingModule) {
  if (verifiedNgModule.get(moduleType)) return;
  // skip verifications of standalone components, directives, and pipes
  if (isStandalone(moduleType)) return;
  verifiedNgModule.set(moduleType, true);
  moduleType = resolveForwardRef(moduleType);
  let ngModuleDef;
  if (importingModule) {
    ngModuleDef = getNgModuleDef(moduleType);
    if (!ngModuleDef) {
      throw new Error(`Unexpected value '${moduleType.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
    }
  } else {
    ngModuleDef = getNgModuleDef(moduleType, true);
  }
  const errors = [];
  const declarations = maybeUnwrapFn(ngModuleDef.declarations);
  const imports = maybeUnwrapFn(ngModuleDef.imports);
  flatten(imports).map(unwrapModuleWithProvidersImports).forEach(modOrStandaloneCmpt => {
    verifySemanticsOfNgModuleImport(modOrStandaloneCmpt, moduleType);
    verifySemanticsOfNgModuleDef(modOrStandaloneCmpt, false, moduleType);
  });
  const exports = maybeUnwrapFn(ngModuleDef.exports);
  declarations.forEach(verifyDeclarationsHaveDefinitions);
  declarations.forEach(verifyDirectivesHaveSelector);
  declarations.forEach(declarationType => verifyNotStandalone(declarationType, moduleType));
  const combinedDeclarations = [...declarations.map(resolveForwardRef), ...flatten(imports.map(computeCombinedExports)).map(resolveForwardRef)];
  exports.forEach(verifyExportsAreDeclaredOrReExported);
  declarations.forEach(decl => verifyDeclarationIsUnique(decl, allowDuplicateDeclarationsInRoot));
  const ngModule = getAnnotation(moduleType, 'NgModule');
  if (ngModule) {
    ngModule.imports && flatten(ngModule.imports).map(unwrapModuleWithProvidersImports).forEach(mod => {
      verifySemanticsOfNgModuleImport(mod, moduleType);
      verifySemanticsOfNgModuleDef(mod, false, moduleType);
    });
    ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyCorrectBootstrapType);
    ngModule.bootstrap && deepForEach(ngModule.bootstrap, verifyComponentIsPartOfNgModule);
  }
  // Throw Error if any errors were detected.
  if (errors.length) {
    throw new Error(errors.join('\n'));
  }
  ////////////////////////////////////////////////////////////////////////////////////////////////
  function verifyDeclarationsHaveDefinitions(type) {
    type = resolveForwardRef(type);
    const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
    if (!def) {
      errors.push(`Unexpected value '${stringifyForError(type)}' declared by the module '${stringifyForError(moduleType)}'. Please add a @Pipe/@Directive/@Component annotation.`);
    }
  }
  function verifyDirectivesHaveSelector(type) {
    type = resolveForwardRef(type);
    const def = getDirectiveDef(type);
    if (!getComponentDef(type) && def && def.selectors.length == 0) {
      errors.push(`Directive ${stringifyForError(type)} has no selector, please add it!`);
    }
  }
  function verifyNotStandalone(type, moduleType) {
    type = resolveForwardRef(type);
    const def = getComponentDef(type) || getDirectiveDef(type) || getPipeDef$1(type);
    if (def?.standalone) {
      const location = `"${stringifyForError(moduleType)}" NgModule`;
      errors.push(generateStandaloneInDeclarationsError(type, location));
    }
  }
  function verifyExportsAreDeclaredOrReExported(type) {
    type = resolveForwardRef(type);
    const kind = getComponentDef(type) && 'component' || getDirectiveDef(type) && 'directive' || getPipeDef$1(type) && 'pipe';
    if (kind) {
      // only checked if we are declared as Component, Directive, or Pipe
      // Modules don't need to be declared or imported.
      if (combinedDeclarations.lastIndexOf(type) === -1) {
        // We are exporting something which we don't explicitly declare or import.
        errors.push(`Can't export ${kind} ${stringifyForError(type)} from ${stringifyForError(moduleType)} as it was neither declared nor imported!`);
      }
    }
  }
  function verifyDeclarationIsUnique(type, suppressErrors) {
    type = resolveForwardRef(type);
    const existingModule = ownerNgModule.get(type);
    if (existingModule && existingModule !== moduleType) {
      if (!suppressErrors) {
        const modules = [existingModule, moduleType].map(stringifyForError).sort();
        errors.push(`Type ${stringifyForError(type)} is part of the declarations of 2 modules: ${modules[0]} and ${modules[1]}! ` + `Please consider moving ${stringifyForError(type)} to a higher module that imports ${modules[0]} and ${modules[1]}. ` + `You can also create a new NgModule that exports and includes ${stringifyForError(type)} then import that NgModule in ${modules[0]} and ${modules[1]}.`);
      }
    } else {
      // Mark type as having owner.
      ownerNgModule.set(type, moduleType);
    }
  }
  function verifyComponentIsPartOfNgModule(type) {
    type = resolveForwardRef(type);
    const existingModule = ownerNgModule.get(type);
    if (!existingModule && !isStandalone(type)) {
      errors.push(`Component ${stringifyForError(type)} is not part of any NgModule or the module has not been imported into your module.`);
    }
  }
  function verifyCorrectBootstrapType(type) {
    type = resolveForwardRef(type);
    if (!getComponentDef(type)) {
      errors.push(`${stringifyForError(type)} cannot be used as an entry component.`);
    }
    if (isStandalone(type)) {
      // Note: this error should be the same as the
      // `NGMODULE_BOOTSTRAP_IS_STANDALONE` one in AOT compiler.
      errors.push(`The \`${stringifyForError(type)}\` class is a standalone component, which can ` + `not be used in the \`@NgModule.bootstrap\` array. Use the \`bootstrapApplication\` ` + `function for bootstrap instead.`);
    }
  }
  function verifySemanticsOfNgModuleImport(type, importingModule) {
    type = resolveForwardRef(type);
    const directiveDef = getComponentDef(type) || getDirectiveDef(type);
    if (directiveDef !== null && !directiveDef.standalone) {
      throw new Error(`Unexpected directive '${type.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
    }
    const pipeDef = getPipeDef$1(type);
    if (pipeDef !== null && !pipeDef.standalone) {
      throw new Error(`Unexpected pipe '${type.name}' imported by the module '${importingModule.name}'. Please add an @NgModule annotation.`);
    }
  }
}
function unwrapModuleWithProvidersImports(typeOrWithProviders) {
  typeOrWithProviders = resolveForwardRef(typeOrWithProviders);
  return typeOrWithProviders.ngModule || typeOrWithProviders;
}
function getAnnotation(type, name) {
  let annotation = null;
  collect(type.__annotations__);
  collect(type.decorators);
  return annotation;
  function collect(annotations) {
    if (annotations) {
      annotations.forEach(readAnnotation);
    }
  }
  function readAnnotation(decorator) {
    if (!annotation) {
      const proto = Object.getPrototypeOf(decorator);
      if (proto.ngMetadataName == name) {
        annotation = decorator;
      } else if (decorator.type) {
        const proto = Object.getPrototypeOf(decorator.type);
        if (proto.ngMetadataName == name) {
          annotation = decorator.args[0];
        }
      }
    }
  }
}
/**
 * Keep track of compiled components. This is needed because in tests we often want to compile the
 * same component with more than one NgModule. This would cause an error unless we reset which
 * NgModule the component belongs to. We keep the list of compiled components here so that the
 * TestBed can reset it later.
 */
let ownerNgModule = new WeakMap();
let verifiedNgModule = new WeakMap();
function resetCompiledComponents() {
  ownerNgModule = new WeakMap();
  verifiedNgModule = new WeakMap();
  moduleQueue.length = 0;
  GENERATED_COMP_IDS.clear();
}
/**
 * Computes the combined declarations of explicit declarations, as well as declarations inherited by
 * traversing the exports of imported modules.
 * @param type
 */
function computeCombinedExports(type) {
  type = resolveForwardRef(type);
  const ngModuleDef = getNgModuleDef(type);
  // a standalone component, directive or pipe
  if (ngModuleDef === null) {
    return [type];
  }
  return flatten(maybeUnwrapFn(ngModuleDef.exports).map(type => {
    const ngModuleDef = getNgModuleDef(type);
    if (ngModuleDef) {
      verifySemanticsOfNgModuleDef(type, false);
      return computeCombinedExports(type);
    } else {
      return type;
    }
  }));
}
/**
 * Some declared components may be compiled asynchronously, and thus may not have their
 * ɵcmp set yet. If this is the case, then a reference to the module is written into
 * the `ngSelectorScope` property of the declared type.
 */
function setScopeOnDeclaredComponents(moduleType, ngModule) {
  const declarations = flatten(ngModule.declarations || EMPTY_ARRAY);
  const transitiveScopes = transitiveScopesFor(moduleType);
  declarations.forEach(declaration => {
    declaration = resolveForwardRef(declaration);
    if (declaration.hasOwnProperty(NG_COMP_DEF)) {
      // A `ɵcmp` field exists - go ahead and patch the component directly.
      const component = declaration;
      const componentDef = getComponentDef(component);
      patchComponentDefWithScope(componentDef, transitiveScopes);
    } else if (!declaration.hasOwnProperty(NG_DIR_DEF) && !declaration.hasOwnProperty(NG_PIPE_DEF)) {
      // Set `ngSelectorScope` for future reference when the component compilation finishes.
      declaration.ngSelectorScope = moduleType;
    }
  });
}
/**
 * Patch the definition of a component with directives and pipes from the compilation scope of
 * a given module.
 */
function patchComponentDefWithScope(componentDef, transitiveScopes) {
  componentDef.directiveDefs = () => Array.from(transitiveScopes.compilation.directives).map(dir => dir.hasOwnProperty(NG_COMP_DEF) ? getComponentDef(dir) : getDirectiveDef(dir)).filter(def => !!def);
  componentDef.pipeDefs = () => Array.from(transitiveScopes.compilation.pipes).map(pipe => getPipeDef$1(pipe));
  componentDef.schemas = transitiveScopes.schemas;
  // Since we avoid Components/Directives/Pipes recompiling in case there are no overrides, we
  // may face a problem where previously compiled defs available to a given Component/Directive
  // are cached in TView and may become stale (in case any of these defs gets recompiled). In
  // order to avoid this problem, we force fresh TView to be created.
  componentDef.tView = null;
}
/**
 * Compute the pair of transitive scopes (compilation scope and exported scope) for a given type
 * (either a NgModule or a standalone component / directive / pipe).
 */
function transitiveScopesFor(type) {
  if (isNgModule(type)) {
    if (USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
      const scope = depsTracker.getNgModuleScope(type);
      const def = getNgModuleDef(type, true);
      return {
        schemas: def.schemas || null,
        ...scope
      };
    } else {
      return transitiveScopesForNgModule(type);
    }
  } else if (isStandalone(type)) {
    const directiveDef = getComponentDef(type) || getDirectiveDef(type);
    if (directiveDef !== null) {
      return {
        schemas: null,
        compilation: {
          directives: new Set(),
          pipes: new Set()
        },
        exported: {
          directives: new Set([type]),
          pipes: new Set()
        }
      };
    }
    const pipeDef = getPipeDef$1(type);
    if (pipeDef !== null) {
      return {
        schemas: null,
        compilation: {
          directives: new Set(),
          pipes: new Set()
        },
        exported: {
          directives: new Set(),
          pipes: new Set([type])
        }
      };
    }
  }
  // TODO: change the error message to be more user-facing and take standalone into account
  throw new Error(`${type.name} does not have a module def (ɵmod property)`);
}
/**
 * Compute the pair of transitive scopes (compilation scope and exported scope) for a given module.
 *
 * This operation is memoized and the result is cached on the module's definition. This function can
 * be called on modules with components that have not fully compiled yet, but the result should not
 * be used until they have.
 *
 * @param moduleType module that transitive scope should be calculated for.
 */
function transitiveScopesForNgModule(moduleType) {
  const def = getNgModuleDef(moduleType, true);
  if (def.transitiveCompileScopes !== null) {
    return def.transitiveCompileScopes;
  }
  const scopes = {
    schemas: def.schemas || null,
    compilation: {
      directives: new Set(),
      pipes: new Set()
    },
    exported: {
      directives: new Set(),
      pipes: new Set()
    }
  };
  maybeUnwrapFn(def.imports).forEach(imported => {
    // When this module imports another, the imported module's exported directives and pipes are
    // added to the compilation scope of this module.
    const importedScope = transitiveScopesFor(imported);
    importedScope.exported.directives.forEach(entry => scopes.compilation.directives.add(entry));
    importedScope.exported.pipes.forEach(entry => scopes.compilation.pipes.add(entry));
  });
  maybeUnwrapFn(def.declarations).forEach(declared => {
    const declaredWithDefs = declared;
    if (getPipeDef$1(declaredWithDefs)) {
      scopes.compilation.pipes.add(declared);
    } else {
      // Either declared has a ɵcmp or ɵdir, or it's a component which hasn't
      // had its template compiled yet. In either case, it gets added to the compilation's
      // directives.
      scopes.compilation.directives.add(declared);
    }
  });
  maybeUnwrapFn(def.exports).forEach(exported => {
    const exportedType = exported;
    // Either the type is a module, a pipe, or a component/directive (which may not have a
    // ɵcmp as it might be compiled asynchronously).
    if (isNgModule(exportedType)) {
      // When this module exports another, the exported module's exported directives and pipes are
      // added to both the compilation and exported scopes of this module.
      const exportedScope = transitiveScopesFor(exportedType);
      exportedScope.exported.directives.forEach(entry => {
        scopes.compilation.directives.add(entry);
        scopes.exported.directives.add(entry);
      });
      exportedScope.exported.pipes.forEach(entry => {
        scopes.compilation.pipes.add(entry);
        scopes.exported.pipes.add(entry);
      });
    } else if (getPipeDef$1(exportedType)) {
      scopes.exported.pipes.add(exportedType);
    } else {
      scopes.exported.directives.add(exportedType);
    }
  });
  def.transitiveCompileScopes = scopes;
  return scopes;
}
function expandModuleWithProviders(value) {
  if (isModuleWithProviders(value)) {
    return value.ngModule;
  }
  return value;
}

/**
 * Keep track of the compilation depth to avoid reentrancy issues during JIT compilation. This
 * matters in the following scenario:
 *
 * Consider a component 'A' that extends component 'B', both declared in module 'M'. During
 * the compilation of 'A' the definition of 'B' is requested to capture the inheritance chain,
 * potentially triggering compilation of 'B'. If this nested compilation were to trigger
 * `flushModuleScopingQueueAsMuchAsPossible` it may happen that module 'M' is still pending in the
 * queue, resulting in 'A' and 'B' to be patched with the NgModule scope. As the compilation of
 * 'A' is still in progress, this would introduce a circular dependency on its compilation. To avoid
 * this issue, the module scope queue is only flushed for compilations at the depth 0, to ensure
 * all compilations have finished.
 */
let compilationDepth = 0;
/**
 * Compile an Angular component according to its decorator metadata, and patch the resulting
 * component def (ɵcmp) onto the component type.
 *
 * Compilation may be asynchronous (due to the need to resolve URLs for the component template or
 * other resources, for example). In the event that compilation is not immediate, `compileComponent`
 * will enqueue resource resolution into a global queue and will fail to return the `ɵcmp`
 * until the global queue has been resolved with a call to `resolveComponentResources`.
 */
function compileComponent(type, metadata) {
  // Initialize ngDevMode. This must be the first statement in compileComponent.
  // See the `initNgDevMode` docstring for more information.
  (typeof ngDevMode === 'undefined' || ngDevMode) && initNgDevMode();
  let ngComponentDef = null;
  // Metadata may have resources which need to be resolved.
  maybeQueueResolutionOfComponentResources(type, metadata);
  // Note that we're using the same function as `Directive`, because that's only subset of metadata
  // that we need to create the ngFactoryDef. We're avoiding using the component metadata
  // because we'd have to resolve the asynchronous templates.
  addDirectiveFactoryDef(type, metadata);
  Object.defineProperty(type, NG_COMP_DEF, {
    get: () => {
      if (ngComponentDef === null) {
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'component',
          type: type
        });
        if (componentNeedsResolution(metadata)) {
          const error = [`Component '${type.name}' is not resolved:`];
          if (metadata.templateUrl) {
            error.push(` - templateUrl: ${metadata.templateUrl}`);
          }
          if (metadata.styleUrls && metadata.styleUrls.length) {
            error.push(` - styleUrls: ${JSON.stringify(metadata.styleUrls)}`);
          }
          if (metadata.styleUrl) {
            error.push(` - styleUrl: ${metadata.styleUrl}`);
          }
          error.push(`Did you run and wait for 'resolveComponentResources()'?`);
          throw new Error(error.join('\n'));
        }
        // This const was called `jitOptions` previously but had to be renamed to `options` because
        // of a bug with Terser that caused optimized JIT builds to throw a `ReferenceError`.
        // This bug was investigated in https://github.com/angular/angular-cli/issues/17264.
        // We should not rename it back until https://github.com/terser/terser/issues/615 is fixed.
        const options = getJitOptions();
        let preserveWhitespaces = metadata.preserveWhitespaces;
        if (preserveWhitespaces === undefined) {
          if (options !== null && options.preserveWhitespaces !== undefined) {
            preserveWhitespaces = options.preserveWhitespaces;
          } else {
            preserveWhitespaces = false;
          }
        }
        let encapsulation = metadata.encapsulation;
        if (encapsulation === undefined) {
          if (options !== null && options.defaultEncapsulation !== undefined) {
            encapsulation = options.defaultEncapsulation;
          } else {
            encapsulation = ViewEncapsulation$1.Emulated;
          }
        }
        const templateUrl = metadata.templateUrl || `ng:///${type.name}/template.html`;
        const meta = {
          ...directiveMetadata(type, metadata),
          typeSourceSpan: compiler.createParseSourceSpan('Component', type.name, templateUrl),
          template: metadata.template || '',
          preserveWhitespaces,
          styles: typeof metadata.styles === 'string' ? [metadata.styles] : metadata.styles || EMPTY_ARRAY,
          animations: metadata.animations,
          // JIT components are always compiled against an empty set of `declarations`. Instead, the
          // `directiveDefs` and `pipeDefs` are updated at a later point:
          //  * for NgModule-based components, they're set when the NgModule which declares the
          //    component resolves in the module scoping queue
          //  * for standalone components, they're set just below, after `compileComponent`.
          declarations: [],
          changeDetection: metadata.changeDetection,
          encapsulation,
          interpolation: metadata.interpolation,
          viewProviders: metadata.viewProviders || null
        };
        compilationDepth++;
        try {
          if (meta.usesInheritance) {
            addDirectiveDefToUndecoratedParents(type);
          }
          ngComponentDef = compiler.compileComponent(angularCoreEnv, templateUrl, meta);
          if (metadata.standalone) {
            // Patch the component definition for standalone components with `directiveDefs` and
            // `pipeDefs` functions which lazily compute the directives/pipes available in the
            // standalone component. Also set `dependencies` to the lazily resolved list of imports.
            const imports = flatten(metadata.imports || EMPTY_ARRAY);
            const {
              directiveDefs,
              pipeDefs
            } = getStandaloneDefFunctions(type, imports);
            ngComponentDef.directiveDefs = directiveDefs;
            ngComponentDef.pipeDefs = pipeDefs;
            ngComponentDef.dependencies = () => imports.map(resolveForwardRef);
          }
        } finally {
          // Ensure that the compilation depth is decremented even when the compilation failed.
          compilationDepth--;
        }
        if (compilationDepth === 0) {
          // When NgModule decorator executed, we enqueued the module definition such that
          // it would only dequeue and add itself as module scope to all of its declarations,
          // but only if  if all of its declarations had resolved. This call runs the check
          // to see if any modules that are in the queue can be dequeued and add scope to
          // their declarations.
          flushModuleScopingQueueAsMuchAsPossible();
        }
        // If component compilation is async, then the @NgModule annotation which declares the
        // component may execute and set an ngSelectorScope property on the component type. This
        // allows the component to patch itself with directiveDefs from the module after it
        // finishes compiling.
        if (hasSelectorScope(type)) {
          const scopes = transitiveScopesFor(type.ngSelectorScope);
          patchComponentDefWithScope(ngComponentDef, scopes);
        }
        if (metadata.schemas) {
          if (metadata.standalone) {
            ngComponentDef.schemas = metadata.schemas;
          } else {
            throw new Error(`The 'schemas' was specified for the ${stringifyForError(type)} but is only valid on a component that is standalone.`);
          }
        } else if (metadata.standalone) {
          ngComponentDef.schemas = [];
        }
      }
      return ngComponentDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
}
/**
 * Build memoized `directiveDefs` and `pipeDefs` functions for the component definition of a
 * standalone component, which process `imports` and filter out directives and pipes. The use of
 * memoized functions here allows for the delayed resolution of any `forwardRef`s present in the
 * component's `imports`.
 */
function getStandaloneDefFunctions(type, imports) {
  let cachedDirectiveDefs = null;
  let cachedPipeDefs = null;
  const directiveDefs = () => {
    if (!USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
      if (cachedDirectiveDefs === null) {
        // Standalone components are always able to self-reference, so include the component's own
        // definition in its `directiveDefs`.
        cachedDirectiveDefs = [getComponentDef(type)];
        const seen = new Set([type]);
        for (const rawDep of imports) {
          ngDevMode && verifyStandaloneImport(rawDep, type);
          const dep = resolveForwardRef(rawDep);
          if (seen.has(dep)) {
            continue;
          }
          seen.add(dep);
          if (!!getNgModuleDef(dep)) {
            const scope = transitiveScopesFor(dep);
            for (const dir of scope.exported.directives) {
              const def = getComponentDef(dir) || getDirectiveDef(dir);
              if (def && !seen.has(dir)) {
                seen.add(dir);
                cachedDirectiveDefs.push(def);
              }
            }
          } else {
            const def = getComponentDef(dep) || getDirectiveDef(dep);
            if (def) {
              cachedDirectiveDefs.push(def);
            }
          }
        }
      }
      return cachedDirectiveDefs;
    } else {
      if (ngDevMode) {
        for (const rawDep of imports) {
          verifyStandaloneImport(rawDep, type);
        }
      }
      if (!isComponent(type)) {
        return [];
      }
      const scope = depsTracker.getStandaloneComponentScope(type, imports);
      return [...scope.compilation.directives].map(p => getComponentDef(p) || getDirectiveDef(p)).filter(d => d !== null);
    }
  };
  const pipeDefs = () => {
    if (!USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
      if (cachedPipeDefs === null) {
        cachedPipeDefs = [];
        const seen = new Set();
        for (const rawDep of imports) {
          const dep = resolveForwardRef(rawDep);
          if (seen.has(dep)) {
            continue;
          }
          seen.add(dep);
          if (!!getNgModuleDef(dep)) {
            const scope = transitiveScopesFor(dep);
            for (const pipe of scope.exported.pipes) {
              const def = getPipeDef$1(pipe);
              if (def && !seen.has(pipe)) {
                seen.add(pipe);
                cachedPipeDefs.push(def);
              }
            }
          } else {
            const def = getPipeDef$1(dep);
            if (def) {
              cachedPipeDefs.push(def);
            }
          }
        }
      }
      return cachedPipeDefs;
    } else {
      if (ngDevMode) {
        for (const rawDep of imports) {
          verifyStandaloneImport(rawDep, type);
        }
      }
      if (!isComponent(type)) {
        return [];
      }
      const scope = depsTracker.getStandaloneComponentScope(type, imports);
      return [...scope.compilation.pipes].map(p => getPipeDef$1(p)).filter(d => d !== null);
    }
  };
  return {
    directiveDefs,
    pipeDefs
  };
}
function hasSelectorScope(component) {
  return component.ngSelectorScope !== undefined;
}
/**
 * Compile an Angular directive according to its decorator metadata, and patch the resulting
 * directive def onto the component type.
 *
 * In the event that compilation is not immediate, `compileDirective` will return a `Promise` which
 * will resolve when compilation completes and the directive becomes usable.
 */
function compileDirective(type, directive) {
  let ngDirectiveDef = null;
  addDirectiveFactoryDef(type, directive || {});
  Object.defineProperty(type, NG_DIR_DEF, {
    get: () => {
      if (ngDirectiveDef === null) {
        // `directive` can be null in the case of abstract directives as a base class
        // that use `@Directive()` with no selector. In that case, pass empty object to the
        // `directiveMetadata` function instead of null.
        const meta = getDirectiveMetadata(type, directive || {});
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'directive',
          type
        });
        ngDirectiveDef = compiler.compileDirective(angularCoreEnv, meta.sourceMapUrl, meta.metadata);
      }
      return ngDirectiveDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
}
function getDirectiveMetadata(type, metadata) {
  const name = type && type.name;
  const sourceMapUrl = `ng:///${name}/ɵdir.js`;
  const compiler = getCompilerFacade({
    usage: 0 /* JitCompilerUsage.Decorator */,
    kind: 'directive',
    type
  });
  const facade = directiveMetadata(type, metadata);
  facade.typeSourceSpan = compiler.createParseSourceSpan('Directive', name, sourceMapUrl);
  if (facade.usesInheritance) {
    addDirectiveDefToUndecoratedParents(type);
  }
  return {
    metadata: facade,
    sourceMapUrl
  };
}
function addDirectiveFactoryDef(type, metadata) {
  let ngFactoryDef = null;
  Object.defineProperty(type, NG_FACTORY_DEF, {
    get: () => {
      if (ngFactoryDef === null) {
        const meta = getDirectiveMetadata(type, metadata);
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'directive',
          type
        });
        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${type.name}/ɵfac.js`, {
          name: meta.metadata.name,
          type: meta.metadata.type,
          typeArgumentCount: 0,
          deps: reflectDependencies(type),
          target: compiler.FactoryTarget.Directive
        });
      }
      return ngFactoryDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
}
function extendsDirectlyFromObject(type) {
  return Object.getPrototypeOf(type.prototype) === Object.prototype;
}
/**
 * Extract the `R3DirectiveMetadata` for a particular directive (either a `Directive` or a
 * `Component`).
 */
function directiveMetadata(type, metadata) {
  // Reflect inputs and outputs.
  const reflect = getReflect();
  const propMetadata = reflect.ownPropMetadata(type);
  return {
    name: type.name,
    type: type,
    selector: metadata.selector !== undefined ? metadata.selector : null,
    host: metadata.host || EMPTY_OBJ,
    propMetadata: propMetadata,
    inputs: metadata.inputs || EMPTY_ARRAY,
    outputs: metadata.outputs || EMPTY_ARRAY,
    queries: extractQueriesMetadata(type, propMetadata, isContentQuery),
    lifecycle: {
      usesOnChanges: reflect.hasLifecycleHook(type, 'ngOnChanges')
    },
    typeSourceSpan: null,
    usesInheritance: !extendsDirectlyFromObject(type),
    exportAs: extractExportAs(metadata.exportAs),
    providers: metadata.providers || null,
    viewQueries: extractQueriesMetadata(type, propMetadata, isViewQuery),
    isStandalone: !!metadata.standalone,
    isSignal: !!metadata.signals,
    hostDirectives: metadata.hostDirectives?.map(directive => typeof directive === 'function' ? {
      directive
    } : directive) || null
  };
}
/**
 * Adds a directive definition to all parent classes of a type that don't have an Angular decorator.
 */
function addDirectiveDefToUndecoratedParents(type) {
  const objPrototype = Object.prototype;
  let parent = Object.getPrototypeOf(type.prototype).constructor;
  // Go up the prototype until we hit `Object`.
  while (parent && parent !== objPrototype) {
    // Since inheritance works if the class was annotated already, we only need to add
    // the def if there are no annotations and the def hasn't been created already.
    if (!getDirectiveDef(parent) && !getComponentDef(parent) && shouldAddAbstractDirective(parent)) {
      compileDirective(parent, null);
    }
    parent = Object.getPrototypeOf(parent);
  }
}
function convertToR3QueryPredicate(selector) {
  return typeof selector === 'string' ? splitByComma(selector) : resolveForwardRef(selector);
}
function convertToR3QueryMetadata(propertyName, ann) {
  return {
    propertyName: propertyName,
    predicate: convertToR3QueryPredicate(ann.selector),
    descendants: ann.descendants,
    first: ann.first,
    read: ann.read ? ann.read : null,
    static: !!ann.static,
    emitDistinctChangesOnly: !!ann.emitDistinctChangesOnly,
    isSignal: !!ann.isSignal
  };
}
function extractQueriesMetadata(type, propMetadata, isQueryAnn) {
  const queriesMeta = [];
  for (const field in propMetadata) {
    if (propMetadata.hasOwnProperty(field)) {
      const annotations = propMetadata[field];
      annotations.forEach(ann => {
        if (isQueryAnn(ann)) {
          if (!ann.selector) {
            throw new Error(`Can't construct a query for the property "${field}" of ` + `"${stringifyForError(type)}" since the query selector wasn't defined.`);
          }
          if (annotations.some(isInputAnnotation)) {
            throw new Error(`Cannot combine @Input decorators with query decorators`);
          }
          queriesMeta.push(convertToR3QueryMetadata(field, ann));
        }
      });
    }
  }
  return queriesMeta;
}
function extractExportAs(exportAs) {
  return exportAs === undefined ? null : splitByComma(exportAs);
}
function isContentQuery(value) {
  const name = value.ngMetadataName;
  return name === 'ContentChild' || name === 'ContentChildren';
}
function isViewQuery(value) {
  const name = value.ngMetadataName;
  return name === 'ViewChild' || name === 'ViewChildren';
}
function isInputAnnotation(value) {
  return value.ngMetadataName === 'Input';
}
function splitByComma(value) {
  return value.split(',').map(piece => piece.trim());
}
const LIFECYCLE_HOOKS = ['ngOnChanges', 'ngOnInit', 'ngOnDestroy', 'ngDoCheck', 'ngAfterViewInit', 'ngAfterViewChecked', 'ngAfterContentInit', 'ngAfterContentChecked'];
function shouldAddAbstractDirective(type) {
  const reflect = getReflect();
  if (LIFECYCLE_HOOKS.some(hookName => reflect.hasLifecycleHook(type, hookName))) {
    return true;
  }
  const propMetadata = reflect.propMetadata(type);
  for (const field in propMetadata) {
    const annotations = propMetadata[field];
    for (let i = 0; i < annotations.length; i++) {
      const current = annotations[i];
      const metadataName = current.ngMetadataName;
      if (isInputAnnotation(current) || isContentQuery(current) || isViewQuery(current) || metadataName === 'Output' || metadataName === 'HostBinding' || metadataName === 'HostListener') {
        return true;
      }
    }
  }
  return false;
}
function compilePipe(type, meta) {
  let ngPipeDef = null;
  let ngFactoryDef = null;
  Object.defineProperty(type, NG_FACTORY_DEF, {
    get: () => {
      if (ngFactoryDef === null) {
        const metadata = getPipeMetadata(type, meta);
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'pipe',
          type: metadata.type
        });
        ngFactoryDef = compiler.compileFactory(angularCoreEnv, `ng:///${metadata.name}/ɵfac.js`, {
          name: metadata.name,
          type: metadata.type,
          typeArgumentCount: 0,
          deps: reflectDependencies(type),
          target: compiler.FactoryTarget.Pipe
        });
      }
      return ngFactoryDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
  Object.defineProperty(type, NG_PIPE_DEF, {
    get: () => {
      if (ngPipeDef === null) {
        const metadata = getPipeMetadata(type, meta);
        const compiler = getCompilerFacade({
          usage: 0 /* JitCompilerUsage.Decorator */,
          kind: 'pipe',
          type: metadata.type
        });
        ngPipeDef = compiler.compilePipe(angularCoreEnv, `ng:///${metadata.name}/ɵpipe.js`, metadata);
      }
      return ngPipeDef;
    },
    // Make the property configurable in dev mode to allow overriding in tests
    configurable: !!ngDevMode
  });
}
function getPipeMetadata(type, meta) {
  return {
    type: type,
    name: type.name,
    pipeName: meta.name,
    pure: meta.pure !== undefined ? meta.pure : true,
    isStandalone: !!meta.standalone
  };
}

/**
 * Type of the Directive metadata.
 *
 * @publicApi
 */
const Directive = makeDecorator('Directive', (dir = {}) => dir, undefined, undefined, (type, meta) => compileDirective(type, meta));
/**
 * Component decorator and metadata.
 *
 * @Annotation
 * @publicApi
 */
const Component = makeDecorator('Component', (c = {}) => ({
  changeDetection: ChangeDetectionStrategy.Default,
  ...c
}), Directive, undefined, (type, meta) => compileComponent(type, meta));
/**
 * @Annotation
 * @publicApi
 */
const Pipe = makeDecorator('Pipe', p => ({
  pure: true,
  ...p
}), undefined, undefined, (type, meta) => compilePipe(type, meta));
/**
 * @Annotation
 * @publicApi
 */
const Input = makePropDecorator('Input', arg => {
  if (!arg) {
    return {};
  }
  return typeof arg === 'string' ? {
    alias: arg
  } : arg;
});
/**
 * @Annotation
 * @publicApi
 */
const Output = makePropDecorator('Output', alias => ({
  alias
}));
/**
 * @Annotation
 * @publicApi
 */
const HostBinding = makePropDecorator('HostBinding', hostPropertyName => ({
  hostPropertyName
}));
/**
 * Decorator that binds a DOM event to a host listener and supplies configuration metadata.
 * Angular invokes the supplied handler method when the host element emits the specified event,
 * and updates the bound element with the result.
 *
 * If the handler method returns false, applies `preventDefault` on the bound element.
 *
 * @usageNotes
 *
 * The following example declares a directive
 * that attaches a click listener to a button and counts clicks.
 *
 * ```ts
 * @Directive({selector: 'button[counting]'})
 * class CountClicks {
 *   numberOfClicks = 0;
 *
 *   @HostListener('click', ['$event.target'])
 *   onClick(btn) {
 *     console.log('button', btn, 'number of clicks:', this.numberOfClicks++);
 *   }
 * }
 *
 * @Component({
 *   selector: 'app',
 *   template: '<button counting>Increment</button>',
 * })
 * class App {}
 *
 * ```
 *
 * The following example registers another DOM event handler that listens for `Enter` key-press
 * events on the global `window`.
 * ``` ts
 * import { HostListener, Component } from "@angular/core";
 *
 * @Component({
 *   selector: 'app',
 *   template: `<h1>Hello, you have pressed enter {{counter}} number of times!</h1> Press enter key
 * to increment the counter.
 *   <button (click)="resetCounter()">Reset Counter</button>`
 * })
 * class AppComponent {
 *   counter = 0;
 *   @HostListener('window:keydown.enter', ['$event'])
 *   handleKeyDown(event: KeyboardEvent) {
 *     this.counter++;
 *   }
 *   resetCounter() {
 *     this.counter = 0;
 *   }
 * }
 * ```
 * The list of valid key names for `keydown` and `keyup` events
 * can be found here:
 * https://www.w3.org/TR/DOM-Level-3-Events-key/#named-key-attribute-values
 *
 * Note that keys can also be combined, e.g. `@HostListener('keydown.shift.a')`.
 *
 * The global target names that can be used to prefix an event name are
 * `document:`, `window:` and `body:`.
 *
 * @Annotation
 * @publicApi
 */
const HostListener = makePropDecorator('HostListener', (eventName, args) => ({
  eventName,
  args
}));

/**
 * @Annotation
 */
const NgModule = makeDecorator('NgModule', ngModule => ngModule, undefined, undefined,
/**
 * Decorator that marks the following class as an NgModule, and supplies
 * configuration metadata for it.
 *
 * * The `declarations` option configures the compiler
 * with information about what belongs to the NgModule.
 * * The `providers` options configures the NgModule's injector to provide
 * dependencies the NgModule members.
 * * The `imports` and `exports` options bring in members from other modules, and make
 * this module's members available to others.
 */
(type, meta) => compileNgModule(type, meta));

/**
 * This indirection is needed to free up Component, etc symbols in the public API
 * to be used by the decorator versions of these annotations.
 */

/**
 * @description Represents the version of Angular
 *
 * @publicApi
 */
class Version {
  constructor(full) {
    this.full = full;
    const parts = full.split('.');
    this.major = parts[0];
    this.minor = parts[1];
    this.patch = parts.slice(2).join('.');
  }
}
/**
 * @publicApi
 */
const VERSION = new Version('17.3.12');
class Console {
  log(message) {
    // tslint:disable-next-line:no-console
    console.log(message);
  }
  // Note: for reporting errors use `DOM.logError()` as it is platform specific
  warn(message) {
    // tslint:disable-next-line:no-console
    console.warn(message);
  }
  static {
    this.ɵfac = function Console_Factory(t) {
      return new (t || Console)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: Console,
      factory: Console.ɵfac,
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Console, [{
    type: Injectable,
    args: [{
      providedIn: 'platform'
    }]
  }], null, null);
})();

/**
 * These are the data structures that our framework injector profiler will fill with data in order
 * to support DI debugging APIs.
 *
 * resolverToTokenToDependencies: Maps an injector to a Map of tokens to an Array of
 * dependencies. Injector -> Token -> Dependencies This is used to support the
 * getDependenciesFromInjectable API, which takes in an injector and a token and returns it's
 * dependencies.
 *
 * resolverToProviders: Maps a DI resolver (an Injector or a TNode) to the providers configured
 * within it This is used to support the getInjectorProviders API, which takes in an injector and
 * returns the providers that it was configured with. Note that for the element injector case we
 * use the TNode instead of the LView as the DI resolver. This is because the registration of
 * providers happens only once per type of TNode. If an injector is created with an identical TNode,
 * the providers for that injector will not be reconfigured.
 *
 * standaloneInjectorToComponent: Maps the injector of a standalone component to the standalone
 * component that it is associated with. Used in the getInjectorProviders API, specificially in the
 * discovery of import paths for each provider. This is necessary because the imports array of a
 * standalone component is processed and configured in its standalone injector, but exists within
 * the component's definition. Because getInjectorProviders takes in an injector, if that injector
 * is the injector of a standalone component, we need to be able to discover the place where the
 * imports array is located (the component) in order to flatten the imports array within it to
 * discover all of it's providers.
 *
 *
 * All of these data structures are instantiated with WeakMaps. This will ensure that the presence
 * of any object in the keys of these maps does not prevent the garbage collector from collecting
 * those objects. Because of this property of WeakMaps, these data structures will never be the
 * source of a memory leak.
 *
 * An example of this advantage: When components are destroyed, we don't need to do
 * any additional work to remove that component from our mappings.
 *
 */
class DIDebugData {
  constructor() {
    this.resolverToTokenToDependencies = new WeakMap();
    this.resolverToProviders = new WeakMap();
    this.standaloneInjectorToComponent = new WeakMap();
  }
  reset() {
    this.resolverToTokenToDependencies = new WeakMap();
    this.resolverToProviders = new WeakMap();
    this.standaloneInjectorToComponent = new WeakMap();
  }
}
let frameworkDIDebugData = new DIDebugData();
function getFrameworkDIDebugData() {
  return frameworkDIDebugData;
}
/**
 * Initalize default handling of injector events. This handling parses events
 * as they are emitted and constructs the data structures necessary to support
 * some of debug APIs.
 *
 * See handleInjectEvent, handleCreateEvent and handleProviderConfiguredEvent
 * for descriptions of each handler
 *
 * Supported APIs:
 *               - getDependenciesFromInjectable
 *               - getInjectorProviders
 */
function setupFrameworkInjectorProfiler() {
  frameworkDIDebugData.reset();
  setInjectorProfiler(injectorProfilerEvent => handleInjectorProfilerEvent(injectorProfilerEvent));
}
function handleInjectorProfilerEvent(injectorProfilerEvent) {
  const {
    context,
    type
  } = injectorProfilerEvent;
  if (type === 0 /* InjectorProfilerEventType.Inject */) {
    handleInjectEvent(context, injectorProfilerEvent.service);
  } else if (type === 1 /* InjectorProfilerEventType.InstanceCreatedByInjector */) {
    handleInstanceCreatedByInjectorEvent(context, injectorProfilerEvent.instance);
  } else if (type === 2 /* InjectorProfilerEventType.ProviderConfigured */) {
    handleProviderConfiguredEvent(context, injectorProfilerEvent.providerRecord);
  }
}
/**
 *
 * Stores the injected service in frameworkDIDebugData.resolverToTokenToDependencies
 * based on it's injector and token.
 *
 * @param context InjectorProfilerContext the injection context that this event occurred in.
 * @param data InjectedService the service associated with this inject event.
 *
 */
function handleInjectEvent(context, data) {
  const diResolver = getDIResolver(context.injector);
  if (diResolver === null) {
    throwError('An Inject event must be run within an injection context.');
  }
  const diResolverToInstantiatedToken = frameworkDIDebugData.resolverToTokenToDependencies;
  if (!diResolverToInstantiatedToken.has(diResolver)) {
    diResolverToInstantiatedToken.set(diResolver, new WeakMap());
  }
  // if token is a primitive type, ignore this event. We do this because we cannot keep track of
  // non-primitive tokens in WeakMaps since they are not garbage collectable.
  if (!canBeHeldWeakly(context.token)) {
    return;
  }
  const instantiatedTokenToDependencies = diResolverToInstantiatedToken.get(diResolver);
  if (!instantiatedTokenToDependencies.has(context.token)) {
    instantiatedTokenToDependencies.set(context.token, []);
  }
  const {
    token,
    value,
    flags
  } = data;
  assertDefined(context.token, 'Injector profiler context token is undefined.');
  const dependencies = instantiatedTokenToDependencies.get(context.token);
  assertDefined(dependencies, 'Could not resolve dependencies for token.');
  if (context.injector instanceof NodeInjector) {
    dependencies.push({
      token,
      value,
      flags,
      injectedIn: getNodeInjectorContext(context.injector)
    });
  } else {
    dependencies.push({
      token,
      value,
      flags
    });
  }
}
/**
 *
 * Returns the LView and TNode associated with a NodeInjector. Returns undefined if the injector
 * is not a NodeInjector.
 *
 * @param injector
 * @returns {lView: LView, tNode: TNode}|undefined
 */
function getNodeInjectorContext(injector) {
  if (!(injector instanceof NodeInjector)) {
    throwError('getNodeInjectorContext must be called with a NodeInjector');
  }
  const lView = getNodeInjectorLView(injector);
  const tNode = getNodeInjectorTNode(injector);
  if (tNode === null) {
    return;
  }
  assertTNodeForLView(tNode, lView);
  return {
    lView,
    tNode
  };
}
/**
 *
 * If the created instance is an instance of a standalone component, maps the injector to that
 * standalone component in frameworkDIDebugData.standaloneInjectorToComponent
 *
 * @param context InjectorProfilerContext the injection context that this event occurred in.
 * @param data InjectorCreatedInstance an object containing the instance that was just created
 *
 */
function handleInstanceCreatedByInjectorEvent(context, data) {
  const {
    value
  } = data;
  if (getDIResolver(context.injector) === null) {
    throwError('An InjectorCreatedInstance event must be run within an injection context.');
  }
  // if our value is an instance of a standalone component, map the injector of that standalone
  // component to the component class. Otherwise, this event is a noop.
  let standaloneComponent = undefined;
  if (typeof value === 'object') {
    standaloneComponent = value?.constructor;
  }
  if (standaloneComponent === undefined || !isStandaloneComponent(standaloneComponent)) {
    return;
  }
  const environmentInjector = context.injector.get(EnvironmentInjector, null, {
    optional: true
  });
  // Standalone components should have an environment injector. If one cannot be
  // found we may be in a test case for low level functionality that did not explictly
  // setup this injector. In those cases, we simply ignore this event.
  if (environmentInjector === null) {
    return;
  }
  const {
    standaloneInjectorToComponent
  } = frameworkDIDebugData;
  // If our injector has already been mapped, as is the case
  // when a standalone component imports another standalone component,
  // we consider the original component (the component doing the importing)
  // as the component connected to our injector.
  if (standaloneInjectorToComponent.has(environmentInjector)) {
    return;
  }
  // If our injector hasn't been mapped, then we map it to the standalone component
  standaloneInjectorToComponent.set(environmentInjector, standaloneComponent);
}
function isStandaloneComponent(value) {
  const def = getComponentDef(value);
  return !!def?.standalone;
}
/**
 *
 * Stores the emitted ProviderRecords from the InjectorProfilerEventType.ProviderConfigured
 * event in frameworkDIDebugData.resolverToProviders
 *
 * @param context InjectorProfilerContext the injection context that this event occurred in.
 * @param data ProviderRecord an object containing the instance that was just created
 *
 */
function handleProviderConfiguredEvent(context, data) {
  const {
    resolverToProviders
  } = frameworkDIDebugData;
  let diResolver;
  if (context?.injector instanceof NodeInjector) {
    diResolver = getNodeInjectorTNode(context.injector);
  } else {
    diResolver = context.injector;
  }
  if (diResolver === null) {
    throwError('A ProviderConfigured event must be run within an injection context.');
  }
  if (!resolverToProviders.has(diResolver)) {
    resolverToProviders.set(diResolver, []);
  }
  resolverToProviders.get(diResolver).push(data);
}
function getDIResolver(injector) {
  let diResolver = null;
  if (injector === undefined) {
    return diResolver;
  }
  // We use the LView as the diResolver for NodeInjectors because they
  // do not persist anywhere in the framework. They are simply wrappers around an LView and a TNode
  // that do persist. Because of this, we rely on the LView of the NodeInjector in order to use
  // as a concrete key to represent this injector. If we get the same LView back later, we know
  // we're looking at the same injector.
  if (injector instanceof NodeInjector) {
    diResolver = getNodeInjectorLView(injector);
  }
  // Other injectors can be used a keys for a map because their instances
  // persist
  else {
    diResolver = injector;
  }
  return diResolver;
}
// inspired by
// https://tc39.es/ecma262/multipage/executable-code-and-execution-contexts.html#sec-canbeheldweakly
function canBeHeldWeakly(value) {
  // we check for value !== null here because typeof null === 'object
  return value !== null && (typeof value === 'object' || typeof value === 'function' || typeof value === 'symbol');
}

/**
 * Marks a component for check (in case of OnPush components) and synchronously
 * performs change detection on the application this component belongs to.
 *
 * @param component Component to {@link ChangeDetectorRef#markForCheck mark for check}.
 *
 * @publicApi
 * @globalApi ng
 */
function applyChanges(component) {
  ngDevMode && assertDefined(component, 'component');
  markViewDirty(getComponentViewByInstance(component));
  getRootComponents(component).forEach(rootComponent => detectChanges(rootComponent));
}
/**
 * Synchronously perform change detection on a component (and possibly its sub-components).
 *
 * This function triggers change detection in a synchronous way on a component.
 *
 * @param component The component which the change detection should be performed on.
 */
function detectChanges(component) {
  const view = getComponentViewByInstance(component);
  view[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
  detectChangesInternal(view);
}

/**
 * Discovers the dependencies of an injectable instance. Provides DI information about each
 * dependency that the injectable was instantiated with, including where they were provided from.
 *
 * @param injector An injector instance
 * @param token a DI token that was constructed by the given injector instance
 * @returns an object that contains the created instance of token as well as all of the dependencies
 * that it was instantiated with OR undefined if the token was not created within the given
 * injector.
 */
function getDependenciesFromInjectable(injector, token) {
  // First we check to see if the token given maps to an actual instance in the injector given.
  // We use `self: true` because we only want to look at the injector we were given.
  // We use `optional: true` because it's possible that the token we were given was never
  // constructed by the injector we were given.
  const instance = injector.get(token, null, {
    self: true,
    optional: true
  });
  if (instance === null) {
    throw new Error(`Unable to determine instance of ${token} in given injector`);
  }
  const unformattedDependencies = getDependenciesForTokenInInjector(token, injector);
  const resolutionPath = getInjectorResolutionPath(injector);
  const dependencies = unformattedDependencies.map(dep => {
    // injectedIn contains private fields, so we omit it from the response
    const formattedDependency = {
      value: dep.value
    };
    // convert injection flags to booleans
    const flags = dep.flags;
    formattedDependency.flags = {
      optional: (8 /* InternalInjectFlags.Optional */ & flags) === 8 /* InternalInjectFlags.Optional */,
      host: (1 /* InternalInjectFlags.Host */ & flags) === 1 /* InternalInjectFlags.Host */,
      self: (2 /* InternalInjectFlags.Self */ & flags) === 2 /* InternalInjectFlags.Self */,
      skipSelf: (4 /* InternalInjectFlags.SkipSelf */ & flags) === 4 /* InternalInjectFlags.SkipSelf */
    };
    // find the injector that provided the dependency
    for (let i = 0; i < resolutionPath.length; i++) {
      const injectorToCheck = resolutionPath[i];
      // if skipSelf is true we skip the first injector
      if (i === 0 && formattedDependency.flags.skipSelf) {
        continue;
      }
      // host only applies to NodeInjectors
      if (formattedDependency.flags.host && injectorToCheck instanceof EnvironmentInjector) {
        break;
      }
      const instance = injectorToCheck.get(dep.token, null, {
        self: true,
        optional: true
      });
      if (instance !== null) {
        // if host flag is true we double check that we can get the service from the first element
        // in the resolution path by using the host flag. This is done to make sure that we've found
        // the correct providing injector, and not a node injector that is connected to our path via
        // a router outlet.
        if (formattedDependency.flags.host) {
          const firstInjector = resolutionPath[0];
          const lookupFromFirstInjector = firstInjector.get(dep.token, null, {
            ...formattedDependency.flags,
            optional: true
          });
          if (lookupFromFirstInjector !== null) {
            formattedDependency.providedIn = injectorToCheck;
          }
          break;
        }
        formattedDependency.providedIn = injectorToCheck;
        break;
      }
      // if self is true we stop after the first injector
      if (i === 0 && formattedDependency.flags.self) {
        break;
      }
    }
    if (dep.token) formattedDependency.token = dep.token;
    return formattedDependency;
  });
  return {
    instance,
    dependencies
  };
}
function getDependenciesForTokenInInjector(token, injector) {
  const {
    resolverToTokenToDependencies
  } = getFrameworkDIDebugData();
  if (!(injector instanceof NodeInjector)) {
    return resolverToTokenToDependencies.get(injector)?.get?.(token) ?? [];
  }
  const lView = getNodeInjectorLView(injector);
  const tokenDependencyMap = resolverToTokenToDependencies.get(lView);
  const dependencies = tokenDependencyMap?.get(token) ?? [];
  // In the NodeInjector case, all injections for every node are stored in the same lView.
  // We use the injectedIn field of the dependency to filter out the dependencies that
  // do not come from the same node as the instance we're looking at.
  return dependencies.filter(dependency => {
    const dependencyNode = dependency.injectedIn?.tNode;
    if (dependencyNode === undefined) {
      return false;
    }
    const instanceNode = getNodeInjectorTNode(injector);
    assertTNode(dependencyNode);
    assertTNode(instanceNode);
    return dependencyNode === instanceNode;
  });
}
/**
 * Gets the class associated with an injector that contains a provider `imports` array in it's
 * definition
 *
 * For Module Injectors this returns the NgModule constructor.
 *
 * For Standalone injectors this returns the standalone component constructor.
 *
 * @param injector Injector an injector instance
 * @returns the constructor where the `imports` array that configures this injector is located
 */
function getProviderImportsContainer(injector) {
  const {
    standaloneInjectorToComponent
  } = getFrameworkDIDebugData();
  // standalone components configure providers through a component def, so we have to
  // use the standalone component associated with this injector if Injector represents
  // a standalone components EnvironmentInjector
  if (standaloneInjectorToComponent.has(injector)) {
    return standaloneInjectorToComponent.get(injector);
  }
  // Module injectors configure providers through their NgModule def, so we use the
  // injector to lookup its NgModuleRef and through that grab its instance
  const defTypeRef = injector.get(NgModuleRef$1, null, {
    self: true,
    optional: true
  });
  // If we can't find an associated imports container, return null.
  // This could be the case if this function is called with an R3Injector that does not represent
  // a standalone component or NgModule.
  if (defTypeRef === null) {
    return null;
  }
  // In standalone applications, the root environment injector created by bootstrapApplication
  // may have no associated "instance".
  if (defTypeRef.instance === null) {
    return null;
  }
  return defTypeRef.instance.constructor;
}
/**
 * Gets the providers configured on a NodeInjector
 *
 * @param injector A NodeInjector instance
 * @returns ProviderRecord[] an array of objects representing the providers configured on this
 *     injector
 */
function getNodeInjectorProviders(injector) {
  const diResolver = getNodeInjectorTNode(injector);
  const {
    resolverToProviders
  } = getFrameworkDIDebugData();
  return resolverToProviders.get(diResolver) ?? [];
}
/**
 * Gets a mapping of providers configured on an injector to their import paths
 *
 * ModuleA -> imports ModuleB
 * ModuleB -> imports ModuleC
 * ModuleB -> provides MyServiceA
 * ModuleC -> provides MyServiceB
 *
 * getProviderImportPaths(ModuleA)
 * > Map(2) {
 *   MyServiceA => [ModuleA, ModuleB]
 *   MyServiceB => [ModuleA, ModuleB, ModuleC]
 *  }
 *
 * @param providerImportsContainer constructor of class that contains an `imports` array in it's
 *     definition
 * @returns A Map object that maps providers to an array of constructors representing it's import
 *     path
 *
 */
function getProviderImportPaths(providerImportsContainer) {
  const providerToPath = new Map();
  const visitedContainers = new Set();
  const visitor = walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers);
  walkProviderTree(providerImportsContainer, visitor, [], new Set());
  return providerToPath;
}
/**
 *
 * Higher order function that returns a visitor for WalkProviderTree
 *
 * Takes in a Map and Set to keep track of the providers and containers
 * visited, so that we can discover the import paths of these providers
 * during the traversal.
 *
 * This visitor takes advantage of the fact that walkProviderTree performs a
 * postorder traversal of the provider tree for the passed in container. Because postorder
 * traversal recursively processes subtrees from leaf nodes until the traversal reaches the root,
 * we write a visitor that constructs provider import paths in reverse.
 *
 *
 * We use the visitedContainers set defined outside this visitor
 * because we want to run some logic only once for
 * each container in the tree. That logic can be described as:
 *
 *
 * 1. for each discovered_provider and discovered_path in the incomplete provider paths we've
 * already discovered
 * 2. get the first container in discovered_path
 * 3. if that first container is in the imports array of the container we're visiting
 *    Then the container we're visiting is also in the import path of discovered_provider, so we
 *    unshift discovered_path with the container we're currently visiting
 *
 *
 * Example Run:
 * ```
 *                 ┌──────────┐
 *                 │containerA│
 *      ┌─imports-─┤          ├──imports─┐
 *      │          │  provA   │          │
 *      │          │  provB   │          │
 *      │          └──────────┘          │
 *      │                                │
 *     ┌▼─────────┐             ┌────────▼─┐
 *     │containerB│             │containerC│
 *     │          │             │          │
 *     │  provD   │             │  provF   │
 *     │  provE   │             │  provG   │
 *     └──────────┘             └──────────┘
 * ```
 *
 * Each step of the traversal,
 *
 * ```
 * visitor(provD, containerB)
 * providerToPath === Map { provD => [containerB] }
 * visitedContainers === Set { containerB }
 *
 * visitor(provE, containerB)
 * providerToPath === Map { provD => [containerB], provE => [containerB] }
 * visitedContainers === Set { containerB }
 *
 * visitor(provF, containerC)
 * providerToPath === Map { provD => [containerB], provE => [containerB], provF => [containerC] }
 * visitedContainers === Set { containerB, containerC }
 *
 * visitor(provG, containerC)
 * providerToPath === Map {
 *   provD => [containerB], provE => [containerB], provF => [containerC], provG => [containerC]
 * }
 * visitedContainers === Set { containerB, containerC }
 *
 * visitor(provA, containerA)
 * providerToPath === Map {
 *   provD => [containerA, containerB],
 *   provE => [containerA, containerB],
 *   provF => [containerA, containerC],
 *   provG => [containerA, containerC],
 *   provA => [containerA]
 * }
 * visitedContainers === Set { containerB, containerC, containerA }
 *
 * visitor(provB, containerA)
 * providerToPath === Map {
 *   provD => [containerA, containerB],
 *   provE => [containerA, containerB],
 *   provF => [containerA, containerC],
 *   provG => [containerA, containerC],
 *   provA => [containerA]
 *   provB => [containerA]
 * }
 * visitedContainers === Set { containerB, containerC, containerA }
 * ```
 *
 * @param providerToPath Map map of providers to paths that this function fills
 * @param visitedContainers Set a set to keep track of the containers we've already visited
 * @return function(provider SingleProvider, container: Type<unknown> | InjectorType<unknown>) =>
 *     void
 */
function walkProviderTreeToDiscoverImportPaths(providerToPath, visitedContainers) {
  return (provider, container) => {
    // If the provider is not already in the providerToPath map,
    // add an entry with the provider as the key and an array containing the current container as
    // the value
    if (!providerToPath.has(provider)) {
      providerToPath.set(provider, [container]);
    }
    // This block will run exactly once for each container in the import tree.
    // This is where we run the logic to check the imports array of the current
    // container to see if it's the next container in the path for our currently
    // discovered providers.
    if (!visitedContainers.has(container)) {
      // Iterate through the providers we've already seen
      for (const prov of providerToPath.keys()) {
        const existingImportPath = providerToPath.get(prov);
        let containerDef = getInjectorDef(container);
        if (!containerDef) {
          const ngModule = container.ngModule;
          containerDef = getInjectorDef(ngModule);
        }
        if (!containerDef) {
          return;
        }
        const lastContainerAddedToPath = existingImportPath[0];
        let isNextStepInPath = false;
        deepForEach(containerDef.imports, moduleImport => {
          if (isNextStepInPath) {
            return;
          }
          isNextStepInPath = moduleImport.ngModule === lastContainerAddedToPath || moduleImport === lastContainerAddedToPath;
          if (isNextStepInPath) {
            providerToPath.get(prov)?.unshift(container);
          }
        });
      }
    }
    visitedContainers.add(container);
  };
}
/**
 * Gets the providers configured on an EnvironmentInjector
 *
 * @param injector EnvironmentInjector
 * @returns an array of objects representing the providers of the given injector
 */
function getEnvironmentInjectorProviders(injector) {
  const providerRecordsWithoutImportPaths = getFrameworkDIDebugData().resolverToProviders.get(injector) ?? [];
  // platform injector has no provider imports container so can we skip trying to
  // find import paths
  if (isPlatformInjector(injector)) {
    return providerRecordsWithoutImportPaths;
  }
  const providerImportsContainer = getProviderImportsContainer(injector);
  if (providerImportsContainer === null) {
    // We assume that if an environment injector exists without an associated provider imports
    // container, it was created without such a container. Some examples cases where this could
    // happen:
    // - The root injector of a standalone application
    // - A router injector created by using the providers array in a lazy loaded route
    // - A manually created injector that is attached to the injector tree
    // Since each of these cases has no provider container, there is no concept of import paths,
    // so we can simply return the provider records.
    return providerRecordsWithoutImportPaths;
  }
  const providerToPath = getProviderImportPaths(providerImportsContainer);
  const providerRecords = [];
  for (const providerRecord of providerRecordsWithoutImportPaths) {
    const provider = providerRecord.provider;
    // Ignore these special providers for now until we have a cleaner way of
    // determing when they are provided by the framework vs provided by the user.
    const token = provider.provide;
    if (token === ENVIRONMENT_INITIALIZER || token === INJECTOR_DEF_TYPES) {
      continue;
    }
    let importPath = providerToPath.get(provider) ?? [];
    const def = getComponentDef(providerImportsContainer);
    const isStandaloneComponent = !!def?.standalone;
    // We prepend the component constructor in the standalone case
    // because walkProviderTree does not visit this constructor during it's traversal
    if (isStandaloneComponent) {
      importPath = [providerImportsContainer, ...importPath];
    }
    providerRecords.push({
      ...providerRecord,
      importPath
    });
  }
  return providerRecords;
}
function isPlatformInjector(injector) {
  return injector instanceof R3Injector && injector.scopes.has('platform');
}
/**
 * Gets the providers configured on an injector.
 *
 * @param injector the injector to lookup the providers of
 * @returns ProviderRecord[] an array of objects representing the providers of the given injector
 */
function getInjectorProviders(injector) {
  if (injector instanceof NodeInjector) {
    return getNodeInjectorProviders(injector);
  } else if (injector instanceof EnvironmentInjector) {
    return getEnvironmentInjectorProviders(injector);
  }
  throwError('getInjectorProviders only supports NodeInjector and EnvironmentInjector');
}
/**
 *
 * Given an injector, this function will return
 * an object containing the type and source of the injector.
 *
 * |              | type        | source                                                      |
 * |--------------|-------------|-------------------------------------------------------------|
 * | NodeInjector | element     | DOM element that created this injector                      |
 * | R3Injector   | environment | `injector.source`                                           |
 * | NullInjector | null        | null                                                        |
 *
 * @param injector the Injector to get metadata for
 * @returns an object containing the type and source of the given injector. If the injector metadata
 *     cannot be determined, returns null.
 */
function getInjectorMetadata(injector) {
  if (injector instanceof NodeInjector) {
    const lView = getNodeInjectorLView(injector);
    const tNode = getNodeInjectorTNode(injector);
    assertTNodeForLView(tNode, lView);
    return {
      type: 'element',
      source: getNativeByTNode(tNode, lView)
    };
  }
  if (injector instanceof R3Injector) {
    return {
      type: 'environment',
      source: injector.source ?? null
    };
  }
  if (injector instanceof NullInjector) {
    return {
      type: 'null',
      source: null
    };
  }
  return null;
}
function getInjectorResolutionPath(injector) {
  const resolutionPath = [injector];
  getInjectorResolutionPathHelper(injector, resolutionPath);
  return resolutionPath;
}
function getInjectorResolutionPathHelper(injector, resolutionPath) {
  const parent = getInjectorParent(injector);
  // if getInjectorParent can't find a parent, then we've either reached the end
  // of the path, or we need to move from the Element Injector tree to the
  // module injector tree using the first injector in our path as the connection point.
  if (parent === null) {
    if (injector instanceof NodeInjector) {
      const firstInjector = resolutionPath[0];
      if (firstInjector instanceof NodeInjector) {
        const moduleInjector = getModuleInjectorOfNodeInjector(firstInjector);
        if (moduleInjector === null) {
          throwError('NodeInjector must have some connection to the module injector tree');
        }
        resolutionPath.push(moduleInjector);
        getInjectorResolutionPathHelper(moduleInjector, resolutionPath);
      }
      return resolutionPath;
    }
  } else {
    resolutionPath.push(parent);
    getInjectorResolutionPathHelper(parent, resolutionPath);
  }
  return resolutionPath;
}
/**
 * Gets the parent of an injector.
 *
 * This function is not able to make the jump from the Element Injector Tree to the Module
 * injector tree. This is because the "parent" (the next step in the reoslution path)
 * of a root NodeInjector is dependent on which NodeInjector ancestor initiated
 * the DI lookup. See getInjectorResolutionPath for a function that can make this jump.
 *
 * In the below diagram:
 * ```ts
 * getInjectorParent(NodeInjectorB)
 *  > NodeInjectorA
 * getInjectorParent(NodeInjectorA) // or getInjectorParent(getInjectorParent(NodeInjectorB))
 *  > null // cannot jump to ModuleInjector tree
 * ```
 *
 * ```
 *                ┌───────┐                ┌───────────────────┐
 *    ┌───────────┤ModuleA├───Injector────►│EnvironmentInjector│
 *    │           └───┬───┘                └───────────────────┘
 *    │               │
 *    │           bootstraps
 *    │               │
 *    │               │
 *    │          ┌────▼─────┐                 ┌─────────────┐
 * declares      │ComponentA├────Injector────►│NodeInjectorA│
 *    │          └────┬─────┘                 └─────▲───────┘
 *    │               │                             │
 *    │            renders                        parent
 *    │               │                             │
 *    │          ┌────▼─────┐                 ┌─────┴───────┐
 *    └─────────►│ComponentB├────Injector────►│NodeInjectorB│
 *               └──────────┘                 └─────────────┘
 *```
 *
 * @param injector an Injector to get the parent of
 * @returns Injector the parent of the given injector
 */
function getInjectorParent(injector) {
  if (injector instanceof R3Injector) {
    return injector.parent;
  }
  let tNode;
  let lView;
  if (injector instanceof NodeInjector) {
    tNode = getNodeInjectorTNode(injector);
    lView = getNodeInjectorLView(injector);
  } else if (injector instanceof NullInjector) {
    return null;
  } else if (injector instanceof ChainedInjector) {
    return injector.parentInjector;
  } else {
    throwError('getInjectorParent only support injectors of type R3Injector, NodeInjector, NullInjector, ChainedInjector');
  }
  const parentLocation = getParentInjectorLocation(tNode, lView);
  if (hasParentInjector(parentLocation)) {
    const parentInjectorIndex = getParentInjectorIndex(parentLocation);
    const parentLView = getParentInjectorView(parentLocation, lView);
    const parentTView = parentLView[TVIEW];
    const parentTNode = parentTView.data[parentInjectorIndex + 8 /* NodeInjectorOffset.TNODE */];
    return new NodeInjector(parentTNode, parentLView);
  } else {
    const chainedInjector = lView[INJECTOR];
    // Case where chainedInjector.injector is an OutletInjector and chainedInjector.injector.parent
    // is a NodeInjector.
    // todo(aleksanderbodurri): ideally nothing in packages/core should deal
    // directly with router concerns. Refactor this so that we can make the jump from
    // NodeInjector -> OutletInjector -> NodeInjector
    // without explictly relying on types contracts from packages/router
    const injectorParent = chainedInjector.injector?.parent;
    if (injectorParent instanceof NodeInjector) {
      return injectorParent;
    }
  }
  return null;
}
/**
 * Gets the module injector of a NodeInjector.
 *
 * @param injector NodeInjector to get module injector of
 * @returns Injector representing module injector of the given NodeInjector
 */
function getModuleInjectorOfNodeInjector(injector) {
  let lView;
  if (injector instanceof NodeInjector) {
    lView = getNodeInjectorLView(injector);
  } else {
    throwError('getModuleInjectorOfNodeInjector must be called with a NodeInjector');
  }
  const inj = lView[INJECTOR];
  const moduleInjector = inj instanceof ChainedInjector ? inj.parentInjector : inj.parent;
  if (!moduleInjector) {
    throwError('NodeInjector must have some connection to the module injector tree');
  }
  return moduleInjector;
}

/**
 * This file introduces series of globally accessible debug tools
 * to allow for the Angular debugging story to function.
 *
 * To see this in action run the following command:
 *
 *   bazel run //packages/core/test/bundling/todo:devserver
 *
 *  Then load `localhost:5432` and start using the console tools.
 */
/**
 * This value reflects the property on the window where the dev
 * tools are patched (window.ng).
 * */
const GLOBAL_PUBLISH_EXPANDO_KEY = 'ng';
const globalUtilsFunctions = {
  /**
   * Warning: functions that start with `ɵ` are considered *INTERNAL* and should not be relied upon
   * in application's code. The contract of those functions might be changed in any release and/or a
   * function can be removed completely.
   */
  'ɵgetDependenciesFromInjectable': getDependenciesFromInjectable,
  'ɵgetInjectorProviders': getInjectorProviders,
  'ɵgetInjectorResolutionPath': getInjectorResolutionPath,
  'ɵgetInjectorMetadata': getInjectorMetadata,
  'ɵsetProfiler': setProfiler,
  'getDirectiveMetadata': getDirectiveMetadata$1,
  'getComponent': getComponent$1,
  'getContext': getContext,
  'getListeners': getListeners,
  'getOwningComponent': getOwningComponent,
  'getHostElement': getHostElement,
  'getInjector': getInjector,
  'getRootComponents': getRootComponents,
  'getDirectives': getDirectives,
  'applyChanges': applyChanges,
  'isSignal': isSignal
};
let _published = false;
/**
 * Publishes a collection of default debug tools onto`window.ng`.
 *
 * These functions are available globally when Angular is in development
 * mode and are automatically stripped away from prod mode is on.
 */
function publishDefaultGlobalUtils$1() {
  if (!_published) {
    _published = true;
    if (typeof window !== 'undefined') {
      // Only configure the injector profiler when running in the browser.
      setupFrameworkInjectorProfiler();
    }
    for (const [methodName, method] of Object.entries(globalUtilsFunctions)) {
      publishGlobalUtil(methodName, method);
    }
  }
}
/**
 * Publishes the given function to `window.ng` so that it can be
 * used from the browser console when an application is not in production.
 */
function publishGlobalUtil(name, fn) {
  if (typeof COMPILED === 'undefined' || !COMPILED) {
    // Note: we can't export `ng` when using closure enhanced optimization as:
    // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
    // - we can't declare a closure extern as the namespace `ng` is already used within Google
    //   for typings for AngularJS (via `goog.provide('ng....')`).
    const w = _global;
    ngDevMode && assertDefined(fn, 'function not defined');
    w[GLOBAL_PUBLISH_EXPANDO_KEY] ??= {};
    w[GLOBAL_PUBLISH_EXPANDO_KEY][name] = fn;
  }
}

/**
 * Internal injection token that can used to access an instance of a Testability class.
 *
 * This token acts as a bridge between the core bootstrap code and the `Testability` class. This is
 * needed to ensure that there are no direct references to the `Testability` class, so it can be
 * tree-shaken away (if not referenced). For the environments/setups when the `Testability` class
 * should be available, this token is used to add a provider that references the `Testability`
 * class. Otherwise, only this token is retained in a bundle, but the `Testability` class is not.
 */
const TESTABILITY = new InjectionToken('');
/**
 * Internal injection token to retrieve Testability getter class instance.
 */
const TESTABILITY_GETTER = new InjectionToken('');
/**
 * The Testability service provides testing hooks that can be accessed from
 * the browser.
 *
 * Angular applications bootstrapped using an NgModule (via `@NgModule.bootstrap` field) will also
 * instantiate Testability by default (in both development and production modes).
 *
 * For applications bootstrapped using the `bootstrapApplication` function, Testability is not
 * included by default. You can include it into your applications by getting the list of necessary
 * providers using the `provideProtractorTestingSupport()` function and adding them into the
 * `options.providers` array. Example:
 *
 * ```typescript
 * import {provideProtractorTestingSupport} from '@angular/platform-browser';
 *
 * await bootstrapApplication(RootComponent, providers: [provideProtractorTestingSupport()]);
 * ```
 *
 * @publicApi
 */
class Testability {
  constructor(_ngZone, registry, testabilityGetter) {
    this._ngZone = _ngZone;
    this.registry = registry;
    this._pendingCount = 0;
    this._isZoneStable = true;
    this._callbacks = [];
    this.taskTrackingZone = null;
    // If there was no Testability logic registered in the global scope
    // before, register the current testability getter as a global one.
    if (!_testabilityGetter) {
      setTestabilityGetter(testabilityGetter);
      testabilityGetter.addToWindow(registry);
    }
    this._watchAngularEvents();
    _ngZone.run(() => {
      this.taskTrackingZone = typeof Zone == 'undefined' ? null : Zone.current.get('TaskTrackingZone');
    });
  }
  _watchAngularEvents() {
    this._ngZone.onUnstable.subscribe({
      next: () => {
        this._isZoneStable = false;
      }
    });
    this._ngZone.runOutsideAngular(() => {
      this._ngZone.onStable.subscribe({
        next: () => {
          NgZone.assertNotInAngularZone();
          queueMicrotask(() => {
            this._isZoneStable = true;
            this._runCallbacksIfReady();
          });
        }
      });
    });
  }
  /**
   * Increases the number of pending request
   * @deprecated pending requests are now tracked with zones.
   */
  increasePendingRequestCount() {
    this._pendingCount += 1;
    return this._pendingCount;
  }
  /**
   * Decreases the number of pending request
   * @deprecated pending requests are now tracked with zones
   */
  decreasePendingRequestCount() {
    this._pendingCount -= 1;
    if (this._pendingCount < 0) {
      throw new Error('pending async requests below zero');
    }
    this._runCallbacksIfReady();
    return this._pendingCount;
  }
  /**
   * Whether an associated application is stable
   */
  isStable() {
    return this._isZoneStable && this._pendingCount === 0 && !this._ngZone.hasPendingMacrotasks;
  }
  _runCallbacksIfReady() {
    if (this.isStable()) {
      // Schedules the call backs in a new frame so that it is always async.
      queueMicrotask(() => {
        while (this._callbacks.length !== 0) {
          let cb = this._callbacks.pop();
          clearTimeout(cb.timeoutId);
          cb.doneCb();
        }
      });
    } else {
      // Still not stable, send updates.
      let pending = this.getPendingTasks();
      this._callbacks = this._callbacks.filter(cb => {
        if (cb.updateCb && cb.updateCb(pending)) {
          clearTimeout(cb.timeoutId);
          return false;
        }
        return true;
      });
    }
  }
  getPendingTasks() {
    if (!this.taskTrackingZone) {
      return [];
    }
    // Copy the tasks data so that we don't leak tasks.
    return this.taskTrackingZone.macroTasks.map(t => {
      return {
        source: t.source,
        // From TaskTrackingZone:
        // https://github.com/angular/zone.js/blob/master/lib/zone-spec/task-tracking.ts#L40
        creationLocation: t.creationLocation,
        data: t.data
      };
    });
  }
  addCallback(cb, timeout, updateCb) {
    let timeoutId = -1;
    if (timeout && timeout > 0) {
      timeoutId = setTimeout(() => {
        this._callbacks = this._callbacks.filter(cb => cb.timeoutId !== timeoutId);
        cb();
      }, timeout);
    }
    this._callbacks.push({
      doneCb: cb,
      timeoutId: timeoutId,
      updateCb: updateCb
    });
  }
  /**
   * Wait for the application to be stable with a timeout. If the timeout is reached before that
   * happens, the callback receives a list of the macro tasks that were pending, otherwise null.
   *
   * @param doneCb The callback to invoke when Angular is stable or the timeout expires
   *    whichever comes first.
   * @param timeout Optional. The maximum time to wait for Angular to become stable. If not
   *    specified, whenStable() will wait forever.
   * @param updateCb Optional. If specified, this callback will be invoked whenever the set of
   *    pending macrotasks changes. If this callback returns true doneCb will not be invoked
   *    and no further updates will be issued.
   */
  whenStable(doneCb, timeout, updateCb) {
    if (updateCb && !this.taskTrackingZone) {
      throw new Error('Task tracking zone is required when passing an update callback to ' + 'whenStable(). Is "zone.js/plugins/task-tracking" loaded?');
    }
    this.addCallback(doneCb, timeout, updateCb);
    this._runCallbacksIfReady();
  }
  /**
   * Get the number of pending requests
   * @deprecated pending requests are now tracked with zones
   */
  getPendingRequestCount() {
    return this._pendingCount;
  }
  /**
   * Registers an application with a testability hook so that it can be tracked.
   * @param token token of application, root element
   *
   * @internal
   */
  registerApplication(token) {
    this.registry.registerApplication(token, this);
  }
  /**
   * Unregisters an application.
   * @param token token of application, root element
   *
   * @internal
   */
  unregisterApplication(token) {
    this.registry.unregisterApplication(token);
  }
  /**
   * Find providers by name
   * @param using The root element to search from
   * @param provider The name of binding variable
   * @param exactMatch Whether using exactMatch
   */
  findProviders(using, provider, exactMatch) {
    // TODO(juliemr): implement.
    return [];
  }
  static {
    this.ɵfac = function Testability_Factory(t) {
      return new (t || Testability)(ɵɵinject(NgZone), ɵɵinject(TestabilityRegistry), ɵɵinject(TESTABILITY_GETTER));
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: Testability,
      factory: Testability.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Testability, [{
    type: Injectable
  }], () => [{
    type: NgZone
  }, {
    type: TestabilityRegistry
  }, {
    type: undefined,
    decorators: [{
      type: Inject,
      args: [TESTABILITY_GETTER]
    }]
  }], null);
})();
/**
 * A global registry of {@link Testability} instances for specific elements.
 * @publicApi
 */
class TestabilityRegistry {
  constructor() {
    /** @internal */
    this._applications = new Map();
  }
  /**
   * Registers an application with a testability hook so that it can be tracked
   * @param token token of application, root element
   * @param testability Testability hook
   */
  registerApplication(token, testability) {
    this._applications.set(token, testability);
  }
  /**
   * Unregisters an application.
   * @param token token of application, root element
   */
  unregisterApplication(token) {
    this._applications.delete(token);
  }
  /**
   * Unregisters all applications
   */
  unregisterAllApplications() {
    this._applications.clear();
  }
  /**
   * Get a testability hook associated with the application
   * @param elem root element
   */
  getTestability(elem) {
    return this._applications.get(elem) || null;
  }
  /**
   * Get all registered testabilities
   */
  getAllTestabilities() {
    return Array.from(this._applications.values());
  }
  /**
   * Get all registered applications(root elements)
   */
  getAllRootElements() {
    return Array.from(this._applications.keys());
  }
  /**
   * Find testability of a node in the Tree
   * @param elem node
   * @param findInAncestors whether finding testability in ancestors if testability was not found in
   * current node
   */
  findTestabilityInTree(elem, findInAncestors = true) {
    return _testabilityGetter?.findTestabilityInTree(this, elem, findInAncestors) ?? null;
  }
  static {
    this.ɵfac = function TestabilityRegistry_Factory(t) {
      return new (t || TestabilityRegistry)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: TestabilityRegistry,
      factory: TestabilityRegistry.ɵfac,
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(TestabilityRegistry, [{
    type: Injectable,
    args: [{
      providedIn: 'platform'
    }]
  }], null, null);
})();
/**
 * Set the {@link GetTestability} implementation used by the Angular testing framework.
 * @publicApi
 */
function setTestabilityGetter(getter) {
  _testabilityGetter = getter;
}
let _testabilityGetter;

/**
 * Determine if the argument is shaped like a Promise
 */
function isPromise(obj) {
  // allow any Promise/A+ compliant thenable.
  // It's up to the caller to ensure that obj.then conforms to the spec
  return !!obj && typeof obj.then === 'function';
}
/**
 * Determine if the argument is a Subscribable
 */
function isSubscribable(obj) {
  return !!obj && typeof obj.subscribe === 'function';
}

/**
 * A [DI token](guide/glossary#di-token "DI token definition") that you can use to provide
 * one or more initialization functions.
 *
 * The provided functions are injected at application startup and executed during
 * app initialization. If any of these functions returns a Promise or an Observable, initialization
 * does not complete until the Promise is resolved or the Observable is completed.
 *
 * You can, for example, create a factory function that loads language data
 * or an external configuration, and provide that function to the `APP_INITIALIZER` token.
 * The function is executed during the application bootstrap process,
 * and the needed data is available on startup.
 *
 * @see {@link ApplicationInitStatus}
 *
 * @usageNotes
 *
 * The following example illustrates how to configure a multi-provider using `APP_INITIALIZER` token
 * and a function returning a promise.
 * ### Example with NgModule-based application
 * ```
 *  function initializeApp(): Promise<any> {
 *    return new Promise((resolve, reject) => {
 *      // Do some asynchronous stuff
 *      resolve();
 *    });
 *  }
 *
 *  @NgModule({
 *   imports: [BrowserModule],
 *   declarations: [AppComponent],
 *   bootstrap: [AppComponent],
 *   providers: [{
 *     provide: APP_INITIALIZER,
 *     useFactory: () => initializeApp,
 *     multi: true
 *    }]
 *   })
 *  export class AppModule {}
 * ```
 *
 * ### Example with standalone application
 * ```
 * export function initializeApp(http: HttpClient) {
 *   return (): Promise<any> =>
 *     firstValueFrom(
 *       http
 *         .get("https://someUrl.com/api/user")
 *         .pipe(tap(user => { ... }))
 *     );
 * }
 *
 * bootstrapApplication(App, {
 *   providers: [
 *     provideHttpClient(),
 *     {
 *       provide: APP_INITIALIZER,
 *       useFactory: initializeApp,
 *       multi: true,
 *       deps: [HttpClient],
 *     },
 *   ],
 * });

 * ```
 *
 *
 * It's also possible to configure a multi-provider using `APP_INITIALIZER` token and a function
 * returning an observable, see an example below. Note: the `HttpClient` in this example is used for
 * demo purposes to illustrate how the factory function can work with other providers available
 * through DI.
 *
 * ### Example with NgModule-based application
 * ```
 *  function initializeAppFactory(httpClient: HttpClient): () => Observable<any> {
 *   return () => httpClient.get("https://someUrl.com/api/user")
 *     .pipe(
 *        tap(user => { ... })
 *     );
 *  }
 *
 *  @NgModule({
 *    imports: [BrowserModule, HttpClientModule],
 *    declarations: [AppComponent],
 *    bootstrap: [AppComponent],
 *    providers: [{
 *      provide: APP_INITIALIZER,
 *      useFactory: initializeAppFactory,
 *      deps: [HttpClient],
 *      multi: true
 *    }]
 *  })
 *  export class AppModule {}
 * ```
 *
 * ### Example with standalone application
 * ```
 *  function initializeAppFactory(httpClient: HttpClient): () => Observable<any> {
 *   return () => httpClient.get("https://someUrl.com/api/user")
 *     .pipe(
 *        tap(user => { ... })
 *     );
 *  }
 *
 * bootstrapApplication(App, {
 *   providers: [
 *     provideHttpClient(),
 *     {
 *       provide: APP_INITIALIZER,
 *       useFactory: initializeAppFactory,
 *       multi: true,
 *       deps: [HttpClient],
 *     },
 *   ],
 * });
 * ```
 *
 * @publicApi
 */
const APP_INITIALIZER = new InjectionToken(ngDevMode ? 'Application Initializer' : '');
/**
 * A class that reflects the state of running {@link APP_INITIALIZER} functions.
 *
 * @publicApi
 */
class ApplicationInitStatus {
  constructor() {
    this.initialized = false;
    this.done = false;
    this.donePromise = new Promise((res, rej) => {
      this.resolve = res;
      this.reject = rej;
    });
    this.appInits = inject(APP_INITIALIZER, {
      optional: true
    }) ?? [];
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && !Array.isArray(this.appInits)) {
      throw new RuntimeError(-209 /* RuntimeErrorCode.INVALID_MULTI_PROVIDER */, 'Unexpected type of the `APP_INITIALIZER` token value ' + `(expected an array, but got ${typeof this.appInits}). ` + 'Please check that the `APP_INITIALIZER` token is configured as a ' + '`multi: true` provider.');
    }
  }
  /** @internal */
  runInitializers() {
    if (this.initialized) {
      return;
    }
    const asyncInitPromises = [];
    for (const appInits of this.appInits) {
      const initResult = appInits();
      if (isPromise(initResult)) {
        asyncInitPromises.push(initResult);
      } else if (isSubscribable(initResult)) {
        const observableAsPromise = new Promise((resolve, reject) => {
          initResult.subscribe({
            complete: resolve,
            error: reject
          });
        });
        asyncInitPromises.push(observableAsPromise);
      }
    }
    const complete = () => {
      // @ts-expect-error overwriting a readonly
      this.done = true;
      this.resolve();
    };
    Promise.all(asyncInitPromises).then(() => {
      complete();
    }).catch(e => {
      this.reject(e);
    });
    if (asyncInitPromises.length === 0) {
      complete();
    }
    this.initialized = true;
  }
  static {
    this.ɵfac = function ApplicationInitStatus_Factory(t) {
      return new (t || ApplicationInitStatus)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: ApplicationInitStatus,
      factory: ApplicationInitStatus.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationInitStatus, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();

/**
 * A [DI token](guide/glossary#di-token "DI token definition") that provides a set of callbacks to
 * be called for every component that is bootstrapped.
 *
 * Each callback must take a `ComponentRef` instance and return nothing.
 *
 * `(componentRef: ComponentRef) => void`
 *
 * @publicApi
 */
const APP_BOOTSTRAP_LISTENER = new InjectionToken(ngDevMode ? 'appBootstrapListener' : '');
function publishDefaultGlobalUtils() {
  ngDevMode && publishDefaultGlobalUtils$1();
}
/**
 * Sets the error for an invalid write to a signal to be an Angular `RuntimeError`.
 */
function publishSignalConfiguration() {
  (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setThrowInvalidWriteToSignalError)(() => {
    throw new RuntimeError(600 /* RuntimeErrorCode.SIGNAL_WRITE_FROM_ILLEGAL_CONTEXT */, ngDevMode && 'Writing to signals is not allowed in a `computed` or an `effect` by default. ' + 'Use `allowSignalWrites` in the `CreateEffectOptions` to enable this inside effects.');
  });
}
function isBoundToModule(cf) {
  return cf.isBoundToModule;
}
/**
 * A token for third-party components that can register themselves with NgProbe.
 *
 * @deprecated
 * @publicApi
 */
class NgProbeToken {
  constructor(name, token) {
    this.name = name;
    this.token = token;
  }
}
function _callAndReportToErrorHandler(errorHandler, ngZone, callback) {
  try {
    const result = callback();
    if (isPromise(result)) {
      return result.catch(e => {
        ngZone.runOutsideAngular(() => errorHandler.handleError(e));
        // rethrow as the exception handler might not do it
        throw e;
      });
    }
    return result;
  } catch (e) {
    ngZone.runOutsideAngular(() => errorHandler.handleError(e));
    // rethrow as the exception handler might not do it
    throw e;
  }
}
function optionsReducer(dst, objs) {
  if (Array.isArray(objs)) {
    return objs.reduce(optionsReducer, dst);
  }
  return {
    ...dst,
    ...objs
  };
}
/**
 * A reference to an Angular application running on a page.
 *
 * @usageNotes
 * {@a is-stable-examples}
 * ### isStable examples and caveats
 *
 * Note two important points about `isStable`, demonstrated in the examples below:
 * - the application will never be stable if you start any kind
 * of recurrent asynchronous task when the application starts
 * (for example for a polling process, started with a `setInterval`, a `setTimeout`
 * or using RxJS operators like `interval`);
 * - the `isStable` Observable runs outside of the Angular zone.
 *
 * Let's imagine that you start a recurrent task
 * (here incrementing a counter, using RxJS `interval`),
 * and at the same time subscribe to `isStable`.
 *
 * ```
 * constructor(appRef: ApplicationRef) {
 *   appRef.isStable.pipe(
 *      filter(stable => stable)
 *   ).subscribe(() => console.log('App is stable now');
 *   interval(1000).subscribe(counter => console.log(counter));
 * }
 * ```
 * In this example, `isStable` will never emit `true`,
 * and the trace "App is stable now" will never get logged.
 *
 * If you want to execute something when the app is stable,
 * you have to wait for the application to be stable
 * before starting your polling process.
 *
 * ```
 * constructor(appRef: ApplicationRef) {
 *   appRef.isStable.pipe(
 *     first(stable => stable),
 *     tap(stable => console.log('App is stable now')),
 *     switchMap(() => interval(1000))
 *   ).subscribe(counter => console.log(counter));
 * }
 * ```
 * In this example, the trace "App is stable now" will be logged
 * and then the counter starts incrementing every second.
 *
 * Note also that this Observable runs outside of the Angular zone,
 * which means that the code in the subscription
 * to this Observable will not trigger the change detection.
 *
 * Let's imagine that instead of logging the counter value,
 * you update a field of your component
 * and display it in its template.
 *
 * ```
 * constructor(appRef: ApplicationRef) {
 *   appRef.isStable.pipe(
 *     first(stable => stable),
 *     switchMap(() => interval(1000))
 *   ).subscribe(counter => this.value = counter);
 * }
 * ```
 * As the `isStable` Observable runs outside the zone,
 * the `value` field will be updated properly,
 * but the template will not be refreshed!
 *
 * You'll have to manually trigger the change detection to update the template.
 *
 * ```
 * constructor(appRef: ApplicationRef, cd: ChangeDetectorRef) {
 *   appRef.isStable.pipe(
 *     first(stable => stable),
 *     switchMap(() => interval(1000))
 *   ).subscribe(counter => {
 *     this.value = counter;
 *     cd.detectChanges();
 *   });
 * }
 * ```
 *
 * Or make the subscription callback run inside the zone.
 *
 * ```
 * constructor(appRef: ApplicationRef, zone: NgZone) {
 *   appRef.isStable.pipe(
 *     first(stable => stable),
 *     switchMap(() => interval(1000))
 *   ).subscribe(counter => zone.run(() => this.value = counter));
 * }
 * ```
 *
 * @publicApi
 */
class ApplicationRef {
  constructor() {
    /** @internal */
    this._bootstrapListeners = [];
    this._runningTick = false;
    this._destroyed = false;
    this._destroyListeners = [];
    /** @internal */
    this._views = [];
    this.internalErrorHandler = inject(INTERNAL_APPLICATION_ERROR_HANDLER);
    this.afterRenderEffectManager = inject(AfterRenderEventManager);
    // Needed for ComponentFixture temporarily during migration of autoDetect behavior
    // Eventually the hostView of the fixture should just attach to ApplicationRef.
    this.externalTestViews = new Set();
    this.beforeRender = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    this.afterTick = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
    /**
     * Get a list of component types registered to this application.
     * This list is populated even before the component is created.
     */
    this.componentTypes = [];
    /**
     * Get a list of components registered to this application.
     */
    this.components = [];
    /**
     * Returns an Observable that indicates when the application is stable or unstable.
     */
    this.isStable = inject(PendingTasks).hasPendingTasks.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.map)(pending => !pending));
    this._injector = inject(EnvironmentInjector);
  }
  /**
   * Indicates whether this instance was destroyed.
   */
  get destroyed() {
    return this._destroyed;
  }
  /**
   * The `EnvironmentInjector` used to create this application.
   */
  get injector() {
    return this._injector;
  }
  /**
   * Bootstrap a component onto the element identified by its selector or, optionally, to a
   * specified element.
   *
   * @usageNotes
   * ### Bootstrap process
   *
   * When bootstrapping a component, Angular mounts it onto a target DOM element
   * and kicks off automatic change detection. The target DOM element can be
   * provided using the `rootSelectorOrNode` argument.
   *
   * If the target DOM element is not provided, Angular tries to find one on a page
   * using the `selector` of the component that is being bootstrapped
   * (first matched element is used).
   *
   * ### Example
   *
   * Generally, we define the component to bootstrap in the `bootstrap` array of `NgModule`,
   * but it requires us to know the component while writing the application code.
   *
   * Imagine a situation where we have to wait for an API call to decide about the component to
   * bootstrap. We can use the `ngDoBootstrap` hook of the `NgModule` and call this method to
   * dynamically bootstrap a component.
   *
   * {@example core/ts/platform/platform.ts region='componentSelector'}
   *
   * Optionally, a component can be mounted onto a DOM element that does not match the
   * selector of the bootstrapped component.
   *
   * In the following example, we are providing a CSS selector to match the target element.
   *
   * {@example core/ts/platform/platform.ts region='cssSelector'}
   *
   * While in this example, we are providing reference to a DOM node.
   *
   * {@example core/ts/platform/platform.ts region='domNode'}
   */
  bootstrap(componentOrFactory, rootSelectorOrNode) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
    const isComponentFactory = componentOrFactory instanceof ComponentFactory$1;
    const initStatus = this._injector.get(ApplicationInitStatus);
    if (!initStatus.done) {
      const standalone = !isComponentFactory && isStandalone(componentOrFactory);
      const errorMessage = (typeof ngDevMode === 'undefined' || ngDevMode) && 'Cannot bootstrap as there are still asynchronous initializers running.' + (standalone ? '' : ' Bootstrap components in the `ngDoBootstrap` method of the root module.');
      throw new RuntimeError(405 /* RuntimeErrorCode.ASYNC_INITIALIZERS_STILL_RUNNING */, errorMessage);
    }
    let componentFactory;
    if (isComponentFactory) {
      componentFactory = componentOrFactory;
    } else {
      const resolver = this._injector.get(ComponentFactoryResolver$1);
      componentFactory = resolver.resolveComponentFactory(componentOrFactory);
    }
    this.componentTypes.push(componentFactory.componentType);
    // Create a factory associated with the current module if it's not bound to some other
    const ngModule = isBoundToModule(componentFactory) ? undefined : this._injector.get(NgModuleRef$1);
    const selectorOrNode = rootSelectorOrNode || componentFactory.selector;
    const compRef = componentFactory.create(Injector.NULL, [], selectorOrNode, ngModule);
    const nativeElement = compRef.location.nativeElement;
    const testability = compRef.injector.get(TESTABILITY, null);
    testability?.registerApplication(nativeElement);
    compRef.onDestroy(() => {
      this.detachView(compRef.hostView);
      remove(this.components, compRef);
      testability?.unregisterApplication(nativeElement);
    });
    this._loadComponent(compRef);
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      const _console = this._injector.get(Console);
      _console.log(`Angular is running in development mode.`);
    }
    return compRef;
  }
  /**
   * Invoke this method to explicitly process change detection and its side-effects.
   *
   * In development mode, `tick()` also performs a second change detection cycle to ensure that no
   * further changes are detected. If additional changes are picked up during this second cycle,
   * bindings in the app have side-effects that cannot be resolved in a single change detection
   * pass.
   * In this case, Angular throws an error, since an Angular application can only have one change
   * detection pass during which all change detection must complete.
   */
  tick() {
    this._tick(true);
  }
  /** @internal */
  _tick(refreshViews) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
    if (this._runningTick) {
      throw new RuntimeError(101 /* RuntimeErrorCode.RECURSIVE_APPLICATION_REF_TICK */, ngDevMode && 'ApplicationRef.tick is called recursively');
    }
    const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
    try {
      this._runningTick = true;
      this.detectChangesInAttachedViews(refreshViews);
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        for (let view of this._views) {
          view.checkNoChanges();
        }
      }
    } catch (e) {
      // Attention: Don't rethrow as it could cancel subscriptions to Observables!
      this.internalErrorHandler(e);
    } finally {
      this.afterTick.next();
      this._runningTick = false;
      (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
    }
  }
  detectChangesInAttachedViews(refreshViews) {
    let runs = 0;
    const afterRenderEffectManager = this.afterRenderEffectManager;
    while (true) {
      if (runs === MAXIMUM_REFRESH_RERUNS) {
        throw new RuntimeError(103 /* RuntimeErrorCode.INFINITE_CHANGE_DETECTION */, ngDevMode && 'Infinite change detection while refreshing application views. ' + 'Ensure afterRender or queueStateUpdate hooks are not continuously causing updates.');
      }
      if (refreshViews) {
        const isFirstPass = runs === 0;
        this.beforeRender.next(isFirstPass);
        for (let {
          _lView,
          notifyErrorHandler
        } of this._views) {
          detectChangesInViewIfRequired(_lView, isFirstPass, notifyErrorHandler);
        }
      }
      runs++;
      afterRenderEffectManager.executeInternalCallbacks();
      // If we have a newly dirty view after running internal callbacks, recheck the views again
      // before running user-provided callbacks
      if ([...this.externalTestViews.keys(), ...this._views].some(({
        _lView
      }) => shouldRecheckView(_lView))) {
        continue;
      }
      afterRenderEffectManager.execute();
      // If after running all afterRender callbacks we have no more views that need to be refreshed,
      // we can break out of the loop
      if (![...this.externalTestViews.keys(), ...this._views].some(({
        _lView
      }) => shouldRecheckView(_lView))) {
        break;
      }
    }
  }
  /**
   * Attaches a view so that it will be dirty checked.
   * The view will be automatically detached when it is destroyed.
   * This will throw if the view is already attached to a ViewContainer.
   */
  attachView(viewRef) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
    const view = viewRef;
    this._views.push(view);
    view.attachToAppRef(this);
  }
  /**
   * Detaches a view from dirty checking again.
   */
  detachView(viewRef) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
    const view = viewRef;
    remove(this._views, view);
    view.detachFromAppRef();
  }
  _loadComponent(componentRef) {
    this.attachView(componentRef.hostView);
    this.tick();
    this.components.push(componentRef);
    // Get the listeners lazily to prevent DI cycles.
    const listeners = this._injector.get(APP_BOOTSTRAP_LISTENER, []);
    if (ngDevMode && !Array.isArray(listeners)) {
      throw new RuntimeError(-209 /* RuntimeErrorCode.INVALID_MULTI_PROVIDER */, 'Unexpected type of the `APP_BOOTSTRAP_LISTENER` token value ' + `(expected an array, but got ${typeof listeners}). ` + 'Please check that the `APP_BOOTSTRAP_LISTENER` token is configured as a ' + '`multi: true` provider.');
    }
    [...this._bootstrapListeners, ...listeners].forEach(listener => listener(componentRef));
  }
  /** @internal */
  ngOnDestroy() {
    if (this._destroyed) return;
    try {
      // Call all the lifecycle hooks.
      this._destroyListeners.forEach(listener => listener());
      // Destroy all registered views.
      this._views.slice().forEach(view => view.destroy());
    } finally {
      // Indicate that this instance is destroyed.
      this._destroyed = true;
      // Release all references.
      this._views = [];
      this._bootstrapListeners = [];
      this._destroyListeners = [];
    }
  }
  /**
   * Registers a listener to be called when an instance is destroyed.
   *
   * @param callback A callback function to add as a listener.
   * @returns A function which unregisters a listener.
   */
  onDestroy(callback) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.warnIfDestroyed();
    this._destroyListeners.push(callback);
    return () => remove(this._destroyListeners, callback);
  }
  /**
   * Destroys an Angular application represented by this `ApplicationRef`. Calling this function
   * will destroy the associated environment injectors as well as all the bootstrapped components
   * with their views.
   */
  destroy() {
    if (this._destroyed) {
      throw new RuntimeError(406 /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */, ngDevMode && 'This instance of the `ApplicationRef` has already been destroyed.');
    }
    const injector = this._injector;
    // Check that this injector instance supports destroy operation.
    if (injector.destroy && !injector.destroyed) {
      // Destroying an underlying injector will trigger the `ngOnDestroy` lifecycle
      // hook, which invokes the remaining cleanup actions.
      injector.destroy();
    }
  }
  /**
   * Returns the number of attached views.
   */
  get viewCount() {
    return this._views.length;
  }
  warnIfDestroyed() {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && this._destroyed) {
      console.warn(formatRuntimeError(406 /* RuntimeErrorCode.APPLICATION_REF_ALREADY_DESTROYED */, 'This instance of the `ApplicationRef` has already been destroyed.'));
    }
  }
  static {
    this.ɵfac = function ApplicationRef_Factory(t) {
      return new (t || ApplicationRef)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: ApplicationRef,
      factory: ApplicationRef.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationRef, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function remove(list, el) {
  const index = list.indexOf(el);
  if (index > -1) {
    list.splice(index, 1);
  }
}
let whenStableStore;
/**
 * Returns a Promise that resolves when the application becomes stable after this method is called
 * the first time.
 */
function whenStable(applicationRef) {
  whenStableStore ??= new WeakMap();
  const cachedWhenStable = whenStableStore.get(applicationRef);
  if (cachedWhenStable) {
    return cachedWhenStable;
  }
  const whenStablePromise = applicationRef.isStable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.first)(isStable => isStable)).toPromise().then(() => void 0);
  whenStableStore.set(applicationRef, whenStablePromise);
  // Be a good citizen and clean the store `onDestroy` even though we are using `WeakMap`.
  applicationRef.onDestroy(() => whenStableStore?.delete(applicationRef));
  return whenStablePromise;
}
function detectChangesInViewIfRequired(lView, isFirstPass, notifyErrorHandler) {
  // When re-checking, only check views which actually need it.
  if (!isFirstPass && !shouldRecheckView(lView)) {
    return;
  }
  detectChangesInView(lView, notifyErrorHandler, isFirstPass);
}
function shouldRecheckView(view) {
  return requiresRefreshOrTraversal(view);
}
function detectChangesInView(lView, notifyErrorHandler, isFirstPass) {
  let mode;
  if (isFirstPass) {
    // The first pass is always in Global mode, which includes `CheckAlways` views.
    mode = 0 /* ChangeDetectionMode.Global */;
    // Add `RefreshView` flag to ensure this view is refreshed if not already dirty.
    // `RefreshView` flag is used intentionally over `Dirty` because it gets cleared before
    // executing any of the actual refresh code while the `Dirty` flag doesn't get cleared
    // until the end of the refresh. Using `RefreshView` prevents creating a potential
    // difference in the state of the LViewFlags during template execution.
    lView[FLAGS] |= 1024 /* LViewFlags.RefreshView */;
  } else if (lView[FLAGS] & 64 /* LViewFlags.Dirty */) {
    // The root view has been explicitly marked for check, so check it in Global mode.
    mode = 0 /* ChangeDetectionMode.Global */;
  } else {
    // The view has not been marked for check, but contains a view marked for refresh
    // (likely via a signal). Start this change detection in Targeted mode to skip the root
    // view and check just the view(s) that need refreshed.
    mode = 1 /* ChangeDetectionMode.Targeted */;
  }
  detectChangesInternal(lView, notifyErrorHandler, mode);
}

/**
 * Combination of NgModuleFactory and ComponentFactories.
 *
 * @publicApi
 *
 * @deprecated
 * Ivy JIT mode doesn't require accessing this symbol.
 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
 * additional context.
 */
class ModuleWithComponentFactories {
  constructor(ngModuleFactory, componentFactories) {
    this.ngModuleFactory = ngModuleFactory;
    this.componentFactories = componentFactories;
  }
}
/**
 * Low-level service for running the angular compiler during runtime
 * to create {@link ComponentFactory}s, which
 * can later be used to create and render a Component instance.
 *
 * Each `@NgModule` provides an own `Compiler` to its injector,
 * that will use the directives/pipes of the ng module for compilation
 * of components.
 *
 * @publicApi
 *
 * @deprecated
 * Ivy JIT mode doesn't require accessing this symbol.
 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
 * additional context.
 */
class Compiler {
  /**
   * Compiles the given NgModule and all of its components. All templates of the components
   * have to be inlined.
   */
  compileModuleSync(moduleType) {
    return new NgModuleFactory(moduleType);
  }
  /**
   * Compiles the given NgModule and all of its components
   */
  compileModuleAsync(moduleType) {
    return Promise.resolve(this.compileModuleSync(moduleType));
  }
  /**
   * Same as {@link #compileModuleSync} but also creates ComponentFactories for all components.
   */
  compileModuleAndAllComponentsSync(moduleType) {
    const ngModuleFactory = this.compileModuleSync(moduleType);
    const moduleDef = getNgModuleDef(moduleType);
    const componentFactories = maybeUnwrapFn(moduleDef.declarations).reduce((factories, declaration) => {
      const componentDef = getComponentDef(declaration);
      componentDef && factories.push(new ComponentFactory(componentDef));
      return factories;
    }, []);
    return new ModuleWithComponentFactories(ngModuleFactory, componentFactories);
  }
  /**
   * Same as {@link #compileModuleAsync} but also creates ComponentFactories for all components.
   */
  compileModuleAndAllComponentsAsync(moduleType) {
    return Promise.resolve(this.compileModuleAndAllComponentsSync(moduleType));
  }
  /**
   * Clears all caches.
   */
  clearCache() {}
  /**
   * Clears the cache for the given component/ngModule.
   */
  clearCacheFor(type) {}
  /**
   * Returns the id for a given NgModule, if one is defined and known to the compiler.
   */
  getModuleId(moduleType) {
    return undefined;
  }
  static {
    this.ɵfac = function Compiler_Factory(t) {
      return new (t || Compiler)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: Compiler,
      factory: Compiler.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(Compiler, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * Token to provide CompilerOptions in the platform injector.
 *
 * @publicApi
 */
const COMPILER_OPTIONS = new InjectionToken(ngDevMode ? 'compilerOptions' : '');
/**
 * A factory for creating a Compiler
 *
 * @publicApi
 *
 * @deprecated
 * Ivy JIT mode doesn't require accessing this symbol.
 * See [JIT API changes due to ViewEngine deprecation](guide/deprecations#jit-api-changes) for
 * additional context.
 */
class CompilerFactory {}
function compileNgModuleFactory(injector, options, moduleType) {
  ngDevMode && assertNgModuleType(moduleType);
  const moduleFactory = new NgModuleFactory(moduleType);
  // All of the logic below is irrelevant for AOT-compiled code.
  if (typeof ngJitMode !== 'undefined' && !ngJitMode) {
    return Promise.resolve(moduleFactory);
  }
  const compilerOptions = injector.get(COMPILER_OPTIONS, []).concat(options);
  // Configure the compiler to use the provided options. This call may fail when multiple modules
  // are bootstrapped with incompatible options, as a component can only be compiled according to
  // a single set of options.
  setJitOptions({
    defaultEncapsulation: _lastDefined(compilerOptions.map(opts => opts.defaultEncapsulation)),
    preserveWhitespaces: _lastDefined(compilerOptions.map(opts => opts.preserveWhitespaces))
  });
  if (isComponentResourceResolutionQueueEmpty()) {
    return Promise.resolve(moduleFactory);
  }
  const compilerProviders = compilerOptions.flatMap(option => option.providers ?? []);
  // In case there are no compiler providers, we just return the module factory as
  // there won't be any resource loader. This can happen with Ivy, because AOT compiled
  // modules can be still passed through "bootstrapModule". In that case we shouldn't
  // unnecessarily require the JIT compiler.
  if (compilerProviders.length === 0) {
    return Promise.resolve(moduleFactory);
  }
  const compiler = getCompilerFacade({
    usage: 0 /* JitCompilerUsage.Decorator */,
    kind: 'NgModule',
    type: moduleType
  });
  const compilerInjector = Injector.create({
    providers: compilerProviders
  });
  const resourceLoader = compilerInjector.get(compiler.ResourceLoader);
  // The resource loader can also return a string while the "resolveComponentResources"
  // always expects a promise. Therefore we need to wrap the returned value in a promise.
  return resolveComponentResources(url => Promise.resolve(resourceLoader.get(url))).then(() => moduleFactory);
}
function _lastDefined(args) {
  for (let i = args.length - 1; i >= 0; i--) {
    if (args[i] !== undefined) {
      return args[i];
    }
  }
  return undefined;
}
class NgZoneChangeDetectionScheduler {
  constructor() {
    this.zone = inject(NgZone);
    this.applicationRef = inject(ApplicationRef);
  }
  initialize() {
    if (this._onMicrotaskEmptySubscription) {
      return;
    }
    this._onMicrotaskEmptySubscription = this.zone.onMicrotaskEmpty.subscribe({
      next: () => {
        this.zone.run(() => {
          this.applicationRef.tick();
        });
      }
    });
  }
  ngOnDestroy() {
    this._onMicrotaskEmptySubscription?.unsubscribe();
  }
  static {
    this.ɵfac = function NgZoneChangeDetectionScheduler_Factory(t) {
      return new (t || NgZoneChangeDetectionScheduler)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: NgZoneChangeDetectionScheduler,
      factory: NgZoneChangeDetectionScheduler.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(NgZoneChangeDetectionScheduler, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * Internal token used to verify that `provideZoneChangeDetection` is not used
 * with the bootstrapModule API.
 */
const PROVIDED_NG_ZONE = new InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'provideZoneChangeDetection token' : '');
function internalProvideZoneChangeDetection(ngZoneFactory) {
  return [{
    provide: NgZone,
    useFactory: ngZoneFactory
  }, {
    provide: ENVIRONMENT_INITIALIZER,
    multi: true,
    useFactory: () => {
      const ngZoneChangeDetectionScheduler = inject(NgZoneChangeDetectionScheduler, {
        optional: true
      });
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && ngZoneChangeDetectionScheduler === null) {
        throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, `A required Injectable was not found in the dependency injection tree. ` + 'If you are bootstrapping an NgModule, make sure that the `BrowserModule` is imported.');
      }
      return () => ngZoneChangeDetectionScheduler.initialize();
    }
  }, {
    provide: ENVIRONMENT_INITIALIZER,
    multi: true,
    useFactory: () => {
      const service = inject(ZoneStablePendingTask);
      return () => {
        service.initialize();
      };
    }
  }, {
    provide: INTERNAL_APPLICATION_ERROR_HANDLER,
    useFactory: ngZoneApplicationErrorHandlerFactory
  }];
}
function ngZoneApplicationErrorHandlerFactory() {
  const zone = inject(NgZone);
  const userErrorHandler = inject(ErrorHandler);
  return e => zone.runOutsideAngular(() => userErrorHandler.handleError(e));
}
/**
 * Provides `NgZone`-based change detection for the application bootstrapped using
 * `bootstrapApplication`.
 *
 * `NgZone` is already provided in applications by default. This provider allows you to configure
 * options like `eventCoalescing` in the `NgZone`.
 * This provider is not available for `platformBrowser().bootstrapModule`, which uses
 * `BootstrapOptions` instead.
 *
 * @usageNotes
 * ```typescript
 * bootstrapApplication(MyApp, {providers: [
 *   provideZoneChangeDetection({eventCoalescing: true}),
 * ]});
 * ```
 *
 * @publicApi
 * @see {@link bootstrapApplication}
 * @see {@link NgZoneOptions}
 */
function provideZoneChangeDetection(options) {
  const zoneProviders = internalProvideZoneChangeDetection(() => new NgZone(getNgZoneOptions(options)));
  return makeEnvironmentProviders([typeof ngDevMode === 'undefined' || ngDevMode ? {
    provide: PROVIDED_NG_ZONE,
    useValue: true
  } : [], zoneProviders]);
}
// Transforms a set of `BootstrapOptions` (supported by the NgModule-based bootstrap APIs) ->
// `NgZoneOptions` that are recognized by the NgZone constructor. Passing no options will result in
// a set of default options returned.
function getNgZoneOptions(options) {
  return {
    enableLongStackTrace: typeof ngDevMode === 'undefined' ? false : !!ngDevMode,
    shouldCoalesceEventChangeDetection: options?.eventCoalescing ?? false,
    shouldCoalesceRunChangeDetection: options?.runCoalescing ?? false
  };
}
class ZoneStablePendingTask {
  constructor() {
    this.subscription = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subscription();
    this.initialized = false;
    this.zone = inject(NgZone);
    this.pendingTasks = inject(PendingTasks);
  }
  initialize() {
    if (this.initialized) {
      return;
    }
    this.initialized = true;
    let task = null;
    if (!this.zone.isStable && !this.zone.hasPendingMacrotasks && !this.zone.hasPendingMicrotasks) {
      task = this.pendingTasks.add();
    }
    this.zone.runOutsideAngular(() => {
      this.subscription.add(this.zone.onStable.subscribe(() => {
        NgZone.assertNotInAngularZone();
        // Check whether there are no pending macro/micro tasks in the next tick
        // to allow for NgZone to update the state.
        queueMicrotask(() => {
          if (task !== null && !this.zone.hasPendingMacrotasks && !this.zone.hasPendingMicrotasks) {
            this.pendingTasks.remove(task);
            task = null;
          }
        });
      }));
    });
    this.subscription.add(this.zone.onUnstable.subscribe(() => {
      NgZone.assertInAngularZone();
      task ??= this.pendingTasks.add();
    }));
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
  static {
    this.ɵfac = function ZoneStablePendingTask_Factory(t) {
      return new (t || ZoneStablePendingTask)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: ZoneStablePendingTask,
      factory: ZoneStablePendingTask.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ZoneStablePendingTask, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * Work out the locale from the potential global properties.
 *
 * * Closure Compiler: use `goog.LOCALE`.
 * * Ivy enabled: use `$localize.locale`
 */
function getGlobalLocale() {
  if (typeof ngI18nClosureMode !== 'undefined' && ngI18nClosureMode && typeof goog !== 'undefined' && goog.LOCALE !== 'en') {
    // * The default `goog.LOCALE` value is `en`, while Angular used `en-US`.
    // * In order to preserve backwards compatibility, we use Angular default value over
    //   Closure Compiler's one.
    return goog.LOCALE;
  } else {
    // KEEP `typeof $localize !== 'undefined' && $localize.locale` IN SYNC WITH THE LOCALIZE
    // COMPILE-TIME INLINER.
    //
    // * During compile time inlining of translations the expression will be replaced
    //   with a string literal that is the current locale. Other forms of this expression are not
    //   guaranteed to be replaced.
    //
    // * During runtime translation evaluation, the developer is required to set `$localize.locale`
    //   if required, or just to provide their own `LOCALE_ID` provider.
    return typeof $localize !== 'undefined' && $localize.locale || DEFAULT_LOCALE_ID;
  }
}
/**
 * Provide this token to set the locale of your application.
 * It is used for i18n extraction, by i18n pipes (DatePipe, I18nPluralPipe, CurrencyPipe,
 * DecimalPipe and PercentPipe) and by ICU expressions.
 *
 * See the [i18n guide](guide/i18n-common-locale-id) for more information.
 *
 * @usageNotes
 * ### Example
 *
 * ```typescript
 * import { LOCALE_ID } from '@angular/core';
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 * import { AppModule } from './app/app.module';
 *
 * platformBrowserDynamic().bootstrapModule(AppModule, {
 *   providers: [{provide: LOCALE_ID, useValue: 'en-US' }]
 * });
 * ```
 *
 * @publicApi
 */
const LOCALE_ID = new InjectionToken(ngDevMode ? 'LocaleId' : '', {
  providedIn: 'root',
  factory: () => inject(LOCALE_ID, InjectFlags.Optional | InjectFlags.SkipSelf) || getGlobalLocale()
});
/**
 * Provide this token to set the default currency code your application uses for
 * CurrencyPipe when there is no currency code passed into it. This is only used by
 * CurrencyPipe and has no relation to locale currency. Defaults to USD if not configured.
 *
 * See the [i18n guide](guide/i18n-common-locale-id) for more information.
 *
 * <div class="alert is-helpful">
 *
 * **Deprecation notice:**
 *
 * The default currency code is currently always `USD` but this is deprecated from v9.
 *
 * **In v10 the default currency code will be taken from the current locale.**
 *
 * If you need the previous behavior then set it by creating a `DEFAULT_CURRENCY_CODE` provider in
 * your application `NgModule`:
 *
 * ```ts
 * {provide: DEFAULT_CURRENCY_CODE, useValue: 'USD'}
 * ```
 *
 * </div>
 *
 * @usageNotes
 * ### Example
 *
 * ```typescript
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 * import { AppModule } from './app/app.module';
 *
 * platformBrowserDynamic().bootstrapModule(AppModule, {
 *   providers: [{provide: DEFAULT_CURRENCY_CODE, useValue: 'EUR' }]
 * });
 * ```
 *
 * @publicApi
 */
const DEFAULT_CURRENCY_CODE = new InjectionToken(ngDevMode ? 'DefaultCurrencyCode' : '', {
  providedIn: 'root',
  factory: () => USD_CURRENCY_CODE
});
/**
 * Use this token at bootstrap to provide the content of your translation file (`xtb`,
 * `xlf` or `xlf2`) when you want to translate your application in another language.
 *
 * See the [i18n guide](guide/i18n-common-merge) for more information.
 *
 * @usageNotes
 * ### Example
 *
 * ```typescript
 * import { TRANSLATIONS } from '@angular/core';
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 * import { AppModule } from './app/app.module';
 *
 * // content of your translation file
 * const translations = '....';
 *
 * platformBrowserDynamic().bootstrapModule(AppModule, {
 *   providers: [{provide: TRANSLATIONS, useValue: translations }]
 * });
 * ```
 *
 * @publicApi
 */
const TRANSLATIONS = new InjectionToken(ngDevMode ? 'Translations' : '');
/**
 * Provide this token at bootstrap to set the format of your {@link TRANSLATIONS}: `xtb`,
 * `xlf` or `xlf2`.
 *
 * See the [i18n guide](guide/i18n-common-merge) for more information.
 *
 * @usageNotes
 * ### Example
 *
 * ```typescript
 * import { TRANSLATIONS_FORMAT } from '@angular/core';
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 * import { AppModule } from './app/app.module';
 *
 * platformBrowserDynamic().bootstrapModule(AppModule, {
 *   providers: [{provide: TRANSLATIONS_FORMAT, useValue: 'xlf' }]
 * });
 * ```
 *
 * @publicApi
 */
const TRANSLATIONS_FORMAT = new InjectionToken(ngDevMode ? 'TranslationsFormat' : '');
/**
 * Use this enum at bootstrap as an option of `bootstrapModule` to define the strategy
 * that the compiler should use in case of missing translations:
 * - Error: throw if you have missing translations.
 * - Warning (default): show a warning in the console and/or shell.
 * - Ignore: do nothing.
 *
 * See the [i18n guide](guide/i18n-common-merge#report-missing-translations) for more information.
 *
 * @usageNotes
 * ### Example
 * ```typescript
 * import { MissingTranslationStrategy } from '@angular/core';
 * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
 * import { AppModule } from './app/app.module';
 *
 * platformBrowserDynamic().bootstrapModule(AppModule, {
 *   missingTranslation: MissingTranslationStrategy.Error
 * });
 * ```
 *
 * @publicApi
 */
var MissingTranslationStrategy;
(function (MissingTranslationStrategy) {
  MissingTranslationStrategy[MissingTranslationStrategy["Error"] = 0] = "Error";
  MissingTranslationStrategy[MissingTranslationStrategy["Warning"] = 1] = "Warning";
  MissingTranslationStrategy[MissingTranslationStrategy["Ignore"] = 2] = "Ignore";
})(MissingTranslationStrategy || (MissingTranslationStrategy = {}));

/**
 * Internal token that allows to register extra callbacks that should be invoked during the
 * `PlatformRef.destroy` operation. This token is needed to avoid a direct reference to the
 * `PlatformRef` class (i.e. register the callback via `PlatformRef.onDestroy`), thus making the
 * entire class tree-shakeable.
 */
const PLATFORM_DESTROY_LISTENERS = new InjectionToken(ngDevMode ? 'PlatformDestroyListeners' : '');
/**
 * The Angular platform is the entry point for Angular on a web page.
 * Each page has exactly one platform. Services (such as reflection) which are common
 * to every Angular application running on the page are bound in its scope.
 * A page's platform is initialized implicitly when a platform is created using a platform
 * factory such as `PlatformBrowser`, or explicitly by calling the `createPlatform()` function.
 *
 * @publicApi
 */
class PlatformRef {
  /** @internal */
  constructor(_injector) {
    this._injector = _injector;
    this._modules = [];
    this._destroyListeners = [];
    this._destroyed = false;
  }
  /**
   * Creates an instance of an `@NgModule` for the given platform.
   *
   * @deprecated Passing NgModule factories as the `PlatformRef.bootstrapModuleFactory` function
   *     argument is deprecated. Use the `PlatformRef.bootstrapModule` API instead.
   */
  bootstrapModuleFactory(moduleFactory, options) {
    // Note: We need to create the NgZone _before_ we instantiate the module,
    // as instantiating the module creates some providers eagerly.
    // So we create a mini parent injector that just contains the new NgZone and
    // pass that as parent to the NgModuleFactory.
    const ngZone = getNgZone(options?.ngZone, getNgZoneOptions({
      eventCoalescing: options?.ngZoneEventCoalescing,
      runCoalescing: options?.ngZoneRunCoalescing
    }));
    // Note: Create ngZoneInjector within ngZone.run so that all of the instantiated services are
    // created within the Angular zone
    // Do not try to replace ngZone.run with ApplicationRef#run because ApplicationRef would then be
    // created outside of the Angular zone.
    return ngZone.run(() => {
      const moduleRef = createNgModuleRefWithProviders(moduleFactory.moduleType, this.injector, internalProvideZoneChangeDetection(() => ngZone));
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && moduleRef.injector.get(PROVIDED_NG_ZONE, null) !== null) {
        throw new RuntimeError(207 /* RuntimeErrorCode.PROVIDER_IN_WRONG_CONTEXT */, '`bootstrapModule` does not support `provideZoneChangeDetection`. Use `BootstrapOptions` instead.');
      }
      const exceptionHandler = moduleRef.injector.get(ErrorHandler, null);
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && exceptionHandler === null) {
        throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, 'No ErrorHandler. Is platform module (BrowserModule) included?');
      }
      ngZone.runOutsideAngular(() => {
        const subscription = ngZone.onError.subscribe({
          next: error => {
            exceptionHandler.handleError(error);
          }
        });
        moduleRef.onDestroy(() => {
          remove(this._modules, moduleRef);
          subscription.unsubscribe();
        });
      });
      return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
        const initStatus = moduleRef.injector.get(ApplicationInitStatus);
        initStatus.runInitializers();
        return initStatus.donePromise.then(() => {
          // If the `LOCALE_ID` provider is defined at bootstrap then we set the value for ivy
          const localeId = moduleRef.injector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
          setLocaleId(localeId || DEFAULT_LOCALE_ID);
          this._moduleDoBootstrap(moduleRef);
          return moduleRef;
        });
      });
    });
  }
  /**
   * Creates an instance of an `@NgModule` for a given platform.
   *
   * @usageNotes
   * ### Simple Example
   *
   * ```typescript
   * @NgModule({
   *   imports: [BrowserModule]
   * })
   * class MyModule {}
   *
   * let moduleRef = platformBrowser().bootstrapModule(MyModule);
   * ```
   *
   */
  bootstrapModule(moduleType, compilerOptions = []) {
    const options = optionsReducer({}, compilerOptions);
    return compileNgModuleFactory(this.injector, options, moduleType).then(moduleFactory => this.bootstrapModuleFactory(moduleFactory, options));
  }
  _moduleDoBootstrap(moduleRef) {
    const appRef = moduleRef.injector.get(ApplicationRef);
    if (moduleRef._bootstrapComponents.length > 0) {
      moduleRef._bootstrapComponents.forEach(f => appRef.bootstrap(f));
    } else if (moduleRef.instance.ngDoBootstrap) {
      moduleRef.instance.ngDoBootstrap(appRef);
    } else {
      throw new RuntimeError(-403 /* RuntimeErrorCode.BOOTSTRAP_COMPONENTS_NOT_FOUND */, ngDevMode && `The module ${stringify(moduleRef.instance.constructor)} was bootstrapped, ` + `but it does not declare "@NgModule.bootstrap" components nor a "ngDoBootstrap" method. ` + `Please define one of these.`);
    }
    this._modules.push(moduleRef);
  }
  /**
   * Registers a listener to be called when the platform is destroyed.
   */
  onDestroy(callback) {
    this._destroyListeners.push(callback);
  }
  /**
   * Retrieves the platform {@link Injector}, which is the parent injector for
   * every Angular application on the page and provides singleton providers.
   */
  get injector() {
    return this._injector;
  }
  /**
   * Destroys the current Angular platform and all Angular applications on the page.
   * Destroys all modules and listeners registered with the platform.
   */
  destroy() {
    if (this._destroyed) {
      throw new RuntimeError(404 /* RuntimeErrorCode.PLATFORM_ALREADY_DESTROYED */, ngDevMode && 'The platform has already been destroyed!');
    }
    this._modules.slice().forEach(module => module.destroy());
    this._destroyListeners.forEach(listener => listener());
    const destroyListeners = this._injector.get(PLATFORM_DESTROY_LISTENERS, null);
    if (destroyListeners) {
      destroyListeners.forEach(listener => listener());
      destroyListeners.clear();
    }
    this._destroyed = true;
  }
  /**
   * Indicates whether this instance was destroyed.
   */
  get destroyed() {
    return this._destroyed;
  }
  static {
    this.ɵfac = function PlatformRef_Factory(t) {
      return new (t || PlatformRef)(ɵɵinject(Injector));
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: PlatformRef,
      factory: PlatformRef.ɵfac,
      providedIn: 'platform'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(PlatformRef, [{
    type: Injectable,
    args: [{
      providedIn: 'platform'
    }]
  }], () => [{
    type: Injector
  }], null);
})();
let _platformInjector = null;
/**
 * Internal token to indicate whether having multiple bootstrapped platform should be allowed (only
 * one bootstrapped platform is allowed by default). This token helps to support SSR scenarios.
 */
const ALLOW_MULTIPLE_PLATFORMS = new InjectionToken(ngDevMode ? 'AllowMultipleToken' : '');
/**
 * Creates a platform.
 * Platforms must be created on launch using this function.
 *
 * @publicApi
 */
function createPlatform(injector) {
  if (_platformInjector && !_platformInjector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
    throw new RuntimeError(400 /* RuntimeErrorCode.MULTIPLE_PLATFORMS */, ngDevMode && 'There can be only one platform. Destroy the previous one to create a new one.');
  }
  publishDefaultGlobalUtils();
  publishSignalConfiguration();
  _platformInjector = injector;
  const platform = injector.get(PlatformRef);
  runPlatformInitializers(injector);
  return platform;
}
/**
 * Creates a factory for a platform. Can be used to provide or override `Providers` specific to
 * your application's runtime needs, such as `PLATFORM_INITIALIZER` and `PLATFORM_ID`.
 * @param parentPlatformFactory Another platform factory to modify. Allows you to compose factories
 * to build up configurations that might be required by different libraries or parts of the
 * application.
 * @param name Identifies the new platform factory.
 * @param providers A set of dependency providers for platforms created with the new factory.
 *
 * @publicApi
 */
function createPlatformFactory(parentPlatformFactory, name, providers = []) {
  const desc = `Platform: ${name}`;
  const marker = new InjectionToken(desc);
  return (extraProviders = []) => {
    let platform = getPlatform();
    if (!platform || platform.injector.get(ALLOW_MULTIPLE_PLATFORMS, false)) {
      const platformProviders = [...providers, ...extraProviders, {
        provide: marker,
        useValue: true
      }];
      if (parentPlatformFactory) {
        parentPlatformFactory(platformProviders);
      } else {
        createPlatform(createPlatformInjector(platformProviders, desc));
      }
    }
    return assertPlatform(marker);
  };
}
/**
 * Helper function to create an instance of a platform injector (that maintains the 'platform'
 * scope).
 */
function createPlatformInjector(providers = [], name) {
  return Injector.create({
    name,
    providers: [{
      provide: INJECTOR_SCOPE,
      useValue: 'platform'
    }, {
      provide: PLATFORM_DESTROY_LISTENERS,
      useValue: new Set([() => _platformInjector = null])
    }, ...providers]
  });
}
/**
 * Checks that there is currently a platform that contains the given token as a provider.
 *
 * @publicApi
 */
function assertPlatform(requiredToken) {
  const platform = getPlatform();
  if (!platform) {
    throw new RuntimeError(401 /* RuntimeErrorCode.PLATFORM_NOT_FOUND */, ngDevMode && 'No platform exists!');
  }
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && !platform.injector.get(requiredToken, null)) {
    throw new RuntimeError(400 /* RuntimeErrorCode.MULTIPLE_PLATFORMS */, 'A platform with a different configuration has been created. Please destroy it first.');
  }
  return platform;
}
/**
 * Returns the current platform.
 *
 * @publicApi
 */
function getPlatform() {
  return _platformInjector?.get(PlatformRef) ?? null;
}
/**
 * Destroys the current Angular platform and all Angular applications on the page.
 * Destroys all modules and listeners registered with the platform.
 *
 * @publicApi
 */
function destroyPlatform() {
  getPlatform()?.destroy();
}
/**
 * The goal of this function is to bootstrap a platform injector,
 * but avoid referencing `PlatformRef` class.
 * This function is needed for bootstrapping a Standalone Component.
 */
function createOrReusePlatformInjector(providers = []) {
  // If a platform injector already exists, it means that the platform
  // is already bootstrapped and no additional actions are required.
  if (_platformInjector) return _platformInjector;
  publishDefaultGlobalUtils();
  // Otherwise, setup a new platform injector and run platform initializers.
  const injector = createPlatformInjector(providers);
  _platformInjector = injector;
  publishSignalConfiguration();
  runPlatformInitializers(injector);
  return injector;
}
function runPlatformInitializers(injector) {
  const inits = injector.get(PLATFORM_INITIALIZER, null);
  inits?.forEach(init => init());
}

/**
 * Returns whether Angular is in development mode.
 *
 * By default, this is true, unless `enableProdMode` is invoked prior to calling this method or the
 * application is built using the Angular CLI with the `optimization` option.
 * @see {@link cli/build ng build}
 *
 * @publicApi
 */
function isDevMode() {
  return typeof ngDevMode === 'undefined' || !!ngDevMode;
}
/**
 * Disable Angular's development mode, which turns off assertions and other
 * checks within the framework.
 *
 * One important assertion this disables verifies that a change detection pass
 * does not result in additional changes to any bindings (also known as
 * unidirectional data flow).
 *
 * Using this method is discouraged as the Angular CLI will set production mode when using the
 * `optimization` option.
 * @see {@link cli/build ng build}
 *
 * @publicApi
 */
function enableProdMode() {
  // The below check is there so when ngDevMode is set via terser
  // `global['ngDevMode'] = false;` is also dropped.
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    _global['ngDevMode'] = false;
  }
}

// Public API for render

/**
 * Returns the NgModuleFactory with the given id (specified using [@NgModule.id
 * field](api/core/NgModule#id)), if it exists and has been loaded. Factories for NgModules that do
 * not specify an `id` cannot be retrieved. Throws if an NgModule cannot be found.
 * @publicApi
 * @deprecated Use `getNgModuleById` instead.
 */
function getModuleFactory(id) {
  const type = getRegisteredNgModuleType(id);
  if (!type) throw noModuleError(id);
  return new NgModuleFactory(type);
}
/**
 * Returns the NgModule class with the given id (specified using [@NgModule.id
 * field](api/core/NgModule#id)), if it exists and has been loaded. Classes for NgModules that do
 * not specify an `id` cannot be retrieved. Throws if an NgModule cannot be found.
 * @publicApi
 */
function getNgModuleById(id) {
  const type = getRegisteredNgModuleType(id);
  if (!type) throw noModuleError(id);
  return type;
}
function noModuleError(id) {
  return new Error(`No module with ID ${id} loaded`);
}

/**
 * Base class that provides change detection functionality.
 * A change-detection tree collects all views that are to be checked for changes.
 * Use the methods to add and remove views from the tree, initiate change-detection,
 * and explicitly mark views as _dirty_, meaning that they have changed and need to be re-rendered.
 *
 * @see [Using change detection hooks](guide/lifecycle-hooks#using-change-detection-hooks)
 * @see [Defining custom change detection](guide/lifecycle-hooks#defining-custom-change-detection)
 *
 * @usageNotes
 *
 * The following examples demonstrate how to modify default change-detection behavior
 * to perform explicit detection when needed.
 *
 * ### Use `markForCheck()` with `CheckOnce` strategy
 *
 * The following example sets the `OnPush` change-detection strategy for a component
 * (`CheckOnce`, rather than the default `CheckAlways`), then forces a second check
 * after an interval.
 *
 * <code-example path="core/ts/change_detect/change-detection.ts"
 * region="mark-for-check"></code-example>
 *
 * ### Detach change detector to limit how often check occurs
 *
 * The following example defines a component with a large list of read-only data
 * that is expected to change constantly, many times per second.
 * To improve performance, we want to check and update the list
 * less often than the changes actually occur. To do that, we detach
 * the component's change detector and perform an explicit local check every five seconds.
 *
 * <code-example path="core/ts/change_detect/change-detection.ts" region="detach"></code-example>
 *
 *
 * ### Reattaching a detached component
 *
 * The following example creates a component displaying live data.
 * The component detaches its change detector from the main change detector tree
 * when the `live` property is set to false, and reattaches it when the property
 * becomes true.
 *
 * <code-example path="core/ts/change_detect/change-detection.ts" region="reattach"></code-example>
 *
 * @publicApi
 */
class ChangeDetectorRef {
  /**
   * @internal
   * @nocollapse
   */
  static {
    this.__NG_ELEMENT_ID__ = injectChangeDetectorRef;
  }
}
/** Returns a ChangeDetectorRef (a.k.a. a ViewRef) */
function injectChangeDetectorRef(flags) {
  return createViewRef(getCurrentTNode(), getLView(), (flags & 16 /* InternalInjectFlags.ForPipe */) === 16 /* InternalInjectFlags.ForPipe */);
}
/**
 * Creates a ViewRef and stores it on the injector as ChangeDetectorRef (public alias).
 *
 * @param tNode The node that is requesting a ChangeDetectorRef
 * @param lView The view to which the node belongs
 * @param isPipe Whether the view is being injected into a pipe.
 * @returns The ChangeDetectorRef to use
 */
function createViewRef(tNode, lView, isPipe) {
  if (isComponentHost(tNode) && !isPipe) {
    // The LView represents the location where the component is declared.
    // Instead we want the LView for the component View and so we need to look it up.
    const componentView = getComponentLViewByIndex(tNode.index, lView); // look down
    return new ViewRef$1(componentView, componentView);
  } else if (tNode.type & (3 /* TNodeType.AnyRNode */ | 12 /* TNodeType.AnyContainer */ | 32 /* TNodeType.Icu */)) {
    // The LView represents the location where the injection is requested from.
    // We need to locate the containing LView (in case where the `lView` is an embedded view)
    const hostComponentView = lView[DECLARATION_COMPONENT_VIEW]; // look up
    return new ViewRef$1(hostComponentView, lView);
  }
  return null;
}

/**
 * Represents an Angular [view](guide/glossary#view "Definition").
 *
 * @see {@link ChangeDetectorRef#usage-notes Change detection usage}
 *
 * @publicApi
 */
class ViewRef extends ChangeDetectorRef {}
/**
 * Represents an Angular [view](guide/glossary#view) in a view container.
 * An [embedded view](guide/glossary#view-hierarchy) can be referenced from a component
 * other than the hosting component whose template defines it, or it can be defined
 * independently by a `TemplateRef`.
 *
 * Properties of elements in a view can change, but the structure (number and order) of elements in
 * a view cannot. Change the structure of elements by inserting, moving, or
 * removing nested views in a view container.
 *
 * @see {@link ViewContainerRef}
 *
 * @usageNotes
 *
 * The following template breaks down into two separate `TemplateRef` instances,
 * an outer one and an inner one.
 *
 * ```
 * Count: {{items.length}}
 * <ul>
 *   <li *ngFor="let  item of items">{{item}}</li>
 * </ul>
 * ```
 *
 * This is the outer `TemplateRef`:
 *
 * ```
 * Count: {{items.length}}
 * <ul>
 *   <ng-template ngFor let-item [ngForOf]="items"></ng-template>
 * </ul>
 * ```
 *
 * This is the inner `TemplateRef`:
 *
 * ```
 *   <li>{{item}}</li>
 * ```
 *
 * The outer and inner `TemplateRef` instances are assembled into views as follows:
 *
 * ```
 * <!-- ViewRef: outer-0 -->
 * Count: 2
 * <ul>
 *   <ng-template view-container-ref></ng-template>
 *   <!-- ViewRef: inner-1 --><li>first</li><!-- /ViewRef: inner-1 -->
 *   <!-- ViewRef: inner-2 --><li>second</li><!-- /ViewRef: inner-2 -->
 * </ul>
 * <!-- /ViewRef: outer-0 -->
 * ```
 * @publicApi
 */
class EmbeddedViewRef extends ViewRef {}

// Public API for compiler

// This file exists for easily patching NgModuleFactoryLoader in g3
var ng_module_factory_loader_impl = {};

/**
 * @publicApi
 */
class DebugEventListener {
  constructor(name, callback) {
    this.name = name;
    this.callback = callback;
  }
}
/**
 * @publicApi
 */
function asNativeElements(debugEls) {
  return debugEls.map(el => el.nativeElement);
}
/**
 * @publicApi
 */
class DebugNode {
  constructor(nativeNode) {
    this.nativeNode = nativeNode;
  }
  /**
   * The `DebugElement` parent. Will be `null` if this is the root element.
   */
  get parent() {
    const parent = this.nativeNode.parentNode;
    return parent ? new DebugElement(parent) : null;
  }
  /**
   * The host dependency injector. For example, the root element's component instance injector.
   */
  get injector() {
    return getInjector(this.nativeNode);
  }
  /**
   * The element's own component instance, if it has one.
   */
  get componentInstance() {
    const nativeElement = this.nativeNode;
    return nativeElement && (getComponent$1(nativeElement) || getOwningComponent(nativeElement));
  }
  /**
   * An object that provides parent context for this element. Often an ancestor component instance
   * that governs this element.
   *
   * When an element is repeated within *ngFor, the context is an `NgForOf` whose `$implicit`
   * property is the value of the row instance value. For example, the `hero` in `*ngFor="let hero
   * of heroes"`.
   */
  get context() {
    return getComponent$1(this.nativeNode) || getContext(this.nativeNode);
  }
  /**
   * The callbacks attached to the component's @Output properties and/or the element's event
   * properties.
   */
  get listeners() {
    return getListeners(this.nativeNode).filter(listener => listener.type === 'dom');
  }
  /**
   * Dictionary of objects associated with template local variables (e.g. #foo), keyed by the local
   * variable name.
   */
  get references() {
    return getLocalRefs(this.nativeNode);
  }
  /**
   * This component's injector lookup tokens. Includes the component itself plus the tokens that the
   * component lists in its providers metadata.
   */
  get providerTokens() {
    return getInjectionTokens(this.nativeNode);
  }
}
/**
 * @publicApi
 *
 * @see [Component testing scenarios](guide/testing-components-scenarios)
 * @see [Basics of testing components](guide/testing-components-basics)
 * @see [Testing utility APIs](guide/testing-utility-apis)
 */
class DebugElement extends DebugNode {
  constructor(nativeNode) {
    ngDevMode && assertDomNode(nativeNode);
    super(nativeNode);
  }
  /**
   * The underlying DOM element at the root of the component.
   */
  get nativeElement() {
    return this.nativeNode.nodeType == Node.ELEMENT_NODE ? this.nativeNode : null;
  }
  /**
   * The element tag name, if it is an element.
   */
  get name() {
    const context = getLContext(this.nativeNode);
    const lView = context ? context.lView : null;
    if (lView !== null) {
      const tData = lView[TVIEW].data;
      const tNode = tData[context.nodeIndex];
      return tNode.value;
    } else {
      return this.nativeNode.nodeName;
    }
  }
  /**
   *  Gets a map of property names to property values for an element.
   *
   *  This map includes:
   *  - Regular property bindings (e.g. `[id]="id"`)
   *  - Host property bindings (e.g. `host: { '[id]': "id" }`)
   *  - Interpolated property bindings (e.g. `id="{{ value }}")
   *
   *  It does not include:
   *  - input property bindings (e.g. `[myCustomInput]="value"`)
   *  - attribute bindings (e.g. `[attr.role]="menu"`)
   */
  get properties() {
    const context = getLContext(this.nativeNode);
    const lView = context ? context.lView : null;
    if (lView === null) {
      return {};
    }
    const tData = lView[TVIEW].data;
    const tNode = tData[context.nodeIndex];
    const properties = {};
    // Collect properties from the DOM.
    copyDomProperties(this.nativeElement, properties);
    // Collect properties from the bindings. This is needed for animation renderer which has
    // synthetic properties which don't get reflected into the DOM.
    collectPropertyBindings(properties, tNode, lView, tData);
    return properties;
  }
  /**
   *  A map of attribute names to attribute values for an element.
   */
  // TODO: replace null by undefined in the return type
  get attributes() {
    const attributes = {};
    const element = this.nativeElement;
    if (!element) {
      return attributes;
    }
    const context = getLContext(element);
    const lView = context ? context.lView : null;
    if (lView === null) {
      return {};
    }
    const tNodeAttrs = lView[TVIEW].data[context.nodeIndex].attrs;
    const lowercaseTNodeAttrs = [];
    // For debug nodes we take the element's attribute directly from the DOM since it allows us
    // to account for ones that weren't set via bindings (e.g. ViewEngine keeps track of the ones
    // that are set through `Renderer2`). The problem is that the browser will lowercase all names,
    // however since we have the attributes already on the TNode, we can preserve the case by going
    // through them once, adding them to the `attributes` map and putting their lower-cased name
    // into an array. Afterwards when we're going through the native DOM attributes, we can check
    // whether we haven't run into an attribute already through the TNode.
    if (tNodeAttrs) {
      let i = 0;
      while (i < tNodeAttrs.length) {
        const attrName = tNodeAttrs[i];
        // Stop as soon as we hit a marker. We only care about the regular attributes. Everything
        // else will be handled below when we read the final attributes off the DOM.
        if (typeof attrName !== 'string') break;
        const attrValue = tNodeAttrs[i + 1];
        attributes[attrName] = attrValue;
        lowercaseTNodeAttrs.push(attrName.toLowerCase());
        i += 2;
      }
    }
    for (const attr of element.attributes) {
      // Make sure that we don't assign the same attribute both in its
      // case-sensitive form and the lower-cased one from the browser.
      if (!lowercaseTNodeAttrs.includes(attr.name)) {
        attributes[attr.name] = attr.value;
      }
    }
    return attributes;
  }
  /**
   * The inline styles of the DOM element.
   */
  // TODO: replace null by undefined in the return type
  get styles() {
    const element = this.nativeElement;
    return element?.style ?? {};
  }
  /**
   * A map containing the class names on the element as keys.
   *
   * This map is derived from the `className` property of the DOM element.
   *
   * Note: The values of this object will always be `true`. The class key will not appear in the KV
   * object if it does not exist on the element.
   *
   * @see [Element.className](https://developer.mozilla.org/en-US/docs/Web/API/Element/className)
   */
  get classes() {
    const result = {};
    const element = this.nativeElement;
    // SVG elements return an `SVGAnimatedString` instead of a plain string for the `className`.
    const className = element.className;
    const classes = typeof className !== 'string' ? className.baseVal.split(' ') : className.split(' ');
    classes.forEach(value => result[value] = true);
    return result;
  }
  /**
   * The `childNodes` of the DOM element as a `DebugNode` array.
   *
   * @see [Node.childNodes](https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes)
   */
  get childNodes() {
    const childNodes = this.nativeNode.childNodes;
    const children = [];
    for (let i = 0; i < childNodes.length; i++) {
      const element = childNodes[i];
      children.push(getDebugNode(element));
    }
    return children;
  }
  /**
   * The immediate `DebugElement` children. Walk the tree by descending through `children`.
   */
  get children() {
    const nativeElement = this.nativeElement;
    if (!nativeElement) return [];
    const childNodes = nativeElement.children;
    const children = [];
    for (let i = 0; i < childNodes.length; i++) {
      const element = childNodes[i];
      children.push(getDebugNode(element));
    }
    return children;
  }
  /**
   * @returns the first `DebugElement` that matches the predicate at any depth in the subtree.
   */
  query(predicate) {
    const results = this.queryAll(predicate);
    return results[0] || null;
  }
  /**
   * @returns All `DebugElement` matches for the predicate at any depth in the subtree.
   */
  queryAll(predicate) {
    const matches = [];
    _queryAll(this, predicate, matches, true);
    return matches;
  }
  /**
   * @returns All `DebugNode` matches for the predicate at any depth in the subtree.
   */
  queryAllNodes(predicate) {
    const matches = [];
    _queryAll(this, predicate, matches, false);
    return matches;
  }
  /**
   * Triggers the event by its name if there is a corresponding listener in the element's
   * `listeners` collection.
   *
   * If the event lacks a listener or there's some other problem, consider
   * calling `nativeElement.dispatchEvent(eventObject)`.
   *
   * @param eventName The name of the event to trigger
   * @param eventObj The _event object_ expected by the handler
   *
   * @see [Testing components scenarios](guide/testing-components-scenarios#trigger-event-handler)
   */
  triggerEventHandler(eventName, eventObj) {
    const node = this.nativeNode;
    const invokedListeners = [];
    this.listeners.forEach(listener => {
      if (listener.name === eventName) {
        const callback = listener.callback;
        callback.call(node, eventObj);
        invokedListeners.push(callback);
      }
    });
    // We need to check whether `eventListeners` exists, because it's something
    // that Zone.js only adds to `EventTarget` in browser environments.
    if (typeof node.eventListeners === 'function') {
      // Note that in Ivy we wrap event listeners with a call to `event.preventDefault` in some
      // cases. We use '__ngUnwrap__' as a special token that gives us access to the actual event
      // listener.
      node.eventListeners(eventName).forEach(listener => {
        // In order to ensure that we can detect the special __ngUnwrap__ token described above, we
        // use `toString` on the listener and see if it contains the token. We use this approach to
        // ensure that it still worked with compiled code since it cannot remove or rename string
        // literals. We also considered using a special function name (i.e. if(listener.name ===
        // special)) but that was more cumbersome and we were also concerned the compiled code could
        // strip the name, turning the condition in to ("" === "") and always returning true.
        if (listener.toString().indexOf('__ngUnwrap__') !== -1) {
          const unwrappedListener = listener('__ngUnwrap__');
          return invokedListeners.indexOf(unwrappedListener) === -1 && unwrappedListener.call(node, eventObj);
        }
      });
    }
  }
}
function copyDomProperties(element, properties) {
  if (element) {
    // Skip own properties (as those are patched)
    let obj = Object.getPrototypeOf(element);
    const NodePrototype = Node.prototype;
    while (obj !== null && obj !== NodePrototype) {
      const descriptors = Object.getOwnPropertyDescriptors(obj);
      for (let key in descriptors) {
        if (!key.startsWith('__') && !key.startsWith('on')) {
          // don't include properties starting with `__` and `on`.
          // `__` are patched values which should not be included.
          // `on` are listeners which also should not be included.
          const value = element[key];
          if (isPrimitiveValue(value)) {
            properties[key] = value;
          }
        }
      }
      obj = Object.getPrototypeOf(obj);
    }
  }
}
function isPrimitiveValue(value) {
  return typeof value === 'string' || typeof value === 'boolean' || typeof value === 'number' || value === null;
}
function _queryAll(parentElement, predicate, matches, elementsOnly) {
  const context = getLContext(parentElement.nativeNode);
  const lView = context ? context.lView : null;
  if (lView !== null) {
    const parentTNode = lView[TVIEW].data[context.nodeIndex];
    _queryNodeChildren(parentTNode, lView, predicate, matches, elementsOnly, parentElement.nativeNode);
  } else {
    // If the context is null, then `parentElement` was either created with Renderer2 or native DOM
    // APIs.
    _queryNativeNodeDescendants(parentElement.nativeNode, predicate, matches, elementsOnly);
  }
}
/**
 * Recursively match the current TNode against the predicate, and goes on with the next ones.
 *
 * @param tNode the current TNode
 * @param lView the LView of this TNode
 * @param predicate the predicate to match
 * @param matches the list of positive matches
 * @param elementsOnly whether only elements should be searched
 * @param rootNativeNode the root native node on which predicate should not be matched
 */
function _queryNodeChildren(tNode, lView, predicate, matches, elementsOnly, rootNativeNode) {
  ngDevMode && assertTNodeForLView(tNode, lView);
  const nativeNode = getNativeByTNodeOrNull(tNode, lView);
  // For each type of TNode, specific logic is executed.
  if (tNode.type & (3 /* TNodeType.AnyRNode */ | 8 /* TNodeType.ElementContainer */)) {
    // Case 1: the TNode is an element
    // The native node has to be checked.
    _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
    if (isComponentHost(tNode)) {
      // If the element is the host of a component, then all nodes in its view have to be processed.
      // Note: the component's content (tNode.child) will be processed from the insertion points.
      const componentView = getComponentLViewByIndex(tNode.index, lView);
      if (componentView && componentView[TVIEW].firstChild) {
        _queryNodeChildren(componentView[TVIEW].firstChild, componentView, predicate, matches, elementsOnly, rootNativeNode);
      }
    } else {
      if (tNode.child) {
        // Otherwise, its children have to be processed.
        _queryNodeChildren(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
      }
      // We also have to query the DOM directly in order to catch elements inserted through
      // Renderer2. Note that this is __not__ optimal, because we're walking similar trees multiple
      // times. ViewEngine could do it more efficiently, because all the insertions go through
      // Renderer2, however that's not the case in Ivy. This approach is being used because:
      // 1. Matching the ViewEngine behavior would mean potentially introducing a dependency
      //    from `Renderer2` to Ivy which could bring Ivy code into ViewEngine.
      // 2. It allows us to capture nodes that were inserted directly via the DOM.
      nativeNode && _queryNativeNodeDescendants(nativeNode, predicate, matches, elementsOnly);
    }
    // In all cases, if a dynamic container exists for this node, each view inside it has to be
    // processed.
    const nodeOrContainer = lView[tNode.index];
    if (isLContainer(nodeOrContainer)) {
      _queryNodeChildrenInContainer(nodeOrContainer, predicate, matches, elementsOnly, rootNativeNode);
    }
  } else if (tNode.type & 4 /* TNodeType.Container */) {
    // Case 2: the TNode is a container
    // The native node has to be checked.
    const lContainer = lView[tNode.index];
    _addQueryMatch(lContainer[NATIVE], predicate, matches, elementsOnly, rootNativeNode);
    // Each view inside the container has to be processed.
    _queryNodeChildrenInContainer(lContainer, predicate, matches, elementsOnly, rootNativeNode);
  } else if (tNode.type & 16 /* TNodeType.Projection */) {
    // Case 3: the TNode is a projection insertion point (i.e. a <ng-content>).
    // The nodes projected at this location all need to be processed.
    const componentView = lView[DECLARATION_COMPONENT_VIEW];
    const componentHost = componentView[T_HOST];
    const head = componentHost.projection[tNode.projection];
    if (Array.isArray(head)) {
      for (let nativeNode of head) {
        _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode);
      }
    } else if (head) {
      const nextLView = componentView[PARENT];
      const nextTNode = nextLView[TVIEW].data[head.index];
      _queryNodeChildren(nextTNode, nextLView, predicate, matches, elementsOnly, rootNativeNode);
    }
  } else if (tNode.child) {
    // Case 4: the TNode is a view.
    _queryNodeChildren(tNode.child, lView, predicate, matches, elementsOnly, rootNativeNode);
  }
  // We don't want to go to the next sibling of the root node.
  if (rootNativeNode !== nativeNode) {
    // To determine the next node to be processed, we need to use the next or the projectionNext
    // link, depending on whether the current node has been projected.
    const nextTNode = tNode.flags & 2 /* TNodeFlags.isProjected */ ? tNode.projectionNext : tNode.next;
    if (nextTNode) {
      _queryNodeChildren(nextTNode, lView, predicate, matches, elementsOnly, rootNativeNode);
    }
  }
}
/**
 * Process all TNodes in a given container.
 *
 * @param lContainer the container to be processed
 * @param predicate the predicate to match
 * @param matches the list of positive matches
 * @param elementsOnly whether only elements should be searched
 * @param rootNativeNode the root native node on which predicate should not be matched
 */
function _queryNodeChildrenInContainer(lContainer, predicate, matches, elementsOnly, rootNativeNode) {
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
    const childView = lContainer[i];
    const firstChild = childView[TVIEW].firstChild;
    if (firstChild) {
      _queryNodeChildren(firstChild, childView, predicate, matches, elementsOnly, rootNativeNode);
    }
  }
}
/**
 * Match the current native node against the predicate.
 *
 * @param nativeNode the current native node
 * @param predicate the predicate to match
 * @param matches the list of positive matches
 * @param elementsOnly whether only elements should be searched
 * @param rootNativeNode the root native node on which predicate should not be matched
 */
function _addQueryMatch(nativeNode, predicate, matches, elementsOnly, rootNativeNode) {
  if (rootNativeNode !== nativeNode) {
    const debugNode = getDebugNode(nativeNode);
    if (!debugNode) {
      return;
    }
    // Type of the "predicate and "matches" array are set based on the value of
    // the "elementsOnly" parameter. TypeScript is not able to properly infer these
    // types with generics, so we manually cast the parameters accordingly.
    if (elementsOnly && debugNode instanceof DebugElement && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
      matches.push(debugNode);
    } else if (!elementsOnly && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
      matches.push(debugNode);
    }
  }
}
/**
 * Match all the descendants of a DOM node against a predicate.
 *
 * @param nativeNode the current native node
 * @param predicate the predicate to match
 * @param matches the list where matches are stored
 * @param elementsOnly whether only elements should be searched
 */
function _queryNativeNodeDescendants(parentNode, predicate, matches, elementsOnly) {
  const nodes = parentNode.childNodes;
  const length = nodes.length;
  for (let i = 0; i < length; i++) {
    const node = nodes[i];
    const debugNode = getDebugNode(node);
    if (debugNode) {
      if (elementsOnly && debugNode instanceof DebugElement && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
        matches.push(debugNode);
      } else if (!elementsOnly && predicate(debugNode) && matches.indexOf(debugNode) === -1) {
        matches.push(debugNode);
      }
      _queryNativeNodeDescendants(node, predicate, matches, elementsOnly);
    }
  }
}
/**
 * Iterates through the property bindings for a given node and generates
 * a map of property names to values. This map only contains property bindings
 * defined in templates, not in host bindings.
 */
function collectPropertyBindings(properties, tNode, lView, tData) {
  let bindingIndexes = tNode.propertyBindings;
  if (bindingIndexes !== null) {
    for (let i = 0; i < bindingIndexes.length; i++) {
      const bindingIndex = bindingIndexes[i];
      const propMetadata = tData[bindingIndex];
      const metadataParts = propMetadata.split(INTERPOLATION_DELIMITER);
      const propertyName = metadataParts[0];
      if (metadataParts.length > 1) {
        let value = metadataParts[1];
        for (let j = 1; j < metadataParts.length - 1; j++) {
          value += renderStringify(lView[bindingIndex + j - 1]) + metadataParts[j + 1];
        }
        properties[propertyName] = value;
      } else {
        properties[propertyName] = lView[bindingIndex];
      }
    }
  }
}
// Need to keep the nodes in a global Map so that multiple angular apps are supported.
const _nativeNodeToDebugNode = new Map();
const NG_DEBUG_PROPERTY = '__ng_debug__';
/**
 * @publicApi
 */
function getDebugNode(nativeNode) {
  if (nativeNode instanceof Node) {
    if (!nativeNode.hasOwnProperty(NG_DEBUG_PROPERTY)) {
      nativeNode[NG_DEBUG_PROPERTY] = nativeNode.nodeType == Node.ELEMENT_NODE ? new DebugElement(nativeNode) : new DebugNode(nativeNode);
    }
    return nativeNode[NG_DEBUG_PROPERTY];
  }
  return null;
}
function getAllDebugNodes() {
  return Array.from(_nativeNodeToDebugNode.values());
}
function indexDebugNode(node) {
  _nativeNodeToDebugNode.set(node.nativeNode, node);
}
function removeDebugNodeFromIndex(node) {
  _nativeNodeToDebugNode.delete(node.nativeNode);
}
class DefaultIterableDifferFactory {
  constructor() {}
  supports(obj) {
    return isListLikeIterable(obj);
  }
  create(trackByFn) {
    return new DefaultIterableDiffer(trackByFn);
  }
}
const trackByIdentity = (index, item) => item;
/**
 * @deprecated v4.0.0 - Should not be part of public API.
 * @publicApi
 */
class DefaultIterableDiffer {
  constructor(trackByFn) {
    this.length = 0;
    // Keeps track of the used records at any point in time (during & across `_check()` calls)
    this._linkedRecords = null;
    // Keeps track of the removed records at any point in time during `_check()` calls.
    this._unlinkedRecords = null;
    this._previousItHead = null;
    this._itHead = null;
    this._itTail = null;
    this._additionsHead = null;
    this._additionsTail = null;
    this._movesHead = null;
    this._movesTail = null;
    this._removalsHead = null;
    this._removalsTail = null;
    // Keeps track of records where custom track by is the same, but item identity has changed
    this._identityChangesHead = null;
    this._identityChangesTail = null;
    this._trackByFn = trackByFn || trackByIdentity;
  }
  forEachItem(fn) {
    let record;
    for (record = this._itHead; record !== null; record = record._next) {
      fn(record);
    }
  }
  forEachOperation(fn) {
    let nextIt = this._itHead;
    let nextRemove = this._removalsHead;
    let addRemoveOffset = 0;
    let moveOffsets = null;
    while (nextIt || nextRemove) {
      // Figure out which is the next record to process
      // Order: remove, add, move
      const record = !nextRemove || nextIt && nextIt.currentIndex < getPreviousIndex(nextRemove, addRemoveOffset, moveOffsets) ? nextIt : nextRemove;
      const adjPreviousIndex = getPreviousIndex(record, addRemoveOffset, moveOffsets);
      const currentIndex = record.currentIndex;
      // consume the item, and adjust the addRemoveOffset and update moveDistance if necessary
      if (record === nextRemove) {
        addRemoveOffset--;
        nextRemove = nextRemove._nextRemoved;
      } else {
        nextIt = nextIt._next;
        if (record.previousIndex == null) {
          addRemoveOffset++;
        } else {
          // INVARIANT:  currentIndex < previousIndex
          if (!moveOffsets) moveOffsets = [];
          const localMovePreviousIndex = adjPreviousIndex - addRemoveOffset;
          const localCurrentIndex = currentIndex - addRemoveOffset;
          if (localMovePreviousIndex != localCurrentIndex) {
            for (let i = 0; i < localMovePreviousIndex; i++) {
              const offset = i < moveOffsets.length ? moveOffsets[i] : moveOffsets[i] = 0;
              const index = offset + i;
              if (localCurrentIndex <= index && index < localMovePreviousIndex) {
                moveOffsets[i] = offset + 1;
              }
            }
            const previousIndex = record.previousIndex;
            moveOffsets[previousIndex] = localCurrentIndex - localMovePreviousIndex;
          }
        }
      }
      if (adjPreviousIndex !== currentIndex) {
        fn(record, adjPreviousIndex, currentIndex);
      }
    }
  }
  forEachPreviousItem(fn) {
    let record;
    for (record = this._previousItHead; record !== null; record = record._nextPrevious) {
      fn(record);
    }
  }
  forEachAddedItem(fn) {
    let record;
    for (record = this._additionsHead; record !== null; record = record._nextAdded) {
      fn(record);
    }
  }
  forEachMovedItem(fn) {
    let record;
    for (record = this._movesHead; record !== null; record = record._nextMoved) {
      fn(record);
    }
  }
  forEachRemovedItem(fn) {
    let record;
    for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
      fn(record);
    }
  }
  forEachIdentityChange(fn) {
    let record;
    for (record = this._identityChangesHead; record !== null; record = record._nextIdentityChange) {
      fn(record);
    }
  }
  diff(collection) {
    if (collection == null) collection = [];
    if (!isListLikeIterable(collection)) {
      throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && `Error trying to diff '${stringify(collection)}'. Only arrays and iterables are allowed`);
    }
    if (this.check(collection)) {
      return this;
    } else {
      return null;
    }
  }
  onDestroy() {}
  check(collection) {
    this._reset();
    let record = this._itHead;
    let mayBeDirty = false;
    let index;
    let item;
    let itemTrackBy;
    if (Array.isArray(collection)) {
      this.length = collection.length;
      for (let index = 0; index < this.length; index++) {
        item = collection[index];
        itemTrackBy = this._trackByFn(index, item);
        if (record === null || !Object.is(record.trackById, itemTrackBy)) {
          record = this._mismatch(record, item, itemTrackBy, index);
          mayBeDirty = true;
        } else {
          if (mayBeDirty) {
            // TODO(misko): can we limit this to duplicates only?
            record = this._verifyReinsertion(record, item, itemTrackBy, index);
          }
          if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
        }
        record = record._next;
      }
    } else {
      index = 0;
      iterateListLike(collection, item => {
        itemTrackBy = this._trackByFn(index, item);
        if (record === null || !Object.is(record.trackById, itemTrackBy)) {
          record = this._mismatch(record, item, itemTrackBy, index);
          mayBeDirty = true;
        } else {
          if (mayBeDirty) {
            // TODO(misko): can we limit this to duplicates only?
            record = this._verifyReinsertion(record, item, itemTrackBy, index);
          }
          if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
        }
        record = record._next;
        index++;
      });
      this.length = index;
    }
    this._truncate(record);
    this.collection = collection;
    return this.isDirty;
  }
  /* CollectionChanges is considered dirty if it has any additions, moves, removals, or identity
   * changes.
   */
  get isDirty() {
    return this._additionsHead !== null || this._movesHead !== null || this._removalsHead !== null || this._identityChangesHead !== null;
  }
  /**
   * Reset the state of the change objects to show no changes. This means set previousKey to
   * currentKey, and clear all of the queues (additions, moves, removals).
   * Set the previousIndexes of moved and added items to their currentIndexes
   * Reset the list of additions, moves and removals
   *
   * @internal
   */
  _reset() {
    if (this.isDirty) {
      let record;
      for (record = this._previousItHead = this._itHead; record !== null; record = record._next) {
        record._nextPrevious = record._next;
      }
      for (record = this._additionsHead; record !== null; record = record._nextAdded) {
        record.previousIndex = record.currentIndex;
      }
      this._additionsHead = this._additionsTail = null;
      for (record = this._movesHead; record !== null; record = record._nextMoved) {
        record.previousIndex = record.currentIndex;
      }
      this._movesHead = this._movesTail = null;
      this._removalsHead = this._removalsTail = null;
      this._identityChangesHead = this._identityChangesTail = null;
      // TODO(vicb): when assert gets supported
      // assert(!this.isDirty);
    }
  }
  /**
   * This is the core function which handles differences between collections.
   *
   * - `record` is the record which we saw at this position last time. If null then it is a new
   *   item.
   * - `item` is the current item in the collection
   * - `index` is the position of the item in the collection
   *
   * @internal
   */
  _mismatch(record, item, itemTrackBy, index) {
    // The previous record after which we will append the current one.
    let previousRecord;
    if (record === null) {
      previousRecord = this._itTail;
    } else {
      previousRecord = record._prev;
      // Remove the record from the collection since we know it does not match the item.
      this._remove(record);
    }
    // See if we have evicted the item, which used to be at some anterior position of _itHead list.
    record = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
    if (record !== null) {
      // It is an item which we have evicted earlier: reinsert it back into the list.
      // But first we need to check if identity changed, so we can update in view if necessary.
      if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
      this._reinsertAfter(record, previousRecord, index);
    } else {
      // Attempt to see if the item is at some posterior position of _itHead list.
      record = this._linkedRecords === null ? null : this._linkedRecords.get(itemTrackBy, index);
      if (record !== null) {
        // We have the item in _itHead at/after `index` position. We need to move it forward in the
        // collection.
        // But first we need to check if identity changed, so we can update in view if necessary.
        if (!Object.is(record.item, item)) this._addIdentityChange(record, item);
        this._moveAfter(record, previousRecord, index);
      } else {
        // It is a new item: add it.
        record = this._addAfter(new IterableChangeRecord_(item, itemTrackBy), previousRecord, index);
      }
    }
    return record;
  }
  /**
   * This check is only needed if an array contains duplicates. (Short circuit of nothing dirty)
   *
   * Use case: `[a, a]` => `[b, a, a]`
   *
   * If we did not have this check then the insertion of `b` would:
   *   1) evict first `a`
   *   2) insert `b` at `0` index.
   *   3) leave `a` at index `1` as is. <-- this is wrong!
   *   3) reinsert `a` at index 2. <-- this is wrong!
   *
   * The correct behavior is:
   *   1) evict first `a`
   *   2) insert `b` at `0` index.
   *   3) reinsert `a` at index 1.
   *   3) move `a` at from `1` to `2`.
   *
   *
   * Double check that we have not evicted a duplicate item. We need to check if the item type may
   * have already been removed:
   * The insertion of b will evict the first 'a'. If we don't reinsert it now it will be reinserted
   * at the end. Which will show up as the two 'a's switching position. This is incorrect, since a
   * better way to think of it is as insert of 'b' rather then switch 'a' with 'b' and then add 'a'
   * at the end.
   *
   * @internal
   */
  _verifyReinsertion(record, item, itemTrackBy, index) {
    let reinsertRecord = this._unlinkedRecords === null ? null : this._unlinkedRecords.get(itemTrackBy, null);
    if (reinsertRecord !== null) {
      record = this._reinsertAfter(reinsertRecord, record._prev, index);
    } else if (record.currentIndex != index) {
      record.currentIndex = index;
      this._addToMoves(record, index);
    }
    return record;
  }
  /**
   * Get rid of any excess {@link IterableChangeRecord_}s from the previous collection
   *
   * - `record` The first excess {@link IterableChangeRecord_}.
   *
   * @internal
   */
  _truncate(record) {
    // Anything after that needs to be removed;
    while (record !== null) {
      const nextRecord = record._next;
      this._addToRemovals(this._unlink(record));
      record = nextRecord;
    }
    if (this._unlinkedRecords !== null) {
      this._unlinkedRecords.clear();
    }
    if (this._additionsTail !== null) {
      this._additionsTail._nextAdded = null;
    }
    if (this._movesTail !== null) {
      this._movesTail._nextMoved = null;
    }
    if (this._itTail !== null) {
      this._itTail._next = null;
    }
    if (this._removalsTail !== null) {
      this._removalsTail._nextRemoved = null;
    }
    if (this._identityChangesTail !== null) {
      this._identityChangesTail._nextIdentityChange = null;
    }
  }
  /** @internal */
  _reinsertAfter(record, prevRecord, index) {
    if (this._unlinkedRecords !== null) {
      this._unlinkedRecords.remove(record);
    }
    const prev = record._prevRemoved;
    const next = record._nextRemoved;
    if (prev === null) {
      this._removalsHead = next;
    } else {
      prev._nextRemoved = next;
    }
    if (next === null) {
      this._removalsTail = prev;
    } else {
      next._prevRemoved = prev;
    }
    this._insertAfter(record, prevRecord, index);
    this._addToMoves(record, index);
    return record;
  }
  /** @internal */
  _moveAfter(record, prevRecord, index) {
    this._unlink(record);
    this._insertAfter(record, prevRecord, index);
    this._addToMoves(record, index);
    return record;
  }
  /** @internal */
  _addAfter(record, prevRecord, index) {
    this._insertAfter(record, prevRecord, index);
    if (this._additionsTail === null) {
      // TODO(vicb):
      // assert(this._additionsHead === null);
      this._additionsTail = this._additionsHead = record;
    } else {
      // TODO(vicb):
      // assert(_additionsTail._nextAdded === null);
      // assert(record._nextAdded === null);
      this._additionsTail = this._additionsTail._nextAdded = record;
    }
    return record;
  }
  /** @internal */
  _insertAfter(record, prevRecord, index) {
    // TODO(vicb):
    // assert(record != prevRecord);
    // assert(record._next === null);
    // assert(record._prev === null);
    const next = prevRecord === null ? this._itHead : prevRecord._next;
    // TODO(vicb):
    // assert(next != record);
    // assert(prevRecord != record);
    record._next = next;
    record._prev = prevRecord;
    if (next === null) {
      this._itTail = record;
    } else {
      next._prev = record;
    }
    if (prevRecord === null) {
      this._itHead = record;
    } else {
      prevRecord._next = record;
    }
    if (this._linkedRecords === null) {
      this._linkedRecords = new _DuplicateMap();
    }
    this._linkedRecords.put(record);
    record.currentIndex = index;
    return record;
  }
  /** @internal */
  _remove(record) {
    return this._addToRemovals(this._unlink(record));
  }
  /** @internal */
  _unlink(record) {
    if (this._linkedRecords !== null) {
      this._linkedRecords.remove(record);
    }
    const prev = record._prev;
    const next = record._next;
    // TODO(vicb):
    // assert((record._prev = null) === null);
    // assert((record._next = null) === null);
    if (prev === null) {
      this._itHead = next;
    } else {
      prev._next = next;
    }
    if (next === null) {
      this._itTail = prev;
    } else {
      next._prev = prev;
    }
    return record;
  }
  /** @internal */
  _addToMoves(record, toIndex) {
    // TODO(vicb):
    // assert(record._nextMoved === null);
    if (record.previousIndex === toIndex) {
      return record;
    }
    if (this._movesTail === null) {
      // TODO(vicb):
      // assert(_movesHead === null);
      this._movesTail = this._movesHead = record;
    } else {
      // TODO(vicb):
      // assert(_movesTail._nextMoved === null);
      this._movesTail = this._movesTail._nextMoved = record;
    }
    return record;
  }
  _addToRemovals(record) {
    if (this._unlinkedRecords === null) {
      this._unlinkedRecords = new _DuplicateMap();
    }
    this._unlinkedRecords.put(record);
    record.currentIndex = null;
    record._nextRemoved = null;
    if (this._removalsTail === null) {
      // TODO(vicb):
      // assert(_removalsHead === null);
      this._removalsTail = this._removalsHead = record;
      record._prevRemoved = null;
    } else {
      // TODO(vicb):
      // assert(_removalsTail._nextRemoved === null);
      // assert(record._nextRemoved === null);
      record._prevRemoved = this._removalsTail;
      this._removalsTail = this._removalsTail._nextRemoved = record;
    }
    return record;
  }
  /** @internal */
  _addIdentityChange(record, item) {
    record.item = item;
    if (this._identityChangesTail === null) {
      this._identityChangesTail = this._identityChangesHead = record;
    } else {
      this._identityChangesTail = this._identityChangesTail._nextIdentityChange = record;
    }
    return record;
  }
}
class IterableChangeRecord_ {
  constructor(item, trackById) {
    this.item = item;
    this.trackById = trackById;
    this.currentIndex = null;
    this.previousIndex = null;
    /** @internal */
    this._nextPrevious = null;
    /** @internal */
    this._prev = null;
    /** @internal */
    this._next = null;
    /** @internal */
    this._prevDup = null;
    /** @internal */
    this._nextDup = null;
    /** @internal */
    this._prevRemoved = null;
    /** @internal */
    this._nextRemoved = null;
    /** @internal */
    this._nextAdded = null;
    /** @internal */
    this._nextMoved = null;
    /** @internal */
    this._nextIdentityChange = null;
  }
}
// A linked list of IterableChangeRecords with the same IterableChangeRecord_.item
class _DuplicateItemRecordList {
  constructor() {
    /** @internal */
    this._head = null;
    /** @internal */
    this._tail = null;
  }
  /**
   * Append the record to the list of duplicates.
   *
   * Note: by design all records in the list of duplicates hold the same value in record.item.
   */
  add(record) {
    if (this._head === null) {
      this._head = this._tail = record;
      record._nextDup = null;
      record._prevDup = null;
    } else {
      // TODO(vicb):
      // assert(record.item ==  _head.item ||
      //       record.item is num && record.item.isNaN && _head.item is num && _head.item.isNaN);
      this._tail._nextDup = record;
      record._prevDup = this._tail;
      record._nextDup = null;
      this._tail = record;
    }
  }
  // Returns a IterableChangeRecord_ having IterableChangeRecord_.trackById == trackById and
  // IterableChangeRecord_.currentIndex >= atOrAfterIndex
  get(trackById, atOrAfterIndex) {
    let record;
    for (record = this._head; record !== null; record = record._nextDup) {
      if ((atOrAfterIndex === null || atOrAfterIndex <= record.currentIndex) && Object.is(record.trackById, trackById)) {
        return record;
      }
    }
    return null;
  }
  /**
   * Remove one {@link IterableChangeRecord_} from the list of duplicates.
   *
   * Returns whether the list of duplicates is empty.
   */
  remove(record) {
    // TODO(vicb):
    // assert(() {
    //  // verify that the record being removed is in the list.
    //  for (IterableChangeRecord_ cursor = _head; cursor != null; cursor = cursor._nextDup) {
    //    if (identical(cursor, record)) return true;
    //  }
    //  return false;
    //});
    const prev = record._prevDup;
    const next = record._nextDup;
    if (prev === null) {
      this._head = next;
    } else {
      prev._nextDup = next;
    }
    if (next === null) {
      this._tail = prev;
    } else {
      next._prevDup = prev;
    }
    return this._head === null;
  }
}
class _DuplicateMap {
  constructor() {
    this.map = new Map();
  }
  put(record) {
    const key = record.trackById;
    let duplicates = this.map.get(key);
    if (!duplicates) {
      duplicates = new _DuplicateItemRecordList();
      this.map.set(key, duplicates);
    }
    duplicates.add(record);
  }
  /**
   * Retrieve the `value` using key. Because the IterableChangeRecord_ value may be one which we
   * have already iterated over, we use the `atOrAfterIndex` to pretend it is not there.
   *
   * Use case: `[a, b, c, a, a]` if we are at index `3` which is the second `a` then asking if we
   * have any more `a`s needs to return the second `a`.
   */
  get(trackById, atOrAfterIndex) {
    const key = trackById;
    const recordList = this.map.get(key);
    return recordList ? recordList.get(trackById, atOrAfterIndex) : null;
  }
  /**
   * Removes a {@link IterableChangeRecord_} from the list of duplicates.
   *
   * The list of duplicates also is removed from the map if it gets empty.
   */
  remove(record) {
    const key = record.trackById;
    const recordList = this.map.get(key);
    // Remove the list of duplicates when it gets empty
    if (recordList.remove(record)) {
      this.map.delete(key);
    }
    return record;
  }
  get isEmpty() {
    return this.map.size === 0;
  }
  clear() {
    this.map.clear();
  }
}
function getPreviousIndex(item, addRemoveOffset, moveOffsets) {
  const previousIndex = item.previousIndex;
  if (previousIndex === null) return previousIndex;
  let moveOffset = 0;
  if (moveOffsets && previousIndex < moveOffsets.length) {
    moveOffset = moveOffsets[previousIndex];
  }
  return previousIndex + addRemoveOffset + moveOffset;
}
class DefaultKeyValueDifferFactory {
  constructor() {}
  supports(obj) {
    return obj instanceof Map || isJsObject(obj);
  }
  create() {
    return new DefaultKeyValueDiffer();
  }
}
class DefaultKeyValueDiffer {
  constructor() {
    this._records = new Map();
    this._mapHead = null;
    // _appendAfter is used in the check loop
    this._appendAfter = null;
    this._previousMapHead = null;
    this._changesHead = null;
    this._changesTail = null;
    this._additionsHead = null;
    this._additionsTail = null;
    this._removalsHead = null;
    this._removalsTail = null;
  }
  get isDirty() {
    return this._additionsHead !== null || this._changesHead !== null || this._removalsHead !== null;
  }
  forEachItem(fn) {
    let record;
    for (record = this._mapHead; record !== null; record = record._next) {
      fn(record);
    }
  }
  forEachPreviousItem(fn) {
    let record;
    for (record = this._previousMapHead; record !== null; record = record._nextPrevious) {
      fn(record);
    }
  }
  forEachChangedItem(fn) {
    let record;
    for (record = this._changesHead; record !== null; record = record._nextChanged) {
      fn(record);
    }
  }
  forEachAddedItem(fn) {
    let record;
    for (record = this._additionsHead; record !== null; record = record._nextAdded) {
      fn(record);
    }
  }
  forEachRemovedItem(fn) {
    let record;
    for (record = this._removalsHead; record !== null; record = record._nextRemoved) {
      fn(record);
    }
  }
  diff(map) {
    if (!map) {
      map = new Map();
    } else if (!(map instanceof Map || isJsObject(map))) {
      throw new RuntimeError(900 /* RuntimeErrorCode.INVALID_DIFFER_INPUT */, ngDevMode && `Error trying to diff '${stringify(map)}'. Only maps and objects are allowed`);
    }
    return this.check(map) ? this : null;
  }
  onDestroy() {}
  /**
   * Check the current state of the map vs the previous.
   * The algorithm is optimised for when the keys do no change.
   */
  check(map) {
    this._reset();
    let insertBefore = this._mapHead;
    this._appendAfter = null;
    this._forEach(map, (value, key) => {
      if (insertBefore && insertBefore.key === key) {
        this._maybeAddToChanges(insertBefore, value);
        this._appendAfter = insertBefore;
        insertBefore = insertBefore._next;
      } else {
        const record = this._getOrCreateRecordForKey(key, value);
        insertBefore = this._insertBeforeOrAppend(insertBefore, record);
      }
    });
    // Items remaining at the end of the list have been deleted
    if (insertBefore) {
      if (insertBefore._prev) {
        insertBefore._prev._next = null;
      }
      this._removalsHead = insertBefore;
      for (let record = insertBefore; record !== null; record = record._nextRemoved) {
        if (record === this._mapHead) {
          this._mapHead = null;
        }
        this._records.delete(record.key);
        record._nextRemoved = record._next;
        record.previousValue = record.currentValue;
        record.currentValue = null;
        record._prev = null;
        record._next = null;
      }
    }
    // Make sure tails have no next records from previous runs
    if (this._changesTail) this._changesTail._nextChanged = null;
    if (this._additionsTail) this._additionsTail._nextAdded = null;
    return this.isDirty;
  }
  /**
   * Inserts a record before `before` or append at the end of the list when `before` is null.
   *
   * Notes:
   * - This method appends at `this._appendAfter`,
   * - This method updates `this._appendAfter`,
   * - The return value is the new value for the insertion pointer.
   */
  _insertBeforeOrAppend(before, record) {
    if (before) {
      const prev = before._prev;
      record._next = before;
      record._prev = prev;
      before._prev = record;
      if (prev) {
        prev._next = record;
      }
      if (before === this._mapHead) {
        this._mapHead = record;
      }
      this._appendAfter = before;
      return before;
    }
    if (this._appendAfter) {
      this._appendAfter._next = record;
      record._prev = this._appendAfter;
    } else {
      this._mapHead = record;
    }
    this._appendAfter = record;
    return null;
  }
  _getOrCreateRecordForKey(key, value) {
    if (this._records.has(key)) {
      const record = this._records.get(key);
      this._maybeAddToChanges(record, value);
      const prev = record._prev;
      const next = record._next;
      if (prev) {
        prev._next = next;
      }
      if (next) {
        next._prev = prev;
      }
      record._next = null;
      record._prev = null;
      return record;
    }
    const record = new KeyValueChangeRecord_(key);
    this._records.set(key, record);
    record.currentValue = value;
    this._addToAdditions(record);
    return record;
  }
  /** @internal */
  _reset() {
    if (this.isDirty) {
      let record;
      // let `_previousMapHead` contain the state of the map before the changes
      this._previousMapHead = this._mapHead;
      for (record = this._previousMapHead; record !== null; record = record._next) {
        record._nextPrevious = record._next;
      }
      // Update `record.previousValue` with the value of the item before the changes
      // We need to update all changed items (that's those which have been added and changed)
      for (record = this._changesHead; record !== null; record = record._nextChanged) {
        record.previousValue = record.currentValue;
      }
      for (record = this._additionsHead; record != null; record = record._nextAdded) {
        record.previousValue = record.currentValue;
      }
      this._changesHead = this._changesTail = null;
      this._additionsHead = this._additionsTail = null;
      this._removalsHead = null;
    }
  }
  // Add the record or a given key to the list of changes only when the value has actually changed
  _maybeAddToChanges(record, newValue) {
    if (!Object.is(newValue, record.currentValue)) {
      record.previousValue = record.currentValue;
      record.currentValue = newValue;
      this._addToChanges(record);
    }
  }
  _addToAdditions(record) {
    if (this._additionsHead === null) {
      this._additionsHead = this._additionsTail = record;
    } else {
      this._additionsTail._nextAdded = record;
      this._additionsTail = record;
    }
  }
  _addToChanges(record) {
    if (this._changesHead === null) {
      this._changesHead = this._changesTail = record;
    } else {
      this._changesTail._nextChanged = record;
      this._changesTail = record;
    }
  }
  /** @internal */
  _forEach(obj, fn) {
    if (obj instanceof Map) {
      obj.forEach(fn);
    } else {
      Object.keys(obj).forEach(k => fn(obj[k], k));
    }
  }
}
class KeyValueChangeRecord_ {
  constructor(key) {
    this.key = key;
    this.previousValue = null;
    this.currentValue = null;
    /** @internal */
    this._nextPrevious = null;
    /** @internal */
    this._next = null;
    /** @internal */
    this._prev = null;
    /** @internal */
    this._nextAdded = null;
    /** @internal */
    this._nextRemoved = null;
    /** @internal */
    this._nextChanged = null;
  }
}
function defaultIterableDiffersFactory() {
  return new IterableDiffers([new DefaultIterableDifferFactory()]);
}
/**
 * A repository of different iterable diffing strategies used by NgFor, NgClass, and others.
 *
 * @publicApi
 */
class IterableDiffers {
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: IterableDiffers,
      providedIn: 'root',
      factory: defaultIterableDiffersFactory
    });
  }
  constructor(factories) {
    this.factories = factories;
  }
  static create(factories, parent) {
    if (parent != null) {
      const copied = parent.factories.slice();
      factories = factories.concat(copied);
    }
    return new IterableDiffers(factories);
  }
  /**
   * Takes an array of {@link IterableDifferFactory} and returns a provider used to extend the
   * inherited {@link IterableDiffers} instance with the provided factories and return a new
   * {@link IterableDiffers} instance.
   *
   * @usageNotes
   * ### Example
   *
   * The following example shows how to extend an existing list of factories,
   * which will only be applied to the injector for this component and its children.
   * This step is all that's required to make a new {@link IterableDiffer} available.
   *
   * ```
   * @Component({
   *   viewProviders: [
   *     IterableDiffers.extend([new ImmutableListDiffer()])
   *   ]
   * })
   * ```
   */
  static extend(factories) {
    return {
      provide: IterableDiffers,
      useFactory: parent => {
        // if parent is null, it means that we are in the root injector and we have just overridden
        // the default injection mechanism for IterableDiffers, in such a case just assume
        // `defaultIterableDiffersFactory`.
        return IterableDiffers.create(factories, parent || defaultIterableDiffersFactory());
      },
      // Dependency technically isn't optional, but we can provide a better error message this way.
      deps: [[IterableDiffers, new SkipSelf(), new Optional()]]
    };
  }
  find(iterable) {
    const factory = this.factories.find(f => f.supports(iterable));
    if (factory != null) {
      return factory;
    } else {
      throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, ngDevMode && `Cannot find a differ supporting object '${iterable}' of type '${getTypeNameForDebugging(iterable)}'`);
    }
  }
}
function getTypeNameForDebugging(type) {
  return type['name'] || typeof type;
}
function defaultKeyValueDiffersFactory() {
  return new KeyValueDiffers([new DefaultKeyValueDifferFactory()]);
}
/**
 * A repository of different Map diffing strategies used by NgClass, NgStyle, and others.
 *
 * @publicApi
 */
class KeyValueDiffers {
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: KeyValueDiffers,
      providedIn: 'root',
      factory: defaultKeyValueDiffersFactory
    });
  }
  constructor(factories) {
    this.factories = factories;
  }
  static create(factories, parent) {
    if (parent) {
      const copied = parent.factories.slice();
      factories = factories.concat(copied);
    }
    return new KeyValueDiffers(factories);
  }
  /**
   * Takes an array of {@link KeyValueDifferFactory} and returns a provider used to extend the
   * inherited {@link KeyValueDiffers} instance with the provided factories and return a new
   * {@link KeyValueDiffers} instance.
   *
   * @usageNotes
   * ### Example
   *
   * The following example shows how to extend an existing list of factories,
   * which will only be applied to the injector for this component and its children.
   * This step is all that's required to make a new {@link KeyValueDiffer} available.
   *
   * ```
   * @Component({
   *   viewProviders: [
   *     KeyValueDiffers.extend([new ImmutableMapDiffer()])
   *   ]
   * })
   * ```
   */
  static extend(factories) {
    return {
      provide: KeyValueDiffers,
      useFactory: parent => {
        // if parent is null, it means that we are in the root injector and we have just overridden
        // the default injection mechanism for KeyValueDiffers, in such a case just assume
        // `defaultKeyValueDiffersFactory`.
        return KeyValueDiffers.create(factories, parent || defaultKeyValueDiffersFactory());
      },
      // Dependency technically isn't optional, but we can provide a better error message this way.
      deps: [[KeyValueDiffers, new SkipSelf(), new Optional()]]
    };
  }
  find(kv) {
    const factory = this.factories.find(f => f.supports(kv));
    if (factory) {
      return factory;
    }
    throw new RuntimeError(901 /* RuntimeErrorCode.NO_SUPPORTING_DIFFER_FACTORY */, ngDevMode && `Cannot find a differ supporting object '${kv}'`);
  }
}

/**
 * Structural diffing for `Object`s and `Map`s.
 */
const keyValDiff = [new DefaultKeyValueDifferFactory()];
/**
 * Structural diffing for `Iterable` types such as `Array`s.
 */
const iterableDiff = [new DefaultIterableDifferFactory()];
const defaultIterableDiffers = new IterableDiffers(iterableDiff);
const defaultKeyValueDiffers = new KeyValueDiffers(keyValDiff);

/**
 * @module
 * @description
 * Change detection enables data binding in Angular.
 */

/**
 * This platform has to be included in any other platform
 *
 * @publicApi
 */
const platformCore = createPlatformFactory(null, 'core', []);

/**
 * Re-exported by `BrowserModule`, which is included automatically in the root
 * `AppModule` when you create a new app with the CLI `new` command. Eagerly injects
 * `ApplicationRef` to instantiate it.
 *
 * @publicApi
 */
class ApplicationModule {
  // Inject ApplicationRef to make it eager...
  constructor(appRef) {}
  static {
    this.ɵfac = function ApplicationModule_Factory(t) {
      return new (t || ApplicationModule)(ɵɵinject(ApplicationRef));
    };
  }
  static {
    this.ɵmod = /*@__PURE__*/ɵɵdefineNgModule({
      type: ApplicationModule
    });
  }
  static {
    this.ɵinj = /*@__PURE__*/ɵɵdefineInjector({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ApplicationModule, [{
    type: NgModule
  }], () => [{
    type: ApplicationRef
  }], null);
})();

/**
 * The default equality function used for `signal` and `computed`, which uses referential equality.
 */
function defaultEquals(a, b) {
  return Object.is(a, b);
}

/**
 * The currently active consumer `ReactiveNode`, if running code in a reactive context.
 *
 * Change this via `setActiveConsumer`.
 */
let activeConsumer = null;
let inNotificationPhase = false;
/**
 * Global epoch counter. Incremented whenever a source signal is set.
 */
let epoch = 1;
/**
 * Symbol used to tell `Signal`s apart from other functions.
 *
 * This can be used to auto-unwrap signals in various cases, or to auto-wrap non-signal values.
 */
const SIGNAL = /* @__PURE__ */Symbol('SIGNAL');
function setActiveConsumer(consumer) {
  const prev = activeConsumer;
  activeConsumer = consumer;
  return prev;
}
function getActiveConsumer() {
  return activeConsumer;
}
function isInNotificationPhase() {
  return inNotificationPhase;
}
function isReactive(value) {
  return value[SIGNAL] !== undefined;
}
const REACTIVE_NODE = {
  version: 0,
  lastCleanEpoch: 0,
  dirty: false,
  producerNode: undefined,
  producerLastReadVersion: undefined,
  producerIndexOfThis: undefined,
  nextProducerIndex: 0,
  liveConsumerNode: undefined,
  liveConsumerIndexOfThis: undefined,
  consumerAllowSignalWrites: false,
  consumerIsAlwaysLive: false,
  producerMustRecompute: () => false,
  producerRecomputeValue: () => {},
  consumerMarkedDirty: () => {},
  consumerOnSignalRead: () => {}
};
/**
 * Called by implementations when a producer's signal is read.
 */
function producerAccessed(node) {
  if (inNotificationPhase) {
    throw new Error(typeof ngDevMode !== 'undefined' && ngDevMode ? `Assertion error: signal read during notification phase` : '');
  }
  if (activeConsumer === null) {
    // Accessed outside of a reactive context, so nothing to record.
    return;
  }
  activeConsumer.consumerOnSignalRead(node);
  // This producer is the `idx`th dependency of `activeConsumer`.
  const idx = activeConsumer.nextProducerIndex++;
  assertConsumerNode(activeConsumer);
  if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {
    // There's been a change in producers since the last execution of `activeConsumer`.
    // `activeConsumer.producerNode[idx]` holds a stale dependency which will be be removed and
    // replaced with `this`.
    //
    // If `activeConsumer` isn't live, then this is a no-op, since we can replace the producer in
    // `activeConsumer.producerNode` directly. However, if `activeConsumer` is live, then we need
    // to remove it from the stale producer's `liveConsumer`s.
    if (consumerIsLive(activeConsumer)) {
      const staleProducer = activeConsumer.producerNode[idx];
      producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);
      // At this point, the only record of `staleProducer` is the reference at
      // `activeConsumer.producerNode[idx]` which will be overwritten below.
    }
  }
  if (activeConsumer.producerNode[idx] !== node) {
    // We're a new dependency of the consumer (at `idx`).
    activeConsumer.producerNode[idx] = node;
    // If the active consumer is live, then add it as a live consumer. If not, then use 0 as a
    // placeholder value.
    activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
  }
  activeConsumer.producerLastReadVersion[idx] = node.version;
}
/**
 * Increment the global epoch counter.
 *
 * Called by source producers (that is, not computeds) whenever their values change.
 */
function producerIncrementEpoch() {
  epoch++;
}
/**
 * Ensure this producer's `version` is up-to-date.
 */
function producerUpdateValueVersion(node) {
  if (consumerIsLive(node) && !node.dirty) {
    // A live consumer will be marked dirty by producers, so a clean state means that its version
    // is guaranteed to be up-to-date.
    return;
  }
  if (!node.dirty && node.lastCleanEpoch === epoch) {
    // Even non-live consumers can skip polling if they previously found themselves to be clean at
    // the current epoch, since their dependencies could not possibly have changed (such a change
    // would've increased the epoch).
    return;
  }
  if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {
    // None of our producers report a change since the last time they were read, so no
    // recomputation of our value is necessary, and we can consider ourselves clean.
    node.dirty = false;
    node.lastCleanEpoch = epoch;
    return;
  }
  node.producerRecomputeValue(node);
  // After recomputing the value, we're no longer dirty.
  node.dirty = false;
  node.lastCleanEpoch = epoch;
}
/**
 * Propagate a dirty notification to live consumers of this producer.
 */
function producerNotifyConsumers(node) {
  if (node.liveConsumerNode === undefined) {
    return;
  }
  // Prevent signal reads when we're updating the graph
  const prev = inNotificationPhase;
  inNotificationPhase = true;
  try {
    for (const consumer of node.liveConsumerNode) {
      if (!consumer.dirty) {
        consumerMarkDirty(consumer);
      }
    }
  } finally {
    inNotificationPhase = prev;
  }
}
/**
 * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
 * based on the current consumer context.
 */
function producerUpdatesAllowed() {
  return activeConsumer?.consumerAllowSignalWrites !== false;
}
function consumerMarkDirty(node) {
  node.dirty = true;
  producerNotifyConsumers(node);
  node.consumerMarkedDirty?.(node);
}
/**
 * Prepare this consumer to run a computation in its reactive context.
 *
 * Must be called by subclasses which represent reactive computations, before those computations
 * begin.
 */
function consumerBeforeComputation(node) {
  node && (node.nextProducerIndex = 0);
  return setActiveConsumer(node);
}
/**
 * Finalize this consumer's state after a reactive computation has run.
 *
 * Must be called by subclasses which represent reactive computations, after those computations
 * have finished.
 */
function consumerAfterComputation(node, prevConsumer) {
  setActiveConsumer(prevConsumer);
  if (!node || node.producerNode === undefined || node.producerIndexOfThis === undefined || node.producerLastReadVersion === undefined) {
    return;
  }
  if (consumerIsLive(node)) {
    // For live consumers, we need to remove the producer -> consumer edge for any stale producers
    // which weren't dependencies after the recomputation.
    for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Truncate the producer tracking arrays.
  // Perf note: this is essentially truncating the length to `node.nextProducerIndex`, but
  // benchmarking has shown that individual pop operations are faster.
  while (node.producerNode.length > node.nextProducerIndex) {
    node.producerNode.pop();
    node.producerLastReadVersion.pop();
    node.producerIndexOfThis.pop();
  }
}
/**
 * Determine whether this consumer has any dependencies which have changed since the last time
 * they were read.
 */
function consumerPollProducersForChange(node) {
  assertConsumerNode(node);
  // Poll producers for change.
  for (let i = 0; i < node.producerNode.length; i++) {
    const producer = node.producerNode[i];
    const seenVersion = node.producerLastReadVersion[i];
    // First check the versions. A mismatch means that the producer's value is known to have
    // changed since the last time we read it.
    if (seenVersion !== producer.version) {
      return true;
    }
    // The producer's version is the same as the last time we read it, but it might itself be
    // stale. Force the producer to recompute its version (calculating a new value if necessary).
    producerUpdateValueVersion(producer);
    // Now when we do this check, `producer.version` is guaranteed to be up to date, so if the
    // versions still match then it has not changed since the last time we read it.
    if (seenVersion !== producer.version) {
      return true;
    }
  }
  return false;
}
/**
 * Disconnect this consumer from the graph.
 */
function consumerDestroy(node) {
  assertConsumerNode(node);
  if (consumerIsLive(node)) {
    // Drop all connections from the graph to this node.
    for (let i = 0; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Truncate all the arrays to drop all connection from this node to the graph.
  node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length = 0;
  if (node.liveConsumerNode) {
    node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
  }
}
/**
 * Add `consumer` as a live consumer of this node.
 *
 * Note that this operation is potentially transitive. If this node becomes live, then it becomes
 * a live consumer of all of its current producers.
 */
function producerAddLiveConsumer(node, consumer, indexOfThis) {
  assertProducerNode(node);
  assertConsumerNode(node);
  if (node.liveConsumerNode.length === 0) {
    // When going from 0 to 1 live consumers, we become a live consumer to our producers.
    for (let i = 0; i < node.producerNode.length; i++) {
      node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
    }
  }
  node.liveConsumerIndexOfThis.push(indexOfThis);
  return node.liveConsumerNode.push(consumer) - 1;
}
/**
 * Remove the live consumer at `idx`.
 */
function producerRemoveLiveConsumerAtIndex(node, idx) {
  assertProducerNode(node);
  assertConsumerNode(node);
  if (typeof ngDevMode !== 'undefined' && ngDevMode && idx >= node.liveConsumerNode.length) {
    throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`);
  }
  if (node.liveConsumerNode.length === 1) {
    // When removing the last live consumer, we will no longer be live. We need to remove
    // ourselves from our producers' tracking (which may cause consumer-producers to lose
    // liveness as well).
    for (let i = 0; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Move the last value of `liveConsumers` into `idx`. Note that if there's only a single
  // live consumer, this is a no-op.
  const lastIdx = node.liveConsumerNode.length - 1;
  node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];
  node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];
  // Truncate the array.
  node.liveConsumerNode.length--;
  node.liveConsumerIndexOfThis.length--;
  // If the index is still valid, then we need to fix the index pointer from the producer to this
  // consumer, and update it from `lastIdx` to `idx` (accounting for the move above).
  if (idx < node.liveConsumerNode.length) {
    const idxProducer = node.liveConsumerIndexOfThis[idx];
    const consumer = node.liveConsumerNode[idx];
    assertConsumerNode(consumer);
    consumer.producerIndexOfThis[idxProducer] = idx;
  }
}
function consumerIsLive(node) {
  return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;
}
function assertConsumerNode(node) {
  node.producerNode ??= [];
  node.producerIndexOfThis ??= [];
  node.producerLastReadVersion ??= [];
}
function assertProducerNode(node) {
  node.liveConsumerNode ??= [];
  node.liveConsumerIndexOfThis ??= [];
}

/**
 * Create a computed signal which derives a reactive value from an expression.
 */
function createComputed(computation) {
  const node = Object.create(COMPUTED_NODE);
  node.computation = computation;
  const computed = () => {
    // Check if the value needs updating before returning it.
    producerUpdateValueVersion(node);
    // Record that someone looked at this signal.
    producerAccessed(node);
    if (node.value === ERRORED) {
      throw node.error;
    }
    return node.value;
  };
  computed[SIGNAL] = node;
  return computed;
}
/**
 * A dedicated symbol used before a computed value has been calculated for the first time.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const UNSET = /* @__PURE__ */Symbol('UNSET');
/**
 * A dedicated symbol used in place of a computed signal value to indicate that a given computation
 * is in progress. Used to detect cycles in computation chains.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const COMPUTING = /* @__PURE__ */Symbol('COMPUTING');
/**
 * A dedicated symbol used in place of a computed signal value to indicate that a given computation
 * failed. The thrown error is cached until the computation gets dirty again.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const ERRORED = /* @__PURE__ */Symbol('ERRORED');
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const COMPUTED_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    value: UNSET,
    dirty: true,
    error: null,
    equal: defaultEquals,
    producerMustRecompute(node) {
      // Force a recomputation if there's no current value, or if the current value is in the
      // process of being calculated (which should throw an error).
      return node.value === UNSET || node.value === COMPUTING;
    },
    producerRecomputeValue(node) {
      if (node.value === COMPUTING) {
        // Our computation somehow led to a cyclic read of itself.
        throw new Error('Detected cycle in computations.');
      }
      const oldValue = node.value;
      node.value = COMPUTING;
      const prevConsumer = consumerBeforeComputation(node);
      let newValue;
      try {
        newValue = node.computation();
      } catch (err) {
        newValue = ERRORED;
        node.error = err;
      } finally {
        consumerAfterComputation(node, prevConsumer);
      }
      if (oldValue !== UNSET && oldValue !== ERRORED && newValue !== ERRORED && node.equal(oldValue, newValue)) {
        // No change to `valueVersion` - old and new values are
        // semantically equivalent.
        node.value = oldValue;
        return;
      }
      node.value = newValue;
      node.version++;
    }
  };
})();
function defaultThrowError() {
  throw new Error();
}
let throwInvalidWriteToSignalErrorFn = defaultThrowError;
function throwInvalidWriteToSignalError() {
  throwInvalidWriteToSignalErrorFn();
}
function setThrowInvalidWriteToSignalError(fn) {
  throwInvalidWriteToSignalErrorFn = fn;
}

/**
 * If set, called after `WritableSignal`s are updated.
 *
 * This hook can be used to achieve various effects, such as running effects synchronously as part
 * of setting a signal.
 */
let postSignalSetFn = null;
/**
 * Create a `Signal` that can be set or updated directly.
 */
function createSignal(initialValue) {
  const node = Object.create(SIGNAL_NODE);
  node.value = initialValue;
  const getter = () => {
    producerAccessed(node);
    return node.value;
  };
  getter[SIGNAL] = node;
  return getter;
}
function setPostSignalSetFn(fn) {
  const prev = postSignalSetFn;
  postSignalSetFn = fn;
  return prev;
}
function signalGetFn() {
  producerAccessed(this);
  return this.value;
}
function signalSetFn(node, newValue) {
  if (!producerUpdatesAllowed()) {
    throwInvalidWriteToSignalError();
  }
  if (!node.equal(node.value, newValue)) {
    node.value = newValue;
    signalValueChanged(node);
  }
}
function signalUpdateFn(node, updater) {
  if (!producerUpdatesAllowed()) {
    throwInvalidWriteToSignalError();
  }
  signalSetFn(node, updater(node.value));
}
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const SIGNAL_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    equal: defaultEquals,
    value: undefined
  };
})();
function signalValueChanged(node) {
  node.version++;
  producerIncrementEpoch();
  producerNotifyConsumers(node);
  postSignalSetFn?.();
}
function createWatch(fn, schedule, allowSignalWrites) {
  const node = Object.create(WATCH_NODE);
  if (allowSignalWrites) {
    node.consumerAllowSignalWrites = true;
  }
  node.fn = fn;
  node.schedule = schedule;
  const registerOnCleanup = cleanupFn => {
    node.cleanupFn = cleanupFn;
  };
  function isWatchNodeDestroyed(node) {
    return node.fn === null && node.schedule === null;
  }
  function destroyWatchNode(node) {
    if (!isWatchNodeDestroyed(node)) {
      consumerDestroy(node); // disconnect watcher from the reactive graph
      node.cleanupFn();
      // nullify references to the integration functions to mark node as destroyed
      node.fn = null;
      node.schedule = null;
      node.cleanupFn = NOOP_CLEANUP_FN;
    }
  }
  const run = () => {
    if (node.fn === null) {
      // trying to run a destroyed watch is noop
      return;
    }
    if (isInNotificationPhase()) {
      throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
    }
    node.dirty = false;
    if (node.hasRun && !consumerPollProducersForChange(node)) {
      return;
    }
    node.hasRun = true;
    const prevConsumer = consumerBeforeComputation(node);
    try {
      node.cleanupFn();
      node.cleanupFn = NOOP_CLEANUP_FN;
      node.fn(registerOnCleanup);
    } finally {
      consumerAfterComputation(node, prevConsumer);
    }
  };
  node.ref = {
    notify: () => consumerMarkDirty(node),
    run,
    cleanup: () => node.cleanupFn(),
    destroy: () => destroyWatchNode(node),
    [SIGNAL]: node
  };
  return node.ref;
}
const NOOP_CLEANUP_FN = () => {};
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const WATCH_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    consumerIsAlwaysLive: true,
    consumerAllowSignalWrites: false,
    consumerMarkedDirty: node => {
      if (node.schedule !== null) {
        node.schedule(node.ref);
      }
    },
    hasRun: false,
    cleanupFn: NOOP_CLEANUP_FN
  };
})();
function setAlternateWeakRefImpl(impl) {
  // TODO: remove this function
}

// A delay in milliseconds before the scan is run after onLoad, to avoid any
// potential race conditions with other LCP-related functions. This delay
// happens outside of the main JavaScript execution and will only effect the timing
// on when the warning becomes visible in the console.
const SCAN_DELAY = 200;
const OVERSIZED_IMAGE_TOLERANCE = 1200;
class ImagePerformanceWarning {
  constructor() {
    // Map of full image URLs -> original `ngSrc` values.
    this.window = null;
    this.observer = null;
    this.options = inject(IMAGE_CONFIG);
    this.ngZone = inject(NgZone);
  }
  start() {
    if (typeof PerformanceObserver === 'undefined' || this.options?.disableImageSizeWarning && this.options?.disableImageLazyLoadWarning) {
      return;
    }
    this.observer = this.initPerformanceObserver();
    const doc = getDocument();
    const win = doc.defaultView;
    if (typeof win !== 'undefined') {
      this.window = win;
      // Wait to avoid race conditions where LCP image triggers
      // load event before it's recorded by the performance observer
      const waitToScan = () => {
        setTimeout(this.scanImages.bind(this), SCAN_DELAY);
      };
      // Angular doesn't have to run change detection whenever any asynchronous tasks are invoked in
      // the scope of this functionality.
      this.ngZone.runOutsideAngular(() => {
        // Consider the case when the application is created and destroyed multiple times.
        // Typically, applications are created instantly once the page is loaded, and the
        // `window.load` listener is always triggered. However, the `window.load` event will never
        // be fired if the page is loaded, and the application is created later. Checking for
        // `readyState` is the easiest way to determine whether the page has been loaded or not.
        if (doc.readyState === 'complete') {
          waitToScan();
        } else {
          this.window?.addEventListener('load', waitToScan, {
            once: true
          });
        }
      });
    }
  }
  ngOnDestroy() {
    this.observer?.disconnect();
  }
  initPerformanceObserver() {
    if (typeof PerformanceObserver === 'undefined') {
      return null;
    }
    const observer = new PerformanceObserver(entryList => {
      const entries = entryList.getEntries();
      if (entries.length === 0) return;
      // We use the latest entry produced by the `PerformanceObserver` as the best
      // signal on which element is actually an LCP one. As an example, the first image to load on
      // a page, by virtue of being the only thing on the page so far, is often a LCP candidate
      // and gets reported by PerformanceObserver, but isn't necessarily the LCP element.
      const lcpElement = entries[entries.length - 1];
      // Cast to `any` due to missing `element` on the `LargestContentfulPaint` type of entry.
      // See https://developer.mozilla.org/en-US/docs/Web/API/LargestContentfulPaint
      const imgSrc = lcpElement.element?.src ?? '';
      // Exclude `data:` and `blob:` URLs, since they are fetched resources.
      if (imgSrc.startsWith('data:') || imgSrc.startsWith('blob:')) return;
      this.lcpImageUrl = imgSrc;
    });
    observer.observe({
      type: 'largest-contentful-paint',
      buffered: true
    });
    return observer;
  }
  scanImages() {
    const images = getDocument().querySelectorAll('img');
    let lcpElementFound,
      lcpElementLoadedCorrectly = false;
    images.forEach(image => {
      if (!this.options?.disableImageSizeWarning) {
        for (const image of images) {
          // Image elements using the NgOptimizedImage directive are excluded,
          // as that directive has its own version of this check.
          if (!image.getAttribute('ng-img') && this.isOversized(image)) {
            logOversizedImageWarning(image.src);
          }
        }
      }
      if (!this.options?.disableImageLazyLoadWarning && this.lcpImageUrl) {
        if (image.src === this.lcpImageUrl) {
          lcpElementFound = true;
          if (image.loading !== 'lazy' || image.getAttribute('ng-img')) {
            // This variable is set to true and never goes back to false to account
            // for the case where multiple images have the same src url, and some
            // have lazy loading while others don't.
            // Also ignore NgOptimizedImage because there's a different warning for that.
            lcpElementLoadedCorrectly = true;
          }
        }
      }
    });
    if (lcpElementFound && !lcpElementLoadedCorrectly && this.lcpImageUrl && !this.options?.disableImageLazyLoadWarning) {
      logLazyLCPWarning(this.lcpImageUrl);
    }
  }
  isOversized(image) {
    if (!this.window) {
      return false;
    }
    const computedStyle = this.window.getComputedStyle(image);
    let renderedWidth = parseFloat(computedStyle.getPropertyValue('width'));
    let renderedHeight = parseFloat(computedStyle.getPropertyValue('height'));
    const boxSizing = computedStyle.getPropertyValue('box-sizing');
    const objectFit = computedStyle.getPropertyValue('object-fit');
    if (objectFit === `cover`) {
      // Object fit cover may indicate a use case such as a sprite sheet where
      // this warning does not apply.
      return false;
    }
    if (boxSizing === 'border-box') {
      const paddingTop = computedStyle.getPropertyValue('padding-top');
      const paddingRight = computedStyle.getPropertyValue('padding-right');
      const paddingBottom = computedStyle.getPropertyValue('padding-bottom');
      const paddingLeft = computedStyle.getPropertyValue('padding-left');
      renderedWidth -= parseFloat(paddingRight) + parseFloat(paddingLeft);
      renderedHeight -= parseFloat(paddingTop) + parseFloat(paddingBottom);
    }
    const intrinsicWidth = image.naturalWidth;
    const intrinsicHeight = image.naturalHeight;
    const recommendedWidth = this.window.devicePixelRatio * renderedWidth;
    const recommendedHeight = this.window.devicePixelRatio * renderedHeight;
    const oversizedWidth = intrinsicWidth - recommendedWidth >= OVERSIZED_IMAGE_TOLERANCE;
    const oversizedHeight = intrinsicHeight - recommendedHeight >= OVERSIZED_IMAGE_TOLERANCE;
    return oversizedWidth || oversizedHeight;
  }
  static {
    this.ɵfac = function ImagePerformanceWarning_Factory(t) {
      return new (t || ImagePerformanceWarning)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: ImagePerformanceWarning,
      factory: ImagePerformanceWarning.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ImagePerformanceWarning, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function logLazyLCPWarning(src) {
  console.warn(formatRuntimeError(-913 /* RuntimeErrorCode.IMAGE_PERFORMANCE_WARNING */, `An image with src ${src} is the Largest Contentful Paint (LCP) element ` + `but was given a "loading" value of "lazy", which can negatively impact ` + `application loading performance. This warning can be addressed by ` + `changing the loading value of the LCP image to "eager", or by using the ` + `NgOptimizedImage directive's prioritization utilities. For more ` + `information about addressing or disabling this warning, see ` + `https://angular.io/errors/NG0913`));
}
function logOversizedImageWarning(src) {
  console.warn(formatRuntimeError(-913 /* RuntimeErrorCode.IMAGE_PERFORMANCE_WARNING */, `An image with src ${src} has intrinsic file dimensions much larger than its ` + `rendered size. This can negatively impact application loading performance. ` + `For more information about addressing or disabling this warning, see ` + `https://angular.io/errors/NG0913`));
}

/**
 * Internal create application API that implements the core application creation logic and optional
 * bootstrap logic.
 *
 * Platforms (such as `platform-browser`) may require different set of application and platform
 * providers for an application to function correctly. As a result, platforms may use this function
 * internally and supply the necessary providers during the bootstrap, while exposing
 * platform-specific APIs as a part of their public API.
 *
 * @returns A promise that returns an `ApplicationRef` instance once resolved.
 */
function internalCreateApplication(config) {
  try {
    const {
      rootComponent,
      appProviders,
      platformProviders
    } = config;
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && rootComponent !== undefined) {
      assertStandaloneComponentType(rootComponent);
    }
    const platformInjector = createOrReusePlatformInjector(platformProviders);
    // Create root application injector based on a set of providers configured at the platform
    // bootstrap level as well as providers passed to the bootstrap call by a user.
    const allAppProviders = [provideZoneChangeDetection(), ...(appProviders || [])];
    const adapter = new EnvironmentNgModuleRefAdapter({
      providers: allAppProviders,
      parent: platformInjector,
      debugName: typeof ngDevMode === 'undefined' || ngDevMode ? 'Environment Injector' : '',
      // We skip environment initializers because we need to run them inside the NgZone, which
      // happens after we get the NgZone instance from the Injector.
      runEnvironmentInitializers: false
    });
    const envInjector = adapter.injector;
    const ngZone = envInjector.get(NgZone);
    return ngZone.run(() => {
      envInjector.resolveInjectorInitializers();
      const exceptionHandler = envInjector.get(ErrorHandler, null);
      if ((typeof ngDevMode === 'undefined' || ngDevMode) && !exceptionHandler) {
        throw new RuntimeError(402 /* RuntimeErrorCode.MISSING_REQUIRED_INJECTABLE_IN_BOOTSTRAP */, 'No `ErrorHandler` found in the Dependency Injection tree.');
      }
      let onErrorSubscription;
      ngZone.runOutsideAngular(() => {
        onErrorSubscription = ngZone.onError.subscribe({
          next: error => {
            exceptionHandler.handleError(error);
          }
        });
      });
      // If the whole platform is destroyed, invoke the `destroy` method
      // for all bootstrapped applications as well.
      const destroyListener = () => envInjector.destroy();
      const onPlatformDestroyListeners = platformInjector.get(PLATFORM_DESTROY_LISTENERS);
      onPlatformDestroyListeners.add(destroyListener);
      envInjector.onDestroy(() => {
        onErrorSubscription.unsubscribe();
        onPlatformDestroyListeners.delete(destroyListener);
      });
      return _callAndReportToErrorHandler(exceptionHandler, ngZone, () => {
        const initStatus = envInjector.get(ApplicationInitStatus);
        initStatus.runInitializers();
        return initStatus.donePromise.then(() => {
          const localeId = envInjector.get(LOCALE_ID, DEFAULT_LOCALE_ID);
          setLocaleId(localeId || DEFAULT_LOCALE_ID);
          const appRef = envInjector.get(ApplicationRef);
          if (rootComponent !== undefined) {
            appRef.bootstrap(rootComponent);
          }
          if (typeof ngDevMode === 'undefined' || ngDevMode) {
            const imagePerformanceService = envInjector.get(ImagePerformanceWarning);
            imagePerformanceService.start();
          }
          return appRef;
        });
      });
    });
  } catch (e) {
    return Promise.reject(e);
  }
}
class ChangeDetectionSchedulerImpl {
  constructor() {
    this.appRef = inject(ApplicationRef);
    this.taskService = inject(PendingTasks);
    this.pendingRenderTaskId = null;
    this.shouldRefreshViews = false;
  }
  notify(type = 0 /* NotificationType.RefreshViews */) {
    // When the only source of notification is an afterRender hook will skip straight to the hooks
    // rather than refreshing views in ApplicationRef.tick
    this.shouldRefreshViews ||= type === 0 /* NotificationType.RefreshViews */;
    if (this.pendingRenderTaskId !== null) {
      return;
    }
    this.pendingRenderTaskId = this.taskService.add();
    this.raceTimeoutAndRequestAnimationFrame();
  }
  /**
   * Run change detection after the first of setTimeout and requestAnimationFrame resolves.
   *
   * - `requestAnimationFrame` ensures that change detection runs ahead of a browser repaint.
   * This ensures that the create and update passes of a change detection always happen
   * in the same frame.
   * - When the browser is resource-starved, `rAF` can execute _before_ a `setTimeout` because
   * rendering is a very high priority process. This means that `setTimeout` cannot guarantee
   * same-frame create and update pass, when `setTimeout` is used to schedule the update phase.
   * - While `rAF` gives us the desirable same-frame updates, it has two limitations that
   * prevent it from being used alone. First, it does not run in background tabs, which would
   * prevent Angular from initializing an application when opened in a new tab (for example).
   * Second, repeated calls to requestAnimationFrame will execute at the refresh rate of the
   * hardware (~16ms for a 60Hz display). This would cause significant slowdown of tests that
   * are written with several updates and asserts in the form of "update; await stable; assert;".
   * - Both `setTimeout` and `rAF` are able to "coalesce" several events from a single user
   * interaction into a single change detection. Importantly, this reduces view tree traversals when
   * compared to an alternative timing mechanism like `queueMicrotask`, where change detection would
   * then be interleaves between each event.
   *
   * By running change detection after the first of `setTimeout` and `rAF` to execute, we get the
   * best of both worlds.
   */
  raceTimeoutAndRequestAnimationFrame() {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      const timeout = new Promise(resolve => setTimeout(resolve));
      const rAF = typeof _global['requestAnimationFrame'] === 'function' ? new Promise(resolve => requestAnimationFrame(() => resolve())) : null;
      yield Promise.race([timeout, rAF]);
      _this.tick();
    })();
  }
  tick() {
    try {
      if (!this.appRef.destroyed) {
        this.appRef._tick(this.shouldRefreshViews);
      }
    } finally {
      this.shouldRefreshViews = false;
      // If this is the last task, the service will synchronously emit a stable notification. If
      // there is a subscriber that then acts in a way that tries to notify the scheduler again,
      // we need to be able to respond to schedule a new change detection. Therefore, we should
      // clear the task ID before removing it from the pending tasks (or the tasks service should
      // not synchronously emit stable, similar to how Zone stableness only happens if it's still
      // stable after a microtask).
      const taskId = this.pendingRenderTaskId;
      this.pendingRenderTaskId = null;
      this.taskService.remove(taskId);
    }
  }
  static {
    this.ɵfac = function ChangeDetectionSchedulerImpl_Factory(t) {
      return new (t || ChangeDetectionSchedulerImpl)();
    };
  }
  static {
    this.ɵprov = /*@__PURE__*/ɵɵdefineInjectable({
      token: ChangeDetectionSchedulerImpl,
      factory: ChangeDetectionSchedulerImpl.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(ChangeDetectionSchedulerImpl, [{
    type: Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function provideZonelessChangeDetection() {
  return makeEnvironmentProviders([{
    provide: ChangeDetectionScheduler,
    useExisting: ChangeDetectionSchedulerImpl
  }, {
    provide: NgZone,
    useClass: NoopNgZone
  }]);
}

/**
 * Retrieves all defer blocks in a given LView.
 *
 * @param lView lView with defer blocks
 * @param deferBlocks defer block aggregator array
 */
function getDeferBlocks(lView, deferBlocks) {
  const tView = lView[TVIEW];
  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
    if (isLContainer(lView[i])) {
      const lContainer = lView[i];
      // An LContainer may represent an instance of a defer block, in which case
      // we store it as a result. Otherwise, keep iterating over LContainer views and
      // look for defer blocks.
      const isLast = i === tView.bindingStartIndex - 1;
      if (!isLast) {
        const tNode = tView.data[i];
        const tDetails = getTDeferBlockDetails(tView, tNode);
        if (isTDeferBlockDetails(tDetails)) {
          deferBlocks.push({
            lContainer,
            lView,
            tNode,
            tDetails
          });
          // This LContainer represents a defer block, so we exit
          // this iteration and don't inspect views in this LContainer.
          continue;
        }
      }
      for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
        getDeferBlocks(lContainer[i], deferBlocks);
      }
    } else if (isLView(lView[i])) {
      // This is a component, enter the `getDeferBlocks` recursively.
      getDeferBlocks(lView[i], deferBlocks);
    }
  }
}

/**
 * Indicates whether the hydration-related code was added,
 * prevents adding it multiple times.
 */
let isHydrationSupportEnabled = false;
/**
 * Indicates whether support for hydrating i18n blocks is enabled.
 */
let _isI18nHydrationSupportEnabled = false;
/**
 * Defines a period of time that Angular waits for the `ApplicationRef.isStable` to emit `true`.
 * If there was no event with the `true` value during this time, Angular reports a warning.
 */
const APPLICATION_IS_STABLE_TIMEOUT = 10_000;
/**
 * Brings the necessary hydration code in tree-shakable manner.
 * The code is only present when the `provideClientHydration` is
 * invoked. Otherwise, this code is tree-shaken away during the
 * build optimization step.
 *
 * This technique allows us to swap implementations of methods so
 * tree shaking works appropriately when hydration is disabled or
 * enabled. It brings in the appropriate version of the method that
 * supports hydration only when enabled.
 */
function enableHydrationRuntimeSupport() {
  if (!isHydrationSupportEnabled) {
    isHydrationSupportEnabled = true;
    enableRetrieveHydrationInfoImpl();
    enableLocateOrCreateElementNodeImpl();
    enableLocateOrCreateTextNodeImpl();
    enableLocateOrCreateElementContainerNodeImpl();
    enableLocateOrCreateContainerAnchorImpl();
    enableLocateOrCreateContainerRefImpl();
    enableFindMatchingDehydratedViewImpl();
    enableApplyRootElementTransformImpl();
    enableLocateOrCreateI18nNodeImpl();
  }
}
/**
 * Outputs a message with hydration stats into a console.
 */
function printHydrationStats(injector) {
  const console = injector.get(Console);
  const message = `Angular hydrated ${ngDevMode.hydratedComponents} component(s) ` + `and ${ngDevMode.hydratedNodes} node(s), ` + `${ngDevMode.componentsSkippedHydration} component(s) were skipped. ` + `Learn more at https://angular.io/guide/hydration.`;
  // tslint:disable-next-line:no-console
  console.log(message);
}
/**
 * Returns a Promise that is resolved when an application becomes stable.
 */
function whenStableWithTimeout(appRef, injector) {
  const whenStablePromise = whenStable(appRef);
  if (typeof ngDevMode !== 'undefined' && ngDevMode) {
    const timeoutTime = APPLICATION_IS_STABLE_TIMEOUT;
    const console = injector.get(Console);
    const ngZone = injector.get(NgZone);
    // The following call should not and does not prevent the app to become stable
    // We cannot use RxJS timer here because the app would remain unstable.
    // This also avoids an extra change detection cycle.
    const timeoutId = ngZone.runOutsideAngular(() => {
      return setTimeout(() => logWarningOnStableTimedout(timeoutTime, console), timeoutTime);
    });
    whenStablePromise.finally(() => clearTimeout(timeoutId));
  }
  return whenStablePromise;
}
/**
 * Returns a set of providers required to setup hydration support
 * for an application that is server side rendered. This function is
 * included into the `provideClientHydration` public API function from
 * the `platform-browser` package.
 *
 * The function sets up an internal flag that would be recognized during
 * the server side rendering time as well, so there is no need to
 * configure or change anything in NgUniversal to enable the feature.
 */
function withDomHydration() {
  return makeEnvironmentProviders([{
    provide: IS_HYDRATION_DOM_REUSE_ENABLED,
    useFactory: () => {
      let isEnabled = true;
      if (isPlatformBrowser()) {
        // On the client, verify that the server response contains
        // hydration annotations. Otherwise, keep hydration disabled.
        const transferState = inject(TransferState, {
          optional: true
        });
        isEnabled = !!transferState?.get(NGH_DATA_KEY, null);
        if (!isEnabled && typeof ngDevMode !== 'undefined' && ngDevMode) {
          const console = inject(Console);
          const message = formatRuntimeError(-505 /* RuntimeErrorCode.MISSING_HYDRATION_ANNOTATIONS */, 'Angular hydration was requested on the client, but there was no ' + 'serialized information present in the server response, ' + 'thus hydration was not enabled. ' + 'Make sure the `provideClientHydration()` is included into the list ' + 'of providers in the server part of the application configuration.');
          // tslint:disable-next-line:no-console
          console.warn(message);
        }
      }
      if (isEnabled) {
        performanceMarkFeature('NgHydration');
      }
      return isEnabled;
    }
  }, {
    provide: ENVIRONMENT_INITIALIZER,
    useValue: () => {
      _isI18nHydrationSupportEnabled = !!inject(IS_I18N_HYDRATION_ENABLED, {
        optional: true
      });
      // Since this function is used across both server and client,
      // make sure that the runtime code is only added when invoked
      // on the client. Moving forward, the `isPlatformBrowser` check should
      // be replaced with a tree-shakable alternative (e.g. `isServer`
      // flag).
      if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
        verifySsrContentsIntegrity();
        enableHydrationRuntimeSupport();
      }
    },
    multi: true
  }, {
    provide: PRESERVE_HOST_CONTENT,
    useFactory: () => {
      // Preserve host element content only in a browser
      // environment and when hydration is configured properly.
      // On a server, an application is rendered from scratch,
      // so the host content needs to be empty.
      return isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED);
    }
  }, {
    provide: APP_BOOTSTRAP_LISTENER,
    useFactory: () => {
      if (isPlatformBrowser() && inject(IS_HYDRATION_DOM_REUSE_ENABLED)) {
        const appRef = inject(ApplicationRef);
        const injector = inject(Injector);
        return () => {
          // Wait until an app becomes stable and cleanup all views that
          // were not claimed during the application bootstrap process.
          // The timing is similar to when we start the serialization process
          // on the server.
          //
          // Note: the cleanup task *MUST* be scheduled within the Angular zone in Zone apps
          // to ensure that change detection is properly run afterward.
          whenStableWithTimeout(appRef, injector).then(() => {
            cleanupDehydratedViews(appRef);
            if (typeof ngDevMode !== 'undefined' && ngDevMode) {
              printHydrationStats(injector);
            }
          });
        };
      }
      return () => {}; // noop
    },
    multi: true
  }]);
}
/**
 * Returns a set of providers required to setup support for i18n hydration.
 * Requires hydration to be enabled separately.
 */
function withI18nHydration() {
  return makeEnvironmentProviders([{
    provide: IS_I18N_HYDRATION_ENABLED,
    useValue: true
  }]);
}
/**
 * Returns whether i18n hydration support is enabled.
 */
function isI18nHydrationSupportEnabled() {
  return _isI18nHydrationSupportEnabled;
}
/**
 *
 * @param time The time in ms until the stable timedout warning message is logged
 */
function logWarningOnStableTimedout(time, console) {
  const message = `Angular hydration expected the ApplicationRef.isStable() to emit \`true\`, but it ` + `didn't happen within ${time}ms. Angular hydration logic depends on the application becoming stable ` + `as a signal to complete hydration process.`;
  console.warn(formatRuntimeError(-506 /* RuntimeErrorCode.HYDRATION_STABLE_TIMEDOUT */, message));
}
/**
 * Verifies whether the DOM contains a special marker added during SSR time to make sure
 * there is no SSR'ed contents transformations happen after SSR is completed. Typically that
 * happens either by CDN or during the build process as an optimization to remove comment nodes.
 * Hydration process requires comment nodes produced by Angular to locate correct DOM segments.
 * When this special marker is *not* present - throw an error and do not proceed with hydration,
 * since it will not be able to function correctly.
 *
 * Note: this function is invoked only on the client, so it's safe to use DOM APIs.
 */
function verifySsrContentsIntegrity() {
  const doc = getDocument();
  let hydrationMarker;
  for (const node of doc.body.childNodes) {
    if (node.nodeType === Node.COMMENT_NODE && node.textContent?.trim() === SSR_CONTENT_INTEGRITY_MARKER) {
      hydrationMarker = node;
      break;
    }
  }
  if (!hydrationMarker) {
    throw new RuntimeError(-507 /* RuntimeErrorCode.MISSING_SSR_CONTENT_INTEGRITY_MARKER */, typeof ngDevMode !== 'undefined' && ngDevMode && 'Angular hydration logic detected that HTML content of this page was modified after it ' + 'was produced during server side rendering. Make sure that there are no optimizations ' + 'that remove comment nodes from HTML enabled on your CDN. Angular hydration ' + 'relies on HTML produced by the server, including whitespaces and comment nodes.');
  }
}

/**
 * A collection that tracks all serialized views (`ngh` DOM annotations)
 * to avoid duplication. An attempt to add a duplicate view results in the
 * collection returning the index of the previously collected serialized view.
 * This reduces the number of annotations needed for a given page.
 */
class SerializedViewCollection {
  constructor() {
    this.views = [];
    this.indexByContent = new Map();
  }
  add(serializedView) {
    const viewAsString = JSON.stringify(serializedView);
    if (!this.indexByContent.has(viewAsString)) {
      const index = this.views.length;
      this.views.push(serializedView);
      this.indexByContent.set(viewAsString, index);
      return index;
    }
    return this.indexByContent.get(viewAsString);
  }
  getAll() {
    return this.views;
  }
}
/**
 * Global counter that is used to generate a unique id for TViews
 * during the serialization process.
 */
let tViewSsrId = 0;
/**
 * Generates a unique id for a given TView and returns this id.
 * The id is also stored on this instance of a TView and reused in
 * subsequent calls.
 *
 * This id is needed to uniquely identify and pick up dehydrated views
 * at runtime.
 */
function getSsrId(tView) {
  if (!tView.ssrId) {
    tView.ssrId = `t${tViewSsrId++}`;
  }
  return tView.ssrId;
}
/**
 * Computes the number of root nodes in a given view
 * (or child nodes in a given container if a tNode is provided).
 */
function calcNumRootNodes(tView, lView, tNode) {
  const rootNodes = [];
  collectNativeNodes(tView, lView, tNode, rootNodes);
  return rootNodes.length;
}
/**
 * Computes the number of root nodes in all views in a given LContainer.
 */
function calcNumRootNodesInLContainer(lContainer) {
  const rootNodes = [];
  collectNativeNodesInLContainer(lContainer, rootNodes);
  return rootNodes.length;
}
/**
 * Annotates root level component's LView for hydration,
 * see `annotateHostElementForHydration` for additional information.
 */
function annotateComponentLViewForHydration(lView, context) {
  const hostElement = lView[HOST];
  // Root elements might also be annotated with the `ngSkipHydration` attribute,
  // check if it's present before starting the serialization process.
  if (hostElement && !hostElement.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
    return annotateHostElementForHydration(hostElement, lView, context);
  }
  return null;
}
/**
 * Annotates root level LContainer for hydration. This happens when a root component
 * injects ViewContainerRef, thus making the component an anchor for a view container.
 * This function serializes the component itself as well as all views from the view
 * container.
 */
function annotateLContainerForHydration(lContainer, context) {
  const componentLView = unwrapLView(lContainer[HOST]);
  // Serialize the root component itself.
  const componentLViewNghIndex = annotateComponentLViewForHydration(componentLView, context);
  const hostElement = unwrapRNode(componentLView[HOST]);
  // Serialize all views within this view container.
  const rootLView = lContainer[PARENT];
  const rootLViewNghIndex = annotateHostElementForHydration(hostElement, rootLView, context);
  const renderer = componentLView[RENDERER];
  // For cases when a root component also acts as an anchor node for a ViewContainerRef
  // (for example, when ViewContainerRef is injected in a root component), there is a need
  // to serialize information about the component itself, as well as an LContainer that
  // represents this ViewContainerRef. Effectively, we need to serialize 2 pieces of info:
  // (1) hydration info for the root component itself and (2) hydration info for the
  // ViewContainerRef instance (an LContainer). Each piece of information is included into
  // the hydration data (in the TransferState object) separately, thus we end up with 2 ids.
  // Since we only have 1 root element, we encode both bits of info into a single string:
  // ids are separated by the `|` char (e.g. `10|25`, where `10` is the ngh for a component view
  // and 25 is the `ngh` for a root view which holds LContainer).
  const finalIndex = `${componentLViewNghIndex}|${rootLViewNghIndex}`;
  renderer.setAttribute(hostElement, NGH_ATTR_NAME, finalIndex);
}
/**
 * Annotates all components bootstrapped in a given ApplicationRef
 * with info needed for hydration.
 *
 * @param appRef An instance of an ApplicationRef.
 * @param doc A reference to the current Document instance.
 */
function annotateForHydration(appRef, doc) {
  const serializedViewCollection = new SerializedViewCollection();
  const corruptedTextNodes = new Map();
  const viewRefs = appRef._views;
  for (const viewRef of viewRefs) {
    const lNode = getLNodeForHydration(viewRef);
    // An `lView` might be `null` if a `ViewRef` represents
    // an embedded view (not a component view).
    if (lNode !== null) {
      const context = {
        serializedViewCollection,
        corruptedTextNodes
      };
      if (isLContainer(lNode)) {
        annotateLContainerForHydration(lNode, context);
      } else {
        annotateComponentLViewForHydration(lNode, context);
      }
      insertCorruptedTextNodeMarkers(corruptedTextNodes, doc);
    }
  }
  // Note: we *always* include hydration info key and a corresponding value
  // into the TransferState, even if the list of serialized views is empty.
  // This is needed as a signal to the client that the server part of the
  // hydration logic was setup and enabled correctly. Otherwise, if a client
  // hydration doesn't find a key in the transfer state - an error is produced.
  const serializedViews = serializedViewCollection.getAll();
  const transferState = appRef.injector.get(TransferState);
  transferState.set(NGH_DATA_KEY, serializedViews);
}
/**
 * Serializes the lContainer data into a list of SerializedView objects,
 * that represent views within this lContainer.
 *
 * @param lContainer the lContainer we are serializing
 * @param context the hydration context
 * @returns an array of the `SerializedView` objects
 */
function serializeLContainer(lContainer, context) {
  const views = [];
  let lastViewAsString = '';
  for (let i = CONTAINER_HEADER_OFFSET; i < lContainer.length; i++) {
    let childLView = lContainer[i];
    let template;
    let numRootNodes;
    let serializedView;
    if (isRootView(childLView)) {
      // If this is a root view, get an LView for the underlying component,
      // because it contains information about the view to serialize.
      childLView = childLView[HEADER_OFFSET];
      // If we have an LContainer at this position, this indicates that the
      // host element was used as a ViewContainerRef anchor (e.g. a `ViewContainerRef`
      // was injected within the component class). This case requires special handling.
      if (isLContainer(childLView)) {
        // Calculate the number of root nodes in all views in a given container
        // and increment by one to account for an anchor node itself, i.e. in this
        // scenario we'll have a layout that would look like this:
        // `<app-root /><#VIEW1><#VIEW2>...<!--container-->`
        // The `+1` is to capture the `<app-root />` element.
        numRootNodes = calcNumRootNodesInLContainer(childLView) + 1;
        annotateLContainerForHydration(childLView, context);
        const componentLView = unwrapLView(childLView[HOST]);
        serializedView = {
          [TEMPLATE_ID]: componentLView[TVIEW].ssrId,
          [NUM_ROOT_NODES]: numRootNodes
        };
      }
    }
    if (!serializedView) {
      const childTView = childLView[TVIEW];
      if (childTView.type === 1 /* TViewType.Component */) {
        template = childTView.ssrId;
        // This is a component view, thus it has only 1 root node: the component
        // host node itself (other nodes would be inside that host node).
        numRootNodes = 1;
      } else {
        template = getSsrId(childTView);
        numRootNodes = calcNumRootNodes(childTView, childLView, childTView.firstChild);
      }
      serializedView = {
        [TEMPLATE_ID]: template,
        [NUM_ROOT_NODES]: numRootNodes,
        ...serializeLView(lContainer[i], context)
      };
    }
    // Check if the previous view has the same shape (for example, it was
    // produced by the *ngFor), in which case bump the counter on the previous
    // view instead of including the same information again.
    const currentViewAsString = JSON.stringify(serializedView);
    if (views.length > 0 && currentViewAsString === lastViewAsString) {
      const previousView = views[views.length - 1];
      previousView[MULTIPLIER] ??= 1;
      previousView[MULTIPLIER]++;
    } else {
      // Record this view as most recently added.
      lastViewAsString = currentViewAsString;
      views.push(serializedView);
    }
  }
  return views;
}
/**
 * Helper function to produce a node path (which navigation steps runtime logic
 * needs to take to locate a node) and stores it in the `NODES` section of the
 * current serialized view.
 */
function appendSerializedNodePath(ngh, tNode, lView) {
  const noOffsetIndex = tNode.index - HEADER_OFFSET;
  ngh[NODES] ??= {};
  ngh[NODES][noOffsetIndex] = calcPathForNode(tNode, lView);
}
/**
 * Helper function to append information about a disconnected node.
 * This info is needed at runtime to avoid DOM lookups for this element
 * and instead, the element would be created from scratch.
 */
function appendDisconnectedNodeIndex(ngh, tNode) {
  const noOffsetIndex = tNode.index - HEADER_OFFSET;
  ngh[DISCONNECTED_NODES] ??= [];
  if (!ngh[DISCONNECTED_NODES].includes(noOffsetIndex)) {
    ngh[DISCONNECTED_NODES].push(noOffsetIndex);
  }
}
/**
 * Serializes the lView data into a SerializedView object that will later be added
 * to the TransferState storage and referenced using the `ngh` attribute on a host
 * element.
 *
 * @param lView the lView we are serializing
 * @param context the hydration context
 * @returns the `SerializedView` object containing the data to be added to the host node
 */
function serializeLView(lView, context) {
  const ngh = {};
  const tView = lView[TVIEW];
  // Iterate over DOM element references in an LView.
  for (let i = HEADER_OFFSET; i < tView.bindingStartIndex; i++) {
    const tNode = tView.data[i];
    const noOffsetIndex = i - HEADER_OFFSET;
    // Skip processing of a given slot in the following cases:
    // - Local refs (e.g. <div #localRef>) take up an extra slot in LViews
    //   to store the same element. In this case, there is no information in
    //   a corresponding slot in TNode data structure.
    // - When a slot contains something other than a TNode. For example, there
    //   might be some metadata information about a defer block or a control flow block.
    if (!isTNodeShape(tNode)) {
      continue;
    }
    // Check if a native node that represents a given TNode is disconnected from the DOM tree.
    // Such nodes must be excluded from the hydration (since the hydration won't be able to
    // find them), so the TNode ids are collected and used at runtime to skip the hydration.
    //
    // This situation may happen during the content projection, when some nodes don't make it
    // into one of the content projection slots (for example, when there is no default
    // <ng-content /> slot in projector component's template).
    if (isDisconnectedNode(tNode, lView) && isContentProjectedNode(tNode)) {
      appendDisconnectedNodeIndex(ngh, tNode);
      continue;
    }
    if (Array.isArray(tNode.projection)) {
      for (const projectionHeadTNode of tNode.projection) {
        // We may have `null`s in slots with no projected content.
        if (!projectionHeadTNode) continue;
        if (!Array.isArray(projectionHeadTNode)) {
          // If we process re-projected content (i.e. `<ng-content>`
          // appears at projection location), skip annotations for this content
          // since all DOM nodes in this projection were handled while processing
          // a parent lView, which contains those nodes.
          if (!isProjectionTNode(projectionHeadTNode) && !isInSkipHydrationBlock(projectionHeadTNode)) {
            if (isDisconnectedNode(projectionHeadTNode, lView)) {
              // Check whether this node is connected, since we may have a TNode
              // in the data structure as a projection segment head, but the
              // content projection slot might be disabled (e.g.
              // <ng-content *ngIf="false" />).
              appendDisconnectedNodeIndex(ngh, projectionHeadTNode);
            } else {
              appendSerializedNodePath(ngh, projectionHeadTNode, lView);
            }
          }
        } else {
          // If a value is an array, it means that we are processing a projection
          // where projectable nodes were passed in as DOM nodes (for example, when
          // calling `ViewContainerRef.createComponent(CmpA, {projectableNodes: [...]})`).
          //
          // In this scenario, nodes can come from anywhere (either created manually,
          // accessed via `document.querySelector`, etc) and may be in any state
          // (attached or detached from the DOM tree). As a result, we can not reliably
          // restore the state for such cases during hydration.
          throw unsupportedProjectionOfDomNodes(unwrapRNode(lView[i]));
        }
      }
    }
    conditionallyAnnotateNodePath(ngh, tNode, lView);
    if (isLContainer(lView[i])) {
      // Serialize information about a template.
      const embeddedTView = tNode.tView;
      if (embeddedTView !== null) {
        ngh[TEMPLATES] ??= {};
        ngh[TEMPLATES][noOffsetIndex] = getSsrId(embeddedTView);
      }
      // Serialize views within this LContainer.
      const hostNode = lView[i][HOST]; // host node of this container
      // LView[i][HOST] can be of 2 different types:
      // - either a DOM node
      // - or an array that represents an LView of a component
      if (Array.isArray(hostNode)) {
        // This is a component, serialize info about it.
        const targetNode = unwrapRNode(hostNode);
        if (!targetNode.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
          annotateHostElementForHydration(targetNode, hostNode, context);
        }
      }
      ngh[CONTAINERS] ??= {};
      ngh[CONTAINERS][noOffsetIndex] = serializeLContainer(lView[i], context);
    } else if (Array.isArray(lView[i])) {
      // This is a component, annotate the host node with an `ngh` attribute.
      const targetNode = unwrapRNode(lView[i][HOST]);
      if (!targetNode.hasAttribute(SKIP_HYDRATION_ATTR_NAME)) {
        annotateHostElementForHydration(targetNode, lView[i], context);
      }
    } else {
      // <ng-container> case
      if (tNode.type & 8 /* TNodeType.ElementContainer */) {
        // An <ng-container> is represented by the number of
        // top-level nodes. This information is needed to skip over
        // those nodes to reach a corresponding anchor node (comment node).
        ngh[ELEMENT_CONTAINERS] ??= {};
        ngh[ELEMENT_CONTAINERS][noOffsetIndex] = calcNumRootNodes(tView, lView, tNode.child);
      } else if (tNode.type & 16 /* TNodeType.Projection */) {
        // Current TNode represents an `<ng-content>` slot, thus it has no
        // DOM elements associated with it, so the **next sibling** node would
        // not be able to find an anchor. In this case, use full path instead.
        let nextTNode = tNode.next;
        // Skip over all `<ng-content>` slots in a row.
        while (nextTNode !== null && nextTNode.type & 16 /* TNodeType.Projection */) {
          nextTNode = nextTNode.next;
        }
        if (nextTNode && !isInSkipHydrationBlock(nextTNode)) {
          // Handle a tNode after the `<ng-content>` slot.
          appendSerializedNodePath(ngh, nextTNode, lView);
        }
      } else {
        // Handle cases where text nodes can be lost after DOM serialization:
        //  1. When there is an *empty text node* in DOM: in this case, this
        //     node would not make it into the serialized string and as a result,
        //     this node wouldn't be created in a browser. This would result in
        //     a mismatch during the hydration, where the runtime logic would expect
        //     a text node to be present in live DOM, but no text node would exist.
        //     Example: `<span>{{ name }}</span>` when the `name` is an empty string.
        //     This would result in `<span></span>` string after serialization and
        //     in a browser only the `span` element would be created. To resolve that,
        //     an extra comment node is appended in place of an empty text node and
        //     that special comment node is replaced with an empty text node *before*
        //     hydration.
        //  2. When there are 2 consecutive text nodes present in the DOM.
        //     Example: `<div>Hello <ng-container *ngIf="true">world</ng-container></div>`.
        //     In this scenario, the live DOM would look like this:
        //       <div>#text('Hello ') #text('world') #comment('container')</div>
        //     Serialized string would look like this: `<div>Hello world<!--container--></div>`.
        //     The live DOM in a browser after that would be:
        //       <div>#text('Hello world') #comment('container')</div>
        //     Notice how 2 text nodes are now "merged" into one. This would cause hydration
        //     logic to fail, since it'd expect 2 text nodes being present, not one.
        //     To fix this, we insert a special comment node in between those text nodes, so
        //     serialized representation is: `<div>Hello <!--ngtns-->world<!--container--></div>`.
        //     This forces browser to create 2 text nodes separated by a comment node.
        //     Before running a hydration process, this special comment node is removed, so the
        //     live DOM has exactly the same state as it was before serialization.
        if (tNode.type & 1 /* TNodeType.Text */) {
          const rNode = unwrapRNode(lView[i]);
          // Collect this node as required special annotation only when its
          // contents is empty. Otherwise, such text node would be present on
          // the client after server-side rendering and no special handling needed.
          if (rNode.textContent === '') {
            context.corruptedTextNodes.set(rNode, "ngetn" /* TextNodeMarker.EmptyNode */);
          } else if (rNode.nextSibling?.nodeType === Node.TEXT_NODE) {
            context.corruptedTextNodes.set(rNode, "ngtns" /* TextNodeMarker.Separator */);
          }
        }
      }
    }
  }
  return ngh;
}
/**
 * Serializes node location in cases when it's needed, specifically:
 *
 *  1. If `tNode.projectionNext` is different from `tNode.next` - it means that
 *     the next `tNode` after projection is different from the one in the original
 *     template. Since hydration relies on `tNode.next`, this serialized info
 *     if required to help runtime code find the node at the correct location.
 *  2. In certain content projection-based use-cases, it's possible that only
 *     a content of a projected element is rendered. In this case, content nodes
 *     require an extra annotation, since runtime logic can't rely on parent-child
 *     connection to identify the location of a node.
 */
function conditionallyAnnotateNodePath(ngh, tNode, lView) {
  // Handle case #1 described above.
  if (tNode.projectionNext && tNode.projectionNext !== tNode.next && !isInSkipHydrationBlock(tNode.projectionNext)) {
    appendSerializedNodePath(ngh, tNode.projectionNext, lView);
  }
  // Handle case #2 described above.
  // Note: we only do that for the first node (i.e. when `tNode.prev === null`),
  // the rest of the nodes would rely on the current node location, so no extra
  // annotation is needed.
  if (tNode.prev === null && tNode.parent !== null && isDisconnectedNode(tNode.parent, lView) && !isDisconnectedNode(tNode, lView)) {
    appendSerializedNodePath(ngh, tNode, lView);
  }
}
/**
 * Determines whether a component instance that is represented
 * by a given LView uses `ViewEncapsulation.ShadowDom`.
 */
function componentUsesShadowDomEncapsulation(lView) {
  const instance = lView[CONTEXT];
  return instance?.constructor ? getComponentDef(instance.constructor)?.encapsulation === ViewEncapsulation$1.ShadowDom : false;
}
/**
 * Annotates component host element for hydration:
 * - by either adding the `ngh` attribute and collecting hydration-related info
 *   for the serialization and transferring to the client
 * - or by adding the `ngSkipHydration` attribute in case Angular detects that
 *   component contents is not compatible with hydration.
 *
 * @param element The Host element to be annotated
 * @param lView The associated LView
 * @param context The hydration context
 * @returns An index of serialized view from the transfer state object
 *          or `null` when a given component can not be serialized.
 */
function annotateHostElementForHydration(element, lView, context) {
  const renderer = lView[RENDERER];
  if (hasI18n(lView) && !isI18nHydrationSupportEnabled() || componentUsesShadowDomEncapsulation(lView)) {
    // Attach the skip hydration attribute if this component:
    // - either has i18n blocks, since hydrating such blocks is not yet supported
    // - or uses ShadowDom view encapsulation, since Domino doesn't support
    //   shadow DOM, so we can not guarantee that client and server representations
    //   would exactly match
    renderer.setAttribute(element, SKIP_HYDRATION_ATTR_NAME, '');
    return null;
  } else {
    const ngh = serializeLView(lView, context);
    const index = context.serializedViewCollection.add(ngh);
    renderer.setAttribute(element, NGH_ATTR_NAME, index.toString());
    return index;
  }
}
/**
 * Physically inserts the comment nodes to ensure empty text nodes and adjacent
 * text node separators are preserved after server serialization of the DOM.
 * These get swapped back for empty text nodes or separators once hydration happens
 * on the client.
 *
 * @param corruptedTextNodes The Map of text nodes to be replaced with comments
 * @param doc The document
 */
function insertCorruptedTextNodeMarkers(corruptedTextNodes, doc) {
  for (const [textNode, marker] of corruptedTextNodes) {
    textNode.after(doc.createComment(marker));
  }
}
/**
 * Detects whether a given TNode represents a node that
 * is being content projected.
 */
function isContentProjectedNode(tNode) {
  let currentTNode = tNode;
  while (currentTNode != null) {
    // If we come across a component host node in parent nodes -
    // this TNode is in the content projection section.
    if (isComponentHost(currentTNode)) {
      return true;
    }
    currentTNode = currentTNode.parent;
  }
  return false;
}

/**
 * Queue a state update to be performed asynchronously.
 *
 * This is useful to safely update application state that is used in an expression that was already
 * checked during change detection. This defers the update until later and prevents
 * `ExpressionChangedAfterItHasBeenChecked` errors. Using signals for state is recommended instead,
 * but it's not always immediately possible to change the state to a signal because it would be a
 * breaking change. When the callback updates state used in an expression, this needs to be
 * accompanied by an explicit notification to the framework that something has changed (i.e.
 * updating a signal or calling `ChangeDetectorRef.markForCheck()`) or may still cause
 * `ExpressionChangedAfterItHasBeenChecked` in dev mode or fail to synchronize the state to the DOM
 * in production.
 */
function queueStateUpdate(callback, options) {
  !options && assertInInjectionContext(queueStateUpdate);
  const injector = options?.injector ?? inject(Injector);
  const appRef = injector.get(ApplicationRef);
  let executed = false;
  const runCallbackOnce = () => {
    if (executed || appRef.destroyed) return;
    executed = true;
    callback();
  };
  internalAfterNextRender(runCallbackOnce, {
    injector,
    runOnServer: true
  });
  queueMicrotask(runCallbackOnce);
}

/**
 * Transforms a value (typically a string) to a boolean.
 * Intended to be used as a transform function of an input.
 *
 *  @usageNotes
 *  ```typescript
 *  @Input({ transform: booleanAttribute }) status!: boolean;
 *  ```
 * @param value Value to be transformed.
 *
 * @publicApi
 */
function booleanAttribute(value) {
  return typeof value === 'boolean' ? value : value != null && value !== 'false';
}
/**
 * Transforms a value (typically a string) to a number.
 * Intended to be used as a transform function of an input.
 * @param value Value to be transformed.
 * @param fallbackValue Value to use if the provided value can't be parsed as a number.
 *
 *  @usageNotes
 *  ```typescript
 *  @Input({ transform: numberAttribute }) id!: number;
 *  ```
 *
 * @publicApi
 */
function numberAttribute(value, fallbackValue = NaN) {
  // parseFloat(value) handles most of the cases we're interested in (it treats null, empty string,
  // and other non-number values as NaN, where Number just uses 0) but it considers the string
  // '123hello' to be a valid number. Therefore we also check if Number(value) is NaN.
  const isNumberValue = !isNaN(parseFloat(value)) && !isNaN(Number(value));
  return isNumberValue ? Number(value) : fallbackValue;
}

/**
 * Compiles a partial directive declaration object into a full directive definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareDirective(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'directive',
    type: decl.type
  });
  return compiler.compileDirectiveDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
}
/**
 * Evaluates the class metadata declaration.
 *
 * @codeGenApi
 */
function ɵɵngDeclareClassMetadata(decl) {
  setClassMetadata(decl.type, decl.decorators, decl.ctorParameters ?? null, decl.propDecorators ?? null);
}
/**
 * Compiles a partial component declaration object into a full component definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareComponent(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'component',
    type: decl.type
  });
  return compiler.compileComponentDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵcmp.js`, decl);
}
/**
 * Compiles a partial pipe declaration object into a full pipe definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareFactory(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: getFactoryKind(decl.target),
    type: decl.type
  });
  return compiler.compileFactoryDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵfac.js`, decl);
}
function getFactoryKind(target) {
  switch (target) {
    case FactoryTarget.Directive:
      return 'directive';
    case FactoryTarget.Component:
      return 'component';
    case FactoryTarget.Injectable:
      return 'injectable';
    case FactoryTarget.Pipe:
      return 'pipe';
    case FactoryTarget.NgModule:
      return 'NgModule';
  }
}
/**
 * Compiles a partial injectable declaration object into a full injectable definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareInjectable(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'injectable',
    type: decl.type
  });
  return compiler.compileInjectableDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵprov.js`, decl);
}
/**
 * Compiles a partial injector declaration object into a full injector definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareInjector(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'NgModule',
    type: decl.type
  });
  return compiler.compileInjectorDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵinj.js`, decl);
}
/**
 * Compiles a partial NgModule declaration object into a full NgModule definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclareNgModule(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'NgModule',
    type: decl.type
  });
  return compiler.compileNgModuleDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵmod.js`, decl);
}
/**
 * Compiles a partial pipe declaration object into a full pipe definition object.
 *
 * @codeGenApi
 */
function ɵɵngDeclarePipe(decl) {
  const compiler = getCompilerFacade({
    usage: 1 /* JitCompilerUsage.PartialDeclaration */,
    kind: 'pipe',
    type: decl.type
  });
  return compiler.compilePipeDeclaration(angularCoreEnv, `ng:///${decl.type.name}/ɵpipe.js`, decl);
}

// clang-format off
// clang-format on

/**
 * Create a computed `Signal` which derives a reactive value from an expression.
 */
function computed(computation, options) {
  performanceMarkFeature('NgSignals');
  const getter = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.createComputed)(computation);
  if (options?.equal) {
    getter[_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.SIGNAL].equal = options.equal;
  }
  if (ngDevMode) {
    getter.toString = () => `[Computed: ${getter()}]`;
  }
  return getter;
}

/**
 * Execute an arbitrary function in a non-reactive (non-tracking) context. The executed function
 * can, optionally, return a value.
 */
function untracked(nonReactiveReadsFn) {
  const prevConsumer = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(null);
  // We are not trying to catch any particular errors here, just making sure that the consumers
  // stack is restored in case of errors.
  try {
    return nonReactiveReadsFn();
  } finally {
    (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.setActiveConsumer)(prevConsumer);
  }
}

/**
 * Not public API, which guarantees `EffectScheduler` only ever comes from the application root
 * injector.
 */
const APP_EFFECT_SCHEDULER = new InjectionToken('', {
  providedIn: 'root',
  factory: () => inject(EffectScheduler)
});
/**
 * A scheduler which manages the execution of effects.
 */
class EffectScheduler {
  /** @nocollapse */
  static {
    this.ɵprov = ɵɵdefineInjectable({
      token: EffectScheduler,
      providedIn: 'root',
      factory: () => new ZoneAwareEffectScheduler()
    });
  }
}
/**
 * A wrapper around `ZoneAwareQueueingScheduler` that schedules flushing via the microtask queue
 * when.
 */
class ZoneAwareEffectScheduler {
  constructor() {
    this.queuedEffectCount = 0;
    this.queues = new Map();
    this.pendingTasks = inject(PendingTasks);
    this.taskId = null;
  }
  scheduleEffect(handle) {
    this.enqueue(handle);
    if (this.taskId === null) {
      const taskId = this.taskId = this.pendingTasks.add();
      queueMicrotask(() => {
        this.flush();
        this.pendingTasks.remove(taskId);
        this.taskId = null;
      });
    }
  }
  enqueue(handle) {
    const zone = handle.creationZone;
    if (!this.queues.has(zone)) {
      this.queues.set(zone, new Set());
    }
    const queue = this.queues.get(zone);
    if (queue.has(handle)) {
      return;
    }
    this.queuedEffectCount++;
    queue.add(handle);
  }
  /**
   * Run all scheduled effects.
   *
   * Execution order of effects within the same zone is guaranteed to be FIFO, but there is no
   * ordering guarantee between effects scheduled in different zones.
   */
  flush() {
    while (this.queuedEffectCount > 0) {
      for (const [zone, queue] of this.queues) {
        // `zone` here must be defined.
        if (zone === null) {
          this.flushQueue(queue);
        } else {
          zone.run(() => this.flushQueue(queue));
        }
      }
    }
  }
  flushQueue(queue) {
    for (const handle of queue) {
      queue.delete(handle);
      this.queuedEffectCount--;
      // TODO: what happens if this throws an error?
      handle.run();
    }
  }
}
/**
 * Core reactive node for an Angular effect.
 *
 * `EffectHandle` combines the reactive graph's `Watch` base node for effects with the framework's
 * scheduling abstraction (`EffectScheduler`) as well as automatic cleanup via `DestroyRef` if
 * available/requested.
 */
class EffectHandle {
  constructor(scheduler, effectFn, creationZone, destroyRef, injector, allowSignalWrites) {
    this.scheduler = scheduler;
    this.effectFn = effectFn;
    this.creationZone = creationZone;
    this.injector = injector;
    this.watcher = (0,_angular_core_primitives_signals__WEBPACK_IMPORTED_MODULE_1__.createWatch)(onCleanup => this.runEffect(onCleanup), () => this.schedule(), allowSignalWrites);
    this.unregisterOnDestroy = destroyRef?.onDestroy(() => this.destroy());
  }
  runEffect(onCleanup) {
    try {
      this.effectFn(onCleanup);
    } catch (err) {
      // Inject the `ErrorHandler` here in order to avoid circular DI error
      // if the effect is used inside of a custom `ErrorHandler`.
      const errorHandler = this.injector.get(ErrorHandler, null, {
        optional: true
      });
      errorHandler?.handleError(err);
    }
  }
  run() {
    this.watcher.run();
  }
  schedule() {
    this.scheduler.scheduleEffect(this);
  }
  destroy() {
    this.watcher.destroy();
    this.unregisterOnDestroy?.();
    // Note: if the effect is currently scheduled, it's not un-scheduled, and so the scheduler will
    // retain a reference to it. Attempting to execute it will be a no-op.
  }
}
/**
 * Create a global `Effect` for the given reactive function.
 *
 * @developerPreview
 */
function effect(effectFn, options) {
  performanceMarkFeature('NgSignals');
  ngDevMode && assertNotInReactiveContext(effect, 'Call `effect` outside of a reactive context. For example, schedule the ' + 'effect inside the component constructor.');
  !options?.injector && assertInInjectionContext(effect);
  const injector = options?.injector ?? inject(Injector);
  const destroyRef = options?.manualCleanup !== true ? injector.get(DestroyRef) : null;
  const handle = new EffectHandle(injector.get(APP_EFFECT_SCHEDULER), effectFn, typeof Zone === 'undefined' ? null : Zone.current, destroyRef, injector, options?.allowSignalWrites ?? false);
  // Effects need to be marked dirty manually to trigger their initial run. The timing of this
  // marking matters, because the effects may read signals that track component inputs, which are
  // only available after those components have had their first update pass.
  //
  // We inject `ChangeDetectorRef` optionally, to determine whether this effect is being created in
  // the context of a component or not. If it is, then we check whether the component has already
  // run its update pass, and defer the effect's initial scheduling until the update pass if it
  // hasn't already run.
  const cdr = injector.get(ChangeDetectorRef, null, {
    optional: true
  });
  if (!cdr || !(cdr._lView[FLAGS] & 8 /* LViewFlags.FirstLViewPass */)) {
    // This effect is either not running in a view injector, or the view has already
    // undergone its first change detection pass, which is necessary for any required inputs to be
    // set.
    handle.watcher.notify();
  } else {
    // Delay the initialization of the effect until the view is fully initialized.
    (cdr._lView[EFFECTS_TO_SCHEDULE] ??= []).push(handle.watcher.notify);
  }
  return handle;
}

// clang-format off
// clang-format on

// This file exists to allow the set of reactivity exports to be modified in g3, as these APIs are

/**
 * Creates a `ComponentRef` instance based on provided component type and a set of options.
 *
 * @usageNotes
 *
 * The example below demonstrates how the `createComponent` function can be used
 * to create an instance of a ComponentRef dynamically and attach it to an ApplicationRef,
 * so that it gets included into change detection cycles.
 *
 * Note: the example uses standalone components, but the function can also be used for
 * non-standalone components (declared in an NgModule) as well.
 *
 * ```typescript
 * @Component({
 *   standalone: true,
 *   template: `Hello {{ name }}!`
 * })
 * class HelloComponent {
 *   name = 'Angular';
 * }
 *
 * @Component({
 *   standalone: true,
 *   template: `<div id="hello-component-host"></div>`
 * })
 * class RootComponent {}
 *
 * // Bootstrap an application.
 * const applicationRef = await bootstrapApplication(RootComponent);
 *
 * // Locate a DOM node that would be used as a host.
 * const hostElement = document.getElementById('hello-component-host');
 *
 * // Get an `EnvironmentInjector` instance from the `ApplicationRef`.
 * const environmentInjector = applicationRef.injector;
 *
 * // We can now create a `ComponentRef` instance.
 * const componentRef = createComponent(HelloComponent, {hostElement, environmentInjector});
 *
 * // Last step is to register the newly created ref using the `ApplicationRef` instance
 * // to include the component view into change detection cycles.
 * applicationRef.attachView(componentRef.hostView);
 * componentRef.changeDetectorRef.detectChanges();
 * ```
 *
 * @param component Component class reference.
 * @param options Set of options to use:
 *  * `environmentInjector`: An `EnvironmentInjector` instance to be used for the component, see
 * additional info about it [here](/guide/standalone-components#environment-injectors).
 *  * `hostElement` (optional): A DOM node that should act as a host node for the component. If not
 * provided, Angular creates one based on the tag name used in the component selector (and falls
 * back to using `div` if selector doesn't have tag name info).
 *  * `elementInjector` (optional): An `ElementInjector` instance, see additional info about it
 * [here](/guide/hierarchical-dependency-injection#elementinjector).
 *  * `projectableNodes` (optional): A list of DOM nodes that should be projected through
 *                      [`<ng-content>`](api/core/ng-content) of the new component instance.
 * @returns ComponentRef instance that represents a given Component.
 *
 * @publicApi
 */
function createComponent(component, options) {
  ngDevMode && assertComponentDef(component);
  const componentDef = getComponentDef(component);
  const elementInjector = options.elementInjector || getNullInjector();
  const factory = new ComponentFactory(componentDef);
  return factory.create(elementInjector, options.projectableNodes, options.hostElement, options.environmentInjector);
}
/**
 * Creates an object that allows to retrieve component metadata.
 *
 * @usageNotes
 *
 * The example below demonstrates how to use the function and how the fields
 * of the returned object map to the component metadata.
 *
 * ```typescript
 * @Component({
 *   standalone: true,
 *   selector: 'foo-component',
 *   template: `
 *     <ng-content></ng-content>
 *     <ng-content select="content-selector-a"></ng-content>
 *   `,
 * })
 * class FooComponent {
 *   @Input('inputName') inputPropName: string;
 *   @Output('outputName') outputPropName = new EventEmitter<void>();
 * }
 *
 * const mirror = reflectComponentType(FooComponent);
 * expect(mirror.type).toBe(FooComponent);
 * expect(mirror.selector).toBe('foo-component');
 * expect(mirror.isStandalone).toBe(true);
 * expect(mirror.inputs).toEqual([{propName: 'inputName', templateName: 'inputPropName'}]);
 * expect(mirror.outputs).toEqual([{propName: 'outputName', templateName: 'outputPropName'}]);
 * expect(mirror.ngContentSelectors).toEqual([
 *   '*',                 // first `<ng-content>` in a template, the selector defaults to `*`
 *   'content-selector-a' // second `<ng-content>` in a template
 * ]);
 * ```
 *
 * @param component Component class reference.
 * @returns An object that allows to retrieve component metadata.
 *
 * @publicApi
 */
function reflectComponentType(component) {
  const componentDef = getComponentDef(component);
  if (!componentDef) return null;
  const factory = new ComponentFactory(componentDef);
  return {
    get selector() {
      return factory.selector;
    },
    get type() {
      return factory.componentType;
    },
    get inputs() {
      return factory.inputs;
    },
    get outputs() {
      return factory.outputs;
    },
    get ngContentSelectors() {
      return factory.ngContentSelectors;
    },
    get isStandalone() {
      return componentDef.standalone;
    },
    get isSignal() {
      return componentDef.signals;
    }
  };
}

/**
 * Merge multiple application configurations from left to right.
 *
 * @param configs Two or more configurations to be merged.
 * @returns A merged [ApplicationConfig](api/core/ApplicationConfig).
 *
 * @publicApi
 */
function mergeApplicationConfig(...configs) {
  return configs.reduce((prev, curr) => {
    return Object.assign(prev, curr, {
      providers: [...prev.providers, ...curr.providers]
    });
  }, {
    providers: []
  });
}

/**
 * @module
 * @description
 * Entry point from which you should import all public core APIs.
 */
if (typeof ngDevMode !== 'undefined' && ngDevMode) {
  // This helper is to give a reasonable error message to people upgrading to v9 that have not yet
  // installed `@angular/localize` in their app.
  // tslint:disable-next-line: no-toplevel-property-access
  _global.$localize ??= function () {
    throw new Error('It looks like your application or one of its dependencies is using i18n.\n' + 'Angular 9 introduced a global `$localize()` function that needs to be loaded.\n' + 'Please run `ng add @angular/localize` from the Angular CLI.\n' + '(For non-CLI projects, add `import \'@angular/localize/init\';` to your `polyfills.ts` file.\n' + 'For server-side rendering applications add the import to your `main.server.ts` file.)');
  };
}

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */
// This file only reexports content of the `src` folder. Keep it that way.

/* This file is not used to build this module. It is only used during editing
 * by the TypeScript language service and during build for verification. `ngc`
 * replaces this file with production index.ts when it rewrites private symbol
 * names.
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 85689:
/*!********************************************************************!*\
  !*** ./node_modules/@angular/core/fesm2022/primitives/signals.mjs ***!
  \********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   REACTIVE_NODE: () => (/* binding */ REACTIVE_NODE),
/* harmony export */   SIGNAL: () => (/* binding */ SIGNAL),
/* harmony export */   SIGNAL_NODE: () => (/* binding */ SIGNAL_NODE),
/* harmony export */   consumerAfterComputation: () => (/* binding */ consumerAfterComputation),
/* harmony export */   consumerBeforeComputation: () => (/* binding */ consumerBeforeComputation),
/* harmony export */   consumerDestroy: () => (/* binding */ consumerDestroy),
/* harmony export */   consumerMarkDirty: () => (/* binding */ consumerMarkDirty),
/* harmony export */   consumerPollProducersForChange: () => (/* binding */ consumerPollProducersForChange),
/* harmony export */   createComputed: () => (/* binding */ createComputed),
/* harmony export */   createSignal: () => (/* binding */ createSignal),
/* harmony export */   createWatch: () => (/* binding */ createWatch),
/* harmony export */   defaultEquals: () => (/* binding */ defaultEquals),
/* harmony export */   getActiveConsumer: () => (/* binding */ getActiveConsumer),
/* harmony export */   isInNotificationPhase: () => (/* binding */ isInNotificationPhase),
/* harmony export */   isReactive: () => (/* binding */ isReactive),
/* harmony export */   producerAccessed: () => (/* binding */ producerAccessed),
/* harmony export */   producerNotifyConsumers: () => (/* binding */ producerNotifyConsumers),
/* harmony export */   producerUpdateValueVersion: () => (/* binding */ producerUpdateValueVersion),
/* harmony export */   producerUpdatesAllowed: () => (/* binding */ producerUpdatesAllowed),
/* harmony export */   setActiveConsumer: () => (/* binding */ setActiveConsumer),
/* harmony export */   setAlternateWeakRefImpl: () => (/* binding */ setAlternateWeakRefImpl),
/* harmony export */   setPostSignalSetFn: () => (/* binding */ setPostSignalSetFn),
/* harmony export */   setThrowInvalidWriteToSignalError: () => (/* binding */ setThrowInvalidWriteToSignalError),
/* harmony export */   signalSetFn: () => (/* binding */ signalSetFn),
/* harmony export */   signalUpdateFn: () => (/* binding */ signalUpdateFn)
/* harmony export */ });
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */

/**
 * The default equality function used for `signal` and `computed`, which uses referential equality.
 */
function defaultEquals(a, b) {
  return Object.is(a, b);
}

/**
 * The currently active consumer `ReactiveNode`, if running code in a reactive context.
 *
 * Change this via `setActiveConsumer`.
 */
let activeConsumer = null;
let inNotificationPhase = false;
/**
 * Global epoch counter. Incremented whenever a source signal is set.
 */
let epoch = 1;
/**
 * Symbol used to tell `Signal`s apart from other functions.
 *
 * This can be used to auto-unwrap signals in various cases, or to auto-wrap non-signal values.
 */
const SIGNAL = /* @__PURE__ */Symbol('SIGNAL');
function setActiveConsumer(consumer) {
  const prev = activeConsumer;
  activeConsumer = consumer;
  return prev;
}
function getActiveConsumer() {
  return activeConsumer;
}
function isInNotificationPhase() {
  return inNotificationPhase;
}
function isReactive(value) {
  return value[SIGNAL] !== undefined;
}
const REACTIVE_NODE = {
  version: 0,
  lastCleanEpoch: 0,
  dirty: false,
  producerNode: undefined,
  producerLastReadVersion: undefined,
  producerIndexOfThis: undefined,
  nextProducerIndex: 0,
  liveConsumerNode: undefined,
  liveConsumerIndexOfThis: undefined,
  consumerAllowSignalWrites: false,
  consumerIsAlwaysLive: false,
  producerMustRecompute: () => false,
  producerRecomputeValue: () => {},
  consumerMarkedDirty: () => {},
  consumerOnSignalRead: () => {}
};
/**
 * Called by implementations when a producer's signal is read.
 */
function producerAccessed(node) {
  if (inNotificationPhase) {
    throw new Error(typeof ngDevMode !== 'undefined' && ngDevMode ? `Assertion error: signal read during notification phase` : '');
  }
  if (activeConsumer === null) {
    // Accessed outside of a reactive context, so nothing to record.
    return;
  }
  activeConsumer.consumerOnSignalRead(node);
  // This producer is the `idx`th dependency of `activeConsumer`.
  const idx = activeConsumer.nextProducerIndex++;
  assertConsumerNode(activeConsumer);
  if (idx < activeConsumer.producerNode.length && activeConsumer.producerNode[idx] !== node) {
    // There's been a change in producers since the last execution of `activeConsumer`.
    // `activeConsumer.producerNode[idx]` holds a stale dependency which will be be removed and
    // replaced with `this`.
    //
    // If `activeConsumer` isn't live, then this is a no-op, since we can replace the producer in
    // `activeConsumer.producerNode` directly. However, if `activeConsumer` is live, then we need
    // to remove it from the stale producer's `liveConsumer`s.
    if (consumerIsLive(activeConsumer)) {
      const staleProducer = activeConsumer.producerNode[idx];
      producerRemoveLiveConsumerAtIndex(staleProducer, activeConsumer.producerIndexOfThis[idx]);
      // At this point, the only record of `staleProducer` is the reference at
      // `activeConsumer.producerNode[idx]` which will be overwritten below.
    }
  }
  if (activeConsumer.producerNode[idx] !== node) {
    // We're a new dependency of the consumer (at `idx`).
    activeConsumer.producerNode[idx] = node;
    // If the active consumer is live, then add it as a live consumer. If not, then use 0 as a
    // placeholder value.
    activeConsumer.producerIndexOfThis[idx] = consumerIsLive(activeConsumer) ? producerAddLiveConsumer(node, activeConsumer, idx) : 0;
  }
  activeConsumer.producerLastReadVersion[idx] = node.version;
}
/**
 * Increment the global epoch counter.
 *
 * Called by source producers (that is, not computeds) whenever their values change.
 */
function producerIncrementEpoch() {
  epoch++;
}
/**
 * Ensure this producer's `version` is up-to-date.
 */
function producerUpdateValueVersion(node) {
  if (consumerIsLive(node) && !node.dirty) {
    // A live consumer will be marked dirty by producers, so a clean state means that its version
    // is guaranteed to be up-to-date.
    return;
  }
  if (!node.dirty && node.lastCleanEpoch === epoch) {
    // Even non-live consumers can skip polling if they previously found themselves to be clean at
    // the current epoch, since their dependencies could not possibly have changed (such a change
    // would've increased the epoch).
    return;
  }
  if (!node.producerMustRecompute(node) && !consumerPollProducersForChange(node)) {
    // None of our producers report a change since the last time they were read, so no
    // recomputation of our value is necessary, and we can consider ourselves clean.
    node.dirty = false;
    node.lastCleanEpoch = epoch;
    return;
  }
  node.producerRecomputeValue(node);
  // After recomputing the value, we're no longer dirty.
  node.dirty = false;
  node.lastCleanEpoch = epoch;
}
/**
 * Propagate a dirty notification to live consumers of this producer.
 */
function producerNotifyConsumers(node) {
  if (node.liveConsumerNode === undefined) {
    return;
  }
  // Prevent signal reads when we're updating the graph
  const prev = inNotificationPhase;
  inNotificationPhase = true;
  try {
    for (const consumer of node.liveConsumerNode) {
      if (!consumer.dirty) {
        consumerMarkDirty(consumer);
      }
    }
  } finally {
    inNotificationPhase = prev;
  }
}
/**
 * Whether this `ReactiveNode` in its producer capacity is currently allowed to initiate updates,
 * based on the current consumer context.
 */
function producerUpdatesAllowed() {
  return activeConsumer?.consumerAllowSignalWrites !== false;
}
function consumerMarkDirty(node) {
  node.dirty = true;
  producerNotifyConsumers(node);
  node.consumerMarkedDirty?.(node);
}
/**
 * Prepare this consumer to run a computation in its reactive context.
 *
 * Must be called by subclasses which represent reactive computations, before those computations
 * begin.
 */
function consumerBeforeComputation(node) {
  node && (node.nextProducerIndex = 0);
  return setActiveConsumer(node);
}
/**
 * Finalize this consumer's state after a reactive computation has run.
 *
 * Must be called by subclasses which represent reactive computations, after those computations
 * have finished.
 */
function consumerAfterComputation(node, prevConsumer) {
  setActiveConsumer(prevConsumer);
  if (!node || node.producerNode === undefined || node.producerIndexOfThis === undefined || node.producerLastReadVersion === undefined) {
    return;
  }
  if (consumerIsLive(node)) {
    // For live consumers, we need to remove the producer -> consumer edge for any stale producers
    // which weren't dependencies after the recomputation.
    for (let i = node.nextProducerIndex; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Truncate the producer tracking arrays.
  // Perf note: this is essentially truncating the length to `node.nextProducerIndex`, but
  // benchmarking has shown that individual pop operations are faster.
  while (node.producerNode.length > node.nextProducerIndex) {
    node.producerNode.pop();
    node.producerLastReadVersion.pop();
    node.producerIndexOfThis.pop();
  }
}
/**
 * Determine whether this consumer has any dependencies which have changed since the last time
 * they were read.
 */
function consumerPollProducersForChange(node) {
  assertConsumerNode(node);
  // Poll producers for change.
  for (let i = 0; i < node.producerNode.length; i++) {
    const producer = node.producerNode[i];
    const seenVersion = node.producerLastReadVersion[i];
    // First check the versions. A mismatch means that the producer's value is known to have
    // changed since the last time we read it.
    if (seenVersion !== producer.version) {
      return true;
    }
    // The producer's version is the same as the last time we read it, but it might itself be
    // stale. Force the producer to recompute its version (calculating a new value if necessary).
    producerUpdateValueVersion(producer);
    // Now when we do this check, `producer.version` is guaranteed to be up to date, so if the
    // versions still match then it has not changed since the last time we read it.
    if (seenVersion !== producer.version) {
      return true;
    }
  }
  return false;
}
/**
 * Disconnect this consumer from the graph.
 */
function consumerDestroy(node) {
  assertConsumerNode(node);
  if (consumerIsLive(node)) {
    // Drop all connections from the graph to this node.
    for (let i = 0; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Truncate all the arrays to drop all connection from this node to the graph.
  node.producerNode.length = node.producerLastReadVersion.length = node.producerIndexOfThis.length = 0;
  if (node.liveConsumerNode) {
    node.liveConsumerNode.length = node.liveConsumerIndexOfThis.length = 0;
  }
}
/**
 * Add `consumer` as a live consumer of this node.
 *
 * Note that this operation is potentially transitive. If this node becomes live, then it becomes
 * a live consumer of all of its current producers.
 */
function producerAddLiveConsumer(node, consumer, indexOfThis) {
  assertProducerNode(node);
  assertConsumerNode(node);
  if (node.liveConsumerNode.length === 0) {
    // When going from 0 to 1 live consumers, we become a live consumer to our producers.
    for (let i = 0; i < node.producerNode.length; i++) {
      node.producerIndexOfThis[i] = producerAddLiveConsumer(node.producerNode[i], node, i);
    }
  }
  node.liveConsumerIndexOfThis.push(indexOfThis);
  return node.liveConsumerNode.push(consumer) - 1;
}
/**
 * Remove the live consumer at `idx`.
 */
function producerRemoveLiveConsumerAtIndex(node, idx) {
  assertProducerNode(node);
  assertConsumerNode(node);
  if (typeof ngDevMode !== 'undefined' && ngDevMode && idx >= node.liveConsumerNode.length) {
    throw new Error(`Assertion error: active consumer index ${idx} is out of bounds of ${node.liveConsumerNode.length} consumers)`);
  }
  if (node.liveConsumerNode.length === 1) {
    // When removing the last live consumer, we will no longer be live. We need to remove
    // ourselves from our producers' tracking (which may cause consumer-producers to lose
    // liveness as well).
    for (let i = 0; i < node.producerNode.length; i++) {
      producerRemoveLiveConsumerAtIndex(node.producerNode[i], node.producerIndexOfThis[i]);
    }
  }
  // Move the last value of `liveConsumers` into `idx`. Note that if there's only a single
  // live consumer, this is a no-op.
  const lastIdx = node.liveConsumerNode.length - 1;
  node.liveConsumerNode[idx] = node.liveConsumerNode[lastIdx];
  node.liveConsumerIndexOfThis[idx] = node.liveConsumerIndexOfThis[lastIdx];
  // Truncate the array.
  node.liveConsumerNode.length--;
  node.liveConsumerIndexOfThis.length--;
  // If the index is still valid, then we need to fix the index pointer from the producer to this
  // consumer, and update it from `lastIdx` to `idx` (accounting for the move above).
  if (idx < node.liveConsumerNode.length) {
    const idxProducer = node.liveConsumerIndexOfThis[idx];
    const consumer = node.liveConsumerNode[idx];
    assertConsumerNode(consumer);
    consumer.producerIndexOfThis[idxProducer] = idx;
  }
}
function consumerIsLive(node) {
  return node.consumerIsAlwaysLive || (node?.liveConsumerNode?.length ?? 0) > 0;
}
function assertConsumerNode(node) {
  node.producerNode ??= [];
  node.producerIndexOfThis ??= [];
  node.producerLastReadVersion ??= [];
}
function assertProducerNode(node) {
  node.liveConsumerNode ??= [];
  node.liveConsumerIndexOfThis ??= [];
}

/**
 * Create a computed signal which derives a reactive value from an expression.
 */
function createComputed(computation) {
  const node = Object.create(COMPUTED_NODE);
  node.computation = computation;
  const computed = () => {
    // Check if the value needs updating before returning it.
    producerUpdateValueVersion(node);
    // Record that someone looked at this signal.
    producerAccessed(node);
    if (node.value === ERRORED) {
      throw node.error;
    }
    return node.value;
  };
  computed[SIGNAL] = node;
  return computed;
}
/**
 * A dedicated symbol used before a computed value has been calculated for the first time.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const UNSET = /* @__PURE__ */Symbol('UNSET');
/**
 * A dedicated symbol used in place of a computed signal value to indicate that a given computation
 * is in progress. Used to detect cycles in computation chains.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const COMPUTING = /* @__PURE__ */Symbol('COMPUTING');
/**
 * A dedicated symbol used in place of a computed signal value to indicate that a given computation
 * failed. The thrown error is cached until the computation gets dirty again.
 * Explicitly typed as `any` so we can use it as signal's value.
 */
const ERRORED = /* @__PURE__ */Symbol('ERRORED');
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const COMPUTED_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    value: UNSET,
    dirty: true,
    error: null,
    equal: defaultEquals,
    producerMustRecompute(node) {
      // Force a recomputation if there's no current value, or if the current value is in the
      // process of being calculated (which should throw an error).
      return node.value === UNSET || node.value === COMPUTING;
    },
    producerRecomputeValue(node) {
      if (node.value === COMPUTING) {
        // Our computation somehow led to a cyclic read of itself.
        throw new Error('Detected cycle in computations.');
      }
      const oldValue = node.value;
      node.value = COMPUTING;
      const prevConsumer = consumerBeforeComputation(node);
      let newValue;
      try {
        newValue = node.computation();
      } catch (err) {
        newValue = ERRORED;
        node.error = err;
      } finally {
        consumerAfterComputation(node, prevConsumer);
      }
      if (oldValue !== UNSET && oldValue !== ERRORED && newValue !== ERRORED && node.equal(oldValue, newValue)) {
        // No change to `valueVersion` - old and new values are
        // semantically equivalent.
        node.value = oldValue;
        return;
      }
      node.value = newValue;
      node.version++;
    }
  };
})();
function defaultThrowError() {
  throw new Error();
}
let throwInvalidWriteToSignalErrorFn = defaultThrowError;
function throwInvalidWriteToSignalError() {
  throwInvalidWriteToSignalErrorFn();
}
function setThrowInvalidWriteToSignalError(fn) {
  throwInvalidWriteToSignalErrorFn = fn;
}

/**
 * If set, called after `WritableSignal`s are updated.
 *
 * This hook can be used to achieve various effects, such as running effects synchronously as part
 * of setting a signal.
 */
let postSignalSetFn = null;
/**
 * Create a `Signal` that can be set or updated directly.
 */
function createSignal(initialValue) {
  const node = Object.create(SIGNAL_NODE);
  node.value = initialValue;
  const getter = () => {
    producerAccessed(node);
    return node.value;
  };
  getter[SIGNAL] = node;
  return getter;
}
function setPostSignalSetFn(fn) {
  const prev = postSignalSetFn;
  postSignalSetFn = fn;
  return prev;
}
function signalGetFn() {
  producerAccessed(this);
  return this.value;
}
function signalSetFn(node, newValue) {
  if (!producerUpdatesAllowed()) {
    throwInvalidWriteToSignalError();
  }
  if (!node.equal(node.value, newValue)) {
    node.value = newValue;
    signalValueChanged(node);
  }
}
function signalUpdateFn(node, updater) {
  if (!producerUpdatesAllowed()) {
    throwInvalidWriteToSignalError();
  }
  signalSetFn(node, updater(node.value));
}
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const SIGNAL_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    equal: defaultEquals,
    value: undefined
  };
})();
function signalValueChanged(node) {
  node.version++;
  producerIncrementEpoch();
  producerNotifyConsumers(node);
  postSignalSetFn?.();
}
function createWatch(fn, schedule, allowSignalWrites) {
  const node = Object.create(WATCH_NODE);
  if (allowSignalWrites) {
    node.consumerAllowSignalWrites = true;
  }
  node.fn = fn;
  node.schedule = schedule;
  const registerOnCleanup = cleanupFn => {
    node.cleanupFn = cleanupFn;
  };
  function isWatchNodeDestroyed(node) {
    return node.fn === null && node.schedule === null;
  }
  function destroyWatchNode(node) {
    if (!isWatchNodeDestroyed(node)) {
      consumerDestroy(node); // disconnect watcher from the reactive graph
      node.cleanupFn();
      // nullify references to the integration functions to mark node as destroyed
      node.fn = null;
      node.schedule = null;
      node.cleanupFn = NOOP_CLEANUP_FN;
    }
  }
  const run = () => {
    if (node.fn === null) {
      // trying to run a destroyed watch is noop
      return;
    }
    if (isInNotificationPhase()) {
      throw new Error(`Schedulers cannot synchronously execute watches while scheduling.`);
    }
    node.dirty = false;
    if (node.hasRun && !consumerPollProducersForChange(node)) {
      return;
    }
    node.hasRun = true;
    const prevConsumer = consumerBeforeComputation(node);
    try {
      node.cleanupFn();
      node.cleanupFn = NOOP_CLEANUP_FN;
      node.fn(registerOnCleanup);
    } finally {
      consumerAfterComputation(node, prevConsumer);
    }
  };
  node.ref = {
    notify: () => consumerMarkDirty(node),
    run,
    cleanup: () => node.cleanupFn(),
    destroy: () => destroyWatchNode(node),
    [SIGNAL]: node
  };
  return node.ref;
}
const NOOP_CLEANUP_FN = () => {};
// Note: Using an IIFE here to ensure that the spread assignment is not considered
// a side-effect, ending up preserving `COMPUTED_NODE` and `REACTIVE_NODE`.
// TODO: remove when https://github.com/evanw/esbuild/issues/3392 is resolved.
const WATCH_NODE = /* @__PURE__ */(() => {
  return {
    ...REACTIVE_NODE,
    consumerIsAlwaysLive: true,
    consumerAllowSignalWrites: false,
    consumerMarkedDirty: node => {
      if (node.schedule !== null) {
        node.schedule(node.ref);
      }
    },
    hasRun: false,
    cleanupFn: NOOP_CLEANUP_FN
  };
})();
function setAlternateWeakRefImpl(impl) {
  // TODO: remove this function
}


/***/ }),

/***/ 49074:
/*!**************************************************************!*\
  !*** ./node_modules/@angular/core/fesm2022/rxjs-interop.mjs ***!
  \**************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   outputFromObservable: () => (/* binding */ outputFromObservable),
/* harmony export */   outputToObservable: () => (/* binding */ outputToObservable),
/* harmony export */   takeUntilDestroyed: () => (/* binding */ takeUntilDestroyed),
/* harmony export */   toObservable: () => (/* binding */ toObservable),
/* harmony export */   toSignal: () => (/* binding */ toSignal)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 56042);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 33900);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */





/**
 * Operator which completes the Observable when the calling context (component, directive, service,
 * etc) is destroyed.
 *
 * @param destroyRef optionally, the `DestroyRef` representing the current context. This can be
 *     passed explicitly to use `takeUntilDestroyed` outside of an [injection
 * context](guide/dependency-injection-context). Otherwise, the current `DestroyRef` is injected.
 *
 * @developerPreview
 */
function takeUntilDestroyed(destroyRef) {
  if (!destroyRef) {
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.assertInInjectionContext)(takeUntilDestroyed);
    destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
  }
  const destroyed$ = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Observable(observer => {
    const unregisterFn = destroyRef.onDestroy(observer.next.bind(observer));
    return unregisterFn;
  });
  return source => {
    return source.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.takeUntil)(destroyed$));
  };
}

/**
 * Implementation of `OutputRef` that emits values from
 * an RxJS observable source.
 *
 * @internal
 */
class OutputFromObservableRef {
  constructor(source) {
    this.source = source;
    this.destroyed = false;
    this.destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this.destroyRef.onDestroy(() => {
      this.destroyed = true;
    });
  }
  subscribe(callbackFn) {
    if (this.destroyed) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](953 /* ɵRuntimeErrorCode.OUTPUT_REF_DESTROYED */, ngDevMode && 'Unexpected subscription to destroyed `OutputRef`. ' + 'The owning directive/component is destroyed.');
    }
    // Stop yielding more values when the directive/component is already destroyed.
    const subscription = this.source.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
      next: value => callbackFn(value)
    });
    return {
      unsubscribe: () => subscription.unsubscribe()
    };
  }
}
/**
 * Declares an Angular output that is using an RxJS observable as a source
 * for events dispatched to parent subscribers.
 *
 * The behavior for an observable as source is defined as followed:
 *    1. New values are forwarded to the Angular output (next notifications).
 *    2. Errors notifications are not handled by Angular. You need to handle these manually.
 *       For example by using `catchError`.
 *    3. Completion notifications stop the output from emitting new values.
 *
 * @usageNotes
 * Initialize an output in your directive by declaring a
 * class field and initializing it with the `outputFromObservable()` function.
 *
 * ```ts
 * @Directive({..})
 * export class MyDir {
 *   nameChange$ = <some-observable>;
 *   nameChange = outputFromObservable(this.nameChange$);
 * }
 * ```
 *
 * @developerPreview
 */
function outputFromObservable(observable, opts) {
  ngDevMode && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.assertInInjectionContext)(outputFromObservable);
  return new OutputFromObservableRef(observable);
}

/**
 * Converts an Angular output declared via `output()` or `outputFromObservable()`
 * to an observable.
 *
 * You can subscribe to the output via `Observable.subscribe` then.
 *
 * @developerPreview
 */
function outputToObservable(ref) {
  const destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵgetOutputDestroyRef"])(ref);
  return new rxjs__WEBPACK_IMPORTED_MODULE_1__.Observable(observer => {
    // Complete the observable upon directive/component destroy.
    // Note: May be `undefined` if an `EventEmitter` is declared outside
    // of an injection context.
    destroyRef?.onDestroy(() => observer.complete());
    const subscription = ref.subscribe(v => observer.next(v));
    return () => subscription.unsubscribe();
  });
}

/**
 * Exposes the value of an Angular `Signal` as an RxJS `Observable`.
 *
 * The signal's value will be propagated into the `Observable`'s subscribers using an `effect`.
 *
 * `toObservable` must be called in an injection context unless an injector is provided via options.
 *
 * @developerPreview
 */
function toObservable(source, options) {
  !options?.injector && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.assertInInjectionContext)(toObservable);
  const injector = options?.injector ?? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
  const subject = new rxjs__WEBPACK_IMPORTED_MODULE_3__.ReplaySubject(1);
  const watcher = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.effect)(() => {
    let value;
    try {
      value = source();
    } catch (err) {
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.untracked)(() => subject.error(err));
      return;
    }
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.untracked)(() => subject.next(value));
  }, {
    injector,
    manualCleanup: true
  });
  injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef).onDestroy(() => {
    watcher.destroy();
    subject.complete();
  });
  return subject.asObservable();
}

/**
 * Get the current value of an `Observable` as a reactive `Signal`.
 *
 * `toSignal` returns a `Signal` which provides synchronous reactive access to values produced
 * by the given `Observable`, by subscribing to that `Observable`. The returned `Signal` will always
 * have the most recent value emitted by the subscription, and will throw an error if the
 * `Observable` errors.
 *
 * With `requireSync` set to `true`, `toSignal` will assert that the `Observable` produces a value
 * immediately upon subscription. No `initialValue` is needed in this case, and the returned signal
 * does not include an `undefined` type.
 *
 * By default, the subscription will be automatically cleaned up when the current [injection
 * context](/guide/dependency-injection-context) is destroyed. For example, when `toSignal` is
 * called during the construction of a component, the subscription will be cleaned up when the
 * component is destroyed. If an injection context is not available, an explicit `Injector` can be
 * passed instead.
 *
 * If the subscription should persist until the `Observable` itself completes, the `manualCleanup`
 * option can be specified instead, which disables the automatic subscription teardown. No injection
 * context is needed in this configuration as well.
 *
 * @developerPreview
 */
function toSignal(source, options) {
  ngDevMode && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.assertNotInReactiveContext)(toSignal, 'Invoking `toSignal` causes new subscriptions every time. ' + 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');
  const requiresCleanup = !options?.manualCleanup;
  requiresCleanup && !options?.injector && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.assertInInjectionContext)(toSignal);
  const cleanupRef = requiresCleanup ? options?.injector?.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef) ?? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef) : null;
  // Note: T is the Observable value type, and U is the initial value type. They don't have to be
  // the same - the returned signal gives values of type `T`.
  let state;
  if (options?.requireSync) {
    // Initially the signal is in a `NoValue` state.
    state = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.signal)({
      kind: 0 /* StateKind.NoValue */
    });
  } else {
    // If an initial value was passed, use it. Otherwise, use `undefined` as the initial value.
    state = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.signal)({
      kind: 1 /* StateKind.Value */,
      value: options?.initialValue
    });
  }
  // Note: This code cannot run inside a reactive context (see assertion above). If we'd support
  // this, we would subscribe to the observable outside of the current reactive context, avoiding
  // that side-effect signal reads/writes are attribute to the current consumer. The current
  // consumer only needs to be notified when the `state` signal changes through the observable
  // subscription. Additional context (related to async pipe):
  // https://github.com/angular/angular/pull/50522.
  const sub = source.subscribe({
    next: value => state.set({
      kind: 1 /* StateKind.Value */,
      value
    }),
    error: error => {
      if (options?.rejectErrors) {
        // Kick the error back to RxJS. It will be caught and rethrown in a macrotask, which causes
        // the error to end up as an uncaught exception.
        throw error;
      }
      state.set({
        kind: 2 /* StateKind.Error */,
        error
      });
    }
    // Completion of the Observable is meaningless to the signal. Signals don't have a concept of
    // "complete".
  });
  if (ngDevMode && options?.requireSync && state().kind === 0 /* StateKind.NoValue */) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](601 /* ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT */, '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
  }
  // Unsubscribe when the current context is destroyed, if requested.
  cleanupRef?.onDestroy(sub.unsubscribe.bind(sub));
  // The actual returned signal is a `computed` of the `State` signal, which maps the various states
  // to either values or errors.
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
    const current = state();
    switch (current.kind) {
      case 1 /* StateKind.Value */:
        return current.value;
      case 2 /* StateKind.Error */:
        throw current.error;
      case 0 /* StateKind.NoValue */:
        // This shouldn't really happen because the error is thrown on creation.
        // TODO(alxhub): use a RuntimeError when we finalize the error semantics
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](601 /* ɵRuntimeErrorCode.REQUIRE_SYNC_WITHOUT_SYNC_EMIT */, '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
    }
  });
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 34456:
/*!********************************************************!*\
  !*** ./node_modules/@angular/forms/fesm2022/forms.mjs ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AbstractControl: () => (/* binding */ AbstractControl),
/* harmony export */   AbstractControlDirective: () => (/* binding */ AbstractControlDirective),
/* harmony export */   AbstractFormGroupDirective: () => (/* binding */ AbstractFormGroupDirective),
/* harmony export */   COMPOSITION_BUFFER_MODE: () => (/* binding */ COMPOSITION_BUFFER_MODE),
/* harmony export */   CheckboxControlValueAccessor: () => (/* binding */ CheckboxControlValueAccessor),
/* harmony export */   CheckboxRequiredValidator: () => (/* binding */ CheckboxRequiredValidator),
/* harmony export */   ControlContainer: () => (/* binding */ ControlContainer),
/* harmony export */   DefaultValueAccessor: () => (/* binding */ DefaultValueAccessor),
/* harmony export */   EmailValidator: () => (/* binding */ EmailValidator),
/* harmony export */   FormArray: () => (/* binding */ FormArray),
/* harmony export */   FormArrayName: () => (/* binding */ FormArrayName),
/* harmony export */   FormBuilder: () => (/* binding */ FormBuilder),
/* harmony export */   FormControl: () => (/* binding */ FormControl),
/* harmony export */   FormControlDirective: () => (/* binding */ FormControlDirective),
/* harmony export */   FormControlName: () => (/* binding */ FormControlName),
/* harmony export */   FormGroup: () => (/* binding */ FormGroup),
/* harmony export */   FormGroupDirective: () => (/* binding */ FormGroupDirective),
/* harmony export */   FormGroupName: () => (/* binding */ FormGroupName),
/* harmony export */   FormRecord: () => (/* binding */ FormRecord),
/* harmony export */   FormsModule: () => (/* binding */ FormsModule),
/* harmony export */   MaxLengthValidator: () => (/* binding */ MaxLengthValidator),
/* harmony export */   MaxValidator: () => (/* binding */ MaxValidator),
/* harmony export */   MinLengthValidator: () => (/* binding */ MinLengthValidator),
/* harmony export */   MinValidator: () => (/* binding */ MinValidator),
/* harmony export */   NG_ASYNC_VALIDATORS: () => (/* binding */ NG_ASYNC_VALIDATORS),
/* harmony export */   NG_VALIDATORS: () => (/* binding */ NG_VALIDATORS),
/* harmony export */   NG_VALUE_ACCESSOR: () => (/* binding */ NG_VALUE_ACCESSOR),
/* harmony export */   NgControl: () => (/* binding */ NgControl),
/* harmony export */   NgControlStatus: () => (/* binding */ NgControlStatus),
/* harmony export */   NgControlStatusGroup: () => (/* binding */ NgControlStatusGroup),
/* harmony export */   NgForm: () => (/* binding */ NgForm),
/* harmony export */   NgModel: () => (/* binding */ NgModel),
/* harmony export */   NgModelGroup: () => (/* binding */ NgModelGroup),
/* harmony export */   NgSelectOption: () => (/* binding */ NgSelectOption),
/* harmony export */   NonNullableFormBuilder: () => (/* binding */ NonNullableFormBuilder),
/* harmony export */   NumberValueAccessor: () => (/* binding */ NumberValueAccessor),
/* harmony export */   PatternValidator: () => (/* binding */ PatternValidator),
/* harmony export */   RadioControlValueAccessor: () => (/* binding */ RadioControlValueAccessor),
/* harmony export */   RangeValueAccessor: () => (/* binding */ RangeValueAccessor),
/* harmony export */   ReactiveFormsModule: () => (/* binding */ ReactiveFormsModule),
/* harmony export */   RequiredValidator: () => (/* binding */ RequiredValidator),
/* harmony export */   SelectControlValueAccessor: () => (/* binding */ SelectControlValueAccessor),
/* harmony export */   SelectMultipleControlValueAccessor: () => (/* binding */ SelectMultipleControlValueAccessor),
/* harmony export */   UntypedFormArray: () => (/* binding */ UntypedFormArray),
/* harmony export */   UntypedFormBuilder: () => (/* binding */ UntypedFormBuilder),
/* harmony export */   UntypedFormControl: () => (/* binding */ UntypedFormControl),
/* harmony export */   UntypedFormGroup: () => (/* binding */ UntypedFormGroup),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   Validators: () => (/* binding */ Validators),
/* harmony export */   isFormArray: () => (/* binding */ isFormArray),
/* harmony export */   isFormControl: () => (/* binding */ isFormControl),
/* harmony export */   isFormGroup: () => (/* binding */ isFormGroup),
/* harmony export */   isFormRecord: () => (/* binding */ isFormRecord),
/* harmony export */   "ɵInternalFormsSharedModule": () => (/* binding */ ɵInternalFormsSharedModule),
/* harmony export */   "ɵNgNoValidate": () => (/* binding */ ɵNgNoValidate),
/* harmony export */   "ɵNgSelectMultipleOption": () => (/* binding */ ɵNgSelectMultipleOption)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 95429);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 61873);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 70271);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */







/**
 * Base class for all ControlValueAccessor classes defined in Forms package.
 * Contains common logic and utility functions.
 *
 * Note: this is an *internal-only* class and should not be extended or used directly in
 * applications code.
 */
class BaseControlValueAccessor {
  constructor(_renderer, _elementRef) {
    this._renderer = _renderer;
    this._elementRef = _elementRef;
    /**
     * The registered callback function called when a change or input event occurs on the input
     * element.
     * @nodoc
     */
    this.onChange = _ => {};
    /**
     * The registered callback function called when a blur event occurs on the input element.
     * @nodoc
     */
    this.onTouched = () => {};
  }
  /**
   * Helper method that sets a property on a target element using the current Renderer
   * implementation.
   * @nodoc
   */
  setProperty(key, value) {
    this._renderer.setProperty(this._elementRef.nativeElement, key, value);
  }
  /**
   * Registers a function called when the control is touched.
   * @nodoc
   */
  registerOnTouched(fn) {
    this.onTouched = fn;
  }
  /**
   * Registers a function called when the control value changes.
   * @nodoc
   */
  registerOnChange(fn) {
    this.onChange = fn;
  }
  /**
   * Sets the "disabled" property on the range input element.
   * @nodoc
   */
  setDisabledState(isDisabled) {
    this.setProperty('disabled', isDisabled);
  }
  static {
    this.ɵfac = function BaseControlValueAccessor_Factory(t) {
      return new (t || BaseControlValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: BaseControlValueAccessor
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BaseControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }], null);
})();
/**
 * Base class for all built-in ControlValueAccessor classes (except DefaultValueAccessor, which is
 * used in case no other CVAs can be found). We use this class to distinguish between default CVA,
 * built-in CVAs and custom CVAs, so that Forms logic can recognize built-in CVAs and treat custom
 * ones with higher priority (when both built-in and custom CVAs are present).
 *
 * Note: this is an *internal-only* class and should not be extended or used directly in
 * applications code.
 */
class BuiltInControlValueAccessor extends BaseControlValueAccessor {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵBuiltInControlValueAccessor_BaseFactory;
      return function BuiltInControlValueAccessor_Factory(t) {
        return (ɵBuiltInControlValueAccessor_BaseFactory || (ɵBuiltInControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](BuiltInControlValueAccessor)))(t || BuiltInControlValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: BuiltInControlValueAccessor,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BuiltInControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
  }], null, null);
})();
/**
 * Used to provide a `ControlValueAccessor` for form controls.
 *
 * See `DefaultValueAccessor` for how to implement one.
 *
 * @publicApi
 */
const NG_VALUE_ACCESSOR = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'NgValueAccessor' : '');
const CHECKBOX_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CheckboxControlValueAccessor),
  multi: true
};
/**
 * @description
 * A `ControlValueAccessor` for writing a value and listening to changes on a checkbox input
 * element.
 *
 * @usageNotes
 *
 * ### Using a checkbox with a reactive form.
 *
 * The following example shows how to use a checkbox with a reactive form.
 *
 * ```ts
 * const rememberLoginControl = new FormControl();
 * ```
 *
 * ```
 * <input type="checkbox" [formControl]="rememberLoginControl">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class CheckboxControlValueAccessor extends BuiltInControlValueAccessor {
  /**
   * Sets the "checked" property on the input element.
   * @nodoc
   */
  writeValue(value) {
    this.setProperty('checked', value);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵCheckboxControlValueAccessor_BaseFactory;
      return function CheckboxControlValueAccessor_Factory(t) {
        return (ɵCheckboxControlValueAccessor_BaseFactory || (ɵCheckboxControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](CheckboxControlValueAccessor)))(t || CheckboxControlValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CheckboxControlValueAccessor,
      selectors: [["input", "type", "checkbox", "formControlName", ""], ["input", "type", "checkbox", "formControl", ""], ["input", "type", "checkbox", "ngModel", ""]],
      hostBindings: function CheckboxControlValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function CheckboxControlValueAccessor_change_HostBindingHandler($event) {
            return ctx.onChange($event.target.checked);
          })("blur", function CheckboxControlValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([CHECKBOX_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CheckboxControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
      host: {
        '(change)': 'onChange($event.target.checked)',
        '(blur)': 'onTouched()'
      },
      providers: [CHECKBOX_VALUE_ACCESSOR]
    }]
  }], null, null);
})();
const DEFAULT_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => DefaultValueAccessor),
  multi: true
};
/**
 * We must check whether the agent is Android because composition events
 * behave differently between iOS and Android.
 */
function _isAndroid() {
  const userAgent = (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__["ɵgetDOM"])() ? (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__["ɵgetDOM"])().getUserAgent() : '';
  return /android (\d+)/.test(userAgent.toLowerCase());
}
/**
 * @description
 * Provide this token to control if form directives buffer IME input until
 * the "compositionend" event occurs.
 * @publicApi
 */
const COMPOSITION_BUFFER_MODE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'CompositionEventMode' : '');
/**
 * The default `ControlValueAccessor` for writing a value and listening to changes on input
 * elements. The accessor is used by the `FormControlDirective`, `FormControlName`, and
 * `NgModel` directives.
 *
 * {@searchKeywords ngDefaultControl}
 *
 * @usageNotes
 *
 * ### Using the default value accessor
 *
 * The following example shows how to use an input element that activates the default value accessor
 * (in this case, a text field).
 *
 * ```ts
 * const firstNameControl = new FormControl();
 * ```
 *
 * ```
 * <input type="text" [formControl]="firstNameControl">
 * ```
 *
 * This value accessor is used by default for `<input type="text">` and `<textarea>` elements, but
 * you could also use it for custom components that have similar behavior and do not require special
 * processing. In order to attach the default value accessor to a custom element, add the
 * `ngDefaultControl` attribute as shown below.
 *
 * ```
 * <custom-input-component ngDefaultControl [(ngModel)]="value"></custom-input-component>
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class DefaultValueAccessor extends BaseControlValueAccessor {
  constructor(renderer, elementRef, _compositionMode) {
    super(renderer, elementRef);
    this._compositionMode = _compositionMode;
    /** Whether the user is creating a composition string (IME events). */
    this._composing = false;
    if (this._compositionMode == null) {
      this._compositionMode = !_isAndroid();
    }
  }
  /**
   * Sets the "value" property on the input element.
   * @nodoc
   */
  writeValue(value) {
    const normalizedValue = value == null ? '' : value;
    this.setProperty('value', normalizedValue);
  }
  /** @internal */
  _handleInput(value) {
    if (!this._compositionMode || this._compositionMode && !this._composing) {
      this.onChange(value);
    }
  }
  /** @internal */
  _compositionStart() {
    this._composing = true;
  }
  /** @internal */
  _compositionEnd(value) {
    this._composing = false;
    this._compositionMode && this.onChange(value);
  }
  static {
    this.ɵfac = function DefaultValueAccessor_Factory(t) {
      return new (t || DefaultValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](COMPOSITION_BUFFER_MODE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: DefaultValueAccessor,
      selectors: [["input", "formControlName", "", 3, "type", "checkbox"], ["textarea", "formControlName", ""], ["input", "formControl", "", 3, "type", "checkbox"], ["textarea", "formControl", ""], ["input", "ngModel", "", 3, "type", "checkbox"], ["textarea", "ngModel", ""], ["", "ngDefaultControl", ""]],
      hostBindings: function DefaultValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function DefaultValueAccessor_input_HostBindingHandler($event) {
            return ctx._handleInput($event.target.value);
          })("blur", function DefaultValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          })("compositionstart", function DefaultValueAccessor_compositionstart_HostBindingHandler() {
            return ctx._compositionStart();
          })("compositionend", function DefaultValueAccessor_compositionend_HostBindingHandler($event) {
            return ctx._compositionEnd($event.target.value);
          });
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([DEFAULT_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DefaultValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
      // TODO: vsavkin replace the above selector with the one below it once
      // https://github.com/angular/angular/issues/3011 is implemented
      // selector: '[ngModel],[formControl],[formControlName]',
      host: {
        '(input)': '$any(this)._handleInput($event.target.value)',
        '(blur)': 'onTouched()',
        '(compositionstart)': '$any(this)._compositionStart()',
        '(compositionend)': '$any(this)._compositionEnd($event.target.value)'
      },
      providers: [DEFAULT_VALUE_ACCESSOR]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [COMPOSITION_BUFFER_MODE]
    }]
  }], null);
})();
function isEmptyInputValue(value) {
  /**
   * Check if the object is a string or array before evaluating the length attribute.
   * This avoids falsely rejecting objects that contain a custom length attribute.
   * For example, the object {id: 1, length: 0, width: 0} should not be returned as empty.
   */
  return value == null || (typeof value === 'string' || Array.isArray(value)) && value.length === 0;
}
function hasValidLength(value) {
  // non-strict comparison is intentional, to check for both `null` and `undefined` values
  return value != null && typeof value.length === 'number';
}
/**
 * @description
 * An `InjectionToken` for registering additional synchronous validators used with
 * `AbstractControl`s.
 *
 * @see {@link NG_ASYNC_VALIDATORS}
 *
 * @usageNotes
 *
 * ### Providing a custom validator
 *
 * The following example registers a custom validator directive. Adding the validator to the
 * existing collection of validators requires the `multi: true` option.
 *
 * ```typescript
 * @Directive({
 *   selector: '[customValidator]',
 *   providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
 * })
 * class CustomValidatorDirective implements Validator {
 *   validate(control: AbstractControl): ValidationErrors | null {
 *     return { 'custom': true };
 *   }
 * }
 * ```
 *
 * @publicApi
 */
const NG_VALIDATORS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'NgValidators' : '');
/**
 * @description
 * An `InjectionToken` for registering additional asynchronous validators used with
 * `AbstractControl`s.
 *
 * @see {@link NG_VALIDATORS}
 *
 * @usageNotes
 *
 * ### Provide a custom async validator directive
 *
 * The following example implements the `AsyncValidator` interface to create an
 * async validator directive with a custom error key.
 *
 * ```typescript
 * @Directive({
 *   selector: '[customAsyncValidator]',
 *   providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: CustomAsyncValidatorDirective, multi:
 * true}]
 * })
 * class CustomAsyncValidatorDirective implements AsyncValidator {
 *   validate(control: AbstractControl): Promise<ValidationErrors|null> {
 *     return Promise.resolve({'custom': true});
 *   }
 * }
 * ```
 *
 * @publicApi
 */
const NG_ASYNC_VALIDATORS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'NgAsyncValidators' : '');
/**
 * A regular expression that matches valid e-mail addresses.
 *
 * At a high level, this regexp matches e-mail addresses of the format `local-part@tld`, where:
 * - `local-part` consists of one or more of the allowed characters (alphanumeric and some
 *   punctuation symbols).
 * - `local-part` cannot begin or end with a period (`.`).
 * - `local-part` cannot be longer than 64 characters.
 * - `tld` consists of one or more `labels` separated by periods (`.`). For example `localhost` or
 *   `foo.com`.
 * - A `label` consists of one or more of the allowed characters (alphanumeric, dashes (`-`) and
 *   periods (`.`)).
 * - A `label` cannot begin or end with a dash (`-`) or a period (`.`).
 * - A `label` cannot be longer than 63 characters.
 * - The whole address cannot be longer than 254 characters.
 *
 * ## Implementation background
 *
 * This regexp was ported over from AngularJS (see there for git history):
 * https://github.com/angular/angular.js/blob/c133ef836/src/ng/directive/input.js#L27
 * It is based on the
 * [WHATWG version](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with
 * some enhancements to incorporate more RFC rules (such as rules related to domain names and the
 * lengths of different parts of the address). The main differences from the WHATWG version are:
 *   - Disallow `local-part` to begin or end with a period (`.`).
 *   - Disallow `local-part` length to exceed 64 characters.
 *   - Disallow total address length to exceed 254 characters.
 *
 * See [this commit](https://github.com/angular/angular.js/commit/f3f5cf72e) for more details.
 */
const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-zA-Z0-9!#$%&'*+/=?^_`{|}~-]+)*@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
/**
 * @description
 * Provides a set of built-in validators that can be used by form controls.
 *
 * A validator is a function that processes a `FormControl` or collection of
 * controls and returns an error map or null. A null map means that validation has passed.
 *
 * @see [Form Validation](/guide/form-validation)
 *
 * @publicApi
 */
class Validators {
  /**
   * @description
   * Validator that requires the control's value to be greater than or equal to the provided number.
   *
   * @usageNotes
   *
   * ### Validate against a minimum of 3
   *
   * ```typescript
   * const control = new FormControl(2, Validators.min(3));
   *
   * console.log(control.errors); // {min: {min: 3, actual: 2}}
   * ```
   *
   * @returns A validator function that returns an error map with the
   * `min` property if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static min(min) {
    return minValidator(min);
  }
  /**
   * @description
   * Validator that requires the control's value to be less than or equal to the provided number.
   *
   * @usageNotes
   *
   * ### Validate against a maximum of 15
   *
   * ```typescript
   * const control = new FormControl(16, Validators.max(15));
   *
   * console.log(control.errors); // {max: {max: 15, actual: 16}}
   * ```
   *
   * @returns A validator function that returns an error map with the
   * `max` property if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static max(max) {
    return maxValidator(max);
  }
  /**
   * @description
   * Validator that requires the control have a non-empty value.
   *
   * @usageNotes
   *
   * ### Validate that the field is non-empty
   *
   * ```typescript
   * const control = new FormControl('', Validators.required);
   *
   * console.log(control.errors); // {required: true}
   * ```
   *
   * @returns An error map with the `required` property
   * if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static required(control) {
    return requiredValidator(control);
  }
  /**
   * @description
   * Validator that requires the control's value be true. This validator is commonly
   * used for required checkboxes.
   *
   * @usageNotes
   *
   * ### Validate that the field value is true
   *
   * ```typescript
   * const control = new FormControl('some value', Validators.requiredTrue);
   *
   * console.log(control.errors); // {required: true}
   * ```
   *
   * @returns An error map that contains the `required` property
   * set to `true` if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static requiredTrue(control) {
    return requiredTrueValidator(control);
  }
  /**
   * @description
   * Validator that requires the control's value pass an email validation test.
   *
   * Tests the value using a [regular
   * expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)
   * pattern suitable for common use cases. The pattern is based on the definition of a valid email
   * address in the [WHATWG HTML
   * specification](https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address) with
   * some enhancements to incorporate more RFC rules (such as rules related to domain names and the
   * lengths of different parts of the address).
   *
   * The differences from the WHATWG version include:
   * - Disallow `local-part` (the part before the `@` symbol) to begin or end with a period (`.`).
   * - Disallow `local-part` to be longer than 64 characters.
   * - Disallow the whole address to be longer than 254 characters.
   *
   * If this pattern does not satisfy your business needs, you can use `Validators.pattern()` to
   * validate the value against a different pattern.
   *
   * @usageNotes
   *
   * ### Validate that the field matches a valid email pattern
   *
   * ```typescript
   * const control = new FormControl('bad@', Validators.email);
   *
   * console.log(control.errors); // {email: true}
   * ```
   *
   * @returns An error map with the `email` property
   * if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static email(control) {
    return emailValidator(control);
  }
  /**
   * @description
   * Validator that requires the length of the control's value to be greater than or equal
   * to the provided minimum length. This validator is also provided by default if you use the
   * the HTML5 `minlength` attribute. Note that the `minLength` validator is intended to be used
   * only for types that have a numeric `length` property, such as strings or arrays. The
   * `minLength` validator logic is also not invoked for values when their `length` property is 0
   * (for example in case of an empty string or an empty array), to support optional controls. You
   * can use the standard `required` validator if empty values should not be considered valid.
   *
   * @usageNotes
   *
   * ### Validate that the field has a minimum of 3 characters
   *
   * ```typescript
   * const control = new FormControl('ng', Validators.minLength(3));
   *
   * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}}
   * ```
   *
   * ```html
   * <input minlength="5">
   * ```
   *
   * @returns A validator function that returns an error map with the
   * `minlength` property if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static minLength(minLength) {
    return minLengthValidator(minLength);
  }
  /**
   * @description
   * Validator that requires the length of the control's value to be less than or equal
   * to the provided maximum length. This validator is also provided by default if you use the
   * the HTML5 `maxlength` attribute. Note that the `maxLength` validator is intended to be used
   * only for types that have a numeric `length` property, such as strings or arrays.
   *
   * @usageNotes
   *
   * ### Validate that the field has maximum of 5 characters
   *
   * ```typescript
   * const control = new FormControl('Angular', Validators.maxLength(5));
   *
   * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}}
   * ```
   *
   * ```html
   * <input maxlength="5">
   * ```
   *
   * @returns A validator function that returns an error map with the
   * `maxlength` property if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static maxLength(maxLength) {
    return maxLengthValidator(maxLength);
  }
  /**
   * @description
   * Validator that requires the control's value to match a regex pattern. This validator is also
   * provided by default if you use the HTML5 `pattern` attribute.
   *
   * @usageNotes
   *
   * ### Validate that the field only contains letters or spaces
   *
   * ```typescript
   * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*'));
   *
   * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}}
   * ```
   *
   * ```html
   * <input pattern="[a-zA-Z ]*">
   * ```
   *
   * ### Pattern matching with the global or sticky flag
   *
   * `RegExp` objects created with the `g` or `y` flags that are passed into `Validators.pattern`
   * can produce different results on the same input when validations are run consecutively. This is
   * due to how the behavior of `RegExp.prototype.test` is
   * specified in [ECMA-262](https://tc39.es/ecma262/#sec-regexpbuiltinexec)
   * (`RegExp` preserves the index of the last match when the global or sticky flag is used).
   * Due to this behavior, it is recommended that when using
   * `Validators.pattern` you **do not** pass in a `RegExp` object with either the global or sticky
   * flag enabled.
   *
   * ```typescript
   * // Not recommended (since the `g` flag is used)
   * const controlOne = new FormControl('1', Validators.pattern(/foo/g));
   *
   * // Good
   * const controlTwo = new FormControl('1', Validators.pattern(/foo/));
   * ```
   *
   * @param pattern A regular expression to be used as is to test the values, or a string.
   * If a string is passed, the `^` character is prepended and the `$` character is
   * appended to the provided string (if not already present), and the resulting regular
   * expression is used to test the values.
   *
   * @returns A validator function that returns an error map with the
   * `pattern` property if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static pattern(pattern) {
    return patternValidator(pattern);
  }
  /**
   * @description
   * Validator that performs no operation.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static nullValidator(control) {
    return nullValidator(control);
  }
  static compose(validators) {
    return compose(validators);
  }
  /**
   * @description
   * Compose multiple async validators into a single function that returns the union
   * of the individual error objects for the provided control.
   *
   * @returns A validator function that returns an error map with the
   * merged error objects of the async validators if the validation check fails, otherwise `null`.
   *
   * @see {@link updateValueAndValidity()}
   *
   */
  static composeAsync(validators) {
    return composeAsync(validators);
  }
}
/**
 * Validator that requires the control's value to be greater than or equal to the provided number.
 * See `Validators.min` for additional information.
 */
function minValidator(min) {
  return control => {
    if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
      return null; // don't validate empty values to allow optional controls
    }
    const value = parseFloat(control.value);
    // Controls with NaN values after parsing should be treated as not having a
    // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
    return !isNaN(value) && value < min ? {
      'min': {
        'min': min,
        'actual': control.value
      }
    } : null;
  };
}
/**
 * Validator that requires the control's value to be less than or equal to the provided number.
 * See `Validators.max` for additional information.
 */
function maxValidator(max) {
  return control => {
    if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
      return null; // don't validate empty values to allow optional controls
    }
    const value = parseFloat(control.value);
    // Controls with NaN values after parsing should be treated as not having a
    // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
    return !isNaN(value) && value > max ? {
      'max': {
        'max': max,
        'actual': control.value
      }
    } : null;
  };
}
/**
 * Validator that requires the control have a non-empty value.
 * See `Validators.required` for additional information.
 */
function requiredValidator(control) {
  return isEmptyInputValue(control.value) ? {
    'required': true
  } : null;
}
/**
 * Validator that requires the control's value be true. This validator is commonly
 * used for required checkboxes.
 * See `Validators.requiredTrue` for additional information.
 */
function requiredTrueValidator(control) {
  return control.value === true ? null : {
    'required': true
  };
}
/**
 * Validator that requires the control's value pass an email validation test.
 * See `Validators.email` for additional information.
 */
function emailValidator(control) {
  if (isEmptyInputValue(control.value)) {
    return null; // don't validate empty values to allow optional controls
  }
  return EMAIL_REGEXP.test(control.value) ? null : {
    'email': true
  };
}
/**
 * Validator that requires the length of the control's value to be greater than or equal
 * to the provided minimum length. See `Validators.minLength` for additional information.
 */
function minLengthValidator(minLength) {
  return control => {
    if (isEmptyInputValue(control.value) || !hasValidLength(control.value)) {
      // don't validate empty values to allow optional controls
      // don't validate values without `length` property
      return null;
    }
    return control.value.length < minLength ? {
      'minlength': {
        'requiredLength': minLength,
        'actualLength': control.value.length
      }
    } : null;
  };
}
/**
 * Validator that requires the length of the control's value to be less than or equal
 * to the provided maximum length. See `Validators.maxLength` for additional information.
 */
function maxLengthValidator(maxLength) {
  return control => {
    return hasValidLength(control.value) && control.value.length > maxLength ? {
      'maxlength': {
        'requiredLength': maxLength,
        'actualLength': control.value.length
      }
    } : null;
  };
}
/**
 * Validator that requires the control's value to match a regex pattern.
 * See `Validators.pattern` for additional information.
 */
function patternValidator(pattern) {
  if (!pattern) return nullValidator;
  let regex;
  let regexStr;
  if (typeof pattern === 'string') {
    regexStr = '';
    if (pattern.charAt(0) !== '^') regexStr += '^';
    regexStr += pattern;
    if (pattern.charAt(pattern.length - 1) !== '$') regexStr += '$';
    regex = new RegExp(regexStr);
  } else {
    regexStr = pattern.toString();
    regex = pattern;
  }
  return control => {
    if (isEmptyInputValue(control.value)) {
      return null; // don't validate empty values to allow optional controls
    }
    const value = control.value;
    return regex.test(value) ? null : {
      'pattern': {
        'requiredPattern': regexStr,
        'actualValue': value
      }
    };
  };
}
/**
 * Function that has `ValidatorFn` shape, but performs no operation.
 */
function nullValidator(control) {
  return null;
}
function isPresent(o) {
  return o != null;
}
function toObservable(value) {
  const obs = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisPromise"])(value) ? (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.from)(value) : value;
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵisSubscribable"])(obs)) {
    let errorMessage = `Expected async validator to return Promise or Observable.`;
    // A synchronous validator will return object or null.
    if (typeof value === 'object') {
      errorMessage += ' Are you using a synchronous validator where an async validator is expected?';
    }
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](-1101 /* RuntimeErrorCode.WRONG_VALIDATOR_RETURN_TYPE */, errorMessage);
  }
  return obs;
}
function mergeErrors(arrayOfErrors) {
  let res = {};
  arrayOfErrors.forEach(errors => {
    res = errors != null ? {
      ...res,
      ...errors
    } : res;
  });
  return Object.keys(res).length === 0 ? null : res;
}
function executeValidators(control, validators) {
  return validators.map(validator => validator(control));
}
function isValidatorFn(validator) {
  return !validator.validate;
}
/**
 * Given the list of validators that may contain both functions as well as classes, return the list
 * of validator functions (convert validator classes into validator functions). This is needed to
 * have consistent structure in validators list before composing them.
 *
 * @param validators The set of validators that may contain validators both in plain function form
 *     as well as represented as a validator class.
 */
function normalizeValidators(validators) {
  return validators.map(validator => {
    return isValidatorFn(validator) ? validator : c => validator.validate(c);
  });
}
/**
 * Merges synchronous validators into a single validator function.
 * See `Validators.compose` for additional information.
 */
function compose(validators) {
  if (!validators) return null;
  const presentValidators = validators.filter(isPresent);
  if (presentValidators.length == 0) return null;
  return function (control) {
    return mergeErrors(executeValidators(control, presentValidators));
  };
}
/**
 * Accepts a list of validators of different possible shapes (`Validator` and `ValidatorFn`),
 * normalizes the list (converts everything to `ValidatorFn`) and merges them into a single
 * validator function.
 */
function composeValidators(validators) {
  return validators != null ? compose(normalizeValidators(validators)) : null;
}
/**
 * Merges asynchronous validators into a single validator function.
 * See `Validators.composeAsync` for additional information.
 */
function composeAsync(validators) {
  if (!validators) return null;
  const presentValidators = validators.filter(isPresent);
  if (presentValidators.length == 0) return null;
  return function (control) {
    const observables = executeValidators(control, presentValidators).map(toObservable);
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.forkJoin)(observables).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(mergeErrors));
  };
}
/**
 * Accepts a list of async validators of different possible shapes (`AsyncValidator` and
 * `AsyncValidatorFn`), normalizes the list (converts everything to `AsyncValidatorFn`) and merges
 * them into a single validator function.
 */
function composeAsyncValidators(validators) {
  return validators != null ? composeAsync(normalizeValidators(validators)) : null;
}
/**
 * Merges raw control validators with a given directive validator and returns the combined list of
 * validators as an array.
 */
function mergeValidators(controlValidators, dirValidator) {
  if (controlValidators === null) return [dirValidator];
  return Array.isArray(controlValidators) ? [...controlValidators, dirValidator] : [controlValidators, dirValidator];
}
/**
 * Retrieves the list of raw synchronous validators attached to a given control.
 */
function getControlValidators(control) {
  return control._rawValidators;
}
/**
 * Retrieves the list of raw asynchronous validators attached to a given control.
 */
function getControlAsyncValidators(control) {
  return control._rawAsyncValidators;
}
/**
 * Accepts a singleton validator, an array, or null, and returns an array type with the provided
 * validators.
 *
 * @param validators A validator, validators, or null.
 * @returns A validators array.
 */
function makeValidatorsArray(validators) {
  if (!validators) return [];
  return Array.isArray(validators) ? validators : [validators];
}
/**
 * Determines whether a validator or validators array has a given validator.
 *
 * @param validators The validator or validators to compare against.
 * @param validator The validator to check.
 * @returns Whether the validator is present.
 */
function hasValidator(validators, validator) {
  return Array.isArray(validators) ? validators.includes(validator) : validators === validator;
}
/**
 * Combines two arrays of validators into one. If duplicates are provided, only one will be added.
 *
 * @param validators The new validators.
 * @param currentValidators The base array of current validators.
 * @returns An array of validators.
 */
function addValidators(validators, currentValidators) {
  const current = makeValidatorsArray(currentValidators);
  const validatorsToAdd = makeValidatorsArray(validators);
  validatorsToAdd.forEach(v => {
    // Note: if there are duplicate entries in the new validators array,
    // only the first one would be added to the current list of validators.
    // Duplicate ones would be ignored since `hasValidator` would detect
    // the presence of a validator function and we update the current list in place.
    if (!hasValidator(current, v)) {
      current.push(v);
    }
  });
  return current;
}
function removeValidators(validators, currentValidators) {
  return makeValidatorsArray(currentValidators).filter(v => !hasValidator(validators, v));
}

/**
 * @description
 * Base class for control directives.
 *
 * This class is only used internally in the `ReactiveFormsModule` and the `FormsModule`.
 *
 * @publicApi
 */
class AbstractControlDirective {
  constructor() {
    /**
     * Set of synchronous validators as they were provided while calling `setValidators` function.
     * @internal
     */
    this._rawValidators = [];
    /**
     * Set of asynchronous validators as they were provided while calling `setAsyncValidators`
     * function.
     * @internal
     */
    this._rawAsyncValidators = [];
    /*
     * The set of callbacks to be invoked when directive instance is being destroyed.
     */
    this._onDestroyCallbacks = [];
  }
  /**
   * @description
   * Reports the value of the control if it is present, otherwise null.
   */
  get value() {
    return this.control ? this.control.value : null;
  }
  /**
   * @description
   * Reports whether the control is valid. A control is considered valid if no
   * validation errors exist with the current value.
   * If the control is not present, null is returned.
   */
  get valid() {
    return this.control ? this.control.valid : null;
  }
  /**
   * @description
   * Reports whether the control is invalid, meaning that an error exists in the input value.
   * If the control is not present, null is returned.
   */
  get invalid() {
    return this.control ? this.control.invalid : null;
  }
  /**
   * @description
   * Reports whether a control is pending, meaning that async validation is occurring and
   * errors are not yet available for the input value. If the control is not present, null is
   * returned.
   */
  get pending() {
    return this.control ? this.control.pending : null;
  }
  /**
   * @description
   * Reports whether the control is disabled, meaning that the control is disabled
   * in the UI and is exempt from validation checks and excluded from aggregate
   * values of ancestor controls. If the control is not present, null is returned.
   */
  get disabled() {
    return this.control ? this.control.disabled : null;
  }
  /**
   * @description
   * Reports whether the control is enabled, meaning that the control is included in ancestor
   * calculations of validity or value. If the control is not present, null is returned.
   */
  get enabled() {
    return this.control ? this.control.enabled : null;
  }
  /**
   * @description
   * Reports the control's validation errors. If the control is not present, null is returned.
   */
  get errors() {
    return this.control ? this.control.errors : null;
  }
  /**
   * @description
   * Reports whether the control is pristine, meaning that the user has not yet changed
   * the value in the UI. If the control is not present, null is returned.
   */
  get pristine() {
    return this.control ? this.control.pristine : null;
  }
  /**
   * @description
   * Reports whether the control is dirty, meaning that the user has changed
   * the value in the UI. If the control is not present, null is returned.
   */
  get dirty() {
    return this.control ? this.control.dirty : null;
  }
  /**
   * @description
   * Reports whether the control is touched, meaning that the user has triggered
   * a `blur` event on it. If the control is not present, null is returned.
   */
  get touched() {
    return this.control ? this.control.touched : null;
  }
  /**
   * @description
   * Reports the validation status of the control. Possible values include:
   * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'.
   * If the control is not present, null is returned.
   */
  get status() {
    return this.control ? this.control.status : null;
  }
  /**
   * @description
   * Reports whether the control is untouched, meaning that the user has not yet triggered
   * a `blur` event on it. If the control is not present, null is returned.
   */
  get untouched() {
    return this.control ? this.control.untouched : null;
  }
  /**
   * @description
   * Returns a multicasting observable that emits a validation status whenever it is
   * calculated for the control. If the control is not present, null is returned.
   */
  get statusChanges() {
    return this.control ? this.control.statusChanges : null;
  }
  /**
   * @description
   * Returns a multicasting observable of value changes for the control that emits every time the
   * value of the control changes in the UI or programmatically.
   * If the control is not present, null is returned.
   */
  get valueChanges() {
    return this.control ? this.control.valueChanges : null;
  }
  /**
   * @description
   * Returns an array that represents the path from the top-level form to this control.
   * Each index is the string name of the control on that level.
   */
  get path() {
    return null;
  }
  /**
   * Sets synchronous validators for this directive.
   * @internal
   */
  _setValidators(validators) {
    this._rawValidators = validators || [];
    this._composedValidatorFn = composeValidators(this._rawValidators);
  }
  /**
   * Sets asynchronous validators for this directive.
   * @internal
   */
  _setAsyncValidators(validators) {
    this._rawAsyncValidators = validators || [];
    this._composedAsyncValidatorFn = composeAsyncValidators(this._rawAsyncValidators);
  }
  /**
   * @description
   * Synchronous validator function composed of all the synchronous validators registered with this
   * directive.
   */
  get validator() {
    return this._composedValidatorFn || null;
  }
  /**
   * @description
   * Asynchronous validator function composed of all the asynchronous validators registered with
   * this directive.
   */
  get asyncValidator() {
    return this._composedAsyncValidatorFn || null;
  }
  /**
   * Internal function to register callbacks that should be invoked
   * when directive instance is being destroyed.
   * @internal
   */
  _registerOnDestroy(fn) {
    this._onDestroyCallbacks.push(fn);
  }
  /**
   * Internal function to invoke all registered "on destroy" callbacks.
   * Note: calling this function also clears the list of callbacks.
   * @internal
   */
  _invokeOnDestroyCallbacks() {
    this._onDestroyCallbacks.forEach(fn => fn());
    this._onDestroyCallbacks = [];
  }
  /**
   * @description
   * Resets the control with the provided value if the control is present.
   */
  reset(value = undefined) {
    if (this.control) this.control.reset(value);
  }
  /**
   * @description
   * Reports whether the control with the given path has the error specified.
   *
   * @param errorCode The code of the error to check
   * @param path A list of control names that designates how to move from the current control
   * to the control that should be queried for errors.
   *
   * @usageNotes
   * For example, for the following `FormGroup`:
   *
   * ```
   * form = new FormGroup({
   *   address: new FormGroup({ street: new FormControl() })
   * });
   * ```
   *
   * The path to the 'street' control from the root form would be 'address' -> 'street'.
   *
   * It can be provided to this method in one of two formats:
   *
   * 1. An array of string control names, e.g. `['address', 'street']`
   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
   *
   * If no path is given, this method checks for the error on the current control.
   *
   * @returns whether the given error is present in the control at the given path.
   *
   * If the control is not present, false is returned.
   */
  hasError(errorCode, path) {
    return this.control ? this.control.hasError(errorCode, path) : false;
  }
  /**
   * @description
   * Reports error data for the control with the given path.
   *
   * @param errorCode The code of the error to check
   * @param path A list of control names that designates how to move from the current control
   * to the control that should be queried for errors.
   *
   * @usageNotes
   * For example, for the following `FormGroup`:
   *
   * ```
   * form = new FormGroup({
   *   address: new FormGroup({ street: new FormControl() })
   * });
   * ```
   *
   * The path to the 'street' control from the root form would be 'address' -> 'street'.
   *
   * It can be provided to this method in one of two formats:
   *
   * 1. An array of string control names, e.g. `['address', 'street']`
   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
   *
   * @returns error data for that particular error. If the control or error is not present,
   * null is returned.
   */
  getError(errorCode, path) {
    return this.control ? this.control.getError(errorCode, path) : null;
  }
}

/**
 * @description
 * A base class for directives that contain multiple registered instances of `NgControl`.
 * Only used by the forms module.
 *
 * @publicApi
 */
class ControlContainer extends AbstractControlDirective {
  /**
   * @description
   * The top-level form directive for the control.
   */
  get formDirective() {
    return null;
  }
  /**
   * @description
   * The path to this group.
   */
  get path() {
    return null;
  }
}

/**
 * @description
 * A base class that all `FormControl`-based directives extend. It binds a `FormControl`
 * object to a DOM element.
 *
 * @publicApi
 */
class NgControl extends AbstractControlDirective {
  constructor() {
    super(...arguments);
    /**
     * @description
     * The parent form for the control.
     *
     * @internal
     */
    this._parent = null;
    /**
     * @description
     * The name for the control
     */
    this.name = null;
    /**
     * @description
     * The value accessor for the control
     */
    this.valueAccessor = null;
  }
}

// DO NOT REFACTOR!
// Each status is represented by a separate function to make sure that
// advanced Closure Compiler optimizations related to property renaming
// can work correctly.
class AbstractControlStatus {
  constructor(cd) {
    this._cd = cd;
  }
  get isTouched() {
    return !!this._cd?.control?.touched;
  }
  get isUntouched() {
    return !!this._cd?.control?.untouched;
  }
  get isPristine() {
    return !!this._cd?.control?.pristine;
  }
  get isDirty() {
    return !!this._cd?.control?.dirty;
  }
  get isValid() {
    return !!this._cd?.control?.valid;
  }
  get isInvalid() {
    return !!this._cd?.control?.invalid;
  }
  get isPending() {
    return !!this._cd?.control?.pending;
  }
  get isSubmitted() {
    // We check for the `submitted` field from `NgForm` and `FormGroupDirective` classes, but
    // we avoid instanceof checks to prevent non-tree-shakable references to those types.
    return !!this._cd?.submitted;
  }
}
const ngControlStatusHost = {
  '[class.ng-untouched]': 'isUntouched',
  '[class.ng-touched]': 'isTouched',
  '[class.ng-pristine]': 'isPristine',
  '[class.ng-dirty]': 'isDirty',
  '[class.ng-valid]': 'isValid',
  '[class.ng-invalid]': 'isInvalid',
  '[class.ng-pending]': 'isPending'
};
const ngGroupStatusHost = {
  ...ngControlStatusHost,
  '[class.ng-submitted]': 'isSubmitted'
};
/**
 * @description
 * Directive automatically applied to Angular form controls that sets CSS classes
 * based on control status.
 *
 * @usageNotes
 *
 * ### CSS classes applied
 *
 * The following classes are applied as the properties become true:
 *
 * * ng-valid
 * * ng-invalid
 * * ng-pending
 * * ng-pristine
 * * ng-dirty
 * * ng-untouched
 * * ng-touched
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class NgControlStatus extends AbstractControlStatus {
  constructor(cd) {
    super(cd);
  }
  static {
    this.ɵfac = function NgControlStatus_Factory(t) {
      return new (t || NgControlStatus)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgControl, 2));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgControlStatus,
      selectors: [["", "formControlName", ""], ["", "ngModel", ""], ["", "formControl", ""]],
      hostVars: 14,
      hostBindings: function NgControlStatus_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending);
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgControlStatus, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formControlName],[ngModel],[formControl]',
      host: ngControlStatusHost
    }]
  }], () => [{
    type: NgControl,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }]
  }], null);
})();
/**
 * @description
 * Directive automatically applied to Angular form groups that sets CSS classes
 * based on control status (valid/invalid/dirty/etc). On groups, this includes the additional
 * class ng-submitted.
 *
 * @see {@link NgControlStatus}
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class NgControlStatusGroup extends AbstractControlStatus {
  constructor(cd) {
    super(cd);
  }
  static {
    this.ɵfac = function NgControlStatusGroup_Factory(t) {
      return new (t || NgControlStatusGroup)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 10));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgControlStatusGroup,
      selectors: [["", "formGroupName", ""], ["", "formArrayName", ""], ["", "ngModelGroup", ""], ["", "formGroup", ""], ["form", 3, "ngNoForm", ""], ["", "ngForm", ""]],
      hostVars: 16,
      hostBindings: function NgControlStatusGroup_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-untouched", ctx.isUntouched)("ng-touched", ctx.isTouched)("ng-pristine", ctx.isPristine)("ng-dirty", ctx.isDirty)("ng-valid", ctx.isValid)("ng-invalid", ctx.isInvalid)("ng-pending", ctx.isPending)("ng-submitted", ctx.isSubmitted);
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgControlStatusGroup, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
      host: ngGroupStatusHost
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }]
  }], null);
})();
const formControlNameExample = `
  <div [formGroup]="myGroup">
    <input formControlName="firstName">
  </div>

  In your class:

  this.myGroup = new FormGroup({
      firstName: new FormControl()
  });`;
const formGroupNameExample = `
  <div [formGroup]="myGroup">
      <div formGroupName="person">
        <input formControlName="firstName">
      </div>
  </div>

  In your class:

  this.myGroup = new FormGroup({
      person: new FormGroup({ firstName: new FormControl() })
  });`;
const formArrayNameExample = `
  <div [formGroup]="myGroup">
    <div formArrayName="cities">
      <div *ngFor="let city of cityArray.controls; index as i">
        <input [formControlName]="i">
      </div>
    </div>
  </div>

  In your class:

  this.cityArray = new FormArray([new FormControl('SF')]);
  this.myGroup = new FormGroup({
    cities: this.cityArray
  });`;
const ngModelGroupExample = `
  <form>
      <div ngModelGroup="person">
        <input [(ngModel)]="person.name" name="firstName">
      </div>
  </form>`;
const ngModelWithFormGroupExample = `
  <div [formGroup]="myGroup">
      <input formControlName="firstName">
      <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}">
  </div>
`;
function controlParentException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1050 /* RuntimeErrorCode.FORM_CONTROL_NAME_MISSING_PARENT */, `formControlName must be used with a parent formGroup directive.  You'll want to add a formGroup
      directive and pass it an existing FormGroup instance (you can create one in your class).

    Example:

    ${formControlNameExample}`);
}
function ngModelGroupException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1051 /* RuntimeErrorCode.FORM_CONTROL_NAME_INSIDE_MODEL_GROUP */, `formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents
      that also have a "form" prefix: formGroupName, formArrayName, or formGroup.

      Option 1:  Update the parent to be formGroupName (reactive form strategy)

      ${formGroupNameExample}

      Option 2: Use ngModel instead of formControlName (template-driven strategy)

      ${ngModelGroupExample}`);
}
function missingFormException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1052 /* RuntimeErrorCode.FORM_GROUP_MISSING_INSTANCE */, `formGroup expects a FormGroup instance. Please pass one in.

      Example:

      ${formControlNameExample}`);
}
function groupParentException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1053 /* RuntimeErrorCode.FORM_GROUP_NAME_MISSING_PARENT */, `formGroupName must be used with a parent formGroup directive.  You'll want to add a formGroup
    directive and pass it an existing FormGroup instance (you can create one in your class).

    Example:

    ${formGroupNameExample}`);
}
function arrayParentException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1054 /* RuntimeErrorCode.FORM_ARRAY_NAME_MISSING_PARENT */, `formArrayName must be used with a parent formGroup directive.  You'll want to add a formGroup
      directive and pass it an existing FormGroup instance (you can create one in your class).

      Example:

      ${formArrayNameExample}`);
}
const disabledAttrWarning = `
  It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
  when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
  you. We recommend using this approach to avoid 'changed after checked' errors.

  Example:
  // Specify the \`disabled\` property at control creation time:
  form = new FormGroup({
    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
    last: new FormControl('Drew', Validators.required)
  });

  // Controls can also be enabled/disabled after creation:
  form.get('first')?.enable();
  form.get('last')?.disable();
`;
const asyncValidatorsDroppedWithOptsWarning = `
  It looks like you're constructing using a FormControl with both an options argument and an
  async validators argument. Mixing these arguments will cause your async validators to be dropped.
  You should either put all your validators in the options object, or in separate validators
  arguments. For example:

  // Using validators arguments
  fc = new FormControl(42, Validators.required, myAsyncValidator);

  // Using AbstractControlOptions
  fc = new FormControl(42, {validators: Validators.required, asyncValidators: myAV});

  // Do NOT mix them: async validators will be dropped!
  fc = new FormControl(42, {validators: Validators.required}, /* Oops! */ myAsyncValidator);
`;
function ngModelWarning(directiveName) {
  return `
  It looks like you're using ngModel on the same form field as ${directiveName}.
  Support for using the ngModel input property and ngModelChange event with
  reactive form directives has been deprecated in Angular v6 and will be removed
  in a future version of Angular.

  For more information on this, see our API docs here:
  https://angular.io/api/forms/${directiveName === 'formControl' ? 'FormControlDirective' : 'FormControlName'}#use-with-ngmodel
  `;
}
function describeKey(isFormGroup, key) {
  return isFormGroup ? `with name: '${key}'` : `at index: ${key}`;
}
function noControlsError(isFormGroup) {
  return `
    There are no form controls registered with this ${isFormGroup ? 'group' : 'array'} yet. If you're using ngModel,
    you may want to check next tick (e.g. use setTimeout).
  `;
}
function missingControlError(isFormGroup, key) {
  return `Cannot find form control ${describeKey(isFormGroup, key)}`;
}
function missingControlValueError(isFormGroup, key) {
  return `Must supply a value for form control ${describeKey(isFormGroup, key)}`;
}

/**
 * Reports that a control is valid, meaning that no errors exist in the input value.
 *
 * @see {@link status}
 */
const VALID = 'VALID';
/**
 * Reports that a control is invalid, meaning that an error exists in the input value.
 *
 * @see {@link status}
 */
const INVALID = 'INVALID';
/**
 * Reports that a control is pending, meaning that async validation is occurring and
 * errors are not yet available for the input value.
 *
 * @see {@link markAsPending}
 * @see {@link status}
 */
const PENDING = 'PENDING';
/**
 * Reports that a control is disabled, meaning that the control is exempt from ancestor
 * calculations of validity or value.
 *
 * @see {@link markAsDisabled}
 * @see {@link status}
 */
const DISABLED = 'DISABLED';
/**
 * Gets validators from either an options object or given validators.
 */
function pickValidators(validatorOrOpts) {
  return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.validators : validatorOrOpts) || null;
}
/**
 * Creates validator function by combining provided validators.
 */
function coerceToValidator(validator) {
  return Array.isArray(validator) ? composeValidators(validator) : validator || null;
}
/**
 * Gets async validators from either an options object or given validators.
 */
function pickAsyncValidators(asyncValidator, validatorOrOpts) {
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    if (isOptionsObj(validatorOrOpts) && asyncValidator) {
      console.warn(asyncValidatorsDroppedWithOptsWarning);
    }
  }
  return (isOptionsObj(validatorOrOpts) ? validatorOrOpts.asyncValidators : asyncValidator) || null;
}
/**
 * Creates async validator function by combining provided async validators.
 */
function coerceToAsyncValidator(asyncValidator) {
  return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) : asyncValidator || null;
}
function isOptionsObj(validatorOrOpts) {
  return validatorOrOpts != null && !Array.isArray(validatorOrOpts) && typeof validatorOrOpts === 'object';
}
function assertControlPresent(parent, isGroup, key) {
  const controls = parent.controls;
  const collection = isGroup ? Object.keys(controls) : controls;
  if (!collection.length) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1000 /* RuntimeErrorCode.NO_CONTROLS */, typeof ngDevMode === 'undefined' || ngDevMode ? noControlsError(isGroup) : '');
  }
  if (!controls[key]) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1001 /* RuntimeErrorCode.MISSING_CONTROL */, typeof ngDevMode === 'undefined' || ngDevMode ? missingControlError(isGroup, key) : '');
  }
}
function assertAllValuesPresent(control, isGroup, value) {
  control._forEachChild((_, key) => {
    if (value[key] === undefined) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1002 /* RuntimeErrorCode.MISSING_CONTROL_VALUE */, typeof ngDevMode === 'undefined' || ngDevMode ? missingControlValueError(isGroup, key) : '');
    }
  });
}
// clang-format on
/**
 * This is the base class for `FormControl`, `FormGroup`, and `FormArray`.
 *
 * It provides some of the shared behavior that all controls and groups of controls have, like
 * running validators, calculating status, and resetting state. It also defines the properties
 * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
 * instantiated directly.
 *
 * The first type parameter TValue represents the value type of the control (`control.value`).
 * The optional type parameter TRawValue  represents the raw value type (`control.getRawValue()`).
 *
 * @see [Forms Guide](/guide/forms)
 * @see [Reactive Forms Guide](/guide/reactive-forms)
 * @see [Dynamic Forms Guide](/guide/dynamic-form)
 *
 * @publicApi
 */
class AbstractControl {
  /**
   * Initialize the AbstractControl instance.
   *
   * @param validators The function or array of functions that is used to determine the validity of
   *     this control synchronously.
   * @param asyncValidators The function or array of functions that is used to determine validity of
   *     this control asynchronously.
   */
  constructor(validators, asyncValidators) {
    /** @internal */
    this._pendingDirty = false;
    /**
     * Indicates that a control has its own pending asynchronous validation in progress.
     *
     * @internal
     */
    this._hasOwnPendingAsyncValidator = false;
    /** @internal */
    this._pendingTouched = false;
    /** @internal */
    this._onCollectionChange = () => {};
    this._parent = null;
    /**
     * A control is `pristine` if the user has not yet changed
     * the value in the UI.
     *
     * @returns True if the user has not yet changed the value in the UI; compare `dirty`.
     * Programmatic changes to a control's value do not mark it dirty.
     */
    this.pristine = true;
    /**
     * True if the control is marked as `touched`.
     *
     * A control is marked `touched` once the user has triggered
     * a `blur` event on it.
     */
    this.touched = false;
    /** @internal */
    this._onDisabledChange = [];
    this._assignValidators(validators);
    this._assignAsyncValidators(asyncValidators);
  }
  /**
   * Returns the function that is used to determine the validity of this control synchronously.
   * If multiple validators have been added, this will be a single composed function.
   * See `Validators.compose()` for additional information.
   */
  get validator() {
    return this._composedValidatorFn;
  }
  set validator(validatorFn) {
    this._rawValidators = this._composedValidatorFn = validatorFn;
  }
  /**
   * Returns the function that is used to determine the validity of this control asynchronously.
   * If multiple validators have been added, this will be a single composed function.
   * See `Validators.compose()` for additional information.
   */
  get asyncValidator() {
    return this._composedAsyncValidatorFn;
  }
  set asyncValidator(asyncValidatorFn) {
    this._rawAsyncValidators = this._composedAsyncValidatorFn = asyncValidatorFn;
  }
  /**
   * The parent control.
   */
  get parent() {
    return this._parent;
  }
  /**
   * A control is `valid` when its `status` is `VALID`.
   *
   * @see {@link AbstractControl.status}
   *
   * @returns True if the control has passed all of its validation tests,
   * false otherwise.
   */
  get valid() {
    return this.status === VALID;
  }
  /**
   * A control is `invalid` when its `status` is `INVALID`.
   *
   * @see {@link AbstractControl.status}
   *
   * @returns True if this control has failed one or more of its validation checks,
   * false otherwise.
   */
  get invalid() {
    return this.status === INVALID;
  }
  /**
   * A control is `pending` when its `status` is `PENDING`.
   *
   * @see {@link AbstractControl.status}
   *
   * @returns True if this control is in the process of conducting a validation check,
   * false otherwise.
   */
  get pending() {
    return this.status == PENDING;
  }
  /**
   * A control is `disabled` when its `status` is `DISABLED`.
   *
   * Disabled controls are exempt from validation checks and
   * are not included in the aggregate value of their ancestor
   * controls.
   *
   * @see {@link AbstractControl.status}
   *
   * @returns True if the control is disabled, false otherwise.
   */
  get disabled() {
    return this.status === DISABLED;
  }
  /**
   * A control is `enabled` as long as its `status` is not `DISABLED`.
   *
   * @returns True if the control has any status other than 'DISABLED',
   * false if the status is 'DISABLED'.
   *
   * @see {@link AbstractControl.status}
   *
   */
  get enabled() {
    return this.status !== DISABLED;
  }
  /**
   * A control is `dirty` if the user has changed the value
   * in the UI.
   *
   * @returns True if the user has changed the value of this control in the UI; compare `pristine`.
   * Programmatic changes to a control's value do not mark it dirty.
   */
  get dirty() {
    return !this.pristine;
  }
  /**
   * True if the control has not been marked as touched
   *
   * A control is `untouched` if the user has not yet triggered
   * a `blur` event on it.
   */
  get untouched() {
    return !this.touched;
  }
  /**
   * Reports the update strategy of the `AbstractControl` (meaning
   * the event on which the control updates itself).
   * Possible values: `'change'` | `'blur'` | `'submit'`
   * Default value: `'change'`
   */
  get updateOn() {
    return this._updateOn ? this._updateOn : this.parent ? this.parent.updateOn : 'change';
  }
  /**
   * Sets the synchronous validators that are active on this control.  Calling
   * this overwrites any existing synchronous validators.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * If you want to add a new validator without affecting existing ones, consider
   * using `addValidators()` method instead.
   */
  setValidators(validators) {
    this._assignValidators(validators);
  }
  /**
   * Sets the asynchronous validators that are active on this control. Calling this
   * overwrites any existing asynchronous validators.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * If you want to add a new validator without affecting existing ones, consider
   * using `addAsyncValidators()` method instead.
   */
  setAsyncValidators(validators) {
    this._assignAsyncValidators(validators);
  }
  /**
   * Add a synchronous validator or validators to this control, without affecting other validators.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * Adding a validator that already exists will have no effect. If duplicate validator functions
   * are present in the `validators` array, only the first instance would be added to a form
   * control.
   *
   * @param validators The new validator function or functions to add to this control.
   */
  addValidators(validators) {
    this.setValidators(addValidators(validators, this._rawValidators));
  }
  /**
   * Add an asynchronous validator or validators to this control, without affecting other
   * validators.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * Adding a validator that already exists will have no effect.
   *
   * @param validators The new asynchronous validator function or functions to add to this control.
   */
  addAsyncValidators(validators) {
    this.setAsyncValidators(addValidators(validators, this._rawAsyncValidators));
  }
  /**
   * Remove a synchronous validator from this control, without affecting other validators.
   * Validators are compared by function reference; you must pass a reference to the exact same
   * validator function as the one that was originally set. If a provided validator is not found,
   * it is ignored.
   *
   * @usageNotes
   *
   * ### Reference to a ValidatorFn
   *
   * ```
   * // Reference to the RequiredValidator
   * const ctrl = new FormControl<string | null>('', Validators.required);
   * ctrl.removeValidators(Validators.required);
   *
   * // Reference to anonymous function inside MinValidator
   * const minValidator = Validators.min(3);
   * const ctrl = new FormControl<string | null>('', minValidator);
   * expect(ctrl.hasValidator(minValidator)).toEqual(true)
   * expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
   *
   * ctrl.removeValidators(minValidator);
   * ```
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * @param validators The validator or validators to remove.
   */
  removeValidators(validators) {
    this.setValidators(removeValidators(validators, this._rawValidators));
  }
  /**
   * Remove an asynchronous validator from this control, without affecting other validators.
   * Validators are compared by function reference; you must pass a reference to the exact same
   * validator function as the one that was originally set. If a provided validator is not found, it
   * is ignored.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   * @param validators The asynchronous validator or validators to remove.
   */
  removeAsyncValidators(validators) {
    this.setAsyncValidators(removeValidators(validators, this._rawAsyncValidators));
  }
  /**
   * Check whether a synchronous validator function is present on this control. The provided
   * validator must be a reference to the exact same function that was provided.
   *
   * @usageNotes
   *
   * ### Reference to a ValidatorFn
   *
   * ```
   * // Reference to the RequiredValidator
   * const ctrl = new FormControl<number | null>(0, Validators.required);
   * expect(ctrl.hasValidator(Validators.required)).toEqual(true)
   *
   * // Reference to anonymous function inside MinValidator
   * const minValidator = Validators.min(3);
   * const ctrl = new FormControl<number | null>(0, minValidator);
   * expect(ctrl.hasValidator(minValidator)).toEqual(true)
   * expect(ctrl.hasValidator(Validators.min(3))).toEqual(false)
   * ```
   *
   * @param validator The validator to check for presence. Compared by function reference.
   * @returns Whether the provided validator was found on this control.
   */
  hasValidator(validator) {
    return hasValidator(this._rawValidators, validator);
  }
  /**
   * Check whether an asynchronous validator function is present on this control. The provided
   * validator must be a reference to the exact same function that was provided.
   *
   * @param validator The asynchronous validator to check for presence. Compared by function
   *     reference.
   * @returns Whether the provided asynchronous validator was found on this control.
   */
  hasAsyncValidator(validator) {
    return hasValidator(this._rawAsyncValidators, validator);
  }
  /**
   * Empties out the synchronous validator list.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   */
  clearValidators() {
    this.validator = null;
  }
  /**
   * Empties out the async validator list.
   *
   * When you add or remove a validator at run time, you must call
   * `updateValueAndValidity()` for the new validation to take effect.
   *
   */
  clearAsyncValidators() {
    this.asyncValidator = null;
  }
  /**
   * Marks the control as `touched`. A control is touched by focus and
   * blur events that do not change the value.
   *
   * @see {@link markAsUntouched()}
   * @see {@link markAsDirty()}
   * @see {@link markAsPristine()}
   *
   * @param opts Configuration options that determine how the control propagates changes
   * and emits events after marking is applied.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   */
  markAsTouched(opts = {}) {
    this.touched = true;
    if (this._parent && !opts.onlySelf) {
      this._parent.markAsTouched(opts);
    }
  }
  /**
   * Marks the control and all its descendant controls as `touched`.
   * @see {@link markAsTouched()}
   */
  markAllAsTouched() {
    this.markAsTouched({
      onlySelf: true
    });
    this._forEachChild(control => control.markAllAsTouched());
  }
  /**
   * Marks the control as `untouched`.
   *
   * If the control has any children, also marks all children as `untouched`
   * and recalculates the `touched` status of all parent controls.
   *
   * @see {@link markAsTouched()}
   * @see {@link markAsDirty()}
   * @see {@link markAsPristine()}
   *
   * @param opts Configuration options that determine how the control propagates changes
   * and emits events after the marking is applied.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   */
  markAsUntouched(opts = {}) {
    this.touched = false;
    this._pendingTouched = false;
    this._forEachChild(control => {
      control.markAsUntouched({
        onlySelf: true
      });
    });
    if (this._parent && !opts.onlySelf) {
      this._parent._updateTouched(opts);
    }
  }
  /**
   * Marks the control as `dirty`. A control becomes dirty when
   * the control's value is changed through the UI; compare `markAsTouched`.
   *
   * @see {@link markAsTouched()}
   * @see {@link markAsUntouched()}
   * @see {@link markAsPristine()}
   *
   * @param opts Configuration options that determine how the control propagates changes
   * and emits events after marking is applied.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   */
  markAsDirty(opts = {}) {
    this.pristine = false;
    if (this._parent && !opts.onlySelf) {
      this._parent.markAsDirty(opts);
    }
  }
  /**
   * Marks the control as `pristine`.
   *
   * If the control has any children, marks all children as `pristine`,
   * and recalculates the `pristine` status of all parent
   * controls.
   *
   * @see {@link markAsTouched()}
   * @see {@link markAsUntouched()}
   * @see {@link markAsDirty()}
   *
   * @param opts Configuration options that determine how the control emits events after
   * marking is applied.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   */
  markAsPristine(opts = {}) {
    this.pristine = true;
    this._pendingDirty = false;
    this._forEachChild(control => {
      control.markAsPristine({
        onlySelf: true
      });
    });
    if (this._parent && !opts.onlySelf) {
      this._parent._updatePristine(opts);
    }
  }
  /**
   * Marks the control as `pending`.
   *
   * A control is pending while the control performs async validation.
   *
   * @see {@link AbstractControl.status}
   *
   * @param opts Configuration options that determine how the control propagates changes and
   * emits events after marking is applied.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   * * `emitEvent`: When true or not supplied (the default), the `statusChanges`
   * observable emits an event with the latest status the control is marked pending.
   * When false, no events are emitted.
   *
   */
  markAsPending(opts = {}) {
    this.status = PENDING;
    if (opts.emitEvent !== false) {
      this.statusChanges.emit(this.status);
    }
    if (this._parent && !opts.onlySelf) {
      this._parent.markAsPending(opts);
    }
  }
  /**
   * Disables the control. This means the control is exempt from validation checks and
   * excluded from the aggregate value of any parent. Its status is `DISABLED`.
   *
   * If the control has children, all children are also disabled.
   *
   * @see {@link AbstractControl.status}
   *
   * @param opts Configuration options that determine how the control propagates
   * changes and emits events after the control is disabled.
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control is disabled.
   * When false, no events are emitted.
   */
  disable(opts = {}) {
    // If parent has been marked artificially dirty we don't want to re-calculate the
    // parent's dirtiness based on the children.
    const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
    this.status = DISABLED;
    this.errors = null;
    this._forEachChild(control => {
      control.disable({
        ...opts,
        onlySelf: true
      });
    });
    this._updateValue();
    if (opts.emitEvent !== false) {
      this.valueChanges.emit(this.value);
      this.statusChanges.emit(this.status);
    }
    this._updateAncestors({
      ...opts,
      skipPristineCheck
    });
    this._onDisabledChange.forEach(changeFn => changeFn(true));
  }
  /**
   * Enables the control. This means the control is included in validation checks and
   * the aggregate value of its parent. Its status recalculates based on its value and
   * its validators.
   *
   * By default, if the control has children, all children are enabled.
   *
   * @see {@link AbstractControl.status}
   *
   * @param opts Configure options that control how the control propagates changes and
   * emits events when marked as untouched
   * * `onlySelf`: When true, mark only this control. When false or not supplied,
   * marks all direct ancestors. Default is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control is enabled.
   * When false, no events are emitted.
   */
  enable(opts = {}) {
    // If parent has been marked artificially dirty we don't want to re-calculate the
    // parent's dirtiness based on the children.
    const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
    this.status = VALID;
    this._forEachChild(control => {
      control.enable({
        ...opts,
        onlySelf: true
      });
    });
    this.updateValueAndValidity({
      onlySelf: true,
      emitEvent: opts.emitEvent
    });
    this._updateAncestors({
      ...opts,
      skipPristineCheck
    });
    this._onDisabledChange.forEach(changeFn => changeFn(false));
  }
  _updateAncestors(opts) {
    if (this._parent && !opts.onlySelf) {
      this._parent.updateValueAndValidity(opts);
      if (!opts.skipPristineCheck) {
        this._parent._updatePristine();
      }
      this._parent._updateTouched();
    }
  }
  /**
   * Sets the parent of the control
   *
   * @param parent The new parent.
   */
  setParent(parent) {
    this._parent = parent;
  }
  /**
   * The raw value of this control. For most control implementations, the raw value will include
   * disabled children.
   */
  getRawValue() {
    return this.value;
  }
  /**
   * Recalculates the value and validation status of the control.
   *
   * By default, it also updates the value and validity of its ancestors.
   *
   * @param opts Configuration options determine how the control propagates changes and emits events
   * after updates and validity checks are applied.
   * * `onlySelf`: When true, only update this control. When false or not supplied,
   * update all direct ancestors. Default is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control is updated.
   * When false, no events are emitted.
   */
  updateValueAndValidity(opts = {}) {
    this._setInitialStatus();
    this._updateValue();
    if (this.enabled) {
      this._cancelExistingSubscription();
      this.errors = this._runValidator();
      this.status = this._calculateStatus();
      if (this.status === VALID || this.status === PENDING) {
        this._runAsyncValidator(opts.emitEvent);
      }
    }
    if (opts.emitEvent !== false) {
      this.valueChanges.emit(this.value);
      this.statusChanges.emit(this.status);
    }
    if (this._parent && !opts.onlySelf) {
      this._parent.updateValueAndValidity(opts);
    }
  }
  /** @internal */
  _updateTreeValidity(opts = {
    emitEvent: true
  }) {
    this._forEachChild(ctrl => ctrl._updateTreeValidity(opts));
    this.updateValueAndValidity({
      onlySelf: true,
      emitEvent: opts.emitEvent
    });
  }
  _setInitialStatus() {
    this.status = this._allControlsDisabled() ? DISABLED : VALID;
  }
  _runValidator() {
    return this.validator ? this.validator(this) : null;
  }
  _runAsyncValidator(emitEvent) {
    if (this.asyncValidator) {
      this.status = PENDING;
      this._hasOwnPendingAsyncValidator = true;
      const obs = toObservable(this.asyncValidator(this));
      this._asyncValidationSubscription = obs.subscribe(errors => {
        this._hasOwnPendingAsyncValidator = false;
        // This will trigger the recalculation of the validation status, which depends on
        // the state of the asynchronous validation (whether it is in progress or not). So, it is
        // necessary that we have updated the `_hasOwnPendingAsyncValidator` boolean flag first.
        this.setErrors(errors, {
          emitEvent
        });
      });
    }
  }
  _cancelExistingSubscription() {
    if (this._asyncValidationSubscription) {
      this._asyncValidationSubscription.unsubscribe();
      this._hasOwnPendingAsyncValidator = false;
    }
  }
  /**
   * Sets errors on a form control when running validations manually, rather than automatically.
   *
   * Calling `setErrors` also updates the validity of the parent control.
   *
   * @param opts Configuration options that determine how the control propagates
   * changes and emits events after the control errors are set.
   * * `emitEvent`: When true or not supplied (the default), the `statusChanges`
   * observable emits an event after the errors are set.
   *
   * @usageNotes
   *
   * ### Manually set the errors for a control
   *
   * ```
   * const login = new FormControl('someLogin');
   * login.setErrors({
   *   notUnique: true
   * });
   *
   * expect(login.valid).toEqual(false);
   * expect(login.errors).toEqual({ notUnique: true });
   *
   * login.setValue('someOtherLogin');
   *
   * expect(login.valid).toEqual(true);
   * ```
   */
  setErrors(errors, opts = {}) {
    this.errors = errors;
    this._updateControlsErrors(opts.emitEvent !== false);
  }
  /**
   * Retrieves a child control given the control's name or path.
   *
   * @param path A dot-delimited string or array of string/number values that define the path to the
   * control. If a string is provided, passing it as a string literal will result in improved type
   * information. Likewise, if an array is provided, passing it `as const` will cause improved type
   * information to be available.
   *
   * @usageNotes
   * ### Retrieve a nested control
   *
   * For example, to get a `name` control nested within a `person` sub-group:
   *
   * * `this.form.get('person.name');`
   *
   * -OR-
   *
   * * `this.form.get(['person', 'name'] as const);` // `as const` gives improved typings
   *
   * ### Retrieve a control in a FormArray
   *
   * When accessing an element inside a FormArray, you can use an element index.
   * For example, to get a `price` control from the first element in an `items` array you can use:
   *
   * * `this.form.get('items.0.price');`
   *
   * -OR-
   *
   * * `this.form.get(['items', 0, 'price']);`
   */
  get(path) {
    let currPath = path;
    if (currPath == null) return null;
    if (!Array.isArray(currPath)) currPath = currPath.split('.');
    if (currPath.length === 0) return null;
    return currPath.reduce((control, name) => control && control._find(name), this);
  }
  /**
   * @description
   * Reports error data for the control with the given path.
   *
   * @param errorCode The code of the error to check
   * @param path A list of control names that designates how to move from the current control
   * to the control that should be queried for errors.
   *
   * @usageNotes
   * For example, for the following `FormGroup`:
   *
   * ```
   * form = new FormGroup({
   *   address: new FormGroup({ street: new FormControl() })
   * });
   * ```
   *
   * The path to the 'street' control from the root form would be 'address' -> 'street'.
   *
   * It can be provided to this method in one of two formats:
   *
   * 1. An array of string control names, e.g. `['address', 'street']`
   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
   *
   * @returns error data for that particular error. If the control or error is not present,
   * null is returned.
   */
  getError(errorCode, path) {
    const control = path ? this.get(path) : this;
    return control && control.errors ? control.errors[errorCode] : null;
  }
  /**
   * @description
   * Reports whether the control with the given path has the error specified.
   *
   * @param errorCode The code of the error to check
   * @param path A list of control names that designates how to move from the current control
   * to the control that should be queried for errors.
   *
   * @usageNotes
   * For example, for the following `FormGroup`:
   *
   * ```
   * form = new FormGroup({
   *   address: new FormGroup({ street: new FormControl() })
   * });
   * ```
   *
   * The path to the 'street' control from the root form would be 'address' -> 'street'.
   *
   * It can be provided to this method in one of two formats:
   *
   * 1. An array of string control names, e.g. `['address', 'street']`
   * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
   *
   * If no path is given, this method checks for the error on the current control.
   *
   * @returns whether the given error is present in the control at the given path.
   *
   * If the control is not present, false is returned.
   */
  hasError(errorCode, path) {
    return !!this.getError(errorCode, path);
  }
  /**
   * Retrieves the top-level ancestor of this control.
   */
  get root() {
    let x = this;
    while (x._parent) {
      x = x._parent;
    }
    return x;
  }
  /** @internal */
  _updateControlsErrors(emitEvent) {
    this.status = this._calculateStatus();
    if (emitEvent) {
      this.statusChanges.emit(this.status);
    }
    if (this._parent) {
      this._parent._updateControlsErrors(emitEvent);
    }
  }
  /** @internal */
  _initObservables() {
    this.valueChanges = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.statusChanges = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  _calculateStatus() {
    if (this._allControlsDisabled()) return DISABLED;
    if (this.errors) return INVALID;
    if (this._hasOwnPendingAsyncValidator || this._anyControlsHaveStatus(PENDING)) return PENDING;
    if (this._anyControlsHaveStatus(INVALID)) return INVALID;
    return VALID;
  }
  /** @internal */
  _anyControlsHaveStatus(status) {
    return this._anyControls(control => control.status === status);
  }
  /** @internal */
  _anyControlsDirty() {
    return this._anyControls(control => control.dirty);
  }
  /** @internal */
  _anyControlsTouched() {
    return this._anyControls(control => control.touched);
  }
  /** @internal */
  _updatePristine(opts = {}) {
    this.pristine = !this._anyControlsDirty();
    if (this._parent && !opts.onlySelf) {
      this._parent._updatePristine(opts);
    }
  }
  /** @internal */
  _updateTouched(opts = {}) {
    this.touched = this._anyControlsTouched();
    if (this._parent && !opts.onlySelf) {
      this._parent._updateTouched(opts);
    }
  }
  /** @internal */
  _registerOnCollectionChange(fn) {
    this._onCollectionChange = fn;
  }
  /** @internal */
  _setUpdateStrategy(opts) {
    if (isOptionsObj(opts) && opts.updateOn != null) {
      this._updateOn = opts.updateOn;
    }
  }
  /**
   * Check to see if parent has been marked artificially dirty.
   *
   * @internal
   */
  _parentMarkedDirty(onlySelf) {
    const parentDirty = this._parent && this._parent.dirty;
    return !onlySelf && !!parentDirty && !this._parent._anyControlsDirty();
  }
  /** @internal */
  _find(name) {
    return null;
  }
  /**
   * Internal implementation of the `setValidators` method. Needs to be separated out into a
   * different method, because it is called in the constructor and it can break cases where
   * a control is extended.
   */
  _assignValidators(validators) {
    this._rawValidators = Array.isArray(validators) ? validators.slice() : validators;
    this._composedValidatorFn = coerceToValidator(this._rawValidators);
  }
  /**
   * Internal implementation of the `setAsyncValidators` method. Needs to be separated out into a
   * different method, because it is called in the constructor and it can break cases where
   * a control is extended.
   */
  _assignAsyncValidators(validators) {
    this._rawAsyncValidators = Array.isArray(validators) ? validators.slice() : validators;
    this._composedAsyncValidatorFn = coerceToAsyncValidator(this._rawAsyncValidators);
  }
}

/**
 * Tracks the value and validity state of a group of `FormControl` instances.
 *
 * A `FormGroup` aggregates the values of each child `FormControl` into one object,
 * with each control name as the key.  It calculates its status by reducing the status values
 * of its children. For example, if one of the controls in a group is invalid, the entire
 * group becomes invalid.
 *
 * `FormGroup` is one of the four fundamental building blocks used to define forms in Angular,
 * along with `FormControl`, `FormArray`, and `FormRecord`.
 *
 * When instantiating a `FormGroup`, pass in a collection of child controls as the first
 * argument. The key for each child registers the name for the control.
 *
 * `FormGroup` is intended for use cases where the keys are known ahead of time.
 * If you need to dynamically add and remove controls, use {@link FormRecord} instead.
 *
 * `FormGroup` accepts an optional type parameter `TControl`, which is an object type with inner
 * control types as values.
 *
 * @usageNotes
 *
 * ### Create a form group with 2 controls
 *
 * ```
 * const form = new FormGroup({
 *   first: new FormControl('Nancy', Validators.minLength(2)),
 *   last: new FormControl('Drew'),
 * });
 *
 * console.log(form.value);   // {first: 'Nancy', last; 'Drew'}
 * console.log(form.status);  // 'VALID'
 * ```
 *
 * ### The type argument, and optional controls
 *
 * `FormGroup` accepts one generic argument, which is an object containing its inner controls.
 * This type will usually be inferred automatically, but you can always specify it explicitly if you
 * wish.
 *
 * If you have controls that are optional (i.e. they can be removed, you can use the `?` in the
 * type):
 *
 * ```
 * const form = new FormGroup<{
 *   first: FormControl<string|null>,
 *   middle?: FormControl<string|null>, // Middle name is optional.
 *   last: FormControl<string|null>,
 * }>({
 *   first: new FormControl('Nancy'),
 *   last: new FormControl('Drew'),
 * });
 * ```
 *
 * ### Create a form group with a group-level validator
 *
 * You include group-level validators as the second arg, or group-level async
 * validators as the third arg. These come in handy when you want to perform validation
 * that considers the value of more than one child control.
 *
 * ```
 * const form = new FormGroup({
 *   password: new FormControl('', Validators.minLength(2)),
 *   passwordConfirm: new FormControl('', Validators.minLength(2)),
 * }, passwordMatchValidator);
 *
 *
 * function passwordMatchValidator(g: FormGroup) {
 *    return g.get('password').value === g.get('passwordConfirm').value
 *       ? null : {'mismatch': true};
 * }
 * ```
 *
 * Like `FormControl` instances, you choose to pass in
 * validators and async validators as part of an options object.
 *
 * ```
 * const form = new FormGroup({
 *   password: new FormControl('')
 *   passwordConfirm: new FormControl('')
 * }, { validators: passwordMatchValidator, asyncValidators: otherValidator });
 * ```
 *
 * ### Set the updateOn property for all controls in a form group
 *
 * The options object is used to set a default value for each child
 * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
 * group level, all child controls default to 'blur', unless the child
 * has explicitly specified a different `updateOn` value.
 *
 * ```ts
 * const c = new FormGroup({
 *   one: new FormControl()
 * }, { updateOn: 'blur' });
 * ```
 *
 * ### Using a FormGroup with optional controls
 *
 * It is possible to have optional controls in a FormGroup. An optional control can be removed later
 * using `removeControl`, and can be omitted when calling `reset`. Optional controls must be
 * declared optional in the group's type.
 *
 * ```ts
 * const c = new FormGroup<{one?: FormControl<string>}>({
 *   one: new FormControl('')
 * });
 * ```
 *
 * Notice that `c.value.one` has type `string|null|undefined`. This is because calling `c.reset({})`
 * without providing the optional key `one` will cause it to become `null`.
 *
 * @publicApi
 */
class FormGroup extends AbstractControl {
  /**
   * Creates a new `FormGroup` instance.
   *
   * @param controls A collection of child controls. The key for each child is the name
   * under which it is registered.
   *
   * @param validatorOrOpts A synchronous validator function, or an array of
   * such functions, or an `AbstractControlOptions` object that contains validation functions
   * and a validation trigger.
   *
   * @param asyncValidator A single async validator or array of async validator functions
   *
   */
  constructor(controls, validatorOrOpts, asyncValidator) {
    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
    (typeof ngDevMode === 'undefined' || ngDevMode) && validateFormGroupControls(controls);
    this.controls = controls;
    this._initObservables();
    this._setUpdateStrategy(validatorOrOpts);
    this._setUpControls();
    this.updateValueAndValidity({
      onlySelf: true,
      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
      // `VALID` or `INVALID`. The status should be broadcasted via the `statusChanges` observable,
      // so we set `emitEvent` to `true` to allow that during the control creation process.
      emitEvent: !!this.asyncValidator
    });
  }
  registerControl(name, control) {
    if (this.controls[name]) return this.controls[name];
    this.controls[name] = control;
    control.setParent(this);
    control._registerOnCollectionChange(this._onCollectionChange);
    return control;
  }
  addControl(name, control, options = {}) {
    this.registerControl(name, control);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
    this._onCollectionChange();
  }
  /**
   * Remove a control from this group. In a strongly-typed group, required controls cannot be
   * removed.
   *
   * This method also updates the value and validity of the control.
   *
   * @param name The control name to remove from the collection
   * @param options Specifies whether this FormGroup instance should emit events after a
   *     control is removed.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control is
   * removed. When false, no events are emitted.
   */
  removeControl(name, options = {}) {
    if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => {});
    delete this.controls[name];
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
    this._onCollectionChange();
  }
  setControl(name, control, options = {}) {
    if (this.controls[name]) this.controls[name]._registerOnCollectionChange(() => {});
    delete this.controls[name];
    if (control) this.registerControl(name, control);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
    this._onCollectionChange();
  }
  contains(controlName) {
    return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
  }
  /**
   * Sets the value of the `FormGroup`. It accepts an object that matches
   * the structure of the group, with control names as keys.
   *
   * @usageNotes
   * ### Set the complete value for the form group
   *
   * ```
   * const form = new FormGroup({
   *   first: new FormControl(),
   *   last: new FormControl()
   * });
   *
   * console.log(form.value);   // {first: null, last: null}
   *
   * form.setValue({first: 'Nancy', last: 'Drew'});
   * console.log(form.value);   // {first: 'Nancy', last: 'Drew'}
   * ```
   *
   * @throws When strict checks fail, such as setting the value of a control
   * that doesn't exist or if you exclude a value of a control that does exist.
   *
   * @param value The new value for the control that matches the structure of the group.
   * @param options Configuration options that determine how the control propagates changes
   * and emits events after the value changes.
   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
   * updateValueAndValidity} method.
   *
   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
   * false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control value is updated.
   * When false, no events are emitted.
   */
  setValue(value, options = {}) {
    assertAllValuesPresent(this, true, value);
    Object.keys(value).forEach(name => {
      assertControlPresent(this, true, name);
      this.controls[name].setValue(value[name], {
        onlySelf: true,
        emitEvent: options.emitEvent
      });
    });
    this.updateValueAndValidity(options);
  }
  /**
   * Patches the value of the `FormGroup`. It accepts an object with control
   * names as keys, and does its best to match the values to the correct controls
   * in the group.
   *
   * It accepts both super-sets and sub-sets of the group without throwing an error.
   *
   * @usageNotes
   * ### Patch the value for a form group
   *
   * ```
   * const form = new FormGroup({
   *    first: new FormControl(),
   *    last: new FormControl()
   * });
   * console.log(form.value);   // {first: null, last: null}
   *
   * form.patchValue({first: 'Nancy'});
   * console.log(form.value);   // {first: 'Nancy', last: null}
   * ```
   *
   * @param value The object that matches the structure of the group.
   * @param options Configuration options that determine how the control propagates changes and
   * emits events after the value is patched.
   * * `onlySelf`: When true, each change only affects this control and not its parent. Default is
   * true.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control value
   * is updated. When false, no events are emitted. The configuration options are passed to
   * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method.
   */
  patchValue(value, options = {}) {
    // Even though the `value` argument type doesn't allow `null` and `undefined` values, the
    // `patchValue` can be called recursively and inner data structures might have these values, so
    // we just ignore such cases when a field containing FormGroup instance receives `null` or
    // `undefined` as a value.
    if (value == null /* both `null` and `undefined` */) return;
    Object.keys(value).forEach(name => {
      // The compiler cannot see through the uninstantiated conditional type of `this.controls`, so
      // `as any` is required.
      const control = this.controls[name];
      if (control) {
        control.patchValue(/* Guaranteed to be present, due to the outer forEach. */value[name], {
          onlySelf: true,
          emitEvent: options.emitEvent
        });
      }
    });
    this.updateValueAndValidity(options);
  }
  /**
   * Resets the `FormGroup`, marks all descendants `pristine` and `untouched` and sets
   * the value of all descendants to their default values, or null if no defaults were provided.
   *
   * You reset to a specific form state by passing in a map of states
   * that matches the structure of your form, with control names as keys. The state
   * is a standalone value or a form state object with both a value and a disabled
   * status.
   *
   * @param value Resets the control with an initial value,
   * or an object that defines the initial value and disabled state.
   *
   * @param options Configuration options that determine how the control propagates changes
   * and emits events when the group is reset.
   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
   * false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control is reset.
   * When false, no events are emitted.
   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
   * updateValueAndValidity} method.
   *
   * @usageNotes
   *
   * ### Reset the form group values
   *
   * ```ts
   * const form = new FormGroup({
   *   first: new FormControl('first name'),
   *   last: new FormControl('last name')
   * });
   *
   * console.log(form.value);  // {first: 'first name', last: 'last name'}
   *
   * form.reset({ first: 'name', last: 'last name' });
   *
   * console.log(form.value);  // {first: 'name', last: 'last name'}
   * ```
   *
   * ### Reset the form group values and disabled status
   *
   * ```
   * const form = new FormGroup({
   *   first: new FormControl('first name'),
   *   last: new FormControl('last name')
   * });
   *
   * form.reset({
   *   first: {value: 'name', disabled: true},
   *   last: 'last'
   * });
   *
   * console.log(form.value);  // {last: 'last'}
   * console.log(form.get('first').status);  // 'DISABLED'
   * ```
   */
  reset(value = {}, options = {}) {
    this._forEachChild((control, name) => {
      control.reset(value ? value[name] : null, {
        onlySelf: true,
        emitEvent: options.emitEvent
      });
    });
    this._updatePristine(options);
    this._updateTouched(options);
    this.updateValueAndValidity(options);
  }
  /**
   * The aggregate value of the `FormGroup`, including any disabled controls.
   *
   * Retrieves all values regardless of disabled status.
   */
  getRawValue() {
    return this._reduceChildren({}, (acc, control, name) => {
      acc[name] = control.getRawValue();
      return acc;
    });
  }
  /** @internal */
  _syncPendingControls() {
    let subtreeUpdated = this._reduceChildren(false, (updated, child) => {
      return child._syncPendingControls() ? true : updated;
    });
    if (subtreeUpdated) this.updateValueAndValidity({
      onlySelf: true
    });
    return subtreeUpdated;
  }
  /** @internal */
  _forEachChild(cb) {
    Object.keys(this.controls).forEach(key => {
      // The list of controls can change (for ex. controls might be removed) while the loop
      // is running (as a result of invoking Forms API in `valueChanges` subscription), so we
      // have to null check before invoking the callback.
      const control = this.controls[key];
      control && cb(control, key);
    });
  }
  /** @internal */
  _setUpControls() {
    this._forEachChild(control => {
      control.setParent(this);
      control._registerOnCollectionChange(this._onCollectionChange);
    });
  }
  /** @internal */
  _updateValue() {
    this.value = this._reduceValue();
  }
  /** @internal */
  _anyControls(condition) {
    for (const [controlName, control] of Object.entries(this.controls)) {
      if (this.contains(controlName) && condition(control)) {
        return true;
      }
    }
    return false;
  }
  /** @internal */
  _reduceValue() {
    let acc = {};
    return this._reduceChildren(acc, (acc, control, name) => {
      if (control.enabled || this.disabled) {
        acc[name] = control.value;
      }
      return acc;
    });
  }
  /** @internal */
  _reduceChildren(initValue, fn) {
    let res = initValue;
    this._forEachChild((control, name) => {
      res = fn(res, control, name);
    });
    return res;
  }
  /** @internal */
  _allControlsDisabled() {
    for (const controlName of Object.keys(this.controls)) {
      if (this.controls[controlName].enabled) {
        return false;
      }
    }
    return Object.keys(this.controls).length > 0 || this.disabled;
  }
  /** @internal */
  _find(name) {
    return this.controls.hasOwnProperty(name) ? this.controls[name] : null;
  }
}
/**
 * Will validate that none of the controls has a key with a dot
 * Throws other wise
 */
function validateFormGroupControls(controls) {
  const invalidKeys = Object.keys(controls).filter(key => key.includes('.'));
  if (invalidKeys.length > 0) {
    // TODO: make this an error once there are no more uses in G3
    console.warn(`FormGroup keys cannot include \`.\`, please replace the keys for: ${invalidKeys.join(',')}.`);
  }
}
const UntypedFormGroup = FormGroup;
/**
 * @description
 * Asserts that the given control is an instance of `FormGroup`
 *
 * @publicApi
 */
const isFormGroup = control => control instanceof FormGroup;
/**
 * Tracks the value and validity state of a collection of `FormControl` instances, each of which has
 * the same value type.
 *
 * `FormRecord` is very similar to {@link FormGroup}, except it can be used with a dynamic keys,
 * with controls added and removed as needed.
 *
 * `FormRecord` accepts one generic argument, which describes the type of the controls it contains.
 *
 * @usageNotes
 *
 * ```
 * let numbers = new FormRecord({bill: new FormControl('415-123-456')});
 * numbers.addControl('bob', new FormControl('415-234-567'));
 * numbers.removeControl('bill');
 * ```
 *
 * @publicApi
 */
class FormRecord extends FormGroup {}
/**
 * @description
 * Asserts that the given control is an instance of `FormRecord`
 *
 * @publicApi
 */
const isFormRecord = control => control instanceof FormRecord;

/**
 * Token to provide to allow SetDisabledState to always be called when a CVA is added, regardless of
 * whether the control is disabled or enabled.
 *
 * @see {@link FormsModule#withconfig}
 */
const CALL_SET_DISABLED_STATE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('CallSetDisabledState', {
  providedIn: 'root',
  factory: () => setDisabledStateDefault
});
/**
 * Whether to use the fixed setDisabledState behavior by default.
 */
const setDisabledStateDefault = 'always';
function controlPath(name, parent) {
  return [...parent.path, name];
}
/**
 * Links a Form control and a Form directive by setting up callbacks (such as `onChange`) on both
 * instances. This function is typically invoked when form directive is being initialized.
 *
 * @param control Form control instance that should be linked.
 * @param dir Directive that should be linked with a given control.
 */
function setUpControl(control, dir, callSetDisabledState = setDisabledStateDefault) {
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    if (!control) _throwError(dir, 'Cannot find control with');
    if (!dir.valueAccessor) _throwMissingValueAccessorError(dir);
  }
  setUpValidators(control, dir);
  dir.valueAccessor.writeValue(control.value);
  // The legacy behavior only calls the CVA's `setDisabledState` if the control is disabled.
  // If the `callSetDisabledState` option is set to `always`, then this bug is fixed and
  // the method is always called.
  if (control.disabled || callSetDisabledState === 'always') {
    dir.valueAccessor.setDisabledState?.(control.disabled);
  }
  setUpViewChangePipeline(control, dir);
  setUpModelChangePipeline(control, dir);
  setUpBlurPipeline(control, dir);
  setUpDisabledChangeHandler(control, dir);
}
/**
 * Reverts configuration performed by the `setUpControl` control function.
 * Effectively disconnects form control with a given form directive.
 * This function is typically invoked when corresponding form directive is being destroyed.
 *
 * @param control Form control which should be cleaned up.
 * @param dir Directive that should be disconnected from a given control.
 * @param validateControlPresenceOnChange Flag that indicates whether onChange handler should
 *     contain asserts to verify that it's not called once directive is destroyed. We need this flag
 *     to avoid potentially breaking changes caused by better control cleanup introduced in #39235.
 */
function cleanUpControl(control, dir, validateControlPresenceOnChange = true) {
  const noop = () => {
    if (validateControlPresenceOnChange && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      _noControlError(dir);
    }
  };
  // The `valueAccessor` field is typically defined on FromControl and FormControlName directive
  // instances and there is a logic in `selectValueAccessor` function that throws if it's not the
  // case. We still check the presence of `valueAccessor` before invoking its methods to make sure
  // that cleanup works correctly if app code or tests are setup to ignore the error thrown from
  // `selectValueAccessor`. See https://github.com/angular/angular/issues/40521.
  if (dir.valueAccessor) {
    dir.valueAccessor.registerOnChange(noop);
    dir.valueAccessor.registerOnTouched(noop);
  }
  cleanUpValidators(control, dir);
  if (control) {
    dir._invokeOnDestroyCallbacks();
    control._registerOnCollectionChange(() => {});
  }
}
function registerOnValidatorChange(validators, onChange) {
  validators.forEach(validator => {
    if (validator.registerOnValidatorChange) validator.registerOnValidatorChange(onChange);
  });
}
/**
 * Sets up disabled change handler function on a given form control if ControlValueAccessor
 * associated with a given directive instance supports the `setDisabledState` call.
 *
 * @param control Form control where disabled change handler should be setup.
 * @param dir Corresponding directive instance associated with this control.
 */
function setUpDisabledChangeHandler(control, dir) {
  if (dir.valueAccessor.setDisabledState) {
    const onDisabledChange = isDisabled => {
      dir.valueAccessor.setDisabledState(isDisabled);
    };
    control.registerOnDisabledChange(onDisabledChange);
    // Register a callback function to cleanup disabled change handler
    // from a control instance when a directive is destroyed.
    dir._registerOnDestroy(() => {
      control._unregisterOnDisabledChange(onDisabledChange);
    });
  }
}
/**
 * Sets up sync and async directive validators on provided form control.
 * This function merges validators from the directive into the validators of the control.
 *
 * @param control Form control where directive validators should be setup.
 * @param dir Directive instance that contains validators to be setup.
 */
function setUpValidators(control, dir) {
  const validators = getControlValidators(control);
  if (dir.validator !== null) {
    control.setValidators(mergeValidators(validators, dir.validator));
  } else if (typeof validators === 'function') {
    // If sync validators are represented by a single validator function, we force the
    // `Validators.compose` call to happen by executing the `setValidators` function with
    // an array that contains that function. We need this to avoid possible discrepancies in
    // validators behavior, so sync validators are always processed by the `Validators.compose`.
    // Note: we should consider moving this logic inside the `setValidators` function itself, so we
    // have consistent behavior on AbstractControl API level. The same applies to the async
    // validators logic below.
    control.setValidators([validators]);
  }
  const asyncValidators = getControlAsyncValidators(control);
  if (dir.asyncValidator !== null) {
    control.setAsyncValidators(mergeValidators(asyncValidators, dir.asyncValidator));
  } else if (typeof asyncValidators === 'function') {
    control.setAsyncValidators([asyncValidators]);
  }
  // Re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
  const onValidatorChange = () => control.updateValueAndValidity();
  registerOnValidatorChange(dir._rawValidators, onValidatorChange);
  registerOnValidatorChange(dir._rawAsyncValidators, onValidatorChange);
}
/**
 * Cleans up sync and async directive validators on provided form control.
 * This function reverts the setup performed by the `setUpValidators` function, i.e.
 * removes directive-specific validators from a given control instance.
 *
 * @param control Form control from where directive validators should be removed.
 * @param dir Directive instance that contains validators to be removed.
 * @returns true if a control was updated as a result of this action.
 */
function cleanUpValidators(control, dir) {
  let isControlUpdated = false;
  if (control !== null) {
    if (dir.validator !== null) {
      const validators = getControlValidators(control);
      if (Array.isArray(validators) && validators.length > 0) {
        // Filter out directive validator function.
        const updatedValidators = validators.filter(validator => validator !== dir.validator);
        if (updatedValidators.length !== validators.length) {
          isControlUpdated = true;
          control.setValidators(updatedValidators);
        }
      }
    }
    if (dir.asyncValidator !== null) {
      const asyncValidators = getControlAsyncValidators(control);
      if (Array.isArray(asyncValidators) && asyncValidators.length > 0) {
        // Filter out directive async validator function.
        const updatedAsyncValidators = asyncValidators.filter(asyncValidator => asyncValidator !== dir.asyncValidator);
        if (updatedAsyncValidators.length !== asyncValidators.length) {
          isControlUpdated = true;
          control.setAsyncValidators(updatedAsyncValidators);
        }
      }
    }
  }
  // Clear onValidatorChange callbacks by providing a noop function.
  const noop = () => {};
  registerOnValidatorChange(dir._rawValidators, noop);
  registerOnValidatorChange(dir._rawAsyncValidators, noop);
  return isControlUpdated;
}
function setUpViewChangePipeline(control, dir) {
  dir.valueAccessor.registerOnChange(newValue => {
    control._pendingValue = newValue;
    control._pendingChange = true;
    control._pendingDirty = true;
    if (control.updateOn === 'change') updateControl(control, dir);
  });
}
function setUpBlurPipeline(control, dir) {
  dir.valueAccessor.registerOnTouched(() => {
    control._pendingTouched = true;
    if (control.updateOn === 'blur' && control._pendingChange) updateControl(control, dir);
    if (control.updateOn !== 'submit') control.markAsTouched();
  });
}
function updateControl(control, dir) {
  if (control._pendingDirty) control.markAsDirty();
  control.setValue(control._pendingValue, {
    emitModelToViewChange: false
  });
  dir.viewToModelUpdate(control._pendingValue);
  control._pendingChange = false;
}
function setUpModelChangePipeline(control, dir) {
  const onChange = (newValue, emitModelEvent) => {
    // control -> view
    dir.valueAccessor.writeValue(newValue);
    // control -> ngModel
    if (emitModelEvent) dir.viewToModelUpdate(newValue);
  };
  control.registerOnChange(onChange);
  // Register a callback function to cleanup onChange handler
  // from a control instance when a directive is destroyed.
  dir._registerOnDestroy(() => {
    control._unregisterOnChange(onChange);
  });
}
/**
 * Links a FormGroup or FormArray instance and corresponding Form directive by setting up validators
 * present in the view.
 *
 * @param control FormGroup or FormArray instance that should be linked.
 * @param dir Directive that provides view validators.
 */
function setUpFormContainer(control, dir) {
  if (control == null && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'Cannot find control with');
  setUpValidators(control, dir);
}
/**
 * Reverts the setup performed by the `setUpFormContainer` function.
 *
 * @param control FormGroup or FormArray instance that should be cleaned up.
 * @param dir Directive that provided view validators.
 * @returns true if a control was updated as a result of this action.
 */
function cleanUpFormContainer(control, dir) {
  return cleanUpValidators(control, dir);
}
function _noControlError(dir) {
  return _throwError(dir, 'There is no FormControl instance attached to form control element with');
}
function _throwError(dir, message) {
  const messageEnd = _describeControlLocation(dir);
  throw new Error(`${message} ${messageEnd}`);
}
function _describeControlLocation(dir) {
  const path = dir.path;
  if (path && path.length > 1) return `path: '${path.join(' -> ')}'`;
  if (path?.[0]) return `name: '${path}'`;
  return 'unspecified name attribute';
}
function _throwMissingValueAccessorError(dir) {
  const loc = _describeControlLocation(dir);
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](-1203 /* RuntimeErrorCode.NG_MISSING_VALUE_ACCESSOR */, `No value accessor for form control ${loc}.`);
}
function _throwInvalidValueAccessorError(dir) {
  const loc = _describeControlLocation(dir);
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1200 /* RuntimeErrorCode.NG_VALUE_ACCESSOR_NOT_PROVIDED */, `Value accessor was not provided as an array for form control with ${loc}. ` + `Check that the \`NG_VALUE_ACCESSOR\` token is configured as a \`multi: true\` provider.`);
}
function isPropertyUpdated(changes, viewModel) {
  if (!changes.hasOwnProperty('model')) return false;
  const change = changes['model'];
  if (change.isFirstChange()) return true;
  return !Object.is(viewModel, change.currentValue);
}
function isBuiltInAccessor(valueAccessor) {
  // Check if a given value accessor is an instance of a class that directly extends
  // `BuiltInControlValueAccessor` one.
  return Object.getPrototypeOf(valueAccessor.constructor) === BuiltInControlValueAccessor;
}
function syncPendingControls(form, directives) {
  form._syncPendingControls();
  directives.forEach(dir => {
    const control = dir.control;
    if (control.updateOn === 'submit' && control._pendingChange) {
      dir.viewToModelUpdate(control._pendingValue);
      control._pendingChange = false;
    }
  });
}
// TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
function selectValueAccessor(dir, valueAccessors) {
  if (!valueAccessors) return null;
  if (!Array.isArray(valueAccessors) && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwInvalidValueAccessorError(dir);
  let defaultAccessor = undefined;
  let builtinAccessor = undefined;
  let customAccessor = undefined;
  valueAccessors.forEach(v => {
    if (v.constructor === DefaultValueAccessor) {
      defaultAccessor = v;
    } else if (isBuiltInAccessor(v)) {
      if (builtinAccessor && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'More than one built-in value accessor matches form control with');
      builtinAccessor = v;
    } else {
      if (customAccessor && (typeof ngDevMode === 'undefined' || ngDevMode)) _throwError(dir, 'More than one custom value accessor matches form control with');
      customAccessor = v;
    }
  });
  if (customAccessor) return customAccessor;
  if (builtinAccessor) return builtinAccessor;
  if (defaultAccessor) return defaultAccessor;
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    _throwError(dir, 'No valid value accessor for form control with');
  }
  return null;
}
function removeListItem$1(list, el) {
  const index = list.indexOf(el);
  if (index > -1) list.splice(index, 1);
}
// TODO(kara): remove after deprecation period
function _ngModelWarning(name, type, instance, warningConfig) {
  if (warningConfig === 'never') return;
  if ((warningConfig === null || warningConfig === 'once') && !type._ngModelWarningSentOnce || warningConfig === 'always' && !instance._ngModelWarningSent) {
    console.warn(ngModelWarning(name));
    type._ngModelWarningSentOnce = true;
    instance._ngModelWarningSent = true;
  }
}
const formDirectiveProvider$1 = {
  provide: ControlContainer,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgForm)
};
const resolvedPromise$1 = (() => Promise.resolve())();
/**
 * @description
 * Creates a top-level `FormGroup` instance and binds it to a form
 * to track aggregate form value and validation status.
 *
 * As soon as you import the `FormsModule`, this directive becomes active by default on
 * all `<form>` tags.  You don't need to add a special selector.
 *
 * You optionally export the directive into a local template variable using `ngForm` as the key
 * (ex: `#myForm="ngForm"`). This is optional, but useful.  Many properties from the underlying
 * `FormGroup` instance are duplicated on the directive itself, so a reference to it
 * gives you access to the aggregate value and validity status of the form, as well as
 * user interaction properties like `dirty` and `touched`.
 *
 * To register child controls with the form, use `NgModel` with a `name`
 * attribute. You may use `NgModelGroup` to create sub-groups within the form.
 *
 * If necessary, listen to the directive's `ngSubmit` event to be notified when the user has
 * triggered a form submission. The `ngSubmit` event emits the original form
 * submission event.
 *
 * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`.
 * To import the `FormsModule` but skip its usage in some forms,
 * for example, to use native HTML5 validation, add the `ngNoForm` and the `<form>`
 * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is
 * unnecessary because the `<form>` tags are inert. In that case, you would
 * refrain from using the `formGroup` directive.
 *
 * @usageNotes
 *
 * ### Listening for form submission
 *
 * The following example shows how to capture the form values from the "ngSubmit" event.
 *
 * {@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
 *
 * ### Setting the update options
 *
 * The following example shows you how to change the "updateOn" option from its default using
 * ngFormOptions.
 *
 * ```html
 * <form [ngFormOptions]="{updateOn: 'blur'}">
 *    <input name="one" ngModel>  <!-- this ngModel will update on blur -->
 * </form>
 * ```
 *
 * ### Native DOM validation UI
 *
 * In order to prevent the native DOM form validation UI from interfering with Angular's form
 * validation, Angular automatically adds the `novalidate` attribute on any `<form>` whenever
 * `FormModule` or `ReactiveFormModule` are imported into the application.
 * If you want to explicitly enable native DOM validation UI with Angular forms, you can add the
 * `ngNativeValidate` attribute to the `<form>` element:
 *
 * ```html
 * <form ngNativeValidate>
 *   ...
 * </form>
 * ```
 *
 * @ngModule FormsModule
 * @publicApi
 */
class NgForm extends ControlContainer {
  constructor(validators, asyncValidators, callSetDisabledState) {
    super();
    this.callSetDisabledState = callSetDisabledState;
    /**
     * @description
     * Returns whether the form submission has been triggered.
     */
    this.submitted = false;
    this._directives = new Set();
    /**
     * @description
     * Event emitter for the "ngSubmit" event
     */
    this.ngSubmit = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.form = new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
  }
  /** @nodoc */
  ngAfterViewInit() {
    this._setUpdateStrategy();
  }
  /**
   * @description
   * The directive instance.
   */
  get formDirective() {
    return this;
  }
  /**
   * @description
   * The internal `FormGroup` instance.
   */
  get control() {
    return this.form;
  }
  /**
   * @description
   * Returns an array representing the path to this group. Because this directive
   * always lives at the top level of a form, it is always an empty array.
   */
  get path() {
    return [];
  }
  /**
   * @description
   * Returns a map of the controls in this group.
   */
  get controls() {
    return this.form.controls;
  }
  /**
   * @description
   * Method that sets up the control directive in this group, re-calculates its value
   * and validity, and adds the instance to the internal list of directives.
   *
   * @param dir The `NgModel` directive instance.
   */
  addControl(dir) {
    resolvedPromise$1.then(() => {
      const container = this._findContainer(dir.path);
      dir.control = container.registerControl(dir.name, dir.control);
      setUpControl(dir.control, dir, this.callSetDisabledState);
      dir.control.updateValueAndValidity({
        emitEvent: false
      });
      this._directives.add(dir);
    });
  }
  /**
   * @description
   * Retrieves the `FormControl` instance from the provided `NgModel` directive.
   *
   * @param dir The `NgModel` directive instance.
   */
  getControl(dir) {
    return this.form.get(dir.path);
  }
  /**
   * @description
   * Removes the `NgModel` instance from the internal list of directives
   *
   * @param dir The `NgModel` directive instance.
   */
  removeControl(dir) {
    resolvedPromise$1.then(() => {
      const container = this._findContainer(dir.path);
      if (container) {
        container.removeControl(dir.name);
      }
      this._directives.delete(dir);
    });
  }
  /**
   * @description
   * Adds a new `NgModelGroup` directive instance to the form.
   *
   * @param dir The `NgModelGroup` directive instance.
   */
  addFormGroup(dir) {
    resolvedPromise$1.then(() => {
      const container = this._findContainer(dir.path);
      const group = new FormGroup({});
      setUpFormContainer(group, dir);
      container.registerControl(dir.name, group);
      group.updateValueAndValidity({
        emitEvent: false
      });
    });
  }
  /**
   * @description
   * Removes the `NgModelGroup` directive instance from the form.
   *
   * @param dir The `NgModelGroup` directive instance.
   */
  removeFormGroup(dir) {
    resolvedPromise$1.then(() => {
      const container = this._findContainer(dir.path);
      if (container) {
        container.removeControl(dir.name);
      }
    });
  }
  /**
   * @description
   * Retrieves the `FormGroup` for a provided `NgModelGroup` directive instance
   *
   * @param dir The `NgModelGroup` directive instance.
   */
  getFormGroup(dir) {
    return this.form.get(dir.path);
  }
  /**
   * Sets the new value for the provided `NgControl` directive.
   *
   * @param dir The `NgControl` directive instance.
   * @param value The new value for the directive's control.
   */
  updateModel(dir, value) {
    resolvedPromise$1.then(() => {
      const ctrl = this.form.get(dir.path);
      ctrl.setValue(value);
    });
  }
  /**
   * @description
   * Sets the value for this `FormGroup`.
   *
   * @param value The new value
   */
  setValue(value) {
    this.control.setValue(value);
  }
  /**
   * @description
   * Method called when the "submit" event is triggered on the form.
   * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
   *
   * @param $event The "submit" event object
   */
  onSubmit($event) {
    this.submitted = true;
    syncPendingControls(this.form, this._directives);
    this.ngSubmit.emit($event);
    // Forms with `method="dialog"` have some special behavior
    // that won't reload the page and that shouldn't be prevented.
    return $event?.target?.method === 'dialog';
  }
  /**
   * @description
   * Method called when the "reset" event is triggered on the form.
   */
  onReset() {
    this.resetForm();
  }
  /**
   * @description
   * Resets the form to an initial value and resets its submitted status.
   *
   * @param value The new value for the form.
   */
  resetForm(value = undefined) {
    this.form.reset(value);
    this.submitted = false;
  }
  _setUpdateStrategy() {
    if (this.options && this.options.updateOn != null) {
      this.form._updateOn = this.options.updateOn;
    }
  }
  _findContainer(path) {
    path.pop();
    return path.length ? this.form.get(path) : this.form;
  }
  static {
    this.ɵfac = function NgForm_Factory(t) {
      return new (t || NgForm)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](CALL_SET_DISABLED_STATE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgForm,
      selectors: [["form", 3, "ngNoForm", "", 3, "formGroup", ""], ["ng-form"], ["", "ngForm", ""]],
      hostBindings: function NgForm_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("submit", function NgForm_submit_HostBindingHandler($event) {
            return ctx.onSubmit($event);
          })("reset", function NgForm_reset_HostBindingHandler() {
            return ctx.onReset();
          });
        }
      },
      inputs: {
        options: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngFormOptions", "options"]
      },
      outputs: {
        ngSubmit: "ngSubmit"
      },
      exportAs: ["ngForm"],
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formDirectiveProvider$1]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgForm, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]',
      providers: [formDirectiveProvider$1],
      host: {
        '(submit)': 'onSubmit($event)',
        '(reset)': 'onReset()'
      },
      outputs: ['ngSubmit'],
      exportAs: 'ngForm'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [CALL_SET_DISABLED_STATE]
    }]
  }], {
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngFormOptions']
    }]
  });
})();
function removeListItem(list, el) {
  const index = list.indexOf(el);
  if (index > -1) list.splice(index, 1);
}
function isFormControlState(formState) {
  return typeof formState === 'object' && formState !== null && Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
}
const FormControl = class FormControl extends AbstractControl {
  constructor(
  // formState and defaultValue will only be null if T is nullable
  formState = null, validatorOrOpts, asyncValidator) {
    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
    /** @publicApi */
    this.defaultValue = null;
    /** @internal */
    this._onChange = [];
    /** @internal */
    this._pendingChange = false;
    this._applyFormState(formState);
    this._setUpdateStrategy(validatorOrOpts);
    this._initObservables();
    this.updateValueAndValidity({
      onlySelf: true,
      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
      // `VALID` or `INVALID`.
      // The status should be broadcasted via the `statusChanges` observable, so we set
      // `emitEvent` to `true` to allow that during the control creation process.
      emitEvent: !!this.asyncValidator
    });
    if (isOptionsObj(validatorOrOpts) && (validatorOrOpts.nonNullable || validatorOrOpts.initialValueIsDefault)) {
      if (isFormControlState(formState)) {
        this.defaultValue = formState.value;
      } else {
        this.defaultValue = formState;
      }
    }
  }
  setValue(value, options = {}) {
    this.value = this._pendingValue = value;
    if (this._onChange.length && options.emitModelToViewChange !== false) {
      this._onChange.forEach(changeFn => changeFn(this.value, options.emitViewToModelChange !== false));
    }
    this.updateValueAndValidity(options);
  }
  patchValue(value, options = {}) {
    this.setValue(value, options);
  }
  reset(formState = this.defaultValue, options = {}) {
    this._applyFormState(formState);
    this.markAsPristine(options);
    this.markAsUntouched(options);
    this.setValue(this.value, options);
    this._pendingChange = false;
  }
  /**  @internal */
  _updateValue() {}
  /**  @internal */
  _anyControls(condition) {
    return false;
  }
  /**  @internal */
  _allControlsDisabled() {
    return this.disabled;
  }
  registerOnChange(fn) {
    this._onChange.push(fn);
  }
  /** @internal */
  _unregisterOnChange(fn) {
    removeListItem(this._onChange, fn);
  }
  registerOnDisabledChange(fn) {
    this._onDisabledChange.push(fn);
  }
  /** @internal */
  _unregisterOnDisabledChange(fn) {
    removeListItem(this._onDisabledChange, fn);
  }
  /** @internal */
  _forEachChild(cb) {}
  /** @internal */
  _syncPendingControls() {
    if (this.updateOn === 'submit') {
      if (this._pendingDirty) this.markAsDirty();
      if (this._pendingTouched) this.markAsTouched();
      if (this._pendingChange) {
        this.setValue(this._pendingValue, {
          onlySelf: true,
          emitModelToViewChange: false
        });
        return true;
      }
    }
    return false;
  }
  _applyFormState(formState) {
    if (isFormControlState(formState)) {
      this.value = this._pendingValue = formState.value;
      formState.disabled ? this.disable({
        onlySelf: true,
        emitEvent: false
      }) : this.enable({
        onlySelf: true,
        emitEvent: false
      });
    } else {
      this.value = this._pendingValue = formState;
    }
  }
};
const UntypedFormControl = FormControl;
/**
 * @description
 * Asserts that the given control is an instance of `FormControl`
 *
 * @publicApi
 */
const isFormControl = control => control instanceof FormControl;

/**
 * @description
 * A base class for code shared between the `NgModelGroup` and `FormGroupName` directives.
 *
 * @publicApi
 */
class AbstractFormGroupDirective extends ControlContainer {
  /** @nodoc */
  ngOnInit() {
    this._checkParentType();
    // Register the group with its parent group.
    this.formDirective.addFormGroup(this);
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this.formDirective) {
      // Remove the group from its parent group.
      this.formDirective.removeFormGroup(this);
    }
  }
  /**
   * @description
   * The `FormGroup` bound to this directive.
   */
  get control() {
    return this.formDirective.getFormGroup(this);
  }
  /**
   * @description
   * The path to this group from the top-level directive.
   */
  get path() {
    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
  }
  /**
   * @description
   * The top-level directive for this group if present, otherwise null.
   */
  get formDirective() {
    return this._parent ? this._parent.formDirective : null;
  }
  /** @internal */
  _checkParentType() {}
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵAbstractFormGroupDirective_BaseFactory;
      return function AbstractFormGroupDirective_Factory(t) {
        return (ɵAbstractFormGroupDirective_BaseFactory || (ɵAbstractFormGroupDirective_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](AbstractFormGroupDirective)))(t || AbstractFormGroupDirective);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: AbstractFormGroupDirective,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AbstractFormGroupDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
  }], null, null);
})();
function modelParentException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1350 /* RuntimeErrorCode.NGMODEL_IN_FORM_GROUP */, `
    ngModel cannot be used to register form controls with a parent formGroup directive.  Try using
    formGroup's partner directive "formControlName" instead.  Example:

    ${formControlNameExample}

    Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:

    Example:

    ${ngModelWithFormGroupExample}`);
}
function formGroupNameException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1351 /* RuntimeErrorCode.NGMODEL_IN_FORM_GROUP_NAME */, `
    ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.

    Option 1: Use formControlName instead of ngModel (reactive strategy):

    ${formGroupNameExample}

    Option 2:  Update ngModel's parent be ngModelGroup (template-driven strategy):

    ${ngModelGroupExample}`);
}
function missingNameException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1352 /* RuntimeErrorCode.NGMODEL_WITHOUT_NAME */, `If ngModel is used within a form tag, either the name attribute must be set or the form
    control must be defined as 'standalone' in ngModelOptions.

    Example 1: <input [(ngModel)]="person.firstName" name="first">
    Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">`);
}
function modelGroupParentException() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1353 /* RuntimeErrorCode.NGMODELGROUP_IN_FORM_GROUP */, `
    ngModelGroup cannot be used with a parent formGroup directive.

    Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):

    ${formGroupNameExample}

    Option 2:  Use a regular form tag instead of the formGroup directive (template-driven strategy):

    ${ngModelGroupExample}`);
}
const modelGroupProvider = {
  provide: ControlContainer,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgModelGroup)
};
/**
 * @description
 * Creates and binds a `FormGroup` instance to a DOM element.
 *
 * This directive can only be used as a child of `NgForm` (within `<form>` tags).
 *
 * Use this directive to validate a sub-group of your form separately from the
 * rest of your form, or if some values in your domain model make more sense
 * to consume together in a nested object.
 *
 * Provide a name for the sub-group and it will become the key
 * for the sub-group in the form's full value. If you need direct access, export the directive into
 * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
 *
 * @usageNotes
 *
 * ### Consuming controls in a grouping
 *
 * The following example shows you how to combine controls together in a sub-group
 * of the form.
 *
 * {@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
 *
 * @ngModule FormsModule
 * @publicApi
 */
class NgModelGroup extends AbstractFormGroupDirective {
  constructor(parent, validators, asyncValidators) {
    super();
    /**
     * @description
     * Tracks the name of the `NgModelGroup` bound to the directive. The name corresponds
     * to a key in the parent `NgForm`.
     */
    this.name = '';
    this._parent = parent;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
  }
  /** @internal */
  _checkParentType() {
    if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw modelGroupParentException();
    }
  }
  static {
    this.ɵfac = function NgModelGroup_Factory(t) {
      return new (t || NgModelGroup)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 5), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgModelGroup,
      selectors: [["", "ngModelGroup", ""]],
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngModelGroup", "name"]
      },
      exportAs: ["ngModelGroup"],
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([modelGroupProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgModelGroup, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngModelGroup]',
      providers: [modelGroupProvider],
      exportAs: 'ngModelGroup'
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngModelGroup']
    }]
  });
})();
const formControlBinding$1 = {
  provide: NgControl,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgModel)
};
/**
 * `ngModel` forces an additional change detection run when its inputs change:
 * E.g.:
 * ```
 * <div>{{myModel.valid}}</div>
 * <input [(ngModel)]="myValue" #myModel="ngModel">
 * ```
 * I.e. `ngModel` can export itself on the element and then be used in the template.
 * Normally, this would result in expressions before the `input` that use the exported directive
 * to have an old value as they have been
 * dirty checked before. As this is a very common case for `ngModel`, we added this second change
 * detection run.
 *
 * Notes:
 * - this is just one extra run no matter how many `ngModel`s have been changed.
 * - this is a general problem when using `exportAs` for directives!
 */
const resolvedPromise = (() => Promise.resolve())();
/**
 * @description
 * Creates a `FormControl` instance from a [domain
 * model](https://en.wikipedia.org/wiki/Domain_model) and binds it to a form control element.
 *
 * The `FormControl` instance tracks the value, user interaction, and
 * validation status of the control and keeps the view synced with the model. If used
 * within a parent form, the directive also registers itself with the form as a child
 * control.
 *
 * This directive is used by itself or as part of a larger form. Use the
 * `ngModel` selector to activate it.
 *
 * It accepts a domain model as an optional `Input`. If you have a one-way binding
 * to `ngModel` with `[]` syntax, changing the domain model's value in the component
 * class sets the value in the view. If you have a two-way binding with `[()]` syntax
 * (also known as 'banana-in-a-box syntax'), the value in the UI always syncs back to
 * the domain model in your class.
 *
 * To inspect the properties of the associated `FormControl` (like the validity state),
 * export the directive into a local template variable using `ngModel` as the key (ex:
 * `#myVar="ngModel"`). You can then access the control using the directive's `control` property.
 * However, the most commonly used properties (like `valid` and `dirty`) also exist on the control
 * for direct access. See a full list of properties directly available in
 * `AbstractControlDirective`.
 *
 * @see {@link RadioControlValueAccessor}
 * @see {@link SelectControlValueAccessor}
 *
 * @usageNotes
 *
 * ### Using ngModel on a standalone control
 *
 * The following examples show a simple standalone control using `ngModel`:
 *
 * {@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
 *
 * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
 * so that the control can be registered with the parent form under that name.
 *
 * In the context of a parent form, it's often unnecessary to include one-way or two-way binding,
 * as the parent form syncs the value for you. You access its properties by exporting it into a
 * local template variable using `ngForm` such as (`#f="ngForm"`). Use the variable where
 * needed on form submission.
 *
 * If you do need to populate initial values into your form, using a one-way binding for
 * `ngModel` tends to be sufficient as long as you use the exported form's value rather
 * than the domain model's value on submit.
 *
 * ### Using ngModel within a form
 *
 * The following example shows controls using `ngModel` within a form:
 *
 * {@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
 *
 * ### Using a standalone ngModel within a group
 *
 * The following example shows you how to use a standalone ngModel control
 * within a form. This controls the display of the form, but doesn't contain form data.
 *
 * ```html
 * <form>
 *   <input name="login" ngModel placeholder="Login">
 *   <input type="checkbox" ngModel [ngModelOptions]="{standalone: true}"> Show more options?
 * </form>
 * <!-- form value: {login: ''} -->
 * ```
 *
 * ### Setting the ngModel `name` attribute through options
 *
 * The following example shows you an alternate way to set the name attribute. Here,
 * an attribute identified as name is used within a custom form control component. To still be able
 * to specify the NgModel's name, you must specify it using the `ngModelOptions` input instead.
 *
 * ```html
 * <form>
 *   <my-custom-form-control name="Nancy" ngModel [ngModelOptions]="{name: 'user'}">
 *   </my-custom-form-control>
 * </form>
 * <!-- form value: {user: ''} -->
 * ```
 *
 * @ngModule FormsModule
 * @publicApi
 */
class NgModel extends NgControl {
  constructor(parent, validators, asyncValidators, valueAccessors, _changeDetectorRef, callSetDisabledState) {
    super();
    this._changeDetectorRef = _changeDetectorRef;
    this.callSetDisabledState = callSetDisabledState;
    this.control = new FormControl();
    /** @internal */
    this._registered = false;
    /**
     * @description
     * Tracks the name bound to the directive. If a parent form exists, it
     * uses this name as a key to retrieve this control's value.
     */
    this.name = '';
    /**
     * @description
     * Event emitter for producing the `ngModelChange` event after
     * the view model updates.
     */
    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._parent = parent;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
    this.valueAccessor = selectValueAccessor(this, valueAccessors);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    this._checkForErrors();
    if (!this._registered || 'name' in changes) {
      if (this._registered) {
        this._checkName();
        if (this.formDirective) {
          // We can't call `formDirective.removeControl(this)`, because the `name` has already been
          // changed. We also can't reset the name temporarily since the logic in `removeControl`
          // is inside a promise and it won't run immediately. We work around it by giving it an
          // object with the same shape instead.
          const oldName = changes['name'].previousValue;
          this.formDirective.removeControl({
            name: oldName,
            path: this._getPath(oldName)
          });
        }
      }
      this._setUpControl();
    }
    if ('isDisabled' in changes) {
      this._updateDisabled(changes);
    }
    if (isPropertyUpdated(changes, this.viewModel)) {
      this._updateValue(this.model);
      this.viewModel = this.model;
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    this.formDirective && this.formDirective.removeControl(this);
  }
  /**
   * @description
   * Returns an array that represents the path from the top-level form to this control.
   * Each index is the string name of the control on that level.
   */
  get path() {
    return this._getPath(this.name);
  }
  /**
   * @description
   * The top-level directive for this control if present, otherwise null.
   */
  get formDirective() {
    return this._parent ? this._parent.formDirective : null;
  }
  /**
   * @description
   * Sets the new value for the view model and emits an `ngModelChange` event.
   *
   * @param newValue The new value emitted by `ngModelChange`.
   */
  viewToModelUpdate(newValue) {
    this.viewModel = newValue;
    this.update.emit(newValue);
  }
  _setUpControl() {
    this._setUpdateStrategy();
    this._isStandalone() ? this._setUpStandalone() : this.formDirective.addControl(this);
    this._registered = true;
  }
  _setUpdateStrategy() {
    if (this.options && this.options.updateOn != null) {
      this.control._updateOn = this.options.updateOn;
    }
  }
  _isStandalone() {
    return !this._parent || !!(this.options && this.options.standalone);
  }
  _setUpStandalone() {
    setUpControl(this.control, this, this.callSetDisabledState);
    this.control.updateValueAndValidity({
      emitEvent: false
    });
  }
  _checkForErrors() {
    if (!this._isStandalone()) {
      this._checkParentType();
    }
    this._checkName();
  }
  _checkParentType() {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (!(this._parent instanceof NgModelGroup) && this._parent instanceof AbstractFormGroupDirective) {
        throw formGroupNameException();
      } else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
        throw modelParentException();
      }
    }
  }
  _checkName() {
    if (this.options && this.options.name) this.name = this.options.name;
    if (!this._isStandalone() && !this.name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw missingNameException();
    }
  }
  _updateValue(value) {
    resolvedPromise.then(() => {
      this.control.setValue(value, {
        emitViewToModelChange: false
      });
      this._changeDetectorRef?.markForCheck();
    });
  }
  _updateDisabled(changes) {
    const disabledValue = changes['isDisabled'].currentValue;
    // checking for 0 to avoid breaking change
    const isDisabled = disabledValue !== 0 && (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute)(disabledValue);
    resolvedPromise.then(() => {
      if (isDisabled && !this.control.disabled) {
        this.control.disable();
      } else if (!isDisabled && this.control.disabled) {
        this.control.enable();
      }
      this._changeDetectorRef?.markForCheck();
    });
  }
  _getPath(controlName) {
    return this._parent ? controlPath(controlName, this._parent) : [controlName];
  }
  static {
    this.ɵfac = function NgModel_Factory(t) {
      return new (t || NgModel)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 9), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](CALL_SET_DISABLED_STATE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgModel,
      selectors: [["", "ngModel", "", 3, "formControlName", "", 3, "formControl", ""]],
      inputs: {
        name: "name",
        isDisabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "disabled", "isDisabled"],
        model: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngModel", "model"],
        options: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngModelOptions", "options"]
      },
      outputs: {
        update: "ngModelChange"
      },
      exportAs: ["ngModel"],
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formControlBinding$1]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgModel, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngModel]:not([formControlName]):not([formControl])',
      providers: [formControlBinding$1],
      exportAs: 'ngModel'
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALUE_ACCESSOR]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [CALL_SET_DISABLED_STATE]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    isDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['disabled']
    }],
    model: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngModel']
    }],
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngModelOptions']
    }],
    update: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['ngModelChange']
    }]
  });
})();

/**
 * @description
 *
 * Adds `novalidate` attribute to all forms by default.
 *
 * `novalidate` is used to disable browser's native form validation.
 *
 * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
 *
 * ```
 * <form ngNativeValidate></form>
 * ```
 *
 * @publicApi
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 */
class ɵNgNoValidate {
  static {
    this.ɵfac = function ɵNgNoValidate_Factory(t) {
      return new (t || ɵNgNoValidate)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: ɵNgNoValidate,
      selectors: [["form", 3, "ngNoForm", "", 3, "ngNativeValidate", ""]],
      hostAttrs: ["novalidate", ""]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵNgNoValidate, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
      host: {
        'novalidate': ''
      }
    }]
  }], null, null);
})();
const NUMBER_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NumberValueAccessor),
  multi: true
};
/**
 * @description
 * The `ControlValueAccessor` for writing a number value and listening to number input changes.
 * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel`
 * directives.
 *
 * @usageNotes
 *
 * ### Using a number input with a reactive form.
 *
 * The following example shows how to use a number input with a reactive form.
 *
 * ```ts
 * const totalCountControl = new FormControl();
 * ```
 *
 * ```
 * <input type="number" [formControl]="totalCountControl">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class NumberValueAccessor extends BuiltInControlValueAccessor {
  /**
   * Sets the "value" property on the input element.
   * @nodoc
   */
  writeValue(value) {
    // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
    const normalizedValue = value == null ? '' : value;
    this.setProperty('value', normalizedValue);
  }
  /**
   * Registers a function called when the control value changes.
   * @nodoc
   */
  registerOnChange(fn) {
    this.onChange = value => {
      fn(value == '' ? null : parseFloat(value));
    };
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNumberValueAccessor_BaseFactory;
      return function NumberValueAccessor_Factory(t) {
        return (ɵNumberValueAccessor_BaseFactory || (ɵNumberValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NumberValueAccessor)))(t || NumberValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NumberValueAccessor,
      selectors: [["input", "type", "number", "formControlName", ""], ["input", "type", "number", "formControl", ""], ["input", "type", "number", "ngModel", ""]],
      hostBindings: function NumberValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function NumberValueAccessor_input_HostBindingHandler($event) {
            return ctx.onChange($event.target.value);
          })("blur", function NumberValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([NUMBER_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NumberValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
      host: {
        '(input)': 'onChange($event.target.value)',
        '(blur)': 'onTouched()'
      },
      providers: [NUMBER_VALUE_ACCESSOR]
    }]
  }], null, null);
})();
const RADIO_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RadioControlValueAccessor),
  multi: true
};
function throwNameError() {
  throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1202 /* RuntimeErrorCode.NAME_AND_FORM_CONTROL_NAME_MUST_MATCH */, `
      If you define both a name and a formControlName attribute on your radio button, their values
      must match. Ex: <input type="radio" formControlName="food" name="food">
    `);
}
/**
 * @description
 * Class used by Angular to track radio buttons. For internal use only.
 */
class RadioControlRegistry {
  constructor() {
    this._accessors = [];
  }
  /**
   * @description
   * Adds a control to the internal registry. For internal use only.
   */
  add(control, accessor) {
    this._accessors.push([control, accessor]);
  }
  /**
   * @description
   * Removes a control from the internal registry. For internal use only.
   */
  remove(accessor) {
    for (let i = this._accessors.length - 1; i >= 0; --i) {
      if (this._accessors[i][1] === accessor) {
        this._accessors.splice(i, 1);
        return;
      }
    }
  }
  /**
   * @description
   * Selects a radio button. For internal use only.
   */
  select(accessor) {
    this._accessors.forEach(c => {
      if (this._isSameGroup(c, accessor) && c[1] !== accessor) {
        c[1].fireUncheck(accessor.value);
      }
    });
  }
  _isSameGroup(controlPair, accessor) {
    if (!controlPair[0].control) return false;
    return controlPair[0]._parent === accessor._control._parent && controlPair[1].name === accessor.name;
  }
  static {
    this.ɵfac = function RadioControlRegistry_Factory(t) {
      return new (t || RadioControlRegistry)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: RadioControlRegistry,
      factory: RadioControlRegistry.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadioControlRegistry, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * @description
 * The `ControlValueAccessor` for writing radio control values and listening to radio control
 * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
 * `NgModel` directives.
 *
 * @usageNotes
 *
 * ### Using radio buttons with reactive form directives
 *
 * The follow example shows how to use radio buttons in a reactive form. When using radio buttons in
 * a reactive form, radio buttons in the same group should have the same `formControlName`.
 * Providing a `name` attribute is optional.
 *
 * {@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class RadioControlValueAccessor extends BuiltInControlValueAccessor {
  constructor(renderer, elementRef, _registry, _injector) {
    super(renderer, elementRef);
    this._registry = _registry;
    this._injector = _injector;
    this.setDisabledStateFired = false;
    /**
     * The registered callback function called when a change event occurs on the input element.
     * Note: we declare `onChange` here (also used as host listener) as a function with no arguments
     * to override the `onChange` function (which expects 1 argument) in the parent
     * `BaseControlValueAccessor` class.
     * @nodoc
     */
    this.onChange = () => {};
    this.callSetDisabledState = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(CALL_SET_DISABLED_STATE, {
      optional: true
    }) ?? setDisabledStateDefault;
  }
  /** @nodoc */
  ngOnInit() {
    this._control = this._injector.get(NgControl);
    this._checkName();
    this._registry.add(this._control, this);
  }
  /** @nodoc */
  ngOnDestroy() {
    this._registry.remove(this);
  }
  /**
   * Sets the "checked" property value on the radio input element.
   * @nodoc
   */
  writeValue(value) {
    this._state = value === this.value;
    this.setProperty('checked', this._state);
  }
  /**
   * Registers a function called when the control value changes.
   * @nodoc
   */
  registerOnChange(fn) {
    this._fn = fn;
    this.onChange = () => {
      fn(this.value);
      this._registry.select(this);
    };
  }
  /** @nodoc */
  setDisabledState(isDisabled) {
    /**
     * `setDisabledState` is supposed to be called whenever the disabled state of a control changes,
     * including upon control creation. However, a longstanding bug caused the method to not fire
     * when an *enabled* control was attached. This bug was fixed in v15 in #47576.
     *
     * This had a side effect: previously, it was possible to instantiate a reactive form control
     * with `[attr.disabled]=true`, even though the corresponding control was enabled in the
     * model. This resulted in a mismatch between the model and the DOM. Now, because
     * `setDisabledState` is always called, the value in the DOM will be immediately overwritten
     * with the "correct" enabled value.
     *
     * However, the fix also created an exceptional case: radio buttons. Because Reactive Forms
     * models the entire group of radio buttons as a single `FormControl`, there is no way to
     * control the disabled state for individual radios, so they can no longer be configured as
     * disabled. Thus, we keep the old behavior for radio buttons, so that `[attr.disabled]`
     * continues to work. Specifically, we drop the first call to `setDisabledState` if `disabled`
     * is `false`, and we are not in legacy mode.
     */
    if (this.setDisabledStateFired || isDisabled || this.callSetDisabledState === 'whenDisabledForLegacyCode') {
      this.setProperty('disabled', isDisabled);
    }
    this.setDisabledStateFired = true;
  }
  /**
   * Sets the "value" on the radio input element and unchecks it.
   *
   * @param value
   */
  fireUncheck(value) {
    this.writeValue(value);
  }
  _checkName() {
    if (this.name && this.formControlName && this.name !== this.formControlName && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throwNameError();
    }
    if (!this.name && this.formControlName) this.name = this.formControlName;
  }
  static {
    this.ɵfac = function RadioControlValueAccessor_Factory(t) {
      return new (t || RadioControlValueAccessor)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](RadioControlRegistry), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: RadioControlValueAccessor,
      selectors: [["input", "type", "radio", "formControlName", ""], ["input", "type", "radio", "formControl", ""], ["input", "type", "radio", "ngModel", ""]],
      hostBindings: function RadioControlValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function RadioControlValueAccessor_change_HostBindingHandler() {
            return ctx.onChange();
          })("blur", function RadioControlValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      inputs: {
        name: "name",
        formControlName: "formControlName",
        value: "value"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([RADIO_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadioControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
      host: {
        '(change)': 'onChange()',
        '(blur)': 'onTouched()'
      },
      providers: [RADIO_VALUE_ACCESSOR]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: RadioControlRegistry
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    formControlName: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
const RANGE_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RangeValueAccessor),
  multi: true
};
/**
 * @description
 * The `ControlValueAccessor` for writing a range value and listening to range input changes.
 * The value accessor is used by the `FormControlDirective`, `FormControlName`, and  `NgModel`
 * directives.
 *
 * @usageNotes
 *
 * ### Using a range input with a reactive form
 *
 * The following example shows how to use a range input with a reactive form.
 *
 * ```ts
 * const ageControl = new FormControl();
 * ```
 *
 * ```
 * <input type="range" [formControl]="ageControl">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class RangeValueAccessor extends BuiltInControlValueAccessor {
  /**
   * Sets the "value" property on the input element.
   * @nodoc
   */
  writeValue(value) {
    this.setProperty('value', parseFloat(value));
  }
  /**
   * Registers a function called when the control value changes.
   * @nodoc
   */
  registerOnChange(fn) {
    this.onChange = value => {
      fn(value == '' ? null : parseFloat(value));
    };
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵRangeValueAccessor_BaseFactory;
      return function RangeValueAccessor_Factory(t) {
        return (ɵRangeValueAccessor_BaseFactory || (ɵRangeValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](RangeValueAccessor)))(t || RangeValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: RangeValueAccessor,
      selectors: [["input", "type", "range", "formControlName", ""], ["input", "type", "range", "formControl", ""], ["input", "type", "range", "ngModel", ""]],
      hostBindings: function RangeValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function RangeValueAccessor_change_HostBindingHandler($event) {
            return ctx.onChange($event.target.value);
          })("input", function RangeValueAccessor_input_HostBindingHandler($event) {
            return ctx.onChange($event.target.value);
          })("blur", function RangeValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([RANGE_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RangeValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
      host: {
        '(change)': 'onChange($event.target.value)',
        '(input)': 'onChange($event.target.value)',
        '(blur)': 'onTouched()'
      },
      providers: [RANGE_VALUE_ACCESSOR]
    }]
  }], null, null);
})();

/**
 * Token to provide to turn off the ngModel warning on formControl and formControlName.
 */
const NG_MODEL_WITH_FORM_CONTROL_WARNING = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken(ngDevMode ? 'NgModelWithFormControlWarning' : '');
const formControlBinding = {
  provide: NgControl,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormControlDirective)
};
/**
 * @description
 * Synchronizes a standalone `FormControl` instance to a form control element.
 *
 * Note that support for using the `ngModel` input property and `ngModelChange` event with reactive
 * form directives was deprecated in Angular v6 and is scheduled for removal in
 * a future version of Angular.
 * For details, see [Deprecated features](guide/deprecations#ngmodel-with-reactive-forms).
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 * @see {@link FormControl}
 * @see {@link AbstractControl}
 *
 * @usageNotes
 *
 * The following example shows how to register a standalone control and set its value.
 *
 * {@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
 *
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class FormControlDirective extends NgControl {
  /**
   * @description
   * Triggers a warning in dev mode that this input should not be used with reactive forms.
   */
  set isDisabled(isDisabled) {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      console.warn(disabledAttrWarning);
    }
  }
  /**
   * @description
   * Static property used to track whether any ngModel warnings have been sent across
   * all instances of FormControlDirective. Used to support warning config of "once".
   *
   * @internal
   */
  static {
    this._ngModelWarningSentOnce = false;
  }
  constructor(validators, asyncValidators, valueAccessors, _ngModelWarningConfig, callSetDisabledState) {
    super();
    this._ngModelWarningConfig = _ngModelWarningConfig;
    this.callSetDisabledState = callSetDisabledState;
    /** @deprecated as of v6 */
    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * @description
     * Instance property used to track whether an ngModel warning has been sent out for this
     * particular `FormControlDirective` instance. Used to support warning config of "always".
     *
     * @internal
     */
    this._ngModelWarningSent = false;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
    this.valueAccessor = selectValueAccessor(this, valueAccessors);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (this._isControlChanged(changes)) {
      const previousForm = changes['form'].previousValue;
      if (previousForm) {
        cleanUpControl(previousForm, this, /* validateControlPresenceOnChange */false);
      }
      setUpControl(this.form, this, this.callSetDisabledState);
      this.form.updateValueAndValidity({
        emitEvent: false
      });
    }
    if (isPropertyUpdated(changes, this.viewModel)) {
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        _ngModelWarning('formControl', FormControlDirective, this, this._ngModelWarningConfig);
      }
      this.form.setValue(this.model);
      this.viewModel = this.model;
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this.form) {
      cleanUpControl(this.form, this, /* validateControlPresenceOnChange */false);
    }
  }
  /**
   * @description
   * Returns an array that represents the path from the top-level form to this control.
   * Each index is the string name of the control on that level.
   */
  get path() {
    return [];
  }
  /**
   * @description
   * The `FormControl` bound to this directive.
   */
  get control() {
    return this.form;
  }
  /**
   * @description
   * Sets the new value for the view model and emits an `ngModelChange` event.
   *
   * @param newValue The new value for the view model.
   */
  viewToModelUpdate(newValue) {
    this.viewModel = newValue;
    this.update.emit(newValue);
  }
  _isControlChanged(changes) {
    return changes.hasOwnProperty('form');
  }
  static {
    this.ɵfac = function FormControlDirective_Factory(t) {
      return new (t || FormControlDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_MODEL_WITH_FORM_CONTROL_WARNING, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](CALL_SET_DISABLED_STATE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: FormControlDirective,
      selectors: [["", "formControl", ""]],
      inputs: {
        form: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "formControl", "form"],
        isDisabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "disabled", "isDisabled"],
        model: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngModel", "model"]
      },
      outputs: {
        update: "ngModelChange"
      },
      exportAs: ["ngForm"],
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formControlBinding]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormControlDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formControl]',
      providers: [formControlBinding],
      exportAs: 'ngForm'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALUE_ACCESSOR]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_MODEL_WITH_FORM_CONTROL_WARNING]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [CALL_SET_DISABLED_STATE]
    }]
  }], {
    form: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['formControl']
    }],
    isDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['disabled']
    }],
    model: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngModel']
    }],
    update: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['ngModelChange']
    }]
  });
})();
const formDirectiveProvider = {
  provide: ControlContainer,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormGroupDirective)
};
/**
 * @description
 *
 * Binds an existing `FormGroup` or `FormRecord` to a DOM element.
 *
 * This directive accepts an existing `FormGroup` instance. It will then use this
 * `FormGroup` instance to match any child `FormControl`, `FormGroup`/`FormRecord`,
 * and `FormArray` instances to child `FormControlName`, `FormGroupName`,
 * and `FormArrayName` directives.
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 * @see {@link AbstractControl}
 *
 * @usageNotes
 * ### Register Form Group
 *
 * The following example registers a `FormGroup` with first name and last name controls,
 * and listens for the *ngSubmit* event when the button is clicked.
 *
 * {@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
 *
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class FormGroupDirective extends ControlContainer {
  constructor(validators, asyncValidators, callSetDisabledState) {
    super();
    this.callSetDisabledState = callSetDisabledState;
    /**
     * @description
     * Reports whether the form submission has been triggered.
     */
    this.submitted = false;
    /**
     * Callback that should be invoked when controls in FormGroup or FormArray collection change
     * (added or removed). This callback triggers corresponding DOM updates.
     */
    this._onCollectionChange = () => this._updateDomValue();
    /**
     * @description
     * Tracks the list of added `FormControlName` instances
     */
    this.directives = [];
    /**
     * @description
     * Tracks the `FormGroup` bound to this directive.
     */
    this.form = null;
    /**
     * @description
     * Emits an event when the form submission has been triggered.
     */
    this.ngSubmit = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    this._checkFormPresent();
    if (changes.hasOwnProperty('form')) {
      this._updateValidators();
      this._updateDomValue();
      this._updateRegistrations();
      this._oldForm = this.form;
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this.form) {
      cleanUpValidators(this.form, this);
      // Currently the `onCollectionChange` callback is rewritten each time the
      // `_registerOnCollectionChange` function is invoked. The implication is that cleanup should
      // happen *only* when the `onCollectionChange` callback was set by this directive instance.
      // Otherwise it might cause overriding a callback of some other directive instances. We should
      // consider updating this logic later to make it similar to how `onChange` callbacks are
      // handled, see https://github.com/angular/angular/issues/39732 for additional info.
      if (this.form._onCollectionChange === this._onCollectionChange) {
        this.form._registerOnCollectionChange(() => {});
      }
    }
  }
  /**
   * @description
   * Returns this directive's instance.
   */
  get formDirective() {
    return this;
  }
  /**
   * @description
   * Returns the `FormGroup` bound to this directive.
   */
  get control() {
    return this.form;
  }
  /**
   * @description
   * Returns an array representing the path to this group. Because this directive
   * always lives at the top level of a form, it always an empty array.
   */
  get path() {
    return [];
  }
  /**
   * @description
   * Method that sets up the control directive in this group, re-calculates its value
   * and validity, and adds the instance to the internal list of directives.
   *
   * @param dir The `FormControlName` directive instance.
   */
  addControl(dir) {
    const ctrl = this.form.get(dir.path);
    setUpControl(ctrl, dir, this.callSetDisabledState);
    ctrl.updateValueAndValidity({
      emitEvent: false
    });
    this.directives.push(dir);
    return ctrl;
  }
  /**
   * @description
   * Retrieves the `FormControl` instance from the provided `FormControlName` directive
   *
   * @param dir The `FormControlName` directive instance.
   */
  getControl(dir) {
    return this.form.get(dir.path);
  }
  /**
   * @description
   * Removes the `FormControlName` instance from the internal list of directives
   *
   * @param dir The `FormControlName` directive instance.
   */
  removeControl(dir) {
    cleanUpControl(dir.control || null, dir, /* validateControlPresenceOnChange */false);
    removeListItem$1(this.directives, dir);
  }
  /**
   * Adds a new `FormGroupName` directive instance to the form.
   *
   * @param dir The `FormGroupName` directive instance.
   */
  addFormGroup(dir) {
    this._setUpFormContainer(dir);
  }
  /**
   * Performs the necessary cleanup when a `FormGroupName` directive instance is removed from the
   * view.
   *
   * @param dir The `FormGroupName` directive instance.
   */
  removeFormGroup(dir) {
    this._cleanUpFormContainer(dir);
  }
  /**
   * @description
   * Retrieves the `FormGroup` for a provided `FormGroupName` directive instance
   *
   * @param dir The `FormGroupName` directive instance.
   */
  getFormGroup(dir) {
    return this.form.get(dir.path);
  }
  /**
   * Performs the necessary setup when a `FormArrayName` directive instance is added to the view.
   *
   * @param dir The `FormArrayName` directive instance.
   */
  addFormArray(dir) {
    this._setUpFormContainer(dir);
  }
  /**
   * Performs the necessary cleanup when a `FormArrayName` directive instance is removed from the
   * view.
   *
   * @param dir The `FormArrayName` directive instance.
   */
  removeFormArray(dir) {
    this._cleanUpFormContainer(dir);
  }
  /**
   * @description
   * Retrieves the `FormArray` for a provided `FormArrayName` directive instance.
   *
   * @param dir The `FormArrayName` directive instance.
   */
  getFormArray(dir) {
    return this.form.get(dir.path);
  }
  /**
   * Sets the new value for the provided `FormControlName` directive.
   *
   * @param dir The `FormControlName` directive instance.
   * @param value The new value for the directive's control.
   */
  updateModel(dir, value) {
    const ctrl = this.form.get(dir.path);
    ctrl.setValue(value);
  }
  /**
   * @description
   * Method called with the "submit" event is triggered on the form.
   * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
   *
   * @param $event The "submit" event object
   */
  onSubmit($event) {
    this.submitted = true;
    syncPendingControls(this.form, this.directives);
    this.ngSubmit.emit($event);
    // Forms with `method="dialog"` have some special behavior that won't reload the page and that
    // shouldn't be prevented. Note that we need to null check the `event` and the `target`, because
    // some internal apps call this method directly with the wrong arguments.
    return $event?.target?.method === 'dialog';
  }
  /**
   * @description
   * Method called when the "reset" event is triggered on the form.
   */
  onReset() {
    this.resetForm();
  }
  /**
   * @description
   * Resets the form to an initial value and resets its submitted status.
   *
   * @param value The new value for the form.
   */
  resetForm(value = undefined) {
    this.form.reset(value);
    this.submitted = false;
  }
  /** @internal */
  _updateDomValue() {
    this.directives.forEach(dir => {
      const oldCtrl = dir.control;
      const newCtrl = this.form.get(dir.path);
      if (oldCtrl !== newCtrl) {
        // Note: the value of the `dir.control` may not be defined, for example when it's a first
        // `FormControl` that is added to a `FormGroup` instance (via `addControl` call).
        cleanUpControl(oldCtrl || null, dir);
        // Check whether new control at the same location inside the corresponding `FormGroup` is an
        // instance of `FormControl` and perform control setup only if that's the case.
        // Note: we don't need to clear the list of directives (`this.directives`) here, it would be
        // taken care of in the `removeControl` method invoked when corresponding `formControlName`
        // directive instance is being removed (invoked from `FormControlName.ngOnDestroy`).
        if (isFormControl(newCtrl)) {
          setUpControl(newCtrl, dir, this.callSetDisabledState);
          dir.control = newCtrl;
        }
      }
    });
    this.form._updateTreeValidity({
      emitEvent: false
    });
  }
  _setUpFormContainer(dir) {
    const ctrl = this.form.get(dir.path);
    setUpFormContainer(ctrl, dir);
    // NOTE: this operation looks unnecessary in case no new validators were added in
    // `setUpFormContainer` call. Consider updating this code to match the logic in
    // `_cleanUpFormContainer` function.
    ctrl.updateValueAndValidity({
      emitEvent: false
    });
  }
  _cleanUpFormContainer(dir) {
    if (this.form) {
      const ctrl = this.form.get(dir.path);
      if (ctrl) {
        const isControlUpdated = cleanUpFormContainer(ctrl, dir);
        if (isControlUpdated) {
          // Run validity check only in case a control was updated (i.e. view validators were
          // removed) as removing view validators might cause validity to change.
          ctrl.updateValueAndValidity({
            emitEvent: false
          });
        }
      }
    }
  }
  _updateRegistrations() {
    this.form._registerOnCollectionChange(this._onCollectionChange);
    if (this._oldForm) {
      this._oldForm._registerOnCollectionChange(() => {});
    }
  }
  _updateValidators() {
    setUpValidators(this.form, this);
    if (this._oldForm) {
      cleanUpValidators(this._oldForm, this);
    }
  }
  _checkFormPresent() {
    if (!this.form && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw missingFormException();
    }
  }
  static {
    this.ɵfac = function FormGroupDirective_Factory(t) {
      return new (t || FormGroupDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](CALL_SET_DISABLED_STATE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: FormGroupDirective,
      selectors: [["", "formGroup", ""]],
      hostBindings: function FormGroupDirective_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("submit", function FormGroupDirective_submit_HostBindingHandler($event) {
            return ctx.onSubmit($event);
          })("reset", function FormGroupDirective_reset_HostBindingHandler() {
            return ctx.onReset();
          });
        }
      },
      inputs: {
        form: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "formGroup", "form"]
      },
      outputs: {
        ngSubmit: "ngSubmit"
      },
      exportAs: ["ngForm"],
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formDirectiveProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormGroupDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formGroup]',
      providers: [formDirectiveProvider],
      host: {
        '(submit)': 'onSubmit($event)',
        '(reset)': 'onReset()'
      },
      exportAs: 'ngForm'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [CALL_SET_DISABLED_STATE]
    }]
  }], {
    form: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['formGroup']
    }],
    ngSubmit: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
const formGroupNameProvider = {
  provide: ControlContainer,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormGroupName)
};
/**
 * @description
 *
 * Syncs a nested `FormGroup` or `FormRecord` to a DOM element.
 *
 * This directive can only be used with a parent `FormGroupDirective`.
 *
 * It accepts the string name of the nested `FormGroup` or `FormRecord` to link, and
 * looks for a `FormGroup` or `FormRecord` registered with that name in the parent
 * `FormGroup` instance you passed into `FormGroupDirective`.
 *
 * Use nested form groups to validate a sub-group of a
 * form separately from the rest or to group the values of certain
 * controls into their own nested object.
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 *
 * @usageNotes
 *
 * ### Access the group by name
 *
 * The following example uses the `AbstractControl.get` method to access the
 * associated `FormGroup`
 *
 * ```ts
 *   this.form.get('name');
 * ```
 *
 * ### Access individual controls in the group
 *
 * The following example uses the `AbstractControl.get` method to access
 * individual controls within the group using dot syntax.
 *
 * ```ts
 *   this.form.get('name.first');
 * ```
 *
 * ### Register a nested `FormGroup`.
 *
 * The following example registers a nested *name* `FormGroup` within an existing `FormGroup`,
 * and provides methods to retrieve the nested `FormGroup` and individual controls.
 *
 * {@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
 *
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class FormGroupName extends AbstractFormGroupDirective {
  constructor(parent, validators, asyncValidators) {
    super();
    /**
     * @description
     * Tracks the name of the `FormGroup` bound to the directive. The name corresponds
     * to a key in the parent `FormGroup` or `FormArray`.
     * Accepts a name as a string or a number.
     * The name in the form of a string is useful for individual forms,
     * while the numerical form allows for form groups to be bound
     * to indices when iterating over groups in a `FormArray`.
     */
    this.name = null;
    this._parent = parent;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
  }
  /** @internal */
  _checkParentType() {
    if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw groupParentException();
    }
  }
  static {
    this.ɵfac = function FormGroupName_Factory(t) {
      return new (t || FormGroupName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: FormGroupName,
      selectors: [["", "formGroupName", ""]],
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "formGroupName", "name"]
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formGroupNameProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormGroupName, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formGroupName]',
      providers: [formGroupNameProvider]
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['formGroupName']
    }]
  });
})();
const formArrayNameProvider = {
  provide: ControlContainer,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormArrayName)
};
/**
 * @description
 *
 * Syncs a nested `FormArray` to a DOM element.
 *
 * This directive is designed to be used with a parent `FormGroupDirective` (selector:
 * `[formGroup]`).
 *
 * It accepts the string name of the nested `FormArray` you want to link, and
 * will look for a `FormArray` registered with that name in the parent
 * `FormGroup` instance you passed into `FormGroupDirective`.
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 * @see {@link AbstractControl}
 *
 * @usageNotes
 *
 * ### Example
 *
 * {@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
 *
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class FormArrayName extends ControlContainer {
  constructor(parent, validators, asyncValidators) {
    super();
    /**
     * @description
     * Tracks the name of the `FormArray` bound to the directive. The name corresponds
     * to a key in the parent `FormGroup` or `FormArray`.
     * Accepts a name as a string or a number.
     * The name in the form of a string is useful for individual forms,
     * while the numerical form allows for form arrays to be bound
     * to indices when iterating over arrays in a `FormArray`.
     */
    this.name = null;
    this._parent = parent;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
  }
  /**
   * A lifecycle method called when the directive's inputs are initialized. For internal use only.
   * @throws If the directive does not have a valid parent.
   * @nodoc
   */
  ngOnInit() {
    this._checkParentType();
    this.formDirective.addFormArray(this);
  }
  /**
   * A lifecycle method called before the directive's instance is destroyed. For internal use only.
   * @nodoc
   */
  ngOnDestroy() {
    if (this.formDirective) {
      this.formDirective.removeFormArray(this);
    }
  }
  /**
   * @description
   * The `FormArray` bound to this directive.
   */
  get control() {
    return this.formDirective.getFormArray(this);
  }
  /**
   * @description
   * The top-level directive for this group if present, otherwise null.
   */
  get formDirective() {
    return this._parent ? this._parent.formDirective : null;
  }
  /**
   * @description
   * Returns an array that represents the path from the top-level form to this control.
   * Each index is the string name of the control on that level.
   */
  get path() {
    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
  }
  _checkParentType() {
    if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw arrayParentException();
    }
  }
  static {
    this.ɵfac = function FormArrayName_Factory(t) {
      return new (t || FormArrayName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: FormArrayName,
      selectors: [["", "formArrayName", ""]],
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "formArrayName", "name"]
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([formArrayNameProvider]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormArrayName, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formArrayName]',
      providers: [formArrayNameProvider]
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['formArrayName']
    }]
  });
})();
function _hasInvalidParent(parent) {
  return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) && !(parent instanceof FormArrayName);
}
const controlNameBinding = {
  provide: NgControl,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => FormControlName)
};
/**
 * @description
 * Syncs a `FormControl` in an existing `FormGroup` to a form control
 * element by name.
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 * @see {@link FormControl}
 * @see {@link AbstractControl}
 *
 * @usageNotes
 *
 * ### Register `FormControl` within a group
 *
 * The following example shows how to register multiple form controls within a form group
 * and set their value.
 *
 * {@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
 *
 * To see `formControlName` examples with different form control types, see:
 *
 * * Radio buttons: `RadioControlValueAccessor`
 * * Selects: `SelectControlValueAccessor`
 *
 * ### Use with ngModel is deprecated
 *
 * Support for using the `ngModel` input property and `ngModelChange` event with reactive
 * form directives has been deprecated in Angular v6 and is scheduled for removal in
 * a future version of Angular.
 *
 * For details, see [Deprecated features](guide/deprecations#ngmodel-with-reactive-forms).
 *
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class FormControlName extends NgControl {
  /**
   * @description
   * Triggers a warning in dev mode that this input should not be used with reactive forms.
   */
  set isDisabled(isDisabled) {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      console.warn(disabledAttrWarning);
    }
  }
  /**
   * @description
   * Static property used to track whether any ngModel warnings have been sent across
   * all instances of FormControlName. Used to support warning config of "once".
   *
   * @internal
   */
  static {
    this._ngModelWarningSentOnce = false;
  }
  constructor(parent, validators, asyncValidators, valueAccessors, _ngModelWarningConfig) {
    super();
    this._ngModelWarningConfig = _ngModelWarningConfig;
    this._added = false;
    /**
     * @description
     * Tracks the name of the `FormControl` bound to the directive. The name corresponds
     * to a key in the parent `FormGroup` or `FormArray`.
     * Accepts a name as a string or a number.
     * The name in the form of a string is useful for individual forms,
     * while the numerical form allows for form controls to be bound
     * to indices when iterating over controls in a `FormArray`.
     */
    this.name = null;
    /** @deprecated as of v6 */
    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * @description
     * Instance property used to track whether an ngModel warning has been sent out for this
     * particular FormControlName instance. Used to support warning config of "always".
     *
     * @internal
     */
    this._ngModelWarningSent = false;
    this._parent = parent;
    this._setValidators(validators);
    this._setAsyncValidators(asyncValidators);
    this.valueAccessor = selectValueAccessor(this, valueAccessors);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (!this._added) this._setUpControl();
    if (isPropertyUpdated(changes, this.viewModel)) {
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        _ngModelWarning('formControlName', FormControlName, this, this._ngModelWarningConfig);
      }
      this.viewModel = this.model;
      this.formDirective.updateModel(this, this.model);
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this.formDirective) {
      this.formDirective.removeControl(this);
    }
  }
  /**
   * @description
   * Sets the new value for the view model and emits an `ngModelChange` event.
   *
   * @param newValue The new value for the view model.
   */
  viewToModelUpdate(newValue) {
    this.viewModel = newValue;
    this.update.emit(newValue);
  }
  /**
   * @description
   * Returns an array that represents the path from the top-level form to this control.
   * Each index is the string name of the control on that level.
   */
  get path() {
    return controlPath(this.name == null ? this.name : this.name.toString(), this._parent);
  }
  /**
   * @description
   * The top-level directive for this group if present, otherwise null.
   */
  get formDirective() {
    return this._parent ? this._parent.formDirective : null;
  }
  _checkParentType() {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (!(this._parent instanceof FormGroupName) && this._parent instanceof AbstractFormGroupDirective) {
        throw ngModelGroupException();
      } else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) && !(this._parent instanceof FormArrayName)) {
        throw controlParentException();
      }
    }
  }
  _setUpControl() {
    this._checkParentType();
    this.control = this.formDirective.addControl(this);
    this._added = true;
  }
  static {
    this.ɵfac = function FormControlName_Factory(t) {
      return new (t || FormControlName)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ControlContainer, 13), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_ASYNC_VALIDATORS, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_VALUE_ACCESSOR, 10), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NG_MODEL_WITH_FORM_CONTROL_WARNING, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: FormControlName,
      selectors: [["", "formControlName", ""]],
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "formControlName", "name"],
        isDisabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "disabled", "isDisabled"],
        model: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngModel", "model"]
      },
      outputs: {
        update: "ngModelChange"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([controlNameBinding]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormControlName, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[formControlName]',
      providers: [controlNameBinding]
    }]
  }], () => [{
    type: ControlContainer,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.SkipSelf
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_ASYNC_VALIDATORS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Self
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_VALUE_ACCESSOR]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [NG_MODEL_WITH_FORM_CONTROL_WARNING]
    }]
  }], {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['formControlName']
    }],
    isDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['disabled']
    }],
    model: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngModel']
    }],
    update: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['ngModelChange']
    }]
  });
})();
const SELECT_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SelectControlValueAccessor),
  multi: true
};
function _buildValueString$1(id, value) {
  if (id == null) return `${value}`;
  if (value && typeof value === 'object') value = 'Object';
  return `${id}: ${value}`.slice(0, 50);
}
function _extractId$1(valueString) {
  return valueString.split(':')[0];
}
/**
 * @description
 * The `ControlValueAccessor` for writing select control values and listening to select control
 * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
 * `NgModel` directives.
 *
 * @usageNotes
 *
 * ### Using select controls in a reactive form
 *
 * The following examples show how to use a select control in a reactive form.
 *
 * {@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
 *
 * ### Using select controls in a template-driven form
 *
 * To use a select in a template-driven form, simply add an `ngModel` and a `name`
 * attribute to the main `<select>` tag.
 *
 * {@example forms/ts/selectControl/select_control_example.ts region='Component'}
 *
 * ### Customizing option selection
 *
 * Angular uses object identity to select option. It's possible for the identities of items
 * to change while the data does not. This can happen, for example, if the items are produced
 * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
 * second response will produce objects with different identities.
 *
 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
 * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
 * If `compareWith` is given, Angular selects option by the return value of the function.
 *
 * ```ts
 * const selectedCountriesControl = new FormControl();
 * ```
 *
 * ```
 * <select [compareWith]="compareFn"  [formControl]="selectedCountriesControl">
 *     <option *ngFor="let country of countries" [ngValue]="country">
 *         {{country.name}}
 *     </option>
 * </select>
 *
 * compareFn(c1: Country, c2: Country): boolean {
 *     return c1 && c2 ? c1.id === c2.id : c1 === c2;
 * }
 * ```
 *
 * **Note:** We listen to the 'change' event because 'input' events aren't fired
 * for selects in IE, see:
 * https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/input_event#browser_compatibility
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class SelectControlValueAccessor extends BuiltInControlValueAccessor {
  constructor() {
    super(...arguments);
    /** @internal */
    this._optionMap = new Map();
    /** @internal */
    this._idCounter = 0;
    this._compareWith = Object.is;
  }
  /**
   * @description
   * Tracks the option comparison algorithm for tracking identities when
   * checking for changes.
   */
  set compareWith(fn) {
    if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1201 /* RuntimeErrorCode.COMPAREWITH_NOT_A_FN */, `compareWith must be a function, but received ${JSON.stringify(fn)}`);
    }
    this._compareWith = fn;
  }
  /**
   * Sets the "value" property on the select element.
   * @nodoc
   */
  writeValue(value) {
    this.value = value;
    const id = this._getOptionId(value);
    const valueString = _buildValueString$1(id, value);
    this.setProperty('value', valueString);
  }
  /**
   * Registers a function called when the control value changes.
   * @nodoc
   */
  registerOnChange(fn) {
    this.onChange = valueString => {
      this.value = this._getOptionValue(valueString);
      fn(this.value);
    };
  }
  /** @internal */
  _registerOption() {
    return (this._idCounter++).toString();
  }
  /** @internal */
  _getOptionId(value) {
    for (const id of this._optionMap.keys()) {
      if (this._compareWith(this._optionMap.get(id), value)) return id;
    }
    return null;
  }
  /** @internal */
  _getOptionValue(valueString) {
    const id = _extractId$1(valueString);
    return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵSelectControlValueAccessor_BaseFactory;
      return function SelectControlValueAccessor_Factory(t) {
        return (ɵSelectControlValueAccessor_BaseFactory || (ɵSelectControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](SelectControlValueAccessor)))(t || SelectControlValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: SelectControlValueAccessor,
      selectors: [["select", "formControlName", "", 3, "multiple", ""], ["select", "formControl", "", 3, "multiple", ""], ["select", "ngModel", "", 3, "multiple", ""]],
      hostBindings: function SelectControlValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function SelectControlValueAccessor_change_HostBindingHandler($event) {
            return ctx.onChange($event.target.value);
          })("blur", function SelectControlValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      inputs: {
        compareWith: "compareWith"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([SELECT_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SelectControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
      host: {
        '(change)': 'onChange($event.target.value)',
        '(blur)': 'onTouched()'
      },
      providers: [SELECT_VALUE_ACCESSOR]
    }]
  }], null, {
    compareWith: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Marks `<option>` as dynamic, so Angular can be notified when options change.
 *
 * @see {@link SelectControlValueAccessor}
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class NgSelectOption {
  constructor(_element, _renderer, _select) {
    this._element = _element;
    this._renderer = _renderer;
    this._select = _select;
    if (this._select) this.id = this._select._registerOption();
  }
  /**
   * @description
   * Tracks the value bound to the option element. Unlike the value binding,
   * ngValue supports binding to objects.
   */
  set ngValue(value) {
    if (this._select == null) return;
    this._select._optionMap.set(this.id, value);
    this._setElementValue(_buildValueString$1(this.id, value));
    this._select.writeValue(this._select.value);
  }
  /**
   * @description
   * Tracks simple string values bound to the option element.
   * For objects, use the `ngValue` input binding.
   */
  set value(value) {
    this._setElementValue(value);
    if (this._select) this._select.writeValue(this._select.value);
  }
  /** @internal */
  _setElementValue(value) {
    this._renderer.setProperty(this._element.nativeElement, 'value', value);
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this._select) {
      this._select._optionMap.delete(this.id);
      this._select.writeValue(this._select.value);
    }
  }
  static {
    this.ɵfac = function NgSelectOption_Factory(t) {
      return new (t || NgSelectOption)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SelectControlValueAccessor, 9));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgSelectOption,
      selectors: [["option"]],
      inputs: {
        ngValue: "ngValue",
        value: "value"
      }
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSelectOption, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'option'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: SelectControlValueAccessor,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }], {
    ngValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngValue']
    }],
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['value']
    }]
  });
})();
const SELECT_MULTIPLE_VALUE_ACCESSOR = {
  provide: NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SelectMultipleControlValueAccessor),
  multi: true
};
function _buildValueString(id, value) {
  if (id == null) return `${value}`;
  if (typeof value === 'string') value = `'${value}'`;
  if (value && typeof value === 'object') value = 'Object';
  return `${id}: ${value}`.slice(0, 50);
}
function _extractId(valueString) {
  return valueString.split(':')[0];
}
/** Mock interface for HTMLCollection */
class HTMLCollection {}
/**
 * @description
 * The `ControlValueAccessor` for writing multi-select control values and listening to multi-select
 * control changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
 * `NgModel` directives.
 *
 * @see {@link SelectControlValueAccessor}
 *
 * @usageNotes
 *
 * ### Using a multi-select control
 *
 * The follow example shows you how to use a multi-select control with a reactive form.
 *
 * ```ts
 * const countryControl = new FormControl();
 * ```
 *
 * ```
 * <select multiple name="countries" [formControl]="countryControl">
 *   <option *ngFor="let country of countries" [ngValue]="country">
 *     {{ country.name }}
 *   </option>
 * </select>
 * ```
 *
 * ### Customizing option selection
 *
 * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
 * See the `SelectControlValueAccessor` for usage.
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class SelectMultipleControlValueAccessor extends BuiltInControlValueAccessor {
  constructor() {
    super(...arguments);
    /** @internal */
    this._optionMap = new Map();
    /** @internal */
    this._idCounter = 0;
    this._compareWith = Object.is;
  }
  /**
   * @description
   * Tracks the option comparison algorithm for tracking identities when
   * checking for changes.
   */
  set compareWith(fn) {
    if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵRuntimeError"](1201 /* RuntimeErrorCode.COMPAREWITH_NOT_A_FN */, `compareWith must be a function, but received ${JSON.stringify(fn)}`);
    }
    this._compareWith = fn;
  }
  /**
   * Sets the "value" property on one or of more of the select's options.
   * @nodoc
   */
  writeValue(value) {
    this.value = value;
    let optionSelectedStateSetter;
    if (Array.isArray(value)) {
      // convert values to ids
      const ids = value.map(v => this._getOptionId(v));
      optionSelectedStateSetter = (opt, o) => {
        opt._setSelected(ids.indexOf(o.toString()) > -1);
      };
    } else {
      optionSelectedStateSetter = (opt, o) => {
        opt._setSelected(false);
      };
    }
    this._optionMap.forEach(optionSelectedStateSetter);
  }
  /**
   * Registers a function called when the control value changes
   * and writes an array of the selected options.
   * @nodoc
   */
  registerOnChange(fn) {
    this.onChange = element => {
      const selected = [];
      const selectedOptions = element.selectedOptions;
      if (selectedOptions !== undefined) {
        const options = selectedOptions;
        for (let i = 0; i < options.length; i++) {
          const opt = options[i];
          const val = this._getOptionValue(opt.value);
          selected.push(val);
        }
      }
      // Degrade to use `options` when `selectedOptions` property is not available.
      // Note: the `selectedOptions` is available in all supported browsers, but the Domino lib
      // doesn't have it currently, see https://github.com/fgnass/domino/issues/177.
      else {
        const options = element.options;
        for (let i = 0; i < options.length; i++) {
          const opt = options[i];
          if (opt.selected) {
            const val = this._getOptionValue(opt.value);
            selected.push(val);
          }
        }
      }
      this.value = selected;
      fn(selected);
    };
  }
  /** @internal */
  _registerOption(value) {
    const id = (this._idCounter++).toString();
    this._optionMap.set(id, value);
    return id;
  }
  /** @internal */
  _getOptionId(value) {
    for (const id of this._optionMap.keys()) {
      if (this._compareWith(this._optionMap.get(id)._value, value)) return id;
    }
    return null;
  }
  /** @internal */
  _getOptionValue(valueString) {
    const id = _extractId(valueString);
    return this._optionMap.has(id) ? this._optionMap.get(id)._value : valueString;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵSelectMultipleControlValueAccessor_BaseFactory;
      return function SelectMultipleControlValueAccessor_Factory(t) {
        return (ɵSelectMultipleControlValueAccessor_BaseFactory || (ɵSelectMultipleControlValueAccessor_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](SelectMultipleControlValueAccessor)))(t || SelectMultipleControlValueAccessor);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: SelectMultipleControlValueAccessor,
      selectors: [["select", "multiple", "", "formControlName", ""], ["select", "multiple", "", "formControl", ""], ["select", "multiple", "", "ngModel", ""]],
      hostBindings: function SelectMultipleControlValueAccessor_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function SelectMultipleControlValueAccessor_change_HostBindingHandler($event) {
            return ctx.onChange($event.target);
          })("blur", function SelectMultipleControlValueAccessor_blur_HostBindingHandler() {
            return ctx.onTouched();
          });
        }
      },
      inputs: {
        compareWith: "compareWith"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([SELECT_MULTIPLE_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SelectMultipleControlValueAccessor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
      host: {
        '(change)': 'onChange($event.target)',
        '(blur)': 'onTouched()'
      },
      providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
    }]
  }], null, {
    compareWith: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Marks `<option>` as dynamic, so Angular can be notified when options change.
 *
 * @see {@link SelectMultipleControlValueAccessor}
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class ɵNgSelectMultipleOption {
  constructor(_element, _renderer, _select) {
    this._element = _element;
    this._renderer = _renderer;
    this._select = _select;
    if (this._select) {
      this.id = this._select._registerOption(this);
    }
  }
  /**
   * @description
   * Tracks the value bound to the option element. Unlike the value binding,
   * ngValue supports binding to objects.
   */
  set ngValue(value) {
    if (this._select == null) return;
    this._value = value;
    this._setElementValue(_buildValueString(this.id, value));
    this._select.writeValue(this._select.value);
  }
  /**
   * @description
   * Tracks simple string values bound to the option element.
   * For objects, use the `ngValue` input binding.
   */
  set value(value) {
    if (this._select) {
      this._value = value;
      this._setElementValue(_buildValueString(this.id, value));
      this._select.writeValue(this._select.value);
    } else {
      this._setElementValue(value);
    }
  }
  /** @internal */
  _setElementValue(value) {
    this._renderer.setProperty(this._element.nativeElement, 'value', value);
  }
  /** @internal */
  _setSelected(selected) {
    this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this._select) {
      this._select._optionMap.delete(this.id);
      this._select.writeValue(this._select.value);
    }
  }
  static {
    this.ɵfac = function ɵNgSelectMultipleOption_Factory(t) {
      return new (t || ɵNgSelectMultipleOption)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SelectMultipleControlValueAccessor, 9));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: ɵNgSelectMultipleOption,
      selectors: [["option"]],
      inputs: {
        ngValue: "ngValue",
        value: "value"
      }
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵNgSelectMultipleOption, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'option'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: SelectMultipleControlValueAccessor,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Host
    }]
  }], {
    ngValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngValue']
    }],
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['value']
    }]
  });
})();

/**
 * Method that updates string to integer if not already a number
 *
 * @param value The value to convert to integer.
 * @returns value of parameter converted to number or integer.
 */
function toInteger(value) {
  return typeof value === 'number' ? value : parseInt(value, 10);
}
/**
 * Method that ensures that provided value is a float (and converts it to float if needed).
 *
 * @param value The value to convert to float.
 * @returns value of parameter converted to number or float.
 */
function toFloat(value) {
  return typeof value === 'number' ? value : parseFloat(value);
}
/**
 * A base class for Validator-based Directives. The class contains common logic shared across such
 * Directives.
 *
 * For internal use only, this class is not intended for use outside of the Forms package.
 */
class AbstractValidatorDirective {
  constructor() {
    this._validator = nullValidator;
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (this.inputName in changes) {
      const input = this.normalizeInput(changes[this.inputName].currentValue);
      this._enabled = this.enabled(input);
      this._validator = this._enabled ? this.createValidator(input) : nullValidator;
      if (this._onChange) {
        this._onChange();
      }
    }
  }
  /** @nodoc */
  validate(control) {
    return this._validator(control);
  }
  /** @nodoc */
  registerOnValidatorChange(fn) {
    this._onChange = fn;
  }
  /**
   * @description
   * Determines whether this validator should be active or not based on an input.
   * Base class implementation checks whether an input is defined (if the value is different from
   * `null` and `undefined`). Validator classes that extend this base class can override this
   * function with the logic specific to a particular validator directive.
   */
  enabled(input) {
    return input != null /* both `null` and `undefined` */;
  }
  static {
    this.ɵfac = function AbstractValidatorDirective_Factory(t) {
      return new (t || AbstractValidatorDirective)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: AbstractValidatorDirective,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AbstractValidatorDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive
  }], null, null);
})();
/**
 * @description
 * Provider which adds `MaxValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const MAX_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MaxValidator),
  multi: true
};
/**
 * A directive which installs the {@link MaxValidator} for any `formControlName`,
 * `formControl`, or control with `ngModel` that also has a `max` attribute.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a max validator
 *
 * The following example shows how to add a max validator to an input attached to an
 * ngModel binding.
 *
 * ```html
 * <input type="number" ngModel max="4">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class MaxValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'max';
    /** @internal */
    this.normalizeInput = input => toFloat(input);
    /** @internal */
    this.createValidator = max => maxValidator(max);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMaxValidator_BaseFactory;
      return function MaxValidator_Factory(t) {
        return (ɵMaxValidator_BaseFactory || (ɵMaxValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MaxValidator)))(t || MaxValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MaxValidator,
      selectors: [["input", "type", "number", "max", "", "formControlName", ""], ["input", "type", "number", "max", "", "formControl", ""], ["input", "type", "number", "max", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function MaxValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("max", ctx._enabled ? ctx.max : null);
        }
      },
      inputs: {
        max: "max"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MAX_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MaxValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]',
      providers: [MAX_VALIDATOR],
      host: {
        '[attr.max]': '_enabled ? max : null'
      }
    }]
  }], null, {
    max: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Provider which adds `MinValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const MIN_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MinValidator),
  multi: true
};
/**
 * A directive which installs the {@link MinValidator} for any `formControlName`,
 * `formControl`, or control with `ngModel` that also has a `min` attribute.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a min validator
 *
 * The following example shows how to add a min validator to an input attached to an
 * ngModel binding.
 *
 * ```html
 * <input type="number" ngModel min="4">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class MinValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'min';
    /** @internal */
    this.normalizeInput = input => toFloat(input);
    /** @internal */
    this.createValidator = min => minValidator(min);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMinValidator_BaseFactory;
      return function MinValidator_Factory(t) {
        return (ɵMinValidator_BaseFactory || (ɵMinValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MinValidator)))(t || MinValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MinValidator,
      selectors: [["input", "type", "number", "min", "", "formControlName", ""], ["input", "type", "number", "min", "", "formControl", ""], ["input", "type", "number", "min", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function MinValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("min", ctx._enabled ? ctx.min : null);
        }
      },
      inputs: {
        min: "min"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MIN_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MinValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]',
      providers: [MIN_VALIDATOR],
      host: {
        '[attr.min]': '_enabled ? min : null'
      }
    }]
  }], null, {
    min: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Provider which adds `RequiredValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const REQUIRED_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => RequiredValidator),
  multi: true
};
/**
 * @description
 * Provider which adds `CheckboxRequiredValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const CHECKBOX_REQUIRED_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => CheckboxRequiredValidator),
  multi: true
};
/**
 * @description
 * A directive that adds the `required` validator to any controls marked with the
 * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a required validator using template-driven forms
 *
 * ```
 * <input name="fullName" ngModel required>
 * ```
 *
 * @ngModule FormsModule
 * @ngModule ReactiveFormsModule
 * @publicApi
 */
class RequiredValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'required';
    /** @internal */
    this.normalizeInput = _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute;
    /** @internal */
    this.createValidator = input => requiredValidator;
  }
  /** @nodoc */
  enabled(input) {
    return input;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵRequiredValidator_BaseFactory;
      return function RequiredValidator_Factory(t) {
        return (ɵRequiredValidator_BaseFactory || (ɵRequiredValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](RequiredValidator)))(t || RequiredValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: RequiredValidator,
      selectors: [["", "required", "", "formControlName", "", 3, "type", "checkbox"], ["", "required", "", "formControl", "", 3, "type", "checkbox"], ["", "required", "", "ngModel", "", 3, "type", "checkbox"]],
      hostVars: 1,
      hostBindings: function RequiredValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("required", ctx._enabled ? "" : null);
        }
      },
      inputs: {
        required: "required"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([REQUIRED_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RequiredValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
      providers: [REQUIRED_VALIDATOR],
      host: {
        '[attr.required]': '_enabled ? "" : null'
      }
    }]
  }], null, {
    required: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * A Directive that adds the `required` validator to checkbox controls marked with the
 * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a required checkbox validator using template-driven forms
 *
 * The following example shows how to add a checkbox required validator to an input attached to an
 * ngModel binding.
 *
 * ```
 * <input type="checkbox" name="active" ngModel required>
 * ```
 *
 * @publicApi
 * @ngModule FormsModule
 * @ngModule ReactiveFormsModule
 */
class CheckboxRequiredValidator extends RequiredValidator {
  constructor() {
    super(...arguments);
    /** @internal */
    this.createValidator = input => requiredTrueValidator;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵCheckboxRequiredValidator_BaseFactory;
      return function CheckboxRequiredValidator_Factory(t) {
        return (ɵCheckboxRequiredValidator_BaseFactory || (ɵCheckboxRequiredValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](CheckboxRequiredValidator)))(t || CheckboxRequiredValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: CheckboxRequiredValidator,
      selectors: [["input", "type", "checkbox", "required", "", "formControlName", ""], ["input", "type", "checkbox", "required", "", "formControl", ""], ["input", "type", "checkbox", "required", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function CheckboxRequiredValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("required", ctx._enabled ? "" : null);
        }
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([CHECKBOX_REQUIRED_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CheckboxRequiredValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
      providers: [CHECKBOX_REQUIRED_VALIDATOR],
      host: {
        '[attr.required]': '_enabled ? "" : null'
      }
    }]
  }], null, null);
})();
/**
 * @description
 * Provider which adds `EmailValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const EMAIL_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => EmailValidator),
  multi: true
};
/**
 * A directive that adds the `email` validator to controls marked with the
 * `email` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * The email validation is based on the WHATWG HTML specification with some enhancements to
 * incorporate more RFC rules. More information can be found on the [Validators.email
 * page](api/forms/Validators#email).
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding an email validator
 *
 * The following example shows how to add an email validator to an input attached to an ngModel
 * binding.
 *
 * ```
 * <input type="email" name="email" ngModel email>
 * <input type="email" name="email" ngModel email="true">
 * <input type="email" name="email" ngModel [email]="true">
 * ```
 *
 * @publicApi
 * @ngModule FormsModule
 * @ngModule ReactiveFormsModule
 */
class EmailValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'email';
    /** @internal */
    this.normalizeInput = _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute;
    /** @internal */
    this.createValidator = input => emailValidator;
  }
  /** @nodoc */
  enabled(input) {
    return input;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵEmailValidator_BaseFactory;
      return function EmailValidator_Factory(t) {
        return (ɵEmailValidator_BaseFactory || (ɵEmailValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](EmailValidator)))(t || EmailValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: EmailValidator,
      selectors: [["", "email", "", "formControlName", ""], ["", "email", "", "formControl", ""], ["", "email", "", "ngModel", ""]],
      inputs: {
        email: "email"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([EMAIL_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmailValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[email][formControlName],[email][formControl],[email][ngModel]',
      providers: [EMAIL_VALIDATOR]
    }]
  }], null, {
    email: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Provider which adds `MinLengthValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const MIN_LENGTH_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MinLengthValidator),
  multi: true
};
/**
 * A directive that adds minimum length validation to controls marked with the
 * `minlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a minimum length validator
 *
 * The following example shows how to add a minimum length validator to an input attached to an
 * ngModel binding.
 *
 * ```html
 * <input name="firstName" ngModel minlength="4">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class MinLengthValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'minlength';
    /** @internal */
    this.normalizeInput = input => toInteger(input);
    /** @internal */
    this.createValidator = minlength => minLengthValidator(minlength);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMinLengthValidator_BaseFactory;
      return function MinLengthValidator_Factory(t) {
        return (ɵMinLengthValidator_BaseFactory || (ɵMinLengthValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MinLengthValidator)))(t || MinLengthValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MinLengthValidator,
      selectors: [["", "minlength", "", "formControlName", ""], ["", "minlength", "", "formControl", ""], ["", "minlength", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function MinLengthValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("minlength", ctx._enabled ? ctx.minlength : null);
        }
      },
      inputs: {
        minlength: "minlength"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MIN_LENGTH_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MinLengthValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
      providers: [MIN_LENGTH_VALIDATOR],
      host: {
        '[attr.minlength]': '_enabled ? minlength : null'
      }
    }]
  }], null, {
    minlength: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Provider which adds `MaxLengthValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const MAX_LENGTH_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => MaxLengthValidator),
  multi: true
};
/**
 * A directive that adds maximum length validation to controls marked with the
 * `maxlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a maximum length validator
 *
 * The following example shows how to add a maximum length validator to an input attached to an
 * ngModel binding.
 *
 * ```html
 * <input name="firstName" ngModel maxlength="25">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class MaxLengthValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'maxlength';
    /** @internal */
    this.normalizeInput = input => toInteger(input);
    /** @internal */
    this.createValidator = maxlength => maxLengthValidator(maxlength);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMaxLengthValidator_BaseFactory;
      return function MaxLengthValidator_Factory(t) {
        return (ɵMaxLengthValidator_BaseFactory || (ɵMaxLengthValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MaxLengthValidator)))(t || MaxLengthValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MaxLengthValidator,
      selectors: [["", "maxlength", "", "formControlName", ""], ["", "maxlength", "", "formControl", ""], ["", "maxlength", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function MaxLengthValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("maxlength", ctx._enabled ? ctx.maxlength : null);
        }
      },
      inputs: {
        maxlength: "maxlength"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([MAX_LENGTH_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MaxLengthValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
      providers: [MAX_LENGTH_VALIDATOR],
      host: {
        '[attr.maxlength]': '_enabled ? maxlength : null'
      }
    }]
  }], null, {
    maxlength: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * @description
 * Provider which adds `PatternValidator` to the `NG_VALIDATORS` multi-provider list.
 */
const PATTERN_VALIDATOR = {
  provide: NG_VALIDATORS,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => PatternValidator),
  multi: true
};
/**
 * @description
 * A directive that adds regex pattern validation to controls marked with the
 * `pattern` attribute. The regex must match the entire control value.
 * The directive is provided with the `NG_VALIDATORS` multi-provider list.
 *
 * @see [Form Validation](guide/form-validation)
 *
 * @usageNotes
 *
 * ### Adding a pattern validator
 *
 * The following example shows how to add a pattern validator to an input attached to an
 * ngModel binding.
 *
 * ```html
 * <input name="firstName" ngModel pattern="[a-zA-Z ]*">
 * ```
 *
 * @ngModule ReactiveFormsModule
 * @ngModule FormsModule
 * @publicApi
 */
class PatternValidator extends AbstractValidatorDirective {
  constructor() {
    super(...arguments);
    /** @internal */
    this.inputName = 'pattern';
    /** @internal */
    this.normalizeInput = input => input;
    /** @internal */
    this.createValidator = input => patternValidator(input);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵPatternValidator_BaseFactory;
      return function PatternValidator_Factory(t) {
        return (ɵPatternValidator_BaseFactory || (ɵPatternValidator_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](PatternValidator)))(t || PatternValidator);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: PatternValidator,
      selectors: [["", "pattern", "", "formControlName", ""], ["", "pattern", "", "formControl", ""], ["", "pattern", "", "ngModel", ""]],
      hostVars: 1,
      hostBindings: function PatternValidator_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("pattern", ctx._enabled ? ctx.pattern : null);
        }
      },
      inputs: {
        pattern: "pattern"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([PATTERN_VALIDATOR]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PatternValidator, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
      providers: [PATTERN_VALIDATOR],
      host: {
        '[attr.pattern]': '_enabled ? pattern : null'
      }
    }]
  }], null, {
    pattern: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
const SHARED_FORM_DIRECTIVES = [ɵNgNoValidate, NgSelectOption, ɵNgSelectMultipleOption, DefaultValueAccessor, NumberValueAccessor, RangeValueAccessor, CheckboxControlValueAccessor, SelectControlValueAccessor, SelectMultipleControlValueAccessor, RadioControlValueAccessor, NgControlStatus, NgControlStatusGroup, RequiredValidator, MinLengthValidator, MaxLengthValidator, PatternValidator, CheckboxRequiredValidator, EmailValidator, MinValidator, MaxValidator];
const TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm];
const REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
/**
 * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
 */
class ɵInternalFormsSharedModule {
  static {
    this.ɵfac = function ɵInternalFormsSharedModule_Factory(t) {
      return new (t || ɵInternalFormsSharedModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: ɵInternalFormsSharedModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ɵInternalFormsSharedModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: SHARED_FORM_DIRECTIVES,
      exports: SHARED_FORM_DIRECTIVES
    }]
  }], null, null);
})();

/**
 * Tracks the value and validity state of an array of `FormControl`,
 * `FormGroup` or `FormArray` instances.
 *
 * A `FormArray` aggregates the values of each child `FormControl` into an array.
 * It calculates its status by reducing the status values of its children. For example, if one of
 * the controls in a `FormArray` is invalid, the entire array becomes invalid.
 *
 * `FormArray` accepts one generic argument, which is the type of the controls inside.
 * If you need a heterogenous array, use {@link UntypedFormArray}.
 *
 * `FormArray` is one of the four fundamental building blocks used to define forms in Angular,
 * along with `FormControl`, `FormGroup`, and `FormRecord`.
 *
 * @usageNotes
 *
 * ### Create an array of form controls
 *
 * ```
 * const arr = new FormArray([
 *   new FormControl('Nancy', Validators.minLength(2)),
 *   new FormControl('Drew'),
 * ]);
 *
 * console.log(arr.value);   // ['Nancy', 'Drew']
 * console.log(arr.status);  // 'VALID'
 * ```
 *
 * ### Create a form array with array-level validators
 *
 * You include array-level validators and async validators. These come in handy
 * when you want to perform validation that considers the value of more than one child
 * control.
 *
 * The two types of validators are passed in separately as the second and third arg
 * respectively, or together as part of an options object.
 *
 * ```
 * const arr = new FormArray([
 *   new FormControl('Nancy'),
 *   new FormControl('Drew')
 * ], {validators: myValidator, asyncValidators: myAsyncValidator});
 * ```
 *
 * ### Set the updateOn property for all controls in a form array
 *
 * The options object is used to set a default value for each child
 * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
 * array level, all child controls default to 'blur', unless the child
 * has explicitly specified a different `updateOn` value.
 *
 * ```ts
 * const arr = new FormArray([
 *    new FormControl()
 * ], {updateOn: 'blur'});
 * ```
 *
 * ### Adding or removing controls from a form array
 *
 * To change the controls in the array, use the `push`, `insert`, `removeAt` or `clear` methods
 * in `FormArray` itself. These methods ensure the controls are properly tracked in the
 * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
 * the `FormArray` directly, as that result in strange and unexpected behavior such
 * as broken change detection.
 *
 * @publicApi
 */
class FormArray extends AbstractControl {
  /**
   * Creates a new `FormArray` instance.
   *
   * @param controls An array of child controls. Each child control is given an index
   * where it is registered.
   *
   * @param validatorOrOpts A synchronous validator function, or an array of
   * such functions, or an `AbstractControlOptions` object that contains validation functions
   * and a validation trigger.
   *
   * @param asyncValidator A single async validator or array of async validator functions
   *
   */
  constructor(controls, validatorOrOpts, asyncValidator) {
    super(pickValidators(validatorOrOpts), pickAsyncValidators(asyncValidator, validatorOrOpts));
    this.controls = controls;
    this._initObservables();
    this._setUpdateStrategy(validatorOrOpts);
    this._setUpControls();
    this.updateValueAndValidity({
      onlySelf: true,
      // If `asyncValidator` is present, it will trigger control status change from `PENDING` to
      // `VALID` or `INVALID`.
      // The status should be broadcasted via the `statusChanges` observable, so we set `emitEvent`
      // to `true` to allow that during the control creation process.
      emitEvent: !!this.asyncValidator
    });
  }
  /**
   * Get the `AbstractControl` at the given `index` in the array.
   *
   * @param index Index in the array to retrieve the control. If `index` is negative, it will wrap
   *     around from the back, and if index is greatly negative (less than `-length`), the result is
   * undefined. This behavior is the same as `Array.at(index)`.
   */
  at(index) {
    return this.controls[this._adjustIndex(index)];
  }
  /**
   * Insert a new `AbstractControl` at the end of the array.
   *
   * @param control Form control to be inserted
   * @param options Specifies whether this FormArray instance should emit events after a new
   *     control is added.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control is
   * inserted. When false, no events are emitted.
   */
  push(control, options = {}) {
    this.controls.push(control);
    this._registerControl(control);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
    this._onCollectionChange();
  }
  /**
   * Insert a new `AbstractControl` at the given `index` in the array.
   *
   * @param index Index in the array to insert the control. If `index` is negative, wraps around
   *     from the back. If `index` is greatly negative (less than `-length`), prepends to the array.
   * This behavior is the same as `Array.splice(index, 0, control)`.
   * @param control Form control to be inserted
   * @param options Specifies whether this FormArray instance should emit events after a new
   *     control is inserted.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control is
   * inserted. When false, no events are emitted.
   */
  insert(index, control, options = {}) {
    this.controls.splice(index, 0, control);
    this._registerControl(control);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
  }
  /**
   * Remove the control at the given `index` in the array.
   *
   * @param index Index in the array to remove the control.  If `index` is negative, wraps around
   *     from the back. If `index` is greatly negative (less than `-length`), removes the first
   *     element. This behavior is the same as `Array.splice(index, 1)`.
   * @param options Specifies whether this FormArray instance should emit events after a
   *     control is removed.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control is
   * removed. When false, no events are emitted.
   */
  removeAt(index, options = {}) {
    // Adjust the index, then clamp it at no less than 0 to prevent undesired underflows.
    let adjustedIndex = this._adjustIndex(index);
    if (adjustedIndex < 0) adjustedIndex = 0;
    if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => {});
    this.controls.splice(adjustedIndex, 1);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
  }
  /**
   * Replace an existing control.
   *
   * @param index Index in the array to replace the control. If `index` is negative, wraps around
   *     from the back. If `index` is greatly negative (less than `-length`), replaces the first
   *     element. This behavior is the same as `Array.splice(index, 1, control)`.
   * @param control The `AbstractControl` control to replace the existing control
   * @param options Specifies whether this FormArray instance should emit events after an
   *     existing control is replaced with a new one.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control is
   * replaced with a new one. When false, no events are emitted.
   */
  setControl(index, control, options = {}) {
    // Adjust the index, then clamp it at no less than 0 to prevent undesired underflows.
    let adjustedIndex = this._adjustIndex(index);
    if (adjustedIndex < 0) adjustedIndex = 0;
    if (this.controls[adjustedIndex]) this.controls[adjustedIndex]._registerOnCollectionChange(() => {});
    this.controls.splice(adjustedIndex, 1);
    if (control) {
      this.controls.splice(adjustedIndex, 0, control);
      this._registerControl(control);
    }
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
    this._onCollectionChange();
  }
  /**
   * Length of the control array.
   */
  get length() {
    return this.controls.length;
  }
  /**
   * Sets the value of the `FormArray`. It accepts an array that matches
   * the structure of the control.
   *
   * This method performs strict checks, and throws an error if you try
   * to set the value of a control that doesn't exist or if you exclude the
   * value of a control.
   *
   * @usageNotes
   * ### Set the values for the controls in the form array
   *
   * ```
   * const arr = new FormArray([
   *   new FormControl(),
   *   new FormControl()
   * ]);
   * console.log(arr.value);   // [null, null]
   *
   * arr.setValue(['Nancy', 'Drew']);
   * console.log(arr.value);   // ['Nancy', 'Drew']
   * ```
   *
   * @param value Array of values for the controls
   * @param options Configure options that determine how the control propagates changes and
   * emits events after the value changes
   *
   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
   * is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control value is updated.
   * When false, no events are emitted.
   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
   * updateValueAndValidity} method.
   */
  setValue(value, options = {}) {
    assertAllValuesPresent(this, false, value);
    value.forEach((newValue, index) => {
      assertControlPresent(this, false, index);
      this.at(index).setValue(newValue, {
        onlySelf: true,
        emitEvent: options.emitEvent
      });
    });
    this.updateValueAndValidity(options);
  }
  /**
   * Patches the value of the `FormArray`. It accepts an array that matches the
   * structure of the control, and does its best to match the values to the correct
   * controls in the group.
   *
   * It accepts both super-sets and sub-sets of the array without throwing an error.
   *
   * @usageNotes
   * ### Patch the values for controls in a form array
   *
   * ```
   * const arr = new FormArray([
   *    new FormControl(),
   *    new FormControl()
   * ]);
   * console.log(arr.value);   // [null, null]
   *
   * arr.patchValue(['Nancy']);
   * console.log(arr.value);   // ['Nancy', null]
   * ```
   *
   * @param value Array of latest values for the controls
   * @param options Configure options that determine how the control propagates changes and
   * emits events after the value changes
   *
   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
   * is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when the control
   * value is updated. When false, no events are emitted. The configuration options are passed to
   * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method.
   */
  patchValue(value, options = {}) {
    // Even though the `value` argument type doesn't allow `null` and `undefined` values, the
    // `patchValue` can be called recursively and inner data structures might have these values,
    // so we just ignore such cases when a field containing FormArray instance receives `null` or
    // `undefined` as a value.
    if (value == null /* both `null` and `undefined` */) return;
    value.forEach((newValue, index) => {
      if (this.at(index)) {
        this.at(index).patchValue(newValue, {
          onlySelf: true,
          emitEvent: options.emitEvent
        });
      }
    });
    this.updateValueAndValidity(options);
  }
  /**
   * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the
   * value of all descendants to null or null maps.
   *
   * You reset to a specific form state by passing in an array of states
   * that matches the structure of the control. The state is a standalone value
   * or a form state object with both a value and a disabled status.
   *
   * @usageNotes
   * ### Reset the values in a form array
   *
   * ```ts
   * const arr = new FormArray([
   *    new FormControl(),
   *    new FormControl()
   * ]);
   * arr.reset(['name', 'last name']);
   *
   * console.log(arr.value);  // ['name', 'last name']
   * ```
   *
   * ### Reset the values in a form array and the disabled status for the first control
   *
   * ```
   * arr.reset([
   *   {value: 'name', disabled: true},
   *   'last'
   * ]);
   *
   * console.log(arr.value);  // ['last']
   * console.log(arr.at(0).status);  // 'DISABLED'
   * ```
   *
   * @param value Array of values for the controls
   * @param options Configure options that determine how the control propagates changes and
   * emits events after the value changes
   *
   * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
   * is false.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges`
   * observables emit events with the latest status and value when the control is reset.
   * When false, no events are emitted.
   * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity
   * updateValueAndValidity} method.
   */
  reset(value = [], options = {}) {
    this._forEachChild((control, index) => {
      control.reset(value[index], {
        onlySelf: true,
        emitEvent: options.emitEvent
      });
    });
    this._updatePristine(options);
    this._updateTouched(options);
    this.updateValueAndValidity(options);
  }
  /**
   * The aggregate value of the array, including any disabled controls.
   *
   * Reports all values regardless of disabled status.
   */
  getRawValue() {
    return this.controls.map(control => control.getRawValue());
  }
  /**
   * Remove all controls in the `FormArray`.
   *
   * @param options Specifies whether this FormArray instance should emit events after all
   *     controls are removed.
   * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
   * `valueChanges` observables emit events with the latest status and value when all controls
   * in this FormArray instance are removed. When false, no events are emitted.
   *
   * @usageNotes
   * ### Remove all elements from a FormArray
   *
   * ```ts
   * const arr = new FormArray([
   *    new FormControl(),
   *    new FormControl()
   * ]);
   * console.log(arr.length);  // 2
   *
   * arr.clear();
   * console.log(arr.length);  // 0
   * ```
   *
   * It's a simpler and more efficient alternative to removing all elements one by one:
   *
   * ```ts
   * const arr = new FormArray([
   *    new FormControl(),
   *    new FormControl()
   * ]);
   *
   * while (arr.length) {
   *    arr.removeAt(0);
   * }
   * ```
   */
  clear(options = {}) {
    if (this.controls.length < 1) return;
    this._forEachChild(control => control._registerOnCollectionChange(() => {}));
    this.controls.splice(0);
    this.updateValueAndValidity({
      emitEvent: options.emitEvent
    });
  }
  /**
   * Adjusts a negative index by summing it with the length of the array. For very negative
   * indices, the result may remain negative.
   * @internal
   */
  _adjustIndex(index) {
    return index < 0 ? index + this.length : index;
  }
  /** @internal */
  _syncPendingControls() {
    let subtreeUpdated = this.controls.reduce((updated, child) => {
      return child._syncPendingControls() ? true : updated;
    }, false);
    if (subtreeUpdated) this.updateValueAndValidity({
      onlySelf: true
    });
    return subtreeUpdated;
  }
  /** @internal */
  _forEachChild(cb) {
    this.controls.forEach((control, index) => {
      cb(control, index);
    });
  }
  /** @internal */
  _updateValue() {
    this.value = this.controls.filter(control => control.enabled || this.disabled).map(control => control.value);
  }
  /** @internal */
  _anyControls(condition) {
    return this.controls.some(control => control.enabled && condition(control));
  }
  /** @internal */
  _setUpControls() {
    this._forEachChild(control => this._registerControl(control));
  }
  /** @internal */
  _allControlsDisabled() {
    for (const control of this.controls) {
      if (control.enabled) return false;
    }
    return this.controls.length > 0 || this.disabled;
  }
  _registerControl(control) {
    control.setParent(this);
    control._registerOnCollectionChange(this._onCollectionChange);
  }
  /** @internal */
  _find(name) {
    return this.at(name) ?? null;
  }
}
const UntypedFormArray = FormArray;
/**
 * @description
 * Asserts that the given control is an instance of `FormArray`
 *
 * @publicApi
 */
const isFormArray = control => control instanceof FormArray;
function isAbstractControlOptions(options) {
  return !!options && (options.asyncValidators !== undefined || options.validators !== undefined || options.updateOn !== undefined);
}
// clang-format on
/**
 * @description
 * Creates an `AbstractControl` from a user-specified configuration.
 *
 * The `FormBuilder` provides syntactic sugar that shortens creating instances of a
 * `FormControl`, `FormGroup`, or `FormArray`. It reduces the amount of boilerplate needed to
 * build complex forms.
 *
 * @see [Reactive Forms Guide](guide/reactive-forms)
 *
 * @publicApi
 */
class FormBuilder {
  constructor() {
    this.useNonNullable = false;
  }
  /**
   * @description
   * Returns a FormBuilder in which automatically constructed `FormControl` elements
   * have `{nonNullable: true}` and are non-nullable.
   *
   * **Constructing non-nullable controls**
   *
   * When constructing a control, it will be non-nullable, and will reset to its initial value.
   *
   * ```ts
   * let nnfb = new FormBuilder().nonNullable;
   * let name = nnfb.control('Alex'); // FormControl<string>
   * name.reset();
   * console.log(name); // 'Alex'
   * ```
   *
   * **Constructing non-nullable groups or arrays**
   *
   * When constructing a group or array, all automatically created inner controls will be
   * non-nullable, and will reset to their initial values.
   *
   * ```ts
   * let nnfb = new FormBuilder().nonNullable;
   * let name = nnfb.group({who: 'Alex'}); // FormGroup<{who: FormControl<string>}>
   * name.reset();
   * console.log(name); // {who: 'Alex'}
   * ```
   * **Constructing *nullable* fields on groups or arrays**
   *
   * It is still possible to have a nullable field. In particular, any `FormControl` which is
   * *already* constructed will not be altered. For example:
   *
   * ```ts
   * let nnfb = new FormBuilder().nonNullable;
   * // FormGroup<{who: FormControl<string|null>}>
   * let name = nnfb.group({who: new FormControl('Alex')});
   * name.reset(); console.log(name); // {who: null}
   * ```
   *
   * Because the inner control is constructed explicitly by the caller, the builder has
   * no control over how it is created, and cannot exclude the `null`.
   */
  get nonNullable() {
    const nnfb = new FormBuilder();
    nnfb.useNonNullable = true;
    return nnfb;
  }
  group(controls, options = null) {
    const reducedControls = this._reduceControls(controls);
    let newOptions = {};
    if (isAbstractControlOptions(options)) {
      // `options` are `AbstractControlOptions`
      newOptions = options;
    } else if (options !== null) {
      // `options` are legacy form group options
      newOptions.validators = options.validator;
      newOptions.asyncValidators = options.asyncValidator;
    }
    return new FormGroup(reducedControls, newOptions);
  }
  /**
   * @description
   * Constructs a new `FormRecord` instance. Accepts a single generic argument, which is an object
   * containing all the keys and corresponding inner control types.
   *
   * @param controls A collection of child controls. The key for each child is the name
   * under which it is registered.
   *
   * @param options Configuration options object for the `FormRecord`. The object should have the
   * `AbstractControlOptions` type and might contain the following fields:
   * * `validators`: A synchronous validator function, or an array of validator functions.
   * * `asyncValidators`: A single async validator or array of async validator functions.
   * * `updateOn`: The event upon which the control should be updated (options: 'change' | 'blur'
   * | submit').
   */
  record(controls, options = null) {
    const reducedControls = this._reduceControls(controls);
    // Cast to `any` because the inferred types are not as specific as Element.
    return new FormRecord(reducedControls, options);
  }
  /**
   * @description
   * Constructs a new `FormControl` with the given state, validators and options. Sets
   * `{nonNullable: true}` in the options to get a non-nullable control. Otherwise, the
   * control will be nullable. Accepts a single generic argument, which is the type  of the
   * control's value.
   *
   * @param formState Initializes the control with an initial state value, or
   * with an object that contains both a value and a disabled status.
   *
   * @param validatorOrOpts A synchronous validator function, or an array of
   * such functions, or a `FormControlOptions` object that contains
   * validation functions and a validation trigger.
   *
   * @param asyncValidator A single async validator or array of async validator
   * functions.
   *
   * @usageNotes
   *
   * ### Initialize a control as disabled
   *
   * The following example returns a control with an initial value in a disabled state.
   *
   * <code-example path="forms/ts/formBuilder/form_builder_example.ts" region="disabled-control">
   * </code-example>
   */
  control(formState, validatorOrOpts, asyncValidator) {
    let newOptions = {};
    if (!this.useNonNullable) {
      return new FormControl(formState, validatorOrOpts, asyncValidator);
    }
    if (isAbstractControlOptions(validatorOrOpts)) {
      // If the second argument is options, then they are copied.
      newOptions = validatorOrOpts;
    } else {
      // If the other arguments are validators, they are copied into an options object.
      newOptions.validators = validatorOrOpts;
      newOptions.asyncValidators = asyncValidator;
    }
    return new FormControl(formState, {
      ...newOptions,
      nonNullable: true
    });
  }
  /**
   * Constructs a new `FormArray` from the given array of configurations,
   * validators and options. Accepts a single generic argument, which is the type of each control
   * inside the array.
   *
   * @param controls An array of child controls or control configs. Each child control is given an
   *     index when it is registered.
   *
   * @param validatorOrOpts A synchronous validator function, or an array of such functions, or an
   *     `AbstractControlOptions` object that contains
   * validation functions and a validation trigger.
   *
   * @param asyncValidator A single async validator or array of async validator functions.
   */
  array(controls, validatorOrOpts, asyncValidator) {
    const createdControls = controls.map(c => this._createControl(c));
    // Cast to `any` because the inferred types are not as specific as Element.
    return new FormArray(createdControls, validatorOrOpts, asyncValidator);
  }
  /** @internal */
  _reduceControls(controls) {
    const createdControls = {};
    Object.keys(controls).forEach(controlName => {
      createdControls[controlName] = this._createControl(controls[controlName]);
    });
    return createdControls;
  }
  /** @internal */
  _createControl(controls) {
    if (controls instanceof FormControl) {
      return controls;
    } else if (controls instanceof AbstractControl) {
      // A control; just return it
      return controls;
    } else if (Array.isArray(controls)) {
      // ControlConfig Tuple
      const value = controls[0];
      const validator = controls.length > 1 ? controls[1] : null;
      const asyncValidator = controls.length > 2 ? controls[2] : null;
      return this.control(value, validator, asyncValidator);
    } else {
      // T or FormControlState<T>
      return this.control(controls);
    }
  }
  static {
    this.ɵfac = function FormBuilder_Factory(t) {
      return new (t || FormBuilder)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: FormBuilder,
      factory: FormBuilder.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormBuilder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * @description
 * `NonNullableFormBuilder` is similar to {@link FormBuilder}, but automatically constructed
 * {@link FormControl} elements have `{nonNullable: true}` and are non-nullable.
 *
 * @publicApi
 */
class NonNullableFormBuilder {
  static {
    this.ɵfac = function NonNullableFormBuilder_Factory(t) {
      return new (t || NonNullableFormBuilder)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NonNullableFormBuilder,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(FormBuilder).nonNullable)(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NonNullableFormBuilder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(FormBuilder).nonNullable
    }]
  }], null, null);
})();
/**
 * UntypedFormBuilder is the same as `FormBuilder`, but it provides untyped controls.
 */
class UntypedFormBuilder extends FormBuilder {
  group(controlsConfig, options = null) {
    return super.group(controlsConfig, options);
  }
  /**
   * Like `FormBuilder#control`, except the resulting control is untyped.
   */
  control(formState, validatorOrOpts, asyncValidator) {
    return super.control(formState, validatorOrOpts, asyncValidator);
  }
  /**
   * Like `FormBuilder#array`, except the resulting array is untyped.
   */
  array(controlsConfig, validatorOrOpts, asyncValidator) {
    return super.array(controlsConfig, validatorOrOpts, asyncValidator);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵUntypedFormBuilder_BaseFactory;
      return function UntypedFormBuilder_Factory(t) {
        return (ɵUntypedFormBuilder_BaseFactory || (ɵUntypedFormBuilder_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](UntypedFormBuilder)))(t || UntypedFormBuilder);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: UntypedFormBuilder,
      factory: UntypedFormBuilder.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UntypedFormBuilder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * @module
 * @description
 * Entry point for all public APIs of the forms package.
 */
/**
 * @publicApi
 */
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('17.3.12');

/**
 * Exports the required providers and directives for template-driven forms,
 * making them available for import by NgModules that import this module.
 *
 * @see [Forms Overview](/guide/forms-overview)
 * @see [Template-driven Forms Guide](/guide/forms)
 *
 * @publicApi
 */
class FormsModule {
  /**
   * @description
   * Provides options for configuring the forms module.
   *
   * @param opts An object of configuration options
   * * `callSetDisabledState` Configures whether to `always` call `setDisabledState`, which is more
   * correct, or to only call it `whenDisabled`, which is the legacy behavior.
   */
  static withConfig(opts) {
    return {
      ngModule: FormsModule,
      providers: [{
        provide: CALL_SET_DISABLED_STATE,
        useValue: opts.callSetDisabledState ?? setDisabledStateDefault
      }]
    };
  }
  static {
    this.ɵfac = function FormsModule_Factory(t) {
      return new (t || FormsModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: FormsModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [ɵInternalFormsSharedModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FormsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: TEMPLATE_DRIVEN_DIRECTIVES,
      exports: [ɵInternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
    }]
  }], null, null);
})();
/**
 * Exports the required infrastructure and directives for reactive forms,
 * making them available for import by NgModules that import this module.
 *
 * @see [Forms Overview](guide/forms-overview)
 * @see [Reactive Forms Guide](guide/reactive-forms)
 *
 * @publicApi
 */
class ReactiveFormsModule {
  /**
   * @description
   * Provides options for configuring the reactive forms module.
   *
   * @param opts An object of configuration options
   * * `warnOnNgModelWithFormControl` Configures when to emit a warning when an `ngModel`
   * binding is used with reactive form directives.
   * * `callSetDisabledState` Configures whether to `always` call `setDisabledState`, which is more
   * correct, or to only call it `whenDisabled`, which is the legacy behavior.
   */
  static withConfig(opts) {
    return {
      ngModule: ReactiveFormsModule,
      providers: [{
        provide: NG_MODEL_WITH_FORM_CONTROL_WARNING,
        useValue: opts.warnOnNgModelWithFormControl ?? 'always'
      }, {
        provide: CALL_SET_DISABLED_STATE,
        useValue: opts.callSetDisabledState ?? setDisabledStateDefault
      }]
    };
  }
  static {
    this.ɵfac = function ReactiveFormsModule_Factory(t) {
      return new (t || ReactiveFormsModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: ReactiveFormsModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [ɵInternalFormsSharedModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ReactiveFormsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: [REACTIVE_DRIVEN_DIRECTIVES],
      exports: [ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
    }]
  }], null, null);
})();

/**
 * @module
 * @description
 * This module is used for handling user input, by defining and building a `FormGroup` that
 * consists of `FormControl` objects, and mapping them onto the DOM. `FormControl`
 * objects can then be used to read information from the form DOM elements.
 *
 * Forms providers are not included in default providers; you must import these providers
 * explicitly.
 */

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */
// This file only reexports content of the `src` folder. Keep it that way.

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 1643:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/localize/fesm2022/init.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   $localize: () => (/* reexport safe */ _angular_localize__WEBPACK_IMPORTED_MODULE_0__["ɵ$localize"])
/* harmony export */ });
/* harmony import */ var _angular_localize__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/localize */ 95116);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */




// Attach $localize to the global context, as a side-effect of this module.
globalThis.$localize = _angular_localize__WEBPACK_IMPORTED_MODULE_0__["ɵ$localize"];

/***/ }),

/***/ 95116:
/*!**************************************************************!*\
  !*** ./node_modules/@angular/localize/fesm2022/localize.mjs ***!
  \**************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   clearTranslations: () => (/* binding */ clearTranslations),
/* harmony export */   loadTranslations: () => (/* binding */ loadTranslations),
/* harmony export */   "ɵ$localize": () => (/* binding */ $localize$1),
/* harmony export */   "ɵMissingTranslationError": () => (/* binding */ MissingTranslationError),
/* harmony export */   "ɵcomputeMsgId": () => (/* binding */ computeMsgId),
/* harmony export */   "ɵfindEndOfBlock": () => (/* binding */ findEndOfBlock),
/* harmony export */   "ɵisMissingTranslationError": () => (/* binding */ isMissingTranslationError),
/* harmony export */   "ɵmakeParsedTranslation": () => (/* binding */ makeParsedTranslation),
/* harmony export */   "ɵmakeTemplateObject": () => (/* binding */ makeTemplateObject),
/* harmony export */   "ɵparseMessage": () => (/* binding */ parseMessage),
/* harmony export */   "ɵparseMetadata": () => (/* binding */ parseMetadata),
/* harmony export */   "ɵparseTranslation": () => (/* binding */ parseTranslation),
/* harmony export */   "ɵsplitBlock": () => (/* binding */ splitBlock),
/* harmony export */   "ɵtranslate": () => (/* binding */ translate$1)
/* harmony export */ });
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */

/**
 * The character used to mark the start and end of a "block" in a `$localize` tagged string.
 * A block can indicate metadata about the message or specify a name of a placeholder for a
 * substitution expressions.
 *
 * For example:
 *
 * ```ts
 * $localize`Hello, ${title}:title:!`;
 * $localize`:meaning|description@@id:source message text`;
 * ```
 */
const BLOCK_MARKER$1 = ':';
/**
 * The marker used to separate a message's "meaning" from its "description" in a metadata block.
 *
 * For example:
 *
 * ```ts
 * $localize `:correct|Indicates that the user got the answer correct: Right!`;
 * $localize `:movement|Button label for moving to the right: Right!`;
 * ```
 */
const MEANING_SEPARATOR = '|';
/**
 * The marker used to separate a message's custom "id" from its "description" in a metadata block.
 *
 * For example:
 *
 * ```ts
 * $localize `:A welcome message on the home page@@myApp-homepage-welcome: Welcome!`;
 * ```
 */
const ID_SEPARATOR = '@@';
/**
 * The marker used to separate legacy message ids from the rest of a metadata block.
 *
 * For example:
 *
 * ```ts
 * $localize `:@@custom-id␟2df64767cd895a8fabe3e18b94b5b6b6f9e2e3f0: Welcome!`;
 * ```
 *
 * Note that this character is the "symbol for the unit separator" (␟) not the "unit separator
 * character" itself, since that has no visual representation. See https://graphemica.com/%E2%90%9F.
 *
 * Here is some background for the original "unit separator character":
 * https://stackoverflow.com/questions/8695118/whats-the-file-group-record-unit-separator-control-characters-and-its-usage
 */
const LEGACY_ID_INDICATOR = '\u241F';

/**
 * A lazily created TextEncoder instance for converting strings into UTF-8 bytes
 */
let textEncoder;
/**
 * Return the message id or compute it using the XLIFF1 digest.
 */
function digest(message) {
  return message.id || computeDigest(message);
}
/**
 * Compute the message id using the XLIFF1 digest.
 */
function computeDigest(message) {
  return sha1(serializeNodes(message.nodes).join('') + `[${message.meaning}]`);
}
/**
 * Return the message id or compute it using the XLIFF2/XMB/$localize digest.
 */
function decimalDigest(message) {
  return message.id || computeDecimalDigest(message);
}
/**
 * Compute the message id using the XLIFF2/XMB/$localize digest.
 */
function computeDecimalDigest(message) {
  const visitor = new _SerializerIgnoreIcuExpVisitor();
  const parts = message.nodes.map(a => a.visit(visitor, null));
  return computeMsgId(parts.join(''), message.meaning);
}
/**
 * Serialize the i18n ast to something xml-like in order to generate an UID.
 *
 * The visitor is also used in the i18n parser tests
 *
 * @internal
 */
class _SerializerVisitor {
  visitText(text, context) {
    return text.value;
  }
  visitContainer(container, context) {
    return `[${container.children.map(child => child.visit(this)).join(', ')}]`;
  }
  visitIcu(icu, context) {
    const strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`);
    return `{${icu.expression}, ${icu.type}, ${strCases.join(', ')}}`;
  }
  visitTagPlaceholder(ph, context) {
    return ph.isVoid ? `<ph tag name="${ph.startName}"/>` : `<ph tag name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
  }
  visitPlaceholder(ph, context) {
    return ph.value ? `<ph name="${ph.name}">${ph.value}</ph>` : `<ph name="${ph.name}"/>`;
  }
  visitIcuPlaceholder(ph, context) {
    return `<ph icu name="${ph.name}">${ph.value.visit(this)}</ph>`;
  }
  visitBlockPlaceholder(ph, context) {
    return `<ph block name="${ph.startName}">${ph.children.map(child => child.visit(this)).join(', ')}</ph name="${ph.closeName}">`;
  }
}
const serializerVisitor = new _SerializerVisitor();
function serializeNodes(nodes) {
  return nodes.map(a => a.visit(serializerVisitor, null));
}
/**
 * Serialize the i18n ast to something xml-like in order to generate an UID.
 *
 * Ignore the ICU expressions so that message IDs stays identical if only the expression changes.
 *
 * @internal
 */
class _SerializerIgnoreIcuExpVisitor extends _SerializerVisitor {
  visitIcu(icu, context) {
    let strCases = Object.keys(icu.cases).map(k => `${k} {${icu.cases[k].visit(this)}}`);
    // Do not take the expression into account
    return `{${icu.type}, ${strCases.join(', ')}}`;
  }
}
/**
 * Compute the SHA1 of the given string
 *
 * see https://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf
 *
 * WARNING: this function has not been designed not tested with security in mind.
 *          DO NOT USE IT IN A SECURITY SENSITIVE CONTEXT.
 */
function sha1(str) {
  textEncoder ??= new TextEncoder();
  const utf8 = [...textEncoder.encode(str)];
  const words32 = bytesToWords32(utf8, Endian.Big);
  const len = utf8.length * 8;
  const w = new Uint32Array(80);
  let a = 0x67452301,
    b = 0xefcdab89,
    c = 0x98badcfe,
    d = 0x10325476,
    e = 0xc3d2e1f0;
  words32[len >> 5] |= 0x80 << 24 - len % 32;
  words32[(len + 64 >> 9 << 4) + 15] = len;
  for (let i = 0; i < words32.length; i += 16) {
    const h0 = a,
      h1 = b,
      h2 = c,
      h3 = d,
      h4 = e;
    for (let j = 0; j < 80; j++) {
      if (j < 16) {
        w[j] = words32[i + j];
      } else {
        w[j] = rol32(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1);
      }
      const fkVal = fk(j, b, c, d);
      const f = fkVal[0];
      const k = fkVal[1];
      const temp = [rol32(a, 5), f, e, k, w[j]].reduce(add32);
      e = d;
      d = c;
      c = rol32(b, 30);
      b = a;
      a = temp;
    }
    a = add32(a, h0);
    b = add32(b, h1);
    c = add32(c, h2);
    d = add32(d, h3);
    e = add32(e, h4);
  }
  // Convert the output parts to a 160-bit hexadecimal string
  return toHexU32(a) + toHexU32(b) + toHexU32(c) + toHexU32(d) + toHexU32(e);
}
/**
 * Convert and format a number as a string representing a 32-bit unsigned hexadecimal number.
 * @param value The value to format as a string.
 * @returns A hexadecimal string representing the value.
 */
function toHexU32(value) {
  // unsigned right shift of zero ensures an unsigned 32-bit number
  return (value >>> 0).toString(16).padStart(8, '0');
}
function fk(index, b, c, d) {
  if (index < 20) {
    return [b & c | ~b & d, 0x5a827999];
  }
  if (index < 40) {
    return [b ^ c ^ d, 0x6ed9eba1];
  }
  if (index < 60) {
    return [b & c | b & d | c & d, 0x8f1bbcdc];
  }
  return [b ^ c ^ d, 0xca62c1d6];
}
/**
 * Compute the fingerprint of the given string
 *
 * The output is 64 bit number encoded as a decimal string
 *
 * based on:
 * https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/GoogleJsMessageIdGenerator.java
 */
function fingerprint(str) {
  textEncoder ??= new TextEncoder();
  const utf8 = textEncoder.encode(str);
  const view = new DataView(utf8.buffer, utf8.byteOffset, utf8.byteLength);
  let hi = hash32(view, utf8.length, 0);
  let lo = hash32(view, utf8.length, 102072);
  if (hi == 0 && (lo == 0 || lo == 1)) {
    hi = hi ^ 0x130f9bef;
    lo = lo ^ -0x6b5f56d8;
  }
  return BigInt.asUintN(32, BigInt(hi)) << BigInt(32) | BigInt.asUintN(32, BigInt(lo));
}
function computeMsgId(msg, meaning = '') {
  let msgFingerprint = fingerprint(msg);
  if (meaning) {
    // Rotate the 64-bit message fingerprint one bit to the left and then add the meaning
    // fingerprint.
    msgFingerprint = BigInt.asUintN(64, msgFingerprint << BigInt(1)) | msgFingerprint >> BigInt(63) & BigInt(1);
    msgFingerprint += fingerprint(meaning);
  }
  return BigInt.asUintN(63, msgFingerprint).toString();
}
function hash32(view, length, c) {
  let a = 0x9e3779b9,
    b = 0x9e3779b9;
  let index = 0;
  const end = length - 12;
  for (; index <= end; index += 12) {
    a += view.getUint32(index, true);
    b += view.getUint32(index + 4, true);
    c += view.getUint32(index + 8, true);
    const res = mix(a, b, c);
    a = res[0], b = res[1], c = res[2];
  }
  const remainder = length - index;
  // the first byte of c is reserved for the length
  c += length;
  if (remainder >= 4) {
    a += view.getUint32(index, true);
    index += 4;
    if (remainder >= 8) {
      b += view.getUint32(index, true);
      index += 4;
      // Partial 32-bit word for c
      if (remainder >= 9) {
        c += view.getUint8(index++) << 8;
      }
      if (remainder >= 10) {
        c += view.getUint8(index++) << 16;
      }
      if (remainder === 11) {
        c += view.getUint8(index++) << 24;
      }
    } else {
      // Partial 32-bit word for b
      if (remainder >= 5) {
        b += view.getUint8(index++);
      }
      if (remainder >= 6) {
        b += view.getUint8(index++) << 8;
      }
      if (remainder === 7) {
        b += view.getUint8(index++) << 16;
      }
    }
  } else {
    // Partial 32-bit word for a
    if (remainder >= 1) {
      a += view.getUint8(index++);
    }
    if (remainder >= 2) {
      a += view.getUint8(index++) << 8;
    }
    if (remainder === 3) {
      a += view.getUint8(index++) << 16;
    }
  }
  return mix(a, b, c)[2];
}
// clang-format off
function mix(a, b, c) {
  a -= b;
  a -= c;
  a ^= c >>> 13;
  b -= c;
  b -= a;
  b ^= a << 8;
  c -= a;
  c -= b;
  c ^= b >>> 13;
  a -= b;
  a -= c;
  a ^= c >>> 12;
  b -= c;
  b -= a;
  b ^= a << 16;
  c -= a;
  c -= b;
  c ^= b >>> 5;
  a -= b;
  a -= c;
  a ^= c >>> 3;
  b -= c;
  b -= a;
  b ^= a << 10;
  c -= a;
  c -= b;
  c ^= b >>> 15;
  return [a, b, c];
}
// clang-format on
// Utils
var Endian;
(function (Endian) {
  Endian[Endian["Little"] = 0] = "Little";
  Endian[Endian["Big"] = 1] = "Big";
})(Endian || (Endian = {}));
function add32(a, b) {
  return add32to64(a, b)[1];
}
function add32to64(a, b) {
  const low = (a & 0xffff) + (b & 0xffff);
  const high = (a >>> 16) + (b >>> 16) + (low >>> 16);
  return [high >>> 16, high << 16 | low & 0xffff];
}
// Rotate a 32b number left `count` position
function rol32(a, count) {
  return a << count | a >>> 32 - count;
}
function bytesToWords32(bytes, endian) {
  const size = bytes.length + 3 >>> 2;
  const words32 = [];
  for (let i = 0; i < size; i++) {
    words32[i] = wordAt(bytes, i * 4, endian);
  }
  return words32;
}
function byteAt(bytes, index) {
  return index >= bytes.length ? 0 : bytes[index];
}
function wordAt(bytes, index, endian) {
  let word = 0;
  if (endian === Endian.Big) {
    for (let i = 0; i < 4; i++) {
      word += byteAt(bytes, index + i) << 24 - 8 * i;
    }
  } else {
    for (let i = 0; i < 4; i++) {
      word += byteAt(bytes, index + i) << 8 * i;
    }
  }
  return word;
}

// This module specifier is intentionally a relative path to allow bundling the code directly
/**
 * Parse a `$localize` tagged string into a structure that can be used for translation or
 * extraction.
 *
 * See `ParsedMessage` for an example.
 */
function parseMessage(messageParts, expressions, location, messagePartLocations, expressionLocations = []) {
  const substitutions = {};
  const substitutionLocations = {};
  const associatedMessageIds = {};
  const metadata = parseMetadata(messageParts[0], messageParts.raw[0]);
  const cleanedMessageParts = [metadata.text];
  const placeholderNames = [];
  let messageString = metadata.text;
  for (let i = 1; i < messageParts.length; i++) {
    const {
      messagePart,
      placeholderName = computePlaceholderName(i),
      associatedMessageId
    } = parsePlaceholder(messageParts[i], messageParts.raw[i]);
    messageString += `{$${placeholderName}}${messagePart}`;
    if (expressions !== undefined) {
      substitutions[placeholderName] = expressions[i - 1];
      substitutionLocations[placeholderName] = expressionLocations[i - 1];
    }
    placeholderNames.push(placeholderName);
    if (associatedMessageId !== undefined) {
      associatedMessageIds[placeholderName] = associatedMessageId;
    }
    cleanedMessageParts.push(messagePart);
  }
  const messageId = metadata.customId || computeMsgId(messageString, metadata.meaning || '');
  const legacyIds = metadata.legacyIds ? metadata.legacyIds.filter(id => id !== messageId) : [];
  return {
    id: messageId,
    legacyIds,
    substitutions,
    substitutionLocations,
    text: messageString,
    customId: metadata.customId,
    meaning: metadata.meaning || '',
    description: metadata.description || '',
    messageParts: cleanedMessageParts,
    messagePartLocations,
    placeholderNames,
    associatedMessageIds,
    location
  };
}
/**
 * Parse the given message part (`cooked` + `raw`) to extract the message metadata from the text.
 *
 * If the message part has a metadata block this function will extract the `meaning`,
 * `description`, `customId` and `legacyId` (if provided) from the block. These metadata properties
 * are serialized in the string delimited by `|`, `@@` and `␟` respectively.
 *
 * (Note that `␟` is the `LEGACY_ID_INDICATOR` - see `constants.ts`.)
 *
 * For example:
 *
 * ```ts
 * `:meaning|description@@custom-id:`
 * `:meaning|@@custom-id:`
 * `:meaning|description:`
 * `:description@@custom-id:`
 * `:meaning|:`
 * `:description:`
 * `:@@custom-id:`
 * `:meaning|description@@custom-id␟legacy-id-1␟legacy-id-2:`
 * ```
 *
 * @param cooked The cooked version of the message part to parse.
 * @param raw The raw version of the message part to parse.
 * @returns A object containing any metadata that was parsed from the message part.
 */
function parseMetadata(cooked, raw) {
  const {
    text: messageString,
    block
  } = splitBlock(cooked, raw);
  if (block === undefined) {
    return {
      text: messageString
    };
  } else {
    const [meaningDescAndId, ...legacyIds] = block.split(LEGACY_ID_INDICATOR);
    const [meaningAndDesc, customId] = meaningDescAndId.split(ID_SEPARATOR, 2);
    let [meaning, description] = meaningAndDesc.split(MEANING_SEPARATOR, 2);
    if (description === undefined) {
      description = meaning;
      meaning = undefined;
    }
    if (description === '') {
      description = undefined;
    }
    return {
      text: messageString,
      meaning,
      description,
      customId,
      legacyIds
    };
  }
}
/**
 * Parse the given message part (`cooked` + `raw`) to extract any placeholder metadata from the
 * text.
 *
 * If the message part has a metadata block this function will extract the `placeholderName` and
 * `associatedMessageId` (if provided) from the block.
 *
 * These metadata properties are serialized in the string delimited by `@@`.
 *
 * For example:
 *
 * ```ts
 * `:placeholder-name@@associated-id:`
 * ```
 *
 * @param cooked The cooked version of the message part to parse.
 * @param raw The raw version of the message part to parse.
 * @returns A object containing the metadata (`placeholderName` and `associatedMessageId`) of the
 *     preceding placeholder, along with the static text that follows.
 */
function parsePlaceholder(cooked, raw) {
  const {
    text: messagePart,
    block
  } = splitBlock(cooked, raw);
  if (block === undefined) {
    return {
      messagePart
    };
  } else {
    const [placeholderName, associatedMessageId] = block.split(ID_SEPARATOR);
    return {
      messagePart,
      placeholderName,
      associatedMessageId
    };
  }
}
/**
 * Split a message part (`cooked` + `raw`) into an optional delimited "block" off the front and the
 * rest of the text of the message part.
 *
 * Blocks appear at the start of message parts. They are delimited by a colon `:` character at the
 * start and end of the block.
 *
 * If the block is in the first message part then it will be metadata about the whole message:
 * meaning, description, id.  Otherwise it will be metadata about the immediately preceding
 * substitution: placeholder name.
 *
 * Since blocks are optional, it is possible that the content of a message block actually starts
 * with a block marker. In this case the marker must be escaped `\:`.
 *
 * @param cooked The cooked version of the message part to parse.
 * @param raw The raw version of the message part to parse.
 * @returns An object containing the `text` of the message part and the text of the `block`, if it
 * exists.
 * @throws an error if the `block` is unterminated
 */
function splitBlock(cooked, raw) {
  if (raw.charAt(0) !== BLOCK_MARKER$1) {
    return {
      text: cooked
    };
  } else {
    const endOfBlock = findEndOfBlock(cooked, raw);
    return {
      block: cooked.substring(1, endOfBlock),
      text: cooked.substring(endOfBlock + 1)
    };
  }
}
function computePlaceholderName(index) {
  return index === 1 ? 'PH' : `PH_${index - 1}`;
}
/**
 * Find the end of a "marked block" indicated by the first non-escaped colon.
 *
 * @param cooked The cooked string (where escaped chars have been processed)
 * @param raw The raw string (where escape sequences are still in place)
 *
 * @returns the index of the end of block marker
 * @throws an error if the block is unterminated
 */
function findEndOfBlock(cooked, raw) {
  for (let cookedIndex = 1, rawIndex = 1; cookedIndex < cooked.length; cookedIndex++, rawIndex++) {
    if (raw[rawIndex] === '\\') {
      rawIndex++;
    } else if (cooked[cookedIndex] === BLOCK_MARKER$1) {
      return cookedIndex;
    }
  }
  throw new Error(`Unterminated $localize metadata block in "${raw}".`);
}
class MissingTranslationError extends Error {
  constructor(parsedMessage) {
    super(`No translation found for ${describeMessage(parsedMessage)}.`);
    this.parsedMessage = parsedMessage;
    this.type = 'MissingTranslationError';
  }
}
function isMissingTranslationError(e) {
  return e.type === 'MissingTranslationError';
}
/**
 * Translate the text of the `$localize` tagged-string (i.e. `messageParts` and
 * `substitutions`) using the given `translations`.
 *
 * The tagged-string is parsed to extract its `messageId` which is used to find an appropriate
 * `ParsedTranslation`. If this doesn't match and there are legacy ids then try matching a
 * translation using those.
 *
 * If one is found then it is used to translate the message into a new set of `messageParts` and
 * `substitutions`.
 * The translation may reorder (or remove) substitutions as appropriate.
 *
 * If there is no translation with a matching message id then an error is thrown.
 * If a translation contains a placeholder that is not found in the message being translated then an
 * error is thrown.
 */
function translate$1(translations, messageParts, substitutions) {
  const message = parseMessage(messageParts, substitutions);
  // Look up the translation using the messageId, and then the legacyId if available.
  let translation = translations[message.id];
  // If the messageId did not match a translation, try matching the legacy ids instead
  if (message.legacyIds !== undefined) {
    for (let i = 0; i < message.legacyIds.length && translation === undefined; i++) {
      translation = translations[message.legacyIds[i]];
    }
  }
  if (translation === undefined) {
    throw new MissingTranslationError(message);
  }
  return [translation.messageParts, translation.placeholderNames.map(placeholder => {
    if (message.substitutions.hasOwnProperty(placeholder)) {
      return message.substitutions[placeholder];
    } else {
      throw new Error(`There is a placeholder name mismatch with the translation provided for the message ${describeMessage(message)}.\n` + `The translation contains a placeholder with name ${placeholder}, which does not exist in the message.`);
    }
  })];
}
/**
 * Parse the `messageParts` and `placeholderNames` out of a target `message`.
 *
 * Used by `loadTranslations()` to convert target message strings into a structure that is more
 * appropriate for doing translation.
 *
 * @param message the message to be parsed.
 */
function parseTranslation(messageString) {
  const parts = messageString.split(/{\$([^}]*)}/);
  const messageParts = [parts[0]];
  const placeholderNames = [];
  for (let i = 1; i < parts.length - 1; i += 2) {
    placeholderNames.push(parts[i]);
    messageParts.push(`${parts[i + 1]}`);
  }
  const rawMessageParts = messageParts.map(part => part.charAt(0) === BLOCK_MARKER$1 ? '\\' + part : part);
  return {
    text: messageString,
    messageParts: makeTemplateObject(messageParts, rawMessageParts),
    placeholderNames
  };
}
/**
 * Create a `ParsedTranslation` from a set of `messageParts` and `placeholderNames`.
 *
 * @param messageParts The message parts to appear in the ParsedTranslation.
 * @param placeholderNames The names of the placeholders to intersperse between the `messageParts`.
 */
function makeParsedTranslation(messageParts, placeholderNames = []) {
  let messageString = messageParts[0];
  for (let i = 0; i < placeholderNames.length; i++) {
    messageString += `{$${placeholderNames[i]}}${messageParts[i + 1]}`;
  }
  return {
    text: messageString,
    messageParts: makeTemplateObject(messageParts, messageParts),
    placeholderNames
  };
}
/**
 * Create the specialized array that is passed to tagged-string tag functions.
 *
 * @param cooked The message parts with their escape codes processed.
 * @param raw The message parts with their escaped codes as-is.
 */
function makeTemplateObject(cooked, raw) {
  Object.defineProperty(cooked, 'raw', {
    value: raw
  });
  return cooked;
}
function describeMessage(message) {
  const meaningString = message.meaning && ` - "${message.meaning}"`;
  const legacy = message.legacyIds && message.legacyIds.length > 0 ? ` [${message.legacyIds.map(l => `"${l}"`).join(', ')}]` : '';
  return `"${message.id}"${legacy} ("${message.text}"${meaningString})`;
}

/**
 * Load translations for use by `$localize`, if doing runtime translation.
 *
 * If the `$localize` tagged strings are not going to be replaced at compiled time, it is possible
 * to load a set of translations that will be applied to the `$localize` tagged strings at runtime,
 * in the browser.
 *
 * Loading a new translation will overwrite a previous translation if it has the same `MessageId`.
 *
 * Note that `$localize` messages are only processed once, when the tagged string is first
 * encountered, and does not provide dynamic language changing without refreshing the browser.
 * Loading new translations later in the application life-cycle will not change the translated text
 * of messages that have already been translated.
 *
 * The message IDs and translations are in the same format as that rendered to "simple JSON"
 * translation files when extracting messages. In particular, placeholders in messages are rendered
 * using the `{$PLACEHOLDER_NAME}` syntax. For example the message from the following template:
 *
 * ```html
 * <div i18n>pre<span>inner-pre<b>bold</b>inner-post</span>post</div>
 * ```
 *
 * would have the following form in the `translations` map:
 *
 * ```ts
 * {
 *   "2932901491976224757":
 *      "pre{$START_TAG_SPAN}inner-pre{$START_BOLD_TEXT}bold{$CLOSE_BOLD_TEXT}inner-post{$CLOSE_TAG_SPAN}post"
 * }
 * ```
 *
 * @param translations A map from message ID to translated message.
 *
 * These messages are processed and added to a lookup based on their `MessageId`.
 *
 * @see {@link clearTranslations} for removing translations loaded using this function.
 * @see {@link $localize} for tagging messages as needing to be translated.
 * @publicApi
 */
function loadTranslations(translations) {
  // Ensure the translate function exists
  if (!$localize.translate) {
    $localize.translate = translate;
  }
  if (!$localize.TRANSLATIONS) {
    $localize.TRANSLATIONS = {};
  }
  Object.keys(translations).forEach(key => {
    $localize.TRANSLATIONS[key] = parseTranslation(translations[key]);
  });
}
/**
 * Remove all translations for `$localize`, if doing runtime translation.
 *
 * All translations that had been loading into memory using `loadTranslations()` will be removed.
 *
 * @see {@link loadTranslations} for loading translations at runtime.
 * @see {@link $localize} for tagging messages as needing to be translated.
 *
 * @publicApi
 */
function clearTranslations() {
  $localize.translate = undefined;
  $localize.TRANSLATIONS = {};
}
/**
 * Translate the text of the given message, using the loaded translations.
 *
 * This function may reorder (or remove) substitutions as indicated in the matching translation.
 */
function translate(messageParts, substitutions) {
  try {
    return translate$1($localize.TRANSLATIONS, messageParts, substitutions);
  } catch (e) {
    console.warn(e.message);
    return [messageParts, substitutions];
  }
}

/**
 * Tag a template literal string for localization.
 *
 * For example:
 *
 * ```ts
 * $localize `some string to localize`
 * ```
 *
 * **Providing meaning, description and id**
 *
 * You can optionally specify one or more of `meaning`, `description` and `id` for a localized
 * string by pre-pending it with a colon delimited block of the form:
 *
 * ```ts
 * $localize`:meaning|description@@id:source message text`;
 *
 * $localize`:meaning|:source message text`;
 * $localize`:description:source message text`;
 * $localize`:@@id:source message text`;
 * ```
 *
 * This format is the same as that used for `i18n` markers in Angular templates. See the
 * [Angular i18n guide](guide/i18n-common-prepare#mark-text-in-component-template).
 *
 * **Naming placeholders**
 *
 * If the template literal string contains expressions, then the expressions will be automatically
 * associated with placeholder names for you.
 *
 * For example:
 *
 * ```ts
 * $localize `Hi ${name}! There are ${items.length} items.`;
 * ```
 *
 * will generate a message-source of `Hi {$PH}! There are {$PH_1} items`.
 *
 * The recommended practice is to name the placeholder associated with each expression though.
 *
 * Do this by providing the placeholder name wrapped in `:` characters directly after the
 * expression. These placeholder names are stripped out of the rendered localized string.
 *
 * For example, to name the `items.length` expression placeholder `itemCount` you write:
 *
 * ```ts
 * $localize `There are ${items.length}:itemCount: items`;
 * ```
 *
 * **Escaping colon markers**
 *
 * If you need to use a `:` character directly at the start of a tagged string that has no
 * metadata block, or directly after a substitution expression that has no name you must escape
 * the `:` by preceding it with a backslash:
 *
 * For example:
 *
 * ```ts
 * // message has a metadata block so no need to escape colon
 * $localize `:some description::this message starts with a colon (:)`;
 * // no metadata block so the colon must be escaped
 * $localize `\:this message starts with a colon (:)`;
 * ```
 *
 * ```ts
 * // named substitution so no need to escape colon
 * $localize `${label}:label:: ${}`
 * // anonymous substitution so colon must be escaped
 * $localize `${label}\: ${}`
 * ```
 *
 * **Processing localized strings:**
 *
 * There are three scenarios:
 *
 * * **compile-time inlining**: the `$localize` tag is transformed at compile time by a
 * transpiler, removing the tag and replacing the template literal string with a translated
 * literal string from a collection of translations provided to the transpilation tool.
 *
 * * **run-time evaluation**: the `$localize` tag is a run-time function that replaces and
 * reorders the parts (static strings and expressions) of the template literal string with strings
 * from a collection of translations loaded at run-time.
 *
 * * **pass-through evaluation**: the `$localize` tag is a run-time function that simply evaluates
 * the original template literal string without applying any translations to the parts. This
 * version is used during development or where there is no need to translate the localized
 * template literals.
 *
 * @param messageParts a collection of the static parts of the template string.
 * @param expressions a collection of the values of each placeholder in the template string.
 * @returns the translated string, with the `messageParts` and `expressions` interleaved together.
 *
 * @globalApi
 * @publicApi
 */
const $localize$1 = function (messageParts, ...expressions) {
  if ($localize$1.translate) {
    // Don't use array expansion here to avoid the compiler adding `__read()` helper unnecessarily.
    const translation = $localize$1.translate(messageParts, expressions);
    messageParts = translation[0];
    expressions = translation[1];
  }
  let message = stripBlock(messageParts[0], messageParts.raw[0]);
  for (let i = 1; i < messageParts.length; i++) {
    message += expressions[i - 1] + stripBlock(messageParts[i], messageParts.raw[i]);
  }
  return message;
};
const BLOCK_MARKER = ':';
/**
 * Strip a delimited "block" from the start of the `messagePart`, if it is found.
 *
 * If a marker character (:) actually appears in the content at the start of a tagged string or
 * after a substitution expression, where a block has not been provided the character must be
 * escaped with a backslash, `\:`. This function checks for this by looking at the `raw`
 * messagePart, which should still contain the backslash.
 *
 * @param messagePart The cooked message part to process.
 * @param rawMessagePart The raw message part to check.
 * @returns the message part with the placeholder name stripped, if found.
 * @throws an error if the block is unterminated
 */
function stripBlock(messagePart, rawMessagePart) {
  return rawMessagePart.charAt(0) === BLOCK_MARKER ? messagePart.substring(findEndOfBlock(messagePart, rawMessagePart) + 1) : messagePart;
}

// This file exports all the `utils` as private exports so that other parts of `@angular/localize`

// This file contains the public API of the `@angular/localize` entry-point

// DO NOT ADD public exports to this file.



/***/ }),

/***/ 74646:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/material/fesm2022/core.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnimationCurves: () => (/* binding */ AnimationCurves),
/* harmony export */   AnimationDurations: () => (/* binding */ AnimationDurations),
/* harmony export */   DateAdapter: () => (/* binding */ DateAdapter),
/* harmony export */   ErrorStateMatcher: () => (/* binding */ ErrorStateMatcher),
/* harmony export */   MATERIAL_SANITY_CHECKS: () => (/* binding */ MATERIAL_SANITY_CHECKS),
/* harmony export */   MAT_DATE_FORMATS: () => (/* binding */ MAT_DATE_FORMATS),
/* harmony export */   MAT_DATE_LOCALE: () => (/* binding */ MAT_DATE_LOCALE),
/* harmony export */   MAT_DATE_LOCALE_FACTORY: () => (/* binding */ MAT_DATE_LOCALE_FACTORY),
/* harmony export */   MAT_NATIVE_DATE_FORMATS: () => (/* binding */ MAT_NATIVE_DATE_FORMATS),
/* harmony export */   MAT_OPTGROUP: () => (/* binding */ MAT_OPTGROUP),
/* harmony export */   MAT_OPTION_PARENT_COMPONENT: () => (/* binding */ MAT_OPTION_PARENT_COMPONENT),
/* harmony export */   MAT_RIPPLE_GLOBAL_OPTIONS: () => (/* binding */ MAT_RIPPLE_GLOBAL_OPTIONS),
/* harmony export */   MatCommonModule: () => (/* binding */ MatCommonModule),
/* harmony export */   MatLine: () => (/* binding */ MatLine),
/* harmony export */   MatLineModule: () => (/* binding */ MatLineModule),
/* harmony export */   MatNativeDateModule: () => (/* binding */ MatNativeDateModule),
/* harmony export */   MatOptgroup: () => (/* binding */ MatOptgroup),
/* harmony export */   MatOption: () => (/* binding */ MatOption),
/* harmony export */   MatOptionModule: () => (/* binding */ MatOptionModule),
/* harmony export */   MatOptionSelectionChange: () => (/* binding */ MatOptionSelectionChange),
/* harmony export */   MatPseudoCheckbox: () => (/* binding */ MatPseudoCheckbox),
/* harmony export */   MatPseudoCheckboxModule: () => (/* binding */ MatPseudoCheckboxModule),
/* harmony export */   MatRipple: () => (/* binding */ MatRipple),
/* harmony export */   MatRippleLoader: () => (/* binding */ MatRippleLoader),
/* harmony export */   MatRippleModule: () => (/* binding */ MatRippleModule),
/* harmony export */   NativeDateAdapter: () => (/* binding */ NativeDateAdapter),
/* harmony export */   NativeDateModule: () => (/* binding */ NativeDateModule),
/* harmony export */   RippleRef: () => (/* binding */ RippleRef),
/* harmony export */   RippleRenderer: () => (/* binding */ RippleRenderer),
/* harmony export */   RippleState: () => (/* binding */ RippleState),
/* harmony export */   ShowOnDirtyErrorStateMatcher: () => (/* binding */ ShowOnDirtyErrorStateMatcher),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   _ErrorStateTracker: () => (/* binding */ _ErrorStateTracker),
/* harmony export */   _MatInternalFormField: () => (/* binding */ _MatInternalFormField),
/* harmony export */   _countGroupLabelsBeforeOption: () => (/* binding */ _countGroupLabelsBeforeOption),
/* harmony export */   _getOptionScrollPosition: () => (/* binding */ _getOptionScrollPosition),
/* harmony export */   defaultRippleAnimationConfig: () => (/* binding */ defaultRippleAnimationConfig),
/* harmony export */   mixinColor: () => (/* binding */ mixinColor),
/* harmony export */   mixinDisableRipple: () => (/* binding */ mixinDisableRipple),
/* harmony export */   mixinDisabled: () => (/* binding */ mixinDisabled),
/* harmony export */   mixinErrorState: () => (/* binding */ mixinErrorState),
/* harmony export */   mixinInitialized: () => (/* binding */ mixinInitialized),
/* harmony export */   mixinTabIndex: () => (/* binding */ mixinTabIndex),
/* harmony export */   provideNativeDateAdapter: () => (/* binding */ provideNativeDateAdapter),
/* harmony export */   setLines: () => (/* binding */ setLines)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/cdk/a11y */ 72102);
/* harmony import */ var _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/cdk/bidi */ 63680);
/* harmony import */ var _angular_cdk__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/cdk */ 31398);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/cdk/platform */ 17699);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @angular/cdk/keycodes */ 74879);














/** Current version of Angular Material. */
const _c0 = ["*", [["mat-option"], ["ng-container"]]];
const _c1 = ["*", "mat-option, ng-container"];
const _c2 = ["text"];
const _c3 = [[["mat-icon"]], "*"];
const _c4 = ["mat-icon", "*"];
function MatOption_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "mat-pseudo-checkbox", 1);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r0.disabled)("state", ctx_r0.selected ? "checked" : "unchecked");
  }
}
function MatOption_Conditional_5_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "mat-pseudo-checkbox", 3);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r0.disabled);
  }
}
function MatOption_Conditional_6_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"]("(", ctx_r0.group.label, ")");
  }
}
const _c5 = ["mat-internal-form-field", ""];
const _c6 = ["*"];
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.Version('18.2.14');

/** @docs-private */
class AnimationCurves {
  static {
    this.STANDARD_CURVE = 'cubic-bezier(0.4,0.0,0.2,1)';
  }
  static {
    this.DECELERATION_CURVE = 'cubic-bezier(0.0,0.0,0.2,1)';
  }
  static {
    this.ACCELERATION_CURVE = 'cubic-bezier(0.4,0.0,1,1)';
  }
  static {
    this.SHARP_CURVE = 'cubic-bezier(0.4,0.0,0.6,1)';
  }
}
/** @docs-private */
class AnimationDurations {
  static {
    this.COMPLEX = '375ms';
  }
  static {
    this.ENTERING = '225ms';
  }
  static {
    this.EXITING = '195ms';
  }
}

/** @docs-private */
function MATERIAL_SANITY_CHECKS_FACTORY() {
  return true;
}
/** Injection token that configures whether the Material sanity checks are enabled. */
const MATERIAL_SANITY_CHECKS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('mat-sanity-checks', {
  providedIn: 'root',
  factory: MATERIAL_SANITY_CHECKS_FACTORY
});
/**
 * Module that captures anything that should be loaded and/or run for *all* Angular Material
 * components. This includes Bidi, etc.
 *
 * This module should be imported to each top-level component module (e.g., MatTabsModule).
 */
class MatCommonModule {
  constructor(highContrastModeDetector, _sanityChecks, _document) {
    this._sanityChecks = _sanityChecks;
    this._document = _document;
    /** Whether we've done the global sanity checks (e.g. a theme is loaded, there is a doctype). */
    this._hasDoneGlobalChecks = false;
    // While A11yModule also does this, we repeat it here to avoid importing A11yModule
    // in MatCommonModule.
    highContrastModeDetector._applyBodyHighContrastModeCssClasses();
    if (!this._hasDoneGlobalChecks) {
      this._hasDoneGlobalChecks = true;
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        // Inject in here so the reference to `Platform` can be removed in production mode.
        const platform = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform, {
          optional: true
        });
        if (this._checkIsEnabled('doctype')) {
          _checkDoctypeIsDefined(this._document);
        }
        if (this._checkIsEnabled('theme')) {
          _checkThemeIsPresent(this._document, !!platform?.isBrowser);
        }
        if (this._checkIsEnabled('version')) {
          _checkCdkVersionMatch();
        }
      }
    }
  }
  /** Gets whether a specific sanity check is enabled. */
  _checkIsEnabled(name) {
    if ((0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__._isTestEnvironment)()) {
      return false;
    }
    if (typeof this._sanityChecks === 'boolean') {
      return this._sanityChecks;
    }
    return !!this._sanityChecks[name];
  }
  static {
    this.ɵfac = function MatCommonModule_Factory(t) {
      return new (t || MatCommonModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_2__.HighContrastModeDetector), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](MATERIAL_SANITY_CHECKS, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_3__.DOCUMENT));
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatCommonModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_4__.BidiModule, _angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_4__.BidiModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatCommonModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_4__.BidiModule],
      exports: [_angular_cdk_bidi__WEBPACK_IMPORTED_MODULE_4__.BidiModule]
    }]
  }], () => [{
    type: _angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_2__.HighContrastModeDetector
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MATERIAL_SANITY_CHECKS]
    }]
  }, {
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_3__.DOCUMENT]
    }]
  }], null);
})();
/** Checks that the page has a doctype. */
function _checkDoctypeIsDefined(doc) {
  if (!doc.doctype) {
    console.warn('Current document does not have a doctype. This may cause ' + 'some Angular Material components not to behave as expected.');
  }
}
/** Checks that a theme has been included. */
function _checkThemeIsPresent(doc, isBrowser) {
  // We need to assert that the `body` is defined, because these checks run very early
  // and the `body` won't be defined if the consumer put their scripts in the `head`.
  if (!doc.body || !isBrowser) {
    return;
  }
  const testElement = doc.createElement('div');
  testElement.classList.add('mat-theme-loaded-marker');
  doc.body.appendChild(testElement);
  const computedStyle = getComputedStyle(testElement);
  // In some situations the computed style of the test element can be null. For example in
  // Firefox, the computed style is null if an application is running inside of a hidden iframe.
  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=548397
  if (computedStyle && computedStyle.display !== 'none') {
    console.warn('Could not find Angular Material core theme. Most Material ' + 'components may not work as expected. For more info refer ' + 'to the theming guide: https://material.angular.io/guide/theming');
  }
  testElement.remove();
}
/** Checks whether the Material version matches the CDK version. */
function _checkCdkVersionMatch() {
  if (VERSION.full !== _angular_cdk__WEBPACK_IMPORTED_MODULE_5__.VERSION.full) {
    console.warn('The Angular Material version (' + VERSION.full + ') does not match ' + 'the Angular CDK version (' + _angular_cdk__WEBPACK_IMPORTED_MODULE_5__.VERSION.full + ').\n' + 'Please ensure the versions of these two packages exactly match.');
  }
}
function mixinDisabled(base) {
  return class extends base {
    get disabled() {
      return this._disabled;
    }
    set disabled(value) {
      this._disabled = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__.coerceBooleanProperty)(value);
    }
    constructor(...args) {
      super(...args);
      this._disabled = false;
    }
  };
}
function mixinColor(base, defaultColor) {
  return class extends base {
    get color() {
      return this._color;
    }
    set color(value) {
      const colorPalette = value || this.defaultColor;
      if (colorPalette !== this._color) {
        if (this._color) {
          this._elementRef.nativeElement.classList.remove(`mat-${this._color}`);
        }
        if (colorPalette) {
          this._elementRef.nativeElement.classList.add(`mat-${colorPalette}`);
        }
        this._color = colorPalette;
      }
    }
    constructor(...args) {
      super(...args);
      this.defaultColor = defaultColor;
      // Set the default color that can be specified from the mixin.
      this.color = defaultColor;
    }
  };
}
function mixinDisableRipple(base) {
  return class extends base {
    /** Whether the ripple effect is disabled or not. */
    get disableRipple() {
      return this._disableRipple;
    }
    set disableRipple(value) {
      this._disableRipple = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__.coerceBooleanProperty)(value);
    }
    constructor(...args) {
      super(...args);
      this._disableRipple = false;
    }
  };
}
function mixinTabIndex(base, defaultTabIndex = 0) {
  return class extends base {
    get tabIndex() {
      return this.disabled ? -1 : this._tabIndex;
    }
    set tabIndex(value) {
      // If the specified tabIndex value is null or undefined, fall back to the default value.
      this._tabIndex = value != null ? (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__.coerceNumberProperty)(value) : this.defaultTabIndex;
    }
    constructor(...args) {
      super(...args);
      this._tabIndex = defaultTabIndex;
      this.defaultTabIndex = defaultTabIndex;
    }
  };
}

/**
 * Class that tracks the error state of a component.
 * @docs-private
 */
class _ErrorStateTracker {
  constructor(_defaultMatcher, ngControl, _parentFormGroup, _parentForm, _stateChanges) {
    this._defaultMatcher = _defaultMatcher;
    this.ngControl = ngControl;
    this._parentFormGroup = _parentFormGroup;
    this._parentForm = _parentForm;
    this._stateChanges = _stateChanges;
    /** Whether the tracker is currently in an error state. */
    this.errorState = false;
  }
  /** Updates the error state based on the provided error state matcher. */
  updateErrorState() {
    const oldState = this.errorState;
    const parent = this._parentFormGroup || this._parentForm;
    const matcher = this.matcher || this._defaultMatcher;
    const control = this.ngControl ? this.ngControl.control : null;
    const newState = matcher?.isErrorState(control, parent) ?? false;
    if (newState !== oldState) {
      this.errorState = newState;
      this._stateChanges.next();
    }
  }
}
function mixinErrorState(base) {
  return class extends base {
    /** Whether the component is in an error state. */
    get errorState() {
      return this._getTracker().errorState;
    }
    set errorState(value) {
      this._getTracker().errorState = value;
    }
    /** An object used to control the error state of the component. */
    get errorStateMatcher() {
      return this._getTracker().matcher;
    }
    set errorStateMatcher(value) {
      this._getTracker().matcher = value;
    }
    /** Updates the error state based on the provided error state matcher. */
    updateErrorState() {
      this._getTracker().updateErrorState();
    }
    _getTracker() {
      if (!this._tracker) {
        this._tracker = new _ErrorStateTracker(this._defaultErrorStateMatcher, this.ngControl, this._parentFormGroup, this._parentForm, this.stateChanges);
      }
      return this._tracker;
    }
    constructor(...args) {
      super(...args);
    }
  };
}

/**
 * Mixin to augment a directive with an initialized property that will emits when ngOnInit ends.
 * @deprecated Track the initialized state manually.
 * @breaking-change 19.0.0
 */
function mixinInitialized(base) {
  return class extends base {
    constructor(...args) {
      super(...args);
      /** Whether this directive has been marked as initialized. */
      this._isInitialized = false;
      /**
       * List of subscribers that subscribed before the directive was initialized. Should be notified
       * during _markInitialized. Set to null after pending subscribers are notified, and should
       * not expect to be populated after.
       */
      this._pendingSubscribers = [];
      /**
       * Observable stream that emits when the directive initializes. If already initialized, the
       * subscriber is stored to be notified once _markInitialized is called.
       */
      this.initialized = new rxjs__WEBPACK_IMPORTED_MODULE_7__.Observable(subscriber => {
        // If initialized, immediately notify the subscriber. Otherwise store the subscriber to notify
        // when _markInitialized is called.
        if (this._isInitialized) {
          this._notifySubscriber(subscriber);
        } else {
          this._pendingSubscribers.push(subscriber);
        }
      });
    }
    /**
     * Marks the state as initialized and notifies pending subscribers. Should be called at the end
     * of ngOnInit.
     * @docs-private
     */
    _markInitialized() {
      if (this._isInitialized && (typeof ngDevMode === 'undefined' || ngDevMode)) {
        throw Error('This directive has already been marked as initialized and ' + 'should not be called twice.');
      }
      this._isInitialized = true;
      this._pendingSubscribers.forEach(this._notifySubscriber);
      this._pendingSubscribers = null;
    }
    /** Emits and completes the subscriber stream (should only emit once). */
    _notifySubscriber(subscriber) {
      subscriber.next();
      subscriber.complete();
    }
  };
}

/** InjectionToken for datepicker that can be used to override default locale code. */
const MAT_DATE_LOCALE = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('MAT_DATE_LOCALE', {
  providedIn: 'root',
  factory: MAT_DATE_LOCALE_FACTORY
});
/** @docs-private */
function MAT_DATE_LOCALE_FACTORY() {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID);
}
/** Adapts type `D` to be usable as a date by cdk-based components that work with dates. */
class DateAdapter {
  constructor() {
    this._localeChanges = new rxjs__WEBPACK_IMPORTED_MODULE_8__.Subject();
    /** A stream that emits when the locale changes. */
    this.localeChanges = this._localeChanges;
  }
  /**
   * Given a potential date object, returns that same date object if it is
   * a valid date, or `null` if it's not a valid date.
   * @param obj The object to check.
   * @returns A date or `null`.
   */
  getValidDateOrNull(obj) {
    return this.isDateInstance(obj) && this.isValid(obj) ? obj : null;
  }
  /**
   * Attempts to deserialize a value to a valid date object. This is different from parsing in that
   * deserialize should only accept non-ambiguous, locale-independent formats (e.g. a ISO 8601
   * string). The default implementation does not allow any deserialization, it simply checks that
   * the given value is already a valid date object or null. The `<mat-datepicker>` will call this
   * method on all of its `@Input()` properties that accept dates. It is therefore possible to
   * support passing values from your backend directly to these properties by overriding this method
   * to also deserialize the format used by your backend.
   * @param value The value to be deserialized into a date object.
   * @returns The deserialized date object, either a valid date, null if the value can be
   *     deserialized into a null date (e.g. the empty string), or an invalid date.
   */
  deserialize(value) {
    if (value == null || this.isDateInstance(value) && this.isValid(value)) {
      return value;
    }
    return this.invalid();
  }
  /**
   * Sets the locale used for all dates.
   * @param locale The new locale.
   */
  setLocale(locale) {
    this.locale = locale;
    this._localeChanges.next();
  }
  /**
   * Compares two dates.
   * @param first The first date to compare.
   * @param second The second date to compare.
   * @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,
   *     a number greater than 0 if the first date is later.
   */
  compareDate(first, second) {
    return this.getYear(first) - this.getYear(second) || this.getMonth(first) - this.getMonth(second) || this.getDate(first) - this.getDate(second);
  }
  /**
   * Checks if two dates are equal.
   * @param first The first date to check.
   * @param second The second date to check.
   * @returns Whether the two dates are equal.
   *     Null dates are considered equal to other null dates.
   */
  sameDate(first, second) {
    if (first && second) {
      let firstValid = this.isValid(first);
      let secondValid = this.isValid(second);
      if (firstValid && secondValid) {
        return !this.compareDate(first, second);
      }
      return firstValid == secondValid;
    }
    return first == second;
  }
  /**
   * Clamp the given date between min and max dates.
   * @param date The date to clamp.
   * @param min The minimum value to allow. If null or omitted no min is enforced.
   * @param max The maximum value to allow. If null or omitted no max is enforced.
   * @returns `min` if `date` is less than `min`, `max` if date is greater than `max`,
   *     otherwise `date`.
   */
  clampDate(date, min, max) {
    if (min && this.compareDate(date, min) < 0) {
      return min;
    }
    if (max && this.compareDate(date, max) > 0) {
      return max;
    }
    return date;
  }
}
const MAT_DATE_FORMATS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('mat-date-formats');

/**
 * Matches strings that have the form of a valid RFC 3339 string
 * (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date
 * because the regex will match strings with an out of bounds month, date, etc.
 */
const ISO_8601_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|(?:(?:\+|-)\d{2}:\d{2}))?)?$/;
/** Creates an array and fills it with values. */
function range(length, valueFunction) {
  const valuesArray = Array(length);
  for (let i = 0; i < length; i++) {
    valuesArray[i] = valueFunction(i);
  }
  return valuesArray;
}
/** Adapts the native JS Date for use with cdk-based components that work with dates. */
class NativeDateAdapter extends DateAdapter {
  constructor(
  /**
   * @deprecated Now injected via inject(), param to be removed.
   * @breaking-change 18.0.0
   */
  matDateLocale) {
    super();
    /**
     * @deprecated No longer being used. To be removed.
     * @breaking-change 14.0.0
     */
    this.useUtcForDisplay = false;
    /** The injected locale. */
    this._matDateLocale = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(MAT_DATE_LOCALE, {
      optional: true
    });
    if (matDateLocale !== undefined) {
      this._matDateLocale = matDateLocale;
    }
    super.setLocale(this._matDateLocale);
  }
  getYear(date) {
    return date.getFullYear();
  }
  getMonth(date) {
    return date.getMonth();
  }
  getDate(date) {
    return date.getDate();
  }
  getDayOfWeek(date) {
    return date.getDay();
  }
  getMonthNames(style) {
    const dtf = new Intl.DateTimeFormat(this.locale, {
      month: style,
      timeZone: 'utc'
    });
    return range(12, i => this._format(dtf, new Date(2017, i, 1)));
  }
  getDateNames() {
    const dtf = new Intl.DateTimeFormat(this.locale, {
      day: 'numeric',
      timeZone: 'utc'
    });
    return range(31, i => this._format(dtf, new Date(2017, 0, i + 1)));
  }
  getDayOfWeekNames(style) {
    const dtf = new Intl.DateTimeFormat(this.locale, {
      weekday: style,
      timeZone: 'utc'
    });
    return range(7, i => this._format(dtf, new Date(2017, 0, i + 1)));
  }
  getYearName(date) {
    const dtf = new Intl.DateTimeFormat(this.locale, {
      year: 'numeric',
      timeZone: 'utc'
    });
    return this._format(dtf, date);
  }
  getFirstDayOfWeek() {
    // At the time of writing `Intl.Locale` isn't available
    // in the internal types so we need to cast to `any`.
    if (typeof Intl !== 'undefined' && Intl.Locale) {
      const locale = new Intl.Locale(this.locale);
      // Some browsers implement a `getWeekInfo` method while others have a `weekInfo` getter.
      // Note that this isn't supported in all browsers so we need to null check it.
      const firstDay = (locale.getWeekInfo?.() || locale.weekInfo)?.firstDay ?? 0;
      // `weekInfo.firstDay` is a number between 1 and 7 where, starting from Monday,
      // whereas our representation is 0 to 6 where 0 is Sunday so we need to normalize it.
      return firstDay === 7 ? 0 : firstDay;
    }
    // Default to Sunday if the browser doesn't provide the week information.
    return 0;
  }
  getNumDaysInMonth(date) {
    return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));
  }
  clone(date) {
    return new Date(date.getTime());
  }
  createDate(year, month, date) {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      // Check for invalid month and date (except upper bound on date which we have to check after
      // creating the Date).
      if (month < 0 || month > 11) {
        throw Error(`Invalid month index "${month}". Month index has to be between 0 and 11.`);
      }
      if (date < 1) {
        throw Error(`Invalid date "${date}". Date has to be greater than 0.`);
      }
    }
    let result = this._createDateWithOverflow(year, month, date);
    // Check that the date wasn't above the upper bound for the month, causing the month to overflow
    if (result.getMonth() != month && (typeof ngDevMode === 'undefined' || ngDevMode)) {
      throw Error(`Invalid date "${date}" for month with index "${month}".`);
    }
    return result;
  }
  today() {
    return new Date();
  }
  parse(value, parseFormat) {
    // We have no way using the native JS Date to set the parse format or locale, so we ignore these
    // parameters.
    if (typeof value == 'number') {
      return new Date(value);
    }
    return value ? new Date(Date.parse(value)) : null;
  }
  format(date, displayFormat) {
    if (!this.isValid(date)) {
      throw Error('NativeDateAdapter: Cannot format invalid date.');
    }
    const dtf = new Intl.DateTimeFormat(this.locale, {
      ...displayFormat,
      timeZone: 'utc'
    });
    return this._format(dtf, date);
  }
  addCalendarYears(date, years) {
    return this.addCalendarMonths(date, years * 12);
  }
  addCalendarMonths(date, months) {
    let newDate = this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + months, this.getDate(date));
    // It's possible to wind up in the wrong month if the original month has more days than the new
    // month. In this case we want to go to the last day of the desired month.
    // Note: the additional + 12 % 12 ensures we end up with a positive number, since JS % doesn't
    // guarantee this.
    if (this.getMonth(newDate) != ((this.getMonth(date) + months) % 12 + 12) % 12) {
      newDate = this._createDateWithOverflow(this.getYear(newDate), this.getMonth(newDate), 0);
    }
    return newDate;
  }
  addCalendarDays(date, days) {
    return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);
  }
  toIso8601(date) {
    return [date.getUTCFullYear(), this._2digit(date.getUTCMonth() + 1), this._2digit(date.getUTCDate())].join('-');
  }
  /**
   * Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings
   * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an
   * invalid date for all other values.
   */
  deserialize(value) {
    if (typeof value === 'string') {
      if (!value) {
        return null;
      }
      // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the
      // string is the right format first.
      if (ISO_8601_REGEX.test(value)) {
        let date = new Date(value);
        if (this.isValid(date)) {
          return date;
        }
      }
    }
    return super.deserialize(value);
  }
  isDateInstance(obj) {
    return obj instanceof Date;
  }
  isValid(date) {
    return !isNaN(date.getTime());
  }
  invalid() {
    return new Date(NaN);
  }
  /** Creates a date but allows the month and date to overflow. */
  _createDateWithOverflow(year, month, date) {
    // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.
    // To work around this we use `setFullYear` and `setHours` instead.
    const d = new Date();
    d.setFullYear(year, month, date);
    d.setHours(0, 0, 0, 0);
    return d;
  }
  /**
   * Pads a number to make it two digits.
   * @param n The number to pad.
   * @returns The padded number.
   */
  _2digit(n) {
    return ('00' + n).slice(-2);
  }
  /**
   * When converting Date object to string, javascript built-in functions may return wrong
   * results because it applies its internal DST rules. The DST rules around the world change
   * very frequently, and the current valid rule is not always valid in previous years though.
   * We work around this problem building a new Date object which has its internal UTC
   * representation with the local date and time.
   * @param dtf Intl.DateTimeFormat object, containing the desired string format. It must have
   *    timeZone set to 'utc' to work fine.
   * @param date Date from which we want to get the string representation according to dtf
   * @returns A Date object with its UTC representation based on the passed in date info
   */
  _format(dtf, date) {
    // Passing the year to the constructor causes year numbers <100 to be converted to 19xx.
    // To work around this we use `setUTCFullYear` and `setUTCHours` instead.
    const d = new Date();
    d.setUTCFullYear(date.getFullYear(), date.getMonth(), date.getDate());
    d.setUTCHours(date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds());
    return dtf.format(d);
  }
  static {
    this.ɵfac = function NativeDateAdapter_Factory(t) {
      return new (t || NativeDateAdapter)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](MAT_DATE_LOCALE, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NativeDateAdapter,
      factory: NativeDateAdapter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NativeDateAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MAT_DATE_LOCALE]
    }]
  }], null);
})();
const MAT_NATIVE_DATE_FORMATS = {
  parse: {
    dateInput: null
  },
  display: {
    dateInput: {
      year: 'numeric',
      month: 'numeric',
      day: 'numeric'
    },
    monthYearLabel: {
      year: 'numeric',
      month: 'short'
    },
    dateA11yLabel: {
      year: 'numeric',
      month: 'long',
      day: 'numeric'
    },
    monthYearA11yLabel: {
      year: 'numeric',
      month: 'long'
    }
  }
};
class NativeDateModule {
  static {
    this.ɵfac = function NativeDateModule_Factory(t) {
      return new (t || NativeDateModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NativeDateModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: [{
        provide: DateAdapter,
        useClass: NativeDateAdapter
      }]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NativeDateModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      providers: [{
        provide: DateAdapter,
        useClass: NativeDateAdapter
      }]
    }]
  }], null, null);
})();
class MatNativeDateModule {
  static {
    this.ɵfac = function MatNativeDateModule_Factory(t) {
      return new (t || MatNativeDateModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatNativeDateModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: [provideNativeDateAdapter()]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatNativeDateModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      providers: [provideNativeDateAdapter()]
    }]
  }], null, null);
})();
function provideNativeDateAdapter(formats = MAT_NATIVE_DATE_FORMATS) {
  return [{
    provide: DateAdapter,
    useClass: NativeDateAdapter
  }, {
    provide: MAT_DATE_FORMATS,
    useValue: formats
  }];
}

/** Error state matcher that matches when a control is invalid and dirty. */
class ShowOnDirtyErrorStateMatcher {
  isErrorState(control, form) {
    return !!(control && control.invalid && (control.dirty || form && form.submitted));
  }
  static {
    this.ɵfac = function ShowOnDirtyErrorStateMatcher_Factory(t) {
      return new (t || ShowOnDirtyErrorStateMatcher)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ShowOnDirtyErrorStateMatcher,
      factory: ShowOnDirtyErrorStateMatcher.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ShowOnDirtyErrorStateMatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
/** Provider that defines how form controls behave with regards to displaying error messages. */
class ErrorStateMatcher {
  isErrorState(control, form) {
    return !!(control && control.invalid && (control.touched || form && form.submitted));
  }
  static {
    this.ɵfac = function ErrorStateMatcher_Factory(t) {
      return new (t || ErrorStateMatcher)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ErrorStateMatcher,
      factory: ErrorStateMatcher.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ErrorStateMatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * Shared directive to count lines inside a text area, such as a list item.
 * Line elements can be extracted with a @ContentChildren(MatLine) query, then
 * counted by checking the query list's length.
 */
class MatLine {
  static {
    this.ɵfac = function MatLine_Factory(t) {
      return new (t || MatLine)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatLine,
      selectors: [["", "mat-line", ""], ["", "matLine", ""]],
      hostAttrs: [1, "mat-line"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatLine, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[mat-line], [matLine]',
      host: {
        'class': 'mat-line'
      },
      standalone: true
    }]
  }], null, null);
})();
/**
 * Helper that takes a query list of lines and sets the correct class on the host.
 * @docs-private
 */
function setLines(lines, element, prefix = 'mat') {
  // Note: doesn't need to unsubscribe, because `changes`
  // gets completed by Angular when the view is destroyed.
  lines.changes.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.startWith)(lines)).subscribe(({
    length
  }) => {
    setClass(element, `${prefix}-2-line`, false);
    setClass(element, `${prefix}-3-line`, false);
    setClass(element, `${prefix}-multi-line`, false);
    if (length === 2 || length === 3) {
      setClass(element, `${prefix}-${length}-line`, true);
    } else if (length > 3) {
      setClass(element, `${prefix}-multi-line`, true);
    }
  });
}
/** Adds or removes a class from an element. */
function setClass(element, className, isAdd) {
  element.nativeElement.classList.toggle(className, isAdd);
}
class MatLineModule {
  static {
    this.ɵfac = function MatLineModule_Factory(t) {
      return new (t || MatLineModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatLineModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [MatCommonModule, MatCommonModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatLineModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [MatCommonModule, MatLine],
      exports: [MatLine, MatCommonModule]
    }]
  }], null, null);
})();

/** Possible states for a ripple element. */
var RippleState;
(function (RippleState) {
  RippleState[RippleState["FADING_IN"] = 0] = "FADING_IN";
  RippleState[RippleState["VISIBLE"] = 1] = "VISIBLE";
  RippleState[RippleState["FADING_OUT"] = 2] = "FADING_OUT";
  RippleState[RippleState["HIDDEN"] = 3] = "HIDDEN";
})(RippleState || (RippleState = {}));
/**
 * Reference to a previously launched ripple element.
 */
class RippleRef {
  constructor(_renderer, /** Reference to the ripple HTML element. */
  element, /** Ripple configuration used for the ripple. */
  config, /* Whether animations are forcibly disabled for ripples through CSS. */
  _animationForciblyDisabledThroughCss = false) {
    this._renderer = _renderer;
    this.element = element;
    this.config = config;
    this._animationForciblyDisabledThroughCss = _animationForciblyDisabledThroughCss;
    /** Current state of the ripple. */
    this.state = RippleState.HIDDEN;
  }
  /** Fades out the ripple element. */
  fadeOut() {
    this._renderer.fadeOutRipple(this);
  }
}

/** Options used to bind a passive capturing event. */
const passiveCapturingEventOptions$1 = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.normalizePassiveListenerOptions)({
  passive: true,
  capture: true
});
/** Manages events through delegation so that as few event handlers as possible are bound. */
class RippleEventManager {
  constructor() {
    this._events = new Map();
    /** Event handler that is bound and which dispatches the events to the different targets. */
    this._delegateEventHandler = event => {
      const target = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__._getEventTarget)(event);
      if (target) {
        this._events.get(event.type)?.forEach((handlers, element) => {
          if (element === target || element.contains(target)) {
            handlers.forEach(handler => handler.handleEvent(event));
          }
        });
      }
    };
  }
  /** Adds an event handler. */
  addHandler(ngZone, name, element, handler) {
    const handlersForEvent = this._events.get(name);
    if (handlersForEvent) {
      const handlersForElement = handlersForEvent.get(element);
      if (handlersForElement) {
        handlersForElement.add(handler);
      } else {
        handlersForEvent.set(element, new Set([handler]));
      }
    } else {
      this._events.set(name, new Map([[element, new Set([handler])]]));
      ngZone.runOutsideAngular(() => {
        document.addEventListener(name, this._delegateEventHandler, passiveCapturingEventOptions$1);
      });
    }
  }
  /** Removes an event handler. */
  removeHandler(name, element, handler) {
    const handlersForEvent = this._events.get(name);
    if (!handlersForEvent) {
      return;
    }
    const handlersForElement = handlersForEvent.get(element);
    if (!handlersForElement) {
      return;
    }
    handlersForElement.delete(handler);
    if (handlersForElement.size === 0) {
      handlersForEvent.delete(element);
    }
    if (handlersForEvent.size === 0) {
      this._events.delete(name);
      document.removeEventListener(name, this._delegateEventHandler, passiveCapturingEventOptions$1);
    }
  }
}

/**
 * Default ripple animation configuration for ripples without an explicit
 * animation config specified.
 */
const defaultRippleAnimationConfig = {
  enterDuration: 225,
  exitDuration: 150
};
/**
 * Timeout for ignoring mouse events. Mouse events will be temporary ignored after touch
 * events to avoid synthetic mouse events.
 */
const ignoreMouseEventsTimeout = 800;
/** Options used to bind a passive capturing event. */
const passiveCapturingEventOptions = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.normalizePassiveListenerOptions)({
  passive: true,
  capture: true
});
/** Events that signal that the pointer is down. */
const pointerDownEvents = ['mousedown', 'touchstart'];
/** Events that signal that the pointer is up. */
const pointerUpEvents = ['mouseup', 'mouseleave', 'touchend', 'touchcancel'];
/**
 * Helper service that performs DOM manipulations. Not intended to be used outside this module.
 * The constructor takes a reference to the ripple directive's host element and a map of DOM
 * event handlers to be installed on the element that triggers ripple animations.
 * This will eventually become a custom renderer once Angular support exists.
 * @docs-private
 */
class RippleRenderer {
  static {
    this._eventManager = new RippleEventManager();
  }
  constructor(_target, _ngZone, elementOrElementRef, _platform) {
    this._target = _target;
    this._ngZone = _ngZone;
    this._platform = _platform;
    /** Whether the pointer is currently down or not. */
    this._isPointerDown = false;
    /**
     * Map of currently active ripple references.
     * The ripple reference is mapped to its element event listeners.
     * The reason why `| null` is used is that event listeners are added only
     * when the condition is truthy (see the `_startFadeOutTransition` method).
     */
    this._activeRipples = new Map();
    /** Whether pointer-up event listeners have been registered. */
    this._pointerUpEventsRegistered = false;
    // Only do anything if we're on the browser.
    if (_platform.isBrowser) {
      this._containerElement = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__.coerceElement)(elementOrElementRef);
    }
  }
  /**
   * Fades in a ripple at the given coordinates.
   * @param x Coordinate within the element, along the X axis at which to start the ripple.
   * @param y Coordinate within the element, along the Y axis at which to start the ripple.
   * @param config Extra ripple options.
   */
  fadeInRipple(x, y, config = {}) {
    const containerRect = this._containerRect = this._containerRect || this._containerElement.getBoundingClientRect();
    const animationConfig = {
      ...defaultRippleAnimationConfig,
      ...config.animation
    };
    if (config.centered) {
      x = containerRect.left + containerRect.width / 2;
      y = containerRect.top + containerRect.height / 2;
    }
    const radius = config.radius || distanceToFurthestCorner(x, y, containerRect);
    const offsetX = x - containerRect.left;
    const offsetY = y - containerRect.top;
    const enterDuration = animationConfig.enterDuration;
    const ripple = document.createElement('div');
    ripple.classList.add('mat-ripple-element');
    ripple.style.left = `${offsetX - radius}px`;
    ripple.style.top = `${offsetY - radius}px`;
    ripple.style.height = `${radius * 2}px`;
    ripple.style.width = `${radius * 2}px`;
    // If a custom color has been specified, set it as inline style. If no color is
    // set, the default color will be applied through the ripple theme styles.
    if (config.color != null) {
      ripple.style.backgroundColor = config.color;
    }
    ripple.style.transitionDuration = `${enterDuration}ms`;
    this._containerElement.appendChild(ripple);
    // By default the browser does not recalculate the styles of dynamically created
    // ripple elements. This is critical to ensure that the `scale` animates properly.
    // We enforce a style recalculation by calling `getComputedStyle` and *accessing* a property.
    // See: https://gist.github.com/paulirish/5d52fb081b3570c81e3a
    const computedStyles = window.getComputedStyle(ripple);
    const userTransitionProperty = computedStyles.transitionProperty;
    const userTransitionDuration = computedStyles.transitionDuration;
    // Note: We detect whether animation is forcibly disabled through CSS (e.g. through
    // `transition: none` or `display: none`). This is technically unexpected since animations are
    // controlled through the animation config, but this exists for backwards compatibility. This
    // logic does not need to be super accurate since it covers some edge cases which can be easily
    // avoided by users.
    const animationForciblyDisabledThroughCss = userTransitionProperty === 'none' ||
    // Note: The canonical unit for serialized CSS `<time>` properties is seconds. Additionally
    // some browsers expand the duration for every property (in our case `opacity` and `transform`).
    userTransitionDuration === '0s' || userTransitionDuration === '0s, 0s' ||
    // If the container is 0x0, it's likely `display: none`.
    containerRect.width === 0 && containerRect.height === 0;
    // Exposed reference to the ripple that will be returned.
    const rippleRef = new RippleRef(this, ripple, config, animationForciblyDisabledThroughCss);
    // Start the enter animation by setting the transform/scale to 100%. The animation will
    // execute as part of this statement because we forced a style recalculation before.
    // Note: We use a 3d transform here in order to avoid an issue in Safari where
    // the ripples aren't clipped when inside the shadow DOM (see #24028).
    ripple.style.transform = 'scale3d(1, 1, 1)';
    rippleRef.state = RippleState.FADING_IN;
    if (!config.persistent) {
      this._mostRecentTransientRipple = rippleRef;
    }
    let eventListeners = null;
    // Do not register the `transition` event listener if fade-in and fade-out duration
    // are set to zero. The events won't fire anyway and we can save resources here.
    if (!animationForciblyDisabledThroughCss && (enterDuration || animationConfig.exitDuration)) {
      this._ngZone.runOutsideAngular(() => {
        const onTransitionEnd = () => {
          // Clear the fallback timer since the transition fired correctly.
          if (eventListeners) {
            eventListeners.fallbackTimer = null;
          }
          clearTimeout(fallbackTimer);
          this._finishRippleTransition(rippleRef);
        };
        const onTransitionCancel = () => this._destroyRipple(rippleRef);
        // In some cases where there's a higher load on the browser, it can choose not to dispatch
        // neither `transitionend` nor `transitioncancel` (see b/227356674). This timer serves as a
        // fallback for such cases so that the ripple doesn't become stuck. We add a 100ms buffer
        // because timers aren't precise. Note that another approach can be to transition the ripple
        // to the `VISIBLE` state immediately above and to `FADING_IN` afterwards inside
        // `transitionstart`. We go with the timer because it's one less event listener and
        // it's less likely to break existing tests.
        const fallbackTimer = setTimeout(onTransitionCancel, enterDuration + 100);
        ripple.addEventListener('transitionend', onTransitionEnd);
        // If the transition is cancelled (e.g. due to DOM removal), we destroy the ripple
        // directly as otherwise we would keep it part of the ripple container forever.
        // https://www.w3.org/TR/css-transitions-1/#:~:text=no%20longer%20in%20the%20document.
        ripple.addEventListener('transitioncancel', onTransitionCancel);
        eventListeners = {
          onTransitionEnd,
          onTransitionCancel,
          fallbackTimer
        };
      });
    }
    // Add the ripple reference to the list of all active ripples.
    this._activeRipples.set(rippleRef, eventListeners);
    // In case there is no fade-in transition duration, we need to manually call the transition
    // end listener because `transitionend` doesn't fire if there is no transition.
    if (animationForciblyDisabledThroughCss || !enterDuration) {
      this._finishRippleTransition(rippleRef);
    }
    return rippleRef;
  }
  /** Fades out a ripple reference. */
  fadeOutRipple(rippleRef) {
    // For ripples already fading out or hidden, this should be a noop.
    if (rippleRef.state === RippleState.FADING_OUT || rippleRef.state === RippleState.HIDDEN) {
      return;
    }
    const rippleEl = rippleRef.element;
    const animationConfig = {
      ...defaultRippleAnimationConfig,
      ...rippleRef.config.animation
    };
    // This starts the fade-out transition and will fire the transition end listener that
    // removes the ripple element from the DOM.
    rippleEl.style.transitionDuration = `${animationConfig.exitDuration}ms`;
    rippleEl.style.opacity = '0';
    rippleRef.state = RippleState.FADING_OUT;
    // In case there is no fade-out transition duration, we need to manually call the
    // transition end listener because `transitionend` doesn't fire if there is no transition.
    if (rippleRef._animationForciblyDisabledThroughCss || !animationConfig.exitDuration) {
      this._finishRippleTransition(rippleRef);
    }
  }
  /** Fades out all currently active ripples. */
  fadeOutAll() {
    this._getActiveRipples().forEach(ripple => ripple.fadeOut());
  }
  /** Fades out all currently active non-persistent ripples. */
  fadeOutAllNonPersistent() {
    this._getActiveRipples().forEach(ripple => {
      if (!ripple.config.persistent) {
        ripple.fadeOut();
      }
    });
  }
  /** Sets up the trigger event listeners */
  setupTriggerEvents(elementOrElementRef) {
    const element = (0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__.coerceElement)(elementOrElementRef);
    if (!this._platform.isBrowser || !element || element === this._triggerElement) {
      return;
    }
    // Remove all previously registered event listeners from the trigger element.
    this._removeTriggerEvents();
    this._triggerElement = element;
    // Use event delegation for the trigger events since they're
    // set up during creation and are performance-sensitive.
    pointerDownEvents.forEach(type => {
      RippleRenderer._eventManager.addHandler(this._ngZone, type, element, this);
    });
  }
  /**
   * Handles all registered events.
   * @docs-private
   */
  handleEvent(event) {
    if (event.type === 'mousedown') {
      this._onMousedown(event);
    } else if (event.type === 'touchstart') {
      this._onTouchStart(event);
    } else {
      this._onPointerUp();
    }
    // If pointer-up events haven't been registered yet, do so now.
    // We do this on-demand in order to reduce the total number of event listeners
    // registered by the ripples, which speeds up the rendering time for large UIs.
    if (!this._pointerUpEventsRegistered) {
      // The events for hiding the ripple are bound directly on the trigger, because:
      // 1. Some of them occur frequently (e.g. `mouseleave`) and any advantage we get from
      // delegation will be diminished by having to look through all the data structures often.
      // 2. They aren't as performance-sensitive, because they're bound only after the user
      // has interacted with an element.
      this._ngZone.runOutsideAngular(() => {
        pointerUpEvents.forEach(type => {
          this._triggerElement.addEventListener(type, this, passiveCapturingEventOptions);
        });
      });
      this._pointerUpEventsRegistered = true;
    }
  }
  /** Method that will be called if the fade-in or fade-in transition completed. */
  _finishRippleTransition(rippleRef) {
    if (rippleRef.state === RippleState.FADING_IN) {
      this._startFadeOutTransition(rippleRef);
    } else if (rippleRef.state === RippleState.FADING_OUT) {
      this._destroyRipple(rippleRef);
    }
  }
  /**
   * Starts the fade-out transition of the given ripple if it's not persistent and the pointer
   * is not held down anymore.
   */
  _startFadeOutTransition(rippleRef) {
    const isMostRecentTransientRipple = rippleRef === this._mostRecentTransientRipple;
    const {
      persistent
    } = rippleRef.config;
    rippleRef.state = RippleState.VISIBLE;
    // When the timer runs out while the user has kept their pointer down, we want to
    // keep only the persistent ripples and the latest transient ripple. We do this,
    // because we don't want stacked transient ripples to appear after their enter
    // animation has finished.
    if (!persistent && (!isMostRecentTransientRipple || !this._isPointerDown)) {
      rippleRef.fadeOut();
    }
  }
  /** Destroys the given ripple by removing it from the DOM and updating its state. */
  _destroyRipple(rippleRef) {
    const eventListeners = this._activeRipples.get(rippleRef) ?? null;
    this._activeRipples.delete(rippleRef);
    // Clear out the cached bounding rect if we have no more ripples.
    if (!this._activeRipples.size) {
      this._containerRect = null;
    }
    // If the current ref is the most recent transient ripple, unset it
    // avoid memory leaks.
    if (rippleRef === this._mostRecentTransientRipple) {
      this._mostRecentTransientRipple = null;
    }
    rippleRef.state = RippleState.HIDDEN;
    if (eventListeners !== null) {
      rippleRef.element.removeEventListener('transitionend', eventListeners.onTransitionEnd);
      rippleRef.element.removeEventListener('transitioncancel', eventListeners.onTransitionCancel);
      if (eventListeners.fallbackTimer !== null) {
        clearTimeout(eventListeners.fallbackTimer);
      }
    }
    rippleRef.element.remove();
  }
  /** Function being called whenever the trigger is being pressed using mouse. */
  _onMousedown(event) {
    // Screen readers will fire fake mouse events for space/enter. Skip launching a
    // ripple in this case for consistency with the non-screen-reader experience.
    const isFakeMousedown = (0,_angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_2__.isFakeMousedownFromScreenReader)(event);
    const isSyntheticEvent = this._lastTouchStartEvent && Date.now() < this._lastTouchStartEvent + ignoreMouseEventsTimeout;
    if (!this._target.rippleDisabled && !isFakeMousedown && !isSyntheticEvent) {
      this._isPointerDown = true;
      this.fadeInRipple(event.clientX, event.clientY, this._target.rippleConfig);
    }
  }
  /** Function being called whenever the trigger is being pressed using touch. */
  _onTouchStart(event) {
    if (!this._target.rippleDisabled && !(0,_angular_cdk_a11y__WEBPACK_IMPORTED_MODULE_2__.isFakeTouchstartFromScreenReader)(event)) {
      // Some browsers fire mouse events after a `touchstart` event. Those synthetic mouse
      // events will launch a second ripple if we don't ignore mouse events for a specific
      // time after a touchstart event.
      this._lastTouchStartEvent = Date.now();
      this._isPointerDown = true;
      // Use `changedTouches` so we skip any touches where the user put
      // their finger down, but used another finger to tap the element again.
      const touches = event.changedTouches;
      // According to the typings the touches should always be defined, but in some cases
      // the browser appears to not assign them in tests which leads to flakes.
      if (touches) {
        for (let i = 0; i < touches.length; i++) {
          this.fadeInRipple(touches[i].clientX, touches[i].clientY, this._target.rippleConfig);
        }
      }
    }
  }
  /** Function being called whenever the trigger is being released. */
  _onPointerUp() {
    if (!this._isPointerDown) {
      return;
    }
    this._isPointerDown = false;
    // Fade-out all ripples that are visible and not persistent.
    this._getActiveRipples().forEach(ripple => {
      // By default, only ripples that are completely visible will fade out on pointer release.
      // If the `terminateOnPointerUp` option is set, ripples that still fade in will also fade out.
      const isVisible = ripple.state === RippleState.VISIBLE || ripple.config.terminateOnPointerUp && ripple.state === RippleState.FADING_IN;
      if (!ripple.config.persistent && isVisible) {
        ripple.fadeOut();
      }
    });
  }
  _getActiveRipples() {
    return Array.from(this._activeRipples.keys());
  }
  /** Removes previously registered event listeners from the trigger element. */
  _removeTriggerEvents() {
    const trigger = this._triggerElement;
    if (trigger) {
      pointerDownEvents.forEach(type => RippleRenderer._eventManager.removeHandler(type, trigger, this));
      if (this._pointerUpEventsRegistered) {
        pointerUpEvents.forEach(type => trigger.removeEventListener(type, this, passiveCapturingEventOptions));
        this._pointerUpEventsRegistered = false;
      }
    }
  }
}
/**
 * Returns the distance from the point (x, y) to the furthest corner of a rectangle.
 */
function distanceToFurthestCorner(x, y, rect) {
  const distX = Math.max(Math.abs(x - rect.left), Math.abs(x - rect.right));
  const distY = Math.max(Math.abs(y - rect.top), Math.abs(y - rect.bottom));
  return Math.sqrt(distX * distX + distY * distY);
}

/** Injection token that can be used to specify the global ripple options. */
const MAT_RIPPLE_GLOBAL_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('mat-ripple-global-options');
class MatRipple {
  /**
   * Whether click events will not trigger the ripple. Ripples can be still launched manually
   * by using the `launch()` method.
   */
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    if (value) {
      this.fadeOutAllNonPersistent();
    }
    this._disabled = value;
    this._setupTriggerEventsIfEnabled();
  }
  /**
   * The element that triggers the ripple when click events are received.
   * Defaults to the directive's host element.
   */
  get trigger() {
    return this._trigger || this._elementRef.nativeElement;
  }
  set trigger(trigger) {
    this._trigger = trigger;
    this._setupTriggerEventsIfEnabled();
  }
  constructor(_elementRef, ngZone, platform, globalOptions, _animationMode) {
    this._elementRef = _elementRef;
    this._animationMode = _animationMode;
    /**
     * If set, the radius in pixels of foreground ripples when fully expanded. If unset, the radius
     * will be the distance from the center of the ripple to the furthest corner of the host element's
     * bounding rectangle.
     */
    this.radius = 0;
    this._disabled = false;
    /** @docs-private Whether ripple directive is initialized and the input bindings are set. */
    this._isInitialized = false;
    this._globalOptions = globalOptions || {};
    this._rippleRenderer = new RippleRenderer(this, ngZone, _elementRef, platform);
  }
  ngOnInit() {
    this._isInitialized = true;
    this._setupTriggerEventsIfEnabled();
  }
  ngOnDestroy() {
    this._rippleRenderer._removeTriggerEvents();
  }
  /** Fades out all currently showing ripple elements. */
  fadeOutAll() {
    this._rippleRenderer.fadeOutAll();
  }
  /** Fades out all currently showing non-persistent ripple elements. */
  fadeOutAllNonPersistent() {
    this._rippleRenderer.fadeOutAllNonPersistent();
  }
  /**
   * Ripple configuration from the directive's input values.
   * @docs-private Implemented as part of RippleTarget
   */
  get rippleConfig() {
    return {
      centered: this.centered,
      radius: this.radius,
      color: this.color,
      animation: {
        ...this._globalOptions.animation,
        ...(this._animationMode === 'NoopAnimations' ? {
          enterDuration: 0,
          exitDuration: 0
        } : {}),
        ...this.animation
      },
      terminateOnPointerUp: this._globalOptions.terminateOnPointerUp
    };
  }
  /**
   * Whether ripples on pointer-down are disabled or not.
   * @docs-private Implemented as part of RippleTarget
   */
  get rippleDisabled() {
    return this.disabled || !!this._globalOptions.disabled;
  }
  /** Sets up the trigger event listeners if ripples are enabled. */
  _setupTriggerEventsIfEnabled() {
    if (!this.disabled && this._isInitialized) {
      this._rippleRenderer.setupTriggerEvents(this.trigger);
    }
  }
  /** Launches a manual ripple at the specified coordinated or just by the ripple config. */
  launch(configOrX, y = 0, config) {
    if (typeof configOrX === 'number') {
      return this._rippleRenderer.fadeInRipple(configOrX, y, {
        ...this.rippleConfig,
        ...config
      });
    } else {
      return this._rippleRenderer.fadeInRipple(0, 0, {
        ...this.rippleConfig,
        ...configOrX
      });
    }
  }
  static {
    this.ɵfac = function MatRipple_Factory(t) {
      return new (t || MatRipple)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](MAT_RIPPLE_GLOBAL_OPTIONS, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatRipple,
      selectors: [["", "mat-ripple", ""], ["", "matRipple", ""]],
      hostAttrs: [1, "mat-ripple"],
      hostVars: 2,
      hostBindings: function MatRipple_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mat-ripple-unbounded", ctx.unbounded);
        }
      },
      inputs: {
        color: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleColor", "color"],
        unbounded: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleUnbounded", "unbounded"],
        centered: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleCentered", "centered"],
        radius: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleRadius", "radius"],
        animation: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleAnimation", "animation"],
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleDisabled", "disabled"],
        trigger: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRippleTrigger", "trigger"]
      },
      exportAs: ["matRipple"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRipple, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[mat-ripple], [matRipple]',
      exportAs: 'matRipple',
      host: {
        'class': 'mat-ripple',
        '[class.mat-ripple-unbounded]': 'unbounded'
      },
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MAT_RIPPLE_GLOBAL_OPTIONS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE]
    }]
  }], {
    color: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleColor']
    }],
    unbounded: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleUnbounded']
    }],
    centered: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleCentered']
    }],
    radius: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleRadius']
    }],
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleAnimation']
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleDisabled']
    }],
    trigger: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matRippleTrigger']
    }]
  });
})();
class MatRippleModule {
  static {
    this.ɵfac = function MatRippleModule_Factory(t) {
      return new (t || MatRippleModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatRippleModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [MatCommonModule, MatCommonModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRippleModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [MatCommonModule, MatRipple],
      exports: [MatRipple, MatCommonModule]
    }]
  }], null, null);
})();

/**
 * Component that shows a simplified checkbox without including any kind of "real" checkbox.
 * Meant to be used when the checkbox is purely decorative and a large number of them will be
 * included, such as for the options in a multi-select. Uses no SVGs or complex animations.
 * Note that theming is meant to be handled by the parent element, e.g.
 * `mat-primary .mat-pseudo-checkbox`.
 *
 * Note that this component will be completely invisible to screen-reader users. This is *not*
 * interchangeable with `<mat-checkbox>` and should *not* be used if the user would directly
 * interact with the checkbox. The pseudo-checkbox should only be used as an implementation detail
 * of more complex components that appropriately handle selected / checked state.
 * @docs-private
 */
class MatPseudoCheckbox {
  constructor(_animationMode) {
    this._animationMode = _animationMode;
    /** Display state of the checkbox. */
    this.state = 'unchecked';
    /** Whether the checkbox is disabled. */
    this.disabled = false;
    /**
     * Appearance of the pseudo checkbox. Default appearance of 'full' renders a checkmark/mixedmark
     * indicator inside a square box. 'minimal' appearance only renders the checkmark/mixedmark.
     */
    this.appearance = 'full';
  }
  static {
    this.ɵfac = function MatPseudoCheckbox_Factory(t) {
      return new (t || MatPseudoCheckbox)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatPseudoCheckbox,
      selectors: [["mat-pseudo-checkbox"]],
      hostAttrs: [1, "mat-pseudo-checkbox"],
      hostVars: 12,
      hostBindings: function MatPseudoCheckbox_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mat-pseudo-checkbox-indeterminate", ctx.state === "indeterminate")("mat-pseudo-checkbox-checked", ctx.state === "checked")("mat-pseudo-checkbox-disabled", ctx.disabled)("mat-pseudo-checkbox-minimal", ctx.appearance === "minimal")("mat-pseudo-checkbox-full", ctx.appearance === "full")("_mat-animation-noopable", ctx._animationMode === "NoopAnimations");
        }
      },
      inputs: {
        state: "state",
        disabled: "disabled",
        appearance: "appearance"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 0,
      vars: 0,
      template: function MatPseudoCheckbox_Template(rf, ctx) {},
      styles: [".mat-pseudo-checkbox{border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0, 0, 0.2, 0.1),background-color 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:\"\";border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox._mat-animation-noopable{transition:none !important;animation:none !important}.mat-pseudo-checkbox._mat-animation-noopable::after{transition:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{left:1px;opacity:1;border-radius:2px}.mat-pseudo-checkbox-checked::after{left:1px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1;box-sizing:content-box}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked::after,.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate::after{color:var(--mat-minimal-pseudo-checkbox-selected-checkmark-color, var(--mat-app-primary))}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled::after,.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled::after{color:var(--mat-minimal-pseudo-checkbox-disabled-selected-checkmark-color)}.mat-pseudo-checkbox-full{border-color:var(--mat-full-pseudo-checkbox-unselected-icon-color, var(--mat-app-on-surface-variant));border-width:2px;border-style:solid}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-disabled{border-color:var(--mat-full-pseudo-checkbox-disabled-unselected-icon-color)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate{background-color:var(--mat-full-pseudo-checkbox-selected-icon-color, var(--mat-app-primary));border-color:rgba(0,0,0,0)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked::after,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate::after{color:var(--mat-full-pseudo-checkbox-selected-checkmark-color, var(--mat-app-on-primary))}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background-color:var(--mat-full-pseudo-checkbox-disabled-selected-icon-color)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled::after,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled::after{color:var(--mat-full-pseudo-checkbox-disabled-selected-checkmark-color, var(--mat-app-surface))}.mat-pseudo-checkbox{width:18px;height:18px}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked::after{width:14px;height:6px;transform-origin:center;top:-4.2426406871px;left:0;bottom:0;right:0;margin:auto}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate::after{top:8px;width:16px}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked::after{width:10px;height:4px;transform-origin:center;top:-2.8284271247px;left:0;bottom:0;right:0;margin:auto}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate::after{top:6px;width:12px}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatPseudoCheckbox, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      selector: 'mat-pseudo-checkbox',
      template: '',
      host: {
        'class': 'mat-pseudo-checkbox',
        '[class.mat-pseudo-checkbox-indeterminate]': 'state === "indeterminate"',
        '[class.mat-pseudo-checkbox-checked]': 'state === "checked"',
        '[class.mat-pseudo-checkbox-disabled]': 'disabled',
        '[class.mat-pseudo-checkbox-minimal]': 'appearance === "minimal"',
        '[class.mat-pseudo-checkbox-full]': 'appearance === "full"',
        '[class._mat-animation-noopable]': '_animationMode === "NoopAnimations"'
      },
      standalone: true,
      styles: [".mat-pseudo-checkbox{border-radius:2px;cursor:pointer;display:inline-block;vertical-align:middle;box-sizing:border-box;position:relative;flex-shrink:0;transition:border-color 90ms cubic-bezier(0, 0, 0.2, 0.1),background-color 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox::after{position:absolute;opacity:0;content:\"\";border-bottom:2px solid currentColor;transition:opacity 90ms cubic-bezier(0, 0, 0.2, 0.1)}.mat-pseudo-checkbox._mat-animation-noopable{transition:none !important;animation:none !important}.mat-pseudo-checkbox._mat-animation-noopable::after{transition:none}.mat-pseudo-checkbox-disabled{cursor:default}.mat-pseudo-checkbox-indeterminate::after{left:1px;opacity:1;border-radius:2px}.mat-pseudo-checkbox-checked::after{left:1px;border-left:2px solid currentColor;transform:rotate(-45deg);opacity:1;box-sizing:content-box}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked::after,.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate::after{color:var(--mat-minimal-pseudo-checkbox-selected-checkmark-color, var(--mat-app-primary))}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled::after,.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled::after{color:var(--mat-minimal-pseudo-checkbox-disabled-selected-checkmark-color)}.mat-pseudo-checkbox-full{border-color:var(--mat-full-pseudo-checkbox-unselected-icon-color, var(--mat-app-on-surface-variant));border-width:2px;border-style:solid}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-disabled{border-color:var(--mat-full-pseudo-checkbox-disabled-unselected-icon-color)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate{background-color:var(--mat-full-pseudo-checkbox-selected-icon-color, var(--mat-app-primary));border-color:rgba(0,0,0,0)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked::after,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate::after{color:var(--mat-full-pseudo-checkbox-selected-checkmark-color, var(--mat-app-on-primary))}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled{background-color:var(--mat-full-pseudo-checkbox-disabled-selected-icon-color)}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked.mat-pseudo-checkbox-disabled::after,.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate.mat-pseudo-checkbox-disabled::after{color:var(--mat-full-pseudo-checkbox-disabled-selected-checkmark-color, var(--mat-app-surface))}.mat-pseudo-checkbox{width:18px;height:18px}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-checked::after{width:14px;height:6px;transform-origin:center;top:-4.2426406871px;left:0;bottom:0;right:0;margin:auto}.mat-pseudo-checkbox-minimal.mat-pseudo-checkbox-indeterminate::after{top:8px;width:16px}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-checked::after{width:10px;height:4px;transform-origin:center;top:-2.8284271247px;left:0;bottom:0;right:0;margin:auto}.mat-pseudo-checkbox-full.mat-pseudo-checkbox-indeterminate::after{top:6px;width:12px}"]
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE]
    }]
  }], {
    state: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    appearance: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class MatPseudoCheckboxModule {
  static {
    this.ɵfac = function MatPseudoCheckboxModule_Factory(t) {
      return new (t || MatPseudoCheckboxModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatPseudoCheckboxModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [MatCommonModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatPseudoCheckboxModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [MatCommonModule, MatPseudoCheckbox],
      exports: [MatPseudoCheckbox]
    }]
  }], null, null);
})();

/**
 * Injection token used to provide the parent component to options.
 */
const MAT_OPTION_PARENT_COMPONENT = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('MAT_OPTION_PARENT_COMPONENT');

// Notes on the accessibility pattern used for `mat-optgroup`.
// The option group has two different "modes": regular and inert. The regular mode uses the
// recommended a11y pattern which has `role="group"` on the group element with `aria-labelledby`
// pointing to the label. This works for `mat-select`, but it seems to hit a bug for autocomplete
// under VoiceOver where the group doesn't get read out at all. The bug appears to be that if
// there's __any__ a11y-related attribute on the group (e.g. `role` or `aria-labelledby`),
// VoiceOver on Safari won't read it out.
// We've introduced the `inert` mode as a workaround. Under this mode, all a11y attributes are
// removed from the group, and we get the screen reader to read out the group label by mirroring it
// inside an invisible element in the option. This is sub-optimal, because the screen reader will
// repeat the group label on each navigation, whereas the default pattern only reads the group when
// the user enters a new group. The following alternate approaches were considered:
// 1. Reading out the group label using the `LiveAnnouncer` solves the problem, but we can't control
//    when the text will be read out so sometimes it comes in too late or never if the user
//    navigates quickly.
// 2. `<mat-option aria-describedby="groupLabel"` - This works on Safari, but VoiceOver in Chrome
//    won't read out the description at all.
// 3. `<mat-option aria-labelledby="optionLabel groupLabel"` - This works on Chrome, but Safari
//     doesn't read out the text at all. Furthermore, on
// Counter for unique group ids.
let _uniqueOptgroupIdCounter = 0;
/**
 * Injection token that can be used to reference instances of `MatOptgroup`. It serves as
 * alternative token to the actual `MatOptgroup` class which could cause unnecessary
 * retention of the class and its component metadata.
 */
const MAT_OPTGROUP = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('MatOptgroup');
/**
 * Component that is used to group instances of `mat-option`.
 */
class MatOptgroup {
  constructor(parent) {
    /** whether the option group is disabled. */
    this.disabled = false;
    /** Unique id for the underlying label. */
    this._labelId = `mat-optgroup-label-${_uniqueOptgroupIdCounter++}`;
    this._inert = parent?.inertGroups ?? false;
  }
  static {
    this.ɵfac = function MatOptgroup_Factory(t) {
      return new (t || MatOptgroup)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](MAT_OPTION_PARENT_COMPONENT, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatOptgroup,
      selectors: [["mat-optgroup"]],
      hostAttrs: [1, "mat-mdc-optgroup"],
      hostVars: 3,
      hostBindings: function MatOptgroup_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("role", ctx._inert ? null : "group")("aria-disabled", ctx._inert ? null : ctx.disabled.toString())("aria-labelledby", ctx._inert ? null : ctx._labelId);
        }
      },
      inputs: {
        label: "label",
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "disabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      exportAs: ["matOptgroup"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: MAT_OPTGROUP,
        useExisting: MatOptgroup
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c1,
      decls: 5,
      vars: 4,
      consts: [["role", "presentation", 1, "mat-mdc-optgroup-label", 3, "id"], [1, "mdc-list-item__primary-text"]],
      template: function MatOptgroup_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"](_c0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 0)(1, "span", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](4, 1);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mdc-list-item--disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", ctx._labelId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"]("", ctx.label, " ");
        }
      },
      styles: [".mat-mdc-optgroup{color:var(--mat-optgroup-label-text-color, var(--mat-app-on-surface-variant));font-family:var(--mat-optgroup-label-text-font, var(--mat-app-title-small-font));line-height:var(--mat-optgroup-label-text-line-height, var(--mat-app-title-small-line-height));font-size:var(--mat-optgroup-label-text-size, var(--mat-app-title-small-size));letter-spacing:var(--mat-optgroup-label-text-tracking, var(--mat-app-title-small-tracking));font-weight:var(--mat-optgroup-label-text-weight, var(--mat-app-title-small-weight))}.mat-mdc-optgroup-label{display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;min-height:48px;padding:0 16px;outline:none}.mat-mdc-optgroup-label.mdc-list-item--disabled{opacity:.38}.mat-mdc-optgroup-label .mdc-list-item__primary-text{font-size:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;font-family:inherit;text-decoration:inherit;text-transform:inherit;white-space:normal}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatOptgroup, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-optgroup',
      exportAs: 'matOptgroup',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      host: {
        'class': 'mat-mdc-optgroup',
        '[attr.role]': '_inert ? null : "group"',
        '[attr.aria-disabled]': '_inert ? null : disabled.toString()',
        '[attr.aria-labelledby]': '_inert ? null : _labelId'
      },
      providers: [{
        provide: MAT_OPTGROUP,
        useExisting: MatOptgroup
      }],
      standalone: true,
      template: "<span\n  class=\"mat-mdc-optgroup-label\"\n  role=\"presentation\"\n  [class.mdc-list-item--disabled]=\"disabled\"\n  [id]=\"_labelId\">\n  <span class=\"mdc-list-item__primary-text\">{{ label }} <ng-content></ng-content></span>\n</span>\n\n<ng-content select=\"mat-option, ng-container\"></ng-content>\n",
      styles: [".mat-mdc-optgroup{color:var(--mat-optgroup-label-text-color, var(--mat-app-on-surface-variant));font-family:var(--mat-optgroup-label-text-font, var(--mat-app-title-small-font));line-height:var(--mat-optgroup-label-text-line-height, var(--mat-app-title-small-line-height));font-size:var(--mat-optgroup-label-text-size, var(--mat-app-title-small-size));letter-spacing:var(--mat-optgroup-label-text-tracking, var(--mat-app-title-small-tracking));font-weight:var(--mat-optgroup-label-text-weight, var(--mat-app-title-small-weight))}.mat-mdc-optgroup-label{display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;min-height:48px;padding:0 16px;outline:none}.mat-mdc-optgroup-label.mdc-list-item--disabled{opacity:.38}.mat-mdc-optgroup-label .mdc-list-item__primary-text{font-size:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;font-family:inherit;text-decoration:inherit;text-transform:inherit;white-space:normal}"]
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MAT_OPTION_PARENT_COMPONENT]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], {
    label: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }]
  });
})();

/**
 * Option IDs need to be unique across components, so this counter exists outside of
 * the component definition.
 */
let _uniqueIdCounter = 0;
/** Event object emitted by MatOption when selected or deselected. */
class MatOptionSelectionChange {
  constructor(/** Reference to the option that emitted the event. */
  source, /** Whether the change in the option's value was a result of a user action. */
  isUserInput = false) {
    this.source = source;
    this.isUserInput = isUserInput;
  }
}
/**
 * Single option inside of a `<mat-select>` element.
 */
class MatOption {
  /** Whether the wrapping component is in multiple selection mode. */
  get multiple() {
    return this._parent && this._parent.multiple;
  }
  /** Whether or not the option is currently selected. */
  get selected() {
    return this._selected;
  }
  /** Whether the option is disabled. */
  get disabled() {
    return this.group && this.group.disabled || this._disabled;
  }
  set disabled(value) {
    this._disabled = value;
  }
  /** Whether ripples for the option are disabled. */
  get disableRipple() {
    return !!(this._parent && this._parent.disableRipple);
  }
  /** Whether to display checkmark for single-selection. */
  get hideSingleSelectionIndicator() {
    return !!(this._parent && this._parent.hideSingleSelectionIndicator);
  }
  constructor(_element, _changeDetectorRef, _parent, group) {
    this._element = _element;
    this._changeDetectorRef = _changeDetectorRef;
    this._parent = _parent;
    this.group = group;
    this._selected = false;
    this._active = false;
    this._disabled = false;
    this._mostRecentViewValue = '';
    /** The unique ID of the option. */
    this.id = `mat-option-${_uniqueIdCounter++}`;
    /** Event emitted when the option is selected or deselected. */
    // tslint:disable-next-line:no-output-on-prefix
    this.onSelectionChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /** Emits when the state of the option changes and any parents have to be notified. */
    this._stateChanges = new rxjs__WEBPACK_IMPORTED_MODULE_8__.Subject();
  }
  /**
   * Whether or not the option is currently active and ready to be selected.
   * An active option displays styles as if it is focused, but the
   * focus is actually retained somewhere else. This comes in handy
   * for components like autocomplete where focus must remain on the input.
   */
  get active() {
    return this._active;
  }
  /**
   * The displayed value of the option. It is necessary to show the selected option in the
   * select's trigger.
   */
  get viewValue() {
    // TODO(kara): Add input property alternative for node envs.
    return (this._text?.nativeElement.textContent || '').trim();
  }
  /** Selects the option. */
  select(emitEvent = true) {
    if (!this._selected) {
      this._selected = true;
      this._changeDetectorRef.markForCheck();
      if (emitEvent) {
        this._emitSelectionChangeEvent();
      }
    }
  }
  /** Deselects the option. */
  deselect(emitEvent = true) {
    if (this._selected) {
      this._selected = false;
      this._changeDetectorRef.markForCheck();
      if (emitEvent) {
        this._emitSelectionChangeEvent();
      }
    }
  }
  /** Sets focus onto this option. */
  focus(_origin, options) {
    // Note that we aren't using `_origin`, but we need to keep it because some internal consumers
    // use `MatOption` in a `FocusKeyManager` and we need it to match `FocusableOption`.
    const element = this._getHostElement();
    if (typeof element.focus === 'function') {
      element.focus(options);
    }
  }
  /**
   * This method sets display styles on the option to make it appear
   * active. This is used by the ActiveDescendantKeyManager so key
   * events will display the proper options as active on arrow key events.
   */
  setActiveStyles() {
    if (!this._active) {
      this._active = true;
      this._changeDetectorRef.markForCheck();
    }
  }
  /**
   * This method removes display styles on the option that made it appear
   * active. This is used by the ActiveDescendantKeyManager so key
   * events will display the proper options as active on arrow key events.
   */
  setInactiveStyles() {
    if (this._active) {
      this._active = false;
      this._changeDetectorRef.markForCheck();
    }
  }
  /** Gets the label to be used when determining whether the option should be focused. */
  getLabel() {
    return this.viewValue;
  }
  /** Ensures the option is selected when activated from the keyboard. */
  _handleKeydown(event) {
    if ((event.keyCode === _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_10__.ENTER || event.keyCode === _angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_10__.SPACE) && !(0,_angular_cdk_keycodes__WEBPACK_IMPORTED_MODULE_10__.hasModifierKey)(event)) {
      this._selectViaInteraction();
      // Prevent the page from scrolling down and form submits.
      event.preventDefault();
    }
  }
  /**
   * `Selects the option while indicating the selection came from the user. Used to
   * determine if the select's view -> model callback should be invoked.`
   */
  _selectViaInteraction() {
    if (!this.disabled) {
      this._selected = this.multiple ? !this._selected : true;
      this._changeDetectorRef.markForCheck();
      this._emitSelectionChangeEvent(true);
    }
  }
  /** Returns the correct tabindex for the option depending on disabled state. */
  // This method is only used by `MatLegacyOption`. Keeping it here to avoid breaking the types.
  // That's because `MatLegacyOption` use `MatOption` type in a few places such as
  // `MatOptionSelectionChange`. It is safe to delete this when `MatLegacyOption` is deleted.
  _getTabIndex() {
    return this.disabled ? '-1' : '0';
  }
  /** Gets the host DOM element. */
  _getHostElement() {
    return this._element.nativeElement;
  }
  ngAfterViewChecked() {
    // Since parent components could be using the option's label to display the selected values
    // (e.g. `mat-select`) and they don't have a way of knowing if the option's label has changed
    // we have to check for changes in the DOM ourselves and dispatch an event. These checks are
    // relatively cheap, however we still limit them only to selected options in order to avoid
    // hitting the DOM too often.
    if (this._selected) {
      const viewValue = this.viewValue;
      if (viewValue !== this._mostRecentViewValue) {
        if (this._mostRecentViewValue) {
          this._stateChanges.next();
        }
        this._mostRecentViewValue = viewValue;
      }
    }
  }
  ngOnDestroy() {
    this._stateChanges.complete();
  }
  /** Emits the selection change event. */
  _emitSelectionChangeEvent(isUserInput = false) {
    this.onSelectionChange.emit(new MatOptionSelectionChange(this, isUserInput));
  }
  static {
    this.ɵfac = function MatOption_Factory(t) {
      return new (t || MatOption)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](MAT_OPTION_PARENT_COMPONENT, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](MAT_OPTGROUP, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatOption,
      selectors: [["mat-option"]],
      viewQuery: function MatOption_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c2, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._text = _t.first);
        }
      },
      hostAttrs: ["role", "option", 1, "mat-mdc-option", "mdc-list-item"],
      hostVars: 11,
      hostBindings: function MatOption_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function MatOption_click_HostBindingHandler() {
            return ctx._selectViaInteraction();
          })("keydown", function MatOption_keydown_HostBindingHandler($event) {
            return ctx._handleKeydown($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-selected", ctx.selected)("aria-disabled", ctx.disabled.toString());
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mdc-list-item--selected", ctx.selected)("mat-mdc-option-multiple", ctx.multiple)("mat-mdc-option-active", ctx.active)("mdc-list-item--disabled", ctx.disabled);
        }
      },
      inputs: {
        value: "value",
        id: "id",
        disabled: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "disabled", "disabled", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      outputs: {
        onSelectionChange: "onSelectionChange"
      },
      exportAs: ["matOption"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c4,
      decls: 8,
      vars: 5,
      consts: [["text", ""], ["aria-hidden", "true", 1, "mat-mdc-option-pseudo-checkbox", 3, "disabled", "state"], [1, "mdc-list-item__primary-text"], ["state", "checked", "aria-hidden", "true", "appearance", "minimal", 1, "mat-mdc-option-pseudo-checkbox", 3, "disabled"], [1, "cdk-visually-hidden"], ["aria-hidden", "true", "mat-ripple", "", 1, "mat-mdc-option-ripple", "mat-mdc-focus-indicator", 3, "matRippleTrigger", "matRippleDisabled"]],
      template: function MatOption_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"](_c3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, MatOption_Conditional_0_Template, 1, 2, "mat-pseudo-checkbox", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 2, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](4, 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](5, MatOption_Conditional_5_Template, 1, 1, "mat-pseudo-checkbox", 3)(6, MatOption_Conditional_6_Template, 2, 1, "span", 4);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](7, "div", 5);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, ctx.multiple ? 0 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](5, !ctx.multiple && ctx.selected && !ctx.hideSingleSelectionIndicator ? 5 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](6, ctx.group && ctx.group._inert ? 6 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("matRippleTrigger", ctx._getHostElement())("matRippleDisabled", ctx.disabled || ctx.disableRipple);
        }
      },
      dependencies: [MatPseudoCheckbox, MatRipple],
      styles: [".mat-mdc-option{-webkit-user-select:none;user-select:none;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;min-height:48px;padding:0 16px;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);color:var(--mat-option-label-text-color, var(--mat-app-on-surface));font-family:var(--mat-option-label-text-font, var(--mat-app-label-large-font));line-height:var(--mat-option-label-text-line-height, var(--mat-app-label-large-line-height));font-size:var(--mat-option-label-text-size, var(--mat-app-body-large-size));letter-spacing:var(--mat-option-label-text-tracking, var(--mat-app-label-large-tracking));font-weight:var(--mat-option-label-text-weight, var(--mat-app-body-large-weight))}.mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:var(--mat-option-hover-state-layer-color)}.mat-mdc-option:focus.mdc-list-item,.mat-mdc-option.mat-mdc-option-active.mdc-list-item{background-color:var(--mat-option-focus-state-layer-color);outline:0}.mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled) .mdc-list-item__primary-text{color:var(--mat-option-selected-state-label-text-color, var(--mat-app-on-secondary-container))}.mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled):not(.mat-mdc-option-multiple){background-color:var(--mat-option-selected-state-layer-color, var(--mat-app-secondary-container))}.mat-mdc-option .mat-pseudo-checkbox{--mat-minimal-pseudo-checkbox-selected-checkmark-color: var(--mat-option-selected-state-label-text-color, var(--mat-app-on-secondary-container))}.mat-mdc-option.mdc-list-item{align-items:center;background:rgba(0,0,0,0)}.mat-mdc-option.mdc-list-item--disabled{cursor:default;pointer-events:none}.mat-mdc-option.mdc-list-item--disabled .mat-mdc-option-pseudo-checkbox,.mat-mdc-option.mdc-list-item--disabled .mdc-list-item__primary-text,.mat-mdc-option.mdc-list-item--disabled>mat-icon{opacity:.38}.mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple){padding-left:32px}[dir=rtl] .mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple){padding-left:16px;padding-right:32px}.mat-mdc-option .mat-icon,.mat-mdc-option .mat-pseudo-checkbox-full{margin-right:16px;flex-shrink:0}[dir=rtl] .mat-mdc-option .mat-icon,[dir=rtl] .mat-mdc-option .mat-pseudo-checkbox-full{margin-right:0;margin-left:16px}.mat-mdc-option .mat-pseudo-checkbox-minimal{margin-left:16px;flex-shrink:0}[dir=rtl] .mat-mdc-option .mat-pseudo-checkbox-minimal{margin-right:16px;margin-left:0}.mat-mdc-option .mat-mdc-option-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-mdc-option .mdc-list-item__primary-text{white-space:normal;font-size:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;font-family:inherit;text-decoration:inherit;text-transform:inherit;margin-right:auto}[dir=rtl] .mat-mdc-option .mdc-list-item__primary-text{margin-right:0;margin-left:auto}.cdk-high-contrast-active .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple)::after{content:\"\";position:absolute;top:50%;right:16px;transform:translateY(-50%);width:10px;height:0;border-bottom:solid 10px;border-radius:10px}[dir=rtl] .cdk-high-contrast-active .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple)::after{right:auto;left:16px}.mat-mdc-option-multiple{--mdc-list-list-item-selected-container-color:var(--mdc-list-list-item-container-color, transparent)}.mat-mdc-option-active .mat-mdc-focus-indicator::before{content:\"\"}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatOption, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-option',
      exportAs: 'matOption',
      host: {
        'role': 'option',
        '[class.mdc-list-item--selected]': 'selected',
        '[class.mat-mdc-option-multiple]': 'multiple',
        '[class.mat-mdc-option-active]': 'active',
        '[class.mdc-list-item--disabled]': 'disabled',
        '[id]': 'id',
        // Set aria-selected to false for non-selected items and true for selected items. Conform to
        // [WAI ARIA Listbox authoring practices guide](
        //  https://www.w3.org/WAI/ARIA/apg/patterns/listbox/), "If any options are selected, each
        // selected option has either aria-selected or aria-checked  set to true. All options that are
        // selectable but not selected have either aria-selected or aria-checked set to false." Align
        // aria-selected implementation of Chips and List components.
        //
        // Set `aria-selected="false"` on not-selected listbox options to fix VoiceOver announcing
        // every option as "selected" (#21491).
        '[attr.aria-selected]': 'selected',
        '[attr.aria-disabled]': 'disabled.toString()',
        '(click)': '_selectViaInteraction()',
        '(keydown)': '_handleKeydown($event)',
        'class': 'mat-mdc-option mdc-list-item'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      standalone: true,
      imports: [MatPseudoCheckbox, MatRipple],
      template: "<!-- Set aria-hidden=\"true\" to this DOM node and other decorative nodes in this file. This might\n be contributing to issue where sometimes VoiceOver focuses on a TextNode in the a11y tree instead\n of the Option node (#23202). Most assistive technology will generally ignore non-role,\n non-text-content elements. Adding aria-hidden seems to make VoiceOver behave more consistently. -->\n@if (multiple) {\n    <mat-pseudo-checkbox\n        class=\"mat-mdc-option-pseudo-checkbox\"\n        [disabled]=\"disabled\"\n        [state]=\"selected ? 'checked' : 'unchecked'\"\n        aria-hidden=\"true\"></mat-pseudo-checkbox>\n}\n\n<ng-content select=\"mat-icon\"></ng-content>\n\n<span class=\"mdc-list-item__primary-text\" #text><ng-content></ng-content></span>\n\n<!-- Render checkmark at the end for single-selection. -->\n@if (!multiple && selected && !hideSingleSelectionIndicator) {\n    <mat-pseudo-checkbox\n        class=\"mat-mdc-option-pseudo-checkbox\"\n        [disabled]=\"disabled\"\n        state=\"checked\"\n        aria-hidden=\"true\"\n        appearance=\"minimal\"></mat-pseudo-checkbox>\n}\n\n<!-- See a11y notes inside optgroup.ts for context behind this element. -->\n@if (group && group._inert) {\n    <span class=\"cdk-visually-hidden\">({{ group.label }})</span>\n}\n\n<div class=\"mat-mdc-option-ripple mat-mdc-focus-indicator\" aria-hidden=\"true\" mat-ripple\n     [matRippleTrigger]=\"_getHostElement()\" [matRippleDisabled]=\"disabled || disableRipple\">\n</div>\n",
      styles: [".mat-mdc-option{-webkit-user-select:none;user-select:none;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:flex;position:relative;align-items:center;justify-content:flex-start;overflow:hidden;min-height:48px;padding:0 16px;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0);color:var(--mat-option-label-text-color, var(--mat-app-on-surface));font-family:var(--mat-option-label-text-font, var(--mat-app-label-large-font));line-height:var(--mat-option-label-text-line-height, var(--mat-app-label-large-line-height));font-size:var(--mat-option-label-text-size, var(--mat-app-body-large-size));letter-spacing:var(--mat-option-label-text-tracking, var(--mat-app-label-large-tracking));font-weight:var(--mat-option-label-text-weight, var(--mat-app-body-large-weight))}.mat-mdc-option:hover:not(.mdc-list-item--disabled){background-color:var(--mat-option-hover-state-layer-color)}.mat-mdc-option:focus.mdc-list-item,.mat-mdc-option.mat-mdc-option-active.mdc-list-item{background-color:var(--mat-option-focus-state-layer-color);outline:0}.mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled) .mdc-list-item__primary-text{color:var(--mat-option-selected-state-label-text-color, var(--mat-app-on-secondary-container))}.mat-mdc-option.mdc-list-item--selected:not(.mdc-list-item--disabled):not(.mat-mdc-option-multiple){background-color:var(--mat-option-selected-state-layer-color, var(--mat-app-secondary-container))}.mat-mdc-option .mat-pseudo-checkbox{--mat-minimal-pseudo-checkbox-selected-checkmark-color: var(--mat-option-selected-state-label-text-color, var(--mat-app-on-secondary-container))}.mat-mdc-option.mdc-list-item{align-items:center;background:rgba(0,0,0,0)}.mat-mdc-option.mdc-list-item--disabled{cursor:default;pointer-events:none}.mat-mdc-option.mdc-list-item--disabled .mat-mdc-option-pseudo-checkbox,.mat-mdc-option.mdc-list-item--disabled .mdc-list-item__primary-text,.mat-mdc-option.mdc-list-item--disabled>mat-icon{opacity:.38}.mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple){padding-left:32px}[dir=rtl] .mat-mdc-optgroup .mat-mdc-option:not(.mat-mdc-option-multiple){padding-left:16px;padding-right:32px}.mat-mdc-option .mat-icon,.mat-mdc-option .mat-pseudo-checkbox-full{margin-right:16px;flex-shrink:0}[dir=rtl] .mat-mdc-option .mat-icon,[dir=rtl] .mat-mdc-option .mat-pseudo-checkbox-full{margin-right:0;margin-left:16px}.mat-mdc-option .mat-pseudo-checkbox-minimal{margin-left:16px;flex-shrink:0}[dir=rtl] .mat-mdc-option .mat-pseudo-checkbox-minimal{margin-right:16px;margin-left:0}.mat-mdc-option .mat-mdc-option-ripple{top:0;left:0;right:0;bottom:0;position:absolute;pointer-events:none}.mat-mdc-option .mdc-list-item__primary-text{white-space:normal;font-size:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;font-family:inherit;text-decoration:inherit;text-transform:inherit;margin-right:auto}[dir=rtl] .mat-mdc-option .mdc-list-item__primary-text{margin-right:0;margin-left:auto}.cdk-high-contrast-active .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple)::after{content:\"\";position:absolute;top:50%;right:16px;transform:translateY(-50%);width:10px;height:0;border-bottom:solid 10px;border-radius:10px}[dir=rtl] .cdk-high-contrast-active .mat-mdc-option.mdc-list-item--selected:not(.mat-mdc-option-multiple)::after{right:auto;left:16px}.mat-mdc-option-multiple{--mdc-list-list-item-selected-container-color:var(--mdc-list-list-item-container-color, transparent)}.mat-mdc-option-active .mat-mdc-focus-indicator::before{content:\"\"}"]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MAT_OPTION_PARENT_COMPONENT]
    }]
  }, {
    type: MatOptgroup,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [MAT_OPTGROUP]
    }]
  }], {
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }]
    }],
    onSelectionChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    _text: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['text', {
        static: true
      }]
    }]
  });
})();
/**
 * Counts the amount of option group labels that precede the specified option.
 * @param optionIndex Index of the option at which to start counting.
 * @param options Flat list of all of the options.
 * @param optionGroups Flat list of all of the option groups.
 * @docs-private
 */
function _countGroupLabelsBeforeOption(optionIndex, options, optionGroups) {
  if (optionGroups.length) {
    let optionsArray = options.toArray();
    let groups = optionGroups.toArray();
    let groupCounter = 0;
    for (let i = 0; i < optionIndex + 1; i++) {
      if (optionsArray[i].group && optionsArray[i].group === groups[groupCounter]) {
        groupCounter++;
      }
    }
    return groupCounter;
  }
  return 0;
}
/**
 * Determines the position to which to scroll a panel in order for an option to be into view.
 * @param optionOffset Offset of the option from the top of the panel.
 * @param optionHeight Height of the options.
 * @param currentScrollPosition Current scroll position of the panel.
 * @param panelHeight Height of the panel.
 * @docs-private
 */
function _getOptionScrollPosition(optionOffset, optionHeight, currentScrollPosition, panelHeight) {
  if (optionOffset < currentScrollPosition) {
    return optionOffset;
  }
  if (optionOffset + optionHeight > currentScrollPosition + panelHeight) {
    return Math.max(0, optionOffset - panelHeight + optionHeight);
  }
  return currentScrollPosition;
}
class MatOptionModule {
  static {
    this.ɵfac = function MatOptionModule_Factory(t) {
      return new (t || MatOptionModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatOptionModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [MatRippleModule, MatCommonModule, MatPseudoCheckboxModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatOptionModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [MatRippleModule, MatCommonModule, MatPseudoCheckboxModule, MatOption, MatOptgroup],
      exports: [MatOption, MatOptgroup]
    }]
  }], null, null);
})();

/** The options for the MatRippleLoader's event listeners. */
const eventListenerOptions = {
  capture: true
};
/**
 * The events that should trigger the initialization of the ripple.
 * Note that we use `mousedown`, rather than `click`, for mouse devices because
 * we can't rely on `mouseenter` in the shadow DOM and `click` happens too late.
 */
const rippleInteractionEvents = ['focus', 'mousedown', 'mouseenter', 'touchstart'];
/** The attribute attached to a component whose ripple has not yet been initialized. */
const matRippleUninitialized = 'mat-ripple-loader-uninitialized';
/** Additional classes that should be added to the ripple when it is rendered. */
const matRippleClassName = 'mat-ripple-loader-class-name';
/** Whether the ripple should be centered. */
const matRippleCentered = 'mat-ripple-loader-centered';
/** Whether the ripple should be disabled. */
const matRippleDisabled = 'mat-ripple-loader-disabled';
/**
 * Handles attaching ripples on demand.
 *
 * This service allows us to avoid eagerly creating & attaching MatRipples.
 * It works by creating & attaching a ripple only when a component is first interacted with.
 *
 * @docs-private
 */
class MatRippleLoader {
  constructor() {
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_3__.DOCUMENT, {
      optional: true
    });
    this._animationMode = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE, {
      optional: true
    });
    this._globalRippleOptions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(MAT_RIPPLE_GLOBAL_OPTIONS, {
      optional: true
    });
    this._platform = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__.Platform);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._hosts = new Map();
    /**
     * Handles creating and attaching component internals
     * when a component is initially interacted with.
     */
    this._onInteraction = event => {
      const eventTarget = (0,_angular_cdk_platform__WEBPACK_IMPORTED_MODULE_1__._getEventTarget)(event);
      if (eventTarget instanceof HTMLElement) {
        // TODO(wagnermaciel): Consider batching these events to improve runtime performance.
        const element = eventTarget.closest(`[${matRippleUninitialized}="${this._globalRippleOptions?.namespace ?? ''}"]`);
        if (element) {
          this._createRipple(element);
        }
      }
    };
    this._ngZone.runOutsideAngular(() => {
      for (const event of rippleInteractionEvents) {
        this._document?.addEventListener(event, this._onInteraction, eventListenerOptions);
      }
    });
  }
  ngOnDestroy() {
    const hosts = this._hosts.keys();
    for (const host of hosts) {
      this.destroyRipple(host);
    }
    for (const event of rippleInteractionEvents) {
      this._document?.removeEventListener(event, this._onInteraction, eventListenerOptions);
    }
  }
  /**
   * Configures the ripple that will be rendered by the ripple loader.
   *
   * Stores the given information about how the ripple should be configured on the host
   * element so that it can later be retrived & used when the ripple is actually created.
   */
  configureRipple(host, config) {
    // Indicates that the ripple has not yet been rendered for this component.
    host.setAttribute(matRippleUninitialized, this._globalRippleOptions?.namespace ?? '');
    // Store the additional class name(s) that should be added to the ripple element.
    if (config.className || !host.hasAttribute(matRippleClassName)) {
      host.setAttribute(matRippleClassName, config.className || '');
    }
    // Store whether the ripple should be centered.
    if (config.centered) {
      host.setAttribute(matRippleCentered, '');
    }
    if (config.disabled) {
      host.setAttribute(matRippleDisabled, '');
    }
  }
  /** Returns the ripple instance for the given host element. */
  getRipple(host) {
    const ripple = this._hosts.get(host);
    return ripple || this._createRipple(host);
  }
  /** Sets the disabled state on the ripple instance corresponding to the given host element. */
  setDisabled(host, disabled) {
    const ripple = this._hosts.get(host);
    // If the ripple has already been instantiated, just disable it.
    if (ripple) {
      ripple.disabled = disabled;
      return;
    }
    // Otherwise, set an attribute so we know what the
    // disabled state should be when the ripple is initialized.
    if (disabled) {
      host.setAttribute(matRippleDisabled, '');
    } else {
      host.removeAttribute(matRippleDisabled);
    }
  }
  /** Creates a MatRipple and appends it to the given element. */
  _createRipple(host) {
    if (!this._document) {
      return;
    }
    const existingRipple = this._hosts.get(host);
    if (existingRipple) {
      return existingRipple;
    }
    // Create the ripple element.
    host.querySelector('.mat-ripple')?.remove();
    const rippleEl = this._document.createElement('span');
    rippleEl.classList.add('mat-ripple', host.getAttribute(matRippleClassName));
    host.append(rippleEl);
    // Create the MatRipple.
    const ripple = new MatRipple(new _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef(rippleEl), this._ngZone, this._platform, this._globalRippleOptions ? this._globalRippleOptions : undefined, this._animationMode ? this._animationMode : undefined);
    ripple._isInitialized = true;
    ripple.trigger = host;
    ripple.centered = host.hasAttribute(matRippleCentered);
    ripple.disabled = host.hasAttribute(matRippleDisabled);
    this.attachRipple(host, ripple);
    return ripple;
  }
  attachRipple(host, ripple) {
    host.removeAttribute(matRippleUninitialized);
    this._hosts.set(host, ripple);
  }
  destroyRipple(host) {
    const ripple = this._hosts.get(host);
    if (ripple) {
      // Since this directive is created manually, it needs to be destroyed manually too.
      // tslint:disable-next-line:no-lifecycle-invocation
      ripple.ngOnDestroy();
      this._hosts.delete(host);
    }
  }
  static {
    this.ɵfac = function MatRippleLoader_Factory(t) {
      return new (t || MatRippleLoader)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: MatRippleLoader,
      factory: MatRippleLoader.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRippleLoader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();

/**
 * Internal shared component used as a container in form field controls.
 * Not to be confused with `mat-form-field` which MDC calls a "text field".
 * @docs-private
 */
class _MatInternalFormField {
  static {
    this.ɵfac = function _MatInternalFormField_Factory(t) {
      return new (t || _MatInternalFormField)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: _MatInternalFormField,
      selectors: [["div", "mat-internal-form-field", ""]],
      hostAttrs: [1, "mdc-form-field", "mat-internal-form-field"],
      hostVars: 2,
      hostBindings: function _MatInternalFormField_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mdc-form-field--align-end", ctx.labelPosition === "before");
        }
      },
      inputs: {
        labelPosition: "labelPosition"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      attrs: _c5,
      ngContentSelectors: _c6,
      decls: 1,
      vars: 0,
      template: function _MatInternalFormField_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
        }
      },
      styles: [".mat-internal-form-field{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-flex;align-items:center;vertical-align:middle}.mat-internal-form-field>label{margin-left:0;margin-right:auto;padding-left:4px;padding-right:0;order:0}[dir=rtl] .mat-internal-form-field>label{margin-left:auto;margin-right:0;padding-left:0;padding-right:4px}.mdc-form-field--align-end>label{margin-left:auto;margin-right:0;padding-left:0;padding-right:4px;order:-1}[dir=rtl] .mdc-form-field--align-end .mdc-form-field--align-end label{margin-left:0;margin-right:auto;padding-left:4px;padding-right:0}"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](_MatInternalFormField, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'div[mat-internal-form-field]',
      standalone: true,
      template: '<ng-content></ng-content>',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      host: {
        'class': 'mdc-form-field mat-internal-form-field',
        '[class.mdc-form-field--align-end]': 'labelPosition === "before"'
      },
      styles: [".mat-internal-form-field{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-flex;align-items:center;vertical-align:middle}.mat-internal-form-field>label{margin-left:0;margin-right:auto;padding-left:4px;padding-right:0;order:0}[dir=rtl] .mat-internal-form-field>label{margin-left:auto;margin-right:0;padding-left:0;padding-right:4px}.mdc-form-field--align-end>label{margin-left:auto;margin-right:0;padding-left:0;padding-right:4px;order:-1}[dir=rtl] .mdc-form-field--align-end .mdc-form-field--align-end label{margin-left:0;margin-right:auto;padding-left:4px;padding-right:0}"]
    }]
  }], null, {
    labelPosition: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true
      }]
    }]
  });
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 77697:
/*!***********************************************************!*\
  !*** ./node_modules/@angular/material/fesm2022/table.mjs ***!
  \***********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   MatCell: () => (/* binding */ MatCell),
/* harmony export */   MatCellDef: () => (/* binding */ MatCellDef),
/* harmony export */   MatColumnDef: () => (/* binding */ MatColumnDef),
/* harmony export */   MatFooterCell: () => (/* binding */ MatFooterCell),
/* harmony export */   MatFooterCellDef: () => (/* binding */ MatFooterCellDef),
/* harmony export */   MatFooterRow: () => (/* binding */ MatFooterRow),
/* harmony export */   MatFooterRowDef: () => (/* binding */ MatFooterRowDef),
/* harmony export */   MatHeaderCell: () => (/* binding */ MatHeaderCell),
/* harmony export */   MatHeaderCellDef: () => (/* binding */ MatHeaderCellDef),
/* harmony export */   MatHeaderRow: () => (/* binding */ MatHeaderRow),
/* harmony export */   MatHeaderRowDef: () => (/* binding */ MatHeaderRowDef),
/* harmony export */   MatNoDataRow: () => (/* binding */ MatNoDataRow),
/* harmony export */   MatRecycleRows: () => (/* binding */ MatRecycleRows),
/* harmony export */   MatRow: () => (/* binding */ MatRow),
/* harmony export */   MatRowDef: () => (/* binding */ MatRowDef),
/* harmony export */   MatTable: () => (/* binding */ MatTable),
/* harmony export */   MatTableDataSource: () => (/* binding */ MatTableDataSource),
/* harmony export */   MatTableModule: () => (/* binding */ MatTableModule),
/* harmony export */   MatTextColumn: () => (/* binding */ MatTextColumn)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/cdk/table */ 90198);
/* harmony import */ var _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/cdk/collections */ 37989);
/* harmony import */ var _angular_material_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/material/core */ 74646);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 19999);
/* harmony import */ var _angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/cdk/coercion */ 2814);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 70271);









/**
 * Enables the recycle view repeater strategy, which reduces rendering latency. Not compatible with
 * tables that animate rows.
 */
const _c0 = [[["caption"]], [["colgroup"], ["col"]], "*"];
const _c1 = ["caption", "colgroup, col", "*"];
function MatTable_Conditional_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0, 2);
  }
}
function MatTable_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "thead", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](1, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "tbody", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](3, 3)(4, 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](5, "tfoot", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](6, 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function MatTable_Conditional_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](0, 1)(1, 3)(2, 4)(3, 5);
  }
}
function MatTextColumn_th_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "th", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("text-align", ctx_r0.justify);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx_r0.headerText, " ");
  }
}
function MatTextColumn_td_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "td", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const data_r2 = ctx.$implicit;
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("text-align", ctx_r0.justify);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx_r0.dataAccessor(data_r2, ctx_r0.name), " ");
  }
}
class MatRecycleRows {
  static {
    this.ɵfac = function MatRecycleRows_Factory(t) {
      return new (t || MatRecycleRows)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatRecycleRows,
      selectors: [["mat-table", "recycleRows", ""], ["table", "mat-table", "", "recycleRows", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._RecycleViewRepeaterStrategy
      }])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRecycleRows, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'mat-table[recycleRows], table[mat-table][recycleRows]',
      providers: [{
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._RecycleViewRepeaterStrategy
      }],
      standalone: true
    }]
  }], null, null);
})();
class MatTable extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTable {
  constructor() {
    super(...arguments);
    /** Overrides the sticky CSS class set by the `CdkTable`. */
    this.stickyCssClass = 'mat-mdc-table-sticky';
    /** Overrides the need to add position: sticky on every sticky cell element in `CdkTable`. */
    this.needsPositionStickyOnElement = false;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatTable_BaseFactory;
      return function MatTable_Factory(t) {
        return (ɵMatTable_BaseFactory || (ɵMatTable_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatTable)))(t || MatTable);
      };
    })();
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatTable,
      selectors: [["mat-table"], ["table", "mat-table", ""]],
      hostAttrs: [1, "mat-mdc-table", "mdc-data-table__table"],
      hostVars: 2,
      hostBindings: function MatTable_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("mdc-table-fixed-layout", ctx.fixedLayout);
        }
      },
      exportAs: ["matTable"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTable,
        useExisting: MatTable
      }, {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CDK_TABLE,
        useExisting: MatTable
      }, {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__._COALESCED_STYLE_SCHEDULER,
        useClass: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__._CoalescedStyleScheduler
      },
      // TODO(michaeljamesparsons) Abstract the view repeater strategy to a directive API so this code
      //  is only included in the build if used.
      {
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._DisposeViewRepeaterStrategy
      },
      // Prevent nested tables from seeing this table's StickyPositioningListener.
      {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.STICKY_POSITIONING_LISTENER,
        useValue: null
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c1,
      decls: 5,
      vars: 2,
      consts: [["role", "rowgroup"], ["headerRowOutlet", ""], ["role", "rowgroup", 1, "mdc-data-table__content"], ["rowOutlet", ""], ["noDataRowOutlet", ""], ["footerRowOutlet", ""]],
      template: function MatTable_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"](_c0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](1, 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, MatTable_Conditional_2_Template, 1, 0)(3, MatTable_Conditional_3_Template, 7, 0)(4, MatTable_Conditional_4_Template, 4, 0);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](2, ctx._isServer ? 2 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, ctx._isNativeHtmlTable ? 3 : 4);
        }
      },
      dependencies: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.HeaderRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.DataRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.NoDataRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.FooterRowOutlet],
      styles: [".mat-mdc-table-sticky{position:sticky !important}mat-table{display:block}mat-header-row{min-height:56px}mat-row,mat-footer-row{min-height:48px}mat-row,mat-header-row,mat-footer-row{display:flex;border-width:0;border-bottom-width:1px;border-style:solid;align-items:center;box-sizing:border-box}mat-cell:first-of-type,mat-header-cell:first-of-type,mat-footer-cell:first-of-type{padding-left:24px}[dir=rtl] mat-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:first-of-type:not(:only-of-type){padding-left:0;padding-right:24px}mat-cell:last-of-type,mat-header-cell:last-of-type,mat-footer-cell:last-of-type{padding-right:24px}[dir=rtl] mat-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:last-of-type:not(:only-of-type){padding-right:0;padding-left:24px}mat-cell,mat-header-cell,mat-footer-cell{flex:1;display:flex;align-items:center;overflow:hidden;word-wrap:break-word;min-height:inherit}.mat-mdc-table{min-width:100%;border:0;border-spacing:0;table-layout:auto;white-space:normal;background-color:var(--mat-table-background-color, var(--mat-app-surface))}.mdc-data-table__cell{box-sizing:border-box;overflow:hidden;text-align:left;text-overflow:ellipsis}[dir=rtl] .mdc-data-table__cell{text-align:right}.mdc-data-table__cell,.mdc-data-table__header-cell{padding:0 16px}.mat-mdc-header-row{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;height:var(--mat-table-header-container-height, 56px);color:var(--mat-table-header-headline-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)));font-family:var(--mat-table-header-headline-font, var(--mat-app-title-small-font, Roboto, sans-serif));line-height:var(--mat-table-header-headline-line-height, var(--mat-app-title-small-line-height));font-size:var(--mat-table-header-headline-size, var(--mat-app-title-small-size, 14px));font-weight:var(--mat-table-header-headline-weight, var(--mat-app-title-small-weight, 500))}.mat-mdc-row{height:var(--mat-table-row-item-container-height, 52px);color:var(--mat-table-row-item-label-text-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)))}.mat-mdc-row,.mdc-data-table__content{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mat-table-row-item-label-text-font, var(--mat-app-body-medium-font, Roboto, sans-serif));line-height:var(--mat-table-row-item-label-text-line-height, var(--mat-app-body-medium-line-height));font-size:var(--mat-table-row-item-label-text-size, var(--mat-app-body-medium-size, 14px));font-weight:var(--mat-table-row-item-label-text-weight, var(--mat-app-body-medium-weight))}.mat-mdc-footer-row{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;height:var(--mat-table-footer-container-height, 52px);color:var(--mat-table-row-item-label-text-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)));font-family:var(--mat-table-footer-supporting-text-font, var(--mat-app-body-medium-font, Roboto, sans-serif));line-height:var(--mat-table-footer-supporting-text-line-height, var(--mat-app-body-medium-line-height));font-size:var(--mat-table-footer-supporting-text-size, var(--mat-app-body-medium-size, 14px));font-weight:var(--mat-table-footer-supporting-text-weight, var(--mat-app-body-medium-weight));letter-spacing:var(--mat-table-footer-supporting-text-tracking, var(--mat-app-body-medium-tracking))}.mat-mdc-header-cell{border-bottom-color:var(--mat-table-row-item-outline-color, var(--mat-app-outline, rgba(0, 0, 0, 0.12)));border-bottom-width:var(--mat-table-row-item-outline-width, 1px);border-bottom-style:solid;letter-spacing:var(--mat-table-header-headline-tracking, var(--mat-app-title-small-tracking));font-weight:inherit;line-height:inherit;box-sizing:border-box;text-overflow:ellipsis;overflow:hidden;outline:none;text-align:left}[dir=rtl] .mat-mdc-header-cell{text-align:right}.mat-mdc-cell{border-bottom-color:var(--mat-table-row-item-outline-color, var(--mat-app-outline, rgba(0, 0, 0, 0.12)));border-bottom-width:var(--mat-table-row-item-outline-width, 1px);border-bottom-style:solid;letter-spacing:var(--mat-table-row-item-label-text-tracking, var(--mat-app-body-medium-tracking));line-height:inherit}.mdc-data-table__row:last-child .mat-mdc-cell{border-bottom:none}.mat-mdc-footer-cell{letter-spacing:var(--mat-table-row-item-label-text-tracking, var(--mat-app-body-medium-tracking))}mat-row.mat-mdc-row,mat-header-row.mat-mdc-header-row,mat-footer-row.mat-mdc-footer-row{border-bottom:none}.mat-mdc-table tbody,.mat-mdc-table tfoot,.mat-mdc-table thead,.mat-mdc-cell,.mat-mdc-footer-cell,.mat-mdc-header-row,.mat-mdc-row,.mat-mdc-footer-row,.mat-mdc-table .mat-mdc-header-cell{background:inherit}.mat-mdc-table mat-header-row.mat-mdc-header-row,.mat-mdc-table mat-row.mat-mdc-row,.mat-mdc-table mat-footer-row.mat-mdc-footer-cell{height:unset}mat-header-cell.mat-mdc-header-cell,mat-cell.mat-mdc-cell,mat-footer-cell.mat-mdc-footer-cell{align-self:stretch}"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatTable, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-table, table[mat-table]',
      exportAs: 'matTable',
      template: `
    <ng-content select="caption"/>
    <ng-content select="colgroup, col"/>

    <!--
      Unprojected content throws a hydration error so we need this to capture it.
      It gets removed on the client so it doesn't affect the layout.
    -->
    @if (_isServer) {
      <ng-content/>
    }

    @if (_isNativeHtmlTable) {
      <thead role="rowgroup">
        <ng-container headerRowOutlet/>
      </thead>
      <tbody class="mdc-data-table__content" role="rowgroup">
        <ng-container rowOutlet/>
        <ng-container noDataRowOutlet/>
      </tbody>
      <tfoot role="rowgroup">
        <ng-container footerRowOutlet/>
      </tfoot>
    } @else {
      <ng-container headerRowOutlet/>
      <ng-container rowOutlet/>
      <ng-container noDataRowOutlet/>
      <ng-container footerRowOutlet/>
    }
  `,
      host: {
        'class': 'mat-mdc-table mdc-data-table__table',
        '[class.mdc-table-fixed-layout]': 'fixedLayout'
      },
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTable,
        useExisting: MatTable
      }, {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CDK_TABLE,
        useExisting: MatTable
      }, {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__._COALESCED_STYLE_SCHEDULER,
        useClass: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__._CoalescedStyleScheduler
      },
      // TODO(michaeljamesparsons) Abstract the view repeater strategy to a directive API so this code
      //  is only included in the build if used.
      {
        provide: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._VIEW_REPEATER_STRATEGY,
        useClass: _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__._DisposeViewRepeaterStrategy
      },
      // Prevent nested tables from seeing this table's StickyPositioningListener.
      {
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.STICKY_POSITIONING_LISTENER,
        useValue: null
      }],
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.Default,
      standalone: true,
      imports: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.HeaderRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.DataRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.NoDataRowOutlet, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.FooterRowOutlet],
      styles: [".mat-mdc-table-sticky{position:sticky !important}mat-table{display:block}mat-header-row{min-height:56px}mat-row,mat-footer-row{min-height:48px}mat-row,mat-header-row,mat-footer-row{display:flex;border-width:0;border-bottom-width:1px;border-style:solid;align-items:center;box-sizing:border-box}mat-cell:first-of-type,mat-header-cell:first-of-type,mat-footer-cell:first-of-type{padding-left:24px}[dir=rtl] mat-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:first-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:first-of-type:not(:only-of-type){padding-left:0;padding-right:24px}mat-cell:last-of-type,mat-header-cell:last-of-type,mat-footer-cell:last-of-type{padding-right:24px}[dir=rtl] mat-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-header-cell:last-of-type:not(:only-of-type),[dir=rtl] mat-footer-cell:last-of-type:not(:only-of-type){padding-right:0;padding-left:24px}mat-cell,mat-header-cell,mat-footer-cell{flex:1;display:flex;align-items:center;overflow:hidden;word-wrap:break-word;min-height:inherit}.mat-mdc-table{min-width:100%;border:0;border-spacing:0;table-layout:auto;white-space:normal;background-color:var(--mat-table-background-color, var(--mat-app-surface))}.mdc-data-table__cell{box-sizing:border-box;overflow:hidden;text-align:left;text-overflow:ellipsis}[dir=rtl] .mdc-data-table__cell{text-align:right}.mdc-data-table__cell,.mdc-data-table__header-cell{padding:0 16px}.mat-mdc-header-row{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;height:var(--mat-table-header-container-height, 56px);color:var(--mat-table-header-headline-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)));font-family:var(--mat-table-header-headline-font, var(--mat-app-title-small-font, Roboto, sans-serif));line-height:var(--mat-table-header-headline-line-height, var(--mat-app-title-small-line-height));font-size:var(--mat-table-header-headline-size, var(--mat-app-title-small-size, 14px));font-weight:var(--mat-table-header-headline-weight, var(--mat-app-title-small-weight, 500))}.mat-mdc-row{height:var(--mat-table-row-item-container-height, 52px);color:var(--mat-table-row-item-label-text-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)))}.mat-mdc-row,.mdc-data-table__content{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:var(--mat-table-row-item-label-text-font, var(--mat-app-body-medium-font, Roboto, sans-serif));line-height:var(--mat-table-row-item-label-text-line-height, var(--mat-app-body-medium-line-height));font-size:var(--mat-table-row-item-label-text-size, var(--mat-app-body-medium-size, 14px));font-weight:var(--mat-table-row-item-label-text-weight, var(--mat-app-body-medium-weight))}.mat-mdc-footer-row{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;height:var(--mat-table-footer-container-height, 52px);color:var(--mat-table-row-item-label-text-color, var(--mat-app-on-surface, rgba(0, 0, 0, 0.87)));font-family:var(--mat-table-footer-supporting-text-font, var(--mat-app-body-medium-font, Roboto, sans-serif));line-height:var(--mat-table-footer-supporting-text-line-height, var(--mat-app-body-medium-line-height));font-size:var(--mat-table-footer-supporting-text-size, var(--mat-app-body-medium-size, 14px));font-weight:var(--mat-table-footer-supporting-text-weight, var(--mat-app-body-medium-weight));letter-spacing:var(--mat-table-footer-supporting-text-tracking, var(--mat-app-body-medium-tracking))}.mat-mdc-header-cell{border-bottom-color:var(--mat-table-row-item-outline-color, var(--mat-app-outline, rgba(0, 0, 0, 0.12)));border-bottom-width:var(--mat-table-row-item-outline-width, 1px);border-bottom-style:solid;letter-spacing:var(--mat-table-header-headline-tracking, var(--mat-app-title-small-tracking));font-weight:inherit;line-height:inherit;box-sizing:border-box;text-overflow:ellipsis;overflow:hidden;outline:none;text-align:left}[dir=rtl] .mat-mdc-header-cell{text-align:right}.mat-mdc-cell{border-bottom-color:var(--mat-table-row-item-outline-color, var(--mat-app-outline, rgba(0, 0, 0, 0.12)));border-bottom-width:var(--mat-table-row-item-outline-width, 1px);border-bottom-style:solid;letter-spacing:var(--mat-table-row-item-label-text-tracking, var(--mat-app-body-medium-tracking));line-height:inherit}.mdc-data-table__row:last-child .mat-mdc-cell{border-bottom:none}.mat-mdc-footer-cell{letter-spacing:var(--mat-table-row-item-label-text-tracking, var(--mat-app-body-medium-tracking))}mat-row.mat-mdc-row,mat-header-row.mat-mdc-header-row,mat-footer-row.mat-mdc-footer-row{border-bottom:none}.mat-mdc-table tbody,.mat-mdc-table tfoot,.mat-mdc-table thead,.mat-mdc-cell,.mat-mdc-footer-cell,.mat-mdc-header-row,.mat-mdc-row,.mat-mdc-footer-row,.mat-mdc-table .mat-mdc-header-cell{background:inherit}.mat-mdc-table mat-header-row.mat-mdc-header-row,.mat-mdc-table mat-row.mat-mdc-row,.mat-mdc-table mat-footer-row.mat-mdc-footer-cell{height:unset}mat-header-cell.mat-mdc-header-cell,mat-cell.mat-mdc-cell,mat-footer-cell.mat-mdc-footer-cell{align-self:stretch}"]
    }]
  }], null, null);
})();

/**
 * Cell definition for the mat-table.
 * Captures the template of a column's data row cell as well as cell-specific properties.
 */
class MatCellDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatCellDef_BaseFactory;
      return function MatCellDef_Factory(t) {
        return (ɵMatCellDef_BaseFactory || (ɵMatCellDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatCellDef)))(t || MatCellDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatCellDef,
      selectors: [["", "matCellDef", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellDef,
        useExisting: MatCellDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matCellDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellDef,
        useExisting: MatCellDef
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Header cell definition for the mat-table.
 * Captures the template of a column's header cell and as well as cell-specific properties.
 */
class MatHeaderCellDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderCellDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatHeaderCellDef_BaseFactory;
      return function MatHeaderCellDef_Factory(t) {
        return (ɵMatHeaderCellDef_BaseFactory || (ɵMatHeaderCellDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatHeaderCellDef)))(t || MatHeaderCellDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatHeaderCellDef,
      selectors: [["", "matHeaderCellDef", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderCellDef,
        useExisting: MatHeaderCellDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatHeaderCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matHeaderCellDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderCellDef,
        useExisting: MatHeaderCellDef
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Footer cell definition for the mat-table.
 * Captures the template of a column's footer cell and as well as cell-specific properties.
 */
class MatFooterCellDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterCellDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatFooterCellDef_BaseFactory;
      return function MatFooterCellDef_Factory(t) {
        return (ɵMatFooterCellDef_BaseFactory || (ɵMatFooterCellDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatFooterCellDef)))(t || MatFooterCellDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatFooterCellDef,
      selectors: [["", "matFooterCellDef", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterCellDef,
        useExisting: MatFooterCellDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatFooterCellDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matFooterCellDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterCellDef,
        useExisting: MatFooterCellDef
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Column definition for the mat-table.
 * Defines a set of cells available for a table column.
 */
class MatColumnDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkColumnDef {
  /** Unique name for this column. */
  get name() {
    return this._name;
  }
  set name(name) {
    this._setNameInput(name);
  }
  /**
   * Add "mat-column-" prefix in addition to "cdk-column-" prefix.
   * In the future, this will only add "mat-column-" and columnCssClassName
   * will change from type string[] to string.
   * @docs-private
   */
  _updateColumnCssClassName() {
    super._updateColumnCssClassName();
    this._columnCssClassName.push(`mat-column-${this.cssClassFriendlyName}`);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatColumnDef_BaseFactory;
      return function MatColumnDef_Factory(t) {
        return (ɵMatColumnDef_BaseFactory || (ɵMatColumnDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatColumnDef)))(t || MatColumnDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatColumnDef,
      selectors: [["", "matColumnDef", ""]],
      inputs: {
        name: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matColumnDef", "name"]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkColumnDef,
        useExisting: MatColumnDef
      }, {
        provide: 'MAT_SORT_HEADER_COLUMN_DEF',
        useExisting: MatColumnDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatColumnDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matColumnDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkColumnDef,
        useExisting: MatColumnDef
      }, {
        provide: 'MAT_SORT_HEADER_COLUMN_DEF',
        useExisting: MatColumnDef
      }],
      standalone: true
    }]
  }], null, {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['matColumnDef']
    }]
  });
})();
/** Header cell template container that adds the right classes and role. */
class MatHeaderCell extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderCell {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatHeaderCell_BaseFactory;
      return function MatHeaderCell_Factory(t) {
        return (ɵMatHeaderCell_BaseFactory || (ɵMatHeaderCell_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatHeaderCell)))(t || MatHeaderCell);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatHeaderCell,
      selectors: [["mat-header-cell"], ["th", "mat-header-cell", ""]],
      hostAttrs: ["role", "columnheader", 1, "mat-mdc-header-cell", "mdc-data-table__header-cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatHeaderCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'mat-header-cell, th[mat-header-cell]',
      host: {
        'class': 'mat-mdc-header-cell mdc-data-table__header-cell',
        'role': 'columnheader'
      },
      standalone: true
    }]
  }], null, null);
})();
/** Footer cell template container that adds the right classes and role. */
class MatFooterCell extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterCell {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatFooterCell_BaseFactory;
      return function MatFooterCell_Factory(t) {
        return (ɵMatFooterCell_BaseFactory || (ɵMatFooterCell_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatFooterCell)))(t || MatFooterCell);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatFooterCell,
      selectors: [["mat-footer-cell"], ["td", "mat-footer-cell", ""]],
      hostAttrs: [1, "mat-mdc-footer-cell", "mdc-data-table__cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatFooterCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'mat-footer-cell, td[mat-footer-cell]',
      host: {
        'class': 'mat-mdc-footer-cell mdc-data-table__cell'
      },
      standalone: true
    }]
  }], null, null);
})();
/** Cell template container that adds the right classes and role. */
class MatCell extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCell {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatCell_BaseFactory;
      return function MatCell_Factory(t) {
        return (ɵMatCell_BaseFactory || (ɵMatCell_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatCell)))(t || MatCell);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatCell,
      selectors: [["mat-cell"], ["td", "mat-cell", ""]],
      hostAttrs: [1, "mat-mdc-cell", "mdc-data-table__cell"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatCell, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'mat-cell, td[mat-cell]',
      host: {
        'class': 'mat-mdc-cell mdc-data-table__cell'
      },
      standalone: true
    }]
  }], null, null);
})();

// We can't reuse `CDK_ROW_TEMPLATE` because it's incompatible with local compilation mode.
const ROW_TEMPLATE = `<ng-container cdkCellOutlet></ng-container>`;
/**
 * Header row definition for the mat-table.
 * Captures the header row's template and other header properties such as the columns to display.
 */
class MatHeaderRowDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRowDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatHeaderRowDef_BaseFactory;
      return function MatHeaderRowDef_Factory(t) {
        return (ɵMatHeaderRowDef_BaseFactory || (ɵMatHeaderRowDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatHeaderRowDef)))(t || MatHeaderRowDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatHeaderRowDef,
      selectors: [["", "matHeaderRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matHeaderRowDef", "columns"],
        sticky: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "matHeaderRowDefSticky", "sticky", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRowDef,
        useExisting: MatHeaderRowDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatHeaderRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matHeaderRowDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRowDef,
        useExisting: MatHeaderRowDef
      }],
      inputs: [{
        name: 'columns',
        alias: 'matHeaderRowDef'
      }, {
        name: 'sticky',
        alias: 'matHeaderRowDefSticky',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Footer row definition for the mat-table.
 * Captures the footer row's template and other footer properties such as the columns to display.
 */
class MatFooterRowDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRowDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatFooterRowDef_BaseFactory;
      return function MatFooterRowDef_Factory(t) {
        return (ɵMatFooterRowDef_BaseFactory || (ɵMatFooterRowDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatFooterRowDef)))(t || MatFooterRowDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatFooterRowDef,
      selectors: [["", "matFooterRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matFooterRowDef", "columns"],
        sticky: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].HasDecoratorInputTransform, "matFooterRowDefSticky", "sticky", _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRowDef,
        useExisting: MatFooterRowDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatFooterRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matFooterRowDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRowDef,
        useExisting: MatFooterRowDef
      }],
      inputs: [{
        name: 'columns',
        alias: 'matFooterRowDef'
      }, {
        name: 'sticky',
        alias: 'matFooterRowDefSticky',
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_0__.booleanAttribute
      }],
      standalone: true
    }]
  }], null, null);
})();
/**
 * Data row definition for the mat-table.
 * Captures the data row's template and other properties such as the columns to display and
 * a when predicate that describes when this row should be used.
 */
class MatRowDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRowDef {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatRowDef_BaseFactory;
      return function MatRowDef_Factory(t) {
        return (ɵMatRowDef_BaseFactory || (ɵMatRowDef_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatRowDef)))(t || MatRowDef);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatRowDef,
      selectors: [["", "matRowDef", ""]],
      inputs: {
        columns: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRowDefColumns", "columns"],
        when: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "matRowDefWhen", "when"]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRowDef,
        useExisting: MatRowDef
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRowDef, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[matRowDef]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRowDef,
        useExisting: MatRowDef
      }],
      inputs: [{
        name: 'columns',
        alias: 'matRowDefColumns'
      }, {
        name: 'when',
        alias: 'matRowDefWhen'
      }],
      standalone: true
    }]
  }], null, null);
})();
/** Header template container that contains the cell outlet. Adds the right class and role. */
class MatHeaderRow extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRow {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatHeaderRow_BaseFactory;
      return function MatHeaderRow_Factory(t) {
        return (ɵMatHeaderRow_BaseFactory || (ɵMatHeaderRow_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatHeaderRow)))(t || MatHeaderRow);
      };
    })();
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatHeaderRow,
      selectors: [["mat-header-row"], ["tr", "mat-header-row", ""]],
      hostAttrs: ["role", "row", 1, "mat-mdc-header-row", "mdc-data-table__header-row"],
      exportAs: ["matHeaderRow"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRow,
        useExisting: MatHeaderRow
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function MatHeaderRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatHeaderRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-header-row, tr[mat-header-row]',
      template: ROW_TEMPLATE,
      host: {
        'class': 'mat-mdc-header-row mdc-data-table__header-row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      exportAs: 'matHeaderRow',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkHeaderRow,
        useExisting: MatHeaderRow
      }],
      standalone: true,
      imports: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet]
    }]
  }], null, null);
})();
/** Footer template container that contains the cell outlet. Adds the right class and role. */
class MatFooterRow extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRow {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatFooterRow_BaseFactory;
      return function MatFooterRow_Factory(t) {
        return (ɵMatFooterRow_BaseFactory || (ɵMatFooterRow_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatFooterRow)))(t || MatFooterRow);
      };
    })();
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatFooterRow,
      selectors: [["mat-footer-row"], ["tr", "mat-footer-row", ""]],
      hostAttrs: ["role", "row", 1, "mat-mdc-footer-row", "mdc-data-table__row"],
      exportAs: ["matFooterRow"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRow,
        useExisting: MatFooterRow
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function MatFooterRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatFooterRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-footer-row, tr[mat-footer-row]',
      template: ROW_TEMPLATE,
      host: {
        'class': 'mat-mdc-footer-row mdc-data-table__row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      exportAs: 'matFooterRow',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkFooterRow,
        useExisting: MatFooterRow
      }],
      standalone: true,
      imports: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet]
    }]
  }], null, null);
})();
/** Data row template container that contains the cell outlet. Adds the right class and role. */
class MatRow extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRow {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatRow_BaseFactory;
      return function MatRow_Factory(t) {
        return (ɵMatRow_BaseFactory || (ɵMatRow_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatRow)))(t || MatRow);
      };
    })();
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatRow,
      selectors: [["mat-row"], ["tr", "mat-row", ""]],
      hostAttrs: ["role", "row", 1, "mat-mdc-row", "mdc-data-table__row"],
      exportAs: ["matRow"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRow,
        useExisting: MatRow
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      consts: [["cdkCellOutlet", ""]],
      template: function MatRow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](0, 0);
        }
      },
      dependencies: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-row, tr[mat-row]',
      template: ROW_TEMPLATE,
      host: {
        'class': 'mat-mdc-row mdc-data-table__row',
        'role': 'row'
      },
      // See note on CdkTable for explanation on why this uses the default change detection strategy.
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.Default,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      exportAs: 'matRow',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkRow,
        useExisting: MatRow
      }],
      standalone: true,
      imports: [_angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkCellOutlet]
    }]
  }], null, null);
})();
/** Row that can be used to display a message when no data is shown in the table. */
class MatNoDataRow extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkNoDataRow {
  constructor() {
    super(...arguments);
    this._contentClassName = 'mat-mdc-no-data-row';
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatNoDataRow_BaseFactory;
      return function MatNoDataRow_Factory(t) {
        return (ɵMatNoDataRow_BaseFactory || (ɵMatNoDataRow_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatNoDataRow)))(t || MatNoDataRow);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: MatNoDataRow,
      selectors: [["ng-template", "matNoDataRow", ""]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkNoDataRow,
        useExisting: MatNoDataRow
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatNoDataRow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[matNoDataRow]',
      providers: [{
        provide: _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkNoDataRow,
        useExisting: MatNoDataRow
      }],
      standalone: true
    }]
  }], null, null);
})();

/**
 * Column that simply shows text content for the header and row cells. Assumes that the table
 * is using the native table implementation (`<table>`).
 *
 * By default, the name of this column will be the header text and data property accessor.
 * The header text can be overridden with the `headerText` input. Cell values can be overridden with
 * the `dataAccessor` input. Change the text justification to the start or end using the `justify`
 * input.
 */
class MatTextColumn extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTextColumn {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵMatTextColumn_BaseFactory;
      return function MatTextColumn_Factory(t) {
        return (ɵMatTextColumn_BaseFactory || (ɵMatTextColumn_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](MatTextColumn)))(t || MatTextColumn);
      };
    })();
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: MatTextColumn,
      selectors: [["mat-text-column"]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 3,
      vars: 0,
      consts: [["matColumnDef", ""], ["mat-header-cell", "", 3, "text-align", 4, "matHeaderCellDef"], ["mat-cell", "", 3, "text-align", 4, "matCellDef"], ["mat-header-cell", ""], ["mat-cell", ""]],
      template: function MatTextColumn_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, MatTextColumn_th_1_Template, 2, 3, "th", 1)(2, MatTextColumn_td_2_Template, 2, 3, "td", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
        }
      },
      dependencies: [MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatTextColumn, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'mat-text-column',
      template: `
    <ng-container matColumnDef>
      <th mat-header-cell *matHeaderCellDef [style.text-align]="justify">
        {{headerText}}
      </th>
      <td mat-cell *matCellDef="let data" [style.text-align]="justify">
        {{dataAccessor(data, name)}}
      </td>
    </ng-container>
  `,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      // Change detection is intentionally not set to OnPush. This component's template will be provided
      // to the table to be inserted into its view. This is problematic when change detection runs since
      // the bindings in this template will be evaluated _after_ the table's view is evaluated, which
      // mean's the template in the table's view will not have the updated value (and in fact will cause
      // an ExpressionChangedAfterItHasBeenCheckedError).
      // tslint:disable-next-line:validate-decorators
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.Default,
      standalone: true,
      imports: [MatColumnDef, MatHeaderCellDef, MatHeaderCell, MatCellDef, MatCell]
    }]
  }], null, null);
})();
const EXPORTED_DECLARATIONS = [
// Table
MatTable, MatRecycleRows,
// Template defs
MatHeaderCellDef, MatHeaderRowDef, MatColumnDef, MatCellDef, MatRowDef, MatFooterCellDef, MatFooterRowDef,
// Cell directives
MatHeaderCell, MatCell, MatFooterCell,
// Row directives
MatHeaderRow, MatRow, MatFooterRow, MatNoDataRow, MatTextColumn];
class MatTableModule {
  static {
    this.ɵfac = function MatTableModule_Factory(t) {
      return new (t || MatTableModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: MatTableModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [_angular_material_core__WEBPACK_IMPORTED_MODULE_3__.MatCommonModule, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTableModule, _angular_material_core__WEBPACK_IMPORTED_MODULE_3__.MatCommonModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatTableModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [_angular_material_core__WEBPACK_IMPORTED_MODULE_3__.MatCommonModule, _angular_cdk_table__WEBPACK_IMPORTED_MODULE_2__.CdkTableModule, ...EXPORTED_DECLARATIONS],
      exports: [_angular_material_core__WEBPACK_IMPORTED_MODULE_3__.MatCommonModule, EXPORTED_DECLARATIONS]
    }]
  }], null, null);
})();

/**
 * Corresponds to `Number.MAX_SAFE_INTEGER`. Moved out into a variable here due to
 * flaky browser support and the value not being defined in Closure's typings.
 */
const MAX_SAFE_INTEGER = 9007199254740991;
/**
 * Data source that accepts a client-side data array and includes native support of filtering,
 * sorting (using MatSort), and pagination (using MatPaginator).
 *
 * Allows for sort customization by overriding sortingDataAccessor, which defines how data
 * properties are accessed. Also allows for filter customization by overriding filterPredicate,
 * which defines how row data is converted to a string for filter matching.
 *
 * **Note:** This class is meant to be a simple data source to help you get started. As such
 * it isn't equipped to handle some more advanced cases like robust i18n support or server-side
 * interactions. If your app needs to support more advanced use cases, consider implementing your
 * own `DataSource`.
 */
class MatTableDataSource extends _angular_cdk_collections__WEBPACK_IMPORTED_MODULE_1__.DataSource {
  /** Array of data that should be rendered by the table, where each object represents one row. */
  get data() {
    return this._data.value;
  }
  set data(data) {
    data = Array.isArray(data) ? data : [];
    this._data.next(data);
    // Normally the `filteredData` is updated by the re-render
    // subscription, but that won't happen if it's inactive.
    if (!this._renderChangesSubscription) {
      this._filterData(data);
    }
  }
  /**
   * Filter term that should be used to filter out objects from the data array. To override how
   * data objects match to this filter string, provide a custom function for filterPredicate.
   */
  get filter() {
    return this._filter.value;
  }
  set filter(filter) {
    this._filter.next(filter);
    // Normally the `filteredData` is updated by the re-render
    // subscription, but that won't happen if it's inactive.
    if (!this._renderChangesSubscription) {
      this._filterData(this.data);
    }
  }
  /**
   * Instance of the MatSort directive used by the table to control its sorting. Sort changes
   * emitted by the MatSort will trigger an update to the table's rendered data.
   */
  get sort() {
    return this._sort;
  }
  set sort(sort) {
    this._sort = sort;
    this._updateChangeSubscription();
  }
  /**
   * Instance of the paginator component used by the table to control what page of the data is
   * displayed. Page changes emitted by the paginator will trigger an update to the
   * table's rendered data.
   *
   * Note that the data source uses the paginator's properties to calculate which page of data
   * should be displayed. If the paginator receives its properties as template inputs,
   * e.g. `[pageLength]=100` or `[pageIndex]=1`, then be sure that the paginator's view has been
   * initialized before assigning it to this data source.
   */
  get paginator() {
    return this._paginator;
  }
  set paginator(paginator) {
    this._paginator = paginator;
    this._updateChangeSubscription();
  }
  constructor(initialData = []) {
    super();
    /** Stream emitting render data to the table (depends on ordered data changes). */
    this._renderData = new rxjs__WEBPACK_IMPORTED_MODULE_4__.BehaviorSubject([]);
    /** Stream that emits when a new filter string is set on the data source. */
    this._filter = new rxjs__WEBPACK_IMPORTED_MODULE_4__.BehaviorSubject('');
    /** Used to react to internal changes of the paginator that are made by the data source itself. */
    this._internalPageChanges = new rxjs__WEBPACK_IMPORTED_MODULE_5__.Subject();
    /**
     * Subscription to the changes that should trigger an update to the table's rendered rows, such
     * as filtering, sorting, pagination, or base data changes.
     */
    this._renderChangesSubscription = null;
    /**
     * Data accessor function that is used for accessing data properties for sorting through
     * the default sortData function.
     * This default function assumes that the sort header IDs (which defaults to the column name)
     * matches the data's properties (e.g. column Xyz represents data['Xyz']).
     * May be set to a custom function for different behavior.
     * @param data Data object that is being accessed.
     * @param sortHeaderId The name of the column that represents the data.
     */
    this.sortingDataAccessor = (data, sortHeaderId) => {
      const value = data[sortHeaderId];
      if ((0,_angular_cdk_coercion__WEBPACK_IMPORTED_MODULE_6__._isNumberValue)(value)) {
        const numberValue = Number(value);
        // Numbers beyond `MAX_SAFE_INTEGER` can't be compared reliably so we leave them as strings.
        // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
        return numberValue < MAX_SAFE_INTEGER ? numberValue : value;
      }
      return value;
    };
    /**
     * Gets a sorted copy of the data array based on the state of the MatSort. Called
     * after changes are made to the filtered data or when sort changes are emitted from MatSort.
     * By default, the function retrieves the active sort and its direction and compares data
     * by retrieving data using the sortingDataAccessor. May be overridden for a custom implementation
     * of data ordering.
     * @param data The array of data that should be sorted.
     * @param sort The connected MatSort that holds the current sort state.
     */
    this.sortData = (data, sort) => {
      const active = sort.active;
      const direction = sort.direction;
      if (!active || direction == '') {
        return data;
      }
      return data.sort((a, b) => {
        let valueA = this.sortingDataAccessor(a, active);
        let valueB = this.sortingDataAccessor(b, active);
        // If there are data in the column that can be converted to a number,
        // it must be ensured that the rest of the data
        // is of the same type so as not to order incorrectly.
        const valueAType = typeof valueA;
        const valueBType = typeof valueB;
        if (valueAType !== valueBType) {
          if (valueAType === 'number') {
            valueA += '';
          }
          if (valueBType === 'number') {
            valueB += '';
          }
        }
        // If both valueA and valueB exist (truthy), then compare the two. Otherwise, check if
        // one value exists while the other doesn't. In this case, existing value should come last.
        // This avoids inconsistent results when comparing values to undefined/null.
        // If neither value exists, return 0 (equal).
        let comparatorResult = 0;
        if (valueA != null && valueB != null) {
          // Check if one value is greater than the other; if equal, comparatorResult should remain 0.
          if (valueA > valueB) {
            comparatorResult = 1;
          } else if (valueA < valueB) {
            comparatorResult = -1;
          }
        } else if (valueA != null) {
          comparatorResult = 1;
        } else if (valueB != null) {
          comparatorResult = -1;
        }
        return comparatorResult * (direction == 'asc' ? 1 : -1);
      });
    };
    /**
     * Checks if a data object matches the data source's filter string. By default, each data object
     * is converted to a string of its properties and returns true if the filter has
     * at least one occurrence in that string. By default, the filter string has its whitespace
     * trimmed and the match is case-insensitive. May be overridden for a custom implementation of
     * filter matching.
     * @param data Data object used to check against the filter.
     * @param filter Filter string that has been set on the data source.
     * @returns Whether the filter matches against the data
     */
    this.filterPredicate = (data, filter) => {
      // Transform the data into a lowercase string of all property values.
      const dataStr = Object.keys(data).reduce((currentTerm, key) => {
        // Use an obscure Unicode character to delimit the words in the concatenated string.
        // This avoids matches where the values of two columns combined will match the user's query
        // (e.g. `Flute` and `Stop` will match `Test`). The character is intended to be something
        // that has a very low chance of being typed in by somebody in a text field. This one in
        // particular is "White up-pointing triangle with dot" from
        // https://en.wikipedia.org/wiki/List_of_Unicode_characters
        return currentTerm + data[key] + '◬';
      }, '').toLowerCase();
      // Transform the filter by converting it to lowercase and removing whitespace.
      const transformedFilter = filter.trim().toLowerCase();
      return dataStr.indexOf(transformedFilter) != -1;
    };
    this._data = new rxjs__WEBPACK_IMPORTED_MODULE_4__.BehaviorSubject(initialData);
    this._updateChangeSubscription();
  }
  /**
   * Subscribe to changes that should trigger an update to the table's rendered rows. When the
   * changes occur, process the current state of the filter, sort, and pagination along with
   * the provided base data and send it to the table for rendering.
   */
  _updateChangeSubscription() {
    // Sorting and/or pagination should be watched if sort and/or paginator are provided.
    // The events should emit whenever the component emits a change or initializes, or if no
    // component is provided, a stream with just a null event should be provided.
    // The `sortChange` and `pageChange` acts as a signal to the combineLatests below so that the
    // pipeline can progress to the next step. Note that the value from these streams are not used,
    // they purely act as a signal to progress in the pipeline.
    const sortChange = this._sort ? (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.merge)(this._sort.sortChange, this._sort.initialized) : (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.of)(null);
    const pageChange = this._paginator ? (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.merge)(this._paginator.page, this._internalPageChanges, this._paginator.initialized) : (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.of)(null);
    const dataStream = this._data;
    // Watch for base data or filter changes to provide a filtered set of data.
    const filteredData = (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.combineLatest)([dataStream, this._filter]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.map)(([data]) => this._filterData(data)));
    // Watch for filtered data or sort changes to provide an ordered set of data.
    const orderedData = (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.combineLatest)([filteredData, sortChange]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.map)(([data]) => this._orderData(data)));
    // Watch for ordered data or page changes to provide a paged set of data.
    const paginatedData = (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.combineLatest)([orderedData, pageChange]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.map)(([data]) => this._pageData(data)));
    // Watched for paged data changes and send the result to the table to render.
    this._renderChangesSubscription?.unsubscribe();
    this._renderChangesSubscription = paginatedData.subscribe(data => this._renderData.next(data));
  }
  /**
   * Returns a filtered data array where each filter object contains the filter string within
   * the result of the filterPredicate function. If no filter is set, returns the data array
   * as provided.
   */
  _filterData(data) {
    // If there is a filter string, filter out data that does not contain it.
    // Each data object is converted to a string using the function defined by filterPredicate.
    // May be overridden for customization.
    this.filteredData = this.filter == null || this.filter === '' ? data : data.filter(obj => this.filterPredicate(obj, this.filter));
    if (this.paginator) {
      this._updatePaginator(this.filteredData.length);
    }
    return this.filteredData;
  }
  /**
   * Returns a sorted copy of the data if MatSort has a sort applied, otherwise just returns the
   * data array as provided. Uses the default data accessor for data lookup, unless a
   * sortDataAccessor function is defined.
   */
  _orderData(data) {
    // If there is no active sort or direction, return the data without trying to sort.
    if (!this.sort) {
      return data;
    }
    return this.sortData(data.slice(), this.sort);
  }
  /**
   * Returns a paged slice of the provided data array according to the provided paginator's page
   * index and length. If there is no paginator provided, returns the data array as provided.
   */
  _pageData(data) {
    if (!this.paginator) {
      return data;
    }
    const startIndex = this.paginator.pageIndex * this.paginator.pageSize;
    return data.slice(startIndex, startIndex + this.paginator.pageSize);
  }
  /**
   * Updates the paginator to reflect the length of the filtered data, and makes sure that the page
   * index does not exceed the paginator's last page. Values are changed in a resolved promise to
   * guard against making property changes within a round of change detection.
   */
  _updatePaginator(filteredDataLength) {
    Promise.resolve().then(() => {
      const paginator = this.paginator;
      if (!paginator) {
        return;
      }
      paginator.length = filteredDataLength;
      // If the page index is set beyond the page, reduce it to the last page.
      if (paginator.pageIndex > 0) {
        const lastPageIndex = Math.ceil(paginator.length / paginator.pageSize) - 1 || 0;
        const newPageIndex = Math.min(paginator.pageIndex, lastPageIndex);
        if (newPageIndex !== paginator.pageIndex) {
          paginator.pageIndex = newPageIndex;
          // Since the paginator only emits after user-generated changes,
          // we need our own stream so we know to should re-render the data.
          this._internalPageChanges.next();
        }
      }
    });
  }
  /**
   * Used by the MatTable. Called when it connects to the data source.
   * @docs-private
   */
  connect() {
    if (!this._renderChangesSubscription) {
      this._updateChangeSubscription();
    }
    return this._renderData;
  }
  /**
   * Used by the MatTable. Called when it disconnects from the data source.
   * @docs-private
   */
  disconnect() {
    this._renderChangesSubscription?.unsubscribe();
    this._renderChangesSubscription = null;
  }
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 43835:
/*!************************************************************************!*\
  !*** ./node_modules/@angular/platform-browser/fesm2022/animations.mjs ***!
  \************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ANIMATION_MODULE_TYPE: () => (/* reexport safe */ _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE),
/* harmony export */   BrowserAnimationsModule: () => (/* binding */ BrowserAnimationsModule),
/* harmony export */   NoopAnimationsModule: () => (/* binding */ NoopAnimationsModule),
/* harmony export */   provideAnimations: () => (/* binding */ provideAnimations),
/* harmony export */   provideNoopAnimations: () => (/* binding */ provideNoopAnimations),
/* harmony export */   "ɵInjectableAnimationEngine": () => (/* binding */ InjectableAnimationEngine)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/platform-browser */ 80436);
/* harmony import */ var _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/animations/browser */ 10655);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 60316);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */








class InjectableAnimationEngine extends _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationEngine"] {
  // The `ApplicationRef` is injected here explicitly to force the dependency ordering.
  // Since the `ApplicationRef` should be created earlier before the `AnimationEngine`, they
  // both have `ngOnDestroy` hooks and `flush()` must be called after all views are destroyed.
  constructor(doc, driver, normalizer) {
    super(doc, driver, normalizer, (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵChangeDetectionScheduler"], {
      optional: true
    }));
  }
  ngOnDestroy() {
    this.flush();
  }
  static {
    this.ɵfac = function InjectableAnimationEngine_Factory(t) {
      return new (t || InjectableAnimationEngine)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__.AnimationDriver), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationStyleNormalizer"]));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: InjectableAnimationEngine,
      factory: InjectableAnimationEngine.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InjectableAnimationEngine, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT]
    }]
  }, {
    type: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__.AnimationDriver
  }, {
    type: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationStyleNormalizer"]
  }], null);
})();
function instantiateDefaultStyleNormalizer() {
  return new _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵWebAnimationsStyleNormalizer"]();
}
function instantiateRendererFactory(renderer, engine, zone) {
  return new _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationRendererFactory"](renderer, engine, zone);
}
const SHARED_ANIMATION_PROVIDERS = [{
  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationStyleNormalizer"],
  useFactory: instantiateDefaultStyleNormalizer
}, {
  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationEngine"],
  useClass: InjectableAnimationEngine
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.RendererFactory2,
  useFactory: instantiateRendererFactory,
  deps: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__["ɵDomRendererFactory2"], _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵAnimationEngine"], _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone]
}];
/**
 * Separate providers from the actual module so that we can do a local modification in Google3 to
 * include them in the BrowserModule.
 */
const BROWSER_ANIMATIONS_PROVIDERS = [{
  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__.AnimationDriver,
  useFactory: () => new _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__["ɵWebAnimationsDriver"]()
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE,
  useValue: 'BrowserAnimations'
}, ...SHARED_ANIMATION_PROVIDERS];
/**
 * Separate providers from the actual module so that we can do a local modification in Google3 to
 * include them in the BrowserTestingModule.
 */
const BROWSER_NOOP_ANIMATIONS_PROVIDERS = [{
  provide: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__.AnimationDriver,
  useClass: _angular_animations_browser__WEBPACK_IMPORTED_MODULE_1__.NoopAnimationDriver
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ANIMATION_MODULE_TYPE,
  useValue: 'NoopAnimations'
}, ...SHARED_ANIMATION_PROVIDERS];

/**
 * Exports `BrowserModule` with additional [dependency-injection providers](guide/glossary#provider)
 * for use with animations. See [Animations](guide/animations).
 * @publicApi
 */
class BrowserAnimationsModule {
  /**
   * Configures the module based on the specified object.
   *
   * @param config Object used to configure the behavior of the `BrowserAnimationsModule`.
   * @see {@link BrowserAnimationsModuleConfig}
   *
   * @usageNotes
   * When registering the `BrowserAnimationsModule`, you can use the `withConfig`
   * function as follows:
   * ```
   * @NgModule({
   *   imports: [BrowserAnimationsModule.withConfig(config)]
   * })
   * class MyNgModule {}
   * ```
   */
  static withConfig(config) {
    return {
      ngModule: BrowserAnimationsModule,
      providers: config.disableAnimations ? BROWSER_NOOP_ANIMATIONS_PROVIDERS : BROWSER_ANIMATIONS_PROVIDERS
    };
  }
  static {
    this.ɵfac = function BrowserAnimationsModule_Factory(t) {
      return new (t || BrowserAnimationsModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: BrowserAnimationsModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: BROWSER_ANIMATIONS_PROVIDERS,
      imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BrowserAnimationsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule],
      providers: BROWSER_ANIMATIONS_PROVIDERS
    }]
  }], null, null);
})();
/**
 * Returns the set of [dependency-injection providers](guide/glossary#provider)
 * to enable animations in an application. See [animations guide](guide/animations)
 * to learn more about animations in Angular.
 *
 * @usageNotes
 *
 * The function is useful when you want to enable animations in an application
 * bootstrapped using the `bootstrapApplication` function. In this scenario there
 * is no need to import the `BrowserAnimationsModule` NgModule at all, just add
 * providers returned by this function to the `providers` list as show below.
 *
 * ```typescript
 * bootstrapApplication(RootComponent, {
 *   providers: [
 *     provideAnimations()
 *   ]
 * });
 * ```
 *
 * @publicApi
 */
function provideAnimations() {
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵperformanceMarkFeature"])('NgEagerAnimations');
  // Return a copy to prevent changes to the original array in case any in-place
  // alterations are performed to the `provideAnimations` call results in app code.
  return [...BROWSER_ANIMATIONS_PROVIDERS];
}
/**
 * A null player that must be imported to allow disabling of animations.
 * @publicApi
 */
class NoopAnimationsModule {
  static {
    this.ɵfac = function NoopAnimationsModule_Factory(t) {
      return new (t || NoopAnimationsModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NoopAnimationsModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: BROWSER_NOOP_ANIMATIONS_PROVIDERS,
      imports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NoopAnimationsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: [_angular_platform_browser__WEBPACK_IMPORTED_MODULE_3__.BrowserModule],
      providers: BROWSER_NOOP_ANIMATIONS_PROVIDERS
    }]
  }], null, null);
})();
/**
 * Returns the set of [dependency-injection providers](guide/glossary#provider)
 * to disable animations in an application. See [animations guide](guide/animations)
 * to learn more about animations in Angular.
 *
 * @usageNotes
 *
 * The function is useful when you want to bootstrap an application using
 * the `bootstrapApplication` function, but you need to disable animations
 * (for example, when running tests).
 *
 * ```typescript
 * bootstrapApplication(RootComponent, {
 *   providers: [
 *     provideNoopAnimations()
 *   ]
 * });
 * ```
 *
 * @publicApi
 */
function provideNoopAnimations() {
  // Return a copy to prevent changes to the original array in case any in-place
  // alterations are performed to the `provideNoopAnimations` call results in app code.
  return [...BROWSER_NOOP_ANIMATIONS_PROVIDERS];
}

/**
 * @module
 * @description
 * Entry point for all animation APIs of the animation browser package.
 */

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 80436:
/*!******************************************************************************!*\
  !*** ./node_modules/@angular/platform-browser/fesm2022/platform-browser.mjs ***!
  \******************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   BrowserModule: () => (/* binding */ BrowserModule),
/* harmony export */   By: () => (/* binding */ By),
/* harmony export */   DomSanitizer: () => (/* binding */ DomSanitizer),
/* harmony export */   EVENT_MANAGER_PLUGINS: () => (/* binding */ EVENT_MANAGER_PLUGINS),
/* harmony export */   EventManager: () => (/* binding */ EventManager),
/* harmony export */   EventManagerPlugin: () => (/* binding */ EventManagerPlugin),
/* harmony export */   HAMMER_GESTURE_CONFIG: () => (/* binding */ HAMMER_GESTURE_CONFIG),
/* harmony export */   HAMMER_LOADER: () => (/* binding */ HAMMER_LOADER),
/* harmony export */   HammerGestureConfig: () => (/* binding */ HammerGestureConfig),
/* harmony export */   HammerModule: () => (/* binding */ HammerModule),
/* harmony export */   HydrationFeatureKind: () => (/* binding */ HydrationFeatureKind),
/* harmony export */   Meta: () => (/* binding */ Meta),
/* harmony export */   REMOVE_STYLES_ON_COMPONENT_DESTROY: () => (/* binding */ REMOVE_STYLES_ON_COMPONENT_DESTROY),
/* harmony export */   Title: () => (/* binding */ Title),
/* harmony export */   TransferState: () => (/* binding */ TransferState),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   bootstrapApplication: () => (/* binding */ bootstrapApplication),
/* harmony export */   createApplication: () => (/* binding */ createApplication),
/* harmony export */   disableDebugTools: () => (/* binding */ disableDebugTools),
/* harmony export */   enableDebugTools: () => (/* binding */ enableDebugTools),
/* harmony export */   makeStateKey: () => (/* binding */ makeStateKey),
/* harmony export */   platformBrowser: () => (/* binding */ platformBrowser),
/* harmony export */   provideClientHydration: () => (/* binding */ provideClientHydration),
/* harmony export */   provideProtractorTestingSupport: () => (/* binding */ provideProtractorTestingSupport),
/* harmony export */   withHttpTransferCacheOptions: () => (/* binding */ withHttpTransferCacheOptions),
/* harmony export */   withNoHttpTransferCache: () => (/* binding */ withNoHttpTransferCache),
/* harmony export */   "ɵBrowserDomAdapter": () => (/* binding */ BrowserDomAdapter),
/* harmony export */   "ɵBrowserGetTestability": () => (/* binding */ BrowserGetTestability),
/* harmony export */   "ɵDomEventsPlugin": () => (/* binding */ DomEventsPlugin),
/* harmony export */   "ɵDomRendererFactory2": () => (/* binding */ DomRendererFactory2),
/* harmony export */   "ɵDomSanitizerImpl": () => (/* binding */ DomSanitizerImpl),
/* harmony export */   "ɵHammerGesturesPlugin": () => (/* binding */ HammerGesturesPlugin),
/* harmony export */   "ɵINTERNAL_BROWSER_PLATFORM_PROVIDERS": () => (/* binding */ INTERNAL_BROWSER_PLATFORM_PROVIDERS),
/* harmony export */   "ɵKeyEventsPlugin": () => (/* binding */ KeyEventsPlugin),
/* harmony export */   "ɵSharedStylesHost": () => (/* binding */ SharedStylesHost),
/* harmony export */   "ɵgetDOM": () => (/* reexport safe */ _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"]),
/* harmony export */   "ɵinitDomAdapter": () => (/* binding */ initDomAdapter)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_common_http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common/http */ 46443);
/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */







/**
 * Provides DOM operations in any browser environment.
 *
 * @security Tread carefully! Interacting with the DOM directly is dangerous and
 * can introduce XSS risks.
 */
class GenericBrowserDomAdapter extends _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵDomAdapter"] {
  constructor() {
    super(...arguments);
    this.supportsDOMEvents = true;
  }
}

/**
 * A `DomAdapter` powered by full browser DOM APIs.
 *
 * @security Tread carefully! Interacting with the DOM directly is dangerous and
 * can introduce XSS risks.
 */
/* tslint:disable:requireParameterType no-console */
class BrowserDomAdapter extends GenericBrowserDomAdapter {
  static makeCurrent() {
    (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵsetRootDomAdapter"])(new BrowserDomAdapter());
  }
  onAndCancel(el, evt, listener) {
    el.addEventListener(evt, listener);
    return () => {
      el.removeEventListener(evt, listener);
    };
  }
  dispatchEvent(el, evt) {
    el.dispatchEvent(evt);
  }
  remove(node) {
    if (node.parentNode) {
      node.parentNode.removeChild(node);
    }
  }
  createElement(tagName, doc) {
    doc = doc || this.getDefaultDocument();
    return doc.createElement(tagName);
  }
  createHtmlDocument() {
    return document.implementation.createHTMLDocument('fakeTitle');
  }
  getDefaultDocument() {
    return document;
  }
  isElementNode(node) {
    return node.nodeType === Node.ELEMENT_NODE;
  }
  isShadowRoot(node) {
    return node instanceof DocumentFragment;
  }
  /** @deprecated No longer being used in Ivy code. To be removed in version 14. */
  getGlobalEventTarget(doc, target) {
    if (target === 'window') {
      return window;
    }
    if (target === 'document') {
      return doc;
    }
    if (target === 'body') {
      return doc.body;
    }
    return null;
  }
  getBaseHref(doc) {
    const href = getBaseElementHref();
    return href == null ? null : relativePath(href);
  }
  resetBaseElement() {
    baseElement = null;
  }
  getUserAgent() {
    return window.navigator.userAgent;
  }
  getCookie(name) {
    return (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵparseCookieValue"])(document.cookie, name);
  }
}
let baseElement = null;
function getBaseElementHref() {
  baseElement = baseElement || document.querySelector('base');
  return baseElement ? baseElement.getAttribute('href') : null;
}
function relativePath(url) {
  // The base URL doesn't really matter, we just need it so relative paths have something
  // to resolve against. In the browser `HTMLBaseElement.href` is always absolute.
  return new URL(url, document.baseURI).pathname;
}
class BrowserGetTestability {
  addToWindow(registry) {
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['getAngularTestability'] = (elem, findInAncestors = true) => {
      const testability = registry.findTestabilityInTree(elem, findInAncestors);
      if (testability == null) {
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5103 /* RuntimeErrorCode.TESTABILITY_NOT_FOUND */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Could not find testability for element.');
      }
      return testability;
    };
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['getAllAngularTestabilities'] = () => registry.getAllTestabilities();
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['getAllAngularRootElements'] = () => registry.getAllRootElements();
    const whenAllStable = callback => {
      const testabilities = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['getAllAngularTestabilities']();
      let count = testabilities.length;
      const decrement = function () {
        count--;
        if (count == 0) {
          callback();
        }
      };
      testabilities.forEach(testability => {
        testability.whenStable(decrement);
      });
    };
    if (!_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['frameworkStabilizers']) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['frameworkStabilizers'] = [];
    }
    _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['frameworkStabilizers'].push(whenAllStable);
  }
  findTestabilityInTree(registry, elem, findInAncestors) {
    if (elem == null) {
      return null;
    }
    const t = registry.getTestability(elem);
    if (t != null) {
      return t;
    } else if (!findInAncestors) {
      return null;
    }
    if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().isShadowRoot(elem)) {
      return this.findTestabilityInTree(registry, elem.host, true);
    }
    return this.findTestabilityInTree(registry, elem.parentElement, true);
  }
}

/**
 * A factory for `HttpXhrBackend` that uses the `XMLHttpRequest` browser API.
 */
class BrowserXhr {
  build() {
    return new XMLHttpRequest();
  }
  static {
    this.ɵfac = function BrowserXhr_Factory(t) {
      return new (t || BrowserXhr)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: BrowserXhr,
      factory: BrowserXhr.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BrowserXhr, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();

/**
 * The injection token for plugins of the `EventManager` service.
 *
 * @publicApi
 */
const EVENT_MANAGER_PLUGINS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken(ngDevMode ? 'EventManagerPlugins' : '');
/**
 * An injectable service that provides event management for Angular
 * through a browser plug-in.
 *
 * @publicApi
 */
class EventManager {
  /**
   * Initializes an instance of the event-manager service.
   */
  constructor(plugins, _zone) {
    this._zone = _zone;
    this._eventNameToPlugin = new Map();
    plugins.forEach(plugin => {
      plugin.manager = this;
    });
    this._plugins = plugins.slice().reverse();
  }
  /**
   * Registers a handler for a specific element and event.
   *
   * @param element The HTML element to receive event notifications.
   * @param eventName The name of the event to listen for.
   * @param handler A function to call when the notification occurs. Receives the
   * event object as an argument.
   * @returns  A callback function that can be used to remove the handler.
   */
  addEventListener(element, eventName, handler) {
    const plugin = this._findPluginFor(eventName);
    return plugin.addEventListener(element, eventName, handler);
  }
  /**
   * Retrieves the compilation zone in which event listeners are registered.
   */
  getZone() {
    return this._zone;
  }
  /** @internal */
  _findPluginFor(eventName) {
    let plugin = this._eventNameToPlugin.get(eventName);
    if (plugin) {
      return plugin;
    }
    const plugins = this._plugins;
    plugin = plugins.find(plugin => plugin.supports(eventName));
    if (!plugin) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5101 /* RuntimeErrorCode.NO_PLUGIN_FOR_EVENT */, (typeof ngDevMode === 'undefined' || ngDevMode) && `No event manager plugin found for event ${eventName}`);
    }
    this._eventNameToPlugin.set(eventName, plugin);
    return plugin;
  }
  static {
    this.ɵfac = function EventManager_Factory(t) {
      return new (t || EventManager)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](EVENT_MANAGER_PLUGINS), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: EventManager,
      factory: EventManager.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](EventManager, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [EVENT_MANAGER_PLUGINS]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], null);
})();
/**
 * The plugin definition for the `EventManager` class
 *
 * It can be used as a base class to create custom manager plugins, i.e. you can create your own
 * class that extends the `EventManagerPlugin` one.
 *
 * @publicApi
 */
class EventManagerPlugin {
  // TODO: remove (has some usage in G3)
  constructor(_doc) {
    this._doc = _doc;
  }
}

/** The style elements attribute name used to set value of `APP_ID` token. */
const APP_ID_ATTRIBUTE_NAME = 'ng-app-id';
class SharedStylesHost {
  constructor(doc, appId, nonce, platformId = {}) {
    this.doc = doc;
    this.appId = appId;
    this.nonce = nonce;
    this.platformId = platformId;
    // Maps all registered host nodes to a list of style nodes that have been added to the host node.
    this.styleRef = new Map();
    this.hostNodes = new Set();
    this.styleNodesInDOM = this.collectServerRenderedStyles();
    this.platformIsServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__.isPlatformServer)(platformId);
    this.resetHostNodes();
  }
  addStyles(styles) {
    for (const style of styles) {
      const usageCount = this.changeUsageCount(style, 1);
      if (usageCount === 1) {
        this.onStyleAdded(style);
      }
    }
  }
  removeStyles(styles) {
    for (const style of styles) {
      const usageCount = this.changeUsageCount(style, -1);
      if (usageCount <= 0) {
        this.onStyleRemoved(style);
      }
    }
  }
  ngOnDestroy() {
    const styleNodesInDOM = this.styleNodesInDOM;
    if (styleNodesInDOM) {
      styleNodesInDOM.forEach(node => node.remove());
      styleNodesInDOM.clear();
    }
    for (const style of this.getAllStyles()) {
      this.onStyleRemoved(style);
    }
    this.resetHostNodes();
  }
  addHost(hostNode) {
    this.hostNodes.add(hostNode);
    for (const style of this.getAllStyles()) {
      this.addStyleToHost(hostNode, style);
    }
  }
  removeHost(hostNode) {
    this.hostNodes.delete(hostNode);
  }
  getAllStyles() {
    return this.styleRef.keys();
  }
  onStyleAdded(style) {
    for (const host of this.hostNodes) {
      this.addStyleToHost(host, style);
    }
  }
  onStyleRemoved(style) {
    const styleRef = this.styleRef;
    styleRef.get(style)?.elements?.forEach(node => node.remove());
    styleRef.delete(style);
  }
  collectServerRenderedStyles() {
    const styles = this.doc.head?.querySelectorAll(`style[${APP_ID_ATTRIBUTE_NAME}="${this.appId}"]`);
    if (styles?.length) {
      const styleMap = new Map();
      styles.forEach(style => {
        if (style.textContent != null) {
          styleMap.set(style.textContent, style);
        }
      });
      return styleMap;
    }
    return null;
  }
  changeUsageCount(style, delta) {
    const map = this.styleRef;
    if (map.has(style)) {
      const styleRefValue = map.get(style);
      styleRefValue.usage += delta;
      return styleRefValue.usage;
    }
    map.set(style, {
      usage: delta,
      elements: []
    });
    return delta;
  }
  getStyleElement(host, style) {
    const styleNodesInDOM = this.styleNodesInDOM;
    const styleEl = styleNodesInDOM?.get(style);
    if (styleEl?.parentNode === host) {
      // `styleNodesInDOM` cannot be undefined due to the above `styleNodesInDOM?.get`.
      styleNodesInDOM.delete(style);
      styleEl.removeAttribute(APP_ID_ATTRIBUTE_NAME);
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        // This attribute is solely used for debugging purposes.
        styleEl.setAttribute('ng-style-reused', '');
      }
      return styleEl;
    } else {
      const styleEl = this.doc.createElement('style');
      if (this.nonce) {
        styleEl.setAttribute('nonce', this.nonce);
      }
      styleEl.textContent = style;
      if (this.platformIsServer) {
        styleEl.setAttribute(APP_ID_ATTRIBUTE_NAME, this.appId);
      }
      host.appendChild(styleEl);
      return styleEl;
    }
  }
  addStyleToHost(host, style) {
    const styleEl = this.getStyleElement(host, style);
    const styleRef = this.styleRef;
    const styleElRef = styleRef.get(style)?.elements;
    if (styleElRef) {
      styleElRef.push(styleEl);
    } else {
      styleRef.set(style, {
        elements: [styleEl],
        usage: 1
      });
    }
  }
  resetHostNodes() {
    const hostNodes = this.hostNodes;
    hostNodes.clear();
    // Re-add the head element back since this is the default host.
    hostNodes.add(this.doc.head);
  }
  static {
    this.ɵfac = function SharedStylesHost_Factory(t) {
      return new (t || SharedStylesHost)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.CSP_NONCE, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: SharedStylesHost,
      factory: SharedStylesHost.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](SharedStylesHost, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.CSP_NONCE]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
    }]
  }], null);
})();
const NAMESPACE_URIS = {
  'svg': 'http://www.w3.org/2000/svg',
  'xhtml': 'http://www.w3.org/1999/xhtml',
  'xlink': 'http://www.w3.org/1999/xlink',
  'xml': 'http://www.w3.org/XML/1998/namespace',
  'xmlns': 'http://www.w3.org/2000/xmlns/',
  'math': 'http://www.w3.org/1998/MathML/'
};
const COMPONENT_REGEX = /%COMP%/g;
const COMPONENT_VARIABLE = '%COMP%';
const HOST_ATTR = `_nghost-${COMPONENT_VARIABLE}`;
const CONTENT_ATTR = `_ngcontent-${COMPONENT_VARIABLE}`;
/**
 * The default value for the `REMOVE_STYLES_ON_COMPONENT_DESTROY` DI token.
 */
const REMOVE_STYLES_ON_COMPONENT_DESTROY_DEFAULT = true;
/**
 * A [DI token](guide/glossary#di-token "DI token definition") that indicates whether styles
 * of destroyed components should be removed from DOM.
 *
 * By default, the value is set to `true`.
 * @publicApi
 */
const REMOVE_STYLES_ON_COMPONENT_DESTROY = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken(ngDevMode ? 'RemoveStylesOnCompDestroy' : '', {
  providedIn: 'root',
  factory: () => REMOVE_STYLES_ON_COMPONENT_DESTROY_DEFAULT
});
function shimContentAttribute(componentShortId) {
  return CONTENT_ATTR.replace(COMPONENT_REGEX, componentShortId);
}
function shimHostAttribute(componentShortId) {
  return HOST_ATTR.replace(COMPONENT_REGEX, componentShortId);
}
function shimStylesContent(compId, styles) {
  return styles.map(s => s.replace(COMPONENT_REGEX, compId));
}
class DomRendererFactory2 {
  constructor(eventManager, sharedStylesHost, appId, removeStylesOnCompDestroy, doc, platformId, ngZone, nonce = null) {
    this.eventManager = eventManager;
    this.sharedStylesHost = sharedStylesHost;
    this.appId = appId;
    this.removeStylesOnCompDestroy = removeStylesOnCompDestroy;
    this.doc = doc;
    this.platformId = platformId;
    this.ngZone = ngZone;
    this.nonce = nonce;
    this.rendererByCompId = new Map();
    this.platformIsServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__.isPlatformServer)(platformId);
    this.defaultRenderer = new DefaultDomRenderer2(eventManager, doc, ngZone, this.platformIsServer);
  }
  createRenderer(element, type) {
    if (!element || !type) {
      return this.defaultRenderer;
    }
    if (this.platformIsServer && type.encapsulation === _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.ShadowDom) {
      // Domino does not support shadow DOM.
      type = {
        ...type,
        encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.Emulated
      };
    }
    const renderer = this.getOrCreateRenderer(element, type);
    // Renderers have different logic due to different encapsulation behaviours.
    // Ex: for emulated, an attribute is added to the element.
    if (renderer instanceof EmulatedEncapsulationDomRenderer2) {
      renderer.applyToHost(element);
    } else if (renderer instanceof NoneEncapsulationDomRenderer) {
      renderer.applyStyles();
    }
    return renderer;
  }
  getOrCreateRenderer(element, type) {
    const rendererByCompId = this.rendererByCompId;
    let renderer = rendererByCompId.get(type.id);
    if (!renderer) {
      const doc = this.doc;
      const ngZone = this.ngZone;
      const eventManager = this.eventManager;
      const sharedStylesHost = this.sharedStylesHost;
      const removeStylesOnCompDestroy = this.removeStylesOnCompDestroy;
      const platformIsServer = this.platformIsServer;
      switch (type.encapsulation) {
        case _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.Emulated:
          renderer = new EmulatedEncapsulationDomRenderer2(eventManager, sharedStylesHost, type, this.appId, removeStylesOnCompDestroy, doc, ngZone, platformIsServer);
          break;
        case _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.ShadowDom:
          return new ShadowDomRenderer(eventManager, sharedStylesHost, element, type, doc, ngZone, this.nonce, platformIsServer);
        default:
          renderer = new NoneEncapsulationDomRenderer(eventManager, sharedStylesHost, type, removeStylesOnCompDestroy, doc, ngZone, platformIsServer);
          break;
      }
      rendererByCompId.set(type.id, renderer);
    }
    return renderer;
  }
  ngOnDestroy() {
    this.rendererByCompId.clear();
  }
  static {
    this.ɵfac = function DomRendererFactory2_Factory(t) {
      return new (t || DomRendererFactory2)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](EventManager), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](SharedStylesHost), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](REMOVE_STYLES_ON_COMPONENT_DESTROY), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.CSP_NONCE));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DomRendererFactory2,
      factory: DomRendererFactory2.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomRendererFactory2, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: EventManager
  }, {
    type: SharedStylesHost
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [REMOVE_STYLES_ON_COMPONENT_DESTROY]
    }]
  }, {
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }, {
    type: Object,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.CSP_NONCE]
    }]
  }], null);
})();
class DefaultDomRenderer2 {
  constructor(eventManager, doc, ngZone, platformIsServer) {
    this.eventManager = eventManager;
    this.doc = doc;
    this.ngZone = ngZone;
    this.platformIsServer = platformIsServer;
    this.data = Object.create(null);
    /**
     * By default this renderer throws when encountering synthetic properties
     * This can be disabled for example by the AsyncAnimationRendererFactory
     */
    this.throwOnSyntheticProps = true;
    this.destroyNode = null;
  }
  destroy() {}
  createElement(name, namespace) {
    if (namespace) {
      // TODO: `|| namespace` was added in
      // https://github.com/angular/angular/commit/2b9cc8503d48173492c29f5a271b61126104fbdb to
      // support how Ivy passed around the namespace URI rather than short name at the time. It did
      // not, however extend the support to other parts of the system (setAttribute, setAttribute,
      // and the ServerRenderer). We should decide what exactly the semantics for dealing with
      // namespaces should be and make it consistent.
      // Related issues:
      // https://github.com/angular/angular/issues/44028
      // https://github.com/angular/angular/issues/44883
      return this.doc.createElementNS(NAMESPACE_URIS[namespace] || namespace, name);
    }
    return this.doc.createElement(name);
  }
  createComment(value) {
    return this.doc.createComment(value);
  }
  createText(value) {
    return this.doc.createTextNode(value);
  }
  appendChild(parent, newChild) {
    const targetParent = isTemplateNode(parent) ? parent.content : parent;
    targetParent.appendChild(newChild);
  }
  insertBefore(parent, newChild, refChild) {
    if (parent) {
      const targetParent = isTemplateNode(parent) ? parent.content : parent;
      targetParent.insertBefore(newChild, refChild);
    }
  }
  removeChild(parent, oldChild) {
    if (parent) {
      parent.removeChild(oldChild);
    }
  }
  selectRootElement(selectorOrNode, preserveContent) {
    let el = typeof selectorOrNode === 'string' ? this.doc.querySelector(selectorOrNode) : selectorOrNode;
    if (!el) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](-5104 /* RuntimeErrorCode.ROOT_NODE_NOT_FOUND */, (typeof ngDevMode === 'undefined' || ngDevMode) && `The selector "${selectorOrNode}" did not match any elements`);
    }
    if (!preserveContent) {
      el.textContent = '';
    }
    return el;
  }
  parentNode(node) {
    return node.parentNode;
  }
  nextSibling(node) {
    return node.nextSibling;
  }
  setAttribute(el, name, value, namespace) {
    if (namespace) {
      name = namespace + ':' + name;
      const namespaceUri = NAMESPACE_URIS[namespace];
      if (namespaceUri) {
        el.setAttributeNS(namespaceUri, name, value);
      } else {
        el.setAttribute(name, value);
      }
    } else {
      el.setAttribute(name, value);
    }
  }
  removeAttribute(el, name, namespace) {
    if (namespace) {
      const namespaceUri = NAMESPACE_URIS[namespace];
      if (namespaceUri) {
        el.removeAttributeNS(namespaceUri, name);
      } else {
        el.removeAttribute(`${namespace}:${name}`);
      }
    } else {
      el.removeAttribute(name);
    }
  }
  addClass(el, name) {
    el.classList.add(name);
  }
  removeClass(el, name) {
    el.classList.remove(name);
  }
  setStyle(el, style, value, flags) {
    if (flags & (_angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.DashCase | _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.Important)) {
      el.style.setProperty(style, value, flags & _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.Important ? 'important' : '');
    } else {
      el.style[style] = value;
    }
  }
  removeStyle(el, style, flags) {
    if (flags & _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererStyleFlags2.DashCase) {
      // removeProperty has no effect when used on camelCased properties.
      el.style.removeProperty(style);
    } else {
      el.style[style] = '';
    }
  }
  setProperty(el, name, value) {
    if (el == null) {
      return;
    }
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.throwOnSyntheticProps && checkNoSyntheticProp(name, 'property');
    el[name] = value;
  }
  setValue(node, value) {
    node.nodeValue = value;
  }
  listen(target, event, callback) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && this.throwOnSyntheticProps && checkNoSyntheticProp(event, 'listener');
    if (typeof target === 'string') {
      target = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().getGlobalEventTarget(this.doc, target);
      if (!target) {
        throw new Error(`Unsupported event target ${target} for event ${event}`);
      }
    }
    return this.eventManager.addEventListener(target, event, this.decoratePreventDefault(callback));
  }
  decoratePreventDefault(eventHandler) {
    // `DebugNode.triggerEventHandler` needs to know if the listener was created with
    // decoratePreventDefault or is a listener added outside the Angular context so it can handle
    // the two differently. In the first case, the special '__ngUnwrap__' token is passed to the
    // unwrap the listener (see below).
    return event => {
      // Ivy uses '__ngUnwrap__' as a special token that allows us to unwrap the function
      // so that it can be invoked programmatically by `DebugNode.triggerEventHandler`. The
      // debug_node can inspect the listener toString contents for the existence of this special
      // token. Because the token is a string literal, it is ensured to not be modified by compiled
      // code.
      if (event === '__ngUnwrap__') {
        return eventHandler;
      }
      // Run the event handler inside the ngZone because event handlers are not patched
      // by Zone on the server. This is required only for tests.
      const allowDefaultBehavior = this.platformIsServer ? this.ngZone.runGuarded(() => eventHandler(event)) : eventHandler(event);
      if (allowDefaultBehavior === false) {
        event.preventDefault();
      }
      return undefined;
    };
  }
}
const AT_CHARCODE = (() => '@'.charCodeAt(0))();
function checkNoSyntheticProp(name, nameKind) {
  if (name.charCodeAt(0) === AT_CHARCODE) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5105 /* RuntimeErrorCode.UNEXPECTED_SYNTHETIC_PROPERTY */, `Unexpected synthetic ${nameKind} ${name} found. Please make sure that:
  - Either \`BrowserAnimationsModule\` or \`NoopAnimationsModule\` are imported in your application.
  - There is corresponding configuration for the animation named \`${name}\` defined in the \`animations\` field of the \`@Component\` decorator (see https://angular.io/api/core/Component#animations).`);
  }
}
function isTemplateNode(node) {
  return node.tagName === 'TEMPLATE' && node.content !== undefined;
}
class ShadowDomRenderer extends DefaultDomRenderer2 {
  constructor(eventManager, sharedStylesHost, hostEl, component, doc, ngZone, nonce, platformIsServer) {
    super(eventManager, doc, ngZone, platformIsServer);
    this.sharedStylesHost = sharedStylesHost;
    this.hostEl = hostEl;
    this.shadowRoot = hostEl.attachShadow({
      mode: 'open'
    });
    this.sharedStylesHost.addHost(this.shadowRoot);
    const styles = shimStylesContent(component.id, component.styles);
    for (const style of styles) {
      const styleEl = document.createElement('style');
      if (nonce) {
        styleEl.setAttribute('nonce', nonce);
      }
      styleEl.textContent = style;
      this.shadowRoot.appendChild(styleEl);
    }
  }
  nodeOrShadowRoot(node) {
    return node === this.hostEl ? this.shadowRoot : node;
  }
  appendChild(parent, newChild) {
    return super.appendChild(this.nodeOrShadowRoot(parent), newChild);
  }
  insertBefore(parent, newChild, refChild) {
    return super.insertBefore(this.nodeOrShadowRoot(parent), newChild, refChild);
  }
  removeChild(parent, oldChild) {
    return super.removeChild(this.nodeOrShadowRoot(parent), oldChild);
  }
  parentNode(node) {
    return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(node)));
  }
  destroy() {
    this.sharedStylesHost.removeHost(this.shadowRoot);
  }
}
class NoneEncapsulationDomRenderer extends DefaultDomRenderer2 {
  constructor(eventManager, sharedStylesHost, component, removeStylesOnCompDestroy, doc, ngZone, platformIsServer, compId) {
    super(eventManager, doc, ngZone, platformIsServer);
    this.sharedStylesHost = sharedStylesHost;
    this.removeStylesOnCompDestroy = removeStylesOnCompDestroy;
    this.styles = compId ? shimStylesContent(compId, component.styles) : component.styles;
  }
  applyStyles() {
    this.sharedStylesHost.addStyles(this.styles);
  }
  destroy() {
    if (!this.removeStylesOnCompDestroy) {
      return;
    }
    this.sharedStylesHost.removeStyles(this.styles);
  }
}
class EmulatedEncapsulationDomRenderer2 extends NoneEncapsulationDomRenderer {
  constructor(eventManager, sharedStylesHost, component, appId, removeStylesOnCompDestroy, doc, ngZone, platformIsServer) {
    const compId = appId + '-' + component.id;
    super(eventManager, sharedStylesHost, component, removeStylesOnCompDestroy, doc, ngZone, platformIsServer, compId);
    this.contentAttr = shimContentAttribute(compId);
    this.hostAttr = shimHostAttribute(compId);
  }
  applyToHost(element) {
    this.applyStyles();
    this.setAttribute(element, this.hostAttr, '');
  }
  createElement(parent, name) {
    const el = super.createElement(parent, name);
    super.setAttribute(el, this.contentAttr, '');
    return el;
  }
}
class DomEventsPlugin extends EventManagerPlugin {
  constructor(doc) {
    super(doc);
  }
  // This plugin should come last in the list of plugins, because it accepts all
  // events.
  supports(eventName) {
    return true;
  }
  addEventListener(element, eventName, handler) {
    element.addEventListener(eventName, handler, false);
    return () => this.removeEventListener(element, eventName, handler);
  }
  removeEventListener(target, eventName, callback) {
    return target.removeEventListener(eventName, callback);
  }
  static {
    this.ɵfac = function DomEventsPlugin_Factory(t) {
      return new (t || DomEventsPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DomEventsPlugin,
      factory: DomEventsPlugin.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomEventsPlugin, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }], null);
})();

/**
 * Defines supported modifiers for key events.
 */
const MODIFIER_KEYS = ['alt', 'control', 'meta', 'shift'];
// The following values are here for cross-browser compatibility and to match the W3C standard
// cf https://www.w3.org/TR/DOM-Level-3-Events-key/
const _keyMap = {
  '\b': 'Backspace',
  '\t': 'Tab',
  '\x7F': 'Delete',
  '\x1B': 'Escape',
  'Del': 'Delete',
  'Esc': 'Escape',
  'Left': 'ArrowLeft',
  'Right': 'ArrowRight',
  'Up': 'ArrowUp',
  'Down': 'ArrowDown',
  'Menu': 'ContextMenu',
  'Scroll': 'ScrollLock',
  'Win': 'OS'
};
/**
 * Retrieves modifiers from key-event objects.
 */
const MODIFIER_KEY_GETTERS = {
  'alt': event => event.altKey,
  'control': event => event.ctrlKey,
  'meta': event => event.metaKey,
  'shift': event => event.shiftKey
};
/**
 * A browser plug-in that provides support for handling of key events in Angular.
 */
class KeyEventsPlugin extends EventManagerPlugin {
  /**
   * Initializes an instance of the browser plug-in.
   * @param doc The document in which key events will be detected.
   */
  constructor(doc) {
    super(doc);
  }
  /**
   * Reports whether a named key event is supported.
   * @param eventName The event name to query.
   * @return True if the named key event is supported.
   */
  supports(eventName) {
    return KeyEventsPlugin.parseEventName(eventName) != null;
  }
  /**
   * Registers a handler for a specific element and key event.
   * @param element The HTML element to receive event notifications.
   * @param eventName The name of the key event to listen for.
   * @param handler A function to call when the notification occurs. Receives the
   * event object as an argument.
   * @returns The key event that was registered.
   */
  addEventListener(element, eventName, handler) {
    const parsedEvent = KeyEventsPlugin.parseEventName(eventName);
    const outsideHandler = KeyEventsPlugin.eventCallback(parsedEvent['fullKey'], handler, this.manager.getZone());
    return this.manager.getZone().runOutsideAngular(() => {
      return (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().onAndCancel(element, parsedEvent['domEventName'], outsideHandler);
    });
  }
  /**
   * Parses the user provided full keyboard event definition and normalizes it for
   * later internal use. It ensures the string is all lowercase, converts special
   * characters to a standard spelling, and orders all the values consistently.
   *
   * @param eventName The name of the key event to listen for.
   * @returns an object with the full, normalized string, and the dom event name
   * or null in the case when the event doesn't match a keyboard event.
   */
  static parseEventName(eventName) {
    const parts = eventName.toLowerCase().split('.');
    const domEventName = parts.shift();
    if (parts.length === 0 || !(domEventName === 'keydown' || domEventName === 'keyup')) {
      return null;
    }
    const key = KeyEventsPlugin._normalizeKey(parts.pop());
    let fullKey = '';
    let codeIX = parts.indexOf('code');
    if (codeIX > -1) {
      parts.splice(codeIX, 1);
      fullKey = 'code.';
    }
    MODIFIER_KEYS.forEach(modifierName => {
      const index = parts.indexOf(modifierName);
      if (index > -1) {
        parts.splice(index, 1);
        fullKey += modifierName + '.';
      }
    });
    fullKey += key;
    if (parts.length != 0 || key.length === 0) {
      // returning null instead of throwing to let another plugin process the event
      return null;
    }
    // NOTE: Please don't rewrite this as so, as it will break JSCompiler property renaming.
    //       The code must remain in the `result['domEventName']` form.
    // return {domEventName, fullKey};
    const result = {};
    result['domEventName'] = domEventName;
    result['fullKey'] = fullKey;
    return result;
  }
  /**
   * Determines whether the actual keys pressed match the configured key code string.
   * The `fullKeyCode` event is normalized in the `parseEventName` method when the
   * event is attached to the DOM during the `addEventListener` call. This is unseen
   * by the end user and is normalized for internal consistency and parsing.
   *
   * @param event The keyboard event.
   * @param fullKeyCode The normalized user defined expected key event string
   * @returns boolean.
   */
  static matchEventFullKeyCode(event, fullKeyCode) {
    let keycode = _keyMap[event.key] || event.key;
    let key = '';
    if (fullKeyCode.indexOf('code.') > -1) {
      keycode = event.code;
      key = 'code.';
    }
    // the keycode could be unidentified so we have to check here
    if (keycode == null || !keycode) return false;
    keycode = keycode.toLowerCase();
    if (keycode === ' ') {
      keycode = 'space'; // for readability
    } else if (keycode === '.') {
      keycode = 'dot'; // because '.' is used as a separator in event names
    }
    MODIFIER_KEYS.forEach(modifierName => {
      if (modifierName !== keycode) {
        const modifierGetter = MODIFIER_KEY_GETTERS[modifierName];
        if (modifierGetter(event)) {
          key += modifierName + '.';
        }
      }
    });
    key += keycode;
    return key === fullKeyCode;
  }
  /**
   * Configures a handler callback for a key event.
   * @param fullKey The event name that combines all simultaneous keystrokes.
   * @param handler The function that responds to the key event.
   * @param zone The zone in which the event occurred.
   * @returns A callback function.
   */
  static eventCallback(fullKey, handler, zone) {
    return event => {
      if (KeyEventsPlugin.matchEventFullKeyCode(event, fullKey)) {
        zone.runGuarded(() => handler(event));
      }
    };
  }
  /** @internal */
  static _normalizeKey(keyName) {
    return keyName === 'esc' ? 'escape' : keyName;
  }
  static {
    this.ɵfac = function KeyEventsPlugin_Factory(t) {
      return new (t || KeyEventsPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: KeyEventsPlugin,
      factory: KeyEventsPlugin.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](KeyEventsPlugin, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }], null);
})();

/**
 * Bootstraps an instance of an Angular application and renders a standalone component as the
 * application's root component. More information about standalone components can be found in [this
 * guide](guide/standalone-components).
 *
 * @usageNotes
 * The root component passed into this function *must* be a standalone one (should have the
 * `standalone: true` flag in the `@Component` decorator config).
 *
 * ```typescript
 * @Component({
 *   standalone: true,
 *   template: 'Hello world!'
 * })
 * class RootComponent {}
 *
 * const appRef: ApplicationRef = await bootstrapApplication(RootComponent);
 * ```
 *
 * You can add the list of providers that should be available in the application injector by
 * specifying the `providers` field in an object passed as the second argument:
 *
 * ```typescript
 * await bootstrapApplication(RootComponent, {
 *   providers: [
 *     {provide: BACKEND_URL, useValue: 'https://yourdomain.com/api'}
 *   ]
 * });
 * ```
 *
 * The `importProvidersFrom` helper method can be used to collect all providers from any
 * existing NgModule (and transitively from all NgModules that it imports):
 *
 * ```typescript
 * await bootstrapApplication(RootComponent, {
 *   providers: [
 *     importProvidersFrom(SomeNgModule)
 *   ]
 * });
 * ```
 *
 * Note: the `bootstrapApplication` method doesn't include [Testability](api/core/Testability) by
 * default. You can add [Testability](api/core/Testability) by getting the list of necessary
 * providers using `provideProtractorTestingSupport()` function and adding them into the `providers`
 * array, for example:
 *
 * ```typescript
 * import {provideProtractorTestingSupport} from '@angular/platform-browser';
 *
 * await bootstrapApplication(RootComponent, {providers: [provideProtractorTestingSupport()]});
 * ```
 *
 * @param rootComponent A reference to a standalone component that should be rendered.
 * @param options Extra configuration for the bootstrap operation, see `ApplicationConfig` for
 *     additional info.
 * @returns A promise that returns an `ApplicationRef` instance once resolved.
 *
 * @publicApi
 */
function bootstrapApplication(rootComponent, options) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵinternalCreateApplication"])({
    rootComponent,
    ...createProvidersConfig(options)
  });
}
/**
 * Create an instance of an Angular application without bootstrapping any components. This is useful
 * for the situation where one wants to decouple application environment creation (a platform and
 * associated injectors) from rendering components on a screen. Components can be subsequently
 * bootstrapped on the returned `ApplicationRef`.
 *
 * @param options Extra configuration for the application environment, see `ApplicationConfig` for
 *     additional info.
 * @returns A promise that returns an `ApplicationRef` instance once resolved.
 *
 * @publicApi
 */
function createApplication(options) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵinternalCreateApplication"])(createProvidersConfig(options));
}
function createProvidersConfig(options) {
  return {
    appProviders: [...BROWSER_MODULE_PROVIDERS, ...(options?.providers ?? [])],
    platformProviders: INTERNAL_BROWSER_PLATFORM_PROVIDERS
  };
}
/**
 * Returns a set of providers required to setup [Testability](api/core/Testability) for an
 * application bootstrapped using the `bootstrapApplication` function. The set of providers is
 * needed to support testing an application with Protractor (which relies on the Testability APIs
 * to be present).
 *
 * @returns An array of providers required to setup Testability for an application and make it
 *     available for testing using Protractor.
 *
 * @publicApi
 */
function provideProtractorTestingSupport() {
  // Return a copy to prevent changes to the original array in case any in-place
  // alterations are performed to the `provideProtractorTestingSupport` call results in app
  // code.
  return [...TESTABILITY_PROVIDERS];
}
function initDomAdapter() {
  BrowserDomAdapter.makeCurrent();
}
function errorHandler() {
  return new _angular_core__WEBPACK_IMPORTED_MODULE_1__.ErrorHandler();
}
function _document() {
  // Tell ivy about the global document
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetDocument"])(document);
  return document;
}
const INTERNAL_BROWSER_PLATFORM_PROVIDERS = [{
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID,
  useValue: _angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵPLATFORM_BROWSER_ID"]
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_INITIALIZER,
  useValue: initDomAdapter,
  multi: true
}, {
  provide: _angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT,
  useFactory: _document,
  deps: []
}];
/**
 * A factory function that returns a `PlatformRef` instance associated with browser service
 * providers.
 *
 * @publicApi
 */
const platformBrowser = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.createPlatformFactory)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.platformCore, 'browser', INTERNAL_BROWSER_PLATFORM_PROVIDERS);
/**
 * Internal marker to signal whether providers from the `BrowserModule` are already present in DI.
 * This is needed to avoid loading `BrowserModule` providers twice. We can't rely on the
 * `BrowserModule` presence itself, since the standalone-based bootstrap just imports
 * `BrowserModule` providers without referencing the module itself.
 */
const BROWSER_MODULE_PROVIDERS_MARKER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'BrowserModule Providers Marker' : '');
const TESTABILITY_PROVIDERS = [{
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"],
  useClass: BrowserGetTestability,
  deps: []
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY"],
  useClass: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
  deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.TestabilityRegistry, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"]]
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
  // Also provide as `Testability` for backwards-compatibility.
  useClass: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Testability,
  deps: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.TestabilityRegistry, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵTESTABILITY_GETTER"]]
}];
const BROWSER_MODULE_PROVIDERS = [{
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵINJECTOR_SCOPE"],
  useValue: 'root'
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ErrorHandler,
  useFactory: errorHandler,
  deps: []
}, {
  provide: EVENT_MANAGER_PLUGINS,
  useClass: DomEventsPlugin,
  multi: true,
  deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone, _angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
}, {
  provide: EVENT_MANAGER_PLUGINS,
  useClass: KeyEventsPlugin,
  multi: true,
  deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
}, DomRendererFactory2, SharedStylesHost, EventManager, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.RendererFactory2,
  useExisting: DomRendererFactory2
}, {
  provide: _angular_common__WEBPACK_IMPORTED_MODULE_0__.XhrFactory,
  useClass: BrowserXhr,
  deps: []
}, typeof ngDevMode === 'undefined' || ngDevMode ? {
  provide: BROWSER_MODULE_PROVIDERS_MARKER,
  useValue: true
} : []];
/**
 * Exports required infrastructure for all Angular apps.
 * Included by default in all Angular apps created with the CLI
 * `new` command.
 * Re-exports `CommonModule` and `ApplicationModule`, making their
 * exports and providers available to all apps.
 *
 * @publicApi
 */
class BrowserModule {
  constructor(providersAlreadyPresent) {
    if ((typeof ngDevMode === 'undefined' || ngDevMode) && providersAlreadyPresent) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5100 /* RuntimeErrorCode.BROWSER_MODULE_ALREADY_LOADED */, `Providers from the \`BrowserModule\` have already been loaded. If you need access ` + `to common directives such as NgIf and NgFor, import the \`CommonModule\` instead.`);
    }
  }
  /**
   * Configures a browser-based app to transition from a server-rendered app, if
   * one is present on the page.
   *
   * @param params An object containing an identifier for the app to transition.
   * The ID must match between the client and server versions of the app.
   * @returns The reconfigured `BrowserModule` to import into the app's root `AppModule`.
   *
   * @deprecated Use {@link APP_ID} instead to set the application ID.
   */
  static withServerTransition(params) {
    return {
      ngModule: BrowserModule,
      providers: [{
        provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.APP_ID,
        useValue: params.appId
      }]
    };
  }
  static {
    this.ɵfac = function BrowserModule_Factory(t) {
      return new (t || BrowserModule)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](BROWSER_MODULE_PROVIDERS_MARKER, 12));
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: BrowserModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
      providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.CommonModule, _angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](BrowserModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      providers: [...BROWSER_MODULE_PROVIDERS, ...TESTABILITY_PROVIDERS],
      exports: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.CommonModule, _angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationModule]
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.SkipSelf
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [BROWSER_MODULE_PROVIDERS_MARKER]
    }]
  }], null);
})();

/**
 * A service for managing HTML `<meta>` tags.
 *
 * Properties of the `MetaDefinition` object match the attributes of the
 * HTML `<meta>` tag. These tags define document metadata that is important for
 * things like configuring a Content Security Policy, defining browser compatibility
 * and security settings, setting HTTP Headers, defining rich content for social sharing,
 * and Search Engine Optimization (SEO).
 *
 * To identify specific `<meta>` tags in a document, use an attribute selection
 * string in the format `"tag_attribute='value string'"`.
 * For example, an `attrSelector` value of `"name='description'"` matches a tag
 * whose `name` attribute has the value `"description"`.
 * Selectors are used with the `querySelector()` Document method,
 * in the format `meta[{attrSelector}]`.
 *
 * @see [HTML meta tag](https://developer.mozilla.org/docs/Web/HTML/Element/meta)
 * @see [Document.querySelector()](https://developer.mozilla.org/docs/Web/API/Document/querySelector)
 *
 *
 * @publicApi
 */
class Meta {
  constructor(_doc) {
    this._doc = _doc;
    this._dom = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])();
  }
  /**
   * Retrieves or creates a specific `<meta>` tag element in the current HTML document.
   * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute
   * values in the provided tag definition, and verifies that all other attribute values are equal.
   * If an existing element is found, it is returned and is not modified in any way.
   * @param tag The definition of a `<meta>` element to match or create.
   * @param forceCreation True to create a new element without checking whether one already exists.
   * @returns The existing element with the same attributes and values if found,
   * the new element if no match is found, or `null` if the tag parameter is not defined.
   */
  addTag(tag, forceCreation = false) {
    if (!tag) return null;
    return this._getOrCreateElement(tag, forceCreation);
  }
  /**
   * Retrieves or creates a set of `<meta>` tag elements in the current HTML document.
   * In searching for an existing tag, Angular attempts to match the `name` or `property` attribute
   * values in the provided tag definition, and verifies that all other attribute values are equal.
   * @param tags An array of tag definitions to match or create.
   * @param forceCreation True to create new elements without checking whether they already exist.
   * @returns The matching elements if found, or the new elements.
   */
  addTags(tags, forceCreation = false) {
    if (!tags) return [];
    return tags.reduce((result, tag) => {
      if (tag) {
        result.push(this._getOrCreateElement(tag, forceCreation));
      }
      return result;
    }, []);
  }
  /**
   * Retrieves a `<meta>` tag element in the current HTML document.
   * @param attrSelector The tag attribute and value to match against, in the format
   * `"tag_attribute='value string'"`.
   * @returns The matching element, if any.
   */
  getTag(attrSelector) {
    if (!attrSelector) return null;
    return this._doc.querySelector(`meta[${attrSelector}]`) || null;
  }
  /**
   * Retrieves a set of `<meta>` tag elements in the current HTML document.
   * @param attrSelector The tag attribute and value to match against, in the format
   * `"tag_attribute='value string'"`.
   * @returns The matching elements, if any.
   */
  getTags(attrSelector) {
    if (!attrSelector) return [];
    const list /*NodeList*/ = this._doc.querySelectorAll(`meta[${attrSelector}]`);
    return list ? [].slice.call(list) : [];
  }
  /**
   * Modifies an existing `<meta>` tag element in the current HTML document.
   * @param tag The tag description with which to replace the existing tag content.
   * @param selector A tag attribute and value to match against, to identify
   * an existing tag. A string in the format `"tag_attribute=`value string`"`.
   * If not supplied, matches a tag with the same `name` or `property` attribute value as the
   * replacement tag.
   * @return The modified element.
   */
  updateTag(tag, selector) {
    if (!tag) return null;
    selector = selector || this._parseSelector(tag);
    const meta = this.getTag(selector);
    if (meta) {
      return this._setMetaElementAttributes(tag, meta);
    }
    return this._getOrCreateElement(tag, true);
  }
  /**
   * Removes an existing `<meta>` tag element from the current HTML document.
   * @param attrSelector A tag attribute and value to match against, to identify
   * an existing tag. A string in the format `"tag_attribute=`value string`"`.
   */
  removeTag(attrSelector) {
    this.removeTagElement(this.getTag(attrSelector));
  }
  /**
   * Removes an existing `<meta>` tag element from the current HTML document.
   * @param meta The tag definition to match against to identify an existing tag.
   */
  removeTagElement(meta) {
    if (meta) {
      this._dom.remove(meta);
    }
  }
  _getOrCreateElement(meta, forceCreation = false) {
    if (!forceCreation) {
      const selector = this._parseSelector(meta);
      // It's allowed to have multiple elements with the same name so it's not enough to
      // just check that element with the same name already present on the page. We also need to
      // check if element has tag attributes
      const elem = this.getTags(selector).filter(elem => this._containsAttributes(meta, elem))[0];
      if (elem !== undefined) return elem;
    }
    const element = this._dom.createElement('meta');
    this._setMetaElementAttributes(meta, element);
    const head = this._doc.getElementsByTagName('head')[0];
    head.appendChild(element);
    return element;
  }
  _setMetaElementAttributes(tag, el) {
    Object.keys(tag).forEach(prop => el.setAttribute(this._getMetaKeyMap(prop), tag[prop]));
    return el;
  }
  _parseSelector(tag) {
    const attr = tag.name ? 'name' : 'property';
    return `${attr}="${tag[attr]}"`;
  }
  _containsAttributes(tag, elem) {
    return Object.keys(tag).every(key => elem.getAttribute(this._getMetaKeyMap(key)) === tag[key]);
  }
  _getMetaKeyMap(prop) {
    return META_KEYS_MAP[prop] || prop;
  }
  static {
    this.ɵfac = function Meta_Factory(t) {
      return new (t || Meta)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: Meta,
      factory: Meta.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Meta, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }], null);
})();
/**
 * Mapping for MetaDefinition properties with their correct meta attribute names
 */
const META_KEYS_MAP = {
  httpEquiv: 'http-equiv'
};

/**
 * A service that can be used to get and set the title of a current HTML document.
 *
 * Since an Angular application can't be bootstrapped on the entire HTML document (`<html>` tag)
 * it is not possible to bind to the `text` property of the `HTMLTitleElement` elements
 * (representing the `<title>` tag). Instead, this service can be used to set and get the current
 * title value.
 *
 * @publicApi
 */
class Title {
  constructor(_doc) {
    this._doc = _doc;
  }
  /**
   * Get the title of the current HTML document.
   */
  getTitle() {
    return this._doc.title;
  }
  /**
   * Set the title of the current HTML document.
   * @param newTitle
   */
  setTitle(newTitle) {
    this._doc.title = newTitle || '';
  }
  static {
    this.ɵfac = function Title_Factory(t) {
      return new (t || Title)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: Title,
      factory: Title.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Title, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }], null);
})();

/**
 * Exports the value under a given `name` in the global property `ng`. For example `ng.probe` if
 * `name` is `'probe'`.
 * @param name Name under which it will be exported. Keep in mind this will be a property of the
 * global `ng` object.
 * @param value The value to export.
 */
function exportNgVar(name, value) {
  if (typeof COMPILED === 'undefined' || !COMPILED) {
    // Note: we can't export `ng` when using closure enhanced optimization as:
    // - closure declares globals itself for minified names, which sometimes clobber our `ng` global
    // - we can't declare a closure extern as the namespace `ng` is already used within Google
    //   for typings for angularJS (via `goog.provide('ng....')`).
    const ng = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['ng'] = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵglobal"]['ng'] || {};
    ng[name] = value;
  }
}
class ChangeDetectionPerfRecord {
  constructor(msPerTick, numTicks) {
    this.msPerTick = msPerTick;
    this.numTicks = numTicks;
  }
}
/**
 * Entry point for all Angular profiling-related debug tools. This object
 * corresponds to the `ng.profiler` in the dev console.
 */
class AngularProfiler {
  constructor(ref) {
    this.appRef = ref.injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_1__.ApplicationRef);
  }
  // tslint:disable:no-console
  /**
   * Exercises change detection in a loop and then prints the average amount of
   * time in milliseconds how long a single round of change detection takes for
   * the current state of the UI. It runs a minimum of 5 rounds for a minimum
   * of 500 milliseconds.
   *
   * Optionally, a user may pass a `config` parameter containing a map of
   * options. Supported options are:
   *
   * `record` (boolean) - causes the profiler to record a CPU profile while
   * it exercises the change detector. Example:
   *
   * ```
   * ng.profiler.timeChangeDetection({record: true})
   * ```
   */
  timeChangeDetection(config) {
    const record = config && config['record'];
    const profileName = 'Change Detection';
    // Profiler is not available in Android browsers without dev tools opened
    if (record && 'profile' in console && typeof console.profile === 'function') {
      console.profile(profileName);
    }
    const start = performance.now();
    let numTicks = 0;
    while (numTicks < 5 || performance.now() - start < 500) {
      this.appRef.tick();
      numTicks++;
    }
    const end = performance.now();
    if (record && 'profileEnd' in console && typeof console.profileEnd === 'function') {
      console.profileEnd(profileName);
    }
    const msPerTick = (end - start) / numTicks;
    console.log(`ran ${numTicks} change detection cycles`);
    console.log(`${msPerTick.toFixed(2)} ms per check`);
    return new ChangeDetectionPerfRecord(msPerTick, numTicks);
  }
}
const PROFILER_GLOBAL_NAME = 'profiler';
/**
 * Enabled Angular debug tools that are accessible via your browser's
 * developer console.
 *
 * Usage:
 *
 * 1. Open developer console (e.g. in Chrome Ctrl + Shift + j)
 * 1. Type `ng.` (usually the console will show auto-complete suggestion)
 * 1. Try the change detection profiler `ng.profiler.timeChangeDetection()`
 *    then hit Enter.
 *
 * @publicApi
 */
function enableDebugTools(ref) {
  exportNgVar(PROFILER_GLOBAL_NAME, new AngularProfiler(ref));
  return ref;
}
/**
 * Disables Angular tools.
 *
 * @publicApi
 */
function disableDebugTools() {
  exportNgVar(PROFILER_GLOBAL_NAME, null);
}

/**
 * Predicates for use with {@link DebugElement}'s query functions.
 *
 * @publicApi
 */
class By {
  /**
   * Match all nodes.
   *
   * @usageNotes
   * ### Example
   *
   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_all'}
   */
  static all() {
    return () => true;
  }
  /**
   * Match elements by the given CSS selector.
   *
   * @usageNotes
   * ### Example
   *
   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_css'}
   */
  static css(selector) {
    return debugElement => {
      return debugElement.nativeElement != null ? elementMatches(debugElement.nativeElement, selector) : false;
    };
  }
  /**
   * Match nodes that have the given directive present.
   *
   * @usageNotes
   * ### Example
   *
   * {@example platform-browser/dom/debug/ts/by/by.ts region='by_directive'}
   */
  static directive(type) {
    return debugNode => debugNode.providerTokens.indexOf(type) !== -1;
  }
}
function elementMatches(n, selector) {
  if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_0__["ɵgetDOM"])().isElementNode(n)) {
    return n.matches && n.matches(selector) || n.msMatchesSelector && n.msMatchesSelector(selector) || n.webkitMatchesSelector && n.webkitMatchesSelector(selector);
  }
  return false;
}

/**
 * Supported HammerJS recognizer event names.
 */
const EVENT_NAMES = {
  // pan
  'pan': true,
  'panstart': true,
  'panmove': true,
  'panend': true,
  'pancancel': true,
  'panleft': true,
  'panright': true,
  'panup': true,
  'pandown': true,
  // pinch
  'pinch': true,
  'pinchstart': true,
  'pinchmove': true,
  'pinchend': true,
  'pinchcancel': true,
  'pinchin': true,
  'pinchout': true,
  // press
  'press': true,
  'pressup': true,
  // rotate
  'rotate': true,
  'rotatestart': true,
  'rotatemove': true,
  'rotateend': true,
  'rotatecancel': true,
  // swipe
  'swipe': true,
  'swipeleft': true,
  'swiperight': true,
  'swipeup': true,
  'swipedown': true,
  // tap
  'tap': true,
  'doubletap': true
};
/**
 * DI token for providing [HammerJS](https://hammerjs.github.io/) support to Angular.
 * @see {@link HammerGestureConfig}
 *
 * @ngModule HammerModule
 * @publicApi
 */
const HAMMER_GESTURE_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('HammerGestureConfig');
/**
 * Injection token used to provide a {@link HammerLoader} to Angular.
 *
 * @publicApi
 */
const HAMMER_LOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('HammerLoader');
/**
 * An injectable [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)
 * for gesture recognition. Configures specific event recognition.
 * @publicApi
 */
class HammerGestureConfig {
  constructor() {
    /**
     * A set of supported event names for gestures to be used in Angular.
     * Angular supports all built-in recognizers, as listed in
     * [HammerJS documentation](https://hammerjs.github.io/).
     */
    this.events = [];
    /**
     * Maps gesture event names to a set of configuration options
     * that specify overrides to the default values for specific properties.
     *
     * The key is a supported event name to be configured,
     * and the options object contains a set of properties, with override values
     * to be applied to the named recognizer event.
     * For example, to disable recognition of the rotate event, specify
     *  `{"rotate": {"enable": false}}`.
     *
     * Properties that are not present take the HammerJS default values.
     * For information about which properties are supported for which events,
     * and their allowed and default values, see
     * [HammerJS documentation](https://hammerjs.github.io/).
     *
     */
    this.overrides = {};
  }
  /**
   * Creates a [HammerJS Manager](https://hammerjs.github.io/api/#hammermanager)
   * and attaches it to a given HTML element.
   * @param element The element that will recognize gestures.
   * @returns A HammerJS event-manager object.
   */
  buildHammer(element) {
    const mc = new Hammer(element, this.options);
    mc.get('pinch').set({
      enable: true
    });
    mc.get('rotate').set({
      enable: true
    });
    for (const eventName in this.overrides) {
      mc.get(eventName).set(this.overrides[eventName]);
    }
    return mc;
  }
  static {
    this.ɵfac = function HammerGestureConfig_Factory(t) {
      return new (t || HammerGestureConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: HammerGestureConfig,
      factory: HammerGestureConfig.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerGestureConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
/**
 * Event plugin that adds Hammer support to an application.
 *
 * @ngModule HammerModule
 */
class HammerGesturesPlugin extends EventManagerPlugin {
  constructor(doc, _config, console, loader) {
    super(doc);
    this._config = _config;
    this.console = console;
    this.loader = loader;
    this._loaderPromise = null;
  }
  supports(eventName) {
    if (!EVENT_NAMES.hasOwnProperty(eventName.toLowerCase()) && !this.isCustomEvent(eventName)) {
      return false;
    }
    if (!window.Hammer && !this.loader) {
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        this.console.warn(`The "${eventName}" event cannot be bound because Hammer.JS is not ` + `loaded and no custom loader has been specified.`);
      }
      return false;
    }
    return true;
  }
  addEventListener(element, eventName, handler) {
    const zone = this.manager.getZone();
    eventName = eventName.toLowerCase();
    // If Hammer is not present but a loader is specified, we defer adding the event listener
    // until Hammer is loaded.
    if (!window.Hammer && this.loader) {
      this._loaderPromise = this._loaderPromise || zone.runOutsideAngular(() => this.loader());
      // This `addEventListener` method returns a function to remove the added listener.
      // Until Hammer is loaded, the returned function needs to *cancel* the registration rather
      // than remove anything.
      let cancelRegistration = false;
      let deregister = () => {
        cancelRegistration = true;
      };
      zone.runOutsideAngular(() => this._loaderPromise.then(() => {
        // If Hammer isn't actually loaded when the custom loader resolves, give up.
        if (!window.Hammer) {
          if (typeof ngDevMode === 'undefined' || ngDevMode) {
            this.console.warn(`The custom HAMMER_LOADER completed, but Hammer.JS is not present.`);
          }
          deregister = () => {};
          return;
        }
        if (!cancelRegistration) {
          // Now that Hammer is loaded and the listener is being loaded for real,
          // the deregistration function changes from canceling registration to
          // removal.
          deregister = this.addEventListener(element, eventName, handler);
        }
      }).catch(() => {
        if (typeof ngDevMode === 'undefined' || ngDevMode) {
          this.console.warn(`The "${eventName}" event cannot be bound because the custom ` + `Hammer.JS loader failed.`);
        }
        deregister = () => {};
      }));
      // Return a function that *executes* `deregister` (and not `deregister` itself) so that we
      // can change the behavior of `deregister` once the listener is added. Using a closure in
      // this way allows us to avoid any additional data structures to track listener removal.
      return () => {
        deregister();
      };
    }
    return zone.runOutsideAngular(() => {
      // Creating the manager bind events, must be done outside of angular
      const mc = this._config.buildHammer(element);
      const callback = function (eventObj) {
        zone.runGuarded(function () {
          handler(eventObj);
        });
      };
      mc.on(eventName, callback);
      return () => {
        mc.off(eventName, callback);
        // destroy mc to prevent memory leak
        if (typeof mc.destroy === 'function') {
          mc.destroy();
        }
      };
    });
  }
  isCustomEvent(eventName) {
    return this._config.events.indexOf(eventName) > -1;
  }
  static {
    this.ɵfac = function HammerGesturesPlugin_Factory(t) {
      return new (t || HammerGesturesPlugin)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](HAMMER_GESTURE_CONFIG), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](HAMMER_LOADER, 8));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: HammerGesturesPlugin,
      factory: HammerGesturesPlugin.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerGesturesPlugin, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }, {
    type: HammerGestureConfig,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [HAMMER_GESTURE_CONFIG]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [HAMMER_LOADER]
    }]
  }], null);
})();
/**
 * Adds support for HammerJS.
 *
 * Import this module at the root of your application so that Angular can work with
 * HammerJS to detect gesture events.
 *
 * Note that applications still need to include the HammerJS script itself. This module
 * simply sets up the coordination layer between HammerJS and Angular's `EventManager`.
 *
 * @publicApi
 */
class HammerModule {
  static {
    this.ɵfac = function HammerModule_Factory(t) {
      return new (t || HammerModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: HammerModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
      providers: [{
        provide: EVENT_MANAGER_PLUGINS,
        useClass: HammerGesturesPlugin,
        multi: true,
        deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, HAMMER_GESTURE_CONFIG, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"], [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional(), HAMMER_LOADER]]
      }, {
        provide: HAMMER_GESTURE_CONFIG,
        useClass: HammerGestureConfig,
        deps: []
      }]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](HammerModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      providers: [{
        provide: EVENT_MANAGER_PLUGINS,
        useClass: HammerGesturesPlugin,
        multi: true,
        deps: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT, HAMMER_GESTURE_CONFIG, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"], [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional(), HAMMER_LOADER]]
      }, {
        provide: HAMMER_GESTURE_CONFIG,
        useClass: HammerGestureConfig,
        deps: []
      }]
    }]
  }], null, null);
})();

/**
 * DomSanitizer helps preventing Cross Site Scripting Security bugs (XSS) by sanitizing
 * values to be safe to use in the different DOM contexts.
 *
 * For example, when binding a URL in an `<a [href]="someValue">` hyperlink, `someValue` will be
 * sanitized so that an attacker cannot inject e.g. a `javascript:` URL that would execute code on
 * the website.
 *
 * In specific situations, it might be necessary to disable sanitization, for example if the
 * application genuinely needs to produce a `javascript:` style link with a dynamic value in it.
 * Users can bypass security by constructing a value with one of the `bypassSecurityTrust...`
 * methods, and then binding to that value from the template.
 *
 * These situations should be very rare, and extraordinary care must be taken to avoid creating a
 * Cross Site Scripting (XSS) security bug!
 *
 * When using `bypassSecurityTrust...`, make sure to call the method as early as possible and as
 * close as possible to the source of the value, to make it easy to verify no security bug is
 * created by its use.
 *
 * It is not required (and not recommended) to bypass security if the value is safe, e.g. a URL that
 * does not start with a suspicious protocol, or an HTML snippet that does not contain dangerous
 * code. The sanitizer leaves safe values intact.
 *
 * @security Calling any of the `bypassSecurityTrust...` APIs disables Angular's built-in
 * sanitization for the value passed in. Carefully check and audit all values and code paths going
 * into this call. Make sure any user data is appropriately escaped for this security context.
 * For more detail, see the [Security Guide](https://g.co/ng/security).
 *
 * @publicApi
 */
class DomSanitizer {
  static {
    this.ɵfac = function DomSanitizer_Factory(t) {
      return new (t || DomSanitizer)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DomSanitizer,
      factory: function DomSanitizer_Factory(t) {
        let r = null;
        if (t) {
          r = new (t || DomSanitizer)();
        } else {
          r = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](DomSanitizerImpl);
        }
        return r;
      },
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomSanitizer, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root',
      useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(() => DomSanitizerImpl)
    }]
  }], null, null);
})();
class DomSanitizerImpl extends DomSanitizer {
  constructor(_doc) {
    super();
    this._doc = _doc;
  }
  sanitize(ctx, value) {
    if (value == null) return null;
    switch (ctx) {
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.NONE:
        return value;
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.HTML:
        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "HTML" /* BypassType.Html */)) {
          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
        }
        return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵ_sanitizeHtml"])(this._doc, String(value)).toString();
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.STYLE:
        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "Style" /* BypassType.Style */)) {
          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
        }
        return value;
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.SCRIPT:
        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "Script" /* BypassType.Script */)) {
          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
        }
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5200 /* RuntimeErrorCode.SANITIZATION_UNSAFE_SCRIPT */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'unsafe value used in a script context');
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.URL:
        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "URL" /* BypassType.Url */)) {
          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
        }
        return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵ_sanitizeUrl"])(String(value));
      case _angular_core__WEBPACK_IMPORTED_MODULE_1__.SecurityContext.RESOURCE_URL:
        if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵallowSanitizationBypassAndThrow"])(value, "ResourceURL" /* BypassType.ResourceUrl */)) {
          return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵunwrapSafeValue"])(value);
        }
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5201 /* RuntimeErrorCode.SANITIZATION_UNSAFE_RESOURCE_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `unsafe value used in a resource URL context (see ${_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵXSS_SECURITY_URL"]})`);
      default:
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵRuntimeError"](5202 /* RuntimeErrorCode.SANITIZATION_UNEXPECTED_CTX */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Unexpected SecurityContext ${ctx} (see ${_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵXSS_SECURITY_URL"]})`);
    }
  }
  bypassSecurityTrustHtml(value) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustHtml"])(value);
  }
  bypassSecurityTrustStyle(value) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustStyle"])(value);
  }
  bypassSecurityTrustScript(value) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustScript"])(value);
  }
  bypassSecurityTrustUrl(value) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustUrl"])(value);
  }
  bypassSecurityTrustResourceUrl(value) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵbypassSanitizationTrustResourceUrl"])(value);
  }
  static {
    this.ɵfac = function DomSanitizerImpl_Factory(t) {
      return new (t || DomSanitizerImpl)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: DomSanitizerImpl,
      factory: DomSanitizerImpl.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](DomSanitizerImpl, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }], null);
})();

/**
 * The list of features as an enum to uniquely type each `HydrationFeature`.
 * @see {@link HydrationFeature}
 *
 * @publicApi
 */
var HydrationFeatureKind;
(function (HydrationFeatureKind) {
  HydrationFeatureKind[HydrationFeatureKind["NoHttpTransferCache"] = 0] = "NoHttpTransferCache";
  HydrationFeatureKind[HydrationFeatureKind["HttpTransferCacheOptions"] = 1] = "HttpTransferCacheOptions";
})(HydrationFeatureKind || (HydrationFeatureKind = {}));
/**
 * Helper function to create an object that represents a Hydration feature.
 */
function hydrationFeature(ɵkind, ɵproviders = [], ɵoptions = {}) {
  return {
    ɵkind,
    ɵproviders
  };
}
/**
 * Disables HTTP transfer cache. Effectively causes HTTP requests to be performed twice: once on the
 * server and other one on the browser.
 *
 * @publicApi
 */
function withNoHttpTransferCache() {
  // This feature has no providers and acts as a flag that turns off
  // HTTP transfer cache (which otherwise is turned on by default).
  return hydrationFeature(HydrationFeatureKind.NoHttpTransferCache);
}
/**
 * The function accepts a an object, which allows to configure cache parameters,
 * such as which headers should be included (no headers are included by default),
 * wether POST requests should be cached or a callback function to determine if a
 * particular request should be cached.
 *
 * @publicApi
 */
function withHttpTransferCacheOptions(options) {
  // This feature has no providers and acts as a flag to pass options to the HTTP transfer cache.
  return hydrationFeature(HydrationFeatureKind.HttpTransferCacheOptions, (0,_angular_common_http__WEBPACK_IMPORTED_MODULE_2__["ɵwithHttpTransferCache"])(options));
}
/**
 * Returns an `ENVIRONMENT_INITIALIZER` token setup with a function
 * that verifies whether compatible ZoneJS was used in an application
 * and logs a warning in a console if it's not the case.
 */
function provideZoneJsCompatibilityDetector() {
  return [{
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ENVIRONMENT_INITIALIZER,
    useValue: () => {
      const ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone);
      // Checking `ngZone instanceof NgZone` would be insufficient here,
      // because custom implementations might use NgZone as a base class.
      if (ngZone.constructor !== _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone) {
        const console = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵConsole"]);
        const message = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵformatRuntimeError"])(-5000 /* RuntimeErrorCode.UNSUPPORTED_ZONEJS_INSTANCE */, 'Angular detected that hydration was enabled for an application ' + 'that uses a custom or a noop Zone.js implementation. ' + 'This is not yet a fully supported configuration.');
        // tslint:disable-next-line:no-console
        console.warn(message);
      }
    },
    multi: true
  }];
}
/**
 * Sets up providers necessary to enable hydration functionality for the application.
 *
 * By default, the function enables the recommended set of features for the optimal
 * performance for most of the applications. It includes the following features:
 *
 * * Reconciling DOM hydration. Learn more about it [here](guide/hydration).
 * * [`HttpClient`](api/common/http/HttpClient) response caching while running on the server and
 * transferring this cache to the client to avoid extra HTTP requests. Learn more about data caching
 * [here](/guide/ssr#caching-data-when-using-httpclient).
 *
 * These functions allow you to disable some of the default features or configure features
 * * {@link withNoHttpTransferCache} to disable HTTP transfer cache
 * * {@link withHttpTransferCacheOptions} to configure some HTTP transfer cache options
 *
 * @usageNotes
 *
 * Basic example of how you can enable hydration in your application when
 * `bootstrapApplication` function is used:
 * ```
 * bootstrapApplication(AppComponent, {
 *   providers: [provideClientHydration()]
 * });
 * ```
 *
 * Alternatively if you are using NgModules, you would add `provideClientHydration`
 * to your root app module's provider list.
 * ```
 * @NgModule({
 *   declarations: [RootCmp],
 *   bootstrap: [RootCmp],
 *   providers: [provideClientHydration()],
 * })
 * export class AppModule {}
 * ```
 *
 * @see {@link withNoHttpTransferCache}
 * @see {@link withHttpTransferCacheOptions}
 *
 * @param features Optional features to configure additional router behaviors.
 * @returns A set of providers to enable hydration.
 *
 * @publicApi
 */
function provideClientHydration(...features) {
  const providers = [];
  const featuresKind = new Set();
  const hasHttpTransferCacheOptions = featuresKind.has(HydrationFeatureKind.HttpTransferCacheOptions);
  for (const {
    ɵproviders,
    ɵkind
  } of features) {
    featuresKind.add(ɵkind);
    if (ɵproviders.length) {
      providers.push(ɵproviders);
    }
  }
  if (typeof ngDevMode !== 'undefined' && ngDevMode && featuresKind.has(HydrationFeatureKind.NoHttpTransferCache) && hasHttpTransferCacheOptions) {
    // TODO: Make this a runtime error
    throw new Error('Configuration error: found both withHttpTransferCacheOptions() and withNoHttpTransferCache() in the same call to provideClientHydration(), which is a contradiction.');
  }
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.makeEnvironmentProviders)([typeof ngDevMode !== 'undefined' && ngDevMode ? provideZoneJsCompatibilityDetector() : [], (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵwithDomHydration"])(), featuresKind.has(HydrationFeatureKind.NoHttpTransferCache) || hasHttpTransferCacheOptions ? [] : (0,_angular_common_http__WEBPACK_IMPORTED_MODULE_2__["ɵwithHttpTransferCache"])({}), providers]);
}

/**
 * @module
 * @description
 * Entry point for all public APIs of the platform-browser package.
 */
/**
 * @publicApi
 */
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Version('17.3.12');

// Re-export TransferState to the public API of the `platform-browser` for backwards-compatibility.
/**
 * Create a `StateKey<T>` that can be used to store value of type T with `TransferState`.
 *
 * Example:
 *
 * ```
 * const COUNTER_KEY = makeStateKey<number>('counter');
 * let value = 10;
 *
 * transferState.set(COUNTER_KEY, value);
 * ```
 *
 * @publicApi
 * @deprecated `makeStateKey` has moved, please import `makeStateKey` from `@angular/core` instead.
 */
// The below is a workaround to add a deprecated message.
const makeStateKey = _angular_core__WEBPACK_IMPORTED_MODULE_1__.makeStateKey;
// The below type is needed for G3 due to JSC_CONFORMANCE_VIOLATION.
const TransferState = _angular_core__WEBPACK_IMPORTED_MODULE_1__.TransferState;

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */
// This file only reexports content of the `src` folder. Keep it that way.

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 95072:
/*!**********************************************************!*\
  !*** ./node_modules/@angular/router/fesm2022/router.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ActivatedRoute: () => (/* binding */ ActivatedRoute),
/* harmony export */   ActivatedRouteSnapshot: () => (/* binding */ ActivatedRouteSnapshot),
/* harmony export */   ActivationEnd: () => (/* binding */ ActivationEnd),
/* harmony export */   ActivationStart: () => (/* binding */ ActivationStart),
/* harmony export */   BaseRouteReuseStrategy: () => (/* binding */ BaseRouteReuseStrategy),
/* harmony export */   ChildActivationEnd: () => (/* binding */ ChildActivationEnd),
/* harmony export */   ChildActivationStart: () => (/* binding */ ChildActivationStart),
/* harmony export */   ChildrenOutletContexts: () => (/* binding */ ChildrenOutletContexts),
/* harmony export */   DefaultTitleStrategy: () => (/* binding */ DefaultTitleStrategy),
/* harmony export */   DefaultUrlSerializer: () => (/* binding */ DefaultUrlSerializer),
/* harmony export */   EventType: () => (/* binding */ EventType),
/* harmony export */   GuardsCheckEnd: () => (/* binding */ GuardsCheckEnd),
/* harmony export */   GuardsCheckStart: () => (/* binding */ GuardsCheckStart),
/* harmony export */   NavigationCancel: () => (/* binding */ NavigationCancel),
/* harmony export */   NavigationCancellationCode: () => (/* binding */ NavigationCancellationCode),
/* harmony export */   NavigationEnd: () => (/* binding */ NavigationEnd),
/* harmony export */   NavigationError: () => (/* binding */ NavigationError),
/* harmony export */   NavigationSkipped: () => (/* binding */ NavigationSkipped),
/* harmony export */   NavigationSkippedCode: () => (/* binding */ NavigationSkippedCode),
/* harmony export */   NavigationStart: () => (/* binding */ NavigationStart),
/* harmony export */   NoPreloading: () => (/* binding */ NoPreloading),
/* harmony export */   OutletContext: () => (/* binding */ OutletContext),
/* harmony export */   PRIMARY_OUTLET: () => (/* binding */ PRIMARY_OUTLET),
/* harmony export */   PreloadAllModules: () => (/* binding */ PreloadAllModules),
/* harmony export */   PreloadingStrategy: () => (/* binding */ PreloadingStrategy),
/* harmony export */   ROUTER_CONFIGURATION: () => (/* binding */ ROUTER_CONFIGURATION),
/* harmony export */   ROUTER_INITIALIZER: () => (/* binding */ ROUTER_INITIALIZER),
/* harmony export */   ROUTES: () => (/* binding */ ROUTES),
/* harmony export */   ResolveEnd: () => (/* binding */ ResolveEnd),
/* harmony export */   ResolveStart: () => (/* binding */ ResolveStart),
/* harmony export */   RouteConfigLoadEnd: () => (/* binding */ RouteConfigLoadEnd),
/* harmony export */   RouteConfigLoadStart: () => (/* binding */ RouteConfigLoadStart),
/* harmony export */   RouteReuseStrategy: () => (/* binding */ RouteReuseStrategy),
/* harmony export */   Router: () => (/* binding */ Router),
/* harmony export */   RouterEvent: () => (/* binding */ RouterEvent),
/* harmony export */   RouterLink: () => (/* binding */ RouterLink),
/* harmony export */   RouterLinkActive: () => (/* binding */ RouterLinkActive),
/* harmony export */   RouterLinkWithHref: () => (/* binding */ RouterLink),
/* harmony export */   RouterModule: () => (/* binding */ RouterModule),
/* harmony export */   RouterOutlet: () => (/* binding */ RouterOutlet),
/* harmony export */   RouterPreloader: () => (/* binding */ RouterPreloader),
/* harmony export */   RouterState: () => (/* binding */ RouterState),
/* harmony export */   RouterStateSnapshot: () => (/* binding */ RouterStateSnapshot),
/* harmony export */   RoutesRecognized: () => (/* binding */ RoutesRecognized),
/* harmony export */   Scroll: () => (/* binding */ Scroll),
/* harmony export */   TitleStrategy: () => (/* binding */ TitleStrategy),
/* harmony export */   UrlHandlingStrategy: () => (/* binding */ UrlHandlingStrategy),
/* harmony export */   UrlSegment: () => (/* binding */ UrlSegment),
/* harmony export */   UrlSegmentGroup: () => (/* binding */ UrlSegmentGroup),
/* harmony export */   UrlSerializer: () => (/* binding */ UrlSerializer),
/* harmony export */   UrlTree: () => (/* binding */ UrlTree),
/* harmony export */   VERSION: () => (/* binding */ VERSION),
/* harmony export */   convertToParamMap: () => (/* binding */ convertToParamMap),
/* harmony export */   createUrlTreeFromSnapshot: () => (/* binding */ createUrlTreeFromSnapshot),
/* harmony export */   defaultUrlMatcher: () => (/* binding */ defaultUrlMatcher),
/* harmony export */   mapToCanActivate: () => (/* binding */ mapToCanActivate),
/* harmony export */   mapToCanActivateChild: () => (/* binding */ mapToCanActivateChild),
/* harmony export */   mapToCanDeactivate: () => (/* binding */ mapToCanDeactivate),
/* harmony export */   mapToCanMatch: () => (/* binding */ mapToCanMatch),
/* harmony export */   mapToResolve: () => (/* binding */ mapToResolve),
/* harmony export */   provideRouter: () => (/* binding */ provideRouter),
/* harmony export */   provideRoutes: () => (/* binding */ provideRoutes),
/* harmony export */   withComponentInputBinding: () => (/* binding */ withComponentInputBinding),
/* harmony export */   withDebugTracing: () => (/* binding */ withDebugTracing),
/* harmony export */   withDisabledInitialNavigation: () => (/* binding */ withDisabledInitialNavigation),
/* harmony export */   withEnabledBlockingInitialNavigation: () => (/* binding */ withEnabledBlockingInitialNavigation),
/* harmony export */   withHashLocation: () => (/* binding */ withHashLocation),
/* harmony export */   withInMemoryScrolling: () => (/* binding */ withInMemoryScrolling),
/* harmony export */   withNavigationErrorHandler: () => (/* binding */ withNavigationErrorHandler),
/* harmony export */   withPreloading: () => (/* binding */ withPreloading),
/* harmony export */   withRouterConfig: () => (/* binding */ withRouterConfig),
/* harmony export */   withViewTransitions: () => (/* binding */ withViewTransitions),
/* harmony export */   "ɵEmptyOutletComponent": () => (/* binding */ ɵEmptyOutletComponent),
/* harmony export */   "ɵROUTER_PROVIDERS": () => (/* binding */ ROUTER_PROVIDERS),
/* harmony export */   "ɵafterNextNavigation": () => (/* binding */ afterNextNavigation),
/* harmony export */   "ɵloadChildren": () => (/* binding */ loadChildren)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 95429);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 19999);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 93335);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs */ 44665);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs */ 137);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs */ 95682);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! rxjs */ 77919);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! rxjs */ 59400);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! rxjs */ 94982);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(/*! rxjs */ 2510);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs/operators */ 13255);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs/operators */ 2435);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! rxjs/operators */ 61318);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! rxjs/operators */ 32112);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! rxjs/operators */ 90778);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! rxjs/operators */ 22157);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! rxjs/operators */ 80602);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! rxjs/operators */ 87378);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! rxjs/operators */ 89475);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! rxjs/operators */ 73481);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(/*! rxjs/operators */ 23222);
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! @angular/platform-browser */ 80436);

/**
 * @license Angular v17.3.12
 * (c) 2010-2024 Google LLC. https://angular.io/
 * License: MIT
 */









/**
 * The primary routing outlet.
 *
 * @publicApi
 */
const PRIMARY_OUTLET = 'primary';
/**
 * A private symbol used to store the value of `Route.title` inside the `Route.data` if it is a
 * static string or `Route.resolve` if anything else. This allows us to reuse the existing route
 * data/resolvers to support the title feature without new instrumentation in the `Router` pipeline.
 */
const RouteTitleKey = /* @__PURE__ */Symbol('RouteTitle');
class ParamsAsMap {
  constructor(params) {
    this.params = params || {};
  }
  has(name) {
    return Object.prototype.hasOwnProperty.call(this.params, name);
  }
  get(name) {
    if (this.has(name)) {
      const v = this.params[name];
      return Array.isArray(v) ? v[0] : v;
    }
    return null;
  }
  getAll(name) {
    if (this.has(name)) {
      const v = this.params[name];
      return Array.isArray(v) ? v : [v];
    }
    return [];
  }
  get keys() {
    return Object.keys(this.params);
  }
}
/**
 * Converts a `Params` instance to a `ParamMap`.
 * @param params The instance to convert.
 * @returns The new map instance.
 *
 * @publicApi
 */
function convertToParamMap(params) {
  return new ParamsAsMap(params);
}
/**
 * Matches the route configuration (`route`) against the actual URL (`segments`).
 *
 * When no matcher is defined on a `Route`, this is the matcher used by the Router by default.
 *
 * @param segments The remaining unmatched segments in the current navigation
 * @param segmentGroup The current segment group being matched
 * @param route The `Route` to match against.
 *
 * @see {@link UrlMatchResult}
 * @see {@link Route}
 *
 * @returns The resulting match information or `null` if the `route` should not match.
 * @publicApi
 */
function defaultUrlMatcher(segments, segmentGroup, route) {
  const parts = route.path.split('/');
  if (parts.length > segments.length) {
    // The actual URL is shorter than the config, no match
    return null;
  }
  if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || parts.length < segments.length)) {
    // The config is longer than the actual URL but we are looking for a full match, return null
    return null;
  }
  const posParams = {};
  // Check each config part against the actual URL
  for (let index = 0; index < parts.length; index++) {
    const part = parts[index];
    const segment = segments[index];
    const isParameter = part.startsWith(':');
    if (isParameter) {
      posParams[part.substring(1)] = segment;
    } else if (part !== segment.path) {
      // The actual URL part does not match the config, no match
      return null;
    }
  }
  return {
    consumed: segments.slice(0, parts.length),
    posParams
  };
}
function shallowEqualArrays(a, b) {
  if (a.length !== b.length) return false;
  for (let i = 0; i < a.length; ++i) {
    if (!shallowEqual(a[i], b[i])) return false;
  }
  return true;
}
function shallowEqual(a, b) {
  // While `undefined` should never be possible, it would sometimes be the case in IE 11
  // and pre-chromium Edge. The check below accounts for this edge case.
  const k1 = a ? getDataKeys(a) : undefined;
  const k2 = b ? getDataKeys(b) : undefined;
  if (!k1 || !k2 || k1.length != k2.length) {
    return false;
  }
  let key;
  for (let i = 0; i < k1.length; i++) {
    key = k1[i];
    if (!equalArraysOrString(a[key], b[key])) {
      return false;
    }
  }
  return true;
}
/**
 * Gets the keys of an object, including `symbol` keys.
 */
function getDataKeys(obj) {
  return [...Object.keys(obj), ...Object.getOwnPropertySymbols(obj)];
}
/**
 * Test equality for arrays of strings or a string.
 */
function equalArraysOrString(a, b) {
  if (Array.isArray(a) && Array.isArray(b)) {
    if (a.length !== b.length) return false;
    const aSorted = [...a].sort();
    const bSorted = [...b].sort();
    return aSorted.every((val, index) => bSorted[index] === val);
  } else {
    return a === b;
  }
}
/**
 * Return the last element of an array.
 */
function last(a) {
  return a.length > 0 ? a[a.length - 1] : null;
}
function wrapIntoObservable(value) {
  if ((0,rxjs__WEBPACK_IMPORTED_MODULE_1__.isObservable)(value)) {
    return value;
  }
  if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵisPromise"])(value)) {
    // Use `Promise.resolve()` to wrap promise-like instances.
    // Required ie when a Resolver returns a AngularJS `$q` promise to correctly trigger the
    // change detection.
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(Promise.resolve(value));
  }
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(value);
}
const pathCompareMap = {
  'exact': equalSegmentGroups,
  'subset': containsSegmentGroup
};
const paramCompareMap = {
  'exact': equalParams,
  'subset': containsParams,
  'ignored': () => true
};
function containsTree(container, containee, options) {
  return pathCompareMap[options.paths](container.root, containee.root, options.matrixParams) && paramCompareMap[options.queryParams](container.queryParams, containee.queryParams) && !(options.fragment === 'exact' && container.fragment !== containee.fragment);
}
function equalParams(container, containee) {
  // TODO: This does not handle array params correctly.
  return shallowEqual(container, containee);
}
function equalSegmentGroups(container, containee, matrixParams) {
  if (!equalPath(container.segments, containee.segments)) return false;
  if (!matrixParamsMatch(container.segments, containee.segments, matrixParams)) {
    return false;
  }
  if (container.numberOfChildren !== containee.numberOfChildren) return false;
  for (const c in containee.children) {
    if (!container.children[c]) return false;
    if (!equalSegmentGroups(container.children[c], containee.children[c], matrixParams)) return false;
  }
  return true;
}
function containsParams(container, containee) {
  return Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every(key => equalArraysOrString(container[key], containee[key]));
}
function containsSegmentGroup(container, containee, matrixParams) {
  return containsSegmentGroupHelper(container, containee, containee.segments, matrixParams);
}
function containsSegmentGroupHelper(container, containee, containeePaths, matrixParams) {
  if (container.segments.length > containeePaths.length) {
    const current = container.segments.slice(0, containeePaths.length);
    if (!equalPath(current, containeePaths)) return false;
    if (containee.hasChildren()) return false;
    if (!matrixParamsMatch(current, containeePaths, matrixParams)) return false;
    return true;
  } else if (container.segments.length === containeePaths.length) {
    if (!equalPath(container.segments, containeePaths)) return false;
    if (!matrixParamsMatch(container.segments, containeePaths, matrixParams)) return false;
    for (const c in containee.children) {
      if (!container.children[c]) return false;
      if (!containsSegmentGroup(container.children[c], containee.children[c], matrixParams)) {
        return false;
      }
    }
    return true;
  } else {
    const current = containeePaths.slice(0, container.segments.length);
    const next = containeePaths.slice(container.segments.length);
    if (!equalPath(container.segments, current)) return false;
    if (!matrixParamsMatch(container.segments, current, matrixParams)) return false;
    if (!container.children[PRIMARY_OUTLET]) return false;
    return containsSegmentGroupHelper(container.children[PRIMARY_OUTLET], containee, next, matrixParams);
  }
}
function matrixParamsMatch(containerPaths, containeePaths, options) {
  return containeePaths.every((containeeSegment, i) => {
    return paramCompareMap[options](containerPaths[i].parameters, containeeSegment.parameters);
  });
}
/**
 * @description
 *
 * Represents the parsed URL.
 *
 * Since a router state is a tree, and the URL is nothing but a serialized state, the URL is a
 * serialized tree.
 * UrlTree is a data structure that provides a lot of affordances in dealing with URLs
 *
 * @usageNotes
 * ### Example
 *
 * ```
 * @Component({templateUrl:'template.html'})
 * class MyComponent {
 *   constructor(router: Router) {
 *     const tree: UrlTree =
 *       router.parseUrl('/team/33/(user/victor//support:help)?debug=true#fragment');
 *     const f = tree.fragment; // return 'fragment'
 *     const q = tree.queryParams; // returns {debug: 'true'}
 *     const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
 *     const s: UrlSegment[] = g.segments; // returns 2 segments 'team' and '33'
 *     g.children[PRIMARY_OUTLET].segments; // returns 2 segments 'user' and 'victor'
 *     g.children['support'].segments; // return 1 segment 'help'
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class UrlTree {
  constructor(/** The root segment group of the URL tree */
  root = new UrlSegmentGroup([], {}), /** The query params of the URL */
  queryParams = {}, /** The fragment of the URL */
  fragment = null) {
    this.root = root;
    this.queryParams = queryParams;
    this.fragment = fragment;
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (root.segments.length > 0) {
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4015 /* RuntimeErrorCode.INVALID_ROOT_URL_SEGMENT */, 'The root `UrlSegmentGroup` should not contain `segments`. ' + 'Instead, these segments belong in the `children` so they can be associated with a named outlet.');
      }
    }
  }
  get queryParamMap() {
    this._queryParamMap ??= convertToParamMap(this.queryParams);
    return this._queryParamMap;
  }
  /** @docsNotRequired */
  toString() {
    return DEFAULT_SERIALIZER.serialize(this);
  }
}
/**
 * @description
 *
 * Represents the parsed URL segment group.
 *
 * See `UrlTree` for more information.
 *
 * @publicApi
 */
class UrlSegmentGroup {
  constructor(/** The URL segments of this group. See `UrlSegment` for more information */
  segments, /** The list of children of this group */
  children) {
    this.segments = segments;
    this.children = children;
    /** The parent node in the url tree */
    this.parent = null;
    Object.values(children).forEach(v => v.parent = this);
  }
  /** Whether the segment has child segments */
  hasChildren() {
    return this.numberOfChildren > 0;
  }
  /** Number of child segments */
  get numberOfChildren() {
    return Object.keys(this.children).length;
  }
  /** @docsNotRequired */
  toString() {
    return serializePaths(this);
  }
}
/**
 * @description
 *
 * Represents a single URL segment.
 *
 * A UrlSegment is a part of a URL between the two slashes. It contains a path and the matrix
 * parameters associated with the segment.
 *
 * @usageNotes
 * ### Example
 *
 * ```
 * @Component({templateUrl:'template.html'})
 * class MyComponent {
 *   constructor(router: Router) {
 *     const tree: UrlTree = router.parseUrl('/team;id=33');
 *     const g: UrlSegmentGroup = tree.root.children[PRIMARY_OUTLET];
 *     const s: UrlSegment[] = g.segments;
 *     s[0].path; // returns 'team'
 *     s[0].parameters; // returns {id: 33}
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class UrlSegment {
  constructor(/** The path part of a URL segment */
  path, /** The matrix parameters associated with a segment */
  parameters) {
    this.path = path;
    this.parameters = parameters;
  }
  get parameterMap() {
    this._parameterMap ??= convertToParamMap(this.parameters);
    return this._parameterMap;
  }
  /** @docsNotRequired */
  toString() {
    return serializePath(this);
  }
}
function equalSegments(as, bs) {
  return equalPath(as, bs) && as.every((a, i) => shallowEqual(a.parameters, bs[i].parameters));
}
function equalPath(as, bs) {
  if (as.length !== bs.length) return false;
  return as.every((a, i) => a.path === bs[i].path);
}
function mapChildrenIntoArray(segment, fn) {
  let res = [];
  Object.entries(segment.children).forEach(([childOutlet, child]) => {
    if (childOutlet === PRIMARY_OUTLET) {
      res = res.concat(fn(child, childOutlet));
    }
  });
  Object.entries(segment.children).forEach(([childOutlet, child]) => {
    if (childOutlet !== PRIMARY_OUTLET) {
      res = res.concat(fn(child, childOutlet));
    }
  });
  return res;
}
/**
 * @description
 *
 * Serializes and deserializes a URL string into a URL tree.
 *
 * The url serialization strategy is customizable. You can
 * make all URLs case insensitive by providing a custom UrlSerializer.
 *
 * See `DefaultUrlSerializer` for an example of a URL serializer.
 *
 * @publicApi
 */
class UrlSerializer {
  static {
    this.ɵfac = function UrlSerializer_Factory(t) {
      return new (t || UrlSerializer)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: UrlSerializer,
      factory: () => (() => new DefaultUrlSerializer())(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](UrlSerializer, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => new DefaultUrlSerializer()
    }]
  }], null, null);
})();
/**
 * @description
 *
 * A default implementation of the `UrlSerializer`.
 *
 * Example URLs:
 *
 * ```
 * /inbox/33(popup:compose)
 * /inbox/33;open=true/messages/44
 * ```
 *
 * DefaultUrlSerializer uses parentheses to serialize secondary segments (e.g., popup:compose), the
 * colon syntax to specify the outlet, and the ';parameter=value' syntax (e.g., open=true) to
 * specify route specific parameters.
 *
 * @publicApi
 */
class DefaultUrlSerializer {
  /** Parses a url into a `UrlTree` */
  parse(url) {
    const p = new UrlParser(url);
    return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
  }
  /** Converts a `UrlTree` into a url */
  serialize(tree) {
    const segment = `/${serializeSegment(tree.root, true)}`;
    const query = serializeQueryParams(tree.queryParams);
    const fragment = typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment)}` : '';
    return `${segment}${query}${fragment}`;
  }
}
const DEFAULT_SERIALIZER = new DefaultUrlSerializer();
function serializePaths(segment) {
  return segment.segments.map(p => serializePath(p)).join('/');
}
function serializeSegment(segment, root) {
  if (!segment.hasChildren()) {
    return serializePaths(segment);
  }
  if (root) {
    const primary = segment.children[PRIMARY_OUTLET] ? serializeSegment(segment.children[PRIMARY_OUTLET], false) : '';
    const children = [];
    Object.entries(segment.children).forEach(([k, v]) => {
      if (k !== PRIMARY_OUTLET) {
        children.push(`${k}:${serializeSegment(v, false)}`);
      }
    });
    return children.length > 0 ? `${primary}(${children.join('//')})` : primary;
  } else {
    const children = mapChildrenIntoArray(segment, (v, k) => {
      if (k === PRIMARY_OUTLET) {
        return [serializeSegment(segment.children[PRIMARY_OUTLET], false)];
      }
      return [`${k}:${serializeSegment(v, false)}`];
    });
    // use no parenthesis if the only child is a primary outlet route
    if (Object.keys(segment.children).length === 1 && segment.children[PRIMARY_OUTLET] != null) {
      return `${serializePaths(segment)}/${children[0]}`;
    }
    return `${serializePaths(segment)}/(${children.join('//')})`;
  }
}
/**
 * Encodes a URI string with the default encoding. This function will only ever be called from
 * `encodeUriQuery` or `encodeUriSegment` as it's the base set of encodings to be used. We need
 * a custom encoding because encodeURIComponent is too aggressive and encodes stuff that doesn't
 * have to be encoded per https://url.spec.whatwg.org.
 */
function encodeUriString(s) {
  return encodeURIComponent(s).replace(/%40/g, '@').replace(/%3A/gi, ':').replace(/%24/g, '$').replace(/%2C/gi, ',');
}
/**
 * This function should be used to encode both keys and values in a query string key/value. In
 * the following URL, you need to call encodeUriQuery on "k" and "v":
 *
 * http://www.site.org/html;mk=mv?k=v#f
 */
function encodeUriQuery(s) {
  return encodeUriString(s).replace(/%3B/gi, ';');
}
/**
 * This function should be used to encode a URL fragment. In the following URL, you need to call
 * encodeUriFragment on "f":
 *
 * http://www.site.org/html;mk=mv?k=v#f
 */
function encodeUriFragment(s) {
  return encodeURI(s);
}
/**
 * This function should be run on any URI segment as well as the key and value in a key/value
 * pair for matrix params. In the following URL, you need to call encodeUriSegment on "html",
 * "mk", and "mv":
 *
 * http://www.site.org/html;mk=mv?k=v#f
 */
function encodeUriSegment(s) {
  return encodeUriString(s).replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/%26/gi, '&');
}
function decode(s) {
  return decodeURIComponent(s);
}
// Query keys/values should have the "+" replaced first, as "+" in a query string is " ".
// decodeURIComponent function will not decode "+" as a space.
function decodeQuery(s) {
  return decode(s.replace(/\+/g, '%20'));
}
function serializePath(path) {
  return `${encodeUriSegment(path.path)}${serializeMatrixParams(path.parameters)}`;
}
function serializeMatrixParams(params) {
  return Object.entries(params).map(([key, value]) => `;${encodeUriSegment(key)}=${encodeUriSegment(value)}`).join('');
}
function serializeQueryParams(params) {
  const strParams = Object.entries(params).map(([name, value]) => {
    return Array.isArray(value) ? value.map(v => `${encodeUriQuery(name)}=${encodeUriQuery(v)}`).join('&') : `${encodeUriQuery(name)}=${encodeUriQuery(value)}`;
  }).filter(s => s);
  return strParams.length ? `?${strParams.join('&')}` : '';
}
const SEGMENT_RE = /^[^\/()?;#]+/;
function matchSegments(str) {
  const match = str.match(SEGMENT_RE);
  return match ? match[0] : '';
}
const MATRIX_PARAM_SEGMENT_RE = /^[^\/()?;=#]+/;
function matchMatrixKeySegments(str) {
  const match = str.match(MATRIX_PARAM_SEGMENT_RE);
  return match ? match[0] : '';
}
const QUERY_PARAM_RE = /^[^=?&#]+/;
// Return the name of the query param at the start of the string or an empty string
function matchQueryParams(str) {
  const match = str.match(QUERY_PARAM_RE);
  return match ? match[0] : '';
}
const QUERY_PARAM_VALUE_RE = /^[^&#]+/;
// Return the value of the query param at the start of the string or an empty string
function matchUrlQueryParamValue(str) {
  const match = str.match(QUERY_PARAM_VALUE_RE);
  return match ? match[0] : '';
}
class UrlParser {
  constructor(url) {
    this.url = url;
    this.remaining = url;
  }
  parseRootSegment() {
    this.consumeOptional('/');
    if (this.remaining === '' || this.peekStartsWith('?') || this.peekStartsWith('#')) {
      return new UrlSegmentGroup([], {});
    }
    // The root segment group never has segments
    return new UrlSegmentGroup([], this.parseChildren());
  }
  parseQueryParams() {
    const params = {};
    if (this.consumeOptional('?')) {
      do {
        this.parseQueryParam(params);
      } while (this.consumeOptional('&'));
    }
    return params;
  }
  parseFragment() {
    return this.consumeOptional('#') ? decodeURIComponent(this.remaining) : null;
  }
  parseChildren() {
    if (this.remaining === '') {
      return {};
    }
    this.consumeOptional('/');
    const segments = [];
    if (!this.peekStartsWith('(')) {
      segments.push(this.parseSegment());
    }
    while (this.peekStartsWith('/') && !this.peekStartsWith('//') && !this.peekStartsWith('/(')) {
      this.capture('/');
      segments.push(this.parseSegment());
    }
    let children = {};
    if (this.peekStartsWith('/(')) {
      this.capture('/');
      children = this.parseParens(true);
    }
    let res = {};
    if (this.peekStartsWith('(')) {
      res = this.parseParens(false);
    }
    if (segments.length > 0 || Object.keys(children).length > 0) {
      res[PRIMARY_OUTLET] = new UrlSegmentGroup(segments, children);
    }
    return res;
  }
  // parse a segment with its matrix parameters
  // ie `name;k1=v1;k2`
  parseSegment() {
    const path = matchSegments(this.remaining);
    if (path === '' && this.peekStartsWith(';')) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4009 /* RuntimeErrorCode.EMPTY_PATH_WITH_PARAMS */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Empty path url segment cannot have parameters: '${this.remaining}'.`);
    }
    this.capture(path);
    return new UrlSegment(decode(path), this.parseMatrixParams());
  }
  parseMatrixParams() {
    const params = {};
    while (this.consumeOptional(';')) {
      this.parseParam(params);
    }
    return params;
  }
  parseParam(params) {
    const key = matchMatrixKeySegments(this.remaining);
    if (!key) {
      return;
    }
    this.capture(key);
    let value = '';
    if (this.consumeOptional('=')) {
      const valueMatch = matchSegments(this.remaining);
      if (valueMatch) {
        value = valueMatch;
        this.capture(value);
      }
    }
    params[decode(key)] = decode(value);
  }
  // Parse a single query parameter `name[=value]`
  parseQueryParam(params) {
    const key = matchQueryParams(this.remaining);
    if (!key) {
      return;
    }
    this.capture(key);
    let value = '';
    if (this.consumeOptional('=')) {
      const valueMatch = matchUrlQueryParamValue(this.remaining);
      if (valueMatch) {
        value = valueMatch;
        this.capture(value);
      }
    }
    const decodedKey = decodeQuery(key);
    const decodedVal = decodeQuery(value);
    if (params.hasOwnProperty(decodedKey)) {
      // Append to existing values
      let currentVal = params[decodedKey];
      if (!Array.isArray(currentVal)) {
        currentVal = [currentVal];
        params[decodedKey] = currentVal;
      }
      currentVal.push(decodedVal);
    } else {
      // Create a new value
      params[decodedKey] = decodedVal;
    }
  }
  // parse `(a/b//outlet_name:c/d)`
  parseParens(allowPrimary) {
    const segments = {};
    this.capture('(');
    while (!this.consumeOptional(')') && this.remaining.length > 0) {
      const path = matchSegments(this.remaining);
      const next = this.remaining[path.length];
      // if is is not one of these characters, then the segment was unescaped
      // or the group was not closed
      if (next !== '/' && next !== ')' && next !== ';') {
        throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4010 /* RuntimeErrorCode.UNPARSABLE_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot parse url '${this.url}'`);
      }
      let outletName = undefined;
      if (path.indexOf(':') > -1) {
        outletName = path.slice(0, path.indexOf(':'));
        this.capture(outletName);
        this.capture(':');
      } else if (allowPrimary) {
        outletName = PRIMARY_OUTLET;
      }
      const children = this.parseChildren();
      segments[outletName] = Object.keys(children).length === 1 ? children[PRIMARY_OUTLET] : new UrlSegmentGroup([], children);
      this.consumeOptional('//');
    }
    return segments;
  }
  peekStartsWith(str) {
    return this.remaining.startsWith(str);
  }
  // Consumes the prefix when it is present and returns whether it has been consumed
  consumeOptional(str) {
    if (this.peekStartsWith(str)) {
      this.remaining = this.remaining.substring(str.length);
      return true;
    }
    return false;
  }
  capture(str) {
    if (!this.consumeOptional(str)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4011 /* RuntimeErrorCode.UNEXPECTED_VALUE_IN_URL */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Expected "${str}".`);
    }
  }
}
function createRoot(rootCandidate) {
  return rootCandidate.segments.length > 0 ? new UrlSegmentGroup([], {
    [PRIMARY_OUTLET]: rootCandidate
  }) : rootCandidate;
}
/**
 * Recursively
 * - merges primary segment children into their parents
 * - drops empty children (those which have no segments and no children themselves). This latter
 * prevents serializing a group into something like `/a(aux:)`, where `aux` is an empty child
 * segment.
 * - merges named outlets without a primary segment sibling into the children. This prevents
 * serializing a URL like `//(a:a)(b:b) instead of `/(a:a//b:b)` when the aux b route lives on the
 * root but the `a` route lives under an empty path primary route.
 */
function squashSegmentGroup(segmentGroup) {
  const newChildren = {};
  for (const [childOutlet, child] of Object.entries(segmentGroup.children)) {
    const childCandidate = squashSegmentGroup(child);
    // moves named children in an empty path primary child into this group
    if (childOutlet === PRIMARY_OUTLET && childCandidate.segments.length === 0 && childCandidate.hasChildren()) {
      for (const [grandChildOutlet, grandChild] of Object.entries(childCandidate.children)) {
        newChildren[grandChildOutlet] = grandChild;
      }
    } // don't add empty children
    else if (childCandidate.segments.length > 0 || childCandidate.hasChildren()) {
      newChildren[childOutlet] = childCandidate;
    }
  }
  const s = new UrlSegmentGroup(segmentGroup.segments, newChildren);
  return mergeTrivialChildren(s);
}
/**
 * When possible, merges the primary outlet child into the parent `UrlSegmentGroup`.
 *
 * When a segment group has only one child which is a primary outlet, merges that child into the
 * parent. That is, the child segment group's segments are merged into the `s` and the child's
 * children become the children of `s`. Think of this like a 'squash', merging the child segment
 * group into the parent.
 */
function mergeTrivialChildren(s) {
  if (s.numberOfChildren === 1 && s.children[PRIMARY_OUTLET]) {
    const c = s.children[PRIMARY_OUTLET];
    return new UrlSegmentGroup(s.segments.concat(c.segments), c.children);
  }
  return s;
}
function isUrlTree(v) {
  return v instanceof UrlTree;
}

/**
 * Creates a `UrlTree` relative to an `ActivatedRouteSnapshot`.
 *
 * @publicApi
 *
 *
 * @param relativeTo The `ActivatedRouteSnapshot` to apply the commands to
 * @param commands An array of URL fragments with which to construct the new URL tree.
 * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
 * segments, followed by the parameters for each segment.
 * The fragments are applied to the one provided in the `relativeTo` parameter.
 * @param queryParams The query parameters for the `UrlTree`. `null` if the `UrlTree` does not have
 *     any query parameters.
 * @param fragment The fragment for the `UrlTree`. `null` if the `UrlTree` does not have a fragment.
 *
 * @usageNotes
 *
 * ```
 * // create /team/33/user/11
 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, 'user', 11]);
 *
 * // create /team/33;expand=true/user/11
 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {expand: true}, 'user', 11]);
 *
 * // you can collapse static segments like this (this works only with the first passed-in value):
 * createUrlTreeFromSnapshot(snapshot, ['/team/33/user', userId]);
 *
 * // If the first segment can contain slashes, and you do not want the router to split it,
 * // you can do the following:
 * createUrlTreeFromSnapshot(snapshot, [{segmentPath: '/one/two'}]);
 *
 * // create /team/33/(user/11//right:chat)
 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right:
 * 'chat'}}], null, null);
 *
 * // remove the right secondary node
 * createUrlTreeFromSnapshot(snapshot, ['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
 *
 * // For the examples below, assume the current URL is for the `/team/33/user/11` and the
 * `ActivatedRouteSnapshot` points to `user/11`:
 *
 * // navigate to /team/33/user/11/details
 * createUrlTreeFromSnapshot(snapshot, ['details']);
 *
 * // navigate to /team/33/user/22
 * createUrlTreeFromSnapshot(snapshot, ['../22']);
 *
 * // navigate to /team/44/user/22
 * createUrlTreeFromSnapshot(snapshot, ['../../team/44/user/22']);
 * ```
 */
function createUrlTreeFromSnapshot(relativeTo, commands, queryParams = null, fragment = null) {
  const relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeTo);
  return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, queryParams, fragment);
}
function createSegmentGroupFromRoute(route) {
  let targetGroup;
  function createSegmentGroupFromRouteRecursive(currentRoute) {
    const childOutlets = {};
    for (const childSnapshot of currentRoute.children) {
      const root = createSegmentGroupFromRouteRecursive(childSnapshot);
      childOutlets[childSnapshot.outlet] = root;
    }
    const segmentGroup = new UrlSegmentGroup(currentRoute.url, childOutlets);
    if (currentRoute === route) {
      targetGroup = segmentGroup;
    }
    return segmentGroup;
  }
  const rootCandidate = createSegmentGroupFromRouteRecursive(route.root);
  const rootSegmentGroup = createRoot(rootCandidate);
  return targetGroup ?? rootSegmentGroup;
}
function createUrlTreeFromSegmentGroup(relativeTo, commands, queryParams, fragment) {
  let root = relativeTo;
  while (root.parent) {
    root = root.parent;
  }
  // There are no commands so the `UrlTree` goes to the same path as the one created from the
  // `UrlSegmentGroup`. All we need to do is update the `queryParams` and `fragment` without
  // applying any other logic.
  if (commands.length === 0) {
    return tree(root, root, root, queryParams, fragment);
  }
  const nav = computeNavigation(commands);
  if (nav.toRoot()) {
    return tree(root, root, new UrlSegmentGroup([], {}), queryParams, fragment);
  }
  const position = findStartingPositionForTargetGroup(nav, root, relativeTo);
  const newSegmentGroup = position.processChildren ? updateSegmentGroupChildren(position.segmentGroup, position.index, nav.commands) : updateSegmentGroup(position.segmentGroup, position.index, nav.commands);
  return tree(root, position.segmentGroup, newSegmentGroup, queryParams, fragment);
}
function isMatrixParams(command) {
  return typeof command === 'object' && command != null && !command.outlets && !command.segmentPath;
}
/**
 * Determines if a given command has an `outlets` map. When we encounter a command
 * with an outlets k/v map, we need to apply each outlet individually to the existing segment.
 */
function isCommandWithOutlets(command) {
  return typeof command === 'object' && command != null && command.outlets;
}
function tree(oldRoot, oldSegmentGroup, newSegmentGroup, queryParams, fragment) {
  let qp = {};
  if (queryParams) {
    Object.entries(queryParams).forEach(([name, value]) => {
      qp[name] = Array.isArray(value) ? value.map(v => `${v}`) : `${value}`;
    });
  }
  let rootCandidate;
  if (oldRoot === oldSegmentGroup) {
    rootCandidate = newSegmentGroup;
  } else {
    rootCandidate = replaceSegment(oldRoot, oldSegmentGroup, newSegmentGroup);
  }
  const newRoot = createRoot(squashSegmentGroup(rootCandidate));
  return new UrlTree(newRoot, qp, fragment);
}
/**
 * Replaces the `oldSegment` which is located in some child of the `current` with the `newSegment`.
 * This also has the effect of creating new `UrlSegmentGroup` copies to update references. This
 * shouldn't be necessary but the fallback logic for an invalid ActivatedRoute in the creation uses
 * the Router's current url tree. If we don't create new segment groups, we end up modifying that
 * value.
 */
function replaceSegment(current, oldSegment, newSegment) {
  const children = {};
  Object.entries(current.children).forEach(([outletName, c]) => {
    if (c === oldSegment) {
      children[outletName] = newSegment;
    } else {
      children[outletName] = replaceSegment(c, oldSegment, newSegment);
    }
  });
  return new UrlSegmentGroup(current.segments, children);
}
class Navigation {
  constructor(isAbsolute, numberOfDoubleDots, commands) {
    this.isAbsolute = isAbsolute;
    this.numberOfDoubleDots = numberOfDoubleDots;
    this.commands = commands;
    if (isAbsolute && commands.length > 0 && isMatrixParams(commands[0])) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4003 /* RuntimeErrorCode.ROOT_SEGMENT_MATRIX_PARAMS */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Root segment cannot have matrix parameters');
    }
    const cmdWithOutlet = commands.find(isCommandWithOutlets);
    if (cmdWithOutlet && cmdWithOutlet !== last(commands)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4004 /* RuntimeErrorCode.MISPLACED_OUTLETS_COMMAND */, (typeof ngDevMode === 'undefined' || ngDevMode) && '{outlets:{}} has to be the last command');
    }
  }
  toRoot() {
    return this.isAbsolute && this.commands.length === 1 && this.commands[0] == '/';
  }
}
/** Transforms commands to a normalized `Navigation` */
function computeNavigation(commands) {
  if (typeof commands[0] === 'string' && commands.length === 1 && commands[0] === '/') {
    return new Navigation(true, 0, commands);
  }
  let numberOfDoubleDots = 0;
  let isAbsolute = false;
  const res = commands.reduce((res, cmd, cmdIdx) => {
    if (typeof cmd === 'object' && cmd != null) {
      if (cmd.outlets) {
        const outlets = {};
        Object.entries(cmd.outlets).forEach(([name, commands]) => {
          outlets[name] = typeof commands === 'string' ? commands.split('/') : commands;
        });
        return [...res, {
          outlets
        }];
      }
      if (cmd.segmentPath) {
        return [...res, cmd.segmentPath];
      }
    }
    if (!(typeof cmd === 'string')) {
      return [...res, cmd];
    }
    if (cmdIdx === 0) {
      cmd.split('/').forEach((urlPart, partIndex) => {
        if (partIndex == 0 && urlPart === '.') {
          // skip './a'
        } else if (partIndex == 0 && urlPart === '') {
          //  '/a'
          isAbsolute = true;
        } else if (urlPart === '..') {
          //  '../a'
          numberOfDoubleDots++;
        } else if (urlPart != '') {
          res.push(urlPart);
        }
      });
      return res;
    }
    return [...res, cmd];
  }, []);
  return new Navigation(isAbsolute, numberOfDoubleDots, res);
}
class Position {
  constructor(segmentGroup, processChildren, index) {
    this.segmentGroup = segmentGroup;
    this.processChildren = processChildren;
    this.index = index;
  }
}
function findStartingPositionForTargetGroup(nav, root, target) {
  if (nav.isAbsolute) {
    return new Position(root, true, 0);
  }
  if (!target) {
    // `NaN` is used only to maintain backwards compatibility with incorrectly mocked
    // `ActivatedRouteSnapshot` in tests. In prior versions of this code, the position here was
    // determined based on an internal property that was rarely mocked, resulting in `NaN`. In
    // reality, this code path should _never_ be touched since `target` is not allowed to be falsey.
    return new Position(root, false, NaN);
  }
  if (target.parent === null) {
    return new Position(target, true, 0);
  }
  const modifier = isMatrixParams(nav.commands[0]) ? 0 : 1;
  const index = target.segments.length - 1 + modifier;
  return createPositionApplyingDoubleDots(target, index, nav.numberOfDoubleDots);
}
function createPositionApplyingDoubleDots(group, index, numberOfDoubleDots) {
  let g = group;
  let ci = index;
  let dd = numberOfDoubleDots;
  while (dd > ci) {
    dd -= ci;
    g = g.parent;
    if (!g) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4005 /* RuntimeErrorCode.INVALID_DOUBLE_DOTS */, (typeof ngDevMode === 'undefined' || ngDevMode) && "Invalid number of '../'");
    }
    ci = g.segments.length;
  }
  return new Position(g, false, ci - dd);
}
function getOutlets(commands) {
  if (isCommandWithOutlets(commands[0])) {
    return commands[0].outlets;
  }
  return {
    [PRIMARY_OUTLET]: commands
  };
}
function updateSegmentGroup(segmentGroup, startIndex, commands) {
  segmentGroup ??= new UrlSegmentGroup([], {});
  if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
    return updateSegmentGroupChildren(segmentGroup, startIndex, commands);
  }
  const m = prefixedWith(segmentGroup, startIndex, commands);
  const slicedCommands = commands.slice(m.commandIndex);
  if (m.match && m.pathIndex < segmentGroup.segments.length) {
    const g = new UrlSegmentGroup(segmentGroup.segments.slice(0, m.pathIndex), {});
    g.children[PRIMARY_OUTLET] = new UrlSegmentGroup(segmentGroup.segments.slice(m.pathIndex), segmentGroup.children);
    return updateSegmentGroupChildren(g, 0, slicedCommands);
  } else if (m.match && slicedCommands.length === 0) {
    return new UrlSegmentGroup(segmentGroup.segments, {});
  } else if (m.match && !segmentGroup.hasChildren()) {
    return createNewSegmentGroup(segmentGroup, startIndex, commands);
  } else if (m.match) {
    return updateSegmentGroupChildren(segmentGroup, 0, slicedCommands);
  } else {
    return createNewSegmentGroup(segmentGroup, startIndex, commands);
  }
}
function updateSegmentGroupChildren(segmentGroup, startIndex, commands) {
  if (commands.length === 0) {
    return new UrlSegmentGroup(segmentGroup.segments, {});
  } else {
    const outlets = getOutlets(commands);
    const children = {};
    // If the set of commands applies to anything other than the primary outlet and the child
    // segment is an empty path primary segment on its own, we want to apply the commands to the
    // empty child path rather than here. The outcome is that the empty primary child is effectively
    // removed from the final output UrlTree. Imagine the following config:
    //
    // {path: '', children: [{path: '**', outlet: 'popup'}]}.
    //
    // Navigation to /(popup:a) will activate the child outlet correctly Given a follow-up
    // navigation with commands
    // ['/', {outlets: {'popup': 'b'}}], we _would not_ want to apply the outlet commands to the
    // root segment because that would result in
    // //(popup:a)(popup:b) since the outlet command got applied one level above where it appears in
    // the `ActivatedRoute` rather than updating the existing one.
    //
    // Because empty paths do not appear in the URL segments and the fact that the segments used in
    // the output `UrlTree` are squashed to eliminate these empty paths where possible
    // https://github.com/angular/angular/blob/13f10de40e25c6900ca55bd83b36bd533dacfa9e/packages/router/src/url_tree.ts#L755
    // it can be hard to determine what is the right thing to do when applying commands to a
    // `UrlSegmentGroup` that is created from an "unsquashed"/expanded `ActivatedRoute` tree.
    // This code effectively "squashes" empty path primary routes when they have no siblings on
    // the same level of the tree.
    if (Object.keys(outlets).some(o => o !== PRIMARY_OUTLET) && segmentGroup.children[PRIMARY_OUTLET] && segmentGroup.numberOfChildren === 1 && segmentGroup.children[PRIMARY_OUTLET].segments.length === 0) {
      const childrenOfEmptyChild = updateSegmentGroupChildren(segmentGroup.children[PRIMARY_OUTLET], startIndex, commands);
      return new UrlSegmentGroup(segmentGroup.segments, childrenOfEmptyChild.children);
    }
    Object.entries(outlets).forEach(([outlet, commands]) => {
      if (typeof commands === 'string') {
        commands = [commands];
      }
      if (commands !== null) {
        children[outlet] = updateSegmentGroup(segmentGroup.children[outlet], startIndex, commands);
      }
    });
    Object.entries(segmentGroup.children).forEach(([childOutlet, child]) => {
      if (outlets[childOutlet] === undefined) {
        children[childOutlet] = child;
      }
    });
    return new UrlSegmentGroup(segmentGroup.segments, children);
  }
}
function prefixedWith(segmentGroup, startIndex, commands) {
  let currentCommandIndex = 0;
  let currentPathIndex = startIndex;
  const noMatch = {
    match: false,
    pathIndex: 0,
    commandIndex: 0
  };
  while (currentPathIndex < segmentGroup.segments.length) {
    if (currentCommandIndex >= commands.length) return noMatch;
    const path = segmentGroup.segments[currentPathIndex];
    const command = commands[currentCommandIndex];
    // Do not try to consume command as part of the prefixing if it has outlets because it can
    // contain outlets other than the one being processed. Consuming the outlets command would
    // result in other outlets being ignored.
    if (isCommandWithOutlets(command)) {
      break;
    }
    const curr = `${command}`;
    const next = currentCommandIndex < commands.length - 1 ? commands[currentCommandIndex + 1] : null;
    if (currentPathIndex > 0 && curr === undefined) break;
    if (curr && next && typeof next === 'object' && next.outlets === undefined) {
      if (!compare(curr, next, path)) return noMatch;
      currentCommandIndex += 2;
    } else {
      if (!compare(curr, {}, path)) return noMatch;
      currentCommandIndex++;
    }
    currentPathIndex++;
  }
  return {
    match: true,
    pathIndex: currentPathIndex,
    commandIndex: currentCommandIndex
  };
}
function createNewSegmentGroup(segmentGroup, startIndex, commands) {
  const paths = segmentGroup.segments.slice(0, startIndex);
  let i = 0;
  while (i < commands.length) {
    const command = commands[i];
    if (isCommandWithOutlets(command)) {
      const children = createNewSegmentChildren(command.outlets);
      return new UrlSegmentGroup(paths, children);
    }
    // if we start with an object literal, we need to reuse the path part from the segment
    if (i === 0 && isMatrixParams(commands[0])) {
      const p = segmentGroup.segments[startIndex];
      paths.push(new UrlSegment(p.path, stringify(commands[0])));
      i++;
      continue;
    }
    const curr = isCommandWithOutlets(command) ? command.outlets[PRIMARY_OUTLET] : `${command}`;
    const next = i < commands.length - 1 ? commands[i + 1] : null;
    if (curr && next && isMatrixParams(next)) {
      paths.push(new UrlSegment(curr, stringify(next)));
      i += 2;
    } else {
      paths.push(new UrlSegment(curr, {}));
      i++;
    }
  }
  return new UrlSegmentGroup(paths, {});
}
function createNewSegmentChildren(outlets) {
  const children = {};
  Object.entries(outlets).forEach(([outlet, commands]) => {
    if (typeof commands === 'string') {
      commands = [commands];
    }
    if (commands !== null) {
      children[outlet] = createNewSegmentGroup(new UrlSegmentGroup([], {}), 0, commands);
    }
  });
  return children;
}
function stringify(params) {
  const res = {};
  Object.entries(params).forEach(([k, v]) => res[k] = `${v}`);
  return res;
}
function compare(path, params, segment) {
  return path == segment.path && shallowEqual(params, segment.parameters);
}
const IMPERATIVE_NAVIGATION = 'imperative';
/**
 * Identifies the type of a router event.
 *
 * @publicApi
 */
var EventType;
(function (EventType) {
  EventType[EventType["NavigationStart"] = 0] = "NavigationStart";
  EventType[EventType["NavigationEnd"] = 1] = "NavigationEnd";
  EventType[EventType["NavigationCancel"] = 2] = "NavigationCancel";
  EventType[EventType["NavigationError"] = 3] = "NavigationError";
  EventType[EventType["RoutesRecognized"] = 4] = "RoutesRecognized";
  EventType[EventType["ResolveStart"] = 5] = "ResolveStart";
  EventType[EventType["ResolveEnd"] = 6] = "ResolveEnd";
  EventType[EventType["GuardsCheckStart"] = 7] = "GuardsCheckStart";
  EventType[EventType["GuardsCheckEnd"] = 8] = "GuardsCheckEnd";
  EventType[EventType["RouteConfigLoadStart"] = 9] = "RouteConfigLoadStart";
  EventType[EventType["RouteConfigLoadEnd"] = 10] = "RouteConfigLoadEnd";
  EventType[EventType["ChildActivationStart"] = 11] = "ChildActivationStart";
  EventType[EventType["ChildActivationEnd"] = 12] = "ChildActivationEnd";
  EventType[EventType["ActivationStart"] = 13] = "ActivationStart";
  EventType[EventType["ActivationEnd"] = 14] = "ActivationEnd";
  EventType[EventType["Scroll"] = 15] = "Scroll";
  EventType[EventType["NavigationSkipped"] = 16] = "NavigationSkipped";
})(EventType || (EventType = {}));
/**
 * Base for events the router goes through, as opposed to events tied to a specific
 * route. Fired one time for any given navigation.
 *
 * The following code shows how a class subscribes to router events.
 *
 * ```ts
 * import {Event, RouterEvent, Router} from '@angular/router';
 *
 * class MyService {
 *   constructor(public router: Router) {
 *     router.events.pipe(
 *        filter((e: Event | RouterEvent): e is RouterEvent => e instanceof RouterEvent)
 *     ).subscribe((e: RouterEvent) => {
 *       // Do something
 *     });
 *   }
 * }
 * ```
 *
 * @see {@link Event}
 * @see [Router events summary](guide/router-reference#router-events)
 * @publicApi
 */
class RouterEvent {
  constructor(/** A unique ID that the router assigns to every router navigation. */
  id, /** The URL that is the destination for this navigation. */
  url) {
    this.id = id;
    this.url = url;
  }
}
/**
 * An event triggered when a navigation starts.
 *
 * @publicApi
 */
class NavigationStart extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  navigationTrigger = 'imperative', /** @docsNotRequired */
  restoredState = null) {
    super(id, url);
    this.type = EventType.NavigationStart;
    this.navigationTrigger = navigationTrigger;
    this.restoredState = restoredState;
  }
  /** @docsNotRequired */
  toString() {
    return `NavigationStart(id: ${this.id}, url: '${this.url}')`;
  }
}
/**
 * An event triggered when a navigation ends successfully.
 *
 * @see {@link NavigationStart}
 * @see {@link NavigationCancel}
 * @see {@link NavigationError}
 *
 * @publicApi
 */
class NavigationEnd extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.type = EventType.NavigationEnd;
  }
  /** @docsNotRequired */
  toString() {
    return `NavigationEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}')`;
  }
}
/**
 * A code for the `NavigationCancel` event of the `Router` to indicate the
 * reason a navigation failed.
 *
 * @publicApi
 */
var NavigationCancellationCode;
(function (NavigationCancellationCode) {
  /**
   * A navigation failed because a guard returned a `UrlTree` to redirect.
   */
  NavigationCancellationCode[NavigationCancellationCode["Redirect"] = 0] = "Redirect";
  /**
   * A navigation failed because a more recent navigation started.
   */
  NavigationCancellationCode[NavigationCancellationCode["SupersededByNewNavigation"] = 1] = "SupersededByNewNavigation";
  /**
   * A navigation failed because one of the resolvers completed without emitting a value.
   */
  NavigationCancellationCode[NavigationCancellationCode["NoDataFromResolver"] = 2] = "NoDataFromResolver";
  /**
   * A navigation failed because a guard returned `false`.
   */
  NavigationCancellationCode[NavigationCancellationCode["GuardRejected"] = 3] = "GuardRejected";
})(NavigationCancellationCode || (NavigationCancellationCode = {}));
/**
 * A code for the `NavigationSkipped` event of the `Router` to indicate the
 * reason a navigation was skipped.
 *
 * @publicApi
 */
var NavigationSkippedCode;
(function (NavigationSkippedCode) {
  /**
   * A navigation was skipped because the navigation URL was the same as the current Router URL.
   */
  NavigationSkippedCode[NavigationSkippedCode["IgnoredSameUrlNavigation"] = 0] = "IgnoredSameUrlNavigation";
  /**
   * A navigation was skipped because the configured `UrlHandlingStrategy` return `false` for both
   * the current Router URL and the target of the navigation.
   *
   * @see {@link UrlHandlingStrategy}
   */
  NavigationSkippedCode[NavigationSkippedCode["IgnoredByUrlHandlingStrategy"] = 1] = "IgnoredByUrlHandlingStrategy";
})(NavigationSkippedCode || (NavigationSkippedCode = {}));
/**
 * An event triggered when a navigation is canceled, directly or indirectly.
 * This can happen for several reasons including when a route guard
 * returns `false` or initiates a redirect by returning a `UrlTree`.
 *
 * @see {@link NavigationStart}
 * @see {@link NavigationEnd}
 * @see {@link NavigationError}
 *
 * @publicApi
 */
class NavigationCancel extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url,
  /**
   * A description of why the navigation was cancelled. For debug purposes only. Use `code`
   * instead for a stable cancellation reason that can be used in production.
   */
  reason,
  /**
   * A code to indicate why the navigation was canceled. This cancellation code is stable for
   * the reason and can be relied on whereas the `reason` string could change and should not be
   * used in production.
   */
  code) {
    super(id, url);
    this.reason = reason;
    this.code = code;
    this.type = EventType.NavigationCancel;
  }
  /** @docsNotRequired */
  toString() {
    return `NavigationCancel(id: ${this.id}, url: '${this.url}')`;
  }
}
/**
 * An event triggered when a navigation is skipped.
 * This can happen for a couple reasons including onSameUrlHandling
 * is set to `ignore` and the navigation URL is not different than the
 * current state.
 *
 * @publicApi
 */
class NavigationSkipped extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url,
  /**
   * A description of why the navigation was skipped. For debug purposes only. Use `code`
   * instead for a stable skipped reason that can be used in production.
   */
  reason,
  /**
   * A code to indicate why the navigation was skipped. This code is stable for
   * the reason and can be relied on whereas the `reason` string could change and should not be
   * used in production.
   */
  code) {
    super(id, url);
    this.reason = reason;
    this.code = code;
    this.type = EventType.NavigationSkipped;
  }
}
/**
 * An event triggered when a navigation fails due to an unexpected error.
 *
 * @see {@link NavigationStart}
 * @see {@link NavigationEnd}
 * @see {@link NavigationCancel}
 *
 * @publicApi
 */
class NavigationError extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  error,
  /**
   * The target of the navigation when the error occurred.
   *
   * Note that this can be `undefined` because an error could have occurred before the
   * `RouterStateSnapshot` was created for the navigation.
   */
  target) {
    super(id, url);
    this.error = error;
    this.target = target;
    this.type = EventType.NavigationError;
  }
  /** @docsNotRequired */
  toString() {
    return `NavigationError(id: ${this.id}, url: '${this.url}', error: ${this.error})`;
  }
}
/**
 * An event triggered when routes are recognized.
 *
 * @publicApi
 */
class RoutesRecognized extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects, /** @docsNotRequired */
  state) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.state = state;
    this.type = EventType.RoutesRecognized;
  }
  /** @docsNotRequired */
  toString() {
    return `RoutesRecognized(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }
}
/**
 * An event triggered at the start of the Guard phase of routing.
 *
 * @see {@link GuardsCheckEnd}
 *
 * @publicApi
 */
class GuardsCheckStart extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects, /** @docsNotRequired */
  state) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.state = state;
    this.type = EventType.GuardsCheckStart;
  }
  toString() {
    return `GuardsCheckStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }
}
/**
 * An event triggered at the end of the Guard phase of routing.
 *
 * @see {@link GuardsCheckStart}
 *
 * @publicApi
 */
class GuardsCheckEnd extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects, /** @docsNotRequired */
  state, /** @docsNotRequired */
  shouldActivate) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.state = state;
    this.shouldActivate = shouldActivate;
    this.type = EventType.GuardsCheckEnd;
  }
  toString() {
    return `GuardsCheckEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state}, shouldActivate: ${this.shouldActivate})`;
  }
}
/**
 * An event triggered at the start of the Resolve phase of routing.
 *
 * Runs in the "resolve" phase whether or not there is anything to resolve.
 * In future, may change to only run when there are things to be resolved.
 *
 * @see {@link ResolveEnd}
 *
 * @publicApi
 */
class ResolveStart extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects, /** @docsNotRequired */
  state) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.state = state;
    this.type = EventType.ResolveStart;
  }
  toString() {
    return `ResolveStart(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }
}
/**
 * An event triggered at the end of the Resolve phase of routing.
 * @see {@link ResolveStart}
 *
 * @publicApi
 */
class ResolveEnd extends RouterEvent {
  constructor(/** @docsNotRequired */
  id, /** @docsNotRequired */
  url, /** @docsNotRequired */
  urlAfterRedirects, /** @docsNotRequired */
  state) {
    super(id, url);
    this.urlAfterRedirects = urlAfterRedirects;
    this.state = state;
    this.type = EventType.ResolveEnd;
  }
  toString() {
    return `ResolveEnd(id: ${this.id}, url: '${this.url}', urlAfterRedirects: '${this.urlAfterRedirects}', state: ${this.state})`;
  }
}
/**
 * An event triggered before lazy loading a route configuration.
 *
 * @see {@link RouteConfigLoadEnd}
 *
 * @publicApi
 */
class RouteConfigLoadStart {
  constructor(/** @docsNotRequired */
  route) {
    this.route = route;
    this.type = EventType.RouteConfigLoadStart;
  }
  toString() {
    return `RouteConfigLoadStart(path: ${this.route.path})`;
  }
}
/**
 * An event triggered when a route has been lazy loaded.
 *
 * @see {@link RouteConfigLoadStart}
 *
 * @publicApi
 */
class RouteConfigLoadEnd {
  constructor(/** @docsNotRequired */
  route) {
    this.route = route;
    this.type = EventType.RouteConfigLoadEnd;
  }
  toString() {
    return `RouteConfigLoadEnd(path: ${this.route.path})`;
  }
}
/**
 * An event triggered at the start of the child-activation
 * part of the Resolve phase of routing.
 * @see {@link ChildActivationEnd}
 * @see {@link ResolveStart}
 *
 * @publicApi
 */
class ChildActivationStart {
  constructor(/** @docsNotRequired */
  snapshot) {
    this.snapshot = snapshot;
    this.type = EventType.ChildActivationStart;
  }
  toString() {
    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
    return `ChildActivationStart(path: '${path}')`;
  }
}
/**
 * An event triggered at the end of the child-activation part
 * of the Resolve phase of routing.
 * @see {@link ChildActivationStart}
 * @see {@link ResolveStart}
 * @publicApi
 */
class ChildActivationEnd {
  constructor(/** @docsNotRequired */
  snapshot) {
    this.snapshot = snapshot;
    this.type = EventType.ChildActivationEnd;
  }
  toString() {
    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
    return `ChildActivationEnd(path: '${path}')`;
  }
}
/**
 * An event triggered at the start of the activation part
 * of the Resolve phase of routing.
 * @see {@link ActivationEnd}
 * @see {@link ResolveStart}
 *
 * @publicApi
 */
class ActivationStart {
  constructor(/** @docsNotRequired */
  snapshot) {
    this.snapshot = snapshot;
    this.type = EventType.ActivationStart;
  }
  toString() {
    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
    return `ActivationStart(path: '${path}')`;
  }
}
/**
 * An event triggered at the end of the activation part
 * of the Resolve phase of routing.
 * @see {@link ActivationStart}
 * @see {@link ResolveStart}
 *
 * @publicApi
 */
class ActivationEnd {
  constructor(/** @docsNotRequired */
  snapshot) {
    this.snapshot = snapshot;
    this.type = EventType.ActivationEnd;
  }
  toString() {
    const path = this.snapshot.routeConfig && this.snapshot.routeConfig.path || '';
    return `ActivationEnd(path: '${path}')`;
  }
}
/**
 * An event triggered by scrolling.
 *
 * @publicApi
 */
class Scroll {
  constructor(/** @docsNotRequired */
  routerEvent, /** @docsNotRequired */
  position, /** @docsNotRequired */
  anchor) {
    this.routerEvent = routerEvent;
    this.position = position;
    this.anchor = anchor;
    this.type = EventType.Scroll;
  }
  toString() {
    const pos = this.position ? `${this.position[0]}, ${this.position[1]}` : null;
    return `Scroll(anchor: '${this.anchor}', position: '${pos}')`;
  }
}
class BeforeActivateRoutes {}
class RedirectRequest {
  constructor(url) {
    this.url = url;
  }
}
function stringifyEvent(routerEvent) {
  switch (routerEvent.type) {
    case EventType.ActivationEnd:
      return `ActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
    case EventType.ActivationStart:
      return `ActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
    case EventType.ChildActivationEnd:
      return `ChildActivationEnd(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
    case EventType.ChildActivationStart:
      return `ChildActivationStart(path: '${routerEvent.snapshot.routeConfig?.path || ''}')`;
    case EventType.GuardsCheckEnd:
      return `GuardsCheckEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state}, shouldActivate: ${routerEvent.shouldActivate})`;
    case EventType.GuardsCheckStart:
      return `GuardsCheckStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
    case EventType.NavigationCancel:
      return `NavigationCancel(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
    case EventType.NavigationSkipped:
      return `NavigationSkipped(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
    case EventType.NavigationEnd:
      return `NavigationEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}')`;
    case EventType.NavigationError:
      return `NavigationError(id: ${routerEvent.id}, url: '${routerEvent.url}', error: ${routerEvent.error})`;
    case EventType.NavigationStart:
      return `NavigationStart(id: ${routerEvent.id}, url: '${routerEvent.url}')`;
    case EventType.ResolveEnd:
      return `ResolveEnd(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
    case EventType.ResolveStart:
      return `ResolveStart(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
    case EventType.RouteConfigLoadEnd:
      return `RouteConfigLoadEnd(path: ${routerEvent.route.path})`;
    case EventType.RouteConfigLoadStart:
      return `RouteConfigLoadStart(path: ${routerEvent.route.path})`;
    case EventType.RoutesRecognized:
      return `RoutesRecognized(id: ${routerEvent.id}, url: '${routerEvent.url}', urlAfterRedirects: '${routerEvent.urlAfterRedirects}', state: ${routerEvent.state})`;
    case EventType.Scroll:
      const pos = routerEvent.position ? `${routerEvent.position[0]}, ${routerEvent.position[1]}` : null;
      return `Scroll(anchor: '${routerEvent.anchor}', position: '${pos}')`;
  }
}

/**
 * Store contextual information about a `RouterOutlet`
 *
 * @publicApi
 */
class OutletContext {
  constructor() {
    this.outlet = null;
    this.route = null;
    this.injector = null;
    this.children = new ChildrenOutletContexts();
    this.attachRef = null;
  }
}
/**
 * Store contextual information about the children (= nested) `RouterOutlet`
 *
 * @publicApi
 */
class ChildrenOutletContexts {
  constructor() {
    // contexts for child outlets, by name.
    this.contexts = new Map();
  }
  /** Called when a `RouterOutlet` directive is instantiated */
  onChildOutletCreated(childName, outlet) {
    const context = this.getOrCreateContext(childName);
    context.outlet = outlet;
    this.contexts.set(childName, context);
  }
  /**
   * Called when a `RouterOutlet` directive is destroyed.
   * We need to keep the context as the outlet could be destroyed inside a NgIf and might be
   * re-created later.
   */
  onChildOutletDestroyed(childName) {
    const context = this.getContext(childName);
    if (context) {
      context.outlet = null;
      context.attachRef = null;
    }
  }
  /**
   * Called when the corresponding route is deactivated during navigation.
   * Because the component get destroyed, all children outlet are destroyed.
   */
  onOutletDeactivated() {
    const contexts = this.contexts;
    this.contexts = new Map();
    return contexts;
  }
  onOutletReAttached(contexts) {
    this.contexts = contexts;
  }
  getOrCreateContext(childName) {
    let context = this.getContext(childName);
    if (!context) {
      context = new OutletContext();
      this.contexts.set(childName, context);
    }
    return context;
  }
  getContext(childName) {
    return this.contexts.get(childName) || null;
  }
  static {
    this.ɵfac = function ChildrenOutletContexts_Factory(t) {
      return new (t || ChildrenOutletContexts)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: ChildrenOutletContexts,
      factory: ChildrenOutletContexts.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](ChildrenOutletContexts, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class Tree {
  constructor(root) {
    this._root = root;
  }
  get root() {
    return this._root.value;
  }
  /**
   * @internal
   */
  parent(t) {
    const p = this.pathFromRoot(t);
    return p.length > 1 ? p[p.length - 2] : null;
  }
  /**
   * @internal
   */
  children(t) {
    const n = findNode(t, this._root);
    return n ? n.children.map(t => t.value) : [];
  }
  /**
   * @internal
   */
  firstChild(t) {
    const n = findNode(t, this._root);
    return n && n.children.length > 0 ? n.children[0].value : null;
  }
  /**
   * @internal
   */
  siblings(t) {
    const p = findPath(t, this._root);
    if (p.length < 2) return [];
    const c = p[p.length - 2].children.map(c => c.value);
    return c.filter(cc => cc !== t);
  }
  /**
   * @internal
   */
  pathFromRoot(t) {
    return findPath(t, this._root).map(s => s.value);
  }
}
// DFS for the node matching the value
function findNode(value, node) {
  if (value === node.value) return node;
  for (const child of node.children) {
    const node = findNode(value, child);
    if (node) return node;
  }
  return null;
}
// Return the path to the node with the given value using DFS
function findPath(value, node) {
  if (value === node.value) return [node];
  for (const child of node.children) {
    const path = findPath(value, child);
    if (path.length) {
      path.unshift(node);
      return path;
    }
  }
  return [];
}
class TreeNode {
  constructor(value, children) {
    this.value = value;
    this.children = children;
  }
  toString() {
    return `TreeNode(${this.value})`;
  }
}
// Return the list of T indexed by outlet name
function nodeChildrenAsMap(node) {
  const map = {};
  if (node) {
    node.children.forEach(child => map[child.value.outlet] = child);
  }
  return map;
}

/**
 * Represents the state of the router as a tree of activated routes.
 *
 * @usageNotes
 *
 * Every node in the route tree is an `ActivatedRoute` instance
 * that knows about the "consumed" URL segments, the extracted parameters,
 * and the resolved data.
 * Use the `ActivatedRoute` properties to traverse the tree from any node.
 *
 * The following fragment shows how a component gets the root node
 * of the current state to establish its own route tree:
 *
 * ```
 * @Component({templateUrl:'template.html'})
 * class MyComponent {
 *   constructor(router: Router) {
 *     const state: RouterState = router.routerState;
 *     const root: ActivatedRoute = state.root;
 *     const child = root.firstChild;
 *     const id: Observable<string> = child.params.map(p => p.id);
 *     //...
 *   }
 * }
 * ```
 *
 * @see {@link ActivatedRoute}
 * @see [Getting route information](guide/router#getting-route-information)
 *
 * @publicApi
 */
class RouterState extends Tree {
  /** @internal */
  constructor(root, /** The current snapshot of the router state */
  snapshot) {
    super(root);
    this.snapshot = snapshot;
    setRouterState(this, root);
  }
  toString() {
    return this.snapshot.toString();
  }
}
function createEmptyState(rootComponent) {
  const snapshot = createEmptyStateSnapshot(rootComponent);
  const emptyUrl = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject([new UrlSegment('', {})]);
  const emptyParams = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject({});
  const emptyData = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject({});
  const emptyQueryParams = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject({});
  const fragment = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject('');
  const activated = new ActivatedRoute(emptyUrl, emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, snapshot.root);
  activated.snapshot = snapshot.root;
  return new RouterState(new TreeNode(activated, []), snapshot);
}
function createEmptyStateSnapshot(rootComponent) {
  const emptyParams = {};
  const emptyData = {};
  const emptyQueryParams = {};
  const fragment = '';
  const activated = new ActivatedRouteSnapshot([], emptyParams, emptyQueryParams, fragment, emptyData, PRIMARY_OUTLET, rootComponent, null, {});
  return new RouterStateSnapshot('', new TreeNode(activated, []));
}
/**
 * Provides access to information about a route associated with a component
 * that is loaded in an outlet.
 * Use to traverse the `RouterState` tree and extract information from nodes.
 *
 * The following example shows how to construct a component using information from a
 * currently activated route.
 *
 * Note: the observables in this class only emit when the current and previous values differ based
 * on shallow equality. For example, changing deeply nested properties in resolved `data` will not
 * cause the `ActivatedRoute.data` `Observable` to emit a new value.
 *
 * {@example router/activated-route/module.ts region="activated-route"
 *     header="activated-route.component.ts"}
 *
 * @see [Getting route information](guide/router#getting-route-information)
 *
 * @publicApi
 */
class ActivatedRoute {
  /** @internal */
  constructor(/** @internal */
  urlSubject, /** @internal */
  paramsSubject, /** @internal */
  queryParamsSubject, /** @internal */
  fragmentSubject, /** @internal */
  dataSubject, /** The outlet name of the route, a constant. */
  outlet, /** The component of the route, a constant. */
  component, futureSnapshot) {
    this.urlSubject = urlSubject;
    this.paramsSubject = paramsSubject;
    this.queryParamsSubject = queryParamsSubject;
    this.fragmentSubject = fragmentSubject;
    this.dataSubject = dataSubject;
    this.outlet = outlet;
    this.component = component;
    this._futureSnapshot = futureSnapshot;
    this.title = this.dataSubject?.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(d => d[RouteTitleKey])) ?? (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(undefined);
    // TODO(atscott): Verify that these can be changed to `.asObservable()` with TGP.
    this.url = urlSubject;
    this.params = paramsSubject;
    this.queryParams = queryParamsSubject;
    this.fragment = fragmentSubject;
    this.data = dataSubject;
  }
  /** The configuration used to match this route. */
  get routeConfig() {
    return this._futureSnapshot.routeConfig;
  }
  /** The root of the router state. */
  get root() {
    return this._routerState.root;
  }
  /** The parent of this route in the router state tree. */
  get parent() {
    return this._routerState.parent(this);
  }
  /** The first child of this route in the router state tree. */
  get firstChild() {
    return this._routerState.firstChild(this);
  }
  /** The children of this route in the router state tree. */
  get children() {
    return this._routerState.children(this);
  }
  /** The path from the root of the router state tree to this route. */
  get pathFromRoot() {
    return this._routerState.pathFromRoot(this);
  }
  /**
   * An Observable that contains a map of the required and optional parameters
   * specific to the route.
   * The map supports retrieving single and multiple values from the same parameter.
   */
  get paramMap() {
    this._paramMap ??= this.params.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(p => convertToParamMap(p)));
    return this._paramMap;
  }
  /**
   * An Observable that contains a map of the query parameters available to all routes.
   * The map supports retrieving single and multiple values from the query parameter.
   */
  get queryParamMap() {
    this._queryParamMap ??= this.queryParams.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(p => convertToParamMap(p)));
    return this._queryParamMap;
  }
  toString() {
    return this.snapshot ? this.snapshot.toString() : `Future(${this._futureSnapshot})`;
  }
}
/**
 * Returns the inherited params, data, and resolve for a given route.
 *
 * By default, we do not inherit parent data unless the current route is path-less or the parent
 * route is component-less.
 */
function getInherited(route, parent, paramsInheritanceStrategy = 'emptyOnly') {
  let inherited;
  const {
    routeConfig
  } = route;
  if (parent !== null && (paramsInheritanceStrategy === 'always' ||
  // inherit parent data if route is empty path
  routeConfig?.path === '' ||
  // inherit parent data if parent was componentless
  !parent.component && !parent.routeConfig?.loadComponent)) {
    inherited = {
      params: {
        ...parent.params,
        ...route.params
      },
      data: {
        ...parent.data,
        ...route.data
      },
      resolve: {
        // Snapshots are created with data inherited from parent and guards (i.e. canActivate) can
        // change data because it's not frozen...
        // This first line could be deleted chose to break/disallow mutating the `data` object in
        // guards.
        // Note that data from parents still override this mutated data so anyone relying on this
        // might be surprised that it doesn't work if parent data is inherited but otherwise does.
        ...route.data,
        // Ensure inherited resolved data overrides inherited static data
        ...parent.data,
        // static data from the current route overrides any inherited data
        ...routeConfig?.data,
        // resolved data from current route overrides everything
        ...route._resolvedData
      }
    };
  } else {
    inherited = {
      params: {
        ...route.params
      },
      data: {
        ...route.data
      },
      resolve: {
        ...route.data,
        ...(route._resolvedData ?? {})
      }
    };
  }
  if (routeConfig && hasStaticTitle(routeConfig)) {
    inherited.resolve[RouteTitleKey] = routeConfig.title;
  }
  return inherited;
}
/**
 * @description
 *
 * Contains the information about a route associated with a component loaded in an
 * outlet at a particular moment in time. ActivatedRouteSnapshot can also be used to
 * traverse the router state tree.
 *
 * The following example initializes a component with route information extracted
 * from the snapshot of the root node at the time of creation.
 *
 * ```
 * @Component({templateUrl:'./my-component.html'})
 * class MyComponent {
 *   constructor(route: ActivatedRoute) {
 *     const id: string = route.snapshot.params.id;
 *     const url: string = route.snapshot.url.join('');
 *     const user = route.snapshot.data.user;
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class ActivatedRouteSnapshot {
  /** The resolved route title */
  get title() {
    // Note: This _must_ be a getter because the data is mutated in the resolvers. Title will not be
    // available at the time of class instantiation.
    return this.data?.[RouteTitleKey];
  }
  /** @internal */
  constructor(/** The URL segments matched by this route */
  url,
  /**
   *  The matrix parameters scoped to this route.
   *
   *  You can compute all params (or data) in the router state or to get params outside
   *  of an activated component by traversing the `RouterState` tree as in the following
   *  example:
   *  ```
   *  collectRouteParams(router: Router) {
   *    let params = {};
   *    let stack: ActivatedRouteSnapshot[] = [router.routerState.snapshot.root];
   *    while (stack.length > 0) {
   *      const route = stack.pop()!;
   *      params = {...params, ...route.params};
   *      stack.push(...route.children);
   *    }
   *    return params;
   *  }
   *  ```
   */
  params, /** The query parameters shared by all the routes */
  queryParams, /** The URL fragment shared by all the routes */
  fragment, /** The static and resolved data of this route */
  data, /** The outlet name of the route */
  outlet, /** The component of the route */
  component, routeConfig, resolve) {
    this.url = url;
    this.params = params;
    this.queryParams = queryParams;
    this.fragment = fragment;
    this.data = data;
    this.outlet = outlet;
    this.component = component;
    this.routeConfig = routeConfig;
    this._resolve = resolve;
  }
  /** The root of the router state */
  get root() {
    return this._routerState.root;
  }
  /** The parent of this route in the router state tree */
  get parent() {
    return this._routerState.parent(this);
  }
  /** The first child of this route in the router state tree */
  get firstChild() {
    return this._routerState.firstChild(this);
  }
  /** The children of this route in the router state tree */
  get children() {
    return this._routerState.children(this);
  }
  /** The path from the root of the router state tree to this route */
  get pathFromRoot() {
    return this._routerState.pathFromRoot(this);
  }
  get paramMap() {
    this._paramMap ??= convertToParamMap(this.params);
    return this._paramMap;
  }
  get queryParamMap() {
    this._queryParamMap ??= convertToParamMap(this.queryParams);
    return this._queryParamMap;
  }
  toString() {
    const url = this.url.map(segment => segment.toString()).join('/');
    const matched = this.routeConfig ? this.routeConfig.path : '';
    return `Route(url:'${url}', path:'${matched}')`;
  }
}
/**
 * @description
 *
 * Represents the state of the router at a moment in time.
 *
 * This is a tree of activated route snapshots. Every node in this tree knows about
 * the "consumed" URL segments, the extracted parameters, and the resolved data.
 *
 * The following example shows how a component is initialized with information
 * from the snapshot of the root node's state at the time of creation.
 *
 * ```
 * @Component({templateUrl:'template.html'})
 * class MyComponent {
 *   constructor(router: Router) {
 *     const state: RouterState = router.routerState;
 *     const snapshot: RouterStateSnapshot = state.snapshot;
 *     const root: ActivatedRouteSnapshot = snapshot.root;
 *     const child = root.firstChild;
 *     const id: Observable<string> = child.params.map(p => p.id);
 *     //...
 *   }
 * }
 * ```
 *
 * @publicApi
 */
class RouterStateSnapshot extends Tree {
  /** @internal */
  constructor(/** The url from which this snapshot was created */
  url, root) {
    super(root);
    this.url = url;
    setRouterState(this, root);
  }
  toString() {
    return serializeNode(this._root);
  }
}
function setRouterState(state, node) {
  node.value._routerState = state;
  node.children.forEach(c => setRouterState(state, c));
}
function serializeNode(node) {
  const c = node.children.length > 0 ? ` { ${node.children.map(serializeNode).join(', ')} } ` : '';
  return `${node.value}${c}`;
}
/**
 * The expectation is that the activate route is created with the right set of parameters.
 * So we push new values into the observables only when they are not the initial values.
 * And we detect that by checking if the snapshot field is set.
 */
function advanceActivatedRoute(route) {
  if (route.snapshot) {
    const currentSnapshot = route.snapshot;
    const nextSnapshot = route._futureSnapshot;
    route.snapshot = nextSnapshot;
    if (!shallowEqual(currentSnapshot.queryParams, nextSnapshot.queryParams)) {
      route.queryParamsSubject.next(nextSnapshot.queryParams);
    }
    if (currentSnapshot.fragment !== nextSnapshot.fragment) {
      route.fragmentSubject.next(nextSnapshot.fragment);
    }
    if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
      route.paramsSubject.next(nextSnapshot.params);
    }
    if (!shallowEqualArrays(currentSnapshot.url, nextSnapshot.url)) {
      route.urlSubject.next(nextSnapshot.url);
    }
    if (!shallowEqual(currentSnapshot.data, nextSnapshot.data)) {
      route.dataSubject.next(nextSnapshot.data);
    }
  } else {
    route.snapshot = route._futureSnapshot;
    // this is for resolved data
    route.dataSubject.next(route._futureSnapshot.data);
  }
}
function equalParamsAndUrlSegments(a, b) {
  const equalUrlParams = shallowEqual(a.params, b.params) && equalSegments(a.url, b.url);
  const parentsMismatch = !a.parent !== !b.parent;
  return equalUrlParams && !parentsMismatch && (!a.parent || equalParamsAndUrlSegments(a.parent, b.parent));
}
function hasStaticTitle(config) {
  return typeof config.title === 'string' || config.title === null;
}

/**
 * @description
 *
 * Acts as a placeholder that Angular dynamically fills based on the current router state.
 *
 * Each outlet can have a unique name, determined by the optional `name` attribute.
 * The name cannot be set or changed dynamically. If not set, default value is "primary".
 *
 * ```
 * <router-outlet></router-outlet>
 * <router-outlet name='left'></router-outlet>
 * <router-outlet name='right'></router-outlet>
 * ```
 *
 * Named outlets can be the targets of secondary routes.
 * The `Route` object for a secondary route has an `outlet` property to identify the target outlet:
 *
 * `{path: <base-path>, component: <component>, outlet: <target_outlet_name>}`
 *
 * Using named outlets and secondary routes, you can target multiple outlets in
 * the same `RouterLink` directive.
 *
 * The router keeps track of separate branches in a navigation tree for each named outlet and
 * generates a representation of that tree in the URL.
 * The URL for a secondary route uses the following syntax to specify both the primary and secondary
 * routes at the same time:
 *
 * `http://base-path/primary-route-path(outlet-name:route-path)`
 *
 * A router outlet emits an activate event when a new component is instantiated,
 * deactivate event when a component is destroyed.
 * An attached event emits when the `RouteReuseStrategy` instructs the outlet to reattach the
 * subtree, and the detached event emits when the `RouteReuseStrategy` instructs the outlet to
 * detach the subtree.
 *
 * ```
 * <router-outlet
 *   (activate)='onActivate($event)'
 *   (deactivate)='onDeactivate($event)'
 *   (attach)='onAttach($event)'
 *   (detach)='onDetach($event)'></router-outlet>
 * ```
 *
 * @see [Routing tutorial](guide/router-tutorial-toh#named-outlets "Example of a named
 * outlet and secondary route configuration").
 * @see {@link RouterLink}
 * @see {@link Route}
 * @ngModule RouterModule
 *
 * @publicApi
 */
class RouterOutlet {
  constructor() {
    this.activated = null;
    this._activatedRoute = null;
    /**
     * The name of the outlet
     *
     * @see [named outlets](guide/router-tutorial-toh#displaying-multiple-routes-in-named-outlets)
     */
    this.name = PRIMARY_OUTLET;
    this.activateEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    this.deactivateEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Emits an attached component instance when the `RouteReuseStrategy` instructs to re-attach a
     * previously detached subtree.
     **/
    this.attachEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Emits a detached component instance when the `RouteReuseStrategy` instructs to detach the
     * subtree.
     */
    this.detachEvents = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    this.parentContexts = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ChildrenOutletContexts);
    this.location = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.ViewContainerRef);
    this.changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.ChangeDetectorRef);
    this.environmentInjector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector);
    this.inputBinder = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(INPUT_BINDER, {
      optional: true
    });
    /** @nodoc */
    this.supportsBindingToComponentInputs = true;
  }
  /** @internal */
  get activatedComponentRef() {
    return this.activated;
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (changes['name']) {
      const {
        firstChange,
        previousValue
      } = changes['name'];
      if (firstChange) {
        // The first change is handled by ngOnInit. Because ngOnChanges doesn't get called when no
        // input is set at all, we need to centrally handle the first change there.
        return;
      }
      // unregister with the old name
      if (this.isTrackedInParentContexts(previousValue)) {
        this.deactivate();
        this.parentContexts.onChildOutletDestroyed(previousValue);
      }
      // register the new name
      this.initializeOutletWithName();
    }
  }
  /** @nodoc */
  ngOnDestroy() {
    // Ensure that the registered outlet is this one before removing it on the context.
    if (this.isTrackedInParentContexts(this.name)) {
      this.parentContexts.onChildOutletDestroyed(this.name);
    }
    this.inputBinder?.unsubscribeFromRouteData(this);
  }
  isTrackedInParentContexts(outletName) {
    return this.parentContexts.getContext(outletName)?.outlet === this;
  }
  /** @nodoc */
  ngOnInit() {
    this.initializeOutletWithName();
  }
  initializeOutletWithName() {
    this.parentContexts.onChildOutletCreated(this.name, this);
    if (this.activated) {
      return;
    }
    // If the outlet was not instantiated at the time the route got activated we need to populate
    // the outlet when it is initialized (ie inside a NgIf)
    const context = this.parentContexts.getContext(this.name);
    if (context?.route) {
      if (context.attachRef) {
        // `attachRef` is populated when there is an existing component to mount
        this.attach(context.attachRef, context.route);
      } else {
        // otherwise the component defined in the configuration is created
        this.activateWith(context.route, context.injector);
      }
    }
  }
  get isActivated() {
    return !!this.activated;
  }
  /**
   * @returns The currently activated component instance.
   * @throws An error if the outlet is not activated.
   */
  get component() {
    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
    return this.activated.instance;
  }
  get activatedRoute() {
    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
    return this._activatedRoute;
  }
  get activatedRouteData() {
    if (this._activatedRoute) {
      return this._activatedRoute.snapshot.data;
    }
    return {};
  }
  /**
   * Called when the `RouteReuseStrategy` instructs to detach the subtree
   */
  detach() {
    if (!this.activated) throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4012 /* RuntimeErrorCode.OUTLET_NOT_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Outlet is not activated');
    this.location.detach();
    const cmp = this.activated;
    this.activated = null;
    this._activatedRoute = null;
    this.detachEvents.emit(cmp.instance);
    return cmp;
  }
  /**
   * Called when the `RouteReuseStrategy` instructs to re-attach a previously detached subtree
   */
  attach(ref, activatedRoute) {
    this.activated = ref;
    this._activatedRoute = activatedRoute;
    this.location.insert(ref.hostView);
    this.inputBinder?.bindActivatedRouteToOutletComponent(this);
    this.attachEvents.emit(ref.instance);
  }
  deactivate() {
    if (this.activated) {
      const c = this.component;
      this.activated.destroy();
      this.activated = null;
      this._activatedRoute = null;
      this.deactivateEvents.emit(c);
    }
  }
  activateWith(activatedRoute, environmentInjector) {
    if (this.isActivated) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4013 /* RuntimeErrorCode.OUTLET_ALREADY_ACTIVATED */, (typeof ngDevMode === 'undefined' || ngDevMode) && 'Cannot activate an already activated outlet');
    }
    this._activatedRoute = activatedRoute;
    const location = this.location;
    const snapshot = activatedRoute.snapshot;
    const component = snapshot.component;
    const childContexts = this.parentContexts.getOrCreateContext(this.name).children;
    const injector = new OutletInjector(activatedRoute, childContexts, location.injector);
    this.activated = location.createComponent(component, {
      index: location.length,
      injector,
      environmentInjector: environmentInjector ?? this.environmentInjector
    });
    // Calling `markForCheck` to make sure we will run the change detection when the
    // `RouterOutlet` is inside a `ChangeDetectionStrategy.OnPush` component.
    this.changeDetector.markForCheck();
    this.inputBinder?.bindActivatedRouteToOutletComponent(this);
    this.activateEvents.emit(this.activated.instance);
  }
  static {
    this.ɵfac = function RouterOutlet_Factory(t) {
      return new (t || RouterOutlet)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineDirective"]({
      type: RouterOutlet,
      selectors: [["router-outlet"]],
      inputs: {
        name: "name"
      },
      outputs: {
        activateEvents: "activate",
        deactivateEvents: "deactivate",
        attachEvents: "attach",
        detachEvents: "detach"
      },
      exportAs: ["outlet"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Directive,
    args: [{
      selector: 'router-outlet',
      exportAs: 'outlet',
      standalone: true
    }]
  }], null, {
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    activateEvents: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output,
      args: ['activate']
    }],
    deactivateEvents: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output,
      args: ['deactivate']
    }],
    attachEvents: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output,
      args: ['attach']
    }],
    detachEvents: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output,
      args: ['detach']
    }]
  });
})();
class OutletInjector {
  /**
   * This injector has a special handing for the `ActivatedRoute` and
   * `ChildrenOutletContexts` tokens: it returns corresponding values for those
   * tokens dynamically. This behavior is different from the regular injector logic,
   * when we initialize and store a value, which is later returned for all inject
   * requests.
   *
   * In some cases (e.g. when using `@defer`), this dynamic behavior requires special
   * handling. This function allows to identify an instance of the `OutletInjector` and
   * create an instance of it without referring to the class itself (so this logic can
   * be invoked from the `core` package). This helps to retain dynamic behavior for the
   * mentioned tokens.
   *
   * Note: it's a temporary solution and we should explore how to support this case better.
   */
  __ngOutletInjector(parentInjector) {
    return new OutletInjector(this.route, this.childContexts, parentInjector);
  }
  constructor(route, childContexts, parent) {
    this.route = route;
    this.childContexts = childContexts;
    this.parent = parent;
  }
  get(token, notFoundValue) {
    if (token === ActivatedRoute) {
      return this.route;
    }
    if (token === ChildrenOutletContexts) {
      return this.childContexts;
    }
    return this.parent.get(token, notFoundValue);
  }
}
const INPUT_BINDER = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken('');
/**
 * Injectable used as a tree-shakable provider for opting in to binding router data to component
 * inputs.
 *
 * The RouterOutlet registers itself with this service when an `ActivatedRoute` is attached or
 * activated. When this happens, the service subscribes to the `ActivatedRoute` observables (params,
 * queryParams, data) and sets the inputs of the component using `ComponentRef.setInput`.
 * Importantly, when an input does not have an item in the route data with a matching key, this
 * input is set to `undefined`. If it were not done this way, the previous information would be
 * retained if the data got removed from the route (i.e. if a query parameter is removed).
 *
 * The `RouterOutlet` should unregister itself when destroyed via `unsubscribeFromRouteData` so that
 * the subscriptions are cleaned up.
 */
class RoutedComponentInputBinder {
  constructor() {
    this.outletDataSubscriptions = new Map();
  }
  bindActivatedRouteToOutletComponent(outlet) {
    this.unsubscribeFromRouteData(outlet);
    this.subscribeToRouteData(outlet);
  }
  unsubscribeFromRouteData(outlet) {
    this.outletDataSubscriptions.get(outlet)?.unsubscribe();
    this.outletDataSubscriptions.delete(outlet);
  }
  subscribeToRouteData(outlet) {
    const {
      activatedRoute
    } = outlet;
    const dataSubscription = (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.combineLatest)([activatedRoute.queryParams, activatedRoute.params, activatedRoute.data]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(([queryParams, params, data], index) => {
      data = {
        ...queryParams,
        ...params,
        ...data
      };
      // Get the first result from the data subscription synchronously so it's available to
      // the component as soon as possible (and doesn't require a second change detection).
      if (index === 0) {
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(data);
      }
      // Promise.resolve is used to avoid synchronously writing the wrong data when
      // two of the Observables in the `combineLatest` stream emit one after
      // another.
      return Promise.resolve(data);
    })).subscribe(data => {
      // Outlet may have been deactivated or changed names to be associated with a different
      // route
      if (!outlet.isActivated || !outlet.activatedComponentRef || outlet.activatedRoute !== activatedRoute || activatedRoute.component === null) {
        this.unsubscribeFromRouteData(outlet);
        return;
      }
      const mirror = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.reflectComponentType)(activatedRoute.component);
      if (!mirror) {
        this.unsubscribeFromRouteData(outlet);
        return;
      }
      for (const {
        templateName
      } of mirror.inputs) {
        outlet.activatedComponentRef.setInput(templateName, data[templateName]);
      }
    });
    this.outletDataSubscriptions.set(outlet, dataSubscription);
  }
  static {
    this.ɵfac = function RoutedComponentInputBinder_Factory(t) {
      return new (t || RoutedComponentInputBinder)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: RoutedComponentInputBinder,
      factory: RoutedComponentInputBinder.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RoutedComponentInputBinder, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable
  }], null, null);
})();
function createRouterState(routeReuseStrategy, curr, prevState) {
  const root = createNode(routeReuseStrategy, curr._root, prevState ? prevState._root : undefined);
  return new RouterState(root, curr);
}
function createNode(routeReuseStrategy, curr, prevState) {
  // reuse an activated route that is currently displayed on the screen
  if (prevState && routeReuseStrategy.shouldReuseRoute(curr.value, prevState.value.snapshot)) {
    const value = prevState.value;
    value._futureSnapshot = curr.value;
    const children = createOrReuseChildren(routeReuseStrategy, curr, prevState);
    return new TreeNode(value, children);
  } else {
    if (routeReuseStrategy.shouldAttach(curr.value)) {
      // retrieve an activated route that is used to be displayed, but is not currently displayed
      const detachedRouteHandle = routeReuseStrategy.retrieve(curr.value);
      if (detachedRouteHandle !== null) {
        const tree = detachedRouteHandle.route;
        tree.value._futureSnapshot = curr.value;
        tree.children = curr.children.map(c => createNode(routeReuseStrategy, c));
        return tree;
      }
    }
    const value = createActivatedRoute(curr.value);
    const children = curr.children.map(c => createNode(routeReuseStrategy, c));
    return new TreeNode(value, children);
  }
}
function createOrReuseChildren(routeReuseStrategy, curr, prevState) {
  return curr.children.map(child => {
    for (const p of prevState.children) {
      if (routeReuseStrategy.shouldReuseRoute(child.value, p.value.snapshot)) {
        return createNode(routeReuseStrategy, child, p);
      }
    }
    return createNode(routeReuseStrategy, child);
  });
}
function createActivatedRoute(c) {
  return new ActivatedRoute(new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject(c.url), new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject(c.params), new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject(c.queryParams), new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject(c.fragment), new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject(c.data), c.outlet, c.component, c);
}
const NAVIGATION_CANCELING_ERROR = 'ngNavigationCancelingError';
function redirectingNavigationError(urlSerializer, redirect) {
  const {
    redirectTo,
    navigationBehaviorOptions
  } = isUrlTree(redirect) ? {
    redirectTo: redirect,
    navigationBehaviorOptions: undefined
  } : redirect;
  const error = navigationCancelingError(ngDevMode && `Redirecting to "${urlSerializer.serialize(redirectTo)}"`, NavigationCancellationCode.Redirect);
  error.url = redirectTo;
  error.navigationBehaviorOptions = navigationBehaviorOptions;
  return error;
}
function navigationCancelingError(message, code) {
  const error = new Error(`NavigationCancelingError: ${message || ''}`);
  error[NAVIGATION_CANCELING_ERROR] = true;
  error.cancellationCode = code;
  return error;
}
function isRedirectingNavigationCancelingError(error) {
  return isNavigationCancelingError(error) && isUrlTree(error.url);
}
function isNavigationCancelingError(error) {
  return !!error && error[NAVIGATION_CANCELING_ERROR];
}

/**
 * This component is used internally within the router to be a placeholder when an empty
 * router-outlet is needed. For example, with a config such as:
 *
 * `{path: 'parent', outlet: 'nav', children: [...]}`
 *
 * In order to render, there needs to be a component on this config, which will default
 * to this `EmptyOutletComponent`.
 */
class ɵEmptyOutletComponent {
  static {
    this.ɵfac = function ɵEmptyOutletComponent_Factory(t) {
      return new (t || ɵEmptyOutletComponent)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineComponent"]({
      type: ɵEmptyOutletComponent,
      selectors: [["ng-component"]],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵStandaloneFeature"]],
      decls: 1,
      vars: 0,
      template: function _EmptyOutletComponent_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵelement"](0, "router-outlet");
        }
      },
      dependencies: [RouterOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](ɵEmptyOutletComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Component,
    args: [{
      template: `<router-outlet></router-outlet>`,
      imports: [RouterOutlet],
      standalone: true
    }]
  }], null, null);
})();

/**
 * Creates an `EnvironmentInjector` if the `Route` has providers and one does not already exist
 * and returns the injector. Otherwise, if the `Route` does not have `providers`, returns the
 * `currentInjector`.
 *
 * @param route The route that might have providers
 * @param currentInjector The parent injector of the `Route`
 */
function getOrCreateRouteInjectorIfNeeded(route, currentInjector) {
  if (route.providers && !route._injector) {
    route._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.createEnvironmentInjector)(route.providers, currentInjector, `Route: ${route.path}`);
  }
  return route._injector ?? currentInjector;
}
function getLoadedRoutes(route) {
  return route._loadedRoutes;
}
function getLoadedInjector(route) {
  return route._loadedInjector;
}
function getLoadedComponent(route) {
  return route._loadedComponent;
}
function getProvidersInjector(route) {
  return route._injector;
}
function validateConfig(config, parentPath = '', requireStandaloneComponents = false) {
  // forEach doesn't iterate undefined values
  for (let i = 0; i < config.length; i++) {
    const route = config[i];
    const fullPath = getFullPath(parentPath, route);
    validateNode(route, fullPath, requireStandaloneComponents);
  }
}
function assertStandalone(fullPath, component) {
  if (component && (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵisNgModule"])(component)) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}'. You are using 'loadComponent' with a module, ` + `but it must be used with standalone components. Use 'loadChildren' instead.`);
  } else if (component && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.isStandalone)(component)) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}'. The component must be standalone.`);
  }
}
function validateNode(route, fullPath, requireStandaloneComponents) {
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    if (!route) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `
      Invalid configuration of route '${fullPath}': Encountered undefined route.
      The reason might be an extra comma.

      Example:
      const routes: Routes = [
        { path: '', redirectTo: '/dashboard', pathMatch: 'full' },
        { path: 'dashboard',  component: DashboardComponent },, << two commas
        { path: 'detail/:id', component: HeroDetailComponent }
      ];
    `);
    }
    if (Array.isArray(route)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': Array cannot be specified`);
    }
    if (!route.redirectTo && !route.component && !route.loadComponent && !route.children && !route.loadChildren && route.outlet && route.outlet !== PRIMARY_OUTLET) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': a componentless route without children or loadChildren cannot have a named outlet set`);
    }
    if (route.redirectTo && route.children) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and children cannot be used together`);
    }
    if (route.redirectTo && route.loadChildren) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and loadChildren cannot be used together`);
    }
    if (route.children && route.loadChildren) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': children and loadChildren cannot be used together`);
    }
    if (route.redirectTo && (route.component || route.loadComponent)) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and component/loadComponent cannot be used together`);
    }
    if (route.component && route.loadComponent) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': component and loadComponent cannot be used together`);
    }
    if (route.redirectTo && route.canActivate) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': redirectTo and canActivate cannot be used together. Redirects happen before activation ` + `so canActivate will never be executed.`);
    }
    if (route.path && route.matcher) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': path and matcher cannot be used together`);
    }
    if (route.redirectTo === void 0 && !route.component && !route.loadComponent && !route.children && !route.loadChildren) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}'. One of the following must be provided: component, loadComponent, redirectTo, children or loadChildren`);
    }
    if (route.path === void 0 && route.matcher === void 0) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': routes must have either a path or a matcher specified`);
    }
    if (typeof route.path === 'string' && route.path.charAt(0) === '/') {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '${fullPath}': path cannot start with a slash`);
    }
    if (route.path === '' && route.redirectTo !== void 0 && route.pathMatch === void 0) {
      const exp = `The default value of 'pathMatch' is 'prefix', but often the intent is to use 'full'.`;
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4014 /* RuntimeErrorCode.INVALID_ROUTE_CONFIG */, `Invalid configuration of route '{path: "${fullPath}", redirectTo: "${route.redirectTo}"}': please provide 'pathMatch'. ${exp}`);
    }
    if (requireStandaloneComponents) {
      assertStandalone(fullPath, route.component);
    }
  }
  if (route.children) {
    validateConfig(route.children, fullPath, requireStandaloneComponents);
  }
}
function getFullPath(parentPath, currentRoute) {
  if (!currentRoute) {
    return parentPath;
  }
  if (!parentPath && !currentRoute.path) {
    return '';
  } else if (parentPath && !currentRoute.path) {
    return `${parentPath}/`;
  } else if (!parentPath && currentRoute.path) {
    return currentRoute.path;
  } else {
    return `${parentPath}/${currentRoute.path}`;
  }
}
/**
 * Makes a copy of the config and adds any default required properties.
 */
function standardizeConfig(r) {
  const children = r.children && r.children.map(standardizeConfig);
  const c = children ? {
    ...r,
    children
  } : {
    ...r
  };
  if (!c.component && !c.loadComponent && (children || c.loadChildren) && c.outlet && c.outlet !== PRIMARY_OUTLET) {
    c.component = ɵEmptyOutletComponent;
  }
  return c;
}
/** Returns the `route.outlet` or PRIMARY_OUTLET if none exists. */
function getOutlet(route) {
  return route.outlet || PRIMARY_OUTLET;
}
/**
 * Sorts the `routes` such that the ones with an outlet matching `outletName` come first.
 * The order of the configs is otherwise preserved.
 */
function sortByMatchingOutlets(routes, outletName) {
  const sortedConfig = routes.filter(r => getOutlet(r) === outletName);
  sortedConfig.push(...routes.filter(r => getOutlet(r) !== outletName));
  return sortedConfig;
}
/**
 * Gets the first injector in the snapshot's parent tree.
 *
 * If the `Route` has a static list of providers, the returned injector will be the one created from
 * those. If it does not exist, the returned injector may come from the parents, which may be from a
 * loaded config or their static providers.
 *
 * Returns `null` if there is neither this nor any parents have a stored injector.
 *
 * Generally used for retrieving the injector to use for getting tokens for guards/resolvers and
 * also used for getting the correct injector to use for creating components.
 */
function getClosestRouteInjector(snapshot) {
  if (!snapshot) return null;
  // If the current route has its own injector, which is created from the static providers on the
  // route itself, we should use that. Otherwise, we start at the parent since we do not want to
  // include the lazy loaded injector from this route.
  if (snapshot.routeConfig?._injector) {
    return snapshot.routeConfig._injector;
  }
  for (let s = snapshot.parent; s; s = s.parent) {
    const route = s.routeConfig;
    // Note that the order here is important. `_loadedInjector` stored on the route with
    // `loadChildren: () => NgModule` so it applies to child routes with priority. The `_injector`
    // is created from the static providers on that parent route, so it applies to the children as
    // well, but only if there is no lazy loaded NgModuleRef injector.
    if (route?._loadedInjector) return route._loadedInjector;
    if (route?._injector) return route._injector;
  }
  return null;
}
let warnedAboutUnsupportedInputBinding = false;
const activateRoutes = (rootContexts, routeReuseStrategy, forwardEvent, inputBindingEnabled) => (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(t => {
  new ActivateRoutes(routeReuseStrategy, t.targetRouterState, t.currentRouterState, forwardEvent, inputBindingEnabled).activate(rootContexts);
  return t;
});
class ActivateRoutes {
  constructor(routeReuseStrategy, futureState, currState, forwardEvent, inputBindingEnabled) {
    this.routeReuseStrategy = routeReuseStrategy;
    this.futureState = futureState;
    this.currState = currState;
    this.forwardEvent = forwardEvent;
    this.inputBindingEnabled = inputBindingEnabled;
  }
  activate(parentContexts) {
    const futureRoot = this.futureState._root;
    const currRoot = this.currState ? this.currState._root : null;
    this.deactivateChildRoutes(futureRoot, currRoot, parentContexts);
    advanceActivatedRoute(this.futureState.root);
    this.activateChildRoutes(futureRoot, currRoot, parentContexts);
  }
  // De-activate the child route that are not re-used for the future state
  deactivateChildRoutes(futureNode, currNode, contexts) {
    const children = nodeChildrenAsMap(currNode);
    // Recurse on the routes active in the future state to de-activate deeper children
    futureNode.children.forEach(futureChild => {
      const childOutletName = futureChild.value.outlet;
      this.deactivateRoutes(futureChild, children[childOutletName], contexts);
      delete children[childOutletName];
    });
    // De-activate the routes that will not be re-used
    Object.values(children).forEach(v => {
      this.deactivateRouteAndItsChildren(v, contexts);
    });
  }
  deactivateRoutes(futureNode, currNode, parentContext) {
    const future = futureNode.value;
    const curr = currNode ? currNode.value : null;
    if (future === curr) {
      // Reusing the node, check to see if the children need to be de-activated
      if (future.component) {
        // If we have a normal route, we need to go through an outlet.
        const context = parentContext.getContext(future.outlet);
        if (context) {
          this.deactivateChildRoutes(futureNode, currNode, context.children);
        }
      } else {
        // if we have a componentless route, we recurse but keep the same outlet map.
        this.deactivateChildRoutes(futureNode, currNode, parentContext);
      }
    } else {
      if (curr) {
        // Deactivate the current route which will not be re-used
        this.deactivateRouteAndItsChildren(currNode, parentContext);
      }
    }
  }
  deactivateRouteAndItsChildren(route, parentContexts) {
    // If there is no component, the Route is never attached to an outlet (because there is no
    // component to attach).
    if (route.value.component && this.routeReuseStrategy.shouldDetach(route.value.snapshot)) {
      this.detachAndStoreRouteSubtree(route, parentContexts);
    } else {
      this.deactivateRouteAndOutlet(route, parentContexts);
    }
  }
  detachAndStoreRouteSubtree(route, parentContexts) {
    const context = parentContexts.getContext(route.value.outlet);
    const contexts = context && route.value.component ? context.children : parentContexts;
    const children = nodeChildrenAsMap(route);
    for (const treeNode of Object.values(children)) {
      this.deactivateRouteAndItsChildren(treeNode, contexts);
    }
    if (context && context.outlet) {
      const componentRef = context.outlet.detach();
      const contexts = context.children.onOutletDeactivated();
      this.routeReuseStrategy.store(route.value.snapshot, {
        componentRef,
        route,
        contexts
      });
    }
  }
  deactivateRouteAndOutlet(route, parentContexts) {
    const context = parentContexts.getContext(route.value.outlet);
    // The context could be `null` if we are on a componentless route but there may still be
    // children that need deactivating.
    const contexts = context && route.value.component ? context.children : parentContexts;
    const children = nodeChildrenAsMap(route);
    for (const treeNode of Object.values(children)) {
      this.deactivateRouteAndItsChildren(treeNode, contexts);
    }
    if (context) {
      if (context.outlet) {
        // Destroy the component
        context.outlet.deactivate();
        // Destroy the contexts for all the outlets that were in the component
        context.children.onOutletDeactivated();
      }
      // Clear the information about the attached component on the context but keep the reference to
      // the outlet. Clear even if outlet was not yet activated to avoid activating later with old
      // info
      context.attachRef = null;
      context.route = null;
    }
  }
  activateChildRoutes(futureNode, currNode, contexts) {
    const children = nodeChildrenAsMap(currNode);
    futureNode.children.forEach(c => {
      this.activateRoutes(c, children[c.value.outlet], contexts);
      this.forwardEvent(new ActivationEnd(c.value.snapshot));
    });
    if (futureNode.children.length) {
      this.forwardEvent(new ChildActivationEnd(futureNode.value.snapshot));
    }
  }
  activateRoutes(futureNode, currNode, parentContexts) {
    const future = futureNode.value;
    const curr = currNode ? currNode.value : null;
    advanceActivatedRoute(future);
    // reusing the node
    if (future === curr) {
      if (future.component) {
        // If we have a normal route, we need to go through an outlet.
        const context = parentContexts.getOrCreateContext(future.outlet);
        this.activateChildRoutes(futureNode, currNode, context.children);
      } else {
        // if we have a componentless route, we recurse but keep the same outlet map.
        this.activateChildRoutes(futureNode, currNode, parentContexts);
      }
    } else {
      if (future.component) {
        // if we have a normal route, we need to place the component into the outlet and recurse.
        const context = parentContexts.getOrCreateContext(future.outlet);
        if (this.routeReuseStrategy.shouldAttach(future.snapshot)) {
          const stored = this.routeReuseStrategy.retrieve(future.snapshot);
          this.routeReuseStrategy.store(future.snapshot, null);
          context.children.onOutletReAttached(stored.contexts);
          context.attachRef = stored.componentRef;
          context.route = stored.route.value;
          if (context.outlet) {
            // Attach right away when the outlet has already been instantiated
            // Otherwise attach from `RouterOutlet.ngOnInit` when it is instantiated
            context.outlet.attach(stored.componentRef, stored.route.value);
          }
          advanceActivatedRoute(stored.route.value);
          this.activateChildRoutes(futureNode, null, context.children);
        } else {
          const injector = getClosestRouteInjector(future.snapshot);
          context.attachRef = null;
          context.route = future;
          context.injector = injector;
          if (context.outlet) {
            // Activate the outlet when it has already been instantiated
            // Otherwise it will get activated from its `ngOnInit` when instantiated
            context.outlet.activateWith(future, context.injector);
          }
          this.activateChildRoutes(futureNode, null, context.children);
        }
      } else {
        // if we have a componentless route, we recurse but keep the same outlet map.
        this.activateChildRoutes(futureNode, null, parentContexts);
      }
    }
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      const context = parentContexts.getOrCreateContext(future.outlet);
      const outlet = context.outlet;
      if (outlet && this.inputBindingEnabled && !outlet.supportsBindingToComponentInputs && !warnedAboutUnsupportedInputBinding) {
        console.warn(`'withComponentInputBinding' feature is enabled but ` + `this application is using an outlet that may not support binding to component inputs.`);
        warnedAboutUnsupportedInputBinding = true;
      }
    }
  }
}
class CanActivate {
  constructor(path) {
    this.path = path;
    this.route = this.path[this.path.length - 1];
  }
}
class CanDeactivate {
  constructor(component, route) {
    this.component = component;
    this.route = route;
  }
}
function getAllRouteGuards(future, curr, parentContexts) {
  const futureRoot = future._root;
  const currRoot = curr ? curr._root : null;
  return getChildRouteGuards(futureRoot, currRoot, parentContexts, [futureRoot.value]);
}
function getCanActivateChild(p) {
  const canActivateChild = p.routeConfig ? p.routeConfig.canActivateChild : null;
  if (!canActivateChild || canActivateChild.length === 0) return null;
  return {
    node: p,
    guards: canActivateChild
  };
}
function getTokenOrFunctionIdentity(tokenOrFunction, injector) {
  const NOT_FOUND = Symbol();
  const result = injector.get(tokenOrFunction, NOT_FOUND);
  if (result === NOT_FOUND) {
    if (typeof tokenOrFunction === 'function' && !(0,_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵisInjectable"])(tokenOrFunction)) {
      // We think the token is just a function so return it as-is
      return tokenOrFunction;
    } else {
      // This will throw the not found error
      return injector.get(tokenOrFunction);
    }
  }
  return result;
}
function getChildRouteGuards(futureNode, currNode, contexts, futurePath, checks = {
  canDeactivateChecks: [],
  canActivateChecks: []
}) {
  const prevChildren = nodeChildrenAsMap(currNode);
  // Process the children of the future route
  futureNode.children.forEach(c => {
    getRouteGuards(c, prevChildren[c.value.outlet], contexts, futurePath.concat([c.value]), checks);
    delete prevChildren[c.value.outlet];
  });
  // Process any children left from the current route (not active for the future route)
  Object.entries(prevChildren).forEach(([k, v]) => deactivateRouteAndItsChildren(v, contexts.getContext(k), checks));
  return checks;
}
function getRouteGuards(futureNode, currNode, parentContexts, futurePath, checks = {
  canDeactivateChecks: [],
  canActivateChecks: []
}) {
  const future = futureNode.value;
  const curr = currNode ? currNode.value : null;
  const context = parentContexts ? parentContexts.getContext(futureNode.value.outlet) : null;
  // reusing the node
  if (curr && future.routeConfig === curr.routeConfig) {
    const shouldRun = shouldRunGuardsAndResolvers(curr, future, future.routeConfig.runGuardsAndResolvers);
    if (shouldRun) {
      checks.canActivateChecks.push(new CanActivate(futurePath));
    } else {
      // we need to set the data
      future.data = curr.data;
      future._resolvedData = curr._resolvedData;
    }
    // If we have a component, we need to go through an outlet.
    if (future.component) {
      getChildRouteGuards(futureNode, currNode, context ? context.children : null, futurePath, checks);
      // if we have a componentless route, we recurse but keep the same outlet map.
    } else {
      getChildRouteGuards(futureNode, currNode, parentContexts, futurePath, checks);
    }
    if (shouldRun && context && context.outlet && context.outlet.isActivated) {
      checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, curr));
    }
  } else {
    if (curr) {
      deactivateRouteAndItsChildren(currNode, context, checks);
    }
    checks.canActivateChecks.push(new CanActivate(futurePath));
    // If we have a component, we need to go through an outlet.
    if (future.component) {
      getChildRouteGuards(futureNode, null, context ? context.children : null, futurePath, checks);
      // if we have a componentless route, we recurse but keep the same outlet map.
    } else {
      getChildRouteGuards(futureNode, null, parentContexts, futurePath, checks);
    }
  }
  return checks;
}
function shouldRunGuardsAndResolvers(curr, future, mode) {
  if (typeof mode === 'function') {
    return mode(curr, future);
  }
  switch (mode) {
    case 'pathParamsChange':
      return !equalPath(curr.url, future.url);
    case 'pathParamsOrQueryParamsChange':
      return !equalPath(curr.url, future.url) || !shallowEqual(curr.queryParams, future.queryParams);
    case 'always':
      return true;
    case 'paramsOrQueryParamsChange':
      return !equalParamsAndUrlSegments(curr, future) || !shallowEqual(curr.queryParams, future.queryParams);
    case 'paramsChange':
    default:
      return !equalParamsAndUrlSegments(curr, future);
  }
}
function deactivateRouteAndItsChildren(route, context, checks) {
  const children = nodeChildrenAsMap(route);
  const r = route.value;
  Object.entries(children).forEach(([childName, node]) => {
    if (!r.component) {
      deactivateRouteAndItsChildren(node, context, checks);
    } else if (context) {
      deactivateRouteAndItsChildren(node, context.children.getContext(childName), checks);
    } else {
      deactivateRouteAndItsChildren(node, null, checks);
    }
  });
  if (!r.component) {
    checks.canDeactivateChecks.push(new CanDeactivate(null, r));
  } else if (context && context.outlet && context.outlet.isActivated) {
    checks.canDeactivateChecks.push(new CanDeactivate(context.outlet.component, r));
  } else {
    checks.canDeactivateChecks.push(new CanDeactivate(null, r));
  }
}

/**
 * Simple function check, but generic so type inference will flow. Example:
 *
 * function product(a: number, b: number) {
 *   return a * b;
 * }
 *
 * if (isFunction<product>(fn)) {
 *   return fn(1, 2);
 * } else {
 *   throw "Must provide the `product` function";
 * }
 */
function isFunction(v) {
  return typeof v === 'function';
}
function isBoolean(v) {
  return typeof v === 'boolean';
}
function isCanLoad(guard) {
  return guard && isFunction(guard.canLoad);
}
function isCanActivate(guard) {
  return guard && isFunction(guard.canActivate);
}
function isCanActivateChild(guard) {
  return guard && isFunction(guard.canActivateChild);
}
function isCanDeactivate(guard) {
  return guard && isFunction(guard.canDeactivate);
}
function isCanMatch(guard) {
  return guard && isFunction(guard.canMatch);
}
function isEmptyError(e) {
  return e instanceof rxjs__WEBPACK_IMPORTED_MODULE_9__.EmptyError || e?.name === 'EmptyError';
}
const INITIAL_VALUE = /* @__PURE__ */Symbol('INITIAL_VALUE');
function prioritizedGuardValue() {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(obs => {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.combineLatest)(obs.map(o => o.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.take)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.startWith)(INITIAL_VALUE)))).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(results => {
      for (const result of results) {
        if (result === true) {
          // If result is true, check the next one
          continue;
        } else if (result === INITIAL_VALUE) {
          // If guard has not finished, we need to stop processing.
          return INITIAL_VALUE;
        } else if (result === false || result instanceof UrlTree) {
          // Result finished and was not true. Return the result.
          // Note that we only allow false/UrlTree. Other values are considered invalid and
          // ignored.
          return result;
        }
      }
      // Everything resolved to true. Return true.
      return true;
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(item => item !== INITIAL_VALUE), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.take)(1));
  });
}
function checkGuards(injector, forwardEvent) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(t => {
    const {
      targetSnapshot,
      currentSnapshot,
      guards: {
        canActivateChecks,
        canDeactivateChecks
      }
    } = t;
    if (canDeactivateChecks.length === 0 && canActivateChecks.length === 0) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({
        ...t,
        guardsResult: true
      });
    }
    return runCanDeactivateChecks(canDeactivateChecks, targetSnapshot, currentSnapshot, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(canDeactivate => {
      return canDeactivate && isBoolean(canDeactivate) ? runCanActivateChecks(targetSnapshot, canActivateChecks, injector, forwardEvent) : (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canDeactivate);
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(guardsResult => ({
      ...t,
      guardsResult
    })));
  });
}
function runCanDeactivateChecks(checks, futureRSS, currRSS, injector) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(checks).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(check => runCanDeactivate(check.component, check.route, currRSS, futureRSS, injector)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)(result => {
    return result !== true;
  }, true));
}
function runCanActivateChecks(futureSnapshot, checks, injector, forwardEvent) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(checks).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap)(check => {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_16__.concat)(fireChildActivationStart(check.route.parent, forwardEvent), fireActivationStart(check.route, forwardEvent), runCanActivateChild(futureSnapshot, check.path, injector), runCanActivate(futureSnapshot, check.route, injector));
  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)(result => {
    return result !== true;
  }, true));
}
/**
 * This should fire off `ActivationStart` events for each route being activated at this
 * level.
 * In other words, if you're activating `a` and `b` below, `path` will contain the
 * `ActivatedRouteSnapshot`s for both and we will fire `ActivationStart` for both. Always
 * return
 * `true` so checks continue to run.
 */
function fireActivationStart(snapshot, forwardEvent) {
  if (snapshot !== null && forwardEvent) {
    forwardEvent(new ActivationStart(snapshot));
  }
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
}
/**
 * This should fire off `ChildActivationStart` events for each route being activated at this
 * level.
 * In other words, if you're activating `a` and `b` below, `path` will contain the
 * `ActivatedRouteSnapshot`s for both and we will fire `ChildActivationStart` for both. Always
 * return
 * `true` so checks continue to run.
 */
function fireChildActivationStart(snapshot, forwardEvent) {
  if (snapshot !== null && forwardEvent) {
    forwardEvent(new ChildActivationStart(snapshot));
  }
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
}
function runCanActivate(futureRSS, futureARS, injector) {
  const canActivate = futureARS.routeConfig ? futureARS.routeConfig.canActivate : null;
  if (!canActivate || canActivate.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
  const canActivateObservables = canActivate.map(canActivate => {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_17__.defer)(() => {
      const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
      const guard = getTokenOrFunctionIdentity(canActivate, closestInjector);
      const guardVal = isCanActivate(guard) ? guard.canActivate(futureARS, futureRSS) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(closestInjector, () => guard(futureARS, futureRSS));
      return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)());
    });
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canActivateObservables).pipe(prioritizedGuardValue());
}
function runCanActivateChild(futureRSS, path, injector) {
  const futureARS = path[path.length - 1];
  const canActivateChildGuards = path.slice(0, path.length - 1).reverse().map(p => getCanActivateChild(p)).filter(_ => _ !== null);
  const canActivateChildGuardsMapped = canActivateChildGuards.map(d => {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_17__.defer)(() => {
      const guardsMapped = d.guards.map(canActivateChild => {
        const closestInjector = getClosestRouteInjector(d.node) ?? injector;
        const guard = getTokenOrFunctionIdentity(canActivateChild, closestInjector);
        const guardVal = isCanActivateChild(guard) ? guard.canActivateChild(futureARS, futureRSS) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(closestInjector, () => guard(futureARS, futureRSS));
        return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)());
      });
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(guardsMapped).pipe(prioritizedGuardValue());
    });
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canActivateChildGuardsMapped).pipe(prioritizedGuardValue());
}
function runCanDeactivate(component, currARS, currRSS, futureRSS, injector) {
  const canDeactivate = currARS && currARS.routeConfig ? currARS.routeConfig.canDeactivate : null;
  if (!canDeactivate || canDeactivate.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
  const canDeactivateObservables = canDeactivate.map(c => {
    const closestInjector = getClosestRouteInjector(currARS) ?? injector;
    const guard = getTokenOrFunctionIdentity(c, closestInjector);
    const guardVal = isCanDeactivate(guard) ? guard.canDeactivate(component, currARS, currRSS, futureRSS) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(closestInjector, () => guard(component, currARS, currRSS, futureRSS));
    return wrapIntoObservable(guardVal).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)());
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canDeactivateObservables).pipe(prioritizedGuardValue());
}
function runCanLoadGuards(injector, route, segments, urlSerializer) {
  const canLoad = route.canLoad;
  if (canLoad === undefined || canLoad.length === 0) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
  }
  const canLoadObservables = canLoad.map(injectionToken => {
    const guard = getTokenOrFunctionIdentity(injectionToken, injector);
    const guardVal = isCanLoad(guard) ? guard.canLoad(route, segments) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(injector, () => guard(route, segments));
    return wrapIntoObservable(guardVal);
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canLoadObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
}
function redirectIfUrlTree(urlSerializer) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_18__.pipe)((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(result => {
    if (!isUrlTree(result)) return;
    throw redirectingNavigationError(urlSerializer, result);
  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(result => result === true));
}
function runCanMatchGuards(injector, route, segments, urlSerializer) {
  const canMatch = route.canMatch;
  if (!canMatch || canMatch.length === 0) return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(true);
  const canMatchObservables = canMatch.map(injectionToken => {
    const guard = getTokenOrFunctionIdentity(injectionToken, injector);
    const guardVal = isCanMatch(guard) ? guard.canMatch(route, segments) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(injector, () => guard(route, segments));
    return wrapIntoObservable(guardVal);
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(canMatchObservables).pipe(prioritizedGuardValue(), redirectIfUrlTree(urlSerializer));
}
class NoMatch {
  constructor(segmentGroup) {
    this.segmentGroup = segmentGroup || null;
  }
}
class AbsoluteRedirect extends Error {
  constructor(urlTree) {
    super();
    this.urlTree = urlTree;
  }
}
function noMatch$1(segmentGroup) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_20__.throwError)(new NoMatch(segmentGroup));
}
function absoluteRedirect(newTree) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_20__.throwError)(new AbsoluteRedirect(newTree));
}
function namedOutletsRedirect(redirectTo) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_20__.throwError)(new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4000 /* RuntimeErrorCode.NAMED_OUTLET_REDIRECT */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Only absolute redirects can have named outlets. redirectTo: '${redirectTo}'`));
}
function canLoadFails(route) {
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_20__.throwError)(navigationCancelingError((typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot load children because the guard of the route "path: '${route.path}'" returned false`, NavigationCancellationCode.GuardRejected));
}
class ApplyRedirects {
  constructor(urlSerializer, urlTree) {
    this.urlSerializer = urlSerializer;
    this.urlTree = urlTree;
  }
  lineralizeSegments(route, urlTree) {
    let res = [];
    let c = urlTree.root;
    while (true) {
      res = res.concat(c.segments);
      if (c.numberOfChildren === 0) {
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(res);
      }
      if (c.numberOfChildren > 1 || !c.children[PRIMARY_OUTLET]) {
        return namedOutletsRedirect(route.redirectTo);
      }
      c = c.children[PRIMARY_OUTLET];
    }
  }
  applyRedirectCommands(segments, redirectTo, posParams) {
    const newTree = this.applyRedirectCreateUrlTree(redirectTo, this.urlSerializer.parse(redirectTo), segments, posParams);
    if (redirectTo.startsWith('/')) {
      throw new AbsoluteRedirect(newTree);
    }
    return newTree;
  }
  applyRedirectCreateUrlTree(redirectTo, urlTree, segments, posParams) {
    const newRoot = this.createSegmentGroup(redirectTo, urlTree.root, segments, posParams);
    return new UrlTree(newRoot, this.createQueryParams(urlTree.queryParams, this.urlTree.queryParams), urlTree.fragment);
  }
  createQueryParams(redirectToParams, actualParams) {
    const res = {};
    Object.entries(redirectToParams).forEach(([k, v]) => {
      const copySourceValue = typeof v === 'string' && v.startsWith(':');
      if (copySourceValue) {
        const sourceName = v.substring(1);
        res[k] = actualParams[sourceName];
      } else {
        res[k] = v;
      }
    });
    return res;
  }
  createSegmentGroup(redirectTo, group, segments, posParams) {
    const updatedSegments = this.createSegments(redirectTo, group.segments, segments, posParams);
    let children = {};
    Object.entries(group.children).forEach(([name, child]) => {
      children[name] = this.createSegmentGroup(redirectTo, child, segments, posParams);
    });
    return new UrlSegmentGroup(updatedSegments, children);
  }
  createSegments(redirectTo, redirectToSegments, actualSegments, posParams) {
    return redirectToSegments.map(s => s.path.startsWith(':') ? this.findPosParam(redirectTo, s, posParams) : this.findOrReturn(s, actualSegments));
  }
  findPosParam(redirectTo, redirectToUrlSegment, posParams) {
    const pos = posParams[redirectToUrlSegment.path.substring(1)];
    if (!pos) throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4001 /* RuntimeErrorCode.MISSING_REDIRECT */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Cannot redirect to '${redirectTo}'. Cannot find '${redirectToUrlSegment.path}'.`);
    return pos;
  }
  findOrReturn(redirectToUrlSegment, actualSegments) {
    let idx = 0;
    for (const s of actualSegments) {
      if (s.path === redirectToUrlSegment.path) {
        actualSegments.splice(idx);
        return s;
      }
      idx++;
    }
    return redirectToUrlSegment;
  }
}
const noMatch = {
  matched: false,
  consumedSegments: [],
  remainingSegments: [],
  parameters: {},
  positionalParamSegments: {}
};
function matchWithChecks(segmentGroup, route, segments, injector, urlSerializer) {
  const result = match(segmentGroup, route, segments);
  if (!result.matched) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(result);
  }
  // Only create the Route's `EnvironmentInjector` if it matches the attempted
  // navigation
  injector = getOrCreateRouteInjectorIfNeeded(route, injector);
  return runCanMatchGuards(injector, route, segments, urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(v => v === true ? result : {
    ...noMatch
  }));
}
function match(segmentGroup, route, segments) {
  if (route.path === '**') {
    return createWildcardMatchResult(segments);
  }
  if (route.path === '') {
    if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) {
      return {
        ...noMatch
      };
    }
    return {
      matched: true,
      consumedSegments: [],
      remainingSegments: segments,
      parameters: {},
      positionalParamSegments: {}
    };
  }
  const matcher = route.matcher || defaultUrlMatcher;
  const res = matcher(segments, segmentGroup, route);
  if (!res) return {
    ...noMatch
  };
  const posParams = {};
  Object.entries(res.posParams ?? {}).forEach(([k, v]) => {
    posParams[k] = v.path;
  });
  const parameters = res.consumed.length > 0 ? {
    ...posParams,
    ...res.consumed[res.consumed.length - 1].parameters
  } : posParams;
  return {
    matched: true,
    consumedSegments: res.consumed,
    remainingSegments: segments.slice(res.consumed.length),
    // TODO(atscott): investigate combining parameters and positionalParamSegments
    parameters,
    positionalParamSegments: res.posParams ?? {}
  };
}
function createWildcardMatchResult(segments) {
  return {
    matched: true,
    parameters: segments.length > 0 ? last(segments).parameters : {},
    consumedSegments: segments,
    remainingSegments: [],
    positionalParamSegments: {}
  };
}
function split(segmentGroup, consumedSegments, slicedSegments, config) {
  if (slicedSegments.length > 0 && containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) {
    const s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(config, new UrlSegmentGroup(slicedSegments, segmentGroup.children)));
    return {
      segmentGroup: s,
      slicedSegments: []
    };
  }
  if (slicedSegments.length === 0 && containsEmptyPathMatches(segmentGroup, slicedSegments, config)) {
    const s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children));
    return {
      segmentGroup: s,
      slicedSegments
    };
  }
  const s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children);
  return {
    segmentGroup: s,
    slicedSegments
  };
}
function addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) {
  const res = {};
  for (const r of routes) {
    if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) {
      const s = new UrlSegmentGroup([], {});
      res[getOutlet(r)] = s;
    }
  }
  return {
    ...children,
    ...res
  };
}
function createChildrenForEmptyPaths(routes, primarySegment) {
  const res = {};
  res[PRIMARY_OUTLET] = primarySegment;
  for (const r of routes) {
    if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) {
      const s = new UrlSegmentGroup([], {});
      res[getOutlet(r)] = s;
    }
  }
  return res;
}
function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) {
  return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET);
}
function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) {
  return routes.some(r => emptyPathMatch(segmentGroup, slicedSegments, r));
}
function emptyPathMatch(segmentGroup, slicedSegments, r) {
  if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') {
    return false;
  }
  return r.path === '';
}
/**
 * Determines if `route` is a path match for the `rawSegment`, `segments`, and `outlet` without
 * verifying that its children are a full match for the remainder of the `rawSegment` children as
 * well.
 */
function isImmediateMatch(route, rawSegment, segments, outlet) {
  // We allow matches to empty paths when the outlets differ so we can match a url like `/(b:b)` to
  // a config like
  // * `{path: '', children: [{path: 'b', outlet: 'b'}]}`
  // or even
  // * `{path: '', outlet: 'a', children: [{path: 'b', outlet: 'b'}]`
  //
  // The exception here is when the segment outlet is for the primary outlet. This would
  // result in a match inside the named outlet because all children there are written as primary
  // outlets. So we need to prevent child named outlet matches in a url like `/b` in a config like
  // * `{path: '', outlet: 'x' children: [{path: 'b'}]}`
  // This should only match if the url is `/(x:b)`.
  if (getOutlet(route) !== outlet && (outlet === PRIMARY_OUTLET || !emptyPathMatch(rawSegment, segments, route))) {
    return false;
  }
  return match(rawSegment, route, segments).matched;
}
function noLeftoversInUrl(segmentGroup, segments, outlet) {
  return segments.length === 0 && !segmentGroup.children[outlet];
}

/**
 * Class used to indicate there were no additional route config matches but that all segments of
 * the URL were consumed during matching so the route was URL matched. When this happens, we still
 * try to match child configs in case there are empty path children.
 */
class NoLeftoversInUrl {}
function recognize$1(injector, configLoader, rootComponentType, config, urlTree, urlSerializer, paramsInheritanceStrategy = 'emptyOnly') {
  return new Recognizer(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer).recognize();
}
const MAX_ALLOWED_REDIRECTS = 31;
class Recognizer {
  constructor(injector, configLoader, rootComponentType, config, urlTree, paramsInheritanceStrategy, urlSerializer) {
    this.injector = injector;
    this.configLoader = configLoader;
    this.rootComponentType = rootComponentType;
    this.config = config;
    this.urlTree = urlTree;
    this.paramsInheritanceStrategy = paramsInheritanceStrategy;
    this.urlSerializer = urlSerializer;
    this.applyRedirects = new ApplyRedirects(this.urlSerializer, this.urlTree);
    this.absoluteRedirectCount = 0;
    this.allowRedirects = true;
  }
  noMatchError(e) {
    return new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4002 /* RuntimeErrorCode.NO_MATCH */, typeof ngDevMode === 'undefined' || ngDevMode ? `Cannot match any routes. URL Segment: '${e.segmentGroup}'` : `'${e.segmentGroup}'`);
  }
  recognize() {
    const rootSegmentGroup = split(this.urlTree.root, [], [], this.config).segmentGroup;
    return this.match(rootSegmentGroup).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(children => {
      // Use Object.freeze to prevent readers of the Router state from modifying it outside
      // of a navigation, resulting in the router being out of sync with the browser.
      const root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze({
        ...this.urlTree.queryParams
      }), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, {});
      const rootNode = new TreeNode(root, children);
      const routeState = new RouterStateSnapshot('', rootNode);
      const tree = createUrlTreeFromSnapshot(root, [], this.urlTree.queryParams, this.urlTree.fragment);
      // https://github.com/angular/angular/issues/47307
      // Creating the tree stringifies the query params
      // We don't want to do this here so reassign them to the original.
      tree.queryParams = this.urlTree.queryParams;
      routeState.url = this.urlSerializer.serialize(tree);
      this.inheritParamsAndData(routeState._root, null);
      return {
        state: routeState,
        tree
      };
    }));
  }
  match(rootSegmentGroup) {
    const expanded$ = this.processSegmentGroup(this.injector, this.config, rootSegmentGroup, PRIMARY_OUTLET);
    return expanded$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(e => {
      if (e instanceof AbsoluteRedirect) {
        this.urlTree = e.urlTree;
        return this.match(e.urlTree.root);
      }
      if (e instanceof NoMatch) {
        throw this.noMatchError(e);
      }
      throw e;
    }));
  }
  inheritParamsAndData(routeNode, parent) {
    const route = routeNode.value;
    const i = getInherited(route, parent, this.paramsInheritanceStrategy);
    route.params = Object.freeze(i.params);
    route.data = Object.freeze(i.data);
    routeNode.children.forEach(n => this.inheritParamsAndData(n, route));
  }
  processSegmentGroup(injector, config, segmentGroup, outlet) {
    if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) {
      return this.processChildren(injector, config, segmentGroup);
    }
    return this.processSegment(injector, config, segmentGroup, segmentGroup.segments, outlet, true).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(child => child instanceof TreeNode ? [child] : []));
  }
  /**
   * Matches every child outlet in the `segmentGroup` to a `Route` in the config. Returns `null` if
   * we cannot find a match for _any_ of the children.
   *
   * @param config - The `Routes` to match against
   * @param segmentGroup - The `UrlSegmentGroup` whose children need to be matched against the
   *     config.
   */
  processChildren(injector, config, segmentGroup) {
    // Expand outlets one at a time, starting with the primary outlet. We need to do it this way
    // because an absolute redirect from the primary outlet takes precedence.
    const childOutlets = [];
    for (const child of Object.keys(segmentGroup.children)) {
      if (child === 'primary') {
        childOutlets.unshift(child);
      } else {
        childOutlets.push(child);
      }
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(childOutlets).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap)(childOutlet => {
      const child = segmentGroup.children[childOutlet];
      // Sort the config so that routes with outlets that match the one being activated
      // appear first, followed by routes for other outlets, which might match if they have
      // an empty path.
      const sortedConfig = sortByMatchingOutlets(config, childOutlet);
      return this.processSegmentGroup(injector, sortedConfig, child, childOutlet);
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_22__.scan)((children, outletChildren) => {
      children.push(...outletChildren);
      return children;
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_23__.defaultIfEmpty)(null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.last)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(children => {
      if (children === null) return noMatch$1(segmentGroup);
      // Because we may have matched two outlets to the same empty path segment, we can have
      // multiple activated results for the same outlet. We should merge the children of
      // these results so the final return value is only one `TreeNode` per outlet.
      const mergedChildren = mergeEmptyPathMatches(children);
      if (typeof ngDevMode === 'undefined' || ngDevMode) {
        // This should really never happen - we are only taking the first match for each
        // outlet and merge the empty path matches.
        checkOutletNameUniqueness(mergedChildren);
      }
      sortActivatedRouteSnapshots(mergedChildren);
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(mergedChildren);
    }));
  }
  processSegment(injector, routes, segmentGroup, segments, outlet, allowRedirects) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(routes).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap)(r => {
      return this.processSegmentAgainstRoute(r._injector ?? injector, routes, r, segmentGroup, segments, outlet, allowRedirects).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(e => {
        if (e instanceof NoMatch) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(null);
        }
        throw e;
      }));
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)(x => !!x), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(e => {
      if (isEmptyError(e)) {
        if (noLeftoversInUrl(segmentGroup, segments, outlet)) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(new NoLeftoversInUrl());
        }
        return noMatch$1(segmentGroup);
      }
      throw e;
    }));
  }
  processSegmentAgainstRoute(injector, routes, route, rawSegment, segments, outlet, allowRedirects) {
    if (!isImmediateMatch(route, rawSegment, segments, outlet)) return noMatch$1(rawSegment);
    if (route.redirectTo === undefined) {
      return this.matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet);
    }
    if (this.allowRedirects && allowRedirects) {
      return this.expandSegmentAgainstRouteUsingRedirect(injector, rawSegment, routes, route, segments, outlet);
    }
    return noMatch$1(rawSegment);
  }
  expandSegmentAgainstRouteUsingRedirect(injector, segmentGroup, routes, route, segments, outlet) {
    const {
      matched,
      consumedSegments,
      positionalParamSegments,
      remainingSegments
    } = match(segmentGroup, route, segments);
    if (!matched) return noMatch$1(segmentGroup);
    // TODO(atscott): Move all of this under an if(ngDevMode) as a breaking change and allow stack
    // size exceeded in production
    if (route.redirectTo.startsWith('/')) {
      this.absoluteRedirectCount++;
      if (this.absoluteRedirectCount > MAX_ALLOWED_REDIRECTS) {
        if (ngDevMode) {
          throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4016 /* RuntimeErrorCode.INFINITE_REDIRECT */, `Detected possible infinite redirect when redirecting from '${this.urlTree}' to '${route.redirectTo}'.\n` + `This is currently a dev mode only error but will become a` + ` call stack size exceeded error in production in a future major version.`);
        }
        this.allowRedirects = false;
      }
    }
    const newTree = this.applyRedirects.applyRedirectCommands(consumedSegments, route.redirectTo, positionalParamSegments);
    return this.applyRedirects.lineralizeSegments(route, newTree).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(newSegments => {
      return this.processSegment(injector, routes, segmentGroup, newSegments.concat(remainingSegments), outlet, false);
    }));
  }
  matchSegmentAgainstRoute(injector, rawSegment, route, segments, outlet) {
    const matchResult = matchWithChecks(rawSegment, route, segments, injector, this.urlSerializer);
    if (route.path === '**') {
      // Prior versions of the route matching algorithm would stop matching at the wildcard route.
      // We should investigate a better strategy for any existing children. Otherwise, these
      // child segments are silently dropped from the navigation.
      // https://github.com/angular/angular/issues/40089
      rawSegment.children = {};
    }
    return matchResult.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(result => {
      if (!result.matched) {
        return noMatch$1(rawSegment);
      }
      // If the route has an injector created from providers, we should start using that.
      injector = route._injector ?? injector;
      return this.getChildConfig(injector, route, segments).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(({
        routes: childConfig
      }) => {
        const childInjector = route._loadedInjector ?? injector;
        const {
          consumedSegments,
          remainingSegments,
          parameters
        } = result;
        const snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze({
          ...this.urlTree.queryParams
        }), this.urlTree.fragment, getData(route), getOutlet(route), route.component ?? route._loadedComponent ?? null, route, getResolve(route));
        const {
          segmentGroup,
          slicedSegments
        } = split(rawSegment, consumedSegments, remainingSegments, childConfig);
        if (slicedSegments.length === 0 && segmentGroup.hasChildren()) {
          return this.processChildren(childInjector, childConfig, segmentGroup).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(children => {
            if (children === null) {
              return null;
            }
            return new TreeNode(snapshot, children);
          }));
        }
        if (childConfig.length === 0 && slicedSegments.length === 0) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(new TreeNode(snapshot, []));
        }
        const matchedOnOutlet = getOutlet(route) === outlet;
        // If we matched a config due to empty path match on a different outlet, we need to
        // continue passing the current outlet for the segment rather than switch to PRIMARY.
        // Note that we switch to primary when we have a match because outlet configs look like
        // this: {path: 'a', outlet: 'a', children: [
        //  {path: 'b', component: B},
        //  {path: 'c', component: C},
        // ]}
        // Notice that the children of the named outlet are configured with the primary outlet
        return this.processSegment(childInjector, childConfig, segmentGroup, slicedSegments, matchedOnOutlet ? PRIMARY_OUTLET : outlet, true).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(child => {
          return new TreeNode(snapshot, child instanceof TreeNode ? [child] : []);
        }));
      }));
    }));
  }
  getChildConfig(injector, route, segments) {
    if (route.children) {
      // The children belong to the same module
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({
        routes: route.children,
        injector
      });
    }
    if (route.loadChildren) {
      // lazy children belong to the loaded module
      if (route._loadedRoutes !== undefined) {
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({
          routes: route._loadedRoutes,
          injector: route._loadedInjector
        });
      }
      return runCanLoadGuards(injector, route, segments, this.urlSerializer).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(shouldLoadResult => {
        if (shouldLoadResult) {
          return this.configLoader.loadChildren(injector, route).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(cfg => {
            route._loadedRoutes = cfg.routes;
            route._loadedInjector = cfg.injector;
          }));
        }
        return canLoadFails(route);
      }));
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({
      routes: [],
      injector
    });
  }
}
function sortActivatedRouteSnapshots(nodes) {
  nodes.sort((a, b) => {
    if (a.value.outlet === PRIMARY_OUTLET) return -1;
    if (b.value.outlet === PRIMARY_OUTLET) return 1;
    return a.value.outlet.localeCompare(b.value.outlet);
  });
}
function hasEmptyPathConfig(node) {
  const config = node.value.routeConfig;
  return config && config.path === '';
}
/**
 * Finds `TreeNode`s with matching empty path route configs and merges them into `TreeNode` with
 * the children from each duplicate. This is necessary because different outlets can match a
 * single empty path route config and the results need to then be merged.
 */
function mergeEmptyPathMatches(nodes) {
  const result = [];
  // The set of nodes which contain children that were merged from two duplicate empty path nodes.
  const mergedNodes = new Set();
  for (const node of nodes) {
    if (!hasEmptyPathConfig(node)) {
      result.push(node);
      continue;
    }
    const duplicateEmptyPathNode = result.find(resultNode => node.value.routeConfig === resultNode.value.routeConfig);
    if (duplicateEmptyPathNode !== undefined) {
      duplicateEmptyPathNode.children.push(...node.children);
      mergedNodes.add(duplicateEmptyPathNode);
    } else {
      result.push(node);
    }
  }
  // For each node which has children from multiple sources, we need to recompute a new `TreeNode`
  // by also merging those children. This is necessary when there are multiple empty path configs
  // in a row. Put another way: whenever we combine children of two nodes, we need to also check
  // if any of those children can be combined into a single node as well.
  for (const mergedNode of mergedNodes) {
    const mergedChildren = mergeEmptyPathMatches(mergedNode.children);
    result.push(new TreeNode(mergedNode.value, mergedChildren));
  }
  return result.filter(n => !mergedNodes.has(n));
}
function checkOutletNameUniqueness(nodes) {
  const names = {};
  nodes.forEach(n => {
    const routeWithSameOutletName = names[n.value.outlet];
    if (routeWithSameOutletName) {
      const p = routeWithSameOutletName.url.map(s => s.toString()).join('/');
      const c = n.value.url.map(s => s.toString()).join('/');
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4006 /* RuntimeErrorCode.TWO_SEGMENTS_WITH_SAME_OUTLET */, (typeof ngDevMode === 'undefined' || ngDevMode) && `Two segments cannot have the same outlet name: '${p}' and '${c}'.`);
    }
    names[n.value.outlet] = n.value;
  });
}
function getData(route) {
  return route.data || {};
}
function getResolve(route) {
  return route.resolve || {};
}
function recognize(injector, configLoader, rootComponentType, config, serializer, paramsInheritanceStrategy) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(t => recognize$1(injector, configLoader, rootComponentType, config, t.extractedUrl, serializer, paramsInheritanceStrategy).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(({
    state: targetSnapshot,
    tree: urlAfterRedirects
  }) => {
    return {
      ...t,
      targetSnapshot,
      urlAfterRedirects
    };
  })));
}
function resolveData(paramsInheritanceStrategy, injector) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(t => {
    const {
      targetSnapshot,
      guards: {
        canActivateChecks
      }
    } = t;
    if (!canActivateChecks.length) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t);
    }
    // Iterating a Set in javascript  happens in insertion order so it is safe to use a `Set` to
    // preserve the correct order that the resolvers should run in.
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#description
    const routesWithResolversToRun = new Set(canActivateChecks.map(check => check.route));
    const routesNeedingDataUpdates = new Set();
    for (const route of routesWithResolversToRun) {
      if (routesNeedingDataUpdates.has(route)) {
        continue;
      }
      // All children under the route with a resolver to run need to recompute inherited data.
      for (const newRoute of flattenRouteTree(route)) {
        routesNeedingDataUpdates.add(newRoute);
      }
    }
    let routesProcessed = 0;
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(routesNeedingDataUpdates).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap)(route => {
      if (routesWithResolversToRun.has(route)) {
        return runResolve(route, targetSnapshot, paramsInheritanceStrategy, injector);
      } else {
        route.data = getInherited(route, route.parent, paramsInheritanceStrategy).resolve;
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(void 0);
      }
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(() => routesProcessed++), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.takeLast)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(_ => routesProcessed === routesNeedingDataUpdates.size ? (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t) : rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY));
  });
}
/**
 *  Returns the `ActivatedRouteSnapshot` tree as an array, using DFS to traverse the route tree.
 */
function flattenRouteTree(route) {
  const descendants = route.children.map(child => flattenRouteTree(child)).flat();
  return [route, ...descendants];
}
function runResolve(futureARS, futureRSS, paramsInheritanceStrategy, injector) {
  const config = futureARS.routeConfig;
  const resolve = futureARS._resolve;
  if (config?.title !== undefined && !hasStaticTitle(config)) {
    resolve[RouteTitleKey] = config.title;
  }
  return resolveNode(resolve, futureARS, futureRSS, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(resolvedData => {
    futureARS._resolvedData = resolvedData;
    futureARS.data = getInherited(futureARS, futureARS.parent, paramsInheritanceStrategy).resolve;
    return null;
  }));
}
function resolveNode(resolve, futureARS, futureRSS, injector) {
  const keys = getDataKeys(resolve);
  if (keys.length === 0) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({});
  }
  const data = {};
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(keys).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(key => getResolver(resolve[key], futureARS, futureRSS, injector).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.first)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(value => {
    data[key] = value;
  }))), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.takeLast)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_27__.mapTo)(data), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(e => isEmptyError(e) ? rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY : (0,rxjs__WEBPACK_IMPORTED_MODULE_20__.throwError)(e)));
}
function getResolver(injectionToken, futureARS, futureRSS, injector) {
  const closestInjector = getClosestRouteInjector(futureARS) ?? injector;
  const resolver = getTokenOrFunctionIdentity(injectionToken, closestInjector);
  const resolverValue = resolver.resolve ? resolver.resolve(futureARS, futureRSS) : (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(closestInjector, () => resolver(futureARS, futureRSS));
  return wrapIntoObservable(resolverValue);
}

/**
 * Perform a side effect through a switchMap for every emission on the source Observable,
 * but return an Observable that is identical to the source. It's essentially the same as
 * the `tap` operator, but if the side effectful `next` function returns an ObservableInput,
 * it will wait before continuing with the original value.
 */
function switchTap(next) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(v => {
    const nextResult = next(v);
    if (nextResult) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(nextResult).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(() => v));
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(v);
  });
}

/**
 * Provides a strategy for setting the page title after a router navigation.
 *
 * The built-in implementation traverses the router state snapshot and finds the deepest primary
 * outlet with `title` property. Given the `Routes` below, navigating to
 * `/base/child(popup:aux)` would result in the document title being set to "child".
 * ```
 * [
 *   {path: 'base', title: 'base', children: [
 *     {path: 'child', title: 'child'},
 *   ],
 *   {path: 'aux', outlet: 'popup', title: 'popupTitle'}
 * ]
 * ```
 *
 * This class can be used as a base class for custom title strategies. That is, you can create your
 * own class that extends the `TitleStrategy`. Note that in the above example, the `title`
 * from the named outlet is never used. However, a custom strategy might be implemented to
 * incorporate titles in named outlets.
 *
 * @publicApi
 * @see [Page title guide](guide/router#setting-the-page-title)
 */
class TitleStrategy {
  /**
   * @returns The `title` of the deepest primary route.
   */
  buildTitle(snapshot) {
    let pageTitle;
    let route = snapshot.root;
    while (route !== undefined) {
      pageTitle = this.getResolvedTitleForRoute(route) ?? pageTitle;
      route = route.children.find(child => child.outlet === PRIMARY_OUTLET);
    }
    return pageTitle;
  }
  /**
   * Given an `ActivatedRouteSnapshot`, returns the final value of the
   * `Route.title` property, which can either be a static string or a resolved value.
   */
  getResolvedTitleForRoute(snapshot) {
    return snapshot.data[RouteTitleKey];
  }
  static {
    this.ɵfac = function TitleStrategy_Factory(t) {
      return new (t || TitleStrategy)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: TitleStrategy,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultTitleStrategy))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](TitleStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultTitleStrategy)
    }]
  }], null, null);
})();
/**
 * The default `TitleStrategy` used by the router that updates the title using the `Title` service.
 */
class DefaultTitleStrategy extends TitleStrategy {
  constructor(title) {
    super();
    this.title = title;
  }
  /**
   * Sets the title of the browser to the given value.
   *
   * @param title The `pageTitle` from the deepest primary route.
   */
  updateTitle(snapshot) {
    const title = this.buildTitle(snapshot);
    if (title !== undefined) {
      this.title.setTitle(title);
    }
  }
  static {
    this.ɵfac = function DefaultTitleStrategy_Factory(t) {
      return new (t || DefaultTitleStrategy)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](_angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__.Title));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: DefaultTitleStrategy,
      factory: DefaultTitleStrategy.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](DefaultTitleStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_platform_browser__WEBPACK_IMPORTED_MODULE_28__.Title
  }], null);
})();

/**
 * A [DI token](guide/glossary/#di-token) for the router service.
 *
 * @publicApi
 */
const ROUTER_CONFIGURATION = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router config' : '', {
  providedIn: 'root',
  factory: () => ({})
});

/**
 * The [DI token](guide/glossary/#di-token) for a router configuration.
 *
 * `ROUTES` is a low level API for router configuration via dependency injection.
 *
 * We recommend that in almost all cases to use higher level APIs such as `RouterModule.forRoot()`,
 * `provideRouter`, or `Router.resetConfig()`.
 *
 * @publicApi
 */
const ROUTES = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(ngDevMode ? 'ROUTES' : '');
class RouterConfigLoader {
  constructor() {
    this.componentLoaders = new WeakMap();
    this.childrenLoaders = new WeakMap();
    this.compiler = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.Compiler);
  }
  loadComponent(route) {
    if (this.componentLoaders.get(route)) {
      return this.componentLoaders.get(route);
    } else if (route._loadedComponent) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(route._loadedComponent);
    }
    if (this.onLoadStartListener) {
      this.onLoadStartListener(route);
    }
    const loadRunner = wrapIntoObservable(route.loadComponent()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(maybeUnwrapDefaultExport), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(component => {
      if (this.onLoadEndListener) {
        this.onLoadEndListener(route);
      }
      (typeof ngDevMode === 'undefined' || ngDevMode) && assertStandalone(route.path ?? '', component);
      route._loadedComponent = component;
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
      this.componentLoaders.delete(route);
    }));
    // Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
    const loader = new rxjs__WEBPACK_IMPORTED_MODULE_30__.ConnectableObservable(loadRunner, () => new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_32__.refCount)());
    this.componentLoaders.set(route, loader);
    return loader;
  }
  loadChildren(parentInjector, route) {
    if (this.childrenLoaders.get(route)) {
      return this.childrenLoaders.get(route);
    } else if (route._loadedRoutes) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)({
        routes: route._loadedRoutes,
        injector: route._loadedInjector
      });
    }
    if (this.onLoadStartListener) {
      this.onLoadStartListener(route);
    }
    const moduleFactoryOrRoutes$ = loadChildren(route, this.compiler, parentInjector, this.onLoadEndListener);
    const loadRunner = moduleFactoryOrRoutes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
      this.childrenLoaders.delete(route);
    }));
    // Use custom ConnectableObservable as share in runners pipe increasing the bundle size too much
    const loader = new rxjs__WEBPACK_IMPORTED_MODULE_30__.ConnectableObservable(loadRunner, () => new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_32__.refCount)());
    this.childrenLoaders.set(route, loader);
    return loader;
  }
  static {
    this.ɵfac = function RouterConfigLoader_Factory(t) {
      return new (t || RouterConfigLoader)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: RouterConfigLoader,
      factory: RouterConfigLoader.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterConfigLoader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * Executes a `route.loadChildren` callback and converts the result to an array of child routes and
 * an injector if that callback returned a module.
 *
 * This function is used for the route discovery during prerendering
 * in @angular-devkit/build-angular. If there are any updates to the contract here, it will require
 * an update to the extractor.
 */
function loadChildren(route, compiler, parentInjector, onLoadEndListener) {
  return wrapIntoObservable(route.loadChildren()).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(maybeUnwrapDefaultExport), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(t => {
    if (t instanceof _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgModuleFactory || Array.isArray(t)) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t);
    } else {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(compiler.compileModuleAsync(t));
    }
  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(factoryOrRoutes => {
    if (onLoadEndListener) {
      onLoadEndListener(route);
    }
    // This injector comes from the `NgModuleRef` when lazy loading an `NgModule`. There is
    // no injector associated with lazy loading a `Route` array.
    let injector;
    let rawRoutes;
    let requireStandaloneComponents = false;
    if (Array.isArray(factoryOrRoutes)) {
      rawRoutes = factoryOrRoutes;
      requireStandaloneComponents = true;
    } else {
      injector = factoryOrRoutes.create(parentInjector).injector;
      // When loading a module that doesn't provide `RouterModule.forChild()` preloader
      // will get stuck in an infinite loop. The child module's Injector will look to
      // its parent `Injector` when it doesn't find any ROUTES so it will return routes
      // for it's parent module instead.
      rawRoutes = injector.get(ROUTES, [], {
        optional: true,
        self: true
      }).flat();
    }
    const routes = rawRoutes.map(standardizeConfig);
    (typeof ngDevMode === 'undefined' || ngDevMode) && validateConfig(routes, route.path, requireStandaloneComponents);
    return {
      routes,
      injector
    };
  }));
}
function isWrappedDefaultExport(value) {
  // We use `in` here with a string key `'default'`, because we expect `DefaultExport` objects to be
  // dynamically imported ES modules with a spec-mandated `default` key. Thus we don't expect that
  // `default` will be a renamed property.
  return value && typeof value === 'object' && 'default' in value;
}
function maybeUnwrapDefaultExport(input) {
  // As per `isWrappedDefaultExport`, the `default` key here is generated by the browser and not
  // subject to property renaming, so we reference it with bracket access.
  return isWrappedDefaultExport(input) ? input['default'] : input;
}

/**
 * @description
 *
 * Provides a way to migrate AngularJS applications to Angular.
 *
 * @publicApi
 */
class UrlHandlingStrategy {
  static {
    this.ɵfac = function UrlHandlingStrategy_Factory(t) {
      return new (t || UrlHandlingStrategy)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: UrlHandlingStrategy,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultUrlHandlingStrategy))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](UrlHandlingStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultUrlHandlingStrategy)
    }]
  }], null, null);
})();
/**
 * @publicApi
 */
class DefaultUrlHandlingStrategy {
  shouldProcessUrl(url) {
    return true;
  }
  extract(url) {
    return url;
  }
  merge(newUrlPart, wholeUrl) {
    return newUrlPart;
  }
  static {
    this.ɵfac = function DefaultUrlHandlingStrategy_Factory(t) {
      return new (t || DefaultUrlHandlingStrategy)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: DefaultUrlHandlingStrategy,
      factory: DefaultUrlHandlingStrategy.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](DefaultUrlHandlingStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/// <reference types="dom-view-transitions" />
const CREATE_VIEW_TRANSITION = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(ngDevMode ? 'view transition helper' : '');
const VIEW_TRANSITION_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(ngDevMode ? 'view transition options' : '');
/**
 * A helper function for using browser view transitions. This function skips the call to
 * `startViewTransition` if the browser does not support it.
 *
 * @returns A Promise that resolves when the view transition callback begins.
 */
function createViewTransition(injector, from, to) {
  const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
  const document = injector.get(_angular_common__WEBPACK_IMPORTED_MODULE_33__.DOCUMENT);
  // Create promises outside the Angular zone to avoid causing extra change detections
  return injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone).runOutsideAngular(() => {
    if (!document.startViewTransition || transitionOptions.skipNextTransition) {
      transitionOptions.skipNextTransition = false;
      // The timing of `startViewTransition` is closer to a macrotask. It won't be called
      // until the current event loop exits so we use a promise resolved in a timeout instead
      // of Promise.resolve().
      return new Promise(resolve => setTimeout(resolve));
    }
    let resolveViewTransitionStarted;
    const viewTransitionStarted = new Promise(resolve => {
      resolveViewTransitionStarted = resolve;
    });
    const transition = document.startViewTransition(() => {
      resolveViewTransitionStarted();
      // We don't actually update dom within the transition callback. The resolving of the above
      // promise unblocks the Router navigation, which synchronously activates and deactivates
      // routes (the DOM update). This view transition waits for the next change detection to
      // complete (below), which includes the update phase of the routed components.
      return createRenderPromise(injector);
    });
    const {
      onViewTransitionCreated
    } = transitionOptions;
    if (onViewTransitionCreated) {
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(injector, () => onViewTransitionCreated({
        transition,
        from,
        to
      }));
    }
    return viewTransitionStarted;
  });
}
/**
 * Creates a promise that resolves after next render.
 */
function createRenderPromise(injector) {
  return new Promise(resolve => {
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.afterNextRender)(resolve, {
      injector
    });
  });
}
class NavigationTransitions {
  get hasRequestedNavigation() {
    return this.navigationId !== 0;
  }
  constructor() {
    this.currentNavigation = null;
    this.currentTransition = null;
    this.lastSuccessfulNavigation = null;
    /**
     * These events are used to communicate back to the Router about the state of the transition. The
     * Router wants to respond to these events in various ways. Because the `NavigationTransition`
     * class is not public, this event subject is not publicly exposed.
     */
    this.events = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
    /**
     * Used to abort the current transition with an error.
     */
    this.transitionAbortSubject = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
    this.configLoader = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(RouterConfigLoader);
    this.environmentInjector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector);
    this.urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlSerializer);
    this.rootContexts = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ChildrenOutletContexts);
    this.location = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location);
    this.inputBindingEnabled = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(INPUT_BINDER, {
      optional: true
    }) !== null;
    this.titleStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(TitleStrategy);
    this.options = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTER_CONFIGURATION, {
      optional: true
    }) || {};
    this.paramsInheritanceStrategy = this.options.paramsInheritanceStrategy || 'emptyOnly';
    this.urlHandlingStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlHandlingStrategy);
    this.createViewTransition = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(CREATE_VIEW_TRANSITION, {
      optional: true
    });
    this.navigationId = 0;
    /**
     * Hook that enables you to pause navigation after the preactivation phase.
     * Used by `RouterModule`.
     *
     * @internal
     */
    this.afterPreactivation = () => (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(void 0);
    /** @internal */
    this.rootComponentType = null;
    const onLoadStart = r => this.events.next(new RouteConfigLoadStart(r));
    const onLoadEnd = r => this.events.next(new RouteConfigLoadEnd(r));
    this.configLoader.onLoadEndListener = onLoadEnd;
    this.configLoader.onLoadStartListener = onLoadStart;
  }
  complete() {
    this.transitions?.complete();
  }
  handleNavigationRequest(request) {
    const id = ++this.navigationId;
    this.transitions?.next({
      ...this.transitions.value,
      ...request,
      id
    });
  }
  setupNavigations(router, initialUrlTree, initialRouterState) {
    this.transitions = new rxjs__WEBPACK_IMPORTED_MODULE_5__.BehaviorSubject({
      id: 0,
      currentUrlTree: initialUrlTree,
      currentRawUrl: initialUrlTree,
      extractedUrl: this.urlHandlingStrategy.extract(initialUrlTree),
      urlAfterRedirects: this.urlHandlingStrategy.extract(initialUrlTree),
      rawUrl: initialUrlTree,
      extras: {},
      resolve: null,
      reject: null,
      promise: Promise.resolve(true),
      source: IMPERATIVE_NAVIGATION,
      restoredState: null,
      currentSnapshot: initialRouterState.snapshot,
      targetSnapshot: null,
      currentRouterState: initialRouterState,
      targetRouterState: null,
      guards: {
        canActivateChecks: [],
        canDeactivateChecks: []
      },
      guardsResult: null
    });
    return this.transitions.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(t => t.id !== 0),
    // Extract URL
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(t => ({
      ...t,
      extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl)
    })),
    // Using switchMap so we cancel executing navigations when a new one comes in
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(overallTransitionState => {
      let completed = false;
      let errored = false;
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(overallTransitionState).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(t => {
        // It is possible that `switchMap` fails to cancel previous navigations if a new one happens synchronously while the operator
        // is processing the `next` notification of that previous navigation. This can happen when a new navigation (say 2) cancels a
        // previous one (1) and yet another navigation (3) happens synchronously in response to the `NavigationCancel` event for (1).
        // https://github.com/ReactiveX/rxjs/issues/7455
        if (this.navigationId > overallTransitionState.id) {
          const cancellationReason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : '';
          this.cancelNavigationTransition(overallTransitionState, cancellationReason, NavigationCancellationCode.SupersededByNewNavigation);
          return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
        }
        this.currentTransition = overallTransitionState;
        // Store the Navigation object
        this.currentNavigation = {
          id: t.id,
          initialUrl: t.rawUrl,
          extractedUrl: t.extractedUrl,
          trigger: t.source,
          extras: t.extras,
          previousNavigation: !this.lastSuccessfulNavigation ? null : {
            ...this.lastSuccessfulNavigation,
            previousNavigation: null
          }
        };
        const urlTransition = !router.navigated || this.isUpdatingInternalState() || this.isUpdatedBrowserUrl();
        const onSameUrlNavigation = t.extras.onSameUrlNavigation ?? router.onSameUrlNavigation;
        if (!urlTransition && onSameUrlNavigation !== 'reload') {
          const reason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation to ${t.rawUrl} was ignored because it is the same as the current Router URL.` : '';
          this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.rawUrl), reason, NavigationSkippedCode.IgnoredSameUrlNavigation));
          t.resolve(null);
          return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
        }
        if (this.urlHandlingStrategy.shouldProcessUrl(t.rawUrl)) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t).pipe(
          // Fire NavigationStart event
          (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(t => {
            const transition = this.transitions?.getValue();
            this.events.next(new NavigationStart(t.id, this.urlSerializer.serialize(t.extractedUrl), t.source, t.restoredState));
            if (transition !== this.transitions?.getValue()) {
              return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
            }
            // This delay is required to match old behavior that forced
            // navigation to always be async
            return Promise.resolve(t);
          }),
          // Recognize
          recognize(this.environmentInjector, this.configLoader, this.rootComponentType, router.config, this.urlSerializer, this.paramsInheritanceStrategy),
          // Update URL if in `eager` update mode
          (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(t => {
            overallTransitionState.targetSnapshot = t.targetSnapshot;
            overallTransitionState.urlAfterRedirects = t.urlAfterRedirects;
            this.currentNavigation = {
              ...this.currentNavigation,
              finalUrl: t.urlAfterRedirects
            };
            // Fire RoutesRecognized
            const routesRecognized = new RoutesRecognized(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
            this.events.next(routesRecognized);
          }));
        } else if (urlTransition && this.urlHandlingStrategy.shouldProcessUrl(t.currentRawUrl)) {
          /* When the current URL shouldn't be processed, but the previous one
           * was, we handle this "error condition" by navigating to the
           * previously successful URL, but leaving the URL intact.*/
          const {
            id,
            extractedUrl,
            source,
            restoredState,
            extras
          } = t;
          const navStart = new NavigationStart(id, this.urlSerializer.serialize(extractedUrl), source, restoredState);
          this.events.next(navStart);
          const targetSnapshot = createEmptyState(this.rootComponentType).snapshot;
          this.currentTransition = overallTransitionState = {
            ...t,
            targetSnapshot,
            urlAfterRedirects: extractedUrl,
            extras: {
              ...extras,
              skipLocationChange: false,
              replaceUrl: false
            }
          };
          this.currentNavigation.finalUrl = extractedUrl;
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(overallTransitionState);
        } else {
          /* When neither the current or previous URL can be processed, do
           * nothing other than update router's internal reference to the
           * current "settled" URL. This way the next navigation will be coming
           * from the current URL in the browser.
           */
          const reason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation was ignored because the UrlHandlingStrategy` + ` indicated neither the current URL ${t.currentRawUrl} nor target URL ${t.rawUrl} should be processed.` : '';
          this.events.next(new NavigationSkipped(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, NavigationSkippedCode.IgnoredByUrlHandlingStrategy));
          t.resolve(null);
          return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
        }
      }),
      // --- GUARDS ---
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(t => {
        const guardsStart = new GuardsCheckStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
        this.events.next(guardsStart);
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(t => {
        this.currentTransition = overallTransitionState = {
          ...t,
          guards: getAllRouteGuards(t.targetSnapshot, t.currentSnapshot, this.rootContexts)
        };
        return overallTransitionState;
      }), checkGuards(this.environmentInjector, evt => this.events.next(evt)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(t => {
        overallTransitionState.guardsResult = t.guardsResult;
        if (isUrlTree(t.guardsResult)) {
          throw redirectingNavigationError(this.urlSerializer, t.guardsResult);
        }
        const guardsEnd = new GuardsCheckEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot, !!t.guardsResult);
        this.events.next(guardsEnd);
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(t => {
        if (!t.guardsResult) {
          this.cancelNavigationTransition(t, '', NavigationCancellationCode.GuardRejected);
          return false;
        }
        return true;
      }),
      // --- RESOLVE ---
      switchTap(t => {
        if (t.guards.canActivateChecks.length) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(t => {
            const resolveStart = new ResolveStart(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
            this.events.next(resolveStart);
          }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(t => {
            let dataResolved = false;
            return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(t).pipe(resolveData(this.paramsInheritanceStrategy, this.environmentInjector), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)({
              next: () => dataResolved = true,
              complete: () => {
                if (!dataResolved) {
                  this.cancelNavigationTransition(t, typeof ngDevMode === 'undefined' || ngDevMode ? `At least one route resolver didn't emit any value.` : '', NavigationCancellationCode.NoDataFromResolver);
                }
              }
            }));
          }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(t => {
            const resolveEnd = new ResolveEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects), t.targetSnapshot);
            this.events.next(resolveEnd);
          }));
        }
        return undefined;
      }),
      // --- LOAD COMPONENTS ---
      switchTap(t => {
        const loadComponents = route => {
          const loaders = [];
          if (route.routeConfig?.loadComponent && !route.routeConfig._loadedComponent) {
            loaders.push(this.configLoader.loadComponent(route.routeConfig).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(loadedComponent => {
              route.component = loadedComponent;
            }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(() => void 0)));
          }
          for (const child of route.children) {
            loaders.push(...loadComponents(child));
          }
          return loaders;
        };
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.combineLatest)(loadComponents(t.targetSnapshot.root)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_23__.defaultIfEmpty)(null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.take)(1));
      }), switchTap(() => this.afterPreactivation()), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.switchMap)(() => {
        const {
          currentSnapshot,
          targetSnapshot
        } = overallTransitionState;
        const viewTransitionStarted = this.createViewTransition?.(this.environmentInjector, currentSnapshot.root, targetSnapshot.root);
        // If view transitions are enabled, block the navigation until the view
        // transition callback starts. Otherwise, continue immediately.
        return viewTransitionStarted ? (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(viewTransitionStarted).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(() => overallTransitionState)) : (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(overallTransitionState);
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(t => {
        const targetRouterState = createRouterState(router.routeReuseStrategy, t.targetSnapshot, t.currentRouterState);
        this.currentTransition = overallTransitionState = {
          ...t,
          targetRouterState
        };
        this.currentNavigation.targetRouterState = targetRouterState;
        return overallTransitionState;
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(() => {
        this.events.next(new BeforeActivateRoutes());
      }), activateRoutes(this.rootContexts, router.routeReuseStrategy, evt => this.events.next(evt), this.inputBindingEnabled),
      // Ensure that if some observable used to drive the transition doesn't
      // complete, the navigation still finalizes This should never happen, but
      // this is done as a safety measure to avoid surfacing this error (#49567).
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.take)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)({
        next: t => {
          completed = true;
          this.lastSuccessfulNavigation = this.currentNavigation;
          this.events.next(new NavigationEnd(t.id, this.urlSerializer.serialize(t.extractedUrl), this.urlSerializer.serialize(t.urlAfterRedirects)));
          this.titleStrategy?.updateTitle(t.targetRouterState.snapshot);
          t.resolve(true);
        },
        complete: () => {
          completed = true;
        }
      }),
      // There used to be a lot more logic happening directly within the
      // transition Observable. Some of this logic has been refactored out to
      // other places but there may still be errors that happen there. This gives
      // us a way to cancel the transition from the outside. This may also be
      // required in the future to support something like the abort signal of the
      // Navigation API where the navigation gets aborted from outside the
      // transition.
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.takeUntil)(this.transitionAbortSubject.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_19__.tap)(err => {
        throw err;
      }))), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_29__.finalize)(() => {
        /* When the navigation stream finishes either through error or success,
         * we set the `completed` or `errored` flag. However, there are some
         * situations where we could get here without either of those being set.
         * For instance, a redirect during NavigationStart. Therefore, this is a
         * catch-all to make sure the NavigationCancel event is fired when a
         * navigation gets cancelled but not caught by other means. */
        if (!completed && !errored) {
          const cancelationReason = typeof ngDevMode === 'undefined' || ngDevMode ? `Navigation ID ${overallTransitionState.id} is not equal to the current navigation id ${this.navigationId}` : '';
          this.cancelNavigationTransition(overallTransitionState, cancelationReason, NavigationCancellationCode.SupersededByNewNavigation);
        }
        // Only clear current navigation if it is still set to the one that
        // finalized.
        if (this.currentTransition?.id === overallTransitionState.id) {
          this.currentNavigation = null;
          this.currentTransition = null;
        }
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(e => {
        errored = true;
        /* This error type is issued during Redirect, and is handled as a
         * cancellation rather than an error. */
        if (isNavigationCancelingError(e)) {
          this.events.next(new NavigationCancel(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e.message, e.cancellationCode));
          // When redirecting, we need to delay resolving the navigation
          // promise and push it to the redirect navigation
          if (!isRedirectingNavigationCancelingError(e)) {
            overallTransitionState.resolve(false);
          } else {
            this.events.next(new RedirectRequest(e.url));
          }
          /* All other errors should reset to the router's internal URL reference
           * to the pre-error state. */
        } else {
          this.events.next(new NavigationError(overallTransitionState.id, this.urlSerializer.serialize(overallTransitionState.extractedUrl), e, overallTransitionState.targetSnapshot ?? undefined));
          try {
            overallTransitionState.resolve(router.errorHandler(e));
          } catch (ee) {
            // TODO(atscott): consider flipping the default behavior of
            // resolveNavigationPromiseOnError to be `resolve(false)` when
            // undefined. This is the most sane thing to do given that
            // applications very rarely handle the promise rejection and, as a
            // result, would get "unhandled promise rejection" console logs.
            // The vast majority of applications would not be affected by this
            // change so omitting a migration seems reasonable. Instead,
            // applications that rely on rejection can specifically opt-in to the
            // old behavior.
            if (this.options.resolveNavigationPromiseOnError) {
              overallTransitionState.resolve(false);
            } else {
              overallTransitionState.reject(ee);
            }
          }
        }
        return rxjs__WEBPACK_IMPORTED_MODULE_26__.EMPTY;
      }));
      // casting because `pipe` returns observable({}) when called with 8+ arguments
    }));
  }
  cancelNavigationTransition(t, reason, code) {
    const navCancel = new NavigationCancel(t.id, this.urlSerializer.serialize(t.extractedUrl), reason, code);
    this.events.next(navCancel);
    t.resolve(false);
  }
  /**
   * @returns Whether we're navigating to somewhere that is not what the Router is
   * currently set to.
   */
  isUpdatingInternalState() {
    // TODO(atscott): The serializer should likely be used instead of
    // `UrlTree.toString()`. Custom serializers are often written to handle
    // things better than the default one (objects, for example will be
    // [Object object] with the custom serializer and be "the same" when they
    // aren't).
    // (Same for isUpdatedBrowserUrl)
    return this.currentTransition?.extractedUrl.toString() !== this.currentTransition?.currentUrlTree.toString();
  }
  /**
   * @returns Whether we're updating the browser URL to something new (navigation is going
   * to somewhere not displayed in the URL bar and we will update the URL
   * bar if navigation succeeds).
   */
  isUpdatedBrowserUrl() {
    // The extracted URL is the part of the URL that this application cares about. `extract` may
    // return only part of the browser URL and that part may have not changed even if some other
    // portion of the URL did.
    const extractedBrowserUrl = this.urlHandlingStrategy.extract(this.urlSerializer.parse(this.location.path(true)));
    return extractedBrowserUrl.toString() !== this.currentTransition?.extractedUrl.toString() && !this.currentTransition?.extras.skipLocationChange;
  }
  static {
    this.ɵfac = function NavigationTransitions_Factory(t) {
      return new (t || NavigationTransitions)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: NavigationTransitions,
      factory: NavigationTransitions.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](NavigationTransitions, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();
function isBrowserTriggeredNavigation(source) {
  return source !== IMPERATIVE_NAVIGATION;
}

/**
 * @description
 *
 * Provides a way to customize when activated routes get reused.
 *
 * @publicApi
 */
class RouteReuseStrategy {
  static {
    this.ɵfac = function RouteReuseStrategy_Factory(t) {
      return new (t || RouteReuseStrategy)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: RouteReuseStrategy,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultRouteReuseStrategy))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouteReuseStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(DefaultRouteReuseStrategy)
    }]
  }], null, null);
})();
/**
 * @description
 *
 * This base route reuse strategy only reuses routes when the matched router configs are
 * identical. This prevents components from being destroyed and recreated
 * when just the route parameters, query parameters or fragment change
 * (that is, the existing component is _reused_).
 *
 * This strategy does not store any routes for later reuse.
 *
 * Angular uses this strategy by default.
 *
 *
 * It can be used as a base class for custom route reuse strategies, i.e. you can create your own
 * class that extends the `BaseRouteReuseStrategy` one.
 * @publicApi
 */
class BaseRouteReuseStrategy {
  /**
   * Whether the given route should detach for later reuse.
   * Always returns false for `BaseRouteReuseStrategy`.
   * */
  shouldDetach(route) {
    return false;
  }
  /**
   * A no-op; the route is never stored since this strategy never detaches routes for later re-use.
   */
  store(route, detachedTree) {}
  /** Returns `false`, meaning the route (and its subtree) is never reattached */
  shouldAttach(route) {
    return false;
  }
  /** Returns `null` because this strategy does not store routes for later re-use. */
  retrieve(route) {
    return null;
  }
  /**
   * Determines if a route should be reused.
   * This strategy returns `true` when the future route config and current route config are
   * identical.
   */
  shouldReuseRoute(future, curr) {
    return future.routeConfig === curr.routeConfig;
  }
}
class DefaultRouteReuseStrategy extends BaseRouteReuseStrategy {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵDefaultRouteReuseStrategy_BaseFactory;
      return function DefaultRouteReuseStrategy_Factory(t) {
        return (ɵDefaultRouteReuseStrategy_BaseFactory || (ɵDefaultRouteReuseStrategy_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵgetInheritedFactory"](DefaultRouteReuseStrategy)))(t || DefaultRouteReuseStrategy);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: DefaultRouteReuseStrategy,
      factory: DefaultRouteReuseStrategy.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](DefaultRouteReuseStrategy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class StateManager {
  static {
    this.ɵfac = function StateManager_Factory(t) {
      return new (t || StateManager)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: StateManager,
      factory: () => (() => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(HistoryStateManager))(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](StateManager, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(HistoryStateManager)
    }]
  }], null, null);
})();
class HistoryStateManager extends StateManager {
  constructor() {
    super(...arguments);
    this.location = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location);
    this.urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlSerializer);
    this.options = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTER_CONFIGURATION, {
      optional: true
    }) || {};
    this.canceledNavigationResolution = this.options.canceledNavigationResolution || 'replace';
    this.urlHandlingStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlHandlingStrategy);
    this.urlUpdateStrategy = this.options.urlUpdateStrategy || 'deferred';
    this.currentUrlTree = new UrlTree();
    this.rawUrlTree = this.currentUrlTree;
    /**
     * The id of the currently active page in the router.
     * Updated to the transition's target id on a successful navigation.
     *
     * This is used to track what page the router last activated. When an attempted navigation fails,
     * the router can then use this to compute how to restore the state back to the previously active
     * page.
     */
    this.currentPageId = 0;
    this.lastSuccessfulId = -1;
    this.routerState = createEmptyState(null);
    this.stateMemento = this.createStateMemento();
  }
  getCurrentUrlTree() {
    return this.currentUrlTree;
  }
  getRawUrlTree() {
    return this.rawUrlTree;
  }
  restoredState() {
    return this.location.getState();
  }
  /**
   * The ɵrouterPageId of whatever page is currently active in the browser history. This is
   * important for computing the target page id for new navigations because we need to ensure each
   * page id in the browser history is 1 more than the previous entry.
   */
  get browserPageId() {
    if (this.canceledNavigationResolution !== 'computed') {
      return this.currentPageId;
    }
    return this.restoredState()?.ɵrouterPageId ?? this.currentPageId;
  }
  getRouterState() {
    return this.routerState;
  }
  createStateMemento() {
    return {
      rawUrlTree: this.rawUrlTree,
      currentUrlTree: this.currentUrlTree,
      routerState: this.routerState
    };
  }
  registerNonRouterCurrentEntryChangeListener(listener) {
    return this.location.subscribe(event => {
      if (event['type'] === 'popstate') {
        listener(event['url'], event.state);
      }
    });
  }
  handleRouterEvent(e, currentTransition) {
    if (e instanceof NavigationStart) {
      this.stateMemento = this.createStateMemento();
    } else if (e instanceof NavigationSkipped) {
      this.rawUrlTree = currentTransition.initialUrl;
    } else if (e instanceof RoutesRecognized) {
      if (this.urlUpdateStrategy === 'eager') {
        if (!currentTransition.extras.skipLocationChange) {
          const rawUrl = this.urlHandlingStrategy.merge(currentTransition.finalUrl, currentTransition.initialUrl);
          this.setBrowserUrl(rawUrl, currentTransition);
        }
      }
    } else if (e instanceof BeforeActivateRoutes) {
      this.currentUrlTree = currentTransition.finalUrl;
      this.rawUrlTree = this.urlHandlingStrategy.merge(currentTransition.finalUrl, currentTransition.initialUrl);
      this.routerState = currentTransition.targetRouterState;
      if (this.urlUpdateStrategy === 'deferred') {
        if (!currentTransition.extras.skipLocationChange) {
          this.setBrowserUrl(this.rawUrlTree, currentTransition);
        }
      }
    } else if (e instanceof NavigationCancel && (e.code === NavigationCancellationCode.GuardRejected || e.code === NavigationCancellationCode.NoDataFromResolver)) {
      this.restoreHistory(currentTransition);
    } else if (e instanceof NavigationError) {
      this.restoreHistory(currentTransition, true);
    } else if (e instanceof NavigationEnd) {
      this.lastSuccessfulId = e.id;
      this.currentPageId = this.browserPageId;
    }
  }
  setBrowserUrl(url, transition) {
    const path = this.urlSerializer.serialize(url);
    if (this.location.isCurrentPathEqualTo(path) || !!transition.extras.replaceUrl) {
      // replacements do not update the target page
      const currentBrowserPageId = this.browserPageId;
      const state = {
        ...transition.extras.state,
        ...this.generateNgRouterState(transition.id, currentBrowserPageId)
      };
      this.location.replaceState(path, '', state);
    } else {
      const state = {
        ...transition.extras.state,
        ...this.generateNgRouterState(transition.id, this.browserPageId + 1)
      };
      this.location.go(path, '', state);
    }
  }
  /**
   * Performs the necessary rollback action to restore the browser URL to the
   * state before the transition.
   */
  restoreHistory(navigation, restoringFromCaughtError = false) {
    if (this.canceledNavigationResolution === 'computed') {
      const currentBrowserPageId = this.browserPageId;
      const targetPagePosition = this.currentPageId - currentBrowserPageId;
      if (targetPagePosition !== 0) {
        this.location.historyGo(targetPagePosition);
      } else if (this.currentUrlTree === navigation.finalUrl && targetPagePosition === 0) {
        // We got to the activation stage (where currentUrlTree is set to the navigation's
        // finalUrl), but we weren't moving anywhere in history (skipLocationChange or replaceUrl).
        // We still need to reset the router state back to what it was when the navigation started.
        this.resetState(navigation);
        this.resetUrlToCurrentUrlTree();
      } else {
        // The browser URL and router state was not updated before the navigation cancelled so
        // there's no restoration needed.
      }
    } else if (this.canceledNavigationResolution === 'replace') {
      // TODO(atscott): It seems like we should _always_ reset the state here. It would be a no-op
      // for `deferred` navigations that haven't change the internal state yet because guards
      // reject. For 'eager' navigations, it seems like we also really should reset the state
      // because the navigation was cancelled. Investigate if this can be done by running TGP.
      if (restoringFromCaughtError) {
        this.resetState(navigation);
      }
      this.resetUrlToCurrentUrlTree();
    }
  }
  resetState(navigation) {
    this.routerState = this.stateMemento.routerState;
    this.currentUrlTree = this.stateMemento.currentUrlTree;
    // Note here that we use the urlHandlingStrategy to get the reset `rawUrlTree` because it may be
    // configured to handle only part of the navigation URL. This means we would only want to reset
    // the part of the navigation handled by the Angular router rather than the whole URL. In
    // addition, the URLHandlingStrategy may be configured to specifically preserve parts of the URL
    // when merging, such as the query params so they are not lost on a refresh.
    this.rawUrlTree = this.urlHandlingStrategy.merge(this.currentUrlTree, navigation.finalUrl ?? this.rawUrlTree);
  }
  resetUrlToCurrentUrlTree() {
    this.location.replaceState(this.urlSerializer.serialize(this.rawUrlTree), '', this.generateNgRouterState(this.lastSuccessfulId, this.currentPageId));
  }
  generateNgRouterState(navigationId, routerPageId) {
    if (this.canceledNavigationResolution === 'computed') {
      return {
        navigationId,
        ɵrouterPageId: routerPageId
      };
    }
    return {
      navigationId
    };
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵHistoryStateManager_BaseFactory;
      return function HistoryStateManager_Factory(t) {
        return (ɵHistoryStateManager_BaseFactory || (ɵHistoryStateManager_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵgetInheritedFactory"](HistoryStateManager)))(t || HistoryStateManager);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: HistoryStateManager,
      factory: HistoryStateManager.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](HistoryStateManager, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
var NavigationResult;
(function (NavigationResult) {
  NavigationResult[NavigationResult["COMPLETE"] = 0] = "COMPLETE";
  NavigationResult[NavigationResult["FAILED"] = 1] = "FAILED";
  NavigationResult[NavigationResult["REDIRECTING"] = 2] = "REDIRECTING";
})(NavigationResult || (NavigationResult = {}));
/**
 * Performs the given action once the router finishes its next/current navigation.
 *
 * The navigation is considered complete under the following conditions:
 * - `NavigationCancel` event emits and the code is not `NavigationCancellationCode.Redirect` or
 * `NavigationCancellationCode.SupersededByNewNavigation`. In these cases, the
 * redirecting/superseding navigation must finish.
 * - `NavigationError`, `NavigationEnd`, or `NavigationSkipped` event emits
 */
function afterNextNavigation(router, action) {
  router.events.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(e => e instanceof NavigationEnd || e instanceof NavigationCancel || e instanceof NavigationError || e instanceof NavigationSkipped), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(e => {
    if (e instanceof NavigationEnd || e instanceof NavigationSkipped) {
      return NavigationResult.COMPLETE;
    }
    const redirecting = e instanceof NavigationCancel ? e.code === NavigationCancellationCode.Redirect || e.code === NavigationCancellationCode.SupersededByNewNavigation : false;
    return redirecting ? NavigationResult.REDIRECTING : NavigationResult.FAILED;
  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(result => result !== NavigationResult.REDIRECTING), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.take)(1)).subscribe(() => {
    action();
  });
}
function defaultErrorHandler(error) {
  throw error;
}
/**
 * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `true`
 * (exact = true).
 */
const exactMatchOptions = {
  paths: 'exact',
  fragment: 'ignored',
  matrixParams: 'ignored',
  queryParams: 'exact'
};
/**
 * The equivalent `IsActiveMatchOptions` options for `Router.isActive` is called with `false`
 * (exact = false).
 */
const subsetMatchOptions = {
  paths: 'subset',
  fragment: 'ignored',
  matrixParams: 'ignored',
  queryParams: 'subset'
};
/**
 * @description
 *
 * A service that provides navigation among views and URL manipulation capabilities.
 *
 * @see {@link Route}
 * @see [Routing and Navigation Guide](guide/router).
 *
 * @ngModule RouterModule
 *
 * @publicApi
 */
class Router {
  get currentUrlTree() {
    return this.stateManager.getCurrentUrlTree();
  }
  get rawUrlTree() {
    return this.stateManager.getRawUrlTree();
  }
  /**
   * An event stream for routing events.
   */
  get events() {
    // TODO(atscott): This _should_ be events.asObservable(). However, this change requires internal
    // cleanup: tests are doing `(route.events as Subject<Event>).next(...)`. This isn't
    // allowed/supported but we still have to fix these or file bugs against the teams before making
    // the change.
    return this._events;
  }
  /**
   * The current state of routing in this NgModule.
   */
  get routerState() {
    return this.stateManager.getRouterState();
  }
  constructor() {
    this.disposed = false;
    this.isNgZoneEnabled = false;
    this.console = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵConsole"]);
    this.stateManager = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(StateManager);
    this.options = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTER_CONFIGURATION, {
      optional: true
    }) || {};
    this.pendingTasks = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵPendingTasks"]);
    this.urlUpdateStrategy = this.options.urlUpdateStrategy || 'deferred';
    this.navigationTransitions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(NavigationTransitions);
    this.urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlSerializer);
    this.location = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location);
    this.urlHandlingStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlHandlingStrategy);
    /**
     * The private `Subject` type for the public events exposed in the getter. This is used internally
     * to push events to. The separate field allows us to expose separate types in the public API
     * (i.e., an Observable rather than the Subject).
     */
    this._events = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
    /**
     * A handler for navigation errors in this NgModule.
     *
     * @deprecated Subscribe to the `Router` events and watch for `NavigationError` instead.
     *   `provideRouter` has the `withNavigationErrorHandler` feature to make this easier.
     * @see {@link withNavigationErrorHandler}
     */
    this.errorHandler = this.options.errorHandler || defaultErrorHandler;
    /**
     * True if at least one navigation event has occurred,
     * false otherwise.
     */
    this.navigated = false;
    /**
     * A strategy for re-using routes.
     *
     * @deprecated Configure using `providers` instead:
     *   `{provide: RouteReuseStrategy, useClass: MyStrategy}`.
     */
    this.routeReuseStrategy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(RouteReuseStrategy);
    /**
     * How to handle a navigation request to the current URL.
     *
     *
     * @deprecated Configure this through `provideRouter` or `RouterModule.forRoot` instead.
     * @see {@link withRouterConfig}
     * @see {@link provideRouter}
     * @see {@link RouterModule}
     */
    this.onSameUrlNavigation = this.options.onSameUrlNavigation || 'ignore';
    this.config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTES, {
      optional: true
    })?.flat() ?? [];
    /**
     * Indicates whether the application has opted in to binding Router data to component inputs.
     *
     * This option is enabled by the `withComponentInputBinding` feature of `provideRouter` or
     * `bindToComponentInputs` in the `ExtraOptions` of `RouterModule.forRoot`.
     */
    this.componentInputBindingEnabled = !!(0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(INPUT_BINDER, {
      optional: true
    });
    this.eventsSubscription = new rxjs__WEBPACK_IMPORTED_MODULE_35__.Subscription();
    this.isNgZoneEnabled = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone) instanceof _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone && _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone.isInAngularZone();
    this.resetConfig(this.config);
    this.navigationTransitions.setupNavigations(this, this.currentUrlTree, this.routerState).subscribe({
      error: e => {
        this.console.warn(ngDevMode ? `Unhandled Navigation Error: ${e}` : e);
      }
    });
    this.subscribeToNavigationEvents();
  }
  subscribeToNavigationEvents() {
    const subscription = this.navigationTransitions.events.subscribe(e => {
      try {
        const currentTransition = this.navigationTransitions.currentTransition;
        const currentNavigation = this.navigationTransitions.currentNavigation;
        if (currentTransition !== null && currentNavigation !== null) {
          this.stateManager.handleRouterEvent(e, currentNavigation);
          if (e instanceof NavigationCancel && e.code !== NavigationCancellationCode.Redirect && e.code !== NavigationCancellationCode.SupersededByNewNavigation) {
            // It seems weird that `navigated` is set to `true` when the navigation is rejected,
            // however it's how things were written initially. Investigation would need to be done
            // to determine if this can be removed.
            this.navigated = true;
          } else if (e instanceof NavigationEnd) {
            this.navigated = true;
          } else if (e instanceof RedirectRequest) {
            const mergedTree = this.urlHandlingStrategy.merge(e.url, currentTransition.currentRawUrl);
            const extras = {
              // Persist transient navigation info from the original navigation request.
              info: currentTransition.extras.info,
              skipLocationChange: currentTransition.extras.skipLocationChange,
              // The URL is already updated at this point if we have 'eager' URL
              // updates or if the navigation was triggered by the browser (back
              // button, URL bar, etc). We want to replace that item in history
              // if the navigation is rejected.
              replaceUrl: this.urlUpdateStrategy === 'eager' || isBrowserTriggeredNavigation(currentTransition.source)
            };
            this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras, {
              resolve: currentTransition.resolve,
              reject: currentTransition.reject,
              promise: currentTransition.promise
            });
          }
        }
        // Note that it's important to have the Router process the events _before_ the event is
        // pushed through the public observable. This ensures the correct router state is in place
        // before applications observe the events.
        if (isPublicRouterEvent(e)) {
          this._events.next(e);
        }
      } catch (e) {
        this.navigationTransitions.transitionAbortSubject.next(e);
      }
    });
    this.eventsSubscription.add(subscription);
  }
  /** @internal */
  resetRootComponentType(rootComponentType) {
    // TODO: vsavkin router 4.0 should make the root component set to null
    // this will simplify the lifecycle of the router.
    this.routerState.root.component = rootComponentType;
    this.navigationTransitions.rootComponentType = rootComponentType;
  }
  /**
   * Sets up the location change listener and performs the initial navigation.
   */
  initialNavigation() {
    this.setUpLocationChangeListener();
    if (!this.navigationTransitions.hasRequestedNavigation) {
      this.navigateToSyncWithBrowser(this.location.path(true), IMPERATIVE_NAVIGATION, this.stateManager.restoredState());
    }
  }
  /**
   * Sets up the location change listener. This listener detects navigations triggered from outside
   * the Router (the browser back/forward buttons, for example) and schedules a corresponding Router
   * navigation so that the correct events, guards, etc. are triggered.
   */
  setUpLocationChangeListener() {
    // Don't need to use Zone.wrap any more, because zone.js
    // already patch onPopState, so location change callback will
    // run into ngZone
    this.nonRouterCurrentEntryChangeSubscription ??= this.stateManager.registerNonRouterCurrentEntryChangeListener((url, state) => {
      // The `setTimeout` was added in #12160 and is likely to support Angular/AngularJS
      // hybrid apps.
      setTimeout(() => {
        this.navigateToSyncWithBrowser(url, 'popstate', state);
      }, 0);
    });
  }
  /**
   * Schedules a router navigation to synchronize Router state with the browser state.
   *
   * This is done as a response to a popstate event and the initial navigation. These
   * two scenarios represent times when the browser URL/state has been updated and
   * the Router needs to respond to ensure its internal state matches.
   */
  navigateToSyncWithBrowser(url, source, state) {
    const extras = {
      replaceUrl: true
    };
    // TODO: restoredState should always include the entire state, regardless
    // of navigationId. This requires a breaking change to update the type on
    // NavigationStart’s restoredState, which currently requires navigationId
    // to always be present. The Router used to only restore history state if
    // a navigationId was present.
    // The stored navigationId is used by the RouterScroller to retrieve the scroll
    // position for the page.
    const restoredState = state?.navigationId ? state : null;
    // Separate to NavigationStart.restoredState, we must also restore the state to
    // history.state and generate a new navigationId, since it will be overwritten
    if (state) {
      const stateCopy = {
        ...state
      };
      delete stateCopy.navigationId;
      delete stateCopy.ɵrouterPageId;
      if (Object.keys(stateCopy).length !== 0) {
        extras.state = stateCopy;
      }
    }
    const urlTree = this.parseUrl(url);
    this.scheduleNavigation(urlTree, source, restoredState, extras);
  }
  /** The current URL. */
  get url() {
    return this.serializeUrl(this.currentUrlTree);
  }
  /**
   * Returns the current `Navigation` object when the router is navigating,
   * and `null` when idle.
   */
  getCurrentNavigation() {
    return this.navigationTransitions.currentNavigation;
  }
  /**
   * The `Navigation` object of the most recent navigation to succeed and `null` if there
   *     has not been a successful navigation yet.
   */
  get lastSuccessfulNavigation() {
    return this.navigationTransitions.lastSuccessfulNavigation;
  }
  /**
   * Resets the route configuration used for navigation and generating links.
   *
   * @param config The route array for the new configuration.
   *
   * @usageNotes
   *
   * ```
   * router.resetConfig([
   *  { path: 'team/:id', component: TeamCmp, children: [
   *    { path: 'simple', component: SimpleCmp },
   *    { path: 'user/:name', component: UserCmp }
   *  ]}
   * ]);
   * ```
   */
  resetConfig(config) {
    (typeof ngDevMode === 'undefined' || ngDevMode) && validateConfig(config);
    this.config = config.map(standardizeConfig);
    this.navigated = false;
  }
  /** @nodoc */
  ngOnDestroy() {
    this.dispose();
  }
  /** Disposes of the router. */
  dispose() {
    this.navigationTransitions.complete();
    if (this.nonRouterCurrentEntryChangeSubscription) {
      this.nonRouterCurrentEntryChangeSubscription.unsubscribe();
      this.nonRouterCurrentEntryChangeSubscription = undefined;
    }
    this.disposed = true;
    this.eventsSubscription.unsubscribe();
  }
  /**
   * Appends URL segments to the current URL tree to create a new URL tree.
   *
   * @param commands An array of URL fragments with which to construct the new URL tree.
   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
   * segments, followed by the parameters for each segment.
   * The fragments are applied to the current URL tree or the one provided  in the `relativeTo`
   * property of the options object, if supplied.
   * @param navigationExtras Options that control the navigation strategy.
   * @returns The new URL tree.
   *
   * @usageNotes
   *
   * ```
   * // create /team/33/user/11
   * router.createUrlTree(['/team', 33, 'user', 11]);
   *
   * // create /team/33;expand=true/user/11
   * router.createUrlTree(['/team', 33, {expand: true}, 'user', 11]);
   *
   * // you can collapse static segments like this (this works only with the first passed-in value):
   * router.createUrlTree(['/team/33/user', userId]);
   *
   * // If the first segment can contain slashes, and you do not want the router to split it,
   * // you can do the following:
   * router.createUrlTree([{segmentPath: '/one/two'}]);
   *
   * // create /team/33/(user/11//right:chat)
   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: 'chat'}}]);
   *
   * // remove the right secondary node
   * router.createUrlTree(['/team', 33, {outlets: {primary: 'user/11', right: null}}]);
   *
   * // assuming the current url is `/team/33/user/11` and the route points to `user/11`
   *
   * // navigate to /team/33/user/11/details
   * router.createUrlTree(['details'], {relativeTo: route});
   *
   * // navigate to /team/33/user/22
   * router.createUrlTree(['../22'], {relativeTo: route});
   *
   * // navigate to /team/44/user/22
   * router.createUrlTree(['../../team/44/user/22'], {relativeTo: route});
   *
   * Note that a value of `null` or `undefined` for `relativeTo` indicates that the
   * tree should be created relative to the root.
   * ```
   */
  createUrlTree(commands, navigationExtras = {}) {
    const {
      relativeTo,
      queryParams,
      fragment,
      queryParamsHandling,
      preserveFragment
    } = navigationExtras;
    const f = preserveFragment ? this.currentUrlTree.fragment : fragment;
    let q = null;
    switch (queryParamsHandling) {
      case 'merge':
        q = {
          ...this.currentUrlTree.queryParams,
          ...queryParams
        };
        break;
      case 'preserve':
        q = this.currentUrlTree.queryParams;
        break;
      default:
        q = queryParams || null;
    }
    if (q !== null) {
      q = this.removeEmptyProps(q);
    }
    let relativeToUrlSegmentGroup;
    try {
      const relativeToSnapshot = relativeTo ? relativeTo.snapshot : this.routerState.snapshot.root;
      relativeToUrlSegmentGroup = createSegmentGroupFromRoute(relativeToSnapshot);
    } catch (e) {
      // This is strictly for backwards compatibility with tests that create
      // invalid `ActivatedRoute` mocks.
      // Note: the difference between having this fallback for invalid `ActivatedRoute` setups and
      // just throwing is ~500 test failures. Fixing all of those tests by hand is not feasible at
      // the moment.
      if (typeof commands[0] !== 'string' || !commands[0].startsWith('/')) {
        // Navigations that were absolute in the old way of creating UrlTrees
        // would still work because they wouldn't attempt to match the
        // segments in the `ActivatedRoute` to the `currentUrlTree` but
        // instead just replace the root segment with the navigation result.
        // Non-absolute navigations would fail to apply the commands because
        // the logic could not find the segment to replace (so they'd act like there were no
        // commands).
        commands = [];
      }
      relativeToUrlSegmentGroup = this.currentUrlTree.root;
    }
    return createUrlTreeFromSegmentGroup(relativeToUrlSegmentGroup, commands, q, f ?? null);
  }
  /**
   * Navigates to a view using an absolute route path.
   *
   * @param url An absolute path for a defined route. The function does not apply any delta to the
   *     current URL.
   * @param extras An object containing properties that modify the navigation strategy.
   *
   * @returns A Promise that resolves to 'true' when navigation succeeds,
   * to 'false' when navigation fails, or is rejected on error.
   *
   * @usageNotes
   *
   * The following calls request navigation to an absolute path.
   *
   * ```
   * router.navigateByUrl("/team/33/user/11");
   *
   * // Navigate without updating the URL
   * router.navigateByUrl("/team/33/user/11", { skipLocationChange: true });
   * ```
   *
   * @see [Routing and Navigation guide](guide/router)
   *
   */
  navigateByUrl(url, extras = {
    skipLocationChange: false
  }) {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (this.isNgZoneEnabled && !_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone.isInAngularZone()) {
        this.console.warn(`Navigation triggered outside Angular zone, did you forget to call 'ngZone.run()'?`);
      }
    }
    const urlTree = isUrlTree(url) ? url : this.parseUrl(url);
    const mergedTree = this.urlHandlingStrategy.merge(urlTree, this.rawUrlTree);
    return this.scheduleNavigation(mergedTree, IMPERATIVE_NAVIGATION, null, extras);
  }
  /**
   * Navigate based on the provided array of commands and a starting point.
   * If no starting route is provided, the navigation is absolute.
   *
   * @param commands An array of URL fragments with which to construct the target URL.
   * If the path is static, can be the literal URL string. For a dynamic path, pass an array of path
   * segments, followed by the parameters for each segment.
   * The fragments are applied to the current URL or the one provided  in the `relativeTo` property
   * of the options object, if supplied.
   * @param extras An options object that determines how the URL should be constructed or
   *     interpreted.
   *
   * @returns A Promise that resolves to `true` when navigation succeeds, or `false` when navigation
   *     fails. The Promise is rejected when an error occurs if `resolveNavigationPromiseOnError` is
   * not `true`.
   *
   * @usageNotes
   *
   * The following calls request navigation to a dynamic route path relative to the current URL.
   *
   * ```
   * router.navigate(['team', 33, 'user', 11], {relativeTo: route});
   *
   * // Navigate without updating the URL, overriding the default behavior
   * router.navigate(['team', 33, 'user', 11], {relativeTo: route, skipLocationChange: true});
   * ```
   *
   * @see [Routing and Navigation guide](guide/router)
   *
   */
  navigate(commands, extras = {
    skipLocationChange: false
  }) {
    validateCommands(commands);
    return this.navigateByUrl(this.createUrlTree(commands, extras), extras);
  }
  /** Serializes a `UrlTree` into a string */
  serializeUrl(url) {
    return this.urlSerializer.serialize(url);
  }
  /** Parses a string into a `UrlTree` */
  parseUrl(url) {
    try {
      return this.urlSerializer.parse(url);
    } catch {
      return this.urlSerializer.parse('/');
    }
  }
  isActive(url, matchOptions) {
    let options;
    if (matchOptions === true) {
      options = {
        ...exactMatchOptions
      };
    } else if (matchOptions === false) {
      options = {
        ...subsetMatchOptions
      };
    } else {
      options = matchOptions;
    }
    if (isUrlTree(url)) {
      return containsTree(this.currentUrlTree, url, options);
    }
    const urlTree = this.parseUrl(url);
    return containsTree(this.currentUrlTree, urlTree, options);
  }
  removeEmptyProps(params) {
    return Object.entries(params).reduce((result, [key, value]) => {
      if (value !== null && value !== undefined) {
        result[key] = value;
      }
      return result;
    }, {});
  }
  scheduleNavigation(rawUrl, source, restoredState, extras, priorPromise) {
    if (this.disposed) {
      return Promise.resolve(false);
    }
    let resolve;
    let reject;
    let promise;
    if (priorPromise) {
      resolve = priorPromise.resolve;
      reject = priorPromise.reject;
      promise = priorPromise.promise;
    } else {
      promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
      });
    }
    // Indicate that the navigation is happening.
    const taskId = this.pendingTasks.add();
    afterNextNavigation(this, () => {
      // Remove pending task in a microtask to allow for cancelled
      // initial navigations and redirects within the same task.
      queueMicrotask(() => this.pendingTasks.remove(taskId));
    });
    this.navigationTransitions.handleNavigationRequest({
      source,
      restoredState,
      currentUrlTree: this.currentUrlTree,
      currentRawUrl: this.currentUrlTree,
      rawUrl,
      extras,
      resolve,
      reject,
      promise,
      currentSnapshot: this.routerState.snapshot,
      currentRouterState: this.routerState
    });
    // Make sure that the error is propagated even though `processNavigations` catch
    // handler does not rethrow
    return promise.catch(e => {
      return Promise.reject(e);
    });
  }
  static {
    this.ɵfac = function Router_Factory(t) {
      return new (t || Router)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: Router,
      factory: Router.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](Router, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();
function validateCommands(commands) {
  for (let i = 0; i < commands.length; i++) {
    const cmd = commands[i];
    if (cmd == null) {
      throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4008 /* RuntimeErrorCode.NULLISH_COMMAND */, (typeof ngDevMode === 'undefined' || ngDevMode) && `The requested path contains ${cmd} segment at index ${i}`);
    }
  }
}
function isPublicRouterEvent(e) {
  return !(e instanceof BeforeActivateRoutes) && !(e instanceof RedirectRequest);
}

/**
 * @description
 *
 * When applied to an element in a template, makes that element a link
 * that initiates navigation to a route. Navigation opens one or more routed components
 * in one or more `<router-outlet>` locations on the page.
 *
 * Given a route configuration `[{ path: 'user/:name', component: UserCmp }]`,
 * the following creates a static link to the route:
 * `<a routerLink="/user/bob">link to user component</a>`
 *
 * You can use dynamic values to generate the link.
 * For a dynamic link, pass an array of path segments,
 * followed by the params for each segment.
 * For example, `['/team', teamId, 'user', userName, {details: true}]`
 * generates a link to `/team/11/user/bob;details=true`.
 *
 * Multiple static segments can be merged into one term and combined with dynamic segments.
 * For example, `['/team/11/user', userName, {details: true}]`
 *
 * The input that you provide to the link is treated as a delta to the current URL.
 * For instance, suppose the current URL is `/user/(box//aux:team)`.
 * The link `<a [routerLink]="['/user/jim']">Jim</a>` creates the URL
 * `/user/(jim//aux:team)`.
 * See {@link Router#createUrlTree} for more information.
 *
 * @usageNotes
 *
 * You can use absolute or relative paths in a link, set query parameters,
 * control how parameters are handled, and keep a history of navigation states.
 *
 * ### Relative link paths
 *
 * The first segment name can be prepended with `/`, `./`, or `../`.
 * * If the first segment begins with `/`, the router looks up the route from the root of the
 *   app.
 * * If the first segment begins with `./`, or doesn't begin with a slash, the router
 *   looks in the children of the current activated route.
 * * If the first segment begins with `../`, the router goes up one level in the route tree.
 *
 * ### Setting and handling query params and fragments
 *
 * The following link adds a query parameter and a fragment to the generated URL:
 *
 * ```
 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" fragment="education">
 *   link to user component
 * </a>
 * ```
 * By default, the directive constructs the new URL using the given query parameters.
 * The example generates the link: `/user/bob?debug=true#education`.
 *
 * You can instruct the directive to handle query parameters differently
 * by specifying the `queryParamsHandling` option in the link.
 * Allowed values are:
 *
 *  - `'merge'`: Merge the given `queryParams` into the current query params.
 *  - `'preserve'`: Preserve the current query params.
 *
 * For example:
 *
 * ```
 * <a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge">
 *   link to user component
 * </a>
 * ```
 *
 * See {@link UrlCreationOptions#queryParamsHandling}.
 *
 * ### Preserving navigation history
 *
 * You can provide a `state` value to be persisted to the browser's
 * [`History.state` property](https://developer.mozilla.org/en-US/docs/Web/API/History#Properties).
 * For example:
 *
 * ```
 * <a [routerLink]="['/user/bob']" [state]="{tracingId: 123}">
 *   link to user component
 * </a>
 * ```
 *
 * Use {@link Router#getCurrentNavigation} to retrieve a saved
 * navigation-state value. For example, to capture the `tracingId` during the `NavigationStart`
 * event:
 *
 * ```
 * // Get NavigationStart events
 * router.events.pipe(filter(e => e instanceof NavigationStart)).subscribe(e => {
 *   const navigation = router.getCurrentNavigation();
 *   tracingService.trace({id: navigation.extras.state.tracingId});
 * });
 * ```
 *
 * @ngModule RouterModule
 *
 * @publicApi
 */
class RouterLink {
  constructor(router, route, tabIndexAttribute, renderer, el, locationStrategy) {
    this.router = router;
    this.route = route;
    this.tabIndexAttribute = tabIndexAttribute;
    this.renderer = renderer;
    this.el = el;
    this.locationStrategy = locationStrategy;
    /**
     * Represents an `href` attribute value applied to a host element,
     * when a host element is `<a>`. For other tags, the value is `null`.
     */
    this.href = null;
    this.commands = null;
    /** @internal */
    this.onChanges = new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
    /**
     * Passed to {@link Router#createUrlTree} as part of the
     * `UrlCreationOptions`.
     * @see {@link UrlCreationOptions#preserveFragment}
     * @see {@link Router#createUrlTree}
     */
    this.preserveFragment = false;
    /**
     * Passed to {@link Router#navigateByUrl} as part of the
     * `NavigationBehaviorOptions`.
     * @see {@link NavigationBehaviorOptions#skipLocationChange}
     * @see {@link Router#navigateByUrl}
     */
    this.skipLocationChange = false;
    /**
     * Passed to {@link Router#navigateByUrl} as part of the
     * `NavigationBehaviorOptions`.
     * @see {@link NavigationBehaviorOptions#replaceUrl}
     * @see {@link Router#navigateByUrl}
     */
    this.replaceUrl = false;
    const tagName = el.nativeElement.tagName?.toLowerCase();
    this.isAnchorElement = tagName === 'a' || tagName === 'area';
    if (this.isAnchorElement) {
      this.subscription = router.events.subscribe(s => {
        if (s instanceof NavigationEnd) {
          this.updateHref();
        }
      });
    } else {
      this.setTabIndexIfNotOnNativeEl('0');
    }
  }
  /**
   * Modifies the tab index if there was not a tabindex attribute on the element during
   * instantiation.
   */
  setTabIndexIfNotOnNativeEl(newTabIndex) {
    if (this.tabIndexAttribute != null /* both `null` and `undefined` */ || this.isAnchorElement) {
      return;
    }
    this.applyAttributeValue('tabindex', newTabIndex);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    if (this.isAnchorElement) {
      this.updateHref();
    }
    // This is subscribed to by `RouterLinkActive` so that it knows to update when there are changes
    // to the RouterLinks it's tracking.
    this.onChanges.next(this);
  }
  /**
   * Commands to pass to {@link Router#createUrlTree}.
   *   - **array**: commands to pass to {@link Router#createUrlTree}.
   *   - **string**: shorthand for array of commands with just the string, i.e. `['/route']`
   *   - **null|undefined**: effectively disables the `routerLink`
   * @see {@link Router#createUrlTree}
   */
  set routerLink(commands) {
    if (commands != null) {
      this.commands = Array.isArray(commands) ? commands : [commands];
      this.setTabIndexIfNotOnNativeEl('0');
    } else {
      this.commands = null;
      this.setTabIndexIfNotOnNativeEl(null);
    }
  }
  /** @nodoc */
  onClick(button, ctrlKey, shiftKey, altKey, metaKey) {
    const urlTree = this.urlTree;
    if (urlTree === null) {
      return true;
    }
    if (this.isAnchorElement) {
      if (button !== 0 || ctrlKey || shiftKey || altKey || metaKey) {
        return true;
      }
      if (typeof this.target === 'string' && this.target != '_self') {
        return true;
      }
    }
    const extras = {
      skipLocationChange: this.skipLocationChange,
      replaceUrl: this.replaceUrl,
      state: this.state,
      info: this.info
    };
    this.router.navigateByUrl(urlTree, extras);
    // Return `false` for `<a>` elements to prevent default action
    // and cancel the native behavior, since the navigation is handled
    // by the Router.
    return !this.isAnchorElement;
  }
  /** @nodoc */
  ngOnDestroy() {
    this.subscription?.unsubscribe();
  }
  updateHref() {
    const urlTree = this.urlTree;
    this.href = urlTree !== null && this.locationStrategy ? this.locationStrategy?.prepareExternalUrl(this.router.serializeUrl(urlTree)) : null;
    const sanitizedValue = this.href === null ? null :
    // This class represents a directive that can be added to both `<a>` elements,
    // as well as other elements. As a result, we can't define security context at
    // compile time. So the security context is deferred to runtime.
    // The `ɵɵsanitizeUrlOrResourceUrl` selects the necessary sanitizer function
    // based on the tag and property names. The logic mimics the one from
    // `packages/compiler/src/schema/dom_security_schema.ts`, which is used at compile time.
    //
    // Note: we should investigate whether we can switch to using `@HostBinding('attr.href')`
    // instead of applying a value via a renderer, after a final merge of the
    // `RouterLinkWithHref` directive.
    (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵsanitizeUrlOrResourceUrl"])(this.href, this.el.nativeElement.tagName.toLowerCase(), 'href');
    this.applyAttributeValue('href', sanitizedValue);
  }
  applyAttributeValue(attrName, attrValue) {
    const renderer = this.renderer;
    const nativeElement = this.el.nativeElement;
    if (attrValue !== null) {
      renderer.setAttribute(nativeElement, attrName, attrValue);
    } else {
      renderer.removeAttribute(nativeElement, attrName);
    }
  }
  get urlTree() {
    if (this.commands === null) {
      return null;
    }
    return this.router.createUrlTree(this.commands, {
      // If the `relativeTo` input is not defined, we want to use `this.route` by default.
      // Otherwise, we should use the value provided by the user in the input.
      relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route,
      queryParams: this.queryParams,
      fragment: this.fragment,
      queryParamsHandling: this.queryParamsHandling,
      preserveFragment: this.preserveFragment
    });
  }
  static {
    this.ɵfac = function RouterLink_Factory(t) {
      return new (t || RouterLink)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](ActivatedRoute), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinjectAttribute"]('tabindex'), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineDirective"]({
      type: RouterLink,
      selectors: [["", "routerLink", ""]],
      hostVars: 1,
      hostBindings: function RouterLink_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵlistener"]("click", function RouterLink_click_HostBindingHandler($event) {
            return ctx.onClick($event.button, $event.ctrlKey, $event.shiftKey, $event.altKey, $event.metaKey);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵattribute"]("target", ctx.target);
        }
      },
      inputs: {
        target: "target",
        queryParams: "queryParams",
        fragment: "fragment",
        queryParamsHandling: "queryParamsHandling",
        state: "state",
        info: "info",
        relativeTo: "relativeTo",
        preserveFragment: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵInputFlags"].HasDecoratorInputTransform, "preserveFragment", "preserveFragment", _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute],
        skipLocationChange: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵInputFlags"].HasDecoratorInputTransform, "skipLocationChange", "skipLocationChange", _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute],
        replaceUrl: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵInputFlags"].HasDecoratorInputTransform, "replaceUrl", "replaceUrl", _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute],
        routerLink: "routerLink"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵInputTransformsFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterLink, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Directive,
    args: [{
      selector: '[routerLink]',
      standalone: true
    }]
  }], () => [{
    type: Router
  }, {
    type: ActivatedRoute
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Attribute,
      args: ['tabindex']
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef
  }, {
    type: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy
  }], {
    target: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.HostBinding,
      args: ['attr.target']
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    queryParams: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    fragment: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    queryParamsHandling: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    state: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    info: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    relativeTo: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    preserveFragment: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute
      }]
    }],
    skipLocationChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute
      }]
    }],
    replaceUrl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input,
      args: [{
        transform: _angular_core__WEBPACK_IMPORTED_MODULE_2__.booleanAttribute
      }]
    }],
    routerLink: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    onClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.HostListener,
      args: ['click', ['$event.button', '$event.ctrlKey', '$event.shiftKey', '$event.altKey', '$event.metaKey']]
    }]
  });
})();

/**
 *
 * @description
 *
 * Tracks whether the linked route of an element is currently active, and allows you
 * to specify one or more CSS classes to add to the element when the linked route
 * is active.
 *
 * Use this directive to create a visual distinction for elements associated with an active route.
 * For example, the following code highlights the word "Bob" when the router
 * activates the associated route:
 *
 * ```
 * <a routerLink="/user/bob" routerLinkActive="active-link">Bob</a>
 * ```
 *
 * Whenever the URL is either '/user' or '/user/bob', the "active-link" class is
 * added to the anchor tag. If the URL changes, the class is removed.
 *
 * You can set more than one class using a space-separated string or an array.
 * For example:
 *
 * ```
 * <a routerLink="/user/bob" routerLinkActive="class1 class2">Bob</a>
 * <a routerLink="/user/bob" [routerLinkActive]="['class1', 'class2']">Bob</a>
 * ```
 *
 * To add the classes only when the URL matches the link exactly, add the option `exact: true`:
 *
 * ```
 * <a routerLink="/user/bob" routerLinkActive="active-link" [routerLinkActiveOptions]="{exact:
 * true}">Bob</a>
 * ```
 *
 * To directly check the `isActive` status of the link, assign the `RouterLinkActive`
 * instance to a template variable.
 * For example, the following checks the status without assigning any CSS classes:
 *
 * ```
 * <a routerLink="/user/bob" routerLinkActive #rla="routerLinkActive">
 *   Bob {{ rla.isActive ? '(already open)' : ''}}
 * </a>
 * ```
 *
 * You can apply the `RouterLinkActive` directive to an ancestor of linked elements.
 * For example, the following sets the active-link class on the `<div>`  parent tag
 * when the URL is either '/user/jim' or '/user/bob'.
 *
 * ```
 * <div routerLinkActive="active-link" [routerLinkActiveOptions]="{exact: true}">
 *   <a routerLink="/user/jim">Jim</a>
 *   <a routerLink="/user/bob">Bob</a>
 * </div>
 * ```
 *
 * The `RouterLinkActive` directive can also be used to set the aria-current attribute
 * to provide an alternative distinction for active elements to visually impaired users.
 *
 * For example, the following code adds the 'active' class to the Home Page link when it is
 * indeed active and in such case also sets its aria-current attribute to 'page':
 *
 * ```
 * <a routerLink="/" routerLinkActive="active" ariaCurrentWhenActive="page">Home Page</a>
 * ```
 *
 * @ngModule RouterModule
 *
 * @publicApi
 */
class RouterLinkActive {
  get isActive() {
    return this._isActive;
  }
  constructor(router, element, renderer, cdr, link) {
    this.router = router;
    this.element = element;
    this.renderer = renderer;
    this.cdr = cdr;
    this.link = link;
    this.classes = [];
    this._isActive = false;
    /**
     * Options to configure how to determine if the router link is active.
     *
     * These options are passed to the `Router.isActive()` function.
     *
     * @see {@link Router#isActive}
     */
    this.routerLinkActiveOptions = {
      exact: false
    };
    /**
     *
     * You can use the output `isActiveChange` to get notified each time the link becomes
     * active or inactive.
     *
     * Emits:
     * true  -> Route is active
     * false -> Route is inactive
     *
     * ```
     * <a
     *  routerLink="/user/bob"
     *  routerLinkActive="active-link"
     *  (isActiveChange)="this.onRouterLinkActive($event)">Bob</a>
     * ```
     */
    this.isActiveChange = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    this.routerEventsSubscription = router.events.subscribe(s => {
      if (s instanceof NavigationEnd) {
        this.update();
      }
    });
  }
  /** @nodoc */
  ngAfterContentInit() {
    // `of(null)` is used to force subscribe body to execute once immediately (like `startWith`).
    (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(this.links.changes, (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(null)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_36__.mergeAll)()).subscribe(_ => {
      this.update();
      this.subscribeToEachLinkOnChanges();
    });
  }
  subscribeToEachLinkOnChanges() {
    this.linkInputChangesSubscription?.unsubscribe();
    const allLinkChanges = [...this.links.toArray(), this.link].filter(link => !!link).map(link => link.onChanges);
    this.linkInputChangesSubscription = (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(allLinkChanges).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_36__.mergeAll)()).subscribe(link => {
      if (this._isActive !== this.isLinkActive(this.router)(link)) {
        this.update();
      }
    });
  }
  set routerLinkActive(data) {
    const classes = Array.isArray(data) ? data : data.split(' ');
    this.classes = classes.filter(c => !!c);
  }
  /** @nodoc */
  ngOnChanges(changes) {
    this.update();
  }
  /** @nodoc */
  ngOnDestroy() {
    this.routerEventsSubscription.unsubscribe();
    this.linkInputChangesSubscription?.unsubscribe();
  }
  update() {
    if (!this.links || !this.router.navigated) return;
    queueMicrotask(() => {
      const hasActiveLinks = this.hasActiveLinks();
      this.classes.forEach(c => {
        if (hasActiveLinks) {
          this.renderer.addClass(this.element.nativeElement, c);
        } else {
          this.renderer.removeClass(this.element.nativeElement, c);
        }
      });
      if (hasActiveLinks && this.ariaCurrentWhenActive !== undefined) {
        this.renderer.setAttribute(this.element.nativeElement, 'aria-current', this.ariaCurrentWhenActive.toString());
      } else {
        this.renderer.removeAttribute(this.element.nativeElement, 'aria-current');
      }
      // Only emit change if the active state changed.
      if (this._isActive !== hasActiveLinks) {
        this._isActive = hasActiveLinks;
        this.cdr.markForCheck();
        // Emit on isActiveChange after classes are updated
        this.isActiveChange.emit(hasActiveLinks);
      }
    });
  }
  isLinkActive(router) {
    const options = isActiveMatchOptions(this.routerLinkActiveOptions) ? this.routerLinkActiveOptions :
    // While the types should disallow `undefined` here, it's possible without strict inputs
    this.routerLinkActiveOptions.exact || false;
    return link => {
      const urlTree = link.urlTree;
      return urlTree ? router.isActive(urlTree, options) : false;
    };
  }
  hasActiveLinks() {
    const isActiveCheckFn = this.isLinkActive(this.router);
    return this.link && isActiveCheckFn(this.link) || this.links.some(isActiveCheckFn);
  }
  static {
    this.ɵfac = function RouterLinkActive_Factory(t) {
      return new (t || RouterLinkActive)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](RouterLink, 8));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineDirective"]({
      type: RouterLinkActive,
      selectors: [["", "routerLinkActive", ""]],
      contentQueries: function RouterLinkActive_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵcontentQuery"](dirIndex, RouterLink, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵloadQuery"]()) && (ctx.links = _t);
        }
      },
      inputs: {
        routerLinkActiveOptions: "routerLinkActiveOptions",
        ariaCurrentWhenActive: "ariaCurrentWhenActive",
        routerLinkActive: "routerLinkActive"
      },
      outputs: {
        isActiveChange: "isActiveChange"
      },
      exportAs: ["routerLinkActive"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterLinkActive, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Directive,
    args: [{
      selector: '[routerLinkActive]',
      exportAs: 'routerLinkActive',
      standalone: true
    }]
  }], () => [{
    type: Router
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ChangeDetectorRef
  }, {
    type: RouterLink,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Optional
    }]
  }], {
    links: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ContentChildren,
      args: [RouterLink, {
        descendants: true
      }]
    }],
    routerLinkActiveOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    ariaCurrentWhenActive: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    isActiveChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }],
    routerLinkActive: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }]
  });
})();
/**
 * Use instead of `'paths' in options` to be compatible with property renaming
 */
function isActiveMatchOptions(options) {
  return !!options.paths;
}

/**
 * @description
 *
 * Provides a preloading strategy.
 *
 * @publicApi
 */
class PreloadingStrategy {}
/**
 * @description
 *
 * Provides a preloading strategy that preloads all modules as quickly as possible.
 *
 * ```
 * RouterModule.forRoot(ROUTES, {preloadingStrategy: PreloadAllModules})
 * ```
 *
 * @publicApi
 */
class PreloadAllModules {
  preload(route, fn) {
    return fn().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.catchError)(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(null)));
  }
  static {
    this.ɵfac = function PreloadAllModules_Factory(t) {
      return new (t || PreloadAllModules)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: PreloadAllModules,
      factory: PreloadAllModules.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](PreloadAllModules, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * @description
 *
 * Provides a preloading strategy that does not preload any modules.
 *
 * This strategy is enabled by default.
 *
 * @publicApi
 */
class NoPreloading {
  preload(route, fn) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(null);
  }
  static {
    this.ɵfac = function NoPreloading_Factory(t) {
      return new (t || NoPreloading)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: NoPreloading,
      factory: NoPreloading.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](NoPreloading, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
/**
 * The preloader optimistically loads all router configurations to
 * make navigations into lazily-loaded sections of the application faster.
 *
 * The preloader runs in the background. When the router bootstraps, the preloader
 * starts listening to all navigation events. After every such event, the preloader
 * will check if any configurations can be loaded lazily.
 *
 * If a route is protected by `canLoad` guards, the preloaded will not load it.
 *
 * @publicApi
 */
class RouterPreloader {
  constructor(router, compiler, injector, preloadingStrategy, loader) {
    this.router = router;
    this.injector = injector;
    this.preloadingStrategy = preloadingStrategy;
    this.loader = loader;
  }
  setUpPreloading() {
    this.subscription = this.router.events.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(e => e instanceof NavigationEnd), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap)(() => this.preload())).subscribe(() => {});
  }
  preload() {
    return this.processRoutes(this.injector, this.router.config);
  }
  /** @nodoc */
  ngOnDestroy() {
    if (this.subscription) {
      this.subscription.unsubscribe();
    }
  }
  processRoutes(injector, routes) {
    const res = [];
    for (const route of routes) {
      if (route.providers && !route._injector) {
        route._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.createEnvironmentInjector)(route.providers, injector, `Route: ${route.path}`);
      }
      const injectorForCurrentRoute = route._injector ?? injector;
      const injectorForChildren = route._loadedInjector ?? injectorForCurrentRoute;
      // Note that `canLoad` is only checked as a condition that prevents `loadChildren` and not
      // `loadComponent`. `canLoad` guards only block loading of child routes by design. This
      // happens as a consequence of needing to descend into children for route matching immediately
      // while component loading is deferred until route activation. Because `canLoad` guards can
      // have side effects, we cannot execute them here so we instead skip preloading altogether
      // when present. Lastly, it remains to be decided whether `canLoad` should behave this way
      // at all. Code splitting and lazy loading is separate from client-side authorization checks
      // and should not be used as a security measure to prevent loading of code.
      if (route.loadChildren && !route._loadedRoutes && route.canLoad === undefined || route.loadComponent && !route._loadedComponent) {
        res.push(this.preloadConfig(injectorForCurrentRoute, route));
      }
      if (route.children || route._loadedRoutes) {
        res.push(this.processRoutes(injectorForChildren, route.children ?? route._loadedRoutes));
      }
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)(res).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_36__.mergeAll)());
  }
  preloadConfig(injector, route) {
    return this.preloadingStrategy.preload(route, () => {
      let loadedChildren$;
      if (route.loadChildren && route.canLoad === undefined) {
        loadedChildren$ = this.loader.loadChildren(injector, route);
      } else {
        loadedChildren$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(null);
      }
      const recursiveLoadChildren$ = loadedChildren$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.mergeMap)(config => {
        if (config === null) {
          return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(void 0);
        }
        route._loadedRoutes = config.routes;
        route._loadedInjector = config.injector;
        // If the loaded config was a module, use that as the module/module injector going
        // forward. Otherwise, continue using the current module/module injector.
        return this.processRoutes(config.injector ?? injector, config.routes);
      }));
      if (route.loadComponent && !route._loadedComponent) {
        const loadComponent$ = this.loader.loadComponent(route);
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.from)([recursiveLoadChildren$, loadComponent$]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_36__.mergeAll)());
      } else {
        return recursiveLoadChildren$;
      }
    });
  }
  static {
    this.ɵfac = function RouterPreloader_Factory(t) {
      return new (t || RouterPreloader)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](Router), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.Compiler), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](PreloadingStrategy), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](RouterConfigLoader));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: RouterPreloader,
      factory: RouterPreloader.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterPreloader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: Router
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Compiler
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector
  }, {
    type: PreloadingStrategy
  }, {
    type: RouterConfigLoader
  }], null);
})();
const ROUTER_SCROLLER = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken('');
class RouterScroller {
  /** @nodoc */
  constructor(urlSerializer, transitions, viewportScroller, zone, options = {}) {
    this.urlSerializer = urlSerializer;
    this.transitions = transitions;
    this.viewportScroller = viewportScroller;
    this.zone = zone;
    this.options = options;
    this.lastId = 0;
    this.lastSource = 'imperative';
    this.restoredId = 0;
    this.store = {};
    this.environmentInjector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector);
    // Default both options to 'disabled'
    options.scrollPositionRestoration ||= 'disabled';
    options.anchorScrolling ||= 'disabled';
  }
  init() {
    // we want to disable the automatic scrolling because having two places
    // responsible for scrolling results race conditions, especially given
    // that browser don't implement this behavior consistently
    if (this.options.scrollPositionRestoration !== 'disabled') {
      this.viewportScroller.setHistoryScrollRestoration('manual');
    }
    this.routerEventsSubscription = this.createScrollEvents();
    this.scrollEventsSubscription = this.consumeScrollEvents();
  }
  createScrollEvents() {
    return this.transitions.events.subscribe(e => {
      if (e instanceof NavigationStart) {
        // store the scroll position of the current stable navigations.
        this.store[this.lastId] = this.viewportScroller.getScrollPosition();
        this.lastSource = e.navigationTrigger;
        this.restoredId = e.restoredState ? e.restoredState.navigationId : 0;
      } else if (e instanceof NavigationEnd) {
        this.lastId = e.id;
        this.scheduleScrollEvent(e, this.urlSerializer.parse(e.urlAfterRedirects).fragment);
      } else if (e instanceof NavigationSkipped && e.code === NavigationSkippedCode.IgnoredSameUrlNavigation) {
        this.lastSource = undefined;
        this.restoredId = 0;
        this.scheduleScrollEvent(e, this.urlSerializer.parse(e.url).fragment);
      }
    });
  }
  consumeScrollEvents() {
    return this.transitions.events.subscribe(e => {
      if (!(e instanceof Scroll)) return;
      // a popstate event. The pop state event will always ignore anchor scrolling.
      if (e.position) {
        if (this.options.scrollPositionRestoration === 'top') {
          this.viewportScroller.scrollToPosition([0, 0]);
        } else if (this.options.scrollPositionRestoration === 'enabled') {
          this.viewportScroller.scrollToPosition(e.position);
        }
        // imperative navigation "forward"
      } else {
        if (e.anchor && this.options.anchorScrolling === 'enabled') {
          this.viewportScroller.scrollToAnchor(e.anchor);
        } else if (this.options.scrollPositionRestoration !== 'disabled') {
          this.viewportScroller.scrollToPosition([0, 0]);
        }
      }
    });
  }
  scheduleScrollEvent(routerEvent, anchor) {
    var _this = this;
    this.zone.runOutsideAngular(/*#__PURE__*/(0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      // The scroll event needs to be delayed until after change detection. Otherwise we may
      // attempt to restore the scroll position before the router outlet has fully rendered the
      // component by executing its update block of the template function.
      yield new Promise(resolve => {
        // TODO(atscott): Attempt to remove the setTimeout in a future PR.
        setTimeout(() => {
          resolve();
        });
        (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.afterNextRender)(() => {
          resolve();
        }, {
          injector: _this.environmentInjector
        });
      });
      _this.zone.run(() => {
        _this.transitions.events.next(new Scroll(routerEvent, _this.lastSource === 'popstate' ? _this.store[_this.restoredId] : null, anchor));
      });
    }));
  }
  /** @nodoc */
  ngOnDestroy() {
    this.routerEventsSubscription?.unsubscribe();
    this.scrollEventsSubscription?.unsubscribe();
  }
  static {
    this.ɵfac = function RouterScroller_Factory(t) {
      _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinvalidFactory"]();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjectable"]({
      token: RouterScroller,
      factory: RouterScroller.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterScroller, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Injectable
  }], () => [{
    type: UrlSerializer
  }, {
    type: NavigationTransitions
  }, {
    type: _angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone
  }, {
    type: undefined
  }], null);
})();

/**
 * Sets up providers necessary to enable `Router` functionality for the application.
 * Allows to configure a set of routes as well as extra features that should be enabled.
 *
 * @usageNotes
 *
 * Basic example of how you can add a Router to your application:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent, {
 *   providers: [provideRouter(appRoutes)]
 * });
 * ```
 *
 * You can also enable optional features in the Router by adding functions from the `RouterFeatures`
 * type:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes,
 *         withDebugTracing(),
 *         withRouterConfig({paramsInheritanceStrategy: 'always'}))
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link RouterFeatures}
 *
 * @publicApi
 * @param routes A set of `Route`s to use for the application routing table.
 * @param features Optional features to configure additional router behaviors.
 * @returns A set of providers to setup a Router.
 */
function provideRouter(routes, ...features) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.makeEnvironmentProviders)([{
    provide: ROUTES,
    multi: true,
    useValue: routes
  }, typeof ngDevMode === 'undefined' || ngDevMode ? {
    provide: ROUTER_IS_PROVIDED,
    useValue: true
  } : [], {
    provide: ActivatedRoute,
    useFactory: rootRoute,
    deps: [Router]
  }, {
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.APP_BOOTSTRAP_LISTENER,
    multi: true,
    useFactory: getBootstrapListener
  }, features.map(feature => feature.ɵproviders)]);
}
function rootRoute(router) {
  return router.routerState.root;
}
/**
 * Helper function to create an object that represents a Router feature.
 */
function routerFeature(kind, providers) {
  return {
    ɵkind: kind,
    ɵproviders: providers
  };
}
/**
 * An Injection token used to indicate whether `provideRouter` or `RouterModule.forRoot` was ever
 * called.
 */
const ROUTER_IS_PROVIDED = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken('', {
  providedIn: 'root',
  factory: () => false
});
const routerIsProvidedDevModeCheck = {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ENVIRONMENT_INITIALIZER,
  multi: true,
  useFactory() {
    return () => {
      if (!(0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTER_IS_PROVIDED)) {
        console.warn('`provideRoutes` was called without `provideRouter` or `RouterModule.forRoot`. ' + 'This is likely a mistake.');
      }
    };
  }
};
/**
 * Registers a [DI provider](guide/glossary#provider) for a set of routes.
 * @param routes The route configuration to provide.
 *
 * @usageNotes
 *
 * ```
 * @NgModule({
 *   providers: [provideRoutes(ROUTES)]
 * })
 * class LazyLoadedChildModule {}
 * ```
 *
 * @deprecated If necessary, provide routes using the `ROUTES` `InjectionToken`.
 * @see {@link ROUTES}
 * @publicApi
 */
function provideRoutes(routes) {
  return [{
    provide: ROUTES,
    multi: true,
    useValue: routes
  }, typeof ngDevMode === 'undefined' || ngDevMode ? routerIsProvidedDevModeCheck : []];
}
/**
 * Enables customizable scrolling behavior for router navigations.
 *
 * @usageNotes
 *
 * Basic example of how you can enable scrolling feature:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withInMemoryScrolling())
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 * @see {@link ViewportScroller}
 *
 * @publicApi
 * @param options Set of configuration parameters to customize scrolling behavior, see
 *     `InMemoryScrollingOptions` for additional information.
 * @returns A set of providers for use with `provideRouter`.
 */
function withInMemoryScrolling(options = {}) {
  const providers = [{
    provide: ROUTER_SCROLLER,
    useFactory: () => {
      const viewportScroller = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller);
      const zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone);
      const transitions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(NavigationTransitions);
      const urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlSerializer);
      return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, options);
    }
  }];
  return routerFeature(4 /* RouterFeatureKind.InMemoryScrollingFeature */, providers);
}
function getBootstrapListener() {
  const injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.Injector);
  return bootstrappedComponentRef => {
    const ref = injector.get(_angular_core__WEBPACK_IMPORTED_MODULE_2__.ApplicationRef);
    if (bootstrappedComponentRef !== ref.components[0]) {
      return;
    }
    const router = injector.get(Router);
    const bootstrapDone = injector.get(BOOTSTRAP_DONE);
    if (injector.get(INITIAL_NAVIGATION) === 1 /* InitialNavigation.EnabledNonBlocking */) {
      router.initialNavigation();
    }
    injector.get(ROUTER_PRELOADER, null, _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectFlags.Optional)?.setUpPreloading();
    injector.get(ROUTER_SCROLLER, null, _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectFlags.Optional)?.init();
    router.resetRootComponentType(ref.componentTypes[0]);
    if (!bootstrapDone.closed) {
      bootstrapDone.next();
      bootstrapDone.complete();
      bootstrapDone.unsubscribe();
    }
  };
}
/**
 * A subject used to indicate that the bootstrapping phase is done. When initial navigation is
 * `enabledBlocking`, the first navigation waits until bootstrapping is finished before continuing
 * to the activation phase.
 */
const BOOTSTRAP_DONE = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'bootstrap done indicator' : '', {
  factory: () => {
    return new rxjs__WEBPACK_IMPORTED_MODULE_31__.Subject();
  }
});
const INITIAL_NAVIGATION = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'initial navigation' : '', {
  providedIn: 'root',
  factory: () => 1 /* InitialNavigation.EnabledNonBlocking */
});
/**
 * Configures initial navigation to start before the root component is created.
 *
 * The bootstrap is blocked until the initial navigation is complete. This value is required for
 * [server-side rendering](guide/ssr) to work.
 *
 * @usageNotes
 *
 * Basic example of how you can enable this navigation behavior:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withEnabledBlockingInitialNavigation())
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 *
 * @publicApi
 * @returns A set of providers for use with `provideRouter`.
 */
function withEnabledBlockingInitialNavigation() {
  const providers = [{
    provide: INITIAL_NAVIGATION,
    useValue: 0 /* InitialNavigation.EnabledBlocking */
  }, {
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.APP_INITIALIZER,
    multi: true,
    deps: [_angular_core__WEBPACK_IMPORTED_MODULE_2__.Injector],
    useFactory: injector => {
      const locationInitialized = injector.get(_angular_common__WEBPACK_IMPORTED_MODULE_33__.LOCATION_INITIALIZED, Promise.resolve());
      return () => {
        return locationInitialized.then(() => {
          return new Promise(resolve => {
            const router = injector.get(Router);
            const bootstrapDone = injector.get(BOOTSTRAP_DONE);
            afterNextNavigation(router, () => {
              // Unblock APP_INITIALIZER in case the initial navigation was canceled or errored
              // without a redirect.
              resolve(true);
            });
            injector.get(NavigationTransitions).afterPreactivation = () => {
              // Unblock APP_INITIALIZER once we get to `afterPreactivation`. At this point, we
              // assume activation will complete successfully (even though this is not
              // guaranteed).
              resolve(true);
              return bootstrapDone.closed ? (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.of)(void 0) : bootstrapDone;
            };
            router.initialNavigation();
          });
        });
      };
    }
  }];
  return routerFeature(2 /* RouterFeatureKind.EnabledBlockingInitialNavigationFeature */, providers);
}
/**
 * Disables initial navigation.
 *
 * Use if there is a reason to have more control over when the router starts its initial navigation
 * due to some complex initialization logic.
 *
 * @usageNotes
 *
 * Basic example of how you can disable initial navigation:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withDisabledInitialNavigation())
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 *
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withDisabledInitialNavigation() {
  const providers = [{
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.APP_INITIALIZER,
    multi: true,
    useFactory: () => {
      const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(Router);
      return () => {
        router.setUpLocationChangeListener();
      };
    }
  }, {
    provide: INITIAL_NAVIGATION,
    useValue: 2 /* InitialNavigation.Disabled */
  }];
  return routerFeature(3 /* RouterFeatureKind.DisabledInitialNavigationFeature */, providers);
}
/**
 * Enables logging of all internal navigation events to the console.
 * Extra logging might be useful for debugging purposes to inspect Router event sequence.
 *
 * @usageNotes
 *
 * Basic example of how you can enable debug tracing:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withDebugTracing())
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 *
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withDebugTracing() {
  let providers = [];
  if (typeof ngDevMode === 'undefined' || ngDevMode) {
    providers = [{
      provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ENVIRONMENT_INITIALIZER,
      multi: true,
      useFactory: () => {
        const router = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(Router);
        return () => router.events.subscribe(e => {
          // tslint:disable:no-console
          console.group?.(`Router Event: ${e.constructor.name}`);
          console.log(stringifyEvent(e));
          console.log(e);
          console.groupEnd?.();
          // tslint:enable:no-console
        });
      }
    }];
  } else {
    providers = [];
  }
  return routerFeature(1 /* RouterFeatureKind.DebugTracingFeature */, providers);
}
const ROUTER_PRELOADER = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router preloader' : '');
/**
 * Allows to configure a preloading strategy to use. The strategy is configured by providing a
 * reference to a class that implements a `PreloadingStrategy`.
 *
 * @usageNotes
 *
 * Basic example of how you can configure preloading:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withPreloading(PreloadAllModules))
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 *
 * @param preloadingStrategy A reference to a class that implements a `PreloadingStrategy` that
 *     should be used.
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withPreloading(preloadingStrategy) {
  const providers = [{
    provide: ROUTER_PRELOADER,
    useExisting: RouterPreloader
  }, {
    provide: PreloadingStrategy,
    useExisting: preloadingStrategy
  }];
  return routerFeature(0 /* RouterFeatureKind.PreloadingFeature */, providers);
}
/**
 * Allows to provide extra parameters to configure Router.
 *
 * @usageNotes
 *
 * Basic example of how you can provide extra configuration options:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withRouterConfig({
 *          onSameUrlNavigation: 'reload'
 *       }))
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 *
 * @param options A set of parameters to configure Router, see `RouterConfigOptions` for
 *     additional information.
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withRouterConfig(options) {
  const providers = [{
    provide: ROUTER_CONFIGURATION,
    useValue: options
  }];
  return routerFeature(5 /* RouterFeatureKind.RouterConfigurationFeature */, providers);
}
/**
 * Provides the location strategy that uses the URL fragment instead of the history API.
 *
 * @usageNotes
 *
 * Basic example of how you can use the hash location option:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withHashLocation())
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link provideRouter}
 * @see {@link HashLocationStrategy}
 *
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withHashLocation() {
  const providers = [{
    provide: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy,
    useClass: _angular_common__WEBPACK_IMPORTED_MODULE_33__.HashLocationStrategy
  }];
  return routerFeature(6 /* RouterFeatureKind.RouterHashLocationFeature */, providers);
}
/**
 * Subscribes to the Router's navigation events and calls the given function when a
 * `NavigationError` happens.
 *
 * This function is run inside application's [injection context](guide/dependency-injection-context)
 * so you can use the [`inject`](api/core/inject) function.
 *
 * @usageNotes
 *
 * Basic example of how you can use the error handler option:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withNavigationErrorHandler((e: NavigationError) =>
 * inject(MyErrorTracker).trackError(e)))
 *     ]
 *   }
 * );
 * ```
 *
 * @see {@link NavigationError}
 * @see {@link core/inject}
 * @see {@link runInInjectionContext}
 *
 * @returns A set of providers for use with `provideRouter`.
 *
 * @publicApi
 */
function withNavigationErrorHandler(fn) {
  const providers = [{
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ENVIRONMENT_INITIALIZER,
    multi: true,
    useValue: () => {
      const injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.EnvironmentInjector);
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(Router).events.subscribe(e => {
        if (e instanceof NavigationError) {
          (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.runInInjectionContext)(injector, () => fn(e));
        }
      });
    }
  }];
  return routerFeature(7 /* RouterFeatureKind.NavigationErrorHandlerFeature */, providers);
}
/**
 * Enables binding information from the `Router` state directly to the inputs of the component in
 * `Route` configurations.
 *
 * @usageNotes
 *
 * Basic example of how you can enable the feature:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withComponentInputBinding())
 *     ]
 *   }
 * );
 * ```
 *
 * @returns A set of providers for use with `provideRouter`.
 */
function withComponentInputBinding() {
  const providers = [RoutedComponentInputBinder, {
    provide: INPUT_BINDER,
    useExisting: RoutedComponentInputBinder
  }];
  return routerFeature(8 /* RouterFeatureKind.ComponentInputBindingFeature */, providers);
}
/**
 * Enables view transitions in the Router by running the route activation and deactivation inside of
 * `document.startViewTransition`.
 *
 * Note: The View Transitions API is not available in all browsers. If the browser does not support
 * view transitions, the Router will not attempt to start a view transition and continue processing
 * the navigation as usual.
 *
 * @usageNotes
 *
 * Basic example of how you can enable the feature:
 * ```
 * const appRoutes: Routes = [];
 * bootstrapApplication(AppComponent,
 *   {
 *     providers: [
 *       provideRouter(appRoutes, withViewTransitions())
 *     ]
 *   }
 * );
 * ```
 *
 * @returns A set of providers for use with `provideRouter`.
 * @see https://developer.chrome.com/docs/web-platform/view-transitions/
 * @see https://developer.mozilla.org/en-US/docs/Web/API/View_Transitions_API
 * @experimental
 */
function withViewTransitions(options) {
  const providers = [{
    provide: CREATE_VIEW_TRANSITION,
    useValue: createViewTransition
  }, {
    provide: VIEW_TRANSITION_OPTIONS,
    useValue: {
      skipNextTransition: !!options?.skipInitialTransition,
      ...options
    }
  }];
  return routerFeature(9 /* RouterFeatureKind.ViewTransitionsFeature */, providers);
}

/**
 * The directives defined in the `RouterModule`.
 */
const ROUTER_DIRECTIVES = [RouterOutlet, RouterLink, RouterLinkActive, ɵEmptyOutletComponent];
/**
 * @docsNotRequired
 */
const ROUTER_FORROOT_GUARD = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'router duplicate forRoot guard' : 'ROUTER_FORROOT_GUARD');
// TODO(atscott): All of these except `ActivatedRoute` are `providedIn: 'root'`. They are only kept
// here to avoid a breaking change whereby the provider order matters based on where the
// `RouterModule`/`RouterTestingModule` is imported. These can/should be removed as a "breaking"
// change in a major version.
const ROUTER_PROVIDERS = [_angular_common__WEBPACK_IMPORTED_MODULE_33__.Location, {
  provide: UrlSerializer,
  useClass: DefaultUrlSerializer
}, Router, ChildrenOutletContexts, {
  provide: ActivatedRoute,
  useFactory: rootRoute,
  deps: [Router]
}, RouterConfigLoader,
// Only used to warn when `provideRoutes` is used without `RouterModule` or `provideRouter`. Can
// be removed when `provideRoutes` is removed.
typeof ngDevMode === 'undefined' || ngDevMode ? {
  provide: ROUTER_IS_PROVIDED,
  useValue: true
} : []];
/**
 * @description
 *
 * Adds directives and providers for in-app navigation among views defined in an application.
 * Use the Angular `Router` service to declaratively specify application states and manage state
 * transitions.
 *
 * You can import this NgModule multiple times, once for each lazy-loaded bundle.
 * However, only one `Router` service can be active.
 * To ensure this, there are two ways to register routes when importing this module:
 *
 * * The `forRoot()` method creates an `NgModule` that contains all the directives, the given
 * routes, and the `Router` service itself.
 * * The `forChild()` method creates an `NgModule` that contains all the directives and the given
 * routes, but does not include the `Router` service.
 *
 * @see [Routing and Navigation guide](guide/router) for an
 * overview of how the `Router` service should be used.
 *
 * @publicApi
 */
class RouterModule {
  constructor(guard) {}
  /**
   * Creates and configures a module with all the router providers and directives.
   * Optionally sets up an application listener to perform an initial navigation.
   *
   * When registering the NgModule at the root, import as follows:
   *
   * ```
   * @NgModule({
   *   imports: [RouterModule.forRoot(ROUTES)]
   * })
   * class MyNgModule {}
   * ```
   *
   * @param routes An array of `Route` objects that define the navigation paths for the application.
   * @param config An `ExtraOptions` configuration object that controls how navigation is performed.
   * @return The new `NgModule`.
   *
   */
  static forRoot(routes, config) {
    return {
      ngModule: RouterModule,
      providers: [ROUTER_PROVIDERS, typeof ngDevMode === 'undefined' || ngDevMode ? config?.enableTracing ? withDebugTracing().ɵproviders : [] : [], {
        provide: ROUTES,
        multi: true,
        useValue: routes
      }, {
        provide: ROUTER_FORROOT_GUARD,
        useFactory: provideForRootGuard,
        deps: [[Router, new _angular_core__WEBPACK_IMPORTED_MODULE_2__.Optional(), new _angular_core__WEBPACK_IMPORTED_MODULE_2__.SkipSelf()]]
      }, {
        provide: ROUTER_CONFIGURATION,
        useValue: config ? config : {}
      }, config?.useHash ? provideHashLocationStrategy() : providePathLocationStrategy(), provideRouterScroller(), config?.preloadingStrategy ? withPreloading(config.preloadingStrategy).ɵproviders : [], config?.initialNavigation ? provideInitialNavigation(config) : [], config?.bindToComponentInputs ? withComponentInputBinding().ɵproviders : [], config?.enableViewTransitions ? withViewTransitions().ɵproviders : [], provideRouterInitializer()]
    };
  }
  /**
   * Creates a module with all the router directives and a provider registering routes,
   * without creating a new Router service.
   * When registering for submodules and lazy-loaded submodules, create the NgModule as follows:
   *
   * ```
   * @NgModule({
   *   imports: [RouterModule.forChild(ROUTES)]
   * })
   * class MyNgModule {}
   * ```
   *
   * @param routes An array of `Route` objects that define the navigation paths for the submodule.
   * @return The new NgModule.
   *
   */
  static forChild(routes) {
    return {
      ngModule: RouterModule,
      providers: [{
        provide: ROUTES,
        multi: true,
        useValue: routes
      }]
    };
  }
  static {
    this.ɵfac = function RouterModule_Factory(t) {
      return new (t || RouterModule)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵinject"](ROUTER_FORROOT_GUARD, 8));
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineNgModule"]({
      type: RouterModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](RouterModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgModule,
    args: [{
      imports: ROUTER_DIRECTIVES,
      exports: ROUTER_DIRECTIVES
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Inject,
      args: [ROUTER_FORROOT_GUARD]
    }]
  }], null);
})();
/**
 * For internal use by `RouterModule` only. Note that this differs from `withInMemoryRouterScroller`
 * because it reads from the `ExtraOptions` which should not be used in the standalone world.
 */
function provideRouterScroller() {
  return {
    provide: ROUTER_SCROLLER,
    useFactory: () => {
      const viewportScroller = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_33__.ViewportScroller);
      const zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone);
      const config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(ROUTER_CONFIGURATION);
      const transitions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(NavigationTransitions);
      const urlSerializer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(UrlSerializer);
      if (config.scrollOffset) {
        viewportScroller.setOffset(config.scrollOffset);
      }
      return new RouterScroller(urlSerializer, transitions, viewportScroller, zone, config);
    }
  };
}
// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` should
// provide hash location directly via `{provide: LocationStrategy, useClass: HashLocationStrategy}`.
function provideHashLocationStrategy() {
  return {
    provide: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy,
    useClass: _angular_common__WEBPACK_IMPORTED_MODULE_33__.HashLocationStrategy
  };
}
// Note: For internal use only with `RouterModule`. Standalone setup via `provideRouter` does not
// need this at all because `PathLocationStrategy` is the default factory for `LocationStrategy`.
function providePathLocationStrategy() {
  return {
    provide: _angular_common__WEBPACK_IMPORTED_MODULE_33__.LocationStrategy,
    useClass: _angular_common__WEBPACK_IMPORTED_MODULE_33__.PathLocationStrategy
  };
}
function provideForRootGuard(router) {
  if ((typeof ngDevMode === 'undefined' || ngDevMode) && router) {
    throw new _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵRuntimeError"](4007 /* RuntimeErrorCode.FOR_ROOT_CALLED_TWICE */, `The Router was provided more than once. This can happen if 'forRoot' is used outside of the root injector.` + ` Lazy loaded modules should use RouterModule.forChild() instead.`);
  }
  return 'guarded';
}
// Note: For internal use only with `RouterModule`. Standalone router setup with `provideRouter`
// users call `withXInitialNavigation` directly.
function provideInitialNavigation(config) {
  return [config.initialNavigation === 'disabled' ? withDisabledInitialNavigation().ɵproviders : [], config.initialNavigation === 'enabledBlocking' ? withEnabledBlockingInitialNavigation().ɵproviders : []];
}
// TODO(atscott): This should not be in the public API
/**
 * A [DI token](guide/glossary/#di-token) for the router initializer that
 * is called after the app is bootstrapped.
 *
 * @publicApi
 */
const ROUTER_INITIALIZER = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.InjectionToken(typeof ngDevMode === 'undefined' || ngDevMode ? 'Router Initializer' : '');
function provideRouterInitializer() {
  return [
  // ROUTER_INITIALIZER token should be removed. It's public API but shouldn't be. We can just
  // have `getBootstrapListener` directly attached to APP_BOOTSTRAP_LISTENER.
  {
    provide: ROUTER_INITIALIZER,
    useFactory: getBootstrapListener
  }, {
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_2__.APP_BOOTSTRAP_LISTENER,
    multi: true,
    useExisting: ROUTER_INITIALIZER
  }];
}

/**
 * Maps an array of injectable classes with canMatch functions to an array of equivalent
 * `CanMatchFn` for use in a `Route` definition.
 *
 * Usage {@example router/utils/functional_guards.ts region='CanActivate'}
 *
 * @publicApi
 * @see {@link Route}
 */
function mapToCanMatch(providers) {
  return providers.map(provider => (...params) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(provider).canMatch(...params));
}
/**
 * Maps an array of injectable classes with canActivate functions to an array of equivalent
 * `CanActivateFn` for use in a `Route` definition.
 *
 * Usage {@example router/utils/functional_guards.ts region='CanActivate'}
 *
 * @publicApi
 * @see {@link Route}
 */
function mapToCanActivate(providers) {
  return providers.map(provider => (...params) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(provider).canActivate(...params));
}
/**
 * Maps an array of injectable classes with canActivateChild functions to an array of equivalent
 * `CanActivateChildFn` for use in a `Route` definition.
 *
 * Usage {@example router/utils/functional_guards.ts region='CanActivate'}
 *
 * @publicApi
 * @see {@link Route}
 */
function mapToCanActivateChild(providers) {
  return providers.map(provider => (...params) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(provider).canActivateChild(...params));
}
/**
 * Maps an array of injectable classes with canDeactivate functions to an array of equivalent
 * `CanDeactivateFn` for use in a `Route` definition.
 *
 * Usage {@example router/utils/functional_guards.ts region='CanActivate'}
 *
 * @publicApi
 * @see {@link Route}
 */
function mapToCanDeactivate(providers) {
  return providers.map(provider => (...params) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(provider).canDeactivate(...params));
}
/**
 * Maps an injectable class with a resolve function to an equivalent `ResolveFn`
 * for use in a `Route` definition.
 *
 * Usage {@example router/utils/functional_guards.ts region='Resolve'}
 *
 * @publicApi
 * @see {@link Route}
 */
function mapToResolve(provider) {
  return (...params) => (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.inject)(provider).resolve(...params);
}

/**
 * @module
 * @description
 * Entry point for all public APIs of the router package.
 */
/**
 * @publicApi
 */
const VERSION = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.Version('17.3.12');

/**
 * @module
 * @description
 * Entry point for all public APIs of this package.
 */
// This file only reexports content of the `src` folder. Keep it that way.

// This file is not used to build this module. It is only used during editing

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 88355:
/*!**********************************************************************************!*\
  !*** ./node_modules/@asymmetrik/ngx-leaflet/fesm2022/asymmetrik-ngx-leaflet.mjs ***!
  \**********************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LeafletBaseLayersDirective: () => (/* binding */ LeafletBaseLayersDirective),
/* harmony export */   LeafletControlLayersChanges: () => (/* binding */ LeafletControlLayersChanges),
/* harmony export */   LeafletControlLayersConfig: () => (/* binding */ LeafletControlLayersConfig),
/* harmony export */   LeafletControlLayersWrapper: () => (/* binding */ LeafletControlLayersWrapper),
/* harmony export */   LeafletDirective: () => (/* binding */ LeafletDirective),
/* harmony export */   LeafletDirectiveWrapper: () => (/* binding */ LeafletDirectiveWrapper),
/* harmony export */   LeafletLayerDirective: () => (/* binding */ LeafletLayerDirective),
/* harmony export */   LeafletLayersControlDirective: () => (/* binding */ LeafletLayersControlDirective),
/* harmony export */   LeafletLayersDirective: () => (/* binding */ LeafletLayersDirective),
/* harmony export */   LeafletModule: () => (/* binding */ LeafletModule),
/* harmony export */   LeafletTileLayerDefinition: () => (/* binding */ LeafletTileLayerDefinition),
/* harmony export */   LeafletUtil: () => (/* binding */ LeafletUtil)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var leaflet__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! leaflet */ 67381);



class LeafletUtil {
  static mapToArray(map) {
    const toReturn = [];
    for (const k in map) {
      if (map.hasOwnProperty(k)) {
        toReturn.push(map[k]);
      }
    }
    return toReturn;
  }
  static handleEvent(zone, eventEmitter, event) {
    // Don't want to emit if there are no observers
    if (0 < eventEmitter.observers.length) {
      zone.run(() => {
        eventEmitter.emit(event);
      });
    }
  }
}
class LeafletDirective {
  constructor(element, zone) {
    this.element = element;
    this.zone = zone;
    this.DEFAULT_ZOOM = 1;
    this.DEFAULT_CENTER = (0,leaflet__WEBPACK_IMPORTED_MODULE_0__.latLng)(38.907192, -77.036871);
    this.DEFAULT_FPZ_OPTIONS = {};
    this.fitBoundsOptions = this.DEFAULT_FPZ_OPTIONS;
    this.panOptions = this.DEFAULT_FPZ_OPTIONS;
    this.zoomOptions = this.DEFAULT_FPZ_OPTIONS;
    this.zoomPanOptions = this.DEFAULT_FPZ_OPTIONS;
    // Default configuration
    this.options = {};
    // Configure callback function for the map
    this.mapReady = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.zoomChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.centerChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    // Mouse Map Events
    this.onClick = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onDoubleClick = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMouseDown = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMouseUp = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMouseMove = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMouseOver = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMouseOut = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    // Map Move Events
    this.onMapMove = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMapMoveStart = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMapMoveEnd = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    // Map Zoom Events
    this.onMapZoom = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMapZoomStart = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onMapZoomEnd = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    // Nothing here
  }
  ngOnInit() {
    // Create the map outside of angular so the various map events don't trigger change detection
    this.zone.runOutsideAngular(() => {
      // Create the map with some reasonable defaults
      this.map = (0,leaflet__WEBPACK_IMPORTED_MODULE_0__.map)(this.element.nativeElement, this.options);
      this.addMapEventListeners();
    });
    // Only setView if there is a center/zoom
    if (null != this.center && null != this.zoom) {
      this.setView(this.center, this.zoom);
    }
    // Set up all the initial settings
    if (null != this.fitBounds) {
      this.setFitBounds(this.fitBounds);
    }
    if (null != this.maxBounds) {
      this.setMaxBounds(this.maxBounds);
    }
    if (null != this.minZoom) {
      this.setMinZoom(this.minZoom);
    }
    if (null != this.maxZoom) {
      this.setMaxZoom(this.maxZoom);
    }
    this.doResize();
    // Fire map ready event
    this.mapReady.emit(this.map);
  }
  ngOnChanges(changes) {
    /*
     * The following code is to address an issue with our (basic) implementation of
     * zooming and panning. From our testing, it seems that a pan operation followed
     * by a zoom operation in the same thread will interfere with eachother. The zoom
     * operation interrupts/cancels the pan, resulting in a final center point that is
     * inaccurate. The solution seems to be to either separate them with a timeout or
      * to collapse them into a setView call.
     */
    // Zooming and Panning
    if (changes['zoom'] && changes['center'] && null != this.zoom && null != this.center) {
      this.setView(changes['center'].currentValue, changes['zoom'].currentValue);
    }
    // Set the zoom level
    else if (changes['zoom']) {
      this.setZoom(changes['zoom'].currentValue);
    }
    // Set the map center
    else if (changes['center']) {
      this.setCenter(changes['center'].currentValue);
    }
    // Other options
    if (changes['fitBounds']) {
      this.setFitBounds(changes['fitBounds'].currentValue);
    }
    if (changes['maxBounds']) {
      this.setMaxBounds(changes['maxBounds'].currentValue);
    }
    if (changes['minZoom']) {
      this.setMinZoom(changes['minZoom'].currentValue);
    }
    if (changes['maxZoom']) {
      this.setMaxZoom(changes['maxZoom'].currentValue);
    }
  }
  ngOnDestroy() {
    // If this directive is destroyed, the map is too
    if (null != this.map) {
      this.map.remove();
    }
  }
  getMap() {
    return this.map;
  }
  onResize() {
    this.delayResize();
  }
  addMapEventListeners() {
    const registerEventHandler = (eventName, handler) => {
      this.map.on(eventName, handler);
    };
    // Add all the pass-through mouse event handlers
    registerEventHandler('click', e => LeafletUtil.handleEvent(this.zone, this.onClick, e));
    registerEventHandler('dblclick', e => LeafletUtil.handleEvent(this.zone, this.onDoubleClick, e));
    registerEventHandler('mousedown', e => LeafletUtil.handleEvent(this.zone, this.onMouseDown, e));
    registerEventHandler('mouseup', e => LeafletUtil.handleEvent(this.zone, this.onMouseUp, e));
    registerEventHandler('mouseover', e => LeafletUtil.handleEvent(this.zone, this.onMouseOver, e));
    registerEventHandler('mouseout', e => LeafletUtil.handleEvent(this.zone, this.onMouseOut, e));
    registerEventHandler('mousemove', e => LeafletUtil.handleEvent(this.zone, this.onMouseMove, e));
    registerEventHandler('zoomstart', e => LeafletUtil.handleEvent(this.zone, this.onMapZoomStart, e));
    registerEventHandler('zoom', e => LeafletUtil.handleEvent(this.zone, this.onMapZoom, e));
    registerEventHandler('zoomend', e => LeafletUtil.handleEvent(this.zone, this.onMapZoomEnd, e));
    registerEventHandler('movestart', e => LeafletUtil.handleEvent(this.zone, this.onMapMoveStart, e));
    registerEventHandler('move', e => LeafletUtil.handleEvent(this.zone, this.onMapMove, e));
    registerEventHandler('moveend', e => LeafletUtil.handleEvent(this.zone, this.onMapMoveEnd, e));
    // Update any things for which we provide output bindings
    const outputUpdateHandler = () => {
      const zoom = this.map.getZoom();
      if (zoom !== this.zoom) {
        this.zoom = zoom;
        LeafletUtil.handleEvent(this.zone, this.zoomChange, zoom);
      }
      const center = this.map.getCenter();
      if (null != center || null != this.center) {
        if ((null == center || null == this.center) && center !== this.center || center.lat !== this.center.lat || center.lng !== this.center.lng) {
          this.center = center;
          LeafletUtil.handleEvent(this.zone, this.centerChange, center);
        }
      }
    };
    registerEventHandler('moveend', outputUpdateHandler);
    registerEventHandler('zoomend', outputUpdateHandler);
  }
  /**
   * Resize the map to fit it's parent container
   */
  doResize() {
    // Run this outside of angular so the map events stay outside of angular
    this.zone.runOutsideAngular(() => {
      // Invalidate the map size to trigger it to update itself
      if (null != this.map) {
        this.map.invalidateSize({});
      }
    });
  }
  /**
   * Manage a delayed resize of the component
   */
  delayResize() {
    if (null != this.resizeTimer) {
      clearTimeout(this.resizeTimer);
    }
    this.resizeTimer = setTimeout(this.doResize.bind(this), 200);
  }
  /**
   * Set the view (center/zoom) all at once
   * @param center The new center
   * @param zoom The new zoom level
   */
  setView(center, zoom) {
    if (null != this.map && null != center && null != zoom) {
      this.map.setView(center, zoom, this.zoomPanOptions);
    }
  }
  /**
   * Set the map zoom level
   * @param zoom the new zoom level for the map
   */
  setZoom(zoom) {
    if (null != this.map && null != zoom) {
      this.map.setZoom(zoom, this.zoomOptions);
    }
  }
  /**
   * Set the center of the map
   * @param center the center point
   */
  setCenter(center) {
    if (null != this.map && null != center) {
      this.map.panTo(center, this.panOptions);
    }
  }
  /**
   * Fit the map to the bounds
   * @param latLngBounds the boundary to set
   */
  setFitBounds(latLngBounds) {
    if (null != this.map && null != latLngBounds) {
      this.map.fitBounds(latLngBounds, this.fitBoundsOptions);
    }
  }
  /**
   * Set the map's max bounds
   * @param latLngBounds the boundary to set
   */
  setMaxBounds(latLngBounds) {
    if (null != this.map && null != latLngBounds) {
      this.map.setMaxBounds(latLngBounds);
    }
  }
  /**
   * Set the map's min zoom
   * @param number the new min zoom
   */
  setMinZoom(zoom) {
    if (null != this.map && null != zoom) {
      this.map.setMinZoom(zoom);
    }
  }
  /**
   * Set the map's min zoom
   * @param number the new min zoom
   */
  setMaxZoom(zoom) {
    if (null != this.map && null != zoom) {
      this.map.setMaxZoom(zoom);
    }
  }
  static {
    this.ɵfac = function LeafletDirective_Factory(t) {
      return new (t || LeafletDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: LeafletDirective,
      selectors: [["", "leaflet", ""]],
      hostBindings: function LeafletDirective_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("resize", function LeafletDirective_resize_HostBindingHandler() {
            return ctx.onResize();
          }, false, _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵresolveWindow"]);
        }
      },
      inputs: {
        fitBoundsOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletFitBoundsOptions", "fitBoundsOptions"],
        panOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletPanOptions", "panOptions"],
        zoomOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletZoomOptions", "zoomOptions"],
        zoomPanOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletZoomPanOptions", "zoomPanOptions"],
        options: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletOptions", "options"],
        zoom: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletZoom", "zoom"],
        center: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletCenter", "center"],
        fitBounds: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletFitBounds", "fitBounds"],
        maxBounds: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletMaxBounds", "maxBounds"],
        minZoom: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletMinZoom", "minZoom"],
        maxZoom: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletMaxZoom", "maxZoom"]
      },
      outputs: {
        mapReady: "leafletMapReady",
        zoomChange: "leafletZoomChange",
        centerChange: "leafletCenterChange",
        onClick: "leafletClick",
        onDoubleClick: "leafletDoubleClick",
        onMouseDown: "leafletMouseDown",
        onMouseUp: "leafletMouseUp",
        onMouseMove: "leafletMouseMove",
        onMouseOver: "leafletMouseOver",
        onMouseOut: "leafletMouseOut",
        onMapMove: "leafletMapMove",
        onMapMoveStart: "leafletMapMoveStart",
        onMapMoveEnd: "leafletMapMoveEnd",
        onMapZoom: "leafletMapZoom",
        onMapZoomStart: "leafletMapZoomStart",
        onMapZoomEnd: "leafletMapZoomEnd"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[leaflet]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    fitBoundsOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletFitBoundsOptions']
    }],
    panOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletPanOptions']
    }],
    zoomOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletZoomOptions']
    }],
    zoomPanOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletZoomPanOptions']
    }],
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletOptions']
    }],
    mapReady: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapReady']
    }],
    zoom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletZoom']
    }],
    zoomChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletZoomChange']
    }],
    center: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletCenter']
    }],
    centerChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletCenterChange']
    }],
    fitBounds: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletFitBounds']
    }],
    maxBounds: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletMaxBounds']
    }],
    minZoom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletMinZoom']
    }],
    maxZoom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletMaxZoom']
    }],
    onClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletClick']
    }],
    onDoubleClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletDoubleClick']
    }],
    onMouseDown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMouseDown']
    }],
    onMouseUp: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMouseUp']
    }],
    onMouseMove: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMouseMove']
    }],
    onMouseOver: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMouseOver']
    }],
    onMouseOut: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMouseOut']
    }],
    onMapMove: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapMove']
    }],
    onMapMoveStart: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapMoveStart']
    }],
    onMapMoveEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapMoveEnd']
    }],
    onMapZoom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapZoom']
    }],
    onMapZoomStart: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapZoomStart']
    }],
    onMapZoomEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletMapZoomEnd']
    }],
    onResize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['window:resize', []]
    }]
  });
})();
class LeafletDirectiveWrapper {
  constructor(leafletDirective) {
    this.leafletDirective = leafletDirective;
  }
  init() {
    // Nothing for now
  }
  getMap() {
    return this.leafletDirective.getMap();
  }
}

/**
 * Layer directive
 *
 * This directive is used to directly control a single map layer. The purpose of this directive is to
 * be used as part of a child structural directive of the map element.
 *
 */
class LeafletLayerDirective {
  constructor(leafletDirective, zone) {
    this.zone = zone;
    // Layer Events
    this.onAdd = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.onRemove = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.leafletDirective = new LeafletDirectiveWrapper(leafletDirective);
  }
  ngOnInit() {
    // Init the map
    this.leafletDirective.init();
  }
  ngOnDestroy() {
    if (null != this.layer) {
      // Unregister the event handlers
      this.removeLayerEventListeners(this.layer);
      // Remove the layer from the map
      this.layer.remove();
    }
  }
  ngOnChanges(changes) {
    if (changes['layer']) {
      // Update the layer
      const p = changes['layer'].previousValue;
      const n = changes['layer'].currentValue;
      this.zone.runOutsideAngular(() => {
        if (null != p) {
          this.removeLayerEventListeners(p);
          p.remove();
        }
        if (null != n) {
          this.addLayerEventListeners(n);
          this.leafletDirective.getMap().addLayer(n);
        }
      });
    }
  }
  addLayerEventListeners(l) {
    this.onAddLayerHandler = e => LeafletUtil.handleEvent(this.zone, this.onAdd, e);
    l.on('add', this.onAddLayerHandler);
    this.onRemoveLayerHandler = e => LeafletUtil.handleEvent(this.zone, this.onRemove, e);
    l.on('remove', this.onRemoveLayerHandler);
  }
  removeLayerEventListeners(l) {
    l.off('add', this.onAddLayerHandler);
    l.off('remove', this.onRemoveLayerHandler);
  }
  static {
    this.ɵfac = function LeafletLayerDirective_Factory(t) {
      return new (t || LeafletLayerDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](LeafletDirective), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: LeafletLayerDirective,
      selectors: [["", "leafletLayer", ""]],
      inputs: {
        layer: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletLayer", "layer"]
      },
      outputs: {
        onAdd: "leafletLayerAdd",
        onRemove: "leafletLayerRemove"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletLayerDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[leafletLayer]'
    }]
  }], () => [{
    type: LeafletDirective
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    layer: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletLayer']
    }],
    onAdd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletLayerAdd']
    }],
    onRemove: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletLayerRemove']
    }]
  });
})();

/**
 * Layers directive
 *
 * This directive is used to directly control map layers. As changes are made to the input array of
 * layers, the map is synched to the array. As layers are added or removed from the input array, they
 * are also added or removed from the map. The input array is treated as immutable. To detect changes,
 * you must change the array instance.
 *
 * Important Note: The input layers array is assumed to be immutable. This means you need to use an
 * immutable array implementation or create a new copy of your array when you make changes, otherwise
 * this directive won't detect the change. This is by design. It's for performance reasons. Change
 * detection of mutable arrays requires diffing the state of the array on every DoCheck cycle, which
 * is extremely expensive from a time complexity perspective.
 *
 */
class LeafletLayersDirective {
  // Set/get the layers
  set layers(v) {
    this.layersValue = v;
    // Now that we have a differ, do an immediate layer update
    this.updateLayers();
  }
  get layers() {
    return this.layersValue;
  }
  constructor(leafletDirective, differs, zone) {
    this.differs = differs;
    this.zone = zone;
    this.leafletDirective = new LeafletDirectiveWrapper(leafletDirective);
    this.layersDiffer = this.differs.find([]).create();
  }
  ngDoCheck() {
    this.updateLayers();
  }
  ngOnInit() {
    // Init the map
    this.leafletDirective.init();
    // Update layers once the map is ready
    this.updateLayers();
  }
  ngOnDestroy() {
    this.layers = [];
  }
  /**
   * Update the state of the layers.
   * We use an iterable differ to synchronize the map layers with the state of the bound layers array.
   * This is important because it allows us to react to changes to the contents of the array as well
   * as changes to the actual array instance.
   */
  updateLayers() {
    const map = this.leafletDirective.getMap();
    if (null != map && null != this.layersDiffer) {
      const changes = this.layersDiffer.diff(this.layersValue);
      if (null != changes) {
        // Run outside angular to ensure layer events don't trigger change detection
        this.zone.runOutsideAngular(() => {
          changes.forEachRemovedItem(c => {
            map.removeLayer(c.item);
          });
          changes.forEachAddedItem(c => {
            map.addLayer(c.item);
          });
        });
      }
    }
  }
  static {
    this.ɵfac = function LeafletLayersDirective_Factory(t) {
      return new (t || LeafletLayersDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](LeafletDirective), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: LeafletLayersDirective,
      selectors: [["", "leafletLayers", ""]],
      inputs: {
        layers: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletLayers", "layers"]
      }
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletLayersDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[leafletLayers]'
    }]
  }], () => [{
    type: LeafletDirective
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.IterableDiffers
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    layers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletLayers']
    }]
  });
})();
class LeafletControlLayersChanges {
  constructor() {
    this.layersRemoved = 0;
    this.layersChanged = 0;
    this.layersAdded = 0;
  }
  changed() {
    return !(this.layersRemoved === 0 && this.layersChanged === 0 && this.layersAdded === 0);
  }
}
class LeafletControlLayersWrapper {
  constructor(zone, layersControlReady) {
    this.zone = zone;
    this.layersControlReady = layersControlReady;
  }
  getLayersControl() {
    return this.layersControl;
  }
  init(controlConfig, controlOptions) {
    const baseLayers = controlConfig.baseLayers || {};
    const overlays = controlConfig.overlays || {};
    // Create the control outside of angular to ensure events don't trigger change detection
    this.zone.runOutsideAngular(() => {
      this.layersControl = leaflet__WEBPACK_IMPORTED_MODULE_0__.control.layers(baseLayers, overlays, controlOptions);
    });
    this.layersControlReady.emit(this.layersControl);
    return this.layersControl;
  }
  applyBaseLayerChanges(changes) {
    let results = new LeafletControlLayersChanges();
    if (null != this.layersControl) {
      results = this.applyChanges(changes, this.layersControl.addBaseLayer);
    }
    return results;
  }
  applyOverlayChanges(changes) {
    let results = new LeafletControlLayersChanges();
    if (null != this.layersControl) {
      results = this.applyChanges(changes, this.layersControl.addOverlay);
    }
    return results;
  }
  applyChanges(changes, addFn) {
    const results = new LeafletControlLayersChanges();
    if (null != changes) {
      // All layer management is outside angular to avoid layer events from triggering change detection
      this.zone.runOutsideAngular(() => {
        changes.forEachChangedItem(c => {
          this.layersControl.removeLayer(c.previousValue);
          addFn.call(this.layersControl, c.currentValue, c.key);
          results.layersChanged++;
        });
        changes.forEachRemovedItem(c => {
          this.layersControl.removeLayer(c.previousValue);
          results.layersRemoved++;
        });
        changes.forEachAddedItem(c => {
          addFn.call(this.layersControl, c.currentValue, c.key);
          results.layersAdded++;
        });
      });
    }
    return results;
  }
}
class LeafletControlLayersConfig {
  constructor() {
    this.baseLayers = {};
    this.overlays = {};
  }
}

/**
 * Layers Control
 *
 * This directive is used to configure the layers control. The input accepts an object with two
 * key-value maps of layer name -> layer. Mutable changes are detected. On changes, a differ is
 * used to determine what changed so that layers are appropriately added or removed.
 *
 * To specify which layer to show as the 'active' baselayer, you will want to add it to the map
 * using the layers directive. Otherwise, the last one it sees will be used.
 */
class LeafletLayersControlDirective {
  set layersControlConfig(v) {
    // Validation/init stuff
    if (null == v) {
      v = new LeafletControlLayersConfig();
    }
    if (null == v.baseLayers) {
      v.baseLayers = {};
    }
    if (null == v.overlays) {
      v.overlays = {};
    }
    // Store the value
    this.layersControlConfigValue = v;
    // Update the map
    this.updateLayers();
  }
  get layersControlConfig() {
    return this.layersControlConfigValue;
  }
  constructor(leafletDirective, differs, zone) {
    this.differs = differs;
    this.zone = zone;
    this.layersControlReady = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.leafletDirective = new LeafletDirectiveWrapper(leafletDirective);
    this.controlLayers = new LeafletControlLayersWrapper(this.zone, this.layersControlReady);
    // Generate differs
    this.baseLayersDiffer = this.differs.find({}).create();
    this.overlaysDiffer = this.differs.find({}).create();
  }
  ngOnInit() {
    // Init the map
    this.leafletDirective.init();
    // Set up control outside of angular to avoid change detection when using the control
    this.zone.runOutsideAngular(() => {
      // Set up all the initial settings
      this.controlLayers.init({}, this.layersControlOptions).addTo(this.leafletDirective.getMap());
    });
    this.updateLayers();
  }
  ngOnDestroy() {
    this.layersControlConfig = {
      baseLayers: {},
      overlays: {}
    };
    this.controlLayers.getLayersControl().remove();
  }
  ngDoCheck() {
    this.updateLayers();
  }
  updateLayers() {
    const map = this.leafletDirective.getMap();
    const layersControl = this.controlLayers.getLayersControl();
    if (null != map && null != layersControl) {
      // Run the baselayers differ
      if (null != this.baseLayersDiffer && null != this.layersControlConfigValue.baseLayers) {
        const changes = this.baseLayersDiffer.diff(this.layersControlConfigValue.baseLayers);
        this.controlLayers.applyBaseLayerChanges(changes);
      }
      // Run the overlays differ
      if (null != this.overlaysDiffer && null != this.layersControlConfigValue.overlays) {
        const changes = this.overlaysDiffer.diff(this.layersControlConfigValue.overlays);
        this.controlLayers.applyOverlayChanges(changes);
      }
    }
  }
  static {
    this.ɵfac = function LeafletLayersControlDirective_Factory(t) {
      return new (t || LeafletLayersControlDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](LeafletDirective), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: LeafletLayersControlDirective,
      selectors: [["", "leafletLayersControl", ""]],
      inputs: {
        layersControlConfig: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletLayersControl", "layersControlConfig"],
        layersControlOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletLayersControlOptions", "layersControlOptions"]
      },
      outputs: {
        layersControlReady: "leafletLayersControlReady"
      }
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletLayersControlDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[leafletLayersControl]'
    }]
  }], () => [{
    type: LeafletDirective
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.KeyValueDiffers
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    layersControlConfig: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletLayersControl']
    }],
    layersControlOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletLayersControlOptions']
    }],
    layersControlReady: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletLayersControlReady']
    }]
  });
})();

/**
 * Baselayers directive
 *
 * This directive is provided as a convenient way to add baselayers to the map. The input accepts
 * a key-value map of layer name -> layer. Mutable changed are detected. On changes, a differ is
 * used to determine what changed so that layers are appropriately added or removed. This directive
 * will also add the layers control so users can switch between available base layers.
 *
 * To specify which layer to show as the 'active' baselayer, you will want to add it to the map
 * using the layers directive. Otherwise, the plugin will use the last one it sees.
 */
class LeafletBaseLayersDirective {
  // Set/get baseLayers
  set baseLayers(v) {
    this.baseLayersValue = v;
    this.updateBaseLayers();
  }
  get baseLayers() {
    return this.baseLayersValue;
  }
  constructor(leafletDirective, differs, zone) {
    this.differs = differs;
    this.zone = zone;
    // Output for once the layers control is ready
    this.layersControlReady = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.leafletDirective = new LeafletDirectiveWrapper(leafletDirective);
    this.controlLayers = new LeafletControlLayersWrapper(this.zone, this.layersControlReady);
    this.baseLayersDiffer = this.differs.find({}).create();
  }
  ngOnDestroy() {
    this.baseLayers = {};
    if (null != this.controlLayers.getLayersControl()) {
      this.controlLayers.getLayersControl().remove();
    }
  }
  ngOnInit() {
    // Init the map
    this.leafletDirective.init();
    // Create the control outside angular to prevent events from triggering chnage detection
    this.zone.runOutsideAngular(() => {
      // Initially configure the controlLayers
      this.controlLayers.init({}, this.layersControlOptions).addTo(this.leafletDirective.getMap());
    });
    this.updateBaseLayers();
  }
  ngDoCheck() {
    this.updateBaseLayers();
  }
  updateBaseLayers() {
    const map = this.leafletDirective.getMap();
    const layersControl = this.controlLayers.getLayersControl();
    if (null != map && null != layersControl && null != this.baseLayersDiffer) {
      const changes = this.baseLayersDiffer.diff(this.baseLayersValue);
      const results = this.controlLayers.applyBaseLayerChanges(changes);
      if (results.changed()) {
        this.syncBaseLayer();
      }
    }
  }
  /**
   * Check the current base layer and change it to the new one if necessary
   */
  syncBaseLayer() {
    const map = this.leafletDirective.getMap();
    const layers = LeafletUtil.mapToArray(this.baseLayers);
    let foundLayer;
    // Search all the layers in the map to see if we can find them in the baselayer array
    map.eachLayer(l => {
      foundLayer = layers.find(bl => l === bl);
    });
    // Did we find the layer?
    if (null != foundLayer) {
      // Yes - set the baselayer to the one we found
      this.baseLayer = foundLayer;
    } else {
      // No - set the baselayer to the first in the array and add it to the map
      if (layers.length > 0) {
        this.baseLayer = layers[0];
        // Add layers outside of angular to prevent events from triggering change detection
        this.zone.runOutsideAngular(() => {
          this.baseLayer.addTo(map);
        });
      }
    }
  }
  static {
    this.ɵfac = function LeafletBaseLayersDirective_Factory(t) {
      return new (t || LeafletBaseLayersDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](LeafletDirective), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.KeyValueDiffers), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: LeafletBaseLayersDirective,
      selectors: [["", "leafletBaseLayers", ""]],
      inputs: {
        baseLayers: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletBaseLayers", "baseLayers"],
        layersControlOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "leafletLayersControlOptions", "layersControlOptions"]
      },
      outputs: {
        layersControlReady: "leafletLayersControlReady"
      }
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletBaseLayersDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[leafletBaseLayers]'
    }]
  }], () => [{
    type: LeafletDirective
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.KeyValueDiffers
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    baseLayers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletBaseLayers']
    }],
    layersControlOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['leafletLayersControlOptions']
    }],
    layersControlReady: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output,
      args: ['leafletLayersControlReady']
    }]
  });
})();
class LeafletModule {
  static {
    this.ɵfac = function LeafletModule_Factory(t) {
      return new (t || LeafletModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: LeafletModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](LeafletModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      exports: [LeafletDirective, LeafletLayerDirective, LeafletLayersDirective, LeafletLayersControlDirective, LeafletBaseLayersDirective],
      declarations: [LeafletDirective, LeafletLayerDirective, LeafletLayersDirective, LeafletLayersControlDirective, LeafletBaseLayersDirective]
    }]
  }], null, null);
})();
class LeafletTileLayerDefinition {
  constructor(type, url, options) {
    this.type = type;
    this.url = url;
    this.options = options;
  }
  /**
   * Creates a TileLayer from the provided definition. This is a convenience function
   * to help with generating layers from objects.
   *
   * @param layerDef The layer to create
   * @returns {TileLayer} The TileLayer that has been created
   */
  static createTileLayer(layerDef) {
    let layer;
    switch (layerDef.type) {
      case 'xyz':
        layer = (0,leaflet__WEBPACK_IMPORTED_MODULE_0__.tileLayer)(layerDef.url, layerDef.options);
        break;
      case 'wms':
      default:
        layer = leaflet__WEBPACK_IMPORTED_MODULE_0__.tileLayer.wms(layerDef.url, layerDef.options);
        break;
    }
    return layer;
  }
  /**
   * Creates a TileLayer for each key in the incoming map. This is a convenience function
   * for generating an associative array of layers from an associative array of objects
   *
   * @param layerDefs A map of key to tile layer definition
   * @returns {{[p: string]: TileLayer}} A new map of key to TileLayer
   */
  static createTileLayers(layerDefs) {
    const layers = {};
    for (const k in layerDefs) {
      if (layerDefs.hasOwnProperty(k)) {
        layers[k] = LeafletTileLayerDefinition.createTileLayer(layerDefs[k]);
      }
    }
    return layers;
  }
  /**
   * Create a Tile Layer from the current state of this object
   *
   * @returns {TileLayer} A new TileLayer
   */
  createTileLayer() {
    return LeafletTileLayerDefinition.createTileLayer(this);
  }
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 34225:
/*!******************************************************************************************!*\
  !*** ./node_modules/@ckeditor/ckeditor5-angular/fesm2020/ckeditor-ckeditor5-angular.mjs ***!
  \******************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CKEditorComponent: () => (/* binding */ CKEditorComponent),
/* harmony export */   CKEditorModule: () => (/* binding */ CKEditorModule)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _ckeditor_ckeditor5_watchdog__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ckeditor/ckeditor5-watchdog */ 63118);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 2435);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @angular/forms */ 34456);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @angular/common */ 60316);








/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */
// A copy of @ckeditor/ckeditor5-utils/src/uid.js
// A hash table of hex numbers to avoid using toString() in uid() which is costly.
// [ '00', '01', '02', ..., 'fe', 'ff' ]
function CKEditorComponent_ng_template_0_Template(rf, ctx) {}
const HEX_NUMBERS = new Array(256).fill(0).map((val, index) => ('0' + index.toString(16)).slice(-2));
/**
 * Returns a unique id. The id starts with an "e" character and a randomly generated string of
 * 32 alphanumeric characters.
 *
 * **Note**: The characters the unique id is built from correspond to the hex number notation
 * (from "0" to "9", from "a" to "f"). In other words, each id corresponds to an "e" followed
 * by 16 8-bit numbers next to each other.
 *
 * @returns An unique id string.
 */
function uid() {
  // Let's create some positive random 32bit integers first.
  //
  // 1. Math.random() is a float between 0 and 1.
  // 2. 0x100000000 is 2^32 = 4294967296.
  // 3. >>> 0 enforces integer (in JS all numbers are floating point).
  //
  // For instance:
  //		Math.random() * 0x100000000 = 3366450031.853859
  // but
  //		Math.random() * 0x100000000 >>> 0 = 3366450031.
  const r1 = Math.random() * 0x100000000 >>> 0;
  const r2 = Math.random() * 0x100000000 >>> 0;
  const r3 = Math.random() * 0x100000000 >>> 0;
  const r4 = Math.random() * 0x100000000 >>> 0;
  // Make sure that id does not start with number.
  return 'e' + HEX_NUMBERS[r1 >> 0 & 0xFF] + HEX_NUMBERS[r1 >> 8 & 0xFF] + HEX_NUMBERS[r1 >> 16 & 0xFF] + HEX_NUMBERS[r1 >> 24 & 0xFF] + HEX_NUMBERS[r2 >> 0 & 0xFF] + HEX_NUMBERS[r2 >> 8 & 0xFF] + HEX_NUMBERS[r2 >> 16 & 0xFF] + HEX_NUMBERS[r2 >> 24 & 0xFF] + HEX_NUMBERS[r3 >> 0 & 0xFF] + HEX_NUMBERS[r3 >> 8 & 0xFF] + HEX_NUMBERS[r3 >> 16 & 0xFF] + HEX_NUMBERS[r3 >> 24 & 0xFF] + HEX_NUMBERS[r4 >> 0 & 0xFF] + HEX_NUMBERS[r4 >> 8 & 0xFF] + HEX_NUMBERS[r4 >> 16 & 0xFF] + HEX_NUMBERS[r4 >> 24 & 0xFF];
}
const ANGULAR_INTEGRATION_READ_ONLY_LOCK_ID = 'Lock from Angular integration (@ckeditor/ckeditor5-angular)';
class CKEditorComponent {
  constructor(elementRef, ngZone) {
    /**
     * The configuration of the editor.
     * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editorconfig-EditorConfig.html
     * to learn more.
     */
    this.config = {};
    /**
     * The initial data of the editor. Useful when not using the ngModel.
     * See https://angular.io/api/forms/NgModel to learn more.
     */
    this.data = '';
    /**
     * Tag name of the editor component.
     *
     * The default tag is 'div'.
     */
    this.tagName = 'div';
    /**
     * Allows disabling the two-way data binding mechanism. Disabling it can boost performance for large documents.
     *
     * When a component is connected using the [(ngModel)] or [formControl] directives and this value is set to true then none of the data
     * will ever be synchronized.
     *
     * An integrator must call `editor.data.get()` manually once the application needs the editor's data.
     * An editor instance can be received in the `ready()` callback.
     */
    this.disableTwoWayDataBinding = false;
    /**
     * Fires when the editor is ready. It corresponds with the `editor#ready`
     * https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html#event-ready
     * event.
     */
    this.ready = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Fires when the content of the editor has changed. It corresponds with the `editor.model.document#change`
     * https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_model_document-Document.html#event-change
     * event.
     */
    this.change = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Fires when the editing view of the editor is blurred. It corresponds with the `editor.editing.view.document#blur`
     * https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_document-Document.html#event-event:blur
     * event.
     */
    this.blur = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Fires when the editing view of the editor is focused. It corresponds with the `editor.editing.view.document#focus`
     * https://ckeditor.com/docs/ckeditor5/latest/api/module_engine_view_document-Document.html#event-event:focus
     * event.
     */
    this.focus = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * Fires when the editor component crashes.
     */
    this.error = new _angular_core__WEBPACK_IMPORTED_MODULE_2__.EventEmitter();
    /**
     * If the component is read–only before the editor instance is created, it remembers that state,
     * so the editor can become read–only once it is ready.
     */
    this.initiallyDisabled = false;
    /**
     * A lock flag preventing from calling the `cvaOnChange()` during setting editor data.
     */
    this.isEditorSettingData = false;
    this.id = uid();
    this.ngZone = ngZone;
    this.elementRef = elementRef;
    // To avoid issues with the community typings and CKEditor 5, let's treat window as any. See #342.
    const {
      CKEDITOR_VERSION
    } = window;
    if (CKEDITOR_VERSION) {
      const [major] = CKEDITOR_VERSION.split('.').map(Number);
      if (major < 37) {
        console.warn('The <CKEditor> component requires using CKEditor 5 in version 37 or higher.');
      }
    } else {
      console.warn('Cannot find the "CKEDITOR_VERSION" in the "window" scope.');
    }
  }
  /**
   * When set `true`, the editor becomes read-only.
   * See https://ckeditor.com/docs/ckeditor5/latest/api/module_core_editor_editor-Editor.html#member-isReadOnly
   * to learn more.
   */
  set disabled(isDisabled) {
    this.setDisabledState(isDisabled);
  }
  get disabled() {
    if (this.editorInstance) {
      return this.editorInstance.isReadOnly;
    }
    return this.initiallyDisabled;
  }
  /**
   * The instance of the editor created by this component.
   */
  get editorInstance() {
    let editorWatchdog = this.editorWatchdog;
    if (this.watchdog) {
      // Temporarily use the `_watchdogs` internal map as the `getItem()` method throws
      // an error when the item is not registered yet.
      // See https://github.com/ckeditor/ckeditor5-angular/issues/177.
      // TODO should be able to change when new chages in Watcdog are released.
      editorWatchdog = this.watchdog._watchdogs.get(this.id);
    }
    if (editorWatchdog) {
      return editorWatchdog.editor;
    }
    return null;
  }
  getId() {
    return this.id;
  }
  // Implementing the OnChanges interface. Whenever the `data` property is changed, update the editor content.
  ngOnChanges(changes) {
    if (Object.prototype.hasOwnProperty.call(changes, 'data') && changes.data && !changes.data.isFirstChange()) {
      this.writeValue(changes.data.currentValue);
    }
  }
  // Implementing the AfterViewInit interface.
  ngAfterViewInit() {
    this.attachToWatchdog();
  }
  // Implementing the OnDestroy interface.
  ngOnDestroy() {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      if (_this.watchdog) {
        yield _this.watchdog.remove(_this.id);
      } else if (_this.editorWatchdog && _this.editorWatchdog.editor) {
        yield _this.editorWatchdog.destroy();
        _this.editorWatchdog = undefined;
      }
    })();
  }
  // Implementing the ControlValueAccessor interface (only when binding to ngModel).
  writeValue(value) {
    // This method is called with the `null` value when the form resets.
    // A component's responsibility is to restore to the initial state.
    if (value === null) {
      value = '';
    }
    // If already initialized.
    if (this.editorInstance) {
      // The lock mechanism prevents from calling `cvaOnChange()` during changing
      // the editor state. See #139
      this.isEditorSettingData = true;
      this.editorInstance.data.set(value);
      this.isEditorSettingData = false;
    }
    // If not, wait for it to be ready; store the data.
    else {
      // If the editor element is already available, then update its content.
      this.data = value;
      // If not, then wait until it is ready
      // and change data only for the first `ready` event.
      this.ready.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.first)()).subscribe(editor => {
        editor.data.set(this.data);
      });
    }
  }
  // Implementing the ControlValueAccessor interface (only when binding to ngModel).
  registerOnChange(callback) {
    this.cvaOnChange = callback;
  }
  // Implementing the ControlValueAccessor interface (only when binding to ngModel).
  registerOnTouched(callback) {
    this.cvaOnTouched = callback;
  }
  // Implementing the ControlValueAccessor interface (only when binding to ngModel).
  setDisabledState(isDisabled) {
    // If already initialized.
    if (this.editorInstance) {
      if (isDisabled) {
        this.editorInstance.enableReadOnlyMode(ANGULAR_INTEGRATION_READ_ONLY_LOCK_ID);
      } else {
        this.editorInstance.disableReadOnlyMode(ANGULAR_INTEGRATION_READ_ONLY_LOCK_ID);
      }
    }
    // Store the state anyway to use it once the editor is created.
    this.initiallyDisabled = isDisabled;
  }
  /**
   * Creates the editor instance, sets initial editor data, then integrates
   * the editor with the Angular component. This method does not use the `editor.data.set()`
   * because of the issue in the collaboration mode (#6).
   */
  attachToWatchdog() {
    var _this2 = this;
    // TODO: elementOrData parameter type can be simplified to HTMLElemen after templated Watchdog will be released.
    const creator = (elementOrData, config) => {
      return this.ngZone.runOutsideAngular(/*#__PURE__*/(0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
        _this2.elementRef.nativeElement.appendChild(elementOrData);
        const editor = yield _this2.editor.create(elementOrData, config);
        if (_this2.initiallyDisabled) {
          editor.enableReadOnlyMode(ANGULAR_INTEGRATION_READ_ONLY_LOCK_ID);
        }
        _this2.ngZone.run(() => {
          _this2.ready.emit(editor);
        });
        _this2.setUpEditorEvents(editor);
        return editor;
      }));
    };
    const destructor = /*#__PURE__*/function () {
      var _ref2 = (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* (editor) {
        yield editor.destroy();
        _this2.elementRef.nativeElement.removeChild(_this2.editorElement);
      });
      return function destructor(_x) {
        return _ref2.apply(this, arguments);
      };
    }();
    const emitError = e => {
      // Do not run change detection by re-entering the Angular zone if the `error`
      // emitter doesn't have any subscribers.
      // Subscribers are pushed onto the list whenever `error` is listened inside the template:
      // `<ckeditor (error)="onError(...)"></ckeditor>`.
      if (hasObservers(this.error)) {
        this.ngZone.run(() => this.error.emit(e));
      }
    };
    const element = document.createElement(this.tagName);
    const config = this.getConfig();
    this.editorElement = element;
    // Based on the presence of the watchdog decide how to initialize the editor.
    if (this.watchdog) {
      // When the context watchdog is passed add the new item to it based on the passed configuration.
      this.watchdog.add({
        id: this.id,
        type: 'editor',
        creator,
        destructor,
        sourceElementOrData: element,
        config
      }).catch(e => {
        emitError(e);
      });
      this.watchdog.on('itemError', (_, {
        itemId
      }) => {
        if (itemId === this.id) {
          emitError();
        }
      });
    } else {
      // In the other case create the watchdog by hand to keep the editor running.
      const editorWatchdog = new _ckeditor_ckeditor5_watchdog__WEBPACK_IMPORTED_MODULE_1__.EditorWatchdog(this.editor, this.editorWatchdogConfig);
      editorWatchdog.setCreator(creator);
      editorWatchdog.setDestructor(destructor);
      editorWatchdog.on('error', emitError);
      this.editorWatchdog = editorWatchdog;
      this.ngZone.runOutsideAngular(() => {
        // Note: must be called outside of the Angular zone too because `create` is calling
        // `_startErrorHandling` within a microtask which sets up `error` listener on the window.
        editorWatchdog.create(element, config).catch(e => {
          emitError(e);
        });
      });
    }
  }
  getConfig() {
    if (this.data && this.config.initialData) {
      throw new Error('Editor data should be provided either using `config.initialData` or `data` properties.');
    }
    const config = {
      ...this.config
    };
    // Merge two possible ways of providing data into the `config.initialData` field.
    const initialData = this.config.initialData || this.data;
    if (initialData) {
      // Define the `config.initialData` only when the initial content is specified.
      config.initialData = initialData;
    }
    return config;
  }
  /**
   * Integrates the editor with the component by attaching related event listeners.
   */
  setUpEditorEvents(editor) {
    const modelDocument = editor.model.document;
    const viewDocument = editor.editing.view.document;
    modelDocument.on('change:data', evt => {
      this.ngZone.run(() => {
        if (this.disableTwoWayDataBinding) {
          return;
        }
        if (this.cvaOnChange && !this.isEditorSettingData) {
          const data = editor.data.get();
          this.cvaOnChange(data);
        }
        this.change.emit({
          event: evt,
          editor
        });
      });
    });
    viewDocument.on('focus', evt => {
      this.ngZone.run(() => {
        this.focus.emit({
          event: evt,
          editor
        });
      });
    });
    viewDocument.on('blur', evt => {
      this.ngZone.run(() => {
        if (this.cvaOnTouched) {
          this.cvaOnTouched();
        }
        this.blur.emit({
          event: evt,
          editor
        });
      });
    });
  }
}
CKEditorComponent.ɵfac = function CKEditorComponent_Factory(t) {
  return new (t || CKEditorComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone));
};
CKEditorComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineComponent"]({
  type: CKEditorComponent,
  selectors: [["ckeditor"]],
  inputs: {
    editor: "editor",
    config: "config",
    data: "data",
    tagName: "tagName",
    watchdog: "watchdog",
    editorWatchdogConfig: "editorWatchdogConfig",
    disableTwoWayDataBinding: "disableTwoWayDataBinding",
    disabled: "disabled"
  },
  outputs: {
    ready: "ready",
    change: "change",
    blur: "blur",
    focus: "focus",
    error: "error"
  },
  features: [_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵProvidersFeature"]([{
    provide: _angular_forms__WEBPACK_IMPORTED_MODULE_4__.NG_VALUE_ACCESSOR,
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.forwardRef)(() => CKEditorComponent),
    multi: true
  }]), _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵNgOnChangesFeature"]],
  decls: 1,
  vars: 0,
  template: function CKEditorComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵtemplate"](0, CKEditorComponent_ng_template_0_Template, 0, 0, "ng-template");
    }
  },
  encapsulation: 2
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](CKEditorComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Component,
    args: [{
      selector: 'ckeditor',
      template: '<ng-template></ng-template>',
      // Integration with @angular/forms.
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_4__.NG_VALUE_ACCESSOR,
        // eslint-disable-next-line @typescript-eslint/no-use-before-define
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_2__.forwardRef)(() => CKEditorComponent),
        multi: true
      }]
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgZone
    }];
  }, {
    editor: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    config: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    tagName: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    watchdog: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    editorWatchdogConfig: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    disableTwoWayDataBinding: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Input
    }],
    ready: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }],
    change: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }],
    blur: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }],
    focus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }],
    error: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.Output
    }]
  });
})();
function hasObservers(emitter) {
  // Cast to `any` because `observed` property is available in RxJS >= 7.2.0.
  // Fallback to checking `observers` list if this property is not defined.
  return emitter.observed || emitter.observers.length > 0;
}

/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */
class CKEditorModule {}
CKEditorModule.ɵfac = function CKEditorModule_Factory(t) {
  return new (t || CKEditorModule)();
};
CKEditorModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineNgModule"]({
  type: CKEditorModule
});
CKEditorModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵɵdefineInjector"]({
  imports: [[_angular_forms__WEBPACK_IMPORTED_MODULE_4__.FormsModule, _angular_common__WEBPACK_IMPORTED_MODULE_5__.CommonModule]]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_2__["ɵsetClassMetadata"](CKEditorModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_2__.NgModule,
    args: [{
      imports: [_angular_forms__WEBPACK_IMPORTED_MODULE_4__.FormsModule, _angular_common__WEBPACK_IMPORTED_MODULE_5__.CommonModule],
      declarations: [CKEditorComponent],
      exports: [CKEditorComponent]
    }]
  }], null, null);
})();

/**
 * @license Copyright (c) 2003-2023, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 3110:
/*!**************************************************************************************!*\
  !*** ./node_modules/@ctrl/ngx-emoji-mart/fesm2022/ctrl-ngx-emoji-mart-ngx-emoji.mjs ***!
  \**************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   DEFAULT_BACKGROUNDFN: () => (/* binding */ DEFAULT_BACKGROUNDFN),
/* harmony export */   EmojiComponent: () => (/* binding */ EmojiComponent),
/* harmony export */   EmojiModule: () => (/* binding */ EmojiModule),
/* harmony export */   EmojiService: () => (/* binding */ EmojiService),
/* harmony export */   categories: () => (/* binding */ categories),
/* harmony export */   emojis: () => (/* binding */ emojis),
/* harmony export */   skins: () => (/* binding */ skins)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 36647);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 18537);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 59400);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 33900);





const _c0 = ["button"];
const _c1 = ["*", "*"];
function EmojiComponent_ng_template_0_button_0_ng_template_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.unified);
  }
}
function EmojiComponent_ng_template_0_button_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 4, 1)(2, "span", 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, EmojiComponent_ng_template_0_button_0_ng_template_3_Template, 1, 1, "ng-template", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("emoji-mart-emoji-native", ctx_r0.isNative)("emoji-mart-emoji-custom", ctx_r0.custom);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("title", ctx_r0.title)("aria-label", ctx_r0.label);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx_r0.style);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r0.isNative);
  }
}
function EmojiComponent_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, EmojiComponent_ng_template_0_button_0_Template, 5, 8, "button", 3);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const spanTpl_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r0.useButton)("ngIfElse", spanTpl_r2);
  }
}
function EmojiComponent_ng_template_1_ng_template_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.unified);
  }
}
function EmojiComponent_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 6, 1)(2, "span", 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, EmojiComponent_ng_template_1_ng_template_3_Template, 1, 1, "ng-template", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](4, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("emoji-mart-emoji-native", ctx_r0.isNative)("emoji-mart-emoji-custom", ctx_r0.custom);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("title", ctx_r0.title)("aria-label", ctx_r0.label);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx_r0.style);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r0.isNative);
  }
}
const categories = [{
  id: 'people',
  name: 'Smileys & People',
  emojis: ['1F600', '1F603', '1F604', '1F601', '1F606', '1F605', '1F923', '1F602', '1F642', '1F643', '1FAE0', '1F609', '1F60A', '1F607', '1F970', '1F60D', '1F929', '1F618', '1F617', '263A-FE0F', '1F61A', '1F619', '1F972', '1F60B', '1F61B', '1F61C', '1F92A', '1F61D', '1F911', '1F917', '1F92D', '1FAE2', '1FAE3', '1F92B', '1F914', '1FAE1', '1F910', '1F928', '1F610', '1F611', '1F636', '1FAE5', '1F636-200D-1F32B-FE0F', '1F60F', '1F612', '1F644', '1F62C', '1F62E-200D-1F4A8', '1F925', '1F60C', '1F614', '1F62A', '1F924', '1F634', '1F637', '1F912', '1F915', '1F922', '1F92E', '1F927', '1F975', '1F976', '1F974', '1F635', '1F635-200D-1F4AB', '1F92F', '1F920', '1F973', '1F978', '1F60E', '1F913', '1F9D0', '1F615', '1FAE4', '1F61F', '1F641', '2639-FE0F', '1F62E', '1F62F', '1F632', '1F633', '1F97A', '1F979', '1F626', '1F627', '1F628', '1F630', '1F625', '1F622', '1F62D', '1F631', '1F616', '1F623', '1F61E', '1F613', '1F629', '1F62B', '1F971', '1F624', '1F621', '1F620', '1F92C', '1F608', '1F47F', '1F480', '2620-FE0F', '1F4A9', '1F921', '1F479', '1F47A', '1F47B', '1F47D', '1F47E', '1F916', '1F44B', '1F91A', '1F590-FE0F', '270B', '1F596', '1FAF1', '1FAF2', '1FAF3', '1FAF4', '1F44C', '1F90C', '1F90F', '270C-FE0F', '1F91E', '1FAF0', '1F91F', '1F918', '1F919', '1F448', '1F449', '1F446', '1F595', '1F447', '261D-FE0F', '1FAF5', '1F44D', '1F44E', '270A', '1F44A', '1F91B', '1F91C', '1F44F', '1F64C', '1FAF6', '1F450', '1F932', '1F91D', '1F64F', '270D-FE0F', '1F485', '1F933', '1F4AA', '1F9BE', '1F9BF', '1F9B5', '1F9B6', '1F442', '1F9BB', '1F443', '1F9E0', '1FAC0', '1FAC1', '1F9B7', '1F9B4', '1F440', '1F441-FE0F', '1F445', '1F444', '1FAE6', '1F476', '1F9D2', '1F466', '1F467', '1F9D1', '1F471', '1F468', '1F9D4', '1F9D4-200D-2642-FE0F', '1F9D4-200D-2640-FE0F', '1F468-200D-1F9B0', '1F468-200D-1F9B1', '1F468-200D-1F9B3', '1F468-200D-1F9B2', '1F469', '1F469-200D-1F9B0', '1F9D1-200D-1F9B0', '1F469-200D-1F9B1', '1F9D1-200D-1F9B1', '1F469-200D-1F9B3', '1F9D1-200D-1F9B3', '1F469-200D-1F9B2', '1F9D1-200D-1F9B2', '1F471-200D-2640-FE0F', '1F471-200D-2642-FE0F', '1F9D3', '1F474', '1F475', '1F64D', '1F64D-200D-2642-FE0F', '1F64D-200D-2640-FE0F', '1F64E', '1F64E-200D-2642-FE0F', '1F64E-200D-2640-FE0F', '1F645', '1F645-200D-2642-FE0F', '1F645-200D-2640-FE0F', '1F646', '1F646-200D-2642-FE0F', '1F646-200D-2640-FE0F', '1F481', '1F481-200D-2642-FE0F', '1F481-200D-2640-FE0F', '1F64B', '1F64B-200D-2642-FE0F', '1F64B-200D-2640-FE0F', '1F9CF', '1F9CF-200D-2642-FE0F', '1F9CF-200D-2640-FE0F', '1F647', '1F647-200D-2642-FE0F', '1F647-200D-2640-FE0F', '1F926', '1F926-200D-2642-FE0F', '1F926-200D-2640-FE0F', '1F937', '1F937-200D-2642-FE0F', '1F937-200D-2640-FE0F', '1F9D1-200D-2695-FE0F', '1F468-200D-2695-FE0F', '1F469-200D-2695-FE0F', '1F9D1-200D-1F393', '1F468-200D-1F393', '1F469-200D-1F393', '1F9D1-200D-1F3EB', '1F468-200D-1F3EB', '1F469-200D-1F3EB', '1F9D1-200D-2696-FE0F', '1F468-200D-2696-FE0F', '1F469-200D-2696-FE0F', '1F9D1-200D-1F33E', '1F468-200D-1F33E', '1F469-200D-1F33E', '1F9D1-200D-1F373', '1F468-200D-1F373', '1F469-200D-1F373', '1F9D1-200D-1F527', '1F468-200D-1F527', '1F469-200D-1F527', '1F9D1-200D-1F3ED', '1F468-200D-1F3ED', '1F469-200D-1F3ED', '1F9D1-200D-1F4BC', '1F468-200D-1F4BC', '1F469-200D-1F4BC', '1F9D1-200D-1F52C', '1F468-200D-1F52C', '1F469-200D-1F52C', '1F9D1-200D-1F4BB', '1F468-200D-1F4BB', '1F469-200D-1F4BB', '1F9D1-200D-1F3A4', '1F468-200D-1F3A4', '1F469-200D-1F3A4', '1F9D1-200D-1F3A8', '1F468-200D-1F3A8', '1F469-200D-1F3A8', '1F9D1-200D-2708-FE0F', '1F468-200D-2708-FE0F', '1F469-200D-2708-FE0F', '1F9D1-200D-1F680', '1F468-200D-1F680', '1F469-200D-1F680', '1F9D1-200D-1F692', '1F468-200D-1F692', '1F469-200D-1F692', '1F46E', '1F46E-200D-2642-FE0F', '1F46E-200D-2640-FE0F', '1F575-FE0F', '1F575-FE0F-200D-2642-FE0F', '1F575-FE0F-200D-2640-FE0F', '1F482', '1F482-200D-2642-FE0F', '1F482-200D-2640-FE0F', '1F977', '1F477', '1F477-200D-2642-FE0F', '1F477-200D-2640-FE0F', '1FAC5', '1F934', '1F478', '1F473', '1F473-200D-2642-FE0F', '1F473-200D-2640-FE0F', '1F472', '1F9D5', '1F935', '1F935-200D-2642-FE0F', '1F935-200D-2640-FE0F', '1F470', '1F470-200D-2642-FE0F', '1F470-200D-2640-FE0F', '1F930', '1FAC3', '1FAC4', '1F931', '1F469-200D-1F37C', '1F468-200D-1F37C', '1F9D1-200D-1F37C', '1F47C', '1F385', '1F936', '1F9D1-200D-1F384', '1F9B8', '1F9B8-200D-2642-FE0F', '1F9B8-200D-2640-FE0F', '1F9B9', '1F9B9-200D-2642-FE0F', '1F9B9-200D-2640-FE0F', '1F9D9', '1F9D9-200D-2642-FE0F', '1F9D9-200D-2640-FE0F', '1F9DA', '1F9DA-200D-2642-FE0F', '1F9DA-200D-2640-FE0F', '1F9DB', '1F9DB-200D-2642-FE0F', '1F9DB-200D-2640-FE0F', '1F9DC', '1F9DC-200D-2642-FE0F', '1F9DC-200D-2640-FE0F', '1F9DD', '1F9DD-200D-2642-FE0F', '1F9DD-200D-2640-FE0F', '1F9DE', '1F9DE-200D-2642-FE0F', '1F9DE-200D-2640-FE0F', '1F9DF', '1F9DF-200D-2642-FE0F', '1F9DF-200D-2640-FE0F', '1F9CC', '1F486', '1F486-200D-2642-FE0F', '1F486-200D-2640-FE0F', '1F487', '1F487-200D-2642-FE0F', '1F487-200D-2640-FE0F', '1F6B6', '1F6B6-200D-2642-FE0F', '1F6B6-200D-2640-FE0F', '1F9CD', '1F9CD-200D-2642-FE0F', '1F9CD-200D-2640-FE0F', '1F9CE', '1F9CE-200D-2642-FE0F', '1F9CE-200D-2640-FE0F', '1F9D1-200D-1F9AF', '1F468-200D-1F9AF', '1F469-200D-1F9AF', '1F9D1-200D-1F9BC', '1F468-200D-1F9BC', '1F469-200D-1F9BC', '1F9D1-200D-1F9BD', '1F468-200D-1F9BD', '1F469-200D-1F9BD', '1F3C3', '1F3C3-200D-2642-FE0F', '1F3C3-200D-2640-FE0F', '1F483', '1F57A', '1F574-FE0F', '1F46F', '1F46F-200D-2642-FE0F', '1F46F-200D-2640-FE0F', '1F9D6', '1F9D6-200D-2642-FE0F', '1F9D6-200D-2640-FE0F', '1F9D7', '1F9D7-200D-2642-FE0F', '1F9D7-200D-2640-FE0F', '1F93A', '1F3C7', '26F7-FE0F', '1F3C2', '1F3CC-FE0F', '1F3CC-FE0F-200D-2642-FE0F', '1F3CC-FE0F-200D-2640-FE0F', '1F3C4', '1F3C4-200D-2642-FE0F', '1F3C4-200D-2640-FE0F', '1F6A3', '1F6A3-200D-2642-FE0F', '1F6A3-200D-2640-FE0F', '1F3CA', '1F3CA-200D-2642-FE0F', '1F3CA-200D-2640-FE0F', '26F9-FE0F', '26F9-FE0F-200D-2642-FE0F', '26F9-FE0F-200D-2640-FE0F', '1F3CB-FE0F', '1F3CB-FE0F-200D-2642-FE0F', '1F3CB-FE0F-200D-2640-FE0F', '1F6B4', '1F6B4-200D-2642-FE0F', '1F6B4-200D-2640-FE0F', '1F6B5', '1F6B5-200D-2642-FE0F', '1F6B5-200D-2640-FE0F', '1F938', '1F938-200D-2642-FE0F', '1F938-200D-2640-FE0F', '1F93C', '1F93C-200D-2642-FE0F', '1F93C-200D-2640-FE0F', '1F93D', '1F93D-200D-2642-FE0F', '1F93D-200D-2640-FE0F', '1F93E', '1F93E-200D-2642-FE0F', '1F93E-200D-2640-FE0F', '1F939', '1F939-200D-2642-FE0F', '1F939-200D-2640-FE0F', '1F9D8', '1F9D8-200D-2642-FE0F', '1F9D8-200D-2640-FE0F', '1F6C0', '1F6CC', '1F9D1-200D-1F91D-200D-1F9D1', '1F46D', '1F46B', '1F46C', '1F48F', '1F469-200D-2764-FE0F-200D-1F48B-200D-1F468', '1F468-200D-2764-FE0F-200D-1F48B-200D-1F468', '1F469-200D-2764-FE0F-200D-1F48B-200D-1F469', '1F491', '1F469-200D-2764-FE0F-200D-1F468', '1F468-200D-2764-FE0F-200D-1F468', '1F469-200D-2764-FE0F-200D-1F469', '1F46A', '1F468-200D-1F469-200D-1F466', '1F468-200D-1F469-200D-1F467', '1F468-200D-1F469-200D-1F467-200D-1F466', '1F468-200D-1F469-200D-1F466-200D-1F466', '1F468-200D-1F469-200D-1F467-200D-1F467', '1F468-200D-1F468-200D-1F466', '1F468-200D-1F468-200D-1F467', '1F468-200D-1F468-200D-1F467-200D-1F466', '1F468-200D-1F468-200D-1F466-200D-1F466', '1F468-200D-1F468-200D-1F467-200D-1F467', '1F469-200D-1F469-200D-1F466', '1F469-200D-1F469-200D-1F467', '1F469-200D-1F469-200D-1F467-200D-1F466', '1F469-200D-1F469-200D-1F466-200D-1F466', '1F469-200D-1F469-200D-1F467-200D-1F467', '1F468-200D-1F466', '1F468-200D-1F466-200D-1F466', '1F468-200D-1F467', '1F468-200D-1F467-200D-1F466', '1F468-200D-1F467-200D-1F467', '1F469-200D-1F466', '1F469-200D-1F466-200D-1F466', '1F469-200D-1F467', '1F469-200D-1F467-200D-1F466', '1F469-200D-1F467-200D-1F467', '1F5E3-FE0F', '1F464', '1F465', '1FAC2', '1F463', '1F63A', '1F638', '1F639', '1F63B', '1F63C', '1F63D', '1F640', '1F63F', '1F63E', '1F648', '1F649', '1F64A', '1F48B', '1F48C', '1F498', '1F49D', '1F496', '1F497', '1F493', '1F49E', '1F495', '1F49F', '2763-FE0F', '1F494', '2764-FE0F-200D-1F525', '2764-FE0F-200D-1FA79', '2764-FE0F', '1F9E1', '1F49B', '1F49A', '1F499', '1F49C', '1F90E', '1F5A4', '1F90D', '1F4AF', '1F4A2', '1F4A5', '1F4AB', '1F4A6', '1F4A8', '1F573-FE0F', '1F4A3', '1F4AC', '1F441-FE0F-200D-1F5E8-FE0F', '1F5E8-FE0F', '1F5EF-FE0F', '1F4AD', '1F4A4']
}, {
  id: 'nature',
  name: 'Animals & Nature',
  emojis: ['1F435', '1F412', '1F98D', '1F9A7', '1F436', '1F415', '1F9AE', '1F415-200D-1F9BA', '1F429', '1F43A', '1F98A', '1F99D', '1F431', '1F408', '1F408-200D-2B1B', '1F981', '1F42F', '1F405', '1F406', '1F434', '1F40E', '1F984', '1F993', '1F98C', '1F9AC', '1F42E', '1F402', '1F403', '1F404', '1F437', '1F416', '1F417', '1F43D', '1F40F', '1F411', '1F410', '1F42A', '1F42B', '1F999', '1F992', '1F418', '1F9A3', '1F98F', '1F99B', '1F42D', '1F401', '1F400', '1F439', '1F430', '1F407', '1F43F-FE0F', '1F9AB', '1F994', '1F987', '1F43B', '1F43B-200D-2744-FE0F', '1F428', '1F43C', '1F9A5', '1F9A6', '1F9A8', '1F998', '1F9A1', '1F43E', '1F983', '1F414', '1F413', '1F423', '1F424', '1F425', '1F426', '1F427', '1F54A-FE0F', '1F985', '1F986', '1F9A2', '1F989', '1F9A4', '1FAB6', '1F9A9', '1F99A', '1F99C', '1F438', '1F40A', '1F422', '1F98E', '1F40D', '1F432', '1F409', '1F995', '1F996', '1F433', '1F40B', '1F42C', '1F9AD', '1F41F', '1F420', '1F421', '1F988', '1F419', '1F41A', '1FAB8', '1F40C', '1F98B', '1F41B', '1F41C', '1F41D', '1FAB2', '1F41E', '1F997', '1FAB3', '1F577-FE0F', '1F578-FE0F', '1F982', '1F99F', '1FAB0', '1FAB1', '1F9A0', '1F490', '1F338', '1F4AE', '1FAB7', '1F3F5-FE0F', '1F339', '1F940', '1F33A', '1F33B', '1F33C', '1F337', '1F331', '1FAB4', '1F332', '1F333', '1F334', '1F335', '1F33E', '1F33F', '2618-FE0F', '1F340', '1F341', '1F342', '1F343', '1FAB9', '1FABA']
}, {
  id: 'foods',
  name: 'Food & Drink',
  emojis: ['1F347', '1F348', '1F349', '1F34A', '1F34B', '1F34C', '1F34D', '1F96D', '1F34E', '1F34F', '1F350', '1F351', '1F352', '1F353', '1FAD0', '1F95D', '1F345', '1FAD2', '1F965', '1F951', '1F346', '1F954', '1F955', '1F33D', '1F336-FE0F', '1FAD1', '1F952', '1F96C', '1F966', '1F9C4', '1F9C5', '1F344', '1F95C', '1FAD8', '1F330', '1F35E', '1F950', '1F956', '1FAD3', '1F968', '1F96F', '1F95E', '1F9C7', '1F9C0', '1F356', '1F357', '1F969', '1F953', '1F354', '1F35F', '1F355', '1F32D', '1F96A', '1F32E', '1F32F', '1FAD4', '1F959', '1F9C6', '1F95A', '1F373', '1F958', '1F372', '1FAD5', '1F963', '1F957', '1F37F', '1F9C8', '1F9C2', '1F96B', '1F371', '1F358', '1F359', '1F35A', '1F35B', '1F35C', '1F35D', '1F360', '1F362', '1F363', '1F364', '1F365', '1F96E', '1F361', '1F95F', '1F960', '1F961', '1F980', '1F99E', '1F990', '1F991', '1F9AA', '1F366', '1F367', '1F368', '1F369', '1F36A', '1F382', '1F370', '1F9C1', '1F967', '1F36B', '1F36C', '1F36D', '1F36E', '1F36F', '1F37C', '1F95B', '2615', '1FAD6', '1F375', '1F376', '1F37E', '1F377', '1F378', '1F379', '1F37A', '1F37B', '1F942', '1F943', '1FAD7', '1F964', '1F9CB', '1F9C3', '1F9C9', '1F9CA', '1F962', '1F37D-FE0F', '1F374', '1F944', '1F52A', '1FAD9', '1F3FA']
}, {
  id: 'activity',
  name: 'Activities',
  emojis: ['1F383', '1F384', '1F386', '1F387', '1F9E8', '2728', '1F388', '1F389', '1F38A', '1F38B', '1F38D', '1F38E', '1F38F', '1F390', '1F391', '1F9E7', '1F380', '1F381', '1F397-FE0F', '1F39F-FE0F', '1F3AB', '1F396-FE0F', '1F3C6', '1F3C5', '1F947', '1F948', '1F949', '26BD', '26BE', '1F94E', '1F3C0', '1F3D0', '1F3C8', '1F3C9', '1F3BE', '1F94F', '1F3B3', '1F3CF', '1F3D1', '1F3D2', '1F94D', '1F3D3', '1F3F8', '1F94A', '1F94B', '1F945', '26F3', '26F8-FE0F', '1F3A3', '1F93F', '1F3BD', '1F3BF', '1F6F7', '1F94C', '1F3AF', '1FA80', '1FA81', '1F3B1', '1F52E', '1FA84', '1F9FF', '1FAAC', '1F3AE', '1F579-FE0F', '1F3B0', '1F3B2', '1F9E9', '1F9F8', '1FA85', '1FAA9', '1FA86', '2660-FE0F', '2665-FE0F', '2666-FE0F', '2663-FE0F', '265F-FE0F', '1F0CF', '1F004', '1F3B4', '1F3AD', '1F5BC-FE0F', '1F3A8', '1F9F5', '1FAA1', '1F9F6', '1FAA2']
}, {
  id: 'places',
  name: 'Travel & Places',
  emojis: ['1F30D', '1F30E', '1F30F', '1F310', '1F5FA-FE0F', '1F5FE', '1F9ED', '1F3D4-FE0F', '26F0-FE0F', '1F30B', '1F5FB', '1F3D5-FE0F', '1F3D6-FE0F', '1F3DC-FE0F', '1F3DD-FE0F', '1F3DE-FE0F', '1F3DF-FE0F', '1F3DB-FE0F', '1F3D7-FE0F', '1F9F1', '1FAA8', '1FAB5', '1F6D6', '1F3D8-FE0F', '1F3DA-FE0F', '1F3E0', '1F3E1', '1F3E2', '1F3E3', '1F3E4', '1F3E5', '1F3E6', '1F3E8', '1F3E9', '1F3EA', '1F3EB', '1F3EC', '1F3ED', '1F3EF', '1F3F0', '1F492', '1F5FC', '1F5FD', '26EA', '1F54C', '1F6D5', '1F54D', '26E9-FE0F', '1F54B', '26F2', '26FA', '1F301', '1F303', '1F3D9-FE0F', '1F304', '1F305', '1F306', '1F307', '1F309', '2668-FE0F', '1F3A0', '1F6DD', '1F3A1', '1F3A2', '1F488', '1F3AA', '1F682', '1F683', '1F684', '1F685', '1F686', '1F687', '1F688', '1F689', '1F68A', '1F69D', '1F69E', '1F68B', '1F68C', '1F68D', '1F68E', '1F690', '1F691', '1F692', '1F693', '1F694', '1F695', '1F696', '1F697', '1F698', '1F699', '1F6FB', '1F69A', '1F69B', '1F69C', '1F3CE-FE0F', '1F3CD-FE0F', '1F6F5', '1F9BD', '1F9BC', '1F6FA', '1F6B2', '1F6F4', '1F6F9', '1F6FC', '1F68F', '1F6E3-FE0F', '1F6E4-FE0F', '1F6E2-FE0F', '26FD', '1F6DE', '1F6A8', '1F6A5', '1F6A6', '1F6D1', '1F6A7', '2693', '1F6DF', '26F5', '1F6F6', '1F6A4', '1F6F3-FE0F', '26F4-FE0F', '1F6E5-FE0F', '1F6A2', '2708-FE0F', '1F6E9-FE0F', '1F6EB', '1F6EC', '1FA82', '1F4BA', '1F681', '1F69F', '1F6A0', '1F6A1', '1F6F0-FE0F', '1F680', '1F6F8', '1F6CE-FE0F', '1F9F3', '231B', '23F3', '231A', '23F0', '23F1-FE0F', '23F2-FE0F', '1F570-FE0F', '1F55B', '1F567', '1F550', '1F55C', '1F551', '1F55D', '1F552', '1F55E', '1F553', '1F55F', '1F554', '1F560', '1F555', '1F561', '1F556', '1F562', '1F557', '1F563', '1F558', '1F564', '1F559', '1F565', '1F55A', '1F566', '1F311', '1F312', '1F313', '1F314', '1F315', '1F316', '1F317', '1F318', '1F319', '1F31A', '1F31B', '1F31C', '1F321-FE0F', '2600-FE0F', '1F31D', '1F31E', '1FA90', '2B50', '1F31F', '1F320', '1F30C', '2601-FE0F', '26C5', '26C8-FE0F', '1F324-FE0F', '1F325-FE0F', '1F326-FE0F', '1F327-FE0F', '1F328-FE0F', '1F329-FE0F', '1F32A-FE0F', '1F32B-FE0F', '1F32C-FE0F', '1F300', '1F308', '1F302', '2602-FE0F', '2614', '26F1-FE0F', '26A1', '2744-FE0F', '2603-FE0F', '26C4', '2604-FE0F', '1F525', '1F4A7', '1F30A']
}, {
  id: 'objects',
  name: 'Objects',
  emojis: ['1F453', '1F576-FE0F', '1F97D', '1F97C', '1F9BA', '1F454', '1F455', '1F456', '1F9E3', '1F9E4', '1F9E5', '1F9E6', '1F457', '1F458', '1F97B', '1FA71', '1FA72', '1FA73', '1F459', '1F45A', '1F45B', '1F45C', '1F45D', '1F6CD-FE0F', '1F392', '1FA74', '1F45E', '1F45F', '1F97E', '1F97F', '1F460', '1F461', '1FA70', '1F462', '1F451', '1F452', '1F3A9', '1F393', '1F9E2', '1FA96', '26D1-FE0F', '1F4FF', '1F484', '1F48D', '1F48E', '1F507', '1F508', '1F509', '1F50A', '1F4E2', '1F4E3', '1F4EF', '1F514', '1F515', '1F3BC', '1F3B5', '1F3B6', '1F399-FE0F', '1F39A-FE0F', '1F39B-FE0F', '1F3A4', '1F3A7', '1F4FB', '1F3B7', '1FA97', '1F3B8', '1F3B9', '1F3BA', '1F3BB', '1FA95', '1F941', '1FA98', '1F4F1', '1F4F2', '260E-FE0F', '1F4DE', '1F4DF', '1F4E0', '1F50B', '1FAAB', '1F50C', '1F4BB', '1F5A5-FE0F', '1F5A8-FE0F', '2328-FE0F', '1F5B1-FE0F', '1F5B2-FE0F', '1F4BD', '1F4BE', '1F4BF', '1F4C0', '1F9EE', '1F3A5', '1F39E-FE0F', '1F4FD-FE0F', '1F3AC', '1F4FA', '1F4F7', '1F4F8', '1F4F9', '1F4FC', '1F50D', '1F50E', '1F56F-FE0F', '1F4A1', '1F526', '1F3EE', '1FA94', '1F4D4', '1F4D5', '1F4D6', '1F4D7', '1F4D8', '1F4D9', '1F4DA', '1F4D3', '1F4D2', '1F4C3', '1F4DC', '1F4C4', '1F4F0', '1F5DE-FE0F', '1F4D1', '1F516', '1F3F7-FE0F', '1F4B0', '1FA99', '1F4B4', '1F4B5', '1F4B6', '1F4B7', '1F4B8', '1F4B3', '1F9FE', '1F4B9', '2709-FE0F', '1F4E7', '1F4E8', '1F4E9', '1F4E4', '1F4E5', '1F4E6', '1F4EB', '1F4EA', '1F4EC', '1F4ED', '1F4EE', '1F5F3-FE0F', '270F-FE0F', '2712-FE0F', '1F58B-FE0F', '1F58A-FE0F', '1F58C-FE0F', '1F58D-FE0F', '1F4DD', '1F4BC', '1F4C1', '1F4C2', '1F5C2-FE0F', '1F4C5', '1F4C6', '1F5D2-FE0F', '1F5D3-FE0F', '1F4C7', '1F4C8', '1F4C9', '1F4CA', '1F4CB', '1F4CC', '1F4CD', '1F4CE', '1F587-FE0F', '1F4CF', '1F4D0', '2702-FE0F', '1F5C3-FE0F', '1F5C4-FE0F', '1F5D1-FE0F', '1F512', '1F513', '1F50F', '1F510', '1F511', '1F5DD-FE0F', '1F528', '1FA93', '26CF-FE0F', '2692-FE0F', '1F6E0-FE0F', '1F5E1-FE0F', '2694-FE0F', '1F52B', '1FA83', '1F3F9', '1F6E1-FE0F', '1FA9A', '1F527', '1FA9B', '1F529', '2699-FE0F', '1F5DC-FE0F', '2696-FE0F', '1F9AF', '1F517', '26D3-FE0F', '1FA9D', '1F9F0', '1F9F2', '1FA9C', '2697-FE0F', '1F9EA', '1F9EB', '1F9EC', '1F52C', '1F52D', '1F4E1', '1F489', '1FA78', '1F48A', '1FA79', '1FA7C', '1FA7A', '1FA7B', '1F6AA', '1F6D7', '1FA9E', '1FA9F', '1F6CF-FE0F', '1F6CB-FE0F', '1FA91', '1F6BD', '1FAA0', '1F6BF', '1F6C1', '1FAA4', '1FA92', '1F9F4', '1F9F7', '1F9F9', '1F9FA', '1F9FB', '1FAA3', '1F9FC', '1FAE7', '1FAA5', '1F9FD', '1F9EF', '1F6D2', '1F6AC', '26B0-FE0F', '1FAA6', '26B1-FE0F', '1F5FF', '1FAA7', '1FAAA']
}, {
  id: 'symbols',
  name: 'Symbols',
  emojis: ['1F3E7', '1F6AE', '1F6B0', '267F', '1F6B9', '1F6BA', '1F6BB', '1F6BC', '1F6BE', '1F6C2', '1F6C3', '1F6C4', '1F6C5', '26A0-FE0F', '1F6B8', '26D4', '1F6AB', '1F6B3', '1F6AD', '1F6AF', '1F6B1', '1F6B7', '1F4F5', '1F51E', '2622-FE0F', '2623-FE0F', '2B06-FE0F', '2197-FE0F', '27A1-FE0F', '2198-FE0F', '2B07-FE0F', '2199-FE0F', '2B05-FE0F', '2196-FE0F', '2195-FE0F', '2194-FE0F', '21A9-FE0F', '21AA-FE0F', '2934-FE0F', '2935-FE0F', '1F503', '1F504', '1F519', '1F51A', '1F51B', '1F51C', '1F51D', '1F6D0', '269B-FE0F', '1F549-FE0F', '2721-FE0F', '2638-FE0F', '262F-FE0F', '271D-FE0F', '2626-FE0F', '262A-FE0F', '262E-FE0F', '1F54E', '1F52F', '2648', '2649', '264A', '264B', '264C', '264D', '264E', '264F', '2650', '2651', '2652', '2653', '26CE', '1F500', '1F501', '1F502', '25B6-FE0F', '23E9', '23ED-FE0F', '23EF-FE0F', '25C0-FE0F', '23EA', '23EE-FE0F', '1F53C', '23EB', '1F53D', '23EC', '23F8-FE0F', '23F9-FE0F', '23FA-FE0F', '23CF-FE0F', '1F3A6', '1F505', '1F506', '1F4F6', '1F4F3', '1F4F4', '2640-FE0F', '2642-FE0F', '26A7-FE0F', '2716-FE0F', '2795', '2796', '2797', '1F7F0', '267E-FE0F', '203C-FE0F', '2049-FE0F', '2753', '2754', '2755', '2757', '3030-FE0F', '1F4B1', '1F4B2', '2695-FE0F', '267B-FE0F', '269C-FE0F', '1F531', '1F4DB', '1F530', '2B55', '2705', '2611-FE0F', '2714-FE0F', '274C', '274E', '27B0', '27BF', '303D-FE0F', '2733-FE0F', '2734-FE0F', '2747-FE0F', '00A9-FE0F', '00AE-FE0F', '2122-FE0F', '0023-FE0F-20E3', '002A-FE0F-20E3', '0030-FE0F-20E3', '0031-FE0F-20E3', '0032-FE0F-20E3', '0033-FE0F-20E3', '0034-FE0F-20E3', '0035-FE0F-20E3', '0036-FE0F-20E3', '0037-FE0F-20E3', '0038-FE0F-20E3', '0039-FE0F-20E3', '1F51F', '1F520', '1F521', '1F522', '1F523', '1F524', '1F170-FE0F', '1F18E', '1F171-FE0F', '1F191', '1F192', '1F193', '2139-FE0F', '1F194', '24C2-FE0F', '1F195', '1F196', '1F17E-FE0F', '1F197', '1F17F-FE0F', '1F198', '1F199', '1F19A', '1F201', '1F202-FE0F', '1F237-FE0F', '1F236', '1F22F', '1F250', '1F239', '1F21A', '1F232', '1F251', '1F238', '1F234', '1F233', '3297-FE0F', '3299-FE0F', '1F23A', '1F235', '1F534', '1F7E0', '1F7E1', '1F7E2', '1F535', '1F7E3', '1F7E4', '26AB', '26AA', '1F7E5', '1F7E7', '1F7E8', '1F7E9', '1F7E6', '1F7EA', '1F7EB', '2B1B', '2B1C', '25FC-FE0F', '25FB-FE0F', '25FE', '25FD', '25AA-FE0F', '25AB-FE0F', '1F536', '1F537', '1F538', '1F539', '1F53A', '1F53B', '1F4A0', '1F518', '1F533', '1F532']
}, {
  id: 'flags',
  name: 'Flags',
  emojis: ['1F1E6-1F1E8', '1F1E6-1F1E9', '1F1E6-1F1EA', '1F1E6-1F1EB', '1F1E6-1F1EC', '1F1E6-1F1EE', '1F1E6-1F1F1', '1F1E6-1F1F2', '1F1E6-1F1F4', '1F1E6-1F1F6', '1F1E6-1F1F7', '1F1E6-1F1F8', '1F1E6-1F1F9', '1F1E6-1F1FA', '1F1E6-1F1FC', '1F1E6-1F1FD', '1F1E6-1F1FF', '1F1E7-1F1E6', '1F1E7-1F1E7', '1F1E7-1F1E9', '1F1E7-1F1EA', '1F1E7-1F1EB', '1F1E7-1F1EC', '1F1E7-1F1ED', '1F1E7-1F1EE', '1F1E7-1F1EF', '1F1E7-1F1F1', '1F1E7-1F1F2', '1F1E7-1F1F3', '1F1E7-1F1F4', '1F1E7-1F1F6', '1F1E7-1F1F7', '1F1E7-1F1F8', '1F1E7-1F1F9', '1F1E7-1F1FB', '1F1E7-1F1FC', '1F1E7-1F1FE', '1F1E7-1F1FF', '1F1E8-1F1E6', '1F1E8-1F1E8', '1F1E8-1F1E9', '1F1E8-1F1EB', '1F1E8-1F1EC', '1F1E8-1F1ED', '1F1E8-1F1EE', '1F1E8-1F1F0', '1F1E8-1F1F1', '1F1E8-1F1F2', '1F1E8-1F1F3', '1F1E8-1F1F4', '1F1E8-1F1F5', '1F1E8-1F1F7', '1F1E8-1F1FA', '1F1E8-1F1FB', '1F1E8-1F1FC', '1F1E8-1F1FD', '1F1E8-1F1FE', '1F1E8-1F1FF', '1F1E9-1F1EA', '1F1E9-1F1EC', '1F1E9-1F1EF', '1F1E9-1F1F0', '1F1E9-1F1F2', '1F1E9-1F1F4', '1F1E9-1F1FF', '1F1EA-1F1E6', '1F1EA-1F1E8', '1F1EA-1F1EA', '1F1EA-1F1EC', '1F1EA-1F1ED', '1F1EA-1F1F7', '1F1EA-1F1F8', '1F1EA-1F1F9', '1F1EA-1F1FA', '1F1EB-1F1EE', '1F1EB-1F1EF', '1F1EB-1F1F0', '1F1EB-1F1F2', '1F1EB-1F1F4', '1F1EB-1F1F7', '1F1EC-1F1E6', '1F1EC-1F1E7', '1F1EC-1F1E9', '1F1EC-1F1EA', '1F1EC-1F1EB', '1F1EC-1F1EC', '1F1EC-1F1ED', '1F1EC-1F1EE', '1F1EC-1F1F1', '1F1EC-1F1F2', '1F1EC-1F1F3', '1F1EC-1F1F5', '1F1EC-1F1F6', '1F1EC-1F1F7', '1F1EC-1F1F8', '1F1EC-1F1F9', '1F1EC-1F1FA', '1F1EC-1F1FC', '1F1EC-1F1FE', '1F1ED-1F1F0', '1F1ED-1F1F2', '1F1ED-1F1F3', '1F1ED-1F1F7', '1F1ED-1F1F9', '1F1ED-1F1FA', '1F1EE-1F1E8', '1F1EE-1F1E9', '1F1EE-1F1EA', '1F1EE-1F1F1', '1F1EE-1F1F2', '1F1EE-1F1F3', '1F1EE-1F1F4', '1F1EE-1F1F6', '1F1EE-1F1F7', '1F1EE-1F1F8', '1F1EE-1F1F9', '1F1EF-1F1EA', '1F1EF-1F1F2', '1F1EF-1F1F4', '1F1EF-1F1F5', '1F1F0-1F1EA', '1F1F0-1F1EC', '1F1F0-1F1ED', '1F1F0-1F1EE', '1F1F0-1F1F2', '1F1F0-1F1F3', '1F1F0-1F1F5', '1F1F0-1F1F7', '1F1F0-1F1FC', '1F1F0-1F1FE', '1F1F0-1F1FF', '1F1F1-1F1E6', '1F1F1-1F1E7', '1F1F1-1F1E8', '1F1F1-1F1EE', '1F1F1-1F1F0', '1F1F1-1F1F7', '1F1F1-1F1F8', '1F1F1-1F1F9', '1F1F1-1F1FA', '1F1F1-1F1FB', '1F1F1-1F1FE', '1F1F2-1F1E6', '1F1F2-1F1E8', '1F1F2-1F1E9', '1F1F2-1F1EA', '1F1F2-1F1EB', '1F1F2-1F1EC', '1F1F2-1F1ED', '1F1F2-1F1F0', '1F1F2-1F1F1', '1F1F2-1F1F2', '1F1F2-1F1F3', '1F1F2-1F1F4', '1F1F2-1F1F5', '1F1F2-1F1F6', '1F1F2-1F1F7', '1F1F2-1F1F8', '1F1F2-1F1F9', '1F1F2-1F1FA', '1F1F2-1F1FB', '1F1F2-1F1FC', '1F1F2-1F1FD', '1F1F2-1F1FE', '1F1F2-1F1FF', '1F1F3-1F1E6', '1F1F3-1F1E8', '1F1F3-1F1EA', '1F1F3-1F1EB', '1F1F3-1F1EC', '1F1F3-1F1EE', '1F1F3-1F1F1', '1F1F3-1F1F4', '1F1F3-1F1F5', '1F1F3-1F1F7', '1F1F3-1F1FA', '1F1F3-1F1FF', '1F1F4-1F1F2', '1F1F5-1F1E6', '1F1F5-1F1EA', '1F1F5-1F1EB', '1F1F5-1F1EC', '1F1F5-1F1ED', '1F1F5-1F1F0', '1F1F5-1F1F1', '1F1F5-1F1F2', '1F1F5-1F1F3', '1F1F5-1F1F7', '1F1F5-1F1F8', '1F1F5-1F1F9', '1F1F5-1F1FC', '1F1F5-1F1FE', '1F1F6-1F1E6', '1F1F7-1F1EA', '1F1F7-1F1F4', '1F1F7-1F1F8', '1F1F7-1F1FA', '1F1F7-1F1FC', '1F1F8-1F1E6', '1F1F8-1F1E7', '1F1F8-1F1E8', '1F1F8-1F1E9', '1F1F8-1F1EA', '1F1F8-1F1EC', '1F1F8-1F1ED', '1F1F8-1F1EE', '1F1F8-1F1EF', '1F1F8-1F1F0', '1F1F8-1F1F1', '1F1F8-1F1F2', '1F1F8-1F1F3', '1F1F8-1F1F4', '1F1F8-1F1F7', '1F1F8-1F1F8', '1F1F8-1F1F9', '1F1F8-1F1FB', '1F1F8-1F1FD', '1F1F8-1F1FE', '1F1F8-1F1FF', '1F1F9-1F1E6', '1F1F9-1F1E8', '1F1F9-1F1E9', '1F1F9-1F1EB', '1F1F9-1F1EC', '1F1F9-1F1ED', '1F1F9-1F1EF', '1F1F9-1F1F0', '1F1F9-1F1F1', '1F1F9-1F1F2', '1F1F9-1F1F3', '1F1F9-1F1F4', '1F1F9-1F1F7', '1F1F9-1F1F9', '1F1F9-1F1FB', '1F1F9-1F1FC', '1F1F9-1F1FF', '1F1FA-1F1E6', '1F1FA-1F1EC', '1F1FA-1F1F2', '1F1FA-1F1F3', '1F1FA-1F1F8', '1F1FA-1F1FE', '1F1FA-1F1FF', '1F1FB-1F1E6', '1F1FB-1F1E8', '1F1FB-1F1EA', '1F1FB-1F1EC', '1F1FB-1F1EE', '1F1FB-1F1F3', '1F1FB-1F1FA', '1F1FC-1F1EB', '1F1FC-1F1F8', '1F1FD-1F1F0', '1F1FE-1F1EA', '1F1FE-1F1F9', '1F1FF-1F1E6', '1F1FF-1F1F2', '1F1FF-1F1FC', '1F38C', '1F3C1', '1F3F3-FE0F', '1F3F3-FE0F-200D-1F308', '1F3F3-FE0F-200D-26A7-FE0F', '1F3F4', '1F3F4-200D-2620-FE0F', '1F3F4-E0067-E0062-E0065-E006E-E0067-E007F', '1F3F4-E0067-E0062-E0073-E0063-E0074-E007F', '1F3F4-E0067-E0062-E0077-E006C-E0073-E007F', '1F6A9']
}];
const emojis = [{
  name: 'Grinning Face',
  unified: '1F600',
  text: ':D',
  keywords: ['grinning_face', 'face', 'smile', 'happy', 'joy', ':D', 'grin'],
  sheet: [32, 20],
  shortName: 'grinning'
}, {
  name: 'Smiling Face with Open Mouth',
  unified: '1F603',
  text: ':)',
  emoticons: ['=)', '=-)'],
  keywords: ['grinning_face_with_big_eyes', 'face', 'happy', 'joy', 'haha', ':D', ':)', 'smile', 'funny'],
  sheet: [32, 23],
  shortName: 'smiley'
}, {
  name: 'Smiling Face with Open Mouth and Smiling Eyes',
  unified: '1F604',
  text: ':)',
  emoticons: ['C:', 'c:', ':D', ':-D'],
  keywords: ['grinning_face_with_smiling_eyes', 'face', 'happy', 'joy', 'funny', 'haha', 'laugh', 'like', ':D', ':)', 'smile'],
  sheet: [32, 24],
  shortName: 'smile'
}, {
  name: 'Grinning Face with Smiling Eyes',
  unified: '1F601',
  keywords: ['beaming_face_with_smiling_eyes', 'face', 'happy', 'smile', 'joy', 'kawaii'],
  sheet: [32, 21],
  shortName: 'grin'
}, {
  name: 'Smiling Face with Open Mouth and Tightly-Closed Eyes',
  unified: '1F606',
  emoticons: [':>', ':->'],
  keywords: ['grinning_squinting_face', 'happy', 'joy', 'lol', 'satisfied', 'haha', 'face', 'glad', 'XD', 'laugh'],
  sheet: [32, 26],
  shortNames: ['satisfied'],
  shortName: 'laughing'
}, {
  name: 'Smiling Face with Open Mouth and Cold Sweat',
  unified: '1F605',
  keywords: ['grinning_face_with_sweat', 'face', 'hot', 'happy', 'laugh', 'sweat', 'smile', 'relief'],
  sheet: [32, 25],
  shortName: 'sweat_smile'
}, {
  name: 'Rolling on the Floor Laughing',
  unified: '1F923',
  keywords: ['rolling_on_the_floor_laughing', 'face', 'rolling', 'floor', 'laughing', 'lol', 'haha', 'rofl'],
  sheet: [40, 15],
  shortName: 'rolling_on_the_floor_laughing'
}, {
  name: 'Face with Tears of Joy',
  unified: '1F602',
  keywords: ['face_with_tears_of_joy', 'face', 'cry', 'tears', 'weep', 'happy', 'happytears', 'haha'],
  sheet: [32, 22],
  shortName: 'joy'
}, {
  name: 'Slightly Smiling Face',
  unified: '1F642',
  emoticons: [':)', '(:', ':-)'],
  keywords: ['slightly_smiling_face', 'face', 'smile'],
  sheet: [33, 28],
  shortName: 'slightly_smiling_face'
}, {
  name: 'Upside-Down Face',
  unified: '1F643',
  keywords: ['upside_down_face', 'face', 'flipped', 'silly', 'smile'],
  sheet: [33, 29],
  shortName: 'upside_down_face'
}, {
  name: 'Melting Face',
  unified: '1FAE0',
  keywords: ['melting face', 'hot', 'heat'],
  sheet: [55, 12],
  hidden: ['facebook'],
  shortName: 'melting_face'
}, {
  name: 'Winking Face',
  unified: '1F609',
  text: ';)',
  emoticons: [';)', ';-)'],
  keywords: ['winking_face', 'face', 'happy', 'mischievous', 'secret', ';)', 'smile', 'eye'],
  sheet: [32, 29],
  shortName: 'wink'
}, {
  name: 'Smiling Face with Smiling Eyes',
  unified: '1F60A',
  text: ':)',
  keywords: ['smiling_face_with_smiling_eyes', 'face', 'smile', 'happy', 'flushed', 'crush', 'embarrassed', 'shy', 'joy'],
  sheet: [32, 30],
  shortName: 'blush'
}, {
  name: 'Smiling Face with Halo',
  unified: '1F607',
  keywords: ['smiling_face_with_halo', 'face', 'angel', 'heaven', 'halo', 'innocent'],
  sheet: [32, 27],
  shortName: 'innocent'
}, {
  name: 'Smiling Face with Smiling Eyes and Three Hearts',
  unified: '1F970',
  keywords: ['smiling_face_with_hearts', 'face', 'love', 'like', 'affection', 'valentines', 'infatuation', 'crush', 'hearts', 'adore'],
  sheet: [43, 58],
  shortName: 'smiling_face_with_3_hearts'
}, {
  name: 'Smiling Face with Heart-Shaped Eyes',
  unified: '1F60D',
  keywords: ['smiling_face_with_heart_eyes', 'face', 'love', 'like', 'affection', 'valentines', 'infatuation', 'crush', 'heart'],
  sheet: [32, 33],
  shortName: 'heart_eyes'
}, {
  name: 'Grinning Face with Star Eyes',
  unified: '1F929',
  keywords: ['star_struck', 'face', 'smile', 'starry', 'eyes', 'grinning'],
  sheet: [40, 38],
  shortNames: ['grinning_face_with_star_eyes'],
  shortName: 'star-struck'
}, {
  name: 'Face Throwing a Kiss',
  unified: '1F618',
  emoticons: [':*', ':-*'],
  keywords: ['face_blowing_a_kiss', 'face', 'love', 'like', 'affection', 'valentines', 'infatuation', 'kiss'],
  sheet: [32, 44],
  shortName: 'kissing_heart'
}, {
  name: 'Kissing Face',
  unified: '1F617',
  keywords: ['kissing_face', 'love', 'like', 'face', '3', 'valentines', 'infatuation', 'kiss'],
  sheet: [32, 43],
  shortName: 'kissing'
}, {
  name: 'White Smiling Face',
  unified: '263A-FE0F',
  keywords: ['smiling_face', 'face', 'blush', 'massage', 'happiness'],
  sheet: [57, 4],
  shortName: 'relaxed'
}, {
  name: 'Kissing Face with Closed Eyes',
  unified: '1F61A',
  keywords: ['kissing_face_with_closed_eyes', 'face', 'love', 'like', 'affection', 'valentines', 'infatuation', 'kiss'],
  sheet: [32, 46],
  shortName: 'kissing_closed_eyes'
}, {
  name: 'Kissing Face with Smiling Eyes',
  unified: '1F619',
  keywords: ['kissing_face_with_smiling_eyes', 'face', 'affection', 'valentines', 'infatuation', 'kiss'],
  sheet: [32, 45],
  shortName: 'kissing_smiling_eyes'
}, {
  name: 'Smiling Face with Tear',
  unified: '1F972',
  keywords: ['smiling face with tear', 'sad', 'cry', 'pretend'],
  sheet: [43, 60],
  shortName: 'smiling_face_with_tear'
}, {
  name: 'Face Savouring Delicious Food',
  unified: '1F60B',
  keywords: ['face_savoring_food', 'happy', 'joy', 'tongue', 'smile', 'face', 'silly', 'yummy', 'nom', 'delicious', 'savouring'],
  sheet: [32, 31],
  shortName: 'yum'
}, {
  name: 'Face with Stuck-out Tongue',
  unified: '1F61B',
  text: ':p',
  emoticons: [':p', ':-p', ':P', ':-P', ':b', ':-b'],
  keywords: ['face_with_tongue', 'face', 'prank', 'childish', 'playful', 'mischievous', 'smile', 'tongue'],
  sheet: [32, 47],
  shortName: 'stuck_out_tongue'
}, {
  name: 'Face with Stuck-out Tongue and Winking Eye',
  unified: '1F61C',
  text: ';p',
  emoticons: [';p', ';-p', ';b', ';-b', ';P', ';-P'],
  keywords: ['winking_face_with_tongue', 'face', 'prank', 'childish', 'playful', 'mischievous', 'smile', 'wink', 'tongue'],
  sheet: [32, 48],
  shortName: 'stuck_out_tongue_winking_eye'
}, {
  name: 'Grinning Face with One Large and One Small Eye',
  unified: '1F92A',
  keywords: ['zany_face', 'face', 'goofy', 'crazy'],
  sheet: [40, 39],
  shortNames: ['grinning_face_with_one_large_and_one_small_eye'],
  shortName: 'zany_face'
}, {
  name: 'Face with Stuck-out Tongue and Tightly-Closed Eyes',
  unified: '1F61D',
  keywords: ['squinting_face_with_tongue', 'face', 'prank', 'playful', 'mischievous', 'smile', 'tongue'],
  sheet: [32, 49],
  shortName: 'stuck_out_tongue_closed_eyes'
}, {
  name: 'Money-Mouth Face',
  unified: '1F911',
  keywords: ['money_mouth_face', 'face', 'rich', 'dollar', 'money'],
  sheet: [38, 59],
  shortName: 'money_mouth_face'
}, {
  name: 'Hugging Face',
  unified: '1F917',
  keywords: ['hugging_face', 'face', 'smile', 'hug'],
  sheet: [39, 4],
  shortName: 'hugging_face'
}, {
  name: 'Smiling Face with Smiling Eyes and Hand Covering Mouth',
  unified: '1F92D',
  keywords: ['face_with_hand_over_mouth', 'face', 'whoops', 'shock', 'surprise'],
  sheet: [40, 42],
  shortNames: ['smiling_face_with_smiling_eyes_and_hand_covering_mouth'],
  shortName: 'face_with_hand_over_mouth'
}, {
  name: 'Face with Open Eyes and Hand over Mouth',
  unified: '1FAE2',
  keywords: ['face with open eyes and hand over mouth', 'silence', 'secret', 'shock', 'surprise'],
  sheet: [55, 14],
  hidden: ['facebook'],
  shortName: 'face_with_open_eyes_and_hand_over_mouth'
}, {
  name: 'Face with Peeking Eye',
  unified: '1FAE3',
  keywords: ['face with peeking eye', 'scared', 'frightening', 'embarrassing', 'shy'],
  sheet: [55, 15],
  hidden: ['facebook'],
  shortName: 'face_with_peeking_eye'
}, {
  name: 'Face with Finger Covering Closed Lips',
  unified: '1F92B',
  keywords: ['shushing_face', 'face', 'quiet', 'shhh'],
  sheet: [40, 40],
  shortNames: ['face_with_finger_covering_closed_lips'],
  shortName: 'shushing_face'
}, {
  name: 'Thinking Face',
  unified: '1F914',
  keywords: ['thinking_face', 'face', 'hmmm', 'think', 'consider'],
  sheet: [39, 1],
  shortName: 'thinking_face'
}, {
  name: 'Saluting Face',
  unified: '1FAE1',
  keywords: ['saluting face', 'respect', 'salute'],
  sheet: [55, 13],
  hidden: ['facebook'],
  shortName: 'saluting_face'
}, {
  name: 'Zipper-Mouth Face',
  unified: '1F910',
  keywords: ['zipper_mouth_face', 'face', 'sealed', 'zipper', 'secret'],
  sheet: [38, 58],
  shortName: 'zipper_mouth_face'
}, {
  name: 'Face with One Eyebrow Raised',
  unified: '1F928',
  keywords: ['face_with_raised_eyebrow', 'face', 'distrust', 'scepticism', 'disapproval', 'disbelief', 'surprise'],
  sheet: [40, 37],
  shortNames: ['face_with_one_eyebrow_raised'],
  shortName: 'face_with_raised_eyebrow'
}, {
  name: 'Neutral Face',
  unified: '1F610',
  emoticons: [':|', ':-|'],
  keywords: ['neutral_face', 'indifference', 'meh', ':|', 'neutral'],
  sheet: [32, 36],
  shortName: 'neutral_face'
}, {
  name: 'Expressionless Face',
  unified: '1F611',
  keywords: ['expressionless_face', 'face', 'indifferent', '-_-', 'meh', 'deadpan'],
  sheet: [32, 37],
  shortName: 'expressionless'
}, {
  name: 'Face Without Mouth',
  unified: '1F636',
  keywords: ['face_without_mouth', 'face', 'hellokitty'],
  sheet: [33, 16],
  shortName: 'no_mouth'
}, {
  name: 'Dotted Line Face',
  unified: '1FAE5',
  keywords: ['dotted line face', 'invisible', 'lonely', 'isolation', 'depression'],
  sheet: [55, 17],
  hidden: ['facebook'],
  shortName: 'dotted_line_face'
}, {
  name: 'Face in Clouds',
  unified: '1F636-200D-1F32B-FE0F',
  keywords: ['face in clouds', 'shower', 'steam', 'dream'],
  sheet: [33, 15],
  hidden: ['facebook'],
  shortName: 'face_in_clouds'
}, {
  name: 'Smirking Face',
  unified: '1F60F',
  keywords: ['smirking_face', 'face', 'smile', 'mean', 'prank', 'smug', 'sarcasm'],
  sheet: [32, 35],
  shortName: 'smirk'
}, {
  name: 'Unamused Face',
  unified: '1F612',
  text: ':(',
  keywords: ['unamused_face', 'indifference', 'bored', 'straight face', 'serious', 'sarcasm', 'unimpressed', 'skeptical', 'dubious', 'side_eye'],
  sheet: [32, 38],
  shortName: 'unamused'
}, {
  name: 'Face with Rolling Eyes',
  unified: '1F644',
  keywords: ['face_with_rolling_eyes', 'face', 'eyeroll', 'frustrated'],
  sheet: [33, 30],
  shortName: 'face_with_rolling_eyes'
}, {
  name: 'Grimacing Face',
  unified: '1F62C',
  keywords: ['grimacing_face', 'face', 'grimace', 'teeth'],
  sheet: [33, 3],
  shortName: 'grimacing'
}, {
  name: 'Face Exhaling',
  unified: '1F62E-200D-1F4A8',
  keywords: ['face exhaling', 'relieve', 'relief', 'tired', 'sigh'],
  sheet: [33, 5],
  hidden: ['facebook'],
  shortName: 'face_exhaling'
}, {
  name: 'Lying Face',
  unified: '1F925',
  keywords: ['lying_face', 'face', 'lie', 'pinocchio'],
  sheet: [40, 17],
  shortName: 'lying_face'
}, {
  name: 'Relieved Face',
  unified: '1F60C',
  keywords: ['relieved_face', 'face', 'relaxed', 'phew', 'massage', 'happiness'],
  sheet: [32, 32],
  shortName: 'relieved'
}, {
  name: 'Pensive Face',
  unified: '1F614',
  keywords: ['pensive_face', 'face', 'sad', 'depressed', 'upset'],
  sheet: [32, 40],
  shortName: 'pensive'
}, {
  name: 'Sleepy Face',
  unified: '1F62A',
  keywords: ['sleepy_face', 'face', 'tired', 'rest', 'nap'],
  sheet: [33, 1],
  shortName: 'sleepy'
}, {
  name: 'Drooling Face',
  unified: '1F924',
  keywords: ['drooling_face', 'face'],
  sheet: [40, 16],
  shortName: 'drooling_face'
}, {
  name: 'Sleeping Face',
  unified: '1F634',
  keywords: ['sleeping_face', 'face', 'tired', 'sleepy', 'night', 'zzz'],
  sheet: [33, 12],
  shortName: 'sleeping'
}, {
  name: 'Face with Medical Mask',
  unified: '1F637',
  keywords: ['face_with_medical_mask', 'face', 'sick', 'ill', 'disease', 'covid'],
  sheet: [33, 17],
  shortName: 'mask'
}, {
  name: 'Face with Thermometer',
  unified: '1F912',
  keywords: ['face_with_thermometer', 'sick', 'temperature', 'thermometer', 'cold', 'fever', 'covid'],
  sheet: [38, 60],
  shortName: 'face_with_thermometer'
}, {
  name: 'Face with Head-Bandage',
  unified: '1F915',
  keywords: ['face_with_head_bandage', 'injured', 'clumsy', 'bandage', 'hurt'],
  sheet: [39, 2],
  shortName: 'face_with_head_bandage'
}, {
  name: 'Nauseated Face',
  unified: '1F922',
  keywords: ['nauseated_face', 'face', 'vomit', 'gross', 'green', 'sick', 'throw up', 'ill'],
  sheet: [40, 14],
  shortName: 'nauseated_face'
}, {
  name: 'Face with Open Mouth Vomiting',
  unified: '1F92E',
  keywords: ['face_vomiting', 'face', 'sick'],
  sheet: [40, 43],
  shortNames: ['face_with_open_mouth_vomiting'],
  shortName: 'face_vomiting'
}, {
  name: 'Sneezing Face',
  unified: '1F927',
  keywords: ['sneezing_face', 'face', 'gesundheit', 'sneeze', 'sick', 'allergy'],
  sheet: [40, 36],
  shortName: 'sneezing_face'
}, {
  name: 'Overheated Face',
  unified: '1F975',
  keywords: ['hot_face', 'face', 'feverish', 'heat', 'red', 'sweating'],
  sheet: [44, 2],
  shortName: 'hot_face'
}, {
  name: 'Freezing Face',
  unified: '1F976',
  keywords: ['cold_face', 'face', 'blue', 'freezing', 'frozen', 'frostbite', 'icicles'],
  sheet: [44, 3],
  shortName: 'cold_face'
}, {
  name: 'Face with Uneven Eyes and Wavy Mouth',
  unified: '1F974',
  keywords: ['woozy_face', 'face', 'dizzy', 'intoxicated', 'tipsy', 'wavy'],
  sheet: [44, 1],
  shortName: 'woozy_face'
}, {
  name: 'Dizzy Face',
  unified: '1F635',
  keywords: ['dizzy_face', 'spent', 'unconscious', 'xox', 'dizzy'],
  sheet: [33, 14],
  shortName: 'dizzy_face'
}, {
  name: 'Face with Spiral Eyes',
  unified: '1F635-200D-1F4AB',
  keywords: ['face with spiral eyes', 'sick', 'ill', 'confused', 'nauseous', 'nausea'],
  sheet: [33, 13],
  hidden: ['facebook'],
  shortName: 'face_with_spiral_eyes'
}, {
  name: 'Shocked Face with Exploding Head',
  unified: '1F92F',
  keywords: ['exploding_head', 'face', 'shocked', 'mind', 'blown'],
  sheet: [40, 44],
  shortNames: ['shocked_face_with_exploding_head'],
  shortName: 'exploding_head'
}, {
  name: 'Face with Cowboy Hat',
  unified: '1F920',
  keywords: ['cowboy_hat_face', 'face', 'cowgirl', 'hat'],
  sheet: [40, 12],
  shortName: 'face_with_cowboy_hat'
}, {
  name: 'Face with Party Horn and Party Hat',
  unified: '1F973',
  keywords: ['partying_face', 'face', 'celebration', 'woohoo'],
  sheet: [44, 0],
  shortName: 'partying_face'
}, {
  name: 'Disguised Face',
  unified: '1F978',
  keywords: ['disguised face', 'pretent', 'brows', 'glasses', 'moustache'],
  sheet: [44, 10],
  shortName: 'disguised_face'
}, {
  name: 'Smiling Face with Sunglasses',
  unified: '1F60E',
  emoticons: ['8)'],
  keywords: ['smiling_face_with_sunglasses', 'face', 'cool', 'smile', 'summer', 'beach', 'sunglass'],
  sheet: [32, 34],
  shortName: 'sunglasses'
}, {
  name: 'Nerd Face',
  unified: '1F913',
  keywords: ['nerd_face', 'face', 'nerdy', 'geek', 'dork'],
  sheet: [39, 0],
  shortName: 'nerd_face'
}, {
  name: 'Face with Monocle',
  unified: '1F9D0',
  keywords: ['face_with_monocle', 'face', 'stuffy', 'wealthy'],
  sheet: [47, 11],
  shortName: 'face_with_monocle'
}, {
  name: 'Confused Face',
  unified: '1F615',
  emoticons: [':\\\\', ':-\\\\', ':/', ':-/'],
  keywords: ['confused_face', 'face', 'indifference', 'huh', 'weird', 'hmmm', ':/'],
  sheet: [32, 41],
  shortName: 'confused'
}, {
  name: 'Face with Diagonal Mouth',
  unified: '1FAE4',
  keywords: ['face with diagonal mouth', 'skeptic', 'confuse', 'frustrated', 'indifferent'],
  sheet: [55, 16],
  hidden: ['facebook'],
  shortName: 'face_with_diagonal_mouth'
}, {
  name: 'Worried Face',
  unified: '1F61F',
  keywords: ['worried_face', 'face', 'concern', 'nervous', ':('],
  sheet: [32, 51],
  shortName: 'worried'
}, {
  name: 'Slightly Frowning Face',
  unified: '1F641',
  keywords: ['slightly_frowning_face', 'face', 'frowning', 'disappointed', 'sad', 'upset'],
  sheet: [33, 27],
  shortName: 'slightly_frowning_face'
}, {
  name: 'Frowning Face',
  unified: '2639-FE0F',
  keywords: ['frowning_face', 'face', 'sad', 'upset', 'frown'],
  sheet: [57, 3],
  shortName: 'white_frowning_face'
}, {
  name: 'Face with Open Mouth',
  unified: '1F62E',
  emoticons: [':o', ':-o', ':O', ':-O'],
  keywords: ['face_with_open_mouth', 'face', 'surprise', 'impressed', 'wow', 'whoa', ':O'],
  sheet: [33, 6],
  shortName: 'open_mouth'
}, {
  name: 'Hushed Face',
  unified: '1F62F',
  keywords: ['hushed_face', 'face', 'woo', 'shh'],
  sheet: [33, 7],
  shortName: 'hushed'
}, {
  name: 'Astonished Face',
  unified: '1F632',
  keywords: ['astonished_face', 'face', 'xox', 'surprised', 'poisoned'],
  sheet: [33, 10],
  shortName: 'astonished'
}, {
  name: 'Flushed Face',
  unified: '1F633',
  keywords: ['flushed_face', 'face', 'blush', 'shy', 'flattered'],
  sheet: [33, 11],
  shortName: 'flushed'
}, {
  name: 'Face with Pleading Eyes',
  unified: '1F97A',
  keywords: ['pleading_face', 'face', 'begging', 'mercy', 'cry', 'tears', 'sad', 'grievance'],
  sheet: [44, 12],
  shortName: 'pleading_face'
}, {
  name: 'Face Holding Back Tears',
  unified: '1F979',
  keywords: ['face holding back tears', 'touched', 'gratitude', 'cry'],
  sheet: [44, 11],
  hidden: ['facebook'],
  shortName: 'face_holding_back_tears'
}, {
  name: 'Frowning Face with Open Mouth',
  unified: '1F626',
  keywords: ['frowning_face_with_open_mouth', 'face', 'aw', 'what'],
  sheet: [32, 58],
  shortName: 'frowning'
}, {
  name: 'Anguished Face',
  unified: '1F627',
  emoticons: ['D:'],
  keywords: ['anguished_face', 'face', 'stunned', 'nervous'],
  sheet: [32, 59],
  shortName: 'anguished'
}, {
  name: 'Fearful Face',
  unified: '1F628',
  keywords: ['fearful_face', 'face', 'scared', 'terrified', 'nervous'],
  sheet: [32, 60],
  shortName: 'fearful'
}, {
  name: 'Face with Open Mouth and Cold Sweat',
  unified: '1F630',
  keywords: ['anxious_face_with_sweat', 'face', 'nervous', 'sweat'],
  sheet: [33, 8],
  shortName: 'cold_sweat'
}, {
  name: 'Disappointed but Relieved Face',
  unified: '1F625',
  keywords: ['sad_but_relieved_face', 'face', 'phew', 'sweat', 'nervous'],
  sheet: [32, 57],
  shortName: 'disappointed_relieved'
}, {
  name: 'Crying Face',
  unified: '1F622',
  text: ':\'(',
  emoticons: [':\'('],
  keywords: ['crying_face', 'face', 'tears', 'sad', 'depressed', 'upset', ':\'('],
  sheet: [32, 54],
  shortName: 'cry'
}, {
  name: 'Loudly Crying Face',
  unified: '1F62D',
  text: ':\'(',
  keywords: ['loudly_crying_face', 'face', 'cry', 'tears', 'sad', 'upset', 'depressed'],
  sheet: [33, 4],
  shortName: 'sob'
}, {
  name: 'Face Screaming in Fear',
  unified: '1F631',
  keywords: ['face_screaming_in_fear', 'face', 'munch', 'scared', 'omg'],
  sheet: [33, 9],
  shortName: 'scream'
}, {
  name: 'Confounded Face',
  unified: '1F616',
  keywords: ['confounded_face', 'face', 'confused', 'sick', 'unwell', 'oops', ':S'],
  sheet: [32, 42],
  shortName: 'confounded'
}, {
  name: 'Persevering Face',
  unified: '1F623',
  keywords: ['persevering_face', 'face', 'sick', 'no', 'upset', 'oops'],
  sheet: [32, 55],
  shortName: 'persevere'
}, {
  name: 'Disappointed Face',
  unified: '1F61E',
  text: ':(',
  emoticons: ['):', ':(', ':-('],
  keywords: ['disappointed_face', 'face', 'sad', 'upset', 'depressed', ':('],
  sheet: [32, 50],
  shortName: 'disappointed'
}, {
  name: 'Face with Cold Sweat',
  unified: '1F613',
  keywords: ['downcast_face_with_sweat', 'face', 'hot', 'sad', 'tired', 'exercise'],
  sheet: [32, 39],
  shortName: 'sweat'
}, {
  name: 'Weary Face',
  unified: '1F629',
  keywords: ['weary_face', 'face', 'tired', 'sleepy', 'sad', 'frustrated', 'upset'],
  sheet: [33, 0],
  shortName: 'weary'
}, {
  name: 'Tired Face',
  unified: '1F62B',
  keywords: ['tired_face', 'sick', 'whine', 'upset', 'frustrated'],
  sheet: [33, 2],
  shortName: 'tired_face'
}, {
  name: 'Yawning Face',
  unified: '1F971',
  keywords: ['yawning_face', 'tired', 'sleepy'],
  sheet: [43, 59],
  shortName: 'yawning_face'
}, {
  name: 'Face with Look of Triumph',
  unified: '1F624',
  keywords: ['face_with_steam_from_nose', 'face', 'gas', 'phew', 'proud', 'pride'],
  sheet: [32, 56],
  shortName: 'triumph'
}, {
  name: 'Pouting Face',
  unified: '1F621',
  keywords: ['pouting_face', 'angry', 'mad', 'hate', 'despise'],
  sheet: [32, 53],
  shortName: 'rage'
}, {
  name: 'Angry Face',
  unified: '1F620',
  emoticons: ['>:(', '>:-('],
  keywords: ['angry_face', 'mad', 'face', 'annoyed', 'frustrated'],
  sheet: [32, 52],
  shortName: 'angry'
}, {
  name: 'Serious Face with Symbols Covering Mouth',
  unified: '1F92C',
  keywords: ['face_with_symbols_on_mouth', 'face', 'swearing', 'cursing', 'cussing', 'profanity', 'expletive'],
  sheet: [40, 41],
  shortNames: ['serious_face_with_symbols_covering_mouth'],
  shortName: 'face_with_symbols_on_mouth'
}, {
  name: 'Smiling Face with Horns',
  unified: '1F608',
  keywords: ['smiling_face_with_horns', 'devil', 'horns'],
  sheet: [32, 28],
  shortName: 'smiling_imp'
}, {
  name: 'Imp',
  unified: '1F47F',
  keywords: ['angry_face_with_horns', 'devil', 'angry', 'horns'],
  sheet: [25, 8],
  shortName: 'imp'
}, {
  name: 'Skull',
  unified: '1F480',
  keywords: ['skull', 'dead', 'skeleton', 'creepy', 'death'],
  sheet: [25, 9],
  shortName: 'skull'
}, {
  name: 'Skull and Crossbones',
  unified: '2620-FE0F',
  keywords: ['skull_and_crossbones', 'poison', 'danger', 'deadly', 'scary', 'death', 'pirate', 'evil'],
  sheet: [56, 56],
  shortName: 'skull_and_crossbones'
}, {
  name: 'Pile of Poo',
  unified: '1F4A9',
  keywords: ['pile_of_poo', 'hankey', 'shitface', 'fail', 'turd', 'shit'],
  sheet: [27, 56],
  shortNames: ['poop', 'shit'],
  shortName: 'hankey'
}, {
  name: 'Clown Face',
  unified: '1F921',
  keywords: ['clown_face', 'face'],
  sheet: [40, 13],
  shortName: 'clown_face'
}, {
  name: 'Japanese Ogre',
  unified: '1F479',
  keywords: ['ogre', 'monster', 'red', 'mask', 'halloween', 'scary', 'creepy', 'devil', 'demon', 'japanese', 'ogre'],
  sheet: [24, 58],
  shortName: 'japanese_ogre'
}, {
  name: 'Japanese Goblin',
  unified: '1F47A',
  keywords: ['goblin', 'red', 'evil', 'mask', 'monster', 'scary', 'creepy', 'japanese', 'goblin'],
  sheet: [24, 59],
  shortName: 'japanese_goblin'
}, {
  name: 'Ghost',
  unified: '1F47B',
  keywords: ['ghost', 'halloween', 'spooky', 'scary'],
  sheet: [24, 60],
  shortName: 'ghost'
}, {
  name: 'Extraterrestrial Alien',
  unified: '1F47D',
  keywords: ['alien', 'UFO', 'paul', 'weird', 'outer_space'],
  sheet: [25, 6],
  shortName: 'alien'
}, {
  name: 'Alien Monster',
  unified: '1F47E',
  keywords: ['alien_monster', 'game', 'arcade', 'play'],
  sheet: [25, 7],
  shortName: 'space_invader'
}, {
  name: 'Robot Face',
  unified: '1F916',
  keywords: ['robot', 'computer', 'machine', 'bot'],
  sheet: [39, 3],
  shortName: 'robot_face'
}, {
  name: 'Smiling Cat Face with Open Mouth',
  unified: '1F63A',
  keywords: ['grinning_cat', 'animal', 'cats', 'happy', 'smile'],
  sheet: [33, 20],
  shortName: 'smiley_cat'
}, {
  name: 'Grinning Cat Face with Smiling Eyes',
  unified: '1F638',
  keywords: ['grinning_cat_with_smiling_eyes', 'animal', 'cats', 'smile'],
  sheet: [33, 18],
  shortName: 'smile_cat'
}, {
  name: 'Cat Face with Tears of Joy',
  unified: '1F639',
  keywords: ['cat_with_tears_of_joy', 'animal', 'cats', 'haha', 'happy', 'tears'],
  sheet: [33, 19],
  shortName: 'joy_cat'
}, {
  name: 'Smiling Cat Face with Heart-Shaped Eyes',
  unified: '1F63B',
  keywords: ['smiling_cat_with_heart_eyes', 'animal', 'love', 'like', 'affection', 'cats', 'valentines', 'heart'],
  sheet: [33, 21],
  shortName: 'heart_eyes_cat'
}, {
  name: 'Cat Face with Wry Smile',
  unified: '1F63C',
  keywords: ['cat_with_wry_smile', 'animal', 'cats', 'smirk'],
  sheet: [33, 22],
  shortName: 'smirk_cat'
}, {
  name: 'Kissing Cat Face with Closed Eyes',
  unified: '1F63D',
  keywords: ['kissing_cat', 'animal', 'cats', 'kiss'],
  sheet: [33, 23],
  shortName: 'kissing_cat'
}, {
  name: 'Weary Cat Face',
  unified: '1F640',
  keywords: ['weary_cat', 'animal', 'cats', 'munch', 'scared', 'scream'],
  sheet: [33, 26],
  shortName: 'scream_cat'
}, {
  name: 'Crying Cat Face',
  unified: '1F63F',
  keywords: ['crying_cat', 'animal', 'tears', 'weep', 'sad', 'cats', 'upset', 'cry'],
  sheet: [33, 25],
  shortName: 'crying_cat_face'
}, {
  name: 'Pouting Cat Face',
  unified: '1F63E',
  keywords: ['pouting_cat', 'animal', 'cats'],
  sheet: [33, 24],
  shortName: 'pouting_cat'
}, {
  name: 'See-No-Evil Monkey',
  unified: '1F648',
  keywords: ['see_no_evil_monkey', 'monkey', 'animal', 'nature', 'haha'],
  sheet: [34, 24],
  shortName: 'see_no_evil'
}, {
  name: 'Hear-No-Evil Monkey',
  unified: '1F649',
  keywords: ['hear_no_evil_monkey', 'animal', 'monkey', 'nature'],
  sheet: [34, 25],
  shortName: 'hear_no_evil'
}, {
  name: 'Speak-No-Evil Monkey',
  unified: '1F64A',
  keywords: ['speak_no_evil_monkey', 'monkey', 'animal', 'nature', 'omg'],
  sheet: [34, 26],
  shortName: 'speak_no_evil'
}, {
  name: 'Kiss Mark',
  unified: '1F48B',
  keywords: ['kiss_mark', 'face', 'lips', 'love', 'like', 'affection', 'valentines'],
  sheet: [26, 37],
  shortName: 'kiss'
}, {
  name: 'Love Letter',
  unified: '1F48C',
  keywords: ['love_letter', 'email', 'like', 'affection', 'envelope', 'valentines'],
  sheet: [26, 38],
  shortName: 'love_letter'
}, {
  name: 'Heart with Arrow',
  unified: '1F498',
  keywords: ['heart_with_arrow', 'love', 'like', 'heart', 'affection', 'valentines'],
  sheet: [27, 39],
  shortName: 'cupid'
}, {
  name: 'Heart with Ribbon',
  unified: '1F49D',
  keywords: ['heart_with_ribbon', 'love', 'valentines'],
  sheet: [27, 44],
  shortName: 'gift_heart'
}, {
  name: 'Sparkling Heart',
  unified: '1F496',
  keywords: ['sparkling_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 37],
  shortName: 'sparkling_heart'
}, {
  name: 'Growing Heart',
  unified: '1F497',
  keywords: ['growing_heart', 'like', 'love', 'affection', 'valentines', 'pink'],
  sheet: [27, 38],
  shortName: 'heartpulse'
}, {
  name: 'Beating Heart',
  unified: '1F493',
  keywords: ['beating_heart', 'love', 'like', 'affection', 'valentines', 'pink', 'heart'],
  sheet: [27, 34],
  shortName: 'heartbeat'
}, {
  name: 'Revolving Hearts',
  unified: '1F49E',
  keywords: ['revolving_hearts', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 45],
  shortName: 'revolving_hearts'
}, {
  name: 'Two Hearts',
  unified: '1F495',
  keywords: ['two_hearts', 'love', 'like', 'affection', 'valentines', 'heart'],
  sheet: [27, 36],
  shortName: 'two_hearts'
}, {
  name: 'Heart Decoration',
  unified: '1F49F',
  keywords: ['heart_decoration', 'purple-square', 'love', 'like'],
  sheet: [27, 46],
  shortName: 'heart_decoration'
}, {
  name: 'Heart Exclamation',
  unified: '2763-FE0F',
  keywords: ['heart_exclamation', 'decoration', 'love'],
  sheet: [59, 7],
  shortName: 'heavy_heart_exclamation_mark_ornament'
}, {
  name: 'Broken Heart',
  unified: '1F494',
  text: '</3',
  emoticons: ['</3'],
  keywords: ['broken_heart', 'sad', 'sorry', 'break', 'heart', 'heartbreak'],
  sheet: [27, 35],
  shortName: 'broken_heart'
}, {
  name: 'Heart on Fire',
  unified: '2764-FE0F-200D-1F525',
  keywords: ['heart on fire', 'passionate', 'enthusiastic'],
  sheet: [59, 8],
  hidden: ['facebook'],
  shortName: 'heart_on_fire'
}, {
  name: 'Mending Heart',
  unified: '2764-FE0F-200D-1FA79',
  keywords: ['mending heart', 'broken heart', 'bandage', 'wounded'],
  sheet: [59, 9],
  hidden: ['facebook'],
  shortName: 'mending_heart'
}, {
  name: 'Heavy Black Heart',
  unified: '2764-FE0F',
  text: '<3',
  emoticons: ['<3'],
  keywords: ['red_heart', 'love', 'like', 'valentines'],
  sheet: [59, 10],
  shortName: 'heart'
}, {
  name: 'Orange Heart',
  unified: '1F9E1',
  keywords: ['orange_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [53, 15],
  shortName: 'orange_heart'
}, {
  name: 'Yellow Heart',
  unified: '1F49B',
  text: '<3',
  keywords: ['yellow_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 42],
  shortName: 'yellow_heart'
}, {
  name: 'Green Heart',
  unified: '1F49A',
  text: '<3',
  keywords: ['green_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 41],
  shortName: 'green_heart'
}, {
  name: 'Blue Heart',
  unified: '1F499',
  text: '<3',
  keywords: ['blue_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 40],
  shortName: 'blue_heart'
}, {
  name: 'Purple Heart',
  unified: '1F49C',
  text: '<3',
  keywords: ['purple_heart', 'love', 'like', 'affection', 'valentines'],
  sheet: [27, 43],
  shortName: 'purple_heart'
}, {
  name: 'Brown Heart',
  unified: '1F90E',
  keywords: ['brown_heart', 'coffee'],
  sheet: [38, 51],
  shortName: 'brown_heart'
}, {
  name: 'Black Heart',
  unified: '1F5A4',
  keywords: ['black_heart', 'evil'],
  sheet: [31, 55],
  shortName: 'black_heart'
}, {
  name: 'White Heart',
  unified: '1F90D',
  keywords: ['white_heart', 'pure'],
  sheet: [38, 50],
  shortName: 'white_heart'
}, {
  name: 'Hundred Points Symbol',
  unified: '1F4AF',
  keywords: ['hundred_points', 'score', 'perfect', 'numbers', 'century', 'exam', 'quiz', 'test', 'pass', 'hundred'],
  sheet: [28, 6],
  shortName: '100'
}, {
  name: 'Anger Symbol',
  unified: '1F4A2',
  keywords: ['anger_symbol', 'angry', 'mad'],
  sheet: [27, 49],
  shortName: 'anger'
}, {
  name: 'Collision Symbol',
  unified: '1F4A5',
  keywords: ['collision', 'bomb', 'explode', 'explosion', 'collision', 'blown'],
  sheet: [27, 52],
  shortNames: ['collision'],
  shortName: 'boom'
}, {
  name: 'Dizzy Symbol',
  unified: '1F4AB',
  keywords: ['dizzy', 'star', 'sparkle', 'shoot', 'magic'],
  sheet: [28, 2],
  shortName: 'dizzy'
}, {
  name: 'Splashing Sweat Symbol',
  unified: '1F4A6',
  keywords: ['sweat_droplets', 'water', 'drip', 'oops'],
  sheet: [27, 53],
  shortName: 'sweat_drops'
}, {
  name: 'Dash Symbol',
  unified: '1F4A8',
  keywords: ['dashing_away', 'wind', 'air', 'fast', 'shoo', 'fart', 'smoke', 'puff'],
  sheet: [27, 55],
  shortName: 'dash'
}, {
  name: 'Hole',
  unified: '1F573-FE0F',
  keywords: ['hole', 'embarrassing'],
  sheet: [30, 58],
  shortName: 'hole'
}, {
  name: 'Bomb',
  unified: '1F4A3',
  keywords: ['bomb', 'boom', 'explode', 'explosion', 'terrorism'],
  sheet: [27, 50],
  shortName: 'bomb'
}, {
  name: 'Speech Balloon',
  unified: '1F4AC',
  keywords: ['speech_balloon', 'bubble', 'words', 'message', 'talk', 'chatting'],
  sheet: [28, 3],
  shortName: 'speech_balloon'
}, {
  name: 'Eye in Speech Bubble',
  unified: '1F441-FE0F-200D-1F5E8-FE0F',
  keywords: ['eye_in_speech_bubble', 'info'],
  sheet: [11, 53],
  hidden: ['facebook'],
  shortName: 'eye-in-speech-bubble'
}, {
  name: 'Left Speech Bubble',
  unified: '1F5E8-FE0F',
  keywords: ['left_speech_bubble', 'words', 'message', 'talk', 'chatting'],
  sheet: [32, 11],
  shortName: 'left_speech_bubble'
}, {
  name: 'Right Anger Bubble',
  unified: '1F5EF-FE0F',
  keywords: ['right_anger_bubble', 'caption', 'speech', 'thinking', 'mad'],
  sheet: [32, 12],
  shortName: 'right_anger_bubble'
}, {
  name: 'Thought Balloon',
  unified: '1F4AD',
  keywords: ['thought_balloon', 'bubble', 'cloud', 'speech', 'thinking', 'dream'],
  sheet: [28, 4],
  shortName: 'thought_balloon'
}, {
  name: 'Sleeping Symbol',
  unified: '1F4A4',
  keywords: ['zzz', 'sleepy', 'tired', 'dream'],
  sheet: [27, 51],
  shortName: 'zzz'
}, {
  name: 'Waving Hand Sign',
  unified: '1F44B',
  keywords: ['waving_hand', 'hands', 'gesture', 'goodbye', 'solong', 'farewell', 'hello', 'hi', 'palm'],
  sheet: [12, 38],
  skinVariations: [{
    unified: '1F44B-1F3FB',
    sheet: [12, 39]
  }, {
    unified: '1F44B-1F3FC',
    sheet: [12, 40]
  }, {
    unified: '1F44B-1F3FD',
    sheet: [12, 41]
  }, {
    unified: '1F44B-1F3FE',
    sheet: [12, 42]
  }, {
    unified: '1F44B-1F3FF',
    sheet: [12, 43]
  }],
  shortName: 'wave'
}, {
  name: 'Raised Back of Hand',
  unified: '1F91A',
  keywords: ['raised_back_of_hand', 'fingers', 'raised', 'backhand'],
  sheet: [39, 17],
  skinVariations: [{
    unified: '1F91A-1F3FB',
    sheet: [39, 18]
  }, {
    unified: '1F91A-1F3FC',
    sheet: [39, 19]
  }, {
    unified: '1F91A-1F3FD',
    sheet: [39, 20]
  }, {
    unified: '1F91A-1F3FE',
    sheet: [39, 21]
  }, {
    unified: '1F91A-1F3FF',
    sheet: [39, 22]
  }],
  shortName: 'raised_back_of_hand'
}, {
  name: 'Hand with Fingers Splayed',
  unified: '1F590-FE0F',
  keywords: ['hand_with_fingers_splayed', 'hand', 'fingers', 'palm'],
  sheet: [31, 37],
  skinVariations: [{
    unified: '1F590-1F3FB',
    sheet: [31, 38]
  }, {
    unified: '1F590-1F3FC',
    sheet: [31, 39]
  }, {
    unified: '1F590-1F3FD',
    sheet: [31, 40]
  }, {
    unified: '1F590-1F3FE',
    sheet: [31, 41]
  }, {
    unified: '1F590-1F3FF',
    sheet: [31, 42]
  }],
  shortName: 'raised_hand_with_fingers_splayed'
}, {
  name: 'Raised Hand',
  unified: '270B',
  keywords: ['raised_hand', 'fingers', 'stop', 'highfive', 'palm', 'ban'],
  sheet: [58, 33],
  skinVariations: [{
    unified: '270B-1F3FB',
    sheet: [58, 34]
  }, {
    unified: '270B-1F3FC',
    sheet: [58, 35]
  }, {
    unified: '270B-1F3FD',
    sheet: [58, 36]
  }, {
    unified: '270B-1F3FE',
    sheet: [58, 37]
  }, {
    unified: '270B-1F3FF',
    sheet: [58, 38]
  }],
  shortNames: ['raised_hand'],
  shortName: 'hand'
}, {
  name: 'Raised Hand with Part Between Middle and Ring Fingers',
  unified: '1F596',
  keywords: ['vulcan_salute', 'hand', 'fingers', 'spock', 'star trek'],
  sheet: [31, 49],
  skinVariations: [{
    unified: '1F596-1F3FB',
    sheet: [31, 50]
  }, {
    unified: '1F596-1F3FC',
    sheet: [31, 51]
  }, {
    unified: '1F596-1F3FD',
    sheet: [31, 52]
  }, {
    unified: '1F596-1F3FE',
    sheet: [31, 53]
  }, {
    unified: '1F596-1F3FF',
    sheet: [31, 54]
  }],
  shortName: 'spock-hand'
}, {
  name: 'Rightwards Hand',
  unified: '1FAF1',
  keywords: ['rightwards hand', 'palm', 'offer'],
  sheet: [55, 26],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF1-1F3FB',
    sheet: [55, 27],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FC',
    sheet: [55, 28],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FD',
    sheet: [55, 29],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FE',
    sheet: [55, 30],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FF',
    sheet: [55, 31],
    hidden: ['facebook']
  }],
  shortName: 'rightwards_hand'
}, {
  name: 'Leftwards Hand',
  unified: '1FAF2',
  keywords: ['leftwards hand', 'palm', 'offer'],
  sheet: [55, 32],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF2-1F3FB',
    sheet: [55, 33],
    hidden: ['facebook']
  }, {
    unified: '1FAF2-1F3FC',
    sheet: [55, 34],
    hidden: ['facebook']
  }, {
    unified: '1FAF2-1F3FD',
    sheet: [55, 35],
    hidden: ['facebook']
  }, {
    unified: '1FAF2-1F3FE',
    sheet: [55, 36],
    hidden: ['facebook']
  }, {
    unified: '1FAF2-1F3FF',
    sheet: [55, 37],
    hidden: ['facebook']
  }],
  shortName: 'leftwards_hand'
}, {
  name: 'Palm Down Hand',
  unified: '1FAF3',
  keywords: ['palm down hand', 'palm', 'drop'],
  sheet: [55, 38],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF3-1F3FB',
    sheet: [55, 39],
    hidden: ['facebook']
  }, {
    unified: '1FAF3-1F3FC',
    sheet: [55, 40],
    hidden: ['facebook']
  }, {
    unified: '1FAF3-1F3FD',
    sheet: [55, 41],
    hidden: ['facebook']
  }, {
    unified: '1FAF3-1F3FE',
    sheet: [55, 42],
    hidden: ['facebook']
  }, {
    unified: '1FAF3-1F3FF',
    sheet: [55, 43],
    hidden: ['facebook']
  }],
  shortName: 'palm_down_hand'
}, {
  name: 'Palm Up Hand',
  unified: '1FAF4',
  keywords: ['palm up hand', 'lift', 'offer', 'demand'],
  sheet: [55, 44],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF4-1F3FB',
    sheet: [55, 45],
    hidden: ['facebook']
  }, {
    unified: '1FAF4-1F3FC',
    sheet: [55, 46],
    hidden: ['facebook']
  }, {
    unified: '1FAF4-1F3FD',
    sheet: [55, 47],
    hidden: ['facebook']
  }, {
    unified: '1FAF4-1F3FE',
    sheet: [55, 48],
    hidden: ['facebook']
  }, {
    unified: '1FAF4-1F3FF',
    sheet: [55, 49],
    hidden: ['facebook']
  }],
  shortName: 'palm_up_hand'
}, {
  name: 'Ok Hand Sign',
  unified: '1F44C',
  keywords: ['ok_hand', 'fingers', 'limbs', 'perfect', 'ok', 'okay'],
  sheet: [12, 44],
  skinVariations: [{
    unified: '1F44C-1F3FB',
    sheet: [12, 45]
  }, {
    unified: '1F44C-1F3FC',
    sheet: [12, 46]
  }, {
    unified: '1F44C-1F3FD',
    sheet: [12, 47]
  }, {
    unified: '1F44C-1F3FE',
    sheet: [12, 48]
  }, {
    unified: '1F44C-1F3FF',
    sheet: [12, 49]
  }],
  shortName: 'ok_hand'
}, {
  name: 'Pinched Fingers',
  unified: '1F90C',
  keywords: ['pinched fingers', 'size', 'tiny', 'small'],
  sheet: [38, 44],
  skinVariations: [{
    unified: '1F90C-1F3FB',
    sheet: [38, 45]
  }, {
    unified: '1F90C-1F3FC',
    sheet: [38, 46]
  }, {
    unified: '1F90C-1F3FD',
    sheet: [38, 47]
  }, {
    unified: '1F90C-1F3FE',
    sheet: [38, 48]
  }, {
    unified: '1F90C-1F3FF',
    sheet: [38, 49]
  }],
  shortName: 'pinched_fingers'
}, {
  name: 'Pinching Hand',
  unified: '1F90F',
  keywords: ['pinching_hand', 'tiny', 'small', 'size'],
  sheet: [38, 52],
  skinVariations: [{
    unified: '1F90F-1F3FB',
    sheet: [38, 53]
  }, {
    unified: '1F90F-1F3FC',
    sheet: [38, 54]
  }, {
    unified: '1F90F-1F3FD',
    sheet: [38, 55]
  }, {
    unified: '1F90F-1F3FE',
    sheet: [38, 56]
  }, {
    unified: '1F90F-1F3FF',
    sheet: [38, 57]
  }],
  shortName: 'pinching_hand'
}, {
  name: 'Victory Hand',
  unified: '270C-FE0F',
  keywords: ['victory_hand', 'fingers', 'ohyeah', 'hand', 'peace', 'victory', 'two'],
  sheet: [58, 39],
  skinVariations: [{
    unified: '270C-1F3FB',
    sheet: [58, 40]
  }, {
    unified: '270C-1F3FC',
    sheet: [58, 41]
  }, {
    unified: '270C-1F3FD',
    sheet: [58, 42]
  }, {
    unified: '270C-1F3FE',
    sheet: [58, 43]
  }, {
    unified: '270C-1F3FF',
    sheet: [58, 44]
  }],
  shortName: 'v'
}, {
  name: 'Hand with Index and Middle Fingers Crossed',
  unified: '1F91E',
  keywords: ['crossed_fingers', 'good', 'lucky'],
  sheet: [40, 0],
  skinVariations: [{
    unified: '1F91E-1F3FB',
    sheet: [40, 1]
  }, {
    unified: '1F91E-1F3FC',
    sheet: [40, 2]
  }, {
    unified: '1F91E-1F3FD',
    sheet: [40, 3]
  }, {
    unified: '1F91E-1F3FE',
    sheet: [40, 4]
  }, {
    unified: '1F91E-1F3FF',
    sheet: [40, 5]
  }],
  shortNames: ['hand_with_index_and_middle_fingers_crossed'],
  shortName: 'crossed_fingers'
}, {
  name: 'Hand with Index Finger and Thumb Crossed',
  unified: '1FAF0',
  keywords: ['hand with index finger and thumb crossed', 'heart', 'love', 'money', 'expensive'],
  sheet: [55, 20],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF0-1F3FB',
    sheet: [55, 21],
    hidden: ['facebook']
  }, {
    unified: '1FAF0-1F3FC',
    sheet: [55, 22],
    hidden: ['facebook']
  }, {
    unified: '1FAF0-1F3FD',
    sheet: [55, 23],
    hidden: ['facebook']
  }, {
    unified: '1FAF0-1F3FE',
    sheet: [55, 24],
    hidden: ['facebook']
  }, {
    unified: '1FAF0-1F3FF',
    sheet: [55, 25],
    hidden: ['facebook']
  }],
  shortName: 'hand_with_index_finger_and_thumb_crossed'
}, {
  name: 'I Love You Hand Sign',
  unified: '1F91F',
  keywords: ['love_you_gesture', 'hand', 'fingers', 'gesture'],
  sheet: [40, 6],
  skinVariations: [{
    unified: '1F91F-1F3FB',
    sheet: [40, 7]
  }, {
    unified: '1F91F-1F3FC',
    sheet: [40, 8]
  }, {
    unified: '1F91F-1F3FD',
    sheet: [40, 9]
  }, {
    unified: '1F91F-1F3FE',
    sheet: [40, 10]
  }, {
    unified: '1F91F-1F3FF',
    sheet: [40, 11]
  }],
  shortName: 'i_love_you_hand_sign'
}, {
  name: 'Sign of the Horns',
  unified: '1F918',
  keywords: ['sign_of_the_horns', 'hand', 'fingers', 'evil_eye', 'sign_of_horns', 'rock_on'],
  sheet: [39, 5],
  skinVariations: [{
    unified: '1F918-1F3FB',
    sheet: [39, 6]
  }, {
    unified: '1F918-1F3FC',
    sheet: [39, 7]
  }, {
    unified: '1F918-1F3FD',
    sheet: [39, 8]
  }, {
    unified: '1F918-1F3FE',
    sheet: [39, 9]
  }, {
    unified: '1F918-1F3FF',
    sheet: [39, 10]
  }],
  shortNames: ['sign_of_the_horns'],
  shortName: 'the_horns'
}, {
  name: 'Call Me Hand',
  unified: '1F919',
  keywords: ['call_me_hand', 'hands', 'gesture', 'shaka'],
  sheet: [39, 11],
  skinVariations: [{
    unified: '1F919-1F3FB',
    sheet: [39, 12]
  }, {
    unified: '1F919-1F3FC',
    sheet: [39, 13]
  }, {
    unified: '1F919-1F3FD',
    sheet: [39, 14]
  }, {
    unified: '1F919-1F3FE',
    sheet: [39, 15]
  }, {
    unified: '1F919-1F3FF',
    sheet: [39, 16]
  }],
  shortName: 'call_me_hand'
}, {
  name: 'White Left Pointing Backhand Index',
  unified: '1F448',
  keywords: ['backhand_index_pointing_left', 'direction', 'fingers', 'hand', 'left'],
  sheet: [12, 20],
  skinVariations: [{
    unified: '1F448-1F3FB',
    sheet: [12, 21]
  }, {
    unified: '1F448-1F3FC',
    sheet: [12, 22]
  }, {
    unified: '1F448-1F3FD',
    sheet: [12, 23]
  }, {
    unified: '1F448-1F3FE',
    sheet: [12, 24]
  }, {
    unified: '1F448-1F3FF',
    sheet: [12, 25]
  }],
  shortName: 'point_left'
}, {
  name: 'White Right Pointing Backhand Index',
  unified: '1F449',
  keywords: ['backhand_index_pointing_right', 'fingers', 'hand', 'direction', 'right'],
  sheet: [12, 26],
  skinVariations: [{
    unified: '1F449-1F3FB',
    sheet: [12, 27]
  }, {
    unified: '1F449-1F3FC',
    sheet: [12, 28]
  }, {
    unified: '1F449-1F3FD',
    sheet: [12, 29]
  }, {
    unified: '1F449-1F3FE',
    sheet: [12, 30]
  }, {
    unified: '1F449-1F3FF',
    sheet: [12, 31]
  }],
  shortName: 'point_right'
}, {
  name: 'White Up Pointing Backhand Index',
  unified: '1F446',
  keywords: ['backhand_index_pointing_up', 'fingers', 'hand', 'direction', 'up'],
  sheet: [12, 8],
  skinVariations: [{
    unified: '1F446-1F3FB',
    sheet: [12, 9]
  }, {
    unified: '1F446-1F3FC',
    sheet: [12, 10]
  }, {
    unified: '1F446-1F3FD',
    sheet: [12, 11]
  }, {
    unified: '1F446-1F3FE',
    sheet: [12, 12]
  }, {
    unified: '1F446-1F3FF',
    sheet: [12, 13]
  }],
  shortName: 'point_up_2'
}, {
  name: 'Reversed Hand with Middle Finger Extended',
  unified: '1F595',
  keywords: ['middle_finger', 'hand', 'fingers', 'rude', 'middle', 'flipping'],
  sheet: [31, 43],
  skinVariations: [{
    unified: '1F595-1F3FB',
    sheet: [31, 44]
  }, {
    unified: '1F595-1F3FC',
    sheet: [31, 45]
  }, {
    unified: '1F595-1F3FD',
    sheet: [31, 46]
  }, {
    unified: '1F595-1F3FE',
    sheet: [31, 47]
  }, {
    unified: '1F595-1F3FF',
    sheet: [31, 48]
  }],
  shortNames: ['reversed_hand_with_middle_finger_extended'],
  shortName: 'middle_finger'
}, {
  name: 'White Down Pointing Backhand Index',
  unified: '1F447',
  keywords: ['backhand_index_pointing_down', 'fingers', 'hand', 'direction', 'down'],
  sheet: [12, 14],
  skinVariations: [{
    unified: '1F447-1F3FB',
    sheet: [12, 15]
  }, {
    unified: '1F447-1F3FC',
    sheet: [12, 16]
  }, {
    unified: '1F447-1F3FD',
    sheet: [12, 17]
  }, {
    unified: '1F447-1F3FE',
    sheet: [12, 18]
  }, {
    unified: '1F447-1F3FF',
    sheet: [12, 19]
  }],
  shortName: 'point_down'
}, {
  name: 'White Up Pointing Index',
  unified: '261D-FE0F',
  keywords: ['index_pointing_up', 'hand', 'fingers', 'direction', 'up'],
  sheet: [56, 50],
  skinVariations: [{
    unified: '261D-1F3FB',
    sheet: [56, 51]
  }, {
    unified: '261D-1F3FC',
    sheet: [56, 52]
  }, {
    unified: '261D-1F3FD',
    sheet: [56, 53]
  }, {
    unified: '261D-1F3FE',
    sheet: [56, 54]
  }, {
    unified: '261D-1F3FF',
    sheet: [56, 55]
  }],
  shortName: 'point_up'
}, {
  name: 'Index Pointing at the Viewer',
  unified: '1FAF5',
  keywords: ['index pointing at the viewer', 'you', 'recruit'],
  sheet: [55, 50],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF5-1F3FB',
    sheet: [55, 51],
    hidden: ['facebook']
  }, {
    unified: '1FAF5-1F3FC',
    sheet: [55, 52],
    hidden: ['facebook']
  }, {
    unified: '1FAF5-1F3FD',
    sheet: [55, 53],
    hidden: ['facebook']
  }, {
    unified: '1FAF5-1F3FE',
    sheet: [55, 54],
    hidden: ['facebook']
  }, {
    unified: '1FAF5-1F3FF',
    sheet: [55, 55],
    hidden: ['facebook']
  }],
  shortName: 'index_pointing_at_the_viewer'
}, {
  name: 'Thumbs Up Sign',
  unified: '1F44D',
  keywords: ['thumbs_up', 'thumbsup', 'yes', 'awesome', 'good', 'agree', 'accept', 'cool', 'hand', 'like', '+1'],
  sheet: [12, 50],
  skinVariations: [{
    unified: '1F44D-1F3FB',
    sheet: [12, 51]
  }, {
    unified: '1F44D-1F3FC',
    sheet: [12, 52]
  }, {
    unified: '1F44D-1F3FD',
    sheet: [12, 53]
  }, {
    unified: '1F44D-1F3FE',
    sheet: [12, 54]
  }, {
    unified: '1F44D-1F3FF',
    sheet: [12, 55]
  }],
  shortNames: ['thumbsup'],
  shortName: '+1'
}, {
  name: 'Thumbs Down Sign',
  unified: '1F44E',
  keywords: ['thumbs_down', 'thumbsdown', 'no', 'dislike', 'hand', '-1'],
  sheet: [12, 56],
  skinVariations: [{
    unified: '1F44E-1F3FB',
    sheet: [12, 57]
  }, {
    unified: '1F44E-1F3FC',
    sheet: [12, 58]
  }, {
    unified: '1F44E-1F3FD',
    sheet: [12, 59]
  }, {
    unified: '1F44E-1F3FE',
    sheet: [12, 60]
  }, {
    unified: '1F44E-1F3FF',
    sheet: [13, 0]
  }],
  shortNames: ['thumbsdown'],
  shortName: '-1'
}, {
  name: 'Raised Fist',
  unified: '270A',
  keywords: ['raised_fist', 'fingers', 'hand', 'grasp'],
  sheet: [58, 27],
  skinVariations: [{
    unified: '270A-1F3FB',
    sheet: [58, 28]
  }, {
    unified: '270A-1F3FC',
    sheet: [58, 29]
  }, {
    unified: '270A-1F3FD',
    sheet: [58, 30]
  }, {
    unified: '270A-1F3FE',
    sheet: [58, 31]
  }, {
    unified: '270A-1F3FF',
    sheet: [58, 32]
  }],
  shortName: 'fist'
}, {
  name: 'Fisted Hand Sign',
  unified: '1F44A',
  keywords: ['oncoming_fist', 'angry', 'violence', 'fist', 'hit', 'attack', 'hand'],
  sheet: [12, 32],
  skinVariations: [{
    unified: '1F44A-1F3FB',
    sheet: [12, 33]
  }, {
    unified: '1F44A-1F3FC',
    sheet: [12, 34]
  }, {
    unified: '1F44A-1F3FD',
    sheet: [12, 35]
  }, {
    unified: '1F44A-1F3FE',
    sheet: [12, 36]
  }, {
    unified: '1F44A-1F3FF',
    sheet: [12, 37]
  }],
  shortNames: ['punch'],
  shortName: 'facepunch'
}, {
  name: 'Left-Facing Fist',
  unified: '1F91B',
  keywords: ['left_facing_fist', 'hand', 'fistbump'],
  sheet: [39, 23],
  skinVariations: [{
    unified: '1F91B-1F3FB',
    sheet: [39, 24]
  }, {
    unified: '1F91B-1F3FC',
    sheet: [39, 25]
  }, {
    unified: '1F91B-1F3FD',
    sheet: [39, 26]
  }, {
    unified: '1F91B-1F3FE',
    sheet: [39, 27]
  }, {
    unified: '1F91B-1F3FF',
    sheet: [39, 28]
  }],
  shortName: 'left-facing_fist'
}, {
  name: 'Right-Facing Fist',
  unified: '1F91C',
  keywords: ['right_facing_fist', 'hand', 'fistbump'],
  sheet: [39, 29],
  skinVariations: [{
    unified: '1F91C-1F3FB',
    sheet: [39, 30]
  }, {
    unified: '1F91C-1F3FC',
    sheet: [39, 31]
  }, {
    unified: '1F91C-1F3FD',
    sheet: [39, 32]
  }, {
    unified: '1F91C-1F3FE',
    sheet: [39, 33]
  }, {
    unified: '1F91C-1F3FF',
    sheet: [39, 34]
  }],
  shortName: 'right-facing_fist'
}, {
  name: 'Clapping Hands Sign',
  unified: '1F44F',
  keywords: ['clapping_hands', 'hands', 'praise', 'applause', 'congrats', 'yay'],
  sheet: [13, 1],
  skinVariations: [{
    unified: '1F44F-1F3FB',
    sheet: [13, 2]
  }, {
    unified: '1F44F-1F3FC',
    sheet: [13, 3]
  }, {
    unified: '1F44F-1F3FD',
    sheet: [13, 4]
  }, {
    unified: '1F44F-1F3FE',
    sheet: [13, 5]
  }, {
    unified: '1F44F-1F3FF',
    sheet: [13, 6]
  }],
  shortName: 'clap'
}, {
  name: 'Person Raising Both Hands in Celebration',
  unified: '1F64C',
  keywords: ['raising_hands', 'gesture', 'hooray', 'yea', 'celebration', 'hands'],
  sheet: [34, 45],
  skinVariations: [{
    unified: '1F64C-1F3FB',
    sheet: [34, 46]
  }, {
    unified: '1F64C-1F3FC',
    sheet: [34, 47]
  }, {
    unified: '1F64C-1F3FD',
    sheet: [34, 48]
  }, {
    unified: '1F64C-1F3FE',
    sheet: [34, 49]
  }, {
    unified: '1F64C-1F3FF',
    sheet: [34, 50]
  }],
  shortName: 'raised_hands'
}, {
  name: 'Heart Hands',
  unified: '1FAF6',
  keywords: ['heart hands', 'love', 'appreciation', 'support'],
  sheet: [55, 56],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAF6-1F3FB',
    sheet: [55, 57],
    hidden: ['facebook']
  }, {
    unified: '1FAF6-1F3FC',
    sheet: [55, 58],
    hidden: ['facebook']
  }, {
    unified: '1FAF6-1F3FD',
    sheet: [55, 59],
    hidden: ['facebook']
  }, {
    unified: '1FAF6-1F3FE',
    sheet: [55, 60],
    hidden: ['facebook']
  }, {
    unified: '1FAF6-1F3FF',
    sheet: [56, 0],
    hidden: ['facebook']
  }],
  shortName: 'heart_hands'
}, {
  name: 'Open Hands Sign',
  unified: '1F450',
  keywords: ['open_hands', 'fingers', 'butterfly', 'hands', 'open'],
  sheet: [13, 7],
  skinVariations: [{
    unified: '1F450-1F3FB',
    sheet: [13, 8]
  }, {
    unified: '1F450-1F3FC',
    sheet: [13, 9]
  }, {
    unified: '1F450-1F3FD',
    sheet: [13, 10]
  }, {
    unified: '1F450-1F3FE',
    sheet: [13, 11]
  }, {
    unified: '1F450-1F3FF',
    sheet: [13, 12]
  }],
  shortName: 'open_hands'
}, {
  name: 'Palms Up Together',
  unified: '1F932',
  keywords: ['palms_up_together', 'hands', 'gesture', 'cupped', 'prayer'],
  sheet: [40, 57],
  skinVariations: [{
    unified: '1F932-1F3FB',
    sheet: [40, 58]
  }, {
    unified: '1F932-1F3FC',
    sheet: [40, 59]
  }, {
    unified: '1F932-1F3FD',
    sheet: [40, 60]
  }, {
    unified: '1F932-1F3FE',
    sheet: [41, 0]
  }, {
    unified: '1F932-1F3FF',
    sheet: [41, 1]
  }],
  shortName: 'palms_up_together'
}, {
  name: 'Handshake',
  unified: '1F91D',
  keywords: ['handshake', 'agreement', 'shake'],
  sheet: [39, 35],
  skinVariations: [{
    unified: '1F91D-1F3FB',
    sheet: [39, 36]
  }, {
    unified: '1F91D-1F3FC',
    sheet: [39, 37]
  }, {
    unified: '1F91D-1F3FD',
    sheet: [39, 38]
  }, {
    unified: '1F91D-1F3FE',
    sheet: [39, 39]
  }, {
    unified: '1F91D-1F3FF',
    sheet: [39, 40]
  }, {
    unified: '1FAF1-1F3FB-200D-1FAF2-1F3FC',
    sheet: [39, 41],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FB-200D-1FAF2-1F3FD',
    sheet: [39, 42],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FB-200D-1FAF2-1F3FE',
    sheet: [39, 43],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FB-200D-1FAF2-1F3FF',
    sheet: [39, 44],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FC-200D-1FAF2-1F3FB',
    sheet: [39, 45],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FC-200D-1FAF2-1F3FD',
    sheet: [39, 46],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FC-200D-1FAF2-1F3FE',
    sheet: [39, 47],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FC-200D-1FAF2-1F3FF',
    sheet: [39, 48],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FD-200D-1FAF2-1F3FB',
    sheet: [39, 49],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FD-200D-1FAF2-1F3FC',
    sheet: [39, 50],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FD-200D-1FAF2-1F3FE',
    sheet: [39, 51],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FD-200D-1FAF2-1F3FF',
    sheet: [39, 52],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FE-200D-1FAF2-1F3FB',
    sheet: [39, 53],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FE-200D-1FAF2-1F3FC',
    sheet: [39, 54],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FE-200D-1FAF2-1F3FD',
    sheet: [39, 55],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FE-200D-1FAF2-1F3FF',
    sheet: [39, 56],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FF-200D-1FAF2-1F3FB',
    sheet: [39, 57],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FF-200D-1FAF2-1F3FC',
    sheet: [39, 58],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FF-200D-1FAF2-1F3FD',
    sheet: [39, 59],
    hidden: ['facebook']
  }, {
    unified: '1FAF1-1F3FF-200D-1FAF2-1F3FE',
    sheet: [39, 60],
    hidden: ['facebook']
  }],
  shortName: 'handshake'
}, {
  name: 'Person with Folded Hands',
  unified: '1F64F',
  keywords: ['folded_hands', 'please', 'hope', 'wish', 'namaste', 'highfive', 'pray', 'thank you', 'thanks', 'appreciate'],
  sheet: [35, 26],
  skinVariations: [{
    unified: '1F64F-1F3FB',
    sheet: [35, 27]
  }, {
    unified: '1F64F-1F3FC',
    sheet: [35, 28]
  }, {
    unified: '1F64F-1F3FD',
    sheet: [35, 29]
  }, {
    unified: '1F64F-1F3FE',
    sheet: [35, 30]
  }, {
    unified: '1F64F-1F3FF',
    sheet: [35, 31]
  }],
  shortName: 'pray'
}, {
  name: 'Writing Hand',
  unified: '270D-FE0F',
  keywords: ['writing_hand', 'lower_left_ballpoint_pen', 'stationery', 'write', 'compose'],
  sheet: [58, 45],
  skinVariations: [{
    unified: '270D-1F3FB',
    sheet: [58, 46]
  }, {
    unified: '270D-1F3FC',
    sheet: [58, 47]
  }, {
    unified: '270D-1F3FD',
    sheet: [58, 48]
  }, {
    unified: '270D-1F3FE',
    sheet: [58, 49]
  }, {
    unified: '270D-1F3FF',
    sheet: [58, 50]
  }],
  shortName: 'writing_hand'
}, {
  name: 'Nail Polish',
  unified: '1F485',
  keywords: ['nail_polish', 'beauty', 'manicure', 'finger', 'fashion', 'nail'],
  sheet: [25, 53],
  skinVariations: [{
    unified: '1F485-1F3FB',
    sheet: [25, 54]
  }, {
    unified: '1F485-1F3FC',
    sheet: [25, 55]
  }, {
    unified: '1F485-1F3FD',
    sheet: [25, 56]
  }, {
    unified: '1F485-1F3FE',
    sheet: [25, 57]
  }, {
    unified: '1F485-1F3FF',
    sheet: [25, 58]
  }],
  shortName: 'nail_care'
}, {
  name: 'Selfie',
  unified: '1F933',
  keywords: ['selfie', 'camera', 'phone'],
  sheet: [41, 2],
  skinVariations: [{
    unified: '1F933-1F3FB',
    sheet: [41, 3]
  }, {
    unified: '1F933-1F3FC',
    sheet: [41, 4]
  }, {
    unified: '1F933-1F3FD',
    sheet: [41, 5]
  }, {
    unified: '1F933-1F3FE',
    sheet: [41, 6]
  }, {
    unified: '1F933-1F3FF',
    sheet: [41, 7]
  }],
  shortName: 'selfie'
}, {
  name: 'Flexed Biceps',
  unified: '1F4AA',
  keywords: ['flexed_biceps', 'arm', 'flex', 'hand', 'summer', 'strong', 'biceps'],
  sheet: [27, 57],
  skinVariations: [{
    unified: '1F4AA-1F3FB',
    sheet: [27, 58]
  }, {
    unified: '1F4AA-1F3FC',
    sheet: [27, 59]
  }, {
    unified: '1F4AA-1F3FD',
    sheet: [27, 60]
  }, {
    unified: '1F4AA-1F3FE',
    sheet: [28, 0]
  }, {
    unified: '1F4AA-1F3FF',
    sheet: [28, 1]
  }],
  shortName: 'muscle'
}, {
  name: 'Mechanical Arm',
  unified: '1F9BE',
  keywords: ['mechanical_arm', 'accessibility'],
  sheet: [46, 3],
  shortName: 'mechanical_arm'
}, {
  name: 'Mechanical Leg',
  unified: '1F9BF',
  keywords: ['mechanical_leg', 'accessibility'],
  sheet: [46, 4],
  shortName: 'mechanical_leg'
}, {
  name: 'Leg',
  unified: '1F9B5',
  keywords: ['leg', 'kick', 'limb'],
  sheet: [45, 6],
  skinVariations: [{
    unified: '1F9B5-1F3FB',
    sheet: [45, 7]
  }, {
    unified: '1F9B5-1F3FC',
    sheet: [45, 8]
  }, {
    unified: '1F9B5-1F3FD',
    sheet: [45, 9]
  }, {
    unified: '1F9B5-1F3FE',
    sheet: [45, 10]
  }, {
    unified: '1F9B5-1F3FF',
    sheet: [45, 11]
  }],
  shortName: 'leg'
}, {
  name: 'Foot',
  unified: '1F9B6',
  keywords: ['foot', 'kick', 'stomp'],
  sheet: [45, 12],
  skinVariations: [{
    unified: '1F9B6-1F3FB',
    sheet: [45, 13]
  }, {
    unified: '1F9B6-1F3FC',
    sheet: [45, 14]
  }, {
    unified: '1F9B6-1F3FD',
    sheet: [45, 15]
  }, {
    unified: '1F9B6-1F3FE',
    sheet: [45, 16]
  }, {
    unified: '1F9B6-1F3FF',
    sheet: [45, 17]
  }],
  shortName: 'foot'
}, {
  name: 'Ear',
  unified: '1F442',
  keywords: ['ear', 'face', 'hear', 'sound', 'listen'],
  sheet: [11, 55],
  skinVariations: [{
    unified: '1F442-1F3FB',
    sheet: [11, 56]
  }, {
    unified: '1F442-1F3FC',
    sheet: [11, 57]
  }, {
    unified: '1F442-1F3FD',
    sheet: [11, 58]
  }, {
    unified: '1F442-1F3FE',
    sheet: [11, 59]
  }, {
    unified: '1F442-1F3FF',
    sheet: [11, 60]
  }],
  shortName: 'ear'
}, {
  name: 'Ear with Hearing Aid',
  unified: '1F9BB',
  keywords: ['ear_with_hearing_aid', 'accessibility'],
  sheet: [45, 56],
  skinVariations: [{
    unified: '1F9BB-1F3FB',
    sheet: [45, 57]
  }, {
    unified: '1F9BB-1F3FC',
    sheet: [45, 58]
  }, {
    unified: '1F9BB-1F3FD',
    sheet: [45, 59]
  }, {
    unified: '1F9BB-1F3FE',
    sheet: [45, 60]
  }, {
    unified: '1F9BB-1F3FF',
    sheet: [46, 0]
  }],
  shortName: 'ear_with_hearing_aid'
}, {
  name: 'Nose',
  unified: '1F443',
  keywords: ['nose', 'smell', 'sniff'],
  sheet: [12, 0],
  skinVariations: [{
    unified: '1F443-1F3FB',
    sheet: [12, 1]
  }, {
    unified: '1F443-1F3FC',
    sheet: [12, 2]
  }, {
    unified: '1F443-1F3FD',
    sheet: [12, 3]
  }, {
    unified: '1F443-1F3FE',
    sheet: [12, 4]
  }, {
    unified: '1F443-1F3FF',
    sheet: [12, 5]
  }],
  shortName: 'nose'
}, {
  name: 'Brain',
  unified: '1F9E0',
  keywords: ['brain', 'smart', 'intelligent'],
  sheet: [53, 14],
  shortName: 'brain'
}, {
  name: 'Anatomical Heart',
  unified: '1FAC0',
  keywords: ['anatomical heart', 'health', 'heartbeat'],
  sheet: [54, 42],
  shortName: 'anatomical_heart'
}, {
  name: 'Lungs',
  unified: '1FAC1',
  keywords: ['lungs', 'breathe'],
  sheet: [54, 43],
  shortName: 'lungs'
}, {
  name: 'Tooth',
  unified: '1F9B7',
  keywords: ['tooth', 'teeth', 'dentist'],
  sheet: [45, 18],
  shortName: 'tooth'
}, {
  name: 'Bone',
  unified: '1F9B4',
  keywords: ['bone', 'skeleton'],
  sheet: [45, 5],
  shortName: 'bone'
}, {
  name: 'Eyes',
  unified: '1F440',
  keywords: ['eyes', 'look', 'watch', 'stalk', 'peek', 'see'],
  sheet: [11, 52],
  shortName: 'eyes'
}, {
  name: 'Eye',
  unified: '1F441-FE0F',
  keywords: ['eye', 'face', 'look', 'see', 'watch', 'stare'],
  sheet: [11, 54],
  shortName: 'eye'
}, {
  name: 'Tongue',
  unified: '1F445',
  keywords: ['tongue', 'mouth', 'playful'],
  sheet: [12, 7],
  shortName: 'tongue'
}, {
  name: 'Mouth',
  unified: '1F444',
  keywords: ['mouth', 'mouth', 'kiss'],
  sheet: [12, 6],
  shortName: 'lips'
}, {
  name: 'Biting Lip',
  unified: '1FAE6',
  keywords: ['biting lip', 'flirt', 'sexy', 'pain', 'worry'],
  sheet: [55, 18],
  hidden: ['facebook'],
  shortName: 'biting_lip'
}, {
  name: 'Baby',
  unified: '1F476',
  keywords: ['baby', 'child', 'boy', 'girl', 'toddler'],
  sheet: [24, 28],
  skinVariations: [{
    unified: '1F476-1F3FB',
    sheet: [24, 29]
  }, {
    unified: '1F476-1F3FC',
    sheet: [24, 30]
  }, {
    unified: '1F476-1F3FD',
    sheet: [24, 31]
  }, {
    unified: '1F476-1F3FE',
    sheet: [24, 32]
  }, {
    unified: '1F476-1F3FF',
    sheet: [24, 33]
  }],
  shortName: 'baby'
}, {
  name: 'Child',
  unified: '1F9D2',
  keywords: ['child', 'gender-neutral', 'young'],
  sheet: [50, 11],
  skinVariations: [{
    unified: '1F9D2-1F3FB',
    sheet: [50, 12]
  }, {
    unified: '1F9D2-1F3FC',
    sheet: [50, 13]
  }, {
    unified: '1F9D2-1F3FD',
    sheet: [50, 14]
  }, {
    unified: '1F9D2-1F3FE',
    sheet: [50, 15]
  }, {
    unified: '1F9D2-1F3FF',
    sheet: [50, 16]
  }],
  shortName: 'child'
}, {
  name: 'Boy',
  unified: '1F466',
  keywords: ['boy', 'man', 'male', 'guy', 'teenager'],
  sheet: [13, 34],
  skinVariations: [{
    unified: '1F466-1F3FB',
    sheet: [13, 35]
  }, {
    unified: '1F466-1F3FC',
    sheet: [13, 36]
  }, {
    unified: '1F466-1F3FD',
    sheet: [13, 37]
  }, {
    unified: '1F466-1F3FE',
    sheet: [13, 38]
  }, {
    unified: '1F466-1F3FF',
    sheet: [13, 39]
  }],
  shortName: 'boy'
}, {
  name: 'Girl',
  unified: '1F467',
  keywords: ['girl', 'female', 'woman', 'teenager'],
  sheet: [13, 40],
  skinVariations: [{
    unified: '1F467-1F3FB',
    sheet: [13, 41]
  }, {
    unified: '1F467-1F3FC',
    sheet: [13, 42]
  }, {
    unified: '1F467-1F3FD',
    sheet: [13, 43]
  }, {
    unified: '1F467-1F3FE',
    sheet: [13, 44]
  }, {
    unified: '1F467-1F3FF',
    sheet: [13, 45]
  }],
  shortName: 'girl'
}, {
  name: 'Adult',
  unified: '1F9D1',
  keywords: ['person', 'gender-neutral', 'person'],
  sheet: [50, 5],
  skinVariations: [{
    unified: '1F9D1-1F3FB',
    sheet: [50, 6]
  }, {
    unified: '1F9D1-1F3FC',
    sheet: [50, 7]
  }, {
    unified: '1F9D1-1F3FD',
    sheet: [50, 8]
  }, {
    unified: '1F9D1-1F3FE',
    sheet: [50, 9]
  }, {
    unified: '1F9D1-1F3FF',
    sheet: [50, 10]
  }],
  shortName: 'adult'
}, {
  name: 'Person with Blond Hair',
  unified: '1F471',
  keywords: ['person_blond_hair', 'hairstyle'],
  sheet: [23, 47],
  skinVariations: [{
    unified: '1F471-1F3FB',
    sheet: [23, 48]
  }, {
    unified: '1F471-1F3FC',
    sheet: [23, 49]
  }, {
    unified: '1F471-1F3FD',
    sheet: [23, 50]
  }, {
    unified: '1F471-1F3FE',
    sheet: [23, 51]
  }, {
    unified: '1F471-1F3FF',
    sheet: [23, 52]
  }],
  shortName: 'person_with_blond_hair',
  obsoletedBy: '1F471-200D-2642-FE0F'
}, {
  name: 'Man',
  unified: '1F468',
  keywords: ['man', 'mustache', 'father', 'dad', 'guy', 'classy', 'sir', 'moustache'],
  sheet: [17, 13],
  skinVariations: [{
    unified: '1F468-1F3FB',
    sheet: [17, 14]
  }, {
    unified: '1F468-1F3FC',
    sheet: [17, 15]
  }, {
    unified: '1F468-1F3FD',
    sheet: [17, 16]
  }, {
    unified: '1F468-1F3FE',
    sheet: [17, 17]
  }, {
    unified: '1F468-1F3FF',
    sheet: [17, 18]
  }],
  shortName: 'man'
}, {
  name: 'Bearded Person',
  unified: '1F9D4',
  keywords: ['man_beard', 'person', 'bewhiskered'],
  sheet: [50, 35],
  skinVariations: [{
    unified: '1F9D4-1F3FB',
    sheet: [50, 36]
  }, {
    unified: '1F9D4-1F3FC',
    sheet: [50, 37]
  }, {
    unified: '1F9D4-1F3FD',
    sheet: [50, 38]
  }, {
    unified: '1F9D4-1F3FE',
    sheet: [50, 39]
  }, {
    unified: '1F9D4-1F3FF',
    sheet: [50, 40]
  }],
  shortName: 'bearded_person'
}, {
  name: 'Man: Beard',
  unified: '1F9D4-200D-2642-FE0F',
  keywords: ['man beard', 'facial hair'],
  sheet: [50, 29],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F9D4-1F3FB-200D-2642-FE0F',
    sheet: [50, 30],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FC-200D-2642-FE0F',
    sheet: [50, 31],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FD-200D-2642-FE0F',
    sheet: [50, 32],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FE-200D-2642-FE0F',
    sheet: [50, 33],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FF-200D-2642-FE0F',
    sheet: [50, 34],
    hidden: ['facebook']
  }],
  shortName: 'man_with_beard'
}, {
  name: 'Woman: Beard',
  unified: '1F9D4-200D-2640-FE0F',
  keywords: ['woman beard', 'facial hair'],
  sheet: [50, 23],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F9D4-1F3FB-200D-2640-FE0F',
    sheet: [50, 24],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FC-200D-2640-FE0F',
    sheet: [50, 25],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FD-200D-2640-FE0F',
    sheet: [50, 26],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FE-200D-2640-FE0F',
    sheet: [50, 27],
    hidden: ['facebook']
  }, {
    unified: '1F9D4-1F3FF-200D-2640-FE0F',
    sheet: [50, 28],
    hidden: ['facebook']
  }],
  shortName: 'woman_with_beard'
}, {
  name: 'Man: Red Hair',
  unified: '1F468-200D-1F9B0',
  keywords: ['man_red_hair', 'hairstyle'],
  sheet: [15, 29],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9B0',
    sheet: [15, 30]
  }, {
    unified: '1F468-1F3FC-200D-1F9B0',
    sheet: [15, 31]
  }, {
    unified: '1F468-1F3FD-200D-1F9B0',
    sheet: [15, 32]
  }, {
    unified: '1F468-1F3FE-200D-1F9B0',
    sheet: [15, 33]
  }, {
    unified: '1F468-1F3FF-200D-1F9B0',
    sheet: [15, 34]
  }],
  shortName: 'red_haired_man'
}, {
  name: 'Man: Curly Hair',
  unified: '1F468-200D-1F9B1',
  keywords: ['man_curly_hair', 'hairstyle'],
  sheet: [15, 35],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9B1',
    sheet: [15, 36]
  }, {
    unified: '1F468-1F3FC-200D-1F9B1',
    sheet: [15, 37]
  }, {
    unified: '1F468-1F3FD-200D-1F9B1',
    sheet: [15, 38]
  }, {
    unified: '1F468-1F3FE-200D-1F9B1',
    sheet: [15, 39]
  }, {
    unified: '1F468-1F3FF-200D-1F9B1',
    sheet: [15, 40]
  }],
  shortName: 'curly_haired_man'
}, {
  name: 'Man: White Hair',
  unified: '1F468-200D-1F9B3',
  keywords: ['man_white_hair', 'old', 'elder'],
  sheet: [15, 47],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9B3',
    sheet: [15, 48]
  }, {
    unified: '1F468-1F3FC-200D-1F9B3',
    sheet: [15, 49]
  }, {
    unified: '1F468-1F3FD-200D-1F9B3',
    sheet: [15, 50]
  }, {
    unified: '1F468-1F3FE-200D-1F9B3',
    sheet: [15, 51]
  }, {
    unified: '1F468-1F3FF-200D-1F9B3',
    sheet: [15, 52]
  }],
  shortName: 'white_haired_man'
}, {
  name: 'Man: Bald',
  unified: '1F468-200D-1F9B2',
  keywords: ['man_bald', 'hairless'],
  sheet: [15, 41],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9B2',
    sheet: [15, 42]
  }, {
    unified: '1F468-1F3FC-200D-1F9B2',
    sheet: [15, 43]
  }, {
    unified: '1F468-1F3FD-200D-1F9B2',
    sheet: [15, 44]
  }, {
    unified: '1F468-1F3FE-200D-1F9B2',
    sheet: [15, 45]
  }, {
    unified: '1F468-1F3FF-200D-1F9B2',
    sheet: [15, 46]
  }],
  shortName: 'bald_man'
}, {
  name: 'Woman',
  unified: '1F469',
  keywords: ['woman', 'female', 'girls', 'lady'],
  sheet: [21, 33],
  skinVariations: [{
    unified: '1F469-1F3FB',
    sheet: [21, 34]
  }, {
    unified: '1F469-1F3FC',
    sheet: [21, 35]
  }, {
    unified: '1F469-1F3FD',
    sheet: [21, 36]
  }, {
    unified: '1F469-1F3FE',
    sheet: [21, 37]
  }, {
    unified: '1F469-1F3FF',
    sheet: [21, 38]
  }],
  shortName: 'woman'
}, {
  name: 'Woman: Red Hair',
  unified: '1F469-200D-1F9B0',
  keywords: ['woman_red_hair', 'hairstyle'],
  sheet: [18, 58],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9B0',
    sheet: [18, 59]
  }, {
    unified: '1F469-1F3FC-200D-1F9B0',
    sheet: [18, 60]
  }, {
    unified: '1F469-1F3FD-200D-1F9B0',
    sheet: [19, 0]
  }, {
    unified: '1F469-1F3FE-200D-1F9B0',
    sheet: [19, 1]
  }, {
    unified: '1F469-1F3FF-200D-1F9B0',
    sheet: [19, 2]
  }],
  shortName: 'red_haired_woman'
}, {
  name: 'Person: Red Hair',
  unified: '1F9D1-200D-1F9B0',
  keywords: ['person_red_hair', 'hairstyle'],
  sheet: [49, 12],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9B0',
    sheet: [49, 13]
  }, {
    unified: '1F9D1-1F3FC-200D-1F9B0',
    sheet: [49, 14]
  }, {
    unified: '1F9D1-1F3FD-200D-1F9B0',
    sheet: [49, 15]
  }, {
    unified: '1F9D1-1F3FE-200D-1F9B0',
    sheet: [49, 16]
  }, {
    unified: '1F9D1-1F3FF-200D-1F9B0',
    sheet: [49, 17]
  }],
  shortName: 'red_haired_person'
}, {
  name: 'Woman: Curly Hair',
  unified: '1F469-200D-1F9B1',
  keywords: ['woman_curly_hair', 'hairstyle'],
  sheet: [19, 3],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9B1',
    sheet: [19, 4]
  }, {
    unified: '1F469-1F3FC-200D-1F9B1',
    sheet: [19, 5]
  }, {
    unified: '1F469-1F3FD-200D-1F9B1',
    sheet: [19, 6]
  }, {
    unified: '1F469-1F3FE-200D-1F9B1',
    sheet: [19, 7]
  }, {
    unified: '1F469-1F3FF-200D-1F9B1',
    sheet: [19, 8]
  }],
  shortName: 'curly_haired_woman'
}, {
  name: 'Person: Curly Hair',
  unified: '1F9D1-200D-1F9B1',
  keywords: ['person_curly_hair', 'hairstyle'],
  sheet: [49, 18],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9B1',
    sheet: [49, 19]
  }, {
    unified: '1F9D1-1F3FC-200D-1F9B1',
    sheet: [49, 20]
  }, {
    unified: '1F9D1-1F3FD-200D-1F9B1',
    sheet: [49, 21]
  }, {
    unified: '1F9D1-1F3FE-200D-1F9B1',
    sheet: [49, 22]
  }, {
    unified: '1F9D1-1F3FF-200D-1F9B1',
    sheet: [49, 23]
  }],
  shortName: 'curly_haired_person'
}, {
  name: 'Woman: White Hair',
  unified: '1F469-200D-1F9B3',
  keywords: ['woman_white_hair', 'old', 'elder'],
  sheet: [19, 15],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9B3',
    sheet: [19, 16]
  }, {
    unified: '1F469-1F3FC-200D-1F9B3',
    sheet: [19, 17]
  }, {
    unified: '1F469-1F3FD-200D-1F9B3',
    sheet: [19, 18]
  }, {
    unified: '1F469-1F3FE-200D-1F9B3',
    sheet: [19, 19]
  }, {
    unified: '1F469-1F3FF-200D-1F9B3',
    sheet: [19, 20]
  }],
  shortName: 'white_haired_woman'
}, {
  name: 'Person: White Hair',
  unified: '1F9D1-200D-1F9B3',
  keywords: ['person_white_hair', 'elder', 'old'],
  sheet: [49, 30],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9B3',
    sheet: [49, 31],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-1F9B3',
    sheet: [49, 32],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-1F9B3',
    sheet: [49, 33],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-1F9B3',
    sheet: [49, 34],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-1F9B3',
    sheet: [49, 35],
    hidden: ['facebook']
  }],
  shortName: 'white_haired_person'
}, {
  name: 'Woman: Bald',
  unified: '1F469-200D-1F9B2',
  keywords: ['woman_bald', 'hairless'],
  sheet: [19, 9],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9B2',
    sheet: [19, 10]
  }, {
    unified: '1F469-1F3FC-200D-1F9B2',
    sheet: [19, 11]
  }, {
    unified: '1F469-1F3FD-200D-1F9B2',
    sheet: [19, 12]
  }, {
    unified: '1F469-1F3FE-200D-1F9B2',
    sheet: [19, 13]
  }, {
    unified: '1F469-1F3FF-200D-1F9B2',
    sheet: [19, 14]
  }],
  shortName: 'bald_woman'
}, {
  name: 'Person: Bald',
  unified: '1F9D1-200D-1F9B2',
  keywords: ['person_bald', 'hairless'],
  sheet: [49, 24],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9B2',
    sheet: [49, 25],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-1F9B2',
    sheet: [49, 26],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-1F9B2',
    sheet: [49, 27],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-1F9B2',
    sheet: [49, 28],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-1F9B2',
    sheet: [49, 29],
    hidden: ['facebook']
  }],
  shortName: 'bald_person'
}, {
  name: 'Woman: Blond Hair',
  unified: '1F471-200D-2640-FE0F',
  keywords: ['woman_blond_hair', 'woman', 'female', 'girl', 'blonde', 'person'],
  sheet: [23, 35],
  skinVariations: [{
    unified: '1F471-1F3FB-200D-2640-FE0F',
    sheet: [23, 36]
  }, {
    unified: '1F471-1F3FC-200D-2640-FE0F',
    sheet: [23, 37]
  }, {
    unified: '1F471-1F3FD-200D-2640-FE0F',
    sheet: [23, 38]
  }, {
    unified: '1F471-1F3FE-200D-2640-FE0F',
    sheet: [23, 39]
  }, {
    unified: '1F471-1F3FF-200D-2640-FE0F',
    sheet: [23, 40]
  }],
  shortName: 'blond-haired-woman'
}, {
  name: 'Man: Blond Hair',
  unified: '1F471-200D-2642-FE0F',
  obsoletes: '1F471',
  keywords: ['man_blond_hair', 'man', 'male', 'boy', 'blonde', 'guy', 'person'],
  sheet: [23, 41],
  skinVariations: [{
    unified: '1F471-1F3FB-200D-2642-FE0F',
    sheet: [23, 42]
  }, {
    unified: '1F471-1F3FC-200D-2642-FE0F',
    sheet: [23, 43]
  }, {
    unified: '1F471-1F3FD-200D-2642-FE0F',
    sheet: [23, 44]
  }, {
    unified: '1F471-1F3FE-200D-2642-FE0F',
    sheet: [23, 45]
  }, {
    unified: '1F471-1F3FF-200D-2642-FE0F',
    sheet: [23, 46]
  }],
  shortName: 'blond-haired-man'
}, {
  name: 'Older Adult',
  unified: '1F9D3',
  keywords: ['older_person', 'human', 'elder', 'senior', 'gender-neutral'],
  sheet: [50, 17],
  skinVariations: [{
    unified: '1F9D3-1F3FB',
    sheet: [50, 18]
  }, {
    unified: '1F9D3-1F3FC',
    sheet: [50, 19]
  }, {
    unified: '1F9D3-1F3FD',
    sheet: [50, 20]
  }, {
    unified: '1F9D3-1F3FE',
    sheet: [50, 21]
  }, {
    unified: '1F9D3-1F3FF',
    sheet: [50, 22]
  }],
  shortName: 'older_adult'
}, {
  name: 'Older Man',
  unified: '1F474',
  keywords: ['old_man', 'human', 'male', 'men', 'old', 'elder', 'senior'],
  sheet: [24, 16],
  skinVariations: [{
    unified: '1F474-1F3FB',
    sheet: [24, 17]
  }, {
    unified: '1F474-1F3FC',
    sheet: [24, 18]
  }, {
    unified: '1F474-1F3FD',
    sheet: [24, 19]
  }, {
    unified: '1F474-1F3FE',
    sheet: [24, 20]
  }, {
    unified: '1F474-1F3FF',
    sheet: [24, 21]
  }],
  shortName: 'older_man'
}, {
  name: 'Older Woman',
  unified: '1F475',
  keywords: ['old_woman', 'human', 'female', 'women', 'lady', 'old', 'elder', 'senior'],
  sheet: [24, 22],
  skinVariations: [{
    unified: '1F475-1F3FB',
    sheet: [24, 23]
  }, {
    unified: '1F475-1F3FC',
    sheet: [24, 24]
  }, {
    unified: '1F475-1F3FD',
    sheet: [24, 25]
  }, {
    unified: '1F475-1F3FE',
    sheet: [24, 26]
  }, {
    unified: '1F475-1F3FF',
    sheet: [24, 27]
  }],
  shortName: 'older_woman'
}, {
  name: 'Person Frowning',
  unified: '1F64D',
  keywords: ['person_frowning', 'worried'],
  sheet: [35, 2],
  skinVariations: [{
    unified: '1F64D-1F3FB',
    sheet: [35, 3]
  }, {
    unified: '1F64D-1F3FC',
    sheet: [35, 4]
  }, {
    unified: '1F64D-1F3FD',
    sheet: [35, 5]
  }, {
    unified: '1F64D-1F3FE',
    sheet: [35, 6]
  }, {
    unified: '1F64D-1F3FF',
    sheet: [35, 7]
  }],
  shortName: 'person_frowning',
  obsoletedBy: '1F64D-200D-2640-FE0F'
}, {
  name: 'Man Frowning',
  unified: '1F64D-200D-2642-FE0F',
  keywords: ['man_frowning', 'male', 'boy', 'man', 'sad', 'depressed', 'discouraged', 'unhappy'],
  sheet: [34, 57],
  skinVariations: [{
    unified: '1F64D-1F3FB-200D-2642-FE0F',
    sheet: [34, 58]
  }, {
    unified: '1F64D-1F3FC-200D-2642-FE0F',
    sheet: [34, 59]
  }, {
    unified: '1F64D-1F3FD-200D-2642-FE0F',
    sheet: [34, 60]
  }, {
    unified: '1F64D-1F3FE-200D-2642-FE0F',
    sheet: [35, 0]
  }, {
    unified: '1F64D-1F3FF-200D-2642-FE0F',
    sheet: [35, 1]
  }],
  shortName: 'man-frowning'
}, {
  name: 'Woman Frowning',
  unified: '1F64D-200D-2640-FE0F',
  obsoletes: '1F64D',
  keywords: ['woman_frowning', 'female', 'girl', 'woman', 'sad', 'depressed', 'discouraged', 'unhappy'],
  sheet: [34, 51],
  skinVariations: [{
    unified: '1F64D-1F3FB-200D-2640-FE0F',
    sheet: [34, 52]
  }, {
    unified: '1F64D-1F3FC-200D-2640-FE0F',
    sheet: [34, 53]
  }, {
    unified: '1F64D-1F3FD-200D-2640-FE0F',
    sheet: [34, 54]
  }, {
    unified: '1F64D-1F3FE-200D-2640-FE0F',
    sheet: [34, 55]
  }, {
    unified: '1F64D-1F3FF-200D-2640-FE0F',
    sheet: [34, 56]
  }],
  shortName: 'woman-frowning'
}, {
  name: 'Person with Pouting Face',
  unified: '1F64E',
  keywords: ['person_pouting', 'upset'],
  sheet: [35, 20],
  skinVariations: [{
    unified: '1F64E-1F3FB',
    sheet: [35, 21]
  }, {
    unified: '1F64E-1F3FC',
    sheet: [35, 22]
  }, {
    unified: '1F64E-1F3FD',
    sheet: [35, 23]
  }, {
    unified: '1F64E-1F3FE',
    sheet: [35, 24]
  }, {
    unified: '1F64E-1F3FF',
    sheet: [35, 25]
  }],
  shortName: 'person_with_pouting_face',
  obsoletedBy: '1F64E-200D-2640-FE0F'
}, {
  name: 'Man Pouting',
  unified: '1F64E-200D-2642-FE0F',
  keywords: ['man_pouting', 'male', 'boy', 'man'],
  sheet: [35, 14],
  skinVariations: [{
    unified: '1F64E-1F3FB-200D-2642-FE0F',
    sheet: [35, 15]
  }, {
    unified: '1F64E-1F3FC-200D-2642-FE0F',
    sheet: [35, 16]
  }, {
    unified: '1F64E-1F3FD-200D-2642-FE0F',
    sheet: [35, 17]
  }, {
    unified: '1F64E-1F3FE-200D-2642-FE0F',
    sheet: [35, 18]
  }, {
    unified: '1F64E-1F3FF-200D-2642-FE0F',
    sheet: [35, 19]
  }],
  shortName: 'man-pouting'
}, {
  name: 'Woman Pouting',
  unified: '1F64E-200D-2640-FE0F',
  obsoletes: '1F64E',
  keywords: ['woman_pouting', 'female', 'girl', 'woman'],
  sheet: [35, 8],
  skinVariations: [{
    unified: '1F64E-1F3FB-200D-2640-FE0F',
    sheet: [35, 9]
  }, {
    unified: '1F64E-1F3FC-200D-2640-FE0F',
    sheet: [35, 10]
  }, {
    unified: '1F64E-1F3FD-200D-2640-FE0F',
    sheet: [35, 11]
  }, {
    unified: '1F64E-1F3FE-200D-2640-FE0F',
    sheet: [35, 12]
  }, {
    unified: '1F64E-1F3FF-200D-2640-FE0F',
    sheet: [35, 13]
  }],
  shortName: 'woman-pouting'
}, {
  name: 'Face with No Good Gesture',
  unified: '1F645',
  keywords: ['person_gesturing_no', 'decline'],
  sheet: [33, 43],
  skinVariations: [{
    unified: '1F645-1F3FB',
    sheet: [33, 44]
  }, {
    unified: '1F645-1F3FC',
    sheet: [33, 45]
  }, {
    unified: '1F645-1F3FD',
    sheet: [33, 46]
  }, {
    unified: '1F645-1F3FE',
    sheet: [33, 47]
  }, {
    unified: '1F645-1F3FF',
    sheet: [33, 48]
  }],
  shortName: 'no_good',
  obsoletedBy: '1F645-200D-2640-FE0F'
}, {
  name: 'Man Gesturing No',
  unified: '1F645-200D-2642-FE0F',
  keywords: ['man_gesturing_no', 'male', 'boy', 'man', 'nope'],
  sheet: [33, 37],
  skinVariations: [{
    unified: '1F645-1F3FB-200D-2642-FE0F',
    sheet: [33, 38]
  }, {
    unified: '1F645-1F3FC-200D-2642-FE0F',
    sheet: [33, 39]
  }, {
    unified: '1F645-1F3FD-200D-2642-FE0F',
    sheet: [33, 40]
  }, {
    unified: '1F645-1F3FE-200D-2642-FE0F',
    sheet: [33, 41]
  }, {
    unified: '1F645-1F3FF-200D-2642-FE0F',
    sheet: [33, 42]
  }],
  shortName: 'man-gesturing-no'
}, {
  name: 'Woman Gesturing No',
  unified: '1F645-200D-2640-FE0F',
  obsoletes: '1F645',
  keywords: ['woman_gesturing_no', 'female', 'girl', 'woman', 'nope'],
  sheet: [33, 31],
  skinVariations: [{
    unified: '1F645-1F3FB-200D-2640-FE0F',
    sheet: [33, 32]
  }, {
    unified: '1F645-1F3FC-200D-2640-FE0F',
    sheet: [33, 33]
  }, {
    unified: '1F645-1F3FD-200D-2640-FE0F',
    sheet: [33, 34]
  }, {
    unified: '1F645-1F3FE-200D-2640-FE0F',
    sheet: [33, 35]
  }, {
    unified: '1F645-1F3FF-200D-2640-FE0F',
    sheet: [33, 36]
  }],
  shortName: 'woman-gesturing-no'
}, {
  name: 'Face with Ok Gesture',
  unified: '1F646',
  keywords: ['person_gesturing_ok', 'agree'],
  sheet: [34, 0],
  skinVariations: [{
    unified: '1F646-1F3FB',
    sheet: [34, 1]
  }, {
    unified: '1F646-1F3FC',
    sheet: [34, 2]
  }, {
    unified: '1F646-1F3FD',
    sheet: [34, 3]
  }, {
    unified: '1F646-1F3FE',
    sheet: [34, 4]
  }, {
    unified: '1F646-1F3FF',
    sheet: [34, 5]
  }],
  shortName: 'ok_woman',
  obsoletedBy: '1F646-200D-2640-FE0F'
}, {
  name: 'Man Gesturing Ok',
  unified: '1F646-200D-2642-FE0F',
  keywords: ['man_gesturing_ok', 'men', 'boy', 'male', 'blue', 'human', 'man'],
  sheet: [33, 55],
  skinVariations: [{
    unified: '1F646-1F3FB-200D-2642-FE0F',
    sheet: [33, 56]
  }, {
    unified: '1F646-1F3FC-200D-2642-FE0F',
    sheet: [33, 57]
  }, {
    unified: '1F646-1F3FD-200D-2642-FE0F',
    sheet: [33, 58]
  }, {
    unified: '1F646-1F3FE-200D-2642-FE0F',
    sheet: [33, 59]
  }, {
    unified: '1F646-1F3FF-200D-2642-FE0F',
    sheet: [33, 60]
  }],
  shortName: 'man-gesturing-ok'
}, {
  name: 'Woman Gesturing Ok',
  unified: '1F646-200D-2640-FE0F',
  obsoletes: '1F646',
  keywords: ['woman_gesturing_ok', 'women', 'girl', 'female', 'pink', 'human', 'woman'],
  sheet: [33, 49],
  skinVariations: [{
    unified: '1F646-1F3FB-200D-2640-FE0F',
    sheet: [33, 50]
  }, {
    unified: '1F646-1F3FC-200D-2640-FE0F',
    sheet: [33, 51]
  }, {
    unified: '1F646-1F3FD-200D-2640-FE0F',
    sheet: [33, 52]
  }, {
    unified: '1F646-1F3FE-200D-2640-FE0F',
    sheet: [33, 53]
  }, {
    unified: '1F646-1F3FF-200D-2640-FE0F',
    sheet: [33, 54]
  }],
  shortName: 'woman-gesturing-ok'
}, {
  name: 'Information Desk Person',
  unified: '1F481',
  keywords: ['person_tipping_hand', 'information'],
  sheet: [25, 22],
  skinVariations: [{
    unified: '1F481-1F3FB',
    sheet: [25, 23]
  }, {
    unified: '1F481-1F3FC',
    sheet: [25, 24]
  }, {
    unified: '1F481-1F3FD',
    sheet: [25, 25]
  }, {
    unified: '1F481-1F3FE',
    sheet: [25, 26]
  }, {
    unified: '1F481-1F3FF',
    sheet: [25, 27]
  }],
  shortName: 'information_desk_person',
  obsoletedBy: '1F481-200D-2640-FE0F'
}, {
  name: 'Man Tipping Hand',
  unified: '1F481-200D-2642-FE0F',
  keywords: ['man_tipping_hand', 'male', 'boy', 'man', 'human', 'information'],
  sheet: [25, 16],
  skinVariations: [{
    unified: '1F481-1F3FB-200D-2642-FE0F',
    sheet: [25, 17]
  }, {
    unified: '1F481-1F3FC-200D-2642-FE0F',
    sheet: [25, 18]
  }, {
    unified: '1F481-1F3FD-200D-2642-FE0F',
    sheet: [25, 19]
  }, {
    unified: '1F481-1F3FE-200D-2642-FE0F',
    sheet: [25, 20]
  }, {
    unified: '1F481-1F3FF-200D-2642-FE0F',
    sheet: [25, 21]
  }],
  shortName: 'man-tipping-hand'
}, {
  name: 'Woman Tipping Hand',
  unified: '1F481-200D-2640-FE0F',
  obsoletes: '1F481',
  keywords: ['woman_tipping_hand', 'female', 'girl', 'woman', 'human', 'information'],
  sheet: [25, 10],
  skinVariations: [{
    unified: '1F481-1F3FB-200D-2640-FE0F',
    sheet: [25, 11]
  }, {
    unified: '1F481-1F3FC-200D-2640-FE0F',
    sheet: [25, 12]
  }, {
    unified: '1F481-1F3FD-200D-2640-FE0F',
    sheet: [25, 13]
  }, {
    unified: '1F481-1F3FE-200D-2640-FE0F',
    sheet: [25, 14]
  }, {
    unified: '1F481-1F3FF-200D-2640-FE0F',
    sheet: [25, 15]
  }],
  shortName: 'woman-tipping-hand'
}, {
  name: 'Happy Person Raising One Hand',
  unified: '1F64B',
  keywords: ['person_raising_hand', 'question'],
  sheet: [34, 39],
  skinVariations: [{
    unified: '1F64B-1F3FB',
    sheet: [34, 40]
  }, {
    unified: '1F64B-1F3FC',
    sheet: [34, 41]
  }, {
    unified: '1F64B-1F3FD',
    sheet: [34, 42]
  }, {
    unified: '1F64B-1F3FE',
    sheet: [34, 43]
  }, {
    unified: '1F64B-1F3FF',
    sheet: [34, 44]
  }],
  shortName: 'raising_hand',
  obsoletedBy: '1F64B-200D-2640-FE0F'
}, {
  name: 'Man Raising Hand',
  unified: '1F64B-200D-2642-FE0F',
  keywords: ['man_raising_hand', 'male', 'boy', 'man'],
  sheet: [34, 33],
  skinVariations: [{
    unified: '1F64B-1F3FB-200D-2642-FE0F',
    sheet: [34, 34]
  }, {
    unified: '1F64B-1F3FC-200D-2642-FE0F',
    sheet: [34, 35]
  }, {
    unified: '1F64B-1F3FD-200D-2642-FE0F',
    sheet: [34, 36]
  }, {
    unified: '1F64B-1F3FE-200D-2642-FE0F',
    sheet: [34, 37]
  }, {
    unified: '1F64B-1F3FF-200D-2642-FE0F',
    sheet: [34, 38]
  }],
  shortName: 'man-raising-hand'
}, {
  name: 'Woman Raising Hand',
  unified: '1F64B-200D-2640-FE0F',
  obsoletes: '1F64B',
  keywords: ['woman_raising_hand', 'female', 'girl', 'woman'],
  sheet: [34, 27],
  skinVariations: [{
    unified: '1F64B-1F3FB-200D-2640-FE0F',
    sheet: [34, 28]
  }, {
    unified: '1F64B-1F3FC-200D-2640-FE0F',
    sheet: [34, 29]
  }, {
    unified: '1F64B-1F3FD-200D-2640-FE0F',
    sheet: [34, 30]
  }, {
    unified: '1F64B-1F3FE-200D-2640-FE0F',
    sheet: [34, 31]
  }, {
    unified: '1F64B-1F3FF-200D-2640-FE0F',
    sheet: [34, 32]
  }],
  shortName: 'woman-raising-hand'
}, {
  name: 'Deaf Person',
  unified: '1F9CF',
  keywords: ['deaf_person', 'accessibility'],
  sheet: [47, 5],
  skinVariations: [{
    unified: '1F9CF-1F3FB',
    sheet: [47, 6]
  }, {
    unified: '1F9CF-1F3FC',
    sheet: [47, 7]
  }, {
    unified: '1F9CF-1F3FD',
    sheet: [47, 8]
  }, {
    unified: '1F9CF-1F3FE',
    sheet: [47, 9]
  }, {
    unified: '1F9CF-1F3FF',
    sheet: [47, 10]
  }],
  shortName: 'deaf_person'
}, {
  name: 'Deaf Man',
  unified: '1F9CF-200D-2642-FE0F',
  keywords: ['deaf_man', 'accessibility'],
  sheet: [46, 60],
  skinVariations: [{
    unified: '1F9CF-1F3FB-200D-2642-FE0F',
    sheet: [47, 0]
  }, {
    unified: '1F9CF-1F3FC-200D-2642-FE0F',
    sheet: [47, 1]
  }, {
    unified: '1F9CF-1F3FD-200D-2642-FE0F',
    sheet: [47, 2]
  }, {
    unified: '1F9CF-1F3FE-200D-2642-FE0F',
    sheet: [47, 3]
  }, {
    unified: '1F9CF-1F3FF-200D-2642-FE0F',
    sheet: [47, 4]
  }],
  shortName: 'deaf_man'
}, {
  name: 'Deaf Woman',
  unified: '1F9CF-200D-2640-FE0F',
  keywords: ['deaf_woman', 'accessibility'],
  sheet: [46, 54],
  skinVariations: [{
    unified: '1F9CF-1F3FB-200D-2640-FE0F',
    sheet: [46, 55]
  }, {
    unified: '1F9CF-1F3FC-200D-2640-FE0F',
    sheet: [46, 56]
  }, {
    unified: '1F9CF-1F3FD-200D-2640-FE0F',
    sheet: [46, 57]
  }, {
    unified: '1F9CF-1F3FE-200D-2640-FE0F',
    sheet: [46, 58]
  }, {
    unified: '1F9CF-1F3FF-200D-2640-FE0F',
    sheet: [46, 59]
  }],
  shortName: 'deaf_woman'
}, {
  name: 'Person Bowing Deeply',
  unified: '1F647',
  keywords: ['person_bowing', 'respectiful'],
  sheet: [34, 18],
  skinVariations: [{
    unified: '1F647-1F3FB',
    sheet: [34, 19]
  }, {
    unified: '1F647-1F3FC',
    sheet: [34, 20]
  }, {
    unified: '1F647-1F3FD',
    sheet: [34, 21]
  }, {
    unified: '1F647-1F3FE',
    sheet: [34, 22]
  }, {
    unified: '1F647-1F3FF',
    sheet: [34, 23]
  }],
  shortName: 'bow',
  obsoletedBy: '1F647-200D-2642-FE0F'
}, {
  name: 'Man Bowing',
  unified: '1F647-200D-2642-FE0F',
  obsoletes: '1F647',
  keywords: ['man_bowing', 'man', 'male', 'boy'],
  sheet: [34, 12],
  skinVariations: [{
    unified: '1F647-1F3FB-200D-2642-FE0F',
    sheet: [34, 13]
  }, {
    unified: '1F647-1F3FC-200D-2642-FE0F',
    sheet: [34, 14]
  }, {
    unified: '1F647-1F3FD-200D-2642-FE0F',
    sheet: [34, 15]
  }, {
    unified: '1F647-1F3FE-200D-2642-FE0F',
    sheet: [34, 16]
  }, {
    unified: '1F647-1F3FF-200D-2642-FE0F',
    sheet: [34, 17]
  }],
  shortName: 'man-bowing'
}, {
  name: 'Woman Bowing',
  unified: '1F647-200D-2640-FE0F',
  keywords: ['woman_bowing', 'woman', 'female', 'girl'],
  sheet: [34, 6],
  skinVariations: [{
    unified: '1F647-1F3FB-200D-2640-FE0F',
    sheet: [34, 7]
  }, {
    unified: '1F647-1F3FC-200D-2640-FE0F',
    sheet: [34, 8]
  }, {
    unified: '1F647-1F3FD-200D-2640-FE0F',
    sheet: [34, 9]
  }, {
    unified: '1F647-1F3FE-200D-2640-FE0F',
    sheet: [34, 10]
  }, {
    unified: '1F647-1F3FF-200D-2640-FE0F',
    sheet: [34, 11]
  }],
  shortName: 'woman-bowing'
}, {
  name: 'Face Palm',
  unified: '1F926',
  keywords: ['person_facepalming', 'disappointed'],
  sheet: [40, 30],
  skinVariations: [{
    unified: '1F926-1F3FB',
    sheet: [40, 31]
  }, {
    unified: '1F926-1F3FC',
    sheet: [40, 32]
  }, {
    unified: '1F926-1F3FD',
    sheet: [40, 33]
  }, {
    unified: '1F926-1F3FE',
    sheet: [40, 34]
  }, {
    unified: '1F926-1F3FF',
    sheet: [40, 35]
  }],
  shortName: 'face_palm'
}, {
  name: 'Man Facepalming',
  unified: '1F926-200D-2642-FE0F',
  keywords: ['man_facepalming', 'man', 'male', 'boy', 'disbelief'],
  sheet: [40, 24],
  skinVariations: [{
    unified: '1F926-1F3FB-200D-2642-FE0F',
    sheet: [40, 25]
  }, {
    unified: '1F926-1F3FC-200D-2642-FE0F',
    sheet: [40, 26]
  }, {
    unified: '1F926-1F3FD-200D-2642-FE0F',
    sheet: [40, 27]
  }, {
    unified: '1F926-1F3FE-200D-2642-FE0F',
    sheet: [40, 28]
  }, {
    unified: '1F926-1F3FF-200D-2642-FE0F',
    sheet: [40, 29]
  }],
  shortName: 'man-facepalming'
}, {
  name: 'Woman Facepalming',
  unified: '1F926-200D-2640-FE0F',
  keywords: ['woman_facepalming', 'woman', 'female', 'girl', 'disbelief'],
  sheet: [40, 18],
  skinVariations: [{
    unified: '1F926-1F3FB-200D-2640-FE0F',
    sheet: [40, 19]
  }, {
    unified: '1F926-1F3FC-200D-2640-FE0F',
    sheet: [40, 20]
  }, {
    unified: '1F926-1F3FD-200D-2640-FE0F',
    sheet: [40, 21]
  }, {
    unified: '1F926-1F3FE-200D-2640-FE0F',
    sheet: [40, 22]
  }, {
    unified: '1F926-1F3FF-200D-2640-FE0F',
    sheet: [40, 23]
  }],
  shortName: 'woman-facepalming'
}, {
  name: 'Shrug',
  unified: '1F937',
  keywords: ['person_shrugging', 'regardless'],
  sheet: [41, 50],
  skinVariations: [{
    unified: '1F937-1F3FB',
    sheet: [41, 51]
  }, {
    unified: '1F937-1F3FC',
    sheet: [41, 52]
  }, {
    unified: '1F937-1F3FD',
    sheet: [41, 53]
  }, {
    unified: '1F937-1F3FE',
    sheet: [41, 54]
  }, {
    unified: '1F937-1F3FF',
    sheet: [41, 55]
  }],
  shortName: 'shrug'
}, {
  name: 'Man Shrugging',
  unified: '1F937-200D-2642-FE0F',
  keywords: ['man_shrugging', 'man', 'male', 'boy', 'confused', 'indifferent', 'doubt'],
  sheet: [41, 44],
  skinVariations: [{
    unified: '1F937-1F3FB-200D-2642-FE0F',
    sheet: [41, 45]
  }, {
    unified: '1F937-1F3FC-200D-2642-FE0F',
    sheet: [41, 46]
  }, {
    unified: '1F937-1F3FD-200D-2642-FE0F',
    sheet: [41, 47]
  }, {
    unified: '1F937-1F3FE-200D-2642-FE0F',
    sheet: [41, 48]
  }, {
    unified: '1F937-1F3FF-200D-2642-FE0F',
    sheet: [41, 49]
  }],
  shortName: 'man-shrugging'
}, {
  name: 'Woman Shrugging',
  unified: '1F937-200D-2640-FE0F',
  keywords: ['woman_shrugging', 'woman', 'female', 'girl', 'confused', 'indifferent', 'doubt'],
  sheet: [41, 38],
  skinVariations: [{
    unified: '1F937-1F3FB-200D-2640-FE0F',
    sheet: [41, 39]
  }, {
    unified: '1F937-1F3FC-200D-2640-FE0F',
    sheet: [41, 40]
  }, {
    unified: '1F937-1F3FD-200D-2640-FE0F',
    sheet: [41, 41]
  }, {
    unified: '1F937-1F3FE-200D-2640-FE0F',
    sheet: [41, 42]
  }, {
    unified: '1F937-1F3FF-200D-2640-FE0F',
    sheet: [41, 43]
  }],
  shortName: 'woman-shrugging'
}, {
  name: 'Health Worker',
  unified: '1F9D1-200D-2695-FE0F',
  keywords: ['health_worker', 'hospital'],
  sheet: [49, 48],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-2695-FE0F',
    sheet: [49, 49]
  }, {
    unified: '1F9D1-1F3FC-200D-2695-FE0F',
    sheet: [49, 50]
  }, {
    unified: '1F9D1-1F3FD-200D-2695-FE0F',
    sheet: [49, 51]
  }, {
    unified: '1F9D1-1F3FE-200D-2695-FE0F',
    sheet: [49, 52]
  }, {
    unified: '1F9D1-1F3FF-200D-2695-FE0F',
    sheet: [49, 53]
  }],
  shortName: 'health_worker'
}, {
  name: 'Man Health Worker',
  unified: '1F468-200D-2695-FE0F',
  keywords: ['man_health_worker', 'doctor', 'nurse', 'therapist', 'healthcare', 'man', 'human'],
  sheet: [16, 4],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-2695-FE0F',
    sheet: [16, 5]
  }, {
    unified: '1F468-1F3FC-200D-2695-FE0F',
    sheet: [16, 6]
  }, {
    unified: '1F468-1F3FD-200D-2695-FE0F',
    sheet: [16, 7]
  }, {
    unified: '1F468-1F3FE-200D-2695-FE0F',
    sheet: [16, 8]
  }, {
    unified: '1F468-1F3FF-200D-2695-FE0F',
    sheet: [16, 9]
  }],
  shortName: 'male-doctor'
}, {
  name: 'Woman Health Worker',
  unified: '1F469-200D-2695-FE0F',
  keywords: ['woman_health_worker', 'doctor', 'nurse', 'therapist', 'healthcare', 'woman', 'human'],
  sheet: [19, 33],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2695-FE0F',
    sheet: [19, 34]
  }, {
    unified: '1F469-1F3FC-200D-2695-FE0F',
    sheet: [19, 35]
  }, {
    unified: '1F469-1F3FD-200D-2695-FE0F',
    sheet: [19, 36]
  }, {
    unified: '1F469-1F3FE-200D-2695-FE0F',
    sheet: [19, 37]
  }, {
    unified: '1F469-1F3FF-200D-2695-FE0F',
    sheet: [19, 38]
  }],
  shortName: 'female-doctor'
}, {
  name: 'Student',
  unified: '1F9D1-200D-1F393',
  keywords: ['student', 'learn'],
  sheet: [47, 36],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F393',
    sheet: [47, 37]
  }, {
    unified: '1F9D1-1F3FC-200D-1F393',
    sheet: [47, 38]
  }, {
    unified: '1F9D1-1F3FD-200D-1F393',
    sheet: [47, 39]
  }, {
    unified: '1F9D1-1F3FE-200D-1F393',
    sheet: [47, 40]
  }, {
    unified: '1F9D1-1F3FF-200D-1F393',
    sheet: [47, 41]
  }],
  shortName: 'student'
}, {
  name: 'Man Student',
  unified: '1F468-200D-1F393',
  keywords: ['man_student', 'graduate', 'man', 'human'],
  sheet: [14, 3],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F393',
    sheet: [14, 4]
  }, {
    unified: '1F468-1F3FC-200D-1F393',
    sheet: [14, 5]
  }, {
    unified: '1F468-1F3FD-200D-1F393',
    sheet: [14, 6]
  }, {
    unified: '1F468-1F3FE-200D-1F393',
    sheet: [14, 7]
  }, {
    unified: '1F468-1F3FF-200D-1F393',
    sheet: [14, 8]
  }],
  shortName: 'male-student'
}, {
  name: 'Woman Student',
  unified: '1F469-200D-1F393',
  keywords: ['woman_student', 'graduate', 'woman', 'human'],
  sheet: [17, 37],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F393',
    sheet: [17, 38]
  }, {
    unified: '1F469-1F3FC-200D-1F393',
    sheet: [17, 39]
  }, {
    unified: '1F469-1F3FD-200D-1F393',
    sheet: [17, 40]
  }, {
    unified: '1F469-1F3FE-200D-1F393',
    sheet: [17, 41]
  }, {
    unified: '1F469-1F3FF-200D-1F393',
    sheet: [17, 42]
  }],
  shortName: 'female-student'
}, {
  name: 'Teacher',
  unified: '1F9D1-200D-1F3EB',
  keywords: ['teacher', 'professor'],
  sheet: [47, 54],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F3EB',
    sheet: [47, 55]
  }, {
    unified: '1F9D1-1F3FC-200D-1F3EB',
    sheet: [47, 56]
  }, {
    unified: '1F9D1-1F3FD-200D-1F3EB',
    sheet: [47, 57]
  }, {
    unified: '1F9D1-1F3FE-200D-1F3EB',
    sheet: [47, 58]
  }, {
    unified: '1F9D1-1F3FF-200D-1F3EB',
    sheet: [47, 59]
  }],
  shortName: 'teacher'
}, {
  name: 'Man Teacher',
  unified: '1F468-200D-1F3EB',
  keywords: ['man_teacher', 'instructor', 'professor', 'man', 'human'],
  sheet: [14, 21],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F3EB',
    sheet: [14, 22]
  }, {
    unified: '1F468-1F3FC-200D-1F3EB',
    sheet: [14, 23]
  }, {
    unified: '1F468-1F3FD-200D-1F3EB',
    sheet: [14, 24]
  }, {
    unified: '1F468-1F3FE-200D-1F3EB',
    sheet: [14, 25]
  }, {
    unified: '1F468-1F3FF-200D-1F3EB',
    sheet: [14, 26]
  }],
  shortName: 'male-teacher'
}, {
  name: 'Woman Teacher',
  unified: '1F469-200D-1F3EB',
  keywords: ['woman_teacher', 'instructor', 'professor', 'woman', 'human'],
  sheet: [17, 55],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F3EB',
    sheet: [17, 56]
  }, {
    unified: '1F469-1F3FC-200D-1F3EB',
    sheet: [17, 57]
  }, {
    unified: '1F469-1F3FD-200D-1F3EB',
    sheet: [17, 58]
  }, {
    unified: '1F469-1F3FE-200D-1F3EB',
    sheet: [17, 59]
  }, {
    unified: '1F469-1F3FF-200D-1F3EB',
    sheet: [17, 60]
  }],
  shortName: 'female-teacher'
}, {
  name: 'Judge',
  unified: '1F9D1-200D-2696-FE0F',
  keywords: ['judge', 'law'],
  sheet: [49, 54],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-2696-FE0F',
    sheet: [49, 55]
  }, {
    unified: '1F9D1-1F3FC-200D-2696-FE0F',
    sheet: [49, 56]
  }, {
    unified: '1F9D1-1F3FD-200D-2696-FE0F',
    sheet: [49, 57]
  }, {
    unified: '1F9D1-1F3FE-200D-2696-FE0F',
    sheet: [49, 58]
  }, {
    unified: '1F9D1-1F3FF-200D-2696-FE0F',
    sheet: [49, 59]
  }],
  shortName: 'judge'
}, {
  name: 'Man Judge',
  unified: '1F468-200D-2696-FE0F',
  keywords: ['man_judge', 'justice', 'court', 'man', 'human'],
  sheet: [16, 10],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-2696-FE0F',
    sheet: [16, 11]
  }, {
    unified: '1F468-1F3FC-200D-2696-FE0F',
    sheet: [16, 12]
  }, {
    unified: '1F468-1F3FD-200D-2696-FE0F',
    sheet: [16, 13]
  }, {
    unified: '1F468-1F3FE-200D-2696-FE0F',
    sheet: [16, 14]
  }, {
    unified: '1F468-1F3FF-200D-2696-FE0F',
    sheet: [16, 15]
  }],
  shortName: 'male-judge'
}, {
  name: 'Woman Judge',
  unified: '1F469-200D-2696-FE0F',
  keywords: ['woman_judge', 'justice', 'court', 'woman', 'human'],
  sheet: [19, 39],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2696-FE0F',
    sheet: [19, 40]
  }, {
    unified: '1F469-1F3FC-200D-2696-FE0F',
    sheet: [19, 41]
  }, {
    unified: '1F469-1F3FD-200D-2696-FE0F',
    sheet: [19, 42]
  }, {
    unified: '1F469-1F3FE-200D-2696-FE0F',
    sheet: [19, 43]
  }, {
    unified: '1F469-1F3FF-200D-2696-FE0F',
    sheet: [19, 44]
  }],
  shortName: 'female-judge'
}, {
  name: 'Farmer',
  unified: '1F9D1-200D-1F33E',
  keywords: ['farmer', 'crops'],
  sheet: [47, 12],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F33E',
    sheet: [47, 13]
  }, {
    unified: '1F9D1-1F3FC-200D-1F33E',
    sheet: [47, 14]
  }, {
    unified: '1F9D1-1F3FD-200D-1F33E',
    sheet: [47, 15]
  }, {
    unified: '1F9D1-1F3FE-200D-1F33E',
    sheet: [47, 16]
  }, {
    unified: '1F9D1-1F3FF-200D-1F33E',
    sheet: [47, 17]
  }],
  shortName: 'farmer'
}, {
  name: 'Man Farmer',
  unified: '1F468-200D-1F33E',
  keywords: ['man_farmer', 'rancher', 'gardener', 'man', 'human'],
  sheet: [13, 46],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F33E',
    sheet: [13, 47]
  }, {
    unified: '1F468-1F3FC-200D-1F33E',
    sheet: [13, 48]
  }, {
    unified: '1F468-1F3FD-200D-1F33E',
    sheet: [13, 49]
  }, {
    unified: '1F468-1F3FE-200D-1F33E',
    sheet: [13, 50]
  }, {
    unified: '1F468-1F3FF-200D-1F33E',
    sheet: [13, 51]
  }],
  shortName: 'male-farmer'
}, {
  name: 'Woman Farmer',
  unified: '1F469-200D-1F33E',
  keywords: ['woman_farmer', 'rancher', 'gardener', 'woman', 'human'],
  sheet: [17, 19],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F33E',
    sheet: [17, 20]
  }, {
    unified: '1F469-1F3FC-200D-1F33E',
    sheet: [17, 21]
  }, {
    unified: '1F469-1F3FD-200D-1F33E',
    sheet: [17, 22]
  }, {
    unified: '1F469-1F3FE-200D-1F33E',
    sheet: [17, 23]
  }, {
    unified: '1F469-1F3FF-200D-1F33E',
    sheet: [17, 24]
  }],
  shortName: 'female-farmer'
}, {
  name: 'Cook',
  unified: '1F9D1-200D-1F373',
  keywords: ['cook', 'food', 'kitchen', 'culinary'],
  sheet: [47, 18],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F373',
    sheet: [47, 19]
  }, {
    unified: '1F9D1-1F3FC-200D-1F373',
    sheet: [47, 20]
  }, {
    unified: '1F9D1-1F3FD-200D-1F373',
    sheet: [47, 21]
  }, {
    unified: '1F9D1-1F3FE-200D-1F373',
    sheet: [47, 22]
  }, {
    unified: '1F9D1-1F3FF-200D-1F373',
    sheet: [47, 23]
  }],
  shortName: 'cook'
}, {
  name: 'Man Cook',
  unified: '1F468-200D-1F373',
  keywords: ['man_cook', 'chef', 'man', 'human'],
  sheet: [13, 52],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F373',
    sheet: [13, 53]
  }, {
    unified: '1F468-1F3FC-200D-1F373',
    sheet: [13, 54]
  }, {
    unified: '1F468-1F3FD-200D-1F373',
    sheet: [13, 55]
  }, {
    unified: '1F468-1F3FE-200D-1F373',
    sheet: [13, 56]
  }, {
    unified: '1F468-1F3FF-200D-1F373',
    sheet: [13, 57]
  }],
  shortName: 'male-cook'
}, {
  name: 'Woman Cook',
  unified: '1F469-200D-1F373',
  keywords: ['woman_cook', 'chef', 'woman', 'human'],
  sheet: [17, 25],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F373',
    sheet: [17, 26]
  }, {
    unified: '1F469-1F3FC-200D-1F373',
    sheet: [17, 27]
  }, {
    unified: '1F469-1F3FD-200D-1F373',
    sheet: [17, 28]
  }, {
    unified: '1F469-1F3FE-200D-1F373',
    sheet: [17, 29]
  }, {
    unified: '1F469-1F3FF-200D-1F373',
    sheet: [17, 30]
  }],
  shortName: 'female-cook'
}, {
  name: 'Mechanic',
  unified: '1F9D1-200D-1F527',
  keywords: ['mechanic', 'worker', 'technician'],
  sheet: [48, 17],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F527',
    sheet: [48, 18]
  }, {
    unified: '1F9D1-1F3FC-200D-1F527',
    sheet: [48, 19]
  }, {
    unified: '1F9D1-1F3FD-200D-1F527',
    sheet: [48, 20]
  }, {
    unified: '1F9D1-1F3FE-200D-1F527',
    sheet: [48, 21]
  }, {
    unified: '1F9D1-1F3FF-200D-1F527',
    sheet: [48, 22]
  }],
  shortName: 'mechanic'
}, {
  name: 'Man Mechanic',
  unified: '1F468-200D-1F527',
  keywords: ['man_mechanic', 'plumber', 'man', 'human', 'wrench'],
  sheet: [14, 60],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F527',
    sheet: [15, 0]
  }, {
    unified: '1F468-1F3FC-200D-1F527',
    sheet: [15, 1]
  }, {
    unified: '1F468-1F3FD-200D-1F527',
    sheet: [15, 2]
  }, {
    unified: '1F468-1F3FE-200D-1F527',
    sheet: [15, 3]
  }, {
    unified: '1F468-1F3FF-200D-1F527',
    sheet: [15, 4]
  }],
  shortName: 'male-mechanic'
}, {
  name: 'Woman Mechanic',
  unified: '1F469-200D-1F527',
  keywords: ['woman_mechanic', 'plumber', 'woman', 'human', 'wrench'],
  sheet: [18, 28],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F527',
    sheet: [18, 29]
  }, {
    unified: '1F469-1F3FC-200D-1F527',
    sheet: [18, 30]
  }, {
    unified: '1F469-1F3FD-200D-1F527',
    sheet: [18, 31]
  }, {
    unified: '1F469-1F3FE-200D-1F527',
    sheet: [18, 32]
  }, {
    unified: '1F469-1F3FF-200D-1F527',
    sheet: [18, 33]
  }],
  shortName: 'female-mechanic'
}, {
  name: 'Factory Worker',
  unified: '1F9D1-200D-1F3ED',
  keywords: ['factory_worker', 'labor'],
  sheet: [47, 60],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F3ED',
    sheet: [48, 0]
  }, {
    unified: '1F9D1-1F3FC-200D-1F3ED',
    sheet: [48, 1]
  }, {
    unified: '1F9D1-1F3FD-200D-1F3ED',
    sheet: [48, 2]
  }, {
    unified: '1F9D1-1F3FE-200D-1F3ED',
    sheet: [48, 3]
  }, {
    unified: '1F9D1-1F3FF-200D-1F3ED',
    sheet: [48, 4]
  }],
  shortName: 'factory_worker'
}, {
  name: 'Man Factory Worker',
  unified: '1F468-200D-1F3ED',
  keywords: ['man_factory_worker', 'assembly', 'industrial', 'man', 'human'],
  sheet: [14, 27],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F3ED',
    sheet: [14, 28]
  }, {
    unified: '1F468-1F3FC-200D-1F3ED',
    sheet: [14, 29]
  }, {
    unified: '1F468-1F3FD-200D-1F3ED',
    sheet: [14, 30]
  }, {
    unified: '1F468-1F3FE-200D-1F3ED',
    sheet: [14, 31]
  }, {
    unified: '1F468-1F3FF-200D-1F3ED',
    sheet: [14, 32]
  }],
  shortName: 'male-factory-worker'
}, {
  name: 'Woman Factory Worker',
  unified: '1F469-200D-1F3ED',
  keywords: ['woman_factory_worker', 'assembly', 'industrial', 'woman', 'human'],
  sheet: [18, 0],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F3ED',
    sheet: [18, 1]
  }, {
    unified: '1F469-1F3FC-200D-1F3ED',
    sheet: [18, 2]
  }, {
    unified: '1F469-1F3FD-200D-1F3ED',
    sheet: [18, 3]
  }, {
    unified: '1F469-1F3FE-200D-1F3ED',
    sheet: [18, 4]
  }, {
    unified: '1F469-1F3FF-200D-1F3ED',
    sheet: [18, 5]
  }],
  shortName: 'female-factory-worker'
}, {
  name: 'Office Worker',
  unified: '1F9D1-200D-1F4BC',
  keywords: ['office_worker', 'business'],
  sheet: [48, 11],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F4BC',
    sheet: [48, 12]
  }, {
    unified: '1F9D1-1F3FC-200D-1F4BC',
    sheet: [48, 13]
  }, {
    unified: '1F9D1-1F3FD-200D-1F4BC',
    sheet: [48, 14]
  }, {
    unified: '1F9D1-1F3FE-200D-1F4BC',
    sheet: [48, 15]
  }, {
    unified: '1F9D1-1F3FF-200D-1F4BC',
    sheet: [48, 16]
  }],
  shortName: 'office_worker'
}, {
  name: 'Man Office Worker',
  unified: '1F468-200D-1F4BC',
  keywords: ['man_office_worker', 'business', 'manager', 'man', 'human'],
  sheet: [14, 54],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F4BC',
    sheet: [14, 55]
  }, {
    unified: '1F468-1F3FC-200D-1F4BC',
    sheet: [14, 56]
  }, {
    unified: '1F468-1F3FD-200D-1F4BC',
    sheet: [14, 57]
  }, {
    unified: '1F468-1F3FE-200D-1F4BC',
    sheet: [14, 58]
  }, {
    unified: '1F468-1F3FF-200D-1F4BC',
    sheet: [14, 59]
  }],
  shortName: 'male-office-worker'
}, {
  name: 'Woman Office Worker',
  unified: '1F469-200D-1F4BC',
  keywords: ['woman_office_worker', 'business', 'manager', 'woman', 'human'],
  sheet: [18, 22],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F4BC',
    sheet: [18, 23]
  }, {
    unified: '1F469-1F3FC-200D-1F4BC',
    sheet: [18, 24]
  }, {
    unified: '1F469-1F3FD-200D-1F4BC',
    sheet: [18, 25]
  }, {
    unified: '1F469-1F3FE-200D-1F4BC',
    sheet: [18, 26]
  }, {
    unified: '1F469-1F3FF-200D-1F4BC',
    sheet: [18, 27]
  }],
  shortName: 'female-office-worker'
}, {
  name: 'Scientist',
  unified: '1F9D1-200D-1F52C',
  keywords: ['scientist', 'chemistry'],
  sheet: [48, 23],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F52C',
    sheet: [48, 24]
  }, {
    unified: '1F9D1-1F3FC-200D-1F52C',
    sheet: [48, 25]
  }, {
    unified: '1F9D1-1F3FD-200D-1F52C',
    sheet: [48, 26]
  }, {
    unified: '1F9D1-1F3FE-200D-1F52C',
    sheet: [48, 27]
  }, {
    unified: '1F9D1-1F3FF-200D-1F52C',
    sheet: [48, 28]
  }],
  shortName: 'scientist'
}, {
  name: 'Man Scientist',
  unified: '1F468-200D-1F52C',
  keywords: ['man_scientist', 'biologist', 'chemist', 'engineer', 'physicist', 'man', 'human'],
  sheet: [15, 5],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F52C',
    sheet: [15, 6]
  }, {
    unified: '1F468-1F3FC-200D-1F52C',
    sheet: [15, 7]
  }, {
    unified: '1F468-1F3FD-200D-1F52C',
    sheet: [15, 8]
  }, {
    unified: '1F468-1F3FE-200D-1F52C',
    sheet: [15, 9]
  }, {
    unified: '1F468-1F3FF-200D-1F52C',
    sheet: [15, 10]
  }],
  shortName: 'male-scientist'
}, {
  name: 'Woman Scientist',
  unified: '1F469-200D-1F52C',
  keywords: ['woman_scientist', 'biologist', 'chemist', 'engineer', 'physicist', 'woman', 'human'],
  sheet: [18, 34],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F52C',
    sheet: [18, 35]
  }, {
    unified: '1F469-1F3FC-200D-1F52C',
    sheet: [18, 36]
  }, {
    unified: '1F469-1F3FD-200D-1F52C',
    sheet: [18, 37]
  }, {
    unified: '1F469-1F3FE-200D-1F52C',
    sheet: [18, 38]
  }, {
    unified: '1F469-1F3FF-200D-1F52C',
    sheet: [18, 39]
  }],
  shortName: 'female-scientist'
}, {
  name: 'Technologist',
  unified: '1F9D1-200D-1F4BB',
  keywords: ['technologist', 'computer'],
  sheet: [48, 5],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F4BB',
    sheet: [48, 6]
  }, {
    unified: '1F9D1-1F3FC-200D-1F4BB',
    sheet: [48, 7]
  }, {
    unified: '1F9D1-1F3FD-200D-1F4BB',
    sheet: [48, 8]
  }, {
    unified: '1F9D1-1F3FE-200D-1F4BB',
    sheet: [48, 9]
  }, {
    unified: '1F9D1-1F3FF-200D-1F4BB',
    sheet: [48, 10]
  }],
  shortName: 'technologist'
}, {
  name: 'Man Technologist',
  unified: '1F468-200D-1F4BB',
  keywords: ['man_technologist', 'coder', 'developer', 'engineer', 'programmer', 'software', 'man', 'human', 'laptop', 'computer'],
  sheet: [14, 48],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F4BB',
    sheet: [14, 49]
  }, {
    unified: '1F468-1F3FC-200D-1F4BB',
    sheet: [14, 50]
  }, {
    unified: '1F468-1F3FD-200D-1F4BB',
    sheet: [14, 51]
  }, {
    unified: '1F468-1F3FE-200D-1F4BB',
    sheet: [14, 52]
  }, {
    unified: '1F468-1F3FF-200D-1F4BB',
    sheet: [14, 53]
  }],
  shortName: 'male-technologist'
}, {
  name: 'Woman Technologist',
  unified: '1F469-200D-1F4BB',
  keywords: ['woman_technologist', 'coder', 'developer', 'engineer', 'programmer', 'software', 'woman', 'human', 'laptop', 'computer'],
  sheet: [18, 16],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F4BB',
    sheet: [18, 17]
  }, {
    unified: '1F469-1F3FC-200D-1F4BB',
    sheet: [18, 18]
  }, {
    unified: '1F469-1F3FD-200D-1F4BB',
    sheet: [18, 19]
  }, {
    unified: '1F469-1F3FE-200D-1F4BB',
    sheet: [18, 20]
  }, {
    unified: '1F469-1F3FF-200D-1F4BB',
    sheet: [18, 21]
  }],
  shortName: 'female-technologist'
}, {
  name: 'Singer',
  unified: '1F9D1-200D-1F3A4',
  keywords: ['singer', 'song', 'artist', 'performer'],
  sheet: [47, 42],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F3A4',
    sheet: [47, 43]
  }, {
    unified: '1F9D1-1F3FC-200D-1F3A4',
    sheet: [47, 44]
  }, {
    unified: '1F9D1-1F3FD-200D-1F3A4',
    sheet: [47, 45]
  }, {
    unified: '1F9D1-1F3FE-200D-1F3A4',
    sheet: [47, 46]
  }, {
    unified: '1F9D1-1F3FF-200D-1F3A4',
    sheet: [47, 47]
  }],
  shortName: 'singer'
}, {
  name: 'Man Singer',
  unified: '1F468-200D-1F3A4',
  keywords: ['man_singer', 'rockstar', 'entertainer', 'man', 'human'],
  sheet: [14, 9],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F3A4',
    sheet: [14, 10]
  }, {
    unified: '1F468-1F3FC-200D-1F3A4',
    sheet: [14, 11]
  }, {
    unified: '1F468-1F3FD-200D-1F3A4',
    sheet: [14, 12]
  }, {
    unified: '1F468-1F3FE-200D-1F3A4',
    sheet: [14, 13]
  }, {
    unified: '1F468-1F3FF-200D-1F3A4',
    sheet: [14, 14]
  }],
  shortName: 'male-singer'
}, {
  name: 'Woman Singer',
  unified: '1F469-200D-1F3A4',
  keywords: ['woman_singer', 'rockstar', 'entertainer', 'woman', 'human'],
  sheet: [17, 43],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F3A4',
    sheet: [17, 44]
  }, {
    unified: '1F469-1F3FC-200D-1F3A4',
    sheet: [17, 45]
  }, {
    unified: '1F469-1F3FD-200D-1F3A4',
    sheet: [17, 46]
  }, {
    unified: '1F469-1F3FE-200D-1F3A4',
    sheet: [17, 47]
  }, {
    unified: '1F469-1F3FF-200D-1F3A4',
    sheet: [17, 48]
  }],
  shortName: 'female-singer'
}, {
  name: 'Artist',
  unified: '1F9D1-200D-1F3A8',
  keywords: ['artist', 'painting', 'draw', 'creativity'],
  sheet: [47, 48],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F3A8',
    sheet: [47, 49]
  }, {
    unified: '1F9D1-1F3FC-200D-1F3A8',
    sheet: [47, 50]
  }, {
    unified: '1F9D1-1F3FD-200D-1F3A8',
    sheet: [47, 51]
  }, {
    unified: '1F9D1-1F3FE-200D-1F3A8',
    sheet: [47, 52]
  }, {
    unified: '1F9D1-1F3FF-200D-1F3A8',
    sheet: [47, 53]
  }],
  shortName: 'artist'
}, {
  name: 'Man Artist',
  unified: '1F468-200D-1F3A8',
  keywords: ['man_artist', 'painter', 'man', 'human'],
  sheet: [14, 15],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F3A8',
    sheet: [14, 16]
  }, {
    unified: '1F468-1F3FC-200D-1F3A8',
    sheet: [14, 17]
  }, {
    unified: '1F468-1F3FD-200D-1F3A8',
    sheet: [14, 18]
  }, {
    unified: '1F468-1F3FE-200D-1F3A8',
    sheet: [14, 19]
  }, {
    unified: '1F468-1F3FF-200D-1F3A8',
    sheet: [14, 20]
  }],
  shortName: 'male-artist'
}, {
  name: 'Woman Artist',
  unified: '1F469-200D-1F3A8',
  keywords: ['woman_artist', 'painter', 'woman', 'human'],
  sheet: [17, 49],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F3A8',
    sheet: [17, 50]
  }, {
    unified: '1F469-1F3FC-200D-1F3A8',
    sheet: [17, 51]
  }, {
    unified: '1F469-1F3FD-200D-1F3A8',
    sheet: [17, 52]
  }, {
    unified: '1F469-1F3FE-200D-1F3A8',
    sheet: [17, 53]
  }, {
    unified: '1F469-1F3FF-200D-1F3A8',
    sheet: [17, 54]
  }],
  shortName: 'female-artist'
}, {
  name: 'Pilot',
  unified: '1F9D1-200D-2708-FE0F',
  keywords: ['pilot', 'fly', 'plane', 'airplane'],
  sheet: [49, 60],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-2708-FE0F',
    sheet: [50, 0]
  }, {
    unified: '1F9D1-1F3FC-200D-2708-FE0F',
    sheet: [50, 1]
  }, {
    unified: '1F9D1-1F3FD-200D-2708-FE0F',
    sheet: [50, 2]
  }, {
    unified: '1F9D1-1F3FE-200D-2708-FE0F',
    sheet: [50, 3]
  }, {
    unified: '1F9D1-1F3FF-200D-2708-FE0F',
    sheet: [50, 4]
  }],
  shortName: 'pilot'
}, {
  name: 'Man Pilot',
  unified: '1F468-200D-2708-FE0F',
  keywords: ['man_pilot', 'aviator', 'plane', 'man', 'human'],
  sheet: [16, 16],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-2708-FE0F',
    sheet: [16, 17]
  }, {
    unified: '1F468-1F3FC-200D-2708-FE0F',
    sheet: [16, 18]
  }, {
    unified: '1F468-1F3FD-200D-2708-FE0F',
    sheet: [16, 19]
  }, {
    unified: '1F468-1F3FE-200D-2708-FE0F',
    sheet: [16, 20]
  }, {
    unified: '1F468-1F3FF-200D-2708-FE0F',
    sheet: [16, 21]
  }],
  shortName: 'male-pilot'
}, {
  name: 'Woman Pilot',
  unified: '1F469-200D-2708-FE0F',
  keywords: ['woman_pilot', 'aviator', 'plane', 'woman', 'human'],
  sheet: [19, 45],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2708-FE0F',
    sheet: [19, 46]
  }, {
    unified: '1F469-1F3FC-200D-2708-FE0F',
    sheet: [19, 47]
  }, {
    unified: '1F469-1F3FD-200D-2708-FE0F',
    sheet: [19, 48]
  }, {
    unified: '1F469-1F3FE-200D-2708-FE0F',
    sheet: [19, 49]
  }, {
    unified: '1F469-1F3FF-200D-2708-FE0F',
    sheet: [19, 50]
  }],
  shortName: 'female-pilot'
}, {
  name: 'Astronaut',
  unified: '1F9D1-200D-1F680',
  keywords: ['astronaut', 'outerspace'],
  sheet: [48, 29],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F680',
    sheet: [48, 30]
  }, {
    unified: '1F9D1-1F3FC-200D-1F680',
    sheet: [48, 31]
  }, {
    unified: '1F9D1-1F3FD-200D-1F680',
    sheet: [48, 32]
  }, {
    unified: '1F9D1-1F3FE-200D-1F680',
    sheet: [48, 33]
  }, {
    unified: '1F9D1-1F3FF-200D-1F680',
    sheet: [48, 34]
  }],
  shortName: 'astronaut'
}, {
  name: 'Man Astronaut',
  unified: '1F468-200D-1F680',
  keywords: ['man_astronaut', 'space', 'rocket', 'man', 'human'],
  sheet: [15, 11],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F680',
    sheet: [15, 12]
  }, {
    unified: '1F468-1F3FC-200D-1F680',
    sheet: [15, 13]
  }, {
    unified: '1F468-1F3FD-200D-1F680',
    sheet: [15, 14]
  }, {
    unified: '1F468-1F3FE-200D-1F680',
    sheet: [15, 15]
  }, {
    unified: '1F468-1F3FF-200D-1F680',
    sheet: [15, 16]
  }],
  shortName: 'male-astronaut'
}, {
  name: 'Woman Astronaut',
  unified: '1F469-200D-1F680',
  keywords: ['woman_astronaut', 'space', 'rocket', 'woman', 'human'],
  sheet: [18, 40],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F680',
    sheet: [18, 41]
  }, {
    unified: '1F469-1F3FC-200D-1F680',
    sheet: [18, 42]
  }, {
    unified: '1F469-1F3FD-200D-1F680',
    sheet: [18, 43]
  }, {
    unified: '1F469-1F3FE-200D-1F680',
    sheet: [18, 44]
  }, {
    unified: '1F469-1F3FF-200D-1F680',
    sheet: [18, 45]
  }],
  shortName: 'female-astronaut'
}, {
  name: 'Firefighter',
  unified: '1F9D1-200D-1F692',
  keywords: ['firefighter', 'fire'],
  sheet: [48, 35],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F692',
    sheet: [48, 36]
  }, {
    unified: '1F9D1-1F3FC-200D-1F692',
    sheet: [48, 37]
  }, {
    unified: '1F9D1-1F3FD-200D-1F692',
    sheet: [48, 38]
  }, {
    unified: '1F9D1-1F3FE-200D-1F692',
    sheet: [48, 39]
  }, {
    unified: '1F9D1-1F3FF-200D-1F692',
    sheet: [48, 40]
  }],
  shortName: 'firefighter'
}, {
  name: 'Man Firefighter',
  unified: '1F468-200D-1F692',
  keywords: ['man_firefighter', 'fireman', 'man', 'human'],
  sheet: [15, 17],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F692',
    sheet: [15, 18]
  }, {
    unified: '1F468-1F3FC-200D-1F692',
    sheet: [15, 19]
  }, {
    unified: '1F468-1F3FD-200D-1F692',
    sheet: [15, 20]
  }, {
    unified: '1F468-1F3FE-200D-1F692',
    sheet: [15, 21]
  }, {
    unified: '1F468-1F3FF-200D-1F692',
    sheet: [15, 22]
  }],
  shortName: 'male-firefighter'
}, {
  name: 'Woman Firefighter',
  unified: '1F469-200D-1F692',
  keywords: ['woman_firefighter', 'fireman', 'woman', 'human'],
  sheet: [18, 46],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F692',
    sheet: [18, 47]
  }, {
    unified: '1F469-1F3FC-200D-1F692',
    sheet: [18, 48]
  }, {
    unified: '1F469-1F3FD-200D-1F692',
    sheet: [18, 49]
  }, {
    unified: '1F469-1F3FE-200D-1F692',
    sheet: [18, 50]
  }, {
    unified: '1F469-1F3FF-200D-1F692',
    sheet: [18, 51]
  }],
  shortName: 'female-firefighter'
}, {
  name: 'Police Officer',
  unified: '1F46E',
  keywords: ['police_officer', 'cop'],
  sheet: [23, 8],
  skinVariations: [{
    unified: '1F46E-1F3FB',
    sheet: [23, 9]
  }, {
    unified: '1F46E-1F3FC',
    sheet: [23, 10]
  }, {
    unified: '1F46E-1F3FD',
    sheet: [23, 11]
  }, {
    unified: '1F46E-1F3FE',
    sheet: [23, 12]
  }, {
    unified: '1F46E-1F3FF',
    sheet: [23, 13]
  }],
  shortName: 'cop',
  obsoletedBy: '1F46E-200D-2642-FE0F'
}, {
  name: 'Man Police Officer',
  unified: '1F46E-200D-2642-FE0F',
  obsoletes: '1F46E',
  keywords: ['man_police_officer', 'man', 'police', 'law', 'legal', 'enforcement', 'arrest', '911'],
  sheet: [23, 2],
  skinVariations: [{
    unified: '1F46E-1F3FB-200D-2642-FE0F',
    sheet: [23, 3]
  }, {
    unified: '1F46E-1F3FC-200D-2642-FE0F',
    sheet: [23, 4]
  }, {
    unified: '1F46E-1F3FD-200D-2642-FE0F',
    sheet: [23, 5]
  }, {
    unified: '1F46E-1F3FE-200D-2642-FE0F',
    sheet: [23, 6]
  }, {
    unified: '1F46E-1F3FF-200D-2642-FE0F',
    sheet: [23, 7]
  }],
  shortName: 'male-police-officer'
}, {
  name: 'Woman Police Officer',
  unified: '1F46E-200D-2640-FE0F',
  keywords: ['woman_police_officer', 'woman', 'police', 'law', 'legal', 'enforcement', 'arrest', '911', 'female'],
  sheet: [22, 57],
  skinVariations: [{
    unified: '1F46E-1F3FB-200D-2640-FE0F',
    sheet: [22, 58]
  }, {
    unified: '1F46E-1F3FC-200D-2640-FE0F',
    sheet: [22, 59]
  }, {
    unified: '1F46E-1F3FD-200D-2640-FE0F',
    sheet: [22, 60]
  }, {
    unified: '1F46E-1F3FE-200D-2640-FE0F',
    sheet: [23, 0]
  }, {
    unified: '1F46E-1F3FF-200D-2640-FE0F',
    sheet: [23, 1]
  }],
  shortName: 'female-police-officer'
}, {
  name: 'Detective',
  unified: '1F575-FE0F',
  keywords: ['detective', 'human', 'spy', 'detective'],
  sheet: [31, 16],
  skinVariations: [{
    unified: '1F575-1F3FB',
    sheet: [31, 17]
  }, {
    unified: '1F575-1F3FC',
    sheet: [31, 18]
  }, {
    unified: '1F575-1F3FD',
    sheet: [31, 19]
  }, {
    unified: '1F575-1F3FE',
    sheet: [31, 20]
  }, {
    unified: '1F575-1F3FF',
    sheet: [31, 21]
  }],
  shortName: 'sleuth_or_spy',
  obsoletedBy: '1F575-FE0F-200D-2642-FE0F'
}, {
  name: 'Man Detective',
  unified: '1F575-FE0F-200D-2642-FE0F',
  obsoletes: '1F575-FE0F',
  keywords: ['man_detective', 'crime'],
  sheet: [31, 10],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F575-1F3FB-200D-2642-FE0F',
    sheet: [31, 11]
  }, {
    unified: '1F575-1F3FC-200D-2642-FE0F',
    sheet: [31, 12]
  }, {
    unified: '1F575-1F3FD-200D-2642-FE0F',
    sheet: [31, 13]
  }, {
    unified: '1F575-1F3FE-200D-2642-FE0F',
    sheet: [31, 14]
  }, {
    unified: '1F575-1F3FF-200D-2642-FE0F',
    sheet: [31, 15]
  }],
  shortName: 'male-detective'
}, {
  name: 'Woman Detective',
  unified: '1F575-FE0F-200D-2640-FE0F',
  keywords: ['woman_detective', 'human', 'spy', 'detective', 'female', 'woman'],
  sheet: [31, 4],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F575-1F3FB-200D-2640-FE0F',
    sheet: [31, 5]
  }, {
    unified: '1F575-1F3FC-200D-2640-FE0F',
    sheet: [31, 6]
  }, {
    unified: '1F575-1F3FD-200D-2640-FE0F',
    sheet: [31, 7]
  }, {
    unified: '1F575-1F3FE-200D-2640-FE0F',
    sheet: [31, 8]
  }, {
    unified: '1F575-1F3FF-200D-2640-FE0F',
    sheet: [31, 9]
  }],
  shortName: 'female-detective'
}, {
  name: 'Guardsman',
  unified: '1F482',
  keywords: ['guard', 'protect'],
  sheet: [25, 40],
  skinVariations: [{
    unified: '1F482-1F3FB',
    sheet: [25, 41]
  }, {
    unified: '1F482-1F3FC',
    sheet: [25, 42]
  }, {
    unified: '1F482-1F3FD',
    sheet: [25, 43]
  }, {
    unified: '1F482-1F3FE',
    sheet: [25, 44]
  }, {
    unified: '1F482-1F3FF',
    sheet: [25, 45]
  }],
  shortName: 'guardsman',
  obsoletedBy: '1F482-200D-2642-FE0F'
}, {
  name: 'Man Guard',
  unified: '1F482-200D-2642-FE0F',
  obsoletes: '1F482',
  keywords: ['man_guard', 'uk', 'gb', 'british', 'male', 'guy', 'royal'],
  sheet: [25, 34],
  skinVariations: [{
    unified: '1F482-1F3FB-200D-2642-FE0F',
    sheet: [25, 35]
  }, {
    unified: '1F482-1F3FC-200D-2642-FE0F',
    sheet: [25, 36]
  }, {
    unified: '1F482-1F3FD-200D-2642-FE0F',
    sheet: [25, 37]
  }, {
    unified: '1F482-1F3FE-200D-2642-FE0F',
    sheet: [25, 38]
  }, {
    unified: '1F482-1F3FF-200D-2642-FE0F',
    sheet: [25, 39]
  }],
  shortName: 'male-guard'
}, {
  name: 'Woman Guard',
  unified: '1F482-200D-2640-FE0F',
  keywords: ['woman_guard', 'uk', 'gb', 'british', 'female', 'royal', 'woman'],
  sheet: [25, 28],
  skinVariations: [{
    unified: '1F482-1F3FB-200D-2640-FE0F',
    sheet: [25, 29]
  }, {
    unified: '1F482-1F3FC-200D-2640-FE0F',
    sheet: [25, 30]
  }, {
    unified: '1F482-1F3FD-200D-2640-FE0F',
    sheet: [25, 31]
  }, {
    unified: '1F482-1F3FE-200D-2640-FE0F',
    sheet: [25, 32]
  }, {
    unified: '1F482-1F3FF-200D-2640-FE0F',
    sheet: [25, 33]
  }],
  shortName: 'female-guard'
}, {
  name: 'Ninja',
  unified: '1F977',
  keywords: ['ninja', 'ninjutsu', 'skills', 'japanese'],
  sheet: [44, 4],
  skinVariations: [{
    unified: '1F977-1F3FB',
    sheet: [44, 5]
  }, {
    unified: '1F977-1F3FC',
    sheet: [44, 6]
  }, {
    unified: '1F977-1F3FD',
    sheet: [44, 7]
  }, {
    unified: '1F977-1F3FE',
    sheet: [44, 8]
  }, {
    unified: '1F977-1F3FF',
    sheet: [44, 9]
  }],
  shortName: 'ninja'
}, {
  name: 'Construction Worker',
  unified: '1F477',
  keywords: ['construction_worker', 'labor', 'build'],
  sheet: [24, 46],
  skinVariations: [{
    unified: '1F477-1F3FB',
    sheet: [24, 47]
  }, {
    unified: '1F477-1F3FC',
    sheet: [24, 48]
  }, {
    unified: '1F477-1F3FD',
    sheet: [24, 49]
  }, {
    unified: '1F477-1F3FE',
    sheet: [24, 50]
  }, {
    unified: '1F477-1F3FF',
    sheet: [24, 51]
  }],
  shortName: 'construction_worker',
  obsoletedBy: '1F477-200D-2642-FE0F'
}, {
  name: 'Man Construction Worker',
  unified: '1F477-200D-2642-FE0F',
  obsoletes: '1F477',
  keywords: ['man_construction_worker', 'male', 'human', 'wip', 'guy', 'build', 'construction', 'worker', 'labor'],
  sheet: [24, 40],
  skinVariations: [{
    unified: '1F477-1F3FB-200D-2642-FE0F',
    sheet: [24, 41]
  }, {
    unified: '1F477-1F3FC-200D-2642-FE0F',
    sheet: [24, 42]
  }, {
    unified: '1F477-1F3FD-200D-2642-FE0F',
    sheet: [24, 43]
  }, {
    unified: '1F477-1F3FE-200D-2642-FE0F',
    sheet: [24, 44]
  }, {
    unified: '1F477-1F3FF-200D-2642-FE0F',
    sheet: [24, 45]
  }],
  shortName: 'male-construction-worker'
}, {
  name: 'Woman Construction Worker',
  unified: '1F477-200D-2640-FE0F',
  keywords: ['woman_construction_worker', 'female', 'human', 'wip', 'build', 'construction', 'worker', 'labor', 'woman'],
  sheet: [24, 34],
  skinVariations: [{
    unified: '1F477-1F3FB-200D-2640-FE0F',
    sheet: [24, 35]
  }, {
    unified: '1F477-1F3FC-200D-2640-FE0F',
    sheet: [24, 36]
  }, {
    unified: '1F477-1F3FD-200D-2640-FE0F',
    sheet: [24, 37]
  }, {
    unified: '1F477-1F3FE-200D-2640-FE0F',
    sheet: [24, 38]
  }, {
    unified: '1F477-1F3FF-200D-2640-FE0F',
    sheet: [24, 39]
  }],
  shortName: 'female-construction-worker'
}, {
  name: 'Person with Crown',
  unified: '1FAC5',
  keywords: ['person with crown', 'royalty', 'power'],
  sheet: [54, 57],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAC5-1F3FB',
    sheet: [54, 58],
    hidden: ['facebook']
  }, {
    unified: '1FAC5-1F3FC',
    sheet: [54, 59],
    hidden: ['facebook']
  }, {
    unified: '1FAC5-1F3FD',
    sheet: [54, 60],
    hidden: ['facebook']
  }, {
    unified: '1FAC5-1F3FE',
    sheet: [55, 0],
    hidden: ['facebook']
  }, {
    unified: '1FAC5-1F3FF',
    sheet: [55, 1],
    hidden: ['facebook']
  }],
  shortName: 'person_with_crown'
}, {
  name: 'Prince',
  unified: '1F934',
  keywords: ['prince', 'boy', 'man', 'male', 'crown', 'royal', 'king'],
  sheet: [41, 8],
  skinVariations: [{
    unified: '1F934-1F3FB',
    sheet: [41, 9]
  }, {
    unified: '1F934-1F3FC',
    sheet: [41, 10]
  }, {
    unified: '1F934-1F3FD',
    sheet: [41, 11]
  }, {
    unified: '1F934-1F3FE',
    sheet: [41, 12]
  }, {
    unified: '1F934-1F3FF',
    sheet: [41, 13]
  }],
  shortName: 'prince'
}, {
  name: 'Princess',
  unified: '1F478',
  keywords: ['princess', 'girl', 'woman', 'female', 'blond', 'crown', 'royal', 'queen'],
  sheet: [24, 52],
  skinVariations: [{
    unified: '1F478-1F3FB',
    sheet: [24, 53]
  }, {
    unified: '1F478-1F3FC',
    sheet: [24, 54]
  }, {
    unified: '1F478-1F3FD',
    sheet: [24, 55]
  }, {
    unified: '1F478-1F3FE',
    sheet: [24, 56]
  }, {
    unified: '1F478-1F3FF',
    sheet: [24, 57]
  }],
  shortName: 'princess'
}, {
  name: 'Man with Turban',
  unified: '1F473',
  keywords: ['person_wearing_turban', 'headdress'],
  sheet: [24, 10],
  skinVariations: [{
    unified: '1F473-1F3FB',
    sheet: [24, 11]
  }, {
    unified: '1F473-1F3FC',
    sheet: [24, 12]
  }, {
    unified: '1F473-1F3FD',
    sheet: [24, 13]
  }, {
    unified: '1F473-1F3FE',
    sheet: [24, 14]
  }, {
    unified: '1F473-1F3FF',
    sheet: [24, 15]
  }],
  shortName: 'man_with_turban',
  obsoletedBy: '1F473-200D-2642-FE0F'
}, {
  name: 'Man Wearing Turban',
  unified: '1F473-200D-2642-FE0F',
  obsoletes: '1F473',
  keywords: ['man_wearing_turban', 'male', 'indian', 'hinduism', 'arabs'],
  sheet: [24, 4],
  skinVariations: [{
    unified: '1F473-1F3FB-200D-2642-FE0F',
    sheet: [24, 5]
  }, {
    unified: '1F473-1F3FC-200D-2642-FE0F',
    sheet: [24, 6]
  }, {
    unified: '1F473-1F3FD-200D-2642-FE0F',
    sheet: [24, 7]
  }, {
    unified: '1F473-1F3FE-200D-2642-FE0F',
    sheet: [24, 8]
  }, {
    unified: '1F473-1F3FF-200D-2642-FE0F',
    sheet: [24, 9]
  }],
  shortName: 'man-wearing-turban'
}, {
  name: 'Woman Wearing Turban',
  unified: '1F473-200D-2640-FE0F',
  keywords: ['woman_wearing_turban', 'female', 'indian', 'hinduism', 'arabs', 'woman'],
  sheet: [23, 59],
  skinVariations: [{
    unified: '1F473-1F3FB-200D-2640-FE0F',
    sheet: [23, 60]
  }, {
    unified: '1F473-1F3FC-200D-2640-FE0F',
    sheet: [24, 0]
  }, {
    unified: '1F473-1F3FD-200D-2640-FE0F',
    sheet: [24, 1]
  }, {
    unified: '1F473-1F3FE-200D-2640-FE0F',
    sheet: [24, 2]
  }, {
    unified: '1F473-1F3FF-200D-2640-FE0F',
    sheet: [24, 3]
  }],
  shortName: 'woman-wearing-turban'
}, {
  name: 'Man with Gua Pi Mao',
  unified: '1F472',
  keywords: ['man_with_skullcap', 'male', 'boy', 'chinese'],
  sheet: [23, 53],
  skinVariations: [{
    unified: '1F472-1F3FB',
    sheet: [23, 54]
  }, {
    unified: '1F472-1F3FC',
    sheet: [23, 55]
  }, {
    unified: '1F472-1F3FD',
    sheet: [23, 56]
  }, {
    unified: '1F472-1F3FE',
    sheet: [23, 57]
  }, {
    unified: '1F472-1F3FF',
    sheet: [23, 58]
  }],
  shortName: 'man_with_gua_pi_mao'
}, {
  name: 'Person with Headscarf',
  unified: '1F9D5',
  keywords: ['woman_with_headscarf', 'female', 'hijab', 'mantilla', 'tichel'],
  sheet: [50, 41],
  skinVariations: [{
    unified: '1F9D5-1F3FB',
    sheet: [50, 42]
  }, {
    unified: '1F9D5-1F3FC',
    sheet: [50, 43]
  }, {
    unified: '1F9D5-1F3FD',
    sheet: [50, 44]
  }, {
    unified: '1F9D5-1F3FE',
    sheet: [50, 45]
  }, {
    unified: '1F9D5-1F3FF',
    sheet: [50, 46]
  }],
  shortName: 'person_with_headscarf'
}, {
  name: 'Man in Tuxedo',
  unified: '1F935',
  keywords: ['man_in_tuxedo', 'couple', 'marriage', 'wedding', 'groom'],
  sheet: [41, 26],
  skinVariations: [{
    unified: '1F935-1F3FB',
    sheet: [41, 27]
  }, {
    unified: '1F935-1F3FC',
    sheet: [41, 28]
  }, {
    unified: '1F935-1F3FD',
    sheet: [41, 29]
  }, {
    unified: '1F935-1F3FE',
    sheet: [41, 30]
  }, {
    unified: '1F935-1F3FF',
    sheet: [41, 31]
  }],
  shortName: 'person_in_tuxedo'
}, {
  name: 'Man in Tuxedo',
  unified: '1F935-200D-2642-FE0F',
  keywords: ['man in tuxedo', 'formal', 'fashion'],
  sheet: [41, 20],
  skinVariations: [{
    unified: '1F935-1F3FB-200D-2642-FE0F',
    sheet: [41, 21]
  }, {
    unified: '1F935-1F3FC-200D-2642-FE0F',
    sheet: [41, 22]
  }, {
    unified: '1F935-1F3FD-200D-2642-FE0F',
    sheet: [41, 23]
  }, {
    unified: '1F935-1F3FE-200D-2642-FE0F',
    sheet: [41, 24]
  }, {
    unified: '1F935-1F3FF-200D-2642-FE0F',
    sheet: [41, 25]
  }],
  shortName: 'man_in_tuxedo'
}, {
  name: 'Woman in Tuxedo',
  unified: '1F935-200D-2640-FE0F',
  keywords: ['woman in tuxedo', 'formal', 'fashion'],
  sheet: [41, 14],
  skinVariations: [{
    unified: '1F935-1F3FB-200D-2640-FE0F',
    sheet: [41, 15]
  }, {
    unified: '1F935-1F3FC-200D-2640-FE0F',
    sheet: [41, 16]
  }, {
    unified: '1F935-1F3FD-200D-2640-FE0F',
    sheet: [41, 17]
  }, {
    unified: '1F935-1F3FE-200D-2640-FE0F',
    sheet: [41, 18]
  }, {
    unified: '1F935-1F3FF-200D-2640-FE0F',
    sheet: [41, 19]
  }],
  shortName: 'woman_in_tuxedo'
}, {
  name: 'Bride with Veil',
  unified: '1F470',
  keywords: ['bride_with_veil', 'couple', 'marriage', 'wedding', 'woman', 'bride'],
  sheet: [23, 29],
  skinVariations: [{
    unified: '1F470-1F3FB',
    sheet: [23, 30]
  }, {
    unified: '1F470-1F3FC',
    sheet: [23, 31]
  }, {
    unified: '1F470-1F3FD',
    sheet: [23, 32]
  }, {
    unified: '1F470-1F3FE',
    sheet: [23, 33]
  }, {
    unified: '1F470-1F3FF',
    sheet: [23, 34]
  }],
  shortName: 'bride_with_veil'
}, {
  name: 'Man with Veil',
  unified: '1F470-200D-2642-FE0F',
  keywords: ['man with veil', 'wedding', 'marriage'],
  sheet: [23, 23],
  skinVariations: [{
    unified: '1F470-1F3FB-200D-2642-FE0F',
    sheet: [23, 24]
  }, {
    unified: '1F470-1F3FC-200D-2642-FE0F',
    sheet: [23, 25]
  }, {
    unified: '1F470-1F3FD-200D-2642-FE0F',
    sheet: [23, 26]
  }, {
    unified: '1F470-1F3FE-200D-2642-FE0F',
    sheet: [23, 27]
  }, {
    unified: '1F470-1F3FF-200D-2642-FE0F',
    sheet: [23, 28]
  }],
  shortName: 'man_with_veil'
}, {
  name: 'Woman with Veil',
  unified: '1F470-200D-2640-FE0F',
  keywords: ['woman with veil', 'wedding', 'marriage'],
  sheet: [23, 17],
  skinVariations: [{
    unified: '1F470-1F3FB-200D-2640-FE0F',
    sheet: [23, 18]
  }, {
    unified: '1F470-1F3FC-200D-2640-FE0F',
    sheet: [23, 19]
  }, {
    unified: '1F470-1F3FD-200D-2640-FE0F',
    sheet: [23, 20]
  }, {
    unified: '1F470-1F3FE-200D-2640-FE0F',
    sheet: [23, 21]
  }, {
    unified: '1F470-1F3FF-200D-2640-FE0F',
    sheet: [23, 22]
  }],
  shortName: 'woman_with_veil'
}, {
  name: 'Pregnant Woman',
  unified: '1F930',
  keywords: ['pregnant_woman', 'baby'],
  sheet: [40, 45],
  skinVariations: [{
    unified: '1F930-1F3FB',
    sheet: [40, 46]
  }, {
    unified: '1F930-1F3FC',
    sheet: [40, 47]
  }, {
    unified: '1F930-1F3FD',
    sheet: [40, 48]
  }, {
    unified: '1F930-1F3FE',
    sheet: [40, 49]
  }, {
    unified: '1F930-1F3FF',
    sheet: [40, 50]
  }],
  shortName: 'pregnant_woman'
}, {
  name: 'Pregnant Man',
  unified: '1FAC3',
  keywords: ['pregnant man', 'baby', 'belly'],
  sheet: [54, 45],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAC3-1F3FB',
    sheet: [54, 46],
    hidden: ['facebook']
  }, {
    unified: '1FAC3-1F3FC',
    sheet: [54, 47],
    hidden: ['facebook']
  }, {
    unified: '1FAC3-1F3FD',
    sheet: [54, 48],
    hidden: ['facebook']
  }, {
    unified: '1FAC3-1F3FE',
    sheet: [54, 49],
    hidden: ['facebook']
  }, {
    unified: '1FAC3-1F3FF',
    sheet: [54, 50],
    hidden: ['facebook']
  }],
  shortName: 'pregnant_man'
}, {
  name: 'Pregnant Person',
  unified: '1FAC4',
  keywords: ['pregnant person', 'baby', 'belly'],
  sheet: [54, 51],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1FAC4-1F3FB',
    sheet: [54, 52],
    hidden: ['facebook']
  }, {
    unified: '1FAC4-1F3FC',
    sheet: [54, 53],
    hidden: ['facebook']
  }, {
    unified: '1FAC4-1F3FD',
    sheet: [54, 54],
    hidden: ['facebook']
  }, {
    unified: '1FAC4-1F3FE',
    sheet: [54, 55],
    hidden: ['facebook']
  }, {
    unified: '1FAC4-1F3FF',
    sheet: [54, 56],
    hidden: ['facebook']
  }],
  shortName: 'pregnant_person'
}, {
  name: 'Breast-Feeding',
  unified: '1F931',
  keywords: ['breast_feeding', 'nursing', 'baby'],
  sheet: [40, 51],
  skinVariations: [{
    unified: '1F931-1F3FB',
    sheet: [40, 52]
  }, {
    unified: '1F931-1F3FC',
    sheet: [40, 53]
  }, {
    unified: '1F931-1F3FD',
    sheet: [40, 54]
  }, {
    unified: '1F931-1F3FE',
    sheet: [40, 55]
  }, {
    unified: '1F931-1F3FF',
    sheet: [40, 56]
  }],
  shortName: 'breast-feeding'
}, {
  name: 'Woman Feeding Baby',
  unified: '1F469-200D-1F37C',
  keywords: ['woman feeding baby', 'birth', 'food'],
  sheet: [17, 31],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F37C',
    sheet: [17, 32]
  }, {
    unified: '1F469-1F3FC-200D-1F37C',
    sheet: [17, 33]
  }, {
    unified: '1F469-1F3FD-200D-1F37C',
    sheet: [17, 34]
  }, {
    unified: '1F469-1F3FE-200D-1F37C',
    sheet: [17, 35]
  }, {
    unified: '1F469-1F3FF-200D-1F37C',
    sheet: [17, 36]
  }],
  shortName: 'woman_feeding_baby'
}, {
  name: 'Man Feeding Baby',
  unified: '1F468-200D-1F37C',
  keywords: ['man feeding baby', 'birth', 'food'],
  sheet: [13, 58],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F37C',
    sheet: [13, 59]
  }, {
    unified: '1F468-1F3FC-200D-1F37C',
    sheet: [13, 60]
  }, {
    unified: '1F468-1F3FD-200D-1F37C',
    sheet: [14, 0]
  }, {
    unified: '1F468-1F3FE-200D-1F37C',
    sheet: [14, 1]
  }, {
    unified: '1F468-1F3FF-200D-1F37C',
    sheet: [14, 2]
  }],
  shortName: 'man_feeding_baby'
}, {
  name: 'Person Feeding Baby',
  unified: '1F9D1-200D-1F37C',
  keywords: ['person feeding baby', 'birth', 'food'],
  sheet: [47, 24],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F37C',
    sheet: [47, 25]
  }, {
    unified: '1F9D1-1F3FC-200D-1F37C',
    sheet: [47, 26]
  }, {
    unified: '1F9D1-1F3FD-200D-1F37C',
    sheet: [47, 27]
  }, {
    unified: '1F9D1-1F3FE-200D-1F37C',
    sheet: [47, 28]
  }, {
    unified: '1F9D1-1F3FF-200D-1F37C',
    sheet: [47, 29]
  }],
  shortName: 'person_feeding_baby'
}, {
  name: 'Baby Angel',
  unified: '1F47C',
  keywords: ['baby_angel', 'heaven', 'wings', 'halo'],
  sheet: [25, 0],
  skinVariations: [{
    unified: '1F47C-1F3FB',
    sheet: [25, 1]
  }, {
    unified: '1F47C-1F3FC',
    sheet: [25, 2]
  }, {
    unified: '1F47C-1F3FD',
    sheet: [25, 3]
  }, {
    unified: '1F47C-1F3FE',
    sheet: [25, 4]
  }, {
    unified: '1F47C-1F3FF',
    sheet: [25, 5]
  }],
  shortName: 'angel'
}, {
  name: 'Father Christmas',
  unified: '1F385',
  keywords: ['santa_claus', 'festival', 'man', 'male', 'xmas', 'father christmas'],
  sheet: [7, 8],
  skinVariations: [{
    unified: '1F385-1F3FB',
    sheet: [7, 9]
  }, {
    unified: '1F385-1F3FC',
    sheet: [7, 10]
  }, {
    unified: '1F385-1F3FD',
    sheet: [7, 11]
  }, {
    unified: '1F385-1F3FE',
    sheet: [7, 12]
  }, {
    unified: '1F385-1F3FF',
    sheet: [7, 13]
  }],
  shortName: 'santa'
}, {
  name: 'Mother Christmas',
  unified: '1F936',
  keywords: ['mrs_claus', 'woman', 'female', 'xmas', 'mother christmas'],
  sheet: [41, 32],
  skinVariations: [{
    unified: '1F936-1F3FB',
    sheet: [41, 33]
  }, {
    unified: '1F936-1F3FC',
    sheet: [41, 34]
  }, {
    unified: '1F936-1F3FD',
    sheet: [41, 35]
  }, {
    unified: '1F936-1F3FE',
    sheet: [41, 36]
  }, {
    unified: '1F936-1F3FF',
    sheet: [41, 37]
  }],
  shortNames: ['mother_christmas'],
  shortName: 'mrs_claus'
}, {
  name: 'Mx Claus',
  unified: '1F9D1-200D-1F384',
  keywords: ['mx claus', 'christmas'],
  sheet: [47, 30],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F384',
    sheet: [47, 31]
  }, {
    unified: '1F9D1-1F3FC-200D-1F384',
    sheet: [47, 32]
  }, {
    unified: '1F9D1-1F3FD-200D-1F384',
    sheet: [47, 33]
  }, {
    unified: '1F9D1-1F3FE-200D-1F384',
    sheet: [47, 34]
  }, {
    unified: '1F9D1-1F3FF-200D-1F384',
    sheet: [47, 35]
  }],
  shortName: 'mx_claus'
}, {
  name: 'Superhero',
  unified: '1F9B8',
  keywords: ['superhero', 'marvel'],
  sheet: [45, 31],
  skinVariations: [{
    unified: '1F9B8-1F3FB',
    sheet: [45, 32]
  }, {
    unified: '1F9B8-1F3FC',
    sheet: [45, 33]
  }, {
    unified: '1F9B8-1F3FD',
    sheet: [45, 34]
  }, {
    unified: '1F9B8-1F3FE',
    sheet: [45, 35]
  }, {
    unified: '1F9B8-1F3FF',
    sheet: [45, 36]
  }],
  shortName: 'superhero'
}, {
  name: 'Man Superhero',
  unified: '1F9B8-200D-2642-FE0F',
  keywords: ['man_superhero', 'man', 'male', 'good', 'hero', 'superpowers'],
  sheet: [45, 25],
  skinVariations: [{
    unified: '1F9B8-1F3FB-200D-2642-FE0F',
    sheet: [45, 26]
  }, {
    unified: '1F9B8-1F3FC-200D-2642-FE0F',
    sheet: [45, 27]
  }, {
    unified: '1F9B8-1F3FD-200D-2642-FE0F',
    sheet: [45, 28]
  }, {
    unified: '1F9B8-1F3FE-200D-2642-FE0F',
    sheet: [45, 29]
  }, {
    unified: '1F9B8-1F3FF-200D-2642-FE0F',
    sheet: [45, 30]
  }],
  shortName: 'male_superhero'
}, {
  name: 'Woman Superhero',
  unified: '1F9B8-200D-2640-FE0F',
  keywords: ['woman_superhero', 'woman', 'female', 'good', 'heroine', 'superpowers'],
  sheet: [45, 19],
  skinVariations: [{
    unified: '1F9B8-1F3FB-200D-2640-FE0F',
    sheet: [45, 20]
  }, {
    unified: '1F9B8-1F3FC-200D-2640-FE0F',
    sheet: [45, 21]
  }, {
    unified: '1F9B8-1F3FD-200D-2640-FE0F',
    sheet: [45, 22]
  }, {
    unified: '1F9B8-1F3FE-200D-2640-FE0F',
    sheet: [45, 23]
  }, {
    unified: '1F9B8-1F3FF-200D-2640-FE0F',
    sheet: [45, 24]
  }],
  shortName: 'female_superhero'
}, {
  name: 'Supervillain',
  unified: '1F9B9',
  keywords: ['supervillain', 'marvel'],
  sheet: [45, 49],
  skinVariations: [{
    unified: '1F9B9-1F3FB',
    sheet: [45, 50]
  }, {
    unified: '1F9B9-1F3FC',
    sheet: [45, 51]
  }, {
    unified: '1F9B9-1F3FD',
    sheet: [45, 52]
  }, {
    unified: '1F9B9-1F3FE',
    sheet: [45, 53]
  }, {
    unified: '1F9B9-1F3FF',
    sheet: [45, 54]
  }],
  shortName: 'supervillain'
}, {
  name: 'Man Supervillain',
  unified: '1F9B9-200D-2642-FE0F',
  keywords: ['man_supervillain', 'man', 'male', 'evil', 'bad', 'criminal', 'hero', 'superpowers'],
  sheet: [45, 43],
  skinVariations: [{
    unified: '1F9B9-1F3FB-200D-2642-FE0F',
    sheet: [45, 44]
  }, {
    unified: '1F9B9-1F3FC-200D-2642-FE0F',
    sheet: [45, 45]
  }, {
    unified: '1F9B9-1F3FD-200D-2642-FE0F',
    sheet: [45, 46]
  }, {
    unified: '1F9B9-1F3FE-200D-2642-FE0F',
    sheet: [45, 47]
  }, {
    unified: '1F9B9-1F3FF-200D-2642-FE0F',
    sheet: [45, 48]
  }],
  shortName: 'male_supervillain'
}, {
  name: 'Woman Supervillain',
  unified: '1F9B9-200D-2640-FE0F',
  keywords: ['woman_supervillain', 'woman', 'female', 'evil', 'bad', 'criminal', 'heroine', 'superpowers'],
  sheet: [45, 37],
  skinVariations: [{
    unified: '1F9B9-1F3FB-200D-2640-FE0F',
    sheet: [45, 38]
  }, {
    unified: '1F9B9-1F3FC-200D-2640-FE0F',
    sheet: [45, 39]
  }, {
    unified: '1F9B9-1F3FD-200D-2640-FE0F',
    sheet: [45, 40]
  }, {
    unified: '1F9B9-1F3FE-200D-2640-FE0F',
    sheet: [45, 41]
  }, {
    unified: '1F9B9-1F3FF-200D-2640-FE0F',
    sheet: [45, 42]
  }],
  shortName: 'female_supervillain'
}, {
  name: 'Mage',
  unified: '1F9D9',
  keywords: ['mage', 'magic'],
  sheet: [51, 52],
  skinVariations: [{
    unified: '1F9D9-1F3FB',
    sheet: [51, 53]
  }, {
    unified: '1F9D9-1F3FC',
    sheet: [51, 54]
  }, {
    unified: '1F9D9-1F3FD',
    sheet: [51, 55]
  }, {
    unified: '1F9D9-1F3FE',
    sheet: [51, 56]
  }, {
    unified: '1F9D9-1F3FF',
    sheet: [51, 57]
  }],
  shortName: 'mage',
  obsoletedBy: '1F9D9-200D-2640-FE0F'
}, {
  name: 'Man Mage',
  unified: '1F9D9-200D-2642-FE0F',
  keywords: ['man_mage', 'man', 'male', 'mage', 'sorcerer'],
  sheet: [51, 46],
  skinVariations: [{
    unified: '1F9D9-1F3FB-200D-2642-FE0F',
    sheet: [51, 47]
  }, {
    unified: '1F9D9-1F3FC-200D-2642-FE0F',
    sheet: [51, 48]
  }, {
    unified: '1F9D9-1F3FD-200D-2642-FE0F',
    sheet: [51, 49]
  }, {
    unified: '1F9D9-1F3FE-200D-2642-FE0F',
    sheet: [51, 50]
  }, {
    unified: '1F9D9-1F3FF-200D-2642-FE0F',
    sheet: [51, 51]
  }],
  shortName: 'male_mage'
}, {
  name: 'Woman Mage',
  unified: '1F9D9-200D-2640-FE0F',
  obsoletes: '1F9D9',
  keywords: ['woman_mage', 'woman', 'female', 'mage', 'witch'],
  sheet: [51, 40],
  skinVariations: [{
    unified: '1F9D9-1F3FB-200D-2640-FE0F',
    sheet: [51, 41]
  }, {
    unified: '1F9D9-1F3FC-200D-2640-FE0F',
    sheet: [51, 42]
  }, {
    unified: '1F9D9-1F3FD-200D-2640-FE0F',
    sheet: [51, 43]
  }, {
    unified: '1F9D9-1F3FE-200D-2640-FE0F',
    sheet: [51, 44]
  }, {
    unified: '1F9D9-1F3FF-200D-2640-FE0F',
    sheet: [51, 45]
  }],
  shortName: 'female_mage'
}, {
  name: 'Fairy',
  unified: '1F9DA',
  keywords: ['fairy', 'wings', 'magical'],
  sheet: [52, 9],
  skinVariations: [{
    unified: '1F9DA-1F3FB',
    sheet: [52, 10]
  }, {
    unified: '1F9DA-1F3FC',
    sheet: [52, 11]
  }, {
    unified: '1F9DA-1F3FD',
    sheet: [52, 12]
  }, {
    unified: '1F9DA-1F3FE',
    sheet: [52, 13]
  }, {
    unified: '1F9DA-1F3FF',
    sheet: [52, 14]
  }],
  shortName: 'fairy',
  obsoletedBy: '1F9DA-200D-2640-FE0F'
}, {
  name: 'Man Fairy',
  unified: '1F9DA-200D-2642-FE0F',
  keywords: ['man_fairy', 'man', 'male'],
  sheet: [52, 3],
  skinVariations: [{
    unified: '1F9DA-1F3FB-200D-2642-FE0F',
    sheet: [52, 4]
  }, {
    unified: '1F9DA-1F3FC-200D-2642-FE0F',
    sheet: [52, 5]
  }, {
    unified: '1F9DA-1F3FD-200D-2642-FE0F',
    sheet: [52, 6]
  }, {
    unified: '1F9DA-1F3FE-200D-2642-FE0F',
    sheet: [52, 7]
  }, {
    unified: '1F9DA-1F3FF-200D-2642-FE0F',
    sheet: [52, 8]
  }],
  shortName: 'male_fairy'
}, {
  name: 'Woman Fairy',
  unified: '1F9DA-200D-2640-FE0F',
  obsoletes: '1F9DA',
  keywords: ['woman_fairy', 'woman', 'female'],
  sheet: [51, 58],
  skinVariations: [{
    unified: '1F9DA-1F3FB-200D-2640-FE0F',
    sheet: [51, 59]
  }, {
    unified: '1F9DA-1F3FC-200D-2640-FE0F',
    sheet: [51, 60]
  }, {
    unified: '1F9DA-1F3FD-200D-2640-FE0F',
    sheet: [52, 0]
  }, {
    unified: '1F9DA-1F3FE-200D-2640-FE0F',
    sheet: [52, 1]
  }, {
    unified: '1F9DA-1F3FF-200D-2640-FE0F',
    sheet: [52, 2]
  }],
  shortName: 'female_fairy'
}, {
  name: 'Vampire',
  unified: '1F9DB',
  keywords: ['vampire', 'blood', 'twilight'],
  sheet: [52, 27],
  skinVariations: [{
    unified: '1F9DB-1F3FB',
    sheet: [52, 28]
  }, {
    unified: '1F9DB-1F3FC',
    sheet: [52, 29]
  }, {
    unified: '1F9DB-1F3FD',
    sheet: [52, 30]
  }, {
    unified: '1F9DB-1F3FE',
    sheet: [52, 31]
  }, {
    unified: '1F9DB-1F3FF',
    sheet: [52, 32]
  }],
  shortName: 'vampire',
  obsoletedBy: '1F9DB-200D-2640-FE0F'
}, {
  name: 'Man Vampire',
  unified: '1F9DB-200D-2642-FE0F',
  keywords: ['man_vampire', 'man', 'male', 'dracula'],
  sheet: [52, 21],
  skinVariations: [{
    unified: '1F9DB-1F3FB-200D-2642-FE0F',
    sheet: [52, 22]
  }, {
    unified: '1F9DB-1F3FC-200D-2642-FE0F',
    sheet: [52, 23]
  }, {
    unified: '1F9DB-1F3FD-200D-2642-FE0F',
    sheet: [52, 24]
  }, {
    unified: '1F9DB-1F3FE-200D-2642-FE0F',
    sheet: [52, 25]
  }, {
    unified: '1F9DB-1F3FF-200D-2642-FE0F',
    sheet: [52, 26]
  }],
  shortName: 'male_vampire'
}, {
  name: 'Woman Vampire',
  unified: '1F9DB-200D-2640-FE0F',
  obsoletes: '1F9DB',
  keywords: ['woman_vampire', 'woman', 'female'],
  sheet: [52, 15],
  skinVariations: [{
    unified: '1F9DB-1F3FB-200D-2640-FE0F',
    sheet: [52, 16]
  }, {
    unified: '1F9DB-1F3FC-200D-2640-FE0F',
    sheet: [52, 17]
  }, {
    unified: '1F9DB-1F3FD-200D-2640-FE0F',
    sheet: [52, 18]
  }, {
    unified: '1F9DB-1F3FE-200D-2640-FE0F',
    sheet: [52, 19]
  }, {
    unified: '1F9DB-1F3FF-200D-2640-FE0F',
    sheet: [52, 20]
  }],
  shortName: 'female_vampire'
}, {
  name: 'Merperson',
  unified: '1F9DC',
  keywords: ['merperson', 'sea'],
  sheet: [52, 45],
  skinVariations: [{
    unified: '1F9DC-1F3FB',
    sheet: [52, 46]
  }, {
    unified: '1F9DC-1F3FC',
    sheet: [52, 47]
  }, {
    unified: '1F9DC-1F3FD',
    sheet: [52, 48]
  }, {
    unified: '1F9DC-1F3FE',
    sheet: [52, 49]
  }, {
    unified: '1F9DC-1F3FF',
    sheet: [52, 50]
  }],
  shortName: 'merperson',
  obsoletedBy: '1F9DC-200D-2642-FE0F'
}, {
  name: 'Merman',
  unified: '1F9DC-200D-2642-FE0F',
  obsoletes: '1F9DC',
  keywords: ['merman', 'man', 'male', 'triton'],
  sheet: [52, 39],
  skinVariations: [{
    unified: '1F9DC-1F3FB-200D-2642-FE0F',
    sheet: [52, 40]
  }, {
    unified: '1F9DC-1F3FC-200D-2642-FE0F',
    sheet: [52, 41]
  }, {
    unified: '1F9DC-1F3FD-200D-2642-FE0F',
    sheet: [52, 42]
  }, {
    unified: '1F9DC-1F3FE-200D-2642-FE0F',
    sheet: [52, 43]
  }, {
    unified: '1F9DC-1F3FF-200D-2642-FE0F',
    sheet: [52, 44]
  }],
  shortName: 'merman'
}, {
  name: 'Mermaid',
  unified: '1F9DC-200D-2640-FE0F',
  keywords: ['mermaid', 'woman', 'female', 'merwoman', 'ariel'],
  sheet: [52, 33],
  skinVariations: [{
    unified: '1F9DC-1F3FB-200D-2640-FE0F',
    sheet: [52, 34]
  }, {
    unified: '1F9DC-1F3FC-200D-2640-FE0F',
    sheet: [52, 35]
  }, {
    unified: '1F9DC-1F3FD-200D-2640-FE0F',
    sheet: [52, 36]
  }, {
    unified: '1F9DC-1F3FE-200D-2640-FE0F',
    sheet: [52, 37]
  }, {
    unified: '1F9DC-1F3FF-200D-2640-FE0F',
    sheet: [52, 38]
  }],
  shortName: 'mermaid'
}, {
  name: 'Elf',
  unified: '1F9DD',
  keywords: ['elf', 'magical'],
  sheet: [53, 2],
  skinVariations: [{
    unified: '1F9DD-1F3FB',
    sheet: [53, 3]
  }, {
    unified: '1F9DD-1F3FC',
    sheet: [53, 4]
  }, {
    unified: '1F9DD-1F3FD',
    sheet: [53, 5]
  }, {
    unified: '1F9DD-1F3FE',
    sheet: [53, 6]
  }, {
    unified: '1F9DD-1F3FF',
    sheet: [53, 7]
  }],
  shortName: 'elf',
  obsoletedBy: '1F9DD-200D-2642-FE0F'
}, {
  name: 'Man Elf',
  unified: '1F9DD-200D-2642-FE0F',
  obsoletes: '1F9DD',
  keywords: ['man_elf', 'man', 'male'],
  sheet: [52, 57],
  skinVariations: [{
    unified: '1F9DD-1F3FB-200D-2642-FE0F',
    sheet: [52, 58]
  }, {
    unified: '1F9DD-1F3FC-200D-2642-FE0F',
    sheet: [52, 59]
  }, {
    unified: '1F9DD-1F3FD-200D-2642-FE0F',
    sheet: [52, 60]
  }, {
    unified: '1F9DD-1F3FE-200D-2642-FE0F',
    sheet: [53, 0]
  }, {
    unified: '1F9DD-1F3FF-200D-2642-FE0F',
    sheet: [53, 1]
  }],
  shortName: 'male_elf'
}, {
  name: 'Woman Elf',
  unified: '1F9DD-200D-2640-FE0F',
  keywords: ['woman_elf', 'woman', 'female'],
  sheet: [52, 51],
  skinVariations: [{
    unified: '1F9DD-1F3FB-200D-2640-FE0F',
    sheet: [52, 52]
  }, {
    unified: '1F9DD-1F3FC-200D-2640-FE0F',
    sheet: [52, 53]
  }, {
    unified: '1F9DD-1F3FD-200D-2640-FE0F',
    sheet: [52, 54]
  }, {
    unified: '1F9DD-1F3FE-200D-2640-FE0F',
    sheet: [52, 55]
  }, {
    unified: '1F9DD-1F3FF-200D-2640-FE0F',
    sheet: [52, 56]
  }],
  shortName: 'female_elf'
}, {
  name: 'Genie',
  unified: '1F9DE',
  keywords: ['genie', 'magical', 'wishes'],
  sheet: [53, 10],
  shortName: 'genie',
  obsoletedBy: '1F9DE-200D-2642-FE0F'
}, {
  name: 'Man Genie',
  unified: '1F9DE-200D-2642-FE0F',
  obsoletes: '1F9DE',
  keywords: ['man_genie', 'man', 'male'],
  sheet: [53, 9],
  shortName: 'male_genie'
}, {
  name: 'Woman Genie',
  unified: '1F9DE-200D-2640-FE0F',
  keywords: ['woman_genie', 'woman', 'female'],
  sheet: [53, 8],
  shortName: 'female_genie'
}, {
  name: 'Zombie',
  unified: '1F9DF',
  keywords: ['zombie', 'dead'],
  sheet: [53, 13],
  shortName: 'zombie',
  obsoletedBy: '1F9DF-200D-2642-FE0F'
}, {
  name: 'Man Zombie',
  unified: '1F9DF-200D-2642-FE0F',
  obsoletes: '1F9DF',
  keywords: ['man_zombie', 'man', 'male', 'dracula', 'undead', 'walking dead'],
  sheet: [53, 12],
  shortName: 'male_zombie'
}, {
  name: 'Woman Zombie',
  unified: '1F9DF-200D-2640-FE0F',
  keywords: ['woman_zombie', 'woman', 'female', 'undead', 'walking dead'],
  sheet: [53, 11],
  shortName: 'female_zombie'
}, {
  name: 'Troll',
  unified: '1F9CC',
  keywords: ['troll', 'mystical', 'monster'],
  sheet: [46, 17],
  hidden: ['facebook'],
  shortName: 'troll'
}, {
  name: 'Face Massage',
  unified: '1F486',
  keywords: ['person_getting_massage', 'relax'],
  sheet: [26, 10],
  skinVariations: [{
    unified: '1F486-1F3FB',
    sheet: [26, 11]
  }, {
    unified: '1F486-1F3FC',
    sheet: [26, 12]
  }, {
    unified: '1F486-1F3FD',
    sheet: [26, 13]
  }, {
    unified: '1F486-1F3FE',
    sheet: [26, 14]
  }, {
    unified: '1F486-1F3FF',
    sheet: [26, 15]
  }],
  shortName: 'massage',
  obsoletedBy: '1F486-200D-2640-FE0F'
}, {
  name: 'Man Getting Massage',
  unified: '1F486-200D-2642-FE0F',
  keywords: ['man_getting_massage', 'male', 'boy', 'man', 'head'],
  sheet: [26, 4],
  skinVariations: [{
    unified: '1F486-1F3FB-200D-2642-FE0F',
    sheet: [26, 5]
  }, {
    unified: '1F486-1F3FC-200D-2642-FE0F',
    sheet: [26, 6]
  }, {
    unified: '1F486-1F3FD-200D-2642-FE0F',
    sheet: [26, 7]
  }, {
    unified: '1F486-1F3FE-200D-2642-FE0F',
    sheet: [26, 8]
  }, {
    unified: '1F486-1F3FF-200D-2642-FE0F',
    sheet: [26, 9]
  }],
  shortName: 'man-getting-massage'
}, {
  name: 'Woman Getting Massage',
  unified: '1F486-200D-2640-FE0F',
  obsoletes: '1F486',
  keywords: ['woman_getting_massage', 'female', 'girl', 'woman', 'head'],
  sheet: [25, 59],
  skinVariations: [{
    unified: '1F486-1F3FB-200D-2640-FE0F',
    sheet: [25, 60]
  }, {
    unified: '1F486-1F3FC-200D-2640-FE0F',
    sheet: [26, 0]
  }, {
    unified: '1F486-1F3FD-200D-2640-FE0F',
    sheet: [26, 1]
  }, {
    unified: '1F486-1F3FE-200D-2640-FE0F',
    sheet: [26, 2]
  }, {
    unified: '1F486-1F3FF-200D-2640-FE0F',
    sheet: [26, 3]
  }],
  shortName: 'woman-getting-massage'
}, {
  name: 'Haircut',
  unified: '1F487',
  keywords: ['person_getting_haircut', 'hairstyle'],
  sheet: [26, 28],
  skinVariations: [{
    unified: '1F487-1F3FB',
    sheet: [26, 29]
  }, {
    unified: '1F487-1F3FC',
    sheet: [26, 30]
  }, {
    unified: '1F487-1F3FD',
    sheet: [26, 31]
  }, {
    unified: '1F487-1F3FE',
    sheet: [26, 32]
  }, {
    unified: '1F487-1F3FF',
    sheet: [26, 33]
  }],
  shortName: 'haircut',
  obsoletedBy: '1F487-200D-2640-FE0F'
}, {
  name: 'Man Getting Haircut',
  unified: '1F487-200D-2642-FE0F',
  keywords: ['man_getting_haircut', 'male', 'boy', 'man'],
  sheet: [26, 22],
  skinVariations: [{
    unified: '1F487-1F3FB-200D-2642-FE0F',
    sheet: [26, 23]
  }, {
    unified: '1F487-1F3FC-200D-2642-FE0F',
    sheet: [26, 24]
  }, {
    unified: '1F487-1F3FD-200D-2642-FE0F',
    sheet: [26, 25]
  }, {
    unified: '1F487-1F3FE-200D-2642-FE0F',
    sheet: [26, 26]
  }, {
    unified: '1F487-1F3FF-200D-2642-FE0F',
    sheet: [26, 27]
  }],
  shortName: 'man-getting-haircut'
}, {
  name: 'Woman Getting Haircut',
  unified: '1F487-200D-2640-FE0F',
  obsoletes: '1F487',
  keywords: ['woman_getting_haircut', 'female', 'girl', 'woman'],
  sheet: [26, 16],
  skinVariations: [{
    unified: '1F487-1F3FB-200D-2640-FE0F',
    sheet: [26, 17]
  }, {
    unified: '1F487-1F3FC-200D-2640-FE0F',
    sheet: [26, 18]
  }, {
    unified: '1F487-1F3FD-200D-2640-FE0F',
    sheet: [26, 19]
  }, {
    unified: '1F487-1F3FE-200D-2640-FE0F',
    sheet: [26, 20]
  }, {
    unified: '1F487-1F3FF-200D-2640-FE0F',
    sheet: [26, 21]
  }],
  shortName: 'woman-getting-haircut'
}, {
  name: 'Pedestrian',
  unified: '1F6B6',
  keywords: ['person_walking', 'move'],
  sheet: [37, 27],
  skinVariations: [{
    unified: '1F6B6-1F3FB',
    sheet: [37, 28]
  }, {
    unified: '1F6B6-1F3FC',
    sheet: [37, 29]
  }, {
    unified: '1F6B6-1F3FD',
    sheet: [37, 30]
  }, {
    unified: '1F6B6-1F3FE',
    sheet: [37, 31]
  }, {
    unified: '1F6B6-1F3FF',
    sheet: [37, 32]
  }],
  shortName: 'walking',
  obsoletedBy: '1F6B6-200D-2642-FE0F'
}, {
  name: 'Man Walking',
  unified: '1F6B6-200D-2642-FE0F',
  obsoletes: '1F6B6',
  keywords: ['man_walking', 'human', 'feet', 'steps'],
  sheet: [37, 21],
  skinVariations: [{
    unified: '1F6B6-1F3FB-200D-2642-FE0F',
    sheet: [37, 22]
  }, {
    unified: '1F6B6-1F3FC-200D-2642-FE0F',
    sheet: [37, 23]
  }, {
    unified: '1F6B6-1F3FD-200D-2642-FE0F',
    sheet: [37, 24]
  }, {
    unified: '1F6B6-1F3FE-200D-2642-FE0F',
    sheet: [37, 25]
  }, {
    unified: '1F6B6-1F3FF-200D-2642-FE0F',
    sheet: [37, 26]
  }],
  shortName: 'man-walking'
}, {
  name: 'Woman Walking',
  unified: '1F6B6-200D-2640-FE0F',
  keywords: ['woman_walking', 'human', 'feet', 'steps', 'woman', 'female'],
  sheet: [37, 15],
  skinVariations: [{
    unified: '1F6B6-1F3FB-200D-2640-FE0F',
    sheet: [37, 16]
  }, {
    unified: '1F6B6-1F3FC-200D-2640-FE0F',
    sheet: [37, 17]
  }, {
    unified: '1F6B6-1F3FD-200D-2640-FE0F',
    sheet: [37, 18]
  }, {
    unified: '1F6B6-1F3FE-200D-2640-FE0F',
    sheet: [37, 19]
  }, {
    unified: '1F6B6-1F3FF-200D-2640-FE0F',
    sheet: [37, 20]
  }],
  shortName: 'woman-walking'
}, {
  name: 'Standing Person',
  unified: '1F9CD',
  keywords: ['person_standing', 'still'],
  sheet: [46, 30],
  skinVariations: [{
    unified: '1F9CD-1F3FB',
    sheet: [46, 31]
  }, {
    unified: '1F9CD-1F3FC',
    sheet: [46, 32]
  }, {
    unified: '1F9CD-1F3FD',
    sheet: [46, 33]
  }, {
    unified: '1F9CD-1F3FE',
    sheet: [46, 34]
  }, {
    unified: '1F9CD-1F3FF',
    sheet: [46, 35]
  }],
  shortName: 'standing_person'
}, {
  name: 'Man Standing',
  unified: '1F9CD-200D-2642-FE0F',
  keywords: ['man_standing', 'still'],
  sheet: [46, 24],
  skinVariations: [{
    unified: '1F9CD-1F3FB-200D-2642-FE0F',
    sheet: [46, 25]
  }, {
    unified: '1F9CD-1F3FC-200D-2642-FE0F',
    sheet: [46, 26]
  }, {
    unified: '1F9CD-1F3FD-200D-2642-FE0F',
    sheet: [46, 27]
  }, {
    unified: '1F9CD-1F3FE-200D-2642-FE0F',
    sheet: [46, 28]
  }, {
    unified: '1F9CD-1F3FF-200D-2642-FE0F',
    sheet: [46, 29]
  }],
  shortName: 'man_standing'
}, {
  name: 'Woman Standing',
  unified: '1F9CD-200D-2640-FE0F',
  keywords: ['woman_standing', 'still'],
  sheet: [46, 18],
  skinVariations: [{
    unified: '1F9CD-1F3FB-200D-2640-FE0F',
    sheet: [46, 19]
  }, {
    unified: '1F9CD-1F3FC-200D-2640-FE0F',
    sheet: [46, 20]
  }, {
    unified: '1F9CD-1F3FD-200D-2640-FE0F',
    sheet: [46, 21]
  }, {
    unified: '1F9CD-1F3FE-200D-2640-FE0F',
    sheet: [46, 22]
  }, {
    unified: '1F9CD-1F3FF-200D-2640-FE0F',
    sheet: [46, 23]
  }],
  shortName: 'woman_standing'
}, {
  name: 'Kneeling Person',
  unified: '1F9CE',
  keywords: ['person_kneeling', 'pray', 'respectful'],
  sheet: [46, 48],
  skinVariations: [{
    unified: '1F9CE-1F3FB',
    sheet: [46, 49]
  }, {
    unified: '1F9CE-1F3FC',
    sheet: [46, 50]
  }, {
    unified: '1F9CE-1F3FD',
    sheet: [46, 51]
  }, {
    unified: '1F9CE-1F3FE',
    sheet: [46, 52]
  }, {
    unified: '1F9CE-1F3FF',
    sheet: [46, 53]
  }],
  shortName: 'kneeling_person'
}, {
  name: 'Man Kneeling',
  unified: '1F9CE-200D-2642-FE0F',
  keywords: ['man_kneeling', 'pray', 'respectful'],
  sheet: [46, 42],
  skinVariations: [{
    unified: '1F9CE-1F3FB-200D-2642-FE0F',
    sheet: [46, 43]
  }, {
    unified: '1F9CE-1F3FC-200D-2642-FE0F',
    sheet: [46, 44]
  }, {
    unified: '1F9CE-1F3FD-200D-2642-FE0F',
    sheet: [46, 45]
  }, {
    unified: '1F9CE-1F3FE-200D-2642-FE0F',
    sheet: [46, 46]
  }, {
    unified: '1F9CE-1F3FF-200D-2642-FE0F',
    sheet: [46, 47]
  }],
  shortName: 'man_kneeling'
}, {
  name: 'Woman Kneeling',
  unified: '1F9CE-200D-2640-FE0F',
  keywords: ['woman_kneeling', 'respectful', 'pray'],
  sheet: [46, 36],
  skinVariations: [{
    unified: '1F9CE-1F3FB-200D-2640-FE0F',
    sheet: [46, 37]
  }, {
    unified: '1F9CE-1F3FC-200D-2640-FE0F',
    sheet: [46, 38]
  }, {
    unified: '1F9CE-1F3FD-200D-2640-FE0F',
    sheet: [46, 39]
  }, {
    unified: '1F9CE-1F3FE-200D-2640-FE0F',
    sheet: [46, 40]
  }, {
    unified: '1F9CE-1F3FF-200D-2640-FE0F',
    sheet: [46, 41]
  }],
  shortName: 'woman_kneeling'
}, {
  name: 'Person with White Cane',
  unified: '1F9D1-200D-1F9AF',
  keywords: ['person_with_probing_cane', 'blind'],
  sheet: [49, 6],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9AF',
    sheet: [49, 7]
  }, {
    unified: '1F9D1-1F3FC-200D-1F9AF',
    sheet: [49, 8]
  }, {
    unified: '1F9D1-1F3FD-200D-1F9AF',
    sheet: [49, 9]
  }, {
    unified: '1F9D1-1F3FE-200D-1F9AF',
    sheet: [49, 10]
  }, {
    unified: '1F9D1-1F3FF-200D-1F9AF',
    sheet: [49, 11]
  }],
  shortName: 'person_with_probing_cane'
}, {
  name: 'Man with White Cane',
  unified: '1F468-200D-1F9AF',
  keywords: ['man_with_probing_cane', 'blind'],
  sheet: [15, 23],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9AF',
    sheet: [15, 24]
  }, {
    unified: '1F468-1F3FC-200D-1F9AF',
    sheet: [15, 25]
  }, {
    unified: '1F468-1F3FD-200D-1F9AF',
    sheet: [15, 26]
  }, {
    unified: '1F468-1F3FE-200D-1F9AF',
    sheet: [15, 27]
  }, {
    unified: '1F468-1F3FF-200D-1F9AF',
    sheet: [15, 28]
  }],
  shortName: 'man_with_probing_cane'
}, {
  name: 'Woman with White Cane',
  unified: '1F469-200D-1F9AF',
  keywords: ['woman_with_probing_cane', 'blind'],
  sheet: [18, 52],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9AF',
    sheet: [18, 53]
  }, {
    unified: '1F469-1F3FC-200D-1F9AF',
    sheet: [18, 54]
  }, {
    unified: '1F469-1F3FD-200D-1F9AF',
    sheet: [18, 55]
  }, {
    unified: '1F469-1F3FE-200D-1F9AF',
    sheet: [18, 56]
  }, {
    unified: '1F469-1F3FF-200D-1F9AF',
    sheet: [18, 57]
  }],
  shortName: 'woman_with_probing_cane'
}, {
  name: 'Person in Motorized Wheelchair',
  unified: '1F9D1-200D-1F9BC',
  keywords: ['person_in_motorized_wheelchair', 'disability', 'accessibility'],
  sheet: [49, 36],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9BC',
    sheet: [49, 37]
  }, {
    unified: '1F9D1-1F3FC-200D-1F9BC',
    sheet: [49, 38]
  }, {
    unified: '1F9D1-1F3FD-200D-1F9BC',
    sheet: [49, 39]
  }, {
    unified: '1F9D1-1F3FE-200D-1F9BC',
    sheet: [49, 40]
  }, {
    unified: '1F9D1-1F3FF-200D-1F9BC',
    sheet: [49, 41]
  }],
  shortName: 'person_in_motorized_wheelchair'
}, {
  name: 'Man in Motorized Wheelchair',
  unified: '1F468-200D-1F9BC',
  keywords: ['man_in_motorized_wheelchair', 'disability', 'accessibility'],
  sheet: [15, 53],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9BC',
    sheet: [15, 54]
  }, {
    unified: '1F468-1F3FC-200D-1F9BC',
    sheet: [15, 55]
  }, {
    unified: '1F468-1F3FD-200D-1F9BC',
    sheet: [15, 56]
  }, {
    unified: '1F468-1F3FE-200D-1F9BC',
    sheet: [15, 57]
  }, {
    unified: '1F468-1F3FF-200D-1F9BC',
    sheet: [15, 58]
  }],
  shortName: 'man_in_motorized_wheelchair'
}, {
  name: 'Woman in Motorized Wheelchair',
  unified: '1F469-200D-1F9BC',
  keywords: ['woman_in_motorized_wheelchair', 'disability', 'accessibility'],
  sheet: [19, 21],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9BC',
    sheet: [19, 22]
  }, {
    unified: '1F469-1F3FC-200D-1F9BC',
    sheet: [19, 23]
  }, {
    unified: '1F469-1F3FD-200D-1F9BC',
    sheet: [19, 24]
  }, {
    unified: '1F469-1F3FE-200D-1F9BC',
    sheet: [19, 25]
  }, {
    unified: '1F469-1F3FF-200D-1F9BC',
    sheet: [19, 26]
  }],
  shortName: 'woman_in_motorized_wheelchair'
}, {
  name: 'Person in Manual Wheelchair',
  unified: '1F9D1-200D-1F9BD',
  keywords: ['person_in_manual_wheelchair', 'disability', 'accessibility'],
  sheet: [49, 42],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F9BD',
    sheet: [49, 43]
  }, {
    unified: '1F9D1-1F3FC-200D-1F9BD',
    sheet: [49, 44]
  }, {
    unified: '1F9D1-1F3FD-200D-1F9BD',
    sheet: [49, 45]
  }, {
    unified: '1F9D1-1F3FE-200D-1F9BD',
    sheet: [49, 46]
  }, {
    unified: '1F9D1-1F3FF-200D-1F9BD',
    sheet: [49, 47]
  }],
  shortName: 'person_in_manual_wheelchair'
}, {
  name: 'Man in Manual Wheelchair',
  unified: '1F468-200D-1F9BD',
  keywords: ['man_in_manual_wheelchair', 'disability', 'accessibility'],
  sheet: [15, 59],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-1F9BD',
    sheet: [15, 60]
  }, {
    unified: '1F468-1F3FC-200D-1F9BD',
    sheet: [16, 0]
  }, {
    unified: '1F468-1F3FD-200D-1F9BD',
    sheet: [16, 1]
  }, {
    unified: '1F468-1F3FE-200D-1F9BD',
    sheet: [16, 2]
  }, {
    unified: '1F468-1F3FF-200D-1F9BD',
    sheet: [16, 3]
  }],
  shortName: 'man_in_manual_wheelchair'
}, {
  name: 'Woman in Manual Wheelchair',
  unified: '1F469-200D-1F9BD',
  keywords: ['woman_in_manual_wheelchair', 'disability', 'accessibility'],
  sheet: [19, 27],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-1F9BD',
    sheet: [19, 28]
  }, {
    unified: '1F469-1F3FC-200D-1F9BD',
    sheet: [19, 29]
  }, {
    unified: '1F469-1F3FD-200D-1F9BD',
    sheet: [19, 30]
  }, {
    unified: '1F469-1F3FE-200D-1F9BD',
    sheet: [19, 31]
  }, {
    unified: '1F469-1F3FF-200D-1F9BD',
    sheet: [19, 32]
  }],
  shortName: 'woman_in_manual_wheelchair'
}, {
  name: 'Runner',
  unified: '1F3C3',
  keywords: ['person_running', 'move'],
  sheet: [8, 26],
  skinVariations: [{
    unified: '1F3C3-1F3FB',
    sheet: [8, 27]
  }, {
    unified: '1F3C3-1F3FC',
    sheet: [8, 28]
  }, {
    unified: '1F3C3-1F3FD',
    sheet: [8, 29]
  }, {
    unified: '1F3C3-1F3FE',
    sheet: [8, 30]
  }, {
    unified: '1F3C3-1F3FF',
    sheet: [8, 31]
  }],
  shortNames: ['running'],
  shortName: 'runner',
  obsoletedBy: '1F3C3-200D-2642-FE0F'
}, {
  name: 'Man Running',
  unified: '1F3C3-200D-2642-FE0F',
  obsoletes: '1F3C3',
  keywords: ['man_running', 'man', 'walking', 'exercise', 'race', 'running'],
  sheet: [8, 20],
  skinVariations: [{
    unified: '1F3C3-1F3FB-200D-2642-FE0F',
    sheet: [8, 21]
  }, {
    unified: '1F3C3-1F3FC-200D-2642-FE0F',
    sheet: [8, 22]
  }, {
    unified: '1F3C3-1F3FD-200D-2642-FE0F',
    sheet: [8, 23]
  }, {
    unified: '1F3C3-1F3FE-200D-2642-FE0F',
    sheet: [8, 24]
  }, {
    unified: '1F3C3-1F3FF-200D-2642-FE0F',
    sheet: [8, 25]
  }],
  shortName: 'man-running'
}, {
  name: 'Woman Running',
  unified: '1F3C3-200D-2640-FE0F',
  keywords: ['woman_running', 'woman', 'walking', 'exercise', 'race', 'running', 'female'],
  sheet: [8, 14],
  skinVariations: [{
    unified: '1F3C3-1F3FB-200D-2640-FE0F',
    sheet: [8, 15]
  }, {
    unified: '1F3C3-1F3FC-200D-2640-FE0F',
    sheet: [8, 16]
  }, {
    unified: '1F3C3-1F3FD-200D-2640-FE0F',
    sheet: [8, 17]
  }, {
    unified: '1F3C3-1F3FE-200D-2640-FE0F',
    sheet: [8, 18]
  }, {
    unified: '1F3C3-1F3FF-200D-2640-FE0F',
    sheet: [8, 19]
  }],
  shortName: 'woman-running'
}, {
  name: 'Dancer',
  unified: '1F483',
  keywords: ['woman_dancing', 'female', 'girl', 'woman', 'fun'],
  sheet: [25, 46],
  skinVariations: [{
    unified: '1F483-1F3FB',
    sheet: [25, 47]
  }, {
    unified: '1F483-1F3FC',
    sheet: [25, 48]
  }, {
    unified: '1F483-1F3FD',
    sheet: [25, 49]
  }, {
    unified: '1F483-1F3FE',
    sheet: [25, 50]
  }, {
    unified: '1F483-1F3FF',
    sheet: [25, 51]
  }],
  shortName: 'dancer'
}, {
  name: 'Man Dancing',
  unified: '1F57A',
  keywords: ['man_dancing', 'male', 'boy', 'fun', 'dancer'],
  sheet: [31, 26],
  skinVariations: [{
    unified: '1F57A-1F3FB',
    sheet: [31, 27]
  }, {
    unified: '1F57A-1F3FC',
    sheet: [31, 28]
  }, {
    unified: '1F57A-1F3FD',
    sheet: [31, 29]
  }, {
    unified: '1F57A-1F3FE',
    sheet: [31, 30]
  }, {
    unified: '1F57A-1F3FF',
    sheet: [31, 31]
  }],
  shortName: 'man_dancing'
}, {
  name: 'Person in Suit Levitating',
  unified: '1F574-FE0F',
  keywords: ['man_in_suit_levitating', 'suit', 'business', 'levitate', 'hover', 'jump'],
  sheet: [30, 59],
  skinVariations: [{
    unified: '1F574-1F3FB',
    sheet: [30, 60]
  }, {
    unified: '1F574-1F3FC',
    sheet: [31, 0]
  }, {
    unified: '1F574-1F3FD',
    sheet: [31, 1]
  }, {
    unified: '1F574-1F3FE',
    sheet: [31, 2]
  }, {
    unified: '1F574-1F3FF',
    sheet: [31, 3]
  }],
  shortName: 'man_in_business_suit_levitating'
}, {
  name: 'Woman with Bunny Ears',
  unified: '1F46F',
  keywords: ['people_with_bunny_ears', 'perform', 'costume'],
  sheet: [23, 16],
  shortName: 'dancers',
  obsoletedBy: '1F46F-200D-2640-FE0F'
}, {
  name: 'Men with Bunny Ears',
  unified: '1F46F-200D-2642-FE0F',
  keywords: ['men_with_bunny_ears', 'male', 'bunny', 'men', 'boys'],
  sheet: [23, 15],
  shortNames: ['man-with-bunny-ears-partying'],
  shortName: 'men-with-bunny-ears-partying'
}, {
  name: 'Women with Bunny Ears',
  unified: '1F46F-200D-2640-FE0F',
  obsoletes: '1F46F',
  keywords: ['women_with_bunny_ears', 'female', 'bunny', 'women', 'girls'],
  sheet: [23, 14],
  shortNames: ['woman-with-bunny-ears-partying'],
  shortName: 'women-with-bunny-ears-partying'
}, {
  name: 'Person in Steamy Room',
  unified: '1F9D6',
  keywords: ['person_in_steamy_room', 'relax', 'spa'],
  sheet: [50, 59],
  skinVariations: [{
    unified: '1F9D6-1F3FB',
    sheet: [50, 60]
  }, {
    unified: '1F9D6-1F3FC',
    sheet: [51, 0]
  }, {
    unified: '1F9D6-1F3FD',
    sheet: [51, 1]
  }, {
    unified: '1F9D6-1F3FE',
    sheet: [51, 2]
  }, {
    unified: '1F9D6-1F3FF',
    sheet: [51, 3]
  }],
  shortName: 'person_in_steamy_room',
  obsoletedBy: '1F9D6-200D-2642-FE0F'
}, {
  name: 'Man in Steamy Room',
  unified: '1F9D6-200D-2642-FE0F',
  obsoletes: '1F9D6',
  keywords: ['man_in_steamy_room', 'male', 'man', 'spa', 'steamroom', 'sauna'],
  sheet: [50, 53],
  skinVariations: [{
    unified: '1F9D6-1F3FB-200D-2642-FE0F',
    sheet: [50, 54]
  }, {
    unified: '1F9D6-1F3FC-200D-2642-FE0F',
    sheet: [50, 55]
  }, {
    unified: '1F9D6-1F3FD-200D-2642-FE0F',
    sheet: [50, 56]
  }, {
    unified: '1F9D6-1F3FE-200D-2642-FE0F',
    sheet: [50, 57]
  }, {
    unified: '1F9D6-1F3FF-200D-2642-FE0F',
    sheet: [50, 58]
  }],
  shortName: 'man_in_steamy_room'
}, {
  name: 'Woman in Steamy Room',
  unified: '1F9D6-200D-2640-FE0F',
  keywords: ['woman_in_steamy_room', 'female', 'woman', 'spa', 'steamroom', 'sauna'],
  sheet: [50, 47],
  skinVariations: [{
    unified: '1F9D6-1F3FB-200D-2640-FE0F',
    sheet: [50, 48]
  }, {
    unified: '1F9D6-1F3FC-200D-2640-FE0F',
    sheet: [50, 49]
  }, {
    unified: '1F9D6-1F3FD-200D-2640-FE0F',
    sheet: [50, 50]
  }, {
    unified: '1F9D6-1F3FE-200D-2640-FE0F',
    sheet: [50, 51]
  }, {
    unified: '1F9D6-1F3FF-200D-2640-FE0F',
    sheet: [50, 52]
  }],
  shortName: 'woman_in_steamy_room'
}, {
  name: 'Person Climbing',
  unified: '1F9D7',
  keywords: ['person_climbing', 'sport'],
  sheet: [51, 16],
  skinVariations: [{
    unified: '1F9D7-1F3FB',
    sheet: [51, 17]
  }, {
    unified: '1F9D7-1F3FC',
    sheet: [51, 18]
  }, {
    unified: '1F9D7-1F3FD',
    sheet: [51, 19]
  }, {
    unified: '1F9D7-1F3FE',
    sheet: [51, 20]
  }, {
    unified: '1F9D7-1F3FF',
    sheet: [51, 21]
  }],
  shortName: 'person_climbing',
  obsoletedBy: '1F9D7-200D-2640-FE0F'
}, {
  name: 'Man Climbing',
  unified: '1F9D7-200D-2642-FE0F',
  keywords: ['man_climbing', 'sports', 'hobby', 'man', 'male', 'rock'],
  sheet: [51, 10],
  skinVariations: [{
    unified: '1F9D7-1F3FB-200D-2642-FE0F',
    sheet: [51, 11]
  }, {
    unified: '1F9D7-1F3FC-200D-2642-FE0F',
    sheet: [51, 12]
  }, {
    unified: '1F9D7-1F3FD-200D-2642-FE0F',
    sheet: [51, 13]
  }, {
    unified: '1F9D7-1F3FE-200D-2642-FE0F',
    sheet: [51, 14]
  }, {
    unified: '1F9D7-1F3FF-200D-2642-FE0F',
    sheet: [51, 15]
  }],
  shortName: 'man_climbing'
}, {
  name: 'Woman Climbing',
  unified: '1F9D7-200D-2640-FE0F',
  obsoletes: '1F9D7',
  keywords: ['woman_climbing', 'sports', 'hobby', 'woman', 'female', 'rock'],
  sheet: [51, 4],
  skinVariations: [{
    unified: '1F9D7-1F3FB-200D-2640-FE0F',
    sheet: [51, 5]
  }, {
    unified: '1F9D7-1F3FC-200D-2640-FE0F',
    sheet: [51, 6]
  }, {
    unified: '1F9D7-1F3FD-200D-2640-FE0F',
    sheet: [51, 7]
  }, {
    unified: '1F9D7-1F3FE-200D-2640-FE0F',
    sheet: [51, 8]
  }, {
    unified: '1F9D7-1F3FF-200D-2640-FE0F',
    sheet: [51, 9]
  }],
  shortName: 'woman_climbing'
}, {
  name: 'Fencer',
  unified: '1F93A',
  keywords: ['person_fencing', 'sports', 'fencing', 'sword'],
  sheet: [42, 31],
  shortName: 'fencer'
}, {
  name: 'Horse Racing',
  unified: '1F3C7',
  keywords: ['horse_racing', 'animal', 'betting', 'competition', 'gambling', 'luck'],
  sheet: [8, 52],
  skinVariations: [{
    unified: '1F3C7-1F3FB',
    sheet: [8, 53]
  }, {
    unified: '1F3C7-1F3FC',
    sheet: [8, 54]
  }, {
    unified: '1F3C7-1F3FD',
    sheet: [8, 55]
  }, {
    unified: '1F3C7-1F3FE',
    sheet: [8, 56]
  }, {
    unified: '1F3C7-1F3FF',
    sheet: [8, 57]
  }],
  shortName: 'horse_racing'
}, {
  name: 'Skier',
  unified: '26F7-FE0F',
  keywords: ['skier', 'sports', 'winter', 'snow'],
  sheet: [58, 1],
  shortName: 'skier'
}, {
  name: 'Snowboarder',
  unified: '1F3C2',
  keywords: ['snowboarder', 'sports', 'winter'],
  sheet: [8, 8],
  skinVariations: [{
    unified: '1F3C2-1F3FB',
    sheet: [8, 9]
  }, {
    unified: '1F3C2-1F3FC',
    sheet: [8, 10]
  }, {
    unified: '1F3C2-1F3FD',
    sheet: [8, 11]
  }, {
    unified: '1F3C2-1F3FE',
    sheet: [8, 12]
  }, {
    unified: '1F3C2-1F3FF',
    sheet: [8, 13]
  }],
  shortName: 'snowboarder'
}, {
  name: 'Person Golfing',
  unified: '1F3CC-FE0F',
  keywords: ['person_golfing', 'sports', 'business'],
  sheet: [9, 47],
  skinVariations: [{
    unified: '1F3CC-1F3FB',
    sheet: [9, 48]
  }, {
    unified: '1F3CC-1F3FC',
    sheet: [9, 49]
  }, {
    unified: '1F3CC-1F3FD',
    sheet: [9, 50]
  }, {
    unified: '1F3CC-1F3FE',
    sheet: [9, 51]
  }, {
    unified: '1F3CC-1F3FF',
    sheet: [9, 52]
  }],
  shortName: 'golfer',
  obsoletedBy: '1F3CC-FE0F-200D-2642-FE0F'
}, {
  name: 'Man Golfing',
  unified: '1F3CC-FE0F-200D-2642-FE0F',
  obsoletes: '1F3CC-FE0F',
  keywords: ['man_golfing', 'sport'],
  sheet: [9, 41],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F3CC-1F3FB-200D-2642-FE0F',
    sheet: [9, 42]
  }, {
    unified: '1F3CC-1F3FC-200D-2642-FE0F',
    sheet: [9, 43]
  }, {
    unified: '1F3CC-1F3FD-200D-2642-FE0F',
    sheet: [9, 44]
  }, {
    unified: '1F3CC-1F3FE-200D-2642-FE0F',
    sheet: [9, 45]
  }, {
    unified: '1F3CC-1F3FF-200D-2642-FE0F',
    sheet: [9, 46]
  }],
  shortName: 'man-golfing'
}, {
  name: 'Woman Golfing',
  unified: '1F3CC-FE0F-200D-2640-FE0F',
  keywords: ['woman_golfing', 'sports', 'business', 'woman', 'female'],
  sheet: [9, 35],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F3CC-1F3FB-200D-2640-FE0F',
    sheet: [9, 36]
  }, {
    unified: '1F3CC-1F3FC-200D-2640-FE0F',
    sheet: [9, 37]
  }, {
    unified: '1F3CC-1F3FD-200D-2640-FE0F',
    sheet: [9, 38]
  }, {
    unified: '1F3CC-1F3FE-200D-2640-FE0F',
    sheet: [9, 39]
  }, {
    unified: '1F3CC-1F3FF-200D-2640-FE0F',
    sheet: [9, 40]
  }],
  shortName: 'woman-golfing'
}, {
  name: 'Surfer',
  unified: '1F3C4',
  keywords: ['person_surfing', 'sport', 'sea'],
  sheet: [8, 44],
  skinVariations: [{
    unified: '1F3C4-1F3FB',
    sheet: [8, 45]
  }, {
    unified: '1F3C4-1F3FC',
    sheet: [8, 46]
  }, {
    unified: '1F3C4-1F3FD',
    sheet: [8, 47]
  }, {
    unified: '1F3C4-1F3FE',
    sheet: [8, 48]
  }, {
    unified: '1F3C4-1F3FF',
    sheet: [8, 49]
  }],
  shortName: 'surfer',
  obsoletedBy: '1F3C4-200D-2642-FE0F'
}, {
  name: 'Man Surfing',
  unified: '1F3C4-200D-2642-FE0F',
  obsoletes: '1F3C4',
  keywords: ['man_surfing', 'sports', 'ocean', 'sea', 'summer', 'beach'],
  sheet: [8, 38],
  skinVariations: [{
    unified: '1F3C4-1F3FB-200D-2642-FE0F',
    sheet: [8, 39]
  }, {
    unified: '1F3C4-1F3FC-200D-2642-FE0F',
    sheet: [8, 40]
  }, {
    unified: '1F3C4-1F3FD-200D-2642-FE0F',
    sheet: [8, 41]
  }, {
    unified: '1F3C4-1F3FE-200D-2642-FE0F',
    sheet: [8, 42]
  }, {
    unified: '1F3C4-1F3FF-200D-2642-FE0F',
    sheet: [8, 43]
  }],
  shortName: 'man-surfing'
}, {
  name: 'Woman Surfing',
  unified: '1F3C4-200D-2640-FE0F',
  keywords: ['woman_surfing', 'sports', 'ocean', 'sea', 'summer', 'beach', 'woman', 'female'],
  sheet: [8, 32],
  skinVariations: [{
    unified: '1F3C4-1F3FB-200D-2640-FE0F',
    sheet: [8, 33]
  }, {
    unified: '1F3C4-1F3FC-200D-2640-FE0F',
    sheet: [8, 34]
  }, {
    unified: '1F3C4-1F3FD-200D-2640-FE0F',
    sheet: [8, 35]
  }, {
    unified: '1F3C4-1F3FE-200D-2640-FE0F',
    sheet: [8, 36]
  }, {
    unified: '1F3C4-1F3FF-200D-2640-FE0F',
    sheet: [8, 37]
  }],
  shortName: 'woman-surfing'
}, {
  name: 'Rowboat',
  unified: '1F6A3',
  keywords: ['person_rowing_boat', 'sport', 'move'],
  sheet: [36, 18],
  skinVariations: [{
    unified: '1F6A3-1F3FB',
    sheet: [36, 19]
  }, {
    unified: '1F6A3-1F3FC',
    sheet: [36, 20]
  }, {
    unified: '1F6A3-1F3FD',
    sheet: [36, 21]
  }, {
    unified: '1F6A3-1F3FE',
    sheet: [36, 22]
  }, {
    unified: '1F6A3-1F3FF',
    sheet: [36, 23]
  }],
  shortName: 'rowboat',
  obsoletedBy: '1F6A3-200D-2642-FE0F'
}, {
  name: 'Man Rowing Boat',
  unified: '1F6A3-200D-2642-FE0F',
  obsoletes: '1F6A3',
  keywords: ['man_rowing_boat', 'sports', 'hobby', 'water', 'ship'],
  sheet: [36, 12],
  skinVariations: [{
    unified: '1F6A3-1F3FB-200D-2642-FE0F',
    sheet: [36, 13]
  }, {
    unified: '1F6A3-1F3FC-200D-2642-FE0F',
    sheet: [36, 14]
  }, {
    unified: '1F6A3-1F3FD-200D-2642-FE0F',
    sheet: [36, 15]
  }, {
    unified: '1F6A3-1F3FE-200D-2642-FE0F',
    sheet: [36, 16]
  }, {
    unified: '1F6A3-1F3FF-200D-2642-FE0F',
    sheet: [36, 17]
  }],
  shortName: 'man-rowing-boat'
}, {
  name: 'Woman Rowing Boat',
  unified: '1F6A3-200D-2640-FE0F',
  keywords: ['woman_rowing_boat', 'sports', 'hobby', 'water', 'ship', 'woman', 'female'],
  sheet: [36, 6],
  skinVariations: [{
    unified: '1F6A3-1F3FB-200D-2640-FE0F',
    sheet: [36, 7]
  }, {
    unified: '1F6A3-1F3FC-200D-2640-FE0F',
    sheet: [36, 8]
  }, {
    unified: '1F6A3-1F3FD-200D-2640-FE0F',
    sheet: [36, 9]
  }, {
    unified: '1F6A3-1F3FE-200D-2640-FE0F',
    sheet: [36, 10]
  }, {
    unified: '1F6A3-1F3FF-200D-2640-FE0F',
    sheet: [36, 11]
  }],
  shortName: 'woman-rowing-boat'
}, {
  name: 'Swimmer',
  unified: '1F3CA',
  keywords: ['person_swimming', 'sport', 'pool'],
  sheet: [9, 11],
  skinVariations: [{
    unified: '1F3CA-1F3FB',
    sheet: [9, 12]
  }, {
    unified: '1F3CA-1F3FC',
    sheet: [9, 13]
  }, {
    unified: '1F3CA-1F3FD',
    sheet: [9, 14]
  }, {
    unified: '1F3CA-1F3FE',
    sheet: [9, 15]
  }, {
    unified: '1F3CA-1F3FF',
    sheet: [9, 16]
  }],
  shortName: 'swimmer',
  obsoletedBy: '1F3CA-200D-2642-FE0F'
}, {
  name: 'Man Swimming',
  unified: '1F3CA-200D-2642-FE0F',
  obsoletes: '1F3CA',
  keywords: ['man_swimming', 'sports', 'exercise', 'human', 'athlete', 'water', 'summer'],
  sheet: [9, 5],
  skinVariations: [{
    unified: '1F3CA-1F3FB-200D-2642-FE0F',
    sheet: [9, 6]
  }, {
    unified: '1F3CA-1F3FC-200D-2642-FE0F',
    sheet: [9, 7]
  }, {
    unified: '1F3CA-1F3FD-200D-2642-FE0F',
    sheet: [9, 8]
  }, {
    unified: '1F3CA-1F3FE-200D-2642-FE0F',
    sheet: [9, 9]
  }, {
    unified: '1F3CA-1F3FF-200D-2642-FE0F',
    sheet: [9, 10]
  }],
  shortName: 'man-swimming'
}, {
  name: 'Woman Swimming',
  unified: '1F3CA-200D-2640-FE0F',
  keywords: ['woman_swimming', 'sports', 'exercise', 'human', 'athlete', 'water', 'summer', 'woman', 'female'],
  sheet: [8, 60],
  skinVariations: [{
    unified: '1F3CA-1F3FB-200D-2640-FE0F',
    sheet: [9, 0]
  }, {
    unified: '1F3CA-1F3FC-200D-2640-FE0F',
    sheet: [9, 1]
  }, {
    unified: '1F3CA-1F3FD-200D-2640-FE0F',
    sheet: [9, 2]
  }, {
    unified: '1F3CA-1F3FE-200D-2640-FE0F',
    sheet: [9, 3]
  }, {
    unified: '1F3CA-1F3FF-200D-2640-FE0F',
    sheet: [9, 4]
  }],
  shortName: 'woman-swimming'
}, {
  name: 'Person Bouncing Ball',
  unified: '26F9-FE0F',
  keywords: ['person_bouncing_ball', 'sports', 'human'],
  sheet: [58, 15],
  skinVariations: [{
    unified: '26F9-1F3FB',
    sheet: [58, 16]
  }, {
    unified: '26F9-1F3FC',
    sheet: [58, 17]
  }, {
    unified: '26F9-1F3FD',
    sheet: [58, 18]
  }, {
    unified: '26F9-1F3FE',
    sheet: [58, 19]
  }, {
    unified: '26F9-1F3FF',
    sheet: [58, 20]
  }],
  shortName: 'person_with_ball',
  obsoletedBy: '26F9-FE0F-200D-2642-FE0F'
}, {
  name: 'Man Bouncing Ball',
  unified: '26F9-FE0F-200D-2642-FE0F',
  obsoletes: '26F9-FE0F',
  keywords: ['man_bouncing_ball', 'sport'],
  sheet: [58, 9],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '26F9-1F3FB-200D-2642-FE0F',
    sheet: [58, 10]
  }, {
    unified: '26F9-1F3FC-200D-2642-FE0F',
    sheet: [58, 11]
  }, {
    unified: '26F9-1F3FD-200D-2642-FE0F',
    sheet: [58, 12]
  }, {
    unified: '26F9-1F3FE-200D-2642-FE0F',
    sheet: [58, 13]
  }, {
    unified: '26F9-1F3FF-200D-2642-FE0F',
    sheet: [58, 14]
  }],
  shortName: 'man-bouncing-ball'
}, {
  name: 'Woman Bouncing Ball',
  unified: '26F9-FE0F-200D-2640-FE0F',
  keywords: ['woman_bouncing_ball', 'sports', 'human', 'woman', 'female'],
  sheet: [58, 3],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '26F9-1F3FB-200D-2640-FE0F',
    sheet: [58, 4]
  }, {
    unified: '26F9-1F3FC-200D-2640-FE0F',
    sheet: [58, 5]
  }, {
    unified: '26F9-1F3FD-200D-2640-FE0F',
    sheet: [58, 6]
  }, {
    unified: '26F9-1F3FE-200D-2640-FE0F',
    sheet: [58, 7]
  }, {
    unified: '26F9-1F3FF-200D-2640-FE0F',
    sheet: [58, 8]
  }],
  shortName: 'woman-bouncing-ball'
}, {
  name: 'Person Lifting Weights',
  unified: '1F3CB-FE0F',
  keywords: ['person_lifting_weights', 'sports', 'training', 'exercise'],
  sheet: [9, 29],
  skinVariations: [{
    unified: '1F3CB-1F3FB',
    sheet: [9, 30]
  }, {
    unified: '1F3CB-1F3FC',
    sheet: [9, 31]
  }, {
    unified: '1F3CB-1F3FD',
    sheet: [9, 32]
  }, {
    unified: '1F3CB-1F3FE',
    sheet: [9, 33]
  }, {
    unified: '1F3CB-1F3FF',
    sheet: [9, 34]
  }],
  shortName: 'weight_lifter',
  obsoletedBy: '1F3CB-FE0F-200D-2642-FE0F'
}, {
  name: 'Man Lifting Weights',
  unified: '1F3CB-FE0F-200D-2642-FE0F',
  obsoletes: '1F3CB-FE0F',
  keywords: ['man_lifting_weights', 'sport'],
  sheet: [9, 23],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F3CB-1F3FB-200D-2642-FE0F',
    sheet: [9, 24]
  }, {
    unified: '1F3CB-1F3FC-200D-2642-FE0F',
    sheet: [9, 25]
  }, {
    unified: '1F3CB-1F3FD-200D-2642-FE0F',
    sheet: [9, 26]
  }, {
    unified: '1F3CB-1F3FE-200D-2642-FE0F',
    sheet: [9, 27]
  }, {
    unified: '1F3CB-1F3FF-200D-2642-FE0F',
    sheet: [9, 28]
  }],
  shortName: 'man-lifting-weights'
}, {
  name: 'Woman Lifting Weights',
  unified: '1F3CB-FE0F-200D-2640-FE0F',
  keywords: ['woman_lifting_weights', 'sports', 'training', 'exercise', 'woman', 'female'],
  sheet: [9, 17],
  hidden: ['facebook'],
  skinVariations: [{
    unified: '1F3CB-1F3FB-200D-2640-FE0F',
    sheet: [9, 18]
  }, {
    unified: '1F3CB-1F3FC-200D-2640-FE0F',
    sheet: [9, 19]
  }, {
    unified: '1F3CB-1F3FD-200D-2640-FE0F',
    sheet: [9, 20]
  }, {
    unified: '1F3CB-1F3FE-200D-2640-FE0F',
    sheet: [9, 21]
  }, {
    unified: '1F3CB-1F3FF-200D-2640-FE0F',
    sheet: [9, 22]
  }],
  shortName: 'woman-lifting-weights'
}, {
  name: 'Bicyclist',
  unified: '1F6B4',
  keywords: ['person_biking', 'sport', 'move'],
  sheet: [36, 52],
  skinVariations: [{
    unified: '1F6B4-1F3FB',
    sheet: [36, 53]
  }, {
    unified: '1F6B4-1F3FC',
    sheet: [36, 54]
  }, {
    unified: '1F6B4-1F3FD',
    sheet: [36, 55]
  }, {
    unified: '1F6B4-1F3FE',
    sheet: [36, 56]
  }, {
    unified: '1F6B4-1F3FF',
    sheet: [36, 57]
  }],
  shortName: 'bicyclist',
  obsoletedBy: '1F6B4-200D-2642-FE0F'
}, {
  name: 'Man Biking',
  unified: '1F6B4-200D-2642-FE0F',
  obsoletes: '1F6B4',
  keywords: ['man_biking', 'sports', 'bike', 'exercise', 'hipster'],
  sheet: [36, 46],
  skinVariations: [{
    unified: '1F6B4-1F3FB-200D-2642-FE0F',
    sheet: [36, 47]
  }, {
    unified: '1F6B4-1F3FC-200D-2642-FE0F',
    sheet: [36, 48]
  }, {
    unified: '1F6B4-1F3FD-200D-2642-FE0F',
    sheet: [36, 49]
  }, {
    unified: '1F6B4-1F3FE-200D-2642-FE0F',
    sheet: [36, 50]
  }, {
    unified: '1F6B4-1F3FF-200D-2642-FE0F',
    sheet: [36, 51]
  }],
  shortName: 'man-biking'
}, {
  name: 'Woman Biking',
  unified: '1F6B4-200D-2640-FE0F',
  keywords: ['woman_biking', 'sports', 'bike', 'exercise', 'hipster', 'woman', 'female'],
  sheet: [36, 40],
  skinVariations: [{
    unified: '1F6B4-1F3FB-200D-2640-FE0F',
    sheet: [36, 41]
  }, {
    unified: '1F6B4-1F3FC-200D-2640-FE0F',
    sheet: [36, 42]
  }, {
    unified: '1F6B4-1F3FD-200D-2640-FE0F',
    sheet: [36, 43]
  }, {
    unified: '1F6B4-1F3FE-200D-2640-FE0F',
    sheet: [36, 44]
  }, {
    unified: '1F6B4-1F3FF-200D-2640-FE0F',
    sheet: [36, 45]
  }],
  shortName: 'woman-biking'
}, {
  name: 'Mountain Bicyclist',
  unified: '1F6B5',
  keywords: ['person_mountain_biking', 'sport', 'move'],
  sheet: [37, 9],
  skinVariations: [{
    unified: '1F6B5-1F3FB',
    sheet: [37, 10]
  }, {
    unified: '1F6B5-1F3FC',
    sheet: [37, 11]
  }, {
    unified: '1F6B5-1F3FD',
    sheet: [37, 12]
  }, {
    unified: '1F6B5-1F3FE',
    sheet: [37, 13]
  }, {
    unified: '1F6B5-1F3FF',
    sheet: [37, 14]
  }],
  shortName: 'mountain_bicyclist',
  obsoletedBy: '1F6B5-200D-2642-FE0F'
}, {
  name: 'Man Mountain Biking',
  unified: '1F6B5-200D-2642-FE0F',
  obsoletes: '1F6B5',
  keywords: ['man_mountain_biking', 'transportation', 'sports', 'human', 'race', 'bike'],
  sheet: [37, 3],
  skinVariations: [{
    unified: '1F6B5-1F3FB-200D-2642-FE0F',
    sheet: [37, 4]
  }, {
    unified: '1F6B5-1F3FC-200D-2642-FE0F',
    sheet: [37, 5]
  }, {
    unified: '1F6B5-1F3FD-200D-2642-FE0F',
    sheet: [37, 6]
  }, {
    unified: '1F6B5-1F3FE-200D-2642-FE0F',
    sheet: [37, 7]
  }, {
    unified: '1F6B5-1F3FF-200D-2642-FE0F',
    sheet: [37, 8]
  }],
  shortName: 'man-mountain-biking'
}, {
  name: 'Woman Mountain Biking',
  unified: '1F6B5-200D-2640-FE0F',
  keywords: ['woman_mountain_biking', 'transportation', 'sports', 'human', 'race', 'bike', 'woman', 'female'],
  sheet: [36, 58],
  skinVariations: [{
    unified: '1F6B5-1F3FB-200D-2640-FE0F',
    sheet: [36, 59]
  }, {
    unified: '1F6B5-1F3FC-200D-2640-FE0F',
    sheet: [36, 60]
  }, {
    unified: '1F6B5-1F3FD-200D-2640-FE0F',
    sheet: [37, 0]
  }, {
    unified: '1F6B5-1F3FE-200D-2640-FE0F',
    sheet: [37, 1]
  }, {
    unified: '1F6B5-1F3FF-200D-2640-FE0F',
    sheet: [37, 2]
  }],
  shortName: 'woman-mountain-biking'
}, {
  name: 'Person Doing Cartwheel',
  unified: '1F938',
  keywords: ['person_cartwheeling', 'sport', 'gymnastic'],
  sheet: [42, 7],
  skinVariations: [{
    unified: '1F938-1F3FB',
    sheet: [42, 8]
  }, {
    unified: '1F938-1F3FC',
    sheet: [42, 9]
  }, {
    unified: '1F938-1F3FD',
    sheet: [42, 10]
  }, {
    unified: '1F938-1F3FE',
    sheet: [42, 11]
  }, {
    unified: '1F938-1F3FF',
    sheet: [42, 12]
  }],
  shortName: 'person_doing_cartwheel'
}, {
  name: 'Man Cartwheeling',
  unified: '1F938-200D-2642-FE0F',
  keywords: ['man_cartwheeling', 'gymnastics'],
  sheet: [42, 1],
  skinVariations: [{
    unified: '1F938-1F3FB-200D-2642-FE0F',
    sheet: [42, 2]
  }, {
    unified: '1F938-1F3FC-200D-2642-FE0F',
    sheet: [42, 3]
  }, {
    unified: '1F938-1F3FD-200D-2642-FE0F',
    sheet: [42, 4]
  }, {
    unified: '1F938-1F3FE-200D-2642-FE0F',
    sheet: [42, 5]
  }, {
    unified: '1F938-1F3FF-200D-2642-FE0F',
    sheet: [42, 6]
  }],
  shortName: 'man-cartwheeling'
}, {
  name: 'Woman Cartwheeling',
  unified: '1F938-200D-2640-FE0F',
  keywords: ['woman_cartwheeling', 'gymnastics'],
  sheet: [41, 56],
  skinVariations: [{
    unified: '1F938-1F3FB-200D-2640-FE0F',
    sheet: [41, 57]
  }, {
    unified: '1F938-1F3FC-200D-2640-FE0F',
    sheet: [41, 58]
  }, {
    unified: '1F938-1F3FD-200D-2640-FE0F',
    sheet: [41, 59]
  }, {
    unified: '1F938-1F3FE-200D-2640-FE0F',
    sheet: [41, 60]
  }, {
    unified: '1F938-1F3FF-200D-2640-FE0F',
    sheet: [42, 0]
  }],
  shortName: 'woman-cartwheeling'
}, {
  name: 'Wrestlers',
  unified: '1F93C',
  keywords: ['people_wrestling', 'sport'],
  sheet: [42, 34],
  shortName: 'wrestlers'
}, {
  name: 'Men Wrestling',
  unified: '1F93C-200D-2642-FE0F',
  keywords: ['men_wrestling', 'sports', 'wrestlers'],
  sheet: [42, 33],
  shortName: 'man-wrestling'
}, {
  name: 'Women Wrestling',
  unified: '1F93C-200D-2640-FE0F',
  keywords: ['women_wrestling', 'sports', 'wrestlers'],
  sheet: [42, 32],
  shortName: 'woman-wrestling'
}, {
  name: 'Water Polo',
  unified: '1F93D',
  keywords: ['person_playing_water_polo', 'sport'],
  sheet: [42, 47],
  skinVariations: [{
    unified: '1F93D-1F3FB',
    sheet: [42, 48]
  }, {
    unified: '1F93D-1F3FC',
    sheet: [42, 49]
  }, {
    unified: '1F93D-1F3FD',
    sheet: [42, 50]
  }, {
    unified: '1F93D-1F3FE',
    sheet: [42, 51]
  }, {
    unified: '1F93D-1F3FF',
    sheet: [42, 52]
  }],
  shortName: 'water_polo'
}, {
  name: 'Man Playing Water Polo',
  unified: '1F93D-200D-2642-FE0F',
  keywords: ['man_playing_water_polo', 'sports', 'pool'],
  sheet: [42, 41],
  skinVariations: [{
    unified: '1F93D-1F3FB-200D-2642-FE0F',
    sheet: [42, 42]
  }, {
    unified: '1F93D-1F3FC-200D-2642-FE0F',
    sheet: [42, 43]
  }, {
    unified: '1F93D-1F3FD-200D-2642-FE0F',
    sheet: [42, 44]
  }, {
    unified: '1F93D-1F3FE-200D-2642-FE0F',
    sheet: [42, 45]
  }, {
    unified: '1F93D-1F3FF-200D-2642-FE0F',
    sheet: [42, 46]
  }],
  shortName: 'man-playing-water-polo'
}, {
  name: 'Woman Playing Water Polo',
  unified: '1F93D-200D-2640-FE0F',
  keywords: ['woman_playing_water_polo', 'sports', 'pool'],
  sheet: [42, 35],
  skinVariations: [{
    unified: '1F93D-1F3FB-200D-2640-FE0F',
    sheet: [42, 36]
  }, {
    unified: '1F93D-1F3FC-200D-2640-FE0F',
    sheet: [42, 37]
  }, {
    unified: '1F93D-1F3FD-200D-2640-FE0F',
    sheet: [42, 38]
  }, {
    unified: '1F93D-1F3FE-200D-2640-FE0F',
    sheet: [42, 39]
  }, {
    unified: '1F93D-1F3FF-200D-2640-FE0F',
    sheet: [42, 40]
  }],
  shortName: 'woman-playing-water-polo'
}, {
  name: 'Handball',
  unified: '1F93E',
  keywords: ['person_playing_handball', 'sport'],
  sheet: [43, 4],
  skinVariations: [{
    unified: '1F93E-1F3FB',
    sheet: [43, 5]
  }, {
    unified: '1F93E-1F3FC',
    sheet: [43, 6]
  }, {
    unified: '1F93E-1F3FD',
    sheet: [43, 7]
  }, {
    unified: '1F93E-1F3FE',
    sheet: [43, 8]
  }, {
    unified: '1F93E-1F3FF',
    sheet: [43, 9]
  }],
  shortName: 'handball'
}, {
  name: 'Man Playing Handball',
  unified: '1F93E-200D-2642-FE0F',
  keywords: ['man_playing_handball', 'sports'],
  sheet: [42, 59],
  skinVariations: [{
    unified: '1F93E-1F3FB-200D-2642-FE0F',
    sheet: [42, 60]
  }, {
    unified: '1F93E-1F3FC-200D-2642-FE0F',
    sheet: [43, 0]
  }, {
    unified: '1F93E-1F3FD-200D-2642-FE0F',
    sheet: [43, 1]
  }, {
    unified: '1F93E-1F3FE-200D-2642-FE0F',
    sheet: [43, 2]
  }, {
    unified: '1F93E-1F3FF-200D-2642-FE0F',
    sheet: [43, 3]
  }],
  shortName: 'man-playing-handball'
}, {
  name: 'Woman Playing Handball',
  unified: '1F93E-200D-2640-FE0F',
  keywords: ['woman_playing_handball', 'sports'],
  sheet: [42, 53],
  skinVariations: [{
    unified: '1F93E-1F3FB-200D-2640-FE0F',
    sheet: [42, 54]
  }, {
    unified: '1F93E-1F3FC-200D-2640-FE0F',
    sheet: [42, 55]
  }, {
    unified: '1F93E-1F3FD-200D-2640-FE0F',
    sheet: [42, 56]
  }, {
    unified: '1F93E-1F3FE-200D-2640-FE0F',
    sheet: [42, 57]
  }, {
    unified: '1F93E-1F3FF-200D-2640-FE0F',
    sheet: [42, 58]
  }],
  shortName: 'woman-playing-handball'
}, {
  name: 'Juggling',
  unified: '1F939',
  keywords: ['person_juggling', 'performance', 'balance'],
  sheet: [42, 25],
  skinVariations: [{
    unified: '1F939-1F3FB',
    sheet: [42, 26]
  }, {
    unified: '1F939-1F3FC',
    sheet: [42, 27]
  }, {
    unified: '1F939-1F3FD',
    sheet: [42, 28]
  }, {
    unified: '1F939-1F3FE',
    sheet: [42, 29]
  }, {
    unified: '1F939-1F3FF',
    sheet: [42, 30]
  }],
  shortName: 'juggling'
}, {
  name: 'Man Juggling',
  unified: '1F939-200D-2642-FE0F',
  keywords: ['man_juggling', 'juggle', 'balance', 'skill', 'multitask'],
  sheet: [42, 19],
  skinVariations: [{
    unified: '1F939-1F3FB-200D-2642-FE0F',
    sheet: [42, 20]
  }, {
    unified: '1F939-1F3FC-200D-2642-FE0F',
    sheet: [42, 21]
  }, {
    unified: '1F939-1F3FD-200D-2642-FE0F',
    sheet: [42, 22]
  }, {
    unified: '1F939-1F3FE-200D-2642-FE0F',
    sheet: [42, 23]
  }, {
    unified: '1F939-1F3FF-200D-2642-FE0F',
    sheet: [42, 24]
  }],
  shortName: 'man-juggling'
}, {
  name: 'Woman Juggling',
  unified: '1F939-200D-2640-FE0F',
  keywords: ['woman_juggling', 'juggle', 'balance', 'skill', 'multitask'],
  sheet: [42, 13],
  skinVariations: [{
    unified: '1F939-1F3FB-200D-2640-FE0F',
    sheet: [42, 14]
  }, {
    unified: '1F939-1F3FC-200D-2640-FE0F',
    sheet: [42, 15]
  }, {
    unified: '1F939-1F3FD-200D-2640-FE0F',
    sheet: [42, 16]
  }, {
    unified: '1F939-1F3FE-200D-2640-FE0F',
    sheet: [42, 17]
  }, {
    unified: '1F939-1F3FF-200D-2640-FE0F',
    sheet: [42, 18]
  }],
  shortName: 'woman-juggling'
}, {
  name: 'Person in Lotus Position',
  unified: '1F9D8',
  keywords: ['person_in_lotus_position', 'meditate'],
  sheet: [51, 34],
  skinVariations: [{
    unified: '1F9D8-1F3FB',
    sheet: [51, 35]
  }, {
    unified: '1F9D8-1F3FC',
    sheet: [51, 36]
  }, {
    unified: '1F9D8-1F3FD',
    sheet: [51, 37]
  }, {
    unified: '1F9D8-1F3FE',
    sheet: [51, 38]
  }, {
    unified: '1F9D8-1F3FF',
    sheet: [51, 39]
  }],
  shortName: 'person_in_lotus_position',
  obsoletedBy: '1F9D8-200D-2640-FE0F'
}, {
  name: 'Man in Lotus Position',
  unified: '1F9D8-200D-2642-FE0F',
  keywords: ['man_in_lotus_position', 'man', 'male', 'meditation', 'yoga', 'serenity', 'zen', 'mindfulness'],
  sheet: [51, 28],
  skinVariations: [{
    unified: '1F9D8-1F3FB-200D-2642-FE0F',
    sheet: [51, 29]
  }, {
    unified: '1F9D8-1F3FC-200D-2642-FE0F',
    sheet: [51, 30]
  }, {
    unified: '1F9D8-1F3FD-200D-2642-FE0F',
    sheet: [51, 31]
  }, {
    unified: '1F9D8-1F3FE-200D-2642-FE0F',
    sheet: [51, 32]
  }, {
    unified: '1F9D8-1F3FF-200D-2642-FE0F',
    sheet: [51, 33]
  }],
  shortName: 'man_in_lotus_position'
}, {
  name: 'Woman in Lotus Position',
  unified: '1F9D8-200D-2640-FE0F',
  obsoletes: '1F9D8',
  keywords: ['woman_in_lotus_position', 'woman', 'female', 'meditation', 'yoga', 'serenity', 'zen', 'mindfulness'],
  sheet: [51, 22],
  skinVariations: [{
    unified: '1F9D8-1F3FB-200D-2640-FE0F',
    sheet: [51, 23]
  }, {
    unified: '1F9D8-1F3FC-200D-2640-FE0F',
    sheet: [51, 24]
  }, {
    unified: '1F9D8-1F3FD-200D-2640-FE0F',
    sheet: [51, 25]
  }, {
    unified: '1F9D8-1F3FE-200D-2640-FE0F',
    sheet: [51, 26]
  }, {
    unified: '1F9D8-1F3FF-200D-2640-FE0F',
    sheet: [51, 27]
  }],
  shortName: 'woman_in_lotus_position'
}, {
  name: 'Bath',
  unified: '1F6C0',
  keywords: ['person_taking_bath', 'clean', 'shower', 'bathroom'],
  sheet: [37, 42],
  skinVariations: [{
    unified: '1F6C0-1F3FB',
    sheet: [37, 43]
  }, {
    unified: '1F6C0-1F3FC',
    sheet: [37, 44]
  }, {
    unified: '1F6C0-1F3FD',
    sheet: [37, 45]
  }, {
    unified: '1F6C0-1F3FE',
    sheet: [37, 46]
  }, {
    unified: '1F6C0-1F3FF',
    sheet: [37, 47]
  }],
  shortName: 'bath'
}, {
  name: 'Sleeping Accommodation',
  unified: '1F6CC',
  keywords: ['person_in_bed', 'bed', 'rest'],
  sheet: [37, 54],
  skinVariations: [{
    unified: '1F6CC-1F3FB',
    sheet: [37, 55]
  }, {
    unified: '1F6CC-1F3FC',
    sheet: [37, 56]
  }, {
    unified: '1F6CC-1F3FD',
    sheet: [37, 57]
  }, {
    unified: '1F6CC-1F3FE',
    sheet: [37, 58]
  }, {
    unified: '1F6CC-1F3FF',
    sheet: [37, 59]
  }],
  shortName: 'sleeping_accommodation'
}, {
  name: 'People Holding Hands',
  unified: '1F9D1-200D-1F91D-200D-1F9D1',
  keywords: ['people_holding_hands', 'friendship'],
  sheet: [48, 41],
  skinVariations: [{
    unified: '1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FB',
    sheet: [48, 42]
  }, {
    unified: '1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FC',
    sheet: [48, 43],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FD',
    sheet: [48, 44],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FE',
    sheet: [48, 45],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-1F91D-200D-1F9D1-1F3FF',
    sheet: [48, 46],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FB',
    sheet: [48, 47]
  }, {
    unified: '1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FC',
    sheet: [48, 48]
  }, {
    unified: '1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FD',
    sheet: [48, 49],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FE',
    sheet: [48, 50],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-1F91D-200D-1F9D1-1F3FF',
    sheet: [48, 51],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FB',
    sheet: [48, 52]
  }, {
    unified: '1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FC',
    sheet: [48, 53]
  }, {
    unified: '1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FD',
    sheet: [48, 54]
  }, {
    unified: '1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FE',
    sheet: [48, 55],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-1F91D-200D-1F9D1-1F3FF',
    sheet: [48, 56],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FB',
    sheet: [48, 57]
  }, {
    unified: '1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FC',
    sheet: [48, 58]
  }, {
    unified: '1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FD',
    sheet: [48, 59]
  }, {
    unified: '1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FE',
    sheet: [48, 60]
  }, {
    unified: '1F9D1-1F3FE-200D-1F91D-200D-1F9D1-1F3FF',
    sheet: [49, 0],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FB',
    sheet: [49, 1]
  }, {
    unified: '1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FC',
    sheet: [49, 2]
  }, {
    unified: '1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FD',
    sheet: [49, 3]
  }, {
    unified: '1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FE',
    sheet: [49, 4]
  }, {
    unified: '1F9D1-1F3FF-200D-1F91D-200D-1F9D1-1F3FF',
    sheet: [49, 5]
  }],
  shortName: 'people_holding_hands'
}, {
  name: 'Two Women Holding Hands',
  unified: '1F46D',
  keywords: ['women_holding_hands', 'pair', 'friendship', 'couple', 'love', 'like', 'female', 'people', 'human'],
  sheet: [22, 31],
  skinVariations: [{
    unified: '1F46D-1F3FB',
    sheet: [22, 32]
  }, {
    unified: '1F46D-1F3FC',
    sheet: [22, 33]
  }, {
    unified: '1F46D-1F3FD',
    sheet: [22, 34]
  }, {
    unified: '1F46D-1F3FE',
    sheet: [22, 35]
  }, {
    unified: '1F46D-1F3FF',
    sheet: [22, 36]
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F469-1F3FC',
    sheet: [22, 37],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F469-1F3FD',
    sheet: [22, 38],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F469-1F3FE',
    sheet: [22, 39],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F469-1F3FF',
    sheet: [22, 40],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F469-1F3FB',
    sheet: [22, 41]
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F469-1F3FD',
    sheet: [22, 42],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F469-1F3FE',
    sheet: [22, 43],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F469-1F3FF',
    sheet: [22, 44],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F469-1F3FB',
    sheet: [22, 45]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F469-1F3FC',
    sheet: [22, 46]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F469-1F3FE',
    sheet: [22, 47],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F469-1F3FF',
    sheet: [22, 48],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F469-1F3FB',
    sheet: [22, 49]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F469-1F3FC',
    sheet: [22, 50]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F469-1F3FD',
    sheet: [22, 51]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F469-1F3FF',
    sheet: [22, 52],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F469-1F3FB',
    sheet: [22, 53]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F469-1F3FC',
    sheet: [22, 54]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F469-1F3FD',
    sheet: [22, 55]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F469-1F3FE',
    sheet: [22, 56]
  }],
  shortNames: ['women_holding_hands'],
  shortName: 'two_women_holding_hands'
}, {
  name: 'Man and Woman Holding Hands',
  unified: '1F46B',
  keywords: ['woman_and_man_holding_hands', 'pair', 'people', 'human', 'love', 'date', 'dating', 'like', 'affection', 'valentines', 'marriage'],
  sheet: [21, 40],
  skinVariations: [{
    unified: '1F46B-1F3FB',
    sheet: [21, 41]
  }, {
    unified: '1F46B-1F3FC',
    sheet: [21, 42]
  }, {
    unified: '1F46B-1F3FD',
    sheet: [21, 43]
  }, {
    unified: '1F46B-1F3FE',
    sheet: [21, 44]
  }, {
    unified: '1F46B-1F3FF',
    sheet: [21, 45]
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F468-1F3FC',
    sheet: [21, 46]
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F468-1F3FD',
    sheet: [21, 47]
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F468-1F3FE',
    sheet: [21, 48]
  }, {
    unified: '1F469-1F3FB-200D-1F91D-200D-1F468-1F3FF',
    sheet: [21, 49]
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F468-1F3FB',
    sheet: [21, 50]
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F468-1F3FD',
    sheet: [21, 51]
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F468-1F3FE',
    sheet: [21, 52]
  }, {
    unified: '1F469-1F3FC-200D-1F91D-200D-1F468-1F3FF',
    sheet: [21, 53]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F468-1F3FB',
    sheet: [21, 54]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F468-1F3FC',
    sheet: [21, 55]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F468-1F3FE',
    sheet: [21, 56]
  }, {
    unified: '1F469-1F3FD-200D-1F91D-200D-1F468-1F3FF',
    sheet: [21, 57]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F468-1F3FB',
    sheet: [21, 58]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F468-1F3FC',
    sheet: [21, 59]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F468-1F3FD',
    sheet: [21, 60]
  }, {
    unified: '1F469-1F3FE-200D-1F91D-200D-1F468-1F3FF',
    sheet: [22, 0]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F468-1F3FB',
    sheet: [22, 1]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F468-1F3FC',
    sheet: [22, 2]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F468-1F3FD',
    sheet: [22, 3]
  }, {
    unified: '1F469-1F3FF-200D-1F91D-200D-1F468-1F3FE',
    sheet: [22, 4]
  }],
  shortNames: ['woman_and_man_holding_hands', 'couple'],
  shortName: 'man_and_woman_holding_hands'
}, {
  name: 'Two Men Holding Hands',
  unified: '1F46C',
  keywords: ['men_holding_hands', 'pair', 'couple', 'love', 'like', 'bromance', 'friendship', 'people', 'human'],
  sheet: [22, 5],
  skinVariations: [{
    unified: '1F46C-1F3FB',
    sheet: [22, 6]
  }, {
    unified: '1F46C-1F3FC',
    sheet: [22, 7]
  }, {
    unified: '1F46C-1F3FD',
    sheet: [22, 8]
  }, {
    unified: '1F46C-1F3FE',
    sheet: [22, 9]
  }, {
    unified: '1F46C-1F3FF',
    sheet: [22, 10]
  }, {
    unified: '1F468-1F3FB-200D-1F91D-200D-1F468-1F3FC',
    sheet: [22, 11],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-1F91D-200D-1F468-1F3FD',
    sheet: [22, 12],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-1F91D-200D-1F468-1F3FE',
    sheet: [22, 13],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-1F91D-200D-1F468-1F3FF',
    sheet: [22, 14],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-1F91D-200D-1F468-1F3FB',
    sheet: [22, 15]
  }, {
    unified: '1F468-1F3FC-200D-1F91D-200D-1F468-1F3FD',
    sheet: [22, 16],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-1F91D-200D-1F468-1F3FE',
    sheet: [22, 17],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-1F91D-200D-1F468-1F3FF',
    sheet: [22, 18],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-1F91D-200D-1F468-1F3FB',
    sheet: [22, 19]
  }, {
    unified: '1F468-1F3FD-200D-1F91D-200D-1F468-1F3FC',
    sheet: [22, 20]
  }, {
    unified: '1F468-1F3FD-200D-1F91D-200D-1F468-1F3FE',
    sheet: [22, 21],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-1F91D-200D-1F468-1F3FF',
    sheet: [22, 22],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-1F91D-200D-1F468-1F3FB',
    sheet: [22, 23]
  }, {
    unified: '1F468-1F3FE-200D-1F91D-200D-1F468-1F3FC',
    sheet: [22, 24]
  }, {
    unified: '1F468-1F3FE-200D-1F91D-200D-1F468-1F3FD',
    sheet: [22, 25]
  }, {
    unified: '1F468-1F3FE-200D-1F91D-200D-1F468-1F3FF',
    sheet: [22, 26],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-1F91D-200D-1F468-1F3FB',
    sheet: [22, 27]
  }, {
    unified: '1F468-1F3FF-200D-1F91D-200D-1F468-1F3FC',
    sheet: [22, 28]
  }, {
    unified: '1F468-1F3FF-200D-1F91D-200D-1F468-1F3FD',
    sheet: [22, 29]
  }, {
    unified: '1F468-1F3FF-200D-1F91D-200D-1F468-1F3FE',
    sheet: [22, 30]
  }],
  shortNames: ['men_holding_hands'],
  shortName: 'two_men_holding_hands'
}, {
  name: 'Kiss',
  unified: '1F48F',
  keywords: ['kiss', 'pair', 'valentines', 'love', 'like', 'dating', 'marriage'],
  sheet: [26, 41],
  skinVariations: [{
    unified: '1F48F-1F3FB',
    sheet: [26, 42]
  }, {
    unified: '1F48F-1F3FC',
    sheet: [26, 43]
  }, {
    unified: '1F48F-1F3FD',
    sheet: [26, 44]
  }, {
    unified: '1F48F-1F3FE',
    sheet: [26, 45]
  }, {
    unified: '1F48F-1F3FF',
    sheet: [26, 46]
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC',
    sheet: [26, 47],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD',
    sheet: [26, 48],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE',
    sheet: [26, 49],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF',
    sheet: [26, 50],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB',
    sheet: [26, 51],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD',
    sheet: [26, 52],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE',
    sheet: [26, 53],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF',
    sheet: [26, 54],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB',
    sheet: [26, 55],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC',
    sheet: [26, 56],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE',
    sheet: [26, 57],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF',
    sheet: [26, 58],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB',
    sheet: [26, 59],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC',
    sheet: [26, 60],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD',
    sheet: [27, 0],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FF',
    sheet: [27, 1],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FB',
    sheet: [27, 2],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FC',
    sheet: [27, 3],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FD',
    sheet: [27, 4],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F9D1-1F3FE',
    sheet: [27, 5],
    hidden: ['facebook']
  }],
  shortName: 'couplekiss'
}, {
  name: 'Kiss: Woman, Man',
  unified: '1F469-200D-2764-FE0F-200D-1F48B-200D-1F468',
  keywords: ['kiss_woman_man', 'love'],
  sheet: [20, 42],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [20, 43],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [20, 44],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [20, 45],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [20, 46],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [20, 47],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [20, 48],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [20, 49],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [20, 50],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [20, 51],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [20, 52],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [20, 53],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [20, 54],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [20, 55],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [20, 56],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [20, 57],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [20, 58],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [20, 59],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [20, 60],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [21, 0],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [21, 1],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [21, 2],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [21, 3],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [21, 4],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [21, 5],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [21, 6],
    hidden: ['facebook']
  }],
  shortName: 'woman-kiss-man'
}, {
  name: 'Kiss: Man, Man',
  unified: '1F468-200D-2764-FE0F-200D-1F48B-200D-1F468',
  keywords: ['kiss_man_man', 'pair', 'valentines', 'love', 'like', 'dating', 'marriage'],
  sheet: [16, 48],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [16, 49],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [16, 50],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [16, 51],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [16, 52],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [16, 53],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [16, 54],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [16, 55],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [16, 56],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [16, 57],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [16, 58],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [16, 59],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [16, 60],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [17, 0],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [17, 1],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [17, 2],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [17, 3],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [17, 4],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [17, 5],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [17, 6],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [17, 7],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FB',
    sheet: [17, 8],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FC',
    sheet: [17, 9],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FD',
    sheet: [17, 10],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FE',
    sheet: [17, 11],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F468-1F3FF',
    sheet: [17, 12],
    hidden: ['facebook']
  }],
  shortName: 'man-kiss-man'
}, {
  name: 'Kiss: Woman, Woman',
  unified: '1F469-200D-2764-FE0F-200D-1F48B-200D-1F469',
  keywords: ['kiss_woman_woman', 'pair', 'valentines', 'love', 'like', 'dating', 'marriage'],
  sheet: [21, 7],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB',
    sheet: [21, 8],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC',
    sheet: [21, 9],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD',
    sheet: [21, 10],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE',
    sheet: [21, 11],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF',
    sheet: [21, 12],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB',
    sheet: [21, 13],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC',
    sheet: [21, 14],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD',
    sheet: [21, 15],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE',
    sheet: [21, 16],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF',
    sheet: [21, 17],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB',
    sheet: [21, 18],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC',
    sheet: [21, 19],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD',
    sheet: [21, 20],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE',
    sheet: [21, 21],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF',
    sheet: [21, 22],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB',
    sheet: [21, 23],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC',
    sheet: [21, 24],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD',
    sheet: [21, 25],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE',
    sheet: [21, 26],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF',
    sheet: [21, 27],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FB',
    sheet: [21, 28],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FC',
    sheet: [21, 29],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FD',
    sheet: [21, 30],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FE',
    sheet: [21, 31],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F48B-200D-1F469-1F3FF',
    sheet: [21, 32],
    hidden: ['facebook']
  }],
  shortName: 'woman-kiss-woman'
}, {
  name: 'Couple with Heart',
  unified: '1F491',
  keywords: ['couple_with_heart', 'pair', 'love', 'like', 'affection', 'human', 'dating', 'valentines', 'marriage'],
  sheet: [27, 7],
  skinVariations: [{
    unified: '1F491-1F3FB',
    sheet: [27, 8]
  }, {
    unified: '1F491-1F3FC',
    sheet: [27, 9]
  }, {
    unified: '1F491-1F3FD',
    sheet: [27, 10]
  }, {
    unified: '1F491-1F3FE',
    sheet: [27, 11]
  }, {
    unified: '1F491-1F3FF',
    sheet: [27, 12]
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FC',
    sheet: [27, 13],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FD',
    sheet: [27, 14],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FE',
    sheet: [27, 15],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FB-200D-2764-FE0F-200D-1F9D1-1F3FF',
    sheet: [27, 16],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FB',
    sheet: [27, 17],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FD',
    sheet: [27, 18],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FE',
    sheet: [27, 19],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FC-200D-2764-FE0F-200D-1F9D1-1F3FF',
    sheet: [27, 20],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FB',
    sheet: [27, 21],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FC',
    sheet: [27, 22],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FE',
    sheet: [27, 23],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FD-200D-2764-FE0F-200D-1F9D1-1F3FF',
    sheet: [27, 24],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FB',
    sheet: [27, 25],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FC',
    sheet: [27, 26],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FD',
    sheet: [27, 27],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FE-200D-2764-FE0F-200D-1F9D1-1F3FF',
    sheet: [27, 28],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FB',
    sheet: [27, 29],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FC',
    sheet: [27, 30],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FD',
    sheet: [27, 31],
    hidden: ['facebook']
  }, {
    unified: '1F9D1-1F3FF-200D-2764-FE0F-200D-1F9D1-1F3FE',
    sheet: [27, 32],
    hidden: ['facebook']
  }],
  shortName: 'couple_with_heart'
}, {
  name: 'Couple with Heart: Woman, Man',
  unified: '1F469-200D-2764-FE0F-200D-1F468',
  keywords: ['couple_with_heart_woman_man', 'love'],
  sheet: [19, 51],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [19, 52],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [19, 53],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [19, 54],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [19, 55],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [19, 56],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [19, 57],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [19, 58],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [19, 59],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [19, 60],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [20, 0],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [20, 1],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [20, 2],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [20, 3],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [20, 4],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [20, 5],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [20, 6],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [20, 7],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [20, 8],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [20, 9],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [20, 10],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [20, 11],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [20, 12],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [20, 13],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [20, 14],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [20, 15],
    hidden: ['facebook']
  }],
  shortName: 'woman-heart-man'
}, {
  name: 'Couple with Heart: Man, Man',
  unified: '1F468-200D-2764-FE0F-200D-1F468',
  keywords: ['couple_with_heart_man_man', 'pair', 'love', 'like', 'affection', 'human', 'dating', 'valentines', 'marriage'],
  sheet: [16, 22],
  skinVariations: [{
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [16, 23],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [16, 24],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [16, 25],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [16, 26],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FB-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [16, 27],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [16, 28],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [16, 29],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [16, 30],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [16, 31],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FC-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [16, 32],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [16, 33],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [16, 34],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [16, 35],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [16, 36],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FD-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [16, 37],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [16, 38],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [16, 39],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [16, 40],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [16, 41],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FE-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [16, 42],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FB',
    sheet: [16, 43],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FC',
    sheet: [16, 44],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FD',
    sheet: [16, 45],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FE',
    sheet: [16, 46],
    hidden: ['facebook']
  }, {
    unified: '1F468-1F3FF-200D-2764-FE0F-200D-1F468-1F3FF',
    sheet: [16, 47],
    hidden: ['facebook']
  }],
  shortName: 'man-heart-man'
}, {
  name: 'Couple with Heart: Woman, Woman',
  unified: '1F469-200D-2764-FE0F-200D-1F469',
  keywords: ['couple_with_heart_woman_woman', 'pair', 'love', 'like', 'affection', 'human', 'dating', 'valentines', 'marriage'],
  sheet: [20, 16],
  skinVariations: [{
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FB',
    sheet: [20, 17],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FC',
    sheet: [20, 18],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FD',
    sheet: [20, 19],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FE',
    sheet: [20, 20],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FB-200D-2764-FE0F-200D-1F469-1F3FF',
    sheet: [20, 21],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FB',
    sheet: [20, 22],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FC',
    sheet: [20, 23],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FD',
    sheet: [20, 24],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FE',
    sheet: [20, 25],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FC-200D-2764-FE0F-200D-1F469-1F3FF',
    sheet: [20, 26],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FB',
    sheet: [20, 27],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FC',
    sheet: [20, 28],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FD',
    sheet: [20, 29],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FE',
    sheet: [20, 30],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FD-200D-2764-FE0F-200D-1F469-1F3FF',
    sheet: [20, 31],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FB',
    sheet: [20, 32],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FC',
    sheet: [20, 33],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FD',
    sheet: [20, 34],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FE',
    sheet: [20, 35],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FE-200D-2764-FE0F-200D-1F469-1F3FF',
    sheet: [20, 36],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FB',
    sheet: [20, 37],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FC',
    sheet: [20, 38],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FD',
    sheet: [20, 39],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FE',
    sheet: [20, 40],
    hidden: ['facebook']
  }, {
    unified: '1F469-1F3FF-200D-2764-FE0F-200D-1F469-1F3FF',
    sheet: [20, 41],
    hidden: ['facebook']
  }],
  shortName: 'woman-heart-woman'
}, {
  name: 'Family',
  unified: '1F46A',
  keywords: ['family', 'home', 'parents', 'child', 'mom', 'dad', 'father', 'mother', 'people', 'human'],
  sheet: [21, 39],
  shortName: 'family',
  obsoletedBy: '1F468-200D-1F469-200D-1F466'
}, {
  name: 'Family: Man, Woman, Boy',
  unified: '1F468-200D-1F469-200D-1F466',
  obsoletes: '1F46A',
  keywords: ['family_man_woman_boy', 'love'],
  sheet: [14, 43],
  shortName: 'man-woman-boy'
}, {
  name: 'Family: Man, Woman, Girl',
  unified: '1F468-200D-1F469-200D-1F467',
  keywords: ['family_man_woman_girl', 'home', 'parents', 'people', 'human', 'child'],
  sheet: [14, 45],
  shortName: 'man-woman-girl'
}, {
  name: 'Family: Man, Woman, Girl, Boy',
  unified: '1F468-200D-1F469-200D-1F467-200D-1F466',
  keywords: ['family_man_woman_girl_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 46],
  shortName: 'man-woman-girl-boy'
}, {
  name: 'Family: Man, Woman, Boy, Boy',
  unified: '1F468-200D-1F469-200D-1F466-200D-1F466',
  keywords: ['family_man_woman_boy_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 44],
  shortName: 'man-woman-boy-boy'
}, {
  name: 'Family: Man, Woman, Girl, Girl',
  unified: '1F468-200D-1F469-200D-1F467-200D-1F467',
  keywords: ['family_man_woman_girl_girl', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 47],
  shortName: 'man-woman-girl-girl'
}, {
  name: 'Family: Man, Man, Boy',
  unified: '1F468-200D-1F468-200D-1F466',
  keywords: ['family_man_man_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 38],
  shortName: 'man-man-boy'
}, {
  name: 'Family: Man, Man, Girl',
  unified: '1F468-200D-1F468-200D-1F467',
  keywords: ['family_man_man_girl', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 40],
  shortName: 'man-man-girl'
}, {
  name: 'Family: Man, Man, Girl, Boy',
  unified: '1F468-200D-1F468-200D-1F467-200D-1F466',
  keywords: ['family_man_man_girl_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 41],
  shortName: 'man-man-girl-boy'
}, {
  name: 'Family: Man, Man, Boy, Boy',
  unified: '1F468-200D-1F468-200D-1F466-200D-1F466',
  keywords: ['family_man_man_boy_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 39],
  shortName: 'man-man-boy-boy'
}, {
  name: 'Family: Man, Man, Girl, Girl',
  unified: '1F468-200D-1F468-200D-1F467-200D-1F467',
  keywords: ['family_man_man_girl_girl', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [14, 42],
  shortName: 'man-man-girl-girl'
}, {
  name: 'Family: Woman, Woman, Boy',
  unified: '1F469-200D-1F469-200D-1F466',
  keywords: ['family_woman_woman_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [18, 11],
  shortName: 'woman-woman-boy'
}, {
  name: 'Family: Woman, Woman, Girl',
  unified: '1F469-200D-1F469-200D-1F467',
  keywords: ['family_woman_woman_girl', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [18, 13],
  shortName: 'woman-woman-girl'
}, {
  name: 'Family: Woman, Woman, Girl, Boy',
  unified: '1F469-200D-1F469-200D-1F467-200D-1F466',
  keywords: ['family_woman_woman_girl_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [18, 14],
  shortName: 'woman-woman-girl-boy'
}, {
  name: 'Family: Woman, Woman, Boy, Boy',
  unified: '1F469-200D-1F469-200D-1F466-200D-1F466',
  keywords: ['family_woman_woman_boy_boy', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [18, 12],
  shortName: 'woman-woman-boy-boy'
}, {
  name: 'Family: Woman, Woman, Girl, Girl',
  unified: '1F469-200D-1F469-200D-1F467-200D-1F467',
  keywords: ['family_woman_woman_girl_girl', 'home', 'parents', 'people', 'human', 'children'],
  sheet: [18, 15],
  shortName: 'woman-woman-girl-girl'
}, {
  name: 'Family: Man, Boy',
  unified: '1F468-200D-1F466',
  keywords: ['family_man_boy', 'home', 'parent', 'people', 'human', 'child'],
  sheet: [14, 34],
  shortName: 'man-boy'
}, {
  name: 'Family: Man, Boy, Boy',
  unified: '1F468-200D-1F466-200D-1F466',
  keywords: ['family_man_boy_boy', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [14, 33],
  shortName: 'man-boy-boy'
}, {
  name: 'Family: Man, Girl',
  unified: '1F468-200D-1F467',
  keywords: ['family_man_girl', 'home', 'parent', 'people', 'human', 'child'],
  sheet: [14, 37],
  shortName: 'man-girl'
}, {
  name: 'Family: Man, Girl, Boy',
  unified: '1F468-200D-1F467-200D-1F466',
  keywords: ['family_man_girl_boy', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [14, 35],
  shortName: 'man-girl-boy'
}, {
  name: 'Family: Man, Girl, Girl',
  unified: '1F468-200D-1F467-200D-1F467',
  keywords: ['family_man_girl_girl', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [14, 36],
  shortName: 'man-girl-girl'
}, {
  name: 'Family: Woman, Boy',
  unified: '1F469-200D-1F466',
  keywords: ['family_woman_boy', 'home', 'parent', 'people', 'human', 'child'],
  sheet: [18, 7],
  shortName: 'woman-boy'
}, {
  name: 'Family: Woman, Boy, Boy',
  unified: '1F469-200D-1F466-200D-1F466',
  keywords: ['family_woman_boy_boy', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [18, 6],
  shortName: 'woman-boy-boy'
}, {
  name: 'Family: Woman, Girl',
  unified: '1F469-200D-1F467',
  keywords: ['family_woman_girl', 'home', 'parent', 'people', 'human', 'child'],
  sheet: [18, 10],
  shortName: 'woman-girl'
}, {
  name: 'Family: Woman, Girl, Boy',
  unified: '1F469-200D-1F467-200D-1F466',
  keywords: ['family_woman_girl_boy', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [18, 8],
  shortName: 'woman-girl-boy'
}, {
  name: 'Family: Woman, Girl, Girl',
  unified: '1F469-200D-1F467-200D-1F467',
  keywords: ['family_woman_girl_girl', 'home', 'parent', 'people', 'human', 'children'],
  sheet: [18, 9],
  shortName: 'woman-girl-girl'
}, {
  name: 'Speaking Head',
  unified: '1F5E3-FE0F',
  keywords: ['speaking_head', 'user', 'person', 'human', 'sing', 'say', 'talk'],
  sheet: [32, 10],
  shortName: 'speaking_head_in_silhouette'
}, {
  name: 'Bust in Silhouette',
  unified: '1F464',
  keywords: ['bust_in_silhouette', 'user', 'person', 'human'],
  sheet: [13, 32],
  shortName: 'bust_in_silhouette'
}, {
  name: 'Busts in Silhouette',
  unified: '1F465',
  keywords: ['busts_in_silhouette', 'user', 'person', 'human', 'group', 'team'],
  sheet: [13, 33],
  shortName: 'busts_in_silhouette'
}, {
  name: 'People Hugging',
  unified: '1FAC2',
  keywords: ['people hugging', 'care'],
  sheet: [54, 44],
  shortName: 'people_hugging'
}, {
  name: 'Footprints',
  unified: '1F463',
  keywords: ['footprints', 'feet', 'tracking', 'walking', 'beach'],
  sheet: [13, 31],
  shortName: 'footprints'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-1-2',
  unified: '1F3FB',
  sheet: [10, 41],
  shortName: 'skin-tone-2'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-3',
  unified: '1F3FC',
  sheet: [10, 42],
  shortName: 'skin-tone-3'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-4',
  unified: '1F3FD',
  sheet: [10, 43],
  shortName: 'skin-tone-4'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-5',
  unified: '1F3FE',
  sheet: [10, 44],
  shortName: 'skin-tone-5'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-6',
  unified: '1F3FF',
  sheet: [10, 45],
  shortName: 'skin-tone-6'
}, {
  name: 'Monkey Face',
  unified: '1F435',
  emoticons: [':o)'],
  keywords: ['monkey_face', 'animal', 'nature', 'circus'],
  sheet: [11, 40],
  shortName: 'monkey_face'
}, {
  name: 'Monkey',
  unified: '1F412',
  keywords: ['monkey', 'animal', 'nature', 'banana', 'circus'],
  sheet: [11, 4],
  shortName: 'monkey'
}, {
  name: 'Gorilla',
  unified: '1F98D',
  keywords: ['gorilla', 'animal', 'nature', 'circus'],
  sheet: [44, 31],
  shortName: 'gorilla'
}, {
  name: 'Orangutan',
  unified: '1F9A7',
  keywords: ['orangutan', 'animal'],
  sheet: [44, 57],
  shortName: 'orangutan'
}, {
  name: 'Dog Face',
  unified: '1F436',
  keywords: ['dog_face', 'animal', 'friend', 'nature', 'woof', 'puppy', 'pet', 'faithful'],
  sheet: [11, 41],
  shortName: 'dog'
}, {
  name: 'Dog',
  unified: '1F415',
  keywords: ['dog', 'animal', 'nature', 'friend', 'doge', 'pet', 'faithful'],
  sheet: [11, 8],
  shortName: 'dog2'
}, {
  name: 'Guide Dog',
  unified: '1F9AE',
  keywords: ['guide_dog', 'animal', 'blind'],
  sheet: [45, 3],
  shortName: 'guide_dog'
}, {
  name: 'Service Dog',
  unified: '1F415-200D-1F9BA',
  keywords: ['service_dog', 'blind', 'animal'],
  sheet: [11, 7],
  shortName: 'service_dog'
}, {
  name: 'Poodle',
  unified: '1F429',
  keywords: ['poodle', 'dog', 'animal', '101', 'nature', 'pet'],
  sheet: [11, 28],
  shortName: 'poodle'
}, {
  name: 'Wolf Face',
  unified: '1F43A',
  keywords: ['wolf', 'animal', 'nature', 'wild'],
  sheet: [11, 45],
  shortName: 'wolf'
}, {
  name: 'Fox Face',
  unified: '1F98A',
  keywords: ['fox', 'animal', 'nature', 'face'],
  sheet: [44, 28],
  shortName: 'fox_face'
}, {
  name: 'Raccoon',
  unified: '1F99D',
  keywords: ['raccoon', 'animal', 'nature'],
  sheet: [44, 47],
  shortName: 'raccoon'
}, {
  name: 'Cat Face',
  unified: '1F431',
  keywords: ['cat_face', 'animal', 'meow', 'nature', 'pet', 'kitten'],
  sheet: [11, 36],
  shortName: 'cat'
}, {
  name: 'Cat',
  unified: '1F408',
  keywords: ['cat', 'animal', 'meow', 'pet', 'cats'],
  sheet: [10, 55],
  shortName: 'cat2'
}, {
  name: 'Black Cat',
  unified: '1F408-200D-2B1B',
  keywords: ['black cat', 'superstition', 'luck'],
  sheet: [10, 54],
  shortName: 'black_cat'
}, {
  name: 'Lion Face',
  unified: '1F981',
  keywords: ['lion', 'animal', 'nature'],
  sheet: [44, 19],
  shortName: 'lion_face'
}, {
  name: 'Tiger Face',
  unified: '1F42F',
  keywords: ['tiger_face', 'animal', 'cat', 'danger', 'wild', 'nature', 'roar'],
  sheet: [11, 34],
  shortName: 'tiger'
}, {
  name: 'Tiger',
  unified: '1F405',
  keywords: ['tiger', 'animal', 'nature', 'roar'],
  sheet: [10, 51],
  shortName: 'tiger2'
}, {
  name: 'Leopard',
  unified: '1F406',
  keywords: ['leopard', 'animal', 'nature'],
  sheet: [10, 52],
  shortName: 'leopard'
}, {
  name: 'Horse Face',
  unified: '1F434',
  keywords: ['horse_face', 'animal', 'brown', 'nature'],
  sheet: [11, 39],
  shortName: 'horse'
}, {
  name: 'Horse',
  unified: '1F40E',
  keywords: ['horse', 'animal', 'gamble', 'luck'],
  sheet: [11, 0],
  shortName: 'racehorse'
}, {
  name: 'Unicorn Face',
  unified: '1F984',
  keywords: ['unicorn', 'animal', 'nature', 'mystical'],
  sheet: [44, 22],
  shortName: 'unicorn_face'
}, {
  name: 'Zebra Face',
  unified: '1F993',
  keywords: ['zebra', 'animal', 'nature', 'stripes', 'safari'],
  sheet: [44, 37],
  shortName: 'zebra_face'
}, {
  name: 'Deer',
  unified: '1F98C',
  keywords: ['deer', 'animal', 'nature', 'horns', 'venison'],
  sheet: [44, 30],
  shortName: 'deer'
}, {
  name: 'Bison',
  unified: '1F9AC',
  keywords: ['bison', 'ox'],
  sheet: [45, 1],
  shortName: 'bison'
}, {
  name: 'Cow Face',
  unified: '1F42E',
  keywords: ['cow_face', 'beef', 'ox', 'animal', 'nature', 'moo', 'milk'],
  sheet: [11, 33],
  shortName: 'cow'
}, {
  name: 'Ox',
  unified: '1F402',
  keywords: ['ox', 'animal', 'cow', 'beef'],
  sheet: [10, 48],
  shortName: 'ox'
}, {
  name: 'Water Buffalo',
  unified: '1F403',
  keywords: ['water_buffalo', 'animal', 'nature', 'ox', 'cow'],
  sheet: [10, 49],
  shortName: 'water_buffalo'
}, {
  name: 'Cow',
  unified: '1F404',
  keywords: ['cow', 'beef', 'ox', 'animal', 'nature', 'moo', 'milk'],
  sheet: [10, 50],
  shortName: 'cow2'
}, {
  name: 'Pig Face',
  unified: '1F437',
  keywords: ['pig_face', 'animal', 'oink', 'nature'],
  sheet: [11, 42],
  shortName: 'pig'
}, {
  name: 'Pig',
  unified: '1F416',
  keywords: ['pig', 'animal', 'nature'],
  sheet: [11, 9],
  shortName: 'pig2'
}, {
  name: 'Boar',
  unified: '1F417',
  keywords: ['boar', 'animal', 'nature'],
  sheet: [11, 10],
  shortName: 'boar'
}, {
  name: 'Pig Nose',
  unified: '1F43D',
  keywords: ['pig_nose', 'animal', 'oink'],
  sheet: [11, 49],
  shortName: 'pig_nose'
}, {
  name: 'Ram',
  unified: '1F40F',
  keywords: ['ram', 'animal', 'sheep', 'nature'],
  sheet: [11, 1],
  shortName: 'ram'
}, {
  name: 'Sheep',
  unified: '1F411',
  keywords: ['ewe', 'animal', 'nature', 'wool', 'shipit'],
  sheet: [11, 3],
  shortName: 'sheep'
}, {
  name: 'Goat',
  unified: '1F410',
  keywords: ['goat', 'animal', 'nature'],
  sheet: [11, 2],
  shortName: 'goat'
}, {
  name: 'Dromedary Camel',
  unified: '1F42A',
  keywords: ['camel', 'animal', 'hot', 'desert', 'hump'],
  sheet: [11, 29],
  shortName: 'dromedary_camel'
}, {
  name: 'Bactrian Camel',
  unified: '1F42B',
  keywords: ['two_hump_camel', 'animal', 'nature', 'hot', 'desert', 'hump'],
  sheet: [11, 30],
  shortName: 'camel'
}, {
  name: 'Llama',
  unified: '1F999',
  keywords: ['llama', 'animal', 'nature', 'alpaca'],
  sheet: [44, 43],
  shortName: 'llama'
}, {
  name: 'Giraffe Face',
  unified: '1F992',
  keywords: ['giraffe', 'animal', 'nature', 'spots', 'safari'],
  sheet: [44, 36],
  shortName: 'giraffe_face'
}, {
  name: 'Elephant',
  unified: '1F418',
  keywords: ['elephant', 'animal', 'nature', 'nose', 'th', 'circus'],
  sheet: [11, 11],
  shortName: 'elephant'
}, {
  name: 'Mammoth',
  unified: '1F9A3',
  keywords: ['mammoth', 'elephant', 'tusks'],
  sheet: [44, 53],
  shortName: 'mammoth'
}, {
  name: 'Rhinoceros',
  unified: '1F98F',
  keywords: ['rhinoceros', 'animal', 'nature', 'horn'],
  sheet: [44, 33],
  shortName: 'rhinoceros'
}, {
  name: 'Hippopotamus',
  unified: '1F99B',
  keywords: ['hippopotamus', 'animal', 'nature'],
  sheet: [44, 45],
  shortName: 'hippopotamus'
}, {
  name: 'Mouse Face',
  unified: '1F42D',
  keywords: ['mouse_face', 'animal', 'nature', 'cheese_wedge', 'rodent'],
  sheet: [11, 32],
  shortName: 'mouse'
}, {
  name: 'Mouse',
  unified: '1F401',
  keywords: ['mouse', 'animal', 'nature', 'rodent'],
  sheet: [10, 47],
  shortName: 'mouse2'
}, {
  name: 'Rat',
  unified: '1F400',
  keywords: ['rat', 'animal', 'mouse', 'rodent'],
  sheet: [10, 46],
  shortName: 'rat'
}, {
  name: 'Hamster Face',
  unified: '1F439',
  keywords: ['hamster', 'animal', 'nature'],
  sheet: [11, 44],
  shortName: 'hamster'
}, {
  name: 'Rabbit Face',
  unified: '1F430',
  keywords: ['rabbit_face', 'animal', 'nature', 'pet', 'spring', 'magic', 'bunny'],
  sheet: [11, 35],
  shortName: 'rabbit'
}, {
  name: 'Rabbit',
  unified: '1F407',
  keywords: ['rabbit', 'animal', 'nature', 'pet', 'magic', 'spring'],
  sheet: [10, 53],
  shortName: 'rabbit2'
}, {
  name: 'Chipmunk',
  unified: '1F43F-FE0F',
  keywords: ['chipmunk', 'animal', 'nature', 'rodent', 'squirrel'],
  sheet: [11, 51],
  shortName: 'chipmunk'
}, {
  name: 'Beaver',
  unified: '1F9AB',
  keywords: ['beaver', 'animal', 'rodent'],
  sheet: [45, 0],
  shortName: 'beaver'
}, {
  name: 'Hedgehog',
  unified: '1F994',
  keywords: ['hedgehog', 'animal', 'nature', 'spiny'],
  sheet: [44, 38],
  shortName: 'hedgehog'
}, {
  name: 'Bat',
  unified: '1F987',
  keywords: ['bat', 'animal', 'nature', 'blind', 'vampire'],
  sheet: [44, 25],
  shortName: 'bat'
}, {
  name: 'Bear Face',
  unified: '1F43B',
  keywords: ['bear', 'animal', 'nature', 'wild'],
  sheet: [11, 47],
  shortName: 'bear'
}, {
  name: 'Polar Bear',
  unified: '1F43B-200D-2744-FE0F',
  keywords: ['polar bear', 'animal', 'arctic'],
  sheet: [11, 46],
  shortName: 'polar_bear'
}, {
  name: 'Koala',
  unified: '1F428',
  keywords: ['koala', 'animal', 'nature'],
  sheet: [11, 27],
  shortName: 'koala'
}, {
  name: 'Panda Face',
  unified: '1F43C',
  keywords: ['panda', 'animal', 'nature', 'panda'],
  sheet: [11, 48],
  shortName: 'panda_face'
}, {
  name: 'Sloth',
  unified: '1F9A5',
  keywords: ['sloth', 'animal'],
  sheet: [44, 55],
  shortName: 'sloth'
}, {
  name: 'Otter',
  unified: '1F9A6',
  keywords: ['otter', 'animal'],
  sheet: [44, 56],
  shortName: 'otter'
}, {
  name: 'Skunk',
  unified: '1F9A8',
  keywords: ['skunk', 'animal'],
  sheet: [44, 58],
  shortName: 'skunk'
}, {
  name: 'Kangaroo',
  unified: '1F998',
  keywords: ['kangaroo', 'animal', 'nature', 'australia', 'joey', 'hop', 'marsupial'],
  sheet: [44, 42],
  shortName: 'kangaroo'
}, {
  name: 'Badger',
  unified: '1F9A1',
  keywords: ['badger', 'animal', 'nature', 'honey'],
  sheet: [44, 51],
  shortName: 'badger'
}, {
  name: 'Paw Prints',
  unified: '1F43E',
  keywords: ['paw_prints', 'animal', 'tracking', 'footprints', 'dog', 'cat', 'pet', 'feet'],
  sheet: [11, 50],
  shortNames: ['paw_prints'],
  shortName: 'feet'
}, {
  name: 'Turkey',
  unified: '1F983',
  keywords: ['turkey', 'animal', 'bird'],
  sheet: [44, 21],
  shortName: 'turkey'
}, {
  name: 'Chicken',
  unified: '1F414',
  keywords: ['chicken', 'animal', 'cluck', 'nature', 'bird'],
  sheet: [11, 6],
  shortName: 'chicken'
}, {
  name: 'Rooster',
  unified: '1F413',
  keywords: ['rooster', 'animal', 'nature', 'chicken'],
  sheet: [11, 5],
  shortName: 'rooster'
}, {
  name: 'Hatching Chick',
  unified: '1F423',
  keywords: ['hatching_chick', 'animal', 'chicken', 'egg', 'born', 'baby', 'bird'],
  sheet: [11, 22],
  shortName: 'hatching_chick'
}, {
  name: 'Baby Chick',
  unified: '1F424',
  keywords: ['baby_chick', 'animal', 'chicken', 'bird'],
  sheet: [11, 23],
  shortName: 'baby_chick'
}, {
  name: 'Front-Facing Baby Chick',
  unified: '1F425',
  keywords: ['front_facing_baby_chick', 'animal', 'chicken', 'baby', 'bird'],
  sheet: [11, 24],
  shortName: 'hatched_chick'
}, {
  name: 'Bird',
  unified: '1F426',
  keywords: ['bird', 'animal', 'nature', 'fly', 'tweet', 'spring'],
  sheet: [11, 25],
  shortName: 'bird'
}, {
  name: 'Penguin',
  unified: '1F427',
  keywords: ['penguin', 'animal', 'nature'],
  sheet: [11, 26],
  shortName: 'penguin'
}, {
  name: 'Dove',
  unified: '1F54A-FE0F',
  keywords: ['dove', 'animal', 'bird'],
  sheet: [30, 27],
  shortName: 'dove_of_peace'
}, {
  name: 'Eagle',
  unified: '1F985',
  keywords: ['eagle', 'animal', 'nature', 'bird'],
  sheet: [44, 23],
  shortName: 'eagle'
}, {
  name: 'Duck',
  unified: '1F986',
  keywords: ['duck', 'animal', 'nature', 'bird', 'mallard'],
  sheet: [44, 24],
  shortName: 'duck'
}, {
  name: 'Swan',
  unified: '1F9A2',
  keywords: ['swan', 'animal', 'nature', 'bird'],
  sheet: [44, 52],
  shortName: 'swan'
}, {
  name: 'Owl',
  unified: '1F989',
  keywords: ['owl', 'animal', 'nature', 'bird', 'hoot'],
  sheet: [44, 27],
  shortName: 'owl'
}, {
  name: 'Dodo',
  unified: '1F9A4',
  keywords: ['dodo', 'animal', 'bird'],
  sheet: [44, 54],
  shortName: 'dodo'
}, {
  name: 'Feather',
  unified: '1FAB6',
  keywords: ['feather', 'bird', 'fly'],
  sheet: [54, 37],
  shortName: 'feather'
}, {
  name: 'Flamingo',
  unified: '1F9A9',
  keywords: ['flamingo', 'animal'],
  sheet: [44, 59],
  shortName: 'flamingo'
}, {
  name: 'Peacock',
  unified: '1F99A',
  keywords: ['peacock', 'animal', 'nature', 'peahen', 'bird'],
  sheet: [44, 44],
  shortName: 'peacock'
}, {
  name: 'Parrot',
  unified: '1F99C',
  keywords: ['parrot', 'animal', 'nature', 'bird', 'pirate', 'talk'],
  sheet: [44, 46],
  shortName: 'parrot'
}, {
  name: 'Frog Face',
  unified: '1F438',
  keywords: ['frog', 'animal', 'nature', 'croak', 'toad'],
  sheet: [11, 43],
  shortName: 'frog'
}, {
  name: 'Crocodile',
  unified: '1F40A',
  keywords: ['crocodile', 'animal', 'nature', 'reptile', 'lizard', 'alligator'],
  sheet: [10, 57],
  shortName: 'crocodile'
}, {
  name: 'Turtle',
  unified: '1F422',
  keywords: ['turtle', 'animal', 'slow', 'nature', 'tortoise'],
  sheet: [11, 21],
  shortName: 'turtle'
}, {
  name: 'Lizard',
  unified: '1F98E',
  keywords: ['lizard', 'animal', 'nature', 'reptile'],
  sheet: [44, 32],
  shortName: 'lizard'
}, {
  name: 'Snake',
  unified: '1F40D',
  keywords: ['snake', 'animal', 'evil', 'nature', 'hiss', 'python'],
  sheet: [10, 60],
  shortName: 'snake'
}, {
  name: 'Dragon Face',
  unified: '1F432',
  keywords: ['dragon_face', 'animal', 'myth', 'nature', 'chinese', 'green'],
  sheet: [11, 37],
  shortName: 'dragon_face'
}, {
  name: 'Dragon',
  unified: '1F409',
  keywords: ['dragon', 'animal', 'myth', 'nature', 'chinese', 'green'],
  sheet: [10, 56],
  shortName: 'dragon'
}, {
  name: 'Sauropod',
  unified: '1F995',
  keywords: ['sauropod', 'animal', 'nature', 'dinosaur', 'brachiosaurus', 'brontosaurus', 'diplodocus', 'extinct'],
  sheet: [44, 39],
  shortName: 'sauropod'
}, {
  name: 'T-Rex',
  unified: '1F996',
  keywords: ['t_rex', 'animal', 'nature', 'dinosaur', 'tyrannosaurus', 'extinct'],
  sheet: [44, 40],
  shortName: 't-rex'
}, {
  name: 'Spouting Whale',
  unified: '1F433',
  keywords: ['spouting_whale', 'animal', 'nature', 'sea', 'ocean'],
  sheet: [11, 38],
  shortName: 'whale'
}, {
  name: 'Whale',
  unified: '1F40B',
  keywords: ['whale', 'animal', 'nature', 'sea', 'ocean'],
  sheet: [10, 58],
  shortName: 'whale2'
}, {
  name: 'Dolphin',
  unified: '1F42C',
  keywords: ['dolphin', 'animal', 'nature', 'fish', 'sea', 'ocean', 'flipper', 'fins', 'beach'],
  sheet: [11, 31],
  shortNames: ['flipper'],
  shortName: 'dolphin'
}, {
  name: 'Seal',
  unified: '1F9AD',
  keywords: ['seal', 'animal', 'creature', 'sea'],
  sheet: [45, 2],
  shortName: 'seal'
}, {
  name: 'Fish',
  unified: '1F41F',
  keywords: ['fish', 'animal', 'food', 'nature'],
  sheet: [11, 18],
  shortName: 'fish'
}, {
  name: 'Tropical Fish',
  unified: '1F420',
  keywords: ['tropical_fish', 'animal', 'swim', 'ocean', 'beach', 'nemo'],
  sheet: [11, 19],
  shortName: 'tropical_fish'
}, {
  name: 'Blowfish',
  unified: '1F421',
  keywords: ['blowfish', 'animal', 'nature', 'food', 'sea', 'ocean'],
  sheet: [11, 20],
  shortName: 'blowfish'
}, {
  name: 'Shark',
  unified: '1F988',
  keywords: ['shark', 'animal', 'nature', 'fish', 'sea', 'ocean', 'jaws', 'fins', 'beach'],
  sheet: [44, 26],
  shortName: 'shark'
}, {
  name: 'Octopus',
  unified: '1F419',
  keywords: ['octopus', 'animal', 'creature', 'ocean', 'sea', 'nature', 'beach'],
  sheet: [11, 12],
  shortName: 'octopus'
}, {
  name: 'Spiral Shell',
  unified: '1F41A',
  keywords: ['spiral_shell', 'nature', 'sea', 'beach'],
  sheet: [11, 13],
  shortName: 'shell'
}, {
  name: 'Coral',
  unified: '1FAB8',
  keywords: ['coral', 'ocean', 'sea', 'reef'],
  sheet: [54, 39],
  hidden: ['facebook'],
  shortName: 'coral'
}, {
  name: 'Snail',
  unified: '1F40C',
  keywords: ['snail', 'slow', 'animal', 'shell'],
  sheet: [10, 59],
  shortName: 'snail'
}, {
  name: 'Butterfly',
  unified: '1F98B',
  keywords: ['butterfly', 'animal', 'insect', 'nature', 'caterpillar'],
  sheet: [44, 29],
  shortName: 'butterfly'
}, {
  name: 'Bug',
  unified: '1F41B',
  keywords: ['bug', 'animal', 'insect', 'nature', 'worm'],
  sheet: [11, 14],
  shortName: 'bug'
}, {
  name: 'Ant',
  unified: '1F41C',
  keywords: ['ant', 'animal', 'insect', 'nature', 'bug'],
  sheet: [11, 15],
  shortName: 'ant'
}, {
  name: 'Honeybee',
  unified: '1F41D',
  keywords: ['honeybee', 'animal', 'insect', 'nature', 'bug', 'spring', 'honey'],
  sheet: [11, 16],
  shortNames: ['honeybee'],
  shortName: 'bee'
}, {
  name: 'Beetle',
  unified: '1FAB2',
  keywords: ['beetle', 'insect'],
  sheet: [54, 33],
  shortName: 'beetle'
}, {
  name: 'Lady Beetle',
  unified: '1F41E',
  keywords: ['lady_beetle', 'animal', 'insect', 'nature', 'ladybug'],
  sheet: [11, 17],
  shortNames: ['lady_beetle'],
  shortName: 'ladybug'
}, {
  name: 'Cricket',
  unified: '1F997',
  keywords: ['cricket', 'animal', 'cricket', 'chirp'],
  sheet: [44, 41],
  shortName: 'cricket'
}, {
  name: 'Cockroach',
  unified: '1FAB3',
  keywords: ['cockroach', 'insect', 'pests'],
  sheet: [54, 34],
  shortName: 'cockroach'
}, {
  name: 'Spider',
  unified: '1F577-FE0F',
  keywords: ['spider', 'animal', 'arachnid'],
  sheet: [31, 23],
  shortName: 'spider'
}, {
  name: 'Spider Web',
  unified: '1F578-FE0F',
  keywords: ['spider_web', 'animal', 'insect', 'arachnid', 'silk'],
  sheet: [31, 24],
  shortName: 'spider_web'
}, {
  name: 'Scorpion',
  unified: '1F982',
  keywords: ['scorpion', 'animal', 'arachnid'],
  sheet: [44, 20],
  shortName: 'scorpion'
}, {
  name: 'Mosquito',
  unified: '1F99F',
  keywords: ['mosquito', 'animal', 'nature', 'insect', 'malaria'],
  sheet: [44, 49],
  shortName: 'mosquito'
}, {
  name: 'Fly',
  unified: '1FAB0',
  keywords: ['fly', 'insect'],
  sheet: [54, 31],
  shortName: 'fly'
}, {
  name: 'Worm',
  unified: '1FAB1',
  keywords: ['worm', 'animal'],
  sheet: [54, 32],
  shortName: 'worm'
}, {
  name: 'Microbe',
  unified: '1F9A0',
  keywords: ['microbe', 'amoeba', 'bacteria', 'germs', 'virus', 'covid'],
  sheet: [44, 50],
  shortName: 'microbe'
}, {
  name: 'Bouquet',
  unified: '1F490',
  keywords: ['bouquet', 'flowers', 'nature', 'spring'],
  sheet: [27, 6],
  shortName: 'bouquet'
}, {
  name: 'Cherry Blossom',
  unified: '1F338',
  keywords: ['cherry_blossom', 'nature', 'plant', 'spring', 'flower'],
  sheet: [5, 53],
  shortName: 'cherry_blossom'
}, {
  name: 'White Flower',
  unified: '1F4AE',
  keywords: ['white_flower', 'japanese', 'spring'],
  sheet: [28, 5],
  shortName: 'white_flower'
}, {
  name: 'Lotus',
  unified: '1FAB7',
  keywords: ['lotus', 'flower', 'calm', 'meditation'],
  sheet: [54, 38],
  hidden: ['facebook'],
  shortName: 'lotus'
}, {
  name: 'Rosette',
  unified: '1F3F5-FE0F',
  keywords: ['rosette', 'flower', 'decoration', 'military'],
  sheet: [10, 36],
  shortName: 'rosette'
}, {
  name: 'Rose',
  unified: '1F339',
  keywords: ['rose', 'flowers', 'valentines', 'love', 'spring'],
  sheet: [5, 54],
  shortName: 'rose'
}, {
  name: 'Wilted Flower',
  unified: '1F940',
  keywords: ['wilted_flower', 'plant', 'nature', 'flower', 'rose'],
  sheet: [43, 11],
  shortName: 'wilted_flower'
}, {
  name: 'Hibiscus',
  unified: '1F33A',
  keywords: ['hibiscus', 'plant', 'vegetable', 'flowers', 'beach'],
  sheet: [5, 55],
  shortName: 'hibiscus'
}, {
  name: 'Sunflower',
  unified: '1F33B',
  keywords: ['sunflower', 'nature', 'plant', 'fall'],
  sheet: [5, 56],
  shortName: 'sunflower'
}, {
  name: 'Blossom',
  unified: '1F33C',
  keywords: ['blossom', 'nature', 'flowers', 'yellow'],
  sheet: [5, 57],
  shortName: 'blossom'
}, {
  name: 'Tulip',
  unified: '1F337',
  keywords: ['tulip', 'flowers', 'plant', 'nature', 'summer', 'spring'],
  sheet: [5, 52],
  shortName: 'tulip'
}, {
  name: 'Seedling',
  unified: '1F331',
  keywords: ['seedling', 'plant', 'nature', 'grass', 'lawn', 'spring'],
  sheet: [5, 46],
  shortName: 'seedling'
}, {
  name: 'Potted Plant',
  unified: '1FAB4',
  keywords: ['potted plant', 'greenery', 'house'],
  sheet: [54, 35],
  shortName: 'potted_plant'
}, {
  name: 'Evergreen Tree',
  unified: '1F332',
  keywords: ['evergreen_tree', 'plant', 'nature'],
  sheet: [5, 47],
  shortName: 'evergreen_tree'
}, {
  name: 'Deciduous Tree',
  unified: '1F333',
  keywords: ['deciduous_tree', 'plant', 'nature'],
  sheet: [5, 48],
  shortName: 'deciduous_tree'
}, {
  name: 'Palm Tree',
  unified: '1F334',
  keywords: ['palm_tree', 'plant', 'vegetable', 'nature', 'summer', 'beach', 'mojito', 'tropical'],
  sheet: [5, 49],
  shortName: 'palm_tree'
}, {
  name: 'Cactus',
  unified: '1F335',
  keywords: ['cactus', 'vegetable', 'plant', 'nature'],
  sheet: [5, 50],
  shortName: 'cactus'
}, {
  name: 'Ear of Rice',
  unified: '1F33E',
  keywords: ['sheaf_of_rice', 'nature', 'plant'],
  sheet: [5, 59],
  shortName: 'ear_of_rice'
}, {
  name: 'Herb',
  unified: '1F33F',
  keywords: ['herb', 'vegetable', 'plant', 'medicine', 'weed', 'grass', 'lawn'],
  sheet: [5, 60],
  shortName: 'herb'
}, {
  name: 'Shamrock',
  unified: '2618-FE0F',
  keywords: ['shamrock', 'vegetable', 'plant', 'nature', 'irish', 'clover'],
  sheet: [56, 49],
  shortName: 'shamrock'
}, {
  name: 'Four Leaf Clover',
  unified: '1F340',
  keywords: ['four_leaf_clover', 'vegetable', 'plant', 'nature', 'lucky', 'irish'],
  sheet: [6, 0],
  shortName: 'four_leaf_clover'
}, {
  name: 'Maple Leaf',
  unified: '1F341',
  keywords: ['maple_leaf', 'nature', 'plant', 'vegetable', 'ca', 'fall'],
  sheet: [6, 1],
  shortName: 'maple_leaf'
}, {
  name: 'Fallen Leaf',
  unified: '1F342',
  keywords: ['fallen_leaf', 'nature', 'plant', 'vegetable', 'leaves'],
  sheet: [6, 2],
  shortName: 'fallen_leaf'
}, {
  name: 'Leaf Fluttering in Wind',
  unified: '1F343',
  keywords: ['leaf_fluttering_in_wind', 'nature', 'plant', 'tree', 'vegetable', 'grass', 'lawn', 'spring'],
  sheet: [6, 3],
  shortName: 'leaves'
}, {
  name: 'Empty Nest',
  unified: '1FAB9',
  keywords: ['empty nest', 'bird'],
  sheet: [54, 40],
  hidden: ['facebook'],
  shortName: 'empty_nest'
}, {
  name: 'Nest with Eggs',
  unified: '1FABA',
  keywords: ['nest with eggs', 'bird'],
  sheet: [54, 41],
  hidden: ['facebook'],
  shortName: 'nest_with_eggs'
}, {
  name: 'Grapes',
  unified: '1F347',
  keywords: ['grapes', 'fruit', 'food', 'wine'],
  sheet: [6, 7],
  shortName: 'grapes'
}, {
  name: 'Melon',
  unified: '1F348',
  keywords: ['melon', 'fruit', 'nature', 'food'],
  sheet: [6, 8],
  shortName: 'melon'
}, {
  name: 'Watermelon',
  unified: '1F349',
  keywords: ['watermelon', 'fruit', 'food', 'picnic', 'summer'],
  sheet: [6, 9],
  shortName: 'watermelon'
}, {
  name: 'Tangerine',
  unified: '1F34A',
  keywords: ['tangerine', 'food', 'fruit', 'nature', 'orange'],
  sheet: [6, 10],
  shortName: 'tangerine'
}, {
  name: 'Lemon',
  unified: '1F34B',
  keywords: ['lemon', 'fruit', 'nature'],
  sheet: [6, 11],
  shortName: 'lemon'
}, {
  name: 'Banana',
  unified: '1F34C',
  keywords: ['banana', 'fruit', 'food', 'monkey'],
  sheet: [6, 12],
  shortName: 'banana'
}, {
  name: 'Pineapple',
  unified: '1F34D',
  keywords: ['pineapple', 'fruit', 'nature', 'food'],
  sheet: [6, 13],
  shortName: 'pineapple'
}, {
  name: 'Mango',
  unified: '1F96D',
  keywords: ['mango', 'fruit', 'food', 'tropical'],
  sheet: [43, 55],
  shortName: 'mango'
}, {
  name: 'Red Apple',
  unified: '1F34E',
  keywords: ['red_apple', 'fruit', 'mac', 'school'],
  sheet: [6, 14],
  shortName: 'apple'
}, {
  name: 'Green Apple',
  unified: '1F34F',
  keywords: ['green_apple', 'fruit', 'nature'],
  sheet: [6, 15],
  shortName: 'green_apple'
}, {
  name: 'Pear',
  unified: '1F350',
  keywords: ['pear', 'fruit', 'nature', 'food'],
  sheet: [6, 16],
  shortName: 'pear'
}, {
  name: 'Peach',
  unified: '1F351',
  keywords: ['peach', 'fruit', 'nature', 'food'],
  sheet: [6, 17],
  shortName: 'peach'
}, {
  name: 'Cherries',
  unified: '1F352',
  keywords: ['cherries', 'food', 'fruit'],
  sheet: [6, 18],
  shortName: 'cherries'
}, {
  name: 'Strawberry',
  unified: '1F353',
  keywords: ['strawberry', 'fruit', 'food', 'nature'],
  sheet: [6, 19],
  shortName: 'strawberry'
}, {
  name: 'Blueberries',
  unified: '1FAD0',
  keywords: ['blueberries', 'fruit'],
  sheet: [55, 2],
  shortName: 'blueberries'
}, {
  name: 'Kiwifruit',
  unified: '1F95D',
  keywords: ['kiwi_fruit', 'fruit', 'food'],
  sheet: [43, 39],
  shortName: 'kiwifruit'
}, {
  name: 'Tomato',
  unified: '1F345',
  keywords: ['tomato', 'fruit', 'vegetable', 'nature', 'food'],
  sheet: [6, 5],
  shortName: 'tomato'
}, {
  name: 'Olive',
  unified: '1FAD2',
  keywords: ['olive', 'fruit'],
  sheet: [55, 4],
  shortName: 'olive'
}, {
  name: 'Coconut',
  unified: '1F965',
  keywords: ['coconut', 'fruit', 'nature', 'food', 'palm'],
  sheet: [43, 47],
  shortName: 'coconut'
}, {
  name: 'Avocado',
  unified: '1F951',
  keywords: ['avocado', 'fruit', 'food'],
  sheet: [43, 27],
  shortName: 'avocado'
}, {
  name: 'Aubergine',
  unified: '1F346',
  keywords: ['eggplant', 'vegetable', 'nature', 'food', 'aubergine'],
  sheet: [6, 6],
  shortName: 'eggplant'
}, {
  name: 'Potato',
  unified: '1F954',
  keywords: ['potato', 'food', 'tuber', 'vegatable', 'starch'],
  sheet: [43, 30],
  shortName: 'potato'
}, {
  name: 'Carrot',
  unified: '1F955',
  keywords: ['carrot', 'vegetable', 'food', 'orange'],
  sheet: [43, 31],
  shortName: 'carrot'
}, {
  name: 'Ear of Maize',
  unified: '1F33D',
  keywords: ['ear_of_corn', 'food', 'vegetable', 'plant'],
  sheet: [5, 58],
  shortName: 'corn'
}, {
  name: 'Hot Pepper',
  unified: '1F336-FE0F',
  keywords: ['hot_pepper', 'food', 'spicy', 'chilli', 'chili'],
  sheet: [5, 51],
  shortName: 'hot_pepper'
}, {
  name: 'Bell Pepper',
  unified: '1FAD1',
  keywords: ['bell pepper', 'fruit', 'plant'],
  sheet: [55, 3],
  shortName: 'bell_pepper'
}, {
  name: 'Cucumber',
  unified: '1F952',
  keywords: ['cucumber', 'fruit', 'food', 'pickle'],
  sheet: [43, 28],
  shortName: 'cucumber'
}, {
  name: 'Leafy Green',
  unified: '1F96C',
  keywords: ['leafy_green', 'food', 'vegetable', 'plant', 'bok choy', 'cabbage', 'kale', 'lettuce'],
  sheet: [43, 54],
  shortName: 'leafy_green'
}, {
  name: 'Broccoli',
  unified: '1F966',
  keywords: ['broccoli', 'fruit', 'food', 'vegetable'],
  sheet: [43, 48],
  shortName: 'broccoli'
}, {
  name: 'Garlic',
  unified: '1F9C4',
  keywords: ['garlic', 'food', 'spice', 'cook'],
  sheet: [46, 9],
  shortName: 'garlic'
}, {
  name: 'Onion',
  unified: '1F9C5',
  keywords: ['onion', 'cook', 'food', 'spice'],
  sheet: [46, 10],
  shortName: 'onion'
}, {
  name: 'Mushroom',
  unified: '1F344',
  keywords: ['mushroom', 'plant', 'vegetable'],
  sheet: [6, 4],
  shortName: 'mushroom'
}, {
  name: 'Peanuts',
  unified: '1F95C',
  keywords: ['peanuts', 'food', 'nut'],
  sheet: [43, 38],
  shortName: 'peanuts'
}, {
  name: 'Beans',
  unified: '1FAD8',
  keywords: ['beans', 'food'],
  sheet: [55, 10],
  hidden: ['facebook'],
  shortName: 'beans'
}, {
  name: 'Chestnut',
  unified: '1F330',
  keywords: ['chestnut', 'food', 'squirrel'],
  sheet: [5, 45],
  shortName: 'chestnut'
}, {
  name: 'Bread',
  unified: '1F35E',
  keywords: ['bread', 'food', 'wheat', 'breakfast', 'toast'],
  sheet: [6, 30],
  shortName: 'bread'
}, {
  name: 'Croissant',
  unified: '1F950',
  keywords: ['croissant', 'food', 'bread', 'french'],
  sheet: [43, 26],
  shortName: 'croissant'
}, {
  name: 'Baguette Bread',
  unified: '1F956',
  keywords: ['baguette_bread', 'food', 'bread', 'french', 'france', 'bakery'],
  sheet: [43, 32],
  shortName: 'baguette_bread'
}, {
  name: 'Flatbread',
  unified: '1FAD3',
  keywords: ['flatbread', 'flour', 'food', 'bakery'],
  sheet: [55, 5],
  shortName: 'flatbread'
}, {
  name: 'Pretzel',
  unified: '1F968',
  keywords: ['pretzel', 'food', 'bread', 'twisted', 'germany', 'bakery'],
  sheet: [43, 50],
  shortName: 'pretzel'
}, {
  name: 'Bagel',
  unified: '1F96F',
  keywords: ['bagel', 'food', 'bread', 'bakery', 'schmear', 'jewish', 'bakery'],
  sheet: [43, 57],
  shortName: 'bagel'
}, {
  name: 'Pancakes',
  unified: '1F95E',
  keywords: ['pancakes', 'food', 'breakfast', 'flapjacks', 'hotcakes', 'brunch'],
  sheet: [43, 40],
  shortName: 'pancakes'
}, {
  name: 'Waffle',
  unified: '1F9C7',
  keywords: ['waffle', 'food', 'breakfast', 'brunch'],
  sheet: [46, 12],
  shortName: 'waffle'
}, {
  name: 'Cheese Wedge',
  unified: '1F9C0',
  keywords: ['cheese_wedge', 'food', 'chadder', 'swiss'],
  sheet: [46, 5],
  shortName: 'cheese_wedge'
}, {
  name: 'Meat on Bone',
  unified: '1F356',
  keywords: ['meat_on_bone', 'good', 'food', 'drumstick'],
  sheet: [6, 22],
  shortName: 'meat_on_bone'
}, {
  name: 'Poultry Leg',
  unified: '1F357',
  keywords: ['poultry_leg', 'food', 'meat', 'drumstick', 'bird', 'chicken', 'turkey'],
  sheet: [6, 23],
  shortName: 'poultry_leg'
}, {
  name: 'Cut of Meat',
  unified: '1F969',
  keywords: ['cut_of_meat', 'food', 'cow', 'meat', 'cut', 'chop', 'lambchop', 'porkchop'],
  sheet: [43, 51],
  shortName: 'cut_of_meat'
}, {
  name: 'Bacon',
  unified: '1F953',
  keywords: ['bacon', 'food', 'breakfast', 'pork', 'pig', 'meat', 'brunch'],
  sheet: [43, 29],
  shortName: 'bacon'
}, {
  name: 'Hamburger',
  unified: '1F354',
  keywords: ['hamburger', 'meat', 'fast food', 'beef', 'cheeseburger', 'mcdonalds', 'burger king'],
  sheet: [6, 20],
  shortName: 'hamburger'
}, {
  name: 'French Fries',
  unified: '1F35F',
  keywords: ['french_fries', 'chips', 'snack', 'fast food', 'potato'],
  sheet: [6, 31],
  shortName: 'fries'
}, {
  name: 'Slice of Pizza',
  unified: '1F355',
  keywords: ['pizza', 'food', 'party', 'italy'],
  sheet: [6, 21],
  shortName: 'pizza'
}, {
  name: 'Hot Dog',
  unified: '1F32D',
  keywords: ['hot_dog', 'food', 'frankfurter', 'america'],
  sheet: [5, 42],
  shortName: 'hotdog'
}, {
  name: 'Sandwich',
  unified: '1F96A',
  keywords: ['sandwich', 'food', 'lunch', 'bread', 'toast', 'bakery'],
  sheet: [43, 52],
  shortName: 'sandwich'
}, {
  name: 'Taco',
  unified: '1F32E',
  keywords: ['taco', 'food', 'mexican'],
  sheet: [5, 43],
  shortName: 'taco'
}, {
  name: 'Burrito',
  unified: '1F32F',
  keywords: ['burrito', 'food', 'mexican'],
  sheet: [5, 44],
  shortName: 'burrito'
}, {
  name: 'Tamale',
  unified: '1FAD4',
  keywords: ['tamale', 'food', 'masa'],
  sheet: [55, 6],
  shortName: 'tamale'
}, {
  name: 'Stuffed Flatbread',
  unified: '1F959',
  keywords: ['stuffed_flatbread', 'food', 'flatbread', 'stuffed', 'gyro', 'mediterranean'],
  sheet: [43, 35],
  shortName: 'stuffed_flatbread'
}, {
  name: 'Falafel',
  unified: '1F9C6',
  keywords: ['falafel', 'food', 'mediterranean'],
  sheet: [46, 11],
  shortName: 'falafel'
}, {
  name: 'Egg',
  unified: '1F95A',
  keywords: ['egg', 'food', 'chicken', 'breakfast'],
  sheet: [43, 36],
  shortName: 'egg'
}, {
  name: 'Cooking',
  unified: '1F373',
  keywords: ['cooking', 'food', 'breakfast', 'kitchen', 'egg', 'skillet'],
  sheet: [6, 51],
  shortNames: ['cooking'],
  shortName: 'fried_egg'
}, {
  name: 'Shallow Pan of Food',
  unified: '1F958',
  keywords: ['shallow_pan_of_food', 'food', 'cooking', 'casserole', 'paella', 'skillet'],
  sheet: [43, 34],
  shortName: 'shallow_pan_of_food'
}, {
  name: 'Pot of Food',
  unified: '1F372',
  keywords: ['pot_of_food', 'food', 'meat', 'soup', 'hot pot'],
  sheet: [6, 50],
  shortName: 'stew'
}, {
  name: 'Fondue',
  unified: '1FAD5',
  keywords: ['fondue', 'cheese', 'pot', 'food'],
  sheet: [55, 7],
  shortName: 'fondue'
}, {
  name: 'Bowl with Spoon',
  unified: '1F963',
  keywords: ['bowl_with_spoon', 'food', 'breakfast', 'cereal', 'oatmeal', 'porridge'],
  sheet: [43, 45],
  shortName: 'bowl_with_spoon'
}, {
  name: 'Green Salad',
  unified: '1F957',
  keywords: ['green_salad', 'food', 'healthy', 'lettuce', 'vegetable'],
  sheet: [43, 33],
  shortName: 'green_salad'
}, {
  name: 'Popcorn',
  unified: '1F37F',
  keywords: ['popcorn', 'food', 'movie theater', 'films', 'snack', 'drama'],
  sheet: [7, 2],
  shortName: 'popcorn'
}, {
  name: 'Butter',
  unified: '1F9C8',
  keywords: ['butter', 'food', 'cook'],
  sheet: [46, 13],
  shortName: 'butter'
}, {
  name: 'Salt Shaker',
  unified: '1F9C2',
  keywords: ['salt', 'condiment', 'shaker'],
  sheet: [46, 7],
  shortName: 'salt'
}, {
  name: 'Canned Food',
  unified: '1F96B',
  keywords: ['canned_food', 'food', 'soup', 'tomatoes'],
  sheet: [43, 53],
  shortName: 'canned_food'
}, {
  name: 'Bento Box',
  unified: '1F371',
  keywords: ['bento_box', 'food', 'japanese', 'box', 'lunch'],
  sheet: [6, 49],
  shortName: 'bento'
}, {
  name: 'Rice Cracker',
  unified: '1F358',
  keywords: ['rice_cracker', 'food', 'japanese', 'snack'],
  sheet: [6, 24],
  shortName: 'rice_cracker'
}, {
  name: 'Rice Ball',
  unified: '1F359',
  keywords: ['rice_ball', 'food', 'japanese'],
  sheet: [6, 25],
  shortName: 'rice_ball'
}, {
  name: 'Cooked Rice',
  unified: '1F35A',
  keywords: ['cooked_rice', 'food', 'asian'],
  sheet: [6, 26],
  shortName: 'rice'
}, {
  name: 'Curry and Rice',
  unified: '1F35B',
  keywords: ['curry_rice', 'food', 'spicy', 'hot', 'indian'],
  sheet: [6, 27],
  shortName: 'curry'
}, {
  name: 'Steaming Bowl',
  unified: '1F35C',
  keywords: ['steaming_bowl', 'food', 'japanese', 'noodle', 'chopsticks', 'ramen'],
  sheet: [6, 28],
  shortName: 'ramen'
}, {
  name: 'Spaghetti',
  unified: '1F35D',
  keywords: ['spaghetti', 'food', 'italian', 'pasta', 'noodle'],
  sheet: [6, 29],
  shortName: 'spaghetti'
}, {
  name: 'Roasted Sweet Potato',
  unified: '1F360',
  keywords: ['roasted_sweet_potato', 'food', 'nature', 'plant'],
  sheet: [6, 32],
  shortName: 'sweet_potato'
}, {
  name: 'Oden',
  unified: '1F362',
  keywords: ['oden', 'food', 'japanese'],
  sheet: [6, 34],
  shortName: 'oden'
}, {
  name: 'Sushi',
  unified: '1F363',
  keywords: ['sushi', 'food', 'fish', 'japanese', 'rice'],
  sheet: [6, 35],
  shortName: 'sushi'
}, {
  name: 'Fried Shrimp',
  unified: '1F364',
  keywords: ['fried_shrimp', 'food', 'animal', 'appetizer', 'summer'],
  sheet: [6, 36],
  shortName: 'fried_shrimp'
}, {
  name: 'Fish Cake with Swirl Design',
  unified: '1F365',
  keywords: ['fish_cake_with_swirl', 'food', 'japan', 'sea', 'beach', 'narutomaki', 'pink', 'swirl', 'kamaboko', 'surimi', 'ramen'],
  sheet: [6, 37],
  shortName: 'fish_cake'
}, {
  name: 'Moon Cake',
  unified: '1F96E',
  keywords: ['moon_cake', 'food', 'autumn', 'dessert'],
  sheet: [43, 56],
  shortName: 'moon_cake'
}, {
  name: 'Dango',
  unified: '1F361',
  keywords: ['dango', 'food', 'dessert', 'sweet', 'japanese', 'barbecue', 'meat'],
  sheet: [6, 33],
  shortName: 'dango'
}, {
  name: 'Dumpling',
  unified: '1F95F',
  keywords: ['dumpling', 'food', 'empanada', 'pierogi', 'potsticker', 'gyoza'],
  sheet: [43, 41],
  shortName: 'dumpling'
}, {
  name: 'Fortune Cookie',
  unified: '1F960',
  keywords: ['fortune_cookie', 'food', 'prophecy', 'dessert'],
  sheet: [43, 42],
  shortName: 'fortune_cookie'
}, {
  name: 'Takeout Box',
  unified: '1F961',
  keywords: ['takeout_box', 'food', 'leftovers'],
  sheet: [43, 43],
  shortName: 'takeout_box'
}, {
  name: 'Crab',
  unified: '1F980',
  keywords: ['crab', 'animal', 'crustacean'],
  sheet: [44, 18],
  shortName: 'crab'
}, {
  name: 'Lobster',
  unified: '1F99E',
  keywords: ['lobster', 'animal', 'nature', 'bisque', 'claws', 'seafood'],
  sheet: [44, 48],
  shortName: 'lobster'
}, {
  name: 'Shrimp',
  unified: '1F990',
  keywords: ['shrimp', 'animal', 'ocean', 'nature', 'seafood'],
  sheet: [44, 34],
  shortName: 'shrimp'
}, {
  name: 'Squid',
  unified: '1F991',
  keywords: ['squid', 'animal', 'nature', 'ocean', 'sea'],
  sheet: [44, 35],
  shortName: 'squid'
}, {
  name: 'Oyster',
  unified: '1F9AA',
  keywords: ['oyster', 'food'],
  sheet: [44, 60],
  shortName: 'oyster'
}, {
  name: 'Soft Ice Cream',
  unified: '1F366',
  keywords: ['soft_ice_cream', 'food', 'hot', 'dessert', 'summer'],
  sheet: [6, 38],
  shortName: 'icecream'
}, {
  name: 'Shaved Ice',
  unified: '1F367',
  keywords: ['shaved_ice', 'hot', 'dessert', 'summer'],
  sheet: [6, 39],
  shortName: 'shaved_ice'
}, {
  name: 'Ice Cream',
  unified: '1F368',
  keywords: ['ice_cream', 'food', 'hot', 'dessert'],
  sheet: [6, 40],
  shortName: 'ice_cream'
}, {
  name: 'Doughnut',
  unified: '1F369',
  keywords: ['doughnut', 'food', 'dessert', 'snack', 'sweet', 'donut'],
  sheet: [6, 41],
  shortName: 'doughnut'
}, {
  name: 'Cookie',
  unified: '1F36A',
  keywords: ['cookie', 'food', 'snack', 'oreo', 'chocolate', 'sweet', 'dessert'],
  sheet: [6, 42],
  shortName: 'cookie'
}, {
  name: 'Birthday Cake',
  unified: '1F382',
  keywords: ['birthday_cake', 'food', 'dessert', 'cake'],
  sheet: [7, 5],
  shortName: 'birthday'
}, {
  name: 'Shortcake',
  unified: '1F370',
  keywords: ['shortcake', 'food', 'dessert'],
  sheet: [6, 48],
  shortName: 'cake'
}, {
  name: 'Cupcake',
  unified: '1F9C1',
  keywords: ['cupcake', 'food', 'dessert', 'bakery', 'sweet'],
  sheet: [46, 6],
  shortName: 'cupcake'
}, {
  name: 'Pie',
  unified: '1F967',
  keywords: ['pie', 'food', 'dessert', 'pastry'],
  sheet: [43, 49],
  shortName: 'pie'
}, {
  name: 'Chocolate Bar',
  unified: '1F36B',
  keywords: ['chocolate_bar', 'food', 'snack', 'dessert', 'sweet'],
  sheet: [6, 43],
  shortName: 'chocolate_bar'
}, {
  name: 'Candy',
  unified: '1F36C',
  keywords: ['candy', 'snack', 'dessert', 'sweet', 'lolly'],
  sheet: [6, 44],
  shortName: 'candy'
}, {
  name: 'Lollipop',
  unified: '1F36D',
  keywords: ['lollipop', 'food', 'snack', 'candy', 'sweet'],
  sheet: [6, 45],
  shortName: 'lollipop'
}, {
  name: 'Custard',
  unified: '1F36E',
  keywords: ['custard', 'dessert', 'food'],
  sheet: [6, 46],
  shortName: 'custard'
}, {
  name: 'Honey Pot',
  unified: '1F36F',
  keywords: ['honey_pot', 'bees', 'sweet', 'kitchen'],
  sheet: [6, 47],
  shortName: 'honey_pot'
}, {
  name: 'Baby Bottle',
  unified: '1F37C',
  keywords: ['baby_bottle', 'food', 'container', 'milk'],
  sheet: [6, 60],
  shortName: 'baby_bottle'
}, {
  name: 'Glass of Milk',
  unified: '1F95B',
  keywords: ['glass_of_milk', 'beverage', 'drink', 'cow'],
  sheet: [43, 37],
  shortName: 'glass_of_milk'
}, {
  name: 'Hot Beverage',
  unified: '2615',
  keywords: ['hot_beverage', 'beverage', 'caffeine', 'latte', 'espresso', 'coffee', 'mug'],
  sheet: [56, 48],
  shortName: 'coffee'
}, {
  name: 'Teapot',
  unified: '1FAD6',
  keywords: ['teapot', 'drink', 'hot'],
  sheet: [55, 8],
  shortName: 'teapot'
}, {
  name: 'Teacup Without Handle',
  unified: '1F375',
  keywords: ['teacup_without_handle', 'drink', 'bowl', 'breakfast', 'green', 'british'],
  sheet: [6, 53],
  shortName: 'tea'
}, {
  name: 'Sake Bottle and Cup',
  unified: '1F376',
  keywords: ['sake', 'wine', 'drink', 'drunk', 'beverage', 'japanese', 'alcohol', 'booze'],
  sheet: [6, 54],
  shortName: 'sake'
}, {
  name: 'Bottle with Popping Cork',
  unified: '1F37E',
  keywords: ['bottle_with_popping_cork', 'drink', 'wine', 'bottle', 'celebration'],
  sheet: [7, 1],
  shortName: 'champagne'
}, {
  name: 'Wine Glass',
  unified: '1F377',
  keywords: ['wine_glass', 'drink', 'beverage', 'drunk', 'alcohol', 'booze'],
  sheet: [6, 55],
  shortName: 'wine_glass'
}, {
  name: 'Cocktail Glass',
  unified: '1F378',
  keywords: ['cocktail_glass', 'drink', 'drunk', 'alcohol', 'beverage', 'booze', 'mojito'],
  sheet: [6, 56],
  shortName: 'cocktail'
}, {
  name: 'Tropical Drink',
  unified: '1F379',
  keywords: ['tropical_drink', 'beverage', 'cocktail', 'summer', 'beach', 'alcohol', 'booze', 'mojito'],
  sheet: [6, 57],
  shortName: 'tropical_drink'
}, {
  name: 'Beer Mug',
  unified: '1F37A',
  keywords: ['beer_mug', 'relax', 'beverage', 'drink', 'drunk', 'party', 'pub', 'summer', 'alcohol', 'booze'],
  sheet: [6, 58],
  shortName: 'beer'
}, {
  name: 'Clinking Beer Mugs',
  unified: '1F37B',
  keywords: ['clinking_beer_mugs', 'relax', 'beverage', 'drink', 'drunk', 'party', 'pub', 'summer', 'alcohol', 'booze'],
  sheet: [6, 59],
  shortName: 'beers'
}, {
  name: 'Clinking Glasses',
  unified: '1F942',
  keywords: ['clinking_glasses', 'beverage', 'drink', 'party', 'alcohol', 'celebrate', 'cheers', 'wine', 'champagne', 'toast'],
  sheet: [43, 13],
  shortName: 'clinking_glasses'
}, {
  name: 'Tumbler Glass',
  unified: '1F943',
  keywords: ['tumbler_glass', 'drink', 'beverage', 'drunk', 'alcohol', 'liquor', 'booze', 'bourbon', 'scotch', 'whisky', 'glass', 'shot'],
  sheet: [43, 14],
  shortName: 'tumbler_glass'
}, {
  name: 'Pouring Liquid',
  unified: '1FAD7',
  keywords: ['pouring liquid', 'cup', 'water'],
  sheet: [55, 9],
  hidden: ['facebook'],
  shortName: 'pouring_liquid'
}, {
  name: 'Cup with Straw',
  unified: '1F964',
  keywords: ['cup_with_straw', 'drink', 'soda'],
  sheet: [43, 46],
  shortName: 'cup_with_straw'
}, {
  name: 'Bubble Tea',
  unified: '1F9CB',
  keywords: ['bubble tea', 'taiwan', 'boba', 'milk tea', 'straw'],
  sheet: [46, 16],
  shortName: 'bubble_tea'
}, {
  name: 'Beverage Box',
  unified: '1F9C3',
  keywords: ['beverage_box', 'drink'],
  sheet: [46, 8],
  shortName: 'beverage_box'
}, {
  name: 'Mate Drink',
  unified: '1F9C9',
  keywords: ['mate', 'drink', 'tea', 'beverage'],
  sheet: [46, 14],
  shortName: 'mate_drink'
}, {
  name: 'Ice Cube',
  unified: '1F9CA',
  keywords: ['ice', 'water', 'cold'],
  sheet: [46, 15],
  shortName: 'ice_cube'
}, {
  name: 'Chopsticks',
  unified: '1F962',
  keywords: ['chopsticks', 'food'],
  sheet: [43, 44],
  shortName: 'chopsticks'
}, {
  name: 'Fork and Knife with Plate',
  unified: '1F37D-FE0F',
  keywords: ['fork_and_knife_with_plate', 'food', 'eat', 'meal', 'lunch', 'dinner', 'restaurant'],
  sheet: [7, 0],
  shortName: 'knife_fork_plate'
}, {
  name: 'Fork and Knife',
  unified: '1F374',
  keywords: ['fork_and_knife', 'cutlery', 'kitchen'],
  sheet: [6, 52],
  shortName: 'fork_and_knife'
}, {
  name: 'Spoon',
  unified: '1F944',
  keywords: ['spoon', 'cutlery', 'kitchen', 'tableware'],
  sheet: [43, 15],
  shortName: 'spoon'
}, {
  name: 'Hocho',
  unified: '1F52A',
  keywords: ['kitchen_knife', 'knife', 'blade', 'cutlery', 'kitchen', 'weapon'],
  sheet: [30, 6],
  shortNames: ['knife'],
  shortName: 'hocho'
}, {
  name: 'Jar',
  unified: '1FAD9',
  keywords: ['jar', 'container', 'sauce'],
  sheet: [55, 11],
  hidden: ['facebook'],
  shortName: 'jar'
}, {
  name: 'Amphora',
  unified: '1F3FA',
  keywords: ['amphora', 'vase', 'jar'],
  sheet: [10, 40],
  shortName: 'amphora'
}, {
  name: 'Earth Globe Europe-Africa',
  unified: '1F30D',
  keywords: ['globe_showing_europe_africa', 'globe', 'world', 'international'],
  sheet: [5, 12],
  shortName: 'earth_africa'
}, {
  name: 'Earth Globe Americas',
  unified: '1F30E',
  keywords: ['globe_showing_americas', 'globe', 'world', 'USA', 'international'],
  sheet: [5, 13],
  shortName: 'earth_americas'
}, {
  name: 'Earth Globe Asia-Australia',
  unified: '1F30F',
  keywords: ['globe_showing_asia_australia', 'globe', 'world', 'east', 'international'],
  sheet: [5, 14],
  shortName: 'earth_asia'
}, {
  name: 'Globe with Meridians',
  unified: '1F310',
  keywords: ['globe_with_meridians', 'earth', 'international', 'world', 'internet', 'interweb', 'i18n'],
  sheet: [5, 15],
  shortName: 'globe_with_meridians'
}, {
  name: 'World Map',
  unified: '1F5FA-FE0F',
  keywords: ['world_map', 'location', 'direction'],
  sheet: [32, 14],
  shortName: 'world_map'
}, {
  name: 'Silhouette of Japan',
  unified: '1F5FE',
  keywords: ['map_of_japan', 'nation', 'country', 'japanese', 'asia'],
  sheet: [32, 18],
  shortName: 'japan'
}, {
  name: 'Compass',
  unified: '1F9ED',
  keywords: ['compass', 'magnetic', 'navigation', 'orienteering'],
  sheet: [53, 27],
  shortName: 'compass'
}, {
  name: 'Snow-Capped Mountain',
  unified: '1F3D4-FE0F',
  keywords: ['snow_capped_mountain', 'photo', 'nature', 'environment', 'winter', 'cold'],
  sheet: [9, 60],
  shortName: 'snow_capped_mountain'
}, {
  name: 'Mountain',
  unified: '26F0-FE0F',
  keywords: ['mountain', 'photo', 'nature', 'environment'],
  sheet: [57, 56],
  shortName: 'mountain'
}, {
  name: 'Volcano',
  unified: '1F30B',
  keywords: ['volcano', 'photo', 'nature', 'disaster'],
  sheet: [5, 10],
  shortName: 'volcano'
}, {
  name: 'Mount Fuji',
  unified: '1F5FB',
  keywords: ['mount_fuji', 'photo', 'mountain', 'nature', 'japanese'],
  sheet: [32, 15],
  shortName: 'mount_fuji'
}, {
  name: 'Camping',
  unified: '1F3D5-FE0F',
  keywords: ['camping', 'photo', 'outdoors', 'tent'],
  sheet: [10, 0],
  shortName: 'camping'
}, {
  name: 'Beach with Umbrella',
  unified: '1F3D6-FE0F',
  keywords: ['beach_with_umbrella', 'weather', 'summer', 'sunny', 'sand', 'mojito'],
  sheet: [10, 1],
  shortName: 'beach_with_umbrella'
}, {
  name: 'Desert',
  unified: '1F3DC-FE0F',
  keywords: ['desert', 'photo', 'warm', 'saharah'],
  sheet: [10, 7],
  shortName: 'desert'
}, {
  name: 'Desert Island',
  unified: '1F3DD-FE0F',
  keywords: ['desert_island', 'photo', 'tropical', 'mojito'],
  sheet: [10, 8],
  shortName: 'desert_island'
}, {
  name: 'National Park',
  unified: '1F3DE-FE0F',
  keywords: ['national_park', 'photo', 'environment', 'nature'],
  sheet: [10, 9],
  shortName: 'national_park'
}, {
  name: 'Stadium',
  unified: '1F3DF-FE0F',
  keywords: ['stadium', 'photo', 'place', 'sports', 'concert', 'venue'],
  sheet: [10, 10],
  shortName: 'stadium'
}, {
  name: 'Classical Building',
  unified: '1F3DB-FE0F',
  keywords: ['classical_building', 'art', 'culture', 'history'],
  sheet: [10, 6],
  shortName: 'classical_building'
}, {
  name: 'Building Construction',
  unified: '1F3D7-FE0F',
  keywords: ['building_construction', 'wip', 'working', 'progress'],
  sheet: [10, 2],
  shortName: 'building_construction'
}, {
  name: 'Brick',
  unified: '1F9F1',
  keywords: ['brick', 'bricks'],
  sheet: [53, 31],
  shortName: 'bricks'
}, {
  name: 'Rock',
  unified: '1FAA8',
  keywords: ['rock', 'stone'],
  sheet: [54, 26],
  shortName: 'rock'
}, {
  name: 'Wood',
  unified: '1FAB5',
  keywords: ['wood', 'nature', 'timber', 'trunk'],
  sheet: [54, 36],
  shortName: 'wood'
}, {
  name: 'Hut',
  unified: '1F6D6',
  keywords: ['hut', 'house', 'structure'],
  sheet: [38, 6],
  shortName: 'hut'
}, {
  name: 'Houses',
  unified: '1F3D8-FE0F',
  keywords: ['houses', 'buildings', 'photo'],
  sheet: [10, 3],
  shortName: 'house_buildings'
}, {
  name: 'Derelict House',
  unified: '1F3DA-FE0F',
  keywords: ['derelict_house', 'abandon', 'evict', 'broken', 'building'],
  sheet: [10, 5],
  shortName: 'derelict_house_building'
}, {
  name: 'House Building',
  unified: '1F3E0',
  keywords: ['house', 'building', 'home'],
  sheet: [10, 11],
  shortName: 'house'
}, {
  name: 'House with Garden',
  unified: '1F3E1',
  keywords: ['house_with_garden', 'home', 'plant', 'nature'],
  sheet: [10, 12],
  shortName: 'house_with_garden'
}, {
  name: 'Office Building',
  unified: '1F3E2',
  keywords: ['office_building', 'building', 'bureau', 'work'],
  sheet: [10, 13],
  shortName: 'office'
}, {
  name: 'Japanese Post Office',
  unified: '1F3E3',
  keywords: ['japanese_post_office', 'building', 'envelope', 'communication'],
  sheet: [10, 14],
  shortName: 'post_office'
}, {
  name: 'European Post Office',
  unified: '1F3E4',
  keywords: ['post_office', 'building', 'email'],
  sheet: [10, 15],
  shortName: 'european_post_office'
}, {
  name: 'Hospital',
  unified: '1F3E5',
  keywords: ['hospital', 'building', 'health', 'surgery', 'doctor'],
  sheet: [10, 16],
  shortName: 'hospital'
}, {
  name: 'Bank',
  unified: '1F3E6',
  keywords: ['bank', 'building', 'money', 'sales', 'cash', 'business', 'enterprise'],
  sheet: [10, 17],
  shortName: 'bank'
}, {
  name: 'Hotel',
  unified: '1F3E8',
  keywords: ['hotel', 'building', 'accomodation', 'checkin'],
  sheet: [10, 19],
  shortName: 'hotel'
}, {
  name: 'Love Hotel',
  unified: '1F3E9',
  keywords: ['love_hotel', 'like', 'affection', 'dating'],
  sheet: [10, 20],
  shortName: 'love_hotel'
}, {
  name: 'Convenience Store',
  unified: '1F3EA',
  keywords: ['convenience_store', 'building', 'shopping', 'groceries'],
  sheet: [10, 21],
  shortName: 'convenience_store'
}, {
  name: 'School',
  unified: '1F3EB',
  keywords: ['school', 'building', 'student', 'education', 'learn', 'teach'],
  sheet: [10, 22],
  shortName: 'school'
}, {
  name: 'Department Store',
  unified: '1F3EC',
  keywords: ['department_store', 'building', 'shopping', 'mall'],
  sheet: [10, 23],
  shortName: 'department_store'
}, {
  name: 'Factory',
  unified: '1F3ED',
  keywords: ['factory', 'building', 'industry', 'pollution', 'smoke'],
  sheet: [10, 24],
  shortName: 'factory'
}, {
  name: 'Japanese Castle',
  unified: '1F3EF',
  keywords: ['japanese_castle', 'photo', 'building'],
  sheet: [10, 26],
  shortName: 'japanese_castle'
}, {
  name: 'European Castle',
  unified: '1F3F0',
  keywords: ['castle', 'building', 'royalty', 'history'],
  sheet: [10, 27],
  shortName: 'european_castle'
}, {
  name: 'Wedding',
  unified: '1F492',
  keywords: ['wedding', 'love', 'like', 'affection', 'couple', 'marriage', 'bride', 'groom'],
  sheet: [27, 33],
  shortName: 'wedding'
}, {
  name: 'Tokyo Tower',
  unified: '1F5FC',
  keywords: ['tokyo_tower', 'photo', 'japanese'],
  sheet: [32, 16],
  shortName: 'tokyo_tower'
}, {
  name: 'Statue of Liberty',
  unified: '1F5FD',
  keywords: ['statue_of_liberty', 'american', 'newyork'],
  sheet: [32, 17],
  shortName: 'statue_of_liberty'
}, {
  name: 'Church',
  unified: '26EA',
  keywords: ['church', 'building', 'religion', 'christ'],
  sheet: [57, 55],
  shortName: 'church'
}, {
  name: 'Mosque',
  unified: '1F54C',
  keywords: ['mosque', 'islam', 'worship', 'minaret'],
  sheet: [30, 29],
  shortName: 'mosque'
}, {
  name: 'Hindu Temple',
  unified: '1F6D5',
  keywords: ['hindu_temple', 'religion'],
  sheet: [38, 5],
  shortName: 'hindu_temple'
}, {
  name: 'Synagogue',
  unified: '1F54D',
  keywords: ['synagogue', 'judaism', 'worship', 'temple', 'jewish'],
  sheet: [30, 30],
  shortName: 'synagogue'
}, {
  name: 'Shinto Shrine',
  unified: '26E9-FE0F',
  keywords: ['shinto_shrine', 'temple', 'japan', 'kyoto'],
  sheet: [57, 54],
  shortName: 'shinto_shrine'
}, {
  name: 'Kaaba',
  unified: '1F54B',
  keywords: ['kaaba', 'mecca', 'mosque', 'islam'],
  sheet: [30, 28],
  shortName: 'kaaba'
}, {
  name: 'Fountain',
  unified: '26F2',
  keywords: ['fountain', 'photo', 'summer', 'water', 'fresh'],
  sheet: [57, 58],
  shortName: 'fountain'
}, {
  name: 'Tent',
  unified: '26FA',
  keywords: ['tent', 'photo', 'camping', 'outdoors'],
  sheet: [58, 21],
  shortName: 'tent'
}, {
  name: 'Foggy',
  unified: '1F301',
  keywords: ['foggy', 'photo', 'mountain'],
  sheet: [5, 0],
  shortName: 'foggy'
}, {
  name: 'Night with Stars',
  unified: '1F303',
  keywords: ['night_with_stars', 'evening', 'city', 'downtown'],
  sheet: [5, 2],
  shortName: 'night_with_stars'
}, {
  name: 'Cityscape',
  unified: '1F3D9-FE0F',
  keywords: ['cityscape', 'photo', 'night life', 'urban'],
  sheet: [10, 4],
  shortName: 'cityscape'
}, {
  name: 'Sunrise over Mountains',
  unified: '1F304',
  keywords: ['sunrise_over_mountains', 'view', 'vacation', 'photo'],
  sheet: [5, 3],
  shortName: 'sunrise_over_mountains'
}, {
  name: 'Sunrise',
  unified: '1F305',
  keywords: ['sunrise', 'morning', 'view', 'vacation', 'photo'],
  sheet: [5, 4],
  shortName: 'sunrise'
}, {
  name: 'Cityscape at Dusk',
  unified: '1F306',
  keywords: ['cityscape_at_dusk', 'photo', 'evening', 'sky', 'buildings'],
  sheet: [5, 5],
  shortName: 'city_sunset'
}, {
  name: 'Sunset over Buildings',
  unified: '1F307',
  keywords: ['sunset', 'photo', 'good morning', 'dawn'],
  sheet: [5, 6],
  shortName: 'city_sunrise'
}, {
  name: 'Bridge at Night',
  unified: '1F309',
  keywords: ['bridge_at_night', 'photo', 'sanfrancisco'],
  sheet: [5, 8],
  shortName: 'bridge_at_night'
}, {
  name: 'Hot Springs',
  unified: '2668-FE0F',
  keywords: ['hot_springs', 'bath', 'warm', 'relax'],
  sheet: [57, 24],
  shortName: 'hotsprings'
}, {
  name: 'Carousel Horse',
  unified: '1F3A0',
  keywords: ['carousel_horse', 'photo', 'carnival'],
  sheet: [7, 35],
  shortName: 'carousel_horse'
}, {
  name: 'Playground Slide',
  unified: '1F6DD',
  keywords: ['playground slide', 'fun', 'park'],
  sheet: [38, 8],
  hidden: ['facebook'],
  shortName: 'playground_slide'
}, {
  name: 'Ferris Wheel',
  unified: '1F3A1',
  keywords: ['ferris_wheel', 'photo', 'carnival', 'londoneye'],
  sheet: [7, 36],
  shortName: 'ferris_wheel'
}, {
  name: 'Roller Coaster',
  unified: '1F3A2',
  keywords: ['roller_coaster', 'carnival', 'playground', 'photo', 'fun'],
  sheet: [7, 37],
  shortName: 'roller_coaster'
}, {
  name: 'Barber Pole',
  unified: '1F488',
  keywords: ['barber_pole', 'hair', 'salon', 'style'],
  sheet: [26, 34],
  shortName: 'barber'
}, {
  name: 'Circus Tent',
  unified: '1F3AA',
  keywords: ['circus_tent', 'festival', 'carnival', 'party'],
  sheet: [7, 45],
  shortName: 'circus_tent'
}, {
  name: 'Steam Locomotive',
  unified: '1F682',
  keywords: ['locomotive', 'transportation', 'vehicle', 'train'],
  sheet: [35, 34],
  shortName: 'steam_locomotive'
}, {
  name: 'Railway Car',
  unified: '1F683',
  keywords: ['railway_car', 'transportation', 'vehicle'],
  sheet: [35, 35],
  shortName: 'railway_car'
}, {
  name: 'High-Speed Train',
  unified: '1F684',
  keywords: ['high_speed_train', 'transportation', 'vehicle'],
  sheet: [35, 36],
  shortName: 'bullettrain_side'
}, {
  name: 'High-Speed Train with Bullet Nose',
  unified: '1F685',
  keywords: ['bullet_train', 'transportation', 'vehicle', 'speed', 'fast', 'public', 'travel'],
  sheet: [35, 37],
  shortName: 'bullettrain_front'
}, {
  name: 'Train',
  unified: '1F686',
  keywords: ['train', 'transportation', 'vehicle'],
  sheet: [35, 38],
  shortName: 'train2'
}, {
  name: 'Metro',
  unified: '1F687',
  keywords: ['metro', 'transportation', 'blue-square', 'mrt', 'underground', 'tube'],
  sheet: [35, 39],
  shortName: 'metro'
}, {
  name: 'Light Rail',
  unified: '1F688',
  keywords: ['light_rail', 'transportation', 'vehicle'],
  sheet: [35, 40],
  shortName: 'light_rail'
}, {
  name: 'Station',
  unified: '1F689',
  keywords: ['station', 'transportation', 'vehicle', 'public'],
  sheet: [35, 41],
  shortName: 'station'
}, {
  name: 'Tram',
  unified: '1F68A',
  keywords: ['tram', 'transportation', 'vehicle'],
  sheet: [35, 42],
  shortName: 'tram'
}, {
  name: 'Monorail',
  unified: '1F69D',
  keywords: ['monorail', 'transportation', 'vehicle'],
  sheet: [36, 0],
  shortName: 'monorail'
}, {
  name: 'Mountain Railway',
  unified: '1F69E',
  keywords: ['mountain_railway', 'transportation', 'vehicle'],
  sheet: [36, 1],
  shortName: 'mountain_railway'
}, {
  name: 'Tram Car',
  unified: '1F68B',
  keywords: ['tram_car', 'transportation', 'vehicle', 'carriage', 'public', 'travel'],
  sheet: [35, 43],
  shortName: 'train'
}, {
  name: 'Bus',
  unified: '1F68C',
  keywords: ['bus', 'car', 'vehicle', 'transportation'],
  sheet: [35, 44],
  shortName: 'bus'
}, {
  name: 'Oncoming Bus',
  unified: '1F68D',
  keywords: ['oncoming_bus', 'vehicle', 'transportation'],
  sheet: [35, 45],
  shortName: 'oncoming_bus'
}, {
  name: 'Trolleybus',
  unified: '1F68E',
  keywords: ['trolleybus', 'bart', 'transportation', 'vehicle'],
  sheet: [35, 46],
  shortName: 'trolleybus'
}, {
  name: 'Minibus',
  unified: '1F690',
  keywords: ['minibus', 'vehicle', 'car', 'transportation'],
  sheet: [35, 48],
  shortName: 'minibus'
}, {
  name: 'Ambulance',
  unified: '1F691',
  keywords: ['ambulance', 'health', '911', 'hospital'],
  sheet: [35, 49],
  shortName: 'ambulance'
}, {
  name: 'Fire Engine',
  unified: '1F692',
  keywords: ['fire_engine', 'transportation', 'cars', 'vehicle'],
  sheet: [35, 50],
  shortName: 'fire_engine'
}, {
  name: 'Police Car',
  unified: '1F693',
  keywords: ['police_car', 'vehicle', 'cars', 'transportation', 'law', 'legal', 'enforcement'],
  sheet: [35, 51],
  shortName: 'police_car'
}, {
  name: 'Oncoming Police Car',
  unified: '1F694',
  keywords: ['oncoming_police_car', 'vehicle', 'law', 'legal', 'enforcement', '911'],
  sheet: [35, 52],
  shortName: 'oncoming_police_car'
}, {
  name: 'Taxi',
  unified: '1F695',
  keywords: ['taxi', 'uber', 'vehicle', 'cars', 'transportation'],
  sheet: [35, 53],
  shortName: 'taxi'
}, {
  name: 'Oncoming Taxi',
  unified: '1F696',
  keywords: ['oncoming_taxi', 'vehicle', 'cars', 'uber'],
  sheet: [35, 54],
  shortName: 'oncoming_taxi'
}, {
  name: 'Automobile',
  unified: '1F697',
  keywords: ['automobile', 'red', 'transportation', 'vehicle'],
  sheet: [35, 55],
  shortNames: ['red_car'],
  shortName: 'car'
}, {
  name: 'Oncoming Automobile',
  unified: '1F698',
  keywords: ['oncoming_automobile', 'car', 'vehicle', 'transportation'],
  sheet: [35, 56],
  shortName: 'oncoming_automobile'
}, {
  name: 'Recreational Vehicle',
  unified: '1F699',
  keywords: ['sport_utility_vehicle', 'transportation', 'vehicle'],
  sheet: [35, 57],
  shortName: 'blue_car'
}, {
  name: 'Pickup Truck',
  unified: '1F6FB',
  keywords: ['pickup truck', 'car', 'transportation'],
  sheet: [38, 29],
  shortName: 'pickup_truck'
}, {
  name: 'Delivery Truck',
  unified: '1F69A',
  keywords: ['delivery_truck', 'cars', 'transportation'],
  sheet: [35, 58],
  shortName: 'truck'
}, {
  name: 'Articulated Lorry',
  unified: '1F69B',
  keywords: ['articulated_lorry', 'vehicle', 'cars', 'transportation', 'express'],
  sheet: [35, 59],
  shortName: 'articulated_lorry'
}, {
  name: 'Tractor',
  unified: '1F69C',
  keywords: ['tractor', 'vehicle', 'car', 'farming', 'agriculture'],
  sheet: [35, 60],
  shortName: 'tractor'
}, {
  name: 'Racing Car',
  unified: '1F3CE-FE0F',
  keywords: ['racing_car', 'sports', 'race', 'fast', 'formula', 'f1'],
  sheet: [9, 54],
  shortName: 'racing_car'
}, {
  name: 'Motorcycle',
  unified: '1F3CD-FE0F',
  keywords: ['motorcycle', 'race', 'sports', 'fast'],
  sheet: [9, 53],
  shortName: 'racing_motorcycle'
}, {
  name: 'Motor Scooter',
  unified: '1F6F5',
  keywords: ['motor_scooter', 'vehicle', 'vespa', 'sasha'],
  sheet: [38, 23],
  shortName: 'motor_scooter'
}, {
  name: 'Manual Wheelchair',
  unified: '1F9BD',
  keywords: ['manual_wheelchair', 'accessibility'],
  sheet: [46, 2],
  shortName: 'manual_wheelchair'
}, {
  name: 'Motorized Wheelchair',
  unified: '1F9BC',
  keywords: ['motorized_wheelchair', 'accessibility'],
  sheet: [46, 1],
  shortName: 'motorized_wheelchair'
}, {
  name: 'Auto Rickshaw',
  unified: '1F6FA',
  keywords: ['auto_rickshaw', 'move', 'transportation'],
  sheet: [38, 28],
  shortName: 'auto_rickshaw'
}, {
  name: 'Bicycle',
  unified: '1F6B2',
  keywords: ['bicycle', 'sports', 'bicycle', 'exercise', 'hipster'],
  sheet: [36, 38],
  shortName: 'bike'
}, {
  name: 'Scooter',
  unified: '1F6F4',
  keywords: ['kick_scooter', 'vehicle', 'kick', 'razor'],
  sheet: [38, 22],
  shortName: 'scooter'
}, {
  name: 'Skateboard',
  unified: '1F6F9',
  keywords: ['skateboard', 'board'],
  sheet: [38, 27],
  shortName: 'skateboard'
}, {
  name: 'Roller Skate',
  unified: '1F6FC',
  keywords: ['roller skate', 'footwear', 'sports'],
  sheet: [38, 30],
  shortName: 'roller_skate'
}, {
  name: 'Bus Stop',
  unified: '1F68F',
  keywords: ['bus_stop', 'transportation', 'wait'],
  sheet: [35, 47],
  shortName: 'busstop'
}, {
  name: 'Motorway',
  unified: '1F6E3-FE0F',
  keywords: ['motorway', 'road', 'cupertino', 'interstate', 'highway'],
  sheet: [38, 14],
  shortName: 'motorway'
}, {
  name: 'Railway Track',
  unified: '1F6E4-FE0F',
  keywords: ['railway_track', 'train', 'transportation'],
  sheet: [38, 15],
  shortName: 'railway_track'
}, {
  name: 'Oil Drum',
  unified: '1F6E2-FE0F',
  keywords: ['oil_drum', 'barrell'],
  sheet: [38, 13],
  shortName: 'oil_drum'
}, {
  name: 'Fuel Pump',
  unified: '26FD',
  keywords: ['fuel_pump', 'gas station', 'petroleum'],
  sheet: [58, 22],
  shortName: 'fuelpump'
}, {
  name: 'Wheel',
  unified: '1F6DE',
  keywords: ['wheel', 'car', 'transport'],
  sheet: [38, 9],
  hidden: ['facebook'],
  shortName: 'wheel'
}, {
  name: 'Police Cars Revolving Light',
  unified: '1F6A8',
  keywords: ['police_car_light', 'police', 'ambulance', '911', 'emergency', 'alert', 'error', 'pinged', 'law', 'legal'],
  sheet: [36, 28],
  shortName: 'rotating_light'
}, {
  name: 'Horizontal Traffic Light',
  unified: '1F6A5',
  keywords: ['horizontal_traffic_light', 'transportation', 'signal'],
  sheet: [36, 25],
  shortName: 'traffic_light'
}, {
  name: 'Vertical Traffic Light',
  unified: '1F6A6',
  keywords: ['vertical_traffic_light', 'transportation', 'driving'],
  sheet: [36, 26],
  shortName: 'vertical_traffic_light'
}, {
  name: 'Octagonal Sign',
  unified: '1F6D1',
  keywords: ['stop_sign', 'stop'],
  sheet: [38, 3],
  shortName: 'octagonal_sign'
}, {
  name: 'Construction Sign',
  unified: '1F6A7',
  keywords: ['construction', 'wip', 'progress', 'caution', 'warning'],
  sheet: [36, 27],
  shortName: 'construction'
}, {
  name: 'Anchor',
  unified: '2693',
  keywords: ['anchor', 'ship', 'ferry', 'sea', 'boat'],
  sheet: [57, 29],
  shortName: 'anchor'
}, {
  name: 'Ring Buoy',
  unified: '1F6DF',
  keywords: ['ring buoy', 'life saver', 'life preserver'],
  sheet: [38, 10],
  hidden: ['facebook'],
  shortName: 'ring_buoy'
}, {
  name: 'Sailboat',
  unified: '26F5',
  keywords: ['sailboat', 'ship', 'summer', 'transportation', 'water', 'sailing'],
  sheet: [58, 0],
  shortNames: ['sailboat'],
  shortName: 'boat'
}, {
  name: 'Canoe',
  unified: '1F6F6',
  keywords: ['canoe', 'boat', 'paddle', 'water', 'ship'],
  sheet: [38, 24],
  shortName: 'canoe'
}, {
  name: 'Speedboat',
  unified: '1F6A4',
  keywords: ['speedboat', 'ship', 'transportation', 'vehicle', 'summer'],
  sheet: [36, 24],
  shortName: 'speedboat'
}, {
  name: 'Passenger Ship',
  unified: '1F6F3-FE0F',
  keywords: ['passenger_ship', 'yacht', 'cruise', 'ferry'],
  sheet: [38, 21],
  shortName: 'passenger_ship'
}, {
  name: 'Ferry',
  unified: '26F4-FE0F',
  keywords: ['ferry', 'boat', 'ship', 'yacht'],
  sheet: [57, 60],
  shortName: 'ferry'
}, {
  name: 'Motor Boat',
  unified: '1F6E5-FE0F',
  keywords: ['motor_boat', 'ship'],
  sheet: [38, 16],
  shortName: 'motor_boat'
}, {
  name: 'Ship',
  unified: '1F6A2',
  keywords: ['ship', 'transportation', 'titanic', 'deploy'],
  sheet: [36, 5],
  shortName: 'ship'
}, {
  name: 'Airplane',
  unified: '2708-FE0F',
  keywords: ['airplane', 'vehicle', 'transportation', 'flight', 'fly'],
  sheet: [58, 25],
  shortName: 'airplane'
}, {
  name: 'Small Airplane',
  unified: '1F6E9-FE0F',
  keywords: ['small_airplane', 'flight', 'transportation', 'fly', 'vehicle'],
  sheet: [38, 17],
  shortName: 'small_airplane'
}, {
  name: 'Airplane Departure',
  unified: '1F6EB',
  keywords: ['airplane_departure', 'airport', 'flight', 'landing'],
  sheet: [38, 18],
  shortName: 'airplane_departure'
}, {
  name: 'Airplane Arriving',
  unified: '1F6EC',
  keywords: ['airplane_arrival', 'airport', 'flight', 'boarding'],
  sheet: [38, 19],
  shortName: 'airplane_arriving'
}, {
  name: 'Parachute',
  unified: '1FA82',
  keywords: ['parachute', 'fly', 'glide'],
  sheet: [53, 58],
  shortName: 'parachute'
}, {
  name: 'Seat',
  unified: '1F4BA',
  keywords: ['seat', 'sit', 'airplane', 'transport', 'bus', 'flight', 'fly'],
  sheet: [28, 17],
  shortName: 'seat'
}, {
  name: 'Helicopter',
  unified: '1F681',
  keywords: ['helicopter', 'transportation', 'vehicle', 'fly'],
  sheet: [35, 33],
  shortName: 'helicopter'
}, {
  name: 'Suspension Railway',
  unified: '1F69F',
  keywords: ['suspension_railway', 'vehicle', 'transportation'],
  sheet: [36, 2],
  shortName: 'suspension_railway'
}, {
  name: 'Mountain Cableway',
  unified: '1F6A0',
  keywords: ['mountain_cableway', 'transportation', 'vehicle', 'ski'],
  sheet: [36, 3],
  shortName: 'mountain_cableway'
}, {
  name: 'Aerial Tramway',
  unified: '1F6A1',
  keywords: ['aerial_tramway', 'transportation', 'vehicle', 'ski'],
  sheet: [36, 4],
  shortName: 'aerial_tramway'
}, {
  name: 'Satellite',
  unified: '1F6F0-FE0F',
  keywords: ['satellite', 'communication', 'gps', 'orbit', 'spaceflight', 'NASA', 'ISS'],
  sheet: [38, 20],
  shortName: 'satellite'
}, {
  name: 'Rocket',
  unified: '1F680',
  keywords: ['rocket', 'launch', 'ship', 'staffmode', 'NASA', 'outer space', 'outer_space', 'fly'],
  sheet: [35, 32],
  shortName: 'rocket'
}, {
  name: 'Flying Saucer',
  unified: '1F6F8',
  keywords: ['flying_saucer', 'transportation', 'vehicle', 'ufo'],
  sheet: [38, 26],
  shortName: 'flying_saucer'
}, {
  name: 'Bellhop Bell',
  unified: '1F6CE-FE0F',
  keywords: ['bellhop_bell', 'service'],
  sheet: [38, 0],
  shortName: 'bellhop_bell'
}, {
  name: 'Luggage',
  unified: '1F9F3',
  keywords: ['luggage', 'packing', 'travel'],
  sheet: [53, 33],
  shortName: 'luggage'
}, {
  name: 'Hourglass',
  unified: '231B',
  keywords: ['hourglass_done', 'time', 'clock', 'oldschool', 'limit', 'exam', 'quiz', 'test'],
  sheet: [56, 14],
  shortName: 'hourglass'
}, {
  name: 'Hourglass with Flowing Sand',
  unified: '23F3',
  keywords: ['hourglass_not_done', 'oldschool', 'time', 'countdown'],
  sheet: [56, 27],
  shortName: 'hourglass_flowing_sand'
}, {
  name: 'Watch',
  unified: '231A',
  keywords: ['watch', 'time', 'accessories'],
  sheet: [56, 13],
  shortName: 'watch'
}, {
  name: 'Alarm Clock',
  unified: '23F0',
  keywords: ['alarm_clock', 'time', 'wake'],
  sheet: [56, 24],
  shortName: 'alarm_clock'
}, {
  name: 'Stopwatch',
  unified: '23F1-FE0F',
  keywords: ['stopwatch', 'time', 'deadline'],
  sheet: [56, 25],
  shortName: 'stopwatch'
}, {
  name: 'Timer Clock',
  unified: '23F2-FE0F',
  keywords: ['timer_clock', 'alarm'],
  sheet: [56, 26],
  shortName: 'timer_clock'
}, {
  name: 'Mantelpiece Clock',
  unified: '1F570-FE0F',
  keywords: ['mantelpiece_clock', 'time'],
  sheet: [30, 57],
  shortName: 'mantelpiece_clock'
}, {
  name: 'Clock Face Twelve Oclock',
  unified: '1F55B',
  keywords: ['twelve_o_clock', '12', '00:00', '0000', '12:00', '1200', 'time', 'noon', 'midnight', 'midday', 'late', 'early', 'schedule'],
  sheet: [30, 43],
  shortName: 'clock12'
}, {
  name: 'Clock Face Twelve-Thirty',
  unified: '1F567',
  keywords: ['twelve_thirty', '00:30', '0030', '12:30', '1230', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 55],
  shortName: 'clock1230'
}, {
  name: 'Clock Face One Oclock',
  unified: '1F550',
  keywords: ['one_o_clock', '1', '1:00', '100', '13:00', '1300', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 32],
  shortName: 'clock1'
}, {
  name: 'Clock Face One-Thirty',
  unified: '1F55C',
  keywords: ['one_thirty', '1:30', '130', '13:30', '1330', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 44],
  shortName: 'clock130'
}, {
  name: 'Clock Face Two Oclock',
  unified: '1F551',
  keywords: ['two_o_clock', '2', '2:00', '200', '14:00', '1400', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 33],
  shortName: 'clock2'
}, {
  name: 'Clock Face Two-Thirty',
  unified: '1F55D',
  keywords: ['two_thirty', '2:30', '230', '14:30', '1430', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 45],
  shortName: 'clock230'
}, {
  name: 'Clock Face Three Oclock',
  unified: '1F552',
  keywords: ['three_o_clock', '3', '3:00', '300', '15:00', '1500', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 34],
  shortName: 'clock3'
}, {
  name: 'Clock Face Three-Thirty',
  unified: '1F55E',
  keywords: ['three_thirty', '3:30', '330', '15:30', '1530', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 46],
  shortName: 'clock330'
}, {
  name: 'Clock Face Four Oclock',
  unified: '1F553',
  keywords: ['four_o_clock', '4', '4:00', '400', '16:00', '1600', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 35],
  shortName: 'clock4'
}, {
  name: 'Clock Face Four-Thirty',
  unified: '1F55F',
  keywords: ['four_thirty', '4:30', '430', '16:30', '1630', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 47],
  shortName: 'clock430'
}, {
  name: 'Clock Face Five Oclock',
  unified: '1F554',
  keywords: ['five_o_clock', '5', '5:00', '500', '17:00', '1700', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 36],
  shortName: 'clock5'
}, {
  name: 'Clock Face Five-Thirty',
  unified: '1F560',
  keywords: ['five_thirty', '5:30', '530', '17:30', '1730', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 48],
  shortName: 'clock530'
}, {
  name: 'Clock Face Six Oclock',
  unified: '1F555',
  keywords: ['six_o_clock', '6', '6:00', '600', '18:00', '1800', 'time', 'late', 'early', 'schedule', 'dawn', 'dusk'],
  sheet: [30, 37],
  shortName: 'clock6'
}, {
  name: 'Clock Face Six-Thirty',
  unified: '1F561',
  keywords: ['six_thirty', '6:30', '630', '18:30', '1830', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 49],
  shortName: 'clock630'
}, {
  name: 'Clock Face Seven Oclock',
  unified: '1F556',
  keywords: ['seven_o_clock', '7', '7:00', '700', '19:00', '1900', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 38],
  shortName: 'clock7'
}, {
  name: 'Clock Face Seven-Thirty',
  unified: '1F562',
  keywords: ['seven_thirty', '7:30', '730', '19:30', '1930', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 50],
  shortName: 'clock730'
}, {
  name: 'Clock Face Eight Oclock',
  unified: '1F557',
  keywords: ['eight_o_clock', '8', '8:00', '800', '20:00', '2000', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 39],
  shortName: 'clock8'
}, {
  name: 'Clock Face Eight-Thirty',
  unified: '1F563',
  keywords: ['eight_thirty', '8:30', '830', '20:30', '2030', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 51],
  shortName: 'clock830'
}, {
  name: 'Clock Face Nine Oclock',
  unified: '1F558',
  keywords: ['nine_o_clock', '9', '9:00', '900', '21:00', '2100', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 40],
  shortName: 'clock9'
}, {
  name: 'Clock Face Nine-Thirty',
  unified: '1F564',
  keywords: ['nine_thirty', '9:30', '930', '21:30', '2130', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 52],
  shortName: 'clock930'
}, {
  name: 'Clock Face Ten Oclock',
  unified: '1F559',
  keywords: ['ten_o_clock', '10', '10:00', '1000', '22:00', '2200', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 41],
  shortName: 'clock10'
}, {
  name: 'Clock Face Ten-Thirty',
  unified: '1F565',
  keywords: ['ten_thirty', '10:30', '1030', '22:30', '2230', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 53],
  shortName: 'clock1030'
}, {
  name: 'Clock Face Eleven Oclock',
  unified: '1F55A',
  keywords: ['eleven_o_clock', '11', '11:00', '1100', '23:00', '2300', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 42],
  shortName: 'clock11'
}, {
  name: 'Clock Face Eleven-Thirty',
  unified: '1F566',
  keywords: ['eleven_thirty', '11:30', '1130', '23:30', '2330', 'time', 'late', 'early', 'schedule'],
  sheet: [30, 54],
  shortName: 'clock1130'
}, {
  name: 'New Moon Symbol',
  unified: '1F311',
  keywords: ['new_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 16],
  shortName: 'new_moon'
}, {
  name: 'Waxing Crescent Moon Symbol',
  unified: '1F312',
  keywords: ['waxing_crescent_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 17],
  shortName: 'waxing_crescent_moon'
}, {
  name: 'First Quarter Moon Symbol',
  unified: '1F313',
  keywords: ['first_quarter_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 18],
  shortName: 'first_quarter_moon'
}, {
  name: 'Waxing Gibbous Moon Symbol',
  unified: '1F314',
  keywords: ['waxing_gibbous_moon', 'nature', 'night', 'sky', 'gray', 'twilight', 'planet', 'space', 'evening', 'sleep'],
  sheet: [5, 19],
  shortNames: ['waxing_gibbous_moon'],
  shortName: 'moon'
}, {
  name: 'Full Moon Symbol',
  unified: '1F315',
  keywords: ['full_moon', 'nature', 'yellow', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 20],
  shortName: 'full_moon'
}, {
  name: 'Waning Gibbous Moon Symbol',
  unified: '1F316',
  keywords: ['waning_gibbous_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep', 'waxing_gibbous_moon'],
  sheet: [5, 21],
  shortName: 'waning_gibbous_moon'
}, {
  name: 'Last Quarter Moon Symbol',
  unified: '1F317',
  keywords: ['last_quarter_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 22],
  shortName: 'last_quarter_moon'
}, {
  name: 'Waning Crescent Moon Symbol',
  unified: '1F318',
  keywords: ['waning_crescent_moon', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 23],
  shortName: 'waning_crescent_moon'
}, {
  name: 'Crescent Moon',
  unified: '1F319',
  keywords: ['crescent_moon', 'night', 'sleep', 'sky', 'evening', 'magic'],
  sheet: [5, 24],
  shortName: 'crescent_moon'
}, {
  name: 'New Moon with Face',
  unified: '1F31A',
  keywords: ['new_moon_face', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 25],
  shortName: 'new_moon_with_face'
}, {
  name: 'First Quarter Moon with Face',
  unified: '1F31B',
  keywords: ['first_quarter_moon_face', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 26],
  shortName: 'first_quarter_moon_with_face'
}, {
  name: 'Last Quarter Moon with Face',
  unified: '1F31C',
  keywords: ['last_quarter_moon_face', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 27],
  shortName: 'last_quarter_moon_with_face'
}, {
  name: 'Thermometer',
  unified: '1F321-FE0F',
  keywords: ['thermometer', 'weather', 'temperature', 'hot', 'cold'],
  sheet: [5, 32],
  shortName: 'thermometer'
}, {
  name: 'Black Sun with Rays',
  unified: '2600-FE0F',
  keywords: ['sun', 'weather', 'nature', 'brightness', 'summer', 'beach', 'spring'],
  sheet: [56, 40],
  shortName: 'sunny'
}, {
  name: 'Full Moon with Face',
  unified: '1F31D',
  keywords: ['full_moon_face', 'nature', 'twilight', 'planet', 'space', 'night', 'evening', 'sleep'],
  sheet: [5, 28],
  shortName: 'full_moon_with_face'
}, {
  name: 'Sun with Face',
  unified: '1F31E',
  keywords: ['sun_with_face', 'nature', 'morning', 'sky'],
  sheet: [5, 29],
  shortName: 'sun_with_face'
}, {
  name: 'Ringed Planet',
  unified: '1FA90',
  keywords: ['ringed_planet', 'outerspace'],
  sheet: [54, 2],
  shortName: 'ringed_planet'
}, {
  name: 'White Medium Star',
  unified: '2B50',
  keywords: ['star', 'night', 'yellow'],
  sheet: [59, 24],
  shortName: 'star'
}, {
  name: 'Glowing Star',
  unified: '1F31F',
  keywords: ['glowing_star', 'night', 'sparkle', 'awesome', 'good', 'magic'],
  sheet: [5, 30],
  shortName: 'star2'
}, {
  name: 'Shooting Star',
  unified: '1F320',
  keywords: ['shooting_star', 'night', 'photo'],
  sheet: [5, 31],
  shortName: 'stars'
}, {
  name: 'Milky Way',
  unified: '1F30C',
  keywords: ['milky_way', 'photo', 'space', 'stars'],
  sheet: [5, 11],
  shortName: 'milky_way'
}, {
  name: 'Cloud',
  unified: '2601-FE0F',
  keywords: ['cloud', 'weather', 'sky'],
  sheet: [56, 41],
  shortName: 'cloud'
}, {
  name: 'Sun Behind Cloud',
  unified: '26C5',
  keywords: ['sun_behind_cloud', 'weather', 'nature', 'cloudy', 'morning', 'fall', 'spring'],
  sheet: [57, 47],
  shortName: 'partly_sunny'
}, {
  name: 'Cloud with Lightning and Rain',
  unified: '26C8-FE0F',
  keywords: ['cloud_with_lightning_and_rain', 'weather', 'lightning'],
  sheet: [57, 48],
  shortName: 'thunder_cloud_and_rain'
}, {
  name: 'Sun Behind Small Cloud',
  unified: '1F324-FE0F',
  keywords: ['sun_behind_small_cloud', 'weather'],
  sheet: [5, 33],
  shortNames: ['sun_small_cloud'],
  shortName: 'mostly_sunny'
}, {
  name: 'Sun Behind Large Cloud',
  unified: '1F325-FE0F',
  keywords: ['sun_behind_large_cloud', 'weather'],
  sheet: [5, 34],
  shortNames: ['sun_behind_cloud'],
  shortName: 'barely_sunny'
}, {
  name: 'Sun Behind Rain Cloud',
  unified: '1F326-FE0F',
  keywords: ['sun_behind_rain_cloud', 'weather'],
  sheet: [5, 35],
  shortNames: ['sun_behind_rain_cloud'],
  shortName: 'partly_sunny_rain'
}, {
  name: 'Cloud with Rain',
  unified: '1F327-FE0F',
  keywords: ['cloud_with_rain', 'weather'],
  sheet: [5, 36],
  shortName: 'rain_cloud'
}, {
  name: 'Cloud with Snow',
  unified: '1F328-FE0F',
  keywords: ['cloud_with_snow', 'weather'],
  sheet: [5, 37],
  shortName: 'snow_cloud'
}, {
  name: 'Cloud with Lightning',
  unified: '1F329-FE0F',
  keywords: ['cloud_with_lightning', 'weather', 'thunder'],
  sheet: [5, 38],
  shortNames: ['lightning_cloud'],
  shortName: 'lightning'
}, {
  name: 'Tornado',
  unified: '1F32A-FE0F',
  keywords: ['tornado', 'weather', 'cyclone', 'twister'],
  sheet: [5, 39],
  shortNames: ['tornado_cloud'],
  shortName: 'tornado'
}, {
  name: 'Fog',
  unified: '1F32B-FE0F',
  keywords: ['fog', 'weather'],
  sheet: [5, 40],
  shortName: 'fog'
}, {
  name: 'Wind Face',
  unified: '1F32C-FE0F',
  keywords: ['wind_face', 'gust', 'air'],
  sheet: [5, 41],
  shortName: 'wind_blowing_face'
}, {
  name: 'Cyclone',
  unified: '1F300',
  keywords: ['cyclone', 'weather', 'swirl', 'blue', 'cloud', 'vortex', 'spiral', 'whirlpool', 'spin', 'tornado', 'hurricane', 'typhoon'],
  sheet: [4, 60],
  shortName: 'cyclone'
}, {
  name: 'Rainbow',
  unified: '1F308',
  keywords: ['rainbow', 'nature', 'happy', 'unicorn_face', 'photo', 'sky', 'spring'],
  sheet: [5, 7],
  shortName: 'rainbow'
}, {
  name: 'Closed Umbrella',
  unified: '1F302',
  keywords: ['closed_umbrella', 'weather', 'rain', 'drizzle'],
  sheet: [5, 1],
  shortName: 'closed_umbrella'
}, {
  name: 'Umbrella',
  unified: '2602-FE0F',
  keywords: ['umbrella', 'weather', 'spring'],
  sheet: [56, 42],
  shortName: 'umbrella'
}, {
  name: 'Umbrella with Rain Drops',
  unified: '2614',
  keywords: ['umbrella_with_rain_drops', 'rainy', 'weather', 'spring'],
  sheet: [56, 47],
  shortName: 'umbrella_with_rain_drops'
}, {
  name: 'Umbrella on Ground',
  unified: '26F1-FE0F',
  keywords: ['umbrella_on_ground', 'weather', 'summer'],
  sheet: [57, 57],
  shortName: 'umbrella_on_ground'
}, {
  name: 'High Voltage Sign',
  unified: '26A1',
  keywords: ['high_voltage', 'thunder', 'weather', 'lightning bolt', 'fast'],
  sheet: [57, 38],
  shortName: 'zap'
}, {
  name: 'Snowflake',
  unified: '2744-FE0F',
  keywords: ['snowflake', 'winter', 'season', 'cold', 'weather', 'christmas', 'xmas'],
  sheet: [58, 60],
  shortName: 'snowflake'
}, {
  name: 'Snowman',
  unified: '2603-FE0F',
  keywords: ['snowman', 'winter', 'season', 'cold', 'weather', 'christmas', 'xmas', 'frozen'],
  sheet: [56, 43],
  shortName: 'snowman'
}, {
  name: 'Snowman Without Snow',
  unified: '26C4',
  keywords: ['snowman_without_snow', 'winter', 'season', 'cold', 'weather', 'christmas', 'xmas', 'frozen', 'without_snow'],
  sheet: [57, 46],
  shortName: 'snowman_without_snow'
}, {
  name: 'Comet',
  unified: '2604-FE0F',
  keywords: ['comet', 'space'],
  sheet: [56, 44],
  shortName: 'comet'
}, {
  name: 'Fire',
  unified: '1F525',
  keywords: ['fire', 'hot', 'cook', 'flame'],
  sheet: [30, 1],
  shortName: 'fire'
}, {
  name: 'Droplet',
  unified: '1F4A7',
  keywords: ['droplet', 'water', 'drip', 'faucet', 'spring'],
  sheet: [27, 54],
  shortName: 'droplet'
}, {
  name: 'Water Wave',
  unified: '1F30A',
  keywords: ['water_wave', 'sea', 'water', 'wave', 'nature', 'tsunami', 'disaster'],
  sheet: [5, 9],
  shortName: 'ocean'
}, {
  name: 'Jack-O-Lantern',
  unified: '1F383',
  keywords: ['jack_o_lantern', 'halloween', 'light', 'pumpkin', 'creepy', 'fall'],
  sheet: [7, 6],
  shortName: 'jack_o_lantern'
}, {
  name: 'Christmas Tree',
  unified: '1F384',
  keywords: ['christmas_tree', 'festival', 'vacation', 'december', 'xmas', 'celebration'],
  sheet: [7, 7],
  shortName: 'christmas_tree'
}, {
  name: 'Fireworks',
  unified: '1F386',
  keywords: ['fireworks', 'photo', 'festival', 'carnival', 'congratulations'],
  sheet: [7, 14],
  shortName: 'fireworks'
}, {
  name: 'Firework Sparkler',
  unified: '1F387',
  keywords: ['sparkler', 'stars', 'night', 'shine'],
  sheet: [7, 15],
  shortName: 'sparkler'
}, {
  name: 'Firecracker',
  unified: '1F9E8',
  keywords: ['firecracker', 'dynamite', 'boom', 'explode', 'explosion', 'explosive'],
  sheet: [53, 22],
  shortName: 'firecracker'
}, {
  name: 'Sparkles',
  unified: '2728',
  keywords: ['sparkles', 'stars', 'shine', 'shiny', 'cool', 'awesome', 'good', 'magic'],
  sheet: [58, 57],
  shortName: 'sparkles'
}, {
  name: 'Balloon',
  unified: '1F388',
  keywords: ['balloon', 'party', 'celebration', 'birthday', 'circus'],
  sheet: [7, 16],
  shortName: 'balloon'
}, {
  name: 'Party Popper',
  unified: '1F389',
  keywords: ['party_popper', 'party', 'congratulations', 'birthday', 'magic', 'circus', 'celebration', 'tada'],
  sheet: [7, 17],
  shortName: 'tada'
}, {
  name: 'Confetti Ball',
  unified: '1F38A',
  keywords: ['confetti_ball', 'festival', 'party', 'birthday', 'circus'],
  sheet: [7, 18],
  shortName: 'confetti_ball'
}, {
  name: 'Tanabata Tree',
  unified: '1F38B',
  keywords: ['tanabata_tree', 'plant', 'nature', 'branch', 'summer', 'bamboo', 'wish', 'star_festival', 'tanzaku'],
  sheet: [7, 19],
  shortName: 'tanabata_tree'
}, {
  name: 'Pine Decoration',
  unified: '1F38D',
  keywords: ['pine_decoration', 'japanese', 'plant', 'nature', 'vegetable', 'panda', 'new_years', 'bamboo'],
  sheet: [7, 21],
  shortName: 'bamboo'
}, {
  name: 'Japanese Dolls',
  unified: '1F38E',
  keywords: ['japanese_dolls', 'japanese', 'toy', 'kimono'],
  sheet: [7, 22],
  shortName: 'dolls'
}, {
  name: 'Carp Streamer',
  unified: '1F38F',
  keywords: ['carp_streamer', 'fish', 'japanese', 'koinobori', 'carp', 'banner'],
  sheet: [7, 23],
  shortName: 'flags'
}, {
  name: 'Wind Chime',
  unified: '1F390',
  keywords: ['wind_chime', 'nature', 'ding', 'spring', 'bell'],
  sheet: [7, 24],
  shortName: 'wind_chime'
}, {
  name: 'Moon Viewing Ceremony',
  unified: '1F391',
  keywords: ['moon_viewing_ceremony', 'photo', 'japan', 'asia', 'tsukimi'],
  sheet: [7, 25],
  shortName: 'rice_scene'
}, {
  name: 'Red Gift Envelope',
  unified: '1F9E7',
  keywords: ['red_envelope', 'gift'],
  sheet: [53, 21],
  shortName: 'red_envelope'
}, {
  name: 'Ribbon',
  unified: '1F380',
  keywords: ['ribbon', 'decoration', 'pink', 'girl', 'bowtie'],
  sheet: [7, 3],
  shortName: 'ribbon'
}, {
  name: 'Wrapped Present',
  unified: '1F381',
  keywords: ['wrapped_gift', 'present', 'birthday', 'christmas', 'xmas'],
  sheet: [7, 4],
  shortName: 'gift'
}, {
  name: 'Reminder Ribbon',
  unified: '1F397-FE0F',
  keywords: ['reminder_ribbon', 'sports', 'cause', 'support', 'awareness'],
  sheet: [7, 29],
  shortName: 'reminder_ribbon'
}, {
  name: 'Admission Tickets',
  unified: '1F39F-FE0F',
  keywords: ['admission_tickets', 'sports', 'concert', 'entrance'],
  sheet: [7, 34],
  shortName: 'admission_tickets'
}, {
  name: 'Ticket',
  unified: '1F3AB',
  keywords: ['ticket', 'event', 'concert', 'pass'],
  sheet: [7, 46],
  shortName: 'ticket'
}, {
  name: 'Military Medal',
  unified: '1F396-FE0F',
  keywords: ['military_medal', 'award', 'winning', 'army'],
  sheet: [7, 28],
  shortName: 'medal'
}, {
  name: 'Trophy',
  unified: '1F3C6',
  keywords: ['trophy', 'win', 'award', 'contest', 'place', 'ftw', 'ceremony'],
  sheet: [8, 51],
  shortName: 'trophy'
}, {
  name: 'Sports Medal',
  unified: '1F3C5',
  keywords: ['sports_medal', 'award', 'winning'],
  sheet: [8, 50],
  shortName: 'sports_medal'
}, {
  name: 'First Place Medal',
  unified: '1F947',
  keywords: ['1st_place_medal', 'award', 'winning', 'first'],
  sheet: [43, 17],
  shortName: 'first_place_medal'
}, {
  name: 'Second Place Medal',
  unified: '1F948',
  keywords: ['2nd_place_medal', 'award', 'second'],
  sheet: [43, 18],
  shortName: 'second_place_medal'
}, {
  name: 'Third Place Medal',
  unified: '1F949',
  keywords: ['3rd_place_medal', 'award', 'third'],
  sheet: [43, 19],
  shortName: 'third_place_medal'
}, {
  name: 'Soccer Ball',
  unified: '26BD',
  keywords: ['soccer_ball', 'sports', 'football'],
  sheet: [57, 44],
  shortName: 'soccer'
}, {
  name: 'Baseball',
  unified: '26BE',
  keywords: ['baseball', 'sports', 'balls'],
  sheet: [57, 45],
  shortName: 'baseball'
}, {
  name: 'Softball',
  unified: '1F94E',
  keywords: ['softball', 'sports', 'balls'],
  sheet: [43, 24],
  shortName: 'softball'
}, {
  name: 'Basketball and Hoop',
  unified: '1F3C0',
  keywords: ['basketball', 'sports', 'balls', 'NBA'],
  sheet: [8, 6],
  shortName: 'basketball'
}, {
  name: 'Volleyball',
  unified: '1F3D0',
  keywords: ['volleyball', 'sports', 'balls'],
  sheet: [9, 56],
  shortName: 'volleyball'
}, {
  name: 'American Football',
  unified: '1F3C8',
  keywords: ['american_football', 'sports', 'balls', 'NFL'],
  sheet: [8, 58],
  shortName: 'football'
}, {
  name: 'Rugby Football',
  unified: '1F3C9',
  keywords: ['rugby_football', 'sports', 'team'],
  sheet: [8, 59],
  shortName: 'rugby_football'
}, {
  name: 'Tennis Racquet and Ball',
  unified: '1F3BE',
  keywords: ['tennis', 'sports', 'balls', 'green'],
  sheet: [8, 4],
  shortName: 'tennis'
}, {
  name: 'Flying Disc',
  unified: '1F94F',
  keywords: ['flying_disc', 'sports', 'frisbee', 'ultimate'],
  sheet: [43, 25],
  shortName: 'flying_disc'
}, {
  name: 'Bowling',
  unified: '1F3B3',
  keywords: ['bowling', 'sports', 'fun', 'play'],
  sheet: [7, 54],
  shortName: 'bowling'
}, {
  name: 'Cricket Bat and Ball',
  unified: '1F3CF',
  keywords: ['cricket_game', 'sports'],
  sheet: [9, 55],
  shortName: 'cricket_bat_and_ball'
}, {
  name: 'Field Hockey Stick and Ball',
  unified: '1F3D1',
  keywords: ['field_hockey', 'sports'],
  sheet: [9, 57],
  shortName: 'field_hockey_stick_and_ball'
}, {
  name: 'Ice Hockey Stick and Puck',
  unified: '1F3D2',
  keywords: ['ice_hockey', 'sports'],
  sheet: [9, 58],
  shortName: 'ice_hockey_stick_and_puck'
}, {
  name: 'Lacrosse Stick and Ball',
  unified: '1F94D',
  keywords: ['lacrosse', 'sports', 'ball', 'stick'],
  sheet: [43, 23],
  shortName: 'lacrosse'
}, {
  name: 'Table Tennis Paddle and Ball',
  unified: '1F3D3',
  keywords: ['ping_pong', 'sports', 'pingpong'],
  sheet: [9, 59],
  shortName: 'table_tennis_paddle_and_ball'
}, {
  name: 'Badminton Racquet and Shuttlecock',
  unified: '1F3F8',
  keywords: ['badminton', 'sports'],
  sheet: [10, 38],
  shortName: 'badminton_racquet_and_shuttlecock'
}, {
  name: 'Boxing Glove',
  unified: '1F94A',
  keywords: ['boxing_glove', 'sports', 'fighting'],
  sheet: [43, 20],
  shortName: 'boxing_glove'
}, {
  name: 'Martial Arts Uniform',
  unified: '1F94B',
  keywords: ['martial_arts_uniform', 'judo', 'karate', 'taekwondo'],
  sheet: [43, 21],
  shortName: 'martial_arts_uniform'
}, {
  name: 'Goal Net',
  unified: '1F945',
  keywords: ['goal_net', 'sports'],
  sheet: [43, 16],
  shortName: 'goal_net'
}, {
  name: 'Flag in Hole',
  unified: '26F3',
  keywords: ['flag_in_hole', 'sports', 'business', 'flag', 'hole', 'summer'],
  sheet: [57, 59],
  shortName: 'golf'
}, {
  name: 'Ice Skate',
  unified: '26F8-FE0F',
  keywords: ['ice_skate', 'sports'],
  sheet: [58, 2],
  shortName: 'ice_skate'
}, {
  name: 'Fishing Pole and Fish',
  unified: '1F3A3',
  keywords: ['fishing_pole', 'food', 'hobby', 'summer'],
  sheet: [7, 38],
  shortName: 'fishing_pole_and_fish'
}, {
  name: 'Diving Mask',
  unified: '1F93F',
  keywords: ['diving_mask', 'sport', 'ocean'],
  sheet: [43, 10],
  shortName: 'diving_mask'
}, {
  name: 'Running Shirt with Sash',
  unified: '1F3BD',
  keywords: ['running_shirt', 'play', 'pageant'],
  sheet: [8, 3],
  shortName: 'running_shirt_with_sash'
}, {
  name: 'Ski and Ski Boot',
  unified: '1F3BF',
  keywords: ['skis', 'sports', 'winter', 'cold', 'snow'],
  sheet: [8, 5],
  shortName: 'ski'
}, {
  name: 'Sled',
  unified: '1F6F7',
  keywords: ['sled', 'sleigh', 'luge', 'toboggan'],
  sheet: [38, 25],
  shortName: 'sled'
}, {
  name: 'Curling Stone',
  unified: '1F94C',
  keywords: ['curling_stone', 'sports'],
  sheet: [43, 22],
  shortName: 'curling_stone'
}, {
  name: 'Direct Hit',
  unified: '1F3AF',
  keywords: ['direct_hit', 'game', 'play', 'bar', 'target', 'bullseye'],
  sheet: [7, 50],
  shortName: 'dart'
}, {
  name: 'Yo-Yo',
  unified: '1FA80',
  keywords: ['yo_yo', 'toy'],
  sheet: [53, 56],
  shortName: 'yo-yo'
}, {
  name: 'Kite',
  unified: '1FA81',
  keywords: ['kite', 'wind', 'fly'],
  sheet: [53, 57],
  shortName: 'kite'
}, {
  name: 'Billiards',
  unified: '1F3B1',
  keywords: ['pool_8_ball', 'pool', 'hobby', 'game', 'luck', 'magic'],
  sheet: [7, 52],
  shortName: '8ball'
}, {
  name: 'Crystal Ball',
  unified: '1F52E',
  keywords: ['crystal_ball', 'disco', 'party', 'magic', 'circus', 'fortune_teller'],
  sheet: [30, 10],
  shortName: 'crystal_ball'
}, {
  name: 'Magic Wand',
  unified: '1FA84',
  keywords: ['magic wand', 'supernature', 'power'],
  sheet: [53, 60],
  shortName: 'magic_wand'
}, {
  name: 'Nazar Amulet',
  unified: '1F9FF',
  keywords: ['nazar_amulet', 'bead', 'charm'],
  sheet: [53, 45],
  shortName: 'nazar_amulet'
}, {
  name: 'Hamsa',
  unified: '1FAAC',
  keywords: ['hamsa', 'religion', 'protection'],
  sheet: [54, 30],
  hidden: ['facebook'],
  shortName: 'hamsa'
}, {
  name: 'Video Game',
  unified: '1F3AE',
  keywords: ['video_game', 'play', 'console', 'PS4', 'controller'],
  sheet: [7, 49],
  shortName: 'video_game'
}, {
  name: 'Joystick',
  unified: '1F579-FE0F',
  keywords: ['joystick', 'game', 'play'],
  sheet: [31, 25],
  shortName: 'joystick'
}, {
  name: 'Slot Machine',
  unified: '1F3B0',
  keywords: ['slot_machine', 'bet', 'gamble', 'vegas', 'fruit machine', 'luck', 'casino'],
  sheet: [7, 51],
  shortName: 'slot_machine'
}, {
  name: 'Game Die',
  unified: '1F3B2',
  keywords: ['game_die', 'dice', 'random', 'tabletop', 'play', 'luck'],
  sheet: [7, 53],
  shortName: 'game_die'
}, {
  name: 'Jigsaw Puzzle Piece',
  unified: '1F9E9',
  keywords: ['puzzle_piece', 'interlocking', 'puzzle', 'piece'],
  sheet: [53, 23],
  shortName: 'jigsaw'
}, {
  name: 'Teddy Bear',
  unified: '1F9F8',
  keywords: ['teddy_bear', 'plush', 'stuffed'],
  sheet: [53, 38],
  shortName: 'teddy_bear'
}, {
  name: 'Pinata',
  unified: '1FA85',
  keywords: ['pinata', 'mexico', 'candy', 'celebration'],
  sheet: [54, 0],
  shortName: 'pinata'
}, {
  name: 'Mirror Ball',
  unified: '1FAA9',
  keywords: ['mirror ball', 'disco', 'dance', 'party'],
  sheet: [54, 27],
  hidden: ['facebook'],
  shortName: 'mirror_ball'
}, {
  name: 'Nesting Dolls',
  unified: '1FA86',
  keywords: ['nesting dolls', 'matryoshka', 'toy'],
  sheet: [54, 1],
  shortName: 'nesting_dolls'
}, {
  name: 'Black Spade Suit',
  unified: '2660-FE0F',
  keywords: ['spade_suit', 'poker', 'cards', 'suits', 'magic'],
  sheet: [57, 20],
  shortName: 'spades'
}, {
  name: 'Black Heart Suit',
  unified: '2665-FE0F',
  keywords: ['heart_suit', 'poker', 'cards', 'magic', 'suits'],
  sheet: [57, 22],
  shortName: 'hearts'
}, {
  name: 'Black Diamond Suit',
  unified: '2666-FE0F',
  keywords: ['diamond_suit', 'poker', 'cards', 'magic', 'suits'],
  sheet: [57, 23],
  shortName: 'diamonds'
}, {
  name: 'Black Club Suit',
  unified: '2663-FE0F',
  keywords: ['club_suit', 'poker', 'cards', 'magic', 'suits'],
  sheet: [57, 21],
  shortName: 'clubs'
}, {
  name: 'Chess Pawn',
  unified: '265F-FE0F',
  keywords: ['chess_pawn', 'expendable'],
  sheet: [57, 19],
  shortName: 'chess_pawn'
}, {
  name: 'Playing Card Black Joker',
  unified: '1F0CF',
  keywords: ['joker', 'poker', 'cards', 'game', 'play', 'magic'],
  sheet: [0, 15],
  shortName: 'black_joker'
}, {
  name: 'Mahjong Tile Red Dragon',
  unified: '1F004',
  keywords: ['mahjong_red_dragon', 'game', 'play', 'chinese', 'kanji'],
  sheet: [0, 14],
  shortName: 'mahjong'
}, {
  name: 'Flower Playing Cards',
  unified: '1F3B4',
  keywords: ['flower_playing_cards', 'game', 'sunset', 'red'],
  sheet: [7, 55],
  shortName: 'flower_playing_cards'
}, {
  name: 'Performing Arts',
  unified: '1F3AD',
  keywords: ['performing_arts', 'acting', 'theater', 'drama'],
  sheet: [7, 48],
  shortName: 'performing_arts'
}, {
  name: 'Framed Picture',
  unified: '1F5BC-FE0F',
  keywords: ['framed_picture', 'photography'],
  sheet: [31, 60],
  shortName: 'frame_with_picture'
}, {
  name: 'Artist Palette',
  unified: '1F3A8',
  keywords: ['artist_palette', 'design', 'paint', 'draw', 'colors'],
  sheet: [7, 43],
  shortName: 'art'
}, {
  name: 'Spool of Thread',
  unified: '1F9F5',
  keywords: ['thread', 'needle', 'sewing', 'spool', 'string'],
  sheet: [53, 35],
  shortName: 'thread'
}, {
  name: 'Sewing Needle',
  unified: '1FAA1',
  keywords: ['sewing needle', 'stitches'],
  sheet: [54, 19],
  shortName: 'sewing_needle'
}, {
  name: 'Ball of Yarn',
  unified: '1F9F6',
  keywords: ['yarn', 'ball', 'crochet', 'knit'],
  sheet: [53, 36],
  shortName: 'yarn'
}, {
  name: 'Knot',
  unified: '1FAA2',
  keywords: ['knot', 'rope', 'scout'],
  sheet: [54, 20],
  shortName: 'knot'
}, {
  name: 'Eyeglasses',
  unified: '1F453',
  keywords: ['glasses', 'fashion', 'accessories', 'eyesight', 'nerdy', 'dork', 'geek'],
  sheet: [13, 15],
  shortName: 'eyeglasses'
}, {
  name: 'Sunglasses',
  unified: '1F576-FE0F',
  keywords: ['sunglasses', 'face', 'cool', 'accessories'],
  sheet: [31, 22],
  shortName: 'dark_sunglasses'
}, {
  name: 'Goggles',
  unified: '1F97D',
  keywords: ['goggles', 'eyes', 'protection', 'safety'],
  sheet: [44, 15],
  shortName: 'goggles'
}, {
  name: 'Lab Coat',
  unified: '1F97C',
  keywords: ['lab_coat', 'doctor', 'experiment', 'scientist', 'chemist'],
  sheet: [44, 14],
  shortName: 'lab_coat'
}, {
  name: 'Safety Vest',
  unified: '1F9BA',
  keywords: ['safety_vest', 'protection'],
  sheet: [45, 55],
  shortName: 'safety_vest'
}, {
  name: 'Necktie',
  unified: '1F454',
  keywords: ['necktie', 'shirt', 'suitup', 'formal', 'fashion', 'cloth', 'business'],
  sheet: [13, 16],
  shortName: 'necktie'
}, {
  name: 'T-Shirt',
  unified: '1F455',
  keywords: ['t_shirt', 'fashion', 'cloth', 'casual', 'shirt', 'tee'],
  sheet: [13, 17],
  shortNames: ['tshirt'],
  shortName: 'shirt'
}, {
  name: 'Jeans',
  unified: '1F456',
  keywords: ['jeans', 'fashion', 'shopping'],
  sheet: [13, 18],
  shortName: 'jeans'
}, {
  name: 'Scarf',
  unified: '1F9E3',
  keywords: ['scarf', 'neck', 'winter', 'clothes'],
  sheet: [53, 17],
  shortName: 'scarf'
}, {
  name: 'Gloves',
  unified: '1F9E4',
  keywords: ['gloves', 'hands', 'winter', 'clothes'],
  sheet: [53, 18],
  shortName: 'gloves'
}, {
  name: 'Coat',
  unified: '1F9E5',
  keywords: ['coat', 'jacket'],
  sheet: [53, 19],
  shortName: 'coat'
}, {
  name: 'Socks',
  unified: '1F9E6',
  keywords: ['socks', 'stockings', 'clothes'],
  sheet: [53, 20],
  shortName: 'socks'
}, {
  name: 'Dress',
  unified: '1F457',
  keywords: ['dress', 'clothes', 'fashion', 'shopping'],
  sheet: [13, 19],
  shortName: 'dress'
}, {
  name: 'Kimono',
  unified: '1F458',
  keywords: ['kimono', 'dress', 'fashion', 'women', 'female', 'japanese'],
  sheet: [13, 20],
  shortName: 'kimono'
}, {
  name: 'Sari',
  unified: '1F97B',
  keywords: ['sari', 'dress'],
  sheet: [44, 13],
  shortName: 'sari'
}, {
  name: 'One-Piece Swimsuit',
  unified: '1FA71',
  keywords: ['one_piece_swimsuit', 'fashion'],
  sheet: [53, 47],
  shortName: 'one-piece_swimsuit'
}, {
  name: 'Briefs',
  unified: '1FA72',
  keywords: ['briefs', 'clothing'],
  sheet: [53, 48],
  shortName: 'briefs'
}, {
  name: 'Shorts',
  unified: '1FA73',
  keywords: ['shorts', 'clothing'],
  sheet: [53, 49],
  shortName: 'shorts'
}, {
  name: 'Bikini',
  unified: '1F459',
  keywords: ['bikini', 'swimming', 'female', 'woman', 'girl', 'fashion', 'beach', 'summer'],
  sheet: [13, 21],
  shortName: 'bikini'
}, {
  name: 'Womans Clothes',
  unified: '1F45A',
  keywords: ['woman_s_clothes', 'fashion', 'shopping_bags', 'female'],
  sheet: [13, 22],
  shortName: 'womans_clothes'
}, {
  name: 'Purse',
  unified: '1F45B',
  keywords: ['purse', 'fashion', 'accessories', 'money', 'sales', 'shopping'],
  sheet: [13, 23],
  shortName: 'purse'
}, {
  name: 'Handbag',
  unified: '1F45C',
  keywords: ['handbag', 'fashion', 'accessory', 'accessories', 'shopping'],
  sheet: [13, 24],
  shortName: 'handbag'
}, {
  name: 'Pouch',
  unified: '1F45D',
  keywords: ['clutch_bag', 'bag', 'accessories', 'shopping'],
  sheet: [13, 25],
  shortName: 'pouch'
}, {
  name: 'Shopping Bags',
  unified: '1F6CD-FE0F',
  keywords: ['shopping_bags', 'mall', 'buy', 'purchase'],
  sheet: [37, 60],
  shortName: 'shopping_bags'
}, {
  name: 'School Satchel',
  unified: '1F392',
  keywords: ['backpack', 'student', 'education', 'bag', 'backpack'],
  sheet: [7, 26],
  shortName: 'school_satchel'
}, {
  name: 'Thong Sandal',
  unified: '1FA74',
  keywords: ['thong sandal', 'footwear', 'summer'],
  sheet: [53, 50],
  shortName: 'thong_sandal'
}, {
  name: 'Mans Shoe',
  unified: '1F45E',
  keywords: ['man_s_shoe', 'fashion', 'male'],
  sheet: [13, 26],
  shortNames: ['shoe'],
  shortName: 'mans_shoe'
}, {
  name: 'Athletic Shoe',
  unified: '1F45F',
  keywords: ['running_shoe', 'shoes', 'sports', 'sneakers'],
  sheet: [13, 27],
  shortName: 'athletic_shoe'
}, {
  name: 'Hiking Boot',
  unified: '1F97E',
  keywords: ['hiking_boot', 'backpacking', 'camping', 'hiking'],
  sheet: [44, 16],
  shortName: 'hiking_boot'
}, {
  name: 'Flat Shoe',
  unified: '1F97F',
  keywords: ['flat_shoe', 'ballet', 'slip-on', 'slipper'],
  sheet: [44, 17],
  shortName: 'womans_flat_shoe'
}, {
  name: 'High-Heeled Shoe',
  unified: '1F460',
  keywords: ['high_heeled_shoe', 'fashion', 'shoes', 'female', 'pumps', 'stiletto'],
  sheet: [13, 28],
  shortName: 'high_heel'
}, {
  name: 'Womans Sandal',
  unified: '1F461',
  keywords: ['woman_s_sandal', 'shoes', 'fashion', 'flip flops'],
  sheet: [13, 29],
  shortName: 'sandal'
}, {
  name: 'Ballet Shoes',
  unified: '1FA70',
  keywords: ['ballet_shoes', 'dance'],
  sheet: [53, 46],
  shortName: 'ballet_shoes'
}, {
  name: 'Womans Boots',
  unified: '1F462',
  keywords: ['woman_s_boot', 'shoes', 'fashion'],
  sheet: [13, 30],
  shortName: 'boot'
}, {
  name: 'Crown',
  unified: '1F451',
  keywords: ['crown', 'king', 'kod', 'leader', 'royalty', 'lord'],
  sheet: [13, 13],
  shortName: 'crown'
}, {
  name: 'Womans Hat',
  unified: '1F452',
  keywords: ['woman_s_hat', 'fashion', 'accessories', 'female', 'lady', 'spring'],
  sheet: [13, 14],
  shortName: 'womans_hat'
}, {
  name: 'Top Hat',
  unified: '1F3A9',
  keywords: ['top_hat', 'magic', 'gentleman', 'classy', 'circus'],
  sheet: [7, 44],
  shortName: 'tophat'
}, {
  name: 'Graduation Cap',
  unified: '1F393',
  keywords: ['graduation_cap', 'school', 'college', 'degree', 'university', 'graduation', 'cap', 'hat', 'legal', 'learn', 'education'],
  sheet: [7, 27],
  shortName: 'mortar_board'
}, {
  name: 'Billed Cap',
  unified: '1F9E2',
  keywords: ['billed_cap', 'cap', 'baseball'],
  sheet: [53, 16],
  shortName: 'billed_cap'
}, {
  name: 'Military Helmet',
  unified: '1FA96',
  keywords: ['military helmet', 'army', 'protection'],
  sheet: [54, 8],
  shortName: 'military_helmet'
}, {
  name: 'Rescue Worker’s Helmet',
  unified: '26D1-FE0F',
  keywords: ['rescue_worker_s_helmet', 'construction', 'build'],
  sheet: [57, 51],
  shortName: 'helmet_with_white_cross'
}, {
  name: 'Prayer Beads',
  unified: '1F4FF',
  keywords: ['prayer_beads', 'dhikr', 'religious'],
  sheet: [29, 24],
  shortName: 'prayer_beads'
}, {
  name: 'Lipstick',
  unified: '1F484',
  keywords: ['lipstick', 'female', 'girl', 'fashion', 'woman'],
  sheet: [25, 52],
  shortName: 'lipstick'
}, {
  name: 'Ring',
  unified: '1F48D',
  keywords: ['ring', 'wedding', 'propose', 'marriage', 'valentines', 'diamond', 'fashion', 'jewelry', 'gem', 'engagement'],
  sheet: [26, 39],
  shortName: 'ring'
}, {
  name: 'Gem Stone',
  unified: '1F48E',
  keywords: ['gem_stone', 'blue', 'ruby', 'diamond', 'jewelry'],
  sheet: [26, 40],
  shortName: 'gem'
}, {
  name: 'Speaker with Cancellation Stroke',
  unified: '1F507',
  keywords: ['muted_speaker', 'sound', 'volume', 'silence', 'quiet'],
  sheet: [29, 32],
  shortName: 'mute'
}, {
  name: 'Speaker',
  unified: '1F508',
  keywords: ['speaker_low_volume', 'sound', 'volume', 'silence', 'broadcast'],
  sheet: [29, 33],
  shortName: 'speaker'
}, {
  name: 'Speaker with One Sound Wave',
  unified: '1F509',
  keywords: ['speaker_medium_volume', 'volume', 'speaker', 'broadcast'],
  sheet: [29, 34],
  shortName: 'sound'
}, {
  name: 'Speaker with Three Sound Waves',
  unified: '1F50A',
  keywords: ['speaker_high_volume', 'volume', 'noise', 'noisy', 'speaker', 'broadcast'],
  sheet: [29, 35],
  shortName: 'loud_sound'
}, {
  name: 'Public Address Loudspeaker',
  unified: '1F4E2',
  keywords: ['loudspeaker', 'volume', 'sound'],
  sheet: [28, 57],
  shortName: 'loudspeaker'
}, {
  name: 'Cheering Megaphone',
  unified: '1F4E3',
  keywords: ['megaphone', 'sound', 'speaker', 'volume'],
  sheet: [28, 58],
  shortName: 'mega'
}, {
  name: 'Postal Horn',
  unified: '1F4EF',
  keywords: ['postal_horn', 'instrument', 'music'],
  sheet: [29, 9],
  shortName: 'postal_horn'
}, {
  name: 'Bell',
  unified: '1F514',
  keywords: ['bell', 'sound', 'notification', 'christmas', 'xmas', 'chime'],
  sheet: [29, 45],
  shortName: 'bell'
}, {
  name: 'Bell with Cancellation Stroke',
  unified: '1F515',
  keywords: ['bell_with_slash', 'sound', 'volume', 'mute', 'quiet', 'silent'],
  sheet: [29, 46],
  shortName: 'no_bell'
}, {
  name: 'Musical Score',
  unified: '1F3BC',
  keywords: ['musical_score', 'treble', 'clef', 'compose'],
  sheet: [8, 2],
  shortName: 'musical_score'
}, {
  name: 'Musical Note',
  unified: '1F3B5',
  keywords: ['musical_note', 'score', 'tone', 'sound'],
  sheet: [7, 56],
  shortName: 'musical_note'
}, {
  name: 'Multiple Musical Notes',
  unified: '1F3B6',
  keywords: ['musical_notes', 'music', 'score'],
  sheet: [7, 57],
  shortName: 'notes'
}, {
  name: 'Studio Microphone',
  unified: '1F399-FE0F',
  keywords: ['studio_microphone', 'sing', 'recording', 'artist', 'talkshow'],
  sheet: [7, 30],
  shortName: 'studio_microphone'
}, {
  name: 'Level Slider',
  unified: '1F39A-FE0F',
  keywords: ['level_slider', 'scale'],
  sheet: [7, 31],
  shortName: 'level_slider'
}, {
  name: 'Control Knobs',
  unified: '1F39B-FE0F',
  keywords: ['control_knobs', 'dial'],
  sheet: [7, 32],
  shortName: 'control_knobs'
}, {
  name: 'Microphone',
  unified: '1F3A4',
  keywords: ['microphone', 'sound', 'music', 'PA', 'sing', 'talkshow'],
  sheet: [7, 39],
  shortName: 'microphone'
}, {
  name: 'Headphone',
  unified: '1F3A7',
  keywords: ['headphone', 'music', 'score', 'gadgets'],
  sheet: [7, 42],
  shortName: 'headphones'
}, {
  name: 'Radio',
  unified: '1F4FB',
  keywords: ['radio', 'communication', 'music', 'podcast', 'program'],
  sheet: [29, 21],
  shortName: 'radio'
}, {
  name: 'Saxophone',
  unified: '1F3B7',
  keywords: ['saxophone', 'music', 'instrument', 'jazz', 'blues'],
  sheet: [7, 58],
  shortName: 'saxophone'
}, {
  name: 'Accordion',
  unified: '1FA97',
  keywords: ['accordion', 'music'],
  sheet: [54, 9],
  shortName: 'accordion'
}, {
  name: 'Guitar',
  unified: '1F3B8',
  keywords: ['guitar', 'music', 'instrument'],
  sheet: [7, 59],
  shortName: 'guitar'
}, {
  name: 'Musical Keyboard',
  unified: '1F3B9',
  keywords: ['musical_keyboard', 'piano', 'instrument', 'compose'],
  sheet: [7, 60],
  shortName: 'musical_keyboard'
}, {
  name: 'Trumpet',
  unified: '1F3BA',
  keywords: ['trumpet', 'music', 'brass'],
  sheet: [8, 0],
  shortName: 'trumpet'
}, {
  name: 'Violin',
  unified: '1F3BB',
  keywords: ['violin', 'music', 'instrument', 'orchestra', 'symphony'],
  sheet: [8, 1],
  shortName: 'violin'
}, {
  name: 'Banjo',
  unified: '1FA95',
  keywords: ['banjo', 'music', 'instructment'],
  sheet: [54, 7],
  shortName: 'banjo'
}, {
  name: 'Drum with Drumsticks',
  unified: '1F941',
  keywords: ['drum', 'music', 'instrument', 'drumsticks', 'snare'],
  sheet: [43, 12],
  shortName: 'drum_with_drumsticks'
}, {
  name: 'Long Drum',
  unified: '1FA98',
  keywords: ['long drum', 'music'],
  sheet: [54, 10],
  shortName: 'long_drum'
}, {
  name: 'Mobile Phone',
  unified: '1F4F1',
  keywords: ['mobile_phone', 'technology', 'apple', 'gadgets', 'dial'],
  sheet: [29, 11],
  shortName: 'iphone'
}, {
  name: 'Mobile Phone with Rightwards Arrow at Left',
  unified: '1F4F2',
  keywords: ['mobile_phone_with_arrow', 'iphone', 'incoming'],
  sheet: [29, 12],
  shortName: 'calling'
}, {
  name: 'Black Telephone',
  unified: '260E-FE0F',
  keywords: ['telephone', 'technology', 'communication', 'dial', 'telephone'],
  sheet: [56, 45],
  shortNames: ['telephone'],
  shortName: 'phone'
}, {
  name: 'Telephone Receiver',
  unified: '1F4DE',
  keywords: ['telephone_receiver', 'technology', 'communication', 'dial'],
  sheet: [28, 53],
  shortName: 'telephone_receiver'
}, {
  name: 'Pager',
  unified: '1F4DF',
  keywords: ['pager', 'bbcall', 'oldschool', '90s'],
  sheet: [28, 54],
  shortName: 'pager'
}, {
  name: 'Fax Machine',
  unified: '1F4E0',
  keywords: ['fax_machine', 'communication', 'technology'],
  sheet: [28, 55],
  shortName: 'fax'
}, {
  name: 'Battery',
  unified: '1F50B',
  keywords: ['battery', 'power', 'energy', 'sustain'],
  sheet: [29, 36],
  shortName: 'battery'
}, {
  name: 'Low Battery',
  unified: '1FAAB',
  keywords: ['low battery', 'drained', 'dead'],
  sheet: [54, 29],
  hidden: ['facebook'],
  shortName: 'low_battery'
}, {
  name: 'Electric Plug',
  unified: '1F50C',
  keywords: ['electric_plug', 'charger', 'power'],
  sheet: [29, 37],
  shortName: 'electric_plug'
}, {
  name: 'Personal Computer',
  unified: '1F4BB',
  keywords: ['laptop', 'technology', 'laptop', 'screen', 'display', 'monitor'],
  sheet: [28, 18],
  shortName: 'computer'
}, {
  name: 'Desktop Computer',
  unified: '1F5A5-FE0F',
  keywords: ['desktop_computer', 'technology', 'computing', 'screen'],
  sheet: [31, 56],
  shortName: 'desktop_computer'
}, {
  name: 'Printer',
  unified: '1F5A8-FE0F',
  keywords: ['printer', 'paper', 'ink'],
  sheet: [31, 57],
  shortName: 'printer'
}, {
  name: 'Keyboard',
  unified: '2328-FE0F',
  keywords: ['keyboard', 'technology', 'computer', 'type', 'input', 'text'],
  sheet: [56, 15],
  shortName: 'keyboard'
}, {
  name: 'Computer Mouse',
  unified: '1F5B1-FE0F',
  keywords: ['computer_mouse', 'click'],
  sheet: [31, 58],
  shortName: 'three_button_mouse'
}, {
  name: 'Trackball',
  unified: '1F5B2-FE0F',
  keywords: ['trackball', 'technology', 'trackpad'],
  sheet: [31, 59],
  shortName: 'trackball'
}, {
  name: 'Minidisc',
  unified: '1F4BD',
  keywords: ['computer_disk', 'technology', 'record', 'data', 'disk', '90s'],
  sheet: [28, 20],
  shortName: 'minidisc'
}, {
  name: 'Floppy Disk',
  unified: '1F4BE',
  keywords: ['floppy_disk', 'oldschool', 'technology', 'save', '90s', '80s'],
  sheet: [28, 21],
  shortName: 'floppy_disk'
}, {
  name: 'Optical Disc',
  unified: '1F4BF',
  keywords: ['optical_disk', 'technology', 'dvd', 'disk', 'disc', '90s'],
  sheet: [28, 22],
  shortName: 'cd'
}, {
  name: 'Dvd',
  unified: '1F4C0',
  keywords: ['dvd', 'cd', 'disk', 'disc'],
  sheet: [28, 23],
  shortName: 'dvd'
}, {
  name: 'Abacus',
  unified: '1F9EE',
  keywords: ['abacus', 'calculation'],
  sheet: [53, 28],
  shortName: 'abacus'
}, {
  name: 'Movie Camera',
  unified: '1F3A5',
  keywords: ['movie_camera', 'film', 'record'],
  sheet: [7, 40],
  shortName: 'movie_camera'
}, {
  name: 'Film Frames',
  unified: '1F39E-FE0F',
  keywords: ['film_frames', 'movie'],
  sheet: [7, 33],
  shortName: 'film_frames'
}, {
  name: 'Film Projector',
  unified: '1F4FD-FE0F',
  keywords: ['film_projector', 'video', 'tape', 'record', 'movie'],
  sheet: [29, 23],
  shortName: 'film_projector'
}, {
  name: 'Clapper Board',
  unified: '1F3AC',
  keywords: ['clapper_board', 'movie', 'film', 'record'],
  sheet: [7, 47],
  shortName: 'clapper'
}, {
  name: 'Television',
  unified: '1F4FA',
  keywords: ['television', 'technology', 'program', 'oldschool', 'show', 'television'],
  sheet: [29, 20],
  shortName: 'tv'
}, {
  name: 'Camera',
  unified: '1F4F7',
  keywords: ['camera', 'gadgets', 'photography'],
  sheet: [29, 17],
  shortName: 'camera'
}, {
  name: 'Camera with Flash',
  unified: '1F4F8',
  keywords: ['camera_with_flash', 'photography', 'gadgets'],
  sheet: [29, 18],
  shortName: 'camera_with_flash'
}, {
  name: 'Video Camera',
  unified: '1F4F9',
  keywords: ['video_camera', 'film', 'record'],
  sheet: [29, 19],
  shortName: 'video_camera'
}, {
  name: 'Videocassette',
  unified: '1F4FC',
  keywords: ['videocassette', 'record', 'video', 'oldschool', '90s', '80s'],
  sheet: [29, 22],
  shortName: 'vhs'
}, {
  name: 'Left-Pointing Magnifying Glass',
  unified: '1F50D',
  keywords: ['magnifying_glass_tilted_left', 'search', 'zoom', 'find', 'detective'],
  sheet: [29, 38],
  shortName: 'mag'
}, {
  name: 'Right-Pointing Magnifying Glass',
  unified: '1F50E',
  keywords: ['magnifying_glass_tilted_right', 'search', 'zoom', 'find', 'detective'],
  sheet: [29, 39],
  shortName: 'mag_right'
}, {
  name: 'Candle',
  unified: '1F56F-FE0F',
  keywords: ['candle', 'fire', 'wax'],
  sheet: [30, 56],
  shortName: 'candle'
}, {
  name: 'Electric Light Bulb',
  unified: '1F4A1',
  keywords: ['light_bulb', 'light', 'electricity', 'idea'],
  sheet: [27, 48],
  shortName: 'bulb'
}, {
  name: 'Electric Torch',
  unified: '1F526',
  keywords: ['flashlight', 'dark', 'camping', 'sight', 'night'],
  sheet: [30, 2],
  shortName: 'flashlight'
}, {
  name: 'Izakaya Lantern',
  unified: '1F3EE',
  keywords: ['red_paper_lantern', 'light', 'paper', 'halloween', 'spooky'],
  sheet: [10, 25],
  shortNames: ['lantern'],
  shortName: 'izakaya_lantern'
}, {
  name: 'Diya Lamp',
  unified: '1FA94',
  keywords: ['diya_lamp', 'lighting'],
  sheet: [54, 6],
  shortName: 'diya_lamp'
}, {
  name: 'Notebook with Decorative Cover',
  unified: '1F4D4',
  keywords: ['notebook_with_decorative_cover', 'classroom', 'notes', 'record', 'paper', 'study'],
  sheet: [28, 43],
  shortName: 'notebook_with_decorative_cover'
}, {
  name: 'Closed Book',
  unified: '1F4D5',
  keywords: ['closed_book', 'read', 'library', 'knowledge', 'textbook', 'learn'],
  sheet: [28, 44],
  shortName: 'closed_book'
}, {
  name: 'Open Book',
  unified: '1F4D6',
  keywords: ['open_book', 'book', 'read', 'library', 'knowledge', 'literature', 'learn', 'study'],
  sheet: [28, 45],
  shortNames: ['open_book'],
  shortName: 'book'
}, {
  name: 'Green Book',
  unified: '1F4D7',
  keywords: ['green_book', 'read', 'library', 'knowledge', 'study'],
  sheet: [28, 46],
  shortName: 'green_book'
}, {
  name: 'Blue Book',
  unified: '1F4D8',
  keywords: ['blue_book', 'read', 'library', 'knowledge', 'learn', 'study'],
  sheet: [28, 47],
  shortName: 'blue_book'
}, {
  name: 'Orange Book',
  unified: '1F4D9',
  keywords: ['orange_book', 'read', 'library', 'knowledge', 'textbook', 'study'],
  sheet: [28, 48],
  shortName: 'orange_book'
}, {
  name: 'Books',
  unified: '1F4DA',
  keywords: ['books', 'literature', 'library', 'study'],
  sheet: [28, 49],
  shortName: 'books'
}, {
  name: 'Notebook',
  unified: '1F4D3',
  keywords: ['notebook', 'stationery', 'record', 'notes', 'paper', 'study'],
  sheet: [28, 42],
  shortName: 'notebook'
}, {
  name: 'Ledger',
  unified: '1F4D2',
  keywords: ['ledger', 'notes', 'paper'],
  sheet: [28, 41],
  shortName: 'ledger'
}, {
  name: 'Page with Curl',
  unified: '1F4C3',
  keywords: ['page_with_curl', 'documents', 'office', 'paper'],
  sheet: [28, 26],
  shortName: 'page_with_curl'
}, {
  name: 'Scroll',
  unified: '1F4DC',
  keywords: ['scroll', 'documents', 'ancient', 'history', 'paper'],
  sheet: [28, 51],
  shortName: 'scroll'
}, {
  name: 'Page Facing Up',
  unified: '1F4C4',
  keywords: ['page_facing_up', 'documents', 'office', 'paper', 'information'],
  sheet: [28, 27],
  shortName: 'page_facing_up'
}, {
  name: 'Newspaper',
  unified: '1F4F0',
  keywords: ['newspaper', 'press', 'headline'],
  sheet: [29, 10],
  shortName: 'newspaper'
}, {
  name: 'Rolled-Up Newspaper',
  unified: '1F5DE-FE0F',
  keywords: ['rolled_up_newspaper', 'press', 'headline'],
  sheet: [32, 8],
  shortName: 'rolled_up_newspaper'
}, {
  name: 'Bookmark Tabs',
  unified: '1F4D1',
  keywords: ['bookmark_tabs', 'favorite', 'save', 'order', 'tidy'],
  sheet: [28, 40],
  shortName: 'bookmark_tabs'
}, {
  name: 'Bookmark',
  unified: '1F516',
  keywords: ['bookmark', 'favorite', 'label', 'save'],
  sheet: [29, 47],
  shortName: 'bookmark'
}, {
  name: 'Label',
  unified: '1F3F7-FE0F',
  keywords: ['label', 'sale', 'tag'],
  sheet: [10, 37],
  shortName: 'label'
}, {
  name: 'Money Bag',
  unified: '1F4B0',
  keywords: ['money_bag', 'dollar', 'payment', 'coins', 'sale'],
  sheet: [28, 7],
  shortName: 'moneybag'
}, {
  name: 'Coin',
  unified: '1FA99',
  keywords: ['coin', 'money', 'currency'],
  sheet: [54, 11],
  shortName: 'coin'
}, {
  name: 'Banknote with Yen Sign',
  unified: '1F4B4',
  keywords: ['yen_banknote', 'money', 'sales', 'japanese', 'dollar', 'currency'],
  sheet: [28, 11],
  shortName: 'yen'
}, {
  name: 'Banknote with Dollar Sign',
  unified: '1F4B5',
  keywords: ['dollar_banknote', 'money', 'sales', 'bill', 'currency'],
  sheet: [28, 12],
  shortName: 'dollar'
}, {
  name: 'Banknote with Euro Sign',
  unified: '1F4B6',
  keywords: ['euro_banknote', 'money', 'sales', 'dollar', 'currency'],
  sheet: [28, 13],
  shortName: 'euro'
}, {
  name: 'Banknote with Pound Sign',
  unified: '1F4B7',
  keywords: ['pound_banknote', 'british', 'sterling', 'money', 'sales', 'bills', 'uk', 'england', 'currency'],
  sheet: [28, 14],
  shortName: 'pound'
}, {
  name: 'Money with Wings',
  unified: '1F4B8',
  keywords: ['money_with_wings', 'dollar', 'bills', 'payment', 'sale'],
  sheet: [28, 15],
  shortName: 'money_with_wings'
}, {
  name: 'Credit Card',
  unified: '1F4B3',
  keywords: ['credit_card', 'money', 'sales', 'dollar', 'bill', 'payment', 'shopping'],
  sheet: [28, 10],
  shortName: 'credit_card'
}, {
  name: 'Receipt',
  unified: '1F9FE',
  keywords: ['receipt', 'accounting', 'expenses'],
  sheet: [53, 44],
  shortName: 'receipt'
}, {
  name: 'Chart with Upwards Trend and Yen Sign',
  unified: '1F4B9',
  keywords: ['chart_increasing_with_yen', 'green-square', 'graph', 'presentation', 'stats'],
  sheet: [28, 16],
  shortName: 'chart'
}, {
  name: 'Envelope',
  unified: '2709-FE0F',
  keywords: ['envelope', 'letter', 'postal', 'inbox', 'communication'],
  sheet: [58, 26],
  shortNames: ['envelope'],
  shortName: 'email'
}, {
  name: 'E-Mail Symbol',
  unified: '1F4E7',
  keywords: ['e_mail', 'communication', 'inbox'],
  sheet: [29, 1],
  shortName: 'e-mail'
}, {
  name: 'Incoming Envelope',
  unified: '1F4E8',
  keywords: ['incoming_envelope', 'email', 'inbox'],
  sheet: [29, 2],
  shortName: 'incoming_envelope'
}, {
  name: 'Envelope with Downwards Arrow Above',
  unified: '1F4E9',
  keywords: ['envelope_with_arrow', 'email', 'communication'],
  sheet: [29, 3],
  shortName: 'envelope_with_arrow'
}, {
  name: 'Outbox Tray',
  unified: '1F4E4',
  keywords: ['outbox_tray', 'inbox', 'email'],
  sheet: [28, 59],
  shortName: 'outbox_tray'
}, {
  name: 'Inbox Tray',
  unified: '1F4E5',
  keywords: ['inbox_tray', 'email', 'documents'],
  sheet: [28, 60],
  shortName: 'inbox_tray'
}, {
  name: 'Package',
  unified: '1F4E6',
  keywords: ['package', 'mail', 'gift', 'cardboard', 'box', 'moving'],
  sheet: [29, 0],
  shortName: 'package'
}, {
  name: 'Closed Mailbox with Raised Flag',
  unified: '1F4EB',
  keywords: ['closed_mailbox_with_raised_flag', 'email', 'inbox', 'communication'],
  sheet: [29, 5],
  shortName: 'mailbox'
}, {
  name: 'Closed Mailbox with Lowered Flag',
  unified: '1F4EA',
  keywords: ['closed_mailbox_with_lowered_flag', 'email', 'communication', 'inbox'],
  sheet: [29, 4],
  shortName: 'mailbox_closed'
}, {
  name: 'Open Mailbox with Raised Flag',
  unified: '1F4EC',
  keywords: ['open_mailbox_with_raised_flag', 'email', 'inbox', 'communication'],
  sheet: [29, 6],
  shortName: 'mailbox_with_mail'
}, {
  name: 'Open Mailbox with Lowered Flag',
  unified: '1F4ED',
  keywords: ['open_mailbox_with_lowered_flag', 'email', 'inbox'],
  sheet: [29, 7],
  shortName: 'mailbox_with_no_mail'
}, {
  name: 'Postbox',
  unified: '1F4EE',
  keywords: ['postbox', 'email', 'letter', 'envelope'],
  sheet: [29, 8],
  shortName: 'postbox'
}, {
  name: 'Ballot Box with Ballot',
  unified: '1F5F3-FE0F',
  keywords: ['ballot_box_with_ballot', 'election', 'vote'],
  sheet: [32, 13],
  shortName: 'ballot_box_with_ballot'
}, {
  name: 'Pencil',
  unified: '270F-FE0F',
  keywords: ['pencil', 'stationery', 'write', 'paper', 'writing', 'school', 'study'],
  sheet: [58, 51],
  shortName: 'pencil2'
}, {
  name: 'Black Nib',
  unified: '2712-FE0F',
  keywords: ['black_nib', 'pen', 'stationery', 'writing', 'write'],
  sheet: [58, 52],
  shortName: 'black_nib'
}, {
  name: 'Fountain Pen',
  unified: '1F58B-FE0F',
  keywords: ['fountain_pen', 'stationery', 'writing', 'write'],
  sheet: [31, 34],
  shortName: 'lower_left_fountain_pen'
}, {
  name: 'Pen',
  unified: '1F58A-FE0F',
  keywords: ['pen', 'stationery', 'writing', 'write'],
  sheet: [31, 33],
  shortName: 'lower_left_ballpoint_pen'
}, {
  name: 'Paintbrush',
  unified: '1F58C-FE0F',
  keywords: ['paintbrush', 'drawing', 'creativity', 'art'],
  sheet: [31, 35],
  shortName: 'lower_left_paintbrush'
}, {
  name: 'Crayon',
  unified: '1F58D-FE0F',
  keywords: ['crayon', 'drawing', 'creativity'],
  sheet: [31, 36],
  shortName: 'lower_left_crayon'
}, {
  name: 'Memo',
  unified: '1F4DD',
  keywords: ['memo', 'write', 'documents', 'stationery', 'pencil', 'paper', 'writing', 'legal', 'exam', 'quiz', 'test', 'study', 'compose'],
  sheet: [28, 52],
  shortNames: ['pencil'],
  shortName: 'memo'
}, {
  name: 'Briefcase',
  unified: '1F4BC',
  keywords: ['briefcase', 'business', 'documents', 'work', 'law', 'legal', 'job', 'career'],
  sheet: [28, 19],
  shortName: 'briefcase'
}, {
  name: 'File Folder',
  unified: '1F4C1',
  keywords: ['file_folder', 'documents', 'business', 'office'],
  sheet: [28, 24],
  shortName: 'file_folder'
}, {
  name: 'Open File Folder',
  unified: '1F4C2',
  keywords: ['open_file_folder', 'documents', 'load'],
  sheet: [28, 25],
  shortName: 'open_file_folder'
}, {
  name: 'Card Index Dividers',
  unified: '1F5C2-FE0F',
  keywords: ['card_index_dividers', 'organizing', 'business', 'stationery'],
  sheet: [32, 0],
  shortName: 'card_index_dividers'
}, {
  name: 'Calendar',
  unified: '1F4C5',
  keywords: ['calendar', 'calendar', 'schedule'],
  sheet: [28, 28],
  shortName: 'date'
}, {
  name: 'Tear-off Calendar',
  unified: '1F4C6',
  keywords: ['tear_off_calendar', 'schedule', 'date', 'planning'],
  sheet: [28, 29],
  shortName: 'calendar'
}, {
  name: 'Spiral Notepad',
  unified: '1F5D2-FE0F',
  keywords: ['spiral_notepad', 'memo', 'stationery'],
  sheet: [32, 4],
  shortName: 'spiral_note_pad'
}, {
  name: 'Spiral Calendar',
  unified: '1F5D3-FE0F',
  keywords: ['spiral_calendar', 'date', 'schedule', 'planning'],
  sheet: [32, 5],
  shortName: 'spiral_calendar_pad'
}, {
  name: 'Card Index',
  unified: '1F4C7',
  keywords: ['card_index', 'business', 'stationery'],
  sheet: [28, 30],
  shortName: 'card_index'
}, {
  name: 'Chart with Upwards Trend',
  unified: '1F4C8',
  keywords: ['chart_increasing', 'graph', 'presentation', 'stats', 'recovery', 'business', 'economics', 'money', 'sales', 'good', 'success'],
  sheet: [28, 31],
  shortName: 'chart_with_upwards_trend'
}, {
  name: 'Chart with Downwards Trend',
  unified: '1F4C9',
  keywords: ['chart_decreasing', 'graph', 'presentation', 'stats', 'recession', 'business', 'economics', 'money', 'sales', 'bad', 'failure'],
  sheet: [28, 32],
  shortName: 'chart_with_downwards_trend'
}, {
  name: 'Bar Chart',
  unified: '1F4CA',
  keywords: ['bar_chart', 'graph', 'presentation', 'stats'],
  sheet: [28, 33],
  shortName: 'bar_chart'
}, {
  name: 'Clipboard',
  unified: '1F4CB',
  keywords: ['clipboard', 'stationery', 'documents'],
  sheet: [28, 34],
  shortName: 'clipboard'
}, {
  name: 'Pushpin',
  unified: '1F4CC',
  keywords: ['pushpin', 'stationery', 'mark', 'here'],
  sheet: [28, 35],
  shortName: 'pushpin'
}, {
  name: 'Round Pushpin',
  unified: '1F4CD',
  keywords: ['round_pushpin', 'stationery', 'location', 'map', 'here'],
  sheet: [28, 36],
  shortName: 'round_pushpin'
}, {
  name: 'Paperclip',
  unified: '1F4CE',
  keywords: ['paperclip', 'documents', 'stationery'],
  sheet: [28, 37],
  shortName: 'paperclip'
}, {
  name: 'Linked Paperclips',
  unified: '1F587-FE0F',
  keywords: ['linked_paperclips', 'documents', 'stationery'],
  sheet: [31, 32],
  shortName: 'linked_paperclips'
}, {
  name: 'Straight Ruler',
  unified: '1F4CF',
  keywords: ['straight_ruler', 'stationery', 'calculate', 'length', 'math', 'school', 'drawing', 'architect', 'sketch'],
  sheet: [28, 38],
  shortName: 'straight_ruler'
}, {
  name: 'Triangular Ruler',
  unified: '1F4D0',
  keywords: ['triangular_ruler', 'stationery', 'math', 'architect', 'sketch'],
  sheet: [28, 39],
  shortName: 'triangular_ruler'
}, {
  name: 'Black Scissors',
  unified: '2702-FE0F',
  keywords: ['scissors', 'stationery', 'cut'],
  sheet: [58, 23],
  shortName: 'scissors'
}, {
  name: 'Card File Box',
  unified: '1F5C3-FE0F',
  keywords: ['card_file_box', 'business', 'stationery'],
  sheet: [32, 1],
  shortName: 'card_file_box'
}, {
  name: 'File Cabinet',
  unified: '1F5C4-FE0F',
  keywords: ['file_cabinet', 'filing', 'organizing'],
  sheet: [32, 2],
  shortName: 'file_cabinet'
}, {
  name: 'Wastebasket',
  unified: '1F5D1-FE0F',
  keywords: ['wastebasket', 'bin', 'trash', 'rubbish', 'garbage', 'toss'],
  sheet: [32, 3],
  shortName: 'wastebasket'
}, {
  name: 'Lock',
  unified: '1F512',
  keywords: ['locked', 'security', 'password', 'padlock'],
  sheet: [29, 43],
  shortName: 'lock'
}, {
  name: 'Open Lock',
  unified: '1F513',
  keywords: ['unlocked', 'privacy', 'security'],
  sheet: [29, 44],
  shortName: 'unlock'
}, {
  name: 'Lock with Ink Pen',
  unified: '1F50F',
  keywords: ['locked_with_pen', 'security', 'secret'],
  sheet: [29, 40],
  shortName: 'lock_with_ink_pen'
}, {
  name: 'Closed Lock with Key',
  unified: '1F510',
  keywords: ['locked_with_key', 'security', 'privacy'],
  sheet: [29, 41],
  shortName: 'closed_lock_with_key'
}, {
  name: 'Key',
  unified: '1F511',
  keywords: ['key', 'lock', 'door', 'password'],
  sheet: [29, 42],
  shortName: 'key'
}, {
  name: 'Old Key',
  unified: '1F5DD-FE0F',
  keywords: ['old_key', 'lock', 'door', 'password'],
  sheet: [32, 7],
  shortName: 'old_key'
}, {
  name: 'Hammer',
  unified: '1F528',
  keywords: ['hammer', 'tools', 'build', 'create'],
  sheet: [30, 4],
  shortName: 'hammer'
}, {
  name: 'Axe',
  unified: '1FA93',
  keywords: ['axe', 'tool', 'chop', 'cut'],
  sheet: [54, 5],
  shortName: 'axe'
}, {
  name: 'Pick',
  unified: '26CF-FE0F',
  keywords: ['pick', 'tools', 'dig'],
  sheet: [57, 50],
  shortName: 'pick'
}, {
  name: 'Hammer and Pick',
  unified: '2692-FE0F',
  keywords: ['hammer_and_pick', 'tools', 'build', 'create'],
  sheet: [57, 28],
  shortName: 'hammer_and_pick'
}, {
  name: 'Hammer and Wrench',
  unified: '1F6E0-FE0F',
  keywords: ['hammer_and_wrench', 'tools', 'build', 'create'],
  sheet: [38, 11],
  shortName: 'hammer_and_wrench'
}, {
  name: 'Dagger',
  unified: '1F5E1-FE0F',
  keywords: ['dagger', 'weapon'],
  sheet: [32, 9],
  shortName: 'dagger_knife'
}, {
  name: 'Crossed Swords',
  unified: '2694-FE0F',
  keywords: ['crossed_swords', 'weapon'],
  sheet: [57, 30],
  shortName: 'crossed_swords'
}, {
  name: 'Pistol',
  unified: '1F52B',
  keywords: ['pistol', 'violence', 'weapon', 'pistol', 'revolver'],
  sheet: [30, 7],
  shortName: 'gun'
}, {
  name: 'Boomerang',
  unified: '1FA83',
  keywords: ['boomerang', 'weapon'],
  sheet: [53, 59],
  shortName: 'boomerang'
}, {
  name: 'Bow and Arrow',
  unified: '1F3F9',
  keywords: ['bow_and_arrow', 'sports'],
  sheet: [10, 39],
  shortName: 'bow_and_arrow'
}, {
  name: 'Shield',
  unified: '1F6E1-FE0F',
  keywords: ['shield', 'protection', 'security'],
  sheet: [38, 12],
  shortName: 'shield'
}, {
  name: 'Carpentry Saw',
  unified: '1FA9A',
  keywords: ['carpentry saw', 'cut', 'chop'],
  sheet: [54, 12],
  shortName: 'carpentry_saw'
}, {
  name: 'Wrench',
  unified: '1F527',
  keywords: ['wrench', 'tools', 'diy', 'ikea', 'fix', 'maintainer'],
  sheet: [30, 3],
  shortName: 'wrench'
}, {
  name: 'Screwdriver',
  unified: '1FA9B',
  keywords: ['screwdriver', 'tools'],
  sheet: [54, 13],
  shortName: 'screwdriver'
}, {
  name: 'Nut and Bolt',
  unified: '1F529',
  keywords: ['nut_and_bolt', 'handy', 'tools', 'fix'],
  sheet: [30, 5],
  shortName: 'nut_and_bolt'
}, {
  name: 'Gear',
  unified: '2699-FE0F',
  keywords: ['gear', 'cog'],
  sheet: [57, 34],
  shortName: 'gear'
}, {
  name: 'Clamp',
  unified: '1F5DC-FE0F',
  keywords: ['clamp', 'tool'],
  sheet: [32, 6],
  shortName: 'compression'
}, {
  name: 'Balance Scale',
  unified: '2696-FE0F',
  keywords: ['balance_scale', 'law', 'fairness', 'weight'],
  sheet: [57, 32],
  shortName: 'scales'
}, {
  name: 'Probing Cane',
  unified: '1F9AF',
  keywords: ['probing_cane', 'accessibility'],
  sheet: [45, 4],
  shortName: 'probing_cane'
}, {
  name: 'Link Symbol',
  unified: '1F517',
  keywords: ['link', 'rings', 'url'],
  sheet: [29, 48],
  shortName: 'link'
}, {
  name: 'Chains',
  unified: '26D3-FE0F',
  keywords: ['chains', 'lock', 'arrest'],
  sheet: [57, 52],
  shortName: 'chains'
}, {
  name: 'Hook',
  unified: '1FA9D',
  keywords: ['hook', 'tools'],
  sheet: [54, 15],
  shortName: 'hook'
}, {
  name: 'Toolbox',
  unified: '1F9F0',
  keywords: ['toolbox', 'tools', 'diy', 'fix', 'maintainer', 'mechanic'],
  sheet: [53, 30],
  shortName: 'toolbox'
}, {
  name: 'Magnet',
  unified: '1F9F2',
  keywords: ['magnet', 'attraction', 'magnetic'],
  sheet: [53, 32],
  shortName: 'magnet'
}, {
  name: 'Ladder',
  unified: '1FA9C',
  keywords: ['ladder', 'tools'],
  sheet: [54, 14],
  shortName: 'ladder'
}, {
  name: 'Alembic',
  unified: '2697-FE0F',
  keywords: ['alembic', 'distilling', 'science', 'experiment', 'chemistry'],
  sheet: [57, 33],
  shortName: 'alembic'
}, {
  name: 'Test Tube',
  unified: '1F9EA',
  keywords: ['test_tube', 'chemistry', 'experiment', 'lab', 'science'],
  sheet: [53, 24],
  shortName: 'test_tube'
}, {
  name: 'Petri Dish',
  unified: '1F9EB',
  keywords: ['petri_dish', 'bacteria', 'biology', 'culture', 'lab'],
  sheet: [53, 25],
  shortName: 'petri_dish'
}, {
  name: 'Dna Double Helix',
  unified: '1F9EC',
  keywords: ['dna', 'biologist', 'genetics', 'life'],
  sheet: [53, 26],
  shortName: 'dna'
}, {
  name: 'Microscope',
  unified: '1F52C',
  keywords: ['microscope', 'laboratory', 'experiment', 'zoomin', 'science', 'study'],
  sheet: [30, 8],
  shortName: 'microscope'
}, {
  name: 'Telescope',
  unified: '1F52D',
  keywords: ['telescope', 'stars', 'space', 'zoom', 'science', 'astronomy'],
  sheet: [30, 9],
  shortName: 'telescope'
}, {
  name: 'Satellite Antenna',
  unified: '1F4E1',
  keywords: ['satellite_antenna', 'communication', 'future', 'radio', 'space'],
  sheet: [28, 56],
  shortName: 'satellite_antenna'
}, {
  name: 'Syringe',
  unified: '1F489',
  keywords: ['syringe', 'health', 'hospital', 'drugs', 'blood', 'medicine', 'needle', 'doctor', 'nurse'],
  sheet: [26, 35],
  shortName: 'syringe'
}, {
  name: 'Drop of Blood',
  unified: '1FA78',
  keywords: ['drop_of_blood', 'period', 'hurt', 'harm', 'wound'],
  sheet: [53, 51],
  shortName: 'drop_of_blood'
}, {
  name: 'Pill',
  unified: '1F48A',
  keywords: ['pill', 'health', 'medicine', 'doctor', 'pharmacy', 'drug'],
  sheet: [26, 36],
  shortName: 'pill'
}, {
  name: 'Adhesive Bandage',
  unified: '1FA79',
  keywords: ['adhesive_bandage', 'heal'],
  sheet: [53, 52],
  shortName: 'adhesive_bandage'
}, {
  name: 'Crutch',
  unified: '1FA7C',
  keywords: ['crutch', 'accessibility', 'assist'],
  sheet: [53, 55],
  hidden: ['facebook'],
  shortName: 'crutch'
}, {
  name: 'Stethoscope',
  unified: '1FA7A',
  keywords: ['stethoscope', 'health'],
  sheet: [53, 53],
  shortName: 'stethoscope'
}, {
  name: 'X-Ray',
  unified: '1FA7B',
  keywords: ['x-ray', 'skeleton', 'medicine'],
  sheet: [53, 54],
  hidden: ['facebook'],
  shortName: 'x-ray'
}, {
  name: 'Door',
  unified: '1F6AA',
  keywords: ['door', 'house', 'entry', 'exit'],
  sheet: [36, 30],
  shortName: 'door'
}, {
  name: 'Elevator',
  unified: '1F6D7',
  keywords: ['elevator', 'lift'],
  sheet: [38, 7],
  shortName: 'elevator'
}, {
  name: 'Mirror',
  unified: '1FA9E',
  keywords: ['mirror', 'reflection'],
  sheet: [54, 16],
  shortName: 'mirror'
}, {
  name: 'Window',
  unified: '1FA9F',
  keywords: ['window', 'scenery'],
  sheet: [54, 17],
  shortName: 'window'
}, {
  name: 'Bed',
  unified: '1F6CF-FE0F',
  keywords: ['bed', 'sleep', 'rest'],
  sheet: [38, 1],
  shortName: 'bed'
}, {
  name: 'Couch and Lamp',
  unified: '1F6CB-FE0F',
  keywords: ['couch_and_lamp', 'read', 'chill'],
  sheet: [37, 53],
  shortName: 'couch_and_lamp'
}, {
  name: 'Chair',
  unified: '1FA91',
  keywords: ['chair', 'sit', 'furniture'],
  sheet: [54, 3],
  shortName: 'chair'
}, {
  name: 'Toilet',
  unified: '1F6BD',
  keywords: ['toilet', 'restroom', 'wc', 'washroom', 'bathroom', 'potty'],
  sheet: [37, 39],
  shortName: 'toilet'
}, {
  name: 'Plunger',
  unified: '1FAA0',
  keywords: ['plunger', 'toilet'],
  sheet: [54, 18],
  shortName: 'plunger'
}, {
  name: 'Shower',
  unified: '1F6BF',
  keywords: ['shower', 'clean', 'water', 'bathroom'],
  sheet: [37, 41],
  shortName: 'shower'
}, {
  name: 'Bathtub',
  unified: '1F6C1',
  keywords: ['bathtub', 'clean', 'shower', 'bathroom'],
  sheet: [37, 48],
  shortName: 'bathtub'
}, {
  name: 'Mouse Trap',
  unified: '1FAA4',
  keywords: ['mouse trap', 'cheese'],
  sheet: [54, 22],
  shortName: 'mouse_trap'
}, {
  name: 'Razor',
  unified: '1FA92',
  keywords: ['razor', 'cut'],
  sheet: [54, 4],
  shortName: 'razor'
}, {
  name: 'Lotion Bottle',
  unified: '1F9F4',
  keywords: ['lotion_bottle', 'moisturizer', 'sunscreen'],
  sheet: [53, 34],
  shortName: 'lotion_bottle'
}, {
  name: 'Safety Pin',
  unified: '1F9F7',
  keywords: ['safety_pin', 'diaper'],
  sheet: [53, 37],
  shortName: 'safety_pin'
}, {
  name: 'Broom',
  unified: '1F9F9',
  keywords: ['broom', 'cleaning', 'sweeping', 'witch'],
  sheet: [53, 39],
  shortName: 'broom'
}, {
  name: 'Basket',
  unified: '1F9FA',
  keywords: ['basket', 'laundry'],
  sheet: [53, 40],
  shortName: 'basket'
}, {
  name: 'Roll of Paper',
  unified: '1F9FB',
  keywords: ['roll_of_paper', 'roll'],
  sheet: [53, 41],
  shortName: 'roll_of_paper'
}, {
  name: 'Bucket',
  unified: '1FAA3',
  keywords: ['bucket', 'water', 'container'],
  sheet: [54, 21],
  shortName: 'bucket'
}, {
  name: 'Bar of Soap',
  unified: '1F9FC',
  keywords: ['soap', 'bar', 'bathing', 'cleaning', 'lather'],
  sheet: [53, 42],
  shortName: 'soap'
}, {
  name: 'Bubbles',
  unified: '1FAE7',
  keywords: ['bubbles', 'soap', 'fun', 'carbonation', 'sparkling'],
  sheet: [55, 19],
  hidden: ['facebook'],
  shortName: 'bubbles'
}, {
  name: 'Toothbrush',
  unified: '1FAA5',
  keywords: ['toothbrush', 'hygiene', 'dental'],
  sheet: [54, 23],
  shortName: 'toothbrush'
}, {
  name: 'Sponge',
  unified: '1F9FD',
  keywords: ['sponge', 'absorbing', 'cleaning', 'porous'],
  sheet: [53, 43],
  shortName: 'sponge'
}, {
  name: 'Fire Extinguisher',
  unified: '1F9EF',
  keywords: ['fire_extinguisher', 'quench'],
  sheet: [53, 29],
  shortName: 'fire_extinguisher'
}, {
  name: 'Shopping Trolley',
  unified: '1F6D2',
  keywords: ['shopping_cart', 'trolley'],
  sheet: [38, 4],
  shortName: 'shopping_trolley'
}, {
  name: 'Smoking Symbol',
  unified: '1F6AC',
  keywords: ['cigarette', 'kills', 'tobacco', 'cigarette', 'joint', 'smoke'],
  sheet: [36, 32],
  shortName: 'smoking'
}, {
  name: 'Coffin',
  unified: '26B0-FE0F',
  keywords: ['coffin', 'vampire', 'dead', 'die', 'death', 'rip', 'graveyard', 'cemetery', 'casket', 'funeral', 'box'],
  sheet: [57, 42],
  shortName: 'coffin'
}, {
  name: 'Headstone',
  unified: '1FAA6',
  keywords: ['headstone', 'death', 'rip', 'grave'],
  sheet: [54, 24],
  shortName: 'headstone'
}, {
  name: 'Funeral Urn',
  unified: '26B1-FE0F',
  keywords: ['funeral_urn', 'dead', 'die', 'death', 'rip', 'ashes'],
  sheet: [57, 43],
  shortName: 'funeral_urn'
}, {
  name: 'Moyai',
  unified: '1F5FF',
  keywords: ['moai', 'rock', 'easter island', 'moai'],
  sheet: [32, 19],
  shortName: 'moyai'
}, {
  name: 'Placard',
  unified: '1FAA7',
  keywords: ['placard', 'announcement'],
  sheet: [54, 25],
  shortName: 'placard'
}, {
  name: 'Identification Card',
  unified: '1FAAA',
  keywords: ['identification card', 'document'],
  sheet: [54, 28],
  hidden: ['facebook'],
  shortName: 'identification_card'
}, {
  name: 'Automated Teller Machine',
  unified: '1F3E7',
  keywords: ['atm_sign', 'money', 'sales', 'cash', 'blue-square', 'payment', 'bank'],
  sheet: [10, 18],
  shortName: 'atm'
}, {
  name: 'Put Litter in Its Place Symbol',
  unified: '1F6AE',
  keywords: ['litter_in_bin_sign', 'blue-square', 'sign', 'human', 'info'],
  sheet: [36, 34],
  shortName: 'put_litter_in_its_place'
}, {
  name: 'Potable Water Symbol',
  unified: '1F6B0',
  keywords: ['potable_water', 'blue-square', 'liquid', 'restroom', 'cleaning', 'faucet'],
  sheet: [36, 36],
  shortName: 'potable_water'
}, {
  name: 'Wheelchair Symbol',
  unified: '267F',
  keywords: ['wheelchair_symbol', 'blue-square', 'disabled', 'accessibility'],
  sheet: [57, 27],
  shortName: 'wheelchair'
}, {
  name: 'Mens Symbol',
  unified: '1F6B9',
  keywords: ['men_s_room', 'toilet', 'restroom', 'wc', 'blue-square', 'gender', 'male'],
  sheet: [37, 35],
  shortName: 'mens'
}, {
  name: 'Womens Symbol',
  unified: '1F6BA',
  keywords: ['women_s_room', 'purple-square', 'woman', 'female', 'toilet', 'loo', 'restroom', 'gender'],
  sheet: [37, 36],
  shortName: 'womens'
}, {
  name: 'Restroom',
  unified: '1F6BB',
  keywords: ['restroom', 'blue-square', 'toilet', 'refresh', 'wc', 'gender'],
  sheet: [37, 37],
  shortName: 'restroom'
}, {
  name: 'Baby Symbol',
  unified: '1F6BC',
  keywords: ['baby_symbol', 'orange-square', 'child'],
  sheet: [37, 38],
  shortName: 'baby_symbol'
}, {
  name: 'Water Closet',
  unified: '1F6BE',
  keywords: ['water_closet', 'toilet', 'restroom', 'blue-square'],
  sheet: [37, 40],
  shortName: 'wc'
}, {
  name: 'Passport Control',
  unified: '1F6C2',
  keywords: ['passport_control', 'custom', 'blue-square'],
  sheet: [37, 49],
  shortName: 'passport_control'
}, {
  name: 'Customs',
  unified: '1F6C3',
  keywords: ['customs', 'passport', 'border', 'blue-square'],
  sheet: [37, 50],
  shortName: 'customs'
}, {
  name: 'Baggage Claim',
  unified: '1F6C4',
  keywords: ['baggage_claim', 'blue-square', 'airport', 'transport'],
  sheet: [37, 51],
  shortName: 'baggage_claim'
}, {
  name: 'Left Luggage',
  unified: '1F6C5',
  keywords: ['left_luggage', 'blue-square', 'travel'],
  sheet: [37, 52],
  shortName: 'left_luggage'
}, {
  name: 'Warning Sign',
  unified: '26A0-FE0F',
  keywords: ['warning', 'exclamation', 'wip', 'alert', 'error', 'problem', 'issue'],
  sheet: [57, 37],
  shortName: 'warning'
}, {
  name: 'Children Crossing',
  unified: '1F6B8',
  keywords: ['children_crossing', 'school', 'warning', 'danger', 'sign', 'driving', 'yellow-diamond'],
  sheet: [37, 34],
  shortName: 'children_crossing'
}, {
  name: 'No Entry',
  unified: '26D4',
  keywords: ['no_entry', 'limit', 'security', 'privacy', 'bad', 'denied', 'stop', 'circle'],
  sheet: [57, 53],
  shortName: 'no_entry'
}, {
  name: 'No Entry Sign',
  unified: '1F6AB',
  keywords: ['prohibited', 'forbid', 'stop', 'limit', 'denied', 'disallow', 'circle'],
  sheet: [36, 31],
  shortName: 'no_entry_sign'
}, {
  name: 'No Bicycles',
  unified: '1F6B3',
  keywords: ['no_bicycles', 'cyclist', 'prohibited', 'circle'],
  sheet: [36, 39],
  shortName: 'no_bicycles'
}, {
  name: 'No Smoking Symbol',
  unified: '1F6AD',
  keywords: ['no_smoking', 'cigarette', 'blue-square', 'smell', 'smoke'],
  sheet: [36, 33],
  shortName: 'no_smoking'
}, {
  name: 'Do Not Litter Symbol',
  unified: '1F6AF',
  keywords: ['no_littering', 'trash', 'bin', 'garbage', 'circle'],
  sheet: [36, 35],
  shortName: 'do_not_litter'
}, {
  name: 'Non-Potable Water Symbol',
  unified: '1F6B1',
  keywords: ['non_potable_water', 'drink', 'faucet', 'tap', 'circle'],
  sheet: [36, 37],
  shortName: 'non-potable_water'
}, {
  name: 'No Pedestrians',
  unified: '1F6B7',
  keywords: ['no_pedestrians', 'rules', 'crossing', 'walking', 'circle'],
  sheet: [37, 33],
  shortName: 'no_pedestrians'
}, {
  name: 'No Mobile Phones',
  unified: '1F4F5',
  keywords: ['no_mobile_phones', 'iphone', 'mute', 'circle'],
  sheet: [29, 15],
  shortName: 'no_mobile_phones'
}, {
  name: 'No One Under Eighteen Symbol',
  unified: '1F51E',
  keywords: ['no_one_under_eighteen', '18', 'drink', 'pub', 'night', 'minor', 'circle'],
  sheet: [29, 55],
  shortName: 'underage'
}, {
  name: 'Radioactive',
  unified: '2622-FE0F',
  keywords: ['radioactive', 'nuclear', 'danger'],
  sheet: [56, 57],
  shortName: 'radioactive_sign'
}, {
  name: 'Biohazard',
  unified: '2623-FE0F',
  keywords: ['biohazard', 'danger'],
  sheet: [56, 58],
  shortName: 'biohazard_sign'
}, {
  name: 'Upwards Black Arrow',
  unified: '2B06-FE0F',
  keywords: ['up_arrow', 'blue-square', 'continue', 'top', 'direction'],
  sheet: [59, 20],
  shortName: 'arrow_up'
}, {
  name: 'North East Arrow',
  unified: '2197-FE0F',
  keywords: ['up_right_arrow', 'blue-square', 'point', 'direction', 'diagonal', 'northeast'],
  sheet: [56, 8],
  shortName: 'arrow_upper_right'
}, {
  name: 'Black Rightwards Arrow',
  unified: '27A1-FE0F',
  keywords: ['right_arrow', 'blue-square', 'next'],
  sheet: [59, 14],
  shortName: 'arrow_right'
}, {
  name: 'South East Arrow',
  unified: '2198-FE0F',
  keywords: ['down_right_arrow', 'blue-square', 'direction', 'diagonal', 'southeast'],
  sheet: [56, 9],
  shortName: 'arrow_lower_right'
}, {
  name: 'Downwards Black Arrow',
  unified: '2B07-FE0F',
  keywords: ['down_arrow', 'blue-square', 'direction', 'bottom'],
  sheet: [59, 21],
  shortName: 'arrow_down'
}, {
  name: 'South West Arrow',
  unified: '2199-FE0F',
  keywords: ['down_left_arrow', 'blue-square', 'direction', 'diagonal', 'southwest'],
  sheet: [56, 10],
  shortName: 'arrow_lower_left'
}, {
  name: 'Leftwards Black Arrow',
  unified: '2B05-FE0F',
  keywords: ['left_arrow', 'blue-square', 'previous', 'back'],
  sheet: [59, 19],
  shortName: 'arrow_left'
}, {
  name: 'North West Arrow',
  unified: '2196-FE0F',
  keywords: ['up_left_arrow', 'blue-square', 'point', 'direction', 'diagonal', 'northwest'],
  sheet: [56, 7],
  shortName: 'arrow_upper_left'
}, {
  name: 'Up Down Arrow',
  unified: '2195-FE0F',
  keywords: ['up_down_arrow', 'blue-square', 'direction', 'way', 'vertical'],
  sheet: [56, 6],
  shortName: 'arrow_up_down'
}, {
  name: 'Left Right Arrow',
  unified: '2194-FE0F',
  keywords: ['left_right_arrow', 'shape', 'direction', 'horizontal', 'sideways'],
  sheet: [56, 5],
  shortName: 'left_right_arrow'
}, {
  name: 'Leftwards Arrow with Hook',
  unified: '21A9-FE0F',
  keywords: ['right_arrow_curving_left', 'back', 'return', 'blue-square', 'undo', 'enter'],
  sheet: [56, 11],
  shortName: 'leftwards_arrow_with_hook'
}, {
  name: 'Rightwards Arrow with Hook',
  unified: '21AA-FE0F',
  keywords: ['left_arrow_curving_right', 'blue-square', 'return', 'rotate', 'direction'],
  sheet: [56, 12],
  shortName: 'arrow_right_hook'
}, {
  name: 'Arrow Pointing Rightwards Then Curving Upwards',
  unified: '2934-FE0F',
  keywords: ['right_arrow_curving_up', 'blue-square', 'direction', 'top'],
  sheet: [59, 17],
  shortName: 'arrow_heading_up'
}, {
  name: 'Arrow Pointing Rightwards Then Curving Downwards',
  unified: '2935-FE0F',
  keywords: ['right_arrow_curving_down', 'blue-square', 'direction', 'bottom'],
  sheet: [59, 18],
  shortName: 'arrow_heading_down'
}, {
  name: 'Clockwise Downwards and Upwards Open Circle Arrows',
  unified: '1F503',
  keywords: ['clockwise_vertical_arrows', 'sync', 'cycle', 'round', 'repeat'],
  sheet: [29, 28],
  shortName: 'arrows_clockwise'
}, {
  name: 'Anticlockwise Downwards and Upwards Open Circle Arrows',
  unified: '1F504',
  keywords: ['counterclockwise_arrows_button', 'blue-square', 'sync', 'cycle'],
  sheet: [29, 29],
  shortName: 'arrows_counterclockwise'
}, {
  name: 'Back with Leftwards Arrow Above',
  unified: '1F519',
  keywords: ['back_arrow', 'arrow', 'words', 'return'],
  sheet: [29, 50],
  shortName: 'back'
}, {
  name: 'End with Leftwards Arrow Above',
  unified: '1F51A',
  keywords: ['end_arrow', 'words', 'arrow'],
  sheet: [29, 51],
  shortName: 'end'
}, {
  name: 'On with Exclamation Mark with Left Right Arrow Above',
  unified: '1F51B',
  keywords: ['on_arrow', 'arrow', 'words'],
  sheet: [29, 52],
  shortName: 'on'
}, {
  name: 'Soon with Rightwards Arrow Above',
  unified: '1F51C',
  keywords: ['soon_arrow', 'arrow', 'words'],
  sheet: [29, 53],
  shortName: 'soon'
}, {
  name: 'Top with Upwards Arrow Above',
  unified: '1F51D',
  keywords: ['top_arrow', 'words', 'blue-square'],
  sheet: [29, 54],
  shortName: 'top'
}, {
  name: 'Place of Worship',
  unified: '1F6D0',
  keywords: ['place_of_worship', 'religion', 'church', 'temple', 'prayer'],
  sheet: [38, 2],
  shortName: 'place_of_worship'
}, {
  name: 'Atom Symbol',
  unified: '269B-FE0F',
  keywords: ['atom_symbol', 'science', 'physics', 'chemistry'],
  sheet: [57, 35],
  shortName: 'atom_symbol'
}, {
  name: 'Om',
  unified: '1F549-FE0F',
  keywords: ['om', 'hinduism', 'buddhism', 'sikhism', 'jainism'],
  sheet: [30, 26],
  shortName: 'om_symbol'
}, {
  name: 'Star of David',
  unified: '2721-FE0F',
  keywords: ['star_of_david', 'judaism'],
  sheet: [58, 56],
  shortName: 'star_of_david'
}, {
  name: 'Wheel of Dharma',
  unified: '2638-FE0F',
  keywords: ['wheel_of_dharma', 'hinduism', 'buddhism', 'sikhism', 'jainism'],
  sheet: [57, 2],
  shortName: 'wheel_of_dharma'
}, {
  name: 'Yin Yang',
  unified: '262F-FE0F',
  keywords: ['yin_yang', 'balance'],
  sheet: [57, 1],
  shortName: 'yin_yang'
}, {
  name: 'Latin Cross',
  unified: '271D-FE0F',
  keywords: ['latin_cross', 'christianity'],
  sheet: [58, 55],
  shortName: 'latin_cross'
}, {
  name: 'Orthodox Cross',
  unified: '2626-FE0F',
  keywords: ['orthodox_cross', 'suppedaneum', 'religion'],
  sheet: [56, 59],
  shortName: 'orthodox_cross'
}, {
  name: 'Star and Crescent',
  unified: '262A-FE0F',
  keywords: ['star_and_crescent', 'islam'],
  sheet: [56, 60],
  shortName: 'star_and_crescent'
}, {
  name: 'Peace Symbol',
  unified: '262E-FE0F',
  keywords: ['peace_symbol', 'hippie'],
  sheet: [57, 0],
  shortName: 'peace_symbol'
}, {
  name: 'Menorah with Nine Branches',
  unified: '1F54E',
  keywords: ['menorah', 'hanukkah', 'candles', 'jewish'],
  sheet: [30, 31],
  shortName: 'menorah_with_nine_branches'
}, {
  name: 'Six Pointed Star with Middle Dot',
  unified: '1F52F',
  keywords: ['dotted_six_pointed_star', 'purple-square', 'religion', 'jewish', 'hexagram'],
  sheet: [30, 11],
  shortName: 'six_pointed_star'
}, {
  name: 'Aries',
  unified: '2648',
  keywords: ['aries', 'sign', 'purple-square', 'zodiac', 'astrology'],
  sheet: [57, 7],
  shortName: 'aries'
}, {
  name: 'Taurus',
  unified: '2649',
  keywords: ['taurus', 'purple-square', 'sign', 'zodiac', 'astrology'],
  sheet: [57, 8],
  shortName: 'taurus'
}, {
  name: 'Gemini',
  unified: '264A',
  keywords: ['gemini', 'sign', 'zodiac', 'purple-square', 'astrology'],
  sheet: [57, 9],
  shortName: 'gemini'
}, {
  name: 'Cancer',
  unified: '264B',
  keywords: ['cancer', 'sign', 'zodiac', 'purple-square', 'astrology'],
  sheet: [57, 10],
  shortName: 'cancer'
}, {
  name: 'Leo',
  unified: '264C',
  keywords: ['leo', 'sign', 'purple-square', 'zodiac', 'astrology'],
  sheet: [57, 11],
  shortName: 'leo'
}, {
  name: 'Virgo',
  unified: '264D',
  keywords: ['virgo', 'sign', 'zodiac', 'purple-square', 'astrology'],
  sheet: [57, 12],
  shortName: 'virgo'
}, {
  name: 'Libra',
  unified: '264E',
  keywords: ['libra', 'sign', 'purple-square', 'zodiac', 'astrology'],
  sheet: [57, 13],
  shortName: 'libra'
}, {
  name: 'Scorpius',
  unified: '264F',
  keywords: ['scorpio', 'sign', 'zodiac', 'purple-square', 'astrology', 'scorpio'],
  sheet: [57, 14],
  shortName: 'scorpius'
}, {
  name: 'Sagittarius',
  unified: '2650',
  keywords: ['sagittarius', 'sign', 'zodiac', 'purple-square', 'astrology'],
  sheet: [57, 15],
  shortName: 'sagittarius'
}, {
  name: 'Capricorn',
  unified: '2651',
  keywords: ['capricorn', 'sign', 'zodiac', 'purple-square', 'astrology'],
  sheet: [57, 16],
  shortName: 'capricorn'
}, {
  name: 'Aquarius',
  unified: '2652',
  keywords: ['aquarius', 'sign', 'purple-square', 'zodiac', 'astrology'],
  sheet: [57, 17],
  shortName: 'aquarius'
}, {
  name: 'Pisces',
  unified: '2653',
  keywords: ['pisces', 'purple-square', 'sign', 'zodiac', 'astrology'],
  sheet: [57, 18],
  shortName: 'pisces'
}, {
  name: 'Ophiuchus',
  unified: '26CE',
  keywords: ['ophiuchus', 'sign', 'purple-square', 'constellation', 'astrology'],
  sheet: [57, 49],
  shortName: 'ophiuchus'
}, {
  name: 'Twisted Rightwards Arrows',
  unified: '1F500',
  keywords: ['shuffle_tracks_button', 'blue-square', 'shuffle', 'music', 'random'],
  sheet: [29, 25],
  shortName: 'twisted_rightwards_arrows'
}, {
  name: 'Clockwise Rightwards and Leftwards Open Circle Arrows',
  unified: '1F501',
  keywords: ['repeat_button', 'loop', 'record'],
  sheet: [29, 26],
  shortName: 'repeat'
}, {
  name: 'Clockwise Rightwards and Leftwards Open Circle Arrows with Circled One Overlay',
  unified: '1F502',
  keywords: ['repeat_single_button', 'blue-square', 'loop'],
  sheet: [29, 27],
  shortName: 'repeat_one'
}, {
  name: 'Black Right-Pointing Triangle',
  unified: '25B6-FE0F',
  keywords: ['play_button', 'blue-square', 'right', 'direction', 'play'],
  sheet: [56, 34],
  shortName: 'arrow_forward'
}, {
  name: 'Black Right-Pointing Double Triangle',
  unified: '23E9',
  keywords: ['fast_forward_button', 'blue-square', 'play', 'speed', 'continue'],
  sheet: [56, 17],
  shortName: 'fast_forward'
}, {
  name: 'Next Track Button',
  unified: '23ED-FE0F',
  keywords: ['next_track_button', 'forward', 'next', 'blue-square'],
  sheet: [56, 21],
  shortName: 'black_right_pointing_double_triangle_with_vertical_bar'
}, {
  name: 'Play or Pause Button',
  unified: '23EF-FE0F',
  keywords: ['play_or_pause_button', 'blue-square', 'play', 'pause'],
  sheet: [56, 23],
  shortName: 'black_right_pointing_triangle_with_double_vertical_bar'
}, {
  name: 'Black Left-Pointing Triangle',
  unified: '25C0-FE0F',
  keywords: ['reverse_button', 'blue-square', 'left', 'direction'],
  sheet: [56, 35],
  shortName: 'arrow_backward'
}, {
  name: 'Black Left-Pointing Double Triangle',
  unified: '23EA',
  keywords: ['fast_reverse_button', 'play', 'blue-square'],
  sheet: [56, 18],
  shortName: 'rewind'
}, {
  name: 'Last Track Button',
  unified: '23EE-FE0F',
  keywords: ['last_track_button', 'backward'],
  sheet: [56, 22],
  shortName: 'black_left_pointing_double_triangle_with_vertical_bar'
}, {
  name: 'Up-Pointing Small Red Triangle',
  unified: '1F53C',
  keywords: ['upwards_button', 'blue-square', 'triangle', 'direction', 'point', 'forward', 'top'],
  sheet: [30, 24],
  shortName: 'arrow_up_small'
}, {
  name: 'Black Up-Pointing Double Triangle',
  unified: '23EB',
  keywords: ['fast_up_button', 'blue-square', 'direction', 'top'],
  sheet: [56, 19],
  shortName: 'arrow_double_up'
}, {
  name: 'Down-Pointing Small Red Triangle',
  unified: '1F53D',
  keywords: ['downwards_button', 'blue-square', 'direction', 'bottom'],
  sheet: [30, 25],
  shortName: 'arrow_down_small'
}, {
  name: 'Black Down-Pointing Double Triangle',
  unified: '23EC',
  keywords: ['fast_down_button', 'blue-square', 'direction', 'bottom'],
  sheet: [56, 20],
  shortName: 'arrow_double_down'
}, {
  name: 'Pause Button',
  unified: '23F8-FE0F',
  keywords: ['pause_button', 'pause', 'blue-square'],
  sheet: [56, 28],
  shortName: 'double_vertical_bar'
}, {
  name: 'Stop Button',
  unified: '23F9-FE0F',
  keywords: ['stop_button', 'blue-square'],
  sheet: [56, 29],
  shortName: 'black_square_for_stop'
}, {
  name: 'Record Button',
  unified: '23FA-FE0F',
  keywords: ['record_button', 'blue-square'],
  sheet: [56, 30],
  shortName: 'black_circle_for_record'
}, {
  name: 'Eject Button',
  unified: '23CF-FE0F',
  keywords: ['eject_button', 'blue-square'],
  sheet: [56, 16],
  shortName: 'eject'
}, {
  name: 'Cinema',
  unified: '1F3A6',
  keywords: ['cinema', 'blue-square', 'record', 'film', 'movie', 'curtain', 'stage', 'theater'],
  sheet: [7, 41],
  shortName: 'cinema'
}, {
  name: 'Low Brightness Symbol',
  unified: '1F505',
  keywords: ['dim_button', 'sun', 'afternoon', 'warm', 'summer'],
  sheet: [29, 30],
  shortName: 'low_brightness'
}, {
  name: 'High Brightness Symbol',
  unified: '1F506',
  keywords: ['bright_button', 'sun', 'light'],
  sheet: [29, 31],
  shortName: 'high_brightness'
}, {
  name: 'Antenna with Bars',
  unified: '1F4F6',
  keywords: ['antenna_bars', 'blue-square', 'reception', 'phone', 'internet', 'connection', 'wifi', 'bluetooth', 'bars'],
  sheet: [29, 16],
  shortName: 'signal_strength'
}, {
  name: 'Vibration Mode',
  unified: '1F4F3',
  keywords: ['vibration_mode', 'orange-square', 'phone'],
  sheet: [29, 13],
  shortName: 'vibration_mode'
}, {
  name: 'Mobile Phone off',
  unified: '1F4F4',
  keywords: ['mobile_phone_off', 'mute', 'orange-square', 'silence', 'quiet'],
  sheet: [29, 14],
  shortName: 'mobile_phone_off'
}, {
  name: 'Female Sign',
  unified: '2640-FE0F',
  keywords: ['female_sign', 'woman', 'women', 'lady', 'girl'],
  sheet: [57, 5],
  hidden: ['apple'],
  shortName: 'female_sign'
}, {
  name: 'Male Sign',
  unified: '2642-FE0F',
  keywords: ['male_sign', 'man', 'boy', 'men'],
  sheet: [57, 6],
  hidden: ['apple'],
  shortName: 'male_sign'
}, {
  name: 'Transgender Symbol',
  unified: '26A7-FE0F',
  keywords: ['transgender symbol', 'lgbtq'],
  sheet: [57, 39],
  shortName: 'transgender_symbol'
}, {
  name: 'Heavy Multiplication X',
  unified: '2716-FE0F',
  keywords: ['multiplication_sign', 'math', 'calculation'],
  sheet: [58, 54],
  shortName: 'heavy_multiplication_x'
}, {
  name: 'Heavy Plus Sign',
  unified: '2795',
  keywords: ['plus_sign', 'math', 'calculation', 'addition', 'more', 'increase'],
  sheet: [59, 11],
  shortName: 'heavy_plus_sign'
}, {
  name: 'Heavy Minus Sign',
  unified: '2796',
  keywords: ['minus_sign', 'math', 'calculation', 'subtract', 'less'],
  sheet: [59, 12],
  shortName: 'heavy_minus_sign'
}, {
  name: 'Heavy Division Sign',
  unified: '2797',
  keywords: ['division_sign', 'divide', 'math', 'calculation'],
  sheet: [59, 13],
  shortName: 'heavy_division_sign'
}, {
  name: 'Heavy Equals Sign',
  unified: '1F7F0',
  keywords: ['heavy equals sign', 'math'],
  sheet: [38, 43],
  hidden: ['facebook'],
  shortName: 'heavy_equals_sign'
}, {
  name: 'Infinity',
  unified: '267E-FE0F',
  keywords: ['infinity', 'forever'],
  sheet: [57, 26],
  shortName: 'infinity'
}, {
  name: 'Double Exclamation Mark',
  unified: '203C-FE0F',
  keywords: ['double_exclamation_mark', 'exclamation', 'surprise'],
  sheet: [56, 1],
  shortName: 'bangbang'
}, {
  name: 'Exclamation Question Mark',
  unified: '2049-FE0F',
  keywords: ['exclamation_question_mark', 'wat', 'punctuation', 'surprise'],
  sheet: [56, 2],
  shortName: 'interrobang'
}, {
  name: 'Black Question Mark Ornament',
  unified: '2753',
  keywords: ['question_mark', 'doubt', 'confused'],
  sheet: [59, 3],
  shortName: 'question'
}, {
  name: 'White Question Mark Ornament',
  unified: '2754',
  keywords: ['white_question_mark', 'doubts', 'gray', 'huh', 'confused'],
  sheet: [59, 4],
  shortName: 'grey_question'
}, {
  name: 'White Exclamation Mark Ornament',
  unified: '2755',
  keywords: ['white_exclamation_mark', 'surprise', 'punctuation', 'gray', 'wow', 'warning'],
  sheet: [59, 5],
  shortName: 'grey_exclamation'
}, {
  name: 'Heavy Exclamation Mark Symbol',
  unified: '2757',
  keywords: ['exclamation_mark', 'heavy_exclamation_mark', 'danger', 'surprise', 'punctuation', 'wow', 'warning'],
  sheet: [59, 6],
  shortNames: ['heavy_exclamation_mark'],
  shortName: 'exclamation'
}, {
  name: 'Wavy Dash',
  unified: '3030-FE0F',
  keywords: ['wavy_dash', 'draw', 'line', 'moustache', 'mustache', 'squiggle', 'scribble'],
  sheet: [59, 26],
  shortName: 'wavy_dash'
}, {
  name: 'Currency Exchange',
  unified: '1F4B1',
  keywords: ['currency_exchange', 'money', 'sales', 'dollar', 'travel'],
  sheet: [28, 8],
  shortName: 'currency_exchange'
}, {
  name: 'Heavy Dollar Sign',
  unified: '1F4B2',
  keywords: ['heavy_dollar_sign', 'money', 'sales', 'payment', 'currency', 'buck'],
  sheet: [28, 9],
  shortName: 'heavy_dollar_sign'
}, {
  name: 'Medical Symbol',
  unified: '2695-FE0F',
  keywords: ['medical_symbol', 'health', 'hospital'],
  sheet: [57, 31],
  hidden: ['apple'],
  shortNames: ['staff_of_aesculapius'],
  shortName: 'medical_symbol'
}, {
  name: 'Black Universal Recycling Symbol',
  unified: '267B-FE0F',
  keywords: ['recycling_symbol', 'arrow', 'environment', 'garbage', 'trash'],
  sheet: [57, 25],
  shortName: 'recycle'
}, {
  name: 'Fleur-De-Lis',
  unified: '269C-FE0F',
  keywords: ['fleur_de_lis', 'decorative', 'scout'],
  sheet: [57, 36],
  shortName: 'fleur_de_lis'
}, {
  name: 'Trident Emblem',
  unified: '1F531',
  keywords: ['trident_emblem', 'weapon', 'spear'],
  sheet: [30, 13],
  shortName: 'trident'
}, {
  name: 'Name Badge',
  unified: '1F4DB',
  keywords: ['name_badge', 'fire', 'forbid'],
  sheet: [28, 50],
  shortName: 'name_badge'
}, {
  name: 'Japanese Symbol for Beginner',
  unified: '1F530',
  keywords: ['japanese_symbol_for_beginner', 'badge', 'shield'],
  sheet: [30, 12],
  shortName: 'beginner'
}, {
  name: 'Heavy Large Circle',
  unified: '2B55',
  keywords: ['hollow_red_circle', 'circle', 'round'],
  sheet: [59, 25],
  shortName: 'o'
}, {
  name: 'White Heavy Check Mark',
  unified: '2705',
  keywords: ['check_mark_button', 'green-square', 'ok', 'agree', 'vote', 'election', 'answer', 'tick'],
  sheet: [58, 24],
  shortName: 'white_check_mark'
}, {
  name: 'Ballot Box with Check',
  unified: '2611-FE0F',
  keywords: ['check_box_with_check', 'ok', 'agree', 'confirm', 'black-square', 'vote', 'election', 'yes', 'tick'],
  sheet: [56, 46],
  shortName: 'ballot_box_with_check'
}, {
  name: 'Heavy Check Mark',
  unified: '2714-FE0F',
  keywords: ['check_mark', 'ok', 'nike', 'answer', 'yes', 'tick'],
  sheet: [58, 53],
  shortName: 'heavy_check_mark'
}, {
  name: 'Cross Mark',
  unified: '274C',
  keywords: ['cross_mark', 'no', 'delete', 'remove', 'cancel', 'red'],
  sheet: [59, 1],
  shortName: 'x'
}, {
  name: 'Negative Squared Cross Mark',
  unified: '274E',
  keywords: ['cross_mark_button', 'x', 'green-square', 'no', 'deny'],
  sheet: [59, 2],
  shortName: 'negative_squared_cross_mark'
}, {
  name: 'Curly Loop',
  unified: '27B0',
  keywords: ['curly_loop', 'scribble', 'draw', 'shape', 'squiggle'],
  sheet: [59, 15],
  shortName: 'curly_loop'
}, {
  name: 'Double Curly Loop',
  unified: '27BF',
  keywords: ['double_curly_loop', 'tape', 'cassette'],
  sheet: [59, 16],
  shortName: 'loop'
}, {
  name: 'Part Alternation Mark',
  unified: '303D-FE0F',
  keywords: ['part_alternation_mark', 'graph', 'presentation', 'stats', 'business', 'economics', 'bad'],
  sheet: [59, 27],
  shortName: 'part_alternation_mark'
}, {
  name: 'Eight Spoked Asterisk',
  unified: '2733-FE0F',
  keywords: ['eight_spoked_asterisk', 'star', 'sparkle', 'green-square'],
  sheet: [58, 58],
  shortName: 'eight_spoked_asterisk'
}, {
  name: 'Eight Pointed Black Star',
  unified: '2734-FE0F',
  keywords: ['eight_pointed_star', 'orange-square', 'shape', 'polygon'],
  sheet: [58, 59],
  shortName: 'eight_pointed_black_star'
}, {
  name: 'Sparkle',
  unified: '2747-FE0F',
  keywords: ['sparkle', 'stars', 'green-square', 'awesome', 'good', 'fireworks'],
  sheet: [59, 0],
  shortName: 'sparkle'
}, {
  name: 'Copyright Sign',
  unified: '00A9-FE0F',
  keywords: ['copyright', 'ip', 'license', 'circle', 'law', 'legal'],
  sheet: [0, 12],
  hidden: ['facebook'],
  shortName: 'copyright'
}, {
  name: 'Registered Sign',
  unified: '00AE-FE0F',
  keywords: ['registered', 'alphabet', 'circle'],
  sheet: [0, 13],
  hidden: ['facebook'],
  shortName: 'registered'
}, {
  name: 'Trade Mark Sign',
  unified: '2122-FE0F',
  keywords: ['trade_mark', 'trademark', 'brand', 'law', 'legal'],
  sheet: [56, 3],
  shortName: 'tm'
}, {
  name: 'Hash Key',
  unified: '0023-FE0F-20E3',
  keywords: ['keycap_', 'symbol', 'blue-square', 'twitter'],
  sheet: [0, 0],
  hidden: ['facebook'],
  shortName: 'hash'
}, {
  name: 'Keycap: *',
  unified: '002A-FE0F-20E3',
  keywords: ['keycap_', 'star', 'keycap'],
  sheet: [0, 1],
  hidden: ['facebook'],
  shortName: 'keycap_star'
}, {
  name: 'Keycap 0',
  unified: '0030-FE0F-20E3',
  keywords: ['keycap_0', '0', 'numbers', 'blue-square', 'null'],
  sheet: [0, 2],
  hidden: ['facebook'],
  shortName: 'zero'
}, {
  name: 'Keycap 1',
  unified: '0031-FE0F-20E3',
  keywords: ['keycap_1', 'blue-square', 'numbers', '1'],
  sheet: [0, 3],
  hidden: ['facebook'],
  shortName: 'one'
}, {
  name: 'Keycap 2',
  unified: '0032-FE0F-20E3',
  keywords: ['keycap_2', 'numbers', '2', 'prime', 'blue-square'],
  sheet: [0, 4],
  hidden: ['facebook'],
  shortName: 'two'
}, {
  name: 'Keycap 3',
  unified: '0033-FE0F-20E3',
  keywords: ['keycap_3', '3', 'numbers', 'prime', 'blue-square'],
  sheet: [0, 5],
  hidden: ['facebook'],
  shortName: 'three'
}, {
  name: 'Keycap 4',
  unified: '0034-FE0F-20E3',
  keywords: ['keycap_4', '4', 'numbers', 'blue-square'],
  sheet: [0, 6],
  hidden: ['facebook'],
  shortName: 'four'
}, {
  name: 'Keycap 5',
  unified: '0035-FE0F-20E3',
  keywords: ['keycap_5', '5', 'numbers', 'blue-square', 'prime'],
  sheet: [0, 7],
  hidden: ['facebook'],
  shortName: 'five'
}, {
  name: 'Keycap 6',
  unified: '0036-FE0F-20E3',
  keywords: ['keycap_6', '6', 'numbers', 'blue-square'],
  sheet: [0, 8],
  hidden: ['facebook'],
  shortName: 'six'
}, {
  name: 'Keycap 7',
  unified: '0037-FE0F-20E3',
  keywords: ['keycap_7', '7', 'numbers', 'blue-square', 'prime'],
  sheet: [0, 9],
  hidden: ['facebook'],
  shortName: 'seven'
}, {
  name: 'Keycap 8',
  unified: '0038-FE0F-20E3',
  keywords: ['keycap_8', '8', 'blue-square', 'numbers'],
  sheet: [0, 10],
  hidden: ['facebook'],
  shortName: 'eight'
}, {
  name: 'Keycap 9',
  unified: '0039-FE0F-20E3',
  keywords: ['keycap_9', 'blue-square', 'numbers', '9'],
  sheet: [0, 11],
  hidden: ['facebook'],
  shortName: 'nine'
}, {
  name: 'Keycap Ten',
  unified: '1F51F',
  keywords: ['keycap_10', 'numbers', '10', 'blue-square'],
  sheet: [29, 56],
  shortName: 'keycap_ten'
}, {
  name: 'Input Symbol for Latin Capital Letters',
  unified: '1F520',
  keywords: ['input_latin_uppercase', 'alphabet', 'words', 'blue-square'],
  sheet: [29, 57],
  shortName: 'capital_abcd'
}, {
  name: 'Input Symbol for Latin Small Letters',
  unified: '1F521',
  keywords: ['input_latin_lowercase', 'blue-square', 'alphabet'],
  sheet: [29, 58],
  shortName: 'abcd'
}, {
  name: 'Input Symbol for Numbers',
  unified: '1F522',
  keywords: ['input_numbers', 'numbers', 'blue-square', '1234', '1', '2', '3', '4'],
  sheet: [29, 59],
  shortName: '1234'
}, {
  name: 'Input Symbol for Symbols',
  unified: '1F523',
  keywords: ['input_symbols', 'blue-square', 'music', 'note', 'ampersand', 'percent', 'glyphs', 'characters'],
  sheet: [29, 60],
  shortName: 'symbols'
}, {
  name: 'Input Symbol for Latin Letters',
  unified: '1F524',
  keywords: ['input_latin_letters', 'blue-square', 'alphabet'],
  sheet: [30, 0],
  shortName: 'abc'
}, {
  name: 'Negative Squared Latin Capital Letter a',
  unified: '1F170-FE0F',
  keywords: ['a_button', 'red-square', 'alphabet', 'letter'],
  sheet: [0, 16],
  shortName: 'a'
}, {
  name: 'Negative Squared Ab',
  unified: '1F18E',
  keywords: ['ab_button', 'red-square', 'alphabet'],
  sheet: [0, 20],
  shortName: 'ab'
}, {
  name: 'Negative Squared Latin Capital Letter B',
  unified: '1F171-FE0F',
  keywords: ['b_button', 'red-square', 'alphabet', 'letter'],
  sheet: [0, 17],
  shortName: 'b'
}, {
  name: 'Squared Cl',
  unified: '1F191',
  keywords: ['cl_button', 'alphabet', 'words', 'red-square'],
  sheet: [0, 21],
  shortName: 'cl'
}, {
  name: 'Squared Cool',
  unified: '1F192',
  keywords: ['cool_button', 'words', 'blue-square'],
  sheet: [0, 22],
  shortName: 'cool'
}, {
  name: 'Squared Free',
  unified: '1F193',
  keywords: ['free_button', 'blue-square', 'words'],
  sheet: [0, 23],
  shortName: 'free'
}, {
  name: 'Information Source',
  unified: '2139-FE0F',
  keywords: ['information', 'blue-square', 'alphabet', 'letter'],
  sheet: [56, 4],
  shortName: 'information_source'
}, {
  name: 'Squared Id',
  unified: '1F194',
  keywords: ['id_button', 'purple-square', 'words'],
  sheet: [0, 24],
  shortName: 'id'
}, {
  name: 'Circled Latin Capital Letter M',
  unified: '24C2-FE0F',
  keywords: ['circled_m', 'alphabet', 'blue-circle', 'letter'],
  sheet: [56, 31],
  shortName: 'm'
}, {
  name: 'Squared New',
  unified: '1F195',
  keywords: ['new_button', 'blue-square', 'words', 'start'],
  sheet: [0, 25],
  shortName: 'new'
}, {
  name: 'Squared Ng',
  unified: '1F196',
  keywords: ['ng_button', 'blue-square', 'words', 'shape', 'icon'],
  sheet: [0, 26],
  shortName: 'ng'
}, {
  name: 'Negative Squared Latin Capital Letter O',
  unified: '1F17E-FE0F',
  keywords: ['o_button', 'alphabet', 'red-square', 'letter'],
  sheet: [0, 18],
  shortName: 'o2'
}, {
  name: 'Squared Ok',
  unified: '1F197',
  keywords: ['ok_button', 'good', 'agree', 'yes', 'blue-square'],
  sheet: [0, 27],
  shortName: 'ok'
}, {
  name: 'Negative Squared Latin Capital Letter P',
  unified: '1F17F-FE0F',
  keywords: ['p_button', 'cars', 'blue-square', 'alphabet', 'letter'],
  sheet: [0, 19],
  shortName: 'parking'
}, {
  name: 'Squared Sos',
  unified: '1F198',
  keywords: ['sos_button', 'help', 'red-square', 'words', 'emergency', '911'],
  sheet: [0, 28],
  shortName: 'sos'
}, {
  name: 'Squared Up with Exclamation Mark',
  unified: '1F199',
  keywords: ['up_button', 'blue-square', 'above', 'high'],
  sheet: [0, 29],
  shortName: 'up'
}, {
  name: 'Squared Vs',
  unified: '1F19A',
  keywords: ['vs_button', 'words', 'orange-square'],
  sheet: [0, 30],
  shortName: 'vs'
}, {
  name: 'Squared Katakana Koko',
  unified: '1F201',
  keywords: ['japanese_here_button', 'blue-square', 'here', 'katakana', 'japanese', 'destination'],
  sheet: [4, 45],
  shortName: 'koko'
}, {
  name: 'Squared Katakana Sa',
  unified: '1F202-FE0F',
  keywords: ['japanese_service_charge_button', 'japanese', 'blue-square', 'katakana'],
  sheet: [4, 46],
  shortName: 'sa'
}, {
  name: 'Squared Cjk Unified Ideograph-6708',
  unified: '1F237-FE0F',
  keywords: ['japanese_monthly_amount_button', 'chinese', 'month', 'moon', 'japanese', 'orange-square', 'kanji'],
  sheet: [4, 54],
  shortName: 'u6708'
}, {
  name: 'Squared Cjk Unified Ideograph-6709',
  unified: '1F236',
  keywords: ['japanese_not_free_of_charge_button', 'orange-square', 'chinese', 'have', 'kanji'],
  sheet: [4, 53],
  shortName: 'u6709'
}, {
  name: 'Squared Cjk Unified Ideograph-6307',
  unified: '1F22F',
  keywords: ['japanese_reserved_button', 'chinese', 'point', 'green-square', 'kanji'],
  sheet: [4, 48],
  shortName: 'u6307'
}, {
  name: 'Circled Ideograph Advantage',
  unified: '1F250',
  keywords: ['japanese_bargain_button', 'chinese', 'kanji', 'obtain', 'get', 'circle'],
  sheet: [4, 58],
  shortName: 'ideograph_advantage'
}, {
  name: 'Squared Cjk Unified Ideograph-5272',
  unified: '1F239',
  keywords: ['japanese_discount_button', 'cut', 'divide', 'chinese', 'kanji', 'pink-square'],
  sheet: [4, 56],
  shortName: 'u5272'
}, {
  name: 'Squared Cjk Unified Ideograph-7121',
  unified: '1F21A',
  keywords: ['japanese_free_of_charge_button', 'nothing', 'chinese', 'kanji', 'japanese', 'orange-square'],
  sheet: [4, 47],
  shortName: 'u7121'
}, {
  name: 'Squared Cjk Unified Ideograph-7981',
  unified: '1F232',
  keywords: ['japanese_prohibited_button', 'kanji', 'japanese', 'chinese', 'forbidden', 'limit', 'restricted', 'red-square'],
  sheet: [4, 49],
  shortName: 'u7981'
}, {
  name: 'Circled Ideograph Accept',
  unified: '1F251',
  keywords: ['japanese_acceptable_button', 'ok', 'good', 'chinese', 'kanji', 'agree', 'yes', 'orange-circle'],
  sheet: [4, 59],
  shortName: 'accept'
}, {
  name: 'Squared Cjk Unified Ideograph-7533',
  unified: '1F238',
  keywords: ['japanese_application_button', 'chinese', 'japanese', 'kanji', 'orange-square'],
  sheet: [4, 55],
  shortName: 'u7533'
}, {
  name: 'Squared Cjk Unified Ideograph-5408',
  unified: '1F234',
  keywords: ['japanese_passing_grade_button', 'japanese', 'chinese', 'join', 'kanji', 'red-square'],
  sheet: [4, 51],
  shortName: 'u5408'
}, {
  name: 'Squared Cjk Unified Ideograph-7a7a',
  unified: '1F233',
  keywords: ['japanese_vacancy_button', 'kanji', 'japanese', 'chinese', 'empty', 'sky', 'blue-square'],
  sheet: [4, 50],
  shortName: 'u7a7a'
}, {
  name: 'Circled Ideograph Congratulation',
  unified: '3297-FE0F',
  keywords: ['japanese_congratulations_button', 'chinese', 'kanji', 'japanese', 'red-circle'],
  sheet: [59, 28],
  shortName: 'congratulations'
}, {
  name: 'Circled Ideograph Secret',
  unified: '3299-FE0F',
  keywords: ['japanese_secret_button', 'privacy', 'chinese', 'sshh', 'kanji', 'red-circle'],
  sheet: [59, 29],
  shortName: 'secret'
}, {
  name: 'Squared Cjk Unified Ideograph-55b6',
  unified: '1F23A',
  keywords: ['japanese_open_for_business_button', 'japanese', 'opening hours', 'orange-square'],
  sheet: [4, 57],
  shortName: 'u55b6'
}, {
  name: 'Squared Cjk Unified Ideograph-6e80',
  unified: '1F235',
  keywords: ['japanese_no_vacancy_button', 'full', 'chinese', 'japanese', 'red-square', 'kanji'],
  sheet: [4, 52],
  shortName: 'u6e80'
}, {
  name: 'Large Red Circle',
  unified: '1F534',
  keywords: ['red_circle', 'shape', 'error', 'danger'],
  sheet: [30, 16],
  shortName: 'red_circle'
}, {
  name: 'Large Orange Circle',
  unified: '1F7E0',
  keywords: ['orange_circle', 'round'],
  sheet: [38, 31],
  shortName: 'large_orange_circle'
}, {
  name: 'Large Yellow Circle',
  unified: '1F7E1',
  keywords: ['yellow_circle', 'round'],
  sheet: [38, 32],
  shortName: 'large_yellow_circle'
}, {
  name: 'Large Green Circle',
  unified: '1F7E2',
  keywords: ['green_circle', 'round'],
  sheet: [38, 33],
  shortName: 'large_green_circle'
}, {
  name: 'Large Blue Circle',
  unified: '1F535',
  keywords: ['blue_circle', 'shape', 'icon', 'button'],
  sheet: [30, 17],
  shortName: 'large_blue_circle'
}, {
  name: 'Large Purple Circle',
  unified: '1F7E3',
  keywords: ['purple_circle', 'round'],
  sheet: [38, 34],
  shortName: 'large_purple_circle'
}, {
  name: 'Large Brown Circle',
  unified: '1F7E4',
  keywords: ['brown_circle', 'round'],
  sheet: [38, 35],
  shortName: 'large_brown_circle'
}, {
  name: 'Medium Black Circle',
  unified: '26AB',
  keywords: ['black_circle', 'shape', 'button', 'round'],
  sheet: [57, 41],
  shortName: 'black_circle'
}, {
  name: 'Medium White Circle',
  unified: '26AA',
  keywords: ['white_circle', 'shape', 'round'],
  sheet: [57, 40],
  shortName: 'white_circle'
}, {
  name: 'Large Red Square',
  unified: '1F7E5',
  keywords: ['red_square'],
  sheet: [38, 36],
  shortName: 'large_red_square'
}, {
  name: 'Large Orange Square',
  unified: '1F7E7',
  keywords: ['orange_square'],
  sheet: [38, 38],
  shortName: 'large_orange_square'
}, {
  name: 'Large Yellow Square',
  unified: '1F7E8',
  keywords: ['yellow_square'],
  sheet: [38, 39],
  shortName: 'large_yellow_square'
}, {
  name: 'Large Green Square',
  unified: '1F7E9',
  keywords: ['green_square'],
  sheet: [38, 40],
  shortName: 'large_green_square'
}, {
  name: 'Large Blue Square',
  unified: '1F7E6',
  keywords: ['blue_square'],
  sheet: [38, 37],
  shortName: 'large_blue_square'
}, {
  name: 'Large Purple Square',
  unified: '1F7EA',
  keywords: ['purple_square'],
  sheet: [38, 41],
  shortName: 'large_purple_square'
}, {
  name: 'Large Brown Square',
  unified: '1F7EB',
  keywords: ['brown_square'],
  sheet: [38, 42],
  shortName: 'large_brown_square'
}, {
  name: 'Black Large Square',
  unified: '2B1B',
  keywords: ['black_large_square', 'shape', 'icon', 'button'],
  sheet: [59, 22],
  shortName: 'black_large_square'
}, {
  name: 'White Large Square',
  unified: '2B1C',
  keywords: ['white_large_square', 'shape', 'icon', 'stone', 'button'],
  sheet: [59, 23],
  shortName: 'white_large_square'
}, {
  name: 'Black Medium Square',
  unified: '25FC-FE0F',
  keywords: ['black_medium_square', 'shape', 'button', 'icon'],
  sheet: [56, 37],
  shortName: 'black_medium_square'
}, {
  name: 'White Medium Square',
  unified: '25FB-FE0F',
  keywords: ['white_medium_square', 'shape', 'stone', 'icon'],
  sheet: [56, 36],
  shortName: 'white_medium_square'
}, {
  name: 'Black Medium Small Square',
  unified: '25FE',
  keywords: ['black_medium_small_square', 'icon', 'shape', 'button'],
  sheet: [56, 39],
  shortName: 'black_medium_small_square'
}, {
  name: 'White Medium Small Square',
  unified: '25FD',
  keywords: ['white_medium_small_square', 'shape', 'stone', 'icon', 'button'],
  sheet: [56, 38],
  shortName: 'white_medium_small_square'
}, {
  name: 'Black Small Square',
  unified: '25AA-FE0F',
  keywords: ['black_small_square', 'shape', 'icon'],
  sheet: [56, 32],
  shortName: 'black_small_square'
}, {
  name: 'White Small Square',
  unified: '25AB-FE0F',
  keywords: ['white_small_square', 'shape', 'icon'],
  sheet: [56, 33],
  shortName: 'white_small_square'
}, {
  name: 'Large Orange Diamond',
  unified: '1F536',
  keywords: ['large_orange_diamond', 'shape', 'jewel', 'gem'],
  sheet: [30, 18],
  shortName: 'large_orange_diamond'
}, {
  name: 'Large Blue Diamond',
  unified: '1F537',
  keywords: ['large_blue_diamond', 'shape', 'jewel', 'gem'],
  sheet: [30, 19],
  shortName: 'large_blue_diamond'
}, {
  name: 'Small Orange Diamond',
  unified: '1F538',
  keywords: ['small_orange_diamond', 'shape', 'jewel', 'gem'],
  sheet: [30, 20],
  shortName: 'small_orange_diamond'
}, {
  name: 'Small Blue Diamond',
  unified: '1F539',
  keywords: ['small_blue_diamond', 'shape', 'jewel', 'gem'],
  sheet: [30, 21],
  shortName: 'small_blue_diamond'
}, {
  name: 'Up-Pointing Red Triangle',
  unified: '1F53A',
  keywords: ['red_triangle_pointed_up', 'shape', 'direction', 'up', 'top'],
  sheet: [30, 22],
  shortName: 'small_red_triangle'
}, {
  name: 'Down-Pointing Red Triangle',
  unified: '1F53B',
  keywords: ['red_triangle_pointed_down', 'shape', 'direction', 'bottom'],
  sheet: [30, 23],
  shortName: 'small_red_triangle_down'
}, {
  name: 'Diamond Shape with a Dot Inside',
  unified: '1F4A0',
  keywords: ['diamond_with_a_dot', 'jewel', 'blue', 'gem', 'crystal', 'fancy'],
  sheet: [27, 47],
  shortName: 'diamond_shape_with_a_dot_inside'
}, {
  name: 'Radio Button',
  unified: '1F518',
  keywords: ['radio_button', 'input', 'old', 'music', 'circle'],
  sheet: [29, 49],
  shortName: 'radio_button'
}, {
  name: 'White Square Button',
  unified: '1F533',
  keywords: ['white_square_button', 'shape', 'input'],
  sheet: [30, 15],
  shortName: 'white_square_button'
}, {
  name: 'Black Square Button',
  unified: '1F532',
  keywords: ['black_square_button', 'shape', 'input', 'frame'],
  sheet: [30, 14],
  shortName: 'black_square_button'
}, {
  name: 'Chequered Flag',
  unified: '1F3C1',
  keywords: ['chequered_flag', 'contest', 'finishline', 'race', 'gokart'],
  sheet: [8, 7],
  shortName: 'checkered_flag'
}, {
  name: 'Triangular Flag on Post',
  unified: '1F6A9',
  keywords: ['triangular_flag', 'mark', 'milestone', 'place'],
  sheet: [36, 29],
  shortName: 'triangular_flag_on_post'
}, {
  name: 'Crossed Flags',
  unified: '1F38C',
  keywords: ['crossed_flags', 'japanese', 'nation', 'country', 'border'],
  sheet: [7, 20],
  shortName: 'crossed_flags'
}, {
  name: 'Waving Black Flag',
  unified: '1F3F4',
  keywords: ['black_flag', 'pirate'],
  sheet: [10, 35],
  shortName: 'waving_black_flag'
}, {
  name: 'White Flag',
  unified: '1F3F3-FE0F',
  keywords: ['white_flag', 'losing', 'loser', 'lost', 'surrender', 'give up', 'fail'],
  sheet: [10, 30],
  shortName: 'waving_white_flag'
}, {
  name: 'Rainbow Flag',
  unified: '1F3F3-FE0F-200D-1F308',
  keywords: ['rainbow_flag', 'flag', 'rainbow', 'pride', 'gay', 'lgbt', 'glbt', 'queer', 'homosexual', 'lesbian', 'bisexual', 'transgender'],
  sheet: [10, 28],
  shortName: 'rainbow-flag'
}, {
  name: 'Transgender Flag',
  unified: '1F3F3-FE0F-200D-26A7-FE0F',
  keywords: ['transgender flag', 'lgbtq'],
  sheet: [10, 29],
  hidden: ['facebook'],
  shortName: 'transgender_flag'
}, {
  name: 'Pirate Flag',
  unified: '1F3F4-200D-2620-FE0F',
  keywords: ['pirate_flag', 'skull', 'crossbones', 'flag', 'banner'],
  sheet: [10, 31],
  shortName: 'pirate_flag'
}, {
  name: 'Ascension Island Flag',
  unified: '1F1E6-1F1E8',
  keywords: ['flag_ascension_island'],
  sheet: [0, 31],
  shortName: 'flag-ac'
}, {
  name: 'Andorra Flag',
  unified: '1F1E6-1F1E9',
  keywords: ['flag_andorra', 'ad', 'flag', 'nation', 'country', 'banner', 'andorra'],
  sheet: [0, 32],
  shortName: 'flag-ad'
}, {
  name: 'United Arab Emirates Flag',
  unified: '1F1E6-1F1EA',
  keywords: ['flag_united_arab_emirates', 'united', 'arab', 'emirates', 'flag', 'nation', 'country', 'banner', 'united_arab_emirates'],
  sheet: [0, 33],
  shortName: 'flag-ae'
}, {
  name: 'Afghanistan Flag',
  unified: '1F1E6-1F1EB',
  keywords: ['flag_afghanistan', 'af', 'flag', 'nation', 'country', 'banner', 'afghanistan'],
  sheet: [0, 34],
  shortName: 'flag-af'
}, {
  name: 'Antigua & Barbuda Flag',
  unified: '1F1E6-1F1EC',
  keywords: ['flag_antigua_barbuda', 'antigua', 'barbuda', 'flag', 'nation', 'country', 'banner', 'antigua_barbuda'],
  sheet: [0, 35],
  shortName: 'flag-ag'
}, {
  name: 'Anguilla Flag',
  unified: '1F1E6-1F1EE',
  keywords: ['flag_anguilla', 'ai', 'flag', 'nation', 'country', 'banner', 'anguilla'],
  sheet: [0, 36],
  shortName: 'flag-ai'
}, {
  name: 'Albania Flag',
  unified: '1F1E6-1F1F1',
  keywords: ['flag_albania', 'al', 'flag', 'nation', 'country', 'banner', 'albania'],
  sheet: [0, 37],
  shortName: 'flag-al'
}, {
  name: 'Armenia Flag',
  unified: '1F1E6-1F1F2',
  keywords: ['flag_armenia', 'am', 'flag', 'nation', 'country', 'banner', 'armenia'],
  sheet: [0, 38],
  shortName: 'flag-am'
}, {
  name: 'Angola Flag',
  unified: '1F1E6-1F1F4',
  keywords: ['flag_angola', 'ao', 'flag', 'nation', 'country', 'banner', 'angola'],
  sheet: [0, 39],
  shortName: 'flag-ao'
}, {
  name: 'Antarctica Flag',
  unified: '1F1E6-1F1F6',
  keywords: ['flag_antarctica', 'aq', 'flag', 'nation', 'country', 'banner', 'antarctica'],
  sheet: [0, 40],
  shortName: 'flag-aq'
}, {
  name: 'Argentina Flag',
  unified: '1F1E6-1F1F7',
  keywords: ['flag_argentina', 'ar', 'flag', 'nation', 'country', 'banner', 'argentina'],
  sheet: [0, 41],
  shortName: 'flag-ar'
}, {
  name: 'American Samoa Flag',
  unified: '1F1E6-1F1F8',
  keywords: ['flag_american_samoa', 'american', 'ws', 'flag', 'nation', 'country', 'banner', 'american_samoa'],
  sheet: [0, 42],
  shortName: 'flag-as'
}, {
  name: 'Austria Flag',
  unified: '1F1E6-1F1F9',
  keywords: ['flag_austria', 'at', 'flag', 'nation', 'country', 'banner', 'austria'],
  sheet: [0, 43],
  shortName: 'flag-at'
}, {
  name: 'Australia Flag',
  unified: '1F1E6-1F1FA',
  keywords: ['flag_australia', 'au', 'flag', 'nation', 'country', 'banner', 'australia'],
  sheet: [0, 44],
  shortName: 'flag-au'
}, {
  name: 'Aruba Flag',
  unified: '1F1E6-1F1FC',
  keywords: ['flag_aruba', 'aw', 'flag', 'nation', 'country', 'banner', 'aruba'],
  sheet: [0, 45],
  shortName: 'flag-aw'
}, {
  name: 'Åland Islands Flag',
  unified: '1F1E6-1F1FD',
  keywords: ['flag_aland_islands', 'Åland', 'islands', 'flag', 'nation', 'country', 'banner', 'aland_islands'],
  sheet: [0, 46],
  shortName: 'flag-ax'
}, {
  name: 'Azerbaijan Flag',
  unified: '1F1E6-1F1FF',
  keywords: ['flag_azerbaijan', 'az', 'flag', 'nation', 'country', 'banner', 'azerbaijan'],
  sheet: [0, 47],
  shortName: 'flag-az'
}, {
  name: 'Bosnia & Herzegovina Flag',
  unified: '1F1E7-1F1E6',
  keywords: ['flag_bosnia_herzegovina', 'bosnia', 'herzegovina', 'flag', 'nation', 'country', 'banner', 'bosnia_herzegovina'],
  sheet: [0, 48],
  shortName: 'flag-ba'
}, {
  name: 'Barbados Flag',
  unified: '1F1E7-1F1E7',
  keywords: ['flag_barbados', 'bb', 'flag', 'nation', 'country', 'banner', 'barbados'],
  sheet: [0, 49],
  shortName: 'flag-bb'
}, {
  name: 'Bangladesh Flag',
  unified: '1F1E7-1F1E9',
  keywords: ['flag_bangladesh', 'bd', 'flag', 'nation', 'country', 'banner', 'bangladesh'],
  sheet: [0, 50],
  shortName: 'flag-bd'
}, {
  name: 'Belgium Flag',
  unified: '1F1E7-1F1EA',
  keywords: ['flag_belgium', 'be', 'flag', 'nation', 'country', 'banner', 'belgium'],
  sheet: [0, 51],
  shortName: 'flag-be'
}, {
  name: 'Burkina Faso Flag',
  unified: '1F1E7-1F1EB',
  keywords: ['flag_burkina_faso', 'burkina', 'faso', 'flag', 'nation', 'country', 'banner', 'burkina_faso'],
  sheet: [0, 52],
  shortName: 'flag-bf'
}, {
  name: 'Bulgaria Flag',
  unified: '1F1E7-1F1EC',
  keywords: ['flag_bulgaria', 'bg', 'flag', 'nation', 'country', 'banner', 'bulgaria'],
  sheet: [0, 53],
  shortName: 'flag-bg'
}, {
  name: 'Bahrain Flag',
  unified: '1F1E7-1F1ED',
  keywords: ['flag_bahrain', 'bh', 'flag', 'nation', 'country', 'banner', 'bahrain'],
  sheet: [0, 54],
  shortName: 'flag-bh'
}, {
  name: 'Burundi Flag',
  unified: '1F1E7-1F1EE',
  keywords: ['flag_burundi', 'bi', 'flag', 'nation', 'country', 'banner', 'burundi'],
  sheet: [0, 55],
  shortName: 'flag-bi'
}, {
  name: 'Benin Flag',
  unified: '1F1E7-1F1EF',
  keywords: ['flag_benin', 'bj', 'flag', 'nation', 'country', 'banner', 'benin'],
  sheet: [0, 56],
  shortName: 'flag-bj'
}, {
  name: 'St. Barthélemy Flag',
  unified: '1F1E7-1F1F1',
  keywords: ['flag_st_barthelemy', 'saint', 'barthélemy', 'flag', 'nation', 'country', 'banner', 'st_barthelemy'],
  sheet: [0, 57],
  shortName: 'flag-bl'
}, {
  name: 'Bermuda Flag',
  unified: '1F1E7-1F1F2',
  keywords: ['flag_bermuda', 'bm', 'flag', 'nation', 'country', 'banner', 'bermuda'],
  sheet: [0, 58],
  shortName: 'flag-bm'
}, {
  name: 'Brunei Flag',
  unified: '1F1E7-1F1F3',
  keywords: ['flag_brunei', 'bn', 'darussalam', 'flag', 'nation', 'country', 'banner', 'brunei'],
  sheet: [0, 59],
  shortName: 'flag-bn'
}, {
  name: 'Bolivia Flag',
  unified: '1F1E7-1F1F4',
  keywords: ['flag_bolivia', 'bo', 'flag', 'nation', 'country', 'banner', 'bolivia'],
  sheet: [0, 60],
  shortName: 'flag-bo'
}, {
  name: 'Caribbean Netherlands Flag',
  unified: '1F1E7-1F1F6',
  keywords: ['flag_caribbean_netherlands', 'bonaire', 'flag', 'nation', 'country', 'banner', 'caribbean_netherlands'],
  sheet: [1, 0],
  shortName: 'flag-bq'
}, {
  name: 'Brazil Flag',
  unified: '1F1E7-1F1F7',
  keywords: ['flag_brazil', 'br', 'flag', 'nation', 'country', 'banner', 'brazil'],
  sheet: [1, 1],
  shortName: 'flag-br'
}, {
  name: 'Bahamas Flag',
  unified: '1F1E7-1F1F8',
  keywords: ['flag_bahamas', 'bs', 'flag', 'nation', 'country', 'banner', 'bahamas'],
  sheet: [1, 2],
  shortName: 'flag-bs'
}, {
  name: 'Bhutan Flag',
  unified: '1F1E7-1F1F9',
  keywords: ['flag_bhutan', 'bt', 'flag', 'nation', 'country', 'banner', 'bhutan'],
  sheet: [1, 3],
  shortName: 'flag-bt'
}, {
  name: 'Bouvet Island Flag',
  unified: '1F1E7-1F1FB',
  keywords: ['flag_bouvet_island', 'norway'],
  sheet: [1, 4],
  shortName: 'flag-bv'
}, {
  name: 'Botswana Flag',
  unified: '1F1E7-1F1FC',
  keywords: ['flag_botswana', 'bw', 'flag', 'nation', 'country', 'banner', 'botswana'],
  sheet: [1, 5],
  shortName: 'flag-bw'
}, {
  name: 'Belarus Flag',
  unified: '1F1E7-1F1FE',
  keywords: ['flag_belarus', 'by', 'flag', 'nation', 'country', 'banner', 'belarus'],
  sheet: [1, 6],
  shortName: 'flag-by'
}, {
  name: 'Belize Flag',
  unified: '1F1E7-1F1FF',
  keywords: ['flag_belize', 'bz', 'flag', 'nation', 'country', 'banner', 'belize'],
  sheet: [1, 7],
  shortName: 'flag-bz'
}, {
  name: 'Canada Flag',
  unified: '1F1E8-1F1E6',
  keywords: ['flag_canada', 'ca', 'flag', 'nation', 'country', 'banner', 'canada'],
  sheet: [1, 8],
  shortName: 'flag-ca'
}, {
  name: 'Cocos (keeling) Islands Flag',
  unified: '1F1E8-1F1E8',
  keywords: ['flag_cocos_islands', 'cocos', 'keeling', 'islands', 'flag', 'nation', 'country', 'banner', 'cocos_islands'],
  sheet: [1, 9],
  shortName: 'flag-cc'
}, {
  name: 'Congo - Kinshasa Flag',
  unified: '1F1E8-1F1E9',
  keywords: ['flag_congo_kinshasa', 'congo', 'democratic', 'republic', 'flag', 'nation', 'country', 'banner', 'congo_kinshasa'],
  sheet: [1, 10],
  shortName: 'flag-cd'
}, {
  name: 'Central African Republic Flag',
  unified: '1F1E8-1F1EB',
  keywords: ['flag_central_african_republic', 'central', 'african', 'republic', 'flag', 'nation', 'country', 'banner', 'central_african_republic'],
  sheet: [1, 11],
  shortName: 'flag-cf'
}, {
  name: 'Congo - Brazzaville Flag',
  unified: '1F1E8-1F1EC',
  keywords: ['flag_congo_brazzaville', 'congo', 'flag', 'nation', 'country', 'banner', 'congo_brazzaville'],
  sheet: [1, 12],
  shortName: 'flag-cg'
}, {
  name: 'Switzerland Flag',
  unified: '1F1E8-1F1ED',
  keywords: ['flag_switzerland', 'ch', 'flag', 'nation', 'country', 'banner', 'switzerland'],
  sheet: [1, 13],
  shortName: 'flag-ch'
}, {
  name: 'Côte D’ivoire Flag',
  unified: '1F1E8-1F1EE',
  keywords: ['flag_cote_d_ivoire', 'ivory', 'coast', 'flag', 'nation', 'country', 'banner', 'cote_d_ivoire'],
  sheet: [1, 14],
  shortName: 'flag-ci'
}, {
  name: 'Cook Islands Flag',
  unified: '1F1E8-1F1F0',
  keywords: ['flag_cook_islands', 'cook', 'islands', 'flag', 'nation', 'country', 'banner', 'cook_islands'],
  sheet: [1, 15],
  shortName: 'flag-ck'
}, {
  name: 'Chile Flag',
  unified: '1F1E8-1F1F1',
  keywords: ['flag_chile', 'flag', 'nation', 'country', 'banner', 'chile'],
  sheet: [1, 16],
  shortName: 'flag-cl'
}, {
  name: 'Cameroon Flag',
  unified: '1F1E8-1F1F2',
  keywords: ['flag_cameroon', 'cm', 'flag', 'nation', 'country', 'banner', 'cameroon'],
  sheet: [1, 17],
  shortName: 'flag-cm'
}, {
  name: 'China Flag',
  unified: '1F1E8-1F1F3',
  keywords: ['flag_china', 'china', 'chinese', 'prc', 'flag', 'country', 'nation', 'banner', 'china'],
  sheet: [1, 18],
  shortNames: ['flag-cn'],
  shortName: 'cn'
}, {
  name: 'Colombia Flag',
  unified: '1F1E8-1F1F4',
  keywords: ['flag_colombia', 'co', 'flag', 'nation', 'country', 'banner', 'colombia'],
  sheet: [1, 19],
  shortName: 'flag-co'
}, {
  name: 'Clipperton Island Flag',
  unified: '1F1E8-1F1F5',
  keywords: ['flag_clipperton_island'],
  sheet: [1, 20],
  shortName: 'flag-cp'
}, {
  name: 'Costa Rica Flag',
  unified: '1F1E8-1F1F7',
  keywords: ['flag_costa_rica', 'costa', 'rica', 'flag', 'nation', 'country', 'banner', 'costa_rica'],
  sheet: [1, 21],
  shortName: 'flag-cr'
}, {
  name: 'Cuba Flag',
  unified: '1F1E8-1F1FA',
  keywords: ['flag_cuba', 'cu', 'flag', 'nation', 'country', 'banner', 'cuba'],
  sheet: [1, 22],
  shortName: 'flag-cu'
}, {
  name: 'Cape Verde Flag',
  unified: '1F1E8-1F1FB',
  keywords: ['flag_cape_verde', 'cabo', 'verde', 'flag', 'nation', 'country', 'banner', 'cape_verde'],
  sheet: [1, 23],
  shortName: 'flag-cv'
}, {
  name: 'Curaçao Flag',
  unified: '1F1E8-1F1FC',
  keywords: ['flag_curacao', 'curaçao', 'flag', 'nation', 'country', 'banner', 'curacao'],
  sheet: [1, 24],
  shortName: 'flag-cw'
}, {
  name: 'Christmas Island Flag',
  unified: '1F1E8-1F1FD',
  keywords: ['flag_christmas_island', 'christmas', 'island', 'flag', 'nation', 'country', 'banner', 'christmas_island'],
  sheet: [1, 25],
  shortName: 'flag-cx'
}, {
  name: 'Cyprus Flag',
  unified: '1F1E8-1F1FE',
  keywords: ['flag_cyprus', 'cy', 'flag', 'nation', 'country', 'banner', 'cyprus'],
  sheet: [1, 26],
  shortName: 'flag-cy'
}, {
  name: 'Czechia Flag',
  unified: '1F1E8-1F1FF',
  keywords: ['flag_czechia', 'cz', 'flag', 'nation', 'country', 'banner', 'czechia'],
  sheet: [1, 27],
  shortName: 'flag-cz'
}, {
  name: 'Germany Flag',
  unified: '1F1E9-1F1EA',
  keywords: ['flag_germany', 'german', 'nation', 'flag', 'country', 'banner', 'germany'],
  sheet: [1, 28],
  shortNames: ['flag-de'],
  shortName: 'de'
}, {
  name: 'Diego Garcia Flag',
  unified: '1F1E9-1F1EC',
  keywords: ['flag_diego_garcia'],
  sheet: [1, 29],
  shortName: 'flag-dg'
}, {
  name: 'Djibouti Flag',
  unified: '1F1E9-1F1EF',
  keywords: ['flag_djibouti', 'dj', 'flag', 'nation', 'country', 'banner', 'djibouti'],
  sheet: [1, 30],
  shortName: 'flag-dj'
}, {
  name: 'Denmark Flag',
  unified: '1F1E9-1F1F0',
  keywords: ['flag_denmark', 'dk', 'flag', 'nation', 'country', 'banner', 'denmark'],
  sheet: [1, 31],
  shortName: 'flag-dk'
}, {
  name: 'Dominica Flag',
  unified: '1F1E9-1F1F2',
  keywords: ['flag_dominica', 'dm', 'flag', 'nation', 'country', 'banner', 'dominica'],
  sheet: [1, 32],
  shortName: 'flag-dm'
}, {
  name: 'Dominican Republic Flag',
  unified: '1F1E9-1F1F4',
  keywords: ['flag_dominican_republic', 'dominican', 'republic', 'flag', 'nation', 'country', 'banner', 'dominican_republic'],
  sheet: [1, 33],
  shortName: 'flag-do'
}, {
  name: 'Algeria Flag',
  unified: '1F1E9-1F1FF',
  keywords: ['flag_algeria', 'dz', 'flag', 'nation', 'country', 'banner', 'algeria'],
  sheet: [1, 34],
  shortName: 'flag-dz'
}, {
  name: 'Ceuta & Melilla Flag',
  unified: '1F1EA-1F1E6',
  keywords: ['flag_ceuta_melilla'],
  sheet: [1, 35],
  shortName: 'flag-ea'
}, {
  name: 'Ecuador Flag',
  unified: '1F1EA-1F1E8',
  keywords: ['flag_ecuador', 'ec', 'flag', 'nation', 'country', 'banner', 'ecuador'],
  sheet: [1, 36],
  shortName: 'flag-ec'
}, {
  name: 'Estonia Flag',
  unified: '1F1EA-1F1EA',
  keywords: ['flag_estonia', 'ee', 'flag', 'nation', 'country', 'banner', 'estonia'],
  sheet: [1, 37],
  shortName: 'flag-ee'
}, {
  name: 'Egypt Flag',
  unified: '1F1EA-1F1EC',
  keywords: ['flag_egypt', 'eg', 'flag', 'nation', 'country', 'banner', 'egypt'],
  sheet: [1, 38],
  shortName: 'flag-eg'
}, {
  name: 'Western Sahara Flag',
  unified: '1F1EA-1F1ED',
  keywords: ['flag_western_sahara', 'western', 'sahara', 'flag', 'nation', 'country', 'banner', 'western_sahara'],
  sheet: [1, 39],
  shortName: 'flag-eh'
}, {
  name: 'Eritrea Flag',
  unified: '1F1EA-1F1F7',
  keywords: ['flag_eritrea', 'er', 'flag', 'nation', 'country', 'banner', 'eritrea'],
  sheet: [1, 40],
  shortName: 'flag-er'
}, {
  name: 'Spain Flag',
  unified: '1F1EA-1F1F8',
  keywords: ['flag_spain', 'spain', 'flag', 'nation', 'country', 'banner', 'spain'],
  sheet: [1, 41],
  shortNames: ['flag-es'],
  shortName: 'es'
}, {
  name: 'Ethiopia Flag',
  unified: '1F1EA-1F1F9',
  keywords: ['flag_ethiopia', 'et', 'flag', 'nation', 'country', 'banner', 'ethiopia'],
  sheet: [1, 42],
  shortName: 'flag-et'
}, {
  name: 'European Union Flag',
  unified: '1F1EA-1F1FA',
  keywords: ['flag_european_union', 'european', 'union', 'flag', 'banner'],
  sheet: [1, 43],
  shortName: 'flag-eu'
}, {
  name: 'Finland Flag',
  unified: '1F1EB-1F1EE',
  keywords: ['flag_finland', 'fi', 'flag', 'nation', 'country', 'banner', 'finland'],
  sheet: [1, 44],
  shortName: 'flag-fi'
}, {
  name: 'Fiji Flag',
  unified: '1F1EB-1F1EF',
  keywords: ['flag_fiji', 'fj', 'flag', 'nation', 'country', 'banner', 'fiji'],
  sheet: [1, 45],
  shortName: 'flag-fj'
}, {
  name: 'Falkland Islands Flag',
  unified: '1F1EB-1F1F0',
  keywords: ['flag_falkland_islands', 'falkland', 'islands', 'malvinas', 'flag', 'nation', 'country', 'banner', 'falkland_islands'],
  sheet: [1, 46],
  shortName: 'flag-fk'
}, {
  name: 'Micronesia Flag',
  unified: '1F1EB-1F1F2',
  keywords: ['flag_micronesia', 'micronesia', 'federated', 'states', 'flag', 'nation', 'country', 'banner', 'micronesia'],
  sheet: [1, 47],
  shortName: 'flag-fm'
}, {
  name: 'Faroe Islands Flag',
  unified: '1F1EB-1F1F4',
  keywords: ['flag_faroe_islands', 'faroe', 'islands', 'flag', 'nation', 'country', 'banner', 'faroe_islands'],
  sheet: [1, 48],
  shortName: 'flag-fo'
}, {
  name: 'France Flag',
  unified: '1F1EB-1F1F7',
  keywords: ['flag_france', 'banner', 'flag', 'nation', 'france', 'french', 'country', 'france'],
  sheet: [1, 49],
  shortNames: ['flag-fr'],
  shortName: 'fr'
}, {
  name: 'Gabon Flag',
  unified: '1F1EC-1F1E6',
  keywords: ['flag_gabon', 'ga', 'flag', 'nation', 'country', 'banner', 'gabon'],
  sheet: [1, 50],
  shortName: 'flag-ga'
}, {
  name: 'United Kingdom Flag',
  unified: '1F1EC-1F1E7',
  keywords: ['flag_united_kingdom', 'united', 'kingdom', 'great', 'britain', 'northern', 'ireland', 'flag', 'nation', 'country', 'banner', 'british', 'UK', 'english', 'england', 'union jack', 'united_kingdom'],
  sheet: [1, 51],
  shortNames: ['uk', 'flag-gb'],
  shortName: 'gb'
}, {
  name: 'Grenada Flag',
  unified: '1F1EC-1F1E9',
  keywords: ['flag_grenada', 'gd', 'flag', 'nation', 'country', 'banner', 'grenada'],
  sheet: [1, 52],
  shortName: 'flag-gd'
}, {
  name: 'Georgia Flag',
  unified: '1F1EC-1F1EA',
  keywords: ['flag_georgia', 'ge', 'flag', 'nation', 'country', 'banner', 'georgia'],
  sheet: [1, 53],
  shortName: 'flag-ge'
}, {
  name: 'French Guiana Flag',
  unified: '1F1EC-1F1EB',
  keywords: ['flag_french_guiana', 'french', 'guiana', 'flag', 'nation', 'country', 'banner', 'french_guiana'],
  sheet: [1, 54],
  shortName: 'flag-gf'
}, {
  name: 'Guernsey Flag',
  unified: '1F1EC-1F1EC',
  keywords: ['flag_guernsey', 'gg', 'flag', 'nation', 'country', 'banner', 'guernsey'],
  sheet: [1, 55],
  shortName: 'flag-gg'
}, {
  name: 'Ghana Flag',
  unified: '1F1EC-1F1ED',
  keywords: ['flag_ghana', 'gh', 'flag', 'nation', 'country', 'banner', 'ghana'],
  sheet: [1, 56],
  shortName: 'flag-gh'
}, {
  name: 'Gibraltar Flag',
  unified: '1F1EC-1F1EE',
  keywords: ['flag_gibraltar', 'gi', 'flag', 'nation', 'country', 'banner', 'gibraltar'],
  sheet: [1, 57],
  shortName: 'flag-gi'
}, {
  name: 'Greenland Flag',
  unified: '1F1EC-1F1F1',
  keywords: ['flag_greenland', 'gl', 'flag', 'nation', 'country', 'banner', 'greenland'],
  sheet: [1, 58],
  shortName: 'flag-gl'
}, {
  name: 'Gambia Flag',
  unified: '1F1EC-1F1F2',
  keywords: ['flag_gambia', 'gm', 'flag', 'nation', 'country', 'banner', 'gambia'],
  sheet: [1, 59],
  shortName: 'flag-gm'
}, {
  name: 'Guinea Flag',
  unified: '1F1EC-1F1F3',
  keywords: ['flag_guinea', 'gn', 'flag', 'nation', 'country', 'banner', 'guinea'],
  sheet: [1, 60],
  shortName: 'flag-gn'
}, {
  name: 'Guadeloupe Flag',
  unified: '1F1EC-1F1F5',
  keywords: ['flag_guadeloupe', 'gp', 'flag', 'nation', 'country', 'banner', 'guadeloupe'],
  sheet: [2, 0],
  shortName: 'flag-gp'
}, {
  name: 'Equatorial Guinea Flag',
  unified: '1F1EC-1F1F6',
  keywords: ['flag_equatorial_guinea', 'equatorial', 'gn', 'flag', 'nation', 'country', 'banner', 'equatorial_guinea'],
  sheet: [2, 1],
  shortName: 'flag-gq'
}, {
  name: 'Greece Flag',
  unified: '1F1EC-1F1F7',
  keywords: ['flag_greece', 'gr', 'flag', 'nation', 'country', 'banner', 'greece'],
  sheet: [2, 2],
  shortName: 'flag-gr'
}, {
  name: 'South Georgia & South Sandwich Islands Flag',
  unified: '1F1EC-1F1F8',
  keywords: ['flag_south_georgia_south_sandwich_islands', 'south', 'georgia', 'sandwich', 'islands', 'flag', 'nation', 'country', 'banner', 'south_georgia_south_sandwich_islands'],
  sheet: [2, 3],
  shortName: 'flag-gs'
}, {
  name: 'Guatemala Flag',
  unified: '1F1EC-1F1F9',
  keywords: ['flag_guatemala', 'gt', 'flag', 'nation', 'country', 'banner', 'guatemala'],
  sheet: [2, 4],
  shortName: 'flag-gt'
}, {
  name: 'Guam Flag',
  unified: '1F1EC-1F1FA',
  keywords: ['flag_guam', 'gu', 'flag', 'nation', 'country', 'banner', 'guam'],
  sheet: [2, 5],
  shortName: 'flag-gu'
}, {
  name: 'Guinea-Bissau Flag',
  unified: '1F1EC-1F1FC',
  keywords: ['flag_guinea_bissau', 'gw', 'bissau', 'flag', 'nation', 'country', 'banner', 'guinea_bissau'],
  sheet: [2, 6],
  shortName: 'flag-gw'
}, {
  name: 'Guyana Flag',
  unified: '1F1EC-1F1FE',
  keywords: ['flag_guyana', 'gy', 'flag', 'nation', 'country', 'banner', 'guyana'],
  sheet: [2, 7],
  shortName: 'flag-gy'
}, {
  name: 'Hong Kong Sar China Flag',
  unified: '1F1ED-1F1F0',
  keywords: ['flag_hong_kong_sar_china', 'hong', 'kong', 'flag', 'nation', 'country', 'banner', 'hong_kong_sar_china'],
  sheet: [2, 8],
  shortName: 'flag-hk'
}, {
  name: 'Heard & Mcdonald Islands Flag',
  unified: '1F1ED-1F1F2',
  keywords: ['flag_heard_mcdonald_islands'],
  sheet: [2, 9],
  shortName: 'flag-hm'
}, {
  name: 'Honduras Flag',
  unified: '1F1ED-1F1F3',
  keywords: ['flag_honduras', 'hn', 'flag', 'nation', 'country', 'banner', 'honduras'],
  sheet: [2, 10],
  shortName: 'flag-hn'
}, {
  name: 'Croatia Flag',
  unified: '1F1ED-1F1F7',
  keywords: ['flag_croatia', 'hr', 'flag', 'nation', 'country', 'banner', 'croatia'],
  sheet: [2, 11],
  shortName: 'flag-hr'
}, {
  name: 'Haiti Flag',
  unified: '1F1ED-1F1F9',
  keywords: ['flag_haiti', 'ht', 'flag', 'nation', 'country', 'banner', 'haiti'],
  sheet: [2, 12],
  shortName: 'flag-ht'
}, {
  name: 'Hungary Flag',
  unified: '1F1ED-1F1FA',
  keywords: ['flag_hungary', 'hu', 'flag', 'nation', 'country', 'banner', 'hungary'],
  sheet: [2, 13],
  shortName: 'flag-hu'
}, {
  name: 'Canary Islands Flag',
  unified: '1F1EE-1F1E8',
  keywords: ['flag_canary_islands', 'canary', 'islands', 'flag', 'nation', 'country', 'banner', 'canary_islands'],
  sheet: [2, 14],
  shortName: 'flag-ic'
}, {
  name: 'Indonesia Flag',
  unified: '1F1EE-1F1E9',
  keywords: ['flag_indonesia', 'flag', 'nation', 'country', 'banner', 'indonesia'],
  sheet: [2, 15],
  shortName: 'flag-id'
}, {
  name: 'Ireland Flag',
  unified: '1F1EE-1F1EA',
  keywords: ['flag_ireland', 'ie', 'flag', 'nation', 'country', 'banner', 'ireland'],
  sheet: [2, 16],
  shortName: 'flag-ie'
}, {
  name: 'Israel Flag',
  unified: '1F1EE-1F1F1',
  keywords: ['flag_israel', 'il', 'flag', 'nation', 'country', 'banner', 'israel'],
  sheet: [2, 17],
  shortName: 'flag-il'
}, {
  name: 'Isle of Man Flag',
  unified: '1F1EE-1F1F2',
  keywords: ['flag_isle_of_man', 'isle', 'man', 'flag', 'nation', 'country', 'banner', 'isle_of_man'],
  sheet: [2, 18],
  shortName: 'flag-im'
}, {
  name: 'India Flag',
  unified: '1F1EE-1F1F3',
  keywords: ['flag_india', 'in', 'flag', 'nation', 'country', 'banner', 'india'],
  sheet: [2, 19],
  shortName: 'flag-in'
}, {
  name: 'British Indian Ocean Territory Flag',
  unified: '1F1EE-1F1F4',
  keywords: ['flag_british_indian_ocean_territory', 'british', 'indian', 'ocean', 'territory', 'flag', 'nation', 'country', 'banner', 'british_indian_ocean_territory'],
  sheet: [2, 20],
  shortName: 'flag-io'
}, {
  name: 'Iraq Flag',
  unified: '1F1EE-1F1F6',
  keywords: ['flag_iraq', 'iq', 'flag', 'nation', 'country', 'banner', 'iraq'],
  sheet: [2, 21],
  shortName: 'flag-iq'
}, {
  name: 'Iran Flag',
  unified: '1F1EE-1F1F7',
  keywords: ['flag_iran', 'iran', 'islamic', 'republic', 'flag', 'nation', 'country', 'banner', 'iran'],
  sheet: [2, 22],
  shortName: 'flag-ir'
}, {
  name: 'Iceland Flag',
  unified: '1F1EE-1F1F8',
  keywords: ['flag_iceland', 'is', 'flag', 'nation', 'country', 'banner', 'iceland'],
  sheet: [2, 23],
  shortName: 'flag-is'
}, {
  name: 'Italy Flag',
  unified: '1F1EE-1F1F9',
  keywords: ['flag_italy', 'italy', 'flag', 'nation', 'country', 'banner', 'italy'],
  sheet: [2, 24],
  shortNames: ['flag-it'],
  shortName: 'it'
}, {
  name: 'Jersey Flag',
  unified: '1F1EF-1F1EA',
  keywords: ['flag_jersey', 'je', 'flag', 'nation', 'country', 'banner', 'jersey'],
  sheet: [2, 25],
  shortName: 'flag-je'
}, {
  name: 'Jamaica Flag',
  unified: '1F1EF-1F1F2',
  keywords: ['flag_jamaica', 'jm', 'flag', 'nation', 'country', 'banner', 'jamaica'],
  sheet: [2, 26],
  shortName: 'flag-jm'
}, {
  name: 'Jordan Flag',
  unified: '1F1EF-1F1F4',
  keywords: ['flag_jordan', 'jo', 'flag', 'nation', 'country', 'banner', 'jordan'],
  sheet: [2, 27],
  shortName: 'flag-jo'
}, {
  name: 'Japan Flag',
  unified: '1F1EF-1F1F5',
  keywords: ['flag_japan', 'japanese', 'nation', 'flag', 'country', 'banner', 'japan', 'jp', 'ja'],
  sheet: [2, 28],
  shortNames: ['flag-jp'],
  shortName: 'jp'
}, {
  name: 'Kenya Flag',
  unified: '1F1F0-1F1EA',
  keywords: ['flag_kenya', 'ke', 'flag', 'nation', 'country', 'banner', 'kenya'],
  sheet: [2, 29],
  shortName: 'flag-ke'
}, {
  name: 'Kyrgyzstan Flag',
  unified: '1F1F0-1F1EC',
  keywords: ['flag_kyrgyzstan', 'kg', 'flag', 'nation', 'country', 'banner', 'kyrgyzstan'],
  sheet: [2, 30],
  shortName: 'flag-kg'
}, {
  name: 'Cambodia Flag',
  unified: '1F1F0-1F1ED',
  keywords: ['flag_cambodia', 'kh', 'flag', 'nation', 'country', 'banner', 'cambodia'],
  sheet: [2, 31],
  shortName: 'flag-kh'
}, {
  name: 'Kiribati Flag',
  unified: '1F1F0-1F1EE',
  keywords: ['flag_kiribati', 'ki', 'flag', 'nation', 'country', 'banner', 'kiribati'],
  sheet: [2, 32],
  shortName: 'flag-ki'
}, {
  name: 'Comoros Flag',
  unified: '1F1F0-1F1F2',
  keywords: ['flag_comoros', 'km', 'flag', 'nation', 'country', 'banner', 'comoros'],
  sheet: [2, 33],
  shortName: 'flag-km'
}, {
  name: 'St. Kitts & Nevis Flag',
  unified: '1F1F0-1F1F3',
  keywords: ['flag_st_kitts_nevis', 'saint', 'kitts', 'nevis', 'flag', 'nation', 'country', 'banner', 'st_kitts_nevis'],
  sheet: [2, 34],
  shortName: 'flag-kn'
}, {
  name: 'North Korea Flag',
  unified: '1F1F0-1F1F5',
  keywords: ['flag_north_korea', 'north', 'korea', 'nation', 'flag', 'country', 'banner', 'north_korea'],
  sheet: [2, 35],
  shortName: 'flag-kp'
}, {
  name: 'South Korea Flag',
  unified: '1F1F0-1F1F7',
  keywords: ['flag_south_korea', 'south', 'korea', 'nation', 'flag', 'country', 'banner', 'south_korea'],
  sheet: [2, 36],
  shortNames: ['flag-kr'],
  shortName: 'kr'
}, {
  name: 'Kuwait Flag',
  unified: '1F1F0-1F1FC',
  keywords: ['flag_kuwait', 'kw', 'flag', 'nation', 'country', 'banner', 'kuwait'],
  sheet: [2, 37],
  shortName: 'flag-kw'
}, {
  name: 'Cayman Islands Flag',
  unified: '1F1F0-1F1FE',
  keywords: ['flag_cayman_islands', 'cayman', 'islands', 'flag', 'nation', 'country', 'banner', 'cayman_islands'],
  sheet: [2, 38],
  shortName: 'flag-ky'
}, {
  name: 'Kazakhstan Flag',
  unified: '1F1F0-1F1FF',
  keywords: ['flag_kazakhstan', 'kz', 'flag', 'nation', 'country', 'banner', 'kazakhstan'],
  sheet: [2, 39],
  shortName: 'flag-kz'
}, {
  name: 'Laos Flag',
  unified: '1F1F1-1F1E6',
  keywords: ['flag_laos', 'lao', 'democratic', 'republic', 'flag', 'nation', 'country', 'banner', 'laos'],
  sheet: [2, 40],
  shortName: 'flag-la'
}, {
  name: 'Lebanon Flag',
  unified: '1F1F1-1F1E7',
  keywords: ['flag_lebanon', 'lb', 'flag', 'nation', 'country', 'banner', 'lebanon'],
  sheet: [2, 41],
  shortName: 'flag-lb'
}, {
  name: 'St. Lucia Flag',
  unified: '1F1F1-1F1E8',
  keywords: ['flag_st_lucia', 'saint', 'lucia', 'flag', 'nation', 'country', 'banner', 'st_lucia'],
  sheet: [2, 42],
  shortName: 'flag-lc'
}, {
  name: 'Liechtenstein Flag',
  unified: '1F1F1-1F1EE',
  keywords: ['flag_liechtenstein', 'li', 'flag', 'nation', 'country', 'banner', 'liechtenstein'],
  sheet: [2, 43],
  shortName: 'flag-li'
}, {
  name: 'Sri Lanka Flag',
  unified: '1F1F1-1F1F0',
  keywords: ['flag_sri_lanka', 'sri', 'lanka', 'flag', 'nation', 'country', 'banner', 'sri_lanka'],
  sheet: [2, 44],
  shortName: 'flag-lk'
}, {
  name: 'Liberia Flag',
  unified: '1F1F1-1F1F7',
  keywords: ['flag_liberia', 'lr', 'flag', 'nation', 'country', 'banner', 'liberia'],
  sheet: [2, 45],
  shortName: 'flag-lr'
}, {
  name: 'Lesotho Flag',
  unified: '1F1F1-1F1F8',
  keywords: ['flag_lesotho', 'ls', 'flag', 'nation', 'country', 'banner', 'lesotho'],
  sheet: [2, 46],
  shortName: 'flag-ls'
}, {
  name: 'Lithuania Flag',
  unified: '1F1F1-1F1F9',
  keywords: ['flag_lithuania', 'lt', 'flag', 'nation', 'country', 'banner', 'lithuania'],
  sheet: [2, 47],
  shortName: 'flag-lt'
}, {
  name: 'Luxembourg Flag',
  unified: '1F1F1-1F1FA',
  keywords: ['flag_luxembourg', 'lu', 'flag', 'nation', 'country', 'banner', 'luxembourg'],
  sheet: [2, 48],
  shortName: 'flag-lu'
}, {
  name: 'Latvia Flag',
  unified: '1F1F1-1F1FB',
  keywords: ['flag_latvia', 'lv', 'flag', 'nation', 'country', 'banner', 'latvia'],
  sheet: [2, 49],
  shortName: 'flag-lv'
}, {
  name: 'Libya Flag',
  unified: '1F1F1-1F1FE',
  keywords: ['flag_libya', 'ly', 'flag', 'nation', 'country', 'banner', 'libya'],
  sheet: [2, 50],
  shortName: 'flag-ly'
}, {
  name: 'Morocco Flag',
  unified: '1F1F2-1F1E6',
  keywords: ['flag_morocco', 'ma', 'flag', 'nation', 'country', 'banner', 'morocco'],
  sheet: [2, 51],
  shortName: 'flag-ma'
}, {
  name: 'Monaco Flag',
  unified: '1F1F2-1F1E8',
  keywords: ['flag_monaco', 'mc', 'flag', 'nation', 'country', 'banner', 'monaco'],
  sheet: [2, 52],
  shortName: 'flag-mc'
}, {
  name: 'Moldova Flag',
  unified: '1F1F2-1F1E9',
  keywords: ['flag_moldova', 'moldova', 'republic', 'flag', 'nation', 'country', 'banner', 'moldova'],
  sheet: [2, 53],
  shortName: 'flag-md'
}, {
  name: 'Montenegro Flag',
  unified: '1F1F2-1F1EA',
  keywords: ['flag_montenegro', 'me', 'flag', 'nation', 'country', 'banner', 'montenegro'],
  sheet: [2, 54],
  shortName: 'flag-me'
}, {
  name: 'St. Martin Flag',
  unified: '1F1F2-1F1EB',
  keywords: ['flag_st_martin'],
  sheet: [2, 55],
  shortName: 'flag-mf'
}, {
  name: 'Madagascar Flag',
  unified: '1F1F2-1F1EC',
  keywords: ['flag_madagascar', 'mg', 'flag', 'nation', 'country', 'banner', 'madagascar'],
  sheet: [2, 56],
  shortName: 'flag-mg'
}, {
  name: 'Marshall Islands Flag',
  unified: '1F1F2-1F1ED',
  keywords: ['flag_marshall_islands', 'marshall', 'islands', 'flag', 'nation', 'country', 'banner', 'marshall_islands'],
  sheet: [2, 57],
  shortName: 'flag-mh'
}, {
  name: 'North Macedonia Flag',
  unified: '1F1F2-1F1F0',
  keywords: ['flag_north_macedonia', 'macedonia', 'flag', 'nation', 'country', 'banner', 'north_macedonia'],
  sheet: [2, 58],
  shortName: 'flag-mk'
}, {
  name: 'Mali Flag',
  unified: '1F1F2-1F1F1',
  keywords: ['flag_mali', 'ml', 'flag', 'nation', 'country', 'banner', 'mali'],
  sheet: [2, 59],
  shortName: 'flag-ml'
}, {
  name: 'Myanmar (burma) Flag',
  unified: '1F1F2-1F1F2',
  keywords: ['flag_myanmar', 'mm', 'flag', 'nation', 'country', 'banner', 'myanmar'],
  sheet: [2, 60],
  shortName: 'flag-mm'
}, {
  name: 'Mongolia Flag',
  unified: '1F1F2-1F1F3',
  keywords: ['flag_mongolia', 'mn', 'flag', 'nation', 'country', 'banner', 'mongolia'],
  sheet: [3, 0],
  shortName: 'flag-mn'
}, {
  name: 'Macao Sar China Flag',
  unified: '1F1F2-1F1F4',
  keywords: ['flag_macao_sar_china', 'macao', 'flag', 'nation', 'country', 'banner', 'macao_sar_china'],
  sheet: [3, 1],
  shortName: 'flag-mo'
}, {
  name: 'Northern Mariana Islands Flag',
  unified: '1F1F2-1F1F5',
  keywords: ['flag_northern_mariana_islands', 'northern', 'mariana', 'islands', 'flag', 'nation', 'country', 'banner', 'northern_mariana_islands'],
  sheet: [3, 2],
  shortName: 'flag-mp'
}, {
  name: 'Martinique Flag',
  unified: '1F1F2-1F1F6',
  keywords: ['flag_martinique', 'mq', 'flag', 'nation', 'country', 'banner', 'martinique'],
  sheet: [3, 3],
  shortName: 'flag-mq'
}, {
  name: 'Mauritania Flag',
  unified: '1F1F2-1F1F7',
  keywords: ['flag_mauritania', 'mr', 'flag', 'nation', 'country', 'banner', 'mauritania'],
  sheet: [3, 4],
  shortName: 'flag-mr'
}, {
  name: 'Montserrat Flag',
  unified: '1F1F2-1F1F8',
  keywords: ['flag_montserrat', 'ms', 'flag', 'nation', 'country', 'banner', 'montserrat'],
  sheet: [3, 5],
  shortName: 'flag-ms'
}, {
  name: 'Malta Flag',
  unified: '1F1F2-1F1F9',
  keywords: ['flag_malta', 'mt', 'flag', 'nation', 'country', 'banner', 'malta'],
  sheet: [3, 6],
  shortName: 'flag-mt'
}, {
  name: 'Mauritius Flag',
  unified: '1F1F2-1F1FA',
  keywords: ['flag_mauritius', 'mu', 'flag', 'nation', 'country', 'banner', 'mauritius'],
  sheet: [3, 7],
  shortName: 'flag-mu'
}, {
  name: 'Maldives Flag',
  unified: '1F1F2-1F1FB',
  keywords: ['flag_maldives', 'mv', 'flag', 'nation', 'country', 'banner', 'maldives'],
  sheet: [3, 8],
  shortName: 'flag-mv'
}, {
  name: 'Malawi Flag',
  unified: '1F1F2-1F1FC',
  keywords: ['flag_malawi', 'mw', 'flag', 'nation', 'country', 'banner', 'malawi'],
  sheet: [3, 9],
  shortName: 'flag-mw'
}, {
  name: 'Mexico Flag',
  unified: '1F1F2-1F1FD',
  keywords: ['flag_mexico', 'mx', 'flag', 'nation', 'country', 'banner', 'mexico'],
  sheet: [3, 10],
  shortName: 'flag-mx'
}, {
  name: 'Malaysia Flag',
  unified: '1F1F2-1F1FE',
  keywords: ['flag_malaysia', 'my', 'flag', 'nation', 'country', 'banner', 'malaysia'],
  sheet: [3, 11],
  shortName: 'flag-my'
}, {
  name: 'Mozambique Flag',
  unified: '1F1F2-1F1FF',
  keywords: ['flag_mozambique', 'mz', 'flag', 'nation', 'country', 'banner', 'mozambique'],
  sheet: [3, 12],
  shortName: 'flag-mz'
}, {
  name: 'Namibia Flag',
  unified: '1F1F3-1F1E6',
  keywords: ['flag_namibia', 'na', 'flag', 'nation', 'country', 'banner', 'namibia'],
  sheet: [3, 13],
  shortName: 'flag-na'
}, {
  name: 'New Caledonia Flag',
  unified: '1F1F3-1F1E8',
  keywords: ['flag_new_caledonia', 'new', 'caledonia', 'flag', 'nation', 'country', 'banner', 'new_caledonia'],
  sheet: [3, 14],
  shortName: 'flag-nc'
}, {
  name: 'Niger Flag',
  unified: '1F1F3-1F1EA',
  keywords: ['flag_niger', 'ne', 'flag', 'nation', 'country', 'banner', 'niger'],
  sheet: [3, 15],
  shortName: 'flag-ne'
}, {
  name: 'Norfolk Island Flag',
  unified: '1F1F3-1F1EB',
  keywords: ['flag_norfolk_island', 'norfolk', 'island', 'flag', 'nation', 'country', 'banner', 'norfolk_island'],
  sheet: [3, 16],
  shortName: 'flag-nf'
}, {
  name: 'Nigeria Flag',
  unified: '1F1F3-1F1EC',
  keywords: ['flag_nigeria', 'flag', 'nation', 'country', 'banner', 'nigeria'],
  sheet: [3, 17],
  shortName: 'flag-ng'
}, {
  name: 'Nicaragua Flag',
  unified: '1F1F3-1F1EE',
  keywords: ['flag_nicaragua', 'ni', 'flag', 'nation', 'country', 'banner', 'nicaragua'],
  sheet: [3, 18],
  shortName: 'flag-ni'
}, {
  name: 'Netherlands Flag',
  unified: '1F1F3-1F1F1',
  keywords: ['flag_netherlands', 'nl', 'flag', 'nation', 'country', 'banner', 'netherlands'],
  sheet: [3, 19],
  shortName: 'flag-nl'
}, {
  name: 'Norway Flag',
  unified: '1F1F3-1F1F4',
  keywords: ['flag_norway', 'no', 'flag', 'nation', 'country', 'banner', 'norway'],
  sheet: [3, 20],
  shortName: 'flag-no'
}, {
  name: 'Nepal Flag',
  unified: '1F1F3-1F1F5',
  keywords: ['flag_nepal', 'np', 'flag', 'nation', 'country', 'banner', 'nepal'],
  sheet: [3, 21],
  shortName: 'flag-np'
}, {
  name: 'Nauru Flag',
  unified: '1F1F3-1F1F7',
  keywords: ['flag_nauru', 'nr', 'flag', 'nation', 'country', 'banner', 'nauru'],
  sheet: [3, 22],
  shortName: 'flag-nr'
}, {
  name: 'Niue Flag',
  unified: '1F1F3-1F1FA',
  keywords: ['flag_niue', 'nu', 'flag', 'nation', 'country', 'banner', 'niue'],
  sheet: [3, 23],
  shortName: 'flag-nu'
}, {
  name: 'New Zealand Flag',
  unified: '1F1F3-1F1FF',
  keywords: ['flag_new_zealand', 'new', 'zealand', 'flag', 'nation', 'country', 'banner', 'new_zealand'],
  sheet: [3, 24],
  shortName: 'flag-nz'
}, {
  name: 'Oman Flag',
  unified: '1F1F4-1F1F2',
  keywords: ['flag_oman', 'om_symbol', 'flag', 'nation', 'country', 'banner', 'oman'],
  sheet: [3, 25],
  shortName: 'flag-om'
}, {
  name: 'Panama Flag',
  unified: '1F1F5-1F1E6',
  keywords: ['flag_panama', 'pa', 'flag', 'nation', 'country', 'banner', 'panama'],
  sheet: [3, 26],
  shortName: 'flag-pa'
}, {
  name: 'Peru Flag',
  unified: '1F1F5-1F1EA',
  keywords: ['flag_peru', 'pe', 'flag', 'nation', 'country', 'banner', 'peru'],
  sheet: [3, 27],
  shortName: 'flag-pe'
}, {
  name: 'French Polynesia Flag',
  unified: '1F1F5-1F1EB',
  keywords: ['flag_french_polynesia', 'french', 'polynesia', 'flag', 'nation', 'country', 'banner', 'french_polynesia'],
  sheet: [3, 28],
  shortName: 'flag-pf'
}, {
  name: 'Papua New Guinea Flag',
  unified: '1F1F5-1F1EC',
  keywords: ['flag_papua_new_guinea', 'papua', 'new', 'guinea', 'flag', 'nation', 'country', 'banner', 'papua_new_guinea'],
  sheet: [3, 29],
  shortName: 'flag-pg'
}, {
  name: 'Philippines Flag',
  unified: '1F1F5-1F1ED',
  keywords: ['flag_philippines', 'ph', 'flag', 'nation', 'country', 'banner', 'philippines'],
  sheet: [3, 30],
  shortName: 'flag-ph'
}, {
  name: 'Pakistan Flag',
  unified: '1F1F5-1F1F0',
  keywords: ['flag_pakistan', 'pk', 'flag', 'nation', 'country', 'banner', 'pakistan'],
  sheet: [3, 31],
  shortName: 'flag-pk'
}, {
  name: 'Poland Flag',
  unified: '1F1F5-1F1F1',
  keywords: ['flag_poland', 'pl', 'flag', 'nation', 'country', 'banner', 'poland'],
  sheet: [3, 32],
  shortName: 'flag-pl'
}, {
  name: 'St. Pierre & Miquelon Flag',
  unified: '1F1F5-1F1F2',
  keywords: ['flag_st_pierre_miquelon', 'saint', 'pierre', 'miquelon', 'flag', 'nation', 'country', 'banner', 'st_pierre_miquelon'],
  sheet: [3, 33],
  shortName: 'flag-pm'
}, {
  name: 'Pitcairn Islands Flag',
  unified: '1F1F5-1F1F3',
  keywords: ['flag_pitcairn_islands', 'pitcairn', 'flag', 'nation', 'country', 'banner', 'pitcairn_islands'],
  sheet: [3, 34],
  shortName: 'flag-pn'
}, {
  name: 'Puerto Rico Flag',
  unified: '1F1F5-1F1F7',
  keywords: ['flag_puerto_rico', 'puerto', 'rico', 'flag', 'nation', 'country', 'banner', 'puerto_rico'],
  sheet: [3, 35],
  shortName: 'flag-pr'
}, {
  name: 'Palestinian Territories Flag',
  unified: '1F1F5-1F1F8',
  keywords: ['flag_palestinian_territories', 'palestine', 'palestinian', 'territories', 'flag', 'nation', 'country', 'banner', 'palestinian_territories'],
  sheet: [3, 36],
  shortName: 'flag-ps'
}, {
  name: 'Portugal Flag',
  unified: '1F1F5-1F1F9',
  keywords: ['flag_portugal', 'pt', 'flag', 'nation', 'country', 'banner', 'portugal'],
  sheet: [3, 37],
  shortName: 'flag-pt'
}, {
  name: 'Palau Flag',
  unified: '1F1F5-1F1FC',
  keywords: ['flag_palau', 'pw', 'flag', 'nation', 'country', 'banner', 'palau'],
  sheet: [3, 38],
  shortName: 'flag-pw'
}, {
  name: 'Paraguay Flag',
  unified: '1F1F5-1F1FE',
  keywords: ['flag_paraguay', 'py', 'flag', 'nation', 'country', 'banner', 'paraguay'],
  sheet: [3, 39],
  shortName: 'flag-py'
}, {
  name: 'Qatar Flag',
  unified: '1F1F6-1F1E6',
  keywords: ['flag_qatar', 'qa', 'flag', 'nation', 'country', 'banner', 'qatar'],
  sheet: [3, 40],
  shortName: 'flag-qa'
}, {
  name: 'Réunion Flag',
  unified: '1F1F7-1F1EA',
  keywords: ['flag_reunion', 'réunion', 'flag', 'nation', 'country', 'banner', 'reunion'],
  sheet: [3, 41],
  shortName: 'flag-re'
}, {
  name: 'Romania Flag',
  unified: '1F1F7-1F1F4',
  keywords: ['flag_romania', 'ro', 'flag', 'nation', 'country', 'banner', 'romania'],
  sheet: [3, 42],
  shortName: 'flag-ro'
}, {
  name: 'Serbia Flag',
  unified: '1F1F7-1F1F8',
  keywords: ['flag_serbia', 'rs', 'flag', 'nation', 'country', 'banner', 'serbia'],
  sheet: [3, 43],
  shortName: 'flag-rs'
}, {
  name: 'Russia Flag',
  unified: '1F1F7-1F1FA',
  keywords: ['flag_russia', 'russian', 'federation', 'flag', 'nation', 'country', 'banner', 'russia'],
  sheet: [3, 44],
  shortNames: ['flag-ru'],
  shortName: 'ru'
}, {
  name: 'Rwanda Flag',
  unified: '1F1F7-1F1FC',
  keywords: ['flag_rwanda', 'rw', 'flag', 'nation', 'country', 'banner', 'rwanda'],
  sheet: [3, 45],
  shortName: 'flag-rw'
}, {
  name: 'Saudi Arabia Flag',
  unified: '1F1F8-1F1E6',
  keywords: ['flag_saudi_arabia', 'flag', 'nation', 'country', 'banner', 'saudi_arabia'],
  sheet: [3, 46],
  shortName: 'flag-sa'
}, {
  name: 'Solomon Islands Flag',
  unified: '1F1F8-1F1E7',
  keywords: ['flag_solomon_islands', 'solomon', 'islands', 'flag', 'nation', 'country', 'banner', 'solomon_islands'],
  sheet: [3, 47],
  shortName: 'flag-sb'
}, {
  name: 'Seychelles Flag',
  unified: '1F1F8-1F1E8',
  keywords: ['flag_seychelles', 'sc', 'flag', 'nation', 'country', 'banner', 'seychelles'],
  sheet: [3, 48],
  shortName: 'flag-sc'
}, {
  name: 'Sudan Flag',
  unified: '1F1F8-1F1E9',
  keywords: ['flag_sudan', 'sd', 'flag', 'nation', 'country', 'banner', 'sudan'],
  sheet: [3, 49],
  shortName: 'flag-sd'
}, {
  name: 'Sweden Flag',
  unified: '1F1F8-1F1EA',
  keywords: ['flag_sweden', 'se', 'flag', 'nation', 'country', 'banner', 'sweden'],
  sheet: [3, 50],
  shortName: 'flag-se'
}, {
  name: 'Singapore Flag',
  unified: '1F1F8-1F1EC',
  keywords: ['flag_singapore', 'sg', 'flag', 'nation', 'country', 'banner', 'singapore'],
  sheet: [3, 51],
  shortName: 'flag-sg'
}, {
  name: 'St. Helena Flag',
  unified: '1F1F8-1F1ED',
  keywords: ['flag_st_helena', 'saint', 'helena', 'ascension', 'tristan', 'cunha', 'flag', 'nation', 'country', 'banner', 'st_helena'],
  sheet: [3, 52],
  shortName: 'flag-sh'
}, {
  name: 'Slovenia Flag',
  unified: '1F1F8-1F1EE',
  keywords: ['flag_slovenia', 'si', 'flag', 'nation', 'country', 'banner', 'slovenia'],
  sheet: [3, 53],
  shortName: 'flag-si'
}, {
  name: 'Svalbard & Jan Mayen Flag',
  unified: '1F1F8-1F1EF',
  keywords: ['flag_svalbard_jan_mayen'],
  sheet: [3, 54],
  shortName: 'flag-sj'
}, {
  name: 'Slovakia Flag',
  unified: '1F1F8-1F1F0',
  keywords: ['flag_slovakia', 'sk', 'flag', 'nation', 'country', 'banner', 'slovakia'],
  sheet: [3, 55],
  shortName: 'flag-sk'
}, {
  name: 'Sierra Leone Flag',
  unified: '1F1F8-1F1F1',
  keywords: ['flag_sierra_leone', 'sierra', 'leone', 'flag', 'nation', 'country', 'banner', 'sierra_leone'],
  sheet: [3, 56],
  shortName: 'flag-sl'
}, {
  name: 'San Marino Flag',
  unified: '1F1F8-1F1F2',
  keywords: ['flag_san_marino', 'san', 'marino', 'flag', 'nation', 'country', 'banner', 'san_marino'],
  sheet: [3, 57],
  shortName: 'flag-sm'
}, {
  name: 'Senegal Flag',
  unified: '1F1F8-1F1F3',
  keywords: ['flag_senegal', 'sn', 'flag', 'nation', 'country', 'banner', 'senegal'],
  sheet: [3, 58],
  shortName: 'flag-sn'
}, {
  name: 'Somalia Flag',
  unified: '1F1F8-1F1F4',
  keywords: ['flag_somalia', 'so', 'flag', 'nation', 'country', 'banner', 'somalia'],
  sheet: [3, 59],
  shortName: 'flag-so'
}, {
  name: 'Suriname Flag',
  unified: '1F1F8-1F1F7',
  keywords: ['flag_suriname', 'sr', 'flag', 'nation', 'country', 'banner', 'suriname'],
  sheet: [3, 60],
  shortName: 'flag-sr'
}, {
  name: 'South Sudan Flag',
  unified: '1F1F8-1F1F8',
  keywords: ['flag_south_sudan', 'south', 'sd', 'flag', 'nation', 'country', 'banner', 'south_sudan'],
  sheet: [4, 0],
  shortName: 'flag-ss'
}, {
  name: 'São Tomé & Príncipe Flag',
  unified: '1F1F8-1F1F9',
  keywords: ['flag_sao_tome_principe', 'sao', 'tome', 'principe', 'flag', 'nation', 'country', 'banner', 'sao_tome_principe'],
  sheet: [4, 1],
  shortName: 'flag-st'
}, {
  name: 'El Salvador Flag',
  unified: '1F1F8-1F1FB',
  keywords: ['flag_el_salvador', 'el', 'salvador', 'flag', 'nation', 'country', 'banner', 'el_salvador'],
  sheet: [4, 2],
  shortName: 'flag-sv'
}, {
  name: 'Sint Maarten Flag',
  unified: '1F1F8-1F1FD',
  keywords: ['flag_sint_maarten', 'sint', 'maarten', 'dutch', 'flag', 'nation', 'country', 'banner', 'sint_maarten'],
  sheet: [4, 3],
  shortName: 'flag-sx'
}, {
  name: 'Syria Flag',
  unified: '1F1F8-1F1FE',
  keywords: ['flag_syria', 'syrian', 'arab', 'republic', 'flag', 'nation', 'country', 'banner', 'syria'],
  sheet: [4, 4],
  shortName: 'flag-sy'
}, {
  name: 'Eswatini Flag',
  unified: '1F1F8-1F1FF',
  keywords: ['flag_eswatini', 'sz', 'flag', 'nation', 'country', 'banner', 'eswatini'],
  sheet: [4, 5],
  shortName: 'flag-sz'
}, {
  name: 'Tristan Da Cunha Flag',
  unified: '1F1F9-1F1E6',
  keywords: ['flag_tristan_da_cunha'],
  sheet: [4, 6],
  shortName: 'flag-ta'
}, {
  name: 'Turks & Caicos Islands Flag',
  unified: '1F1F9-1F1E8',
  keywords: ['flag_turks_caicos_islands', 'turks', 'caicos', 'islands', 'flag', 'nation', 'country', 'banner', 'turks_caicos_islands'],
  sheet: [4, 7],
  shortName: 'flag-tc'
}, {
  name: 'Chad Flag',
  unified: '1F1F9-1F1E9',
  keywords: ['flag_chad', 'td', 'flag', 'nation', 'country', 'banner', 'chad'],
  sheet: [4, 8],
  shortName: 'flag-td'
}, {
  name: 'French Southern Territories Flag',
  unified: '1F1F9-1F1EB',
  keywords: ['flag_french_southern_territories', 'french', 'southern', 'territories', 'flag', 'nation', 'country', 'banner', 'french_southern_territories'],
  sheet: [4, 9],
  shortName: 'flag-tf'
}, {
  name: 'Togo Flag',
  unified: '1F1F9-1F1EC',
  keywords: ['flag_togo', 'tg', 'flag', 'nation', 'country', 'banner', 'togo'],
  sheet: [4, 10],
  shortName: 'flag-tg'
}, {
  name: 'Thailand Flag',
  unified: '1F1F9-1F1ED',
  keywords: ['flag_thailand', 'th', 'flag', 'nation', 'country', 'banner', 'thailand'],
  sheet: [4, 11],
  shortName: 'flag-th'
}, {
  name: 'Tajikistan Flag',
  unified: '1F1F9-1F1EF',
  keywords: ['flag_tajikistan', 'tj', 'flag', 'nation', 'country', 'banner', 'tajikistan'],
  sheet: [4, 12],
  shortName: 'flag-tj'
}, {
  name: 'Tokelau Flag',
  unified: '1F1F9-1F1F0',
  keywords: ['flag_tokelau', 'tk', 'flag', 'nation', 'country', 'banner', 'tokelau'],
  sheet: [4, 13],
  shortName: 'flag-tk'
}, {
  name: 'Timor-Leste Flag',
  unified: '1F1F9-1F1F1',
  keywords: ['flag_timor_leste', 'timor', 'leste', 'flag', 'nation', 'country', 'banner', 'timor_leste'],
  sheet: [4, 14],
  shortName: 'flag-tl'
}, {
  name: 'Turkmenistan Flag',
  unified: '1F1F9-1F1F2',
  keywords: ['flag_turkmenistan', 'flag', 'nation', 'country', 'banner', 'turkmenistan'],
  sheet: [4, 15],
  shortName: 'flag-tm'
}, {
  name: 'Tunisia Flag',
  unified: '1F1F9-1F1F3',
  keywords: ['flag_tunisia', 'tn', 'flag', 'nation', 'country', 'banner', 'tunisia'],
  sheet: [4, 16],
  shortName: 'flag-tn'
}, {
  name: 'Tonga Flag',
  unified: '1F1F9-1F1F4',
  keywords: ['flag_tonga', 'to', 'flag', 'nation', 'country', 'banner', 'tonga'],
  sheet: [4, 17],
  shortName: 'flag-to'
}, {
  name: 'Turkey Flag',
  unified: '1F1F9-1F1F7',
  keywords: ['flag_turkey', 'turkey', 'flag', 'nation', 'country', 'banner', 'turkey'],
  sheet: [4, 18],
  shortName: 'flag-tr'
}, {
  name: 'Trinidad & Tobago Flag',
  unified: '1F1F9-1F1F9',
  keywords: ['flag_trinidad_tobago', 'trinidad', 'tobago', 'flag', 'nation', 'country', 'banner', 'trinidad_tobago'],
  sheet: [4, 19],
  shortName: 'flag-tt'
}, {
  name: 'Tuvalu Flag',
  unified: '1F1F9-1F1FB',
  keywords: ['flag_tuvalu', 'flag', 'nation', 'country', 'banner', 'tuvalu'],
  sheet: [4, 20],
  shortName: 'flag-tv'
}, {
  name: 'Taiwan Flag',
  unified: '1F1F9-1F1FC',
  keywords: ['flag_taiwan', 'tw', 'flag', 'nation', 'country', 'banner', 'taiwan'],
  sheet: [4, 21],
  shortName: 'flag-tw'
}, {
  name: 'Tanzania Flag',
  unified: '1F1F9-1F1FF',
  keywords: ['flag_tanzania', 'tanzania', 'united', 'republic', 'flag', 'nation', 'country', 'banner', 'tanzania'],
  sheet: [4, 22],
  shortName: 'flag-tz'
}, {
  name: 'Ukraine Flag',
  unified: '1F1FA-1F1E6',
  keywords: ['flag_ukraine', 'ua', 'flag', 'nation', 'country', 'banner', 'ukraine'],
  sheet: [4, 23],
  shortName: 'flag-ua'
}, {
  name: 'Uganda Flag',
  unified: '1F1FA-1F1EC',
  keywords: ['flag_uganda', 'ug', 'flag', 'nation', 'country', 'banner', 'uganda'],
  sheet: [4, 24],
  shortName: 'flag-ug'
}, {
  name: 'U.s. Outlying Islands Flag',
  unified: '1F1FA-1F1F2',
  keywords: ['flag_u_s_outlying_islands'],
  sheet: [4, 25],
  shortName: 'flag-um'
}, {
  name: 'United Nations Flag',
  unified: '1F1FA-1F1F3',
  keywords: ['flag_united_nations', 'un', 'flag', 'banner'],
  sheet: [4, 26],
  shortName: 'flag-un'
}, {
  name: 'United States Flag',
  unified: '1F1FA-1F1F8',
  keywords: ['flag_united_states', 'united', 'states', 'america', 'flag', 'nation', 'country', 'banner', 'united_states'],
  sheet: [4, 27],
  shortNames: ['flag-us'],
  shortName: 'us'
}, {
  name: 'Uruguay Flag',
  unified: '1F1FA-1F1FE',
  keywords: ['flag_uruguay', 'uy', 'flag', 'nation', 'country', 'banner', 'uruguay'],
  sheet: [4, 28],
  shortName: 'flag-uy'
}, {
  name: 'Uzbekistan Flag',
  unified: '1F1FA-1F1FF',
  keywords: ['flag_uzbekistan', 'uz', 'flag', 'nation', 'country', 'banner', 'uzbekistan'],
  sheet: [4, 29],
  shortName: 'flag-uz'
}, {
  name: 'Vatican City Flag',
  unified: '1F1FB-1F1E6',
  keywords: ['flag_vatican_city', 'vatican', 'city', 'flag', 'nation', 'country', 'banner', 'vatican_city'],
  sheet: [4, 30],
  shortName: 'flag-va'
}, {
  name: 'St. Vincent & Grenadines Flag',
  unified: '1F1FB-1F1E8',
  keywords: ['flag_st_vincent_grenadines', 'saint', 'vincent', 'grenadines', 'flag', 'nation', 'country', 'banner', 'st_vincent_grenadines'],
  sheet: [4, 31],
  shortName: 'flag-vc'
}, {
  name: 'Venezuela Flag',
  unified: '1F1FB-1F1EA',
  keywords: ['flag_venezuela', 've', 'bolivarian', 'republic', 'flag', 'nation', 'country', 'banner', 'venezuela'],
  sheet: [4, 32],
  shortName: 'flag-ve'
}, {
  name: 'British Virgin Islands Flag',
  unified: '1F1FB-1F1EC',
  keywords: ['flag_british_virgin_islands', 'british', 'virgin', 'islands', 'bvi', 'flag', 'nation', 'country', 'banner', 'british_virgin_islands'],
  sheet: [4, 33],
  shortName: 'flag-vg'
}, {
  name: 'U.s. Virgin Islands Flag',
  unified: '1F1FB-1F1EE',
  keywords: ['flag_u_s_virgin_islands', 'virgin', 'islands', 'us', 'flag', 'nation', 'country', 'banner', 'u_s_virgin_islands'],
  sheet: [4, 34],
  shortName: 'flag-vi'
}, {
  name: 'Vietnam Flag',
  unified: '1F1FB-1F1F3',
  keywords: ['flag_vietnam', 'viet', 'nam', 'flag', 'nation', 'country', 'banner', 'vietnam'],
  sheet: [4, 35],
  shortName: 'flag-vn'
}, {
  name: 'Vanuatu Flag',
  unified: '1F1FB-1F1FA',
  keywords: ['flag_vanuatu', 'vu', 'flag', 'nation', 'country', 'banner', 'vanuatu'],
  sheet: [4, 36],
  shortName: 'flag-vu'
}, {
  name: 'Wallis & Futuna Flag',
  unified: '1F1FC-1F1EB',
  keywords: ['flag_wallis_futuna', 'wallis', 'futuna', 'flag', 'nation', 'country', 'banner', 'wallis_futuna'],
  sheet: [4, 37],
  shortName: 'flag-wf'
}, {
  name: 'Samoa Flag',
  unified: '1F1FC-1F1F8',
  keywords: ['flag_samoa', 'ws', 'flag', 'nation', 'country', 'banner', 'samoa'],
  sheet: [4, 38],
  shortName: 'flag-ws'
}, {
  name: 'Kosovo Flag',
  unified: '1F1FD-1F1F0',
  keywords: ['flag_kosovo', 'xk', 'flag', 'nation', 'country', 'banner', 'kosovo'],
  sheet: [4, 39],
  shortName: 'flag-xk'
}, {
  name: 'Yemen Flag',
  unified: '1F1FE-1F1EA',
  keywords: ['flag_yemen', 'ye', 'flag', 'nation', 'country', 'banner', 'yemen'],
  sheet: [4, 40],
  shortName: 'flag-ye'
}, {
  name: 'Mayotte Flag',
  unified: '1F1FE-1F1F9',
  keywords: ['flag_mayotte', 'yt', 'flag', 'nation', 'country', 'banner', 'mayotte'],
  sheet: [4, 41],
  shortName: 'flag-yt'
}, {
  name: 'South Africa Flag',
  unified: '1F1FF-1F1E6',
  keywords: ['flag_south_africa', 'south', 'africa', 'flag', 'nation', 'country', 'banner', 'south_africa'],
  sheet: [4, 42],
  shortName: 'flag-za'
}, {
  name: 'Zambia Flag',
  unified: '1F1FF-1F1F2',
  keywords: ['flag_zambia', 'zm', 'flag', 'nation', 'country', 'banner', 'zambia'],
  sheet: [4, 43],
  shortName: 'flag-zm'
}, {
  name: 'Zimbabwe Flag',
  unified: '1F1FF-1F1FC',
  keywords: ['flag_zimbabwe', 'zw', 'flag', 'nation', 'country', 'banner', 'zimbabwe'],
  sheet: [4, 44],
  shortName: 'flag-zw'
}, {
  name: 'England Flag',
  unified: '1F3F4-E0067-E0062-E0065-E006E-E0067-E007F',
  keywords: ['flag_england', 'flag', 'english'],
  sheet: [10, 32],
  shortName: 'flag-england'
}, {
  name: 'Scotland Flag',
  unified: '1F3F4-E0067-E0062-E0073-E0063-E0074-E007F',
  keywords: ['flag_scotland', 'flag', 'scottish'],
  sheet: [10, 33],
  shortName: 'flag-scotland'
}, {
  name: 'Wales Flag',
  unified: '1F3F4-E0067-E0062-E0077-E006C-E0073-E007F',
  keywords: ['flag_wales', 'flag', 'welsh'],
  sheet: [10, 34],
  shortName: 'flag-wales'
}];
const skins = [{
  name: 'Emoji Modifier Fitzpatrick Type-1-2',
  unified: '1F3FB',
  sheet: [10, 41],
  shortName: 'skin-tone-2'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-3',
  unified: '1F3FC',
  sheet: [10, 42],
  shortName: 'skin-tone-3'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-4',
  unified: '1F3FD',
  sheet: [10, 43],
  shortName: 'skin-tone-4'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-5',
  unified: '1F3FE',
  sheet: [10, 44],
  shortName: 'skin-tone-5'
}, {
  name: 'Emoji Modifier Fitzpatrick Type-6',
  unified: '1F3FF',
  sheet: [10, 45],
  shortName: 'skin-tone-6'
}];
const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/;
const SKINS = ['1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF'];
const DEFAULT_BACKGROUNDFN = (set, sheetSize) => `https://cdn.jsdelivr.net/npm/emoji-datasource-${set}@14.0.0/img/${set}/sheets-256/${sheetSize}.png`;
class EmojiService {
  uncompressed = false;
  names = {};
  emojis = [];
  constructor() {
    if (!this.uncompressed) {
      this.uncompress(emojis);
      this.uncompressed = true;
    }
  }
  uncompress(list) {
    this.emojis = list.map(emoji => {
      const data = {
        ...emoji
      };
      if (!data.shortNames) {
        data.shortNames = [];
      }
      data.shortNames.unshift(data.shortName);
      data.id = data.shortName;
      data.native = this.unifiedToNative(data.unified);
      if (!data.skinVariations) {
        data.skinVariations = [];
      }
      if (!data.keywords) {
        data.keywords = [];
      }
      if (!data.emoticons) {
        data.emoticons = [];
      }
      if (!data.hidden) {
        data.hidden = [];
      }
      if (!data.text) {
        data.text = '';
      }
      if (data.obsoletes) {
        // get keywords from emoji that it obsoletes since that is shared
        const f = list.find(x => x.unified === data.obsoletes);
        if (f) {
          if (f.keywords) {
            data.keywords = [...data.keywords, ...f.keywords, f.shortName];
          } else {
            data.keywords = [...data.keywords, f.shortName];
          }
        }
      }
      this.names[data.unified] = data;
      for (const n of data.shortNames) {
        this.names[n] = data;
      }
      return data;
    });
  }
  getData(emoji, skin, set) {
    let emojiData;
    if (typeof emoji === 'string') {
      const matches = emoji.match(COLONS_REGEX);
      if (matches) {
        emoji = matches[1];
        if (matches[2]) {
          skin = parseInt(matches[2], 10);
        }
      }
      if (this.names.hasOwnProperty(emoji)) {
        emojiData = this.names[emoji];
      } else {
        return null;
      }
    } else if (emoji.id) {
      emojiData = this.names[emoji.id];
    } else if (emoji.unified) {
      emojiData = this.names[emoji.unified.toUpperCase()];
    }
    if (!emojiData) {
      emojiData = emoji;
      emojiData.custom = true;
    }
    const hasSkinVariations = emojiData.skinVariations && emojiData.skinVariations.length;
    if (hasSkinVariations && skin && skin > 1 && set) {
      emojiData = {
        ...emojiData
      };
      const skinKey = SKINS[skin - 1];
      const variationData = emojiData.skinVariations.find(n => n.unified.includes(skinKey));
      if (!variationData.hidden || !variationData.hidden.includes(set)) {
        emojiData.skinTone = skin;
        emojiData = {
          ...emojiData,
          ...variationData
        };
      }
      emojiData.native = this.unifiedToNative(emojiData.unified);
    }
    emojiData.set = set || '';
    return emojiData;
  }
  unifiedToNative(unified) {
    const codePoints = unified.split('-').map(u => parseInt(`0x${u}`, 16));
    return String.fromCodePoint(...codePoints);
  }
  emojiSpriteStyles(sheet, set = 'apple', size = 24, sheetSize = 64, sheetRows = 60, backgroundImageFn = DEFAULT_BACKGROUNDFN, sheetColumns = 61, url) {
    const hasImageUrl = !!url;
    url = url || backgroundImageFn(set, sheetSize);
    return {
      width: `${size}px`,
      height: `${size}px`,
      display: 'inline-block',
      'background-image': `url(${url})`,
      'background-size': hasImageUrl ? '100% 100%' : `${100 * sheetColumns}% ${100 * sheetRows}%`,
      'background-position': hasImageUrl ? undefined : this.getSpritePosition(sheet, sheetColumns)
    };
  }
  getSpritePosition(sheet, sheetColumns) {
    const [sheetX, sheetY] = sheet;
    const multiply = 100 / (sheetColumns - 1);
    return `${multiply * sheetX}% ${multiply * sheetY}%`;
  }
  sanitize(emoji) {
    if (emoji === null) {
      return null;
    }
    const id = emoji.id || emoji.shortNames[0];
    let colons = `:${id}:`;
    if (emoji.skinTone) {
      colons += `:skin-tone-${emoji.skinTone}:`;
    }
    emoji.colons = colons;
    return {
      ...emoji
    };
  }
  getSanitizedData(emoji, skin, set) {
    return this.sanitize(this.getData(emoji, skin, set));
  }
  static ɵfac = function EmojiService_Factory(t) {
    return new (t || EmojiService)();
  };
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
    token: EmojiService,
    factory: EmojiService.ɵfac,
    providedIn: 'root'
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmojiService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], function () {
    return [];
  }, null);
})();
class EmojiComponent {
  skin = 1;
  set = 'apple';
  sheetSize = 64;
  /** Renders the native unicode emoji */
  isNative = false;
  forceSize = false;
  tooltip = false;
  size = 24;
  emoji = '';
  fallback;
  hideObsolete = false;
  sheetRows;
  sheetColumns;
  useButton;
  /**
   * Note: `emojiOver` and `emojiOverOutsideAngular` are dispatched on the same event (`mouseenter`), but
   *       for different purposes. The `emojiOverOutsideAngular` event is listened only in `emoji-category`
   *       component and the category component doesn't care about zone context the callback is being called in.
   *       The `emojiOver` is for backwards compatibility if anyone is listening to this event explicitly in their code.
   */
  emojiOver = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiOverOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  /** See comments above, this serves the same purpose. */
  emojiLeave = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiLeaveOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiClick = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiClickOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  style;
  title = undefined;
  label = '';
  unified;
  custom = false;
  isVisible = true;
  // TODO: replace 4.0.3 w/ dynamic get verison from emoji-datasource in package.json
  backgroundImageFn = DEFAULT_BACKGROUNDFN;
  imageUrlFn;
  set button(button) {
    // Note: `runOutsideAngular` is used to trigger `addEventListener` outside of the Angular zone
    //       too. See `setupMouseEnterListener`. The `switchMap` will subscribe to `fromEvent` considering
    //       the context where the factory is called in.
    this.ngZone.runOutsideAngular(() => this.button$.next(button?.nativeElement));
  }
  /**
   * The subject used to emit whenever view queries are run and `button` or `span` is set/removed.
   * We use subject to keep the reactive behavior so we don't have to add and remove event listeners manually.
   */
  button$ = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
  destroy$ = new rxjs__WEBPACK_IMPORTED_MODULE_1__.Subject();
  ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  emojiService = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(EmojiService);
  constructor() {
    this.setupMouseListeners();
  }
  ngOnChanges() {
    if (!this.emoji) {
      return this.isVisible = false;
    }
    const data = this.getData();
    if (!data) {
      return this.isVisible = false;
    }
    // const children = this.children;
    this.unified = data.native || null;
    if (data.custom) {
      this.custom = data.custom;
    }
    if (!data.unified && !data.custom) {
      return this.isVisible = false;
    }
    if (this.tooltip) {
      this.title = data.shortNames[0];
    }
    if (data.obsoletedBy && this.hideObsolete) {
      return this.isVisible = false;
    }
    this.label = [data.native].concat(data.shortNames).filter(Boolean).join(', ');
    if (this.isNative && data.unified && data.native) {
      // hide older emoji before the split into gendered emoji
      this.style = {
        fontSize: `${this.size}px`
      };
      if (this.forceSize) {
        this.style.display = 'inline-block';
        this.style.width = `${this.size}px`;
        this.style.height = `${this.size}px`;
        this.style['word-break'] = 'keep-all';
      }
    } else if (data.custom) {
      this.style = {
        width: `${this.size}px`,
        height: `${this.size}px`,
        display: 'inline-block'
      };
      if (data.spriteUrl && this.sheetRows && this.sheetColumns) {
        this.style = {
          ...this.style,
          backgroundImage: `url(${data.spriteUrl})`,
          backgroundSize: `${100 * this.sheetColumns}% ${100 * this.sheetRows}%`,
          backgroundPosition: this.emojiService.getSpritePosition(data.sheet, this.sheetColumns)
        };
      } else {
        this.style = {
          ...this.style,
          backgroundImage: `url(${data.imageUrl})`,
          backgroundSize: 'contain'
        };
      }
    } else {
      if (data.hidden.length && data.hidden.includes(this.set)) {
        if (this.fallback) {
          this.style = {
            fontSize: `${this.size}px`
          };
          this.unified = this.fallback(data, this);
        } else {
          return this.isVisible = false;
        }
      } else {
        this.style = this.emojiService.emojiSpriteStyles(data.sheet, this.set, this.size, this.sheetSize, this.sheetRows, this.backgroundImageFn, this.sheetColumns, this.imageUrlFn?.(this.getData()));
      }
    }
    return this.isVisible = true;
  }
  ngOnDestroy() {
    this.destroy$.next();
  }
  getData() {
    return this.emojiService.getData(this.emoji, this.skin, this.set);
  }
  getSanitizedData() {
    return this.emojiService.getSanitizedData(this.emoji, this.skin, this.set);
  }
  setupMouseListeners() {
    const eventListener$ = eventName => this.button$.pipe(
    // Note: `EMPTY` is used to remove event listener once the DOM node is removed.
    (0,rxjs__WEBPACK_IMPORTED_MODULE_2__.switchMap)(button => button ? (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.fromEvent)(button, eventName) : rxjs__WEBPACK_IMPORTED_MODULE_4__.EMPTY), (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this.destroy$));
    eventListener$('click').subscribe($event => {
      const emoji = this.getSanitizedData();
      this.emojiClickOutsideAngular.emit({
        emoji,
        $event
      });
      // Note: this is done for backwards compatibility. We run change detection if developers
      //       are listening to `emojiClick` in their code. For instance:
      //       `<ngx-emoji (emojiClick)="..."></ngx-emoji>`.
      if (this.emojiClick.observed) {
        this.ngZone.run(() => this.emojiClick.emit({
          emoji,
          $event
        }));
      }
    });
    eventListener$('mouseenter').subscribe($event => {
      const emoji = this.getSanitizedData();
      this.emojiOverOutsideAngular.emit({
        emoji,
        $event
      });
      // Note: this is done for backwards compatibility. We run change detection if developers
      //       are listening to `emojiOver` in their code. For instance:
      //       `<ngx-emoji (emojiOver)="..."></ngx-emoji>`.
      if (this.emojiOver.observed) {
        this.ngZone.run(() => this.emojiOver.emit({
          emoji,
          $event
        }));
      }
    });
    eventListener$('mouseleave').subscribe($event => {
      const emoji = this.getSanitizedData();
      this.emojiLeaveOutsideAngular.emit({
        emoji,
        $event
      });
      // Note: this is done for backwards compatibility. We run change detection if developers
      //       are listening to `emojiLeave` in their code. For instance:
      //       `<ngx-emoji (emojiLeave)="..."></ngx-emoji>`.
      if (this.emojiLeave.observed) {
        this.ngZone.run(() => this.emojiLeave.emit({
          emoji,
          $event
        }));
      }
    });
  }
  static ɵfac = function EmojiComponent_Factory(t) {
    return new (t || EmojiComponent)();
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: EmojiComponent,
    selectors: [["ngx-emoji"]],
    viewQuery: function EmojiComponent_Query(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 5);
      }
      if (rf & 2) {
        let _t;
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.button = _t.first);
      }
    },
    inputs: {
      skin: "skin",
      set: "set",
      sheetSize: "sheetSize",
      isNative: "isNative",
      forceSize: "forceSize",
      tooltip: "tooltip",
      size: "size",
      emoji: "emoji",
      fallback: "fallback",
      hideObsolete: "hideObsolete",
      sheetRows: "sheetRows",
      sheetColumns: "sheetColumns",
      useButton: "useButton",
      backgroundImageFn: "backgroundImageFn",
      imageUrlFn: "imageUrlFn"
    },
    outputs: {
      emojiOver: "emojiOver",
      emojiOverOutsideAngular: "emojiOverOutsideAngular",
      emojiLeave: "emojiLeave",
      emojiLeaveOutsideAngular: "emojiLeaveOutsideAngular",
      emojiClick: "emojiClick",
      emojiClickOutsideAngular: "emojiClickOutsideAngular"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    ngContentSelectors: _c1,
    decls: 3,
    vars: 1,
    consts: [["spanTpl", ""], ["button", ""], [3, "ngIf"], ["type", "button", "class", "emoji-mart-emoji", 3, "emoji-mart-emoji-native", "emoji-mart-emoji-custom", 4, "ngIf", "ngIfElse"], ["type", "button", 1, "emoji-mart-emoji"], [3, "ngStyle"], [1, "emoji-mart-emoji"]],
    template: function EmojiComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"](_c1);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, EmojiComponent_ng_template_0_Template, 1, 2, "ng-template", 2)(1, EmojiComponent_ng_template_1_Template, 5, 8, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.isVisible);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_6__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_6__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_6__.NgStyle],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmojiComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngx-emoji',
      template: `
    <ng-template [ngIf]="isVisible">
      <button
        *ngIf="useButton; else spanTpl"
        #button
        type="button"
        [attr.title]="title"
        [attr.aria-label]="label"
        class="emoji-mart-emoji"
        [class.emoji-mart-emoji-native]="isNative"
        [class.emoji-mart-emoji-custom]="custom"
      >
        <span [ngStyle]="style">
          <ng-template [ngIf]="isNative">{{ unified }}</ng-template>
          <ng-content></ng-content>
        </span>
      </button>
    </ng-template>

    <ng-template #spanTpl>
      <span
        #button
        [attr.title]="title"
        [attr.aria-label]="label"
        class="emoji-mart-emoji"
        [class.emoji-mart-emoji-native]="isNative"
        [class.emoji-mart-emoji-custom]="custom"
      >
        <span [ngStyle]="style">
          <ng-template [ngIf]="isNative">{{ unified }}</ng-template>
          <ng-content></ng-content>
        </span>
      </span>
    </ng-template>
  `,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_6__.CommonModule]
    }]
  }], function () {
    return [];
  }, {
    skin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    set: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    sheetSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    isNative: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    forceSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    tooltip: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    size: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    fallback: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hideObsolete: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    sheetRows: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    sheetColumns: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    useButton: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiOver: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiOverOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiLeave: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiLeaveOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiClickOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    backgroundImageFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    imageUrlFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    button: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['button', {
        static: false
      }]
    }]
  });
})();
class EmojiModule {
  static ɵfac = function EmojiModule_Factory(t) {
    return new (t || EmojiModule)();
  };
  static ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
    type: EmojiModule
  });
  static ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
    imports: [EmojiComponent]
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmojiModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [EmojiComponent],
      exports: [EmojiComponent]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 34707:
/*!****************************************************************************!*\
  !*** ./node_modules/@ctrl/ngx-emoji-mart/fesm2022/ctrl-ngx-emoji-mart.mjs ***!
  \****************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AnchorsComponent: () => (/* binding */ AnchorsComponent),
/* harmony export */   CategoryComponent: () => (/* binding */ CategoryComponent),
/* harmony export */   EmojiFrequentlyService: () => (/* binding */ EmojiFrequentlyService),
/* harmony export */   EmojiSearch: () => (/* binding */ EmojiSearch),
/* harmony export */   PickerComponent: () => (/* binding */ PickerComponent),
/* harmony export */   PickerModule: () => (/* binding */ PickerModule),
/* harmony export */   PreviewComponent: () => (/* binding */ PreviewComponent),
/* harmony export */   SearchComponent: () => (/* binding */ SearchComponent),
/* harmony export */   SkinComponent: () => (/* binding */ SkinComponent)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @ctrl/ngx-emoji-mart/ngx-emoji */ 3110);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 18537);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 33900);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @angular/forms */ 34456);









function AnchorsComponent_ng_template_1_span_0_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function AnchorsComponent_ng_template_1_span_0_Template_span_click_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const idx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().index;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleClick($event, idx_r2));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnamespaceSVG"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "svg", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](3, "path");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnamespaceHTML"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](4, "span", 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const category_r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("color", category_r4.name === ctx_r2.selected ? ctx_r2.color : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("emoji-mart-anchor-selected", category_r4.name === ctx_r2.selected);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("title", ctx_r2.i18n.categories[category_r4.id]);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("d", ctx_r2.icons[category_r4.id]);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("background-color", ctx_r2.color);
  }
}
function AnchorsComponent_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, AnchorsComponent_ng_template_1_span_0_Template, 5, 8, "span", 2);
  }
  if (rf & 2) {
    const category_r4 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", category_r4.anchor !== false);
  }
}
const _c0 = ["container"];
const _c1 = ["label"];
function CategoryComponent_div_6_div_1_ngx_emoji_1_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "ngx-emoji", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("emojiOverOutsideAngular", function CategoryComponent_div_6_div_1_ngx_emoji_1_Template_ngx_emoji_emojiOverOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiOverOutsideAngular.emit($event));
    })("emojiLeaveOutsideAngular", function CategoryComponent_div_6_div_1_ngx_emoji_1_Template_ngx_emoji_emojiLeaveOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiLeaveOutsideAngular.emit($event));
    })("emojiClickOutsideAngular", function CategoryComponent_div_6_div_1_ngx_emoji_1_Template_ngx_emoji_emojiClickOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiClickOutsideAngular.emit($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const emoji_r3 = ctx.$implicit;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("emoji", emoji_r3)("size", ctx_r1.emojiSize)("skin", ctx_r1.emojiSkin)("isNative", ctx_r1.emojiIsNative)("set", ctx_r1.emojiSet)("sheetSize", ctx_r1.emojiSheetSize)("forceSize", ctx_r1.emojiForceSize)("tooltip", ctx_r1.emojiTooltip)("backgroundImageFn", ctx_r1.emojiBackgroundImageFn)("imageUrlFn", ctx_r1.emojiImageUrlFn)("hideObsolete", ctx_r1.hideObsolete)("useButton", ctx_r1.emojiUseButton);
  }
}
function CategoryComponent_div_6_div_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, CategoryComponent_div_6_div_1_ngx_emoji_1_Template, 1, 12, "ngx-emoji", 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const filteredEmojis_r4 = ctx.ngIf;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", filteredEmojis_r4)("ngForTrackBy", ctx_r1.trackById);
  }
}
function CategoryComponent_div_6_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, CategoryComponent_div_6_div_1_Template, 2, 2, "div", 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipe"](2, "async");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipeBind1"](2, 1, ctx_r1.filteredEmojis$));
  }
}
function CategoryComponent_div_7_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div")(1, "div");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](2, "ngx-emoji", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](3, "div", 11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("emoji", ctx_r1.notFoundEmoji)("size", 38)("skin", ctx_r1.emojiSkin)("isNative", ctx_r1.emojiIsNative)("set", ctx_r1.emojiSet)("sheetSize", ctx_r1.emojiSheetSize)("forceSize", ctx_r1.emojiForceSize)("tooltip", ctx_r1.emojiTooltip)("backgroundImageFn", ctx_r1.emojiBackgroundImageFn)("useButton", ctx_r1.emojiUseButton);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx_r1.i18n.notfound, " ");
  }
}
function CategoryComponent_ng_template_8_ngx_emoji_0_Template(rf, ctx) {
  if (rf & 1) {
    const _r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "ngx-emoji", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("emojiOverOutsideAngular", function CategoryComponent_ng_template_8_ngx_emoji_0_Template_ngx_emoji_emojiOverOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r5);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiOverOutsideAngular.emit($event));
    })("emojiLeaveOutsideAngular", function CategoryComponent_ng_template_8_ngx_emoji_0_Template_ngx_emoji_emojiLeaveOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r5);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiLeaveOutsideAngular.emit($event));
    })("emojiClickOutsideAngular", function CategoryComponent_ng_template_8_ngx_emoji_0_Template_ngx_emoji_emojiClickOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r5);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.emojiClickOutsideAngular.emit($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const emoji_r6 = ctx.$implicit;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("emoji", emoji_r6)("size", ctx_r1.emojiSize)("skin", ctx_r1.emojiSkin)("isNative", ctx_r1.emojiIsNative)("set", ctx_r1.emojiSet)("sheetSize", ctx_r1.emojiSheetSize)("forceSize", ctx_r1.emojiForceSize)("tooltip", ctx_r1.emojiTooltip)("backgroundImageFn", ctx_r1.emojiBackgroundImageFn)("imageUrlFn", ctx_r1.emojiImageUrlFn)("hideObsolete", ctx_r1.hideObsolete)("useButton", ctx_r1.emojiUseButton);
  }
}
function CategoryComponent_ng_template_8_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, CategoryComponent_ng_template_8_ngx_emoji_0_Template, 1, 12, "ngx-emoji", 8);
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx_r1.emojisToDisplay)("ngForTrackBy", ctx_r1.trackById);
  }
}
function SkinComponent_span_1_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 2)(1, "span", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function SkinComponent_span_1_Template_span_click_1_listener() {
      const skinTone_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1).$implicit;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleClick(skinTone_r2));
    })("keyup.enter", function SkinComponent_span_1_Template_span_keyup_enter_1_listener() {
      const skinTone_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1).$implicit;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleClick(skinTone_r2));
    })("keyup.space", function SkinComponent_span_1_Template_span_keyup_space_1_listener() {
      const skinTone_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1).$implicit;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleClick(skinTone_r2));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const skinTone_r2 = ctx.$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("selected", skinTone_r2 === ctx_r2.skin);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMapInterpolate1"]("emoji-mart-skin emoji-mart-skin-tone-", skinTone_r2, "");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("tabIndex", ctx_r2.tabIndex(skinTone_r2));
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-hidden", !ctx_r2.isVisible(skinTone_r2))("aria-pressed", ctx_r2.pressed(skinTone_r2))("aria-haspopup", !!ctx_r2.isSelected(skinTone_r2))("aria-expanded", ctx_r2.expanded(skinTone_r2))("aria-label", ctx_r2.i18n.skintones[skinTone_r2])("title", ctx_r2.i18n.skintones[skinTone_r2]);
  }
}
function PreviewComponent_div_0_span_7_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const short_name_r1 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" :", short_name_r1, ": ");
  }
}
function PreviewComponent_div_0_span_9_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const emoticon_r2 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", emoticon_r2, " ");
  }
}
function PreviewComponent_div_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 8)(1, "div", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](2, "ngx-emoji", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](3, "div", 4)(4, "div", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "div", 11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](7, PreviewComponent_div_0_span_7_Template, 2, 1, "span", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](8, "div", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](9, PreviewComponent_div_0_span_9_Template, 2, 1, "span", 14);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("emoji", ctx_r2.emoji)("size", 38)("isNative", ctx_r2.emojiIsNative)("skin", ctx_r2.emojiSkin)("size", ctx_r2.emojiSize)("set", ctx_r2.emojiSet)("sheetSize", ctx_r2.emojiSheetSize)("backgroundImageFn", ctx_r2.emojiBackgroundImageFn)("imageUrlFn", ctx_r2.emojiImageUrlFn);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r2.emojiData.name);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx_r2.emojiData.shortNames);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx_r2.listedEmoticons);
  }
}
function PreviewComponent_ngx_emoji_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "ngx-emoji", 16);
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("isNative", ctx_r2.emojiIsNative)("skin", ctx_r2.emojiSkin)("set", ctx_r2.emojiSet)("emoji", ctx_r2.idleEmoji)("backgroundImageFn", ctx_r2.emojiBackgroundImageFn)("size", 38)("imageUrlFn", ctx_r2.emojiImageUrlFn);
  }
}
const _c2 = ["inputRef"];
const _c3 = ["scrollRef"];
function PickerComponent_emoji_search_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "emoji-search", 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("searchResults", function PickerComponent_emoji_search_3_Template_emoji_search_searchResults_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleSearch($event));
    })("enterKeyOutsideAngular", function PickerComponent_emoji_search_3_Template_emoji_search_enterKeyOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleEnterKey($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("i18n", ctx_r2.i18n)("include", ctx_r2.include)("exclude", ctx_r2.exclude)("custom", ctx_r2.custom)("autoFocus", ctx_r2.autoFocus)("icons", ctx_r2.searchIcons)("emojisToShowFilter", ctx_r2.emojisToShowFilter);
  }
}
function PickerComponent_emoji_category_6_Template(rf, ctx) {
  if (rf & 1) {
    const _r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "emoji-category", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("emojiOverOutsideAngular", function PickerComponent_emoji_category_6_Template_emoji_category_emojiOverOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleEmojiOver($event));
    })("emojiLeaveOutsideAngular", function PickerComponent_emoji_category_6_Template_emoji_category_emojiLeaveOutsideAngular_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleEmojiLeave());
    })("emojiClickOutsideAngular", function PickerComponent_emoji_category_6_Template_emoji_category_emojiClickOutsideAngular_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleEmojiClick($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const category_r5 = ctx.$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", category_r5.id)("name", category_r5.name)("emojis", category_r5.emojis)("perLine", ctx_r2.perLine)("totalFrequentLines", ctx_r2.totalFrequentLines)("hasStickyPosition", ctx_r2.isNative)("i18n", ctx_r2.i18n)("hideObsolete", ctx_r2.hideObsolete)("notFoundEmoji", ctx_r2.notFoundEmoji)("custom", category_r5.id === ctx_r2.RECENT_CATEGORY.id ? ctx_r2.CUSTOM_CATEGORY.emojis : undefined)("recent", category_r5.id === ctx_r2.RECENT_CATEGORY.id ? ctx_r2.recent : undefined)("virtualize", ctx_r2.virtualize)("virtualizeOffset", ctx_r2.virtualizeOffset)("emojiIsNative", ctx_r2.isNative)("emojiSkin", ctx_r2.skin)("emojiSize", ctx_r2.emojiSize)("emojiSet", ctx_r2.set)("emojiSheetSize", ctx_r2.sheetSize)("emojiForceSize", ctx_r2.isNative)("emojiTooltip", ctx_r2.emojiTooltip)("emojiBackgroundImageFn", ctx_r2.backgroundImageFn)("emojiImageUrlFn", ctx_r2.imageUrlFn)("emojiUseButton", ctx_r2.useButton);
  }
}
function PickerComponent_div_7_Template(rf, ctx) {
  if (rf & 1) {
    const _r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 2)(1, "emoji-preview", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("skinChange", function PickerComponent_div_7_Template_emoji_preview_skinChange_1_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.handleSkinChange($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("emoji", ctx_r2.previewEmoji)("idleEmoji", ctx_r2.emoji)("emojiIsNative", ctx_r2.isNative)("emojiSize", 38)("emojiSkin", ctx_r2.skin)("emojiSet", ctx_r2.set)("i18n", ctx_r2.i18n)("emojiSheetSize", ctx_r2.sheetSize)("emojiBackgroundImageFn", ctx_r2.backgroundImageFn)("emojiImageUrlFn", ctx_r2.imageUrlFn);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("title", ctx_r2.title);
  }
}
class AnchorsComponent {
  categories = [];
  color;
  selected;
  i18n;
  icons = {};
  anchorClick = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  trackByFn(idx, cat) {
    return cat.id;
  }
  handleClick($event, index) {
    this.anchorClick.emit({
      category: this.categories[index],
      index
    });
  }
  static ɵfac = function AnchorsComponent_Factory(t) {
    return new (t || AnchorsComponent)();
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: AnchorsComponent,
    selectors: [["emoji-mart-anchors"]],
    inputs: {
      categories: "categories",
      color: "color",
      selected: "selected",
      i18n: "i18n",
      icons: "icons"
    },
    outputs: {
      anchorClick: "anchorClick"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 2,
    vars: 2,
    consts: [[1, "emoji-mart-anchors"], ["ngFor", "", 3, "ngForOf", "ngForTrackBy"], ["class", "emoji-mart-anchor", 3, "emoji-mart-anchor-selected", "color", "click", 4, "ngIf"], [1, "emoji-mart-anchor", 3, "click"], ["xmlns", "http://www.w3.org/2000/svg", "viewBox", "0 0 24 24", "width", "24", "height", "24"], [1, "emoji-mart-anchor-bar"]],
    template: function AnchorsComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, AnchorsComponent_ng_template_1_Template, 1, 1, "ng-template", 1);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx.categories)("ngForTrackBy", ctx.trackByFn);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgIf],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AnchorsComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-mart-anchors',
      template: `
    <div class="emoji-mart-anchors">
      <ng-template
        ngFor
        let-category
        [ngForOf]="categories"
        let-idx="index"
        [ngForTrackBy]="trackByFn"
      >
        <span
          *ngIf="category.anchor !== false"
          [attr.title]="i18n.categories[category.id]"
          (click)="this.handleClick($event, idx)"
          class="emoji-mart-anchor"
          [class.emoji-mart-anchor-selected]="category.name === selected"
          [style.color]="category.name === selected ? color : null"
        >
          <div>
            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
              <path [attr.d]="icons[category.id]" />
            </svg>
          </div>
          <span class="emoji-mart-anchor-bar" [style.background-color]="color"></span>
        </span>
      </ng-template>
    </div>
  `,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule]
    }]
  }], null, {
    categories: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    color: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selected: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    icons: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    anchorClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class EmojiFrequentlyService {
  platformId;
  NAMESPACE = 'emoji-mart';
  frequently = null;
  defaults = {};
  initialized = false;
  DEFAULTS = ['+1', 'grinning', 'kissing_heart', 'heart_eyes', 'laughing', 'stuck_out_tongue_winking_eye', 'sweat_smile', 'joy', 'scream', 'disappointed', 'unamused', 'weary', 'sob', 'sunglasses', 'heart', 'poop'];
  constructor(platformId) {
    this.platformId = platformId;
  }
  init() {
    this.frequently = JSON.parse((0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformBrowser)(this.platformId) && localStorage.getItem(`${this.NAMESPACE}.frequently`) || 'null');
    this.initialized = true;
  }
  add(emoji) {
    if (!this.initialized) {
      this.init();
    }
    if (!this.frequently) {
      this.frequently = this.defaults;
    }
    if (!this.frequently[emoji.id]) {
      this.frequently[emoji.id] = 0;
    }
    this.frequently[emoji.id] += 1;
    if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformBrowser)(this.platformId)) {
      localStorage.setItem(`${this.NAMESPACE}.last`, emoji.id);
      localStorage.setItem(`${this.NAMESPACE}.frequently`, JSON.stringify(this.frequently));
    }
  }
  get(perLine, totalLines) {
    if (!this.initialized) {
      this.init();
    }
    if (this.frequently === null) {
      this.defaults = {};
      const result = [];
      for (let i = 0; i < perLine; i++) {
        this.defaults[this.DEFAULTS[i]] = perLine - i;
        result.push(this.DEFAULTS[i]);
      }
      return result;
    }
    const quantity = perLine * totalLines;
    const frequentlyKeys = Object.keys(this.frequently);
    const sorted = frequentlyKeys.sort((a, b) => this.frequently[a] - this.frequently[b]).reverse();
    const sliced = sorted.slice(0, quantity);
    const last = (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformBrowser)(this.platformId) && localStorage.getItem(`${this.NAMESPACE}.last`);
    if (last && !sliced.includes(last)) {
      sliced.pop();
      sliced.push(last);
    }
    return sliced;
  }
  static ɵfac = function EmojiFrequentlyService_Factory(t) {
    return new (t || EmojiFrequentlyService)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID));
  };
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
    token: EmojiFrequentlyService,
    factory: EmojiFrequentlyService.ɵfac,
    providedIn: 'root'
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmojiFrequentlyService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], function () {
    return [{
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID]
      }]
    }];
  }, null);
})();
class CategoryComponent {
  ref;
  emojiService;
  frequently;
  emojis = null;
  hasStickyPosition = true;
  name = '';
  perLine = 9;
  totalFrequentLines = 4;
  recent = [];
  custom = [];
  i18n;
  id;
  hideObsolete = true;
  notFoundEmoji;
  virtualize = false;
  virtualizeOffset = 0;
  emojiIsNative;
  emojiSkin;
  emojiSize;
  emojiSet;
  emojiSheetSize;
  emojiForceSize;
  emojiTooltip;
  emojiBackgroundImageFn;
  emojiImageUrlFn;
  emojiUseButton;
  /**
   * Note: the suffix is added explicitly so we know the event is dispatched outside of the Angular zone.
   */
  emojiOverOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiLeaveOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiClickOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  container;
  label;
  containerStyles = {};
  emojisToDisplay = [];
  filteredEmojisSubject = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
  filteredEmojis$ = this.filteredEmojisSubject.asObservable();
  labelStyles = {};
  labelSpanStyles = {};
  margin = 0;
  minMargin = 0;
  maxMargin = 0;
  top = 0;
  rows = 0;
  constructor(ref, emojiService, frequently) {
    this.ref = ref;
    this.emojiService = emojiService;
    this.frequently = frequently;
  }
  ngOnInit() {
    this.updateRecentEmojis();
    this.emojisToDisplay = this.filterEmojis();
    if (this.noEmojiToDisplay) {
      this.containerStyles = {
        display: 'none'
      };
    }
    if (!this.hasStickyPosition) {
      this.labelStyles = {
        height: 28
      };
      // this.labelSpanStyles = { position: 'absolute' };
    }
  }
  ngOnChanges(changes) {
    if (changes.emojis?.currentValue?.length !== changes.emojis?.previousValue?.length) {
      this.emojisToDisplay = this.filterEmojis();
      this.ngAfterViewInit();
    }
  }
  ngAfterViewInit() {
    if (!this.virtualize) {
      return;
    }
    const {
      width
    } = this.container.nativeElement.getBoundingClientRect();
    const perRow = Math.floor(width / (this.emojiSize + 12));
    this.rows = Math.ceil(this.emojisToDisplay.length / perRow);
    this.containerStyles = {
      ...this.containerStyles,
      minHeight: `${this.rows * (this.emojiSize + 12) + 28}px`
    };
    this.ref.detectChanges();
    this.handleScroll(this.container.nativeElement.parentNode.parentNode.scrollTop);
  }
  get noEmojiToDisplay() {
    return this.emojisToDisplay.length === 0;
  }
  memoizeSize() {
    const parent = this.container.nativeElement.parentNode.parentNode;
    const {
      top,
      height
    } = this.container.nativeElement.getBoundingClientRect();
    const parentTop = parent.getBoundingClientRect().top;
    const labelHeight = this.label.nativeElement.getBoundingClientRect().height;
    this.top = top - parentTop + parent.scrollTop;
    if (height === 0) {
      this.maxMargin = 0;
    } else {
      this.maxMargin = height - labelHeight;
    }
  }
  handleScroll(scrollTop) {
    let margin = scrollTop - this.top;
    margin = margin < this.minMargin ? this.minMargin : margin;
    margin = margin > this.maxMargin ? this.maxMargin : margin;
    if (this.virtualize) {
      const {
        top,
        height
      } = this.container.nativeElement.getBoundingClientRect();
      const parentHeight = this.container.nativeElement.parentNode.parentNode.clientHeight;
      if (parentHeight + (parentHeight + this.virtualizeOffset) >= top && -height - (parentHeight + this.virtualizeOffset) <= top) {
        this.filteredEmojisSubject.next(this.emojisToDisplay);
      } else {
        this.filteredEmojisSubject.next([]);
      }
    }
    if (margin === this.margin) {
      this.ref.detectChanges();
      return false;
    }
    if (!this.hasStickyPosition) {
      this.label.nativeElement.style.top = `${margin}px`;
    }
    this.margin = margin;
    this.ref.detectChanges();
    return true;
  }
  updateRecentEmojis() {
    if (this.name !== 'Recent') {
      return;
    }
    let frequentlyUsed = this.recent || this.frequently.get(this.perLine, this.totalFrequentLines);
    if (!frequentlyUsed || !frequentlyUsed.length) {
      frequentlyUsed = this.frequently.get(this.perLine, this.totalFrequentLines);
    }
    if (!frequentlyUsed.length) {
      return;
    }
    this.emojis = frequentlyUsed.map(id => {
      const emoji = this.custom.filter(e => e.id === id)[0];
      if (emoji) {
        return emoji;
      }
      return id;
    }).filter(id => !!this.emojiService.getData(id));
  }
  updateDisplay(display) {
    this.containerStyles.display = display;
    this.updateRecentEmojis();
    this.ref.detectChanges();
  }
  trackById(index, item) {
    return item;
  }
  filterEmojis() {
    const newEmojis = [];
    for (const emoji of this.emojis || []) {
      if (!emoji) {
        continue;
      }
      const data = this.emojiService.getData(emoji);
      if (!data || data.obsoletedBy && this.hideObsolete || !data.unified && !data.custom) {
        continue;
      }
      newEmojis.push(emoji);
    }
    return newEmojis;
  }
  static ɵfac = function CategoryComponent_Factory(t) {
    return new (t || CategoryComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](EmojiFrequentlyService));
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: CategoryComponent,
    selectors: [["emoji-category"]],
    viewQuery: function CategoryComponent_Query(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c1, 7);
      }
      if (rf & 2) {
        let _t;
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.container = _t.first);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.label = _t.first);
      }
    },
    inputs: {
      emojis: "emojis",
      hasStickyPosition: "hasStickyPosition",
      name: "name",
      perLine: "perLine",
      totalFrequentLines: "totalFrequentLines",
      recent: "recent",
      custom: "custom",
      i18n: "i18n",
      id: "id",
      hideObsolete: "hideObsolete",
      notFoundEmoji: "notFoundEmoji",
      virtualize: "virtualize",
      virtualizeOffset: "virtualizeOffset",
      emojiIsNative: "emojiIsNative",
      emojiSkin: "emojiSkin",
      emojiSize: "emojiSize",
      emojiSet: "emojiSet",
      emojiSheetSize: "emojiSheetSize",
      emojiForceSize: "emojiForceSize",
      emojiTooltip: "emojiTooltip",
      emojiBackgroundImageFn: "emojiBackgroundImageFn",
      emojiImageUrlFn: "emojiImageUrlFn",
      emojiUseButton: "emojiUseButton"
    },
    outputs: {
      emojiOverOutsideAngular: "emojiOverOutsideAngular",
      emojiLeaveOutsideAngular: "emojiLeaveOutsideAngular",
      emojiClickOutsideAngular: "emojiClickOutsideAngular"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 10,
    vars: 11,
    consts: [["container", ""], ["label", ""], ["normalRenderTemplate", ""], [1, "emoji-mart-category", 3, "ngStyle"], [1, "emoji-mart-category-label", 3, "ngStyle"], ["aria-hidden", "true", 3, "ngStyle"], [4, "ngIf", "ngIfElse"], [4, "ngIf"], [3, "emoji", "size", "skin", "isNative", "set", "sheetSize", "forceSize", "tooltip", "backgroundImageFn", "imageUrlFn", "hideObsolete", "useButton", "emojiOverOutsideAngular", "emojiLeaveOutsideAngular", "emojiClickOutsideAngular", 4, "ngFor", "ngForOf", "ngForTrackBy"], [3, "emojiOverOutsideAngular", "emojiLeaveOutsideAngular", "emojiClickOutsideAngular", "emoji", "size", "skin", "isNative", "set", "sheetSize", "forceSize", "tooltip", "backgroundImageFn", "imageUrlFn", "hideObsolete", "useButton"], [3, "emoji", "size", "skin", "isNative", "set", "sheetSize", "forceSize", "tooltip", "backgroundImageFn", "useButton"], [1, "emoji-mart-no-results-label"]],
    template: function CategoryComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "section", 3, 0)(2, "div", 4)(3, "span", 5, 1);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](5);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](6, CategoryComponent_div_6_Template, 3, 3, "div", 6)(7, CategoryComponent_div_7_Template, 5, 11, "div", 7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](8, CategoryComponent_ng_template_8_Template, 1, 2, "ng-template", null, 2, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
      }
      if (rf & 2) {
        const normalRenderTemplate_r7 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](9);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("emoji-mart-no-results", ctx.noEmojiToDisplay);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx.containerStyles);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-label", ctx.i18n.categories[ctx.id]);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx.labelStyles);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("data-name", ctx.name);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx.labelSpanStyles);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx.i18n.categories[ctx.id], " ");
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.virtualize)("ngIfElse", normalRenderTemplate_r7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.noEmojiToDisplay);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgStyle, _angular_common__WEBPACK_IMPORTED_MODULE_1__.AsyncPipe, _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiComponent],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CategoryComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-category',
      template: `
    <section
      #container
      class="emoji-mart-category"
      [attr.aria-label]="i18n.categories[id]"
      [class.emoji-mart-no-results]="noEmojiToDisplay"
      [ngStyle]="containerStyles"
    >
      <div class="emoji-mart-category-label" [ngStyle]="labelStyles" [attr.data-name]="name">
        <!-- already labeled by the section aria-label -->
        <span #label [ngStyle]="labelSpanStyles" aria-hidden="true">
          {{ i18n.categories[id] }}
        </span>
      </div>

      <div *ngIf="virtualize; else normalRenderTemplate">
        <div *ngIf="filteredEmojis$ | async as filteredEmojis">
          <ngx-emoji
            *ngFor="let emoji of filteredEmojis; trackBy: trackById"
            [emoji]="emoji"
            [size]="emojiSize"
            [skin]="emojiSkin"
            [isNative]="emojiIsNative"
            [set]="emojiSet"
            [sheetSize]="emojiSheetSize"
            [forceSize]="emojiForceSize"
            [tooltip]="emojiTooltip"
            [backgroundImageFn]="emojiBackgroundImageFn"
            [imageUrlFn]="emojiImageUrlFn"
            [hideObsolete]="hideObsolete"
            [useButton]="emojiUseButton"
            (emojiOverOutsideAngular)="emojiOverOutsideAngular.emit($event)"
            (emojiLeaveOutsideAngular)="emojiLeaveOutsideAngular.emit($event)"
            (emojiClickOutsideAngular)="emojiClickOutsideAngular.emit($event)"
          ></ngx-emoji>
        </div>
      </div>

      <div *ngIf="noEmojiToDisplay">
        <div>
          <ngx-emoji
            [emoji]="notFoundEmoji"
            [size]="38"
            [skin]="emojiSkin"
            [isNative]="emojiIsNative"
            [set]="emojiSet"
            [sheetSize]="emojiSheetSize"
            [forceSize]="emojiForceSize"
            [tooltip]="emojiTooltip"
            [backgroundImageFn]="emojiBackgroundImageFn"
            [useButton]="emojiUseButton"
          ></ngx-emoji>
        </div>

        <div class="emoji-mart-no-results-label">
          {{ i18n.notfound }}
        </div>
      </div>
    </section>

    <ng-template #normalRenderTemplate>
      <ngx-emoji
        *ngFor="let emoji of emojisToDisplay; trackBy: trackById"
        [emoji]="emoji"
        [size]="emojiSize"
        [skin]="emojiSkin"
        [isNative]="emojiIsNative"
        [set]="emojiSet"
        [sheetSize]="emojiSheetSize"
        [forceSize]="emojiForceSize"
        [tooltip]="emojiTooltip"
        [backgroundImageFn]="emojiBackgroundImageFn"
        [imageUrlFn]="emojiImageUrlFn"
        [hideObsolete]="hideObsolete"
        [useButton]="emojiUseButton"
        (emojiOverOutsideAngular)="emojiOverOutsideAngular.emit($event)"
        (emojiLeaveOutsideAngular)="emojiLeaveOutsideAngular.emit($event)"
        (emojiClickOutsideAngular)="emojiClickOutsideAngular.emit($event)"
      ></ngx-emoji>
    </ng-template>
  `,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiComponent]
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
    }, {
      type: _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService
    }, {
      type: EmojiFrequentlyService
    }];
  }, {
    emojis: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hasStickyPosition: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    name: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    perLine: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    totalFrequentLines: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    recent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    custom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hideObsolete: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    notFoundEmoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualizeOffset: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiIsNative: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSkin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSet: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSheetSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiForceSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiTooltip: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiBackgroundImageFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiImageUrlFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiUseButton: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiOverOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiLeaveOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiClickOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['container', {
        static: true
      }]
    }],
    label: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['label', {
        static: true
      }]
    }]
  });
})();
function uniq(arr) {
  return arr.reduce((acc, item) => {
    if (!acc.includes(item)) {
      acc.push(item);
    }
    return acc;
  }, []);
}
function intersect(a, b) {
  const uniqA = uniq(a);
  const uniqB = uniq(b);
  return uniqA.filter(item => uniqB.indexOf(item) >= 0);
}
// https://github.com/sonicdoe/measure-scrollbar
function measureScrollbar() {
  if (typeof document === 'undefined') {
    return 0;
  }
  const div = document.createElement('div');
  div.style.width = '100px';
  div.style.height = '100px';
  div.style.overflow = 'scroll';
  div.style.position = 'absolute';
  div.style.top = '-9999px';
  document.body.appendChild(div);
  const scrollbarWidth = div.offsetWidth - div.clientWidth;
  document.body.removeChild(div);
  return scrollbarWidth;
}
class EmojiSearch {
  emojiService;
  originalPool = {};
  index = {};
  emojisList = {};
  emoticonsList = {};
  emojiSearch = {};
  constructor(emojiService) {
    this.emojiService = emojiService;
    for (const emojiData of this.emojiService.emojis) {
      const {
        shortNames,
        emoticons
      } = emojiData;
      const id = shortNames[0];
      for (const emoticon of emoticons) {
        if (this.emoticonsList[emoticon]) {
          continue;
        }
        this.emoticonsList[emoticon] = id;
      }
      this.emojisList[id] = this.emojiService.getSanitizedData(id);
      this.originalPool[id] = emojiData;
    }
  }
  addCustomToPool(custom, pool) {
    for (const emoji of custom) {
      const emojiId = emoji.id || emoji.shortNames[0];
      if (emojiId && !pool[emojiId]) {
        pool[emojiId] = this.emojiService.getData(emoji);
        this.emojisList[emojiId] = this.emojiService.getSanitizedData(emoji);
      }
    }
  }
  search(value, emojisToShowFilter, maxResults = 75, include = [], exclude = [], custom = []) {
    this.addCustomToPool(custom, this.originalPool);
    let results;
    let pool = this.originalPool;
    if (value.length) {
      if (value === '-' || value === '-1') {
        return [this.emojisList['-1']];
      }
      if (value === '+' || value === '+1') {
        return [this.emojisList['+1']];
      }
      let values = value.toLowerCase().split(/[\s|,|\-|_]+/);
      let allResults = [];
      if (values.length > 2) {
        values = [values[0], values[1]];
      }
      if (include.length || exclude.length) {
        pool = {};
        for (const category of _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.categories || []) {
          const isIncluded = include && include.length ? include.indexOf(category.id) > -1 : true;
          const isExcluded = exclude && exclude.length ? exclude.indexOf(category.id) > -1 : false;
          if (!isIncluded || isExcluded) {
            continue;
          }
          for (const emojiId of category.emojis || []) {
            // Need to make sure that pool gets keyed
            // with the correct id, which is why we call emojiService.getData below
            const emoji = this.emojiService.getData(emojiId);
            pool[emoji?.id ?? ''] = emoji;
          }
        }
        if (custom.length) {
          const customIsIncluded = include && include.length ? include.indexOf('custom') > -1 : true;
          const customIsExcluded = exclude && exclude.length ? exclude.indexOf('custom') > -1 : false;
          if (customIsIncluded && !customIsExcluded) {
            this.addCustomToPool(custom, pool);
          }
        }
      }
      allResults = values.map(v => {
        let aPool = pool;
        let aIndex = this.index;
        let length = 0;
        for (let charIndex = 0; charIndex < v.length; charIndex++) {
          const char = v[charIndex];
          length++;
          if (!aIndex[char]) {
            aIndex[char] = {};
          }
          aIndex = aIndex[char];
          if (!aIndex.results) {
            const scores = {};
            aIndex.results = [];
            aIndex.pool = {};
            for (const id of Object.keys(aPool)) {
              const emoji = aPool[id];
              if (!this.emojiSearch[id]) {
                this.emojiSearch[id] = this.buildSearch(emoji.short_names, emoji.name, emoji.id, emoji.keywords, emoji.emoticons);
              }
              const query = this.emojiSearch[id];
              const sub = v.substr(0, length);
              const subIndex = query.indexOf(sub);
              if (subIndex !== -1) {
                let score = subIndex + 1;
                if (sub === id) {
                  score = 0;
                }
                aIndex.results.push(this.emojisList[id]);
                aIndex.pool[id] = emoji;
                scores[id] = score;
              }
            }
            aIndex.results.sort((a, b) => {
              const aScore = scores[a.id];
              const bScore = scores[b.id];
              return aScore - bScore;
            });
          }
          aPool = aIndex.pool;
        }
        return aIndex.results;
      }).filter(a => a);
      if (allResults.length > 1) {
        results = intersect.apply(null, allResults);
      } else if (allResults.length) {
        results = allResults[0];
      } else {
        results = [];
      }
    }
    if (results) {
      if (emojisToShowFilter) {
        results = results.filter(result => {
          if (result && result.id) {
            return emojisToShowFilter(this.emojiService.names[result.id]);
          }
          return false;
        });
      }
      if (results && results.length > maxResults) {
        results = results.slice(0, maxResults);
      }
    }
    return results || null;
  }
  buildSearch(shortNames, name, id, keywords, emoticons) {
    const search = [];
    const addToSearch = (strings, split) => {
      if (!strings) {
        return;
      }
      const arr = Array.isArray(strings) ? strings : [strings];
      for (const str of arr) {
        const substrings = split ? str.split(/[-|_|\s]+/) : [str];
        for (let s of substrings) {
          s = s.toLowerCase();
          if (!search.includes(s)) {
            search.push(s);
          }
        }
      }
    };
    addToSearch(shortNames, true);
    addToSearch(name, true);
    addToSearch(id, true);
    addToSearch(keywords, true);
    addToSearch(emoticons, false);
    return search.join(',');
  }
  static ɵfac = function EmojiSearch_Factory(t) {
    return new (t || EmojiSearch)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService));
  };
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
    token: EmojiSearch,
    factory: EmojiSearch.ɵfac,
    providedIn: 'root'
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EmojiSearch, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], function () {
    return [{
      type: _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService
    }];
  }, null);
})();
class SkinComponent {
  /** currently selected skin */
  skin;
  i18n;
  changeSkin = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  opened = false;
  skinTones = [1, 2, 3, 4, 5, 6];
  toggleOpen() {
    this.opened = !this.opened;
  }
  isSelected(skinTone) {
    return skinTone === this.skin;
  }
  isVisible(skinTone) {
    return this.opened || this.isSelected(skinTone);
  }
  pressed(skinTone) {
    return this.opened ? !!this.isSelected(skinTone) : '';
  }
  tabIndex(skinTone) {
    return this.isVisible(skinTone) ? '0' : '';
  }
  expanded(skinTone) {
    return this.isSelected(skinTone) ? this.opened : '';
  }
  handleClick(skin) {
    if (!this.opened) {
      this.opened = true;
      return;
    }
    this.opened = false;
    if (skin !== this.skin) {
      this.changeSkin.emit(skin);
    }
  }
  static ɵfac = function SkinComponent_Factory(t) {
    return new (t || SkinComponent)();
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: SkinComponent,
    selectors: [["emoji-skins"]],
    inputs: {
      skin: "skin",
      i18n: "i18n"
    },
    outputs: {
      changeSkin: "changeSkin"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 2,
    vars: 3,
    consts: [[1, "emoji-mart-skin-swatches"], ["class", "emoji-mart-skin-swatch", 3, "selected", 4, "ngFor", "ngForOf"], [1, "emoji-mart-skin-swatch"], ["role", "button", 3, "click", "keyup.enter", "keyup.space", "tabIndex"]],
    template: function SkinComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "section", 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, SkinComponent_span_1_Template, 2, 12, "span", 1);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("opened", ctx.opened);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx.skinTones);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SkinComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-skins',
      template: `
    <section class="emoji-mart-skin-swatches" [class.opened]="opened">
      <span
        *ngFor="let skinTone of skinTones"
        class="emoji-mart-skin-swatch"
        [class.selected]="skinTone === skin"
      >
        <span
          (click)="handleClick(skinTone)"
          (keyup.enter)="handleClick(skinTone)"
          (keyup.space)="handleClick(skinTone)"
          class="emoji-mart-skin emoji-mart-skin-tone-{{ skinTone }}"
          role="button"
          [tabIndex]="tabIndex(skinTone)"
          [attr.aria-hidden]="!isVisible(skinTone)"
          [attr.aria-pressed]="pressed(skinTone)"
          [attr.aria-haspopup]="!!isSelected(skinTone)"
          [attr.aria-expanded]="expanded(skinTone)"
          [attr.aria-label]="i18n.skintones[skinTone]"
          [attr.title]="i18n.skintones[skinTone]"
        ></span>
      </span>
    </section>
  `,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule]
    }]
  }], null, {
    skin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    changeSkin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class PreviewComponent {
  ref;
  emojiService;
  title;
  emoji;
  idleEmoji;
  i18n;
  emojiIsNative;
  emojiSkin;
  emojiSize;
  emojiSet;
  emojiSheetSize;
  emojiBackgroundImageFn;
  emojiImageUrlFn;
  skinChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiData = {};
  listedEmoticons;
  constructor(ref, emojiService) {
    this.ref = ref;
    this.emojiService = emojiService;
  }
  ngOnChanges() {
    if (!this.emoji) {
      return;
    }
    this.emojiData = this.emojiService.getData(this.emoji, this.emojiSkin, this.emojiSet);
    const knownEmoticons = [];
    const listedEmoticons = [];
    const emoitcons = this.emojiData.emoticons || [];
    emoitcons.forEach(emoticon => {
      if (knownEmoticons.indexOf(emoticon.toLowerCase()) >= 0) {
        return;
      }
      knownEmoticons.push(emoticon.toLowerCase());
      listedEmoticons.push(emoticon);
    });
    this.listedEmoticons = listedEmoticons;
    this.ref?.detectChanges();
  }
  static ɵfac = function PreviewComponent_Factory(t) {
    return new (t || PreviewComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService));
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: PreviewComponent,
    selectors: [["emoji-preview"]],
    inputs: {
      title: "title",
      emoji: "emoji",
      idleEmoji: "idleEmoji",
      i18n: "i18n",
      emojiIsNative: "emojiIsNative",
      emojiSkin: "emojiSkin",
      emojiSize: "emojiSize",
      emojiSet: "emojiSet",
      emojiSheetSize: "emojiSheetSize",
      emojiBackgroundImageFn: "emojiBackgroundImageFn",
      emojiImageUrlFn: "emojiImageUrlFn"
    },
    outputs: {
      skinChange: "skinChange"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 9,
    vars: 6,
    consts: [["class", "emoji-mart-preview", 4, "ngIf"], [1, "emoji-mart-preview", 3, "hidden"], [1, "emoji-mart-preview-emoji"], [3, "isNative", "skin", "set", "emoji", "backgroundImageFn", "size", "imageUrlFn", 4, "ngIf"], [1, "emoji-mart-preview-data"], [1, "emoji-mart-title-label"], [1, "emoji-mart-preview-skins"], [3, "changeSkin", "skin", "i18n"], [1, "emoji-mart-preview"], [3, "emoji", "size", "isNative", "skin", "set", "sheetSize", "backgroundImageFn", "imageUrlFn"], [1, "emoji-mart-preview-name"], [1, "emoji-mart-preview-shortname"], ["class", "emoji-mart-preview-shortname", 4, "ngFor", "ngForOf"], [1, "emoji-mart-preview-emoticons"], ["class", "emoji-mart-preview-emoticon", 4, "ngFor", "ngForOf"], [1, "emoji-mart-preview-emoticon"], [3, "isNative", "skin", "set", "emoji", "backgroundImageFn", "size", "imageUrlFn"]],
    template: function PreviewComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, PreviewComponent_div_0_Template, 10, 12, "div", 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 1)(2, "div", 2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, PreviewComponent_ngx_emoji_3_Template, 1, 7, "ngx-emoji", 3);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "div", 4)(5, "span", 5);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](6);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](7, "div", 6)(8, "emoji-skins", 7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("changeSkin", function PreviewComponent_Template_emoji_skins_changeSkin_8_listener($event) {
          return ctx.skinChange.emit($event);
        });
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()()();
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.emoji && ctx.emojiData);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("hidden", ctx.emoji);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.idleEmoji && ctx.idleEmoji.length);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx.title);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("skin", ctx.emojiSkin)("i18n", ctx.i18n);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgIf, _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiComponent, SkinComponent],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PreviewComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-preview',
      template: `
    <div class="emoji-mart-preview" *ngIf="emoji && emojiData">
      <div class="emoji-mart-preview-emoji">
        <ngx-emoji
          [emoji]="emoji"
          [size]="38"
          [isNative]="emojiIsNative"
          [skin]="emojiSkin"
          [size]="emojiSize"
          [set]="emojiSet"
          [sheetSize]="emojiSheetSize"
          [backgroundImageFn]="emojiBackgroundImageFn"
          [imageUrlFn]="emojiImageUrlFn"
        ></ngx-emoji>
      </div>

      <div class="emoji-mart-preview-data">
        <div class="emoji-mart-preview-name">{{ emojiData.name }}</div>
        <div class="emoji-mart-preview-shortname">
          <span
            class="emoji-mart-preview-shortname"
            *ngFor="let short_name of emojiData.shortNames"
          >
            :{{ short_name }}:
          </span>
        </div>
        <div class="emoji-mart-preview-emoticons">
          <span class="emoji-mart-preview-emoticon" *ngFor="let emoticon of listedEmoticons">
            {{ emoticon }}
          </span>
        </div>
      </div>
    </div>

    <div class="emoji-mart-preview" [hidden]="emoji">
      <div class="emoji-mart-preview-emoji">
        <ngx-emoji
          *ngIf="idleEmoji && idleEmoji.length"
          [isNative]="emojiIsNative"
          [skin]="emojiSkin"
          [set]="emojiSet"
          [emoji]="idleEmoji"
          [backgroundImageFn]="emojiBackgroundImageFn"
          [size]="38"
          [imageUrlFn]="emojiImageUrlFn"
        ></ngx-emoji>
      </div>

      <div class="emoji-mart-preview-data">
        <span class="emoji-mart-title-label">{{ title }}</span>
      </div>

      <div class="emoji-mart-preview-skins">
        <emoji-skins
          [skin]="emojiSkin"
          (changeSkin)="skinChange.emit($event)"
          [i18n]="i18n"
        ></emoji-skins>
      </div>
    </div>
  `,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiComponent, SkinComponent]
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
    }, {
      type: _ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.EmojiService
    }];
  }, {
    title: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    idleEmoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiIsNative: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSkin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSet: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSheetSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiBackgroundImageFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiImageUrlFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    skinChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
let id = 0;
class SearchComponent {
  ngZone;
  emojiSearch;
  maxResults = 75;
  autoFocus = false;
  i18n;
  include = [];
  exclude = [];
  custom = [];
  icons;
  emojisToShowFilter;
  searchResults = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  enterKeyOutsideAngular = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  inputRef;
  isSearching = false;
  icon;
  query = '';
  inputId = `emoji-mart-search-${++id}`;
  destroy$ = new rxjs__WEBPACK_IMPORTED_MODULE_2__.Subject();
  constructor(ngZone, emojiSearch) {
    this.ngZone = ngZone;
    this.emojiSearch = emojiSearch;
  }
  ngOnInit() {
    this.icon = this.icons.search;
    this.setupKeyupListener();
  }
  ngAfterViewInit() {
    if (this.autoFocus) {
      this.inputRef.nativeElement.focus();
    }
  }
  ngOnDestroy() {
    this.destroy$.next();
  }
  clear() {
    this.query = '';
    this.handleSearch('');
    this.inputRef.nativeElement.focus();
  }
  handleSearch(value) {
    if (value === '') {
      this.icon = this.icons.search;
      this.isSearching = false;
    } else {
      this.icon = this.icons.delete;
      this.isSearching = true;
    }
    const emojis = this.emojiSearch.search(this.query, this.emojisToShowFilter, this.maxResults, this.include, this.exclude, this.custom);
    this.searchResults.emit(emojis);
  }
  handleChange() {
    this.handleSearch(this.query);
  }
  setupKeyupListener() {
    this.ngZone.runOutsideAngular(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.fromEvent)(this.inputRef.nativeElement, 'keyup').pipe((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this.destroy$)).subscribe($event => {
      if (!this.query || $event.key !== 'Enter') {
        return;
      }
      this.enterKeyOutsideAngular.emit($event);
      $event.preventDefault();
    }));
  }
  static ɵfac = function SearchComponent_Factory(t) {
    return new (t || SearchComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](EmojiSearch));
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: SearchComponent,
    selectors: [["emoji-search"]],
    viewQuery: function SearchComponent_Query(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c2, 7);
      }
      if (rf & 2) {
        let _t;
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.inputRef = _t.first);
      }
    },
    inputs: {
      maxResults: "maxResults",
      autoFocus: "autoFocus",
      i18n: "i18n",
      include: "include",
      exclude: "exclude",
      custom: "custom",
      icons: "icons",
      emojisToShowFilter: "emojisToShowFilter"
    },
    outputs: {
      searchResults: "searchResults",
      enterKeyOutsideAngular: "enterKeyOutsideAngular"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 8,
    vars: 9,
    consts: [["inputRef", ""], [1, "emoji-mart-search"], ["type", "search", 3, "ngModelChange", "id", "placeholder", "autofocus", "ngModel"], [1, "emoji-mart-sr-only", 3, "htmlFor"], ["type", "button", 1, "emoji-mart-search-icon", 3, "click", "keyup.enter", "disabled"], ["xmlns", "http://www.w3.org/2000/svg", "viewBox", "0 0 20 20", "width", "13", "height", "13", "opacity", "0.5"]],
    template: function SearchComponent_Template(rf, ctx) {
      if (rf & 1) {
        const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 1)(1, "input", 2, 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtwoWayListener"]("ngModelChange", function SearchComponent_Template_input_ngModelChange_1_listener($event) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtwoWayBindingSet"](ctx.query, $event) || (ctx.query = $event);
          return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event);
        });
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("ngModelChange", function SearchComponent_Template_input_ngModelChange_1_listener() {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
          return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.handleChange());
        });
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](3, "label", 3);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](4);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](5, "button", 4);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function SearchComponent_Template_button_click_5_listener() {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
          return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.clear());
        })("keyup.enter", function SearchComponent_Template_button_keyup_enter_5_listener() {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
          return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.clear());
        });
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnamespaceSVG"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "svg", 5);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](7, "path");
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()()();
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", ctx.inputId)("placeholder", ctx.i18n.search)("autofocus", ctx.autoFocus);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtwoWayProperty"]("ngModel", ctx.query);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("htmlFor", ctx.inputId);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx.i18n.search, " ");
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", !ctx.isSearching);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-label", ctx.i18n.clear);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("d", ctx.icon);
      }
    },
    dependencies: [_angular_forms__WEBPACK_IMPORTED_MODULE_6__.FormsModule, _angular_forms__WEBPACK_IMPORTED_MODULE_6__.DefaultValueAccessor, _angular_forms__WEBPACK_IMPORTED_MODULE_6__.NgControlStatus, _angular_forms__WEBPACK_IMPORTED_MODULE_6__.NgModel],
    encapsulation: 2
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SearchComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-search',
      template: `
    <div class="emoji-mart-search">
      <input
        [id]="inputId"
        #inputRef
        type="search"
        [placeholder]="i18n.search"
        [autofocus]="autoFocus"
        [(ngModel)]="query"
        (ngModelChange)="handleChange()"
      />
      <!--
      Use a <label> in addition to the placeholder for accessibility, but place it off-screen
      http://www.maxability.co.in/2016/01/placeholder-attribute-and-why-it-is-not-accessible/
      -->
      <label class="emoji-mart-sr-only" [htmlFor]="inputId">
        {{ i18n.search }}
      </label>
      <button
        type="button"
        class="emoji-mart-search-icon"
        (click)="clear()"
        (keyup.enter)="clear()"
        [disabled]="!isSearching"
        [attr.aria-label]="i18n.clear"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 20 20"
          width="13"
          height="13"
          opacity="0.5"
        >
          <path [attr.d]="icon" />
        </svg>
      </button>
    </div>
  `,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_forms__WEBPACK_IMPORTED_MODULE_6__.FormsModule]
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
    }, {
      type: EmojiSearch
    }];
  }, {
    maxResults: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    autoFocus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    include: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    exclude: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    custom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    icons: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojisToShowFilter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    searchResults: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    enterKeyOutsideAngular: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    inputRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['inputRef', {
        static: true
      }]
    }]
  });
})();

/* eslint-disable  max-len */
const categories = {
  activity: `M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24m10 11h-5c.3-2.5 1.3-4.8 2-6.1a10 10 0 0 1 3 6.1m-9 0V2a10 10 0 0 1 4.4 1.6A18 18 0 0 0 15 11h-2zm-2 0H9a18 18 0 0 0-2.4-7.4A10 10 0 0 1 11 2.1V11zm0 2v9a10 10 0 0 1-4.4-1.6A18 18 0 0 0 9 13h2zm4 0a18 18 0 0 0 2.4 7.4 10 10 0 0 1-4.4 1.5V13h2zM5 4.9c.7 1.3 1.7 3.6 2 6.1H2a10 10 0 0 1 3-6.1M2 13h5c-.3 2.5-1.3 4.8-2 6.1A10 10 0 0 1 2 13m17 6.1c-.7-1.3-1.7-3.6-2-6.1h5a10 10 0 0 1-3 6.1`,
  custom: `M10 1h3v21h-3zm10.186 4l1.5 2.598L3.5 18.098 2 15.5zM2 7.598L3.5 5l18.186 10.5-1.5 2.598z`,
  flags: `M0 0l6 24h2L2 0zm21 5h-4l-1-4H4l3 12h3l1 4h13L21 5zM6.6 3h7.8l2 8H8.6l-2-8zm8.8 10l-2.9 1.9-.4-1.9h3.3zm3.6 0l-1.5-6h2l2 8H16l3-2z`,
  foods: `M17 5c-1.8 0-2.9.4-3.7 1 .5-1.3 1.8-3 4.7-3a1 1 0 0 0 0-2c-3 0-4.6 1.3-5.5 2.5l-.2.2c-.6-1.9-1.5-3.7-3-3.7C8.5 0 7.7.3 7 1c-2 1.5-1.7 2.9-.5 4C3.6 5.2 0 7.4 0 13c0 4.6 5 11 9 11 2 0 2.4-.5 3-1 .6.5 1 1 3 1 4 0 9-6.4 9-11 0-6-4-8-7-8M8.2 2.5c.7-.5 1-.5 1-.5.4.2 1 1.4 1.4 3-1.6-.6-2.8-1.3-3-1.8l.6-.7M15 22c-1 0-1.2-.1-1.6-.4l-.1-.2a2 2 0 0 0-2.6 0l-.1.2c-.4.3-.5.4-1.6.4-2.8 0-7-5.4-7-9 0-6 4.5-6 5-6 2 0 2.5.4 3.4 1.2l.3.3a2 2 0 0 0 2.6 0l.3-.3c1-.8 1.5-1.2 3.4-1.2.5 0 5 .1 5 6 0 3.6-4.2 9-7 9`,
  nature: `M15.5 8a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m-7 0a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m10.43-8h-.02c-.97 0-2.14.79-3.02 1.5A13.88 13.88 0 0 0 12 .99c-1.28 0-2.62.13-3.87.51C7.24.8 6.07 0 5.09 0h-.02C3.35 0 .07 2.67 0 7.03c-.04 2.47.28 4.23 1.04 5 .26.27.88.69 1.3.9.19 3.17.92 5.23 2.53 6.37.9.64 2.19.95 3.2 1.1-.03.2-.07.4-.07.6 0 1.77 2.35 3 4 3s4-1.23 4-3c0-.2-.04-.4-.07-.59 2.57-.38 5.43-1.87 5.92-7.58.4-.22.89-.57 1.1-.8.77-.76 1.09-2.52 1.05-5C23.93 2.67 20.65 0 18.93 0M3.23 9.13c-.24.29-.84 1.16-.9 1.24A9.67 9.67 0 0 1 2 7.08c.05-3.28 2.48-4.97 3.1-5.03.25.02.72.27 1.26.65A7.95 7.95 0 0 0 4 7.82c-.14.55-.4.86-.79 1.31M12 22c-.9 0-1.95-.7-2-1 0-.65.47-1.24 1-1.6v.6a1 1 0 1 0 2 0v-.6c.52.36 1 .95 1 1.6-.05.3-1.1 1-2 1m3-3.48v.02a4.75 4.75 0 0 0-1.26-1.02c1.09-.52 2.24-1.33 2.24-2.22 0-1.84-1.78-2.2-3.98-2.2s-3.98.36-3.98 2.2c0 .89 1.15 1.7 2.24 2.22A4.8 4.8 0 0 0 9 18.54v-.03a6.1 6.1 0 0 1-2.97-.84c-1.3-.92-1.84-3.04-1.86-6.48l.03-.04c.5-.82 1.49-1.45 1.8-3.1C6 6 7.36 4.42 8.36 3.53c1.01-.35 2.2-.53 3.59-.53 1.45 0 2.68.2 3.73.57 1 .9 2.32 2.46 2.32 4.48.31 1.65 1.3 2.27 1.8 3.1l.1.18c-.06 5.97-1.95 7.01-4.9 7.19m6.63-8.2l-.11-.2a7.59 7.59 0 0 0-.74-.98 3.02 3.02 0 0 1-.79-1.32 7.93 7.93 0 0 0-2.35-5.12c.53-.38 1-.63 1.26-.65.64.07 3.05 1.77 3.1 5.03.02 1.81-.35 3.22-.37 3.24`,
  objects: `M12 0a9 9 0 0 0-5 16.5V21s2 3 5 3 5-3 5-3v-4.5A9 9 0 0 0 12 0zm0 2a7 7 0 1 1 0 14 7 7 0 0 1 0-14zM9 17.5a9 9 0 0 0 6 0v.8a7 7 0 0 1-3 .7 7 7 0 0 1-3-.7v-.8zm.2 3a8.9 8.9 0 0 0 2.8.5c1 0 1.9-.2 2.8-.5-.6.7-1.6 1.5-2.8 1.5-1.1 0-2.1-.8-2.8-1.5zm5.5-8.1c-.8 0-1.1-.8-1.5-1.8-.5-1-.7-1.5-1.2-1.5s-.8.5-1.3 1.5c-.4 1-.8 1.8-1.6 1.8h-.3c-.5-.2-.8-.7-1.3-1.8l-.2-1A3 3 0 0 0 7 9a1 1 0 0 1 0-2c1.7 0 2 1.4 2.2 2.1.5-1 1.3-2 2.8-2 1.5 0 2.3 1.1 2.7 2.1.2-.8.6-2.2 2.3-2.2a1 1 0 1 1 0 2c-.2 0-.3.5-.3.7a6.5 6.5 0 0 1-.3 1c-.5 1-.8 1.7-1.7 1.7`,
  people: `M12 0a12 12 0 1 0 0 24 12 12 0 0 0 0-24m0 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20M8 7a2 2 0 1 0 0 4 2 2 0 0 0 0-4m8 0a2 2 0 1 0 0 4 2 2 0 0 0 0-4m-.8 8c-.7 1.2-1.8 2-3.3 2-1.5 0-2.7-.8-3.4-2H15m3-2H6a6 6 0 1 0 12 0`,
  places: `M6.5 12a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5m0 3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5m11-3a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5m0 3c-.3 0-.5-.2-.5-.5s.2-.5.5-.5.5.2.5.5-.2.5-.5.5m5-5.5l-1-.4-.1-.1h.6c.6 0 1-.4 1-1 0-1-.9-2-2-2h-.6l-.8-1.7A3 3 0 0 0 16.8 2H7.2a3 3 0 0 0-2.8 2.3L3.6 6H3a2 2 0 0 0-2 2c0 .6.4 1 1 1h.6v.1l-1 .4a2 2 0 0 0-1.4 2l.7 7.6a1 1 0 0 0 1 .9H3v1c0 1.1.9 2 2 2h2a2 2 0 0 0 2-2v-1h6v1c0 1.1.9 2 2 2h2a2 2 0 0 0 2-2v-1h1.1a1 1 0 0 0 1-.9l.7-7.5a2 2 0 0 0-1.3-2.1M6.3 4.9c.1-.5.5-.9 1-.9h9.5c.4 0 .8.4 1 .9L19.2 9H4.7l1.6-4.1zM7 21H5v-1h2v1zm12 0h-2v-1h2v1zm2.2-3H2.8l-.7-6.6.9-.4h18l.9.4-.7 6.6z`,
  recent: `M13 4h-2v7H9v2h2v2h2v-2h4v-2h-4zm-1-4a12 12 0 1 0 0 24 12 12 0 0 0 0-24m0 22a10 10 0 1 1 0-20 10 10 0 0 1 0 20`,
  symbols: `M0 0h11v2H0zm4 11h3V6h4V4H0v2h4zm11.5 6a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5m0-2.99a.5.5 0 0 1 0 .99c-.28 0-.5-.22-.5-.5s.22-.49.5-.49m6 5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5m0 2.99a.5.5 0 0 1-.5-.5.5.5 0 0 1 1 .01.5.5 0 0 1-.5.49m.5-9l-9 9 1.51 1.5 9-9zm-5-2c2.2 0 4-1.12 4-2.5V2s.98-.16 1.5.95C23 4.05 23 6 23 6s1-1.12 1-3.13C24-.02 21 0 21 0h-2v6.35A5.85 5.85 0 0 0 17 6c-2.2 0-4 1.12-4 2.5s1.8 2.5 4 2.5m-6.7 9.48L8.82 18.9a47.54 47.54 0 0 1-1.44 1.13c-.3-.3-.99-1.02-2.04-2.19.9-.83 1.47-1.46 1.72-1.89s.38-.87.38-1.33c0-.6-.27-1.18-.82-1.76-.54-.58-1.33-.87-2.35-.87-1 0-1.79.29-2.34.87-.56.6-.83 1.18-.83 1.79 0 .81.42 1.75 1.25 2.8a6.57 6.57 0 0 0-1.8 1.79 3.46 3.46 0 0 0-.51 1.83c0 .86.3 1.56.92 2.1a3.5 3.5 0 0 0 2.42.83c1.17 0 2.44-.38 3.81-1.14L8.23 24h2.82l-2.09-2.38 1.34-1.14zM3.56 14.1a1.02 1.02 0 0 1 .73-.28c.31 0 .56.08.75.25a.85.85 0 0 1 .28.66c0 .52-.42 1.11-1.26 1.78-.53-.65-.8-1.23-.8-1.74a.9.9 0 0 1 .3-.67m.18 7.9c-.43 0-.78-.12-1.06-.35-.28-.23-.41-.49-.41-.76 0-.6.5-1.3 1.52-2.09a31.23 31.23 0 0 0 2.25 2.44c-.92.5-1.69.76-2.3.76`
};
const search = {
  search: `M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z`,
  delete: `M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z`
};
const I18N = {
  search: 'Search',
  emojilist: 'List of emoji',
  notfound: 'No Emoji Found',
  clear: 'Clear',
  categories: {
    search: 'Search Results',
    recent: 'Frequently Used',
    people: 'Smileys & People',
    nature: 'Animals & Nature',
    foods: 'Food & Drink',
    activity: 'Activity',
    places: 'Travel & Places',
    objects: 'Objects',
    symbols: 'Symbols',
    flags: 'Flags',
    custom: 'Custom'
  },
  skintones: {
    1: 'Default Skin Tone',
    2: 'Light Skin Tone',
    3: 'Medium-Light Skin Tone',
    4: 'Medium Skin Tone',
    5: 'Medium-Dark Skin Tone',
    6: 'Dark Skin Tone'
  }
};
class PickerComponent {
  ngZone;
  renderer;
  ref;
  frequently;
  platformId;
  perLine = 9;
  totalFrequentLines = 4;
  i18n = {};
  style = {};
  title = 'Emoji Mart™';
  emoji = 'department_store';
  darkMode = !!(typeof matchMedia === 'function' && matchMedia('(prefers-color-scheme: dark)').matches);
  color = '#ae65c5';
  hideObsolete = true;
  /** all categories shown */
  categories = [];
  /** used to temporarily draw categories */
  activeCategories = [];
  set = 'apple';
  skin = 1;
  /** Renders the native unicode emoji */
  isNative = false;
  emojiSize = 24;
  sheetSize = 64;
  emojisToShowFilter;
  showPreview = true;
  emojiTooltip = false;
  autoFocus = false;
  custom = [];
  hideRecent = true;
  imageUrlFn;
  include;
  exclude;
  notFoundEmoji = 'sleuth_or_spy';
  categoriesIcons = categories;
  searchIcons = search;
  useButton = false;
  enableFrequentEmojiSort = false;
  enableSearch = true;
  showSingleCategory = false;
  virtualize = false;
  virtualizeOffset = 0;
  recent;
  emojiClick = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  emojiSelect = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  skinChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  scrollRef;
  previewRef;
  searchRef;
  categoryRefs;
  scrollHeight = 0;
  clientHeight = 0;
  clientWidth = 0;
  selected;
  nextScroll;
  scrollTop;
  firstRender = true;
  previewEmoji = null;
  animationFrameRequestId = null;
  NAMESPACE = 'emoji-mart';
  measureScrollbar = 0;
  RECENT_CATEGORY = {
    id: 'recent',
    name: 'Recent',
    emojis: null
  };
  SEARCH_CATEGORY = {
    id: 'search',
    name: 'Search',
    emojis: null,
    anchor: false
  };
  CUSTOM_CATEGORY = {
    id: 'custom',
    name: 'Custom',
    emojis: []
  };
  scrollListener;
  backgroundImageFn = (set, sheetSize) => `https://cdn.jsdelivr.net/npm/emoji-datasource-${set}@14.0.0/img/${set}/sheets-256/${sheetSize}.png`;
  constructor(ngZone, renderer, ref, frequently, platformId) {
    this.ngZone = ngZone;
    this.renderer = renderer;
    this.ref = ref;
    this.frequently = frequently;
    this.platformId = platformId;
  }
  ngOnInit() {
    // measure scroll
    this.measureScrollbar = measureScrollbar();
    this.i18n = {
      ...I18N,
      ...this.i18n
    };
    this.i18n.categories = {
      ...I18N.categories,
      ...this.i18n.categories
    };
    this.skin = JSON.parse((0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformBrowser)(this.platformId) && localStorage.getItem(`${this.NAMESPACE}.skin`) || 'null') || this.skin;
    const allCategories = [..._ctrl_ngx_emoji_mart_ngx_emoji__WEBPACK_IMPORTED_MODULE_3__.categories];
    if (this.custom.length > 0) {
      this.CUSTOM_CATEGORY.emojis = this.custom.map(emoji => {
        return {
          ...emoji,
          // `<Category />` expects emoji to have an `id`.
          id: emoji.shortNames[0],
          custom: true
        };
      });
      allCategories.push(this.CUSTOM_CATEGORY);
    }
    if (this.include !== undefined) {
      allCategories.sort((a, b) => {
        if (this.include.indexOf(a.id) > this.include.indexOf(b.id)) {
          return 1;
        }
        return -1;
      });
    }
    for (const category of allCategories) {
      const isIncluded = this.include && this.include.length ? this.include.indexOf(category.id) > -1 : true;
      const isExcluded = this.exclude && this.exclude.length ? this.exclude.indexOf(category.id) > -1 : false;
      if (!isIncluded || isExcluded) {
        continue;
      }
      if (this.emojisToShowFilter) {
        const newEmojis = [];
        const {
          emojis
        } = category;
        for (let emojiIndex = 0; emojiIndex < emojis.length; emojiIndex++) {
          const emoji = emojis[emojiIndex];
          if (this.emojisToShowFilter(emoji)) {
            newEmojis.push(emoji);
          }
        }
        if (newEmojis.length) {
          const newCategory = {
            emojis: newEmojis,
            name: category.name,
            id: category.id
          };
          this.categories.push(newCategory);
        }
      } else {
        this.categories.push(category);
      }
      this.categoriesIcons = {
        ...categories,
        ...this.categoriesIcons
      };
      this.searchIcons = {
        ...search,
        ...this.searchIcons
      };
    }
    const includeRecent = this.include && this.include.length ? this.include.indexOf(this.RECENT_CATEGORY.id) > -1 : true;
    const excludeRecent = this.exclude && this.exclude.length ? this.exclude.indexOf(this.RECENT_CATEGORY.id) > -1 : false;
    if (includeRecent && !excludeRecent) {
      this.hideRecent = false;
      this.categories.unshift(this.RECENT_CATEGORY);
    }
    if (this.categories[0]) {
      this.categories[0].first = true;
    }
    this.categories.unshift(this.SEARCH_CATEGORY);
    this.selected = this.categories.filter(category => category.first)[0].name;
    // Need to be careful if small number of categories
    const categoriesToLoadFirst = Math.min(this.categories.length, 3);
    this.setActiveCategories(this.activeCategories = this.categories.slice(0, categoriesToLoadFirst));
    // Trim last active category
    const lastActiveCategoryEmojis = this.categories[categoriesToLoadFirst - 1].emojis.slice();
    this.categories[categoriesToLoadFirst - 1].emojis = lastActiveCategoryEmojis.slice(0, 60);
    setTimeout(() => {
      // Restore last category
      this.categories[categoriesToLoadFirst - 1].emojis = lastActiveCategoryEmojis;
      this.setActiveCategories(this.categories);
      // The `setTimeout` will trigger the change detection, but since we're inside
      // the OnPush component we can run change detection locally starting from this
      // component and going down to the children.
      this.ref.detectChanges();
      (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformBrowser)(this.platformId) && this.ngZone.runOutsideAngular(() => {
        // The `updateCategoriesSize` doesn't change properties that are used
        // in templates, thus this is run in the context of the root zone to avoid
        // running change detection.
        requestAnimationFrame(() => {
          this.updateCategoriesSize();
        });
      });
    });
    this.ngZone.runOutsideAngular(() => {
      // DOM events that are listened by Angular inside the template trigger change detection
      // and also wrapped into additional functions that call `markForCheck()`. We listen `scroll`
      // in the context of the root zone since it will not trigger change detection each time
      // the `scroll` event is dispatched.
      this.scrollListener = this.renderer.listen(this.scrollRef.nativeElement, 'scroll', () => {
        this.handleScroll();
      });
    });
  }
  ngOnDestroy() {
    this.scrollListener?.();
    // This is called here because the component might be destroyed
    // but there will still be a `requestAnimationFrame` callback in the queue
    // that calls `detectChanges()` on the `ViewRef`. This will lead to a runtime
    // exception if the `detectChanges()` is called after the `ViewRef` is destroyed.
    this.cancelAnimationFrame();
  }
  setActiveCategories(categoriesToMakeActive) {
    if (this.showSingleCategory) {
      this.activeCategories = categoriesToMakeActive.filter(x => x.name === this.selected || x === this.SEARCH_CATEGORY);
    } else {
      this.activeCategories = categoriesToMakeActive;
    }
  }
  updateCategoriesSize() {
    this.categoryRefs.forEach(component => component.memoizeSize());
    if (this.scrollRef) {
      const target = this.scrollRef.nativeElement;
      this.scrollHeight = target.scrollHeight;
      this.clientHeight = target.clientHeight;
      this.clientWidth = target.clientWidth;
    }
  }
  handleAnchorClick($event) {
    this.updateCategoriesSize();
    this.selected = $event.category.name;
    this.setActiveCategories(this.categories);
    if (this.SEARCH_CATEGORY.emojis) {
      this.handleSearch(null);
      this.searchRef?.clear();
      this.handleAnchorClick($event);
      return;
    }
    const component = this.categoryRefs.find(n => n.id === $event.category.id);
    if (component) {
      let {
        top
      } = component;
      if ($event.category.first) {
        top = 0;
      } else {
        top += 1;
      }
      this.scrollRef.nativeElement.scrollTop = top;
    }
    this.nextScroll = $event.category.name;
    // handle component scrolling to load emojis
    for (const category of this.categories) {
      const componentToScroll = this.categoryRefs.find(({
        id
      }) => id === category.id);
      componentToScroll?.handleScroll(this.scrollRef.nativeElement.scrollTop);
    }
  }
  categoryTrack(index, item) {
    return item.id;
  }
  handleScroll(noSelectionChange = false) {
    if (this.nextScroll) {
      this.selected = this.nextScroll;
      this.nextScroll = undefined;
      this.ref.detectChanges();
      return;
    }
    if (!this.scrollRef) {
      return;
    }
    if (this.showSingleCategory) {
      return;
    }
    let activeCategory;
    if (this.SEARCH_CATEGORY.emojis) {
      activeCategory = this.SEARCH_CATEGORY;
    } else {
      const target = this.scrollRef.nativeElement;
      // check scroll is not at bottom
      if (target.scrollTop === 0) {
        // hit the TOP
        activeCategory = this.categories.find(n => n.first === true);
      } else if (target.scrollHeight - target.scrollTop === this.clientHeight) {
        // scrolled to bottom activate last category
        activeCategory = this.categories[this.categories.length - 1];
      } else {
        // scrolling
        for (const category of this.categories) {
          const component = this.categoryRefs.find(({
            id
          }) => id === category.id);
          const active = component?.handleScroll(target.scrollTop);
          if (active) {
            activeCategory = category;
          }
        }
      }
      this.scrollTop = target.scrollTop;
    }
    // This will allow us to run the change detection only when the category changes.
    if (!noSelectionChange && activeCategory && activeCategory.name !== this.selected) {
      this.selected = activeCategory.name;
      this.ref.detectChanges();
    } else if (noSelectionChange) {
      this.ref.detectChanges();
    }
  }
  handleSearch($emojis) {
    this.SEARCH_CATEGORY.emojis = $emojis;
    for (const component of this.categoryRefs.toArray()) {
      if (component.name === 'Search') {
        component.emojis = $emojis;
        component.updateDisplay($emojis ? 'block' : 'none');
      } else {
        component.updateDisplay($emojis ? 'none' : 'block');
      }
    }
    this.scrollRef.nativeElement.scrollTop = 0;
    this.handleScroll();
  }
  handleEnterKey($event, emoji) {
    // Note: the `handleEnterKey` is invoked when the search component dispatches the
    //       `enterKeyOutsideAngular` event or when any emoji is clicked thus `emojiClickOutsideAngular`
    //       event is dispatched. Both events are dispatched outside of the Angular zone to prevent
    //       no-op ticks, basically when users outside of the picker component are not listening
    //       to any of these events.
    if (!emoji) {
      if (this.SEARCH_CATEGORY.emojis !== null && this.SEARCH_CATEGORY.emojis.length) {
        emoji = this.SEARCH_CATEGORY.emojis[0];
        if (emoji) {
          dispatchInAngularContextIfObserved(this.emojiSelect, this.ngZone, {
            $event,
            emoji
          });
        } else {
          return;
        }
      }
    }
    if (!this.hideRecent && !this.recent && emoji) {
      this.frequently.add(emoji);
    }
    const component = this.categoryRefs.toArray()[1];
    if (component && this.enableFrequentEmojiSort) {
      this.ngZone.run(() => {
        component.updateRecentEmojis();
        component.ref.markForCheck();
      });
    }
  }
  handleEmojiOver($event) {
    if (!this.showPreview || !this.previewRef) {
      return;
    }
    const emojiData = this.CUSTOM_CATEGORY.emojis.find(customEmoji => customEmoji.id === $event.emoji.id);
    if (emojiData) {
      $event.emoji = {
        ...emojiData
      };
    }
    this.previewEmoji = $event.emoji;
    this.cancelAnimationFrame();
    this.ref.detectChanges();
  }
  handleEmojiLeave() {
    if (!this.showPreview || !this.previewRef) {
      return;
    }
    // Note: `handleEmojiLeave` will be invoked outside of the Angular zone because of the `mouseleave`
    //       event set up outside of the Angular zone in `ngx-emoji`. See `setupMouseLeaveListener`.
    //       This is done explicitly because we don't have to run redundant change detection since we
    //       would still want to leave the Angular zone here when scheduling animation frame.
    this.animationFrameRequestId = requestAnimationFrame(() => {
      this.previewEmoji = null;
      this.ref.detectChanges();
    });
  }
  handleEmojiClick($event) {
    // Note: we're getting back into the Angular zone because click events on emojis are handled
    //       outside of the Angular zone.
    dispatchInAngularContextIfObserved(this.emojiClick, this.ngZone, $event);
    dispatchInAngularContextIfObserved(this.emojiSelect, this.ngZone, $event);
    this.handleEnterKey($event.$event, $event.emoji);
  }
  handleSkinChange(skin) {
    this.skin = skin;
    localStorage.setItem(`${this.NAMESPACE}.skin`, String(skin));
    this.skinChange.emit(skin);
  }
  getWidth() {
    if (this.style && this.style.width) {
      return this.style.width;
    }
    return this.perLine * (this.emojiSize + 12) + 12 + 2 + this.measureScrollbar + 'px';
  }
  cancelAnimationFrame() {
    if (this.animationFrameRequestId !== null) {
      cancelAnimationFrame(this.animationFrameRequestId);
      this.animationFrameRequestId = null;
    }
  }
  static ɵfac = function PickerComponent_Factory(t) {
    return new (t || PickerComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](EmojiFrequentlyService), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID));
  };
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: PickerComponent,
    selectors: [["emoji-mart"]],
    viewQuery: function PickerComponent_Query(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c3, 7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](PreviewComponent, 5);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](SearchComponent, 5);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](CategoryComponent, 5);
      }
      if (rf & 2) {
        let _t;
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.scrollRef = _t.first);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.previewRef = _t.first);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.searchRef = _t.first);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.categoryRefs = _t);
      }
    },
    inputs: {
      perLine: "perLine",
      totalFrequentLines: "totalFrequentLines",
      i18n: "i18n",
      style: "style",
      title: "title",
      emoji: "emoji",
      darkMode: "darkMode",
      color: "color",
      hideObsolete: "hideObsolete",
      categories: "categories",
      activeCategories: "activeCategories",
      set: "set",
      skin: "skin",
      isNative: "isNative",
      emojiSize: "emojiSize",
      sheetSize: "sheetSize",
      emojisToShowFilter: "emojisToShowFilter",
      showPreview: "showPreview",
      emojiTooltip: "emojiTooltip",
      autoFocus: "autoFocus",
      custom: "custom",
      hideRecent: "hideRecent",
      imageUrlFn: "imageUrlFn",
      include: "include",
      exclude: "exclude",
      notFoundEmoji: "notFoundEmoji",
      categoriesIcons: "categoriesIcons",
      searchIcons: "searchIcons",
      useButton: "useButton",
      enableFrequentEmojiSort: "enableFrequentEmojiSort",
      enableSearch: "enableSearch",
      showSingleCategory: "showSingleCategory",
      virtualize: "virtualize",
      virtualizeOffset: "virtualizeOffset",
      recent: "recent",
      backgroundImageFn: "backgroundImageFn"
    },
    outputs: {
      emojiClick: "emojiClick",
      emojiSelect: "emojiSelect",
      skinChange: "skinChange"
    },
    standalone: true,
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
    decls: 8,
    vars: 16,
    consts: [["scrollRef", ""], [3, "ngStyle"], [1, "emoji-mart-bar"], [3, "anchorClick", "categories", "color", "selected", "i18n", "icons"], [3, "i18n", "include", "exclude", "custom", "autoFocus", "icons", "emojisToShowFilter", "searchResults", "enterKeyOutsideAngular", 4, "ngIf"], [1, "emoji-mart-scroll"], [3, "id", "name", "emojis", "perLine", "totalFrequentLines", "hasStickyPosition", "i18n", "hideObsolete", "notFoundEmoji", "custom", "recent", "virtualize", "virtualizeOffset", "emojiIsNative", "emojiSkin", "emojiSize", "emojiSet", "emojiSheetSize", "emojiForceSize", "emojiTooltip", "emojiBackgroundImageFn", "emojiImageUrlFn", "emojiUseButton", "emojiOverOutsideAngular", "emojiLeaveOutsideAngular", "emojiClickOutsideAngular", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "emoji-mart-bar", 4, "ngIf"], [3, "searchResults", "enterKeyOutsideAngular", "i18n", "include", "exclude", "custom", "autoFocus", "icons", "emojisToShowFilter"], [3, "emojiOverOutsideAngular", "emojiLeaveOutsideAngular", "emojiClickOutsideAngular", "id", "name", "emojis", "perLine", "totalFrequentLines", "hasStickyPosition", "i18n", "hideObsolete", "notFoundEmoji", "custom", "recent", "virtualize", "virtualizeOffset", "emojiIsNative", "emojiSkin", "emojiSize", "emojiSet", "emojiSheetSize", "emojiForceSize", "emojiTooltip", "emojiBackgroundImageFn", "emojiImageUrlFn", "emojiUseButton"], [3, "skinChange", "emoji", "idleEmoji", "emojiIsNative", "emojiSize", "emojiSkin", "emojiSet", "i18n", "emojiSheetSize", "emojiBackgroundImageFn", "emojiImageUrlFn"]],
    template: function PickerComponent_Template(rf, ctx) {
      if (rf & 1) {
        const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "section", 1)(1, "div", 2)(2, "emoji-mart-anchors", 3);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("anchorClick", function PickerComponent_Template_emoji_mart_anchors_anchorClick_2_listener($event) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
          return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.handleAnchorClick($event));
        });
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, PickerComponent_emoji_search_3_Template, 1, 7, "emoji-search", 4);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "section", 5, 0);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](6, PickerComponent_emoji_category_6_Template, 1, 23, "emoji-category", 6);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](7, PickerComponent_div_7_Template, 2, 11, "div", 7);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMapInterpolate1"]("emoji-mart ", ctx.darkMode ? "emoji-mart-dark" : "", "");
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("width", ctx.getWidth());
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngStyle", ctx.style);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("categories", ctx.categories)("color", ctx.color)("selected", ctx.selected)("i18n", ctx.i18n)("icons", ctx.categoriesIcons);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.enableSearch);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-label", ctx.i18n.emojilist);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx.activeCategories)("ngForTrackBy", ctx.categoryTrack);
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.showPreview);
      }
    },
    dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgStyle, AnchorsComponent, SearchComponent, PreviewComponent, CategoryComponent],
    encapsulation: 2,
    changeDetection: 0
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PickerComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'emoji-mart',
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      preserveWhitespaces: false,
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule, AnchorsComponent, SearchComponent, PreviewComponent, CategoryComponent],
      template: "<section\n  class=\"emoji-mart {{ darkMode ? 'emoji-mart-dark' : '' }}\"\n  [style.width]=\"getWidth()\"\n  [ngStyle]=\"style\"\n>\n  <div class=\"emoji-mart-bar\">\n    <emoji-mart-anchors\n      [categories]=\"categories\"\n      (anchorClick)=\"handleAnchorClick($event)\"\n      [color]=\"color\"\n      [selected]=\"selected\"\n      [i18n]=\"i18n\"\n      [icons]=\"categoriesIcons\"\n    ></emoji-mart-anchors>\n  </div>\n  <emoji-search\n    *ngIf=\"enableSearch\"\n    [i18n]=\"i18n\"\n    (searchResults)=\"handleSearch($event)\"\n    (enterKeyOutsideAngular)=\"handleEnterKey($event)\"\n    [include]=\"include\"\n    [exclude]=\"exclude\"\n    [custom]=\"custom\"\n    [autoFocus]=\"autoFocus\"\n    [icons]=\"searchIcons\"\n    [emojisToShowFilter]=\"emojisToShowFilter\"\n  ></emoji-search>\n  <section #scrollRef class=\"emoji-mart-scroll\" [attr.aria-label]=\"i18n.emojilist\">\n    <emoji-category\n      *ngFor=\"let category of activeCategories; let idx = index; trackBy: categoryTrack\"\n      [id]=\"category.id\"\n      [name]=\"category.name\"\n      [emojis]=\"category.emojis\"\n      [perLine]=\"perLine\"\n      [totalFrequentLines]=\"totalFrequentLines\"\n      [hasStickyPosition]=\"isNative\"\n      [i18n]=\"i18n\"\n      [hideObsolete]=\"hideObsolete\"\n      [notFoundEmoji]=\"notFoundEmoji\"\n      [custom]=\"category.id === RECENT_CATEGORY.id ? CUSTOM_CATEGORY.emojis : undefined\"\n      [recent]=\"category.id === RECENT_CATEGORY.id ? recent : undefined\"\n      [virtualize]=\"virtualize\"\n      [virtualizeOffset]=\"virtualizeOffset\"\n      [emojiIsNative]=\"isNative\"\n      [emojiSkin]=\"skin\"\n      [emojiSize]=\"emojiSize\"\n      [emojiSet]=\"set\"\n      [emojiSheetSize]=\"sheetSize\"\n      [emojiForceSize]=\"isNative\"\n      [emojiTooltip]=\"emojiTooltip\"\n      [emojiBackgroundImageFn]=\"backgroundImageFn\"\n      [emojiImageUrlFn]=\"imageUrlFn\"\n      [emojiUseButton]=\"useButton\"\n      (emojiOverOutsideAngular)=\"handleEmojiOver($event)\"\n      (emojiLeaveOutsideAngular)=\"handleEmojiLeave()\"\n      (emojiClickOutsideAngular)=\"handleEmojiClick($event)\"\n    ></emoji-category>\n  </section>\n  <div class=\"emoji-mart-bar\" *ngIf=\"showPreview\">\n    <emoji-preview\n      [attr.title]=\"title\"\n      [emoji]=\"previewEmoji\"\n      [idleEmoji]=\"emoji\"\n      [emojiIsNative]=\"isNative\"\n      [emojiSize]=\"38\"\n      [emojiSkin]=\"skin\"\n      [emojiSet]=\"set\"\n      [i18n]=\"i18n\"\n      [emojiSheetSize]=\"sheetSize\"\n      [emojiBackgroundImageFn]=\"backgroundImageFn\"\n      [emojiImageUrlFn]=\"imageUrlFn\"\n      (skinChange)=\"handleSkinChange($event)\"\n    ></emoji-preview>\n  </div>\n</section>\n"
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
    }, {
      type: EmojiFrequentlyService
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
        args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID]
      }]
    }];
  }, {
    perLine: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    totalFrequentLines: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    i18n: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    style: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    title: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    darkMode: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    color: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hideObsolete: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    categories: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    activeCategories: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    set: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    skin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    isNative: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    sheetSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojisToShowFilter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showPreview: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiTooltip: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    autoFocus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    custom: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hideRecent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    imageUrlFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    include: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    exclude: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    notFoundEmoji: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    categoriesIcons: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    searchIcons: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    useButton: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    enableFrequentEmojiSort: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    enableSearch: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showSingleCategory: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualizeOffset: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    recent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    emojiClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    emojiSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    skinChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    scrollRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['scrollRef', {
        static: true
      }]
    }],
    previewRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: [PreviewComponent, {
        static: false
      }]
    }],
    searchRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: [SearchComponent, {
        static: false
      }]
    }],
    categoryRefs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChildren,
      args: [CategoryComponent]
    }],
    backgroundImageFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * This is only a helper function because the same code is being re-used many times.
 */
function dispatchInAngularContextIfObserved(emitter, ngZone, value) {
  if (emitter.observed) {
    ngZone.run(() => emitter.emit(value));
  }
}
const components = [PickerComponent, AnchorsComponent, CategoryComponent, SearchComponent, PreviewComponent, SkinComponent];
class PickerModule {
  static ɵfac = function PickerModule_Factory(t) {
    return new (t || PickerModule)();
  };
  static ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
    type: PickerModule
  });
  static ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
    imports: [components]
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PickerModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: components,
      exports: components
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 87997:
/*!******************************************************************************!*\
  !*** ./node_modules/@fullcalendar/angular/fesm2020/fullcalendar-angular.mjs ***!
  \******************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   FullCalendarComponent: () => (/* binding */ FullCalendarComponent),
/* harmony export */   FullCalendarModule: () => (/* binding */ FullCalendarModule)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _fullcalendar_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @fullcalendar/core */ 46633);
/* harmony import */ var _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fullcalendar/core/internal */ 3436);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);






const _c0 = ["*"];
const _c1 = ["rootEl"];
const _c2 = a0 => ({
  $implicit: a0
});
function TransportContainerComponent_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
function TransportContainerComponent_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
function TransportContainerComponent_ng_template_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "a", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
function TransportContainerComponent_ng_template_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "tr", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
function TransportContainerComponent_ng_template_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "th", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
function TransportContainerComponent_ng_template_5_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "td", 2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](2, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngClass", ctx_r0.elClasses || "")("ngStyle", ctx_r0.elStyle || null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.template)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c2, ctx_r0.renderProps));
  }
}
const _c3 = ["dayHeaderContent"];
const _c4 = ["dayCellContent"];
const _c5 = ["weekNumberContent"];
const _c6 = ["nowIndicatorContent"];
const _c7 = ["eventContent"];
const _c8 = ["slotLaneContent"];
const _c9 = ["slotLabelContent"];
const _c10 = ["allDayContent"];
const _c11 = ["moreLinkContent"];
const _c12 = ["noEventsContent"];
const _c13 = ["resourceAreaHeaderContent"];
const _c14 = ["resourceGroupLabelContent"];
const _c15 = ["resourceLabelContent"];
const _c16 = ["resourceLaneContent"];
const _c17 = ["resourceGroupLaneContent"];
function FullCalendarComponent_transport_container_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "transport-container", 1);
  }
  if (rf & 2) {
    const customRendering_r1 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("inPlaceOf", customRendering_r1.containerEl)("reportEl", customRendering_r1.reportNewContainerEl)("elTag", customRendering_r1.elTag)("elClasses", customRendering_r1.elClasses)("elStyle", customRendering_r1.elStyle)("elAttrs", customRendering_r1.elAttrs)("template", customRendering_r1.generatorMeta)("renderProps", customRendering_r1.renderProps);
  }
}
const OPTION_IS_DEEP = {
  headerToolbar: true,
  footerToolbar: true,
  events: true,
  eventSources: true,
  resources: true
};
/*
NOTE: keep synced with component
*/
const OPTION_INPUT_NAMES = ['events', 'eventSources', 'resources'];
const hasOwnProperty = Object.prototype.hasOwnProperty;
/*
Really simple clone utility. Only copies plain arrays, objects, and Dates. Transfers everything else as-is.
Wanted to use a third-party lib, but none did exactly this.
*/
function deepCopy(input) {
  if (Array.isArray(input)) {
    return input.map(deepCopy);
  } else if (input instanceof Date) {
    return new Date(input.valueOf());
  } else if (typeof input === 'object' && input) {
    // non-null object
    return mapHash(input, deepCopy);
  } else {
    // everything else (null, function, etc)
    return input;
  }
}
function mapHash(input, func) {
  const output = {};
  for (const key in input) {
    if (hasOwnProperty.call(input, key)) {
      output[key] = func(input[key], key);
    }
  }
  return output;
}

/*
Forked from https://github.com/epoberezkin/fast-deep-equal (also has MIT license)
Needed ESM support or else Angular complains about treeshaking
(https://github.com/fullcalendar/fullcalendar-angular/issues/421)
*/
function deepEqual(a, b) {
  if (a === b) return true;
  if (a && b && typeof a == 'object' && typeof b == 'object') {
    if (a.constructor !== b.constructor) return false;
    var length, i, keys;
    if (Array.isArray(a)) {
      length = a.length;
      if (length != b.length) return false;
      for (i = length; i-- !== 0;) if (!deepEqual(a[i], b[i])) return false;
      return true;
    }
    if (a.constructor === RegExp) return a.source === b.source && a.flags === b.flags;
    if (a.valueOf !== Object.prototype.valueOf) return a.valueOf() === b.valueOf();
    if (a.toString !== Object.prototype.toString) return a.toString() === b.toString();
    keys = Object.keys(a);
    length = keys.length;
    if (length !== Object.keys(b).length) return false;
    for (i = length; i-- !== 0;) if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;
    for (i = length; i-- !== 0;) {
      var key = keys[i];
      if (!deepEqual(a[key], b[key])) return false;
    }
    return true;
  }
  // true if both NaN, false otherwise
  return a !== a && b !== b;
}
const dummyContainer$1 = typeof document !== 'undefined' ? document.createDocumentFragment() : null;
class OffscreenFragmentComponent {
  constructor(element) {
    this.element = element;
  }
  ngAfterViewInit() {
    if (dummyContainer$1) {
      dummyContainer$1.appendChild(this.element.nativeElement);
    }
  }
  // invoked BEFORE component removed from DOM
  ngOnDestroy() {
    if (dummyContainer$1) {
      dummyContainer$1.removeChild(this.element.nativeElement);
    }
  }
}
OffscreenFragmentComponent.ɵfac = function OffscreenFragmentComponent_Factory(t) {
  return new (t || OffscreenFragmentComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
};
OffscreenFragmentComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
  type: OffscreenFragmentComponent,
  selectors: [["offscreen-fragment"]],
  ngContentSelectors: _c0,
  decls: 1,
  vars: 0,
  template: function OffscreenFragmentComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
    }
  },
  encapsulation: 2
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](OffscreenFragmentComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'offscreen-fragment',
      template: '<ng-content></ng-content>',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
    }];
  }, null);
})();
const dummyContainer = typeof document !== 'undefined' ? document.createDocumentFragment() : null;
class TransportContainerComponent {
  ngAfterViewInit() {
    const rootEl = this.rootElRef?.nativeElement; // assumed defined
    replaceEl(rootEl, this.inPlaceOf);
    applyElAttrs(rootEl, undefined, this.elAttrs);
    // insurance for if Preact recreates and reroots inPlaceOf element
    this.inPlaceOf.style.display = 'none';
    this.reportEl(rootEl);
  }
  ngOnChanges(changes) {
    const rootEl = this.rootElRef?.nativeElement;
    // ngOnChanges is called before ngAfterViewInit (and before DOM initializes)
    // so make sure rootEl is defined before doing anything
    if (rootEl) {
      // If the ContentContainer's tagName changed, it will create a new DOM element in its
      // original place. Detect this and re-replace.
      if (this.inPlaceOf.parentNode !== dummyContainer) {
        replaceEl(rootEl, this.inPlaceOf);
        applyElAttrs(rootEl, undefined, this.elAttrs);
        this.reportEl(rootEl);
      } else {
        const elAttrsChange = changes['elAttrs'];
        if (elAttrsChange) {
          applyElAttrs(rootEl, elAttrsChange.previousValue, elAttrsChange.currentValue);
        }
      }
    }
  }
  // invoked BEFORE component removed from DOM
  ngOnDestroy() {
    if (
    // protect against Preact recreating and rerooting inPlaceOf element
    this.inPlaceOf.parentNode === dummyContainer && dummyContainer) {
      dummyContainer.removeChild(this.inPlaceOf);
    }
    this.reportEl(null);
  }
}
TransportContainerComponent.ɵfac = function TransportContainerComponent_Factory(t) {
  return new (t || TransportContainerComponent)();
};
TransportContainerComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
  type: TransportContainerComponent,
  selectors: [["transport-container"]],
  viewQuery: function TransportContainerComponent_Query(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c1, 5);
    }
    if (rf & 2) {
      let _t;
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.rootElRef = _t.first);
    }
  },
  inputs: {
    inPlaceOf: "inPlaceOf",
    reportEl: "reportEl",
    elTag: "elTag",
    elClasses: "elClasses",
    elStyle: "elStyle",
    elAttrs: "elAttrs",
    template: "template",
    renderProps: "renderProps"
  },
  features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
  decls: 6,
  vars: 6,
  consts: [["rootEl", ""], [3, "ngIf"], [3, "ngClass", "ngStyle"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
  template: function TransportContainerComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, TransportContainerComponent_ng_template_0_Template, 3, 6, "ng-template", 1)(1, TransportContainerComponent_ng_template_1_Template, 3, 6, "ng-template", 1)(2, TransportContainerComponent_ng_template_2_Template, 3, 6, "ng-template", 1)(3, TransportContainerComponent_ng_template_3_Template, 3, 6, "ng-template", 1)(4, TransportContainerComponent_ng_template_4_Template, 3, 6, "ng-template", 1)(5, TransportContainerComponent_ng_template_5_Template, 3, 6, "ng-template", 1);
    }
    if (rf & 2) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "div");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "span");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "a");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "tr");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "th");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.elTag == "td");
    }
  },
  dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgClass, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgStyle, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgTemplateOutlet],
  encapsulation: 2
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TransportContainerComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'transport-container',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: "<ng-template [ngIf]=\"elTag == 'div'\">\n  <div #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </div>\n</ng-template>\n<ng-template [ngIf]=\"elTag == 'span'\">\n  <span #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </span>\n</ng-template>\n<ng-template [ngIf]=\"elTag == 'a'\">\n  <a #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </a>\n</ng-template>\n<ng-template [ngIf]=\"elTag == 'tr'\">\n  <tr #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </tr>\n</ng-template>\n<ng-template [ngIf]=\"elTag == 'th'\">\n  <th #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </th>\n</ng-template>\n<ng-template [ngIf]=\"elTag == 'td'\">\n  <td #rootEl [ngClass]=\"elClasses || ''\" [ngStyle]=\"elStyle || null\">\n    <ng-container\n      [ngTemplateOutlet]=\"template\"\n      [ngTemplateOutletContext]=\"{ $implicit: renderProps }\"\n    ></ng-container>\n  </td>\n</ng-template>\n"
    }]
  }], null, {
    inPlaceOf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    reportEl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    elTag: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    elClasses: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    elStyle: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    elAttrs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    template: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    renderProps: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    rootElRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['rootEl']
    }]
  });
})();
function replaceEl(subject, inPlaceOf) {
  inPlaceOf.parentNode?.insertBefore(subject, inPlaceOf.nextSibling);
  if (dummyContainer) {
    dummyContainer.appendChild(inPlaceOf);
  }
}
function applyElAttrs(el, previousAttrs = {}, currentAttrs = {}) {
  // these are called "attributes" but they manipulate DOM node *properties*
  for (const attrName in previousAttrs) {
    if (!(attrName in currentAttrs)) {
      el[attrName] = null;
    }
  }
  for (const attrName in currentAttrs) {
    el[attrName] = currentAttrs[attrName];
  }
}
class FullCalendarComponent {
  constructor(element, changeDetector) {
    this.element = element;
    this.calendar = null;
    this.optionSnapshot = {}; // for diffing
    this.customRenderingMap = new Map();
    const customRenderingStore = new _fullcalendar_core_internal__WEBPACK_IMPORTED_MODULE_2__.cv();
    customRenderingStore.subscribe(customRenderingMap => {
      this.customRenderingMap = customRenderingMap;
      this.customRenderingArray = undefined; // clear cache
      changeDetector.detectChanges();
    });
    this.handleCustomRendering = customRenderingStore.handle.bind(customRenderingStore);
  }
  ngAfterViewInit() {
    const {
      deepChangeDetection
    } = this;
    const options = {
      ...this.options,
      ...this.buildInputOptions()
    };
    // initialize snapshot
    this.optionSnapshot = mapHash(options, (optionVal, optionName) => deepChangeDetection && OPTION_IS_DEEP[optionName] ? deepCopy(optionVal) : optionVal);
    const calendarEl = this.element.nativeElement;
    const calendar = this.calendar = new _fullcalendar_core__WEBPACK_IMPORTED_MODULE_3__.Calendar(calendarEl, {
      ...options,
      ...this.buildExtraOptions()
    });
    // Ionic dimensions hack
    // https://github.com/fullcalendar/fullcalendar/issues/4976
    const ionContent = calendarEl.closest('ion-content');
    if (ionContent && ionContent.componentOnReady) {
      ionContent.componentOnReady().then(() => {
        window.requestAnimationFrame(() => {
          calendar.render();
        });
      });
    } else {
      calendar.render();
    }
    // Angular v19, whether because of new Vite dev environment or not,
    // loads outer elements' styles late, so dimensions might not be final here.
    // Force a size-update after a delay.
    setTimeout(() => calendar.updateSize());
  }
  /*
  allows us to manually detect complex input changes, internal mutations to certain options.
  called before ngOnChanges. called much more often than ngOnChanges.
  */
  ngDoCheck() {
    if (this.calendar) {
      // not the initial render
      const {
        deepChangeDetection,
        optionSnapshot
      } = this;
      const newOptions = {
        ...this.options,
        ...this.buildInputOptions()
      };
      const newProcessedOptions = {};
      const changedOptionNames = [];
      // detect adds and updates (and update snapshot)
      for (const optionName in newOptions) {
        if (newOptions.hasOwnProperty(optionName)) {
          let optionVal = newOptions[optionName];
          if (deepChangeDetection && OPTION_IS_DEEP[optionName]) {
            if (!deepEqual(optionSnapshot[optionName], optionVal)) {
              optionSnapshot[optionName] = deepCopy(optionVal);
              changedOptionNames.push(optionName);
            }
          } else {
            if (optionSnapshot[optionName] !== optionVal) {
              optionSnapshot[optionName] = optionVal;
              changedOptionNames.push(optionName);
            }
          }
          newProcessedOptions[optionName] = optionVal;
        }
      }
      const oldOptionNames = Object.keys(optionSnapshot);
      // detect removals (and update snapshot)
      for (const optionName of oldOptionNames) {
        if (!(optionName in newOptions)) {
          // doesn't exist in new options?
          delete optionSnapshot[optionName];
          changedOptionNames.push(optionName);
        }
      }
      if (changedOptionNames.length) {
        this.calendar.pauseRendering();
        this.calendar.resetOptions({
          ...newProcessedOptions,
          ...this.buildExtraOptions()
        }, changedOptionNames);
      }
    }
  }
  ngAfterContentChecked() {
    if (this.calendar) {
      // too defensive?
      this.calendar.resumeRendering();
    }
  }
  ngOnDestroy() {
    if (this.calendar) {
      // too defensive?
      this.calendar.destroy();
      this.calendar = null;
    }
  }
  get customRenderings() {
    return this.customRenderingArray || (this.customRenderingArray = [...this.customRenderingMap.values()]);
  }
  getApi() {
    return this.calendar;
  }
  buildInputOptions() {
    const options = {};
    for (const inputName of OPTION_INPUT_NAMES) {
      const inputValue = this[inputName];
      if (inputValue != null) {
        // exclude both null and undefined
        options[inputName] = inputValue;
      }
    }
    return options;
  }
  buildExtraOptions() {
    return {
      handleCustomRendering: this.handleCustomRendering,
      customRenderingMetaMap: this,
      customRenderingReplaces: true
    };
  }
  // for `trackBy` in loop
  trackCustomRendering(index, customRendering) {
    return customRendering.id;
  }
}
FullCalendarComponent.ɵfac = function FullCalendarComponent_Factory(t) {
  return new (t || FullCalendarComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef));
};
FullCalendarComponent.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
  type: FullCalendarComponent,
  selectors: [["full-calendar"]],
  contentQueries: function FullCalendarComponent_ContentQueries(rf, ctx, dirIndex) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c3, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c4, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c5, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c6, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c7, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c8, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c9, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c10, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c11, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c12, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c13, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c14, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c15, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c16, 7);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _c17, 7);
    }
    if (rf & 2) {
      let _t;
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.dayHeaderContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.dayCellContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.weekNumberContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.nowIndicatorContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.eventContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.slotLaneContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.slotLabelContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.allDayContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.moreLinkContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.noEventsContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.resourceAreaHeaderContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.resourceGroupLabelContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.resourceLabelContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.resourceLaneContent = _t.first);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.resourceGroupLaneContent = _t.first);
    }
  },
  inputs: {
    options: "options",
    deepChangeDetection: "deepChangeDetection",
    events: "events",
    eventSources: "eventSources",
    resources: "resources"
  },
  decls: 2,
  vars: 2,
  consts: [[3, "inPlaceOf", "reportEl", "elTag", "elClasses", "elStyle", "elAttrs", "template", "renderProps", 4, "ngFor", "ngForOf", "ngForTrackBy"], [3, "inPlaceOf", "reportEl", "elTag", "elClasses", "elStyle", "elAttrs", "template", "renderProps"]],
  template: function FullCalendarComponent_Template(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "offscreen-fragment");
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, FullCalendarComponent_transport_container_1_Template, 1, 8, "transport-container", 0);
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    }
    if (rf & 2) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx.customRenderings)("ngForTrackBy", ctx.trackCustomRendering);
    }
  },
  dependencies: [OffscreenFragmentComponent, TransportContainerComponent, _angular_common__WEBPACK_IMPORTED_MODULE_1__.NgForOf],
  encapsulation: 2
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FullCalendarComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'full-calendar',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None // the styles are root-level, not scoped within the component
      ,
      template: "<offscreen-fragment>\n  <transport-container *ngFor=\"let customRendering of customRenderings; trackBy:trackCustomRendering\"\n    [inPlaceOf]=\"customRendering.containerEl\"\n    [reportEl]=\"customRendering.reportNewContainerEl\"\n    [elTag]=\"customRendering.elTag\"\n    [elClasses]=\"customRendering.elClasses\"\n    [elStyle]=\"customRendering.elStyle\"\n    [elAttrs]=\"customRendering.elAttrs\"\n    [template]=\"customRendering.generatorMeta\"\n    [renderProps]=\"customRendering.renderProps\"\n  ></transport-container>\n</offscreen-fragment>\n"
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
    }];
  }, {
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    deepChangeDetection: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    events: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    eventSources: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    resources: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dayHeaderContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['dayHeaderContent', {
        static: true
      }]
    }],
    dayCellContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['dayCellContent', {
        static: true
      }]
    }],
    weekNumberContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['weekNumberContent', {
        static: true
      }]
    }],
    nowIndicatorContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['nowIndicatorContent', {
        static: true
      }]
    }],
    eventContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['eventContent', {
        static: true
      }]
    }],
    slotLaneContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['slotLaneContent', {
        static: true
      }]
    }],
    slotLabelContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['slotLabelContent', {
        static: true
      }]
    }],
    allDayContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['allDayContent', {
        static: true
      }]
    }],
    moreLinkContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['moreLinkContent', {
        static: true
      }]
    }],
    noEventsContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['noEventsContent', {
        static: true
      }]
    }],
    resourceAreaHeaderContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['resourceAreaHeaderContent', {
        static: true
      }]
    }],
    resourceGroupLabelContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['resourceGroupLabelContent', {
        static: true
      }]
    }],
    resourceLabelContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['resourceLabelContent', {
        static: true
      }]
    }],
    resourceLaneContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['resourceLaneContent', {
        static: true
      }]
    }],
    resourceGroupLaneContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: ['resourceGroupLaneContent', {
        static: true
      }]
    }]
  });
})();
class FullCalendarModule {}
FullCalendarModule.ɵfac = function FullCalendarModule_Factory(t) {
  return new (t || FullCalendarModule)();
};
FullCalendarModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: FullCalendarModule
});
FullCalendarModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
  imports: [[_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule]]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FullCalendarModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: [FullCalendarComponent, OffscreenFragmentComponent, TransportContainerComponent],
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule],
      exports: [FullCalendarComponent]
    }]
  }], null, null);
})();

/*
 * Public API Surface of lib
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 46633:
/*!**************************************************!*\
  !*** ./node_modules/@fullcalendar/core/index.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Calendar: () => (/* binding */ Calendar),
/* harmony export */   JsonRequestError: () => (/* reexport safe */ _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ae),
/* harmony export */   createPlugin: () => (/* binding */ createPlugin),
/* harmony export */   formatDate: () => (/* binding */ formatDate),
/* harmony export */   formatRange: () => (/* binding */ formatRange),
/* harmony export */   globalLocales: () => (/* binding */ globalLocales),
/* harmony export */   globalPlugins: () => (/* binding */ globalPlugins),
/* harmony export */   sliceEvents: () => (/* binding */ sliceEvents),
/* harmony export */   version: () => (/* binding */ version)
/* harmony export */ });
/* harmony import */ var _internal_common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./internal-common.js */ 3436);
/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact */ 78048);
/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! preact/compat */ 40174);




const globalLocales = [];
const MINIMAL_RAW_EN_LOCALE = {
  code: 'en',
  week: {
    dow: 0,
    doy: 4 // 4 days need to be within the year to be considered the first week
  },
  direction: 'ltr',
  buttonText: {
    prev: 'prev',
    next: 'next',
    prevYear: 'prev year',
    nextYear: 'next year',
    year: 'year',
    today: 'today',
    month: 'month',
    week: 'week',
    day: 'day',
    list: 'list'
  },
  weekText: 'W',
  weekTextLong: 'Week',
  closeHint: 'Close',
  timeHint: 'Time',
  eventHint: 'Event',
  allDayText: 'all-day',
  moreLinkText: 'more',
  noEventsText: 'No events to display'
};
const RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), {
  // Includes things we don't want other locales to inherit,
  // things that derive from other translatable strings.
  buttonHints: {
    prev: 'Previous $0',
    next: 'Next $0',
    today(buttonText, unit) {
      return unit === 'day' ? 'Today' : `This ${buttonText}`;
    }
  },
  viewHint: '$0 view',
  navLinkHint: 'Go to $0',
  moreLinkHint(eventCnt) {
    return `Show ${eventCnt} more event${eventCnt === 1 ? '' : 's'}`;
  }
});
function organizeRawLocales(explicitRawLocales) {
  let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : 'en';
  let allRawLocales = globalLocales.concat(explicitRawLocales);
  let rawLocaleMap = {
    en: RAW_EN_LOCALE
  };
  for (let rawLocale of allRawLocales) {
    rawLocaleMap[rawLocale.code] = rawLocale;
  }
  return {
    map: rawLocaleMap,
    defaultCode
  };
}
function buildLocale(inputSingular, available) {
  if (typeof inputSingular === 'object' && !Array.isArray(inputSingular)) {
    return parseLocale(inputSingular.code, [inputSingular.code], inputSingular);
  }
  return queryLocale(inputSingular, available);
}
function queryLocale(codeArg, available) {
  let codes = [].concat(codeArg || []); // will convert to array
  let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE;
  return parseLocale(codeArg, codes, raw);
}
function queryRawLocale(codes, available) {
  for (let i = 0; i < codes.length; i += 1) {
    let parts = codes[i].toLocaleLowerCase().split('-');
    for (let j = parts.length; j > 0; j -= 1) {
      let simpleId = parts.slice(0, j).join('-');
      if (available[simpleId]) {
        return available[simpleId];
      }
    }
  }
  return null;
}
function parseLocale(codeArg, codes, raw) {
  let merged = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.m)([MINIMAL_RAW_EN_LOCALE, raw], ['buttonText']);
  delete merged.code; // don't want this part of the options
  let {
    week
  } = merged;
  delete merged.week;
  return {
    codeArg,
    codes,
    week,
    simpleNumberFormat: new Intl.NumberFormat(codeArg),
    options: merged
  };
}

// TODO: easier way to add new hooks? need to update a million things
function createPlugin(input) {
  return {
    id: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)(),
    name: input.name,
    premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : undefined,
    deps: input.deps || [],
    reducers: input.reducers || [],
    isLoadingFuncs: input.isLoadingFuncs || [],
    contextInit: [].concat(input.contextInit || []),
    eventRefiners: input.eventRefiners || {},
    eventDefMemberAdders: input.eventDefMemberAdders || [],
    eventSourceRefiners: input.eventSourceRefiners || {},
    isDraggableTransformers: input.isDraggableTransformers || [],
    eventDragMutationMassagers: input.eventDragMutationMassagers || [],
    eventDefMutationAppliers: input.eventDefMutationAppliers || [],
    dateSelectionTransformers: input.dateSelectionTransformers || [],
    datePointTransforms: input.datePointTransforms || [],
    dateSpanTransforms: input.dateSpanTransforms || [],
    views: input.views || {},
    viewPropsTransformers: input.viewPropsTransformers || [],
    isPropsValid: input.isPropsValid || null,
    externalDefTransforms: input.externalDefTransforms || [],
    viewContainerAppends: input.viewContainerAppends || [],
    eventDropTransformers: input.eventDropTransformers || [],
    componentInteractions: input.componentInteractions || [],
    calendarInteractions: input.calendarInteractions || [],
    themeClasses: input.themeClasses || {},
    eventSourceDefs: input.eventSourceDefs || [],
    cmdFormatter: input.cmdFormatter,
    recurringTypes: input.recurringTypes || [],
    namedTimeZonedImpl: input.namedTimeZonedImpl,
    initialView: input.initialView || '',
    elementDraggingImpl: input.elementDraggingImpl,
    optionChangeHandlers: input.optionChangeHandlers || {},
    scrollGridImpl: input.scrollGridImpl || null,
    listenerRefiners: input.listenerRefiners || {},
    optionRefiners: input.optionRefiners || {},
    propSetHandlers: input.propSetHandlers || {}
  };
}
function buildPluginHooks(pluginDefs, globalDefs) {
  let currentPluginIds = {};
  let hooks = {
    premiumReleaseDate: undefined,
    reducers: [],
    isLoadingFuncs: [],
    contextInit: [],
    eventRefiners: {},
    eventDefMemberAdders: [],
    eventSourceRefiners: {},
    isDraggableTransformers: [],
    eventDragMutationMassagers: [],
    eventDefMutationAppliers: [],
    dateSelectionTransformers: [],
    datePointTransforms: [],
    dateSpanTransforms: [],
    views: {},
    viewPropsTransformers: [],
    isPropsValid: null,
    externalDefTransforms: [],
    viewContainerAppends: [],
    eventDropTransformers: [],
    componentInteractions: [],
    calendarInteractions: [],
    themeClasses: {},
    eventSourceDefs: [],
    cmdFormatter: null,
    recurringTypes: [],
    namedTimeZonedImpl: null,
    initialView: '',
    elementDraggingImpl: null,
    optionChangeHandlers: {},
    scrollGridImpl: null,
    listenerRefiners: {},
    optionRefiners: {},
    propSetHandlers: {}
  };
  function addDefs(defs) {
    for (let def of defs) {
      const pluginName = def.name;
      const currentId = currentPluginIds[pluginName];
      if (currentId === undefined) {
        currentPluginIds[pluginName] = def.id;
        addDefs(def.deps);
        hooks = combineHooks(hooks, def);
      } else if (currentId !== def.id) {
        // different ID than the one already added
        console.warn(`Duplicate plugin '${pluginName}'`);
      }
    }
  }
  if (pluginDefs) {
    addDefs(pluginDefs);
  }
  addDefs(globalDefs);
  return hooks;
}
function buildBuildPluginHooks() {
  let currentOverrideDefs = [];
  let currentGlobalDefs = [];
  let currentHooks;
  return (overrideDefs, globalDefs) => {
    if (!currentHooks || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(overrideDefs, currentOverrideDefs) || !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(globalDefs, currentGlobalDefs)) {
      currentHooks = buildPluginHooks(overrideDefs, globalDefs);
    }
    currentOverrideDefs = overrideDefs;
    currentGlobalDefs = globalDefs;
    return currentHooks;
  };
}
function combineHooks(hooks0, hooks1) {
  return {
    premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate),
    reducers: hooks0.reducers.concat(hooks1.reducers),
    isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs),
    contextInit: hooks0.contextInit.concat(hooks1.contextInit),
    eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners),
    eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders),
    eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners),
    isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers),
    eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers),
    eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers),
    dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers),
    datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms),
    dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms),
    views: Object.assign(Object.assign({}, hooks0.views), hooks1.views),
    viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers),
    isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid,
    externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms),
    viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends),
    eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers),
    calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions),
    componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
    themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses),
    eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs),
    cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter,
    recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes),
    namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl,
    initialView: hooks0.initialView || hooks1.initialView,
    elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl,
    optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers),
    scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl,
    listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners),
    optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners),
    propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers)
  };
}
function compareOptionalDates(date0, date1) {
  if (date0 === undefined) {
    return date1;
  }
  if (date1 === undefined) {
    return date0;
  }
  return new Date(Math.max(date0.valueOf(), date1.valueOf()));
}
class StandardTheme extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.T {}
StandardTheme.prototype.classes = {
  root: 'fc-theme-standard',
  tableCellShaded: 'fc-cell-shaded',
  buttonGroup: 'fc-button-group',
  button: 'fc-button fc-button-primary',
  buttonActive: 'fc-button-active'
};
StandardTheme.prototype.baseIconClass = 'fc-icon';
StandardTheme.prototype.iconClasses = {
  close: 'fc-icon-x',
  prev: 'fc-icon-chevron-left',
  next: 'fc-icon-chevron-right',
  prevYear: 'fc-icon-chevrons-left',
  nextYear: 'fc-icon-chevrons-right'
};
StandardTheme.prototype.rtlIconClasses = {
  prev: 'fc-icon-chevron-right',
  next: 'fc-icon-chevron-left',
  prevYear: 'fc-icon-chevrons-right',
  nextYear: 'fc-icon-chevrons-left'
};
StandardTheme.prototype.iconOverrideOption = 'buttonIcons'; // TODO: make TS-friendly
StandardTheme.prototype.iconOverrideCustomButtonOption = 'icon';
StandardTheme.prototype.iconOverridePrefix = 'fc-icon-';
function compileViewDefs(defaultConfigs, overrideConfigs) {
  let hash = {};
  let viewType;
  for (viewType in defaultConfigs) {
    ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
  }
  for (viewType in overrideConfigs) {
    ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs);
  }
  return hash;
}
function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
  if (hash[viewType]) {
    return hash[viewType];
  }
  let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs);
  if (viewDef) {
    hash[viewType] = viewDef;
  }
  return viewDef;
}
function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) {
  let defaultConfig = defaultConfigs[viewType];
  let overrideConfig = overrideConfigs[viewType];
  let queryProp = name => defaultConfig && defaultConfig[name] !== null ? defaultConfig[name] : overrideConfig && overrideConfig[name] !== null ? overrideConfig[name] : null;
  let theComponent = queryProp('component');
  let superType = queryProp('superType');
  let superDef = null;
  if (superType) {
    if (superType === viewType) {
      throw new Error('Can\'t have a custom view type that references itself');
    }
    superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs);
  }
  if (!theComponent && superDef) {
    theComponent = superDef.component;
  }
  if (!theComponent) {
    return null; // don't throw a warning, might be settings for a single-unit view
  }
  return {
    type: viewType,
    component: theComponent,
    defaults: Object.assign(Object.assign({}, superDef ? superDef.defaults : {}), defaultConfig ? defaultConfig.rawOptions : {}),
    overrides: Object.assign(Object.assign({}, superDef ? superDef.overrides : {}), overrideConfig ? overrideConfig.rawOptions : {})
  };
}
function parseViewConfigs(inputs) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(inputs, parseViewConfig);
}
function parseViewConfig(input) {
  let rawOptions = typeof input === 'function' ? {
    component: input
  } : input;
  let {
    component
  } = rawOptions;
  if (rawOptions.content) {
    // TODO: remove content/classNames/didMount/etc from options?
    component = createViewHookComponent(rawOptions);
  } else if (component && !(component.prototype instanceof _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B)) {
    // WHY?: people were using `component` property for `content`
    // TODO: converge on one setting name
    component = createViewHookComponent(Object.assign(Object.assign({}, rawOptions), {
      content: component
    }));
  }
  return {
    superType: rawOptions.type,
    component: component,
    rawOptions // includes type and component too :(
  };
}
function createViewHookComponent(options) {
  return viewProps => (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, context => (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.C, {
    elTag: "div",
    elClasses: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.b)(context.viewSpec),
    renderProps: Object.assign(Object.assign({}, viewProps), {
      nextDayThreshold: context.options.nextDayThreshold
    }),
    generatorName: undefined,
    customGenerator: options.content,
    classNameGenerator: options.classNames,
    didMount: options.didMount,
    willUnmount: options.willUnmount
  }));
}
function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
  let defaultConfigs = parseViewConfigs(defaultInputs);
  let overrideConfigs = parseViewConfigs(optionOverrides.views);
  let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs);
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(viewDefs, viewDef => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults));
}
function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) {
  let durationInput = viewDef.overrides.duration || viewDef.defaults.duration || dynamicOptionOverrides.duration || optionOverrides.duration;
  let duration = null;
  let durationUnit = '';
  let singleUnit = '';
  let singleUnitOverrides = {};
  if (durationInput) {
    duration = createDurationCached(durationInput);
    if (duration) {
      // valid?
      let denom = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.c)(duration);
      durationUnit = denom.unit;
      if (denom.value === 1) {
        singleUnit = durationUnit;
        singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {};
      }
    }
  }
  let queryButtonText = optionsSubset => {
    let buttonTextMap = optionsSubset.buttonText || {};
    let buttonTextKey = viewDef.defaults.buttonTextKey;
    if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) {
      return buttonTextMap[buttonTextKey];
    }
    if (buttonTextMap[viewDef.type] != null) {
      return buttonTextMap[viewDef.type];
    }
    if (buttonTextMap[singleUnit] != null) {
      return buttonTextMap[singleUnit];
    }
    return null;
  };
  let queryButtonTitle = optionsSubset => {
    let buttonHints = optionsSubset.buttonHints || {};
    let buttonKey = viewDef.defaults.buttonTextKey; // use same key as text
    if (buttonKey != null && buttonHints[buttonKey] != null) {
      return buttonHints[buttonKey];
    }
    if (buttonHints[viewDef.type] != null) {
      return buttonHints[viewDef.type];
    }
    if (buttonHints[singleUnit] != null) {
      return buttonHints[singleUnit];
    }
    return null;
  };
  return {
    type: viewDef.type,
    component: viewDef.component,
    duration,
    durationUnit,
    singleUnit,
    optionDefaults: viewDef.defaults,
    optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides),
    buttonTextOverride: queryButtonText(dynamicOptionOverrides) || queryButtonText(optionOverrides) ||
    // constructor-specified buttonText lookup hash takes precedence
    viewDef.overrides.buttonText,
    buttonTextDefault: queryButtonText(localeDefaults) || viewDef.defaults.buttonText || queryButtonText(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e) || viewDef.type,
    // not DRY
    buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) || queryButtonTitle(optionOverrides) || viewDef.overrides.buttonHint,
    buttonTitleDefault: queryButtonTitle(localeDefaults) || viewDef.defaults.buttonHint || queryButtonTitle(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e)
    // will eventually fall back to buttonText
  };
}
// hack to get memoization working
let durationInputMap = {};
function createDurationCached(durationInput) {
  let json = JSON.stringify(durationInput);
  let res = durationInputMap[json];
  if (res === undefined) {
    res = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d)(durationInput);
    durationInputMap[json] = res;
  }
  return res;
}
function reduceViewType(viewType, action) {
  switch (action.type) {
    case 'CHANGE_VIEW_TYPE':
      viewType = action.viewType;
  }
  return viewType;
}
function reduceCurrentDate(currentDate, action) {
  switch (action.type) {
    case 'CHANGE_DATE':
      return action.dateMarker;
    default:
      return currentDate;
  }
}
// should be initialized once and stay constant
// this will change too
function getInitialDate(options, dateEnv, nowManager) {
  let initialDateInput = options.initialDate;
  // compute the initial ambig-timezone date
  if (initialDateInput != null) {
    return dateEnv.createMarker(initialDateInput);
  }
  return nowManager.getDateMarker();
}
function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) {
  switch (action.type) {
    case 'SET_OPTION':
      return Object.assign(Object.assign({}, dynamicOptionOverrides), {
        [action.optionName]: action.rawOptionValue
      });
    default:
      return dynamicOptionOverrides;
  }
}
function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) {
  let dp;
  switch (action.type) {
    case 'CHANGE_VIEW_TYPE':
      return dateProfileGenerator.build(action.dateMarker || currentDate);
    case 'CHANGE_DATE':
      return dateProfileGenerator.build(action.dateMarker);
    case 'PREV':
      dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate);
      if (dp.isValid) {
        return dp;
      }
      break;
    case 'NEXT':
      dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate);
      if (dp.isValid) {
        return dp;
      }
      break;
  }
  return currentDateProfile;
}
function initEventSources(calendarOptions, dateProfile, context) {
  let activeRange = dateProfile ? dateProfile.activeRange : null;
  return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context);
}
function reduceEventSources(eventSources, action, dateProfile, context) {
  let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
  switch (action.type) {
    case 'ADD_EVENT_SOURCES':
      // already parsed
      return addSources(eventSources, action.sources, activeRange, context);
    case 'REMOVE_EVENT_SOURCE':
      return removeSource(eventSources, action.sourceId);
    case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
    case 'NEXT':
    case 'CHANGE_DATE':
    case 'CHANGE_VIEW_TYPE':
      if (dateProfile) {
        return fetchDirtySources(eventSources, activeRange, context);
      }
      return eventSources;
    case 'FETCH_EVENT_SOURCES':
      return fetchSourcesByIds(eventSources, action.sourceIds ?
      // why no type?
      (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(action.sourceIds) : excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context);
    case 'RECEIVE_EVENTS':
    case 'RECEIVE_EVENT_ERROR':
      return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange);
    case 'REMOVE_ALL_EVENT_SOURCES':
      return {};
    default:
      return eventSources;
  }
}
function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) {
  let activeRange = dateProfile ? dateProfile.activeRange : null; // need this check?
  return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context);
}
function computeEventSourcesLoading(eventSources) {
  for (let sourceId in eventSources) {
    if (eventSources[sourceId].isFetching) {
      return true;
    }
  }
  return false;
}
function addSources(eventSourceHash, sources, fetchRange, context) {
  let hash = {};
  for (let source of sources) {
    hash[source.sourceId] = source;
  }
  if (fetchRange) {
    hash = fetchDirtySources(hash, fetchRange, context);
  }
  return Object.assign(Object.assign({}, eventSourceHash), hash);
}
function removeSource(eventSourceHash, sourceId) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSourceHash, eventSource => eventSource.sourceId !== sourceId);
}
function fetchDirtySources(sourceHash, fetchRange, context) {
  return fetchSourcesByIds(sourceHash, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(sourceHash, eventSource => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context);
}
function isSourceDirty(eventSource, fetchRange, context) {
  if (!doesSourceNeedRange(eventSource, context)) {
    return !eventSource.latestFetchId;
  }
  return !context.options.lazyFetching || !eventSource.fetchRange || eventSource.isFetching ||
  // always cancel outdated in-progress fetches
  fetchRange.start < eventSource.fetchRange.start || fetchRange.end > eventSource.fetchRange.end;
}
function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) {
  let nextSources = {};
  for (let sourceId in prevSources) {
    let source = prevSources[sourceId];
    if (sourceIdHash[sourceId]) {
      nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context);
    } else {
      nextSources[sourceId] = source;
    }
  }
  return nextSources;
}
function fetchSource(eventSource, fetchRange, isRefetch, context) {
  let {
    options,
    calendarApi
  } = context;
  let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId];
  let fetchId = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.g)();
  sourceDef.fetch({
    eventSource,
    range: fetchRange,
    isRefetch,
    context
  }, res => {
    let {
      rawEvents
    } = res;
    if (options.eventSourceSuccess) {
      rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents;
    }
    if (eventSource.success) {
      rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents;
    }
    context.dispatch({
      type: 'RECEIVE_EVENTS',
      sourceId: eventSource.sourceId,
      fetchId,
      fetchRange,
      rawEvents
    });
  }, error => {
    let errorHandled = false;
    if (options.eventSourceFailure) {
      options.eventSourceFailure.call(calendarApi, error);
      errorHandled = true;
    }
    if (eventSource.failure) {
      eventSource.failure(error);
      errorHandled = true;
    }
    if (!errorHandled) {
      console.warn(error.message, error);
    }
    context.dispatch({
      type: 'RECEIVE_EVENT_ERROR',
      sourceId: eventSource.sourceId,
      fetchId,
      fetchRange,
      error
    });
  });
  return Object.assign(Object.assign({}, eventSource), {
    isFetching: true,
    latestFetchId: fetchId
  });
}
function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) {
  let eventSource = sourceHash[sourceId];
  if (eventSource &&
  // not already removed
  fetchId === eventSource.latestFetchId) {
    return Object.assign(Object.assign({}, sourceHash), {
      [sourceId]: Object.assign(Object.assign({}, eventSource), {
        isFetching: false,
        fetchRange
      })
    });
  }
  return sourceHash;
}
function excludeStaticSources(eventSources, context) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.h)(eventSources, eventSource => doesSourceNeedRange(eventSource, context));
}
function parseInitialSources(rawOptions, context) {
  let refiners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.j)(context);
  let rawSources = [].concat(rawOptions.eventSources || []);
  let sources = []; // parsed
  if (rawOptions.initialEvents) {
    rawSources.unshift(rawOptions.initialEvents);
  }
  if (rawOptions.events) {
    rawSources.unshift(rawOptions.events);
  }
  for (let rawSource of rawSources) {
    let source = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.p)(rawSource, context, refiners);
    if (source) {
      sources.push(source);
    }
  }
  return sources;
}
function doesSourceNeedRange(eventSource, context) {
  let defs = context.pluginHooks.eventSourceDefs;
  return !defs[eventSource.sourceDefId].ignoreRange;
}
function reduceDateSelection(currentSelection, action) {
  switch (action.type) {
    case 'UNSELECT_DATES':
      return null;
    case 'SELECT_DATES':
      return action.selection;
    default:
      return currentSelection;
  }
}
function reduceSelectedEvent(currentInstanceId, action) {
  switch (action.type) {
    case 'UNSELECT_EVENT':
      return '';
    case 'SELECT_EVENT':
      return action.eventInstanceId;
    default:
      return currentInstanceId;
  }
}
function reduceEventDrag(currentDrag, action) {
  let newDrag;
  switch (action.type) {
    case 'UNSET_EVENT_DRAG':
      return null;
    case 'SET_EVENT_DRAG':
      newDrag = action.state;
      return {
        affectedEvents: newDrag.affectedEvents,
        mutatedEvents: newDrag.mutatedEvents,
        isEvent: newDrag.isEvent
      };
    default:
      return currentDrag;
  }
}
function reduceEventResize(currentResize, action) {
  let newResize;
  switch (action.type) {
    case 'UNSET_EVENT_RESIZE':
      return null;
    case 'SET_EVENT_RESIZE':
      newResize = action.state;
      return {
        affectedEvents: newResize.affectedEvents,
        mutatedEvents: newResize.mutatedEvents,
        isEvent: newResize.isEvent
      };
    default:
      return currentResize;
  }
}
function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
  let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
  let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null;
  return {
    header,
    footer
  };
}
function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) {
  let sectionWidgets = {};
  let viewsWithButtons = [];
  let hasTitle = false;
  for (let sectionName in sectionStrHash) {
    let sectionStr = sectionStrHash[sectionName];
    let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi);
    sectionWidgets[sectionName] = sectionRes.widgets;
    viewsWithButtons.push(...sectionRes.viewsWithButtons);
    hasTitle = hasTitle || sectionRes.hasTitle;
  }
  return {
    sectionWidgets,
    viewsWithButtons,
    hasTitle
  };
}
/*
BAD: querying icons and text here. should be done at render time
*/
function parseSection(sectionStr, calendarOptions,
// defaults+overrides, then refined
calendarOptionOverrides,
// overrides only!, unrefined :(
theme, viewSpecs, calendarApi) {
  let isRtl = calendarOptions.direction === 'rtl';
  let calendarCustomButtons = calendarOptions.customButtons || {};
  let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {};
  let calendarButtonText = calendarOptions.buttonText || {};
  let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {};
  let calendarButtonHints = calendarOptions.buttonHints || {};
  let sectionSubstrs = sectionStr ? sectionStr.split(' ') : [];
  let viewsWithButtons = [];
  let hasTitle = false;
  let widgets = sectionSubstrs.map(buttonGroupStr => buttonGroupStr.split(',').map(buttonName => {
    if (buttonName === 'title') {
      hasTitle = true;
      return {
        buttonName
      };
    }
    let customButtonProps;
    let viewSpec;
    let buttonClick;
    let buttonIcon; // only one of these will be set
    let buttonText; // "
    let buttonHint;
    // ^ for the title="" attribute, for accessibility
    if (customButtonProps = calendarCustomButtons[buttonName]) {
      buttonClick = ev => {
        if (customButtonProps.click) {
          customButtonProps.click.call(ev.target, ev, ev.target); // TODO: use Calendar this context?
        }
      };
      (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = customButtonProps.text);
      buttonHint = customButtonProps.hint || customButtonProps.text;
    } else if (viewSpec = viewSpecs[buttonName]) {
      viewsWithButtons.push(buttonName);
      buttonClick = () => {
        calendarApi.changeView(buttonName);
      };
      (buttonText = viewSpec.buttonTextOverride) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = viewSpec.buttonTextDefault);
      let textFallback = viewSpec.buttonTextOverride || viewSpec.buttonTextDefault;
      buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(viewSpec.buttonTitleOverride || viewSpec.buttonTitleDefault || calendarOptions.viewHint, [textFallback, buttonName],
      // view-name = buttonName
      textFallback);
    } else if (calendarApi[buttonName]) {
      // a calendarApi method
      buttonClick = () => {
        calendarApi[buttonName]();
      };
      (buttonText = calendarButtonTextOverrides[buttonName]) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = calendarButtonText[buttonName]); // everything else is considered default
      if (buttonName === 'prevYear' || buttonName === 'nextYear') {
        let prevOrNext = buttonName === 'prevYear' ? 'prev' : 'next';
        buttonHint = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[prevOrNext] || calendarButtonHints[prevOrNext], [calendarButtonText.year || 'year', 'year'], calendarButtonText[buttonName]);
      } else {
        buttonHint = navUnit => (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.k)(calendarButtonHintOverrides[buttonName] || calendarButtonHints[buttonName], [calendarButtonText[navUnit] || navUnit, navUnit], calendarButtonText[buttonName]);
      }
    }
    return {
      buttonName,
      buttonClick,
      buttonIcon,
      buttonText,
      buttonHint
    };
  }));
  return {
    widgets,
    viewsWithButtons,
    hasTitle
  };
}

// always represents the current view. otherwise, it'd need to change value every time date changes
class ViewImpl {
  constructor(type, getCurrentData, dateEnv) {
    this.type = type;
    this.getCurrentData = getCurrentData;
    this.dateEnv = dateEnv;
  }
  get calendar() {
    return this.getCurrentData().calendarApi;
  }
  get title() {
    return this.getCurrentData().viewTitle;
  }
  get activeStart() {
    return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start);
  }
  get activeEnd() {
    return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end);
  }
  get currentStart() {
    return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start);
  }
  get currentEnd() {
    return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end);
  }
  getOption(name) {
    return this.getCurrentData().options[name]; // are the view-specific options
  }
}
let eventSourceDef$2 = {
  ignoreRange: true,
  parseMeta(refined) {
    if (Array.isArray(refined.events)) {
      return refined.events;
    }
    return null;
  },
  fetch(arg, successCallback) {
    successCallback({
      rawEvents: arg.eventSource.meta
    });
  }
};
const arrayEventSourcePlugin = createPlugin({
  name: 'array-event-source',
  eventSourceDefs: [eventSourceDef$2]
});
let eventSourceDef$1 = {
  parseMeta(refined) {
    if (typeof refined.events === 'function') {
      return refined.events;
    }
    return null;
  },
  fetch(arg, successCallback, errorCallback) {
    const {
      dateEnv
    } = arg.context;
    const func = arg.eventSource.meta;
    (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.u)(func.bind(null, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(arg.range, dateEnv)), rawEvents => successCallback({
      rawEvents
    }), errorCallback);
  }
};
const funcEventSourcePlugin = createPlugin({
  name: 'func-event-source',
  eventSourceDefs: [eventSourceDef$1]
});
const JSON_FEED_EVENT_SOURCE_REFINERS = {
  method: String,
  extraParams: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,
  startParam: String,
  endParam: String,
  timeZoneParam: String
};
let eventSourceDef = {
  parseMeta(refined) {
    if (refined.url && (refined.format === 'json' || !refined.format)) {
      return {
        url: refined.url,
        format: 'json',
        method: (refined.method || 'GET').toUpperCase(),
        extraParams: refined.extraParams,
        startParam: refined.startParam,
        endParam: refined.endParam,
        timeZoneParam: refined.timeZoneParam
      };
    }
    return null;
  },
  fetch(arg, successCallback, errorCallback) {
    const {
      meta
    } = arg.eventSource;
    const requestParams = buildRequestParams(meta, arg.range, arg.context);
    (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.r)(meta.method, meta.url, requestParams).then(([rawEvents, response]) => {
      successCallback({
        rawEvents,
        response
      });
    }, errorCallback);
  }
};
const jsonFeedEventSourcePlugin = createPlugin({
  name: 'json-event-source',
  eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS,
  eventSourceDefs: [eventSourceDef]
});
function buildRequestParams(meta, range, context) {
  let {
    dateEnv,
    options
  } = context;
  let startParam;
  let endParam;
  let timeZoneParam;
  let customRequestParams;
  let params = {};
  startParam = meta.startParam;
  if (startParam == null) {
    startParam = options.startParam;
  }
  endParam = meta.endParam;
  if (endParam == null) {
    endParam = options.endParam;
  }
  timeZoneParam = meta.timeZoneParam;
  if (timeZoneParam == null) {
    timeZoneParam = options.timeZoneParam;
  }
  // retrieve any outbound GET/POST data from the options
  if (typeof meta.extraParams === 'function') {
    // supplied as a function that returns a key/value object
    customRequestParams = meta.extraParams();
  } else {
    // probably supplied as a straight key/value object
    customRequestParams = meta.extraParams || {};
  }
  Object.assign(params, customRequestParams);
  params[startParam] = dateEnv.formatIso(range.start);
  params[endParam] = dateEnv.formatIso(range.end);
  if (dateEnv.timeZone !== 'local') {
    params[timeZoneParam] = dateEnv.timeZone;
  }
  return params;
}
const SIMPLE_RECURRING_REFINERS = {
  daysOfWeek: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,
  startTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,
  endTime: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,
  duration: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.d,
  startRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n,
  endRecur: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.n
};
let recurring = {
  parse(refined, dateEnv) {
    if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) {
      let recurringData = {
        daysOfWeek: refined.daysOfWeek || null,
        startTime: refined.startTime || null,
        endTime: refined.endTime || null,
        startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null,
        endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null,
        dateEnv
      };
      let duration;
      if (refined.duration) {
        duration = refined.duration;
      }
      if (!duration && refined.startTime && refined.endTime) {
        duration = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.s)(refined.endTime, refined.startTime);
      }
      return {
        allDayGuess: Boolean(!refined.startTime && !refined.endTime),
        duration,
        typeData: recurringData // doesn't need endTime anymore but oh well
      };
    }
    return null;
  },
  expand(typeData, framingRange, dateEnv) {
    let clippedFramingRange = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.o)(framingRange, {
      start: typeData.startRecur,
      end: typeData.endRecur
    });
    if (clippedFramingRange) {
      return expandRanges(typeData.daysOfWeek, typeData.startTime, typeData.dateEnv, dateEnv, clippedFramingRange);
    }
    return [];
  }
};
const simpleRecurringEventsPlugin = createPlugin({
  name: 'simple-recurring-event',
  recurringTypes: [recurring],
  eventRefiners: SIMPLE_RECURRING_REFINERS
});
function expandRanges(daysOfWeek, startTime, eventDateEnv, calendarDateEnv, framingRange) {
  let dowHash = daysOfWeek ? (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.f)(daysOfWeek) : null;
  let dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.q)(framingRange.start);
  let endMarker = framingRange.end;
  let instanceStarts = [];
  // https://github.com/fullcalendar/fullcalendar/issues/7934
  if (startTime) {
    if (startTime.milliseconds < 0) {
      // possible for next-day to have negative business hours that go into current day
      endMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(endMarker, 1);
    } else if (startTime.milliseconds >= 1000 * 60 * 60 * 24) {
      // possible for prev-day to have >24hr business hours that go into current day
      dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, -1);
    }
  }
  while (dayMarker < endMarker) {
    let instanceStart;
    // if everyday, or this particular day-of-week
    if (!dowHash || dowHash[dayMarker.getUTCDay()]) {
      if (startTime) {
        instanceStart = calendarDateEnv.add(dayMarker, startTime);
      } else {
        instanceStart = dayMarker;
      }
      instanceStarts.push(calendarDateEnv.createMarker(eventDateEnv.toDate(instanceStart)));
    }
    dayMarker = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayMarker, 1);
  }
  return instanceStarts;
}
const changeHandlerPlugin = createPlugin({
  name: 'change-handler',
  optionChangeHandlers: {
    events(events, context) {
      handleEventSources([events], context);
    },
    eventSources: handleEventSources
  }
});
/*
BUG: if `event` was supplied, all previously-given `eventSources` will be wiped out
*/
function handleEventSources(inputs, context) {
  let unfoundSources = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.v)(context.getCurrentData().eventSources);
  if (unfoundSources.length === 1 && inputs.length === 1 && Array.isArray(unfoundSources[0]._raw) && Array.isArray(inputs[0])) {
    context.dispatch({
      type: 'RESET_RAW_EVENTS',
      sourceId: unfoundSources[0].sourceId,
      rawEvents: inputs[0]
    });
    return;
  }
  let newInputs = [];
  for (let input of inputs) {
    let inputFound = false;
    for (let i = 0; i < unfoundSources.length; i += 1) {
      if (unfoundSources[i]._raw === input) {
        unfoundSources.splice(i, 1); // delete
        inputFound = true;
        break;
      }
    }
    if (!inputFound) {
      newInputs.push(input);
    }
  }
  for (let unfoundSource of unfoundSources) {
    context.dispatch({
      type: 'REMOVE_EVENT_SOURCE',
      sourceId: unfoundSource.sourceId
    });
  }
  for (let newInput of newInputs) {
    context.calendarApi.addEventSource(newInput);
  }
}
function handleDateProfile(dateProfile, context) {
  context.emitter.trigger('datesSet', Object.assign(Object.assign({}, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.l)(dateProfile.activeRange, context.dateEnv)), {
    view: context.viewApi
  }));
}
function handleEventStore(eventStore, context) {
  let {
    emitter
  } = context;
  if (emitter.hasHandlers('eventsSet')) {
    emitter.trigger('eventsSet', (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.w)(eventStore, context));
  }
}

/*
this array is exposed on the root namespace so that UMD plugins can add to it.
see the rollup-bundles script.
*/
const globalPlugins = [arrayEventSourcePlugin, funcEventSourcePlugin, jsonFeedEventSourcePlugin, simpleRecurringEventsPlugin, changeHandlerPlugin, createPlugin({
  name: 'misc',
  isLoadingFuncs: [state => computeEventSourcesLoading(state.eventSources)],
  propSetHandlers: {
    dateProfile: handleDateProfile,
    eventStore: handleEventStore
  }
})];
class TaskRunner {
  constructor(runTaskOption, drainedOption) {
    this.runTaskOption = runTaskOption;
    this.drainedOption = drainedOption;
    this.queue = [];
    this.delayedRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.drain.bind(this));
  }
  request(task, delay) {
    this.queue.push(task);
    this.delayedRunner.request(delay);
  }
  pause(scope) {
    this.delayedRunner.pause(scope);
  }
  resume(scope, force) {
    this.delayedRunner.resume(scope, force);
  }
  drain() {
    let {
      queue
    } = this;
    while (queue.length) {
      let completedTasks = [];
      let task;
      while (task = queue.shift()) {
        this.runTask(task);
        completedTasks.push(task);
      }
      this.drained(completedTasks);
    } // keep going, in case new tasks were added in the drained handler
  }
  runTask(task) {
    if (this.runTaskOption) {
      this.runTaskOption(task);
    }
  }
  drained(completedTasks) {
    if (this.drainedOption) {
      this.drainedOption(completedTasks);
    }
  }
}

// Computes what the title at the top of the calendarApi should be for this view
function buildTitle(dateProfile, viewOptions, dateEnv) {
  let range;
  // for views that span a large unit of time, show the proper interval, ignoring stray days before and after
  if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) {
    range = dateProfile.currentRange;
  } else {
    // for day units or smaller, use the actual day range
    range = dateProfile.activeRange;
  }
  return dateEnv.formatRange(range.start, range.end, (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(viewOptions.titleFormat || buildTitleFormat(dateProfile)), {
    isEndExclusive: dateProfile.isRangeAllDay,
    defaultSeparator: viewOptions.titleRangeSeparator
  });
}
// Generates the format string that should be used to generate the title for the current date range.
// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.
function buildTitleFormat(dateProfile) {
  let {
    currentRangeUnit
  } = dateProfile;
  if (currentRangeUnit === 'year') {
    return {
      year: 'numeric'
    };
  }
  if (currentRangeUnit === 'month') {
    return {
      year: 'numeric',
      month: 'long'
    }; // like "September 2014"
  }
  let days = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.y)(dateProfile.currentRange.start, dateProfile.currentRange.end);
  if (days !== null && days > 1) {
    // multi-day range. shorter, like "Sep 9 - 10 2014"
    return {
      year: 'numeric',
      month: 'short',
      day: 'numeric'
    };
  }
  // one day. longer, like "September 9 2014"
  return {
    year: 'numeric',
    month: 'long',
    day: 'numeric'
  };
}

/*
TODO: test switching timezones when NO timezone plugin
*/
class CalendarNowManager {
  constructor() {
    this.resetListeners = new Set();
  }
  handleInput(dateEnv,
  // will change if timezone setup changed
  nowInput) {
    const oldDateEnv = this.dateEnv;
    if (dateEnv !== oldDateEnv) {
      if (typeof nowInput === 'function') {
        this.nowFn = nowInput;
      } else if (!oldDateEnv) {
        // first time?
        this.nowAnchorDate = dateEnv.toDate(nowInput ? dateEnv.createMarker(nowInput) : dateEnv.createNowMarker());
        this.nowAnchorQueried = Date.now();
      }
      this.dateEnv = dateEnv;
      // not first time? fire reset handlers
      if (oldDateEnv) {
        for (const resetListener of this.resetListeners.values()) {
          resetListener();
        }
      }
    }
  }
  getDateMarker() {
    return this.nowAnchorDate ? this.dateEnv.timestampToMarker(this.nowAnchorDate.valueOf() + (Date.now() - this.nowAnchorQueried)) : this.dateEnv.createMarker(this.nowFn());
  }
  addResetListener(handler) {
    this.resetListeners.add(handler);
  }
  removeResetListener(handler) {
    this.resetListeners.delete(handler);
  }
}

// in future refactor, do the redux-style function(state=initial) for initial-state
// also, whatever is happening in constructor, have it happen in action queue too
class CalendarDataManager {
  constructor(props) {
    this.computeCurrentViewData = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._computeCurrentViewData);
    this.organizeRawLocales = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(organizeRawLocales);
    this.buildLocale = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildLocale);
    this.buildPluginHooks = buildBuildPluginHooks();
    this.buildDateEnv = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDateEnv$1);
    this.buildTheme = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTheme);
    this.parseToolbars = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(parseToolbars);
    this.buildViewSpecs = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewSpecs);
    this.buildDateProfileGenerator = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildDateProfileGenerator);
    this.buildViewApi = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewApi);
    this.buildViewUiProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(buildViewUiProps);
    this.buildEventUiBySource = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBySource, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.E);
    this.buildEventUiBases = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildEventUiBases);
    this.parseContextBusinessHours = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.A)(parseContextBusinessHours);
    this.buildTitle = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTitle);
    this.nowManager = new CalendarNowManager();
    this.emitter = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.F();
    this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this));
    this.currentCalendarOptionsInput = {};
    this.currentCalendarOptionsRefined = {};
    this.currentViewOptionsInput = {};
    this.currentViewOptionsRefined = {};
    this.currentCalendarOptionsRefiners = {};
    this.optionsForRefining = [];
    this.optionsForHandling = [];
    this.getCurrentData = () => this.data;
    this.dispatch = action => {
      this.actionRunner.request(action); // protects against recursive calls to _handleAction
    };
    this.props = props;
    this.actionRunner.pause();
    this.nowManager = new CalendarNowManager();
    let dynamicOptionOverrides = {};
    let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
    let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView;
    let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
    // wire things up
    // TODO: not DRY
    props.calendarApi.currentDataManager = this;
    this.emitter.setThisContext(props.calendarApi);
    this.emitter.setOptions(currentViewData.options);
    let calendarContext = {
      nowManager: this.nowManager,
      dateEnv: optionsData.dateEnv,
      options: optionsData.calendarOptions,
      pluginHooks: optionsData.pluginHooks,
      calendarApi: props.calendarApi,
      dispatch: this.dispatch,
      emitter: this.emitter,
      getCurrentData: this.getCurrentData
    };
    let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv, this.nowManager);
    let dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
    if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.activeRange, currentDate)) {
      currentDate = dateProfile.currentRange.start;
    }
    // needs to be after setThisContext
    for (let callback of optionsData.pluginHooks.contextInit) {
      callback(calendarContext);
    }
    // NOT DRY
    let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext);
    let initialState = {
      dynamicOptionOverrides,
      currentViewType,
      currentDate,
      dateProfile,
      businessHours: this.parseContextBusinessHours(calendarContext),
      eventSources,
      eventUiBases: {},
      eventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
      renderableEventStore: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
      dateSelection: null,
      eventSelection: '',
      eventDrag: null,
      eventResize: null,
      selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig
    };
    let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState);
    for (let reducer of optionsData.pluginHooks.reducers) {
      Object.assign(initialState, reducer(null, null, contextAndState));
    }
    if (computeIsLoading(initialState, calendarContext)) {
      this.emitter.trigger('loading', true); // NOT DRY
    }
    this.state = initialState;
    this.updateData();
    this.actionRunner.resume();
  }
  resetOptions(optionOverrides, changedOptionNames) {
    let {
      props
    } = this;
    if (changedOptionNames === undefined) {
      props.optionOverrides = optionOverrides;
    } else {
      props.optionOverrides = Object.assign(Object.assign({}, props.optionOverrides || {}), optionOverrides);
      this.optionsForRefining.push(...changedOptionNames);
    }
    if (changedOptionNames === undefined || changedOptionNames.length) {
      this.actionRunner.request({
        type: 'NOTHING'
      });
    }
  }
  _handleAction(action) {
    let {
      props,
      state,
      emitter
    } = this;
    let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action);
    let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
    let currentViewType = reduceViewType(state.currentViewType, action);
    let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides);
    // wire things up
    // TODO: not DRY
    props.calendarApi.currentDataManager = this;
    emitter.setThisContext(props.calendarApi);
    emitter.setOptions(currentViewData.options);
    let calendarContext = {
      nowManager: this.nowManager,
      dateEnv: optionsData.dateEnv,
      options: optionsData.calendarOptions,
      pluginHooks: optionsData.pluginHooks,
      calendarApi: props.calendarApi,
      dispatch: this.dispatch,
      emitter,
      getCurrentData: this.getCurrentData
    };
    let {
      currentDate,
      dateProfile
    } = state;
    if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) {
      // hack
      dateProfile = currentViewData.dateProfileGenerator.build(currentDate);
    }
    currentDate = reduceCurrentDate(currentDate, action);
    dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator);
    if (action.type === 'PREV' ||
    // TODO: move this logic into DateProfileGenerator
    action.type === 'NEXT' ||
    // "
    !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, currentDate)) {
      currentDate = dateProfile.currentRange.start;
    }
    let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext);
    let eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.I)(state.eventStore, action, eventSources, dateProfile, calendarContext);
    let isEventsLoading = computeEventSourcesLoading(eventSources); // BAD. also called in this func in computeIsLoading
    let renderableEventStore = isEventsLoading && !currentViewData.options.progressiveEventRendering ? state.renderableEventStore || eventStore :
    // try from previous state
    eventStore;
    let {
      eventUiSingleBase,
      selectionConfig
    } = this.buildViewUiProps(calendarContext); // will memoize obj
    let eventUiBySource = this.buildEventUiBySource(eventSources);
    let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource);
    let newState = {
      dynamicOptionOverrides,
      currentViewType,
      currentDate,
      dateProfile,
      eventSources,
      eventStore,
      renderableEventStore,
      selectionConfig,
      eventUiBases,
      businessHours: this.parseContextBusinessHours(calendarContext),
      dateSelection: reduceDateSelection(state.dateSelection, action),
      eventSelection: reduceSelectedEvent(state.eventSelection, action),
      eventDrag: reduceEventDrag(state.eventDrag, action),
      eventResize: reduceEventResize(state.eventResize, action)
    };
    let contextAndState = Object.assign(Object.assign({}, calendarContext), newState);
    for (let reducer of optionsData.pluginHooks.reducers) {
      Object.assign(newState, reducer(state, action, contextAndState)); // give the OLD state, for old value
    }
    let wasLoading = computeIsLoading(state, calendarContext);
    let isLoading = computeIsLoading(newState, calendarContext);
    // TODO: use propSetHandlers in plugin system
    if (!wasLoading && isLoading) {
      emitter.trigger('loading', true);
    } else if (wasLoading && !isLoading) {
      emitter.trigger('loading', false);
    }
    this.state = newState;
    if (props.onAction) {
      props.onAction(action);
    }
  }
  updateData() {
    let {
      props,
      state
    } = this;
    let oldData = this.data;
    let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi);
    let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides);
    let data = this.data = Object.assign(Object.assign(Object.assign({
      nowManager: this.nowManager,
      viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv),
      calendarApi: props.calendarApi,
      dispatch: this.dispatch,
      emitter: this.emitter,
      getCurrentData: this.getCurrentData
    }, optionsData), currentViewData), state);
    let changeHandlers = optionsData.pluginHooks.optionChangeHandlers;
    let oldCalendarOptions = oldData && oldData.calendarOptions;
    let newCalendarOptions = optionsData.calendarOptions;
    if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) {
      if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) {
        // hack
        state.eventSources = data.eventSources = reduceEventSourcesNewTimeZone(data.eventSources, state.dateProfile, data);
        state.eventStore = data.eventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.eventStore, oldData.dateEnv, data.dateEnv);
        state.renderableEventStore = data.renderableEventStore = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.J)(data.renderableEventStore, oldData.dateEnv, data.dateEnv);
      }
      for (let optionName in changeHandlers) {
        if (this.optionsForHandling.indexOf(optionName) !== -1 || oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) {
          changeHandlers[optionName](newCalendarOptions[optionName], data);
        }
      }
    }
    this.optionsForHandling = [];
    if (props.onData) {
      props.onData(data);
    }
  }
  computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) {
    // TODO: blacklist options that are handled by optionChangeHandlers
    if (!this.optionsForRefining.length && optionOverrides === this.stableOptionOverrides && dynamicOptionOverrides === this.stableDynamicOptionOverrides) {
      return this.stableCalendarOptionsData;
    }
    let {
      refinedOptions,
      pluginHooks,
      localeDefaults,
      availableLocaleData,
      extra
    } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides);
    warnUnknownOptions(extra);
    let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator);
    let viewSpecs = this.buildViewSpecs(pluginHooks.views, this.stableOptionOverrides, this.stableDynamicOptionOverrides, localeDefaults);
    let theme = this.buildTheme(refinedOptions, pluginHooks);
    let toolbarConfig = this.parseToolbars(refinedOptions, this.stableOptionOverrides, theme, viewSpecs, calendarApi);
    return this.stableCalendarOptionsData = {
      calendarOptions: refinedOptions,
      pluginHooks,
      dateEnv,
      viewSpecs,
      theme,
      toolbarConfig,
      localeDefaults,
      availableRawLocales: availableLocaleData.map
    };
  }
  // always called from behind a memoizer
  processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) {
    let {
      locales,
      locale
    } = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e, optionOverrides, dynamicOptionOverrides]);
    let availableLocaleData = this.organizeRawLocales(locales);
    let availableRawLocales = availableLocaleData.map;
    let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options;
    let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins);
    let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
    let extra = {};
    let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e, localeDefaults, optionOverrides, dynamicOptionOverrides]);
    let refined = {};
    let currentRaw = this.currentCalendarOptionsInput;
    let currentRefined = this.currentCalendarOptionsRefined;
    let anyChanges = false;
    for (let optionName in raw) {
      if (this.optionsForRefining.indexOf(optionName) === -1 && (raw[optionName] === currentRaw[optionName] || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] && optionName in currentRaw && _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](currentRaw[optionName], raw[optionName]))) {
        refined[optionName] = currentRefined[optionName];
      } else if (refiners[optionName]) {
        refined[optionName] = refiners[optionName](raw[optionName]);
        anyChanges = true;
      } else {
        extra[optionName] = currentRaw[optionName];
      }
    }
    if (anyChanges) {
      this.currentCalendarOptionsInput = raw;
      this.currentCalendarOptionsRefined = refined;
      this.stableOptionOverrides = optionOverrides;
      this.stableDynamicOptionOverrides = dynamicOptionOverrides;
    }
    this.optionsForHandling.push(...this.optionsForRefining);
    this.optionsForRefining = [];
    return {
      rawOptions: this.currentCalendarOptionsInput,
      refinedOptions: this.currentCalendarOptionsRefined,
      pluginHooks,
      availableLocaleData,
      localeDefaults,
      extra
    };
  }
  _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) {
    let viewSpec = optionsData.viewSpecs[viewType];
    if (!viewSpec) {
      throw new Error(`viewType "${viewType}" is not available. Please make sure you've loaded all neccessary plugins`);
    }
    let {
      refinedOptions,
      extra
    } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides);
    warnUnknownOptions(extra);
    this.nowManager.handleInput(optionsData.dateEnv, refinedOptions.now);
    let dateProfileGenerator = this.buildDateProfileGenerator({
      dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass,
      nowManager: this.nowManager,
      duration: viewSpec.duration,
      durationUnit: viewSpec.durationUnit,
      usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime,
      dateEnv: optionsData.dateEnv,
      calendarApi: this.props.calendarApi,
      slotMinTime: refinedOptions.slotMinTime,
      slotMaxTime: refinedOptions.slotMaxTime,
      showNonCurrentDates: refinedOptions.showNonCurrentDates,
      dayCount: refinedOptions.dayCount,
      dateAlignment: refinedOptions.dateAlignment,
      dateIncrement: refinedOptions.dateIncrement,
      hiddenDays: refinedOptions.hiddenDays,
      weekends: refinedOptions.weekends,
      validRangeInput: refinedOptions.validRange,
      visibleRangeInput: refinedOptions.visibleRange,
      fixedWeekCount: refinedOptions.fixedWeekCount
    });
    let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv);
    return {
      viewSpec,
      options: refinedOptions,
      dateProfileGenerator,
      viewApi
    };
  }
  processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) {
    let raw = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.K)([_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e, viewSpec.optionDefaults, localeDefaults, optionOverrides, viewSpec.optionOverrides, dynamicOptionOverrides]);
    let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.L), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.M), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.N), _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.P), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
    let refined = {};
    let currentRaw = this.currentViewOptionsInput;
    let currentRefined = this.currentViewOptionsRefined;
    let anyChanges = false;
    let extra = {};
    for (let optionName in raw) {
      if (raw[optionName] === currentRaw[optionName] || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] && _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], currentRaw[optionName])) {
        refined[optionName] = currentRefined[optionName];
      } else {
        if (raw[optionName] === this.currentCalendarOptionsInput[optionName] || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName] && _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.O[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName])) {
          if (optionName in this.currentCalendarOptionsRefined) {
            // might be an "extra" prop
            refined[optionName] = this.currentCalendarOptionsRefined[optionName];
          }
        } else if (refiners[optionName]) {
          refined[optionName] = refiners[optionName](raw[optionName]);
        } else {
          extra[optionName] = raw[optionName];
        }
        anyChanges = true;
      }
    }
    if (anyChanges) {
      this.currentViewOptionsInput = raw;
      this.currentViewOptionsRefined = refined;
    }
    return {
      rawOptions: this.currentViewOptionsInput,
      refinedOptions: this.currentViewOptionsRefined,
      extra
    };
  }
}
function buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) {
  let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map);
  return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q({
    calendarSystem: 'gregory',
    timeZone,
    namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl,
    locale,
    weekNumberCalculation,
    firstDay,
    weekText,
    cmdFormatter: pluginHooks.cmdFormatter,
    defaultSeparator
  });
}
function buildTheme(options, pluginHooks) {
  let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme;
  return new ThemeClass(options);
}
function buildDateProfileGenerator(props) {
  let DateProfileGeneratorClass = props.dateProfileGeneratorClass || _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.R;
  return new DateProfileGeneratorClass(props);
}
function buildViewApi(type, getCurrentData, dateEnv) {
  return new ViewImpl(type, getCurrentData, dateEnv);
}
function buildEventUiBySource(eventSources) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a)(eventSources, eventSource => eventSource.ui);
}
function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) {
  let eventUiBases = {
    '': eventUiSingleBase
  };
  for (let defId in eventDefs) {
    let def = eventDefs[defId];
    if (def.sourceId && eventUiBySource[def.sourceId]) {
      eventUiBases[defId] = eventUiBySource[def.sourceId];
    }
  }
  return eventUiBases;
}
function buildViewUiProps(calendarContext) {
  let {
    options
  } = calendarContext;
  return {
    eventUiSingleBase: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({
      display: options.eventDisplay,
      editable: options.editable,
      startEditable: options.eventStartEditable,
      durationEditable: options.eventDurationEditable,
      constraint: options.eventConstraint,
      overlap: typeof options.eventOverlap === 'boolean' ? options.eventOverlap : undefined,
      allow: options.eventAllow,
      backgroundColor: options.eventBackgroundColor,
      borderColor: options.eventBorderColor,
      textColor: options.eventTextColor,
      color: options.eventColor
      // classNames: options.eventClassNames // render hook will handle this
    }, calendarContext),
    selectionConfig: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.S)({
      constraint: options.selectConstraint,
      overlap: typeof options.selectOverlap === 'boolean' ? options.selectOverlap : undefined,
      allow: options.selectAllow
    }, calendarContext)
  };
}
function computeIsLoading(state, context) {
  for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) {
    if (isLoadingFunc(state)) {
      return true;
    }
  }
  return false;
}
function parseContextBusinessHours(calendarContext) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.U)(calendarContext.options.businessHours, calendarContext);
}
function warnUnknownOptions(options, viewName) {
  for (let optionName in options) {
    console.warn(`Unknown option '${optionName}'` + (viewName ? ` for view '${viewName}'` : ''));
  }
}
class ToolbarSection extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let children = this.props.widgetGroups.map(widgetGroup => this.renderWidgetGroup(widgetGroup));
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', {
      className: 'fc-toolbar-chunk'
    }, ...children);
  }
  renderWidgetGroup(widgetGroup) {
    let {
      props
    } = this;
    let {
      theme
    } = this.context;
    let children = [];
    let isOnlyButtons = true;
    for (let widget of widgetGroup) {
      let {
        buttonName,
        buttonClick,
        buttonText,
        buttonIcon,
        buttonHint
      } = widget;
      if (buttonName === 'title') {
        isOnlyButtons = false;
        children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)("h2", {
          className: "fc-toolbar-title",
          id: props.titleId
        }, props.title));
      } else {
        let isPressed = buttonName === props.activeButton;
        let isDisabled = !props.isTodayEnabled && buttonName === 'today' || !props.isPrevEnabled && buttonName === 'prev' || !props.isNextEnabled && buttonName === 'next';
        let buttonClasses = [`fc-${buttonName}-button`, theme.getClass('button')];
        if (isPressed) {
          buttonClasses.push(theme.getClass('buttonActive'));
        }
        children.push((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)("button", {
          type: "button",
          title: typeof buttonHint === 'function' ? buttonHint(props.navUnit) : buttonHint,
          disabled: isDisabled,
          "aria-pressed": isPressed,
          className: buttonClasses.join(' '),
          onClick: buttonClick
        }, buttonText || (buttonIcon ? (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)("span", {
          className: buttonIcon,
          role: "img"
        }) : '')));
      }
    }
    if (children.length > 1) {
      let groupClassName = isOnlyButtons && theme.getClass('buttonGroup') || '';
      return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)('div', {
        className: groupClassName
      }, ...children);
    }
    return children[0];
  }
}
class Toolbar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      model,
      extraClassName
    } = this.props;
    let forceLtr = false;
    let startContent;
    let endContent;
    let sectionWidgets = model.sectionWidgets;
    let centerContent = sectionWidgets.center;
    if (sectionWidgets.left) {
      forceLtr = true;
      startContent = sectionWidgets.left;
    } else {
      startContent = sectionWidgets.start;
    }
    if (sectionWidgets.right) {
      forceLtr = true;
      endContent = sectionWidgets.right;
    } else {
      endContent = sectionWidgets.end;
    }
    let classNames = [extraClassName || '', 'fc-toolbar', forceLtr ? 'fc-toolbar-ltr' : ''];
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: classNames.join(' ')
    }, this.renderSection('start', startContent || []), this.renderSection('center', centerContent || []), this.renderSection('end', endContent || []));
  }
  renderSection(key, widgetGroups) {
    let {
      props
    } = this;
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ToolbarSection, {
      key: key,
      widgetGroups: widgetGroups,
      title: props.title,
      navUnit: props.navUnit,
      activeButton: props.activeButton,
      isTodayEnabled: props.isTodayEnabled,
      isPrevEnabled: props.isPrevEnabled,
      isNextEnabled: props.isNextEnabled,
      titleId: props.titleId
    });
  }
}
class ViewHarness extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.state = {
      availableWidth: null
    };
    this.handleEl = el => {
      this.el = el;
      (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.W)(this.props.elRef, el);
      this.updateAvailableWidth();
    };
    this.handleResize = () => {
      this.updateAvailableWidth();
    };
  }
  render() {
    let {
      props,
      state
    } = this;
    let {
      aspectRatio
    } = props;
    let classNames = ['fc-view-harness', aspectRatio || props.liquid || props.height ? 'fc-view-harness-active' // harness controls the height
    : 'fc-view-harness-passive' // let the view do the height
    ];
    let height = '';
    let paddingBottom = '';
    if (aspectRatio) {
      if (state.availableWidth !== null) {
        height = state.availableWidth / aspectRatio;
      } else {
        // while waiting to know availableWidth, we can't set height to *zero*
        // because will cause lots of unnecessary scrollbars within scrollgrid.
        // BETTER: don't start rendering ANYTHING yet until we know container width
        // NOTE: why not always use paddingBottom? Causes height oscillation (issue 5606)
        paddingBottom = `${1 / aspectRatio * 100}%`;
      }
    } else {
      height = props.height || '';
    }
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      "aria-labelledby": props.labeledById,
      ref: this.handleEl,
      className: classNames.join(' '),
      style: {
        height,
        paddingBottom
      }
    }, props.children);
  }
  componentDidMount() {
    this.context.addResizeHandler(this.handleResize);
  }
  componentWillUnmount() {
    this.context.removeResizeHandler(this.handleResize);
  }
  updateAvailableWidth() {
    if (this.el &&
    // needed. but why?
    this.props.aspectRatio // aspectRatio is the only height setting that needs availableWidth
    ) {
      this.setState({
        availableWidth: this.el.offsetWidth
      });
    }
  }
}

/*
Detects when the user clicks on an event within a DateComponent
*/
class EventClicking extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    this.handleSegClick = (ev, segEl) => {
      let {
        component
      } = this;
      let {
        context
      } = component;
      let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);
      if (seg &&
      // might be the <div> surrounding the more link
      component.isValidSegDownEl(ev.target)) {
        // our way to simulate a link click for elements that can't be <a> tags
        // grab before trigger fired in case trigger trashes DOM thru rerendering
        let hasUrlContainer = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ev.target, '.fc-event-forced-url');
        let url = hasUrlContainer ? hasUrlContainer.querySelector('a[href]').href : '';
        context.emitter.trigger('eventClick', {
          el: segEl,
          event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(component.context, seg.eventRange.def, seg.eventRange.instance),
          jsEvent: ev,
          view: context.viewApi
        });
        if (url && !ev.defaultPrevented) {
          window.location.href = url;
        }
      }
    };
    this.destroy = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.$)(settings.el, 'click', '.fc-event',
    // on both fg and bg events
    this.handleSegClick);
  }
}

/*
Triggers events and adds/removes core classNames when the user's pointer
enters/leaves event-elements of a component.
*/
class EventHovering extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    // for simulating an eventMouseLeave when the event el is destroyed while mouse is over it
    this.handleEventElRemove = el => {
      if (el === this.currentSegEl) {
        this.handleSegLeave(null, this.currentSegEl);
      }
    };
    this.handleSegEnter = (ev, segEl) => {
      if ((0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl)) {
        // TODO: better way to make sure not hovering over more+ link or its wrapper
        this.currentSegEl = segEl;
        this.triggerEvent('eventMouseEnter', ev, segEl);
      }
    };
    this.handleSegLeave = (ev, segEl) => {
      if (this.currentSegEl) {
        this.currentSegEl = null;
        this.triggerEvent('eventMouseLeave', ev, segEl);
      }
    };
    this.removeHoverListeners = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a0)(settings.el, '.fc-event',
    // on both fg and bg events
    this.handleSegEnter, this.handleSegLeave);
  }
  destroy() {
    this.removeHoverListeners();
  }
  triggerEvent(publicEvName, ev, segEl) {
    let {
      component
    } = this;
    let {
      context
    } = component;
    let seg = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);
    if (!ev || component.isValidSegDownEl(ev.target)) {
      context.emitter.trigger(publicEvName, {
        el: segEl,
        event: new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__._(context, seg.eventRange.def, seg.eventRange.instance),
        jsEvent: ev,
        view: context.viewApi
      });
    }
  }
}
class CalendarContent extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a1 {
  constructor() {
    super(...arguments);
    this.buildViewContext = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a2);
    this.buildViewPropTransformers = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildViewPropTransformers);
    this.buildToolbarProps = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildToolbarProps);
    this.headerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.footerRef = (0,preact__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.interactionsStore = {};
    // eslint-disable-next-line
    this.state = {
      viewLabelId: (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a3)()
    };
    // Component Registration
    // -----------------------------------------------------------------------------------------------------------------
    this.registerInteractiveComponent = (component, settingsInput) => {
      let settings = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a4)(component, settingsInput);
      let DEFAULT_INTERACTIONS = [EventClicking, EventHovering];
      let interactionClasses = DEFAULT_INTERACTIONS.concat(this.props.pluginHooks.componentInteractions);
      let interactions = interactionClasses.map(TheInteractionClass => new TheInteractionClass(settings));
      this.interactionsStore[component.uid] = interactions;
      _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid] = settings;
    };
    this.unregisterInteractiveComponent = component => {
      let listeners = this.interactionsStore[component.uid];
      if (listeners) {
        for (let listener of listeners) {
          listener.destroy();
        }
        delete this.interactionsStore[component.uid];
      }
      delete _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a5[component.uid];
    };
    // Resizing
    // -----------------------------------------------------------------------------------------------------------------
    this.resizeRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(() => {
      this.props.emitter.trigger('_resize', true); // should window resizes be considered "forced" ?
      this.props.emitter.trigger('windowResize', {
        view: this.props.viewApi
      });
    });
    this.handleWindowResize = ev => {
      let {
        options
      } = this.props;
      if (options.handleWindowResize && ev.target === window // avoid jqui events
      ) {
        this.resizeRunner.request(options.windowResizeDelay);
      }
    };
  }
  /*
  renders INSIDE of an outer div
  */
  render() {
    let {
      props
    } = this;
    let {
      toolbarConfig,
      options
    } = props;
    let viewVGrow = false;
    let viewHeight = '';
    let viewAspectRatio;
    if (props.isHeightAuto || props.forPrint) {
      viewHeight = '';
    } else if (options.height != null) {
      viewVGrow = true;
    } else if (options.contentHeight != null) {
      viewHeight = options.contentHeight;
    } else {
      viewAspectRatio = Math.max(options.aspectRatio, 0.5); // prevent from getting too tall
    }
    let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.nowManager, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent);
    let viewLabelId = toolbarConfig.header && toolbarConfig.header.hasTitle ? this.state.viewLabelId : undefined;
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.V.Provider, {
      value: viewContext
    }, (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a6, {
      unit: "day"
    }, nowDate => {
      let toolbarProps = this.buildToolbarProps(props.viewSpec, props.dateProfile, props.dateProfileGenerator, props.currentDate, nowDate, props.viewTitle);
      return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, toolbarConfig.header && (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({
        ref: this.headerRef,
        extraClassName: "fc-header-toolbar",
        model: toolbarConfig.header,
        titleId: viewLabelId
      }, toolbarProps)), (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewHarness, {
        liquid: viewVGrow,
        height: viewHeight,
        aspectRatio: viewAspectRatio,
        labeledById: viewLabelId
      }, this.renderView(props), this.buildAppendContent()), toolbarConfig.footer && (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(Toolbar, Object.assign({
        ref: this.footerRef,
        extraClassName: "fc-footer-toolbar",
        model: toolbarConfig.footer,
        titleId: ""
      }, toolbarProps)));
    }));
  }
  componentDidMount() {
    let {
      props
    } = this;
    this.calendarInteractions = props.pluginHooks.calendarInteractions.map(CalendarInteractionClass => new CalendarInteractionClass(props));
    window.addEventListener('resize', this.handleWindowResize);
    let {
      propSetHandlers
    } = props.pluginHooks;
    for (let propName in propSetHandlers) {
      propSetHandlers[propName](props[propName], props);
    }
  }
  componentDidUpdate(prevProps) {
    let {
      props
    } = this;
    let {
      propSetHandlers
    } = props.pluginHooks;
    for (let propName in propSetHandlers) {
      if (props[propName] !== prevProps[propName]) {
        propSetHandlers[propName](props[propName], props);
      }
    }
  }
  componentWillUnmount() {
    window.removeEventListener('resize', this.handleWindowResize);
    this.resizeRunner.clear();
    for (let interaction of this.calendarInteractions) {
      interaction.destroy();
    }
    this.props.emitter.trigger('_unmount');
  }
  buildAppendContent() {
    let {
      props
    } = this;
    let children = props.pluginHooks.viewContainerAppends.map(buildAppendContent => buildAppendContent(props));
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(preact__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...children);
  }
  renderView(props) {
    let {
      pluginHooks
    } = props;
    let {
      viewSpec
    } = props;
    let viewProps = {
      dateProfile: props.dateProfile,
      businessHours: props.businessHours,
      eventStore: props.renderableEventStore,
      eventUiBases: props.eventUiBases,
      dateSelection: props.dateSelection,
      eventSelection: props.eventSelection,
      eventDrag: props.eventDrag,
      eventResize: props.eventResize,
      isHeightAuto: props.isHeightAuto,
      forPrint: props.forPrint
    };
    let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers);
    for (let transformer of transformers) {
      Object.assign(viewProps, transformer.transform(viewProps, props));
    }
    let ViewComponent = viewSpec.component;
    return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(ViewComponent, Object.assign({}, viewProps));
  }
}
function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) {
  // don't force any date-profiles to valid date profiles (the `false`) so that we can tell if it's invalid
  let todayInfo = dateProfileGenerator.build(now, undefined, false); // TODO: need `undefined` or else INFINITE LOOP for some reason
  let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false);
  let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false);
  return {
    title,
    activeButton: viewSpec.type,
    navUnit: viewSpec.singleUnit,
    isTodayEnabled: todayInfo.isValid && !(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, now),
    isPrevEnabled: prevInfo.isValid,
    isNextEnabled: nextInfo.isValid
  };
}
// Plugin
// -----------------------------------------------------------------------------------------------------------------
function buildViewPropTransformers(theClasses) {
  return theClasses.map(TheClass => new TheClass());
}
class Calendar extends _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a7 {
  constructor(el, optionOverrides = {}) {
    super();
    this.isRendering = false;
    this.isRendered = false;
    this.currentClassNames = [];
    this.customContentRenderId = 0;
    this.handleAction = action => {
      // actions we know we want to render immediately
      switch (action.type) {
        case 'SET_EVENT_DRAG':
        case 'SET_EVENT_RESIZE':
          this.renderRunner.tryDrain();
      }
    };
    this.handleData = data => {
      this.currentData = data;
      this.renderRunner.request(data.calendarOptions.rerenderDelay);
    };
    this.handleRenderRequest = () => {
      if (this.isRendering) {
        this.isRendered = true;
        let {
          currentData
        } = this;
        (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {
          (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)((0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a9, {
            options: currentData.calendarOptions,
            theme: currentData.theme,
            emitter: currentData.emitter
          }, (classNames, height, isHeightAuto, forPrint) => {
            this.setClassNames(classNames);
            this.setHeight(height);
            return (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.aa.Provider, {
              value: this.customContentRenderId
            }, (0,preact__WEBPACK_IMPORTED_MODULE_1__.createElement)(CalendarContent, Object.assign({
              isHeightAuto: isHeightAuto,
              forPrint: forPrint
            }, currentData)));
          }), this.el);
        });
      } else if (this.isRendered) {
        this.isRendered = false;
        (0,preact__WEBPACK_IMPORTED_MODULE_1__.render)(null, this.el);
        this.setClassNames([]);
        this.setHeight('');
      }
    };
    (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ab)(el);
    this.el = el;
    this.renderRunner = new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.D(this.handleRenderRequest);
    new CalendarDataManager({
      optionOverrides,
      calendarApi: this,
      onAction: this.handleAction,
      onData: this.handleData
    });
  }
  render() {
    let wasRendering = this.isRendering;
    if (!wasRendering) {
      this.isRendering = true;
    } else {
      this.customContentRenderId += 1;
    }
    this.renderRunner.request();
    if (wasRendering) {
      this.updateSize();
    }
  }
  destroy() {
    if (this.isRendering) {
      this.isRendering = false;
      this.renderRunner.request();
    }
  }
  updateSize() {
    (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.a8)(() => {
      super.updateSize();
    });
  }
  batchRendering(func) {
    this.renderRunner.pause('batchRendering');
    func();
    this.renderRunner.resume('batchRendering');
  }
  pauseRendering() {
    this.renderRunner.pause('pauseRendering');
  }
  resumeRendering() {
    this.renderRunner.resume('pauseRendering', true);
  }
  resetOptions(optionOverrides, changedOptionNames) {
    this.currentDataManager.resetOptions(optionOverrides, changedOptionNames);
  }
  setClassNames(classNames) {
    if (!(0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.i)(classNames, this.currentClassNames)) {
      let {
        classList
      } = this.el;
      for (let className of this.currentClassNames) {
        classList.remove(className);
      }
      for (let className of classNames) {
        classList.add(className);
      }
      this.currentClassNames = classNames;
    }
  }
  setHeight(height) {
    (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ac)(this.el, 'height', height);
  }
}
function formatDate(dateInput, options = {}) {
  let dateEnv = buildDateEnv(options);
  let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);
  let dateMeta = dateEnv.createMarkerMeta(dateInput);
  if (!dateMeta) {
    // TODO: warning?
    return '';
  }
  return dateEnv.format(dateMeta.marker, formatter, {
    forcedTzo: dateMeta.forcedTzo
  });
}
function formatRange(startInput, endInput, options) {
  let dateEnv = buildDateEnv(typeof options === 'object' && options ? options : {}); // pass in if non-null object
  let formatter = (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.x)(options);
  let startMeta = dateEnv.createMarkerMeta(startInput);
  let endMeta = dateEnv.createMarkerMeta(endInput);
  if (!startMeta || !endMeta) {
    // TODO: warning?
    return '';
  }
  return dateEnv.formatRange(startMeta.marker, endMeta.marker, formatter, {
    forcedStartTzo: startMeta.forcedTzo,
    forcedEndTzo: endMeta.forcedTzo,
    isEndExclusive: options.isEndExclusive,
    defaultSeparator: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.defaultRangeSeparator
  });
}
// TODO: more DRY and optimized
function buildDateEnv(settings) {
  let locale = buildLocale(settings.locale || 'en', organizeRawLocales([]).map); // TODO: don't hardcode 'en' everywhere
  return new _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.Q(Object.assign(Object.assign({
    timeZone: _internal_common_js__WEBPACK_IMPORTED_MODULE_0__.e.timeZone,
    calendarSystem: 'gregory'
  }, settings), {
    locale
  }));
}

// HELPERS
/*
if nextDayThreshold is specified, slicing is done in an all-day fashion.
you can get nextDayThreshold from context.nextDayThreshold
*/
function sliceEvents(props, allDay) {
  return (0,_internal_common_js__WEBPACK_IMPORTED_MODULE_0__.ad)(props.eventStore, props.eventUiBases, props.dateProfile.activeRange, allDay ? props.nextDayThreshold : null).fg;
}
const version = '6.1.19';


/***/ }),

/***/ 3436:
/*!************************************************************!*\
  !*** ./node_modules/@fullcalendar/core/internal-common.js ***!
  \************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   $: () => (/* binding */ listenBySelector),
/* harmony export */   A: () => (/* binding */ memoizeObjArg),
/* harmony export */   B: () => (/* binding */ BaseComponent),
/* harmony export */   C: () => (/* binding */ ContentContainer),
/* harmony export */   D: () => (/* binding */ DelayedRunner),
/* harmony export */   E: () => (/* binding */ isPropsEqual),
/* harmony export */   F: () => (/* binding */ Emitter),
/* harmony export */   G: () => (/* binding */ rangeContainsMarker),
/* harmony export */   H: () => (/* binding */ createEmptyEventStore),
/* harmony export */   I: () => (/* binding */ reduceEventStore),
/* harmony export */   J: () => (/* binding */ rezoneEventStoreDates),
/* harmony export */   K: () => (/* binding */ mergeRawOptions),
/* harmony export */   L: () => (/* binding */ BASE_OPTION_REFINERS),
/* harmony export */   M: () => (/* binding */ CALENDAR_LISTENER_REFINERS),
/* harmony export */   N: () => (/* binding */ CALENDAR_OPTION_REFINERS),
/* harmony export */   O: () => (/* binding */ COMPLEX_OPTION_COMPARATORS),
/* harmony export */   P: () => (/* binding */ VIEW_OPTION_REFINERS),
/* harmony export */   Q: () => (/* binding */ DateEnv),
/* harmony export */   R: () => (/* binding */ DateProfileGenerator),
/* harmony export */   S: () => (/* binding */ createEventUi),
/* harmony export */   T: () => (/* binding */ Theme),
/* harmony export */   U: () => (/* binding */ parseBusinessHours),
/* harmony export */   V: () => (/* binding */ ViewContextType),
/* harmony export */   W: () => (/* binding */ setRef),
/* harmony export */   X: () => (/* binding */ Interaction),
/* harmony export */   Y: () => (/* binding */ getElSeg),
/* harmony export */   Z: () => (/* binding */ elementClosest),
/* harmony export */   _: () => (/* binding */ EventImpl),
/* harmony export */   a: () => (/* binding */ mapHash),
/* harmony export */   a$: () => (/* binding */ preventDefault),
/* harmony export */   a0: () => (/* binding */ listenToHoverBySelector),
/* harmony export */   a1: () => (/* binding */ PureComponent),
/* harmony export */   a2: () => (/* binding */ buildViewContext),
/* harmony export */   a3: () => (/* binding */ getUniqueDomId),
/* harmony export */   a4: () => (/* binding */ parseInteractionSettings),
/* harmony export */   a5: () => (/* binding */ interactionSettingsStore),
/* harmony export */   a6: () => (/* binding */ NowTimer),
/* harmony export */   a7: () => (/* binding */ CalendarImpl),
/* harmony export */   a8: () => (/* binding */ flushSync),
/* harmony export */   a9: () => (/* binding */ CalendarRoot),
/* harmony export */   aA: () => (/* binding */ memoizeArraylike),
/* harmony export */   aB: () => (/* binding */ memoizeHashlike),
/* harmony export */   aC: () => (/* binding */ intersectRects),
/* harmony export */   aD: () => (/* binding */ pointInsideRect),
/* harmony export */   aE: () => (/* binding */ constrainPoint),
/* harmony export */   aF: () => (/* binding */ getRectCenter),
/* harmony export */   aG: () => (/* binding */ diffPoints),
/* harmony export */   aH: () => (/* binding */ translateRect),
/* harmony export */   aI: () => (/* binding */ compareObjs),
/* harmony export */   aJ: () => (/* binding */ collectFromHash),
/* harmony export */   aK: () => (/* binding */ findElements),
/* harmony export */   aL: () => (/* binding */ findDirectChildren),
/* harmony export */   aM: () => (/* binding */ removeElement),
/* harmony export */   aN: () => (/* binding */ applyStyle),
/* harmony export */   aO: () => (/* binding */ elementMatches),
/* harmony export */   aP: () => (/* binding */ getEventTargetViaRoot),
/* harmony export */   aQ: () => (/* binding */ parseClassNames),
/* harmony export */   aR: () => (/* binding */ getCanVGrowWithinCell),
/* harmony export */   aS: () => (/* binding */ mergeEventStores),
/* harmony export */   aT: () => (/* binding */ getRelevantEvents),
/* harmony export */   aU: () => (/* binding */ eventTupleToStore),
/* harmony export */   aV: () => (/* binding */ combineEventUis),
/* harmony export */   aW: () => (/* binding */ Splitter),
/* harmony export */   aX: () => (/* binding */ getDayClassNames),
/* harmony export */   aY: () => (/* binding */ getDateMeta),
/* harmony export */   aZ: () => (/* binding */ getSlotClassNames),
/* harmony export */   a_: () => (/* binding */ buildNavLinkAttrs),
/* harmony export */   aa: () => (/* binding */ RenderId),
/* harmony export */   ab: () => (/* binding */ ensureElHasStyles),
/* harmony export */   ac: () => (/* binding */ applyStyleProp),
/* harmony export */   ad: () => (/* binding */ sliceEventStore),
/* harmony export */   ae: () => (/* binding */ JsonRequestError),
/* harmony export */   af: () => (/* binding */ createContext),
/* harmony export */   ag: () => (/* binding */ refineProps),
/* harmony export */   ah: () => (/* binding */ createEventInstance),
/* harmony export */   ai: () => (/* binding */ parseEventDef),
/* harmony export */   aj: () => (/* binding */ refineEventDef),
/* harmony export */   ak: () => (/* binding */ padStart),
/* harmony export */   al: () => (/* binding */ isInt),
/* harmony export */   am: () => (/* binding */ parseFieldSpecs),
/* harmony export */   an: () => (/* binding */ compareByFieldSpecs),
/* harmony export */   ao: () => (/* binding */ flexibleCompare),
/* harmony export */   ap: () => (/* binding */ preventSelection),
/* harmony export */   aq: () => (/* binding */ allowSelection),
/* harmony export */   ar: () => (/* binding */ preventContextMenu),
/* harmony export */   as: () => (/* binding */ allowContextMenu),
/* harmony export */   at: () => (/* binding */ compareNumbers),
/* harmony export */   au: () => (/* binding */ enableCursor),
/* harmony export */   av: () => (/* binding */ disableCursor),
/* harmony export */   aw: () => (/* binding */ computeVisibleDayRange),
/* harmony export */   ax: () => (/* binding */ isMultiDayRange),
/* harmony export */   ay: () => (/* binding */ diffDates),
/* harmony export */   az: () => (/* binding */ removeExact),
/* harmony export */   b: () => (/* binding */ buildViewClassNames),
/* harmony export */   b$: () => (/* binding */ renderMicroColGroup),
/* harmony export */   b0: () => (/* binding */ whenTransitionDone),
/* harmony export */   b1: () => (/* binding */ computeInnerRect),
/* harmony export */   b2: () => (/* binding */ computeEdges),
/* harmony export */   b3: () => (/* binding */ getClippingParents),
/* harmony export */   b4: () => (/* binding */ computeRect),
/* harmony export */   b5: () => (/* binding */ rangesEqual),
/* harmony export */   b6: () => (/* binding */ rangesIntersect),
/* harmony export */   b7: () => (/* binding */ rangeContainsRange),
/* harmony export */   b8: () => (/* binding */ PositionCache),
/* harmony export */   b9: () => (/* binding */ ScrollController),
/* harmony export */   bA: () => (/* binding */ getEntrySpanEnd),
/* harmony export */   bB: () => (/* binding */ binarySearch),
/* harmony export */   bC: () => (/* binding */ groupIntersectingEntries),
/* harmony export */   bD: () => (/* binding */ intersectSpans),
/* harmony export */   bE: () => (/* binding */ interactionSettingsToStore),
/* harmony export */   bF: () => (/* binding */ ElementDragging),
/* harmony export */   bG: () => (/* binding */ config),
/* harmony export */   bH: () => (/* binding */ parseDragMeta),
/* harmony export */   bI: () => (/* binding */ DayHeader),
/* harmony export */   bJ: () => (/* binding */ computeFallbackHeaderFormat),
/* harmony export */   bK: () => (/* binding */ TableDateCell),
/* harmony export */   bL: () => (/* binding */ TableDowCell),
/* harmony export */   bM: () => (/* binding */ DaySeriesModel),
/* harmony export */   bN: () => (/* binding */ hasBgRendering),
/* harmony export */   bO: () => (/* binding */ buildSegTimeText),
/* harmony export */   bP: () => (/* binding */ sortEventSegs),
/* harmony export */   bQ: () => (/* binding */ getSegMeta),
/* harmony export */   bR: () => (/* binding */ buildEventRangeKey),
/* harmony export */   bS: () => (/* binding */ getSegAnchorAttrs),
/* harmony export */   bT: () => (/* binding */ DayTableModel),
/* harmony export */   bU: () => (/* binding */ Slicer),
/* harmony export */   bV: () => (/* binding */ applyMutationToEventStore),
/* harmony export */   bW: () => (/* binding */ isPropsValid),
/* harmony export */   bX: () => (/* binding */ isInteractionValid),
/* harmony export */   bY: () => (/* binding */ isDateSelectionValid),
/* harmony export */   bZ: () => (/* binding */ SimpleScrollGrid),
/* harmony export */   b_: () => (/* binding */ hasShrinkWidth),
/* harmony export */   ba: () => (/* binding */ ElementScrollController),
/* harmony export */   bb: () => (/* binding */ WindowScrollController),
/* harmony export */   bc: () => (/* binding */ DateComponent),
/* harmony export */   bd: () => (/* binding */ isDateSpansEqual),
/* harmony export */   be: () => (/* binding */ addMs),
/* harmony export */   bf: () => (/* binding */ addWeeks),
/* harmony export */   bg: () => (/* binding */ diffWeeks),
/* harmony export */   bh: () => (/* binding */ diffWholeWeeks),
/* harmony export */   bi: () => (/* binding */ diffDayAndTime),
/* harmony export */   bj: () => (/* binding */ diffDays),
/* harmony export */   bk: () => (/* binding */ isValidDate),
/* harmony export */   bl: () => (/* binding */ asCleanDays),
/* harmony export */   bm: () => (/* binding */ multiplyDuration),
/* harmony export */   bn: () => (/* binding */ addDurations),
/* harmony export */   bo: () => (/* binding */ asRoughMinutes),
/* harmony export */   bp: () => (/* binding */ asRoughSeconds),
/* harmony export */   bq: () => (/* binding */ asRoughMs),
/* harmony export */   br: () => (/* binding */ wholeDivideDurations),
/* harmony export */   bs: () => (/* binding */ formatIsoTimeString),
/* harmony export */   bt: () => (/* binding */ formatDayString),
/* harmony export */   bu: () => (/* binding */ buildIsoString),
/* harmony export */   bv: () => (/* binding */ formatIsoMonthStr),
/* harmony export */   bw: () => (/* binding */ NamedTimeZoneImpl),
/* harmony export */   bx: () => (/* binding */ parse),
/* harmony export */   by: () => (/* binding */ SegHierarchy),
/* harmony export */   bz: () => (/* binding */ buildEntryKey),
/* harmony export */   c: () => (/* binding */ greatestDurationDenominator),
/* harmony export */   c0: () => (/* binding */ getScrollGridClassNames),
/* harmony export */   c1: () => (/* binding */ getSectionClassNames),
/* harmony export */   c2: () => (/* binding */ getSectionHasLiquidHeight),
/* harmony export */   c3: () => (/* binding */ getAllowYScrolling),
/* harmony export */   c4: () => (/* binding */ renderChunkContent),
/* harmony export */   c5: () => (/* binding */ computeShrinkWidth),
/* harmony export */   c6: () => (/* binding */ sanitizeShrinkWidth),
/* harmony export */   c7: () => (/* binding */ isColPropsEqual),
/* harmony export */   c8: () => (/* binding */ renderScrollShim),
/* harmony export */   c9: () => (/* binding */ getStickyFooterScrollbar),
/* harmony export */   ca: () => (/* binding */ getStickyHeaderDates),
/* harmony export */   cb: () => (/* binding */ Scroller),
/* harmony export */   cc: () => (/* binding */ getScrollbarWidths),
/* harmony export */   cd: () => (/* binding */ RefMap),
/* harmony export */   ce: () => (/* binding */ getIsRtlScrollbarOnLeft),
/* harmony export */   cf: () => (/* binding */ ScrollResponder),
/* harmony export */   cg: () => (/* binding */ StandardEvent),
/* harmony export */   ch: () => (/* binding */ NowIndicatorContainer),
/* harmony export */   ci: () => (/* binding */ DayCellContainer),
/* harmony export */   cj: () => (/* binding */ hasCustomDayCellContent),
/* harmony export */   ck: () => (/* binding */ EventContainer),
/* harmony export */   cl: () => (/* binding */ renderFill),
/* harmony export */   cm: () => (/* binding */ BgEvent),
/* harmony export */   cn: () => (/* binding */ WeekNumberContainer),
/* harmony export */   co: () => (/* binding */ MoreLinkContainer),
/* harmony export */   cp: () => (/* binding */ computeEarliestSegStart),
/* harmony export */   cq: () => (/* binding */ ViewContainer),
/* harmony export */   cr: () => (/* binding */ triggerDateSelect),
/* harmony export */   cs: () => (/* binding */ getDefaultEventEnd),
/* harmony export */   ct: () => (/* binding */ injectStyles),
/* harmony export */   cu: () => (/* binding */ buildElAttrs),
/* harmony export */   cv: () => (/* binding */ CustomRenderingStore),
/* harmony export */   d: () => (/* binding */ createDuration),
/* harmony export */   e: () => (/* binding */ BASE_OPTION_DEFAULTS),
/* harmony export */   f: () => (/* binding */ arrayToHash),
/* harmony export */   g: () => (/* binding */ guid),
/* harmony export */   h: () => (/* binding */ filterHash),
/* harmony export */   i: () => (/* binding */ isArraysEqual),
/* harmony export */   j: () => (/* binding */ buildEventSourceRefiners),
/* harmony export */   k: () => (/* binding */ formatWithOrdinals),
/* harmony export */   l: () => (/* binding */ buildRangeApiWithTimeZone),
/* harmony export */   m: () => (/* binding */ mergeProps),
/* harmony export */   n: () => (/* binding */ identity),
/* harmony export */   o: () => (/* binding */ intersectRanges),
/* harmony export */   p: () => (/* binding */ parseEventSource),
/* harmony export */   q: () => (/* binding */ startOfDay),
/* harmony export */   r: () => (/* binding */ requestJson),
/* harmony export */   s: () => (/* binding */ subtractDurations),
/* harmony export */   t: () => (/* binding */ addDays),
/* harmony export */   u: () => (/* binding */ unpromisify),
/* harmony export */   v: () => (/* binding */ hashValuesToArray),
/* harmony export */   w: () => (/* binding */ buildEventApis),
/* harmony export */   x: () => (/* binding */ createFormatter),
/* harmony export */   y: () => (/* binding */ diffWholeDays),
/* harmony export */   z: () => (/* binding */ memoize)
/* harmony export */ });
/* harmony import */ var preact__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! preact */ 78048);
/* harmony import */ var preact_compat__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! preact/compat */ 40174);



const styleTexts = [];
const styleEls = new Map();
function injectStyles(styleText) {
  styleTexts.push(styleText);
  styleEls.forEach(styleEl => {
    appendStylesTo(styleEl, styleText);
  });
}
function ensureElHasStyles(el) {
  if (el.isConnected &&
  // sometimes true if SSR system simulates DOM
  el.getRootNode // sometimes undefined if SSR system simulates DOM
  ) {
    registerStylesRoot(el.getRootNode());
  }
}
function registerStylesRoot(rootNode) {
  let styleEl = styleEls.get(rootNode);
  if (!styleEl || !styleEl.isConnected) {
    styleEl = rootNode.querySelector('style[data-fullcalendar]');
    if (!styleEl) {
      styleEl = document.createElement('style');
      styleEl.setAttribute('data-fullcalendar', '');
      const nonce = getNonceValue();
      if (nonce) {
        styleEl.nonce = nonce;
      }
      const parentEl = rootNode === document ? document.head : rootNode;
      const insertBefore = rootNode === document ? parentEl.querySelector('script,link[rel=stylesheet],link[as=style],style') : parentEl.firstChild;
      parentEl.insertBefore(styleEl, insertBefore);
    }
    styleEls.set(rootNode, styleEl);
    hydrateStylesRoot(styleEl);
  }
}
function hydrateStylesRoot(styleEl) {
  for (const styleText of styleTexts) {
    appendStylesTo(styleEl, styleText);
  }
}
function appendStylesTo(styleEl, styleText) {
  const {
    sheet
  } = styleEl;
  const ruleCnt = sheet.cssRules.length;
  styleText.split('}').forEach((styleStr, i) => {
    styleStr = styleStr.trim();
    if (styleStr) {
      sheet.insertRule(styleStr + '}', ruleCnt + i);
    }
  });
}
// nonce
// -------------------------------------------------------------------------------------------------
let queriedNonceValue;
function getNonceValue() {
  if (queriedNonceValue === undefined) {
    queriedNonceValue = queryNonceValue();
  }
  return queriedNonceValue;
}
/*
TODO: discourage meta tag and instead put nonce attribute on placeholder <style> tag
*/
function queryNonceValue() {
  const metaWithNonce = document.querySelector('meta[name="csp-nonce"]');
  if (metaWithNonce && metaWithNonce.hasAttribute('content')) {
    return metaWithNonce.getAttribute('content');
  }
  const elWithNonce = document.querySelector('script[nonce]');
  if (elWithNonce) {
    return elWithNonce.nonce || '';
  }
  return '';
}
// main
// -------------------------------------------------------------------------------------------------
if (typeof document !== 'undefined') {
  registerStylesRoot(document);
}
var css_248z = ":root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url(\"data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyYiDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=\") format(\"truetype\")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:\"\\e900\"}.fc-icon-chevron-right:before{content:\"\\e901\"}.fc-icon-chevrons-left:before{content:\"\\e902\"}.fc-icon-chevrons-right:before{content:\"\\e903\"}.fc-icon-minus-square:before{content:\"\\e904\"}.fc-icon-plus-square:before{content:\"\\e905\"}.fc-icon-x:before{content:\"\\e906\"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center;-webkit-user-select:none;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:\"\";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:\"\";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:\"\";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}";
injectStyles(css_248z);
class DelayedRunner {
  constructor(drainedOption) {
    this.drainedOption = drainedOption;
    this.isRunning = false;
    this.isDirty = false;
    this.pauseDepths = {};
    this.timeoutId = 0;
  }
  request(delay) {
    this.isDirty = true;
    if (!this.isPaused()) {
      this.clearTimeout();
      if (delay == null) {
        this.tryDrain();
      } else {
        this.timeoutId = setTimeout(
        // NOT OPTIMAL! TODO: look at debounce
        this.tryDrain.bind(this), delay);
      }
    }
  }
  pause(scope = '') {
    let {
      pauseDepths
    } = this;
    pauseDepths[scope] = (pauseDepths[scope] || 0) + 1;
    this.clearTimeout();
  }
  resume(scope = '', force) {
    let {
      pauseDepths
    } = this;
    if (scope in pauseDepths) {
      if (force) {
        delete pauseDepths[scope];
      } else {
        pauseDepths[scope] -= 1;
        let depth = pauseDepths[scope];
        if (depth <= 0) {
          delete pauseDepths[scope];
        }
      }
      this.tryDrain();
    }
  }
  isPaused() {
    return Object.keys(this.pauseDepths).length;
  }
  tryDrain() {
    if (!this.isRunning && !this.isPaused()) {
      this.isRunning = true;
      while (this.isDirty) {
        this.isDirty = false;
        this.drained(); // might set isDirty to true again
      }
      this.isRunning = false;
    }
  }
  clear() {
    this.clearTimeout();
    this.isDirty = false;
    this.pauseDepths = {};
  }
  clearTimeout() {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId);
      this.timeoutId = 0;
    }
  }
  drained() {
    if (this.drainedOption) {
      this.drainedOption();
    }
  }
}
function removeElement(el) {
  if (el.parentNode) {
    el.parentNode.removeChild(el);
  }
}
// Querying
// ----------------------------------------------------------------------------------------------------------------
function elementClosest(el, selector) {
  if (el.closest) {
    return el.closest(selector);
    // really bad fallback for IE
    // from https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
  }
  if (!document.documentElement.contains(el)) {
    return null;
  }
  do {
    if (elementMatches(el, selector)) {
      return el;
    }
    el = el.parentElement || el.parentNode;
  } while (el !== null && el.nodeType === 1);
  return null;
}
function elementMatches(el, selector) {
  let method = el.matches || el.matchesSelector || el.msMatchesSelector;
  return method.call(el, selector);
}
// accepts multiple subject els
// returns a real array. good for methods like forEach
// TODO: accept the document
function findElements(container, selector) {
  let containers = container instanceof HTMLElement ? [container] : container;
  let allMatches = [];
  for (let i = 0; i < containers.length; i += 1) {
    let matches = containers[i].querySelectorAll(selector);
    for (let j = 0; j < matches.length; j += 1) {
      allMatches.push(matches[j]);
    }
  }
  return allMatches;
}
// accepts multiple subject els
// only queries direct child elements // TODO: rename to findDirectChildren!
function findDirectChildren(parent, selector) {
  let parents = parent instanceof HTMLElement ? [parent] : parent;
  let allMatches = [];
  for (let i = 0; i < parents.length; i += 1) {
    let childNodes = parents[i].children; // only ever elements
    for (let j = 0; j < childNodes.length; j += 1) {
      let childNode = childNodes[j];
      if (!selector || elementMatches(childNode, selector)) {
        allMatches.push(childNode);
      }
    }
  }
  return allMatches;
}
// Style
// ----------------------------------------------------------------------------------------------------------------
const PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i;
function applyStyle(el, props) {
  for (let propName in props) {
    applyStyleProp(el, propName, props[propName]);
  }
}
function applyStyleProp(el, name, val) {
  if (val == null) {
    el.style[name] = '';
  } else if (typeof val === 'number' && PIXEL_PROP_RE.test(name)) {
    el.style[name] = `${val}px`;
  } else {
    el.style[name] = val;
  }
}
// Event Handling
// ----------------------------------------------------------------------------------------------------------------
// if intercepting bubbled events at the document/window/body level,
// and want to see originating element (the 'target'), use this util instead
// of `ev.target` because it goes within web-component boundaries.
function getEventTargetViaRoot(ev) {
  var _a, _b;
  return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target;
}
// Unique ID for DOM attribute
let guid$1 = 0;
function getUniqueDomId() {
  guid$1 += 1;
  return 'fc-dom-' + guid$1;
}

// Stops a mouse/touch event from doing it's native browser action
function preventDefault(ev) {
  ev.preventDefault();
}
// Event Delegation
// ----------------------------------------------------------------------------------------------------------------
function buildDelegationHandler(selector, handler) {
  return ev => {
    let matchedChild = elementClosest(ev.target, selector);
    if (matchedChild) {
      handler.call(matchedChild, ev, matchedChild);
    }
  };
}
function listenBySelector(container, eventType, selector, handler) {
  let attachedHandler = buildDelegationHandler(selector, handler);
  container.addEventListener(eventType, attachedHandler);
  return () => {
    container.removeEventListener(eventType, attachedHandler);
  };
}
function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) {
  let currentMatchedChild;
  return listenBySelector(container, 'mouseover', selector, (mouseOverEv, matchedChild) => {
    if (matchedChild !== currentMatchedChild) {
      currentMatchedChild = matchedChild;
      onMouseEnter(mouseOverEv, matchedChild);
      let realOnMouseLeave = mouseLeaveEv => {
        currentMatchedChild = null;
        onMouseLeave(mouseLeaveEv, matchedChild);
        matchedChild.removeEventListener('mouseleave', realOnMouseLeave);
      };
      // listen to the next mouseleave, and then unattach
      matchedChild.addEventListener('mouseleave', realOnMouseLeave);
    }
  });
}
// Animation
// ----------------------------------------------------------------------------------------------------------------
const transitionEventNames = ['webkitTransitionEnd', 'otransitionend', 'oTransitionEnd', 'msTransitionEnd', 'transitionend'];
// triggered only when the next single subsequent transition finishes
function whenTransitionDone(el, callback) {
  let realCallback = ev => {
    callback(ev);
    transitionEventNames.forEach(eventName => {
      el.removeEventListener(eventName, realCallback);
    });
  };
  transitionEventNames.forEach(eventName => {
    el.addEventListener(eventName, realCallback); // cross-browser way to determine when the transition finishes
  });
}
// ARIA workarounds
// ----------------------------------------------------------------------------------------------------------------
function createAriaClickAttrs(handler) {
  return Object.assign({
    onClick: handler
  }, createAriaKeyboardAttrs(handler));
}
function createAriaKeyboardAttrs(handler) {
  return {
    tabIndex: 0,
    onKeyDown(ev) {
      if (ev.key === 'Enter' || ev.key === ' ') {
        handler(ev);
        ev.preventDefault(); // if space, don't scroll down page
      }
    }
  };
}
let guidNumber = 0;
function guid() {
  guidNumber += 1;
  return String(guidNumber);
}
/* FullCalendar-specific DOM Utilities
----------------------------------------------------------------------------------------------------------------------*/
// Make the mouse cursor express that an event is not allowed in the current area
function disableCursor() {
  document.body.classList.add('fc-not-allowed');
}
// Returns the mouse cursor to its original look
function enableCursor() {
  document.body.classList.remove('fc-not-allowed');
}
/* Selection
----------------------------------------------------------------------------------------------------------------------*/
function preventSelection(el) {
  el.style.userSelect = 'none';
  el.style.webkitUserSelect = 'none';
  el.addEventListener('selectstart', preventDefault);
}
function allowSelection(el) {
  el.style.userSelect = '';
  el.style.webkitUserSelect = '';
  el.removeEventListener('selectstart', preventDefault);
}
/* Context Menu
----------------------------------------------------------------------------------------------------------------------*/
function preventContextMenu(el) {
  el.addEventListener('contextmenu', preventDefault);
}
function allowContextMenu(el) {
  el.removeEventListener('contextmenu', preventDefault);
}
function parseFieldSpecs(input) {
  let specs = [];
  let tokens = [];
  let i;
  let token;
  if (typeof input === 'string') {
    tokens = input.split(/\s*,\s*/);
  } else if (typeof input === 'function') {
    tokens = [input];
  } else if (Array.isArray(input)) {
    tokens = input;
  }
  for (i = 0; i < tokens.length; i += 1) {
    token = tokens[i];
    if (typeof token === 'string') {
      specs.push(token.charAt(0) === '-' ? {
        field: token.substring(1),
        order: -1
      } : {
        field: token,
        order: 1
      });
    } else if (typeof token === 'function') {
      specs.push({
        func: token
      });
    }
  }
  return specs;
}
function compareByFieldSpecs(obj0, obj1, fieldSpecs) {
  let i;
  let cmp;
  for (i = 0; i < fieldSpecs.length; i += 1) {
    cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i]);
    if (cmp) {
      return cmp;
    }
  }
  return 0;
}
function compareByFieldSpec(obj0, obj1, fieldSpec) {
  if (fieldSpec.func) {
    return fieldSpec.func(obj0, obj1);
  }
  return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) * (fieldSpec.order || 1);
}
function flexibleCompare(a, b) {
  if (!a && !b) {
    return 0;
  }
  if (b == null) {
    return -1;
  }
  if (a == null) {
    return 1;
  }
  if (typeof a === 'string' || typeof b === 'string') {
    return String(a).localeCompare(String(b));
  }
  return a - b;
}
/* String Utilities
----------------------------------------------------------------------------------------------------------------------*/
function padStart(val, len) {
  let s = String(val);
  return '000'.substr(0, len - s.length) + s;
}
function formatWithOrdinals(formatter, args, fallbackText) {
  if (typeof formatter === 'function') {
    return formatter(...args);
  }
  if (typeof formatter === 'string') {
    // non-blank string
    return args.reduce((str, arg, index) => str.replace('$' + index, arg || ''), formatter);
  }
  return fallbackText;
}
/* Number Utilities
----------------------------------------------------------------------------------------------------------------------*/
function compareNumbers(a, b) {
  return a - b;
}
function isInt(n) {
  return n % 1 === 0;
}
/* FC-specific DOM dimension stuff
----------------------------------------------------------------------------------------------------------------------*/
function computeSmallestCellWidth(cellEl) {
  let allWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-frame');
  let contentWidthEl = cellEl.querySelector('.fc-scrollgrid-shrink-cushion');
  if (!allWidthEl) {
    throw new Error('needs fc-scrollgrid-shrink-frame className'); // TODO: use const
  }
  if (!contentWidthEl) {
    throw new Error('needs fc-scrollgrid-shrink-cushion className');
  }
  return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width +
  // the cell padding+border
  contentWidthEl.getBoundingClientRect().width;
}
const INTERNAL_UNITS = ['years', 'months', 'days', 'milliseconds'];
const PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/;
// Parsing and Creation
function createDuration(input, unit) {
  if (typeof input === 'string') {
    return parseString(input);
  }
  if (typeof input === 'object' && input) {
    // non-null object
    return parseObject(input);
  }
  if (typeof input === 'number') {
    return parseObject({
      [unit || 'milliseconds']: input
    });
  }
  return null;
}
function parseString(s) {
  let m = PARSE_RE.exec(s);
  if (m) {
    let sign = m[1] ? -1 : 1;
    return {
      years: 0,
      months: 0,
      days: sign * (m[2] ? parseInt(m[2], 10) : 0),
      milliseconds: sign * ((m[3] ? parseInt(m[3], 10) : 0) * 60 * 60 * 1000 +
      // hours
      (m[4] ? parseInt(m[4], 10) : 0) * 60 * 1000 +
      // minutes
      (m[5] ? parseInt(m[5], 10) : 0) * 1000 + (
      // seconds
      m[6] ? parseInt(m[6], 10) : 0) // ms
      )
    };
  }
  return null;
}
function parseObject(obj) {
  let duration = {
    years: obj.years || obj.year || 0,
    months: obj.months || obj.month || 0,
    days: obj.days || obj.day || 0,
    milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1000 +
    // hours
    (obj.minutes || obj.minute || 0) * 60 * 1000 +
    // minutes
    (obj.seconds || obj.second || 0) * 1000 + (
    // seconds
    obj.milliseconds || obj.millisecond || obj.ms || 0) // ms
  };
  let weeks = obj.weeks || obj.week;
  if (weeks) {
    duration.days += weeks * 7;
    duration.specifiedWeeks = true;
  }
  return duration;
}
// Equality
function durationsEqual(d0, d1) {
  return d0.years === d1.years && d0.months === d1.months && d0.days === d1.days && d0.milliseconds === d1.milliseconds;
}
function asCleanDays(dur) {
  if (!dur.years && !dur.months && !dur.milliseconds) {
    return dur.days;
  }
  return 0;
}
// Simple Math
function addDurations(d0, d1) {
  return {
    years: d0.years + d1.years,
    months: d0.months + d1.months,
    days: d0.days + d1.days,
    milliseconds: d0.milliseconds + d1.milliseconds
  };
}
function subtractDurations(d1, d0) {
  return {
    years: d1.years - d0.years,
    months: d1.months - d0.months,
    days: d1.days - d0.days,
    milliseconds: d1.milliseconds - d0.milliseconds
  };
}
function multiplyDuration(d, n) {
  return {
    years: d.years * n,
    months: d.months * n,
    days: d.days * n,
    milliseconds: d.milliseconds * n
  };
}
// Conversions
// "Rough" because they are based on average-case Gregorian months/years
function asRoughYears(dur) {
  return asRoughDays(dur) / 365;
}
function asRoughMonths(dur) {
  return asRoughDays(dur) / 30;
}
function asRoughDays(dur) {
  return asRoughMs(dur) / 864e5;
}
function asRoughMinutes(dur) {
  return asRoughMs(dur) / (1000 * 60);
}
function asRoughSeconds(dur) {
  return asRoughMs(dur) / 1000;
}
function asRoughMs(dur) {
  return dur.years * (365 * 864e5) + dur.months * (30 * 864e5) + dur.days * 864e5 + dur.milliseconds;
}
// Advanced Math
function wholeDivideDurations(numerator, denominator) {
  let res = null;
  for (let i = 0; i < INTERNAL_UNITS.length; i += 1) {
    let unit = INTERNAL_UNITS[i];
    if (denominator[unit]) {
      let localRes = numerator[unit] / denominator[unit];
      if (!isInt(localRes) || res !== null && res !== localRes) {
        return null;
      }
      res = localRes;
    } else if (numerator[unit]) {
      // needs to divide by something but can't!
      return null;
    }
  }
  return res;
}
function greatestDurationDenominator(dur) {
  let ms = dur.milliseconds;
  if (ms) {
    if (ms % 1000 !== 0) {
      return {
        unit: 'millisecond',
        value: ms
      };
    }
    if (ms % (1000 * 60) !== 0) {
      return {
        unit: 'second',
        value: ms / 1000
      };
    }
    if (ms % (1000 * 60 * 60) !== 0) {
      return {
        unit: 'minute',
        value: ms / (1000 * 60)
      };
    }
    if (ms) {
      return {
        unit: 'hour',
        value: ms / (1000 * 60 * 60)
      };
    }
  }
  if (dur.days) {
    if (dur.specifiedWeeks && dur.days % 7 === 0) {
      return {
        unit: 'week',
        value: dur.days / 7
      };
    }
    return {
      unit: 'day',
      value: dur.days
    };
  }
  if (dur.months) {
    return {
      unit: 'month',
      value: dur.months
    };
  }
  if (dur.years) {
    return {
      unit: 'year',
      value: dur.years
    };
  }
  return {
    unit: 'millisecond',
    value: 0
  };
}

// TODO: new util arrayify?
function removeExact(array, exactVal) {
  let removeCnt = 0;
  let i = 0;
  while (i < array.length) {
    if (array[i] === exactVal) {
      array.splice(i, 1);
      removeCnt += 1;
    } else {
      i += 1;
    }
  }
  return removeCnt;
}
function isArraysEqual(a0, a1, equalityFunc) {
  if (a0 === a1) {
    return true;
  }
  let len = a0.length;
  let i;
  if (len !== a1.length) {
    // not array? or not same length?
    return false;
  }
  for (i = 0; i < len; i += 1) {
    if (!(equalityFunc ? equalityFunc(a0[i], a1[i]) : a0[i] === a1[i])) {
      return false;
    }
  }
  return true;
}
const DAY_IDS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
// Adding
function addWeeks(m, n) {
  let a = dateToUtcArray(m);
  a[2] += n * 7;
  return arrayToUtcDate(a);
}
function addDays(m, n) {
  let a = dateToUtcArray(m);
  a[2] += n;
  return arrayToUtcDate(a);
}
function addMs(m, n) {
  let a = dateToUtcArray(m);
  a[6] += n;
  return arrayToUtcDate(a);
}
// Diffing (all return floats)
// TODO: why not use ranges?
function diffWeeks(m0, m1) {
  return diffDays(m0, m1) / 7;
}
function diffDays(m0, m1) {
  return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60 * 24);
}
function diffHours(m0, m1) {
  return (m1.valueOf() - m0.valueOf()) / (1000 * 60 * 60);
}
function diffMinutes(m0, m1) {
  return (m1.valueOf() - m0.valueOf()) / (1000 * 60);
}
function diffSeconds(m0, m1) {
  return (m1.valueOf() - m0.valueOf()) / 1000;
}
function diffDayAndTime(m0, m1) {
  let m0day = startOfDay(m0);
  let m1day = startOfDay(m1);
  return {
    years: 0,
    months: 0,
    days: Math.round(diffDays(m0day, m1day)),
    milliseconds: m1.valueOf() - m1day.valueOf() - (m0.valueOf() - m0day.valueOf())
  };
}
// Diffing Whole Units
function diffWholeWeeks(m0, m1) {
  let d = diffWholeDays(m0, m1);
  if (d !== null && d % 7 === 0) {
    return d / 7;
  }
  return null;
}
function diffWholeDays(m0, m1) {
  if (timeAsMs(m0) === timeAsMs(m1)) {
    return Math.round(diffDays(m0, m1));
  }
  return null;
}
// Start-Of
function startOfDay(m) {
  return arrayToUtcDate([m.getUTCFullYear(), m.getUTCMonth(), m.getUTCDate()]);
}
function startOfHour(m) {
  return arrayToUtcDate([m.getUTCFullYear(), m.getUTCMonth(), m.getUTCDate(), m.getUTCHours()]);
}
function startOfMinute(m) {
  return arrayToUtcDate([m.getUTCFullYear(), m.getUTCMonth(), m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes()]);
}
function startOfSecond(m) {
  return arrayToUtcDate([m.getUTCFullYear(), m.getUTCMonth(), m.getUTCDate(), m.getUTCHours(), m.getUTCMinutes(), m.getUTCSeconds()]);
}
// Week Computation
function weekOfYear(marker, dow, doy) {
  let y = marker.getUTCFullYear();
  let w = weekOfGivenYear(marker, y, dow, doy);
  if (w < 1) {
    return weekOfGivenYear(marker, y - 1, dow, doy);
  }
  let nextW = weekOfGivenYear(marker, y + 1, dow, doy);
  if (nextW >= 1) {
    return Math.min(w, nextW);
  }
  return w;
}
function weekOfGivenYear(marker, year, dow, doy) {
  let firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]);
  let dayStart = startOfDay(marker);
  let days = Math.round(diffDays(firstWeekStart, dayStart));
  return Math.floor(days / 7) + 1; // zero-indexed
}
// start-of-first-week - start-of-year
function firstWeekOffset(year, dow, doy) {
  // first-week day -- which january is always in the first week (4 for iso, 1 for other)
  let fwd = 7 + dow - doy;
  // first-week day local weekday -- which local weekday is fwd
  let fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7;
  return -fwdlw + fwd - 1;
}
// Array Conversion
function dateToLocalArray(date) {
  return [date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()];
}
function arrayToLocalDate(a) {
  return new Date(a[0], a[1] || 0, a[2] == null ? 1 : a[2],
  // day of month
  a[3] || 0, a[4] || 0, a[5] || 0);
}
function dateToUtcArray(date) {
  return [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds()];
}
function arrayToUtcDate(a) {
  // according to web standards (and Safari), a month index is required.
  // massage if only given a year.
  if (a.length === 1) {
    a = a.concat([0]);
  }
  return new Date(Date.UTC(...a));
}
// Other Utils
function isValidDate(m) {
  return !isNaN(m.valueOf());
}
function timeAsMs(m) {
  return m.getUTCHours() * 1000 * 60 * 60 + m.getUTCMinutes() * 1000 * 60 + m.getUTCSeconds() * 1000 + m.getUTCMilliseconds();
}

// timeZoneOffset is in minutes
function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) {
  let s = marker.toISOString();
  s = s.replace('.000', '');
  if (stripZeroTime) {
    s = s.replace('T00:00:00Z', '');
  }
  if (s.length > 10) {
    // time part wasn't stripped, can add timezone info
    if (timeZoneOffset == null) {
      s = s.replace('Z', '');
    } else if (timeZoneOffset !== 0) {
      s = s.replace('Z', formatTimeZoneOffset(timeZoneOffset, true));
    }
    // otherwise, its UTC-0 and we want to keep the Z
  }
  return s;
}
// formats the date, but with no time part
// TODO: somehow merge with buildIsoString and stripZeroTime
// TODO: rename. omit "string"
function formatDayString(marker) {
  return marker.toISOString().replace(/T.*$/, '');
}
function formatIsoMonthStr(marker) {
  return marker.toISOString().match(/^\d{4}-\d{2}/)[0];
}
// TODO: use Date::toISOString and use everything after the T?
function formatIsoTimeString(marker) {
  return padStart(marker.getUTCHours(), 2) + ':' + padStart(marker.getUTCMinutes(), 2) + ':' + padStart(marker.getUTCSeconds(), 2);
}
function formatTimeZoneOffset(minutes, doIso = false) {
  let sign = minutes < 0 ? '-' : '+';
  let abs = Math.abs(minutes);
  let hours = Math.floor(abs / 60);
  let mins = Math.round(abs % 60);
  if (doIso) {
    return `${sign + padStart(hours, 2)}:${padStart(mins, 2)}`;
  }
  return `GMT${sign}${hours}${mins ? `:${padStart(mins, 2)}` : ''}`;
}
function memoize(workerFunc, resEquality, teardownFunc) {
  let currentArgs;
  let currentRes;
  return function (...newArgs) {
    if (!currentArgs) {
      currentRes = workerFunc.apply(this, newArgs);
    } else if (!isArraysEqual(currentArgs, newArgs)) {
      if (teardownFunc) {
        teardownFunc(currentRes);
      }
      let res = workerFunc.apply(this, newArgs);
      if (!resEquality || !resEquality(res, currentRes)) {
        currentRes = res;
      }
    }
    currentArgs = newArgs;
    return currentRes;
  };
}
function memoizeObjArg(workerFunc, resEquality, teardownFunc) {
  let currentArg;
  let currentRes;
  return newArg => {
    if (!currentArg) {
      currentRes = workerFunc.call(this, newArg);
    } else if (!isPropsEqual(currentArg, newArg)) {
      if (teardownFunc) {
        teardownFunc(currentRes);
      }
      let res = workerFunc.call(this, newArg);
      if (!resEquality || !resEquality(res, currentRes)) {
        currentRes = res;
      }
    }
    currentArg = newArg;
    return currentRes;
  };
}
function memoizeArraylike(
// used at all?
workerFunc, resEquality, teardownFunc) {
  let currentArgSets = [];
  let currentResults = [];
  return newArgSets => {
    let currentLen = currentArgSets.length;
    let newLen = newArgSets.length;
    let i = 0;
    for (; i < currentLen; i += 1) {
      if (!newArgSets[i]) {
        // one of the old sets no longer exists
        if (teardownFunc) {
          teardownFunc(currentResults[i]);
        }
      } else if (!isArraysEqual(currentArgSets[i], newArgSets[i])) {
        if (teardownFunc) {
          teardownFunc(currentResults[i]);
        }
        let res = workerFunc.apply(this, newArgSets[i]);
        if (!resEquality || !resEquality(res, currentResults[i])) {
          currentResults[i] = res;
        }
      }
    }
    for (; i < newLen; i += 1) {
      currentResults[i] = workerFunc.apply(this, newArgSets[i]);
    }
    currentArgSets = newArgSets;
    currentResults.splice(newLen); // remove excess
    return currentResults;
  };
}
function memoizeHashlike(workerFunc, resEquality, teardownFunc) {
  let currentArgHash = {};
  let currentResHash = {};
  return newArgHash => {
    let newResHash = {};
    for (let key in newArgHash) {
      if (!currentResHash[key]) {
        newResHash[key] = workerFunc.apply(this, newArgHash[key]);
      } else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) {
        if (teardownFunc) {
          teardownFunc(currentResHash[key]);
        }
        let res = workerFunc.apply(this, newArgHash[key]);
        newResHash[key] = resEquality && resEquality(res, currentResHash[key]) ? currentResHash[key] : res;
      } else {
        newResHash[key] = currentResHash[key];
      }
    }
    currentArgHash = newArgHash;
    currentResHash = newResHash;
    return newResHash;
  };
}
const EXTENDED_SETTINGS_AND_SEVERITIES = {
  week: 3,
  separator: 9,
  omitZeroMinute: 9,
  meridiem: 9,
  omitCommas: 9
};
const STANDARD_DATE_PROP_SEVERITIES = {
  timeZoneName: 7,
  era: 6,
  year: 5,
  month: 4,
  day: 2,
  weekday: 2,
  hour: 1,
  minute: 1,
  second: 1
};
const MERIDIEM_RE = /\s*([ap])\.?m\.?/i; // eats up leading spaces too
const COMMA_RE = /,/g; // we need re for globalness
const MULTI_SPACE_RE = /\s+/g;
const LTR_RE = /\u200e/g; // control character
const UTC_RE = /UTC|GMT/;
class NativeFormatter {
  constructor(formatSettings) {
    let standardDateProps = {};
    let extendedSettings = {};
    let smallestUnitNum = 9; // the smallest unit in the formatter (9 is a sentinel, beyond max)
    for (let name in formatSettings) {
      if (name in EXTENDED_SETTINGS_AND_SEVERITIES) {
        extendedSettings[name] = formatSettings[name];
        const severity = EXTENDED_SETTINGS_AND_SEVERITIES[name];
        if (severity < 9) {
          smallestUnitNum = Math.min(EXTENDED_SETTINGS_AND_SEVERITIES[name], smallestUnitNum);
        }
      } else {
        standardDateProps[name] = formatSettings[name];
        if (name in STANDARD_DATE_PROP_SEVERITIES) {
          // TODO: what about hour12? no severity
          smallestUnitNum = Math.min(STANDARD_DATE_PROP_SEVERITIES[name], smallestUnitNum);
        }
      }
    }
    this.standardDateProps = standardDateProps;
    this.extendedSettings = extendedSettings;
    this.smallestUnitNum = smallestUnitNum;
    this.buildFormattingFunc = memoize(buildFormattingFunc);
  }
  format(date, context) {
    return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date);
  }
  formatRange(start, end, context, betterDefaultSeparator) {
    let {
      standardDateProps,
      extendedSettings
    } = this;
    let diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem);
    if (!diffSeverity) {
      return this.format(start, context);
    }
    let biggestUnitForPartial = diffSeverity;
    if (biggestUnitForPartial > 1 && (
    // the two dates are different in a way that's larger scale than time
    standardDateProps.year === 'numeric' || standardDateProps.year === '2-digit') && (standardDateProps.month === 'numeric' || standardDateProps.month === '2-digit') && (standardDateProps.day === 'numeric' || standardDateProps.day === '2-digit')) {
      biggestUnitForPartial = 1; // make it look like the dates are only different in terms of time
    }
    let full0 = this.format(start, context);
    let full1 = this.format(end, context);
    if (full0 === full1) {
      return full0;
    }
    let partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial);
    let partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context);
    let partial0 = partialFormattingFunc(start);
    let partial1 = partialFormattingFunc(end);
    let insertion = findCommonInsertion(full0, partial0, full1, partial1);
    let separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || '';
    if (insertion) {
      return insertion.before + partial0 + separator + partial1 + insertion.after;
    }
    return full0 + separator + full1;
  }
  getSmallestUnit() {
    switch (this.smallestUnitNum) {
      case 7:
      case 6:
      case 5:
        return 'year';
      case 4:
        return 'month';
      case 3:
        return 'week';
      case 2:
        return 'day';
      default:
        return 'time';
      // really?
    }
  }
}
function buildFormattingFunc(standardDateProps, extendedSettings, context) {
  let standardDatePropCnt = Object.keys(standardDateProps).length;
  if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === 'short') {
    return date => formatTimeZoneOffset(date.timeZoneOffset);
  }
  if (standardDatePropCnt === 0 && extendedSettings.week) {
    return date => formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week);
  }
  return buildNativeFormattingFunc(standardDateProps, extendedSettings, context);
}
function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) {
  standardDateProps = Object.assign({}, standardDateProps); // copy
  extendedSettings = Object.assign({}, extendedSettings); // copy
  sanitizeSettings(standardDateProps, extendedSettings);
  standardDateProps.timeZone = 'UTC'; // we leverage the only guaranteed timeZone for our UTC markers
  let normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps);
  let zeroFormat; // needed?
  if (extendedSettings.omitZeroMinute) {
    let zeroProps = Object.assign({}, standardDateProps);
    delete zeroProps.minute; // seconds and ms were already considered in sanitizeSettings
    zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps);
  }
  return date => {
    let {
      marker
    } = date;
    let format;
    if (zeroFormat && !marker.getUTCMinutes()) {
      format = zeroFormat;
    } else {
      format = normalFormat;
    }
    let s = format.format(marker);
    return postProcess(s, date, standardDateProps, extendedSettings, context);
  };
}
function sanitizeSettings(standardDateProps, extendedSettings) {
  // deal with a browser inconsistency where formatting the timezone
  // requires that the hour/minute be present.
  if (standardDateProps.timeZoneName) {
    if (!standardDateProps.hour) {
      standardDateProps.hour = '2-digit';
    }
    if (!standardDateProps.minute) {
      standardDateProps.minute = '2-digit';
    }
  }
  // only support short timezone names
  if (standardDateProps.timeZoneName === 'long') {
    standardDateProps.timeZoneName = 'short';
  }
  // if requesting to display seconds, MUST display minutes
  if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) {
    delete extendedSettings.omitZeroMinute;
  }
}
function postProcess(s, date, standardDateProps, extendedSettings, context) {
  s = s.replace(LTR_RE, ''); // remove left-to-right control chars. do first. good for other regexes
  if (standardDateProps.timeZoneName === 'short') {
    s = injectTzoStr(s, context.timeZone === 'UTC' || date.timeZoneOffset == null ? 'UTC' :
    // important to normalize for IE, which does "GMT"
    formatTimeZoneOffset(date.timeZoneOffset));
  }
  if (extendedSettings.omitCommas) {
    s = s.replace(COMMA_RE, '').trim();
  }
  if (extendedSettings.omitZeroMinute) {
    s = s.replace(':00', ''); // zeroFormat doesn't always achieve this
  }
  // ^ do anything that might create adjacent spaces before this point,
  // because MERIDIEM_RE likes to eat up loading spaces
  if (extendedSettings.meridiem === false) {
    s = s.replace(MERIDIEM_RE, '').trim();
  } else if (extendedSettings.meridiem === 'narrow') {
    // a/p
    s = s.replace(MERIDIEM_RE, (m0, m1) => m1.toLocaleLowerCase());
  } else if (extendedSettings.meridiem === 'short') {
    // am/pm
    s = s.replace(MERIDIEM_RE, (m0, m1) => `${m1.toLocaleLowerCase()}m`);
  } else if (extendedSettings.meridiem === 'lowercase') {
    // other meridiem transformers already converted to lowercase
    s = s.replace(MERIDIEM_RE, m0 => m0.toLocaleLowerCase());
  }
  s = s.replace(MULTI_SPACE_RE, ' ');
  s = s.trim();
  return s;
}
function injectTzoStr(s, tzoStr) {
  let replaced = false;
  s = s.replace(UTC_RE, () => {
    replaced = true;
    return tzoStr;
  });
  // IE11 doesn't include UTC/GMT in the original string, so append to end
  if (!replaced) {
    s += ` ${tzoStr}`;
  }
  return s;
}
function formatWeekNumber(num, weekText, weekTextLong, locale, display) {
  let parts = [];
  if (display === 'long') {
    parts.push(weekTextLong);
  } else if (display === 'short' || display === 'narrow') {
    parts.push(weekText);
  }
  if (display === 'long' || display === 'short') {
    parts.push(' ');
  }
  parts.push(locale.simpleNumberFormat.format(num));
  if (locale.options.direction === 'rtl') {
    // TODO: use control characters instead?
    parts.reverse();
  }
  return parts.join('');
}
// Range Formatting Utils
// 0 = exactly the same
// 1 = different by time
// and bigger
function computeMarkerDiffSeverity(d0, d1, ca) {
  if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) {
    return 5;
  }
  if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) {
    return 4;
  }
  if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) {
    return 2;
  }
  if (timeAsMs(d0) !== timeAsMs(d1)) {
    return 1;
  }
  return 0;
}
function computePartialFormattingOptions(options, biggestUnit) {
  let partialOptions = {};
  for (let name in options) {
    if (!(name in STANDARD_DATE_PROP_SEVERITIES) ||
    // not a date part prop (like timeZone)
    STANDARD_DATE_PROP_SEVERITIES[name] <= biggestUnit) {
      partialOptions[name] = options[name];
    }
  }
  return partialOptions;
}
function findCommonInsertion(full0, partial0, full1, partial1) {
  let i0 = 0;
  while (i0 < full0.length) {
    let found0 = full0.indexOf(partial0, i0);
    if (found0 === -1) {
      break;
    }
    let before0 = full0.substr(0, found0);
    i0 = found0 + partial0.length;
    let after0 = full0.substr(i0);
    let i1 = 0;
    while (i1 < full1.length) {
      let found1 = full1.indexOf(partial1, i1);
      if (found1 === -1) {
        break;
      }
      let before1 = full1.substr(0, found1);
      i1 = found1 + partial1.length;
      let after1 = full1.substr(i1);
      if (before0 === before1 && after0 === after1) {
        return {
          before: before0,
          after: after0
        };
      }
    }
  }
  return null;
}
function expandZonedMarker(dateInfo, calendarSystem) {
  let a = calendarSystem.markerToArray(dateInfo.marker);
  return {
    marker: dateInfo.marker,
    timeZoneOffset: dateInfo.timeZoneOffset,
    array: a,
    year: a[0],
    month: a[1],
    day: a[2],
    hour: a[3],
    minute: a[4],
    second: a[5],
    millisecond: a[6]
  };
}
function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) {
  let startInfo = expandZonedMarker(start, context.calendarSystem);
  let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null;
  return {
    date: startInfo,
    start: startInfo,
    end: endInfo,
    timeZone: context.timeZone,
    localeCodes: context.locale.codes,
    defaultSeparator: betterDefaultSeparator || context.defaultSeparator
  };
}

/*
TODO: fix the terminology of "formatter" vs "formatting func"
*/
/*
At the time of instantiation, this object does not know which cmd-formatting system it will use.
It receives this at the time of formatting, as a setting.
*/
class CmdFormatter {
  constructor(cmdStr) {
    this.cmdStr = cmdStr;
  }
  format(date, context, betterDefaultSeparator) {
    return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
  }
  formatRange(start, end, context, betterDefaultSeparator) {
    return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
  }
}
class FuncFormatter {
  constructor(func) {
    this.func = func;
  }
  format(date, context, betterDefaultSeparator) {
    return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator));
  }
  formatRange(start, end, context, betterDefaultSeparator) {
    return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator));
  }
}
function createFormatter(input) {
  if (typeof input === 'object' && input) {
    // non-null object
    return new NativeFormatter(input);
  }
  if (typeof input === 'string') {
    return new CmdFormatter(input);
  }
  if (typeof input === 'function') {
    return new FuncFormatter(input);
  }
  return null;
}

// base options
// ------------
const BASE_OPTION_REFINERS = {
  navLinkDayClick: identity,
  navLinkWeekClick: identity,
  duration: createDuration,
  bootstrapFontAwesome: identity,
  buttonIcons: identity,
  customButtons: identity,
  defaultAllDayEventDuration: createDuration,
  defaultTimedEventDuration: createDuration,
  nextDayThreshold: createDuration,
  scrollTime: createDuration,
  scrollTimeReset: Boolean,
  slotMinTime: createDuration,
  slotMaxTime: createDuration,
  dayPopoverFormat: createFormatter,
  slotDuration: createDuration,
  snapDuration: createDuration,
  headerToolbar: identity,
  footerToolbar: identity,
  defaultRangeSeparator: String,
  titleRangeSeparator: String,
  forceEventDuration: Boolean,
  dayHeaders: Boolean,
  dayHeaderFormat: createFormatter,
  dayHeaderClassNames: identity,
  dayHeaderContent: identity,
  dayHeaderDidMount: identity,
  dayHeaderWillUnmount: identity,
  dayCellClassNames: identity,
  dayCellContent: identity,
  dayCellDidMount: identity,
  dayCellWillUnmount: identity,
  initialView: String,
  aspectRatio: Number,
  weekends: Boolean,
  weekNumberCalculation: identity,
  weekNumbers: Boolean,
  weekNumberClassNames: identity,
  weekNumberContent: identity,
  weekNumberDidMount: identity,
  weekNumberWillUnmount: identity,
  editable: Boolean,
  viewClassNames: identity,
  viewDidMount: identity,
  viewWillUnmount: identity,
  nowIndicator: Boolean,
  nowIndicatorSnap: identity,
  nowIndicatorClassNames: identity,
  nowIndicatorContent: identity,
  nowIndicatorDidMount: identity,
  nowIndicatorWillUnmount: identity,
  showNonCurrentDates: Boolean,
  lazyFetching: Boolean,
  startParam: String,
  endParam: String,
  timeZoneParam: String,
  timeZone: String,
  locales: identity,
  locale: identity,
  themeSystem: String,
  dragRevertDuration: Number,
  dragScroll: Boolean,
  allDayMaintainDuration: Boolean,
  unselectAuto: Boolean,
  dropAccept: identity,
  eventOrder: parseFieldSpecs,
  eventOrderStrict: Boolean,
  handleWindowResize: Boolean,
  windowResizeDelay: Number,
  longPressDelay: Number,
  eventDragMinDistance: Number,
  expandRows: Boolean,
  height: identity,
  contentHeight: identity,
  direction: String,
  weekNumberFormat: createFormatter,
  eventResizableFromStart: Boolean,
  displayEventTime: Boolean,
  displayEventEnd: Boolean,
  weekText: String,
  weekTextLong: String,
  progressiveEventRendering: Boolean,
  businessHours: identity,
  initialDate: identity,
  now: identity,
  eventDataTransform: identity,
  stickyHeaderDates: identity,
  stickyFooterScrollbar: identity,
  viewHeight: identity,
  defaultAllDay: Boolean,
  eventSourceFailure: identity,
  eventSourceSuccess: identity,
  eventDisplay: String,
  eventStartEditable: Boolean,
  eventDurationEditable: Boolean,
  eventOverlap: identity,
  eventConstraint: identity,
  eventAllow: identity,
  eventBackgroundColor: String,
  eventBorderColor: String,
  eventTextColor: String,
  eventColor: String,
  eventClassNames: identity,
  eventContent: identity,
  eventDidMount: identity,
  eventWillUnmount: identity,
  selectConstraint: identity,
  selectOverlap: identity,
  selectAllow: identity,
  droppable: Boolean,
  unselectCancel: String,
  slotLabelFormat: identity,
  slotLaneClassNames: identity,
  slotLaneContent: identity,
  slotLaneDidMount: identity,
  slotLaneWillUnmount: identity,
  slotLabelClassNames: identity,
  slotLabelContent: identity,
  slotLabelDidMount: identity,
  slotLabelWillUnmount: identity,
  dayMaxEvents: identity,
  dayMaxEventRows: identity,
  dayMinWidth: Number,
  slotLabelInterval: createDuration,
  allDayText: String,
  allDayClassNames: identity,
  allDayContent: identity,
  allDayDidMount: identity,
  allDayWillUnmount: identity,
  slotMinWidth: Number,
  navLinks: Boolean,
  eventTimeFormat: createFormatter,
  rerenderDelay: Number,
  moreLinkText: identity,
  moreLinkHint: identity,
  selectMinDistance: Number,
  selectable: Boolean,
  selectLongPressDelay: Number,
  eventLongPressDelay: Number,
  selectMirror: Boolean,
  eventMaxStack: Number,
  eventMinHeight: Number,
  eventMinWidth: Number,
  eventShortHeight: Number,
  slotEventOverlap: Boolean,
  plugins: identity,
  firstDay: Number,
  dayCount: Number,
  dateAlignment: String,
  dateIncrement: createDuration,
  hiddenDays: identity,
  fixedWeekCount: Boolean,
  validRange: identity,
  visibleRange: identity,
  titleFormat: identity,
  eventInteractive: Boolean,
  // only used by list-view, but languages define the value, so we need it in base options
  noEventsText: String,
  viewHint: identity,
  navLinkHint: identity,
  closeHint: String,
  timeHint: String,
  eventHint: String,
  moreLinkClick: identity,
  moreLinkClassNames: identity,
  moreLinkContent: identity,
  moreLinkDidMount: identity,
  moreLinkWillUnmount: identity,
  monthStartFormat: createFormatter,
  // for connectors
  // (can't be part of plugin system b/c must be provided at runtime)
  handleCustomRendering: identity,
  customRenderingMetaMap: identity,
  customRenderingReplaces: Boolean
};
// do NOT give a type here. need `typeof BASE_OPTION_DEFAULTS` to give real results.
// raw values.
const BASE_OPTION_DEFAULTS = {
  eventDisplay: 'auto',
  defaultRangeSeparator: ' - ',
  titleRangeSeparator: ' \u2013 ',
  defaultTimedEventDuration: '01:00:00',
  defaultAllDayEventDuration: {
    day: 1
  },
  forceEventDuration: false,
  nextDayThreshold: '00:00:00',
  dayHeaders: true,
  initialView: '',
  aspectRatio: 1.35,
  headerToolbar: {
    start: 'title',
    center: '',
    end: 'today prev,next'
  },
  weekends: true,
  weekNumbers: false,
  weekNumberCalculation: 'local',
  editable: false,
  nowIndicator: false,
  scrollTime: '06:00:00',
  scrollTimeReset: true,
  slotMinTime: '00:00:00',
  slotMaxTime: '24:00:00',
  showNonCurrentDates: true,
  lazyFetching: true,
  startParam: 'start',
  endParam: 'end',
  timeZoneParam: 'timeZone',
  timeZone: 'local',
  locales: [],
  locale: '',
  themeSystem: 'standard',
  dragRevertDuration: 500,
  dragScroll: true,
  allDayMaintainDuration: false,
  unselectAuto: true,
  dropAccept: '*',
  eventOrder: 'start,-duration,allDay,title',
  dayPopoverFormat: {
    month: 'long',
    day: 'numeric',
    year: 'numeric'
  },
  handleWindowResize: true,
  windowResizeDelay: 100,
  longPressDelay: 1000,
  eventDragMinDistance: 5,
  expandRows: false,
  navLinks: false,
  selectable: false,
  eventMinHeight: 15,
  eventMinWidth: 30,
  eventShortHeight: 30,
  monthStartFormat: {
    month: 'long',
    day: 'numeric'
  },
  nowIndicatorSnap: 'auto'
};
// calendar listeners
// ------------------
const CALENDAR_LISTENER_REFINERS = {
  datesSet: identity,
  eventsSet: identity,
  eventAdd: identity,
  eventChange: identity,
  eventRemove: identity,
  windowResize: identity,
  eventClick: identity,
  eventMouseEnter: identity,
  eventMouseLeave: identity,
  select: identity,
  unselect: identity,
  loading: identity,
  // internal
  _unmount: identity,
  _beforeprint: identity,
  _afterprint: identity,
  _noEventDrop: identity,
  _noEventResize: identity,
  _resize: identity,
  _scrollRequest: identity
};
// calendar-specific options
// -------------------------
const CALENDAR_OPTION_REFINERS = {
  buttonText: identity,
  buttonHints: identity,
  views: identity,
  plugins: identity,
  initialEvents: identity,
  events: identity,
  eventSources: identity
};
const COMPLEX_OPTION_COMPARATORS = {
  headerToolbar: isMaybeObjectsEqual,
  footerToolbar: isMaybeObjectsEqual,
  buttonText: isMaybeObjectsEqual,
  buttonHints: isMaybeObjectsEqual,
  buttonIcons: isMaybeObjectsEqual,
  dateIncrement: isMaybeObjectsEqual,
  plugins: isMaybeArraysEqual,
  events: isMaybeArraysEqual,
  eventSources: isMaybeArraysEqual,
  ['resources']: isMaybeArraysEqual
};
function isMaybeObjectsEqual(a, b) {
  if (typeof a === 'object' && typeof b === 'object' && a && b) {
    // both non-null objects
    return isPropsEqual(a, b);
  }
  return a === b;
}
function isMaybeArraysEqual(a, b) {
  if (Array.isArray(a) && Array.isArray(b)) {
    return isArraysEqual(a, b);
  }
  return a === b;
}
// view-specific options
// ---------------------
const VIEW_OPTION_REFINERS = {
  type: String,
  component: identity,
  buttonText: String,
  buttonTextKey: String,
  dateProfileGeneratorClass: identity,
  usesMinMaxTime: Boolean,
  classNames: identity,
  content: identity,
  didMount: identity,
  willUnmount: identity
};
// util funcs
// ----------------------------------------------------------------------------------------------------
function mergeRawOptions(optionSets) {
  return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS);
}
function refineProps(input, refiners) {
  let refined = {};
  let extra = {};
  for (let propName in refiners) {
    if (propName in input) {
      refined[propName] = refiners[propName](input[propName]);
    }
  }
  for (let propName in input) {
    if (!(propName in refiners)) {
      extra[propName] = input[propName];
    }
  }
  return {
    refined,
    extra
  };
}
function identity(raw) {
  return raw;
}
const {
  hasOwnProperty
} = Object.prototype;
// Merges an array of objects into a single object.
// The second argument allows for an array of property names who's object values will be merged together.
function mergeProps(propObjs, complexPropsMap) {
  let dest = {};
  if (complexPropsMap) {
    for (let name in complexPropsMap) {
      if (complexPropsMap[name] === isMaybeObjectsEqual) {
        // implies that it's object-mergeable
        let complexObjs = [];
        // collect the trailing object values, stopping when a non-object is discovered
        for (let i = propObjs.length - 1; i >= 0; i -= 1) {
          let val = propObjs[i][name];
          if (typeof val === 'object' && val) {
            // non-null object
            complexObjs.unshift(val);
          } else if (val !== undefined) {
            dest[name] = val; // if there were no objects, this value will be used
            break;
          }
        }
        // if the trailing values were objects, use the merged value
        if (complexObjs.length) {
          dest[name] = mergeProps(complexObjs);
        }
      }
    }
  }
  // copy values into the destination, going from last to first
  for (let i = propObjs.length - 1; i >= 0; i -= 1) {
    let props = propObjs[i];
    for (let name in props) {
      if (!(name in dest)) {
        // if already assigned by previous props or complex props, don't reassign
        dest[name] = props[name];
      }
    }
  }
  return dest;
}
function filterHash(hash, func) {
  let filtered = {};
  for (let key in hash) {
    if (func(hash[key], key)) {
      filtered[key] = hash[key];
    }
  }
  return filtered;
}
function mapHash(hash, func) {
  let newHash = {};
  for (let key in hash) {
    newHash[key] = func(hash[key], key);
  }
  return newHash;
}
function arrayToHash(a) {
  let hash = {};
  for (let item of a) {
    hash[item] = true;
  }
  return hash;
}
// TODO: reassess browser support
// https://caniuse.com/?search=object.values
function hashValuesToArray(obj) {
  let a = [];
  for (let key in obj) {
    a.push(obj[key]);
  }
  return a;
}
function isPropsEqual(obj0, obj1) {
  if (obj0 === obj1) {
    return true;
  }
  for (let key in obj0) {
    if (hasOwnProperty.call(obj0, key)) {
      if (!(key in obj1)) {
        return false;
      }
    }
  }
  for (let key in obj1) {
    if (hasOwnProperty.call(obj1, key)) {
      if (obj0[key] !== obj1[key]) {
        return false;
      }
    }
  }
  return true;
}
const HANDLER_RE = /^on[A-Z]/;
function isNonHandlerPropsEqual(obj0, obj1) {
  const keys = getUnequalProps(obj0, obj1);
  for (let key of keys) {
    if (!HANDLER_RE.test(key)) {
      return false;
    }
  }
  return true;
}
function getUnequalProps(obj0, obj1) {
  let keys = [];
  for (let key in obj0) {
    if (hasOwnProperty.call(obj0, key)) {
      if (!(key in obj1)) {
        keys.push(key);
      }
    }
  }
  for (let key in obj1) {
    if (hasOwnProperty.call(obj1, key)) {
      if (obj0[key] !== obj1[key]) {
        keys.push(key);
      }
    }
  }
  return keys;
}
function compareObjs(oldProps, newProps, equalityFuncs = {}) {
  if (oldProps === newProps) {
    return true;
  }
  // if (debug) {
  //   for (let key in newProps) {
  //     if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) {
  //       // equal
  //     } else {
  //       if (debug) {
  //         console.log('prop difference', key, oldProps[key], newProps[key])
  //       }
  //     }
  //   }
  //   // check for props that were omitted in the new
  //   for (let key in oldProps) {
  //     if (!(key in newProps)) {
  //       if (debug) {
  //         console.log('prop absent', key)
  //       }
  //     }
  //   }
  // }
  for (let key in newProps) {
    if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ;else {
      return false;
    }
  }
  // check for props that were omitted in the new
  for (let key in oldProps) {
    if (!(key in newProps)) {
      return false;
    }
  }
  return true;
}
/*
assumed "true" equality for handler names like "onReceiveSomething"
*/
function isObjValsEqual(val0, val1, comparator) {
  if (val0 === val1 || comparator === true) {
    return true;
  }
  if (comparator) {
    return comparator(val0, val1);
  }
  return false;
}
function collectFromHash(hash, startIndex = 0, endIndex, step = 1) {
  let res = [];
  if (endIndex == null) {
    endIndex = Object.keys(hash).length;
  }
  for (let i = startIndex; i < endIndex; i += step) {
    let val = hash[i];
    if (val !== undefined) {
      // will disregard undefined for sparse arrays
      res.push(val);
    }
  }
  return res;
}
let calendarSystemClassMap = {};
function registerCalendarSystem(name, theClass) {
  calendarSystemClassMap[name] = theClass;
}
function createCalendarSystem(name) {
  return new calendarSystemClassMap[name]();
}
class GregorianCalendarSystem {
  getMarkerYear(d) {
    return d.getUTCFullYear();
  }
  getMarkerMonth(d) {
    return d.getUTCMonth();
  }
  getMarkerDay(d) {
    return d.getUTCDate();
  }
  arrayToMarker(arr) {
    return arrayToUtcDate(arr);
  }
  markerToArray(marker) {
    return dateToUtcArray(marker);
  }
}
registerCalendarSystem('gregory', GregorianCalendarSystem);
const ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/;
function parse(str) {
  let m = ISO_RE.exec(str);
  if (m) {
    let marker = new Date(Date.UTC(Number(m[1]), m[3] ? Number(m[3]) - 1 : 0, Number(m[5] || 1), Number(m[7] || 0), Number(m[8] || 0), Number(m[10] || 0), m[12] ? Number(`0.${m[12]}`) * 1000 : 0));
    if (isValidDate(marker)) {
      let timeZoneOffset = null;
      if (m[13]) {
        timeZoneOffset = (m[15] === '-' ? -1 : 1) * (Number(m[16] || 0) * 60 + Number(m[18] || 0));
      }
      return {
        marker,
        isTimeUnspecified: !m[6],
        timeZoneOffset
      };
    }
  }
  return null;
}
class DateEnv {
  constructor(settings) {
    let timeZone = this.timeZone = settings.timeZone;
    let isNamedTimeZone = timeZone !== 'local' && timeZone !== 'UTC';
    if (settings.namedTimeZoneImpl && isNamedTimeZone) {
      this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone);
    }
    this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl);
    this.calendarSystem = createCalendarSystem(settings.calendarSystem);
    this.locale = settings.locale;
    this.weekDow = settings.locale.week.dow;
    this.weekDoy = settings.locale.week.doy;
    if (settings.weekNumberCalculation === 'ISO') {
      this.weekDow = 1;
      this.weekDoy = 4;
    }
    if (typeof settings.firstDay === 'number') {
      this.weekDow = settings.firstDay;
    }
    if (typeof settings.weekNumberCalculation === 'function') {
      this.weekNumberFunc = settings.weekNumberCalculation;
    }
    this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText;
    this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText;
    this.cmdFormatter = settings.cmdFormatter;
    this.defaultSeparator = settings.defaultSeparator;
  }
  // Creating / Parsing
  createMarker(input) {
    let meta = this.createMarkerMeta(input);
    if (meta === null) {
      return null;
    }
    return meta.marker;
  }
  createNowMarker() {
    if (this.canComputeOffset) {
      return this.timestampToMarker(new Date().valueOf());
    }
    // if we can't compute the current date val for a timezone,
    // better to give the current local date vals than UTC
    return arrayToUtcDate(dateToLocalArray(new Date()));
  }
  createMarkerMeta(input) {
    if (typeof input === 'string') {
      return this.parse(input);
    }
    let marker = null;
    if (typeof input === 'number') {
      marker = this.timestampToMarker(input);
    } else if (input instanceof Date) {
      input = input.valueOf();
      if (!isNaN(input)) {
        marker = this.timestampToMarker(input);
      }
    } else if (Array.isArray(input)) {
      marker = arrayToUtcDate(input);
    }
    if (marker === null || !isValidDate(marker)) {
      return null;
    }
    return {
      marker,
      isTimeUnspecified: false,
      forcedTzo: null
    };
  }
  parse(s) {
    let parts = parse(s);
    if (parts === null) {
      return null;
    }
    let {
      marker
    } = parts;
    let forcedTzo = null;
    if (parts.timeZoneOffset !== null) {
      if (this.canComputeOffset) {
        marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1000);
      } else {
        forcedTzo = parts.timeZoneOffset;
      }
    }
    return {
      marker,
      isTimeUnspecified: parts.isTimeUnspecified,
      forcedTzo
    };
  }
  // Accessors
  getYear(marker) {
    return this.calendarSystem.getMarkerYear(marker);
  }
  getMonth(marker) {
    return this.calendarSystem.getMarkerMonth(marker);
  }
  getDay(marker) {
    return this.calendarSystem.getMarkerDay(marker);
  }
  // Adding / Subtracting
  add(marker, dur) {
    let a = this.calendarSystem.markerToArray(marker);
    a[0] += dur.years;
    a[1] += dur.months;
    a[2] += dur.days;
    a[6] += dur.milliseconds;
    return this.calendarSystem.arrayToMarker(a);
  }
  subtract(marker, dur) {
    let a = this.calendarSystem.markerToArray(marker);
    a[0] -= dur.years;
    a[1] -= dur.months;
    a[2] -= dur.days;
    a[6] -= dur.milliseconds;
    return this.calendarSystem.arrayToMarker(a);
  }
  addYears(marker, n) {
    let a = this.calendarSystem.markerToArray(marker);
    a[0] += n;
    return this.calendarSystem.arrayToMarker(a);
  }
  addMonths(marker, n) {
    let a = this.calendarSystem.markerToArray(marker);
    a[1] += n;
    return this.calendarSystem.arrayToMarker(a);
  }
  // Diffing Whole Units
  diffWholeYears(m0, m1) {
    let {
      calendarSystem
    } = this;
    if (timeAsMs(m0) === timeAsMs(m1) && calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) {
      return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0);
    }
    return null;
  }
  diffWholeMonths(m0, m1) {
    let {
      calendarSystem
    } = this;
    if (timeAsMs(m0) === timeAsMs(m1) && calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) {
      return calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0) + (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12;
    }
    return null;
  }
  // Range / Duration
  greatestWholeUnit(m0, m1) {
    let n = this.diffWholeYears(m0, m1);
    if (n !== null) {
      return {
        unit: 'year',
        value: n
      };
    }
    n = this.diffWholeMonths(m0, m1);
    if (n !== null) {
      return {
        unit: 'month',
        value: n
      };
    }
    n = diffWholeWeeks(m0, m1);
    if (n !== null) {
      return {
        unit: 'week',
        value: n
      };
    }
    n = diffWholeDays(m0, m1);
    if (n !== null) {
      return {
        unit: 'day',
        value: n
      };
    }
    n = diffHours(m0, m1);
    if (isInt(n)) {
      return {
        unit: 'hour',
        value: n
      };
    }
    n = diffMinutes(m0, m1);
    if (isInt(n)) {
      return {
        unit: 'minute',
        value: n
      };
    }
    n = diffSeconds(m0, m1);
    if (isInt(n)) {
      return {
        unit: 'second',
        value: n
      };
    }
    return {
      unit: 'millisecond',
      value: m1.valueOf() - m0.valueOf()
    };
  }
  countDurationsBetween(m0, m1, d) {
    // TODO: can use greatestWholeUnit
    let diff;
    if (d.years) {
      diff = this.diffWholeYears(m0, m1);
      if (diff !== null) {
        return diff / asRoughYears(d);
      }
    }
    if (d.months) {
      diff = this.diffWholeMonths(m0, m1);
      if (diff !== null) {
        return diff / asRoughMonths(d);
      }
    }
    if (d.days) {
      diff = diffWholeDays(m0, m1);
      if (diff !== null) {
        return diff / asRoughDays(d);
      }
    }
    return (m1.valueOf() - m0.valueOf()) / asRoughMs(d);
  }
  // Start-Of
  // these DON'T return zoned-dates. only UTC start-of dates
  startOf(m, unit) {
    if (unit === 'year') {
      return this.startOfYear(m);
    }
    if (unit === 'month') {
      return this.startOfMonth(m);
    }
    if (unit === 'week') {
      return this.startOfWeek(m);
    }
    if (unit === 'day') {
      return startOfDay(m);
    }
    if (unit === 'hour') {
      return startOfHour(m);
    }
    if (unit === 'minute') {
      return startOfMinute(m);
    }
    if (unit === 'second') {
      return startOfSecond(m);
    }
    return null;
  }
  startOfYear(m) {
    return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(m)]);
  }
  startOfMonth(m) {
    return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(m), this.calendarSystem.getMarkerMonth(m)]);
  }
  startOfWeek(m) {
    return this.calendarSystem.arrayToMarker([this.calendarSystem.getMarkerYear(m), this.calendarSystem.getMarkerMonth(m), m.getUTCDate() - (m.getUTCDay() - this.weekDow + 7) % 7]);
  }
  // Week Number
  computeWeekNumber(marker) {
    if (this.weekNumberFunc) {
      return this.weekNumberFunc(this.toDate(marker));
    }
    return weekOfYear(marker, this.weekDow, this.weekDoy);
  }
  // TODO: choke on timeZoneName: long
  format(marker, formatter, dateOptions = {}) {
    return formatter.format({
      marker,
      timeZoneOffset: dateOptions.forcedTzo != null ? dateOptions.forcedTzo : this.offsetForMarker(marker)
    }, this);
  }
  formatRange(start, end, formatter, dateOptions = {}) {
    if (dateOptions.isEndExclusive) {
      end = addMs(end, -1);
    }
    return formatter.formatRange({
      marker: start,
      timeZoneOffset: dateOptions.forcedStartTzo != null ? dateOptions.forcedStartTzo : this.offsetForMarker(start)
    }, {
      marker: end,
      timeZoneOffset: dateOptions.forcedEndTzo != null ? dateOptions.forcedEndTzo : this.offsetForMarker(end)
    }, this, dateOptions.defaultSeparator);
  }
  /*
  DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that,
  might as well use buildIsoString or some other util directly
  */
  formatIso(marker, extraOptions = {}) {
    let timeZoneOffset = null;
    if (!extraOptions.omitTimeZoneOffset) {
      if (extraOptions.forcedTzo != null) {
        timeZoneOffset = extraOptions.forcedTzo;
      } else {
        timeZoneOffset = this.offsetForMarker(marker);
      }
    }
    return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime);
  }
  // TimeZone
  timestampToMarker(ms) {
    if (this.timeZone === 'local') {
      return arrayToUtcDate(dateToLocalArray(new Date(ms)));
    }
    if (this.timeZone === 'UTC' || !this.namedTimeZoneImpl) {
      return new Date(ms);
    }
    return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms));
  }
  offsetForMarker(m) {
    if (this.timeZone === 'local') {
      return -arrayToLocalDate(dateToUtcArray(m)).getTimezoneOffset(); // convert "inverse" offset to "normal" offset
    }
    if (this.timeZone === 'UTC') {
      return 0;
    }
    if (this.namedTimeZoneImpl) {
      return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m));
    }
    return null;
  }
  // Conversion
  toDate(m, forcedTzo) {
    if (this.timeZone === 'local') {
      return arrayToLocalDate(dateToUtcArray(m));
    }
    if (this.timeZone === 'UTC') {
      return new Date(m.valueOf()); // make sure it's a copy
    }
    if (!this.namedTimeZoneImpl) {
      return new Date(m.valueOf() - (forcedTzo || 0));
    }
    return new Date(m.valueOf() - this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m)) * 1000 * 60);
  }
}
class Theme {
  constructor(calendarOptions) {
    if (this.iconOverrideOption) {
      this.setIconOverride(calendarOptions[this.iconOverrideOption]);
    }
  }
  setIconOverride(iconOverrideHash) {
    let iconClassesCopy;
    let buttonName;
    if (typeof iconOverrideHash === 'object' && iconOverrideHash) {
      // non-null object
      iconClassesCopy = Object.assign({}, this.iconClasses);
      for (buttonName in iconOverrideHash) {
        iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]);
      }
      this.iconClasses = iconClassesCopy;
    } else if (iconOverrideHash === false) {
      this.iconClasses = {};
    }
  }
  applyIconOverridePrefix(className) {
    let prefix = this.iconOverridePrefix;
    if (prefix && className.indexOf(prefix) !== 0) {
      // if not already present
      className = prefix + className;
    }
    return className;
  }
  getClass(key) {
    return this.classes[key] || '';
  }
  getIconClass(buttonName, isRtl) {
    let className;
    if (isRtl && this.rtlIconClasses) {
      className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName];
    } else {
      className = this.iconClasses[buttonName];
    }
    if (className) {
      return `${this.baseIconClass} ${className}`;
    }
    return '';
  }
  getCustomButtonIconClass(customButtonProps) {
    let className;
    if (this.iconOverrideCustomButtonOption) {
      className = customButtonProps[this.iconOverrideCustomButtonOption];
      if (className) {
        return `${this.baseIconClass} ${this.applyIconOverridePrefix(className)}`;
      }
    }
    return '';
  }
}
Theme.prototype.classes = {};
Theme.prototype.iconClasses = {};
Theme.prototype.baseIconClass = '';
Theme.prototype.iconOverridePrefix = '';

/*
NOTE: this can be a public API, especially createElement for hooks.
See examples/typescript-scheduler/src/index.ts
*/
function flushSync(runBeforeFlush) {
  runBeforeFlush();
  let oldDebounceRendering = preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering; // orig
  let callbackQ = [];
  function execCallbackSync(callback) {
    callbackQ.push(callback);
  }
  preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering = execCallbackSync;
  preact__WEBPACK_IMPORTED_MODULE_0__.render(preact__WEBPACK_IMPORTED_MODULE_0__.createElement(FakeComponent, {}), document.createElement('div'));
  while (callbackQ.length) {
    callbackQ.shift()();
  }
  preact__WEBPACK_IMPORTED_MODULE_0__.options.debounceRendering = oldDebounceRendering;
}
class FakeComponent extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {
  render() {
    return preact__WEBPACK_IMPORTED_MODULE_0__.createElement('div', {});
  }
  componentDidMount() {
    this.setState({});
  }
}
// TODO: use preact/compat instead?
function createContext(defaultValue) {
  let ContextType = preact__WEBPACK_IMPORTED_MODULE_0__.createContext(defaultValue);
  let origProvider = ContextType.Provider;
  ContextType.Provider = function () {
    let isNew = !this.getChildContext;
    let children = origProvider.apply(this, arguments); // eslint-disable-line prefer-rest-params
    if (isNew) {
      let subs = [];
      this.shouldComponentUpdate = _props => {
        if (this.props.value !== _props.value) {
          subs.forEach(c => {
            c.context = _props.value;
            c.forceUpdate();
          });
        }
      };
      this.sub = c => {
        subs.push(c);
        let old = c.componentWillUnmount;
        c.componentWillUnmount = () => {
          subs.splice(subs.indexOf(c), 1);
          old && old.call(c);
        };
      };
    }
    return children;
  };
  return ContextType;
}
class ScrollResponder {
  constructor(execFunc, emitter, scrollTime, scrollTimeReset) {
    this.execFunc = execFunc;
    this.emitter = emitter;
    this.scrollTime = scrollTime;
    this.scrollTimeReset = scrollTimeReset;
    this.handleScrollRequest = request => {
      this.queuedRequest = Object.assign({}, this.queuedRequest || {}, request);
      this.drain();
    };
    emitter.on('_scrollRequest', this.handleScrollRequest);
    this.fireInitialScroll();
  }
  detach() {
    this.emitter.off('_scrollRequest', this.handleScrollRequest);
  }
  update(isDatesNew) {
    if (isDatesNew && this.scrollTimeReset) {
      this.fireInitialScroll(); // will drain
    } else {
      this.drain();
    }
  }
  fireInitialScroll() {
    this.handleScrollRequest({
      time: this.scrollTime
    });
  }
  drain() {
    if (this.queuedRequest && this.execFunc(this.queuedRequest)) {
      this.queuedRequest = null;
    }
  }
}
const ViewContextType = createContext({}); // for Components
function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, nowManager, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) {
  return {
    dateEnv,
    nowManager,
    options: viewOptions,
    pluginHooks,
    emitter,
    dispatch,
    getCurrentData,
    calendarApi,
    viewSpec,
    viewApi,
    dateProfileGenerator,
    theme,
    isRtl: viewOptions.direction === 'rtl',
    addResizeHandler(handler) {
      emitter.on('_resize', handler);
    },
    removeResizeHandler(handler) {
      emitter.off('_resize', handler);
    },
    createScrollResponder(execFunc) {
      return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset);
    },
    registerInteractiveComponent,
    unregisterInteractiveComponent
  };
}

/* eslint max-classes-per-file: off */
class PureComponent extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {
  // debug: boolean
  shouldComponentUpdate(nextProps, nextState) {
    const shouldUpdate = !compareObjs(this.props, nextProps, this.propEquality /*, this.debug */) || !compareObjs(this.state, nextState, this.stateEquality /*, this.debug */);
    // if (this.debug && shouldUpdate) {
    //   console.log('shouldUpdate!')
    // }
    return shouldUpdate;
  }
  // HACK for freakin' React StrictMode
  safeSetState(newState) {
    if (!compareObjs(this.state, Object.assign(Object.assign({}, this.state), newState), this.stateEquality)) {
      this.setState(newState);
    }
  }
}
PureComponent.addPropsEquality = addPropsEquality;
PureComponent.addStateEquality = addStateEquality;
PureComponent.contextType = ViewContextType;
PureComponent.prototype.propEquality = {};
PureComponent.prototype.stateEquality = {};
class BaseComponent extends PureComponent {}
BaseComponent.contextType = ViewContextType;
function addPropsEquality(propEquality) {
  let hash = Object.create(this.prototype.propEquality);
  Object.assign(hash, propEquality);
  this.prototype.propEquality = hash;
}
function addStateEquality(stateEquality) {
  let hash = Object.create(this.prototype.stateEquality);
  Object.assign(hash, stateEquality);
  this.prototype.stateEquality = hash;
}
// use other one
function setRef(ref, current) {
  if (typeof ref === 'function') {
    ref(current);
  } else if (ref) {
    // see https://github.com/facebook/react/issues/13029
    ref.current = current;
  }
}
class ContentInjector extends BaseComponent {
  constructor() {
    super(...arguments);
    this.id = guid();
    this.queuedDomNodes = [];
    this.currentDomNodes = [];
    this.handleEl = el => {
      const {
        options
      } = this.context;
      const {
        generatorName
      } = this.props;
      if (!options.customRenderingReplaces || !hasCustomRenderingHandler(generatorName, options)) {
        this.updateElRef(el);
      }
    };
    this.updateElRef = el => {
      if (this.props.elRef) {
        setRef(this.props.elRef, el);
      }
    };
  }
  render() {
    const {
      props,
      context
    } = this;
    const {
      options
    } = context;
    const {
      customGenerator,
      defaultGenerator,
      renderProps
    } = props;
    const attrs = buildElAttrs(props, [], this.handleEl);
    let useDefault = false;
    let innerContent;
    let queuedDomNodes = [];
    let currentGeneratorMeta;
    if (customGenerator != null) {
      const customGeneratorRes = typeof customGenerator === 'function' ? customGenerator(renderProps, preact__WEBPACK_IMPORTED_MODULE_0__.createElement) : customGenerator;
      if (customGeneratorRes === true) {
        useDefault = true;
      } else {
        const isObject = customGeneratorRes && typeof customGeneratorRes === 'object'; // non-null
        if (isObject && 'html' in customGeneratorRes) {
          attrs.dangerouslySetInnerHTML = {
            __html: customGeneratorRes.html
          };
        } else if (isObject && 'domNodes' in customGeneratorRes) {
          queuedDomNodes = Array.prototype.slice.call(customGeneratorRes.domNodes);
        } else if (isObject ? (0,preact__WEBPACK_IMPORTED_MODULE_0__.isValidElement)(customGeneratorRes) // vdom node
        : typeof customGeneratorRes !== 'function' // primitive value (like string or number)
        ) {
          // use in vdom
          innerContent = customGeneratorRes;
        } else {
          // an exotic object for handleCustomRendering
          currentGeneratorMeta = customGeneratorRes;
        }
      }
    } else {
      useDefault = !hasCustomRenderingHandler(props.generatorName, options);
    }
    if (useDefault && defaultGenerator) {
      innerContent = defaultGenerator(renderProps);
    }
    this.queuedDomNodes = queuedDomNodes;
    this.currentGeneratorMeta = currentGeneratorMeta;
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(props.elTag, attrs, innerContent);
  }
  componentDidMount() {
    this.applyQueueudDomNodes();
    this.triggerCustomRendering(true);
  }
  componentDidUpdate() {
    this.applyQueueudDomNodes();
    this.triggerCustomRendering(true);
  }
  componentWillUnmount() {
    this.triggerCustomRendering(false); // TODO: different API for removal?
  }
  triggerCustomRendering(isActive) {
    var _a;
    const {
      props,
      context
    } = this;
    const {
      handleCustomRendering,
      customRenderingMetaMap
    } = context.options;
    if (handleCustomRendering) {
      const generatorMeta = (_a = this.currentGeneratorMeta) !== null && _a !== void 0 ? _a : customRenderingMetaMap === null || customRenderingMetaMap === void 0 ? void 0 : customRenderingMetaMap[props.generatorName];
      if (generatorMeta) {
        handleCustomRendering(Object.assign(Object.assign({
          id: this.id,
          isActive,
          containerEl: this.base,
          reportNewContainerEl: this.updateElRef,
          // front-end framework tells us about new container els
          generatorMeta
        }, props), {
          elClasses: (props.elClasses || []).filter(isTruthy)
        }));
      }
    }
  }
  applyQueueudDomNodes() {
    const {
      queuedDomNodes,
      currentDomNodes
    } = this;
    const el = this.base;
    if (!isArraysEqual(queuedDomNodes, currentDomNodes)) {
      currentDomNodes.forEach(removeElement);
      for (let newNode of queuedDomNodes) {
        el.appendChild(newNode);
      }
      this.currentDomNodes = queuedDomNodes;
    }
  }
}
ContentInjector.addPropsEquality({
  elClasses: isArraysEqual,
  elStyle: isPropsEqual,
  elAttrs: isNonHandlerPropsEqual,
  renderProps: isPropsEqual
});
// Util
/*
Does UI-framework provide custom way of rendering that does not use Preact VDOM
AND does the calendar's options define custom rendering?
AKA. Should we NOT render the default content?
*/
function hasCustomRenderingHandler(generatorName, options) {
  var _a;
  return Boolean(options.handleCustomRendering && generatorName && ((_a = options.customRenderingMetaMap) === null || _a === void 0 ? void 0 : _a[generatorName]));
}
function buildElAttrs(props, extraClassNames, elRef) {
  const attrs = Object.assign(Object.assign({}, props.elAttrs), {
    ref: elRef
  });
  if (props.elClasses || extraClassNames) {
    attrs.className = (props.elClasses || []).concat(extraClassNames || []).concat(attrs.className || []).filter(Boolean).join(' ');
  }
  if (props.elStyle) {
    attrs.style = props.elStyle;
  }
  return attrs;
}
function isTruthy(val) {
  return Boolean(val);
}
const RenderId = createContext(0);
class ContentContainer extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {
  constructor() {
    super(...arguments);
    this.InnerContent = InnerContentInjector.bind(undefined, this);
    this.handleEl = el => {
      this.el = el;
      if (this.props.elRef) {
        setRef(this.props.elRef, el);
        if (el && this.didMountMisfire) {
          this.componentDidMount();
        }
      }
    };
  }
  render() {
    const {
      props
    } = this;
    const generatedClassNames = generateClassNames(props.classNameGenerator, props.renderProps);
    if (props.children) {
      const elAttrs = buildElAttrs(props, generatedClassNames, this.handleEl);
      const children = props.children(this.InnerContent, props.renderProps, elAttrs);
      if (props.elTag) {
        return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(props.elTag, elAttrs, children);
      } else {
        return children;
      }
    } else {
      return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentInjector, Object.assign(Object.assign({}, props), {
        elRef: this.handleEl,
        elTag: props.elTag || 'div',
        elClasses: (props.elClasses || []).concat(generatedClassNames),
        renderId: this.context
      }));
    }
  }
  componentDidMount() {
    var _a, _b;
    if (this.el) {
      (_b = (_a = this.props).didMount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), {
        el: this.el
      }));
    } else {
      this.didMountMisfire = true;
    }
  }
  componentWillUnmount() {
    var _a, _b;
    (_b = (_a = this.props).willUnmount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), {
      el: this.el
    }));
  }
}
ContentContainer.contextType = RenderId;
function InnerContentInjector(containerComponent, props) {
  const parentProps = containerComponent.props;
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentInjector, Object.assign({
    renderProps: parentProps.renderProps,
    generatorName: parentProps.generatorName,
    customGenerator: parentProps.customGenerator,
    defaultGenerator: parentProps.defaultGenerator,
    renderId: containerComponent.context
  }, props));
}
// Utils
function generateClassNames(classNameGenerator, renderProps) {
  const classNames = typeof classNameGenerator === 'function' ? classNameGenerator(renderProps) : classNameGenerator || [];
  return typeof classNames === 'string' ? [classNames] : classNames;
}
class ViewContainer extends BaseComponent {
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let renderProps = {
      view: context.viewApi
    };
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
      elRef: props.elRef,
      elTag: props.elTag || 'div',
      elAttrs: props.elAttrs,
      elClasses: [...buildViewClassNames(props.viewSpec), ...(props.elClasses || [])],
      elStyle: props.elStyle,
      renderProps: renderProps,
      classNameGenerator: options.viewClassNames,
      generatorName: undefined,
      didMount: options.viewDidMount,
      willUnmount: options.viewWillUnmount
    }, () => props.children);
  }
}
function buildViewClassNames(viewSpec) {
  return [`fc-${viewSpec.type}-view`, 'fc-view'];
}
function parseRange(input, dateEnv) {
  let start = null;
  let end = null;
  if (input.start) {
    start = dateEnv.createMarker(input.start);
  }
  if (input.end) {
    end = dateEnv.createMarker(input.end);
  }
  if (!start && !end) {
    return null;
  }
  if (start && end && end < start) {
    return null;
  }
  return {
    start,
    end
  };
}
// SIDE-EFFECT: will mutate ranges.
// Will return a new array result.
function invertRanges(ranges, constraintRange) {
  let invertedRanges = [];
  let {
    start
  } = constraintRange; // the end of the previous range. the start of the new range
  let i;
  let dateRange;
  // ranges need to be in order. required for our date-walking algorithm
  ranges.sort(compareRanges);
  for (i = 0; i < ranges.length; i += 1) {
    dateRange = ranges[i];
    // add the span of time before the event (if there is any)
    if (dateRange.start > start) {
      // compare millisecond time (skip any ambig logic)
      invertedRanges.push({
        start,
        end: dateRange.start
      });
    }
    if (dateRange.end > start) {
      start = dateRange.end;
    }
  }
  // add the span of time after the last event (if there is any)
  if (start < constraintRange.end) {
    // compare millisecond time (skip any ambig logic)
    invertedRanges.push({
      start,
      end: constraintRange.end
    });
  }
  return invertedRanges;
}
function compareRanges(range0, range1) {
  return range0.start.valueOf() - range1.start.valueOf(); // earlier ranges go first
}
function intersectRanges(range0, range1) {
  let {
    start,
    end
  } = range0;
  let newRange = null;
  if (range1.start !== null) {
    if (start === null) {
      start = range1.start;
    } else {
      start = new Date(Math.max(start.valueOf(), range1.start.valueOf()));
    }
  }
  if (range1.end != null) {
    if (end === null) {
      end = range1.end;
    } else {
      end = new Date(Math.min(end.valueOf(), range1.end.valueOf()));
    }
  }
  if (start === null || end === null || start < end) {
    newRange = {
      start,
      end
    };
  }
  return newRange;
}
function rangesEqual(range0, range1) {
  return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf());
}
function rangesIntersect(range0, range1) {
  return (range0.end === null || range1.start === null || range0.end > range1.start) && (range0.start === null || range1.end === null || range0.start < range1.end);
}
function rangeContainsRange(outerRange, innerRange) {
  return (outerRange.start === null || innerRange.start !== null && innerRange.start >= outerRange.start) && (outerRange.end === null || innerRange.end !== null && innerRange.end <= outerRange.end);
}
function rangeContainsMarker(range, date) {
  return (range.start === null || date >= range.start) && (range.end === null || date < range.end);
}
// If the given date is not within the given range, move it inside.
// (If it's past the end, make it one millisecond before the end).
function constrainMarkerToRange(date, range) {
  if (range.start != null && date < range.start) {
    return range.start;
  }
  if (range.end != null && date >= range.end) {
    return new Date(range.end.valueOf() - 1);
  }
  return date;
}

/* Date stuff that doesn't belong in datelib core
----------------------------------------------------------------------------------------------------------------------*/
// given a timed range, computes an all-day range that has the same exact duration,
// but whose start time is aligned with the start of the day.
function computeAlignedDayRange(timedRange) {
  let dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1;
  let start = startOfDay(timedRange.start);
  let end = addDays(start, dayCnt);
  return {
    start,
    end
  };
}
// given a timed range, computes an all-day range based on how for the end date bleeds into the next day
// TODO: give nextDayThreshold a default arg
function computeVisibleDayRange(timedRange, nextDayThreshold = createDuration(0)) {
  let startDay = null;
  let endDay = null;
  if (timedRange.end) {
    endDay = startOfDay(timedRange.end);
    let endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); // # of milliseconds into `endDay`
    // If the end time is actually inclusively part of the next day and is equal to or
    // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
    // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
    if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) {
      endDay = addDays(endDay, 1);
    }
  }
  if (timedRange.start) {
    startDay = startOfDay(timedRange.start); // the beginning of the day the range starts
    // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
    if (endDay && endDay <= startDay) {
      endDay = addDays(startDay, 1);
    }
  }
  return {
    start: startDay,
    end: endDay
  };
}
// spans from one day into another?
function isMultiDayRange(range) {
  let visibleRange = computeVisibleDayRange(range);
  return diffDays(visibleRange.start, visibleRange.end) > 1;
}
function diffDates(date0, date1, dateEnv, largeUnit) {
  if (largeUnit === 'year') {
    return createDuration(dateEnv.diffWholeYears(date0, date1), 'year');
  }
  if (largeUnit === 'month') {
    return createDuration(dateEnv.diffWholeMonths(date0, date1), 'month');
  }
  return diffDayAndTime(date0, date1); // returns a duration
}
class DateProfileGenerator {
  constructor(props) {
    this.props = props;
    this.initHiddenDays();
  }
  /* Date Range Computation
  ------------------------------------------------------------------------------------------------------------------*/
  // Builds a structure with info about what the dates/ranges will be for the "prev" view.
  buildPrev(currentDateProfile, currentDate, forceToValid) {
    let {
      dateEnv
    } = this.props;
    let prevDate = dateEnv.subtract(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit),
    // important for start-of-month
    currentDateProfile.dateIncrement);
    return this.build(prevDate, -1, forceToValid);
  }
  // Builds a structure with info about what the dates/ranges will be for the "next" view.
  buildNext(currentDateProfile, currentDate, forceToValid) {
    let {
      dateEnv
    } = this.props;
    let nextDate = dateEnv.add(dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit),
    // important for start-of-month
    currentDateProfile.dateIncrement);
    return this.build(nextDate, 1, forceToValid);
  }
  // Builds a structure holding dates/ranges for rendering around the given date.
  // Optional direction param indicates whether the date is being incremented/decremented
  // from its previous value. decremented = -1, incremented = 1 (default).
  build(currentDate, direction, forceToValid = true) {
    let {
      props
    } = this;
    let validRange;
    let currentInfo;
    let isRangeAllDay;
    let renderRange;
    let activeRange;
    let isValid;
    validRange = this.buildValidRange();
    validRange = this.trimHiddenDays(validRange);
    if (forceToValid) {
      currentDate = constrainMarkerToRange(currentDate, validRange);
    }
    currentInfo = this.buildCurrentRangeInfo(currentDate, direction);
    isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
    renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay);
    renderRange = this.trimHiddenDays(renderRange);
    activeRange = renderRange;
    if (!props.showNonCurrentDates) {
      activeRange = intersectRanges(activeRange, currentInfo.range);
    }
    activeRange = this.adjustActiveRange(activeRange);
    activeRange = intersectRanges(activeRange, validRange); // might return null
    // it's invalid if the originally requested date is not contained,
    // or if the range is completely outside of the valid range.
    isValid = rangesIntersect(currentInfo.range, validRange);
    // HACK: constrain to render-range so `currentDate` is more useful to view rendering
    if (!rangeContainsMarker(renderRange, currentDate)) {
      currentDate = renderRange.start;
    }
    return {
      currentDate,
      // constraint for where prev/next operations can go and where events can be dragged/resized to.
      // an object with optional start and end properties.
      validRange,
      // range the view is formally responsible for.
      // for example, a month view might have 1st-31st, excluding padded dates
      currentRange: currentInfo.range,
      // name of largest unit being displayed, like "month" or "week"
      currentRangeUnit: currentInfo.unit,
      isRangeAllDay,
      // dates that display events and accept drag-n-drop
      // will be `null` if no dates accept events
      activeRange,
      // date range with a rendered skeleton
      // includes not-active days that need some sort of DOM
      renderRange,
      // Duration object that denotes the first visible time of any given day
      slotMinTime: props.slotMinTime,
      // Duration object that denotes the exclusive visible end time of any given day
      slotMaxTime: props.slotMaxTime,
      isValid,
      // how far the current date will move for a prev/next operation
      dateIncrement: this.buildDateIncrement(currentInfo.duration)
      // pass a fallback (might be null) ^
    };
  }
  // Builds an object with optional start/end properties.
  // Indicates the minimum/maximum dates to display.
  // not responsible for trimming hidden days.
  buildValidRange() {
    let input = this.props.validRangeInput;
    let simpleInput = typeof input === 'function' ? input.call(this.props.calendarApi, this.props.dateEnv.toDate(this.props.nowManager.getDateMarker())) : input;
    return this.refineRange(simpleInput) || {
      start: null,
      end: null
    }; // completely open-ended
  }
  // Builds a structure with info about the "current" range, the range that is
  // highlighted as being the current month for example.
  // See build() for a description of `direction`.
  // Guaranteed to have `range` and `unit` properties. `duration` is optional.
  buildCurrentRangeInfo(date, direction) {
    let {
      props
    } = this;
    let duration = null;
    let unit = null;
    let range = null;
    let dayCount;
    if (props.duration) {
      duration = props.duration;
      unit = props.durationUnit;
      range = this.buildRangeFromDuration(date, direction, duration, unit);
    } else if (dayCount = this.props.dayCount) {
      unit = 'day';
      range = this.buildRangeFromDayCount(date, direction, dayCount);
    } else if (range = this.buildCustomVisibleRange(date)) {
      unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit;
    } else {
      duration = this.getFallbackDuration();
      unit = greatestDurationDenominator(duration).unit;
      range = this.buildRangeFromDuration(date, direction, duration, unit);
    }
    return {
      duration,
      unit,
      range
    };
  }
  getFallbackDuration() {
    return createDuration({
      day: 1
    });
  }
  // Returns a new activeRange to have time values (un-ambiguate)
  // slotMinTime or slotMaxTime causes the range to expand.
  adjustActiveRange(range) {
    let {
      dateEnv,
      usesMinMaxTime,
      slotMinTime,
      slotMaxTime
    } = this.props;
    let {
      start,
      end
    } = range;
    if (usesMinMaxTime) {
      // expand active range if slotMinTime is negative (why not when positive?)
      if (asRoughDays(slotMinTime) < 0) {
        start = startOfDay(start); // necessary?
        start = dateEnv.add(start, slotMinTime);
      }
      // expand active range if slotMaxTime is beyond one day (why not when negative?)
      if (asRoughDays(slotMaxTime) > 1) {
        end = startOfDay(end); // necessary?
        end = addDays(end, -1);
        end = dateEnv.add(end, slotMaxTime);
      }
    }
    return {
      start,
      end
    };
  }
  // Builds the "current" range when it is specified as an explicit duration.
  // `unit` is the already-computed greatestDurationDenominator unit of duration.
  buildRangeFromDuration(date, direction, duration, unit) {
    let {
      dateEnv,
      dateAlignment
    } = this.props;
    let start;
    let end;
    let res;
    // compute what the alignment should be
    if (!dateAlignment) {
      let {
        dateIncrement
      } = this.props;
      if (dateIncrement) {
        // use the smaller of the two units
        if (asRoughMs(dateIncrement) < asRoughMs(duration)) {
          dateAlignment = greatestDurationDenominator(dateIncrement).unit;
        } else {
          dateAlignment = unit;
        }
      } else {
        dateAlignment = unit;
      }
    }
    // if the view displays a single day or smaller
    if (asRoughDays(duration) <= 1) {
      if (this.isHiddenDay(start)) {
        start = this.skipHiddenDays(start, direction);
        start = startOfDay(start);
      }
    }
    function computeRes() {
      start = dateEnv.startOf(date, dateAlignment);
      end = dateEnv.add(start, duration);
      res = {
        start,
        end
      };
    }
    computeRes();
    // if range is completely enveloped by hidden days, go past the hidden days
    if (!this.trimHiddenDays(res)) {
      date = this.skipHiddenDays(date, direction);
      computeRes();
    }
    return res;
  }
  // Builds the "current" range when a dayCount is specified.
  buildRangeFromDayCount(date, direction, dayCount) {
    let {
      dateEnv,
      dateAlignment
    } = this.props;
    let runningCount = 0;
    let start = date;
    let end;
    if (dateAlignment) {
      start = dateEnv.startOf(start, dateAlignment);
    }
    start = startOfDay(start);
    start = this.skipHiddenDays(start, direction);
    end = start;
    do {
      end = addDays(end, 1);
      if (!this.isHiddenDay(end)) {
        runningCount += 1;
      }
    } while (runningCount < dayCount);
    return {
      start,
      end
    };
  }
  // Builds a normalized range object for the "visible" range,
  // which is a way to define the currentRange and activeRange at the same time.
  buildCustomVisibleRange(date) {
    let {
      props
    } = this;
    let input = props.visibleRangeInput;
    let simpleInput = typeof input === 'function' ? input.call(props.calendarApi, props.dateEnv.toDate(date)) : input;
    let range = this.refineRange(simpleInput);
    if (range && (range.start == null || range.end == null)) {
      return null;
    }
    return range;
  }
  // Computes the range that will represent the element/cells for *rendering*,
  // but which may have voided days/times.
  // not responsible for trimming hidden days.
  buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {
    return currentRange;
  }
  // Compute the duration value that should be added/substracted to the current date
  // when a prev/next operation happens.
  buildDateIncrement(fallback) {
    let {
      dateIncrement
    } = this.props;
    let customAlignment;
    if (dateIncrement) {
      return dateIncrement;
    }
    if (customAlignment = this.props.dateAlignment) {
      return createDuration(1, customAlignment);
    }
    if (fallback) {
      return fallback;
    }
    return createDuration({
      days: 1
    });
  }
  refineRange(rangeInput) {
    if (rangeInput) {
      let range = parseRange(rangeInput, this.props.dateEnv);
      if (range) {
        range = computeVisibleDayRange(range);
      }
      return range;
    }
    return null;
  }
  /* Hidden Days
  ------------------------------------------------------------------------------------------------------------------*/
  // Initializes internal variables related to calculating hidden days-of-week
  initHiddenDays() {
    let hiddenDays = this.props.hiddenDays || []; // array of day-of-week indices that are hidden
    let isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
    let dayCnt = 0;
    let i;
    if (this.props.weekends === false) {
      hiddenDays.push(0, 6); // 0=sunday, 6=saturday
    }
    for (i = 0; i < 7; i += 1) {
      if (!(isHiddenDayHash[i] = hiddenDays.indexOf(i) !== -1)) {
        dayCnt += 1;
      }
    }
    if (!dayCnt) {
      throw new Error('invalid hiddenDays'); // all days were hidden? bad.
    }
    this.isHiddenDayHash = isHiddenDayHash;
  }
  // Remove days from the beginning and end of the range that are computed as hidden.
  // If the whole range is trimmed off, returns null
  trimHiddenDays(range) {
    let {
      start,
      end
    } = range;
    if (start) {
      start = this.skipHiddenDays(start);
    }
    if (end) {
      end = this.skipHiddenDays(end, -1, true);
    }
    if (start == null || end == null || start < end) {
      return {
        start,
        end
      };
    }
    return null;
  }
  // Is the current day hidden?
  // `day` is a day-of-week index (0-6), or a Date (used for UTC)
  isHiddenDay(day) {
    if (day instanceof Date) {
      day = day.getUTCDay();
    }
    return this.isHiddenDayHash[day];
  }
  // Incrementing the current day until it is no longer a hidden day, returning a copy.
  // DOES NOT CONSIDER validRange!
  // If the initial value of `date` is not a hidden day, don't do anything.
  // Pass `isExclusive` as `true` if you are dealing with an end date.
  // `inc` defaults to `1` (increment one day forward each time)
  skipHiddenDays(date, inc = 1, isExclusive = false) {
    while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) {
      date = addDays(date, inc);
    }
    return date;
  }
}
function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) {
  return {
    instanceId: guid(),
    defId,
    range,
    forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo,
    forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo
  };
}
function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) {
  for (let i = 0; i < recurringTypes.length; i += 1) {
    let parsed = recurringTypes[i].parse(refined, dateEnv);
    if (parsed) {
      let {
        allDay
      } = refined;
      if (allDay == null) {
        allDay = defaultAllDay;
        if (allDay == null) {
          allDay = parsed.allDayGuess;
          if (allDay == null) {
            allDay = false;
          }
        }
      }
      return {
        allDay,
        duration: parsed.duration,
        typeData: parsed.typeData,
        typeId: i
      };
    }
  }
  return null;
}
function expandRecurring(eventStore, framingRange, context) {
  let {
    dateEnv,
    pluginHooks,
    options
  } = context;
  let {
    defs,
    instances
  } = eventStore;
  // remove existing recurring instances
  // TODO: bad. always expand events as a second step
  instances = filterHash(instances, instance => !defs[instance.defId].recurringDef);
  for (let defId in defs) {
    let def = defs[defId];
    if (def.recurringDef) {
      let {
        duration
      } = def.recurringDef;
      if (!duration) {
        duration = def.allDay ? options.defaultAllDayEventDuration : options.defaultTimedEventDuration;
      }
      let starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes);
      for (let start of starts) {
        let instance = createEventInstance(defId, {
          start,
          end: dateEnv.add(start, duration)
        });
        instances[instance.instanceId] = instance;
      }
    }
  }
  return {
    defs,
    instances
  };
}
/*
Event MUST have a recurringDef
*/
function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) {
  let typeDef = recurringTypes[eventDef.recurringDef.typeId];
  let markers = typeDef.expand(eventDef.recurringDef.typeData, {
    start: dateEnv.subtract(framingRange.start, duration),
    end: framingRange.end
  }, dateEnv);
  // the recurrence plugins don't guarantee that all-day events are start-of-day, so we have to
  if (eventDef.allDay) {
    markers = markers.map(startOfDay);
  }
  return markers;
}
const EVENT_NON_DATE_REFINERS = {
  id: String,
  groupId: String,
  title: String,
  url: String,
  interactive: Boolean
};
const EVENT_DATE_REFINERS = {
  start: identity,
  end: identity,
  date: identity,
  allDay: Boolean
};
const EVENT_REFINERS = Object.assign(Object.assign(Object.assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), {
  extendedProps: identity
});
function parseEvent(raw, eventSource, context, allowOpenRange, refiners = buildEventRefiners(context), defIdMap, instanceIdMap) {
  let {
    refined,
    extra
  } = refineEventDef(raw, context, refiners);
  let defaultAllDay = computeIsDefaultAllDay(eventSource, context);
  let recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes);
  if (recurringRes) {
    let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', recurringRes.allDay, Boolean(recurringRes.duration), context, defIdMap);
    def.recurringDef = {
      typeId: recurringRes.typeId,
      typeData: recurringRes.typeData,
      duration: recurringRes.duration
    };
    return {
      def,
      instance: null
    };
  }
  let singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange);
  if (singleRes) {
    let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : '', singleRes.allDay, singleRes.hasEnd, context, defIdMap);
    let instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo);
    if (instanceIdMap && def.publicId && instanceIdMap[def.publicId]) {
      instance.instanceId = instanceIdMap[def.publicId];
    }
    return {
      def,
      instance
    };
  }
  return null;
}
function refineEventDef(raw, context, refiners = buildEventRefiners(context)) {
  return refineProps(raw, refiners);
}
function buildEventRefiners(context) {
  return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners);
}
/*
Will NOT populate extendedProps with the leftover properties.
Will NOT populate date-related props.
*/
function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context, defIdMap) {
  let def = {
    title: refined.title || '',
    groupId: refined.groupId || '',
    publicId: refined.id || '',
    url: refined.url || '',
    recurringDef: null,
    defId: (defIdMap && refined.id ? defIdMap[refined.id] : '') || guid(),
    sourceId,
    allDay,
    hasEnd,
    interactive: refined.interactive,
    ui: createEventUi(refined, context),
    extendedProps: Object.assign(Object.assign({}, refined.extendedProps || {}), extra)
  };
  for (let memberAdder of context.pluginHooks.eventDefMemberAdders) {
    Object.assign(def, memberAdder(refined));
  }
  // help out EventImpl from having user modify props
  Object.freeze(def.ui.classNames);
  Object.freeze(def.extendedProps);
  return def;
}
function parseSingle(refined, defaultAllDay, context, allowOpenRange) {
  let {
    allDay
  } = refined;
  let startMeta;
  let startMarker = null;
  let hasEnd = false;
  let endMeta;
  let endMarker = null;
  let startInput = refined.start != null ? refined.start : refined.date;
  startMeta = context.dateEnv.createMarkerMeta(startInput);
  if (startMeta) {
    startMarker = startMeta.marker;
  } else if (!allowOpenRange) {
    return null;
  }
  if (refined.end != null) {
    endMeta = context.dateEnv.createMarkerMeta(refined.end);
  }
  if (allDay == null) {
    if (defaultAllDay != null) {
      allDay = defaultAllDay;
    } else {
      // fall back to the date props LAST
      allDay = (!startMeta || startMeta.isTimeUnspecified) && (!endMeta || endMeta.isTimeUnspecified);
    }
  }
  if (allDay && startMarker) {
    startMarker = startOfDay(startMarker);
  }
  if (endMeta) {
    endMarker = endMeta.marker;
    if (allDay) {
      endMarker = startOfDay(endMarker);
    }
    if (startMarker && endMarker <= startMarker) {
      endMarker = null;
    }
  }
  if (endMarker) {
    hasEnd = true;
  } else if (!allowOpenRange) {
    hasEnd = context.options.forceEventDuration || false;
    endMarker = context.dateEnv.add(startMarker, allDay ? context.options.defaultAllDayEventDuration : context.options.defaultTimedEventDuration);
  }
  return {
    allDay,
    hasEnd,
    range: {
      start: startMarker,
      end: endMarker
    },
    forcedStartTzo: startMeta ? startMeta.forcedTzo : null,
    forcedEndTzo: endMeta ? endMeta.forcedTzo : null
  };
}
function computeIsDefaultAllDay(eventSource, context) {
  let res = null;
  if (eventSource) {
    res = eventSource.defaultAllDay;
  }
  if (res == null) {
    res = context.options.defaultAllDay;
  }
  return res;
}
function parseEvents(rawEvents, eventSource, context, allowOpenRange, defIdMap, instanceIdMap) {
  let eventStore = createEmptyEventStore();
  let eventRefiners = buildEventRefiners(context);
  for (let rawEvent of rawEvents) {
    let tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners, defIdMap, instanceIdMap);
    if (tuple) {
      eventTupleToStore(tuple, eventStore);
    }
  }
  return eventStore;
}
function eventTupleToStore(tuple, eventStore = createEmptyEventStore()) {
  eventStore.defs[tuple.def.defId] = tuple.def;
  if (tuple.instance) {
    eventStore.instances[tuple.instance.instanceId] = tuple.instance;
  }
  return eventStore;
}
// retrieves events that have the same groupId as the instance specified by `instanceId`
// or they are the same as the instance.
// why might instanceId not be in the store? an event from another calendar?
function getRelevantEvents(eventStore, instanceId) {
  let instance = eventStore.instances[instanceId];
  if (instance) {
    let def = eventStore.defs[instance.defId];
    // get events/instances with same group
    let newStore = filterEventStoreDefs(eventStore, lookDef => isEventDefsGrouped(def, lookDef));
    // add the original
    // TODO: wish we could use eventTupleToStore or something like it
    newStore.defs[def.defId] = def;
    newStore.instances[instance.instanceId] = instance;
    return newStore;
  }
  return createEmptyEventStore();
}
function isEventDefsGrouped(def0, def1) {
  return Boolean(def0.groupId && def0.groupId === def1.groupId);
}
function createEmptyEventStore() {
  return {
    defs: {},
    instances: {}
  };
}
function mergeEventStores(store0, store1) {
  return {
    defs: Object.assign(Object.assign({}, store0.defs), store1.defs),
    instances: Object.assign(Object.assign({}, store0.instances), store1.instances)
  };
}
function filterEventStoreDefs(eventStore, filterFunc) {
  let defs = filterHash(eventStore.defs, filterFunc);
  let instances = filterHash(eventStore.instances, instance => defs[instance.defId] // still exists?
  );
  return {
    defs,
    instances
  };
}
function excludeSubEventStore(master, sub) {
  let {
    defs,
    instances
  } = master;
  let filteredDefs = {};
  let filteredInstances = {};
  for (let defId in defs) {
    if (!sub.defs[defId]) {
      // not explicitly excluded
      filteredDefs[defId] = defs[defId];
    }
  }
  for (let instanceId in instances) {
    if (!sub.instances[instanceId] &&
    // not explicitly excluded
    filteredDefs[instances[instanceId].defId] // def wasn't filtered away
    ) {
      filteredInstances[instanceId] = instances[instanceId];
    }
  }
  return {
    defs: filteredDefs,
    instances: filteredInstances
  };
}
function normalizeConstraint(input, context) {
  if (Array.isArray(input)) {
    return parseEvents(input, null, context, true); // allowOpenRange=true
  }
  if (typeof input === 'object' && input) {
    // non-null object
    return parseEvents([input], null, context, true); // allowOpenRange=true
  }
  if (input != null) {
    return String(input);
  }
  return null;
}
function parseClassNames(raw) {
  if (Array.isArray(raw)) {
    return raw;
  }
  if (typeof raw === 'string') {
    return raw.split(/\s+/);
  }
  return [];
}

// TODO: better called "EventSettings" or "EventConfig"
// TODO: move this file into structs
// TODO: separate constraint/overlap/allow, because selection uses only that, not other props
const EVENT_UI_REFINERS = {
  display: String,
  editable: Boolean,
  startEditable: Boolean,
  durationEditable: Boolean,
  constraint: identity,
  overlap: identity,
  allow: identity,
  className: parseClassNames,
  classNames: parseClassNames,
  color: String,
  backgroundColor: String,
  borderColor: String,
  textColor: String
};
const EMPTY_EVENT_UI = {
  display: null,
  startEditable: null,
  durationEditable: null,
  constraints: [],
  overlap: null,
  allows: [],
  backgroundColor: '',
  borderColor: '',
  textColor: '',
  classNames: []
};
function createEventUi(refined, context) {
  let constraint = normalizeConstraint(refined.constraint, context);
  return {
    display: refined.display || null,
    startEditable: refined.startEditable != null ? refined.startEditable : refined.editable,
    durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable,
    constraints: constraint != null ? [constraint] : [],
    overlap: refined.overlap != null ? refined.overlap : null,
    allows: refined.allow != null ? [refined.allow] : [],
    backgroundColor: refined.backgroundColor || refined.color || '',
    borderColor: refined.borderColor || refined.color || '',
    textColor: refined.textColor || '',
    classNames: (refined.className || []).concat(refined.classNames || []) // join singular and plural
  };
}
// TODO: prevent against problems with <2 args!
function combineEventUis(uis) {
  return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI);
}
function combineTwoEventUis(item0, item1) {
  return {
    display: item1.display != null ? item1.display : item0.display,
    startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable,
    durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable,
    constraints: item0.constraints.concat(item1.constraints),
    overlap: typeof item1.overlap === 'boolean' ? item1.overlap : item0.overlap,
    allows: item0.allows.concat(item1.allows),
    backgroundColor: item1.backgroundColor || item0.backgroundColor,
    borderColor: item1.borderColor || item0.borderColor,
    textColor: item1.textColor || item0.textColor,
    classNames: item0.classNames.concat(item1.classNames)
  };
}
const EVENT_SOURCE_REFINERS = {
  id: String,
  defaultAllDay: Boolean,
  url: String,
  format: String,
  events: identity,
  eventDataTransform: identity,
  // for any network-related sources
  success: identity,
  failure: identity
};
function parseEventSource(raw, context, refiners = buildEventSourceRefiners(context)) {
  let rawObj;
  if (typeof raw === 'string') {
    rawObj = {
      url: raw
    };
  } else if (typeof raw === 'function' || Array.isArray(raw)) {
    rawObj = {
      events: raw
    };
  } else if (typeof raw === 'object' && raw) {
    // not null
    rawObj = raw;
  }
  if (rawObj) {
    let {
      refined,
      extra
    } = refineProps(rawObj, refiners);
    let metaRes = buildEventSourceMeta(refined, context);
    if (metaRes) {
      return {
        _raw: raw,
        isFetching: false,
        latestFetchId: '',
        fetchRange: null,
        defaultAllDay: refined.defaultAllDay,
        eventDataTransform: refined.eventDataTransform,
        success: refined.success,
        failure: refined.failure,
        publicId: refined.id || '',
        sourceId: guid(),
        sourceDefId: metaRes.sourceDefId,
        meta: metaRes.meta,
        ui: createEventUi(refined, context),
        extendedProps: extra
      };
    }
  }
  return null;
}
function buildEventSourceRefiners(context) {
  return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners);
}
function buildEventSourceMeta(raw, context) {
  let defs = context.pluginHooks.eventSourceDefs;
  for (let i = defs.length - 1; i >= 0; i -= 1) {
    // later-added plugins take precedence
    let def = defs[i];
    let meta = def.parseMeta(raw);
    if (meta) {
      return {
        sourceDefId: i,
        meta
      };
    }
  }
  return null;
}
function reduceEventStore(eventStore, action, eventSources, dateProfile, context) {
  switch (action.type) {
    case 'RECEIVE_EVENTS':
      // raw
      return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context);
    case 'RESET_RAW_EVENTS':
      return resetRawEvents(eventStore, eventSources[action.sourceId], action.rawEvents, dateProfile.activeRange, context);
    case 'ADD_EVENTS':
      // already parsed, but not expanded
      return addEvent(eventStore, action.eventStore,
      // new ones
      dateProfile ? dateProfile.activeRange : null, context);
    case 'RESET_EVENTS':
      return action.eventStore;
    case 'MERGE_EVENTS':
      // already parsed and expanded
      return mergeEventStores(eventStore, action.eventStore);
    case 'PREV': // TODO: how do we track all actions that affect dateProfile :(
    case 'NEXT':
    case 'CHANGE_DATE':
    case 'CHANGE_VIEW_TYPE':
      if (dateProfile) {
        return expandRecurring(eventStore, dateProfile.activeRange, context);
      }
      return eventStore;
    case 'REMOVE_EVENTS':
      return excludeSubEventStore(eventStore, action.eventStore);
    case 'REMOVE_EVENT_SOURCE':
      return excludeEventsBySourceId(eventStore, action.sourceId);
    case 'REMOVE_ALL_EVENT_SOURCES':
      return filterEventStoreDefs(eventStore, eventDef => !eventDef.sourceId // only keep events with no source id
      );
    case 'REMOVE_ALL_EVENTS':
      return createEmptyEventStore();
    default:
      return eventStore;
  }
}
function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) {
  if (eventSource &&
  // not already removed
  fetchId === eventSource.latestFetchId // TODO: wish this logic was always in event-sources
  ) {
    let subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context);
    if (fetchRange) {
      subset = expandRecurring(subset, fetchRange, context);
    }
    return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset);
  }
  return eventStore;
}
function resetRawEvents(existingEventStore, eventSource, rawEvents, activeRange, context) {
  const {
    defIdMap,
    instanceIdMap
  } = buildPublicIdMaps(existingEventStore);
  let newEventStore = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context, false, defIdMap, instanceIdMap);
  return expandRecurring(newEventStore, activeRange, context);
}
function transformRawEvents(rawEvents, eventSource, context) {
  let calEachTransform = context.options.eventDataTransform;
  let sourceEachTransform = eventSource ? eventSource.eventDataTransform : null;
  if (sourceEachTransform) {
    rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform);
  }
  if (calEachTransform) {
    rawEvents = transformEachRawEvent(rawEvents, calEachTransform);
  }
  return rawEvents;
}
function transformEachRawEvent(rawEvents, func) {
  let refinedEvents;
  if (!func) {
    refinedEvents = rawEvents;
  } else {
    refinedEvents = [];
    for (let rawEvent of rawEvents) {
      let refinedEvent = func(rawEvent);
      if (refinedEvent) {
        refinedEvents.push(refinedEvent);
      } else if (refinedEvent == null) {
        refinedEvents.push(rawEvent);
      } // if a different falsy value, do nothing
    }
  }
  return refinedEvents;
}
function addEvent(eventStore, subset, expandRange, context) {
  if (expandRange) {
    subset = expandRecurring(subset, expandRange, context);
  }
  return mergeEventStores(eventStore, subset);
}
function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) {
  let {
    defs
  } = eventStore;
  let instances = mapHash(eventStore.instances, instance => {
    let def = defs[instance.defId];
    if (def.allDay) {
      return instance; // isn't dependent on timezone
    }
    return Object.assign(Object.assign({}, instance), {
      range: {
        start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)),
        end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo))
      },
      forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo,
      forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo
    });
  });
  return {
    defs,
    instances
  };
}
function excludeEventsBySourceId(eventStore, sourceId) {
  return filterEventStoreDefs(eventStore, eventDef => eventDef.sourceId !== sourceId);
}
// QUESTION: why not just return instances? do a general object-property-exclusion util
function excludeInstances(eventStore, removals) {
  return {
    defs: eventStore.defs,
    instances: filterHash(eventStore.instances, instance => !removals[instance.instanceId])
  };
}
function buildPublicIdMaps(eventStore) {
  const {
    defs,
    instances
  } = eventStore;
  const defIdMap = {};
  const instanceIdMap = {};
  for (let defId in defs) {
    const def = defs[defId];
    const {
      publicId
    } = def;
    if (publicId) {
      defIdMap[publicId] = defId;
    }
  }
  for (let instanceId in instances) {
    const instance = instances[instanceId];
    const def = defs[instance.defId];
    const {
      publicId
    } = def;
    if (publicId) {
      instanceIdMap[publicId] = instanceId;
    }
  }
  return {
    defIdMap,
    instanceIdMap
  };
}
class Emitter {
  constructor() {
    this.handlers = {};
    this.thisContext = null;
  }
  setThisContext(thisContext) {
    this.thisContext = thisContext;
  }
  setOptions(options) {
    this.options = options;
  }
  on(type, handler) {
    addToHash(this.handlers, type, handler);
  }
  off(type, handler) {
    removeFromHash(this.handlers, type, handler);
  }
  trigger(type, ...args) {
    let attachedHandlers = this.handlers[type] || [];
    let optionHandler = this.options && this.options[type];
    let handlers = [].concat(optionHandler || [], attachedHandlers);
    for (let handler of handlers) {
      handler.apply(this.thisContext, args);
    }
  }
  hasHandlers(type) {
    return Boolean(this.handlers[type] && this.handlers[type].length || this.options && this.options[type]);
  }
}
function addToHash(hash, type, handler) {
  (hash[type] || (hash[type] = [])).push(handler);
}
function removeFromHash(hash, type, handler) {
  if (handler) {
    if (hash[type]) {
      hash[type] = hash[type].filter(func => func !== handler);
    }
  } else {
    delete hash[type]; // remove all handler funcs for this type
  }
}
const DEF_DEFAULTS = {
  startTime: '09:00',
  endTime: '17:00',
  daysOfWeek: [1, 2, 3, 4, 5],
  display: 'inverse-background',
  classNames: 'fc-non-business',
  groupId: '_businessHours' // so multiple defs get grouped
};
/*
TODO: pass around as EventDefHash!!!
*/
function parseBusinessHours(input, context) {
  return parseEvents(refineInputs(input), null, context);
}
function refineInputs(input) {
  let rawDefs;
  if (input === true) {
    rawDefs = [{}]; // will get DEF_DEFAULTS verbatim
  } else if (Array.isArray(input)) {
    // if specifying an array, every sub-definition NEEDS a day-of-week
    rawDefs = input.filter(rawDef => rawDef.daysOfWeek);
  } else if (typeof input === 'object' && input) {
    // non-null object
    rawDefs = [input];
  } else {
    // is probably false
    rawDefs = [];
  }
  rawDefs = rawDefs.map(rawDef => Object.assign(Object.assign({}, DEF_DEFAULTS), rawDef));
  return rawDefs;
}
function triggerDateSelect(selection, pev, context) {
  context.emitter.trigger('select', Object.assign(Object.assign({}, buildDateSpanApiWithContext(selection, context)), {
    jsEvent: pev ? pev.origEvent : null,
    view: context.viewApi || context.calendarApi.view
  }));
}
function triggerDateUnselect(pev, context) {
  context.emitter.trigger('unselect', {
    jsEvent: pev ? pev.origEvent : null,
    view: context.viewApi || context.calendarApi.view
  });
}
function buildDateSpanApiWithContext(dateSpan, context) {
  let props = {};
  for (let transform of context.pluginHooks.dateSpanTransforms) {
    Object.assign(props, transform(dateSpan, context));
  }
  Object.assign(props, buildDateSpanApi(dateSpan, context.dateEnv));
  return props;
}
// Given an event's allDay status and start date, return what its fallback end date should be.
// TODO: rename to computeDefaultEventEnd
function getDefaultEventEnd(allDay, marker, context) {
  let {
    dateEnv,
    options
  } = context;
  let end = marker;
  if (allDay) {
    end = startOfDay(end);
    end = dateEnv.add(end, options.defaultAllDayEventDuration);
  } else {
    end = dateEnv.add(end, options.defaultTimedEventDuration);
  }
  return end;
}

// applies the mutation to ALL defs/instances within the event store
function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) {
  let eventConfigs = compileEventUis(eventStore.defs, eventConfigBase);
  let dest = createEmptyEventStore();
  for (let defId in eventStore.defs) {
    let def = eventStore.defs[defId];
    dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context);
  }
  for (let instanceId in eventStore.instances) {
    let instance = eventStore.instances[instanceId];
    let def = dest.defs[instance.defId]; // important to grab the newly modified def
    dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context);
  }
  return dest;
}
function applyMutationToEventDef(eventDef, eventConfig, mutation, context) {
  let standardProps = mutation.standardProps || {};
  // if hasEnd has not been specified, guess a good value based on deltas.
  // if duration will change, there's no way the default duration will persist,
  // and thus, we need to mark the event as having a real end
  if (standardProps.hasEnd == null && eventConfig.durationEditable && (mutation.startDelta || mutation.endDelta)) {
    standardProps.hasEnd = true; // TODO: is this mutation okay?
  }
  let copy = Object.assign(Object.assign(Object.assign({}, eventDef), standardProps), {
    ui: Object.assign(Object.assign({}, eventDef.ui), standardProps.ui)
  });
  if (mutation.extendedProps) {
    copy.extendedProps = Object.assign(Object.assign({}, copy.extendedProps), mutation.extendedProps);
  }
  for (let applier of context.pluginHooks.eventDefMutationAppliers) {
    applier(copy, mutation, context);
  }
  if (!copy.hasEnd && context.options.forceEventDuration) {
    copy.hasEnd = true;
  }
  return copy;
}
function applyMutationToEventInstance(eventInstance, eventDef,
// must first be modified by applyMutationToEventDef
eventConfig, mutation, context) {
  let {
    dateEnv
  } = context;
  let forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true;
  let clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false;
  let copy = Object.assign({}, eventInstance);
  if (forceAllDay) {
    copy.range = computeAlignedDayRange(copy.range);
  }
  if (mutation.datesDelta && eventConfig.startEditable) {
    copy.range = {
      start: dateEnv.add(copy.range.start, mutation.datesDelta),
      end: dateEnv.add(copy.range.end, mutation.datesDelta)
    };
  }
  if (mutation.startDelta && eventConfig.durationEditable) {
    copy.range = {
      start: dateEnv.add(copy.range.start, mutation.startDelta),
      end: copy.range.end
    };
  }
  if (mutation.endDelta && eventConfig.durationEditable) {
    copy.range = {
      start: copy.range.start,
      end: dateEnv.add(copy.range.end, mutation.endDelta)
    };
  }
  if (clearEnd) {
    copy.range = {
      start: copy.range.start,
      end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context)
    };
  }
  // in case event was all-day but the supplied deltas were not
  // better util for this?
  if (eventDef.allDay) {
    copy.range = {
      start: startOfDay(copy.range.start),
      end: startOfDay(copy.range.end)
    };
  }
  // handle invalid durations
  if (copy.range.end < copy.range.start) {
    copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context);
  }
  return copy;
}
class EventSourceImpl {
  constructor(context, internalEventSource) {
    this.context = context;
    this.internalEventSource = internalEventSource;
  }
  remove() {
    this.context.dispatch({
      type: 'REMOVE_EVENT_SOURCE',
      sourceId: this.internalEventSource.sourceId
    });
  }
  refetch() {
    this.context.dispatch({
      type: 'FETCH_EVENT_SOURCES',
      sourceIds: [this.internalEventSource.sourceId],
      isRefetch: true
    });
  }
  get id() {
    return this.internalEventSource.publicId;
  }
  get url() {
    return this.internalEventSource.meta.url;
  }
  get format() {
    return this.internalEventSource.meta.format; // TODO: bad. not guaranteed
  }
}
class EventImpl {
  // instance will be null if expressing a recurring event that has no current instances,
  // OR if trying to validate an incoming external event that has no dates assigned
  constructor(context, def, instance) {
    this._context = context;
    this._def = def;
    this._instance = instance || null;
  }
  /*
  TODO: make event struct more responsible for this
  */
  setProp(name, val) {
    if (name in EVENT_DATE_REFINERS) {
      console.warn('Could not set date-related prop \'name\'. Use one of the date-related methods instead.');
      // TODO: make proper aliasing system?
    } else if (name === 'id') {
      val = EVENT_NON_DATE_REFINERS[name](val);
      this.mutate({
        standardProps: {
          publicId: val
        } // hardcoded internal name
      });
    } else if (name in EVENT_NON_DATE_REFINERS) {
      val = EVENT_NON_DATE_REFINERS[name](val);
      this.mutate({
        standardProps: {
          [name]: val
        }
      });
    } else if (name in EVENT_UI_REFINERS) {
      let ui = EVENT_UI_REFINERS[name](val);
      if (name === 'color') {
        ui = {
          backgroundColor: val,
          borderColor: val
        };
      } else if (name === 'editable') {
        ui = {
          startEditable: val,
          durationEditable: val
        };
      } else {
        ui = {
          [name]: val
        };
      }
      this.mutate({
        standardProps: {
          ui
        }
      });
    } else {
      console.warn(`Could not set prop '${name}'. Use setExtendedProp instead.`);
    }
  }
  setExtendedProp(name, val) {
    this.mutate({
      extendedProps: {
        [name]: val
      }
    });
  }
  setStart(startInput, options = {}) {
    let {
      dateEnv
    } = this._context;
    let start = dateEnv.createMarker(startInput);
    if (start && this._instance) {
      // TODO: warning if parsed bad
      let instanceRange = this._instance.range;
      let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); // what if parsed bad!?
      if (options.maintainDuration) {
        this.mutate({
          datesDelta: startDelta
        });
      } else {
        this.mutate({
          startDelta
        });
      }
    }
  }
  setEnd(endInput, options = {}) {
    let {
      dateEnv
    } = this._context;
    let end;
    if (endInput != null) {
      end = dateEnv.createMarker(endInput);
      if (!end) {
        return; // TODO: warning if parsed bad
      }
    }
    if (this._instance) {
      if (end) {
        let endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity);
        this.mutate({
          endDelta
        });
      } else {
        this.mutate({
          standardProps: {
            hasEnd: false
          }
        });
      }
    }
  }
  setDates(startInput, endInput, options = {}) {
    let {
      dateEnv
    } = this._context;
    let standardProps = {
      allDay: options.allDay
    };
    let start = dateEnv.createMarker(startInput);
    let end;
    if (!start) {
      return; // TODO: warning if parsed bad
    }
    if (endInput != null) {
      end = dateEnv.createMarker(endInput);
      if (!end) {
        // TODO: warning if parsed bad
        return;
      }
    }
    if (this._instance) {
      let instanceRange = this._instance.range;
      // when computing the diff for an event being converted to all-day,
      // compute diff off of the all-day values the way event-mutation does.
      if (options.allDay === true) {
        instanceRange = computeAlignedDayRange(instanceRange);
      }
      let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity);
      if (end) {
        let endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity);
        if (durationsEqual(startDelta, endDelta)) {
          this.mutate({
            datesDelta: startDelta,
            standardProps
          });
        } else {
          this.mutate({
            startDelta,
            endDelta,
            standardProps
          });
        }
      } else {
        // means "clear the end"
        standardProps.hasEnd = false;
        this.mutate({
          datesDelta: startDelta,
          standardProps
        });
      }
    }
  }
  moveStart(deltaInput) {
    let delta = createDuration(deltaInput);
    if (delta) {
      // TODO: warning if parsed bad
      this.mutate({
        startDelta: delta
      });
    }
  }
  moveEnd(deltaInput) {
    let delta = createDuration(deltaInput);
    if (delta) {
      // TODO: warning if parsed bad
      this.mutate({
        endDelta: delta
      });
    }
  }
  moveDates(deltaInput) {
    let delta = createDuration(deltaInput);
    if (delta) {
      // TODO: warning if parsed bad
      this.mutate({
        datesDelta: delta
      });
    }
  }
  setAllDay(allDay, options = {}) {
    let standardProps = {
      allDay
    };
    let {
      maintainDuration
    } = options;
    if (maintainDuration == null) {
      maintainDuration = this._context.options.allDayMaintainDuration;
    }
    if (this._def.allDay !== allDay) {
      standardProps.hasEnd = maintainDuration;
    }
    this.mutate({
      standardProps
    });
  }
  formatRange(formatInput) {
    let {
      dateEnv
    } = this._context;
    let instance = this._instance;
    let formatter = createFormatter(formatInput);
    if (this._def.hasEnd) {
      return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, {
        forcedStartTzo: instance.forcedStartTzo,
        forcedEndTzo: instance.forcedEndTzo
      });
    }
    return dateEnv.format(instance.range.start, formatter, {
      forcedTzo: instance.forcedStartTzo
    });
  }
  mutate(mutation) {
    let instance = this._instance;
    if (instance) {
      let def = this._def;
      let context = this._context;
      let {
        eventStore
      } = context.getCurrentData();
      let relevantEvents = getRelevantEvents(eventStore, instance.instanceId);
      let eventConfigBase = {
        '': {
          display: '',
          startEditable: true,
          durationEditable: true,
          constraints: [],
          overlap: null,
          allows: [],
          backgroundColor: '',
          borderColor: '',
          textColor: '',
          classNames: []
        }
      };
      relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context);
      let oldEvent = new EventImpl(context, def, instance); // snapshot
      this._def = relevantEvents.defs[def.defId];
      this._instance = relevantEvents.instances[instance.instanceId];
      context.dispatch({
        type: 'MERGE_EVENTS',
        eventStore: relevantEvents
      });
      context.emitter.trigger('eventChange', {
        oldEvent,
        event: this,
        relatedEvents: buildEventApis(relevantEvents, context, instance),
        revert() {
          context.dispatch({
            type: 'RESET_EVENTS',
            eventStore // the ORIGINAL store
          });
        }
      });
    }
  }
  remove() {
    let context = this._context;
    let asStore = eventApiToStore(this);
    context.dispatch({
      type: 'REMOVE_EVENTS',
      eventStore: asStore
    });
    context.emitter.trigger('eventRemove', {
      event: this,
      relatedEvents: [],
      revert() {
        context.dispatch({
          type: 'MERGE_EVENTS',
          eventStore: asStore
        });
      }
    });
  }
  get source() {
    let {
      sourceId
    } = this._def;
    if (sourceId) {
      return new EventSourceImpl(this._context, this._context.getCurrentData().eventSources[sourceId]);
    }
    return null;
  }
  get start() {
    return this._instance ? this._context.dateEnv.toDate(this._instance.range.start) : null;
  }
  get end() {
    return this._instance && this._def.hasEnd ? this._context.dateEnv.toDate(this._instance.range.end) : null;
  }
  get startStr() {
    let instance = this._instance;
    if (instance) {
      return this._context.dateEnv.formatIso(instance.range.start, {
        omitTime: this._def.allDay,
        forcedTzo: instance.forcedStartTzo
      });
    }
    return '';
  }
  get endStr() {
    let instance = this._instance;
    if (instance && this._def.hasEnd) {
      return this._context.dateEnv.formatIso(instance.range.end, {
        omitTime: this._def.allDay,
        forcedTzo: instance.forcedEndTzo
      });
    }
    return '';
  }
  // computable props that all access the def
  // TODO: find a TypeScript-compatible way to do this at scale
  get id() {
    return this._def.publicId;
  }
  get groupId() {
    return this._def.groupId;
  }
  get allDay() {
    return this._def.allDay;
  }
  get title() {
    return this._def.title;
  }
  get url() {
    return this._def.url;
  }
  get display() {
    return this._def.ui.display || 'auto';
  } // bad. just normalize the type earlier
  get startEditable() {
    return this._def.ui.startEditable;
  }
  get durationEditable() {
    return this._def.ui.durationEditable;
  }
  get constraint() {
    return this._def.ui.constraints[0] || null;
  }
  get overlap() {
    return this._def.ui.overlap;
  }
  get allow() {
    return this._def.ui.allows[0] || null;
  }
  get backgroundColor() {
    return this._def.ui.backgroundColor;
  }
  get borderColor() {
    return this._def.ui.borderColor;
  }
  get textColor() {
    return this._def.ui.textColor;
  }
  // NOTE: user can't modify these because Object.freeze was called in event-def parsing
  get classNames() {
    return this._def.ui.classNames;
  }
  get extendedProps() {
    return this._def.extendedProps;
  }
  toPlainObject(settings = {}) {
    let def = this._def;
    let {
      ui
    } = def;
    let {
      startStr,
      endStr
    } = this;
    let res = {
      allDay: def.allDay
    };
    if (def.title) {
      res.title = def.title;
    }
    if (startStr) {
      res.start = startStr;
    }
    if (endStr) {
      res.end = endStr;
    }
    if (def.publicId) {
      res.id = def.publicId;
    }
    if (def.groupId) {
      res.groupId = def.groupId;
    }
    if (def.url) {
      res.url = def.url;
    }
    if (ui.display && ui.display !== 'auto') {
      res.display = ui.display;
    }
    // TODO: what about recurring-event properties???
    // TODO: include startEditable/durationEditable/constraint/overlap/allow
    if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) {
      res.color = ui.backgroundColor;
    } else {
      if (ui.backgroundColor) {
        res.backgroundColor = ui.backgroundColor;
      }
      if (ui.borderColor) {
        res.borderColor = ui.borderColor;
      }
    }
    if (ui.textColor) {
      res.textColor = ui.textColor;
    }
    if (ui.classNames.length) {
      res.classNames = ui.classNames;
    }
    if (Object.keys(def.extendedProps).length) {
      if (settings.collapseExtendedProps) {
        Object.assign(res, def.extendedProps);
      } else {
        res.extendedProps = def.extendedProps;
      }
    }
    return res;
  }
  toJSON() {
    return this.toPlainObject();
  }
}
function eventApiToStore(eventApi) {
  let def = eventApi._def;
  let instance = eventApi._instance;
  return {
    defs: {
      [def.defId]: def
    },
    instances: instance ? {
      [instance.instanceId]: instance
    } : {}
  };
}
function buildEventApis(eventStore, context, excludeInstance) {
  let {
    defs,
    instances
  } = eventStore;
  let eventApis = [];
  let excludeInstanceId = excludeInstance ? excludeInstance.instanceId : '';
  for (let id in instances) {
    let instance = instances[id];
    let def = defs[instance.defId];
    if (instance.instanceId !== excludeInstanceId) {
      eventApis.push(new EventImpl(context, def, instance));
    }
  }
  return eventApis;
}

/*
Specifying nextDayThreshold signals that all-day ranges should be sliced.
*/
function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) {
  let inverseBgByGroupId = {};
  let inverseBgByDefId = {};
  let defByGroupId = {};
  let bgRanges = [];
  let fgRanges = [];
  let eventUis = compileEventUis(eventStore.defs, eventUiBases);
  for (let defId in eventStore.defs) {
    let def = eventStore.defs[defId];
    let ui = eventUis[def.defId];
    if (ui.display === 'inverse-background') {
      if (def.groupId) {
        inverseBgByGroupId[def.groupId] = [];
        if (!defByGroupId[def.groupId]) {
          defByGroupId[def.groupId] = def;
        }
      } else {
        inverseBgByDefId[defId] = [];
      }
    }
  }
  for (let instanceId in eventStore.instances) {
    let instance = eventStore.instances[instanceId];
    let def = eventStore.defs[instance.defId];
    let ui = eventUis[def.defId];
    let origRange = instance.range;
    let normalRange = !def.allDay && nextDayThreshold ? computeVisibleDayRange(origRange, nextDayThreshold) : origRange;
    let slicedRange = intersectRanges(normalRange, framingRange);
    if (slicedRange) {
      if (ui.display === 'inverse-background') {
        if (def.groupId) {
          inverseBgByGroupId[def.groupId].push(slicedRange);
        } else {
          inverseBgByDefId[instance.defId].push(slicedRange);
        }
      } else if (ui.display !== 'none') {
        (ui.display === 'background' ? bgRanges : fgRanges).push({
          def,
          ui,
          instance,
          range: slicedRange,
          isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(),
          isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf()
        });
      }
    }
  }
  for (let groupId in inverseBgByGroupId) {
    // BY GROUP
    let ranges = inverseBgByGroupId[groupId];
    let invertedRanges = invertRanges(ranges, framingRange);
    for (let invertedRange of invertedRanges) {
      let def = defByGroupId[groupId];
      let ui = eventUis[def.defId];
      bgRanges.push({
        def,
        ui,
        instance: null,
        range: invertedRange,
        isStart: false,
        isEnd: false
      });
    }
  }
  for (let defId in inverseBgByDefId) {
    let ranges = inverseBgByDefId[defId];
    let invertedRanges = invertRanges(ranges, framingRange);
    for (let invertedRange of invertedRanges) {
      bgRanges.push({
        def: eventStore.defs[defId],
        ui: eventUis[defId],
        instance: null,
        range: invertedRange,
        isStart: false,
        isEnd: false
      });
    }
  }
  return {
    bg: bgRanges,
    fg: fgRanges
  };
}
function hasBgRendering(def) {
  return def.ui.display === 'background' || def.ui.display === 'inverse-background';
}
function setElSeg(el, seg) {
  el.fcSeg = seg;
}
function getElSeg(el) {
  return el.fcSeg || el.parentNode.fcSeg ||
  // for the harness
  null;
}
// event ui computation
function compileEventUis(eventDefs, eventUiBases) {
  return mapHash(eventDefs, eventDef => compileEventUi(eventDef, eventUiBases));
}
function compileEventUi(eventDef, eventUiBases) {
  let uis = [];
  if (eventUiBases['']) {
    uis.push(eventUiBases['']);
  }
  if (eventUiBases[eventDef.defId]) {
    uis.push(eventUiBases[eventDef.defId]);
  }
  uis.push(eventDef.ui);
  return combineEventUis(uis);
}
function sortEventSegs(segs, eventOrderSpecs) {
  let objs = segs.map(buildSegCompareObj);
  objs.sort((obj0, obj1) => compareByFieldSpecs(obj0, obj1, eventOrderSpecs));
  return objs.map(c => c._seg);
}
// returns a object with all primitive props that can be compared
function buildSegCompareObj(seg) {
  let {
    eventRange
  } = seg;
  let eventDef = eventRange.def;
  let range = eventRange.instance ? eventRange.instance.range : eventRange.range;
  let start = range.start ? range.start.valueOf() : 0; // TODO: better support for open-range events
  let end = range.end ? range.end.valueOf() : 0; // "
  return Object.assign(Object.assign(Object.assign({}, eventDef.extendedProps), eventDef), {
    id: eventDef.publicId,
    start,
    end,
    duration: end - start,
    allDay: Number(eventDef.allDay),
    _seg: seg
  });
}
function computeSegDraggable(seg, context) {
  let {
    pluginHooks
  } = context;
  let transformers = pluginHooks.isDraggableTransformers;
  let {
    def,
    ui
  } = seg.eventRange;
  let val = ui.startEditable;
  for (let transformer of transformers) {
    val = transformer(val, def, ui, context);
  }
  return val;
}
function computeSegStartResizable(seg, context) {
  return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart;
}
function computeSegEndResizable(seg, context) {
  return seg.isEnd && seg.eventRange.ui.durationEditable;
}
function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime,
// defaults to true
defaultDisplayEventEnd,
// defaults to true
startOverride, endOverride) {
  let {
    dateEnv,
    options
  } = context;
  let {
    displayEventTime,
    displayEventEnd
  } = options;
  let eventDef = seg.eventRange.def;
  let eventInstance = seg.eventRange.instance;
  if (displayEventTime == null) {
    displayEventTime = defaultDisplayEventTime !== false;
  }
  if (displayEventEnd == null) {
    displayEventEnd = defaultDisplayEventEnd !== false;
  }
  let wholeEventStart = eventInstance.range.start;
  let wholeEventEnd = eventInstance.range.end;
  let segStart = startOverride || seg.start || seg.eventRange.range.start;
  let segEnd = endOverride || seg.end || seg.eventRange.range.end;
  let isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf();
  let isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf();
  if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) {
    segStart = isStartDay ? wholeEventStart : segStart;
    segEnd = isEndDay ? wholeEventEnd : segEnd;
    if (displayEventEnd && eventDef.hasEnd) {
      return dateEnv.formatRange(segStart, segEnd, timeFormat, {
        forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo,
        forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo
      });
    }
    return dateEnv.format(segStart, timeFormat, {
      forcedTzo: startOverride ? null : eventInstance.forcedStartTzo // nooooo, same
    });
  }
  return '';
}
function getSegMeta(seg, todayRange, nowDate) {
  let segRange = seg.eventRange.range;
  return {
    isPast: segRange.end <= (nowDate || todayRange.start),
    isFuture: segRange.start >= (nowDate || todayRange.end),
    isToday: todayRange && rangeContainsMarker(todayRange, segRange.start)
  };
}
function getEventClassNames(props) {
  let classNames = ['fc-event'];
  if (props.isMirror) {
    classNames.push('fc-event-mirror');
  }
  if (props.isDraggable) {
    classNames.push('fc-event-draggable');
  }
  if (props.isStartResizable || props.isEndResizable) {
    classNames.push('fc-event-resizable');
  }
  if (props.isDragging) {
    classNames.push('fc-event-dragging');
  }
  if (props.isResizing) {
    classNames.push('fc-event-resizing');
  }
  if (props.isSelected) {
    classNames.push('fc-event-selected');
  }
  if (props.isStart) {
    classNames.push('fc-event-start');
  }
  if (props.isEnd) {
    classNames.push('fc-event-end');
  }
  if (props.isPast) {
    classNames.push('fc-event-past');
  }
  if (props.isToday) {
    classNames.push('fc-event-today');
  }
  if (props.isFuture) {
    classNames.push('fc-event-future');
  }
  return classNames;
}
function buildEventRangeKey(eventRange) {
  return eventRange.instance ? eventRange.instance.instanceId : `${eventRange.def.defId}:${eventRange.range.start.toISOString()}`;
  // inverse-background events don't have specific instances. TODO: better solution
}
function getSegAnchorAttrs(seg, context) {
  let {
    def,
    instance
  } = seg.eventRange;
  let {
    url
  } = def;
  if (url) {
    return {
      href: url
    };
  }
  let {
    emitter,
    options
  } = context;
  let {
    eventInteractive
  } = options;
  if (eventInteractive == null) {
    eventInteractive = def.interactive;
    if (eventInteractive == null) {
      eventInteractive = Boolean(emitter.hasHandlers('eventClick'));
    }
  }
  // mock what happens in EventClicking
  if (eventInteractive) {
    // only attach keyboard-related handlers because click handler is already done in EventClicking
    return createAriaKeyboardAttrs(ev => {
      emitter.trigger('eventClick', {
        el: ev.target,
        event: new EventImpl(context, def, instance),
        jsEvent: ev,
        view: context.viewApi
      });
    });
  }
  return {};
}
const STANDARD_PROPS = {
  start: identity,
  end: identity,
  allDay: Boolean
};
function parseDateSpan(raw, dateEnv, defaultDuration) {
  let span = parseOpenDateSpan(raw, dateEnv);
  let {
    range
  } = span;
  if (!range.start) {
    return null;
  }
  if (!range.end) {
    if (defaultDuration == null) {
      return null;
    }
    range.end = dateEnv.add(range.start, defaultDuration);
  }
  return span;
}
/*
TODO: somehow combine with parseRange?
Will return null if the start/end props were present but parsed invalidly.
*/
function parseOpenDateSpan(raw, dateEnv) {
  let {
    refined: standardProps,
    extra
  } = refineProps(raw, STANDARD_PROPS);
  let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null;
  let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null;
  let {
    allDay
  } = standardProps;
  if (allDay == null) {
    allDay = startMeta && startMeta.isTimeUnspecified && (!endMeta || endMeta.isTimeUnspecified);
  }
  return Object.assign({
    range: {
      start: startMeta ? startMeta.marker : null,
      end: endMeta ? endMeta.marker : null
    },
    allDay
  }, extra);
}
function isDateSpansEqual(span0, span1) {
  return rangesEqual(span0.range, span1.range) && span0.allDay === span1.allDay && isSpanPropsEqual(span0, span1);
}
// the NON-DATE-RELATED props
function isSpanPropsEqual(span0, span1) {
  for (let propName in span1) {
    if (propName !== 'range' && propName !== 'allDay') {
      if (span0[propName] !== span1[propName]) {
        return false;
      }
    }
  }
  // are there any props that span0 has that span1 DOESN'T have?
  // both have range/allDay, so no need to special-case.
  for (let propName in span0) {
    if (!(propName in span1)) {
      return false;
    }
  }
  return true;
}
function buildDateSpanApi(span, dateEnv) {
  return Object.assign(Object.assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), {
    allDay: span.allDay
  });
}
function buildRangeApiWithTimeZone(range, dateEnv, omitTime) {
  return Object.assign(Object.assign({}, buildRangeApi(range, dateEnv, omitTime)), {
    timeZone: dateEnv.timeZone
  });
}
function buildRangeApi(range, dateEnv, omitTime) {
  return {
    start: dateEnv.toDate(range.start),
    end: dateEnv.toDate(range.end),
    startStr: dateEnv.formatIso(range.start, {
      omitTime
    }),
    endStr: dateEnv.formatIso(range.end, {
      omitTime
    })
  };
}
function fabricateEventRange(dateSpan, eventUiBases, context) {
  let res = refineEventDef({
    editable: false
  }, context);
  let def = parseEventDef(res.refined, res.extra, '',
  // sourceId
  dateSpan.allDay, true,
  // hasEnd
  context);
  return {
    def,
    ui: compileEventUi(def, eventUiBases),
    instance: createEventInstance(def.defId, dateSpan.range),
    range: dateSpan.range,
    isStart: true,
    isEnd: true
  };
}

/*
given a function that resolves a result asynchronously.
the function can either call passed-in success and failure callbacks,
or it can return a promise.
if you need to pass additional params to func, bind them first.
*/
function unpromisify(func, normalizedSuccessCallback, normalizedFailureCallback) {
  // guard against success/failure callbacks being called more than once
  // and guard against a promise AND callback being used together.
  let isResolved = false;
  let wrappedSuccess = function (res) {
    if (!isResolved) {
      isResolved = true;
      normalizedSuccessCallback(res);
    }
  };
  let wrappedFailure = function (error) {
    if (!isResolved) {
      isResolved = true;
      normalizedFailureCallback(error);
    }
  };
  let res = func(wrappedSuccess, wrappedFailure);
  if (res && typeof res.then === 'function') {
    res.then(wrappedSuccess, wrappedFailure);
  }
}
class JsonRequestError extends Error {
  constructor(message, response) {
    super(message);
    this.response = response;
  }
}
function requestJson(method, url, params) {
  method = method.toUpperCase();
  const fetchOptions = {
    method
  };
  if (method === 'GET') {
    url += (url.indexOf('?') === -1 ? '?' : '&') + new URLSearchParams(params);
  } else {
    fetchOptions.body = new URLSearchParams(params);
    fetchOptions.headers = {
      'Content-Type': 'application/x-www-form-urlencoded'
    };
  }
  return fetch(url, fetchOptions).then(fetchRes => {
    if (fetchRes.ok) {
      return fetchRes.json().then(parsedResponse => {
        return [parsedResponse, fetchRes];
      }, () => {
        throw new JsonRequestError('Failure parsing JSON', fetchRes);
      });
    } else {
      throw new JsonRequestError('Request failed', fetchRes);
    }
  });
}
let canVGrowWithinCell;
function getCanVGrowWithinCell() {
  if (canVGrowWithinCell == null) {
    canVGrowWithinCell = computeCanVGrowWithinCell();
  }
  return canVGrowWithinCell;
}
function computeCanVGrowWithinCell() {
  // for SSR, because this function is call immediately at top-level
  // TODO: just make this logic execute top-level, immediately, instead of doing lazily
  if (typeof document === 'undefined') {
    return true;
  }
  let el = document.createElement('div');
  el.style.position = 'absolute';
  el.style.top = '0px';
  el.style.left = '0px';
  el.innerHTML = '<table><tr><td><div></div></td></tr></table>';
  el.querySelector('table').style.height = '100px';
  el.querySelector('div').style.height = '100%';
  document.body.appendChild(el);
  let div = el.querySelector('div');
  let possible = div.offsetHeight > 0;
  document.body.removeChild(el);
  return possible;
}
class CalendarRoot extends BaseComponent {
  constructor() {
    super(...arguments);
    this.state = {
      forPrint: false
    };
    this.handleBeforePrint = () => {
      flushSync(() => {
        this.setState({
          forPrint: true
        });
      });
    };
    this.handleAfterPrint = () => {
      flushSync(() => {
        this.setState({
          forPrint: false
        });
      });
    };
  }
  render() {
    let {
      props
    } = this;
    let {
      options
    } = props;
    let {
      forPrint
    } = this.state;
    let isHeightAuto = forPrint || options.height === 'auto' || options.contentHeight === 'auto';
    let height = !isHeightAuto && options.height != null ? options.height : '';
    let classNames = ['fc', forPrint ? 'fc-media-print' : 'fc-media-screen', `fc-direction-${options.direction}`, props.theme.getClass('root')];
    if (!getCanVGrowWithinCell()) {
      classNames.push('fc-liquid-hack');
    }
    return props.children(classNames, height, isHeightAuto, forPrint);
  }
  componentDidMount() {
    let {
      emitter
    } = this.props;
    emitter.on('_beforeprint', this.handleBeforePrint);
    emitter.on('_afterprint', this.handleAfterPrint);
  }
  componentWillUnmount() {
    let {
      emitter
    } = this.props;
    emitter.off('_beforeprint', this.handleBeforePrint);
    emitter.off('_afterprint', this.handleAfterPrint);
  }
}
class Interaction {
  constructor(settings) {
    this.component = settings.component;
    this.isHitComboAllowed = settings.isHitComboAllowed || null;
  }
  destroy() {}
}
function parseInteractionSettings(component, input) {
  return {
    component,
    el: input.el,
    useEventCenter: input.useEventCenter != null ? input.useEventCenter : true,
    isHitComboAllowed: input.isHitComboAllowed || null
  };
}
function interactionSettingsToStore(settings) {
  return {
    [settings.component.uid]: settings
  };
}
// global state
const interactionSettingsStore = {};
class NowTimer extends preact__WEBPACK_IMPORTED_MODULE_0__.Component {
  constructor(props, context) {
    super(props, context);
    this.handleRefresh = () => {
      let timing = this.computeTiming();
      if (timing.state.nowDate.valueOf() !== this.state.nowDate.valueOf()) {
        this.setState(timing.state);
      }
      this.clearTimeout();
      this.setTimeout(timing.waitMs);
    };
    this.handleVisibilityChange = () => {
      if (!document.hidden) {
        this.handleRefresh();
      }
    };
    this.state = this.computeTiming().state;
  }
  render() {
    let {
      props,
      state
    } = this;
    return props.children(state.nowDate, state.todayRange);
  }
  componentDidMount() {
    this.setTimeout();
    this.context.nowManager.addResetListener(this.handleRefresh);
    // fired tab becomes visible after being hidden
    document.addEventListener('visibilitychange', this.handleVisibilityChange);
  }
  componentDidUpdate(prevProps) {
    if (prevProps.unit !== this.props.unit) {
      this.clearTimeout();
      this.setTimeout();
    }
  }
  componentWillUnmount() {
    this.clearTimeout();
    this.context.nowManager.removeResetListener(this.handleRefresh);
    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
  }
  computeTiming() {
    let {
      props,
      context
    } = this;
    let unroundedNow = context.nowManager.getDateMarker();
    let {
      nowIndicatorSnap
    } = context.options;
    if (nowIndicatorSnap === 'auto') {
      nowIndicatorSnap =
      // large unit?
      /year|month|week|day/.test(props.unit) ||
      // if slotDuration 30 mins for example, would NOT appear to snap (legacy behavior)
      (props.unitValue || 1) === 1;
    }
    let nowDate;
    let waitMs;
    if (nowIndicatorSnap) {
      nowDate = context.dateEnv.startOf(unroundedNow, props.unit); // aka currentUnitStart
      let nextUnitStart = context.dateEnv.add(nowDate, createDuration(1, props.unit));
      waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf();
    } else {
      nowDate = unroundedNow;
      waitMs = 1000 * 60; // 1 minute
    }
    // there is a max setTimeout ms value (https://stackoverflow.com/a/3468650/96342)
    // ensure no longer than a day
    waitMs = Math.min(1000 * 60 * 60 * 24, waitMs);
    return {
      state: {
        nowDate,
        todayRange: buildDayRange(nowDate)
      },
      waitMs
    };
  }
  setTimeout(waitMs = this.computeTiming().waitMs) {
    // NOTE: timeout could take longer than expected if tab sleeps,
    // which is why we listen to 'visibilitychange'
    this.timeoutId = setTimeout(() => {
      // NOTE: timeout could also return *earlier* than expected, and we need to wait 2 ms more
      // This is why use use same waitMs from computeTiming, so we don't skip an interval while
      // .setState() is executing
      const timing = this.computeTiming();
      this.setState(timing.state, () => {
        this.setTimeout(timing.waitMs);
      });
    }, waitMs);
  }
  clearTimeout() {
    if (this.timeoutId) {
      clearTimeout(this.timeoutId);
    }
  }
}
NowTimer.contextType = ViewContextType;
function buildDayRange(date) {
  let start = startOfDay(date);
  let end = addDays(start, 1);
  return {
    start,
    end
  };
}
class CalendarImpl {
  getCurrentData() {
    return this.currentDataManager.getCurrentData();
  }
  dispatch(action) {
    this.currentDataManager.dispatch(action);
  }
  get view() {
    return this.getCurrentData().viewApi;
  }
  batchRendering(callback) {
    callback();
  }
  updateSize() {
    this.trigger('_resize', true);
  }
  // Options
  // -----------------------------------------------------------------------------------------------------------------
  setOption(name, val) {
    this.dispatch({
      type: 'SET_OPTION',
      optionName: name,
      rawOptionValue: val
    });
  }
  getOption(name) {
    return this.currentDataManager.currentCalendarOptionsInput[name];
  }
  getAvailableLocaleCodes() {
    return Object.keys(this.getCurrentData().availableRawLocales);
  }
  // Trigger
  // -----------------------------------------------------------------------------------------------------------------
  on(handlerName, handler) {
    let {
      currentDataManager
    } = this;
    if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) {
      currentDataManager.emitter.on(handlerName, handler);
    } else {
      console.warn(`Unknown listener name '${handlerName}'`);
    }
  }
  off(handlerName, handler) {
    this.currentDataManager.emitter.off(handlerName, handler);
  }
  // not meant for public use
  trigger(handlerName, ...args) {
    this.currentDataManager.emitter.trigger(handlerName, ...args);
  }
  // View
  // -----------------------------------------------------------------------------------------------------------------
  changeView(viewType, dateOrRange) {
    this.batchRendering(() => {
      this.unselect();
      if (dateOrRange) {
        if (dateOrRange.start && dateOrRange.end) {
          // a range
          this.dispatch({
            type: 'CHANGE_VIEW_TYPE',
            viewType
          });
          this.dispatch({
            type: 'SET_OPTION',
            optionName: 'visibleRange',
            rawOptionValue: dateOrRange
          });
        } else {
          let {
            dateEnv
          } = this.getCurrentData();
          this.dispatch({
            type: 'CHANGE_VIEW_TYPE',
            viewType,
            dateMarker: dateEnv.createMarker(dateOrRange)
          });
        }
      } else {
        this.dispatch({
          type: 'CHANGE_VIEW_TYPE',
          viewType
        });
      }
    });
  }
  // Forces navigation to a view for the given date.
  // `viewType` can be a specific view name or a generic one like "week" or "day".
  // needs to change
  zoomTo(dateMarker, viewType) {
    let state = this.getCurrentData();
    let spec;
    viewType = viewType || 'day'; // day is default zoom
    spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType);
    this.unselect();
    if (spec) {
      this.dispatch({
        type: 'CHANGE_VIEW_TYPE',
        viewType: spec.type,
        dateMarker
      });
    } else {
      this.dispatch({
        type: 'CHANGE_DATE',
        dateMarker
      });
    }
  }
  // Given a duration singular unit, like "week" or "day", finds a matching view spec.
  // Preference is given to views that have corresponding buttons.
  getUnitViewSpec(unit) {
    let {
      viewSpecs,
      toolbarConfig
    } = this.getCurrentData();
    let viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []);
    let i;
    let spec;
    for (let viewType in viewSpecs) {
      viewTypes.push(viewType);
    }
    for (i = 0; i < viewTypes.length; i += 1) {
      spec = viewSpecs[viewTypes[i]];
      if (spec) {
        if (spec.singleUnit === unit) {
          return spec;
        }
      }
    }
    return null;
  }
  // Current Date
  // -----------------------------------------------------------------------------------------------------------------
  prev() {
    this.unselect();
    this.dispatch({
      type: 'PREV'
    });
  }
  next() {
    this.unselect();
    this.dispatch({
      type: 'NEXT'
    });
  }
  prevYear() {
    let state = this.getCurrentData();
    this.unselect();
    this.dispatch({
      type: 'CHANGE_DATE',
      dateMarker: state.dateEnv.addYears(state.currentDate, -1)
    });
  }
  nextYear() {
    let state = this.getCurrentData();
    this.unselect();
    this.dispatch({
      type: 'CHANGE_DATE',
      dateMarker: state.dateEnv.addYears(state.currentDate, 1)
    });
  }
  today() {
    let state = this.getCurrentData();
    this.unselect();
    this.dispatch({
      type: 'CHANGE_DATE',
      dateMarker: state.nowManager.getDateMarker()
    });
  }
  gotoDate(zonedDateInput) {
    let state = this.getCurrentData();
    this.unselect();
    this.dispatch({
      type: 'CHANGE_DATE',
      dateMarker: state.dateEnv.createMarker(zonedDateInput)
    });
  }
  incrementDate(deltaInput) {
    let state = this.getCurrentData();
    let delta = createDuration(deltaInput);
    if (delta) {
      // else, warn about invalid input?
      this.unselect();
      this.dispatch({
        type: 'CHANGE_DATE',
        dateMarker: state.dateEnv.add(state.currentDate, delta)
      });
    }
  }
  getDate() {
    let state = this.getCurrentData();
    return state.dateEnv.toDate(state.currentDate);
  }
  // Date Formatting Utils
  // -----------------------------------------------------------------------------------------------------------------
  formatDate(d, formatter) {
    let {
      dateEnv
    } = this.getCurrentData();
    return dateEnv.format(dateEnv.createMarker(d), createFormatter(formatter));
  }
  // `settings` is for formatter AND isEndExclusive
  formatRange(d0, d1, settings) {
    let {
      dateEnv
    } = this.getCurrentData();
    return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings);
  }
  formatIso(d, omitTime) {
    let {
      dateEnv
    } = this.getCurrentData();
    return dateEnv.formatIso(dateEnv.createMarker(d), {
      omitTime
    });
  }
  // Date Selection / Event Selection / DayClick
  // -----------------------------------------------------------------------------------------------------------------
  select(dateOrObj, endDate) {
    let selectionInput;
    if (endDate == null) {
      if (dateOrObj.start != null) {
        selectionInput = dateOrObj;
      } else {
        selectionInput = {
          start: dateOrObj,
          end: null
        };
      }
    } else {
      selectionInput = {
        start: dateOrObj,
        end: endDate
      };
    }
    let state = this.getCurrentData();
    let selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({
      days: 1
    }));
    if (selection) {
      // throw parse error otherwise?
      this.dispatch({
        type: 'SELECT_DATES',
        selection
      });
      triggerDateSelect(selection, null, state);
    }
  }
  unselect(pev) {
    let state = this.getCurrentData();
    if (state.dateSelection) {
      this.dispatch({
        type: 'UNSELECT_DATES'
      });
      triggerDateUnselect(pev, state);
    }
  }
  // Public Events API
  // -----------------------------------------------------------------------------------------------------------------
  addEvent(eventInput, sourceInput) {
    if (eventInput instanceof EventImpl) {
      let def = eventInput._def;
      let instance = eventInput._instance;
      let currentData = this.getCurrentData();
      // not already present? don't want to add an old snapshot
      if (!currentData.eventStore.defs[def.defId]) {
        this.dispatch({
          type: 'ADD_EVENTS',
          eventStore: eventTupleToStore({
            def,
            instance
          }) // TODO: better util for two args?
        });
        this.triggerEventAdd(eventInput);
      }
      return eventInput;
    }
    let state = this.getCurrentData();
    let eventSource;
    if (sourceInput instanceof EventSourceImpl) {
      eventSource = sourceInput.internalEventSource;
    } else if (typeof sourceInput === 'boolean') {
      if (sourceInput) {
        // true. part of the first event source
        [eventSource] = hashValuesToArray(state.eventSources);
      }
    } else if (sourceInput != null) {
      // an ID. accepts a number too
      let sourceApi = this.getEventSourceById(sourceInput); // TODO: use an internal function
      if (!sourceApi) {
        console.warn(`Could not find an event source with ID "${sourceInput}"`); // TODO: test
        return null;
      }
      eventSource = sourceApi.internalEventSource;
    }
    let tuple = parseEvent(eventInput, eventSource, state, false);
    if (tuple) {
      let newEventApi = new EventImpl(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance);
      this.dispatch({
        type: 'ADD_EVENTS',
        eventStore: eventTupleToStore(tuple)
      });
      this.triggerEventAdd(newEventApi);
      return newEventApi;
    }
    return null;
  }
  triggerEventAdd(eventApi) {
    let {
      emitter
    } = this.getCurrentData();
    emitter.trigger('eventAdd', {
      event: eventApi,
      relatedEvents: [],
      revert: () => {
        this.dispatch({
          type: 'REMOVE_EVENTS',
          eventStore: eventApiToStore(eventApi)
        });
      }
    });
  }
  // TODO: optimize
  getEventById(id) {
    let state = this.getCurrentData();
    let {
      defs,
      instances
    } = state.eventStore;
    id = String(id);
    for (let defId in defs) {
      let def = defs[defId];
      if (def.publicId === id) {
        if (def.recurringDef) {
          return new EventImpl(state, def, null);
        }
        for (let instanceId in instances) {
          let instance = instances[instanceId];
          if (instance.defId === def.defId) {
            return new EventImpl(state, def, instance);
          }
        }
      }
    }
    return null;
  }
  getEvents() {
    let currentData = this.getCurrentData();
    return buildEventApis(currentData.eventStore, currentData);
  }
  removeAllEvents() {
    this.dispatch({
      type: 'REMOVE_ALL_EVENTS'
    });
  }
  // Public Event Sources API
  // -----------------------------------------------------------------------------------------------------------------
  getEventSources() {
    let state = this.getCurrentData();
    let sourceHash = state.eventSources;
    let sourceApis = [];
    for (let internalId in sourceHash) {
      sourceApis.push(new EventSourceImpl(state, sourceHash[internalId]));
    }
    return sourceApis;
  }
  getEventSourceById(id) {
    let state = this.getCurrentData();
    let sourceHash = state.eventSources;
    id = String(id);
    for (let sourceId in sourceHash) {
      if (sourceHash[sourceId].publicId === id) {
        return new EventSourceImpl(state, sourceHash[sourceId]);
      }
    }
    return null;
  }
  addEventSource(sourceInput) {
    let state = this.getCurrentData();
    if (sourceInput instanceof EventSourceImpl) {
      // not already present? don't want to add an old snapshot
      if (!state.eventSources[sourceInput.internalEventSource.sourceId]) {
        this.dispatch({
          type: 'ADD_EVENT_SOURCES',
          sources: [sourceInput.internalEventSource]
        });
      }
      return sourceInput;
    }
    let eventSource = parseEventSource(sourceInput, state);
    if (eventSource) {
      // TODO: error otherwise?
      this.dispatch({
        type: 'ADD_EVENT_SOURCES',
        sources: [eventSource]
      });
      return new EventSourceImpl(state, eventSource);
    }
    return null;
  }
  removeAllEventSources() {
    this.dispatch({
      type: 'REMOVE_ALL_EVENT_SOURCES'
    });
  }
  refetchEvents() {
    this.dispatch({
      type: 'FETCH_EVENT_SOURCES',
      isRefetch: true
    });
  }
  // Scroll
  // -----------------------------------------------------------------------------------------------------------------
  scrollToTime(timeInput) {
    let time = createDuration(timeInput);
    if (time) {
      this.trigger('_scrollRequest', {
        time
      });
    }
  }
}
function pointInsideRect(point, rect) {
  return point.left >= rect.left && point.left < rect.right && point.top >= rect.top && point.top < rect.bottom;
}
// Returns a new rectangle that is the intersection of the two rectangles. If they don't intersect, returns false
function intersectRects(rect1, rect2) {
  let res = {
    left: Math.max(rect1.left, rect2.left),
    right: Math.min(rect1.right, rect2.right),
    top: Math.max(rect1.top, rect2.top),
    bottom: Math.min(rect1.bottom, rect2.bottom)
  };
  if (res.left < res.right && res.top < res.bottom) {
    return res;
  }
  return false;
}
function translateRect(rect, deltaX, deltaY) {
  return {
    left: rect.left + deltaX,
    right: rect.right + deltaX,
    top: rect.top + deltaY,
    bottom: rect.bottom + deltaY
  };
}
// Returns a new point that will have been moved to reside within the given rectangle
function constrainPoint(point, rect) {
  return {
    left: Math.min(Math.max(point.left, rect.left), rect.right),
    top: Math.min(Math.max(point.top, rect.top), rect.bottom)
  };
}
// Returns a point that is the center of the given rectangle
function getRectCenter(rect) {
  return {
    left: (rect.left + rect.right) / 2,
    top: (rect.top + rect.bottom) / 2
  };
}
// Subtracts point2's coordinates from point1's coordinates, returning a delta
function diffPoints(point1, point2) {
  return {
    left: point1.left - point2.left,
    top: point1.top - point2.top
  };
}
const EMPTY_EVENT_STORE = createEmptyEventStore(); // for purecomponents. TODO: keep elsewhere
class Splitter {
  constructor() {
    this.getKeysForEventDefs = memoize(this._getKeysForEventDefs);
    this.splitDateSelection = memoize(this._splitDateSpan);
    this.splitEventStore = memoize(this._splitEventStore);
    this.splitIndividualUi = memoize(this._splitIndividualUi);
    this.splitEventDrag = memoize(this._splitInteraction);
    this.splitEventResize = memoize(this._splitInteraction);
    this.eventUiBuilders = {}; // TODO: typescript protection
  }
  splitProps(props) {
    let keyInfos = this.getKeyInfo(props);
    let defKeys = this.getKeysForEventDefs(props.eventStore);
    let dateSelections = this.splitDateSelection(props.dateSelection);
    let individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); // the individual *bases*
    let eventStores = this.splitEventStore(props.eventStore, defKeys);
    let eventDrags = this.splitEventDrag(props.eventDrag);
    let eventResizes = this.splitEventResize(props.eventResize);
    let splitProps = {};
    this.eventUiBuilders = mapHash(keyInfos, (info, key) => this.eventUiBuilders[key] || memoize(buildEventUiForKey));
    for (let key in keyInfos) {
      let keyInfo = keyInfos[key];
      let eventStore = eventStores[key] || EMPTY_EVENT_STORE;
      let buildEventUi = this.eventUiBuilders[key];
      splitProps[key] = {
        businessHours: keyInfo.businessHours || props.businessHours,
        dateSelection: dateSelections[key] || null,
        eventStore,
        eventUiBases: buildEventUi(props.eventUiBases[''], keyInfo.ui, individualUi[key]),
        eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : '',
        eventDrag: eventDrags[key] || null,
        eventResize: eventResizes[key] || null
      };
    }
    return splitProps;
  }
  _splitDateSpan(dateSpan) {
    let dateSpans = {};
    if (dateSpan) {
      let keys = this.getKeysForDateSpan(dateSpan);
      for (let key of keys) {
        dateSpans[key] = dateSpan;
      }
    }
    return dateSpans;
  }
  _getKeysForEventDefs(eventStore) {
    return mapHash(eventStore.defs, eventDef => this.getKeysForEventDef(eventDef));
  }
  _splitEventStore(eventStore, defKeys) {
    let {
      defs,
      instances
    } = eventStore;
    let splitStores = {};
    for (let defId in defs) {
      for (let key of defKeys[defId]) {
        if (!splitStores[key]) {
          splitStores[key] = createEmptyEventStore();
        }
        splitStores[key].defs[defId] = defs[defId];
      }
    }
    for (let instanceId in instances) {
      let instance = instances[instanceId];
      for (let key of defKeys[instance.defId]) {
        if (splitStores[key]) {
          // must have already been created
          splitStores[key].instances[instanceId] = instance;
        }
      }
    }
    return splitStores;
  }
  _splitIndividualUi(eventUiBases, defKeys) {
    let splitHashes = {};
    for (let defId in eventUiBases) {
      if (defId) {
        // not the '' key
        for (let key of defKeys[defId]) {
          if (!splitHashes[key]) {
            splitHashes[key] = {};
          }
          splitHashes[key][defId] = eventUiBases[defId];
        }
      }
    }
    return splitHashes;
  }
  _splitInteraction(interaction) {
    let splitStates = {};
    if (interaction) {
      let affectedStores = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents));
      // can't rely on defKeys because event data is mutated
      let mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents);
      let mutatedStores = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId);
      let populate = key => {
        if (!splitStates[key]) {
          splitStates[key] = {
            affectedEvents: affectedStores[key] || EMPTY_EVENT_STORE,
            mutatedEvents: mutatedStores[key] || EMPTY_EVENT_STORE,
            isEvent: interaction.isEvent
          };
        }
      };
      for (let key in affectedStores) {
        populate(key);
      }
      for (let key in mutatedStores) {
        populate(key);
      }
    }
    return splitStates;
  }
}
function buildEventUiForKey(allUi, eventUiForKey, individualUi) {
  let baseParts = [];
  if (allUi) {
    baseParts.push(allUi);
  }
  if (eventUiForKey) {
    baseParts.push(eventUiForKey);
  }
  let stuff = {
    '': combineEventUis(baseParts)
  };
  if (individualUi) {
    Object.assign(stuff, individualUi);
  }
  return stuff;
}
function getDateMeta(date, todayRange, nowDate, dateProfile) {
  return {
    dow: date.getUTCDay(),
    isDisabled: Boolean(dateProfile && (!dateProfile.activeRange || !rangeContainsMarker(dateProfile.activeRange, date))),
    isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)),
    isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)),
    isPast: Boolean(nowDate ? date < nowDate : todayRange ? date < todayRange.start : false),
    isFuture: Boolean(nowDate ? date > nowDate : todayRange ? date >= todayRange.end : false)
  };
}
function getDayClassNames(meta, theme) {
  let classNames = ['fc-day', `fc-day-${DAY_IDS[meta.dow]}`];
  if (meta.isDisabled) {
    classNames.push('fc-day-disabled');
  } else {
    if (meta.isToday) {
      classNames.push('fc-day-today');
      classNames.push(theme.getClass('today'));
    }
    if (meta.isPast) {
      classNames.push('fc-day-past');
    }
    if (meta.isFuture) {
      classNames.push('fc-day-future');
    }
    if (meta.isOther) {
      classNames.push('fc-day-other');
    }
  }
  return classNames;
}
function getSlotClassNames(meta, theme) {
  let classNames = ['fc-slot', `fc-slot-${DAY_IDS[meta.dow]}`];
  if (meta.isDisabled) {
    classNames.push('fc-slot-disabled');
  } else {
    if (meta.isToday) {
      classNames.push('fc-slot-today');
      classNames.push(theme.getClass('today'));
    }
    if (meta.isPast) {
      classNames.push('fc-slot-past');
    }
    if (meta.isFuture) {
      classNames.push('fc-slot-future');
    }
  }
  return classNames;
}
const DAY_FORMAT = createFormatter({
  year: 'numeric',
  month: 'long',
  day: 'numeric'
});
const WEEK_FORMAT = createFormatter({
  week: 'long'
});
function buildNavLinkAttrs(context, dateMarker, viewType = 'day', isTabbable = true) {
  const {
    dateEnv,
    options,
    calendarApi
  } = context;
  let dateStr = dateEnv.format(dateMarker, viewType === 'week' ? WEEK_FORMAT : DAY_FORMAT);
  if (options.navLinks) {
    let zonedDate = dateEnv.toDate(dateMarker);
    const handleInteraction = ev => {
      let customAction = viewType === 'day' ? options.navLinkDayClick : viewType === 'week' ? options.navLinkWeekClick : null;
      if (typeof customAction === 'function') {
        customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev);
      } else {
        if (typeof customAction === 'string') {
          viewType = customAction;
        }
        calendarApi.zoomTo(dateMarker, viewType);
      }
    };
    return Object.assign({
      title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr),
      'data-navlink': ''
    }, isTabbable ? createAriaClickAttrs(handleInteraction) : {
      onClick: handleInteraction
    });
  }
  return {
    'aria-label': dateStr
  };
}
let _isRtlScrollbarOnLeft = null;
function getIsRtlScrollbarOnLeft() {
  if (_isRtlScrollbarOnLeft === null) {
    _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft();
  }
  return _isRtlScrollbarOnLeft;
}
function computeIsRtlScrollbarOnLeft() {
  let outerEl = document.createElement('div');
  applyStyle(outerEl, {
    position: 'absolute',
    top: -1000,
    left: 0,
    border: 0,
    padding: 0,
    overflow: 'scroll',
    direction: 'rtl'
  });
  outerEl.innerHTML = '<div></div>';
  document.body.appendChild(outerEl);
  let innerEl = outerEl.firstChild;
  let res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left;
  removeElement(outerEl);
  return res;
}
let _scrollbarWidths;
function getScrollbarWidths() {
  if (!_scrollbarWidths) {
    _scrollbarWidths = computeScrollbarWidths();
  }
  return _scrollbarWidths;
}
function computeScrollbarWidths() {
  let el = document.createElement('div');
  el.style.overflow = 'scroll';
  el.style.position = 'absolute';
  el.style.top = '-9999px';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  let res = computeScrollbarWidthsForEl(el);
  document.body.removeChild(el);
  return res;
}
// WARNING: will include border
function computeScrollbarWidthsForEl(el) {
  return {
    x: el.offsetHeight - el.clientHeight,
    y: el.offsetWidth - el.clientWidth
  };
}
function computeEdges(el, getPadding = false) {
  let computedStyle = window.getComputedStyle(el);
  let borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0;
  let borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0;
  let borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0;
  let borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
  let badScrollbarWidths = computeScrollbarWidthsForEl(el); // includes border!
  let scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight;
  let scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom;
  let res = {
    borderLeft,
    borderRight,
    borderTop,
    borderBottom,
    scrollbarBottom,
    scrollbarLeft: 0,
    scrollbarRight: 0
  };
  if (getIsRtlScrollbarOnLeft() && computedStyle.direction === 'rtl') {
    // is the scrollbar on the left side?
    res.scrollbarLeft = scrollbarLeftRight;
  } else {
    res.scrollbarRight = scrollbarLeftRight;
  }
  if (getPadding) {
    res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0;
    res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0;
    res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0;
    res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0;
  }
  return res;
}
function computeInnerRect(el, goWithinPadding = false, doFromWindowViewport) {
  let outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el);
  let edges = computeEdges(el, goWithinPadding);
  let res = {
    left: outerRect.left + edges.borderLeft + edges.scrollbarLeft,
    right: outerRect.right - edges.borderRight - edges.scrollbarRight,
    top: outerRect.top + edges.borderTop,
    bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom
  };
  if (goWithinPadding) {
    res.left += edges.paddingLeft;
    res.right -= edges.paddingRight;
    res.top += edges.paddingTop;
    res.bottom -= edges.paddingBottom;
  }
  return res;
}
function computeRect(el) {
  let rect = el.getBoundingClientRect();
  return {
    left: rect.left + window.scrollX,
    top: rect.top + window.scrollY,
    right: rect.right + window.scrollX,
    bottom: rect.bottom + window.scrollY
  };
}
function computeClippedClientRect(el) {
  let clippingParents = getClippingParents(el);
  let rect = el.getBoundingClientRect();
  for (let clippingParent of clippingParents) {
    let intersection = intersectRects(rect, clippingParent.getBoundingClientRect());
    if (intersection) {
      rect = intersection;
    } else {
      return null;
    }
  }
  return rect;
}
// does not return window
function getClippingParents(el) {
  let parents = [];
  while (el instanceof HTMLElement) {
    // will stop when gets to document or null
    let computedStyle = window.getComputedStyle(el);
    if (computedStyle.position === 'fixed') {
      break;
    }
    if (/(auto|scroll)/.test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) {
      parents.push(el);
    }
    el = el.parentNode;
  }
  return parents;
}

/*
Records offset information for a set of elements, relative to an origin element.
Can record the left/right OR the top/bottom OR both.
Provides methods for querying the cache by position.
*/
class PositionCache {
  constructor(originEl, els, isHorizontal, isVertical) {
    this.els = els;
    let originClientRect = this.originClientRect = originEl.getBoundingClientRect(); // relative to viewport top-left
    if (isHorizontal) {
      this.buildElHorizontals(originClientRect.left);
    }
    if (isVertical) {
      this.buildElVerticals(originClientRect.top);
    }
  }
  // Populates the left/right internal coordinate arrays
  buildElHorizontals(originClientLeft) {
    let lefts = [];
    let rights = [];
    for (let el of this.els) {
      let rect = el.getBoundingClientRect();
      lefts.push(rect.left - originClientLeft);
      rights.push(rect.right - originClientLeft);
    }
    this.lefts = lefts;
    this.rights = rights;
  }
  // Populates the top/bottom internal coordinate arrays
  buildElVerticals(originClientTop) {
    let tops = [];
    let bottoms = [];
    for (let el of this.els) {
      let rect = el.getBoundingClientRect();
      tops.push(rect.top - originClientTop);
      bottoms.push(rect.bottom - originClientTop);
    }
    this.tops = tops;
    this.bottoms = bottoms;
  }
  // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
  // If no intersection is made, returns undefined.
  leftToIndex(leftPosition) {
    let {
      lefts,
      rights
    } = this;
    let len = lefts.length;
    let i;
    for (i = 0; i < len; i += 1) {
      if (leftPosition >= lefts[i] && leftPosition < rights[i]) {
        return i;
      }
    }
    return undefined; // TODO: better
  }
  // Given a top offset (from document top), returns the index of the el that it vertically intersects.
  // If no intersection is made, returns undefined.
  topToIndex(topPosition) {
    let {
      tops,
      bottoms
    } = this;
    let len = tops.length;
    let i;
    for (i = 0; i < len; i += 1) {
      if (topPosition >= tops[i] && topPosition < bottoms[i]) {
        return i;
      }
    }
    return undefined; // TODO: better
  }
  // Gets the width of the element at the given index
  getWidth(leftIndex) {
    return this.rights[leftIndex] - this.lefts[leftIndex];
  }
  // Gets the height of the element at the given index
  getHeight(topIndex) {
    return this.bottoms[topIndex] - this.tops[topIndex];
  }
  similarTo(otherCache) {
    return similarNumArrays(this.tops || [], otherCache.tops || []) && similarNumArrays(this.bottoms || [], otherCache.bottoms || []) && similarNumArrays(this.lefts || [], otherCache.lefts || []) && similarNumArrays(this.rights || [], otherCache.rights || []);
  }
}
function similarNumArrays(a, b) {
  const len = a.length;
  if (len !== b.length) {
    return false;
  }
  for (let i = 0; i < len; i++) {
    if (Math.round(a[i]) !== Math.round(b[i])) {
      return false;
    }
  }
  return true;
}

/* eslint max-classes-per-file: "off" */
/*
An object for getting/setting scroll-related information for an element.
Internally, this is done very differently for window versus DOM element,
so this object serves as a common interface.
*/
class ScrollController {
  getMaxScrollTop() {
    return this.getScrollHeight() - this.getClientHeight();
  }
  getMaxScrollLeft() {
    return this.getScrollWidth() - this.getClientWidth();
  }
  canScrollVertically() {
    return this.getMaxScrollTop() > 0;
  }
  canScrollHorizontally() {
    return this.getMaxScrollLeft() > 0;
  }
  canScrollUp() {
    return this.getScrollTop() > 0;
  }
  canScrollDown() {
    return this.getScrollTop() < this.getMaxScrollTop();
  }
  canScrollLeft() {
    return this.getScrollLeft() > 0;
  }
  canScrollRight() {
    return this.getScrollLeft() < this.getMaxScrollLeft();
  }
}
class ElementScrollController extends ScrollController {
  constructor(el) {
    super();
    this.el = el;
  }
  getScrollTop() {
    return this.el.scrollTop;
  }
  getScrollLeft() {
    return this.el.scrollLeft;
  }
  setScrollTop(top) {
    this.el.scrollTop = top;
  }
  setScrollLeft(left) {
    this.el.scrollLeft = left;
  }
  getScrollWidth() {
    return this.el.scrollWidth;
  }
  getScrollHeight() {
    return this.el.scrollHeight;
  }
  getClientHeight() {
    return this.el.clientHeight;
  }
  getClientWidth() {
    return this.el.clientWidth;
  }
}
class WindowScrollController extends ScrollController {
  getScrollTop() {
    return window.scrollY;
  }
  getScrollLeft() {
    return window.scrollX;
  }
  setScrollTop(n) {
    window.scroll(window.scrollX, n);
  }
  setScrollLeft(n) {
    window.scroll(n, window.scrollY);
  }
  getScrollWidth() {
    return document.documentElement.scrollWidth;
  }
  getScrollHeight() {
    return document.documentElement.scrollHeight;
  }
  getClientHeight() {
    return document.documentElement.clientHeight;
  }
  getClientWidth() {
    return document.documentElement.clientWidth;
  }
}

/*
an INTERACTABLE date component

PURPOSES:
- hook up to fg, fill, and mirror renderers
- interface for dragging and hits
*/
class DateComponent extends BaseComponent {
  constructor() {
    super(...arguments);
    this.uid = guid();
  }
  // Hit System
  // -----------------------------------------------------------------------------------------------------------------
  prepareHits() {}
  queryHit(positionLeft, positionTop, elWidth, elHeight) {
    return null; // this should be abstract
  }
  // Pointer Interaction Utils
  // -----------------------------------------------------------------------------------------------------------------
  isValidSegDownEl(el) {
    return !this.props.eventDrag &&
    // HACK
    !this.props.eventResize &&
    // HACK
    !elementClosest(el, '.fc-event-mirror');
  }
  isValidDateDownEl(el) {
    return !elementClosest(el, '.fc-event:not(.fc-bg-event)') && !elementClosest(el, '.fc-more-link') &&
    // a "more.." link
    !elementClosest(el, 'a[data-navlink]') &&
    // a clickable nav link
    !elementClosest(el, '.fc-popover'); // hack
  }
}
class NamedTimeZoneImpl {
  constructor(timeZoneName) {
    this.timeZoneName = timeZoneName;
  }
}
class SegHierarchy {
  constructor(getEntryThickness = entry => {
    // if no thickness known, assume 1 (if 0, so small it always fits)
    return entry.thickness || 1;
  }) {
    this.getEntryThickness = getEntryThickness;
    // settings
    this.strictOrder = false;
    this.allowReslicing = false;
    this.maxCoord = -1; // -1 means no max
    this.maxStackCnt = -1; // -1 means no max
    this.levelCoords = []; // ordered
    this.entriesByLevel = []; // parallel with levelCoords
    this.stackCnts = {}; // TODO: use better technique!?
  }
  addSegs(inputs) {
    let hiddenEntries = [];
    for (let input of inputs) {
      this.insertEntry(input, hiddenEntries);
    }
    return hiddenEntries;
  }
  insertEntry(entry, hiddenEntries) {
    let insertion = this.findInsertion(entry);
    if (this.isInsertionValid(insertion, entry)) {
      this.insertEntryAt(entry, insertion);
    } else {
      this.handleInvalidInsertion(insertion, entry, hiddenEntries);
    }
  }
  isInsertionValid(insertion, entry) {
    return (this.maxCoord === -1 || insertion.levelCoord + this.getEntryThickness(entry) <= this.maxCoord) && (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt);
  }
  handleInvalidInsertion(insertion, entry, hiddenEntries) {
    if (this.allowReslicing && insertion.touchingEntry) {
      const hiddenEntry = Object.assign(Object.assign({}, entry), {
        span: intersectSpans(entry.span, insertion.touchingEntry.span)
      });
      hiddenEntries.push(hiddenEntry);
      this.splitEntry(entry, insertion.touchingEntry, hiddenEntries);
    } else {
      hiddenEntries.push(entry);
    }
  }
  /*
  Does NOT add what hit the `barrier` into hiddenEntries. Should already be done.
  */
  splitEntry(entry, barrier, hiddenEntries) {
    let entrySpan = entry.span;
    let barrierSpan = barrier.span;
    if (entrySpan.start < barrierSpan.start) {
      this.insertEntry({
        index: entry.index,
        thickness: entry.thickness,
        span: {
          start: entrySpan.start,
          end: barrierSpan.start
        }
      }, hiddenEntries);
    }
    if (entrySpan.end > barrierSpan.end) {
      this.insertEntry({
        index: entry.index,
        thickness: entry.thickness,
        span: {
          start: barrierSpan.end,
          end: entrySpan.end
        }
      }, hiddenEntries);
    }
  }
  insertEntryAt(entry, insertion) {
    let {
      entriesByLevel,
      levelCoords
    } = this;
    if (insertion.lateral === -1) {
      // create a new level
      insertAt(levelCoords, insertion.level, insertion.levelCoord);
      insertAt(entriesByLevel, insertion.level, [entry]);
    } else {
      // insert into existing level
      insertAt(entriesByLevel[insertion.level], insertion.lateral, entry);
    }
    this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt;
  }
  /*
  does not care about limits
  */
  findInsertion(newEntry) {
    let {
      levelCoords,
      entriesByLevel,
      strictOrder,
      stackCnts
    } = this;
    let levelCnt = levelCoords.length;
    let candidateCoord = 0;
    let touchingLevel = -1;
    let touchingLateral = -1;
    let touchingEntry = null;
    let stackCnt = 0;
    for (let trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) {
      const trackingCoord = levelCoords[trackingLevel];
      // if the current level is past the placed entry, we have found a good empty space and can stop.
      // if strictOrder, keep finding more lateral intersections.
      if (!strictOrder && trackingCoord >= candidateCoord + this.getEntryThickness(newEntry)) {
        break;
      }
      let trackingEntries = entriesByLevel[trackingLevel];
      let trackingEntry;
      let searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); // find first entry after newEntry's end
      let lateralIndex = searchRes[0] + searchRes[1]; // if exact match (which doesn't collide), go to next one
      while (
      // loop through entries that horizontally intersect
      (trackingEntry = trackingEntries[lateralIndex]) &&
      // but not past the whole entry list
      trackingEntry.span.start < newEntry.span.end // and not entirely past newEntry
      ) {
        let trackingEntryBottom = trackingCoord + this.getEntryThickness(trackingEntry);
        // intersects into the top of the candidate?
        if (trackingEntryBottom > candidateCoord) {
          candidateCoord = trackingEntryBottom;
          touchingEntry = trackingEntry;
          touchingLevel = trackingLevel;
          touchingLateral = lateralIndex;
        }
        // butts up against top of candidate? (will happen if just intersected as well)
        if (trackingEntryBottom === candidateCoord) {
          // accumulate the highest possible stackCnt of the trackingEntries that butt up
          stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1);
        }
        lateralIndex += 1;
      }
    }
    // the destination level will be after touchingEntry's level. find it
    let destLevel = 0;
    if (touchingEntry) {
      destLevel = touchingLevel + 1;
      while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) {
        destLevel += 1;
      }
    }
    // if adding to an existing level, find where to insert
    let destLateral = -1;
    if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) {
      destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0];
    }
    return {
      touchingLevel,
      touchingLateral,
      touchingEntry,
      stackCnt,
      levelCoord: candidateCoord,
      level: destLevel,
      lateral: destLateral
    };
  }
  // sorted by levelCoord (lowest to highest)
  toRects() {
    let {
      entriesByLevel,
      levelCoords
    } = this;
    let levelCnt = entriesByLevel.length;
    let rects = [];
    for (let level = 0; level < levelCnt; level += 1) {
      let entries = entriesByLevel[level];
      let levelCoord = levelCoords[level];
      for (let entry of entries) {
        rects.push(Object.assign(Object.assign({}, entry), {
          thickness: this.getEntryThickness(entry),
          levelCoord
        }));
      }
    }
    return rects;
  }
}
function getEntrySpanEnd(entry) {
  return entry.span.end;
}
function buildEntryKey(entry) {
  return entry.index + ':' + entry.span.start;
}
// returns groups with entries sorted by input order
function groupIntersectingEntries(entries) {
  let merges = [];
  for (let entry of entries) {
    let filteredMerges = [];
    let hungryMerge = {
      span: entry.span,
      entries: [entry]
    };
    for (let merge of merges) {
      if (intersectSpans(merge.span, hungryMerge.span)) {
        hungryMerge = {
          entries: merge.entries.concat(hungryMerge.entries),
          span: joinSpans(merge.span, hungryMerge.span)
        };
      } else {
        filteredMerges.push(merge);
      }
    }
    filteredMerges.push(hungryMerge);
    merges = filteredMerges;
  }
  return merges;
}
function joinSpans(span0, span1) {
  return {
    start: Math.min(span0.start, span1.start),
    end: Math.max(span0.end, span1.end)
  };
}
function intersectSpans(span0, span1) {
  let start = Math.max(span0.start, span1.start);
  let end = Math.min(span0.end, span1.end);
  if (start < end) {
    return {
      start,
      end
    };
  }
  return null;
}
// general util
// ---------------------------------------------------------------------------------------------------------------------
function insertAt(arr, index, item) {
  arr.splice(index, 0, item);
}
function binarySearch(a, searchVal, getItemVal) {
  let startIndex = 0;
  let endIndex = a.length; // exclusive
  if (!endIndex || searchVal < getItemVal(a[startIndex])) {
    // no items OR before first item
    return [0, 0];
  }
  if (searchVal > getItemVal(a[endIndex - 1])) {
    // after last item
    return [endIndex, 0];
  }
  while (startIndex < endIndex) {
    let middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2);
    let middleVal = getItemVal(a[middleIndex]);
    if (searchVal < middleVal) {
      endIndex = middleIndex;
    } else if (searchVal > middleVal) {
      startIndex = middleIndex + 1;
    } else {
      // equal!
      return [middleIndex, 1];
    }
  }
  return [startIndex, 0];
}

/*
An abstraction for a dragging interaction originating on an event.
Does higher-level things than PointerDragger, such as possibly:
- a "mirror" that moves with the pointer
- a minimum number of pixels or other criteria for a true drag to begin

subclasses must emit:
- pointerdown
- dragstart
- dragmove
- pointerup
- dragend
*/
class ElementDragging {
  constructor(el, selector) {
    this.emitter = new Emitter();
  }
  destroy() {}
  setMirrorIsVisible(bool) {
    // optional if subclass doesn't want to support a mirror
  }
  setMirrorNeedsRevert(bool) {
    // optional if subclass doesn't want to support a mirror
  }
  setAutoScrollEnabled(bool) {
    // optional
  }
}

// TODO: get rid of this in favor of options system,
// tho it's really easy to access this globally rather than pass thru options.
const config = {};

/*
Information about what will happen when an external element is dragged-and-dropped
onto a calendar. Contains information for creating an event.
*/
const DRAG_META_REFINERS = {
  startTime: createDuration,
  duration: createDuration,
  create: Boolean,
  sourceId: String
};
function parseDragMeta(raw) {
  let {
    refined,
    extra
  } = refineProps(raw, DRAG_META_REFINERS);
  return {
    startTime: refined.startTime || null,
    duration: refined.duration || null,
    create: refined.create != null ? refined.create : true,
    sourceId: refined.sourceId,
    leftoverProps: extra
  };
}

// Computes a default column header formatting string if `colFormat` is not explicitly defined
function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) {
  // if more than one week row, or if there are a lot of columns with not much space,
  // put just the day numbers will be in each cell
  if (!datesRepDistinctDays || dayCnt > 10) {
    return createFormatter({
      weekday: 'short'
    }); // "Sat"
  }
  if (dayCnt > 1) {
    return createFormatter({
      weekday: 'short',
      month: 'numeric',
      day: 'numeric',
      omitCommas: true
    }); // "Sat 11/12"
  }
  return createFormatter({
    weekday: 'long'
  }); // "Saturday"
}
const CLASS_NAME = 'fc-col-header-cell'; // do the cushion too? no
function renderInner$1(renderProps) {
  return renderProps.text;
}

// BAD name for this class now. used in the Header
class TableDateCell extends BaseComponent {
  render() {
    let {
      dateEnv,
      options,
      theme,
      viewApi
    } = this.context;
    let {
      props
    } = this;
    let {
      date,
      dateProfile
    } = props;
    let dayMeta = getDateMeta(date, props.todayRange, null, dateProfile);
    let classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme));
    let text = dateEnv.format(date, props.dayHeaderFormat);
    // if colCnt is 1, we are already in a day-view and don't need a navlink
    let navLinkAttrs = !dayMeta.isDisabled && props.colCnt > 1 ? buildNavLinkAttrs(this.context, date) : {};
    let publicDate = dateEnv.toDate(date);
    // workaround for Luxon (and maybe moment) returning prior-days when start-of-day
    // in DST gap: https://github.com/fullcalendar/fullcalendar/issues/7633
    if (dateEnv.namedTimeZoneImpl) {
      publicDate = addMs(publicDate, 3600000); // add an hour
    }
    let renderProps = Object.assign(Object.assign(Object.assign({
      date: publicDate,
      view: viewApi
    }, props.extraRenderProps), {
      text
    }), dayMeta);
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
      elTag: "th",
      elClasses: classNames,
      elAttrs: Object.assign({
        role: 'columnheader',
        colSpan: props.colSpan,
        'data-date': !dayMeta.isDisabled ? formatDayString(date) : undefined
      }, props.extraDataAttrs),
      renderProps: renderProps,
      generatorName: "dayHeaderContent",
      customGenerator: options.dayHeaderContent,
      defaultGenerator: renderInner$1,
      classNameGenerator: options.dayHeaderClassNames,
      didMount: options.dayHeaderDidMount,
      willUnmount: options.dayHeaderWillUnmount
    }, InnerContainer => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: "fc-scrollgrid-sync-inner"
    }, !dayMeta.isDisabled && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContainer, {
      elTag: "a",
      elAttrs: navLinkAttrs,
      elClasses: ['fc-col-header-cell-cushion', props.isSticky && 'fc-sticky']
    })));
  }
}
const WEEKDAY_FORMAT = createFormatter({
  weekday: 'long'
});
class TableDowCell extends BaseComponent {
  render() {
    let {
      props
    } = this;
    let {
      dateEnv,
      theme,
      viewApi,
      options
    } = this.context;
    let date = addDays(new Date(259200000), props.dow); // start with Sun, 04 Jan 1970 00:00:00 GMT
    let dateMeta = {
      dow: props.dow,
      isDisabled: false,
      isFuture: false,
      isPast: false,
      isToday: false,
      isOther: false
    };
    let text = dateEnv.format(date, props.dayHeaderFormat);
    let renderProps = Object.assign(Object.assign(Object.assign(Object.assign({
      // TODO: make this public?
      date
    }, dateMeta), {
      view: viewApi
    }), props.extraRenderProps), {
      text
    });
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
      elTag: "th",
      elClasses: [CLASS_NAME, ...getDayClassNames(dateMeta, theme), ...(props.extraClassNames || [])],
      elAttrs: Object.assign({
        role: 'columnheader',
        colSpan: props.colSpan
      }, props.extraDataAttrs),
      renderProps: renderProps,
      generatorName: "dayHeaderContent",
      customGenerator: options.dayHeaderContent,
      defaultGenerator: renderInner$1,
      classNameGenerator: options.dayHeaderClassNames,
      didMount: options.dayHeaderDidMount,
      willUnmount: options.dayHeaderWillUnmount
    }, InnerContent => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: "fc-scrollgrid-sync-inner"
    }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, {
      elTag: "a",
      elClasses: ['fc-col-header-cell-cushion', props.isSticky && 'fc-sticky'],
      elAttrs: {
        'aria-label': dateEnv.format(date, WEEKDAY_FORMAT)
      }
    })));
  }
}
class DayHeader extends BaseComponent {
  constructor() {
    super(...arguments);
    this.createDayHeaderFormatter = memoize(createDayHeaderFormatter);
  }
  render() {
    let {
      context
    } = this;
    let {
      dates,
      dateProfile,
      datesRepDistinctDays,
      renderIntro
    } = this.props;
    let dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length);
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(NowTimer, {
      unit: "day"
    }, (nowDate, todayRange) => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("tr", {
      role: "row"
    }, renderIntro && renderIntro('day'), dates.map(date => datesRepDistinctDays ? (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(TableDateCell, {
      key: date.toISOString(),
      date: date,
      dateProfile: dateProfile,
      todayRange: todayRange,
      colCnt: dates.length,
      dayHeaderFormat: dayHeaderFormat
    }) : (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(TableDowCell, {
      key: date.getUTCDay(),
      dow: date.getUTCDay(),
      dayHeaderFormat: dayHeaderFormat
    }))));
  }
}
function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) {
  return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt);
}
class DaySeriesModel {
  constructor(range, dateProfileGenerator) {
    let date = range.start;
    let {
      end
    } = range;
    let indices = [];
    let dates = [];
    let dayIndex = -1;
    while (date < end) {
      // loop each day from start to end
      if (dateProfileGenerator.isHiddenDay(date)) {
        indices.push(dayIndex + 0.5); // mark that it's between indices
      } else {
        dayIndex += 1;
        indices.push(dayIndex);
        dates.push(date);
      }
      date = addDays(date, 1);
    }
    this.dates = dates;
    this.indices = indices;
    this.cnt = dates.length;
  }
  sliceRange(range) {
    let firstIndex = this.getDateDayIndex(range.start); // inclusive first index
    let lastIndex = this.getDateDayIndex(addDays(range.end, -1)); // inclusive last index
    let clippedFirstIndex = Math.max(0, firstIndex);
    let clippedLastIndex = Math.min(this.cnt - 1, lastIndex);
    // deal with in-between indices
    clippedFirstIndex = Math.ceil(clippedFirstIndex); // in-between starts round to next cell
    clippedLastIndex = Math.floor(clippedLastIndex); // in-between ends round to prev cell
    if (clippedFirstIndex <= clippedLastIndex) {
      return {
        firstIndex: clippedFirstIndex,
        lastIndex: clippedLastIndex,
        isStart: firstIndex === clippedFirstIndex,
        isEnd: lastIndex === clippedLastIndex
      };
    }
    return null;
  }
  // Given a date, returns its chronolocial cell-index from the first cell of the grid.
  // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.
  // If before the first offset, returns a negative number.
  // If after the last offset, returns an offset past the last cell offset.
  // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
  getDateDayIndex(date) {
    let {
      indices
    } = this;
    let dayOffset = Math.floor(diffDays(this.dates[0], date));
    if (dayOffset < 0) {
      return indices[0] - 1;
    }
    if (dayOffset >= indices.length) {
      return indices[indices.length - 1] + 1;
    }
    return indices[dayOffset];
  }
}
class DayTableModel {
  constructor(daySeries, breakOnWeeks) {
    let {
      dates
    } = daySeries;
    let daysPerRow;
    let firstDay;
    let rowCnt;
    if (breakOnWeeks) {
      // count columns until the day-of-week repeats
      firstDay = dates[0].getUTCDay();
      for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) {
        if (dates[daysPerRow].getUTCDay() === firstDay) {
          break;
        }
      }
      rowCnt = Math.ceil(dates.length / daysPerRow);
    } else {
      rowCnt = 1;
      daysPerRow = dates.length;
    }
    this.rowCnt = rowCnt;
    this.colCnt = daysPerRow;
    this.daySeries = daySeries;
    this.cells = this.buildCells();
    this.headerDates = this.buildHeaderDates();
  }
  buildCells() {
    let rows = [];
    for (let row = 0; row < this.rowCnt; row += 1) {
      let cells = [];
      for (let col = 0; col < this.colCnt; col += 1) {
        cells.push(this.buildCell(row, col));
      }
      rows.push(cells);
    }
    return rows;
  }
  buildCell(row, col) {
    let date = this.daySeries.dates[row * this.colCnt + col];
    return {
      key: date.toISOString(),
      date
    };
  }
  buildHeaderDates() {
    let dates = [];
    for (let col = 0; col < this.colCnt; col += 1) {
      dates.push(this.cells[0][col].date);
    }
    return dates;
  }
  sliceRange(range) {
    let {
      colCnt
    } = this;
    let seriesSeg = this.daySeries.sliceRange(range);
    let segs = [];
    if (seriesSeg) {
      let {
        firstIndex,
        lastIndex
      } = seriesSeg;
      let index = firstIndex;
      while (index <= lastIndex) {
        let row = Math.floor(index / colCnt);
        let nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1);
        segs.push({
          row,
          firstCol: index % colCnt,
          lastCol: (nextIndex - 1) % colCnt,
          isStart: seriesSeg.isStart && index === firstIndex,
          isEnd: seriesSeg.isEnd && nextIndex - 1 === lastIndex
        });
        index = nextIndex;
      }
    }
    return segs;
  }
}
class Slicer {
  constructor() {
    this.sliceBusinessHours = memoize(this._sliceBusinessHours);
    this.sliceDateSelection = memoize(this._sliceDateSpan);
    this.sliceEventStore = memoize(this._sliceEventStore);
    this.sliceEventDrag = memoize(this._sliceInteraction);
    this.sliceEventResize = memoize(this._sliceInteraction);
    this.forceDayIfListItem = false; // hack
  }
  sliceProps(props, dateProfile, nextDayThreshold, context, ...extraArgs) {
    let {
      eventUiBases
    } = props;
    let eventSegs = this.sliceEventStore(props.eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs);
    return {
      dateSelectionSegs: this.sliceDateSelection(props.dateSelection, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs),
      businessHourSegs: this.sliceBusinessHours(props.businessHours, dateProfile, nextDayThreshold, context, ...extraArgs),
      fgEventSegs: eventSegs.fg,
      bgEventSegs: eventSegs.bg,
      eventDrag: this.sliceEventDrag(props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),
      eventResize: this.sliceEventResize(props.eventResize, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs),
      eventSelection: props.eventSelection
    }; // TODO: give interactionSegs?
  }
  sliceNowDate(
  // does not memoize
  date, dateProfile, nextDayThreshold, context, ...extraArgs) {
    return this._sliceDateSpan({
      range: {
        start: date,
        end: addMs(date, 1)
      },
      allDay: false
    },
    // add 1 ms, protect against null range
    dateProfile, nextDayThreshold, {}, context, ...extraArgs);
  }
  _sliceBusinessHours(businessHours, dateProfile, nextDayThreshold, context, ...extraArgs) {
    if (!businessHours) {
      return [];
    }
    return this._sliceEventStore(expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), {}, dateProfile, nextDayThreshold, ...extraArgs).bg;
  }
  _sliceEventStore(eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {
    if (eventStore) {
      let rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
      return {
        bg: this.sliceEventRanges(rangeRes.bg, extraArgs),
        fg: this.sliceEventRanges(rangeRes.fg, extraArgs)
      };
    }
    return {
      bg: [],
      fg: []
    };
  }
  _sliceInteraction(interaction, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) {
    if (!interaction) {
      return null;
    }
    let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold);
    return {
      segs: this.sliceEventRanges(rangeRes.fg, extraArgs),
      affectedInstances: interaction.affectedEvents.instances,
      isEvent: interaction.isEvent
    };
  }
  _sliceDateSpan(dateSpan, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs) {
    if (!dateSpan) {
      return [];
    }
    let activeRange = computeActiveRange(dateProfile, Boolean(nextDayThreshold));
    let activeDateSpanRange = intersectRanges(dateSpan.range, activeRange);
    if (activeDateSpanRange) {
      dateSpan = Object.assign(Object.assign({}, dateSpan), {
        range: activeDateSpanRange
      });
      let eventRange = fabricateEventRange(dateSpan, eventUiBases, context);
      let segs = this.sliceRange(dateSpan.range, ...extraArgs);
      for (let seg of segs) {
        seg.eventRange = eventRange;
      }
      return segs;
    }
    return [];
  }
  /*
  "complete" seg means it has component and eventRange
  */
  sliceEventRanges(eventRanges, extraArgs) {
    let segs = [];
    for (let eventRange of eventRanges) {
      segs.push(...this.sliceEventRange(eventRange, extraArgs));
    }
    return segs;
  }
  /*
  "complete" seg means it has component and eventRange
  */
  sliceEventRange(eventRange, extraArgs) {
    let dateRange = eventRange.range;
    // hack to make multi-day events that are being force-displayed as list-items to take up only one day
    if (this.forceDayIfListItem && eventRange.ui.display === 'list-item') {
      dateRange = {
        start: dateRange.start,
        end: addDays(dateRange.start, 1)
      };
    }
    let segs = this.sliceRange(dateRange, ...extraArgs);
    for (let seg of segs) {
      seg.eventRange = eventRange;
      seg.isStart = eventRange.isStart && seg.isStart;
      seg.isEnd = eventRange.isEnd && seg.isEnd;
    }
    return segs;
  }
}
/*
for incorporating slotMinTime/slotMaxTime if appropriate
TODO: should be part of DateProfile!
TimelineDateProfile already does this btw
*/
function computeActiveRange(dateProfile, isComponentAllDay) {
  let range = dateProfile.activeRange;
  if (isComponentAllDay) {
    return range;
  }
  return {
    start: addMs(range.start, dateProfile.slotMinTime.milliseconds),
    end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5) // 864e5 = ms in a day
  };
}

// high-level segmenting-aware tester functions
// ------------------------------------------------------------------------------------------------------------------------
function isInteractionValid(interaction, dateProfile, context) {
  let {
    instances
  } = interaction.mutatedEvents;
  for (let instanceId in instances) {
    if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) {
      return false;
    }
  }
  return isNewPropsValid({
    eventDrag: interaction
  }, context); // HACK: the eventDrag props is used for ALL interactions
}
function isDateSelectionValid(dateSelection, dateProfile, context) {
  if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) {
    return false;
  }
  return isNewPropsValid({
    dateSelection
  }, context);
}
function isNewPropsValid(newProps, context) {
  let calendarState = context.getCurrentData();
  let props = Object.assign({
    businessHours: calendarState.businessHours,
    dateSelection: '',
    eventStore: calendarState.eventStore,
    eventUiBases: calendarState.eventUiBases,
    eventSelection: '',
    eventDrag: null,
    eventResize: null
  }, newProps);
  return (context.pluginHooks.isPropsValid || isPropsValid)(props, context);
}
function isPropsValid(state, context, dateSpanMeta = {}, filterConfig) {
  if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) {
    return false;
  }
  if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) {
    return false;
  }
  return true;
}
// Moving Event Validation
// ------------------------------------------------------------------------------------------------------------------------
function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) {
  let currentState = context.getCurrentData();
  let interaction = state.eventDrag; // HACK: the eventDrag props is used for ALL interactions
  let subjectEventStore = interaction.mutatedEvents;
  let subjectDefs = subjectEventStore.defs;
  let subjectInstances = subjectEventStore.instances;
  let subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? state.eventUiBases : {
    '': currentState.selectionConfig
  });
  if (filterConfig) {
    subjectConfigs = mapHash(subjectConfigs, filterConfig);
  }
  // exclude the subject events. TODO: exclude defs too?
  let otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances);
  let otherDefs = otherEventStore.defs;
  let otherInstances = otherEventStore.instances;
  let otherConfigs = compileEventUis(otherDefs, state.eventUiBases);
  for (let subjectInstanceId in subjectInstances) {
    let subjectInstance = subjectInstances[subjectInstanceId];
    let subjectRange = subjectInstance.range;
    let subjectConfig = subjectConfigs[subjectInstance.defId];
    let subjectDef = subjectDefs[subjectInstance.defId];
    // constraint
    if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) {
      return false;
    }
    // overlap
    let {
      eventOverlap
    } = context.options;
    let eventOverlapFunc = typeof eventOverlap === 'function' ? eventOverlap : null;
    for (let otherInstanceId in otherInstances) {
      let otherInstance = otherInstances[otherInstanceId];
      // intersect! evaluate
      if (rangesIntersect(subjectRange, otherInstance.range)) {
        let otherOverlap = otherConfigs[otherInstance.defId].overlap;
        // consider the other event's overlap. only do this if the subject event is a "real" event
        if (otherOverlap === false && interaction.isEvent) {
          return false;
        }
        if (subjectConfig.overlap === false) {
          return false;
        }
        if (eventOverlapFunc && !eventOverlapFunc(new EventImpl(context, otherDefs[otherInstance.defId], otherInstance),
        // still event
        new EventImpl(context, subjectDef, subjectInstance))) {
          return false;
        }
      }
    }
    // allow (a function)
    let calendarEventStore = currentState.eventStore; // need global-to-calendar, not local to component (splittable)state
    for (let subjectAllow of subjectConfig.allows) {
      let subjectDateSpan = Object.assign(Object.assign({}, dateSpanMeta), {
        range: subjectInstance.range,
        allDay: subjectDef.allDay
      });
      let origDef = calendarEventStore.defs[subjectDef.defId];
      let origInstance = calendarEventStore.instances[subjectInstanceId];
      let eventApi;
      if (origDef) {
        // was previously in the calendar
        eventApi = new EventImpl(context, origDef, origInstance);
      } else {
        // was an external event
        eventApi = new EventImpl(context, subjectDef); // no instance, because had no dates
      }
      if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) {
        return false;
      }
    }
  }
  return true;
}
// Date Selection Validation
// ------------------------------------------------------------------------------------------------------------------------
function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) {
  let relevantEventStore = state.eventStore;
  let relevantDefs = relevantEventStore.defs;
  let relevantInstances = relevantEventStore.instances;
  let selection = state.dateSelection;
  let selectionRange = selection.range;
  let {
    selectionConfig
  } = context.getCurrentData();
  if (filterConfig) {
    selectionConfig = filterConfig(selectionConfig);
  }
  // constraint
  if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) {
    return false;
  }
  // overlap
  let {
    selectOverlap
  } = context.options;
  let selectOverlapFunc = typeof selectOverlap === 'function' ? selectOverlap : null;
  for (let relevantInstanceId in relevantInstances) {
    let relevantInstance = relevantInstances[relevantInstanceId];
    // intersect! evaluate
    if (rangesIntersect(selectionRange, relevantInstance.range)) {
      if (selectionConfig.overlap === false) {
        return false;
      }
      if (selectOverlapFunc && !selectOverlapFunc(new EventImpl(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) {
        return false;
      }
    }
  }
  // allow (a function)
  for (let selectionAllow of selectionConfig.allows) {
    let fullDateSpan = Object.assign(Object.assign({}, dateSpanMeta), selection);
    if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) {
      return false;
    }
  }
  return true;
}
// Constraint Utils
// ------------------------------------------------------------------------------------------------------------------------
function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) {
  for (let constraint of constraints) {
    if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) {
      return false;
    }
  }
  return true;
}
function constraintToRanges(constraint, subjectRange,
// for expanding a recurring constraint, or expanding business hours
otherEventStore,
// for if constraint is an even group ID
businessHoursUnexpanded,
// for if constraint is 'businessHours'
context) {
  if (constraint === 'businessHours') {
    return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context));
  }
  if (typeof constraint === 'string') {
    // an group ID
    return eventStoreToRanges(filterEventStoreDefs(otherEventStore, eventDef => eventDef.groupId === constraint));
  }
  if (typeof constraint === 'object' && constraint) {
    // non-null object
    return eventStoreToRanges(expandRecurring(constraint, subjectRange, context));
  }
  return []; // if it's false
}
// TODO: move to event-store file?
function eventStoreToRanges(eventStore) {
  let {
    instances
  } = eventStore;
  let ranges = [];
  for (let instanceId in instances) {
    ranges.push(instances[instanceId].range);
  }
  return ranges;
}
// TODO: move to geom file?
function anyRangesContainRange(outerRanges, innerRange) {
  for (let outerRange of outerRanges) {
    if (rangeContainsRange(outerRange, innerRange)) {
      return true;
    }
  }
  return false;
}
const VISIBLE_HIDDEN_RE = /^(visible|hidden)$/;
class Scroller extends BaseComponent {
  constructor() {
    super(...arguments);
    this.handleEl = el => {
      this.el = el;
      setRef(this.props.elRef, el);
    };
  }
  render() {
    let {
      props
    } = this;
    let {
      liquid,
      liquidIsAbsolute
    } = props;
    let isAbsolute = liquid && liquidIsAbsolute;
    let className = ['fc-scroller'];
    if (liquid) {
      if (liquidIsAbsolute) {
        className.push('fc-scroller-liquid-absolute');
      } else {
        className.push('fc-scroller-liquid');
      }
    }
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      ref: this.handleEl,
      className: className.join(' '),
      style: {
        overflowX: props.overflowX,
        overflowY: props.overflowY,
        left: isAbsolute && -(props.overcomeLeft || 0) || '',
        right: isAbsolute && -(props.overcomeRight || 0) || '',
        bottom: isAbsolute && -(props.overcomeBottom || 0) || '',
        marginLeft: !isAbsolute && -(props.overcomeLeft || 0) || '',
        marginRight: !isAbsolute && -(props.overcomeRight || 0) || '',
        marginBottom: !isAbsolute && -(props.overcomeBottom || 0) || '',
        maxHeight: props.maxHeight || ''
      }
    }, props.children);
  }
  needsXScrolling() {
    if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
      return false;
    }
    // testing scrollWidth>clientWidth is unreliable cross-browser when pixel heights aren't integers.
    // much more reliable to see if children are taller than the scroller, even tho doesn't account for
    // inner-child margins and absolute positioning
    let {
      el
    } = this;
    let realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth();
    let {
      children
    } = el;
    for (let i = 0; i < children.length; i += 1) {
      let childEl = children[i];
      if (childEl.getBoundingClientRect().width > realClientWidth) {
        return true;
      }
    }
    return false;
  }
  needsYScrolling() {
    if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
      return false;
    }
    // testing scrollHeight>clientHeight is unreliable cross-browser when pixel heights aren't integers.
    // much more reliable to see if children are taller than the scroller, even tho doesn't account for
    // inner-child margins and absolute positioning
    let {
      el
    } = this;
    let realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth();
    let {
      children
    } = el;
    for (let i = 0; i < children.length; i += 1) {
      let childEl = children[i];
      if (childEl.getBoundingClientRect().height > realClientHeight) {
        return true;
      }
    }
    return false;
  }
  getXScrollbarWidth() {
    if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) {
      return 0;
    }
    return this.el.offsetHeight - this.el.clientHeight; // only works because we guarantee no borders. TODO: add to CSS with important?
  }
  getYScrollbarWidth() {
    if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) {
      return 0;
    }
    return this.el.offsetWidth - this.el.clientWidth; // only works because we guarantee no borders. TODO: add to CSS with important?
  }
}

/*
TODO: somehow infer OtherArgs from masterCallback?
TODO: infer RefType from masterCallback if provided
*/
class RefMap {
  constructor(masterCallback) {
    this.masterCallback = masterCallback;
    this.currentMap = {};
    this.depths = {};
    this.callbackMap = {};
    this.handleValue = (val, key) => {
      let {
        depths,
        currentMap
      } = this;
      let removed = false;
      let added = false;
      if (val !== null) {
        // for bug... ACTUALLY: can probably do away with this now that callers don't share numeric indices anymore
        removed = key in currentMap;
        currentMap[key] = val;
        depths[key] = (depths[key] || 0) + 1;
        added = true;
      } else {
        depths[key] -= 1;
        if (!depths[key]) {
          delete currentMap[key];
          delete this.callbackMap[key];
          removed = true;
        }
      }
      if (this.masterCallback) {
        if (removed) {
          this.masterCallback(null, String(key));
        }
        if (added) {
          this.masterCallback(val, String(key));
        }
      }
    };
  }
  createRef(key) {
    let refCallback = this.callbackMap[key];
    if (!refCallback) {
      refCallback = this.callbackMap[key] = val => {
        this.handleValue(val, String(key));
      };
    }
    return refCallback;
  }
  // TODO: check callers that don't care about order. should use getAll instead
  // NOTE: this method has become less valuable now that we are encouraged to map order by some other index
  // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect"
  collect(startIndex, endIndex, step) {
    return collectFromHash(this.currentMap, startIndex, endIndex, step);
  }
  getAll() {
    return hashValuesToArray(this.currentMap);
  }
}
function computeShrinkWidth(chunkEls) {
  let shrinkCells = findElements(chunkEls, '.fc-scrollgrid-shrink');
  let largestWidth = 0;
  for (let shrinkCell of shrinkCells) {
    largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell));
  }
  return Math.ceil(largestWidth); // <table> elements work best with integers. round up to ensure contents fits
}
function getSectionHasLiquidHeight(props, sectionConfig) {
  return props.liquid && sectionConfig.liquid; // does the section do liquid-height? (need to have whole scrollgrid liquid-height as well)
}
function getAllowYScrolling(props, sectionConfig) {
  return sectionConfig.maxHeight != null ||
  // if its possible for the height to max out, we might need scrollbars
  getSectionHasLiquidHeight(props, sectionConfig); // if the section is liquid height, it might condense enough to require scrollbars
}
// TODO: ONLY use `arg`. force out internal function to use same API
function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) {
  let {
    expandRows
  } = arg;
  let content = typeof chunkConfig.content === 'function' ? chunkConfig.content(arg) : (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('table', {
    role: 'presentation',
    className: [chunkConfig.tableClassName, sectionConfig.syncRowHeights ? 'fc-scrollgrid-sync-table' : ''].join(' '),
    style: {
      minWidth: arg.tableMinWidth,
      width: arg.clientWidth,
      height: expandRows ? arg.clientHeight : '' // css `height` on a <table> serves as a min-height
    }
  }, arg.tableColGroupNode, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(isHeader ? 'thead' : 'tbody', {
    role: 'presentation'
  }, typeof chunkConfig.rowContent === 'function' ? chunkConfig.rowContent(arg) : chunkConfig.rowContent));
  return content;
}
function isColPropsEqual(cols0, cols1) {
  return isArraysEqual(cols0, cols1, isPropsEqual);
}
function renderMicroColGroup(cols, shrinkWidth) {
  let colNodes = [];
  /*
  for ColProps with spans, it would have been great to make a single <col span="">
  HOWEVER, Chrome was getting messing up distributing the width to <td>/<th> elements with colspans.
  SOLUTION: making individual <col> elements makes Chrome behave.
  */
  for (let colProps of cols) {
    let span = colProps.span || 1;
    for (let i = 0; i < span; i += 1) {
      colNodes.push((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("col", {
        style: {
          width: colProps.width === 'shrink' ? sanitizeShrinkWidth(shrinkWidth) : colProps.width || '',
          minWidth: colProps.minWidth || ''
        }
      }));
    }
  }
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('colgroup', {}, ...colNodes);
}
function sanitizeShrinkWidth(shrinkWidth) {
  /* why 4? if we do 0, it will kill any border, which are needed for computeSmallestCellWidth
  4 accounts for 2 2-pixel borders. TODO: better solution? */
  return shrinkWidth == null ? 4 : shrinkWidth;
}
function hasShrinkWidth(cols) {
  for (let col of cols) {
    if (col.width === 'shrink') {
      return true;
    }
  }
  return false;
}
function getScrollGridClassNames(liquid, context) {
  let classNames = ['fc-scrollgrid', context.theme.getClass('table')];
  if (liquid) {
    classNames.push('fc-scrollgrid-liquid');
  }
  return classNames;
}
function getSectionClassNames(sectionConfig, wholeTableVGrow) {
  let classNames = ['fc-scrollgrid-section', `fc-scrollgrid-section-${sectionConfig.type}`, sectionConfig.className // used?
  ];
  if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) {
    classNames.push('fc-scrollgrid-section-liquid');
  }
  if (sectionConfig.isSticky) {
    classNames.push('fc-scrollgrid-section-sticky');
  }
  return classNames;
}
function renderScrollShim(arg) {
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-scrollgrid-sticky-shim",
    style: {
      width: arg.clientWidth,
      minWidth: arg.tableMinWidth
    }
  });
}
function getStickyHeaderDates(options) {
  let {
    stickyHeaderDates
  } = options;
  if (stickyHeaderDates == null || stickyHeaderDates === 'auto') {
    stickyHeaderDates = options.height === 'auto' || options.viewHeight === 'auto';
  }
  return stickyHeaderDates;
}
function getStickyFooterScrollbar(options) {
  let {
    stickyFooterScrollbar
  } = options;
  if (stickyFooterScrollbar == null || stickyFooterScrollbar === 'auto') {
    stickyFooterScrollbar = options.height === 'auto' || options.viewHeight === 'auto';
  }
  return stickyFooterScrollbar;
}
class SimpleScrollGrid extends BaseComponent {
  constructor() {
    super(...arguments);
    this.processCols = memoize(a => a, isColPropsEqual); // so we get same `cols` props every time
    // yucky to memoize VNodes, but much more efficient for consumers
    this.renderMicroColGroup = memoize(renderMicroColGroup);
    this.scrollerRefs = new RefMap();
    this.scrollerElRefs = new RefMap(this._handleScrollerEl.bind(this));
    this.state = {
      shrinkWidth: null,
      forceYScrollbars: false,
      scrollerClientWidths: {},
      scrollerClientHeights: {}
    };
    // TODO: can do a really simple print-view. dont need to join rows
    this.handleSizing = () => {
      this.safeSetState(Object.assign({
        shrinkWidth: this.computeShrinkWidth()
      }, this.computeScrollerDims()));
    };
  }
  render() {
    let {
      props,
      state,
      context
    } = this;
    let sectionConfigs = props.sections || [];
    let cols = this.processCols(props.cols);
    let microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth);
    let classNames = getScrollGridClassNames(props.liquid, context);
    if (props.collapsibleWidth) {
      classNames.push('fc-scrollgrid-collapsible');
    }
    // TODO: make DRY
    let configCnt = sectionConfigs.length;
    let configI = 0;
    let currentConfig;
    let headSectionNodes = [];
    let bodySectionNodes = [];
    let footSectionNodes = [];
    while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'header') {
      headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
      configI += 1;
    }
    while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'body') {
      bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false));
      configI += 1;
    }
    while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === 'footer') {
      footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true));
      configI += 1;
    }
    // firefox bug: when setting height on table and there is a thead or tfoot,
    // the necessary height:100% on the liquid-height body section forces the *whole* table to be taller. (bug #5524)
    // use getCanVGrowWithinCell as a way to detect table-stupid firefox.
    // if so, use a simpler dom structure, jam everything into a lone tbody.
    let isBuggy = !getCanVGrowWithinCell();
    const roleAttrs = {
      role: 'rowgroup'
    };
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('table', {
      role: 'grid',
      className: classNames.join(' '),
      style: {
        height: props.height
      }
    }, Boolean(!isBuggy && headSectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('thead', roleAttrs, ...headSectionNodes), Boolean(!isBuggy && bodySectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tbody', roleAttrs, ...bodySectionNodes), Boolean(!isBuggy && footSectionNodes.length) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tfoot', roleAttrs, ...footSectionNodes), isBuggy && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)('tbody', roleAttrs, ...headSectionNodes, ...bodySectionNodes, ...footSectionNodes));
  }
  renderSection(sectionConfig, microColGroupNode, isHeader) {
    if ('outerContent' in sectionConfig) {
      return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, {
        key: sectionConfig.key
      }, sectionConfig.outerContent);
    }
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("tr", {
      key: sectionConfig.key,
      role: "presentation",
      className: getSectionClassNames(sectionConfig, this.props.liquid).join(' ')
    }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader));
  }
  renderChunkTd(sectionConfig, microColGroupNode, chunkConfig, isHeader) {
    if ('outerContent' in chunkConfig) {
      return chunkConfig.outerContent;
    }
    let {
      props
    } = this;
    let {
      forceYScrollbars,
      scrollerClientWidths,
      scrollerClientHeights
    } = this.state;
    let needsYScrolling = getAllowYScrolling(props, sectionConfig); // TODO: do lazily. do in section config?
    let isLiquid = getSectionHasLiquidHeight(props, sectionConfig);
    // for `!props.liquid` - is WHOLE scrollgrid natural height?
    // TODO: do same thing in advanced scrollgrid? prolly not b/c always has horizontal scrollbars
    let overflowY = !props.liquid ? 'visible' : forceYScrollbars ? 'scroll' : !needsYScrolling ? 'hidden' : 'auto';
    let sectionKey = sectionConfig.key;
    let content = renderChunkContent(sectionConfig, chunkConfig, {
      tableColGroupNode: microColGroupNode,
      tableMinWidth: '',
      clientWidth: !props.collapsibleWidth && scrollerClientWidths[sectionKey] !== undefined ? scrollerClientWidths[sectionKey] : null,
      clientHeight: scrollerClientHeights[sectionKey] !== undefined ? scrollerClientHeights[sectionKey] : null,
      expandRows: sectionConfig.expandRows,
      syncRowHeights: false,
      rowSyncHeights: [],
      reportRowHeightChange: () => {}
    }, isHeader);
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(isHeader ? 'th' : 'td', {
      ref: chunkConfig.elRef,
      role: 'presentation'
    }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: `fc-scroller-harness${isLiquid ? ' fc-scroller-harness-liquid' : ''}`
    }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(Scroller, {
      ref: this.scrollerRefs.createRef(sectionKey),
      elRef: this.scrollerElRefs.createRef(sectionKey),
      overflowY: overflowY,
      overflowX: !props.liquid ? 'visible' : 'hidden' /* natural height? */,
      maxHeight: sectionConfig.maxHeight,
      liquid: isLiquid,
      liquidIsAbsolute // because its within a harness
      : true
    }, content)));
  }
  _handleScrollerEl(scrollerEl, key) {
    let section = getSectionByKey(this.props.sections, key);
    if (section) {
      setRef(section.chunk.scrollerElRef, scrollerEl);
    }
  }
  componentDidMount() {
    this.handleSizing();
    this.context.addResizeHandler(this.handleSizing);
  }
  componentDidUpdate() {
    // TODO: need better solution when state contains non-sizing things
    this.handleSizing();
  }
  componentWillUnmount() {
    this.context.removeResizeHandler(this.handleSizing);
  }
  computeShrinkWidth() {
    return hasShrinkWidth(this.props.cols) ? computeShrinkWidth(this.scrollerElRefs.getAll()) : 0;
  }
  computeScrollerDims() {
    let scrollbarWidth = getScrollbarWidths();
    let {
      scrollerRefs,
      scrollerElRefs
    } = this;
    let forceYScrollbars = false;
    let scrollerClientWidths = {};
    let scrollerClientHeights = {};
    for (let sectionKey in scrollerRefs.currentMap) {
      let scroller = scrollerRefs.currentMap[sectionKey];
      if (scroller && scroller.needsYScrolling()) {
        forceYScrollbars = true;
        break;
      }
    }
    for (let section of this.props.sections) {
      let sectionKey = section.key;
      let scrollerEl = scrollerElRefs.currentMap[sectionKey];
      if (scrollerEl) {
        let harnessEl = scrollerEl.parentNode; // TODO: weird way to get this. need harness b/c doesn't include table borders
        scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars ? scrollbarWidth.y // use global because scroller might not have scrollbars yet but will need them in future
        : 0));
        scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height);
      }
    }
    return {
      forceYScrollbars,
      scrollerClientWidths,
      scrollerClientHeights
    };
  }
}
SimpleScrollGrid.addStateEquality({
  scrollerClientWidths: isPropsEqual,
  scrollerClientHeights: isPropsEqual
});
function getSectionByKey(sections, key) {
  for (let section of sections) {
    if (section.key === key) {
      return section;
    }
  }
  return null;
}
class EventContainer extends BaseComponent {
  constructor() {
    super(...arguments);
    // memo
    this.buildPublicEvent = memoize((context, eventDef, eventInstance) => new EventImpl(context, eventDef, eventInstance));
    this.handleEl = el => {
      this.el = el;
      setRef(this.props.elRef, el);
      if (el) {
        setElSeg(el, this.props.seg);
      }
    };
  }
  render() {
    const {
      props,
      context
    } = this;
    const {
      options
    } = context;
    const {
      seg
    } = props;
    const {
      eventRange
    } = seg;
    const {
      ui
    } = eventRange;
    const renderProps = {
      event: this.buildPublicEvent(context, eventRange.def, eventRange.instance),
      view: context.viewApi,
      timeText: props.timeText,
      textColor: ui.textColor,
      backgroundColor: ui.backgroundColor,
      borderColor: ui.borderColor,
      isDraggable: !props.disableDragging && computeSegDraggable(seg, context),
      isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context),
      isEndResizable: !props.disableResizing && computeSegEndResizable(seg),
      isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
      isStart: Boolean(seg.isStart),
      isEnd: Boolean(seg.isEnd),
      isPast: Boolean(props.isPast),
      isFuture: Boolean(props.isFuture),
      isToday: Boolean(props.isToday),
      isSelected: Boolean(props.isSelected),
      isDragging: Boolean(props.isDragging),
      isResizing: Boolean(props.isResizing)
    };
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
      elRef: this.handleEl,
      elTag: props.elTag,
      elAttrs: props.elAttrs,
      elClasses: [...getEventClassNames(renderProps), ...seg.eventRange.ui.classNames, ...(props.elClasses || [])],
      elStyle: props.elStyle,
      renderProps: renderProps,
      generatorName: "eventContent",
      customGenerator: options.eventContent,
      defaultGenerator: props.defaultGenerator,
      classNameGenerator: options.eventClassNames,
      didMount: options.eventDidMount,
      willUnmount: options.eventWillUnmount
    }, props.children);
  }
  componentDidUpdate(prevProps) {
    if (this.el && this.props.seg !== prevProps.seg) {
      setElSeg(this.el, this.props.seg);
    }
  }
}

// should not be a purecomponent
class StandardEvent extends BaseComponent {
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let {
      seg
    } = props;
    let {
      ui
    } = seg.eventRange;
    let timeFormat = options.eventTimeFormat || props.defaultTimeFormat;
    let timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd);
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(EventContainer, Object.assign({}, props /* includes elRef */, {
      elTag: "a",
      elStyle: {
        borderColor: ui.borderColor,
        backgroundColor: ui.backgroundColor
      },
      elAttrs: getSegAnchorAttrs(seg, context),
      defaultGenerator: renderInnerContent$1,
      timeText: timeText
    }), (InnerContent, eventContentArg) => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-event-main'],
      elStyle: {
        color: eventContentArg.textColor
      }
    }), Boolean(eventContentArg.isStartResizable) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: "fc-event-resizer fc-event-resizer-start"
    }), Boolean(eventContentArg.isEndResizable) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: "fc-event-resizer fc-event-resizer-end"
    })));
  }
}
StandardEvent.addPropsEquality({
  seg: isPropsEqual
});
function renderInnerContent$1(innerProps) {
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-event-main-frame"
  }, innerProps.timeText && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-event-time"
  }, innerProps.timeText), (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-event-title-container"
  }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-event-title fc-sticky"
  }, innerProps.event.title || (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, "\u00A0"))));
}
const NowIndicatorContainer = props => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, context => {
  let {
    options
  } = context;
  let renderProps = {
    isAxis: props.isAxis,
    date: context.dateEnv.toDate(props.date),
    view: context.viewApi
  };
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
    elRef: props.elRef,
    elTag: props.elTag || 'div',
    elAttrs: props.elAttrs,
    elClasses: props.elClasses,
    elStyle: props.elStyle,
    renderProps: renderProps,
    generatorName: "nowIndicatorContent",
    customGenerator: options.nowIndicatorContent,
    classNameGenerator: options.nowIndicatorClassNames,
    didMount: options.nowIndicatorDidMount,
    willUnmount: options.nowIndicatorWillUnmount
  }, props.children);
});
const DAY_NUM_FORMAT = createFormatter({
  day: 'numeric'
});
class DayCellContainer extends BaseComponent {
  constructor() {
    super(...arguments);
    this.refineRenderProps = memoizeObjArg(refineRenderProps);
  }
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let renderProps = this.refineRenderProps({
      date: props.date,
      dateProfile: props.dateProfile,
      todayRange: props.todayRange,
      isMonthStart: props.isMonthStart || false,
      showDayNumber: props.showDayNumber,
      extraRenderProps: props.extraRenderProps,
      viewApi: context.viewApi,
      dateEnv: context.dateEnv,
      monthStartFormat: options.monthStartFormat
    });
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
      elRef: props.elRef,
      elTag: props.elTag,
      elAttrs: Object.assign(Object.assign({}, props.elAttrs), renderProps.isDisabled ? {} : {
        'data-date': formatDayString(props.date)
      }),
      elClasses: [...getDayClassNames(renderProps, context.theme), ...(props.elClasses || [])],
      elStyle: props.elStyle,
      renderProps: renderProps,
      generatorName: "dayCellContent",
      customGenerator: options.dayCellContent,
      defaultGenerator: props.defaultGenerator,
      classNameGenerator:
      // don't use custom classNames if disabled
      renderProps.isDisabled ? undefined : options.dayCellClassNames,
      didMount: options.dayCellDidMount,
      willUnmount: options.dayCellWillUnmount
    }, props.children);
  }
}
function hasCustomDayCellContent(options) {
  return Boolean(options.dayCellContent || hasCustomRenderingHandler('dayCellContent', options));
}
function refineRenderProps(raw) {
  let {
    date,
    dateEnv,
    dateProfile,
    isMonthStart
  } = raw;
  let dayMeta = getDateMeta(date, raw.todayRange, null, dateProfile);
  let dayNumberText = raw.showDayNumber ? dateEnv.format(date, isMonthStart ? raw.monthStartFormat : DAY_NUM_FORMAT) : '';
  return Object.assign(Object.assign(Object.assign({
    date: dateEnv.toDate(date),
    view: raw.viewApi
  }, dayMeta), {
    isMonthStart,
    dayNumberText
  }), raw.extraRenderProps);
}
class BgEvent extends BaseComponent {
  render() {
    let {
      props
    } = this;
    let {
      seg
    } = props;
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(EventContainer, {
      elTag: "div",
      elClasses: ['fc-bg-event'],
      elStyle: {
        backgroundColor: seg.eventRange.ui.backgroundColor
      },
      defaultGenerator: renderInnerContent,
      seg: seg,
      timeText: "",
      isDragging: false,
      isResizing: false,
      isDateSelecting: false,
      isSelected: false,
      isPast: props.isPast,
      isFuture: props.isFuture,
      isToday: props.isToday,
      disableDragging: true,
      disableResizing: true
    });
  }
}
function renderInnerContent(props) {
  let {
    title
  } = props.event;
  return title && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: "fc-event-title"
  }, props.event.title);
}
function renderFill(fillType) {
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
    className: `fc-${fillType}`
  });
}
const WeekNumberContainer = props => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, context => {
  let {
    dateEnv,
    options
  } = context;
  let {
    date
  } = props;
  let format = options.weekNumberFormat || props.defaultFormat;
  let num = dateEnv.computeWeekNumber(date); // TODO: somehow use for formatting as well?
  let text = dateEnv.format(date, format);
  let renderProps = {
    num,
    text,
    date
  };
  return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer // why isn't WeekNumberContentArg being auto-detected?
  , {
    elRef: props.elRef,
    elTag: props.elTag,
    elAttrs: props.elAttrs,
    elClasses: props.elClasses,
    elStyle: props.elStyle,
    renderProps: renderProps,
    generatorName: "weekNumberContent",
    customGenerator: options.weekNumberContent,
    defaultGenerator: renderInner,
    classNameGenerator: options.weekNumberClassNames,
    didMount: options.weekNumberDidMount,
    willUnmount: options.weekNumberWillUnmount
  }, props.children);
});
function renderInner(innerProps) {
  return innerProps.text;
}
const PADDING_FROM_VIEWPORT = 10;
class Popover extends BaseComponent {
  constructor() {
    super(...arguments);
    this.state = {
      titleId: getUniqueDomId()
    };
    this.handleRootEl = el => {
      this.rootEl = el;
      if (this.props.elRef) {
        setRef(this.props.elRef, el);
      }
    };
    // Triggered when the user clicks *anywhere* in the document, for the autoHide feature
    this.handleDocumentMouseDown = ev => {
      // only hide the popover if the click happened outside the popover
      const target = getEventTargetViaRoot(ev);
      if (!this.rootEl.contains(target)) {
        this.handleCloseClick();
      }
    };
    this.handleDocumentKeyDown = ev => {
      if (ev.key === 'Escape') {
        this.handleCloseClick();
      }
    };
    this.handleCloseClick = () => {
      let {
        onClose
      } = this.props;
      if (onClose) {
        onClose();
      }
    };
  }
  render() {
    let {
      theme,
      options
    } = this.context;
    let {
      props,
      state
    } = this;
    let classNames = ['fc-popover', theme.getClass('popover')].concat(props.extraClassNames || []);
    return (0,preact_compat__WEBPACK_IMPORTED_MODULE_1__.createPortal)((0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", Object.assign({}, props.extraAttrs, {
      id: props.id,
      className: classNames.join(' '),
      "aria-labelledby": state.titleId,
      ref: this.handleRootEl
    }), (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: 'fc-popover-header ' + theme.getClass('popoverHeader')
    }, (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("span", {
      className: "fc-popover-title",
      id: state.titleId
    }, props.title), (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("span", {
      className: 'fc-popover-close ' + theme.getIconClass('close'),
      title: options.closeHint,
      onClick: this.handleCloseClick
    })), (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)("div", {
      className: 'fc-popover-body ' + theme.getClass('popoverContent')
    }, props.children)), props.parentEl);
  }
  componentDidMount() {
    document.addEventListener('mousedown', this.handleDocumentMouseDown);
    document.addEventListener('keydown', this.handleDocumentKeyDown);
    this.updateSize();
  }
  componentWillUnmount() {
    document.removeEventListener('mousedown', this.handleDocumentMouseDown);
    document.removeEventListener('keydown', this.handleDocumentKeyDown);
  }
  updateSize() {
    let {
      isRtl
    } = this.context;
    let {
      alignmentEl,
      alignGridTop
    } = this.props;
    let {
      rootEl
    } = this;
    let alignmentRect = computeClippedClientRect(alignmentEl);
    if (alignmentRect) {
      let popoverDims = rootEl.getBoundingClientRect();
      // position relative to viewport
      let popoverTop = alignGridTop ? elementClosest(alignmentEl, '.fc-scrollgrid').getBoundingClientRect().top : alignmentRect.top;
      let popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left;
      // constrain
      popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT);
      popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width);
      popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT);
      let origin = rootEl.offsetParent.getBoundingClientRect();
      applyStyle(rootEl, {
        top: popoverTop - origin.top,
        left: popoverLeft - origin.left
      });
    }
  }
}
class MorePopover extends DateComponent {
  constructor() {
    super(...arguments);
    this.handleRootEl = rootEl => {
      this.rootEl = rootEl;
      if (rootEl) {
        this.context.registerInteractiveComponent(this, {
          el: rootEl,
          useEventCenter: false
        });
      } else {
        this.context.unregisterInteractiveComponent(this);
      }
    };
  }
  render() {
    let {
      options,
      dateEnv
    } = this.context;
    let {
      props
    } = this;
    let {
      startDate,
      todayRange,
      dateProfile
    } = props;
    let title = dateEnv.format(startDate, options.dayPopoverFormat);
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(DayCellContainer, {
      elRef: this.handleRootEl,
      date: startDate,
      dateProfile: dateProfile,
      todayRange: todayRange
    }, (InnerContent, renderProps, elAttrs) => (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(Popover, {
      elRef: elAttrs.ref,
      id: props.id,
      title: title,
      extraClassNames: ['fc-more-popover'].concat(elAttrs.className || []),
      extraAttrs: elAttrs /* TODO: make these time-based when not whole-day? */,
      parentEl: props.parentEl,
      alignmentEl: props.alignmentEl,
      alignGridTop: props.alignGridTop,
      onClose: props.onClose
    }, hasCustomDayCellContent(options) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-more-popover-misc']
    }), props.children));
  }
  queryHit(positionLeft, positionTop, elWidth, elHeight) {
    let {
      rootEl,
      props
    } = this;
    if (positionLeft >= 0 && positionLeft < elWidth && positionTop >= 0 && positionTop < elHeight) {
      return {
        dateProfile: props.dateProfile,
        dateSpan: Object.assign({
          allDay: !props.forceTimed,
          range: {
            start: props.startDate,
            end: props.endDate
          }
        }, props.extraDateSpan),
        dayEl: rootEl,
        rect: {
          left: 0,
          top: 0,
          right: elWidth,
          bottom: elHeight
        },
        layer: 1 // important when comparing with hits from other components
      };
    }
    return null;
  }
}
class MoreLinkContainer extends BaseComponent {
  constructor() {
    super(...arguments);
    this.state = {
      isPopoverOpen: false,
      popoverId: getUniqueDomId()
    };
    this.handleLinkEl = linkEl => {
      this.linkEl = linkEl;
      if (this.props.elRef) {
        setRef(this.props.elRef, linkEl);
      }
    };
    this.handleClick = ev => {
      let {
        props,
        context
      } = this;
      let {
        moreLinkClick
      } = context.options;
      let date = computeRange(props).start;
      function buildPublicSeg(seg) {
        let {
          def,
          instance,
          range
        } = seg.eventRange;
        return {
          event: new EventImpl(context, def, instance),
          start: context.dateEnv.toDate(range.start),
          end: context.dateEnv.toDate(range.end),
          isStart: seg.isStart,
          isEnd: seg.isEnd
        };
      }
      if (typeof moreLinkClick === 'function') {
        moreLinkClick = moreLinkClick({
          date,
          allDay: Boolean(props.allDayDate),
          allSegs: props.allSegs.map(buildPublicSeg),
          hiddenSegs: props.hiddenSegs.map(buildPublicSeg),
          jsEvent: ev,
          view: context.viewApi
        });
      }
      if (!moreLinkClick || moreLinkClick === 'popover') {
        this.setState({
          isPopoverOpen: true
        });
      } else if (typeof moreLinkClick === 'string') {
        // a view name
        context.calendarApi.zoomTo(date, moreLinkClick);
      }
    };
    this.handlePopoverClose = () => {
      this.setState({
        isPopoverOpen: false
      });
    };
  }
  render() {
    let {
      props,
      state
    } = this;
    return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ViewContextType.Consumer, null, context => {
      let {
        viewApi,
        options,
        calendarApi
      } = context;
      let {
        moreLinkText
      } = options;
      let {
        moreCnt
      } = props;
      let range = computeRange(props);
      let text = typeof moreLinkText === 'function' // TODO: eventually use formatWithOrdinals
      ? moreLinkText.call(calendarApi, moreCnt) : `+${moreCnt} ${moreLinkText}`;
      let hint = formatWithOrdinals(options.moreLinkHint, [moreCnt], text);
      let renderProps = {
        num: moreCnt,
        shortText: `+${moreCnt}`,
        text,
        view: viewApi
      };
      return (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(preact__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, Boolean(props.moreCnt) && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(ContentContainer, {
        elTag: props.elTag || 'a',
        elRef: this.handleLinkEl,
        elClasses: [...(props.elClasses || []), 'fc-more-link'],
        elStyle: props.elStyle,
        elAttrs: Object.assign(Object.assign(Object.assign({}, props.elAttrs), createAriaClickAttrs(this.handleClick)), {
          title: hint,
          'aria-expanded': state.isPopoverOpen,
          'aria-controls': state.isPopoverOpen ? state.popoverId : ''
        }),
        renderProps: renderProps,
        generatorName: "moreLinkContent",
        customGenerator: options.moreLinkContent,
        defaultGenerator: props.defaultGenerator || renderMoreLinkInner,
        classNameGenerator: options.moreLinkClassNames,
        didMount: options.moreLinkDidMount,
        willUnmount: options.moreLinkWillUnmount
      }, props.children), state.isPopoverOpen && (0,preact__WEBPACK_IMPORTED_MODULE_0__.createElement)(MorePopover, {
        id: state.popoverId,
        startDate: range.start,
        endDate: range.end,
        dateProfile: props.dateProfile,
        todayRange: props.todayRange,
        extraDateSpan: props.extraDateSpan,
        parentEl: this.parentEl,
        alignmentEl: props.alignmentElRef ? props.alignmentElRef.current : this.linkEl,
        alignGridTop: props.alignGridTop,
        forceTimed: props.forceTimed,
        onClose: this.handlePopoverClose
      }, props.popoverContent()));
    });
  }
  componentDidMount() {
    this.updateParentEl();
  }
  componentDidUpdate() {
    this.updateParentEl();
  }
  updateParentEl() {
    if (this.linkEl) {
      this.parentEl = elementClosest(this.linkEl, '.fc-view-harness');
    }
  }
}
function renderMoreLinkInner(props) {
  return props.text;
}
function computeRange(props) {
  if (props.allDayDate) {
    return {
      start: props.allDayDate,
      end: addDays(props.allDayDate, 1)
    };
  }
  let {
    hiddenSegs
  } = props;
  return {
    start: computeEarliestSegStart(hiddenSegs),
    end: computeLatestSegEnd(hiddenSegs)
  };
}
function computeEarliestSegStart(segs) {
  return segs.reduce(pickEarliestStart).eventRange.range.start;
}
function pickEarliestStart(seg0, seg1) {
  return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1;
}
function computeLatestSegEnd(segs) {
  return segs.reduce(pickLatestEnd).eventRange.range.end;
}
function pickLatestEnd(seg0, seg1) {
  return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1;
}
class Store {
  constructor() {
    this.handlers = [];
  }
  set(value) {
    this.currentValue = value;
    for (let handler of this.handlers) {
      handler(value);
    }
  }
  subscribe(handler) {
    this.handlers.push(handler);
    if (this.currentValue !== undefined) {
      handler(this.currentValue);
    }
  }
}

/*
Subscribers will get a LIST of CustomRenderings
*/
class CustomRenderingStore extends Store {
  constructor() {
    super(...arguments);
    this.map = new Map();
  }
  // for consistent order
  handle(customRendering) {
    const {
      map
    } = this;
    let updated = false;
    if (customRendering.isActive) {
      map.set(customRendering.id, customRendering);
      updated = true;
    } else if (map.has(customRendering.id)) {
      map.delete(customRendering.id);
      updated = true;
    }
    if (updated) {
      this.set(map);
    }
  }
}


/***/ }),

/***/ 61785:
/*!*******************************************************!*\
  !*** ./node_modules/@fullcalendar/core/locales/es.js ***!
  \*******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ l24)
/* harmony export */ });
var l24 = {
  code: 'es',
  week: {
    dow: 1,
    doy: 4 // The week that contains Jan 4th is the first week of the year.
  },
  buttonText: {
    prev: 'Ant',
    next: 'Sig',
    today: 'Hoy',
    year: 'Año',
    month: 'Mes',
    week: 'Semana',
    day: 'Día',
    list: 'Agenda'
  },
  buttonHints: {
    prev: '$0 antes',
    next: '$0 siguiente',
    today(buttonText) {
      return buttonText === 'Día' ? 'Hoy' : (buttonText === 'Semana' ? 'Esta' : 'Este') + ' ' + buttonText.toLocaleLowerCase();
    }
  },
  viewHint(buttonText) {
    return 'Vista ' + (buttonText === 'Semana' ? 'de la' : 'del') + ' ' + buttonText.toLocaleLowerCase();
  },
  weekText: 'Sm',
  weekTextLong: 'Semana',
  allDayText: 'Todo el día',
  moreLinkText: 'más',
  moreLinkHint(eventCnt) {
    return `Mostrar ${eventCnt} eventos más`;
  },
  noEventsText: 'No hay eventos para mostrar',
  navLinkHint: 'Ir al $0',
  closeHint: 'Cerrar',
  timeHint: 'La hora',
  eventHint: 'Evento'
};


/***/ }),

/***/ 75660:
/*!*****************************************************!*\
  !*** ./node_modules/@fullcalendar/daygrid/index.js ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ index)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/index.js */ 46633);
/* harmony import */ var _internal_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal.js */ 78107);




var index = (0,_fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_0__.createPlugin)({
  name: '@fullcalendar/daygrid',
  initialView: 'dayGridMonth',
  views: {
    dayGrid: {
      component: _internal_js__WEBPACK_IMPORTED_MODULE_1__.DayGridView,
      dateProfileGeneratorClass: _internal_js__WEBPACK_IMPORTED_MODULE_1__.TableDateProfileGenerator
    },
    dayGridDay: {
      type: 'dayGrid',
      duration: {
        days: 1
      }
    },
    dayGridWeek: {
      type: 'dayGrid',
      duration: {
        weeks: 1
      }
    },
    dayGridMonth: {
      type: 'dayGrid',
      duration: {
        months: 1
      },
      fixedWeekCount: true
    },
    dayGridYear: {
      type: 'dayGrid',
      duration: {
        years: 1
      }
    }
  }
});


/***/ }),

/***/ 78107:
/*!********************************************************!*\
  !*** ./node_modules/@fullcalendar/daygrid/internal.js ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   DayGridView: () => (/* binding */ DayTableView),
/* harmony export */   DayTable: () => (/* binding */ DayTable),
/* harmony export */   DayTableSlicer: () => (/* binding */ DayTableSlicer),
/* harmony export */   Table: () => (/* binding */ Table),
/* harmony export */   TableDateProfileGenerator: () => (/* binding */ TableDateProfileGenerator),
/* harmony export */   TableRows: () => (/* binding */ TableRows),
/* harmony export */   TableView: () => (/* binding */ TableView),
/* harmony export */   buildDayTableModel: () => (/* binding */ buildDayTableModel),
/* harmony export */   buildDayTableRenderRange: () => (/* binding */ buildDayTableRenderRange)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);
/* harmony import */ var _fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact.js */ 78048);



/* An abstract class for the daygrid views, as well as month view. Renders one or more rows of day cells.
----------------------------------------------------------------------------------------------------------------------*/
// It is a manager for a Table subcomponent, which does most of the heavy lifting.
// It is responsible for managing width/height.
class TableView extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.headerElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
  }
  renderSimpleLayout(headerRowContent, bodyContent) {
    let {
      props,
      context
    } = this;
    let sections = [];
    let stickyHeaderDates = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ca)(context.options);
    if (headerRowContent) {
      sections.push({
        type: 'header',
        key: 'header',
        isSticky: stickyHeaderDates,
        chunk: {
          elRef: this.headerElRef,
          tableClassName: 'fc-col-header',
          rowContent: headerRowContent
        }
      });
    }
    sections.push({
      type: 'body',
      key: 'body',
      liquid: true,
      chunk: {
        content: bodyContent
      }
    });
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elClasses: ['fc-daygrid'],
      viewSpec: context.viewSpec
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bZ, {
      liquid: !props.isHeightAuto && !props.forPrint,
      collapsibleWidth: props.forPrint,
      cols: [] /* TODO: make optional? */,
      sections: sections
    }));
  }
  renderHScrollLayout(headerRowContent, bodyContent, colCnt, dayMinWidth) {
    let ScrollGrid = this.context.pluginHooks.scrollGridImpl;
    if (!ScrollGrid) {
      throw new Error('No ScrollGrid implementation');
    }
    let {
      props,
      context
    } = this;
    let stickyHeaderDates = !props.forPrint && (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ca)(context.options);
    let stickyFooterScrollbar = !props.forPrint && (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.c9)(context.options);
    let sections = [];
    if (headerRowContent) {
      sections.push({
        type: 'header',
        key: 'header',
        isSticky: stickyHeaderDates,
        chunks: [{
          key: 'main',
          elRef: this.headerElRef,
          tableClassName: 'fc-col-header',
          rowContent: headerRowContent
        }]
      });
    }
    sections.push({
      type: 'body',
      key: 'body',
      liquid: true,
      chunks: [{
        key: 'main',
        content: bodyContent
      }]
    });
    if (stickyFooterScrollbar) {
      sections.push({
        type: 'footer',
        key: 'footer',
        isSticky: true,
        chunks: [{
          key: 'main',
          content: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.c8
        }]
      });
    }
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elClasses: ['fc-daygrid'],
      viewSpec: context.viewSpec
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(ScrollGrid, {
      liquid: !props.isHeightAuto && !props.forPrint,
      forPrint: props.forPrint,
      collapsibleWidth: props.forPrint,
      colGroups: [{
        cols: [{
          span: colCnt,
          minWidth: dayMinWidth
        }]
      }],
      sections: sections
    }));
  }
}
function splitSegsByRow(segs, rowCnt) {
  let byRow = [];
  for (let i = 0; i < rowCnt; i += 1) {
    byRow[i] = [];
  }
  for (let seg of segs) {
    byRow[seg.row].push(seg);
  }
  return byRow;
}
function splitSegsByFirstCol(segs, colCnt) {
  let byCol = [];
  for (let i = 0; i < colCnt; i += 1) {
    byCol[i] = [];
  }
  for (let seg of segs) {
    byCol[seg.firstCol].push(seg);
  }
  return byCol;
}
function splitInteractionByRow(ui, rowCnt) {
  let byRow = [];
  if (!ui) {
    for (let i = 0; i < rowCnt; i += 1) {
      byRow[i] = null;
    }
  } else {
    for (let i = 0; i < rowCnt; i += 1) {
      byRow[i] = {
        affectedInstances: ui.affectedInstances,
        isEvent: ui.isEvent,
        segs: []
      };
    }
    for (let seg of ui.segs) {
      byRow[seg.row].segs.push(seg);
    }
  }
  return byRow;
}
const DEFAULT_TABLE_EVENT_TIME_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  hour: 'numeric',
  minute: '2-digit',
  omitZeroMinute: true,
  meridiem: 'narrow'
});
function hasListItemDisplay(seg) {
  let {
    display
  } = seg.eventRange.ui;
  return display === 'list-item' || display === 'auto' && !seg.eventRange.def.allDay && seg.firstCol === seg.lastCol &&
  // can't be multi-day
  seg.isStart &&
  // "
  seg.isEnd // "
  ;
}
class TableBlockEvent extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      props
    } = this;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cg, Object.assign({}, props, {
      elClasses: ['fc-daygrid-event', 'fc-daygrid-block-event', 'fc-h-event'],
      defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT,
      defaultDisplayEventEnd: props.defaultDisplayEventEnd,
      disableResizing: !props.seg.eventRange.def.allDay
    }));
  }
}
class TableListItemEvent extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let {
      seg
    } = props;
    let timeFormat = options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT;
    let timeText = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bO)(seg, timeFormat, context, true, props.defaultDisplayEventEnd);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ck, Object.assign({}, props, {
      elTag: "a",
      elClasses: ['fc-daygrid-event', 'fc-daygrid-dot-event'],
      elAttrs: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bS)(props.seg, context),
      defaultGenerator: renderInnerContent,
      timeText: timeText,
      isResizing: false,
      isDateSelecting: false
    }));
  }
}
function renderInnerContent(renderProps) {
  return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
    className: "fc-daygrid-event-dot",
    style: {
      borderColor: renderProps.borderColor || renderProps.backgroundColor
    }
  }), renderProps.timeText && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
    className: "fc-event-time"
  }, renderProps.timeText), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
    className: "fc-event-title"
  }, renderProps.event.title || (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, "\u00A0")));
}
class TableCellMoreLink extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.compileSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(compileSegs);
  }
  render() {
    let {
      props
    } = this;
    let {
      allSegs,
      invisibleSegs
    } = this.compileSegs(props.singlePlacements);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.co, {
      elClasses: ['fc-daygrid-more-link'],
      dateProfile: props.dateProfile,
      todayRange: props.todayRange,
      allDayDate: props.allDayDate,
      moreCnt: props.moreCnt,
      allSegs: allSegs,
      hiddenSegs: invisibleSegs,
      alignmentElRef: props.alignmentElRef,
      alignGridTop: props.alignGridTop,
      extraDateSpan: props.extraDateSpan,
      popoverContent: () => {
        let isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || (props.eventResize ? props.eventResize.affectedInstances : null) || {};
        return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, allSegs.map(seg => {
          let instanceId = seg.eventRange.instance.instanceId;
          return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
            className: "fc-daygrid-event-harness",
            key: instanceId,
            style: {
              visibility: isForcedInvisible[instanceId] ? 'hidden' : ''
            }
          }, hasListItemDisplay(seg) ? (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableListItemEvent, Object.assign({
            seg: seg,
            isDragging: false,
            isSelected: instanceId === props.eventSelection,
            defaultDisplayEventEnd: false
          }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, props.todayRange))) : (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableBlockEvent, Object.assign({
            seg: seg,
            isDragging: false,
            isResizing: false,
            isDateSelecting: false,
            isSelected: instanceId === props.eventSelection,
            defaultDisplayEventEnd: false
          }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, props.todayRange))));
        }));
      }
    });
  }
}
function compileSegs(singlePlacements) {
  let allSegs = [];
  let invisibleSegs = [];
  for (let placement of singlePlacements) {
    allSegs.push(placement.seg);
    if (!placement.isVisible) {
      invisibleSegs.push(placement.seg);
    }
  }
  return {
    allSegs,
    invisibleSegs
  };
}
const DEFAULT_WEEK_NUM_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  week: 'narrow'
});
class TableCell extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.rootElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.state = {
      dayNumberId: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)()
    };
    this.handleRootEl = el => {
      (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.W)(this.rootElRef, el);
      (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.W)(this.props.elRef, el);
    };
  }
  render() {
    let {
      context,
      props,
      state,
      rootElRef
    } = this;
    let {
      options,
      dateEnv
    } = context;
    let {
      date,
      dateProfile
    } = props;
    // TODO: memoize this?
    const isMonthStart = props.showDayNumber && shouldDisplayMonthStart(date, dateProfile.currentRange, dateEnv);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ci, {
      elTag: "td",
      elRef: this.handleRootEl,
      elClasses: ['fc-daygrid-day', ...(props.extraClassNames || [])],
      elAttrs: Object.assign(Object.assign(Object.assign({}, props.extraDataAttrs), props.showDayNumber ? {
        'aria-labelledby': state.dayNumberId
      } : {}), {
        role: 'gridcell'
      }),
      defaultGenerator: renderTopInner,
      date: date,
      dateProfile: dateProfile,
      todayRange: props.todayRange,
      showDayNumber: props.showDayNumber,
      isMonthStart: isMonthStart,
      extraRenderProps: props.extraRenderProps
    }, (InnerContent, renderProps) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      ref: props.innerElRef,
      className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner",
      style: {
        minHeight: props.minHeight
      }
    }, props.showWeekNumber && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cn, {
      elTag: "a",
      elClasses: ['fc-daygrid-week-number'],
      elAttrs: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a_)(context, date, 'week'),
      date: date,
      defaultFormat: DEFAULT_WEEK_NUM_FORMAT
    }), !renderProps.isDisabled && (props.showDayNumber || (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cj)(options) || props.forceDayTop) ? (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-daygrid-day-top"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "a",
      elClasses: ['fc-daygrid-day-number', isMonthStart && 'fc-daygrid-month-start'],
      elAttrs: Object.assign(Object.assign({}, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a_)(context, date)), {
        id: state.dayNumberId
      })
    })) : props.showDayNumber ?
    // for creating correct amount of space (see issue #7162)
    (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-daygrid-day-top",
      style: {
        visibility: 'hidden'
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("a", {
      className: "fc-daygrid-day-number"
    }, "\u00A0")) : undefined, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-daygrid-day-events",
      ref: props.fgContentElRef
    }, props.fgContent, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-daygrid-day-bottom",
      style: {
        marginTop: props.moreMarginTop
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableCellMoreLink, {
      allDayDate: date,
      singlePlacements: props.singlePlacements,
      moreCnt: props.moreCnt,
      alignmentElRef: rootElRef,
      alignGridTop: !props.showDayNumber,
      extraDateSpan: props.extraDateSpan,
      dateProfile: props.dateProfile,
      eventSelection: props.eventSelection,
      eventDrag: props.eventDrag,
      eventResize: props.eventResize,
      todayRange: props.todayRange
    }))), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-daygrid-day-bg"
    }, props.bgContent)));
  }
}
function renderTopInner(props) {
  return props.dayNumberText || (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, "\u00A0");
}
function shouldDisplayMonthStart(date, currentRange, dateEnv) {
  const {
    start: currentStart,
    end: currentEnd
  } = currentRange;
  const currentEndIncl = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.be)(currentEnd, -1);
  const currentFirstYear = dateEnv.getYear(currentStart);
  const currentFirstMonth = dateEnv.getMonth(currentStart);
  const currentLastYear = dateEnv.getYear(currentEndIncl);
  const currentLastMonth = dateEnv.getMonth(currentEndIncl);
  // spans more than one month?
  return !(currentFirstYear === currentLastYear && currentFirstMonth === currentLastMonth) && Boolean(
  // first date in current view?
  date.valueOf() === currentStart.valueOf() ||
  // a month-start that's within the current range?
  dateEnv.getDay(date) === 1 && date.valueOf() < currentEnd.valueOf());
}
function generateSegKey(seg) {
  return seg.eventRange.instance.instanceId + ':' + seg.firstCol;
}
function generateSegUid(seg) {
  return generateSegKey(seg) + ':' + seg.lastCol;
}
function computeFgSegPlacement(segs,
// assumed already sorted
dayMaxEvents, dayMaxEventRows, strictOrder, segHeights, maxContentHeight, cells) {
  let hierarchy = new DayGridSegHierarchy(segEntry => {
    // TODO: more DRY with generateSegUid
    let segUid = segs[segEntry.index].eventRange.instance.instanceId + ':' + segEntry.span.start + ':' + (segEntry.span.end - 1);
    // if no thickness known, assume 1 (if 0, so small it always fits)
    return segHeights[segUid] || 1;
  });
  hierarchy.allowReslicing = true;
  hierarchy.strictOrder = strictOrder;
  if (dayMaxEvents === true || dayMaxEventRows === true) {
    hierarchy.maxCoord = maxContentHeight;
    hierarchy.hiddenConsumes = true;
  } else if (typeof dayMaxEvents === 'number') {
    hierarchy.maxStackCnt = dayMaxEvents;
  } else if (typeof dayMaxEventRows === 'number') {
    hierarchy.maxStackCnt = dayMaxEventRows;
    hierarchy.hiddenConsumes = true;
  }
  // create segInputs only for segs with known heights
  let segInputs = [];
  let unknownHeightSegs = [];
  for (let i = 0; i < segs.length; i += 1) {
    let seg = segs[i];
    let segUid = generateSegUid(seg);
    let eventHeight = segHeights[segUid];
    if (eventHeight != null) {
      segInputs.push({
        index: i,
        span: {
          start: seg.firstCol,
          end: seg.lastCol + 1
        }
      });
    } else {
      unknownHeightSegs.push(seg);
    }
  }
  let hiddenEntries = hierarchy.addSegs(segInputs);
  let segRects = hierarchy.toRects();
  let {
    singleColPlacements,
    multiColPlacements,
    leftoverMargins
  } = placeRects(segRects, segs, cells);
  let moreCnts = [];
  let moreMarginTops = [];
  // add segs with unknown heights
  for (let seg of unknownHeightSegs) {
    multiColPlacements[seg.firstCol].push({
      seg,
      isVisible: false,
      isAbsolute: true,
      absoluteTop: 0,
      marginTop: 0
    });
    for (let col = seg.firstCol; col <= seg.lastCol; col += 1) {
      singleColPlacements[col].push({
        seg: resliceSeg(seg, col, col + 1, cells),
        isVisible: false,
        isAbsolute: false,
        absoluteTop: 0,
        marginTop: 0
      });
    }
  }
  // add the hidden entries
  for (let col = 0; col < cells.length; col += 1) {
    moreCnts.push(0);
  }
  for (let hiddenEntry of hiddenEntries) {
    let seg = segs[hiddenEntry.index];
    let hiddenSpan = hiddenEntry.span;
    multiColPlacements[hiddenSpan.start].push({
      seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells),
      isVisible: false,
      isAbsolute: true,
      absoluteTop: 0,
      marginTop: 0
    });
    for (let col = hiddenSpan.start; col < hiddenSpan.end; col += 1) {
      moreCnts[col] += 1;
      singleColPlacements[col].push({
        seg: resliceSeg(seg, col, col + 1, cells),
        isVisible: false,
        isAbsolute: false,
        absoluteTop: 0,
        marginTop: 0
      });
    }
  }
  // deal with leftover margins
  for (let col = 0; col < cells.length; col += 1) {
    moreMarginTops.push(leftoverMargins[col]);
  }
  return {
    singleColPlacements,
    multiColPlacements,
    moreCnts,
    moreMarginTops
  };
}
// rects ordered by top coord, then left
function placeRects(allRects, segs, cells) {
  let rectsByEachCol = groupRectsByEachCol(allRects, cells.length);
  let singleColPlacements = [];
  let multiColPlacements = [];
  let leftoverMargins = [];
  for (let col = 0; col < cells.length; col += 1) {
    let rects = rectsByEachCol[col];
    // compute all static segs in singlePlacements
    let singlePlacements = [];
    let currentHeight = 0;
    let currentMarginTop = 0;
    for (let rect of rects) {
      let seg = segs[rect.index];
      singlePlacements.push({
        seg: resliceSeg(seg, col, col + 1, cells),
        isVisible: true,
        isAbsolute: false,
        absoluteTop: rect.levelCoord,
        marginTop: rect.levelCoord - currentHeight
      });
      currentHeight = rect.levelCoord + rect.thickness;
    }
    // compute mixed static/absolute segs in multiPlacements
    let multiPlacements = [];
    currentHeight = 0;
    currentMarginTop = 0;
    for (let rect of rects) {
      let seg = segs[rect.index];
      let isAbsolute = rect.span.end - rect.span.start > 1; // multi-column?
      let isFirstCol = rect.span.start === col;
      currentMarginTop += rect.levelCoord - currentHeight; // amount of space since bottom of previous seg
      currentHeight = rect.levelCoord + rect.thickness; // height will now be bottom of current seg
      if (isAbsolute) {
        currentMarginTop += rect.thickness;
        if (isFirstCol) {
          multiPlacements.push({
            seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
            isVisible: true,
            isAbsolute: true,
            absoluteTop: rect.levelCoord,
            marginTop: 0
          });
        }
      } else if (isFirstCol) {
        multiPlacements.push({
          seg: resliceSeg(seg, rect.span.start, rect.span.end, cells),
          isVisible: true,
          isAbsolute: false,
          absoluteTop: rect.levelCoord,
          marginTop: currentMarginTop // claim the margin
        });
        currentMarginTop = 0;
      }
    }
    singleColPlacements.push(singlePlacements);
    multiColPlacements.push(multiPlacements);
    leftoverMargins.push(currentMarginTop);
  }
  return {
    singleColPlacements,
    multiColPlacements,
    leftoverMargins
  };
}
function groupRectsByEachCol(rects, colCnt) {
  let rectsByEachCol = [];
  for (let col = 0; col < colCnt; col += 1) {
    rectsByEachCol.push([]);
  }
  for (let rect of rects) {
    for (let col = rect.span.start; col < rect.span.end; col += 1) {
      rectsByEachCol[col].push(rect);
    }
  }
  return rectsByEachCol;
}
function resliceSeg(seg, spanStart, spanEnd, cells) {
  if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) {
    return seg;
  }
  let eventRange = seg.eventRange;
  let origRange = eventRange.range;
  let slicedRange = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.o)(origRange, {
    start: cells[spanStart].date,
    end: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.t)(cells[spanEnd - 1].date, 1)
  });
  return Object.assign(Object.assign({}, seg), {
    firstCol: spanStart,
    lastCol: spanEnd - 1,
    eventRange: {
      def: eventRange.def,
      ui: Object.assign(Object.assign({}, eventRange.ui), {
        durationEditable: false
      }),
      instance: eventRange.instance,
      range: slicedRange
    },
    isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(),
    isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf()
  });
}
class DayGridSegHierarchy extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.by {
  constructor() {
    super(...arguments);
    // config
    this.hiddenConsumes = false;
    // allows us to keep hidden entries in the hierarchy so they take up space
    this.forceHidden = {};
  }
  addSegs(segInputs) {
    const hiddenSegs = super.addSegs(segInputs);
    const {
      entriesByLevel
    } = this;
    const excludeHidden = entry => !this.forceHidden[(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bz)(entry)];
    // remove the forced-hidden segs
    for (let level = 0; level < entriesByLevel.length; level += 1) {
      entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden);
    }
    return hiddenSegs;
  }
  handleInvalidInsertion(insertion, entry, hiddenEntries) {
    const {
      entriesByLevel,
      forceHidden
    } = this;
    const {
      touchingEntry,
      touchingLevel,
      touchingLateral
    } = insertion;
    // the entry that the new insertion is touching must be hidden
    if (this.hiddenConsumes && touchingEntry) {
      const touchingEntryId = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bz)(touchingEntry);
      if (!forceHidden[touchingEntryId]) {
        if (this.allowReslicing) {
          // split up the touchingEntry, reinsert it
          const hiddenEntry = Object.assign(Object.assign({}, touchingEntry), {
            span: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bD)(touchingEntry.span, entry.span)
          });
          // reinsert the area that turned into a "more" link (so no other entries try to
          // occupy the space) but mark it forced-hidden
          const hiddenEntryId = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bz)(hiddenEntry);
          forceHidden[hiddenEntryId] = true;
          entriesByLevel[touchingLevel][touchingLateral] = hiddenEntry;
          hiddenEntries.push(hiddenEntry);
          this.splitEntry(touchingEntry, entry, hiddenEntries);
        } else {
          forceHidden[touchingEntryId] = true;
          hiddenEntries.push(touchingEntry);
        }
      }
    }
    // will try to reslice...
    super.handleInvalidInsertion(insertion, entry, hiddenEntries);
  }
}
class TableRow extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.cellElRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd(); // the <td>
    this.frameElRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd(); // the fc-daygrid-day-frame
    this.fgElRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd(); // the fc-daygrid-day-events
    this.segHarnessRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd(); // indexed by "instanceId:firstCol"
    this.rootElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.state = {
      framePositions: null,
      maxContentHeight: null,
      segHeights: {}
    };
    this.handleResize = isForced => {
      if (isForced) {
        this.updateSizing(true); // isExternal=true
      }
    };
  }
  render() {
    let {
      props,
      state,
      context
    } = this;
    let {
      options
    } = context;
    let colCnt = props.cells.length;
    let businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt);
    let bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt);
    let highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt);
    let mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt);
    let {
      singleColPlacements,
      multiColPlacements,
      moreCnts,
      moreMarginTops
    } = computeFgSegPlacement((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bP)(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.segHeights, state.maxContentHeight, props.cells);
    let isForcedInvisible =
    // TODO: messy way to compute this
    props.eventDrag && props.eventDrag.affectedInstances || props.eventResize && props.eventResize.affectedInstances || {};
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
      ref: this.rootElRef,
      role: "row"
    }, props.renderIntro && props.renderIntro(), props.cells.map((cell, col) => {
      let normalFgNodes = this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible);
      let mirrorFgNodes = this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false);
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableCell, {
        key: cell.key,
        elRef: this.cellElRefs.createRef(cell.key),
        innerElRef: this.frameElRefs.createRef(cell.key) /* FF <td> problem, but okay to use for left/right. TODO: rename prop */,
        dateProfile: props.dateProfile,
        date: cell.date,
        showDayNumber: props.showDayNumbers,
        showWeekNumber: props.showWeekNumbers && col === 0,
        forceDayTop: props.showWeekNumbers /* even displaying weeknum for row, not necessarily day */,
        todayRange: props.todayRange,
        eventSelection: props.eventSelection,
        eventDrag: props.eventDrag,
        eventResize: props.eventResize,
        extraRenderProps: cell.extraRenderProps,
        extraDataAttrs: cell.extraDataAttrs,
        extraClassNames: cell.extraClassNames,
        extraDateSpan: cell.extraDateSpan,
        moreCnt: moreCnts[col],
        moreMarginTop: moreMarginTops[col],
        singlePlacements: singleColPlacements[col],
        fgContentElRef: this.fgElRefs.createRef(cell.key),
        fgContent:
        // Fragment scopes the keys
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, normalFgNodes), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, mirrorFgNodes)),
        bgContent:
        // Fragment scopes the keys
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, this.renderFillSegs(highlightSegsByCol[col], 'highlight'), this.renderFillSegs(businessHoursByCol[col], 'non-business'), this.renderFillSegs(bgEventSegsByCol[col], 'bg-event')),
        minHeight: props.cellMinHeight
      });
    }));
  }
  componentDidMount() {
    this.updateSizing(true);
    this.context.addResizeHandler(this.handleResize);
  }
  componentDidUpdate(prevProps, prevState) {
    let currentProps = this.props;
    this.updateSizing(!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.E)(prevProps, currentProps));
  }
  componentWillUnmount() {
    this.context.removeResizeHandler(this.handleResize);
  }
  getHighlightSegs() {
    let {
      props
    } = this;
    if (props.eventDrag && props.eventDrag.segs.length) {
      // messy check
      return props.eventDrag.segs;
    }
    if (props.eventResize && props.eventResize.segs.length) {
      // messy check
      return props.eventResize.segs;
    }
    return props.dateSelectionSegs;
  }
  getMirrorSegs() {
    let {
      props
    } = this;
    if (props.eventResize && props.eventResize.segs.length) {
      // messy check
      return props.eventResize.segs;
    }
    return [];
  }
  renderFgSegs(col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) {
    let {
      context
    } = this;
    let {
      eventSelection
    } = this.props;
    let {
      framePositions
    } = this.state;
    let defaultDisplayEventEnd = this.props.cells.length === 1; // colCnt === 1
    let isMirror = isDragging || isResizing || isDateSelecting;
    let nodes = [];
    if (framePositions) {
      for (let placement of segPlacements) {
        let {
          seg
        } = placement;
        let {
          instanceId
        } = seg.eventRange.instance;
        let isVisible = placement.isVisible && !isForcedInvisible[instanceId];
        let isAbsolute = placement.isAbsolute;
        let left = '';
        let right = '';
        if (isAbsolute) {
          if (context.isRtl) {
            right = 0;
            left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol];
          } else {
            left = 0;
            right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol];
          }
        }
        /*
        known bug: events that are force to be list-item but span multiple days still take up space in later columns
        todo: in print view, for multi-day events, don't display title within non-start/end segs
        */
        nodes.push((0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          className: 'fc-daygrid-event-harness' + (isAbsolute ? ' fc-daygrid-event-harness-abs' : ''),
          key: generateSegKey(seg),
          ref: isMirror ? null : this.segHarnessRefs.createRef(generateSegUid(seg)),
          style: {
            visibility: isVisible ? '' : 'hidden',
            marginTop: isAbsolute ? '' : placement.marginTop,
            top: isAbsolute ? placement.absoluteTop : '',
            left,
            right
          }
        }, hasListItemDisplay(seg) ? (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableListItemEvent, Object.assign({
          seg: seg,
          isDragging: isDragging,
          isSelected: instanceId === eventSelection,
          defaultDisplayEventEnd: defaultDisplayEventEnd
        }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange))) : (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableBlockEvent, Object.assign({
          seg: seg,
          isDragging: isDragging,
          isResizing: isResizing,
          isDateSelecting: isDateSelecting,
          isSelected: instanceId === eventSelection,
          defaultDisplayEventEnd: defaultDisplayEventEnd
        }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange)))));
      }
    }
    return nodes;
  }
  renderFillSegs(segs, fillType) {
    let {
      isRtl
    } = this.context;
    let {
      todayRange
    } = this.props;
    let {
      framePositions
    } = this.state;
    let nodes = [];
    if (framePositions) {
      for (let seg of segs) {
        let leftRightCss = isRtl ? {
          right: 0,
          left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]
        } : {
          left: 0,
          right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]
        };
        nodes.push((0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          key: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bR)(seg.eventRange),
          className: "fc-daygrid-bg-harness",
          style: leftRightCss
        }, fillType === 'bg-event' ? (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cm, Object.assign({
          seg: seg
        }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange))) : (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cl)(fillType)));
      }
    }
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, {}, ...nodes);
  }
  updateSizing(isExternalSizingChange) {
    let {
      props,
      state,
      frameElRefs
    } = this;
    if (!props.forPrint && props.clientWidth !== null // positioning ready?
    ) {
      if (isExternalSizingChange) {
        let frameEls = props.cells.map(cell => frameElRefs.currentMap[cell.key]);
        if (frameEls.length) {
          let originEl = this.rootElRef.current;
          let newPositionCache = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(originEl, frameEls, true,
          // isHorizontal
          false);
          if (!state.framePositions || !state.framePositions.similarTo(newPositionCache)) {
            this.setState({
              framePositions: new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(originEl, frameEls, true,
              // isHorizontal
              false)
            });
          }
        }
      }
      const oldSegHeights = this.state.segHeights;
      const newSegHeights = this.querySegHeights();
      const limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true;
      this.safeSetState({
        // HACK to prevent oscillations of events being shown/hidden from max-event-rows
        // Essentially, once you compute an element's height, never null-out.
        // TODO: always display all events, as visibility:hidden?
        segHeights: Object.assign(Object.assign({}, oldSegHeights), newSegHeights),
        maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null
      });
    }
  }
  querySegHeights() {
    let segElMap = this.segHarnessRefs.currentMap;
    let segHeights = {};
    // get the max height amongst instance segs
    for (let segUid in segElMap) {
      let height = Math.round(segElMap[segUid].getBoundingClientRect().height);
      segHeights[segUid] = Math.max(segHeights[segUid] || 0, height);
    }
    return segHeights;
  }
  computeMaxContentHeight() {
    let firstKey = this.props.cells[0].key;
    let cellEl = this.cellElRefs.currentMap[firstKey];
    let fcContainerEl = this.fgElRefs.currentMap[firstKey];
    return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top;
  }
  getCellEls() {
    let elMap = this.cellElRefs.currentMap;
    return this.props.cells.map(cell => elMap[cell.key]);
  }
}
TableRow.addStateEquality({
  segHeights: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.E
});
function buildMirrorPlacements(mirrorSegs, colPlacements) {
  if (!mirrorSegs.length) {
    return [];
  }
  let topsByInstanceId = buildAbsoluteTopHash(colPlacements); // TODO: cache this at first render?
  return mirrorSegs.map(seg => ({
    seg,
    isVisible: true,
    isAbsolute: true,
    absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId],
    marginTop: 0
  }));
}
function buildAbsoluteTopHash(colPlacements) {
  let topsByInstanceId = {};
  for (let placements of colPlacements) {
    for (let placement of placements) {
      topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop;
    }
  }
  return topsByInstanceId;
}
class TableRows extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.splitBusinessHourSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);
    this.splitBgEventSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitAllDaySegsByRow);
    this.splitFgEventSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);
    this.splitDateSelectionSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByRow);
    this.splitEventDrag = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByRow);
    this.splitEventResize = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByRow);
    this.rowRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd();
  }
  render() {
    let {
      props,
      context
    } = this;
    let rowCnt = props.cells.length;
    let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt);
    let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt);
    let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt);
    let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt);
    let eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt);
    let eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
    // for DayGrid view with many rows, force a min-height on cells so doesn't appear squished
    // choose 7 because a month view will have max 6 rows
    let cellMinHeight = rowCnt >= 7 && props.clientWidth ? props.clientWidth / context.options.aspectRatio / 6 : null;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a6, {
      unit: "day"
    }, (nowDate, todayRange) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, props.cells.map((cells, row) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableRow, {
      ref: this.rowRefs.createRef(row),
      key: cells.length ? cells[0].date.toISOString() /* best? or put key on cell? or use diff formatter? */ : row // in case there are no cells (like when resource view is loading)
      ,
      showDayNumbers: rowCnt > 1,
      showWeekNumbers: props.showWeekNumbers,
      todayRange: todayRange,
      dateProfile: props.dateProfile,
      cells: cells,
      renderIntro: props.renderRowIntro,
      businessHourSegs: businessHourSegsByRow[row],
      eventSelection: props.eventSelection,
      bgEventSegs: bgEventSegsByRow[row],
      fgEventSegs: fgEventSegsByRow[row],
      dateSelectionSegs: dateSelectionSegsByRow[row],
      eventDrag: eventDragByRow[row],
      eventResize: eventResizeByRow[row],
      dayMaxEvents: props.dayMaxEvents,
      dayMaxEventRows: props.dayMaxEventRows,
      clientWidth: props.clientWidth,
      clientHeight: props.clientHeight,
      cellMinHeight: cellMinHeight,
      forPrint: props.forPrint
    }))));
  }
  componentDidMount() {
    this.registerInteractiveComponent();
  }
  componentDidUpdate() {
    // for if started with zero cells
    this.registerInteractiveComponent();
  }
  registerInteractiveComponent() {
    if (!this.rootEl) {
      // HACK: need a daygrid wrapper parent to do positioning
      // NOTE: a daygrid resource view w/o resources can have zero cells
      const firstCellEl = this.rowRefs.currentMap[0].getCellEls()[0];
      const rootEl = firstCellEl ? firstCellEl.closest('.fc-daygrid-body') : null;
      if (rootEl) {
        this.rootEl = rootEl;
        this.context.registerInteractiveComponent(this, {
          el: rootEl,
          isHitComboAllowed: this.props.isHitComboAllowed
        });
      }
    }
  }
  componentWillUnmount() {
    if (this.rootEl) {
      this.context.unregisterInteractiveComponent(this);
      this.rootEl = null;
    }
  }
  // Hit System
  // ----------------------------------------------------------------------------------------------------
  prepareHits() {
    this.rowPositions = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(this.rootEl, this.rowRefs.collect().map(rowObj => rowObj.getCellEls()[0]),
    // first cell el in each row. TODO: not optimal
    false, true);
    this.colPositions = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(this.rootEl, this.rowRefs.currentMap[0].getCellEls(),
    // cell els in first row
    true,
    // horizontal
    false);
  }
  queryHit(positionLeft, positionTop) {
    let {
      colPositions,
      rowPositions
    } = this;
    let col = colPositions.leftToIndex(positionLeft);
    let row = rowPositions.topToIndex(positionTop);
    if (row != null && col != null) {
      let cell = this.props.cells[row][col];
      return {
        dateProfile: this.props.dateProfile,
        dateSpan: Object.assign({
          range: this.getCellRange(row, col),
          allDay: true
        }, cell.extraDateSpan),
        dayEl: this.getCellEl(row, col),
        rect: {
          left: colPositions.lefts[col],
          right: colPositions.rights[col],
          top: rowPositions.tops[row],
          bottom: rowPositions.bottoms[row]
        },
        layer: 0
      };
    }
    return null;
  }
  getCellEl(row, col) {
    return this.rowRefs.currentMap[row].getCellEls()[col]; // TODO: not optimal
  }
  getCellRange(row, col) {
    let start = this.props.cells[row][col].date;
    let end = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.t)(start, 1);
    return {
      start,
      end
    };
  }
}
function splitAllDaySegsByRow(segs, rowCnt) {
  return splitSegsByRow(segs.filter(isSegAllDay), rowCnt);
}
function isSegAllDay(seg) {
  return seg.eventRange.def.allDay;
}
class Table extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.elRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.needsScrollReset = false;
  }
  render() {
    let {
      props
    } = this;
    let {
      dayMaxEventRows,
      dayMaxEvents,
      expandRows
    } = props;
    let limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true;
    // if rows can't expand to fill fixed height, can't do balanced-height event limit
    // TODO: best place to normalize these options?
    if (limitViaBalanced && !expandRows) {
      limitViaBalanced = false;
      dayMaxEventRows = null;
      dayMaxEvents = null;
    }
    let classNames = ['fc-daygrid-body', limitViaBalanced ? 'fc-daygrid-body-balanced' : 'fc-daygrid-body-unbalanced', expandRows ? '' : 'fc-daygrid-body-natural' // will height of one row depend on the others?
    ];
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      ref: this.elRef,
      className: classNames.join(' '),
      style: {
        // these props are important to give this wrapper correct dimensions for interactions
        // TODO: if we set it here, can we avoid giving to inner tables?
        width: props.clientWidth,
        minWidth: props.tableMinWidth
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("table", {
      role: "presentation",
      className: "fc-scrollgrid-sync-table",
      style: {
        width: props.clientWidth,
        minWidth: props.tableMinWidth,
        height: expandRows ? props.clientHeight : ''
      }
    }, props.colGroupNode, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tbody", {
      role: "presentation"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TableRows, {
      dateProfile: props.dateProfile,
      cells: props.cells,
      renderRowIntro: props.renderRowIntro,
      showWeekNumbers: props.showWeekNumbers,
      clientWidth: props.clientWidth,
      clientHeight: props.clientHeight,
      businessHourSegs: props.businessHourSegs,
      bgEventSegs: props.bgEventSegs,
      fgEventSegs: props.fgEventSegs,
      dateSelectionSegs: props.dateSelectionSegs,
      eventSelection: props.eventSelection,
      eventDrag: props.eventDrag,
      eventResize: props.eventResize,
      dayMaxEvents: dayMaxEvents,
      dayMaxEventRows: dayMaxEventRows,
      forPrint: props.forPrint,
      isHitComboAllowed: props.isHitComboAllowed
    }))));
  }
  componentDidMount() {
    this.requestScrollReset();
  }
  componentDidUpdate(prevProps) {
    if (prevProps.dateProfile !== this.props.dateProfile) {
      this.requestScrollReset();
    } else {
      this.flushScrollReset();
    }
  }
  requestScrollReset() {
    this.needsScrollReset = true;
    this.flushScrollReset();
  }
  flushScrollReset() {
    if (this.needsScrollReset && this.props.clientWidth // sizes computed?
    ) {
      const subjectEl = getScrollSubjectEl(this.elRef.current, this.props.dateProfile);
      if (subjectEl) {
        const originEl = subjectEl.closest('.fc-daygrid-body');
        const scrollEl = originEl.closest('.fc-scroller');
        const scrollTop = subjectEl.getBoundingClientRect().top - originEl.getBoundingClientRect().top;
        scrollEl.scrollTop = scrollTop ? scrollTop + 1 : 0; // overcome border
      }
      this.needsScrollReset = false;
    }
  }
}
function getScrollSubjectEl(containerEl, dateProfile) {
  let el;
  if (dateProfile.currentRangeUnit.match(/year|month/)) {
    el = containerEl.querySelector(`[data-date="${(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bv)(dateProfile.currentDate)}-01"]`);
    // even if view is month-based, first-of-month might be hidden...
  }
  if (!el) {
    el = containerEl.querySelector(`[data-date="${(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bt)(dateProfile.currentDate)}"]`);
    // could still be hidden if an interior-view hidden day
  }
  return el;
}
class DayTableSlicer extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bU {
  constructor() {
    super(...arguments);
    this.forceDayIfListItem = true;
  }
  sliceRange(dateRange, dayTableModel) {
    return dayTableModel.sliceRange(dateRange);
  }
}
class DayTable extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.slicer = new DayTableSlicer();
    this.tableRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
  }
  render() {
    let {
      props,
      context
    } = this;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(Table, Object.assign({
      ref: this.tableRef
    }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), {
      dateProfile: props.dateProfile,
      cells: props.dayTableModel.cells,
      colGroupNode: props.colGroupNode,
      tableMinWidth: props.tableMinWidth,
      renderRowIntro: props.renderRowIntro,
      dayMaxEvents: props.dayMaxEvents,
      dayMaxEventRows: props.dayMaxEventRows,
      showWeekNumbers: props.showWeekNumbers,
      expandRows: props.expandRows,
      headerAlignElRef: props.headerAlignElRef,
      clientWidth: props.clientWidth,
      clientHeight: props.clientHeight,
      forPrint: props.forPrint
    }));
  }
}
class DayTableView extends TableView {
  constructor() {
    super(...arguments);
    this.buildDayTableModel = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDayTableModel);
    this.headerRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.tableRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    // can't override any lifecycle methods from parent
  }
  render() {
    let {
      options,
      dateProfileGenerator
    } = this.context;
    let {
      props
    } = this;
    let dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator);
    let headerContent = options.dayHeaders && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bI, {
      ref: this.headerRef,
      dateProfile: props.dateProfile,
      dates: dayTableModel.headerDates,
      datesRepDistinctDays: dayTableModel.rowCnt === 1
    });
    let bodyContent = contentArg => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(DayTable, {
      ref: this.tableRef,
      dateProfile: props.dateProfile,
      dayTableModel: dayTableModel,
      businessHours: props.businessHours,
      dateSelection: props.dateSelection,
      eventStore: props.eventStore,
      eventUiBases: props.eventUiBases,
      eventSelection: props.eventSelection,
      eventDrag: props.eventDrag,
      eventResize: props.eventResize,
      nextDayThreshold: options.nextDayThreshold,
      colGroupNode: contentArg.tableColGroupNode,
      tableMinWidth: contentArg.tableMinWidth,
      dayMaxEvents: options.dayMaxEvents,
      dayMaxEventRows: options.dayMaxEventRows,
      showWeekNumbers: options.weekNumbers,
      expandRows: !props.isHeightAuto,
      headerAlignElRef: this.headerElRef,
      clientWidth: contentArg.clientWidth,
      clientHeight: contentArg.clientHeight,
      forPrint: props.forPrint
    });
    return options.dayMinWidth ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) : this.renderSimpleLayout(headerContent, bodyContent);
  }
}
function buildDayTableModel(dateProfile, dateProfileGenerator) {
  let daySeries = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bM(dateProfile.renderRange, dateProfileGenerator);
  return new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bT(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit));
}
class TableDateProfileGenerator extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.R {
  // Computes the date range that will be rendered
  buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) {
    let renderRange = super.buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay);
    let {
      props
    } = this;
    return buildDayTableRenderRange({
      currentRange: renderRange,
      snapToWeek: /^(year|month)$/.test(currentRangeUnit),
      fixedWeekCount: props.fixedWeekCount,
      dateEnv: props.dateEnv
    });
  }
}
function buildDayTableRenderRange(props) {
  let {
    dateEnv,
    currentRange
  } = props;
  let {
    start,
    end
  } = currentRange;
  let endOfWeek;
  // year and month views should be aligned with weeks. this is already done for week
  if (props.snapToWeek) {
    start = dateEnv.startOfWeek(start);
    // make end-of-week if not already
    endOfWeek = dateEnv.startOfWeek(end);
    if (endOfWeek.valueOf() !== end.valueOf()) {
      end = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bf)(endOfWeek, 1);
    }
  }
  // ensure 6 weeks
  if (props.fixedWeekCount) {
    // TODO: instead of these date-math gymnastics (for multimonth view),
    // compute dateprofiles of all months, then use start of first and end of last.
    let lastMonthRenderStart = dateEnv.startOfWeek(dateEnv.startOfMonth((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.t)(currentRange.end, -1)));
    let rowCnt = Math.ceil(
    // could be partial weeks due to hiddenDays
    (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bg)(lastMonthRenderStart, end));
    end = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bf)(end, 6 - rowCnt);
  }
  return {
    start,
    end
  };
}
var css_248z = ":root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:\"\";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;margin:0 2px}.fc .fc-daygrid-day-bottom:after,.fc .fc-daygrid-day-bottom:before{clear:both;content:\"\";display:table}.fc .fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc .fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc .fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-more-link{float:left}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-more-link{float:right}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}";
(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ct)(css_248z);


/***/ }),

/***/ 19426:
/*!*********************************************************!*\
  !*** ./node_modules/@fullcalendar/interaction/index.js ***!
  \*********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Draggable: () => (/* binding */ ExternalDraggable),
/* harmony export */   ThirdPartyDraggable: () => (/* binding */ ThirdPartyDraggable),
/* harmony export */   "default": () => (/* binding */ index)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/index.js */ 46633);
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);


_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bG.touchMouseIgnoreWait = 500;
let ignoreMouseDepth = 0;
let listenerCnt = 0;
let isWindowTouchMoveCancelled = false;
/*
Uses a "pointer" abstraction, which monitors UI events for both mouse and touch.
Tracks when the pointer "drags" on a certain element, meaning down+move+up.

Also, tracks if there was touch-scrolling.
Also, can prevent touch-scrolling from happening.
Also, can fire pointermove events when scrolling happens underneath, even when no real pointer movement.

emits:
- pointerdown
- pointermove
- pointerup
*/
class PointerDragging {
  constructor(containerEl) {
    this.subjectEl = null;
    // options that can be directly assigned by caller
    this.selector = ''; // will cause subjectEl in all emitted events to be this element
    this.handleSelector = '';
    this.shouldIgnoreMove = false;
    this.shouldWatchScroll = true; // for simulating pointermove on scroll
    // internal states
    this.isDragging = false;
    this.isTouchDragging = false;
    this.wasTouchScroll = false;
    // Mouse
    // ----------------------------------------------------------------------------------------------------
    this.handleMouseDown = ev => {
      if (!this.shouldIgnoreMouse() && isPrimaryMouseButton(ev) && this.tryStart(ev)) {
        let pev = this.createEventFromMouse(ev, true);
        this.emitter.trigger('pointerdown', pev);
        this.initScrollWatch(pev);
        if (!this.shouldIgnoreMove) {
          document.addEventListener('mousemove', this.handleMouseMove);
        }
        document.addEventListener('mouseup', this.handleMouseUp);
      }
    };
    this.handleMouseMove = ev => {
      let pev = this.createEventFromMouse(ev);
      this.recordCoords(pev);
      this.emitter.trigger('pointermove', pev);
    };
    this.handleMouseUp = ev => {
      document.removeEventListener('mousemove', this.handleMouseMove);
      document.removeEventListener('mouseup', this.handleMouseUp);
      this.emitter.trigger('pointerup', this.createEventFromMouse(ev));
      this.cleanup(); // call last so that pointerup has access to props
    };
    // Touch
    // ----------------------------------------------------------------------------------------------------
    this.handleTouchStart = ev => {
      if (this.tryStart(ev)) {
        this.isTouchDragging = true;
        let pev = this.createEventFromTouch(ev, true);
        this.emitter.trigger('pointerdown', pev);
        this.initScrollWatch(pev);
        // unlike mouse, need to attach to target, not document
        // https://stackoverflow.com/a/45760014
        let targetEl = ev.target;
        if (!this.shouldIgnoreMove) {
          targetEl.addEventListener('touchmove', this.handleTouchMove);
        }
        targetEl.addEventListener('touchend', this.handleTouchEnd);
        targetEl.addEventListener('touchcancel', this.handleTouchEnd); // treat it as a touch end
        // attach a handler to get called when ANY scroll action happens on the page.
        // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
        // http://stackoverflow.com/a/32954565/96342
        window.addEventListener('scroll', this.handleTouchScroll, true);
      }
    };
    this.handleTouchMove = ev => {
      let pev = this.createEventFromTouch(ev);
      this.recordCoords(pev);
      this.emitter.trigger('pointermove', pev);
    };
    this.handleTouchEnd = ev => {
      if (this.isDragging) {
        // done to guard against touchend followed by touchcancel
        let targetEl = ev.target;
        targetEl.removeEventListener('touchmove', this.handleTouchMove);
        targetEl.removeEventListener('touchend', this.handleTouchEnd);
        targetEl.removeEventListener('touchcancel', this.handleTouchEnd);
        window.removeEventListener('scroll', this.handleTouchScroll, true); // useCaptured=true
        this.emitter.trigger('pointerup', this.createEventFromTouch(ev));
        this.cleanup(); // call last so that pointerup has access to props
        this.isTouchDragging = false;
        startIgnoringMouse();
      }
    };
    this.handleTouchScroll = () => {
      this.wasTouchScroll = true;
    };
    this.handleScroll = ev => {
      if (!this.shouldIgnoreMove) {
        let pageX = window.scrollX - this.prevScrollX + this.prevPageX;
        let pageY = window.scrollY - this.prevScrollY + this.prevPageY;
        this.emitter.trigger('pointermove', {
          origEvent: ev,
          isTouch: this.isTouchDragging,
          subjectEl: this.subjectEl,
          pageX,
          pageY,
          deltaX: pageX - this.origPageX,
          deltaY: pageY - this.origPageY
        });
      }
    };
    this.containerEl = containerEl;
    this.emitter = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.F();
    containerEl.addEventListener('mousedown', this.handleMouseDown);
    containerEl.addEventListener('touchstart', this.handleTouchStart, {
      passive: true
    });
    listenerCreated();
  }
  destroy() {
    this.containerEl.removeEventListener('mousedown', this.handleMouseDown);
    this.containerEl.removeEventListener('touchstart', this.handleTouchStart, {
      passive: true
    });
    listenerDestroyed();
  }
  tryStart(ev) {
    let subjectEl = this.querySubjectEl(ev);
    let downEl = ev.target;
    if (subjectEl && (!this.handleSelector || (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(downEl, this.handleSelector))) {
      this.subjectEl = subjectEl;
      this.isDragging = true; // do this first so cancelTouchScroll will work
      this.wasTouchScroll = false;
      return true;
    }
    return false;
  }
  cleanup() {
    isWindowTouchMoveCancelled = false;
    this.isDragging = false;
    this.subjectEl = null;
    // keep wasTouchScroll around for later access
    this.destroyScrollWatch();
  }
  querySubjectEl(ev) {
    if (this.selector) {
      return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ev.target, this.selector);
    }
    return this.containerEl;
  }
  shouldIgnoreMouse() {
    return ignoreMouseDepth || this.isTouchDragging;
  }
  // can be called by user of this class, to cancel touch-based scrolling for the current drag
  cancelTouchScroll() {
    if (this.isDragging) {
      isWindowTouchMoveCancelled = true;
    }
  }
  // Scrolling that simulates pointermoves
  // ----------------------------------------------------------------------------------------------------
  initScrollWatch(ev) {
    if (this.shouldWatchScroll) {
      this.recordCoords(ev);
      window.addEventListener('scroll', this.handleScroll, true); // useCapture=true
    }
  }
  recordCoords(ev) {
    if (this.shouldWatchScroll) {
      this.prevPageX = ev.pageX;
      this.prevPageY = ev.pageY;
      this.prevScrollX = window.scrollX;
      this.prevScrollY = window.scrollY;
    }
  }
  destroyScrollWatch() {
    if (this.shouldWatchScroll) {
      window.removeEventListener('scroll', this.handleScroll, true); // useCaptured=true
    }
  }
  // Event Normalization
  // ----------------------------------------------------------------------------------------------------
  createEventFromMouse(ev, isFirst) {
    let deltaX = 0;
    let deltaY = 0;
    // TODO: repeat code
    if (isFirst) {
      this.origPageX = ev.pageX;
      this.origPageY = ev.pageY;
    } else {
      deltaX = ev.pageX - this.origPageX;
      deltaY = ev.pageY - this.origPageY;
    }
    return {
      origEvent: ev,
      isTouch: false,
      subjectEl: this.subjectEl,
      pageX: ev.pageX,
      pageY: ev.pageY,
      deltaX,
      deltaY
    };
  }
  createEventFromTouch(ev, isFirst) {
    let touches = ev.touches;
    let pageX;
    let pageY;
    let deltaX = 0;
    let deltaY = 0;
    // if touch coords available, prefer,
    // because FF would give bad ev.pageX ev.pageY
    if (touches && touches.length) {
      pageX = touches[0].pageX;
      pageY = touches[0].pageY;
    } else {
      pageX = ev.pageX;
      pageY = ev.pageY;
    }
    // TODO: repeat code
    if (isFirst) {
      this.origPageX = pageX;
      this.origPageY = pageY;
    } else {
      deltaX = pageX - this.origPageX;
      deltaY = pageY - this.origPageY;
    }
    return {
      origEvent: ev,
      isTouch: true,
      subjectEl: this.subjectEl,
      pageX,
      pageY,
      deltaX,
      deltaY
    };
  }
}
// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)
function isPrimaryMouseButton(ev) {
  return ev.button === 0 && !ev.ctrlKey;
}
// Ignoring fake mouse events generated by touch
// ----------------------------------------------------------------------------------------------------
function startIgnoringMouse() {
  ignoreMouseDepth += 1;
  setTimeout(() => {
    ignoreMouseDepth -= 1;
  }, _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bG.touchMouseIgnoreWait);
}
// We want to attach touchmove as early as possible for Safari
// ----------------------------------------------------------------------------------------------------
function listenerCreated() {
  listenerCnt += 1;
  if (listenerCnt === 1) {
    window.addEventListener('touchmove', onWindowTouchMove, {
      passive: false
    });
  }
}
function listenerDestroyed() {
  listenerCnt -= 1;
  if (!listenerCnt) {
    window.removeEventListener('touchmove', onWindowTouchMove, {
      passive: false
    });
  }
}
function onWindowTouchMove(ev) {
  if (isWindowTouchMoveCancelled) {
    ev.preventDefault();
  }
}

/*
An effect in which an element follows the movement of a pointer across the screen.
The moving element is a clone of some other element.
Must call start + handleMove + stop.
*/
class ElementMirror {
  constructor() {
    this.isVisible = false; // must be explicitly enabled
    this.sourceEl = null;
    this.mirrorEl = null;
    this.sourceElRect = null; // screen coords relative to viewport
    // options that can be set directly by caller
    this.parentNode = document.body; // HIGHLY SUGGESTED to set this to sidestep ShadowDOM issues
    this.zIndex = 9999;
    this.revertDuration = 0;
  }
  start(sourceEl, pageX, pageY) {
    this.sourceEl = sourceEl;
    this.sourceElRect = this.sourceEl.getBoundingClientRect();
    this.origScreenX = pageX - window.scrollX;
    this.origScreenY = pageY - window.scrollY;
    this.deltaX = 0;
    this.deltaY = 0;
    this.updateElPosition();
  }
  handleMove(pageX, pageY) {
    this.deltaX = pageX - window.scrollX - this.origScreenX;
    this.deltaY = pageY - window.scrollY - this.origScreenY;
    this.updateElPosition();
  }
  // can be called before start
  setIsVisible(bool) {
    if (bool) {
      if (!this.isVisible) {
        if (this.mirrorEl) {
          this.mirrorEl.style.display = '';
        }
        this.isVisible = bool; // needs to happen before updateElPosition
        this.updateElPosition(); // because was not updating the position while invisible
      }
    } else if (this.isVisible) {
      if (this.mirrorEl) {
        this.mirrorEl.style.display = 'none';
      }
      this.isVisible = bool;
    }
  }
  // always async
  stop(needsRevertAnimation, callback) {
    let done = () => {
      this.cleanup();
      callback();
    };
    if (needsRevertAnimation && this.mirrorEl && this.isVisible && this.revertDuration && (
    // if 0, transition won't work
    this.deltaX || this.deltaY) // if same coords, transition won't work
    ) {
      this.doRevertAnimation(done, this.revertDuration);
    } else {
      setTimeout(done, 0);
    }
  }
  doRevertAnimation(callback, revertDuration) {
    let mirrorEl = this.mirrorEl;
    let finalSourceElRect = this.sourceEl.getBoundingClientRect(); // because autoscrolling might have happened
    mirrorEl.style.transition = 'top ' + revertDuration + 'ms,' + 'left ' + revertDuration + 'ms';
    (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aN)(mirrorEl, {
      left: finalSourceElRect.left,
      top: finalSourceElRect.top
    });
    (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b0)(mirrorEl, () => {
      mirrorEl.style.transition = '';
      callback();
    });
  }
  cleanup() {
    if (this.mirrorEl) {
      (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aM)(this.mirrorEl);
      this.mirrorEl = null;
    }
    this.sourceEl = null;
  }
  updateElPosition() {
    if (this.sourceEl && this.isVisible) {
      (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aN)(this.getMirrorEl(), {
        left: this.sourceElRect.left + this.deltaX,
        top: this.sourceElRect.top + this.deltaY
      });
    }
  }
  getMirrorEl() {
    let sourceElRect = this.sourceElRect;
    let mirrorEl = this.mirrorEl;
    if (!mirrorEl) {
      mirrorEl = this.mirrorEl = this.sourceEl.cloneNode(true); // cloneChildren=true
      // we don't want long taps or any mouse interaction causing selection/menus.
      // would use preventSelection(), but that prevents selectstart, causing problems.
      mirrorEl.style.userSelect = 'none';
      mirrorEl.style.webkitUserSelect = 'none';
      mirrorEl.style.pointerEvents = 'none';
      mirrorEl.classList.add('fc-event-dragging');
      (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aN)(mirrorEl, {
        position: 'fixed',
        zIndex: this.zIndex,
        visibility: '',
        boxSizing: 'border-box',
        width: sourceElRect.right - sourceElRect.left,
        height: sourceElRect.bottom - sourceElRect.top,
        right: 'auto',
        bottom: 'auto',
        margin: 0
      });
      this.parentNode.appendChild(mirrorEl);
    }
    return mirrorEl;
  }
}

/*
Is a cache for a given element's scroll information (all the info that ScrollController stores)
in addition the "client rectangle" of the element.. the area within the scrollbars.

The cache can be in one of two modes:
- doesListening:false - ignores when the container is scrolled by someone else
- doesListening:true - watch for scrolling and update the cache
*/
class ScrollGeomCache extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b9 {
  constructor(scrollController, doesListening) {
    super();
    this.handleScroll = () => {
      this.scrollTop = this.scrollController.getScrollTop();
      this.scrollLeft = this.scrollController.getScrollLeft();
      this.handleScrollChange();
    };
    this.scrollController = scrollController;
    this.doesListening = doesListening;
    this.scrollTop = this.origScrollTop = scrollController.getScrollTop();
    this.scrollLeft = this.origScrollLeft = scrollController.getScrollLeft();
    this.scrollWidth = scrollController.getScrollWidth();
    this.scrollHeight = scrollController.getScrollHeight();
    this.clientWidth = scrollController.getClientWidth();
    this.clientHeight = scrollController.getClientHeight();
    this.clientRect = this.computeClientRect(); // do last in case it needs cached values
    if (this.doesListening) {
      this.getEventTarget().addEventListener('scroll', this.handleScroll);
    }
  }
  destroy() {
    if (this.doesListening) {
      this.getEventTarget().removeEventListener('scroll', this.handleScroll);
    }
  }
  getScrollTop() {
    return this.scrollTop;
  }
  getScrollLeft() {
    return this.scrollLeft;
  }
  setScrollTop(top) {
    this.scrollController.setScrollTop(top);
    if (!this.doesListening) {
      // we are not relying on the element to normalize out-of-bounds scroll values
      // so we need to sanitize ourselves
      this.scrollTop = Math.max(Math.min(top, this.getMaxScrollTop()), 0);
      this.handleScrollChange();
    }
  }
  setScrollLeft(top) {
    this.scrollController.setScrollLeft(top);
    if (!this.doesListening) {
      // we are not relying on the element to normalize out-of-bounds scroll values
      // so we need to sanitize ourselves
      this.scrollLeft = Math.max(Math.min(top, this.getMaxScrollLeft()), 0);
      this.handleScrollChange();
    }
  }
  getClientWidth() {
    return this.clientWidth;
  }
  getClientHeight() {
    return this.clientHeight;
  }
  getScrollWidth() {
    return this.scrollWidth;
  }
  getScrollHeight() {
    return this.scrollHeight;
  }
  handleScrollChange() {}
}
class ElementScrollGeomCache extends ScrollGeomCache {
  constructor(el, doesListening) {
    super(new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ba(el), doesListening);
  }
  getEventTarget() {
    return this.scrollController.el;
  }
  computeClientRect() {
    return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b1)(this.scrollController.el);
  }
}
class WindowScrollGeomCache extends ScrollGeomCache {
  constructor(doesListening) {
    super(new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bb(), doesListening);
  }
  getEventTarget() {
    return window;
  }
  computeClientRect() {
    return {
      left: this.scrollLeft,
      right: this.scrollLeft + this.clientWidth,
      top: this.scrollTop,
      bottom: this.scrollTop + this.clientHeight
    };
  }
  // the window is the only scroll object that changes it's rectangle relative
  // to the document's topleft as it scrolls
  handleScrollChange() {
    this.clientRect = this.computeClientRect();
  }
}

// If available we are using native "performance" API instead of "Date"
// Read more about it on MDN:
// https://developer.mozilla.org/en-US/docs/Web/API/Performance
const getTime = typeof performance === 'function' ? performance.now : Date.now;
/*
For a pointer interaction, automatically scrolls certain scroll containers when the pointer
approaches the edge.

The caller must call start + handleMove + stop.
*/
class AutoScroller {
  constructor() {
    // options that can be set by caller
    this.isEnabled = true;
    this.scrollQuery = [window, '.fc-scroller'];
    this.edgeThreshold = 50; // pixels
    this.maxVelocity = 300; // pixels per second
    // internal state
    this.pointerScreenX = null;
    this.pointerScreenY = null;
    this.isAnimating = false;
    this.scrollCaches = null;
    // protect against the initial pointerdown being too close to an edge and starting the scroll
    this.everMovedUp = false;
    this.everMovedDown = false;
    this.everMovedLeft = false;
    this.everMovedRight = false;
    this.animate = () => {
      if (this.isAnimating) {
        // wasn't cancelled between animation calls
        let edge = this.computeBestEdge(this.pointerScreenX + window.scrollX, this.pointerScreenY + window.scrollY);
        if (edge) {
          let now = getTime();
          this.handleSide(edge, (now - this.msSinceRequest) / 1000);
          this.requestAnimation(now);
        } else {
          this.isAnimating = false; // will stop animation
        }
      }
    };
  }
  start(pageX, pageY, scrollStartEl) {
    if (this.isEnabled) {
      this.scrollCaches = this.buildCaches(scrollStartEl);
      this.pointerScreenX = null;
      this.pointerScreenY = null;
      this.everMovedUp = false;
      this.everMovedDown = false;
      this.everMovedLeft = false;
      this.everMovedRight = false;
      this.handleMove(pageX, pageY);
    }
  }
  handleMove(pageX, pageY) {
    if (this.isEnabled) {
      let pointerScreenX = pageX - window.scrollX;
      let pointerScreenY = pageY - window.scrollY;
      let yDelta = this.pointerScreenY === null ? 0 : pointerScreenY - this.pointerScreenY;
      let xDelta = this.pointerScreenX === null ? 0 : pointerScreenX - this.pointerScreenX;
      if (yDelta < 0) {
        this.everMovedUp = true;
      } else if (yDelta > 0) {
        this.everMovedDown = true;
      }
      if (xDelta < 0) {
        this.everMovedLeft = true;
      } else if (xDelta > 0) {
        this.everMovedRight = true;
      }
      this.pointerScreenX = pointerScreenX;
      this.pointerScreenY = pointerScreenY;
      if (!this.isAnimating) {
        this.isAnimating = true;
        this.requestAnimation(getTime());
      }
    }
  }
  stop() {
    if (this.isEnabled) {
      this.isAnimating = false; // will stop animation
      for (let scrollCache of this.scrollCaches) {
        scrollCache.destroy();
      }
      this.scrollCaches = null;
    }
  }
  requestAnimation(now) {
    this.msSinceRequest = now;
    requestAnimationFrame(this.animate);
  }
  handleSide(edge, seconds) {
    let {
      scrollCache
    } = edge;
    let {
      edgeThreshold
    } = this;
    let invDistance = edgeThreshold - edge.distance;
    let velocity =
    // the closer to the edge, the faster we scroll
    invDistance * invDistance / (edgeThreshold * edgeThreshold) *
    // quadratic
    this.maxVelocity * seconds;
    let sign = 1;
    switch (edge.name) {
      case 'left':
        sign = -1;
      // falls through
      case 'right':
        scrollCache.setScrollLeft(scrollCache.getScrollLeft() + velocity * sign);
        break;
      case 'top':
        sign = -1;
      // falls through
      case 'bottom':
        scrollCache.setScrollTop(scrollCache.getScrollTop() + velocity * sign);
        break;
    }
  }
  // left/top are relative to document topleft
  computeBestEdge(left, top) {
    let {
      edgeThreshold
    } = this;
    let bestSide = null;
    let scrollCaches = this.scrollCaches || [];
    for (let scrollCache of scrollCaches) {
      let rect = scrollCache.clientRect;
      let leftDist = left - rect.left;
      let rightDist = rect.right - left;
      let topDist = top - rect.top;
      let bottomDist = rect.bottom - top;
      // completely within the rect?
      if (leftDist >= 0 && rightDist >= 0 && topDist >= 0 && bottomDist >= 0) {
        if (topDist <= edgeThreshold && this.everMovedUp && scrollCache.canScrollUp() && (!bestSide || bestSide.distance > topDist)) {
          bestSide = {
            scrollCache,
            name: 'top',
            distance: topDist
          };
        }
        if (bottomDist <= edgeThreshold && this.everMovedDown && scrollCache.canScrollDown() && (!bestSide || bestSide.distance > bottomDist)) {
          bestSide = {
            scrollCache,
            name: 'bottom',
            distance: bottomDist
          };
        }
        /*
        TODO: fix broken RTL scrolling. canScrollLeft always returning false
        https://github.com/fullcalendar/fullcalendar/issues/4837
        */
        if (leftDist <= edgeThreshold && this.everMovedLeft && scrollCache.canScrollLeft() && (!bestSide || bestSide.distance > leftDist)) {
          bestSide = {
            scrollCache,
            name: 'left',
            distance: leftDist
          };
        }
        if (rightDist <= edgeThreshold && this.everMovedRight && scrollCache.canScrollRight() && (!bestSide || bestSide.distance > rightDist)) {
          bestSide = {
            scrollCache,
            name: 'right',
            distance: rightDist
          };
        }
      }
    }
    return bestSide;
  }
  buildCaches(scrollStartEl) {
    return this.queryScrollEls(scrollStartEl).map(el => {
      if (el === window) {
        return new WindowScrollGeomCache(false); // false = don't listen to user-generated scrolls
      }
      return new ElementScrollGeomCache(el, false); // false = don't listen to user-generated scrolls
    });
  }
  queryScrollEls(scrollStartEl) {
    let els = [];
    for (let query of this.scrollQuery) {
      if (typeof query === 'object') {
        els.push(query);
      } else {
        /*
        TODO: in the future, always have auto-scroll happen on element where current Hit came from
        Ticket: https://github.com/fullcalendar/fullcalendar/issues/4593
        */
        els.push(...Array.prototype.slice.call(scrollStartEl.getRootNode().querySelectorAll(query)));
      }
    }
    return els;
  }
}

/*
Monitors dragging on an element. Has a number of high-level features:
- minimum distance required before dragging
- minimum wait time ("delay") before dragging
- a mirror element that follows the pointer
*/
class FeaturefulElementDragging extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bF {
  constructor(containerEl, selector) {
    super(containerEl);
    this.containerEl = containerEl;
    // options that can be directly set by caller
    // the caller can also set the PointerDragging's options as well
    this.delay = null;
    this.minDistance = 0;
    this.touchScrollAllowed = true; // prevents drag from starting and blocks scrolling during drag
    this.mirrorNeedsRevert = false;
    this.isInteracting = false; // is the user validly moving the pointer? lasts until pointerup
    this.isDragging = false; // is it INTENTFULLY dragging? lasts until after revert animation
    this.isDelayEnded = false;
    this.isDistanceSurpassed = false;
    this.delayTimeoutId = null;
    this.onPointerDown = ev => {
      if (!this.isDragging) {
        // so new drag doesn't happen while revert animation is going
        this.isInteracting = true;
        this.isDelayEnded = false;
        this.isDistanceSurpassed = false;
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ap)(document.body);
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ar)(document.body);
        // prevent links from being visited if there's an eventual drag.
        // also prevents selection in older browsers (maybe?).
        // not necessary for touch, besides, browser would complain about passiveness.
        if (!ev.isTouch) {
          ev.origEvent.preventDefault();
        }
        this.emitter.trigger('pointerdown', ev);
        if (this.isInteracting &&
        // not destroyed via pointerdown handler
        !this.pointer.shouldIgnoreMove) {
          // actions related to initiating dragstart+dragmove+dragend...
          this.mirror.setIsVisible(false); // reset. caller must set-visible
          this.mirror.start(ev.subjectEl, ev.pageX, ev.pageY); // must happen on first pointer down
          this.startDelay(ev);
          if (!this.minDistance) {
            this.handleDistanceSurpassed(ev);
          }
        }
      }
    };
    this.onPointerMove = ev => {
      if (this.isInteracting) {
        this.emitter.trigger('pointermove', ev);
        if (!this.isDistanceSurpassed) {
          let minDistance = this.minDistance;
          let distanceSq; // current distance from the origin, squared
          let {
            deltaX,
            deltaY
          } = ev;
          distanceSq = deltaX * deltaX + deltaY * deltaY;
          if (distanceSq >= minDistance * minDistance) {
            // use pythagorean theorem
            this.handleDistanceSurpassed(ev);
          }
        }
        if (this.isDragging) {
          // a real pointer move? (not one simulated by scrolling)
          if (ev.origEvent.type !== 'scroll') {
            this.mirror.handleMove(ev.pageX, ev.pageY);
            this.autoScroller.handleMove(ev.pageX, ev.pageY);
          }
          this.emitter.trigger('dragmove', ev);
        }
      }
    };
    this.onPointerUp = ev => {
      if (this.isInteracting) {
        this.isInteracting = false;
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aq)(document.body);
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.as)(document.body);
        this.emitter.trigger('pointerup', ev); // can potentially set mirrorNeedsRevert
        if (this.isDragging) {
          this.autoScroller.stop();
          this.tryStopDrag(ev); // which will stop the mirror
        }
        if (this.delayTimeoutId) {
          clearTimeout(this.delayTimeoutId);
          this.delayTimeoutId = null;
        }
      }
    };
    let pointer = this.pointer = new PointerDragging(containerEl);
    pointer.emitter.on('pointerdown', this.onPointerDown);
    pointer.emitter.on('pointermove', this.onPointerMove);
    pointer.emitter.on('pointerup', this.onPointerUp);
    if (selector) {
      pointer.selector = selector;
    }
    this.mirror = new ElementMirror();
    this.autoScroller = new AutoScroller();
  }
  destroy() {
    this.pointer.destroy();
    // HACK: simulate a pointer-up to end the current drag
    // TODO: fire 'dragend' directly and stop interaction. discourage use of pointerup event (b/c might not fire)
    this.onPointerUp({});
  }
  startDelay(ev) {
    if (typeof this.delay === 'number') {
      this.delayTimeoutId = setTimeout(() => {
        this.delayTimeoutId = null;
        this.handleDelayEnd(ev);
      }, this.delay); // not assignable to number!
    } else {
      this.handleDelayEnd(ev);
    }
  }
  handleDelayEnd(ev) {
    this.isDelayEnded = true;
    this.tryStartDrag(ev);
  }
  handleDistanceSurpassed(ev) {
    this.isDistanceSurpassed = true;
    this.tryStartDrag(ev);
  }
  tryStartDrag(ev) {
    if (this.isDelayEnded && this.isDistanceSurpassed) {
      if (!this.pointer.wasTouchScroll || this.touchScrollAllowed) {
        this.isDragging = true;
        this.mirrorNeedsRevert = false;
        this.autoScroller.start(ev.pageX, ev.pageY, this.containerEl);
        this.emitter.trigger('dragstart', ev);
        if (this.touchScrollAllowed === false) {
          this.pointer.cancelTouchScroll();
        }
      }
    }
  }
  tryStopDrag(ev) {
    // .stop() is ALWAYS asynchronous, which we NEED because we want all pointerup events
    // that come from the document to fire beforehand. much more convenient this way.
    this.mirror.stop(this.mirrorNeedsRevert, this.stopDrag.bind(this, ev));
  }
  stopDrag(ev) {
    this.isDragging = false;
    this.emitter.trigger('dragend', ev);
  }
  // fill in the implementations...
  setIgnoreMove(bool) {
    this.pointer.shouldIgnoreMove = bool;
  }
  setMirrorIsVisible(bool) {
    this.mirror.setIsVisible(bool);
  }
  setMirrorNeedsRevert(bool) {
    this.mirrorNeedsRevert = bool;
  }
  setAutoScrollEnabled(bool) {
    this.autoScroller.isEnabled = bool;
  }
}

/*
When this class is instantiated, it records the offset of an element (relative to the document topleft),
and continues to monitor scrolling, updating the cached coordinates if it needs to.
Does not access the DOM after instantiation, so highly performant.

Also keeps track of all scrolling/overflow:hidden containers that are parents of the given element
and an determine if a given point is inside the combined clipping rectangle.
*/
class OffsetTracker {
  constructor(el) {
    this.el = el;
    this.origRect = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b4)(el);
    // will work fine for divs that have overflow:hidden
    this.scrollCaches = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b3)(el).map(scrollEl => new ElementScrollGeomCache(scrollEl, true));
  }
  destroy() {
    for (let scrollCache of this.scrollCaches) {
      scrollCache.destroy();
    }
  }
  computeLeft() {
    let left = this.origRect.left;
    for (let scrollCache of this.scrollCaches) {
      left += scrollCache.origScrollLeft - scrollCache.getScrollLeft();
    }
    return left;
  }
  computeTop() {
    let top = this.origRect.top;
    for (let scrollCache of this.scrollCaches) {
      top += scrollCache.origScrollTop - scrollCache.getScrollTop();
    }
    return top;
  }
  isWithinClipping(pageX, pageY) {
    let point = {
      left: pageX,
      top: pageY
    };
    for (let scrollCache of this.scrollCaches) {
      if (!isIgnoredClipping(scrollCache.getEventTarget()) && !(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aD)(point, scrollCache.clientRect)) {
        return false;
      }
    }
    return true;
  }
}
// certain clipping containers should never constrain interactions, like <html> and <body>
// https://github.com/fullcalendar/fullcalendar/issues/3615
function isIgnoredClipping(node) {
  let tagName = node.tagName;
  return tagName === 'HTML' || tagName === 'BODY';
}

/*
Tracks movement over multiple droppable areas (aka "hits")
that exist in one or more DateComponents.
Relies on an existing draggable.

emits:
- pointerdown
- dragstart
- hitchange - fires initially, even if not over a hit
- pointerup
- (hitchange - again, to null, if ended over a hit)
- dragend
*/
class HitDragging {
  constructor(dragging, droppableStore) {
    // options that can be set by caller
    this.useSubjectCenter = false;
    this.requireInitial = true; // if doesn't start out on a hit, won't emit any events
    this.disablePointCheck = false;
    this.initialHit = null;
    this.movingHit = null;
    this.finalHit = null; // won't ever be populated if shouldIgnoreMove
    this.handlePointerDown = ev => {
      let {
        dragging
      } = this;
      this.initialHit = null;
      this.movingHit = null;
      this.finalHit = null;
      this.prepareHits();
      this.processFirstCoord(ev);
      if (this.initialHit || !this.requireInitial) {
        dragging.setIgnoreMove(false);
        // TODO: fire this before computing processFirstCoord, so listeners can cancel. this gets fired by almost every handler :(
        this.emitter.trigger('pointerdown', ev);
      } else {
        dragging.setIgnoreMove(true);
      }
    };
    this.handleDragStart = ev => {
      this.emitter.trigger('dragstart', ev);
      this.handleMove(ev, true); // force = fire even if initially null
    };
    this.handleDragMove = ev => {
      this.emitter.trigger('dragmove', ev);
      this.handleMove(ev);
    };
    this.handlePointerUp = ev => {
      this.releaseHits();
      this.emitter.trigger('pointerup', ev);
    };
    this.handleDragEnd = ev => {
      if (this.movingHit) {
        this.emitter.trigger('hitupdate', null, true, ev);
      }
      this.finalHit = this.movingHit;
      this.movingHit = null;
      this.emitter.trigger('dragend', ev);
    };
    this.droppableStore = droppableStore;
    dragging.emitter.on('pointerdown', this.handlePointerDown);
    dragging.emitter.on('dragstart', this.handleDragStart);
    dragging.emitter.on('dragmove', this.handleDragMove);
    dragging.emitter.on('pointerup', this.handlePointerUp);
    dragging.emitter.on('dragend', this.handleDragEnd);
    this.dragging = dragging;
    this.emitter = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.F();
  }
  // sets initialHit
  // sets coordAdjust
  processFirstCoord(ev) {
    let origPoint = {
      left: ev.pageX,
      top: ev.pageY
    };
    let adjustedPoint = origPoint;
    let subjectEl = ev.subjectEl;
    let subjectRect;
    if (subjectEl instanceof HTMLElement) {
      // i.e. not a Document/ShadowRoot
      subjectRect = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b4)(subjectEl);
      adjustedPoint = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aE)(adjustedPoint, subjectRect);
    }
    let initialHit = this.initialHit = this.queryHitForOffset(adjustedPoint.left, adjustedPoint.top);
    if (initialHit) {
      if (this.useSubjectCenter && subjectRect) {
        let slicedSubjectRect = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aC)(subjectRect, initialHit.rect);
        if (slicedSubjectRect) {
          adjustedPoint = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aF)(slicedSubjectRect);
        }
      }
      this.coordAdjust = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aG)(adjustedPoint, origPoint);
    } else {
      this.coordAdjust = {
        left: 0,
        top: 0
      };
    }
  }
  handleMove(ev, forceHandle) {
    let hit = this.queryHitForOffset(ev.pageX + this.coordAdjust.left, ev.pageY + this.coordAdjust.top);
    if (forceHandle || !isHitsEqual(this.movingHit, hit)) {
      this.movingHit = hit;
      this.emitter.trigger('hitupdate', hit, false, ev);
    }
  }
  prepareHits() {
    this.offsetTrackers = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a)(this.droppableStore, interactionSettings => {
      interactionSettings.component.prepareHits();
      return new OffsetTracker(interactionSettings.el);
    });
  }
  releaseHits() {
    let {
      offsetTrackers
    } = this;
    for (let id in offsetTrackers) {
      offsetTrackers[id].destroy();
    }
    this.offsetTrackers = {};
  }
  queryHitForOffset(offsetLeft, offsetTop) {
    let {
      droppableStore,
      offsetTrackers
    } = this;
    let bestHit = null;
    for (let id in droppableStore) {
      let component = droppableStore[id].component;
      let offsetTracker = offsetTrackers[id];
      if (offsetTracker &&
      // wasn't destroyed mid-drag
      offsetTracker.isWithinClipping(offsetLeft, offsetTop)) {
        let originLeft = offsetTracker.computeLeft();
        let originTop = offsetTracker.computeTop();
        let positionLeft = offsetLeft - originLeft;
        let positionTop = offsetTop - originTop;
        let {
          origRect
        } = offsetTracker;
        let width = origRect.right - origRect.left;
        let height = origRect.bottom - origRect.top;
        if (
        // must be within the element's bounds
        positionLeft >= 0 && positionLeft < width && positionTop >= 0 && positionTop < height) {
          let hit = component.queryHit(positionLeft, positionTop, width, height);
          if (hit &&
          // make sure the hit is within activeRange, meaning it's not a dead cell
          (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b7)(hit.dateProfile.activeRange, hit.dateSpan.range) && (
          // Ensure the component we are querying for the hit is accessibly my the pointer
          // Prevents obscured calendars (ex: under a modal dialog) from accepting hit
          // https://github.com/fullcalendar/fullcalendar/issues/5026
          this.disablePointCheck || offsetTracker.el.contains(offsetTracker.el.getRootNode().elementFromPoint(
          // add-back origins to get coordinate relative to top-left of window viewport
          positionLeft + originLeft - window.scrollX, positionTop + originTop - window.scrollY))) && (!bestHit || hit.layer > bestHit.layer)) {
            hit.componentId = id;
            hit.context = component.context;
            // TODO: better way to re-orient rectangle
            hit.rect.left += originLeft;
            hit.rect.right += originLeft;
            hit.rect.top += originTop;
            hit.rect.bottom += originTop;
            bestHit = hit;
          }
        }
      }
    }
    return bestHit;
  }
}
function isHitsEqual(hit0, hit1) {
  if (!hit0 && !hit1) {
    return true;
  }
  if (Boolean(hit0) !== Boolean(hit1)) {
    return false;
  }
  return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bd)(hit0.dateSpan, hit1.dateSpan);
}
function buildDatePointApiWithContext(dateSpan, context) {
  let props = {};
  for (let transform of context.pluginHooks.datePointTransforms) {
    Object.assign(props, transform(dateSpan, context));
  }
  Object.assign(props, buildDatePointApi(dateSpan, context.dateEnv));
  return props;
}
function buildDatePointApi(span, dateEnv) {
  return {
    date: dateEnv.toDate(span.range.start),
    dateStr: dateEnv.formatIso(span.range.start, {
      omitTime: span.allDay
    }),
    allDay: span.allDay
  };
}

/*
Monitors when the user clicks on a specific date/time of a component.
A pointerdown+pointerup on the same "hit" constitutes a click.
*/
class DateClicking extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    this.handlePointerDown = pev => {
      let {
        dragging
      } = this;
      let downEl = pev.origEvent.target;
      // do this in pointerdown (not dragend) because DOM might be mutated by the time dragend is fired
      dragging.setIgnoreMove(!this.component.isValidDateDownEl(downEl));
    };
    // won't even fire if moving was ignored
    this.handleDragEnd = ev => {
      let {
        component
      } = this;
      let {
        pointer
      } = this.dragging;
      if (!pointer.wasTouchScroll) {
        let {
          initialHit,
          finalHit
        } = this.hitDragging;
        if (initialHit && finalHit && isHitsEqual(initialHit, finalHit)) {
          let {
            context
          } = component;
          let arg = Object.assign(Object.assign({}, buildDatePointApiWithContext(initialHit.dateSpan, context)), {
            dayEl: initialHit.dayEl,
            jsEvent: ev.origEvent,
            view: context.viewApi || context.calendarApi.view
          });
          context.emitter.trigger('dateClick', arg);
        }
      }
    };
    // we DO want to watch pointer moves because otherwise finalHit won't get populated
    this.dragging = new FeaturefulElementDragging(settings.el);
    this.dragging.autoScroller.isEnabled = false;
    let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bE)(settings));
    hitDragging.emitter.on('pointerdown', this.handlePointerDown);
    hitDragging.emitter.on('dragend', this.handleDragEnd);
  }
  destroy() {
    this.dragging.destroy();
  }
}

/*
Tracks when the user selects a portion of time of a component,
constituted by a drag over date cells, with a possible delay at the beginning of the drag.
*/
class DateSelecting extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    this.dragSelection = null;
    this.handlePointerDown = ev => {
      let {
        component,
        dragging
      } = this;
      let {
        options
      } = component.context;
      let canSelect = options.selectable && component.isValidDateDownEl(ev.origEvent.target);
      // don't bother to watch expensive moves if component won't do selection
      dragging.setIgnoreMove(!canSelect);
      // if touch, require user to hold down
      dragging.delay = ev.isTouch ? getComponentTouchDelay$1(component) : null;
    };
    this.handleDragStart = ev => {
      this.component.context.calendarApi.unselect(ev); // unselect previous selections
    };
    this.handleHitUpdate = (hit, isFinal) => {
      let {
        context
      } = this.component;
      let dragSelection = null;
      let isInvalid = false;
      if (hit) {
        let initialHit = this.hitDragging.initialHit;
        let disallowed = hit.componentId === initialHit.componentId && this.isHitComboAllowed && !this.isHitComboAllowed(initialHit, hit);
        if (!disallowed) {
          dragSelection = joinHitsIntoSelection(initialHit, hit, context.pluginHooks.dateSelectionTransformers);
        }
        if (!dragSelection || !(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bY)(dragSelection, hit.dateProfile, context)) {
          isInvalid = true;
          dragSelection = null;
        }
      }
      if (dragSelection) {
        context.dispatch({
          type: 'SELECT_DATES',
          selection: dragSelection
        });
      } else if (!isFinal) {
        // only unselect if moved away while dragging
        context.dispatch({
          type: 'UNSELECT_DATES'
        });
      }
      if (!isInvalid) {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.au)();
      } else {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.av)();
      }
      if (!isFinal) {
        this.dragSelection = dragSelection; // only clear if moved away from all hits while dragging
      }
    };
    this.handlePointerUp = pev => {
      if (this.dragSelection) {
        // selection is already rendered, so just need to report selection
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cr)(this.dragSelection, pev, this.component.context);
        this.dragSelection = null;
      }
    };
    let {
      component
    } = settings;
    let {
      options
    } = component.context;
    let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
    dragging.touchScrollAllowed = false;
    dragging.minDistance = options.selectMinDistance || 0;
    dragging.autoScroller.isEnabled = options.dragScroll;
    let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bE)(settings));
    hitDragging.emitter.on('pointerdown', this.handlePointerDown);
    hitDragging.emitter.on('dragstart', this.handleDragStart);
    hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
    hitDragging.emitter.on('pointerup', this.handlePointerUp);
  }
  destroy() {
    this.dragging.destroy();
  }
}
function getComponentTouchDelay$1(component) {
  let {
    options
  } = component.context;
  let delay = options.selectLongPressDelay;
  if (delay == null) {
    delay = options.longPressDelay;
  }
  return delay;
}
function joinHitsIntoSelection(hit0, hit1, dateSelectionTransformers) {
  let dateSpan0 = hit0.dateSpan;
  let dateSpan1 = hit1.dateSpan;
  let ms = [dateSpan0.range.start, dateSpan0.range.end, dateSpan1.range.start, dateSpan1.range.end];
  ms.sort(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.at);
  let props = {};
  for (let transformer of dateSelectionTransformers) {
    let res = transformer(hit0, hit1);
    if (res === false) {
      return null;
    }
    if (res) {
      Object.assign(props, res);
    }
  }
  props.range = {
    start: ms[0],
    end: ms[3]
  };
  props.allDay = dateSpan0.allDay;
  return props;
}
class EventDragging extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    // internal state
    this.subjectEl = null;
    this.subjectSeg = null; // the seg being selected/dragged
    this.isDragging = false;
    this.eventRange = null;
    this.relevantEvents = null; // the events being dragged
    this.receivingContext = null;
    this.validMutation = null;
    this.mutatedRelevantEvents = null;
    this.handlePointerDown = ev => {
      let origTarget = ev.origEvent.target;
      let {
        component,
        dragging
      } = this;
      let {
        mirror
      } = dragging;
      let {
        options
      } = component.context;
      let initialContext = component.context;
      this.subjectEl = ev.subjectEl;
      let subjectSeg = this.subjectSeg = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Y)(ev.subjectEl);
      let eventRange = this.eventRange = subjectSeg.eventRange;
      let eventInstanceId = eventRange.instance.instanceId;
      this.relevantEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aT)(initialContext.getCurrentData().eventStore, eventInstanceId);
      dragging.minDistance = ev.isTouch ? 0 : options.eventDragMinDistance;
      dragging.delay =
      // only do a touch delay if touch and this event hasn't been selected yet
      ev.isTouch && eventInstanceId !== component.props.eventSelection ? getComponentTouchDelay(component) : null;
      if (options.fixedMirrorParent) {
        mirror.parentNode = options.fixedMirrorParent;
      } else {
        mirror.parentNode = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(origTarget, '.fc');
      }
      mirror.revertDuration = options.dragRevertDuration;
      let isValid = component.isValidSegDownEl(origTarget) && !(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(origTarget, '.fc-event-resizer'); // NOT on a resizer
      dragging.setIgnoreMove(!isValid);
      // disable dragging for elements that are resizable (ie, selectable)
      // but are not draggable
      this.isDragging = isValid && ev.subjectEl.classList.contains('fc-event-draggable');
    };
    this.handleDragStart = ev => {
      let initialContext = this.component.context;
      let eventRange = this.eventRange;
      let eventInstanceId = eventRange.instance.instanceId;
      if (ev.isTouch) {
        // need to select a different event?
        if (eventInstanceId !== this.component.props.eventSelection) {
          initialContext.dispatch({
            type: 'SELECT_EVENT',
            eventInstanceId
          });
        }
      } else {
        // if now using mouse, but was previous touch interaction, clear selected event
        initialContext.dispatch({
          type: 'UNSELECT_EVENT'
        });
      }
      if (this.isDragging) {
        initialContext.calendarApi.unselect(ev); // unselect *date* selection
        initialContext.emitter.trigger('eventDragStart', {
          el: this.subjectEl,
          event: new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(initialContext, eventRange.def, eventRange.instance),
          jsEvent: ev.origEvent,
          view: initialContext.viewApi
        });
      }
    };
    this.handleHitUpdate = (hit, isFinal) => {
      if (!this.isDragging) {
        return;
      }
      let relevantEvents = this.relevantEvents;
      let initialHit = this.hitDragging.initialHit;
      let initialContext = this.component.context;
      // states based on new hit
      let receivingContext = null;
      let mutation = null;
      let mutatedRelevantEvents = null;
      let isInvalid = false;
      let interaction = {
        affectedEvents: relevantEvents,
        mutatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
        isEvent: true
      };
      if (hit) {
        receivingContext = hit.context;
        let receivingOptions = receivingContext.options;
        if (initialContext === receivingContext || receivingOptions.editable && receivingOptions.droppable) {
          mutation = computeEventMutation(initialHit, hit, this.eventRange.instance.range.start, receivingContext.getCurrentData().pluginHooks.eventDragMutationMassagers);
          if (mutation) {
            mutatedRelevantEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bV)(relevantEvents, receivingContext.getCurrentData().eventUiBases, mutation, receivingContext);
            interaction.mutatedEvents = mutatedRelevantEvents;
            if (!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bX)(interaction, hit.dateProfile, receivingContext)) {
              isInvalid = true;
              mutation = null;
              mutatedRelevantEvents = null;
              interaction.mutatedEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)();
            }
          }
        } else {
          receivingContext = null;
        }
      }
      this.displayDrag(receivingContext, interaction);
      if (!isInvalid) {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.au)();
      } else {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.av)();
      }
      if (!isFinal) {
        if (initialContext === receivingContext &&
        // TODO: write test for this
        isHitsEqual(initialHit, hit)) {
          mutation = null;
        }
        this.dragging.setMirrorNeedsRevert(!mutation);
        // render the mirror if no already-rendered mirror
        // TODO: wish we could somehow wait for dispatch to guarantee render
        this.dragging.setMirrorIsVisible(!hit || !this.subjectEl.getRootNode().querySelector('.fc-event-mirror'));
        // assign states based on new hit
        this.receivingContext = receivingContext;
        this.validMutation = mutation;
        this.mutatedRelevantEvents = mutatedRelevantEvents;
      }
    };
    this.handlePointerUp = () => {
      if (!this.isDragging) {
        this.cleanup(); // because handleDragEnd won't fire
      }
    };
    this.handleDragEnd = ev => {
      if (this.isDragging) {
        let initialContext = this.component.context;
        let initialView = initialContext.viewApi;
        let {
          receivingContext,
          validMutation
        } = this;
        let eventDef = this.eventRange.def;
        let eventInstance = this.eventRange.instance;
        let eventApi = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(initialContext, eventDef, eventInstance);
        let relevantEvents = this.relevantEvents;
        let mutatedRelevantEvents = this.mutatedRelevantEvents;
        let {
          finalHit
        } = this.hitDragging;
        this.clearDrag(); // must happen after revert animation
        initialContext.emitter.trigger('eventDragStop', {
          el: this.subjectEl,
          event: eventApi,
          jsEvent: ev.origEvent,
          view: initialView
        });
        if (validMutation) {
          // dropped within same calendar
          if (receivingContext === initialContext) {
            let updatedEventApi = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(initialContext, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
            initialContext.dispatch({
              type: 'MERGE_EVENTS',
              eventStore: mutatedRelevantEvents
            });
            let eventChangeArg = {
              oldEvent: eventApi,
              event: updatedEventApi,
              relatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, initialContext, eventInstance),
              revert() {
                initialContext.dispatch({
                  type: 'MERGE_EVENTS',
                  eventStore: relevantEvents // the pre-change data
                });
              }
            };
            let transformed = {};
            for (let transformer of initialContext.getCurrentData().pluginHooks.eventDropTransformers) {
              Object.assign(transformed, transformer(validMutation, initialContext));
            }
            initialContext.emitter.trigger('eventDrop', Object.assign(Object.assign(Object.assign({}, eventChangeArg), transformed), {
              el: ev.subjectEl,
              delta: validMutation.datesDelta,
              jsEvent: ev.origEvent,
              view: initialView
            }));
            initialContext.emitter.trigger('eventChange', eventChangeArg);
            // dropped in different calendar
          } else if (receivingContext) {
            let eventRemoveArg = {
              event: eventApi,
              relatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.w)(relevantEvents, initialContext, eventInstance),
              revert() {
                initialContext.dispatch({
                  type: 'MERGE_EVENTS',
                  eventStore: relevantEvents
                });
              }
            };
            initialContext.emitter.trigger('eventLeave', Object.assign(Object.assign({}, eventRemoveArg), {
              draggedEl: ev.subjectEl,
              view: initialView
            }));
            initialContext.dispatch({
              type: 'REMOVE_EVENTS',
              eventStore: relevantEvents
            });
            initialContext.emitter.trigger('eventRemove', eventRemoveArg);
            let addedEventDef = mutatedRelevantEvents.defs[eventDef.defId];
            let addedEventInstance = mutatedRelevantEvents.instances[eventInstance.instanceId];
            let addedEventApi = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(receivingContext, addedEventDef, addedEventInstance);
            receivingContext.dispatch({
              type: 'MERGE_EVENTS',
              eventStore: mutatedRelevantEvents
            });
            let eventAddArg = {
              event: addedEventApi,
              relatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, receivingContext, addedEventInstance),
              revert() {
                receivingContext.dispatch({
                  type: 'REMOVE_EVENTS',
                  eventStore: mutatedRelevantEvents
                });
              }
            };
            receivingContext.emitter.trigger('eventAdd', eventAddArg);
            if (ev.isTouch) {
              receivingContext.dispatch({
                type: 'SELECT_EVENT',
                eventInstanceId: eventInstance.instanceId
              });
            }
            receivingContext.emitter.trigger('drop', Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), {
              draggedEl: ev.subjectEl,
              jsEvent: ev.origEvent,
              view: finalHit.context.viewApi
            }));
            receivingContext.emitter.trigger('eventReceive', Object.assign(Object.assign({}, eventAddArg), {
              draggedEl: ev.subjectEl,
              view: finalHit.context.viewApi
            }));
          }
        } else {
          initialContext.emitter.trigger('_noEventDrop');
        }
      }
      this.cleanup();
    };
    let {
      component
    } = this;
    let {
      options
    } = component.context;
    let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
    dragging.pointer.selector = EventDragging.SELECTOR;
    dragging.touchScrollAllowed = false;
    dragging.autoScroller.isEnabled = options.dragScroll;
    let hitDragging = this.hitDragging = new HitDragging(this.dragging, _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a5);
    hitDragging.useSubjectCenter = settings.useEventCenter;
    hitDragging.emitter.on('pointerdown', this.handlePointerDown);
    hitDragging.emitter.on('dragstart', this.handleDragStart);
    hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
    hitDragging.emitter.on('pointerup', this.handlePointerUp);
    hitDragging.emitter.on('dragend', this.handleDragEnd);
  }
  destroy() {
    this.dragging.destroy();
  }
  // render a drag state on the next receivingCalendar
  displayDrag(nextContext, state) {
    let initialContext = this.component.context;
    let prevContext = this.receivingContext;
    // does the previous calendar need to be cleared?
    if (prevContext && prevContext !== nextContext) {
      // does the initial calendar need to be cleared?
      // if so, don't clear all the way. we still need to to hide the affectedEvents
      if (prevContext === initialContext) {
        prevContext.dispatch({
          type: 'SET_EVENT_DRAG',
          state: {
            affectedEvents: state.affectedEvents,
            mutatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
            isEvent: true
          }
        });
        // completely clear the old calendar if it wasn't the initial
      } else {
        prevContext.dispatch({
          type: 'UNSET_EVENT_DRAG'
        });
      }
    }
    if (nextContext) {
      nextContext.dispatch({
        type: 'SET_EVENT_DRAG',
        state
      });
    }
  }
  clearDrag() {
    let initialCalendar = this.component.context;
    let {
      receivingContext
    } = this;
    if (receivingContext) {
      receivingContext.dispatch({
        type: 'UNSET_EVENT_DRAG'
      });
    }
    // the initial calendar might have an dummy drag state from displayDrag
    if (initialCalendar !== receivingContext) {
      initialCalendar.dispatch({
        type: 'UNSET_EVENT_DRAG'
      });
    }
  }
  cleanup() {
    this.subjectSeg = null;
    this.isDragging = false;
    this.eventRange = null;
    this.relevantEvents = null;
    this.receivingContext = null;
    this.validMutation = null;
    this.mutatedRelevantEvents = null;
  }
}
// TODO: test this in IE11
// QUESTION: why do we need it on the resizable???
EventDragging.SELECTOR = '.fc-event-draggable, .fc-event-resizable';
function computeEventMutation(hit0, hit1, eventInstanceStart, massagers) {
  let dateSpan0 = hit0.dateSpan;
  let dateSpan1 = hit1.dateSpan;
  let date0 = dateSpan0.range.start;
  let date1 = dateSpan1.range.start;
  let standardProps = {};
  if (dateSpan0.allDay !== dateSpan1.allDay) {
    standardProps.allDay = dateSpan1.allDay;
    standardProps.hasEnd = hit1.context.options.allDayMaintainDuration;
    if (dateSpan1.allDay) {
      // means date1 is already start-of-day,
      // but date0 needs to be converted
      date0 = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.q)(eventInstanceStart);
    } else {
      // Moving from allDate->timed
      // Doesn't matter where on the event the drag began, mutate the event's start-date to date1
      date0 = eventInstanceStart;
    }
  }
  let delta = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ay)(date0, date1, hit0.context.dateEnv, hit0.componentId === hit1.componentId ? hit0.largeUnit : null);
  if (delta.milliseconds) {
    // has hours/minutes/seconds
    standardProps.allDay = false;
  }
  let mutation = {
    datesDelta: delta,
    standardProps
  };
  for (let massager of massagers) {
    massager(mutation, hit0, hit1);
  }
  return mutation;
}
function getComponentTouchDelay(component) {
  let {
    options
  } = component.context;
  let delay = options.eventLongPressDelay;
  if (delay == null) {
    delay = options.longPressDelay;
  }
  return delay;
}
class EventResizing extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.X {
  constructor(settings) {
    super(settings);
    // internal state
    this.draggingSegEl = null;
    this.draggingSeg = null; // TODO: rename to resizingSeg? subjectSeg?
    this.eventRange = null;
    this.relevantEvents = null;
    this.validMutation = null;
    this.mutatedRelevantEvents = null;
    this.handlePointerDown = ev => {
      let {
        component
      } = this;
      let segEl = this.querySegEl(ev);
      let seg = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);
      let eventRange = this.eventRange = seg.eventRange;
      this.dragging.minDistance = component.context.options.eventDragMinDistance;
      // if touch, need to be working with a selected event
      this.dragging.setIgnoreMove(!this.component.isValidSegDownEl(ev.origEvent.target) || ev.isTouch && this.component.props.eventSelection !== eventRange.instance.instanceId);
    };
    this.handleDragStart = ev => {
      let {
        context
      } = this.component;
      let eventRange = this.eventRange;
      this.relevantEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aT)(context.getCurrentData().eventStore, this.eventRange.instance.instanceId);
      let segEl = this.querySegEl(ev);
      this.draggingSegEl = segEl;
      this.draggingSeg = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Y)(segEl);
      context.calendarApi.unselect();
      context.emitter.trigger('eventResizeStart', {
        el: segEl,
        event: new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(context, eventRange.def, eventRange.instance),
        jsEvent: ev.origEvent,
        view: context.viewApi
      });
    };
    this.handleHitUpdate = (hit, isFinal, ev) => {
      let {
        context
      } = this.component;
      let relevantEvents = this.relevantEvents;
      let initialHit = this.hitDragging.initialHit;
      let eventInstance = this.eventRange.instance;
      let mutation = null;
      let mutatedRelevantEvents = null;
      let isInvalid = false;
      let interaction = {
        affectedEvents: relevantEvents,
        mutatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
        isEvent: true
      };
      if (hit) {
        let disallowed = hit.componentId === initialHit.componentId && this.isHitComboAllowed && !this.isHitComboAllowed(initialHit, hit);
        if (!disallowed) {
          mutation = computeMutation(initialHit, hit, ev.subjectEl.classList.contains('fc-event-resizer-start'), eventInstance.range);
        }
      }
      if (mutation) {
        mutatedRelevantEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bV)(relevantEvents, context.getCurrentData().eventUiBases, mutation, context);
        interaction.mutatedEvents = mutatedRelevantEvents;
        if (!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bX)(interaction, hit.dateProfile, context)) {
          isInvalid = true;
          mutation = null;
          mutatedRelevantEvents = null;
          interaction.mutatedEvents = null;
        }
      }
      if (mutatedRelevantEvents) {
        context.dispatch({
          type: 'SET_EVENT_RESIZE',
          state: interaction
        });
      } else {
        context.dispatch({
          type: 'UNSET_EVENT_RESIZE'
        });
      }
      if (!isInvalid) {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.au)();
      } else {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.av)();
      }
      if (!isFinal) {
        if (mutation && isHitsEqual(initialHit, hit)) {
          mutation = null;
        }
        this.validMutation = mutation;
        this.mutatedRelevantEvents = mutatedRelevantEvents;
      }
    };
    this.handleDragEnd = ev => {
      let {
        context
      } = this.component;
      let eventDef = this.eventRange.def;
      let eventInstance = this.eventRange.instance;
      let eventApi = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(context, eventDef, eventInstance);
      let relevantEvents = this.relevantEvents;
      let mutatedRelevantEvents = this.mutatedRelevantEvents;
      context.emitter.trigger('eventResizeStop', {
        el: this.draggingSegEl,
        event: eventApi,
        jsEvent: ev.origEvent,
        view: context.viewApi
      });
      if (this.validMutation) {
        let updatedEventApi = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(context, mutatedRelevantEvents.defs[eventDef.defId], eventInstance ? mutatedRelevantEvents.instances[eventInstance.instanceId] : null);
        context.dispatch({
          type: 'MERGE_EVENTS',
          eventStore: mutatedRelevantEvents
        });
        let eventChangeArg = {
          oldEvent: eventApi,
          event: updatedEventApi,
          relatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.w)(mutatedRelevantEvents, context, eventInstance),
          revert() {
            context.dispatch({
              type: 'MERGE_EVENTS',
              eventStore: relevantEvents // the pre-change events
            });
          }
        };
        context.emitter.trigger('eventResize', Object.assign(Object.assign({}, eventChangeArg), {
          el: this.draggingSegEl,
          startDelta: this.validMutation.startDelta || (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(0),
          endDelta: this.validMutation.endDelta || (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(0),
          jsEvent: ev.origEvent,
          view: context.viewApi
        }));
        context.emitter.trigger('eventChange', eventChangeArg);
      } else {
        context.emitter.trigger('_noEventResize');
      }
      // reset all internal state
      this.draggingSeg = null;
      this.relevantEvents = null;
      this.validMutation = null;
      // okay to keep eventInstance around. useful to set it in handlePointerDown
    };
    let {
      component
    } = settings;
    let dragging = this.dragging = new FeaturefulElementDragging(settings.el);
    dragging.pointer.selector = '.fc-event-resizer';
    dragging.touchScrollAllowed = false;
    dragging.autoScroller.isEnabled = component.context.options.dragScroll;
    let hitDragging = this.hitDragging = new HitDragging(this.dragging, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bE)(settings));
    hitDragging.emitter.on('pointerdown', this.handlePointerDown);
    hitDragging.emitter.on('dragstart', this.handleDragStart);
    hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
    hitDragging.emitter.on('dragend', this.handleDragEnd);
  }
  destroy() {
    this.dragging.destroy();
  }
  querySegEl(ev) {
    return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(ev.subjectEl, '.fc-event');
  }
}
function computeMutation(hit0, hit1, isFromStart, instanceRange) {
  let dateEnv = hit0.context.dateEnv;
  let date0 = hit0.dateSpan.range.start;
  let date1 = hit1.dateSpan.range.start;
  let delta = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ay)(date0, date1, dateEnv, hit0.largeUnit);
  if (isFromStart) {
    if (dateEnv.add(instanceRange.start, delta) < instanceRange.end) {
      return {
        startDelta: delta
      };
    }
  } else if (dateEnv.add(instanceRange.end, delta) > instanceRange.start) {
    return {
      endDelta: delta
    };
  }
  return null;
}
class UnselectAuto {
  constructor(context) {
    this.context = context;
    this.isRecentPointerDateSelect = false; // wish we could use a selector to detect date selection, but uses hit system
    this.matchesCancel = false;
    this.matchesEvent = false;
    this.onSelect = selectInfo => {
      if (selectInfo.jsEvent) {
        this.isRecentPointerDateSelect = true;
      }
    };
    this.onDocumentPointerDown = pev => {
      let unselectCancel = this.context.options.unselectCancel;
      let downEl = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aP)(pev.origEvent);
      this.matchesCancel = !!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(downEl, unselectCancel);
      this.matchesEvent = !!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.Z)(downEl, EventDragging.SELECTOR); // interaction started on an event?
    };
    this.onDocumentPointerUp = pev => {
      let {
        context
      } = this;
      let {
        documentPointer
      } = this;
      let calendarState = context.getCurrentData();
      // touch-scrolling should never unfocus any type of selection
      if (!documentPointer.wasTouchScroll) {
        if (calendarState.dateSelection &&
        // an existing date selection?
        !this.isRecentPointerDateSelect // a new pointer-initiated date selection since last onDocumentPointerUp?
        ) {
          let unselectAuto = context.options.unselectAuto;
          if (unselectAuto && (!unselectAuto || !this.matchesCancel)) {
            context.calendarApi.unselect(pev);
          }
        }
        if (calendarState.eventSelection &&
        // an existing event selected?
        !this.matchesEvent // interaction DIDN'T start on an event
        ) {
          context.dispatch({
            type: 'UNSELECT_EVENT'
          });
        }
      }
      this.isRecentPointerDateSelect = false;
    };
    let documentPointer = this.documentPointer = new PointerDragging(document);
    documentPointer.shouldIgnoreMove = true;
    documentPointer.shouldWatchScroll = false;
    documentPointer.emitter.on('pointerdown', this.onDocumentPointerDown);
    documentPointer.emitter.on('pointerup', this.onDocumentPointerUp);
    /*
    TODO: better way to know about whether there was a selection with the pointer
    */
    context.emitter.on('select', this.onSelect);
  }
  destroy() {
    this.context.emitter.off('select', this.onSelect);
    this.documentPointer.destroy();
  }
}
const OPTION_REFINERS = {
  fixedMirrorParent: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n
};
const LISTENER_REFINERS = {
  dateClick: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventDragStart: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventDragStop: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventDrop: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventResizeStart: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventResizeStop: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventResize: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  drop: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventReceive: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  eventLeave: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n
};

/*
Given an already instantiated draggable object for one-or-more elements,
Interprets any dragging as an attempt to drag an events that lives outside
of a calendar onto a calendar.
*/
class ExternalElementDragging {
  constructor(dragging, suppliedDragMeta) {
    this.receivingContext = null;
    this.droppableEvent = null; // will exist for all drags, even if create:false
    this.suppliedDragMeta = null;
    this.dragMeta = null;
    this.handleDragStart = ev => {
      this.dragMeta = this.buildDragMeta(ev.subjectEl);
    };
    this.handleHitUpdate = (hit, isFinal, ev) => {
      let {
        dragging
      } = this.hitDragging;
      let receivingContext = null;
      let droppableEvent = null;
      let isInvalid = false;
      let interaction = {
        affectedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
        mutatedEvents: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)(),
        isEvent: this.dragMeta.create
      };
      if (hit) {
        receivingContext = hit.context;
        if (this.canDropElOnCalendar(ev.subjectEl, receivingContext)) {
          droppableEvent = computeEventForDateSpan(hit.dateSpan, this.dragMeta, receivingContext);
          interaction.mutatedEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aU)(droppableEvent);
          isInvalid = !(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bX)(interaction, hit.dateProfile, receivingContext);
          if (isInvalid) {
            interaction.mutatedEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.H)();
            droppableEvent = null;
          }
        }
      }
      this.displayDrag(receivingContext, interaction);
      // show mirror if no already-rendered mirror element OR if we are shutting down the mirror (?)
      // TODO: wish we could somehow wait for dispatch to guarantee render
      dragging.setMirrorIsVisible(isFinal || !droppableEvent || !document.querySelector('.fc-event-mirror'));
      if (!isInvalid) {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.au)();
      } else {
        (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.av)();
      }
      if (!isFinal) {
        dragging.setMirrorNeedsRevert(!droppableEvent);
        this.receivingContext = receivingContext;
        this.droppableEvent = droppableEvent;
      }
    };
    this.handleDragEnd = pev => {
      let {
        receivingContext,
        droppableEvent
      } = this;
      this.clearDrag();
      if (receivingContext && droppableEvent) {
        let finalHit = this.hitDragging.finalHit;
        let finalView = finalHit.context.viewApi;
        let dragMeta = this.dragMeta;
        receivingContext.emitter.trigger('drop', Object.assign(Object.assign({}, buildDatePointApiWithContext(finalHit.dateSpan, receivingContext)), {
          draggedEl: pev.subjectEl,
          jsEvent: pev.origEvent,
          view: finalView
        }));
        if (dragMeta.create) {
          let addingEvents = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aU)(droppableEvent);
          receivingContext.dispatch({
            type: 'MERGE_EVENTS',
            eventStore: addingEvents
          });
          if (pev.isTouch) {
            receivingContext.dispatch({
              type: 'SELECT_EVENT',
              eventInstanceId: droppableEvent.instance.instanceId
            });
          }
          // signal that an external event landed
          receivingContext.emitter.trigger('eventReceive', {
            event: new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__._(receivingContext, droppableEvent.def, droppableEvent.instance),
            relatedEvents: [],
            revert() {
              receivingContext.dispatch({
                type: 'REMOVE_EVENTS',
                eventStore: addingEvents
              });
            },
            draggedEl: pev.subjectEl,
            view: finalView
          });
        }
      }
      this.receivingContext = null;
      this.droppableEvent = null;
    };
    let hitDragging = this.hitDragging = new HitDragging(dragging, _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a5);
    hitDragging.requireInitial = false; // will start outside of a component
    hitDragging.emitter.on('dragstart', this.handleDragStart);
    hitDragging.emitter.on('hitupdate', this.handleHitUpdate);
    hitDragging.emitter.on('dragend', this.handleDragEnd);
    this.suppliedDragMeta = suppliedDragMeta;
  }
  buildDragMeta(subjectEl) {
    if (typeof this.suppliedDragMeta === 'object') {
      return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bH)(this.suppliedDragMeta);
    }
    if (typeof this.suppliedDragMeta === 'function') {
      return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bH)(this.suppliedDragMeta(subjectEl));
    }
    return getDragMetaFromEl(subjectEl);
  }
  displayDrag(nextContext, state) {
    let prevContext = this.receivingContext;
    if (prevContext && prevContext !== nextContext) {
      prevContext.dispatch({
        type: 'UNSET_EVENT_DRAG'
      });
    }
    if (nextContext) {
      nextContext.dispatch({
        type: 'SET_EVENT_DRAG',
        state
      });
    }
  }
  clearDrag() {
    if (this.receivingContext) {
      this.receivingContext.dispatch({
        type: 'UNSET_EVENT_DRAG'
      });
    }
  }
  canDropElOnCalendar(el, receivingContext) {
    let dropAccept = receivingContext.options.dropAccept;
    if (typeof dropAccept === 'function') {
      return dropAccept.call(receivingContext.calendarApi, el);
    }
    if (typeof dropAccept === 'string' && dropAccept) {
      return Boolean((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aO)(el, dropAccept));
    }
    return true;
  }
}
// Utils for computing event store from the DragMeta
// ----------------------------------------------------------------------------------------------------
function computeEventForDateSpan(dateSpan, dragMeta, context) {
  let defProps = Object.assign({}, dragMeta.leftoverProps);
  for (let transform of context.pluginHooks.externalDefTransforms) {
    Object.assign(defProps, transform(dateSpan, dragMeta));
  }
  let {
    refined,
    extra
  } = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aj)(defProps, context);
  let def = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ai)(refined, extra, dragMeta.sourceId, dateSpan.allDay, context.options.forceEventDuration || Boolean(dragMeta.duration),
  // hasEnd
  context);
  let start = dateSpan.range.start;
  // only rely on time info if drop zone is all-day,
  // otherwise, we already know the time
  if (dateSpan.allDay && dragMeta.startTime) {
    start = context.dateEnv.add(start, dragMeta.startTime);
  }
  let end = dragMeta.duration ? context.dateEnv.add(start, dragMeta.duration) : (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cs)(dateSpan.allDay, start, context);
  let instance = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ah)(def.defId, {
    start,
    end
  });
  return {
    def,
    instance
  };
}
// Utils for extracting data from element
// ----------------------------------------------------------------------------------------------------
function getDragMetaFromEl(el) {
  let str = getEmbeddedElData(el, 'event');
  let obj = str ? JSON.parse(str) : {
    create: false
  }; // if no embedded data, assume no event creation
  return (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bH)(obj);
}
_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bG.dataAttrPrefix = '';
function getEmbeddedElData(el, name) {
  let prefix = _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bG.dataAttrPrefix;
  let prefixedName = (prefix ? prefix + '-' : '') + name;
  return el.getAttribute('data-' + prefixedName) || '';
}

/*
Makes an element (that is *external* to any calendar) draggable.
Can pass in data that determines how an event will be created when dropped onto a calendar.
Leverages FullCalendar's internal drag-n-drop functionality WITHOUT a third-party drag system.
*/
class ExternalDraggable {
  constructor(el, settings = {}) {
    this.handlePointerDown = ev => {
      let {
        dragging
      } = this;
      let {
        minDistance,
        longPressDelay
      } = this.settings;
      dragging.minDistance = minDistance != null ? minDistance : ev.isTouch ? 0 : _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.e.eventDragMinDistance;
      dragging.delay = ev.isTouch ?
      // TODO: eventually read eventLongPressDelay instead vvv
      longPressDelay != null ? longPressDelay : _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.e.longPressDelay : 0;
    };
    this.handleDragStart = ev => {
      if (ev.isTouch && this.dragging.delay && ev.subjectEl.classList.contains('fc-event')) {
        this.dragging.mirror.getMirrorEl().classList.add('fc-event-selected');
      }
    };
    this.settings = settings;
    let dragging = this.dragging = new FeaturefulElementDragging(el);
    dragging.touchScrollAllowed = false;
    if (settings.itemSelector != null) {
      dragging.pointer.selector = settings.itemSelector;
    }
    if (settings.appendTo != null) {
      dragging.mirror.parentNode = settings.appendTo; // TODO: write tests
    }
    dragging.emitter.on('pointerdown', this.handlePointerDown);
    dragging.emitter.on('dragstart', this.handleDragStart);
    new ExternalElementDragging(dragging, settings.eventData); // eslint-disable-line no-new
  }
  destroy() {
    this.dragging.destroy();
  }
}

/*
Detects when a *THIRD-PARTY* drag-n-drop system interacts with elements.
The third-party system is responsible for drawing the visuals effects of the drag.
This class simply monitors for pointer movements and fires events.
It also has the ability to hide the moving element (the "mirror") during the drag.
*/
class InferredElementDragging extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bF {
  constructor(containerEl) {
    super(containerEl);
    this.shouldIgnoreMove = false;
    this.mirrorSelector = '';
    this.currentMirrorEl = null;
    this.handlePointerDown = ev => {
      this.emitter.trigger('pointerdown', ev);
      if (!this.shouldIgnoreMove) {
        // fire dragstart right away. does not support delay or min-distance
        this.emitter.trigger('dragstart', ev);
      }
    };
    this.handlePointerMove = ev => {
      if (!this.shouldIgnoreMove) {
        this.emitter.trigger('dragmove', ev);
      }
    };
    this.handlePointerUp = ev => {
      this.emitter.trigger('pointerup', ev);
      if (!this.shouldIgnoreMove) {
        // fire dragend right away. does not support a revert animation
        this.emitter.trigger('dragend', ev);
      }
    };
    let pointer = this.pointer = new PointerDragging(containerEl);
    pointer.emitter.on('pointerdown', this.handlePointerDown);
    pointer.emitter.on('pointermove', this.handlePointerMove);
    pointer.emitter.on('pointerup', this.handlePointerUp);
  }
  destroy() {
    this.pointer.destroy();
  }
  setIgnoreMove(bool) {
    this.shouldIgnoreMove = bool;
  }
  setMirrorIsVisible(bool) {
    if (bool) {
      // restore a previously hidden element.
      // use the reference in case the selector class has already been removed.
      if (this.currentMirrorEl) {
        this.currentMirrorEl.style.visibility = '';
        this.currentMirrorEl = null;
      }
    } else {
      let mirrorEl = this.mirrorSelector
      // TODO: somehow query FullCalendars WITHIN shadow-roots
      ? document.querySelector(this.mirrorSelector) : null;
      if (mirrorEl) {
        this.currentMirrorEl = mirrorEl;
        mirrorEl.style.visibility = 'hidden';
      }
    }
  }
}

/*
Bridges third-party drag-n-drop systems with FullCalendar.
Must be instantiated and destroyed by caller.
*/
class ThirdPartyDraggable {
  constructor(containerOrSettings, settings) {
    let containerEl = document;
    if (
    // wish we could just test instanceof EventTarget, but doesn't work in IE11
    containerOrSettings === document || containerOrSettings instanceof Element) {
      containerEl = containerOrSettings;
      settings = settings || {};
    } else {
      settings = containerOrSettings || {};
    }
    let dragging = this.dragging = new InferredElementDragging(containerEl);
    if (typeof settings.itemSelector === 'string') {
      dragging.pointer.selector = settings.itemSelector;
    } else if (containerEl === document) {
      dragging.pointer.selector = '[data-event]';
    }
    if (typeof settings.mirrorSelector === 'string') {
      dragging.mirrorSelector = settings.mirrorSelector;
    }
    let externalDragging = new ExternalElementDragging(dragging, settings.eventData);
    // The hit-detection system requires that the dnd-mirror-element be pointer-events:none,
    // but this can't be guaranteed for third-party draggables, so disable
    externalDragging.hitDragging.disablePointCheck = true;
  }
  destroy() {
    this.dragging.destroy();
  }
}
var index = (0,_fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({
  name: '@fullcalendar/interaction',
  componentInteractions: [DateClicking, DateSelecting, EventDragging, EventResizing],
  calendarInteractions: [UnselectAuto],
  elementDraggingImpl: FeaturefulElementDragging,
  optionRefiners: OPTION_REFINERS,
  listenerRefiners: LISTENER_REFINERS
});


/***/ }),

/***/ 64342:
/*!**************************************************!*\
  !*** ./node_modules/@fullcalendar/list/index.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ index)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/index.js */ 46633);
/* harmony import */ var _internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./internal.js */ 42393);
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);




const OPTION_REFINERS = {
  listDayFormat: createFalsableFormatter,
  listDaySideFormat: createFalsableFormatter,
  noEventsClassNames: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  noEventsContent: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  noEventsDidMount: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n,
  noEventsWillUnmount: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.n
  // noEventsText is defined in base options
};
function createFalsableFormatter(input) {
  return input === false ? null : (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)(input);
}
var index = (0,_fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_1__.createPlugin)({
  name: '@fullcalendar/list',
  optionRefiners: OPTION_REFINERS,
  views: {
    list: {
      component: _internal_js__WEBPACK_IMPORTED_MODULE_2__.ListView,
      buttonTextKey: 'list',
      listDayFormat: {
        month: 'long',
        day: 'numeric',
        year: 'numeric'
      } // like "January 1, 2016"
    },
    listDay: {
      type: 'list',
      duration: {
        days: 1
      },
      listDayFormat: {
        weekday: 'long'
      } // day-of-week is all we need. full date is probably in headerToolbar
    },
    listWeek: {
      type: 'list',
      duration: {
        weeks: 1
      },
      listDayFormat: {
        weekday: 'long'
      },
      listDaySideFormat: {
        month: 'long',
        day: 'numeric',
        year: 'numeric'
      }
    },
    listMonth: {
      type: 'list',
      duration: {
        month: 1
      },
      listDaySideFormat: {
        weekday: 'long'
      } // day-of-week is nice-to-have
    },
    listYear: {
      type: 'list',
      duration: {
        year: 1
      },
      listDaySideFormat: {
        weekday: 'long'
      } // day-of-week is nice-to-have
    }
  }
});


/***/ }),

/***/ 42393:
/*!*****************************************************!*\
  !*** ./node_modules/@fullcalendar/list/internal.js ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ListView: () => (/* binding */ ListView)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);
/* harmony import */ var _fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact.js */ 78048);


class ListViewHeaderRow extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.state = {
      textId: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)()
    };
  }
  render() {
    let {
      theme,
      dateEnv,
      options,
      viewApi
    } = this.context;
    let {
      cellId,
      dayDate,
      todayRange
    } = this.props;
    let {
      textId
    } = this.state;
    let dayMeta = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aY)(dayDate, todayRange);
    // will ever be falsy?
    let text = options.listDayFormat ? dateEnv.format(dayDate, options.listDayFormat) : '';
    // will ever be falsy? also, BAD NAME "alt"
    let sideText = options.listDaySideFormat ? dateEnv.format(dayDate, options.listDaySideFormat) : '';
    let renderProps = Object.assign({
      date: dateEnv.toDate(dayDate),
      view: viewApi,
      textId,
      text,
      sideText,
      navLinkAttrs: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a_)(this.context, dayDate),
      sideNavLinkAttrs: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a_)(this.context, dayDate, 'day', false)
    }, dayMeta);
    // TODO: make a reusable HOC for dayHeader (used in daygrid/timegrid too)
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
      elTag: "tr",
      elClasses: ['fc-list-day', ...(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aX)(dayMeta, theme)],
      elAttrs: {
        'data-date': (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bt)(dayDate)
      },
      renderProps: renderProps,
      generatorName: "dayHeaderContent",
      customGenerator: options.dayHeaderContent,
      defaultGenerator: renderInnerContent,
      classNameGenerator: options.dayHeaderClassNames,
      didMount: options.dayHeaderDidMount,
      willUnmount: options.dayHeaderWillUnmount
    }, InnerContent =>
    // TODO: force-hide top border based on :first-child
    (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("th", {
      scope: "colgroup",
      colSpan: 3,
      id: cellId,
      "aria-labelledby": textId
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-list-day-cushion', theme.getClass('tableCellShaded')]
    })));
  }
}
function renderInnerContent(props) {
  return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, props.text && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("a", Object.assign({
    id: props.textId,
    className: "fc-list-day-text"
  }, props.navLinkAttrs), props.text), props.sideText && (/* not keyboard tabbable */(0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("a", Object.assign({
    "aria-hidden": true,
    className: "fc-list-day-side-text"
  }, props.sideNavLinkAttrs), props.sideText)));
}
const DEFAULT_TIME_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  hour: 'numeric',
  minute: '2-digit',
  meridiem: 'short'
});
class ListViewEventRow extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let {
      seg,
      timeHeaderId,
      eventHeaderId,
      dateHeaderId
    } = props;
    let timeFormat = options.eventTimeFormat || DEFAULT_TIME_FORMAT;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ck, Object.assign({}, props, {
      elTag: "tr",
      elClasses: ['fc-list-event', seg.eventRange.def.url && 'fc-event-forced-url'],
      defaultGenerator: () => renderEventInnerContent(seg, context) /* weird */,
      seg: seg,
      timeText: "",
      disableDragging: true,
      disableResizing: true
    }), (InnerContent, eventContentArg) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
      "aria-hidden": true,
      className: "fc-list-event-graphic"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("span", {
      className: "fc-list-event-dot",
      style: {
        borderColor: eventContentArg.borderColor || eventContentArg.backgroundColor
      }
    })), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "td",
      elClasses: ['fc-list-event-title'],
      elAttrs: {
        headers: `${eventHeaderId} ${dateHeaderId}`
      }
    })));
  }
}
function renderEventInnerContent(seg, context) {
  let interactiveAttrs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bS)(seg, context);
  return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("a", Object.assign({}, interactiveAttrs), seg.eventRange.def.title);
}
function buildTimeContent(seg, timeFormat, context, timeHeaderId, dateHeaderId) {
  let {
    options
  } = context;
  if (options.displayEventTime !== false) {
    let eventDef = seg.eventRange.def;
    let eventInstance = seg.eventRange.instance;
    let doAllDay = false;
    let timeText;
    if (eventDef.allDay) {
      doAllDay = true;
    } else if ((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ax)(seg.eventRange.range)) {
      // TODO: use (!isStart || !isEnd) instead?
      if (seg.isStart) {
        timeText = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bO)(seg, timeFormat, context, null, null, eventInstance.range.start, seg.end);
      } else if (seg.isEnd) {
        timeText = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bO)(seg, timeFormat, context, null, null, seg.start, eventInstance.range.end);
      } else {
        doAllDay = true;
      }
    } else {
      timeText = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bO)(seg, timeFormat, context);
    }
    if (doAllDay) {
      let renderProps = {
        text: context.options.allDayText,
        view: context.viewApi
      };
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
        elTag: "td",
        elClasses: ['fc-list-event-time'],
        elAttrs: {
          headers: `${timeHeaderId} ${dateHeaderId}`
        },
        renderProps: renderProps,
        generatorName: "allDayContent",
        customGenerator: options.allDayContent,
        defaultGenerator: renderAllDayInner,
        classNameGenerator: options.allDayClassNames,
        didMount: options.allDayDidMount,
        willUnmount: options.allDayWillUnmount
      });
    }
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
      className: "fc-list-event-time"
    }, timeText);
  }
  return null;
}
function renderAllDayInner(renderProps) {
  return renderProps.text;
}

/*
Responsible for the scroller, and forwarding event-related actions into the "grid".
*/
class ListView extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.computeDateVars = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(computeDateVars);
    this.eventStoreToSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(this._eventStoreToSegs);
    this.state = {
      timeHeaderId: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)(),
      eventHeaderId: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)(),
      dateHeaderIdRoot: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)()
    };
    this.setRootEl = rootEl => {
      if (rootEl) {
        this.context.registerInteractiveComponent(this, {
          el: rootEl
        });
      } else {
        this.context.unregisterInteractiveComponent(this);
      }
    };
  }
  render() {
    let {
      props,
      context
    } = this;
    let {
      dayDates,
      dayRanges
    } = this.computeDateVars(props.dateProfile);
    let eventSegs = this.eventStoreToSegs(props.eventStore, props.eventUiBases, dayRanges);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elRef: this.setRootEl,
      elClasses: ['fc-list', context.theme.getClass('table'), context.options.stickyHeaderDates !== false ? 'fc-list-sticky' : ''],
      viewSpec: context.viewSpec
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cb, {
      liquid: !props.isHeightAuto,
      overflowX: props.isHeightAuto ? 'visible' : 'hidden',
      overflowY: props.isHeightAuto ? 'visible' : 'auto'
    }, eventSegs.length > 0 ? this.renderSegList(eventSegs, dayDates) : this.renderEmptyMessage()));
  }
  renderEmptyMessage() {
    let {
      options,
      viewApi
    } = this.context;
    let renderProps = {
      text: options.noEventsText,
      view: viewApi
    };
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
      elTag: "div",
      elClasses: ['fc-list-empty'],
      renderProps: renderProps,
      generatorName: "noEventsContent",
      customGenerator: options.noEventsContent,
      defaultGenerator: renderNoEventsInner,
      classNameGenerator: options.noEventsClassNames,
      didMount: options.noEventsDidMount,
      willUnmount: options.noEventsWillUnmount
    }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-list-empty-cushion']
    }));
  }
  renderSegList(allSegs, dayDates) {
    let {
      theme,
      options
    } = this.context;
    let {
      timeHeaderId,
      eventHeaderId,
      dateHeaderIdRoot
    } = this.state;
    let segsByDay = groupSegsByDay(allSegs); // sparse array
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a6, {
      unit: "day"
    }, (nowDate, todayRange) => {
      let innerNodes = [];
      for (let dayIndex = 0; dayIndex < segsByDay.length; dayIndex += 1) {
        let daySegs = segsByDay[dayIndex];
        if (daySegs) {
          // sparse array, so might be undefined
          let dayStr = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bt)(dayDates[dayIndex]);
          let dateHeaderId = dateHeaderIdRoot + '-' + dayStr;
          // append a day header
          innerNodes.push((0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(ListViewHeaderRow, {
            key: dayStr,
            cellId: dateHeaderId,
            dayDate: dayDates[dayIndex],
            todayRange: todayRange
          }));
          daySegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bP)(daySegs, options.eventOrder);
          for (let seg of daySegs) {
            innerNodes.push((0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(ListViewEventRow, Object.assign({
              key: dayStr + ':' + seg.eventRange.instance.instanceId /* are multiple segs for an instanceId */,
              seg: seg,
              isDragging: false,
              isResizing: false,
              isDateSelecting: false,
              isSelected: false,
              timeHeaderId: timeHeaderId,
              eventHeaderId: eventHeaderId,
              dateHeaderId: dateHeaderId
            }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange, nowDate))));
          }
        }
      }
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("table", {
        className: 'fc-list-table ' + theme.getClass('table')
      }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("thead", null, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", null, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("th", {
        scope: "col",
        id: timeHeaderId
      }, options.timeHint), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("th", {
        scope: "col",
        "aria-hidden": true
      }), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("th", {
        scope: "col",
        id: eventHeaderId
      }, options.eventHint))), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tbody", null, innerNodes));
    });
  }
  _eventStoreToSegs(eventStore, eventUiBases, dayRanges) {
    return this.eventRangesToSegs((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ad)(eventStore, eventUiBases, this.props.dateProfile.activeRange, this.context.options.nextDayThreshold).fg, dayRanges);
  }
  eventRangesToSegs(eventRanges, dayRanges) {
    let segs = [];
    for (let eventRange of eventRanges) {
      segs.push(...this.eventRangeToSegs(eventRange, dayRanges));
    }
    return segs;
  }
  eventRangeToSegs(eventRange, dayRanges) {
    let {
      dateEnv
    } = this.context;
    let {
      nextDayThreshold
    } = this.context.options;
    let range = eventRange.range;
    let allDay = eventRange.def.allDay;
    let dayIndex;
    let segRange;
    let seg;
    let segs = [];
    for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex += 1) {
      segRange = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.o)(range, dayRanges[dayIndex]);
      if (segRange) {
        seg = {
          component: this,
          eventRange,
          start: segRange.start,
          end: segRange.end,
          isStart: eventRange.isStart && segRange.start.valueOf() === range.start.valueOf(),
          isEnd: eventRange.isEnd && segRange.end.valueOf() === range.end.valueOf(),
          dayIndex
        };
        segs.push(seg);
        // detect when range won't go fully into the next day,
        // and mutate the latest seg to the be the end.
        if (!seg.isEnd && !allDay && dayIndex + 1 < dayRanges.length && range.end < dateEnv.add(dayRanges[dayIndex + 1].start, nextDayThreshold)) {
          seg.end = range.end;
          seg.isEnd = true;
          break;
        }
      }
    }
    return segs;
  }
}
function renderNoEventsInner(renderProps) {
  return renderProps.text;
}
function computeDateVars(dateProfile) {
  let dayStart = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.q)(dateProfile.renderRange.start);
  let viewEnd = dateProfile.renderRange.end;
  let dayDates = [];
  let dayRanges = [];
  while (dayStart < viewEnd) {
    dayDates.push(dayStart);
    dayRanges.push({
      start: dayStart,
      end: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayStart, 1)
    });
    dayStart = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.t)(dayStart, 1);
  }
  return {
    dayDates,
    dayRanges
  };
}
// Returns a sparse array of arrays, segs grouped by their dayIndex
function groupSegsByDay(segs) {
  let segsByDay = []; // sparse array
  let i;
  let seg;
  for (i = 0; i < segs.length; i += 1) {
    seg = segs[i];
    (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = [])).push(seg);
  }
  return segsByDay;
}
var css_248z = ":root{--fc-list-event-dot-width:10px;--fc-list-event-hover-bg-color:#f5f5f5}.fc-theme-standard .fc-list{border:1px solid var(--fc-border-color)}.fc .fc-list-empty{align-items:center;background-color:var(--fc-neutral-bg-color);display:flex;height:100%;justify-content:center}.fc .fc-list-empty-cushion{margin:5em 0}.fc .fc-list-table{border-style:hidden;width:100%}.fc .fc-list-table tr>*{border-left:0;border-right:0}.fc .fc-list-sticky .fc-list-day>*{background:var(--fc-page-bg-color);position:sticky;top:0}.fc .fc-list-table thead{left:-10000px;position:absolute}.fc .fc-list-table tbody>tr:first-child th{border-top:0}.fc .fc-list-table th{padding:0}.fc .fc-list-day-cushion,.fc .fc-list-table td{padding:8px 14px}.fc .fc-list-day-cushion:after{clear:both;content:\"\";display:table}.fc-theme-standard .fc-list-day-cushion{background-color:var(--fc-neutral-bg-color)}.fc-direction-ltr .fc-list-day-text,.fc-direction-rtl .fc-list-day-side-text{float:left}.fc-direction-ltr .fc-list-day-side-text,.fc-direction-rtl .fc-list-day-text{float:right}.fc-direction-ltr .fc-list-table .fc-list-event-graphic{padding-right:0}.fc-direction-rtl .fc-list-table .fc-list-event-graphic{padding-left:0}.fc .fc-list-event.fc-event-forced-url{cursor:pointer}.fc .fc-list-event:hover td{background-color:var(--fc-list-event-hover-bg-color)}.fc .fc-list-event-graphic,.fc .fc-list-event-time{white-space:nowrap;width:1px}.fc .fc-list-event-dot{border:calc(var(--fc-list-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-list-event-dot-width)/2);box-sizing:content-box;display:inline-block;height:0;width:0}.fc .fc-list-event-title a{color:inherit;text-decoration:none}.fc .fc-list-event.fc-event-forced-url:hover a{text-decoration:underline}";
(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ct)(css_248z);


/***/ }),

/***/ 43951:
/*!********************************************************!*\
  !*** ./node_modules/@fullcalendar/multimonth/index.js ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ index)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @fullcalendar/core/index.js */ 46633);
/* harmony import */ var _fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/daygrid/internal.js */ 78107);
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);
/* harmony import */ var _fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fullcalendar/core/preact.js */ 78048);




class SingleMonth extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.buildDayTableModel = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(_fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__.buildDayTableModel);
    this.slicer = new _fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__.DayTableSlicer();
    this.state = {
      labelId: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a3)()
    };
  }
  render() {
    const {
      props,
      state,
      context
    } = this;
    const {
      dateProfile,
      forPrint
    } = props;
    const {
      options
    } = context;
    const dayTableModel = this.buildDayTableModel(dateProfile, context.dateProfileGenerator);
    const slicedProps = this.slicer.sliceProps(props, dateProfile, options.nextDayThreshold, context, dayTableModel);
    // ensure single-month has aspect ratio
    const tableHeight = props.tableWidth != null ? props.tableWidth / options.aspectRatio : null;
    const rowCnt = dayTableModel.cells.length;
    const rowHeight = tableHeight != null ? tableHeight / rowCnt : null;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("div", {
      ref: props.elRef,
      "data-date": props.isoDateStr,
      className: "fc-multimonth-month",
      style: {
        width: props.width
      },
      role: "grid",
      "aria-labelledby": state.labelId
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("div", {
      className: "fc-multimonth-header",
      style: {
        marginBottom: rowHeight
      },
      role: "presentation"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("div", {
      className: "fc-multimonth-title",
      id: state.labelId
    }, context.dateEnv.format(props.dateProfile.currentRange.start, props.titleFormat)), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("table", {
      className: ['fc-multimonth-header-table', context.theme.getClass('table')].join(' '),
      role: "presentation"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("thead", {
      role: "rowgroup"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bI, {
      dateProfile: props.dateProfile,
      dates: dayTableModel.headerDates,
      datesRepDistinctDays: false
    })))), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("div", {
      className: ['fc-multimonth-daygrid', 'fc-daygrid', 'fc-daygrid-body', !forPrint && 'fc-daygrid-body-balanced', forPrint && 'fc-daygrid-body-unbalanced', forPrint && 'fc-daygrid-body-natural'].join(' '),
      style: {
        marginTop: -rowHeight
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("table", {
      className: ['fc-multimonth-daygrid-table', context.theme.getClass('table')].join(' '),
      style: {
        height: forPrint ? '' : tableHeight
      },
      role: "presentation"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)("tbody", {
      role: "rowgroup"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)(_fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__.TableRows, Object.assign({}, slicedProps, {
      dateProfile: dateProfile,
      cells: dayTableModel.cells,
      eventSelection: props.eventSelection,
      dayMaxEvents: !forPrint,
      dayMaxEventRows: !forPrint,
      showWeekNumbers: options.weekNumbers,
      clientWidth: props.clientWidth,
      clientHeight: props.clientHeight,
      forPrint: forPrint
    }))))));
  }
}
class MultiMonthView extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.splitDateProfileByMonth = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitDateProfileByMonth);
    this.buildMonthFormat = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildMonthFormat);
    this.scrollElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createRef)();
    this.firstMonthElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createRef)();
    this.needsScrollReset = false;
    this.handleSizing = isForced => {
      if (isForced) {
        this.updateSize();
      }
    };
  }
  render() {
    const {
      context,
      props,
      state
    } = this;
    const {
      options
    } = context;
    const {
      clientWidth,
      clientHeight
    } = state;
    const monthHPadding = state.monthHPadding || 0;
    const colCount = Math.min(clientWidth != null ? Math.floor(clientWidth / (options.multiMonthMinWidth + monthHPadding)) : 1, options.multiMonthMaxColumns) || 1;
    const monthWidthPct = 100 / colCount + '%';
    const monthTableWidth = clientWidth == null ? null : clientWidth / colCount - monthHPadding;
    const isLegitSingleCol = clientWidth != null && colCount === 1;
    const monthDateProfiles = this.splitDateProfileByMonth(context.dateProfileGenerator, props.dateProfile, context.dateEnv, isLegitSingleCol ? false : options.fixedWeekCount, options.showNonCurrentDates);
    const monthTitleFormat = this.buildMonthFormat(options.multiMonthTitleFormat, monthDateProfiles);
    const rootClassNames = ['fc-multimonth', isLegitSingleCol ? 'fc-multimonth-singlecol' : 'fc-multimonth-multicol', monthTableWidth != null && monthTableWidth < 400 ? 'fc-multimonth-compact' : '', props.isHeightAuto ? '' : 'fc-scroller' // for AutoScroller
    ];
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elRef: this.scrollElRef,
      elClasses: rootClassNames,
      viewSpec: context.viewSpec
    }, monthDateProfiles.map((monthDateProfile, i) => {
      const monthStr = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bv)(monthDateProfile.currentRange.start);
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_2__.createElement)(SingleMonth, Object.assign({}, props, {
        key: monthStr,
        isoDateStr: monthStr,
        elRef: i === 0 ? this.firstMonthElRef : undefined,
        titleFormat: monthTitleFormat,
        dateProfile: monthDateProfile,
        width: monthWidthPct,
        tableWidth: monthTableWidth,
        clientWidth: clientWidth,
        clientHeight: clientHeight
      }));
    }));
  }
  componentDidMount() {
    this.updateSize();
    this.context.addResizeHandler(this.handleSizing);
    this.requestScrollReset();
  }
  componentDidUpdate(prevProps) {
    if (!(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.E)(prevProps, this.props)) {
      // an external change?
      this.handleSizing(false);
    }
    if (prevProps.dateProfile !== this.props.dateProfile) {
      this.requestScrollReset();
    } else {
      this.flushScrollReset();
    }
  }
  componentWillUnmount() {
    this.context.removeResizeHandler(this.handleSizing);
  }
  updateSize() {
    const scrollEl = this.scrollElRef.current;
    const firstMonthEl = this.firstMonthElRef.current;
    if (scrollEl) {
      this.setState({
        clientWidth: scrollEl.clientWidth,
        clientHeight: scrollEl.clientHeight
      });
    }
    if (firstMonthEl && scrollEl) {
      if (this.state.monthHPadding == null) {
        // always remember initial non-zero value
        this.setState({
          monthHPadding: scrollEl.clientWidth -
          // go within padding
          firstMonthEl.firstChild.offsetWidth
        });
      }
    }
  }
  requestScrollReset() {
    this.needsScrollReset = true;
    this.flushScrollReset();
  }
  flushScrollReset() {
    if (this.needsScrollReset && this.state.monthHPadding != null // indicates sizing already happened
    ) {
      const {
        currentDate
      } = this.props.dateProfile;
      const scrollEl = this.scrollElRef.current;
      const monthEl = scrollEl.querySelector(`[data-date="${(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bv)(currentDate)}"]`);
      scrollEl.scrollTop = monthEl.getBoundingClientRect().top - this.firstMonthElRef.current.getBoundingClientRect().top;
      this.needsScrollReset = false;
    }
  }
  // workaround for when queued setState render (w/ clientWidth) gets cancelled because
  // subsequent update and shouldComponentUpdate says not to render :(
  shouldComponentUpdate() {
    return true;
  }
}
// date profile
// -------------------------------------------------------------------------------------------------
const oneMonthDuration = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(1, 'month');
function splitDateProfileByMonth(dateProfileGenerator, dateProfile, dateEnv, fixedWeekCount, showNonCurrentDates) {
  const {
    start,
    end
  } = dateProfile.currentRange;
  let monthStart = start;
  const monthDateProfiles = [];
  while (monthStart.valueOf() < end.valueOf()) {
    const monthEnd = dateEnv.add(monthStart, oneMonthDuration);
    const currentRange = {
      // yuck
      start: dateProfileGenerator.skipHiddenDays(monthStart),
      end: dateProfileGenerator.skipHiddenDays(monthEnd, -1, true)
    };
    let renderRange = (0,_fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__.buildDayTableRenderRange)({
      currentRange,
      snapToWeek: true,
      fixedWeekCount,
      dateEnv
    });
    renderRange = {
      // yuck
      start: dateProfileGenerator.skipHiddenDays(renderRange.start),
      end: dateProfileGenerator.skipHiddenDays(renderRange.end, -1, true)
    };
    const activeRange = dateProfile.activeRange ? (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.o)(dateProfile.activeRange, showNonCurrentDates ? renderRange : currentRange) : null;
    monthDateProfiles.push({
      currentDate: dateProfile.currentDate,
      isValid: dateProfile.isValid,
      validRange: dateProfile.validRange,
      renderRange,
      activeRange,
      currentRange,
      currentRangeUnit: 'month',
      isRangeAllDay: true,
      dateIncrement: dateProfile.dateIncrement,
      slotMinTime: dateProfile.slotMaxTime,
      slotMaxTime: dateProfile.slotMinTime
    });
    monthStart = monthEnd;
  }
  return monthDateProfiles;
}
// date formatting
// -------------------------------------------------------------------------------------------------
const YEAR_MONTH_FORMATTER = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  year: 'numeric',
  month: 'long'
});
const YEAR_FORMATTER = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  month: 'long'
});
function buildMonthFormat(formatOverride, monthDateProfiles) {
  return formatOverride || (monthDateProfiles[0].currentRange.start.getUTCFullYear() !== monthDateProfiles[monthDateProfiles.length - 1].currentRange.start.getUTCFullYear() ? YEAR_MONTH_FORMATTER : YEAR_FORMATTER);
}
const OPTION_REFINERS = {
  multiMonthTitleFormat: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x,
  multiMonthMaxColumns: Number,
  multiMonthMinWidth: Number
};
var css_248z = ".fc .fc-multimonth{border:1px solid var(--fc-border-color);display:flex;flex-wrap:wrap;overflow-x:hidden;overflow-y:auto}.fc .fc-multimonth-title{font-size:1.2em;font-weight:700;padding:1em 0;text-align:center}.fc .fc-multimonth-daygrid{background:var(--fc-page-bg-color)}.fc .fc-multimonth-daygrid-table,.fc .fc-multimonth-header-table{table-layout:fixed;width:100%}.fc .fc-multimonth-daygrid-table{border-top-style:hidden!important}.fc .fc-multimonth-singlecol .fc-multimonth{position:relative}.fc .fc-multimonth-singlecol .fc-multimonth-header{background:var(--fc-page-bg-color);position:relative;top:0;z-index:2}.fc .fc-multimonth-singlecol .fc-multimonth-daygrid{position:relative;z-index:1}.fc .fc-multimonth-singlecol .fc-multimonth-daygrid-table,.fc .fc-multimonth-singlecol .fc-multimonth-header-table{border-left-style:hidden;border-right-style:hidden}.fc .fc-multimonth-singlecol .fc-multimonth-month:last-child .fc-multimonth-daygrid-table{border-bottom-style:hidden}.fc .fc-multimonth-multicol{line-height:1}.fc .fc-multimonth-multicol .fc-multimonth-month{padding:0 1.2em 1.2em}.fc .fc-multimonth-multicol .fc-daygrid-more-link{border:1px solid var(--fc-event-border-color);display:block;float:none;padding:1px}.fc .fc-multimonth-compact{line-height:1}.fc .fc-multimonth-compact .fc-multimonth-daygrid-table,.fc .fc-multimonth-compact .fc-multimonth-header-table{font-size:.9em}.fc-media-screen .fc-multimonth-singlecol .fc-multimonth-header{position:sticky}.fc-media-print .fc-multimonth{overflow:visible}";
(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ct)(css_248z);
var index = (0,_fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_3__.createPlugin)({
  name: '@fullcalendar/multimonth',
  initialView: 'multiMonthYear',
  optionRefiners: OPTION_REFINERS,
  views: {
    multiMonth: {
      component: MultiMonthView,
      dateProfileGeneratorClass: _fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_1__.TableDateProfileGenerator,
      multiMonthMinWidth: 350,
      multiMonthMaxColumns: 3
    },
    multiMonthYear: {
      type: 'multiMonth',
      duration: {
        years: 1
      },
      fixedWeekCount: true,
      showNonCurrentDates: false
    }
  }
});


/***/ }),

/***/ 76863:
/*!******************************************************!*\
  !*** ./node_modules/@fullcalendar/timegrid/index.js ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ index)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/index.js */ 46633);
/* harmony import */ var _internal_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./internal.js */ 60022);





const OPTION_REFINERS = {
  allDaySlot: Boolean
};
var index = (0,_fullcalendar_core_index_js__WEBPACK_IMPORTED_MODULE_0__.createPlugin)({
  name: '@fullcalendar/timegrid',
  initialView: 'timeGridWeek',
  optionRefiners: OPTION_REFINERS,
  views: {
    timeGrid: {
      component: _internal_js__WEBPACK_IMPORTED_MODULE_1__.DayTimeColsView,
      usesMinMaxTime: true,
      allDaySlot: true,
      slotDuration: '00:30:00',
      slotEventOverlap: true // a bad name. confused with overlap/constraint system
    },
    timeGridDay: {
      type: 'timeGrid',
      duration: {
        days: 1
      }
    },
    timeGridWeek: {
      type: 'timeGrid',
      duration: {
        weeks: 1
      }
    }
  }
});


/***/ }),

/***/ 60022:
/*!*********************************************************!*\
  !*** ./node_modules/@fullcalendar/timegrid/internal.js ***!
  \*********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   DayTimeCols: () => (/* binding */ DayTimeCols),
/* harmony export */   DayTimeColsSlicer: () => (/* binding */ DayTimeColsSlicer),
/* harmony export */   DayTimeColsView: () => (/* binding */ DayTimeColsView),
/* harmony export */   TimeCols: () => (/* binding */ TimeCols),
/* harmony export */   TimeColsSlatsCoords: () => (/* binding */ TimeColsSlatsCoords),
/* harmony export */   TimeColsView: () => (/* binding */ TimeColsView),
/* harmony export */   buildDayRanges: () => (/* binding */ buildDayRanges),
/* harmony export */   buildSlatMetas: () => (/* binding */ buildSlatMetas),
/* harmony export */   buildTimeColsModel: () => (/* binding */ buildTimeColsModel)
/* harmony export */ });
/* harmony import */ var _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @fullcalendar/core/internal.js */ 3436);
/* harmony import */ var _fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @fullcalendar/core/preact.js */ 78048);
/* harmony import */ var _fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fullcalendar/daygrid/internal.js */ 78107);



class AllDaySplitter extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.aW {
  getKeyInfo() {
    return {
      allDay: {},
      timed: {}
    };
  }
  getKeysForDateSpan(dateSpan) {
    if (dateSpan.allDay) {
      return ['allDay'];
    }
    return ['timed'];
  }
  getKeysForEventDef(eventDef) {
    if (!eventDef.allDay) {
      return ['timed'];
    }
    if ((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bN)(eventDef)) {
      return ['timed', 'allDay'];
    }
    return ['allDay'];
  }
}
const DEFAULT_SLAT_LABEL_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  hour: 'numeric',
  minute: '2-digit',
  omitZeroMinute: true,
  meridiem: 'short'
});
function TimeColsAxisCell(props) {
  let classNames = ['fc-timegrid-slot', 'fc-timegrid-slot-label', props.isLabeled ? 'fc-scrollgrid-shrink' : 'fc-timegrid-slot-minor'];
  return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.V.Consumer, null, context => {
    if (!props.isLabeled) {
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
        className: classNames.join(' '),
        "data-time": props.isoTimeStr
      });
    }
    let {
      dateEnv,
      options,
      viewApi
    } = context;
    let labelFormat =
    // TODO: fully pre-parse
    options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : Array.isArray(options.slotLabelFormat) ? (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)(options.slotLabelFormat[0]) : (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)(options.slotLabelFormat);
    let renderProps = {
      level: 0,
      time: props.time,
      date: dateEnv.toDate(props.date),
      view: viewApi,
      text: dateEnv.format(props.date, labelFormat)
    };
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
      elTag: "td",
      elClasses: classNames,
      elAttrs: {
        'data-time': props.isoTimeStr
      },
      renderProps: renderProps,
      generatorName: "slotLabelContent",
      customGenerator: options.slotLabelContent,
      defaultGenerator: renderInnerContent,
      classNameGenerator: options.slotLabelClassNames,
      didMount: options.slotLabelDidMount,
      willUnmount: options.slotLabelWillUnmount
    }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-timegrid-slot-label-cushion', 'fc-scrollgrid-shrink-cushion']
    })));
  });
}
function renderInnerContent(props) {
  return props.text;
}
class TimeBodyAxis extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    return this.props.slatMetas.map(slatMeta => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
      key: slatMeta.key
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsAxisCell, Object.assign({}, slatMeta))));
  }
}
const DEFAULT_WEEK_NUM_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  week: 'short'
});
const AUTO_ALL_DAY_MAX_EVENT_ROWS = 5;
class TimeColsView extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.allDaySplitter = new AllDaySplitter(); // for use by subclasses
    this.headerElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.rootElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.scrollerElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.state = {
      slatCoords: null
    };
    this.handleScrollTopRequest = scrollTop => {
      let scrollerEl = this.scrollerElRef.current;
      if (scrollerEl) {
        // TODO: not sure how this could ever be null. weirdness with the reducer
        scrollerEl.scrollTop = scrollTop;
      }
    };
    /* Header Render Methods
    ------------------------------------------------------------------------------------------------------------------*/
    this.renderHeadAxis = (rowKey, frameHeight = '') => {
      let {
        options
      } = this.context;
      let {
        dateProfile
      } = this.props;
      let range = dateProfile.renderRange;
      let dayCnt = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bj)(range.start, range.end);
      // only do in day views (to avoid doing in week views that dont need it)
      let navLinkAttrs = dayCnt === 1 ? (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a_)(this.context, range.start, 'week') : {};
      if (options.weekNumbers && rowKey === 'day') {
        return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cn, {
          elTag: "th",
          elClasses: ['fc-timegrid-axis', 'fc-scrollgrid-shrink'],
          elAttrs: {
            'aria-hidden': true
          },
          date: range.start,
          defaultFormat: DEFAULT_WEEK_NUM_FORMAT
        }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          className: ['fc-timegrid-axis-frame', 'fc-scrollgrid-shrink-frame', 'fc-timegrid-axis-frame-liquid'].join(' '),
          style: {
            height: frameHeight
          }
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
          elTag: "a",
          elClasses: ['fc-timegrid-axis-cushion', 'fc-scrollgrid-shrink-cushion', 'fc-scrollgrid-sync-inner'],
          elAttrs: navLinkAttrs
        })));
      }
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("th", {
        "aria-hidden": true,
        className: "fc-timegrid-axis"
      }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
        className: "fc-timegrid-axis-frame",
        style: {
          height: frameHeight
        }
      }));
    };
    /* Table Component Render Methods
    ------------------------------------------------------------------------------------------------------------------*/
    // only a one-way height sync. we don't send the axis inner-content height to the DayGrid,
    // but DayGrid still needs to have classNames on inner elements in order to measure.
    this.renderTableRowAxis = rowHeight => {
      let {
        options,
        viewApi
      } = this.context;
      let renderProps = {
        text: options.allDayText,
        view: viewApi
      };
      return (
        // TODO: make reusable hook. used in list view too
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
          elTag: "td",
          elClasses: ['fc-timegrid-axis', 'fc-scrollgrid-shrink'],
          elAttrs: {
            'aria-hidden': true
          },
          renderProps: renderProps,
          generatorName: "allDayContent",
          customGenerator: options.allDayContent,
          defaultGenerator: renderAllDayInner,
          classNameGenerator: options.allDayClassNames,
          didMount: options.allDayDidMount,
          willUnmount: options.allDayWillUnmount
        }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          className: ['fc-timegrid-axis-frame', 'fc-scrollgrid-shrink-frame', rowHeight == null ? ' fc-timegrid-axis-frame-liquid' : ''].join(' '),
          style: {
            height: rowHeight
          }
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
          elTag: "span",
          elClasses: ['fc-timegrid-axis-cushion', 'fc-scrollgrid-shrink-cushion', 'fc-scrollgrid-sync-inner']
        })))
      );
    };
    this.handleSlatCoords = slatCoords => {
      this.setState({
        slatCoords
      });
    };
  }
  // rendering
  // ----------------------------------------------------------------------------------------------------
  renderSimpleLayout(headerRowContent, allDayContent, timeContent) {
    let {
      context,
      props
    } = this;
    let sections = [];
    let stickyHeaderDates = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ca)(context.options);
    if (headerRowContent) {
      sections.push({
        type: 'header',
        key: 'header',
        isSticky: stickyHeaderDates,
        chunk: {
          elRef: this.headerElRef,
          tableClassName: 'fc-col-header',
          rowContent: headerRowContent
        }
      });
    }
    if (allDayContent) {
      sections.push({
        type: 'body',
        key: 'all-day',
        chunk: {
          content: allDayContent
        }
      });
      sections.push({
        type: 'body',
        key: 'all-day-divider',
        outerContent:
        // TODO: rename to cellContent so don't need to define <tr>?
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
          role: "presentation",
          className: "fc-scrollgrid-section"
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
          className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded')
        }))
      });
    }
    sections.push({
      type: 'body',
      key: 'body',
      liquid: true,
      expandRows: Boolean(context.options.expandRows),
      chunk: {
        scrollerElRef: this.scrollerElRef,
        content: timeContent
      }
    });
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elRef: this.rootElRef,
      elClasses: ['fc-timegrid'],
      viewSpec: context.viewSpec
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bZ, {
      liquid: !props.isHeightAuto && !props.forPrint,
      collapsibleWidth: props.forPrint,
      cols: [{
        width: 'shrink'
      }],
      sections: sections
    }));
  }
  renderHScrollLayout(headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) {
    let ScrollGrid = this.context.pluginHooks.scrollGridImpl;
    if (!ScrollGrid) {
      throw new Error('No ScrollGrid implementation');
    }
    let {
      context,
      props
    } = this;
    let stickyHeaderDates = !props.forPrint && (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ca)(context.options);
    let stickyFooterScrollbar = !props.forPrint && (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.c9)(context.options);
    let sections = [];
    if (headerRowContent) {
      sections.push({
        type: 'header',
        key: 'header',
        isSticky: stickyHeaderDates,
        syncRowHeights: true,
        chunks: [{
          key: 'axis',
          rowContent: arg => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
            role: "presentation"
          }, this.renderHeadAxis('day', arg.rowSyncHeights[0]))
        }, {
          key: 'cols',
          elRef: this.headerElRef,
          tableClassName: 'fc-col-header',
          rowContent: headerRowContent
        }]
      });
    }
    if (allDayContent) {
      sections.push({
        type: 'body',
        key: 'all-day',
        syncRowHeights: true,
        chunks: [{
          key: 'axis',
          rowContent: contentArg => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
            role: "presentation"
          }, this.renderTableRowAxis(contentArg.rowSyncHeights[0]))
        }, {
          key: 'cols',
          content: allDayContent
        }]
      });
      sections.push({
        key: 'all-day-divider',
        type: 'body',
        outerContent:
        // TODO: rename to cellContent so don't need to define <tr>?
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
          role: "presentation",
          className: "fc-scrollgrid-section"
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
          colSpan: 2,
          className: 'fc-timegrid-divider ' + context.theme.getClass('tableCellShaded')
        }))
      });
    }
    let isNowIndicator = context.options.nowIndicator;
    sections.push({
      type: 'body',
      key: 'body',
      liquid: true,
      expandRows: Boolean(context.options.expandRows),
      chunks: [{
        key: 'axis',
        content: arg =>
        // TODO: make this now-indicator arrow more DRY with TimeColsContent
        (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          className: "fc-timegrid-axis-chunk"
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("table", {
          "aria-hidden": true,
          style: {
            height: arg.expandRows ? arg.clientHeight : ''
          }
        }, arg.tableColGroupNode, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tbody", null, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeBodyAxis, {
          slatMetas: slatMetas
        }))), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
          className: "fc-timegrid-now-indicator-container"
        }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a6, {
          unit: isNowIndicator ? 'minute' : 'day' /* hacky */
        }, nowDate => {
          let nowIndicatorTop = isNowIndicator && slatCoords && slatCoords.safeComputeTop(nowDate); // might return void
          if (typeof nowIndicatorTop === 'number') {
            return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ch, {
              elClasses: ['fc-timegrid-now-indicator-arrow'],
              elStyle: {
                top: nowIndicatorTop
              },
              isAxis: true,
              date: nowDate
            });
          }
          return null;
        })))
      }, {
        key: 'cols',
        scrollerElRef: this.scrollerElRef,
        content: timeContent
      }]
    });
    if (stickyFooterScrollbar) {
      sections.push({
        key: 'footer',
        type: 'footer',
        isSticky: true,
        chunks: [{
          key: 'axis',
          content: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.c8
        }, {
          key: 'cols',
          content: _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.c8
        }]
      });
    }
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cq, {
      elRef: this.rootElRef,
      elClasses: ['fc-timegrid'],
      viewSpec: context.viewSpec
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(ScrollGrid, {
      liquid: !props.isHeightAuto && !props.forPrint,
      forPrint: props.forPrint,
      collapsibleWidth: false,
      colGroups: [{
        width: 'shrink',
        cols: [{
          width: 'shrink'
        }]
      }, {
        cols: [{
          span: colCnt,
          minWidth: dayMinWidth
        }]
      }],
      sections: sections
    }));
  }
  /* Dimensions
  ------------------------------------------------------------------------------------------------------------------*/
  getAllDayMaxEventProps() {
    let {
      dayMaxEvents,
      dayMaxEventRows
    } = this.context.options;
    if (dayMaxEvents === true || dayMaxEventRows === true) {
      // is auto?
      dayMaxEvents = undefined;
      dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; // make sure "auto" goes to a real number
    }
    return {
      dayMaxEvents,
      dayMaxEventRows
    };
  }
}
function renderAllDayInner(renderProps) {
  return renderProps.text;
}
class TimeColsSlatsCoords {
  constructor(positions, dateProfile, slotDuration) {
    this.positions = positions;
    this.dateProfile = dateProfile;
    this.slotDuration = slotDuration;
  }
  safeComputeTop(date) {
    let {
      dateProfile
    } = this;
    if ((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.G)(dateProfile.currentRange, date)) {
      let startOfDayDate = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.q)(date);
      let timeMs = date.valueOf() - startOfDayDate.valueOf();
      if (timeMs >= (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(dateProfile.slotMinTime) && timeMs < (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(dateProfile.slotMaxTime)) {
        return this.computeTimeTop((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(timeMs));
      }
    }
    return null;
  }
  // Computes the top coordinate, relative to the bounds of the grid, of the given date.
  // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.
  computeDateTop(when, startOfDayDate) {
    if (!startOfDayDate) {
      startOfDayDate = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.q)(when);
    }
    return this.computeTimeTop((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(when.valueOf() - startOfDayDate.valueOf()));
  }
  // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
  // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform.
  // Eventually allow computation with arbirary slat dates.
  computeTimeTop(duration) {
    let {
      positions,
      dateProfile
    } = this;
    let len = positions.els.length;
    // floating-point value of # of slots covered
    let slatCoverage = (duration.milliseconds - (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(dateProfile.slotMinTime)) / (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(this.slotDuration);
    let slatIndex;
    let slatRemainder;
    // compute a floating-point number for how many slats should be progressed through.
    // from 0 to number of slats (inclusive)
    // constrained because slotMinTime/slotMaxTime might be customized.
    slatCoverage = Math.max(0, slatCoverage);
    slatCoverage = Math.min(len, slatCoverage);
    // an integer index of the furthest whole slat
    // from 0 to number slats (*exclusive*, so len-1)
    slatIndex = Math.floor(slatCoverage);
    slatIndex = Math.min(slatIndex, len - 1);
    // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
    // could be 1.0 if slatCoverage is covering *all* the slots
    slatRemainder = slatCoverage - slatIndex;
    return positions.tops[slatIndex] + positions.getHeight(slatIndex) * slatRemainder;
  }
}
class TimeColsSlatsBody extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let {
      slatElRefs
    } = props;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tbody", null, props.slatMetas.map((slatMeta, i) => {
      let renderProps = {
        time: slatMeta.time,
        date: context.dateEnv.toDate(slatMeta.date),
        view: context.viewApi
      };
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
        key: slatMeta.key,
        ref: slatElRefs.createRef(slatMeta.key)
      }, props.axis && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsAxisCell, Object.assign({}, slatMeta)), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.C, {
        elTag: "td",
        elClasses: ['fc-timegrid-slot', 'fc-timegrid-slot-lane', !slatMeta.isLabeled && 'fc-timegrid-slot-minor'],
        elAttrs: {
          'data-time': slatMeta.isoTimeStr
        },
        renderProps: renderProps,
        generatorName: "slotLaneContent",
        customGenerator: options.slotLaneContent,
        classNameGenerator: options.slotLaneClassNames,
        didMount: options.slotLaneDidMount,
        willUnmount: options.slotLaneWillUnmount
      }));
    }));
  }
}

/*
for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
*/
class TimeColsSlats extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.rootElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.slatElRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd();
  }
  render() {
    let {
      props,
      context
    } = this;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      ref: this.rootElRef,
      className: "fc-timegrid-slots"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("table", {
      "aria-hidden": true,
      className: context.theme.getClass('table'),
      style: {
        minWidth: props.tableMinWidth,
        width: props.clientWidth,
        height: props.minHeight
      }
    }, props.tableColGroupNode /* relies on there only being a single <col> for the axis */, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsSlatsBody, {
      slatElRefs: this.slatElRefs,
      axis: props.axis,
      slatMetas: props.slatMetas
    })));
  }
  componentDidMount() {
    this.updateSizing();
  }
  componentDidUpdate() {
    this.updateSizing();
  }
  componentWillUnmount() {
    if (this.props.onCoords) {
      this.props.onCoords(null);
    }
  }
  updateSizing() {
    let {
      context,
      props
    } = this;
    if (props.onCoords && props.clientWidth !== null // means sizing has stabilized
    ) {
      let rootEl = this.rootElRef.current;
      if (rootEl.offsetHeight) {
        // not hidden by css
        props.onCoords(new TimeColsSlatsCoords(new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration));
      }
    }
  }
}
function collectSlatEls(elMap, slatMetas) {
  return slatMetas.map(slatMeta => elMap[slatMeta.key]);
}
function splitSegsByCol(segs, colCnt) {
  let segsByCol = [];
  let i;
  for (i = 0; i < colCnt; i += 1) {
    segsByCol.push([]);
  }
  if (segs) {
    for (i = 0; i < segs.length; i += 1) {
      segsByCol[segs[i].col].push(segs[i]);
    }
  }
  return segsByCol;
}
function splitInteractionByCol(ui, colCnt) {
  let byRow = [];
  if (!ui) {
    for (let i = 0; i < colCnt; i += 1) {
      byRow[i] = null;
    }
  } else {
    for (let i = 0; i < colCnt; i += 1) {
      byRow[i] = {
        affectedInstances: ui.affectedInstances,
        isEvent: ui.isEvent,
        segs: []
      };
    }
    for (let seg of ui.segs) {
      byRow[seg.col].segs.push(seg);
    }
  }
  return byRow;
}
class TimeColMoreLink extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    let {
      props
    } = this;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.co, {
      elClasses: ['fc-timegrid-more-link'],
      elStyle: {
        top: props.top,
        bottom: props.bottom
      },
      allDayDate: null,
      moreCnt: props.hiddenSegs.length,
      allSegs: props.hiddenSegs,
      hiddenSegs: props.hiddenSegs,
      extraDateSpan: props.extraDateSpan,
      dateProfile: props.dateProfile,
      todayRange: props.todayRange,
      popoverContent: () => renderPlainFgSegs(props.hiddenSegs, props),
      defaultGenerator: renderMoreLinkInner,
      forceTimed: true
    }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-timegrid-more-link-inner', 'fc-sticky']
    }));
  }
}
function renderMoreLinkInner(props) {
  return props.shortText;
}

// segInputs assumed sorted
function buildPositioning(segInputs, strictOrder, maxStackCnt) {
  let hierarchy = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.by();
  if (strictOrder != null) {
    hierarchy.strictOrder = strictOrder;
  }
  if (maxStackCnt != null) {
    hierarchy.maxStackCnt = maxStackCnt;
  }
  let hiddenEntries = hierarchy.addSegs(segInputs);
  let hiddenGroups = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bC)(hiddenEntries);
  let web = buildWeb(hierarchy);
  web = stretchWeb(web, 1); // all levelCoords/thickness will have 0.0-1.0
  let segRects = webToRects(web);
  return {
    segRects,
    hiddenGroups
  };
}
function buildWeb(hierarchy) {
  const {
    entriesByLevel
  } = hierarchy;
  const buildNode = cacheable((level, lateral) => level + ':' + lateral, (level, lateral) => {
    let siblingRange = findNextLevelSegs(hierarchy, level, lateral);
    let nextLevelRes = buildNodes(siblingRange, buildNode);
    let entry = entriesByLevel[level][lateral];
    return [Object.assign(Object.assign({}, entry), {
      nextLevelNodes: nextLevelRes[0]
    }), entry.thickness + nextLevelRes[1] // the pressure builds
    ];
  });
  return buildNodes(entriesByLevel.length ? {
    level: 0,
    lateralStart: 0,
    lateralEnd: entriesByLevel[0].length
  } : null, buildNode)[0];
}
function buildNodes(siblingRange, buildNode) {
  if (!siblingRange) {
    return [[], 0];
  }
  let {
    level,
    lateralStart,
    lateralEnd
  } = siblingRange;
  let lateral = lateralStart;
  let pairs = [];
  while (lateral < lateralEnd) {
    pairs.push(buildNode(level, lateral));
    lateral += 1;
  }
  pairs.sort(cmpDescPressures);
  return [pairs.map(extractNode), pairs[0][1] // first item's pressure
  ];
}
function cmpDescPressures(a, b) {
  return b[1] - a[1];
}
function extractNode(a) {
  return a[0];
}
function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) {
  let {
    levelCoords,
    entriesByLevel
  } = hierarchy;
  let subjectEntry = entriesByLevel[subjectLevel][subjectLateral];
  let afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness;
  let levelCnt = levelCoords.length;
  let level = subjectLevel;
  // skip past levels that are too high up
  for (; level < levelCnt && levelCoords[level] < afterSubject; level += 1); // do nothing
  for (; level < levelCnt; level += 1) {
    let entries = entriesByLevel[level];
    let entry;
    let searchIndex = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bB)(entries, subjectEntry.span.start, _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bA);
    let lateralStart = searchIndex[0] + searchIndex[1]; // if exact match (which doesn't collide), go to next one
    let lateralEnd = lateralStart;
    while (
    // loop through entries that horizontally intersect
    (entry = entries[lateralEnd]) &&
    // but not past the whole seg list
    entry.span.start < subjectEntry.span.end) {
      lateralEnd += 1;
    }
    if (lateralStart < lateralEnd) {
      return {
        level,
        lateralStart,
        lateralEnd
      };
    }
  }
  return null;
}
function stretchWeb(topLevelNodes, totalThickness) {
  const stretchNode = cacheable((node, startCoord, prevThickness) => (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bz)(node), (node, startCoord, prevThickness) => {
    let {
      nextLevelNodes,
      thickness
    } = node;
    let allThickness = thickness + prevThickness;
    let thicknessFraction = thickness / allThickness;
    let endCoord;
    let newChildren = [];
    if (!nextLevelNodes.length) {
      endCoord = totalThickness;
    } else {
      for (let childNode of nextLevelNodes) {
        if (endCoord === undefined) {
          let res = stretchNode(childNode, startCoord, allThickness);
          endCoord = res[0];
          newChildren.push(res[1]);
        } else {
          let res = stretchNode(childNode, endCoord, 0);
          newChildren.push(res[1]);
        }
      }
    }
    let newThickness = (endCoord - startCoord) * thicknessFraction;
    return [endCoord - newThickness, Object.assign(Object.assign({}, node), {
      thickness: newThickness,
      nextLevelNodes: newChildren
    })];
  });
  return topLevelNodes.map(node => stretchNode(node, 0, 0)[1]);
}
// not sorted in any particular order
function webToRects(topLevelNodes) {
  let rects = [];
  const processNode = cacheable((node, levelCoord, stackDepth) => (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bz)(node), (node, levelCoord, stackDepth) => {
    let rect = Object.assign(Object.assign({}, node), {
      levelCoord,
      stackDepth,
      stackForward: 0
    });
    rects.push(rect);
    return rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1;
  });
  function processNodes(nodes, levelCoord, stackDepth) {
    let stackForward = 0;
    for (let node of nodes) {
      stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward);
    }
    return stackForward;
  }
  processNodes(topLevelNodes, 0, 0);
  return rects; // TODO: sort rects by levelCoord to be consistent with toRects?
}
// TODO: move to general util
function cacheable(keyFunc, workFunc) {
  const cache = {};
  return (...args) => {
    let key = keyFunc(...args);
    return key in cache ? cache[key] : cache[key] = workFunc(...args);
  };
}
function computeSegVCoords(segs, colDate, slatCoords = null, eventMinHeight = 0) {
  let vcoords = [];
  if (slatCoords) {
    for (let i = 0; i < segs.length; i += 1) {
      let seg = segs[i];
      let spanStart = slatCoords.computeDateTop(seg.start, colDate);
      let spanEnd = Math.max(spanStart + (eventMinHeight || 0),
      // :(
      slatCoords.computeDateTop(seg.end, colDate));
      vcoords.push({
        start: Math.round(spanStart),
        end: Math.round(spanEnd) //
      });
    }
  }
  return vcoords;
}
function computeFgSegPlacements(segs, segVCoords,
// might not have for every seg
eventOrderStrict, eventMaxStack) {
  let segInputs = [];
  let dumbSegs = []; // segs without coords
  for (let i = 0; i < segs.length; i += 1) {
    let vcoords = segVCoords[i];
    if (vcoords) {
      segInputs.push({
        index: i,
        thickness: 1,
        span: vcoords
      });
    } else {
      dumbSegs.push(segs[i]);
    }
  }
  let {
    segRects,
    hiddenGroups
  } = buildPositioning(segInputs, eventOrderStrict, eventMaxStack);
  let segPlacements = [];
  for (let segRect of segRects) {
    segPlacements.push({
      seg: segs[segRect.index],
      rect: segRect
    });
  }
  for (let dumbSeg of dumbSegs) {
    segPlacements.push({
      seg: dumbSeg,
      rect: null
    });
  }
  return {
    segPlacements,
    hiddenGroups
  };
}
const DEFAULT_TIME_FORMAT = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.x)({
  hour: 'numeric',
  minute: '2-digit',
  meridiem: false
});
class TimeColEvent extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  render() {
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cg, Object.assign({}, this.props, {
      elClasses: ['fc-timegrid-event', 'fc-v-event', this.props.isShort && 'fc-timegrid-event-short'],
      defaultTimeFormat: DEFAULT_TIME_FORMAT
    }));
  }
}
class TimeCol extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.sortEventSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bP);
  }
  // TODO: memoize event-placement?
  render() {
    let {
      props,
      context
    } = this;
    let {
      options
    } = context;
    let isSelectMirror = options.selectMirror;
    let mirrorSegs =
    // yuck
    props.eventDrag && props.eventDrag.segs || props.eventResize && props.eventResize.segs || isSelectMirror && props.dateSelectionSegs || [];
    let interactionAffectedInstances =
    // TODO: messy way to compute this
    props.eventDrag && props.eventDrag.affectedInstances || props.eventResize && props.eventResize.affectedInstances || {};
    let sortedFgSegs = this.sortEventSegs(props.fgEventSegs, options.eventOrder);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ci, {
      elTag: "td",
      elRef: props.elRef,
      elClasses: ['fc-timegrid-col', ...(props.extraClassNames || [])],
      elAttrs: Object.assign({
        role: 'gridcell'
      }, props.extraDataAttrs),
      date: props.date,
      dateProfile: props.dateProfile,
      todayRange: props.todayRange,
      extraRenderProps: props.extraRenderProps
    }, InnerContent => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-col-frame"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-col-bg"
    }, this.renderFillSegs(props.businessHourSegs, 'non-business'), this.renderFillSegs(props.bgEventSegs, 'bg-event'), this.renderFillSegs(props.dateSelectionSegs, 'highlight')), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-col-events"
    }, this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-col-events"
    }, this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror), 'mirror')), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-now-indicator-container"
    }, this.renderNowIndicator(props.nowIndicatorSegs)), (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cj)(options) && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(InnerContent, {
      elTag: "div",
      elClasses: ['fc-timegrid-col-misc']
    })));
  }
  renderFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey) {
    let {
      props
    } = this;
    if (props.forPrint) {
      return renderPlainFgSegs(sortedFgSegs, props);
    }
    return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey);
  }
  renderPositionedFgSegs(segs,
  // if not mirror, needs to be sorted
  segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey) {
    let {
      eventMaxStack,
      eventShortHeight,
      eventOrderStrict,
      eventMinHeight
    } = this.context.options;
    let {
      date,
      slatCoords,
      eventSelection,
      todayRange,
      nowDate
    } = this.props;
    let isMirror = isDragging || isResizing || isDateSelecting;
    let segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight);
    let {
      segPlacements,
      hiddenGroups
    } = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, this.renderHiddenGroups(hiddenGroups, segs), segPlacements.map(segPlacement => {
      let {
        seg,
        rect
      } = segPlacement;
      let instanceId = seg.eventRange.instance.instanceId;
      let isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect);
      let vStyle = computeSegVStyle(rect && rect.span);
      let hStyle = !isMirror && rect ? this.computeSegHStyle(rect) : {
        left: 0,
        right: 0
      };
      let isInset = Boolean(rect) && rect.stackForward > 0;
      let isShort = Boolean(rect) && rect.span.end - rect.span.start < eventShortHeight; // look at other places for this problem
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
        className: 'fc-timegrid-event-harness' + (isInset ? ' fc-timegrid-event-harness-inset' : ''),
        key: forcedKey || instanceId,
        style: Object.assign(Object.assign({
          visibility: isVisible ? '' : 'hidden'
        }, vStyle), hStyle)
      }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColEvent, Object.assign({
        seg: seg,
        isDragging: isDragging,
        isResizing: isResizing,
        isDateSelecting: isDateSelecting,
        isSelected: instanceId === eventSelection,
        isShort: isShort
      }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange, nowDate))));
    }));
  }
  // will already have eventMinHeight applied because segInputs already had it
  renderHiddenGroups(hiddenGroups, segs) {
    let {
      extraDateSpan,
      dateProfile,
      todayRange,
      nowDate,
      eventSelection,
      eventDrag,
      eventResize
    } = this.props;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, hiddenGroups.map(hiddenGroup => {
      let positionCss = computeSegVStyle(hiddenGroup.span);
      let hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs);
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColMoreLink, {
        key: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bu)((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cp)(hiddenSegs)),
        hiddenSegs: hiddenSegs,
        top: positionCss.top,
        bottom: positionCss.bottom,
        extraDateSpan: extraDateSpan,
        dateProfile: dateProfile,
        todayRange: todayRange,
        nowDate: nowDate,
        eventSelection: eventSelection,
        eventDrag: eventDrag,
        eventResize: eventResize
      });
    }));
  }
  renderFillSegs(segs, fillType) {
    let {
      props,
      context
    } = this;
    let segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); // don't assume all populated
    let children = segVCoords.map((vcoords, i) => {
      let seg = segs[i];
      return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
        key: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bR)(seg.eventRange),
        className: "fc-timegrid-bg-harness",
        style: computeSegVStyle(vcoords)
      }, fillType === 'bg-event' ? (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cm, Object.assign({
        seg: seg
      }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, props.todayRange, props.nowDate))) : (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cl)(fillType));
    });
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, children);
  }
  renderNowIndicator(segs) {
    let {
      slatCoords,
      date
    } = this.props;
    if (!slatCoords) {
      return null;
    }
    return segs.map((seg, i) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ch
    // key doesn't matter. will only ever be one
    , {
      // key doesn't matter. will only ever be one
      key: i,
      elClasses: ['fc-timegrid-now-indicator-line'],
      elStyle: {
        top: slatCoords.computeDateTop(seg.start, date)
      },
      isAxis: false,
      date: date
    }));
  }
  computeSegHStyle(segHCoords) {
    let {
      isRtl,
      options
    } = this.context;
    let shouldOverlap = options.slotEventOverlap;
    let nearCoord = segHCoords.levelCoord; // the left side if LTR. the right side if RTL. floating-point
    let farCoord = segHCoords.levelCoord + segHCoords.thickness; // the right side if LTR. the left side if RTL. floating-point
    let left; // amount of space from left edge, a fraction of the total width
    let right; // amount of space from right edge, a fraction of the total width
    if (shouldOverlap) {
      // double the width, but don't go beyond the maximum forward coordinate (1.0)
      farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2);
    }
    if (isRtl) {
      left = 1 - farCoord;
      right = nearCoord;
    } else {
      left = nearCoord;
      right = 1 - farCoord;
    }
    let props = {
      zIndex: segHCoords.stackDepth + 1,
      left: left * 100 + '%',
      right: right * 100 + '%'
    };
    if (shouldOverlap && !segHCoords.stackForward) {
      // add padding to the edge so that forward stacked events don't cover the resizer's icon
      props[isRtl ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
    }
    return props;
  }
}
function renderPlainFgSegs(sortedFgSegs, {
  todayRange,
  nowDate,
  eventSelection,
  eventDrag,
  eventResize
}) {
  let hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || (eventResize ? eventResize.affectedInstances : null) || {};
  return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.Fragment, null, sortedFgSegs.map(seg => {
    let instanceId = seg.eventRange.instance.instanceId;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      key: instanceId,
      style: {
        visibility: hiddenInstances[instanceId] ? 'hidden' : ''
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColEvent, Object.assign({
      seg: seg,
      isDragging: false,
      isResizing: false,
      isDateSelecting: false,
      isSelected: instanceId === eventSelection,
      isShort: false
    }, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bQ)(seg, todayRange, nowDate))));
  }));
}
function computeSegVStyle(segVCoords) {
  if (!segVCoords) {
    return {
      top: '',
      bottom: ''
    };
  }
  return {
    top: segVCoords.start,
    bottom: -segVCoords.end
  };
}
function compileSegsFromEntries(segEntries, allSegs) {
  return segEntries.map(segEntry => allSegs[segEntry.index]);
}
class TimeColsContent extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.B {
  constructor() {
    super(...arguments);
    this.splitFgEventSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);
    this.splitBgEventSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);
    this.splitBusinessHourSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);
    this.splitNowIndicatorSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);
    this.splitDateSelectionSegs = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitSegsByCol);
    this.splitEventDrag = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByCol);
    this.splitEventResize = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(splitInteractionByCol);
    this.rootElRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
    this.cellElRefs = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.cd();
  }
  render() {
    let {
      props,
      context
    } = this;
    let nowIndicatorTop = context.options.nowIndicator && props.slatCoords && props.slatCoords.safeComputeTop(props.nowDate); // might return void
    let colCnt = props.cells.length;
    let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt);
    let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt);
    let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt);
    let nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt);
    let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt);
    let eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt);
    let eventResizeByRow = this.splitEventResize(props.eventResize, colCnt);
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-cols",
      ref: this.rootElRef
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("table", {
      role: "presentation",
      style: {
        minWidth: props.tableMinWidth,
        width: props.clientWidth
      }
    }, props.tableColGroupNode, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tbody", {
      role: "presentation"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("tr", {
      role: "row"
    }, props.axis && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("td", {
      "aria-hidden": true,
      className: "fc-timegrid-col fc-timegrid-axis"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-col-frame"
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-now-indicator-container"
    }, typeof nowIndicatorTop === 'number' && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ch, {
      elClasses: ['fc-timegrid-now-indicator-arrow'],
      elStyle: {
        top: nowIndicatorTop
      },
      isAxis: true,
      date: props.nowDate
    })))), props.cells.map((cell, i) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeCol, {
      key: cell.key,
      elRef: this.cellElRefs.createRef(cell.key),
      dateProfile: props.dateProfile,
      date: cell.date,
      nowDate: props.nowDate,
      todayRange: props.todayRange,
      extraRenderProps: cell.extraRenderProps,
      extraDataAttrs: cell.extraDataAttrs,
      extraClassNames: cell.extraClassNames,
      extraDateSpan: cell.extraDateSpan,
      fgEventSegs: fgEventSegsByRow[i],
      bgEventSegs: bgEventSegsByRow[i],
      businessHourSegs: businessHourSegsByRow[i],
      nowIndicatorSegs: nowIndicatorSegsByRow[i],
      dateSelectionSegs: dateSelectionSegsByRow[i],
      eventDrag: eventDragByRow[i],
      eventResize: eventResizeByRow[i],
      slatCoords: props.slatCoords,
      eventSelection: props.eventSelection,
      forPrint: props.forPrint
    }))))));
  }
  componentDidMount() {
    this.updateCoords();
  }
  componentDidUpdate() {
    this.updateCoords();
  }
  updateCoords() {
    let {
      props
    } = this;
    if (props.onColCoords && props.clientWidth !== null // means sizing has stabilized
    ) {
      props.onColCoords(new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.b8(this.rootElRef.current, collectCellEls(this.cellElRefs.currentMap, props.cells), true,
      // horizontal
      false));
    }
  }
}
function collectCellEls(elMap, cells) {
  return cells.map(cell => elMap[cell.key]);
}

/* A component that renders one or more columns of vertical time slots
----------------------------------------------------------------------------------------------------------------------*/
class TimeCols extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.processSlotOptions = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(processSlotOptions);
    this.state = {
      slatCoords: null
    };
    this.handleRootEl = el => {
      if (el) {
        this.context.registerInteractiveComponent(this, {
          el,
          isHitComboAllowed: this.props.isHitComboAllowed
        });
      } else {
        this.context.unregisterInteractiveComponent(this);
      }
    };
    this.handleScrollRequest = request => {
      let {
        onScrollTopRequest
      } = this.props;
      let {
        slatCoords
      } = this.state;
      if (onScrollTopRequest && slatCoords) {
        if (request.time) {
          let top = slatCoords.computeTimeTop(request.time);
          top = Math.ceil(top); // zoom can give weird floating-point values. rather scroll a little bit further
          if (top) {
            top += 1; // to overcome top border that slots beyond the first have. looks better
          }
          onScrollTopRequest(top);
        }
        return true;
      }
      return false;
    };
    this.handleColCoords = colCoords => {
      this.colCoords = colCoords;
    };
    this.handleSlatCoords = slatCoords => {
      this.setState({
        slatCoords
      });
      if (this.props.onSlatCoords) {
        this.props.onSlatCoords(slatCoords);
      }
    };
  }
  render() {
    let {
      props,
      state
    } = this;
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)("div", {
      className: "fc-timegrid-body",
      ref: this.handleRootEl,
      style: {
        // these props are important to give this wrapper correct dimensions for interactions
        // TODO: if we set it here, can we avoid giving to inner tables?
        width: props.clientWidth,
        minWidth: props.tableMinWidth
      }
    }, (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsSlats, {
      axis: props.axis,
      dateProfile: props.dateProfile,
      slatMetas: props.slatMetas,
      clientWidth: props.clientWidth,
      minHeight: props.expandRows ? props.clientHeight : '',
      tableMinWidth: props.tableMinWidth,
      tableColGroupNode: props.axis ? props.tableColGroupNode : null /* axis depends on the colgroup's shrinking */,
      onCoords: this.handleSlatCoords
    }), (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeColsContent, {
      cells: props.cells,
      axis: props.axis,
      dateProfile: props.dateProfile,
      businessHourSegs: props.businessHourSegs,
      bgEventSegs: props.bgEventSegs,
      fgEventSegs: props.fgEventSegs,
      dateSelectionSegs: props.dateSelectionSegs,
      eventSelection: props.eventSelection,
      eventDrag: props.eventDrag,
      eventResize: props.eventResize,
      todayRange: props.todayRange,
      nowDate: props.nowDate,
      nowIndicatorSegs: props.nowIndicatorSegs,
      clientWidth: props.clientWidth,
      tableMinWidth: props.tableMinWidth,
      tableColGroupNode: props.tableColGroupNode,
      slatCoords: state.slatCoords,
      onColCoords: this.handleColCoords,
      forPrint: props.forPrint
    }));
  }
  componentDidMount() {
    this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest);
  }
  componentDidUpdate(prevProps) {
    this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile);
  }
  componentWillUnmount() {
    this.scrollResponder.detach();
  }
  queryHit(positionLeft, positionTop) {
    let {
      dateEnv,
      options
    } = this.context;
    let {
      colCoords
    } = this;
    let {
      dateProfile
    } = this.props;
    let {
      slatCoords
    } = this.state;
    let {
      snapDuration,
      snapsPerSlot
    } = this.processSlotOptions(this.props.slotDuration, options.snapDuration);
    let colIndex = colCoords.leftToIndex(positionLeft);
    let slatIndex = slatCoords.positions.topToIndex(positionTop);
    if (colIndex != null && slatIndex != null) {
      let cell = this.props.cells[colIndex];
      let slatTop = slatCoords.positions.tops[slatIndex];
      let slatHeight = slatCoords.positions.getHeight(slatIndex);
      let partial = (positionTop - slatTop) / slatHeight; // floating point number between 0 and 1
      let localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
      let snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
      let dayDate = this.props.cells[colIndex].date;
      let time = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bn)(dateProfile.slotMinTime, (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bm)(snapDuration, snapIndex));
      let start = dateEnv.add(dayDate, time);
      let end = dateEnv.add(start, snapDuration);
      return {
        dateProfile,
        dateSpan: Object.assign({
          range: {
            start,
            end
          },
          allDay: false
        }, cell.extraDateSpan),
        dayEl: colCoords.els[colIndex],
        rect: {
          left: colCoords.lefts[colIndex],
          right: colCoords.rights[colIndex],
          top: slatTop,
          bottom: slatTop + slatHeight
        },
        layer: 0
      };
    }
    return null;
  }
}
function processSlotOptions(slotDuration, snapDurationOverride) {
  let snapDuration = snapDurationOverride || slotDuration;
  let snapsPerSlot = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.br)(slotDuration, snapDuration);
  if (snapsPerSlot === null) {
    snapDuration = slotDuration;
    snapsPerSlot = 1;
    // TODO: say warning?
  }
  return {
    snapDuration,
    snapsPerSlot
  };
}
class DayTimeColsSlicer extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bU {
  sliceRange(range, dayRanges) {
    let segs = [];
    for (let col = 0; col < dayRanges.length; col += 1) {
      let segRange = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.o)(range, dayRanges[col]);
      if (segRange) {
        segs.push({
          start: segRange.start,
          end: segRange.end,
          isStart: segRange.start.valueOf() === range.start.valueOf(),
          isEnd: segRange.end.valueOf() === range.end.valueOf(),
          col
        });
      }
    }
    return segs;
  }
}
class DayTimeCols extends _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bc {
  constructor() {
    super(...arguments);
    this.buildDayRanges = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildDayRanges);
    this.slicer = new DayTimeColsSlicer();
    this.timeColsRef = (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createRef)();
  }
  render() {
    let {
      props,
      context
    } = this;
    let {
      dateProfile,
      dayTableModel
    } = props;
    let {
      nowIndicator,
      nextDayThreshold
    } = context.options;
    let dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv);
    // give it the first row of cells
    // TODO: would move this further down hierarchy, but sliceNowDate needs it
    return (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.a6, {
      unit: nowIndicator ? 'minute' : 'day'
    }, (nowDate, todayRange) => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(TimeCols, Object.assign({
      ref: this.timeColsRef
    }, this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), {
      forPrint: props.forPrint,
      axis: props.axis,
      dateProfile: dateProfile,
      slatMetas: props.slatMetas,
      slotDuration: props.slotDuration,
      cells: dayTableModel.cells[0],
      tableColGroupNode: props.tableColGroupNode,
      tableMinWidth: props.tableMinWidth,
      clientWidth: props.clientWidth,
      clientHeight: props.clientHeight,
      expandRows: props.expandRows,
      nowDate: nowDate,
      nowIndicatorSegs: nowIndicator && this.slicer.sliceNowDate(nowDate, dateProfile, nextDayThreshold, context, dayRanges),
      todayRange: todayRange,
      onScrollTopRequest: props.onScrollTopRequest,
      onSlatCoords: props.onSlatCoords
    })));
  }
}
function buildDayRanges(dayTableModel, dateProfile, dateEnv) {
  let ranges = [];
  for (let date of dayTableModel.headerDates) {
    ranges.push({
      start: dateEnv.add(date, dateProfile.slotMinTime),
      end: dateEnv.add(date, dateProfile.slotMaxTime)
    });
  }
  return ranges;
}

// potential nice values for the slot-duration and interval-duration
// from largest to smallest
const STOCK_SUB_DURATIONS = [{
  hours: 1
}, {
  minutes: 30
}, {
  minutes: 15
}, {
  seconds: 30
}, {
  seconds: 15
}];
function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) {
  let dayStart = new Date(0);
  let slatTime = slotMinTime;
  let slatIterator = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(0);
  let labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration);
  let metas = [];
  while ((0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(slatTime) < (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bq)(slotMaxTime)) {
    let date = dateEnv.add(dayStart, slatTime);
    let isLabeled = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.br)(slatIterator, labelInterval) !== null;
    metas.push({
      date,
      time: slatTime,
      key: date.toISOString(),
      isoTimeStr: (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bs)(date),
      isLabeled
    });
    slatTime = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bn)(slatTime, slotDuration);
    slatIterator = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bn)(slatIterator, slotDuration);
  }
  return metas;
}
// Computes an automatic value for slotLabelInterval
function computeLabelInterval(slotDuration) {
  let i;
  let labelInterval;
  let slotsPerLabel;
  // find the smallest stock label interval that results in more than one slots-per-label
  for (i = STOCK_SUB_DURATIONS.length - 1; i >= 0; i -= 1) {
    labelInterval = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.d)(STOCK_SUB_DURATIONS[i]);
    slotsPerLabel = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.br)(labelInterval, slotDuration);
    if (slotsPerLabel !== null && slotsPerLabel > 1) {
      return labelInterval;
    }
  }
  return slotDuration; // fall back
}
class DayTimeColsView extends TimeColsView {
  constructor() {
    super(...arguments);
    this.buildTimeColsModel = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildTimeColsModel);
    this.buildSlatMetas = (0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.z)(buildSlatMetas);
  }
  render() {
    let {
      options,
      dateEnv,
      dateProfileGenerator
    } = this.context;
    let {
      props
    } = this;
    let {
      dateProfile
    } = props;
    let dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator);
    let splitProps = this.allDaySplitter.splitProps(props);
    let slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv);
    let {
      dayMinWidth
    } = options;
    let hasAttachedAxis = !dayMinWidth;
    let hasDetachedAxis = dayMinWidth;
    let headerContent = options.dayHeaders && (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bI, {
      dates: dayTableModel.headerDates,
      dateProfile: dateProfile,
      datesRepDistinctDays: true,
      renderIntro: hasAttachedAxis ? this.renderHeadAxis : null
    });
    let allDayContent = options.allDaySlot !== false && (contentArg => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(_fullcalendar_daygrid_internal_js__WEBPACK_IMPORTED_MODULE_2__.DayTable, Object.assign({}, splitProps.allDay, {
      dateProfile: dateProfile,
      dayTableModel: dayTableModel,
      nextDayThreshold: options.nextDayThreshold,
      tableMinWidth: contentArg.tableMinWidth,
      colGroupNode: contentArg.tableColGroupNode,
      renderRowIntro: hasAttachedAxis ? this.renderTableRowAxis : null,
      showWeekNumbers: false,
      expandRows: false,
      headerAlignElRef: this.headerElRef,
      clientWidth: contentArg.clientWidth,
      clientHeight: contentArg.clientHeight,
      forPrint: props.forPrint
    }, this.getAllDayMaxEventProps())));
    let timeGridContent = contentArg => (0,_fullcalendar_core_preact_js__WEBPACK_IMPORTED_MODULE_1__.createElement)(DayTimeCols, Object.assign({}, splitProps.timed, {
      dayTableModel: dayTableModel,
      dateProfile: dateProfile,
      axis: hasAttachedAxis,
      slotDuration: options.slotDuration,
      slatMetas: slatMetas,
      forPrint: props.forPrint,
      tableColGroupNode: contentArg.tableColGroupNode,
      tableMinWidth: contentArg.tableMinWidth,
      clientWidth: contentArg.clientWidth,
      clientHeight: contentArg.clientHeight,
      onSlatCoords: this.handleSlatCoords,
      expandRows: contentArg.expandRows,
      onScrollTopRequest: this.handleScrollTopRequest
    }));
    return hasDetachedAxis ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent);
  }
}
function buildTimeColsModel(dateProfile, dateProfileGenerator) {
  let daySeries = new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bM(dateProfile.renderRange, dateProfileGenerator);
  return new _fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.bT(daySeries, false);
}
var css_248z = ".fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:\"\\00a0\"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:\"\\00a0-\\00a0\"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-arrow,.fc .fc-timegrid-now-indicator-line{pointer-events:none}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}";
(0,_fullcalendar_core_internal_js__WEBPACK_IMPORTED_MODULE_0__.ct)(css_248z);


/***/ }),

/***/ 59848:
/*!******************************************************!*\
  !*** ./node_modules/@lordicon/element/dist/index.js ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Boomerang: () => (/* binding */ D),
/* harmony export */   Click: () => (/* binding */ P),
/* harmony export */   Element: () => (/* binding */ I),
/* harmony export */   Hover: () => (/* binding */ A),
/* harmony export */   In: () => (/* binding */ F),
/* harmony export */   Loop: () => (/* binding */ x),
/* harmony export */   LoopOnHover: () => (/* binding */ M),
/* harmony export */   Morph: () => (/* binding */ S),
/* harmony export */   Player: () => (/* binding */ L),
/* harmony export */   Sequence: () => (/* binding */ q),
/* harmony export */   defineElement: () => (/* binding */ O)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);

function e(e) {
  return JSON.parse(JSON.stringify(e));
}
function t(e) {
  return null == e;
}
function i(e) {
  return null !== e && "object" == typeof e;
}
function s(e, t, s) {
  const r = Array.isArray(t) ? t : t.split(".");
  let n = e;
  for (const e of r) {
    if (!i(n)) return s;
    if (!(e in n)) return s;
    n = n[e];
  }
  return void 0 === n ? s : n;
}
function r(e, t, i) {
  let s = e;
  const r = Array.isArray(t) ? t : t.split(".");
  for (let e = 0; e < r.length; ++e) e === r.length - 1 ? s[r[e]] = i : s = s[r[e]];
}
const n = {
  aliceblue: "#f0f8ff",
  antiquewhite: "#faebd7",
  aqua: "#00ffff",
  aquamarine: "#7fffd4",
  azure: "#f0ffff",
  beige: "#f5f5dc",
  bisque: "#ffe4c4",
  black: "#000000",
  blanchedalmond: "#ffebcd",
  blue: "#0000ff",
  blueviolet: "#8a2be2",
  brown: "#a52a2a",
  burlywood: "#deb887",
  cadetblue: "#5f9ea0",
  chartreuse: "#7fff00",
  chocolate: "#d2691e",
  coral: "#ff7f50",
  cornflowerblue: "#6495ed",
  cornsilk: "#fff8dc",
  crimson: "#dc143c",
  cyan: "#00ffff",
  darkblue: "#00008b",
  darkcyan: "#008b8b",
  darkgoldenrod: "#b8860b",
  darkgray: "#a9a9a9",
  darkgreen: "#006400",
  darkkhaki: "#bdb76b",
  darkmagenta: "#8b008b",
  darkolivegreen: "#556b2f",
  darkorange: "#ff8c00",
  darkorchid: "#9932cc",
  darkred: "#8b0000",
  darksalmon: "#e9967a",
  darkseagreen: "#8fbc8f",
  darkslateblue: "#483d8b",
  darkslategray: "#2f4f4f",
  darkturquoise: "#00ced1",
  darkviolet: "#9400d3",
  deeppink: "#ff1493",
  deepskyblue: "#00bfff",
  dimgray: "#696969",
  dodgerblue: "#1e90ff",
  firebrick: "#b22222",
  floralwhite: "#fffaf0",
  forestgreen: "#228b22",
  fuchsia: "#ff00ff",
  gainsboro: "#dcdcdc",
  ghostwhite: "#f8f8ff",
  gold: "#ffd700",
  goldenrod: "#daa520",
  gray: "#808080",
  green: "#008000",
  greenyellow: "#adff2f",
  honeydew: "#f0fff0",
  hotpink: "#ff69b4",
  "indianred ": "#cd5c5c",
  indigo: "#4b0082",
  ivory: "#fffff0",
  khaki: "#f0e68c",
  lavender: "#e6e6fa",
  lavenderblush: "#fff0f5",
  lawngreen: "#7cfc00",
  lemonchiffon: "#fffacd",
  lightblue: "#add8e6",
  lightcoral: "#f08080",
  lightcyan: "#e0ffff",
  lightgoldenrodyellow: "#fafad2",
  lightgrey: "#d3d3d3",
  lightgreen: "#90ee90",
  lightpink: "#ffb6c1",
  lightsalmon: "#ffa07a",
  lightseagreen: "#20b2aa",
  lightskyblue: "#87cefa",
  lightslategray: "#778899",
  lightsteelblue: "#b0c4de",
  lightyellow: "#ffffe0",
  lime: "#00ff00",
  limegreen: "#32cd32",
  linen: "#faf0e6",
  magenta: "#ff00ff",
  maroon: "#800000",
  mediumaquamarine: "#66cdaa",
  mediumblue: "#0000cd",
  mediumorchid: "#ba55d3",
  mediumpurple: "#9370d8",
  mediumseagreen: "#3cb371",
  mediumslateblue: "#7b68ee",
  mediumspringgreen: "#00fa9a",
  mediumturquoise: "#48d1cc",
  mediumvioletred: "#c71585",
  midnightblue: "#191970",
  mintcream: "#f5fffa",
  mistyrose: "#ffe4e1",
  moccasin: "#ffe4b5",
  navajowhite: "#ffdead",
  navy: "#000080",
  oldlace: "#fdf5e6",
  olive: "#808000",
  olivedrab: "#6b8e23",
  orange: "#ffa500",
  orangered: "#ff4500",
  orchid: "#da70d6",
  palegoldenrod: "#eee8aa",
  palegreen: "#98fb98",
  paleturquoise: "#afeeee",
  palevioletred: "#d87093",
  papayawhip: "#ffefd5",
  peachpuff: "#ffdab9",
  peru: "#cd853f",
  pink: "#ffc0cb",
  plum: "#dda0dd",
  powderblue: "#b0e0e6",
  purple: "#800080",
  rebeccapurple: "#663399",
  red: "#ff0000",
  rosybrown: "#bc8f8f",
  royalblue: "#4169e1",
  saddlebrown: "#8b4513",
  salmon: "#fa8072",
  sandybrown: "#f4a460",
  seagreen: "#2e8b57",
  seashell: "#fff5ee",
  sienna: "#a0522d",
  silver: "#c0c0c0",
  skyblue: "#87ceeb",
  slateblue: "#6a5acd",
  slategray: "#708090",
  snow: "#fffafa",
  springgreen: "#00ff7f",
  steelblue: "#4682b4",
  tan: "#d2b48c",
  teal: "#008080",
  thistle: "#d8bfd8",
  tomato: "#ff6347",
  turquoise: "#40e0d0",
  violet: "#ee82ee",
  wheat: "#f5deb3",
  white: "#ffffff",
  whitesmoke: "#f5f5f5",
  yellow: "#ffff00",
  yellowgreen: "#9acd32"
};
function a(e) {
  return e.startsWith("#") ? 4 === e.length ? `#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}` : e : n[e.toLowerCase()] || "#000000";
}
function o(e) {
  if (e && "string" == typeof e) return e.split(",").filter(e => e).map(e => e.split(":")).filter(e => 2 == e.length).reduce((e, t) => (e[t[0].toLowerCase()] = a(t[1]), e), {});
}
function l(e) {
  return "light" === e || 1 === e || "1" === e ? 1 : "regular" === e || 2 === e || "2" === e ? 2 : "bold" === e || 3 === e || "3" === e ? 3 : "number" == typeof e || "string" == typeof e ? +e : void 0;
}
function h(e) {
  if ("string" == typeof e) return e;
}
function c(e) {
  const t = e.toString(16);
  return 1 == t.length ? "0" + t : t;
}
function d(e) {
  return Math.round(e / 255 * 1e3) / 1e3;
}
function g(e) {
  return Math.round(255 * e);
}
function f(e) {
  const {
    r: t,
    g: i,
    b: s
  } = function (e) {
    let t = parseInt("#" != e[0] ? e : e.substring(1), 16);
    return {
      r: t >> 16 & 255,
      g: t >> 8 & 255,
      b: 255 & t
    };
  }(e);
  return [d(t), d(i), d(s)];
}
function u(e) {
  return function (e) {
    return "#" + c(e.r) + c(e.g) + c(e.b);
  }({
    r: g(e[0]),
    g: g(e[1]),
    b: g(e[2])
  });
}
function m(e, {
  lottieInstance: t
} = {}) {
  const i = [];
  return e && e.layers ? (e.layers.forEach((e, s) => {
    e.nm && e.ef && e.ef.forEach((e, r) => {
      const n = e?.ef?.[0]?.v?.k;
      if (void 0 === n) return;
      let a, o;
      if (a = t ? `renderer.elements.${s}.effectsManager.effectElements.${r}.effectElements.0.p.v` : `layers.${s}.ef.${r}.ef.0.v.k`, "ADBE Color Control" === e.mn ? o = "color" : "ADBE Slider Control" === e.mn ? o = "slider" : "ADBE Point Control" === e.mn ? o = "point" : "ADBE Checkbox Control" === e.mn ? o = "checkbox" : e.mn.startsWith("Pseudo/") && (o = "feature"), !o) return;
      const l = e.nm.toLowerCase();
      i.push({
        name: l,
        path: a,
        value: n,
        type: o
      });
    });
  }), i) : i;
}
function y(e, t) {
  for (const i of t) r(e, i.path, i.value);
}
function p(e, t, i) {
  for (const s of t) "color" === s.type ? "object" == typeof i && "r" in i && "g" in i && "b" in i ? r(e, s.path, [d(i.r), d(i.g), d(i.b)]) : Array.isArray(i) ? r(e, s.path, i) : "string" == typeof i && r(e, s.path, f(a(i))) : "point" === s.type ? "object" == typeof i && "x" in i && "y" in i ? (r(e, s.path + ".0", i.x), r(e, s.path + ".1", i.y)) : Array.isArray(i) && (r(e, s.path + ".0", i[0]), r(e, s.path + ".1", i[1])) : r(e, s.path, i);
}
const _ = ["click", "mouseenter", "mouseleave"],
  b = "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype,
  v = "\n    :host {\n        position: relative;\n        display: inline-block;\n        width: 32px;\n        height: 32px;\n        transform: translate3d(0px, 0px, 0px);\n    }\n\n    :host(.current-color) svg path[fill] {\n        fill: currentColor;\n    }\n\n    :host(.current-color) svg path[stroke] {\n        stroke: currentColor;\n    }\n\n    svg {\n        position: absolute;\n        pointer-events: none;\n        display: block;\n        transform: unset!important;\n    }\n\n    ::slotted(*) {\n        position: absolute;\n        left: 0;\n        top: 0;\n        width: 100%;\n        height: 100%;\n    }\n\n    .body.ready ::slotted(*) {\n        display: none;\n    }\n";
let E = null;
const k = ["colors", "src", "icon", "state", "trigger", "loading", "target", "stroke"];
class I extends HTMLElement {
  static _iconLoader;
  static _playerFactory;
  static _definedTriggers = new Map();
  static get version() {
    return "1.10.1";
  }
  static get observedAttributes() {
    return k;
  }
  static setIconLoader(e) {
    I._iconLoader = e;
  }
  static setPlayerFactory(e) {
    I._playerFactory = e;
  }
  static defineTrigger(e, t) {
    I._definedTriggers.set(e, t);
  }
  _root;
  _isConnected = !1;
  _isReady = !1;
  _assignedIconData;
  _loadedIconData;
  _triggerInstance;
  _playerInstance;
  delayedLoading = null;
  attributeChangedCallback(e, t, i) {
    this[`${e}Changed`].call(this);
  }
  connectedCallback() {
    if (this._root || this.createElements(), "lazy" === this.loading) {
      let e;
      this.delayedLoading = t => {
        e.unobserve(this), e = void 0, this.delayedLoading = null, t || this.createPlayer();
      };
      e = new IntersectionObserver((t, i) => {
        t.forEach(t => {
          t.isIntersecting && e && this.delayedLoading && this.delayedLoading();
        });
      }), e.observe(this);
    } else if ("interaction" === this.loading) {
      let e;
      this.delayedLoading = s => {
        for (const e of _) (t || this).removeEventListener(e, i);
        this.delayedLoading = null, s || this.createPlayer().then(() => {
          e && (t || this).dispatchEvent(new Event(e));
        });
      };
      const t = this.target ? this.closest(this.target) : null;
      let i = t => {
        const i = t?.type;
        e ? e = i : (e = i, this.delayedLoading && this.delayedLoading());
      };
      i = i.bind(this);
      for (const e of _) (t || this).addEventListener(e, i);
    } else if ("delay" === this.loading) {
      this.delayedLoading = e => {
        this.delayedLoading = null, e || this.createPlayer();
      };
      const e = this.hasAttribute("delay") ? +this.getAttribute("delay") : 0;
      setTimeout(() => {
        this.delayedLoading && this.delayedLoading();
      }, e);
    } else this.createPlayer();
    this._isConnected = !0;
  }
  disconnectedCallback() {
    this.delayedLoading && this.delayedLoading(!0), this.destroyPlayer(), this._isConnected = !1;
  }
  createElements() {
    if (this._root = this.attachShadow({
      mode: "open"
    }), b) E || (E = new CSSStyleSheet(), E.replaceSync(v)), this._root.adoptedStyleSheets = [E];else {
      const e = document.createElement("style");
      e.innerHTML = v, this._root.appendChild(e);
    }
    const e = document.createElement("div");
    e.classList.add("body"), this._root.appendChild(e);
    const t = document.createElement("slot");
    e.appendChild(t);
  }
  createPlayer() {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      if (!I._playerFactory) throw new Error("Missing player loader!");
      if (_this.delayedLoading) return;
      const e = yield _this.loadIconData();
      if (!e) return;
      _this._playerInstance = I._playerFactory(_this.animationContainer, e, {
        state: h(_this.state),
        stroke: l(_this.stroke),
        colors: o(_this.colors),
        scale: parseFloat("" + _this.getAttribute("scale") || ""),
        axisX: parseFloat("" + _this.getAttribute("axis-x") || ""),
        axisY: parseFloat("" + _this.getAttribute("axis-y") || "")
      });
      const t = Object.entries(_this._playerInstance.colors || {});
      if (t.length) {
        let e = "";
        for (const [i, s] of t) e += `\n                    :host(:not(.current-color)) svg path[fill].${i} {\n                        fill: var(--lord-icon-${i}, var(--lord-icon-${i}-base, #000));\n                    }\n        \n                    :host(:not(.current-color)) svg path[stroke].${i} {\n                        stroke: var(--lord-icon-${i}, var(--lord-icon-${i}-base, #000));\n                    }\n                `;
        const i = document.createElement("style");
        i.innerHTML = e, _this.animationContainer.appendChild(i);
      }
      _this._playerInstance.connect(), _this._playerInstance.addEventListener("ready", () => {
        _this._triggerInstance && _this._triggerInstance.onReady && _this._triggerInstance.onReady();
      }), _this._playerInstance.addEventListener("refresh", () => {
        _this.refresh(), _this._triggerInstance && _this._triggerInstance.onRefresh && _this._triggerInstance.onRefresh();
      }), _this._playerInstance.addEventListener("complete", () => {
        _this._triggerInstance && _this._triggerInstance.onComplete && _this._triggerInstance.onComplete();
      }), _this._playerInstance.addEventListener("frame", () => {
        _this._triggerInstance && _this._triggerInstance.onFrame && _this._triggerInstance.onFrame();
      }), _this.refresh(), _this.triggerChanged(), yield new Promise((e, t) => {
        _this._playerInstance.isReady ? e() : _this._playerInstance.addEventListener("ready", e);
      }), _this.animationContainer.classList.add("ready"), _this._isReady = !0, _this.dispatchEvent(new CustomEvent("ready"));
    })();
  }
  destroyPlayer() {
    this._isReady = !1, this._loadedIconData = void 0, this._triggerInstance && (this._triggerInstance.onDisconnected && this._triggerInstance.onDisconnected(), this._triggerInstance = void 0), this._playerInstance && (this._playerInstance.disconnect(), this._playerInstance = void 0, this.animationContainer.classList.remove("ready"));
  }
  loadIconData() {
    var _this2 = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      let e = _this2.iconData;
      if (!e) if (_this2.icon && I._iconLoader) _this2._loadedIconData = e = yield I._iconLoader(_this2.icon);else if (_this2.src) {
        const t = yield fetch(_this2.src);
        _this2._loadedIconData = e = yield t.json();
      }
      return e;
    })();
  }
  refresh() {
    this.movePaletteToCssVariables();
  }
  movePaletteToCssVariables() {
    for (const [e, t] of Object.entries(this._playerInstance.colors || {})) t ? this.animationContainer.style.setProperty(`--lord-icon-${e}-base`, t) : this.animationContainer.style.removeProperty(`--lord-icon-${e}-base`);
  }
  targetChanged() {
    this.triggerChanged();
  }
  loadingChanged() {}
  triggerChanged() {
    if (this._triggerInstance && (this._triggerInstance.onDisconnected && this._triggerInstance.onDisconnected(), this._triggerInstance = void 0, this._playerInstance?.pause()), !this.trigger || !this._playerInstance) return;
    const e = I._definedTriggers.get(this.trigger);
    if (!e) throw new Error("Can't use unregistered trigger!");
    const t = this.target ? this.closest(this.target) : null;
    this._triggerInstance = new e(this._playerInstance, this, t || this), this._triggerInstance.onConnected && this._triggerInstance.onConnected(), this._playerInstance.isReady && this._triggerInstance.onReady && this._triggerInstance.onReady();
  }
  colorsChanged() {
    this._playerInstance && (this._playerInstance.colors = o(this.colors) || null);
  }
  strokeChanged() {
    this._playerInstance && (this._playerInstance.stroke = l(this.stroke) || null);
  }
  stateChanged() {
    this._playerInstance && (this._playerInstance.state = this.state);
  }
  iconChanged() {
    this._isConnected && (this.destroyPlayer(), this.createPlayer());
  }
  srcChanged() {
    this._isConnected && (this.destroyPlayer(), this.createPlayer());
  }
  set icon(e) {
    const t = this._assignedIconData;
    e && i(e) ? (this._assignedIconData = e, t !== e && (this.hasAttribute("icon") ? this.removeAttribute("icon") : this.iconChanged())) : (this._assignedIconData = void 0, e && "string" == typeof e ? this.setAttribute("icon", e) : this.hasAttribute("icon") ? this.removeAttribute("icon") : t && this.iconChanged());
  }
  get icon() {
    return this._assignedIconData || this.getAttribute("icon");
  }
  set src(e) {
    e ? this.setAttribute("src", e) : this.removeAttribute("src");
  }
  get src() {
    return this.getAttribute("src");
  }
  set state(e) {
    e ? this.setAttribute("state", e) : this.removeAttribute("state");
  }
  get state() {
    return this.getAttribute("state");
  }
  set colors(e) {
    e ? this.setAttribute("colors", e) : this.removeAttribute("colors");
  }
  get colors() {
    return this.getAttribute("colors");
  }
  set trigger(e) {
    e ? this.setAttribute("trigger", e) : this.removeAttribute("trigger");
  }
  get trigger() {
    return this.getAttribute("trigger");
  }
  set loading(e) {
    e ? this.setAttribute("loading", e) : this.removeAttribute("loading");
  }
  get loading() {
    if (this.getAttribute("loading")) {
      const e = this.getAttribute("loading").toLowerCase();
      if ("lazy" === e) return "lazy";
      if ("interaction" === e) return "interaction";
      if ("delay" === e) return "delay";
    }
    return null;
  }
  set target(e) {
    e ? this.setAttribute("target", e) : this.removeAttribute("target");
  }
  get target() {
    return this.getAttribute("target");
  }
  set stroke(e) {
    e ? this.setAttribute("stroke", e) : this.removeAttribute("stroke");
  }
  get stroke() {
    return this.hasAttribute("stroke") ? this.getAttribute("stroke") : null;
  }
  set iconData(e) {
    e !== this._assignedIconData && (this._assignedIconData = e, this.iconChanged());
  }
  get iconData() {
    return this._assignedIconData || this._loadedIconData;
  }
  get isReady() {
    return this._isReady;
  }
  get playerInstance() {
    return this._playerInstance;
  }
  get triggerInstance() {
    return this._triggerInstance;
  }
  get animationContainer() {
    return this._root.lastElementChild;
  }
}
const C = {
  renderer: "svg",
  loop: !1,
  autoplay: !1,
  rendererSettings: {
    preserveAspectRatio: "xMidYMid meet",
    progressiveLoad: !0,
    hideOnTransparent: !0
  }
};
function w() {
  return new Proxy(this, {
    set: (e, t, i, s) => ("string" == typeof t && (i ? p(this.lottie, this.rawProperties.filter(e => "color" === e.type && e.name === t), i) : y(this.lottie, this.rawProperties.filter(e => "color" === e.type && e.name === t)), e.refresh()), !0),
    get: (e, t, i) => {
      for (const i of e.rawProperties) if ("color" == i.type && "string" == typeof t && t == i.name) {
        const e = s(this.lottie, i.path);
        if (e) return u(e);
      }
    },
    deleteProperty: (e, t) => ("string" == typeof t && (y(this.lottie, this.rawProperties.filter(e => "color" === e.type && e.name === t)), e.refresh()), !0),
    ownKeys: e => e.rawProperties.filter(e => "color" == e.type).map(e => e.name),
    has: (e, t) => {
      for (const i of e.rawProperties) if ("color" == i.type && "string" == typeof t && t == i.name) return !0;
      return !1;
    },
    getOwnPropertyDescriptor: e => ({
      enumerable: !0,
      configurable: !0
    })
  });
}
class L {
  _animationLoader;
  _container;
  _iconData;
  _initial;
  _options;
  _lottie;
  _isReady = !1;
  _colorsProxy;
  _direction = 1;
  _speed = 1;
  _rawProperties;
  _eventCallbacks = {};
  _state;
  _states;
  constructor(i, s, n, a, o) {
    if (this._animationLoader = i, this._container = s, this._iconData = n, this._initial = a || {}, this._options = o || C, this._states = (n.markers || []).map(e => {
      const [i, s] = e.cm.split(":"),
        r = {
          time: e.tm,
          duration: e.dr,
          name: s || i,
          default: !(!s || !i.includes("default"))
        };
      return (r.name === this._initial.state || r.default && t(this._initial.state)) && (this._state = r), r;
    }).filter(e => e.duration > 0), this._states.length && (this._initial.stroke && ![1, 2, 3, "light", "regular", "bold"].includes(this._initial.stroke) && delete this._initial.stroke, this._initial.state && !this._state && (this._state = this._states.filter(e => e.default)[0])), !this._states.length) {
      this._iconData = e(this._iconData);
      const t = m(this._iconData, {
        lottieInstance: !1
      });
      if (t && this._initial.state) {
        const e = `state-${this._initial.state.toLowerCase()}`;
        p(this._iconData, t.filter(e => e.name.startsWith("state-")), 0), p(this._iconData, t.filter(t => t.name === e), 1);
      }
      if (t && this._initial.stroke) {
        const e = t.filter(e => "stroke" === e.name)[0];
        if (e) {
          const t = e.value / 50,
            i = this._initial.stroke * t;
          r(this._iconData, e.path, i);
        }
      }
      if (t && this._initial.scale) {
        const e = t.filter(e => "scale" === e.name)[0];
        if (e) {
          const t = e.value / 50,
            i = this._initial.scale * t;
          r(this._iconData, e.path, i);
        }
      }
      if (t && this._initial.axisX && this._initial.axisY) {
        const e = t.filter(e => "axis" === e.name)[0];
        if (e) {
          const t = (e.value[0] + e.value[1]) / 2 / 50;
          r(this._iconData, e.path + ".0", this._initial.axisX * t), r(this._iconData, e.path + ".1", this._initial.axisY * t);
        }
      }
    }
  }
  connect() {
    if (this._lottie) throw new Error("Already connected player!");
    const t = {},
      i = {};
    if (this._state && (i.initialSegment = [this._state.time, this._state.time + this._state.duration + 1]), this._states.length) {
      const e = this._states[0],
        i = this._states[this._states.length - 1];
      t.ip = e.time, t.op = i.time + i.duration + 1;
    }
    this._lottie = this._animationLoader({
      ...this._options,
      ...i,
      container: this._container,
      animationData: Object.assign(e(this._iconData), t)
    }), this._initial.colors && (this.colors = this._initial.colors), this._initial.stroke && (this.stroke = this._initial.stroke), this._lottie.addEventListener("complete", e => {
      this.triggerEvent("complete");
    }), this._lottie.addEventListener("loopComplete", () => {
      this.triggerEvent("complete");
    }), this._lottie.addEventListener("enterFrame", e => {
      this.triggerEvent("frame");
    }), this._lottie.isLoaded ? (this._isReady = !0, this.triggerEvent("ready")) : this._lottie.addEventListener("config_ready", () => {
      this._isReady = !0, this.triggerEvent("ready");
    });
  }
  disconnect() {
    if (!this._lottie) throw new Error("Not connected player!");
    this._isReady = !1, this._lottie.destroy(), this._lottie = void 0, this._colorsProxy = void 0, this._rawProperties = void 0;
  }
  addEventListener(e, t) {
    return this._eventCallbacks[e] || (this._eventCallbacks[e] = []), this._eventCallbacks[e].push(t), () => {
      this.removeEventListener(e, t);
    };
  }
  removeEventListener(e, t) {
    if (t) {
      if (this._eventCallbacks[e]) {
        let i = 0,
          s = this._eventCallbacks[e].length;
        for (; i < s;) this._eventCallbacks[e][i] === t && (this._eventCallbacks[e].splice(i, 1), i -= 1, s -= 1), i += 1;
        this._eventCallbacks[e].length || (this._eventCallbacks[e] = null);
      }
    } else this._eventCallbacks[e] = null;
  }
  triggerEvent(e, t) {
    if (this._eventCallbacks[e]) {
      const i = this._eventCallbacks[e];
      for (let e = 0; e < i.length; e += 1) i[e](t);
    }
  }
  refresh() {
    this._lottie?.renderer.renderFrame(null), this.triggerEvent("refresh");
  }
  play() {
    this._lottie.setDirection(this._direction), this._lottie.play();
  }
  playFromBeginning() {
    this._lottie.setDirection(1), this._state ? this._lottie.playSegments([this._state.time, this._state.time + this._state.duration + 1], !0) : this._lottie.goToAndPlay(0);
  }
  pause() {
    this._lottie.pause();
  }
  stop() {
    this._lottie.stop();
  }
  goToFrame(e) {
    this._lottie.goToAndStop(e, !0);
  }
  goToFirstFrame() {
    this.goToFrame(0);
  }
  goToLastFrame() {
    this.goToFrame(Math.max(0, this.frames));
  }
  set properties(e) {
    this.colors = e.colors || null, this.stroke = e.stroke || null, this.state = e.state || null;
  }
  get properties() {
    const e = {};
    return this.rawProperties.filter(e => "color" === e.type).length && (e.colors = {
      ...this.colors
    }), this.rawProperties.filter(e => "stroke" === e.name || "stroke-layers" === e.name).length && (e.stroke = this.stroke), this._states.length && (e.state = this.state), e;
  }
  set colors(e) {
    if (y(this._lottie, this.rawProperties.filter(e => "color" === e.type)), e) for (const [t, i] of Object.entries(e)) p(this._lottie, this.rawProperties.filter(e => "color" === e.type && e.name === t), i);
    this.refresh();
  }
  get colors() {
    return this._colorsProxy || (this._colorsProxy = w.call(this)), this._colorsProxy;
  }
  set stroke(e) {
    y(this._lottie, this.rawProperties.filter(e => "stroke" === e.name || "stroke-layers" === e.name));
    const t = l(e);
    t && p(this._lottie, this.rawProperties.filter(e => "stroke" === e.name || "stroke-layers" === e.name), t), this.refresh();
  }
  get stroke() {
    const e = this.rawProperties.filter(e => "stroke" === e.name || "stroke-layers" === e.name)[0];
    if (e) {
      return l(+s(this._lottie, e.path)) || null;
    }
    return null;
  }
  set state(e) {
    if (e === this.state) return;
    const i = this.isPlaying;
    this._state = void 0, t(e) ? this._state = this._states.filter(e => e.default)[0] : e && (this._state = this._states.filter(t => t.name === e)[0], this._state || (this._state = this._states.filter(e => e.default)[0])), this._state ? this._lottie?.setSegment(this._state.time, this._state.time + this._state.duration + 1) : this._lottie.resetSegments(!0), this.goToFirstFrame(), i && (this.pause(), this.play());
  }
  get state() {
    return this._state ? this._state.name : "";
  }
  set speed(e) {
    this._speed = e, this._lottie?.setSpeed(e);
  }
  get speed() {
    return this._speed;
  }
  set direction(e) {
    this._direction = e, this._lottie.setDirection(e);
  }
  get direction() {
    return this._direction;
  }
  set loop(e) {
    this._lottie.loop = e;
  }
  get loop() {
    return !!this._lottie.loop;
  }
  set frame(e) {
    this.goToFrame(Math.max(0, Math.min(this.frames, e)));
  }
  get frame() {
    return this._lottie.currentFrame;
  }
  get states() {
    return this._states;
  }
  get isPlaying() {
    return !this._lottie.isPaused;
  }
  get isReady() {
    return this._isReady;
  }
  get frames() {
    return this._lottie.getDuration(!0) - 1;
  }
  get duration() {
    return this._lottie.getDuration(!1);
  }
  get lottie() {
    return this._lottie;
  }
  get rawProperties() {
    return this._rawProperties || (this._rawProperties = m(this._iconData, {
      lottieInstance: !0
    }), !this._states.length && this._rawProperties && (this._rawProperties = this._rawProperties.filter(e => "scale" !== e.name && "axis" !== e.name && "stroke" !== e.name && !e.name.startsWith("state-")))), this._rawProperties || [];
  }
}
class D {
  player;
  element;
  targetElement;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.onHover = this.onHover.bind(this);
  }
  onConnected() {
    this.targetElement.addEventListener("mouseenter", this.onHover);
  }
  onDisconnected() {
    this.targetElement.removeEventListener("mouseenter", this.onHover), this.player.direction = 1;
  }
  onComplete() {
    this.player.direction = -1, this.player.play();
  }
  onHover() {
    this.player.direction = 1, this.player.play();
  }
}
const T = [{
  name: "mousedown"
}, {
  name: "touchstart",
  options: {
    passive: !0
  }
}];
class P {
  player;
  element;
  targetElement;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.onClick = this.onClick.bind(this);
  }
  onConnected() {
    for (const e of T) this.targetElement.addEventListener(e.name, this.onClick, e.options);
  }
  onDisconnected() {
    for (const e of T) this.targetElement.removeEventListener(e.name, this.onClick);
  }
  onClick() {
    this.player.isPlaying || this.player.playFromBeginning();
  }
}
class A {
  player;
  element;
  targetElement;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.onHover = this.onHover.bind(this);
  }
  onConnected() {
    this.targetElement.addEventListener("mouseenter", this.onHover);
  }
  onDisconnected() {
    this.targetElement.removeEventListener("mouseenter", this.onHover);
  }
  onHover() {
    this.player.isPlaying || this.player.playFromBeginning();
  }
}
class F {
  player;
  element;
  targetElement;
  playTimeout = null;
  played = !1;
  intersectionObserver;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i;
  }
  onConnected() {
    if (this.loading) this.play();else {
      const e = (e, t) => {
        e.forEach(e => {
          e.isIntersecting && (this.play(), this.resetIntersectionObserver());
        });
      };
      this.intersectionObserver = new IntersectionObserver(e), this.intersectionObserver.observe(this.element);
    }
  }
  onDisconnected() {
    this.played = !1, this.resetIntersectionObserver(), this.resetPlayDelayTimer();
  }
  play() {
    this.played || (this.played = !0, this.resetPlayDelayTimer(), this.delay > 0 ? this.playTimeout = setTimeout(() => {
      this.player.playFromBeginning(), this.playTimeout = null;
    }, this.delay) : this.player.playFromBeginning());
  }
  resetIntersectionObserver() {
    this.intersectionObserver && (this.intersectionObserver.unobserve(this.element), this.intersectionObserver = void 0);
  }
  resetPlayDelayTimer() {
    this.playTimeout && (clearTimeout(this.playTimeout), this.playTimeout = null);
  }
  get delay() {
    const e = this.element.hasAttribute("delay") ? +(this.element.getAttribute("delay") || 0) : 0;
    return Math.max(e, 0);
  }
  get loading() {
    return this.element.hasAttribute("loading");
  }
}
class x {
  player;
  element;
  targetElement;
  playTimeout = null;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i;
  }
  onReady() {
    this.play();
  }
  onComplete() {
    this.play();
  }
  onDisconnected() {
    this.resetPlayDelayTimer();
  }
  play() {
    this.resetPlayDelayTimer(), this.delay > 0 ? this.playTimeout = setTimeout(() => {
      this.player.playFromBeginning();
    }, this.delay) : this.player.playFromBeginning();
  }
  resetPlayDelayTimer() {
    this.playTimeout && (clearTimeout(this.playTimeout), this.playTimeout = null);
  }
  get delay() {
    const e = this.element.hasAttribute("delay") ? +(this.element.getAttribute("delay") || 0) : 0;
    return Math.max(e, 0);
  }
}
class M {
  player;
  element;
  targetElement;
  playTimeout = null;
  mouseIn = !1;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.onMouseEnter = this.onMouseEnter.bind(this), this.onMouseLeave = this.onMouseLeave.bind(this);
  }
  onConnected() {
    this.targetElement.addEventListener("mouseenter", this.onMouseEnter), this.targetElement.addEventListener("mouseleave", this.onMouseLeave);
  }
  onDisconnected() {
    this.targetElement.removeEventListener("mouseenter", this.onMouseEnter), this.targetElement.removeEventListener("mouseleave", this.onMouseLeave), this.resetPlayDelayTimer();
  }
  onMouseEnter() {
    this.mouseIn = !0, this.player.isPlaying || this.play();
  }
  onMouseLeave() {
    this.mouseIn = !1, this.resetPlayDelayTimer();
  }
  onComplete() {
    this.play();
  }
  play() {
    this.resetPlayDelayTimer(), this.mouseIn && (this.delay > 0 ? this.playTimeout = setTimeout(() => {
      this.player.playFromBeginning();
    }, this.delay) : this.player.playFromBeginning());
  }
  resetPlayDelayTimer() {
    this.playTimeout && (clearTimeout(this.playTimeout), this.playTimeout = null);
  }
  get delay() {
    const e = this.element.hasAttribute("delay") ? +(this.element.getAttribute("delay") || 0) : 0;
    return Math.max(e, 0);
  }
}
class S {
  player;
  element;
  targetElement;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.onMouseEnter = this.onMouseEnter.bind(this), this.onMouseLeave = this.onMouseLeave.bind(this);
  }
  onConnected() {
    this.targetElement.addEventListener("mouseenter", this.onMouseEnter), this.targetElement.addEventListener("mouseleave", this.onMouseLeave);
  }
  onDisconnected() {
    this.targetElement.removeEventListener("mouseenter", this.onMouseEnter), this.targetElement.removeEventListener("mouseleave", this.onMouseLeave), this.player.direction = 1;
  }
  onMouseEnter() {
    this.player.direction = 1, this.player.play();
  }
  onMouseLeave() {
    this.player.direction = -1, this.player.play();
  }
}
const R = /^\d*(\.\d+)?$/,
  $ = {
    attributes: !0,
    childList: !1,
    subtree: !1
  };
class q {
  player;
  element;
  targetElement;
  sequenceIndex = 0;
  frameState = null;
  frameDelayFirst = null;
  frameDelayLast = null;
  timer;
  observer;
  constructor(e, t, i) {
    this.player = e, this.element = t, this.targetElement = i, this.observer = new MutationObserver((e, t) => {
      for (const t of e) "attributes" === t.type && ["sequence", "speed"].includes(t.attributeName) && (this.reset(), this.step());
    });
  }
  onReady() {
    this.step();
  }
  onComplete() {
    this.timer = setTimeout(() => {
      this.timer = null, this.frameDelayLast = null, this.step();
    }, this.frameDelayLast || 0);
  }
  onConnected() {
    this.observer.observe(this.element, $), this.player.speed = this.speed;
  }
  onDisconnected() {
    this.observer.disconnect(), this.timer && (clearTimeout(this.timer), this.timer = null), this.player.speed = 1;
  }
  reset() {
    this.player.pause(), this.player.speed = this.speed, this.sequenceIndex = 0, this.frameState = this.frameDelayFirst = this.frameDelayLast = null, this.timer && (clearTimeout(this.timer), this.timer = null);
  }
  takeStep() {
    const e = this.sequence.split(","),
      t = e[this.sequenceIndex];
    this.sequenceIndex++, this.sequenceIndex >= e.length && (this.sequenceIndex = 0);
    const [i, ...s] = t.split(":");
    return {
      action: i,
      params: s
    };
  }
  handleStep(e, t) {
    if ("play" === e) {
      this.frameState && (this.player.state = this.frameState, this.frameState = null);
      t.includes("reverse") ? (this.player.goToLastFrame(), this.player.direction = -1) : (this.player.goToFirstFrame(), this.player.direction = 1), this.timer = setTimeout(() => {
        this.timer = null, this.frameDelayFirst = null, this.player.play();
      }, this.frameDelayFirst || 0);
    } else if ("frame" === e) {
      let e = 0;
      t.length && t[0].match(R) && (e = Math.max(0, Math.min(this.player.frames, +t[0]))), this.player.frame = e, this.timer = setTimeout(() => {
        this.timer = null, this.frameDelayFirst = null, this.step();
      }, this.frameDelayFirst || 0);
    } else if ("state" === e) this.frameState = t[0], this.step();else if ("delay" === e) {
      let e = null;
      for (const i of t) i && i.match(R) && (e = +i);
      e && e > 0 && (t.includes("first") && t.includes("last") ? (this.frameDelayFirst = e, this.frameDelayLast = e) : t.includes("first") ? this.frameDelayFirst = e : t.includes("last") ? this.frameDelayLast = e : this.frameDelayFirst = e), this.step();
    } else if ("idle" !== e) throw new Error(`Invalid sequence action: ${e}`);
  }
  step() {
    const {
      action: e,
      params: t
    } = this.takeStep();
    e && this.handleStep(e, t);
  }
  get sequence() {
    return this.element.getAttribute("sequence") || "";
  }
  get speed() {
    return this.element.hasAttribute("speed") ? +(this.element.getAttribute("speed") || 1) : 1;
  }
}
function O(e) {
  I.setPlayerFactory((t, i, s) => new L(e, t, i, s)), I.defineTrigger("in", F), I.defineTrigger("click", P), I.defineTrigger("hover", A), I.defineTrigger("loop", x), I.defineTrigger("loop-on-hover", M), I.defineTrigger("morph", S), I.defineTrigger("boomerang", D), I.defineTrigger("sequence", q), I.defineTrigger("morph-two-way", D), customElements.get && customElements.get("lord-icon") || customElements.define("lord-icon", I);
}


/***/ }),

/***/ 48418:
/*!***************************************************************************!*\
  !*** ./node_modules/@ng-bootstrap/ng-bootstrap/fesm2022/ng-bootstrap.mjs ***!
  \***************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ModalDismissReasons: () => (/* binding */ ModalDismissReasons),
/* harmony export */   NgbAccordionBody: () => (/* binding */ NgbAccordionBody),
/* harmony export */   NgbAccordionButton: () => (/* binding */ NgbAccordionButton),
/* harmony export */   NgbAccordionCollapse: () => (/* binding */ NgbAccordionCollapse),
/* harmony export */   NgbAccordionConfig: () => (/* binding */ NgbAccordionConfig),
/* harmony export */   NgbAccordionDirective: () => (/* binding */ NgbAccordionDirective),
/* harmony export */   NgbAccordionHeader: () => (/* binding */ NgbAccordionHeader),
/* harmony export */   NgbAccordionItem: () => (/* binding */ NgbAccordionItem),
/* harmony export */   NgbAccordionModule: () => (/* binding */ NgbAccordionModule),
/* harmony export */   NgbAccordionToggle: () => (/* binding */ NgbAccordionToggle),
/* harmony export */   NgbActiveModal: () => (/* binding */ NgbActiveModal),
/* harmony export */   NgbActiveOffcanvas: () => (/* binding */ NgbActiveOffcanvas),
/* harmony export */   NgbAlert: () => (/* binding */ NgbAlert),
/* harmony export */   NgbAlertConfig: () => (/* binding */ NgbAlertConfig),
/* harmony export */   NgbAlertModule: () => (/* binding */ NgbAlertModule),
/* harmony export */   NgbCalendar: () => (/* binding */ NgbCalendar),
/* harmony export */   NgbCalendarBuddhist: () => (/* binding */ NgbCalendarBuddhist),
/* harmony export */   NgbCalendarEthiopian: () => (/* binding */ NgbCalendarEthiopian),
/* harmony export */   NgbCalendarGregorian: () => (/* binding */ NgbCalendarGregorian),
/* harmony export */   NgbCalendarHebrew: () => (/* binding */ NgbCalendarHebrew),
/* harmony export */   NgbCalendarIslamicCivil: () => (/* binding */ NgbCalendarIslamicCivil),
/* harmony export */   NgbCalendarIslamicUmalqura: () => (/* binding */ NgbCalendarIslamicUmalqura),
/* harmony export */   NgbCalendarPersian: () => (/* binding */ NgbCalendarPersian),
/* harmony export */   NgbCarousel: () => (/* binding */ NgbCarousel),
/* harmony export */   NgbCarouselConfig: () => (/* binding */ NgbCarouselConfig),
/* harmony export */   NgbCarouselModule: () => (/* binding */ NgbCarouselModule),
/* harmony export */   NgbCollapse: () => (/* binding */ NgbCollapse),
/* harmony export */   NgbCollapseConfig: () => (/* binding */ NgbCollapseConfig),
/* harmony export */   NgbCollapseModule: () => (/* binding */ NgbCollapseModule),
/* harmony export */   NgbConfig: () => (/* binding */ NgbConfig),
/* harmony export */   NgbDate: () => (/* binding */ NgbDate),
/* harmony export */   NgbDateAdapter: () => (/* binding */ NgbDateAdapter),
/* harmony export */   NgbDateNativeAdapter: () => (/* binding */ NgbDateNativeAdapter),
/* harmony export */   NgbDateNativeUTCAdapter: () => (/* binding */ NgbDateNativeUTCAdapter),
/* harmony export */   NgbDateParserFormatter: () => (/* binding */ NgbDateParserFormatter),
/* harmony export */   NgbDateStructAdapter: () => (/* binding */ NgbDateStructAdapter),
/* harmony export */   NgbDatepicker: () => (/* binding */ NgbDatepicker),
/* harmony export */   NgbDatepickerConfig: () => (/* binding */ NgbDatepickerConfig),
/* harmony export */   NgbDatepickerContent: () => (/* binding */ NgbDatepickerContent),
/* harmony export */   NgbDatepickerI18n: () => (/* binding */ NgbDatepickerI18n),
/* harmony export */   NgbDatepickerI18nAmharic: () => (/* binding */ NgbDatepickerI18nAmharic),
/* harmony export */   NgbDatepickerI18nDefault: () => (/* binding */ NgbDatepickerI18nDefault),
/* harmony export */   NgbDatepickerI18nHebrew: () => (/* binding */ NgbDatepickerI18nHebrew),
/* harmony export */   NgbDatepickerKeyboardService: () => (/* binding */ NgbDatepickerKeyboardService),
/* harmony export */   NgbDatepickerModule: () => (/* binding */ NgbDatepickerModule),
/* harmony export */   NgbDatepickerMonth: () => (/* binding */ NgbDatepickerMonth),
/* harmony export */   NgbDropdown: () => (/* binding */ NgbDropdown),
/* harmony export */   NgbDropdownAnchor: () => (/* binding */ NgbDropdownAnchor),
/* harmony export */   NgbDropdownButtonItem: () => (/* binding */ NgbDropdownButtonItem),
/* harmony export */   NgbDropdownConfig: () => (/* binding */ NgbDropdownConfig),
/* harmony export */   NgbDropdownItem: () => (/* binding */ NgbDropdownItem),
/* harmony export */   NgbDropdownMenu: () => (/* binding */ NgbDropdownMenu),
/* harmony export */   NgbDropdownModule: () => (/* binding */ NgbDropdownModule),
/* harmony export */   NgbDropdownToggle: () => (/* binding */ NgbDropdownToggle),
/* harmony export */   NgbHighlight: () => (/* binding */ NgbHighlight),
/* harmony export */   NgbInputDatepicker: () => (/* binding */ NgbInputDatepicker),
/* harmony export */   NgbInputDatepickerConfig: () => (/* binding */ NgbInputDatepickerConfig),
/* harmony export */   NgbModal: () => (/* binding */ NgbModal),
/* harmony export */   NgbModalConfig: () => (/* binding */ NgbModalConfig),
/* harmony export */   NgbModalModule: () => (/* binding */ NgbModalModule),
/* harmony export */   NgbModalRef: () => (/* binding */ NgbModalRef),
/* harmony export */   NgbModule: () => (/* binding */ NgbModule),
/* harmony export */   NgbNav: () => (/* binding */ NgbNav),
/* harmony export */   NgbNavConfig: () => (/* binding */ NgbNavConfig),
/* harmony export */   NgbNavContent: () => (/* binding */ NgbNavContent),
/* harmony export */   NgbNavItem: () => (/* binding */ NgbNavItem),
/* harmony export */   NgbNavItemRole: () => (/* binding */ NgbNavItemRole),
/* harmony export */   NgbNavLink: () => (/* binding */ NgbNavLink),
/* harmony export */   NgbNavLinkBase: () => (/* binding */ NgbNavLinkBase),
/* harmony export */   NgbNavLinkButton: () => (/* binding */ NgbNavLinkButton),
/* harmony export */   NgbNavModule: () => (/* binding */ NgbNavModule),
/* harmony export */   NgbNavOutlet: () => (/* binding */ NgbNavOutlet),
/* harmony export */   NgbNavPane: () => (/* binding */ NgbNavPane),
/* harmony export */   NgbOffcanvas: () => (/* binding */ NgbOffcanvas),
/* harmony export */   NgbOffcanvasConfig: () => (/* binding */ NgbOffcanvasConfig),
/* harmony export */   NgbOffcanvasModule: () => (/* binding */ NgbOffcanvasModule),
/* harmony export */   NgbOffcanvasRef: () => (/* binding */ NgbOffcanvasRef),
/* harmony export */   NgbPagination: () => (/* binding */ NgbPagination),
/* harmony export */   NgbPaginationConfig: () => (/* binding */ NgbPaginationConfig),
/* harmony export */   NgbPaginationEllipsis: () => (/* binding */ NgbPaginationEllipsis),
/* harmony export */   NgbPaginationFirst: () => (/* binding */ NgbPaginationFirst),
/* harmony export */   NgbPaginationLast: () => (/* binding */ NgbPaginationLast),
/* harmony export */   NgbPaginationModule: () => (/* binding */ NgbPaginationModule),
/* harmony export */   NgbPaginationNext: () => (/* binding */ NgbPaginationNext),
/* harmony export */   NgbPaginationNumber: () => (/* binding */ NgbPaginationNumber),
/* harmony export */   NgbPaginationPages: () => (/* binding */ NgbPaginationPages),
/* harmony export */   NgbPaginationPrevious: () => (/* binding */ NgbPaginationPrevious),
/* harmony export */   NgbPopover: () => (/* binding */ NgbPopover),
/* harmony export */   NgbPopoverConfig: () => (/* binding */ NgbPopoverConfig),
/* harmony export */   NgbPopoverModule: () => (/* binding */ NgbPopoverModule),
/* harmony export */   NgbProgressbar: () => (/* binding */ NgbProgressbar),
/* harmony export */   NgbProgressbarConfig: () => (/* binding */ NgbProgressbarConfig),
/* harmony export */   NgbProgressbarModule: () => (/* binding */ NgbProgressbarModule),
/* harmony export */   NgbProgressbarStacked: () => (/* binding */ NgbProgressbarStacked),
/* harmony export */   NgbRating: () => (/* binding */ NgbRating),
/* harmony export */   NgbRatingConfig: () => (/* binding */ NgbRatingConfig),
/* harmony export */   NgbRatingModule: () => (/* binding */ NgbRatingModule),
/* harmony export */   NgbScrollSpy: () => (/* binding */ NgbScrollSpy),
/* harmony export */   NgbScrollSpyConfig: () => (/* binding */ NgbScrollSpyConfig),
/* harmony export */   NgbScrollSpyFragment: () => (/* binding */ NgbScrollSpyFragment),
/* harmony export */   NgbScrollSpyItem: () => (/* binding */ NgbScrollSpyItem),
/* harmony export */   NgbScrollSpyMenu: () => (/* binding */ NgbScrollSpyMenu),
/* harmony export */   NgbScrollSpyModule: () => (/* binding */ NgbScrollSpyModule),
/* harmony export */   NgbScrollSpyService: () => (/* binding */ NgbScrollSpyService),
/* harmony export */   NgbSlide: () => (/* binding */ NgbSlide),
/* harmony export */   NgbSlideEventDirection: () => (/* binding */ NgbSlideEventDirection),
/* harmony export */   NgbSlideEventSource: () => (/* binding */ NgbSlideEventSource),
/* harmony export */   NgbTimeAdapter: () => (/* binding */ NgbTimeAdapter),
/* harmony export */   NgbTimepicker: () => (/* binding */ NgbTimepicker),
/* harmony export */   NgbTimepickerConfig: () => (/* binding */ NgbTimepickerConfig),
/* harmony export */   NgbTimepickerI18n: () => (/* binding */ NgbTimepickerI18n),
/* harmony export */   NgbTimepickerModule: () => (/* binding */ NgbTimepickerModule),
/* harmony export */   NgbToast: () => (/* binding */ NgbToast),
/* harmony export */   NgbToastConfig: () => (/* binding */ NgbToastConfig),
/* harmony export */   NgbToastHeader: () => (/* binding */ NgbToastHeader),
/* harmony export */   NgbToastModule: () => (/* binding */ NgbToastModule),
/* harmony export */   NgbTooltip: () => (/* binding */ NgbTooltip),
/* harmony export */   NgbTooltipConfig: () => (/* binding */ NgbTooltipConfig),
/* harmony export */   NgbTooltipModule: () => (/* binding */ NgbTooltipModule),
/* harmony export */   NgbTypeahead: () => (/* binding */ NgbTypeahead),
/* harmony export */   NgbTypeaheadConfig: () => (/* binding */ NgbTypeaheadConfig),
/* harmony export */   NgbTypeaheadModule: () => (/* binding */ NgbTypeaheadModule),
/* harmony export */   OffcanvasDismissReasons: () => (/* binding */ OffcanvasDismissReasons)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @angular/core/rxjs-interop */ 49074);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 59400);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 18537);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 14876);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs */ 66096);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs */ 19999);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs */ 79439);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! rxjs */ 50774);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 12576);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs/operators */ 91817);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(/*! rxjs/operators */ 15842);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(/*! rxjs/operators */ 95074);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(/*! rxjs/operators */ 13255);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(/*! rxjs/operators */ 47470);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(/*! rxjs/operators */ 89475);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! @angular/forms */ 34456);
/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(/*! @popperjs/core */ 94970);
/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(/*! @popperjs/core */ 77437);
/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(/*! @popperjs/core */ 87348);
/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(/*! @popperjs/core */ 65125);
/* harmony import */ var _popperjs_core__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(/*! @popperjs/core */ 30142);








const _c0 = ["*"];
function NgbAlert_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbAlert_Conditional_1_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.close());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function NgbCarousel_For_2_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbCarousel_For_2_Template_button_click_0_listener() {
      const slide_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1).$implicit;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r2.focus();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.select(slide_r2.id, ctx_r2.NgbSlideEventSource.INDICATOR));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const slide_r2 = ctx.$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("active", slide_r2.id === ctx_r2.activeId);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-labelledby", "slide-" + slide_r2.id)("aria-controls", "slide-" + slide_r2.id)("aria-selected", slide_r2.id === ctx_r2.activeId);
  }
}
function NgbCarousel_For_5_ng_template_3_Template(rf, ctx) {}
function NgbCarousel_For_5_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 6)(1, "span", 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](2, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbCarousel_For_5_ng_template_3_Template, 0, 0, "ng-template", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const slide_r4 = ctx.$implicit;
    const i_r5 = ctx.$index;
    const c_r6 = ctx.$count;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", "slide-" + slide_r4.id);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nExp"](i_r5 + 1)(c_r6);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nApply"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", slide_r4.templateRef);
  }
}
function NgbCarousel_Conditional_6_Template(rf, ctx) {
  if (rf & 1) {
    const _r7 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbCarousel_Conditional_6_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r7);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.arrowLeft());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "button", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbCarousel_Conditional_6_Template_button_click_4_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r7);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r2.arrowRight());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](5, "span", 14);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "span", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](7, 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-labelledby", ctx_r2.id + "-previous");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", ctx_r2.id + "-previous");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-labelledby", ctx_r2.id + "-next");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", ctx_r2.id + "-next");
  }
}
const _c1 = ["ngbDatepickerDayView", ""];
const _c2 = ["month"];
const _c3 = ["year"];
function NgbDatepickerNavigationSelect_For_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "option", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const m_r2 = ctx.$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("value", m_r2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-label", ctx_r2.i18n.getMonthFullName(m_r2, ctx_r2.date.year));
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r2.i18n.getMonthShortName(m_r2, ctx_r2.date.year));
  }
}
function NgbDatepickerNavigationSelect_For_7_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "option", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const y_r4 = ctx.$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("value", y_r4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r2.i18n.getYearNumerals(y_r4));
  }
}
function NgbDatepickerNavigation_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "ngb-datepicker-navigation-select", 6);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("select", function NgbDatepickerNavigation_Conditional_3_Template_ngb_datepicker_navigation_select_select_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.select.emit($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("date", ctx_r1.date)("disabled", ctx_r1.disabled)("months", ctx_r1.selectBoxes.months)("years", ctx_r1.selectBoxes.years);
  }
}
function NgbDatepickerNavigation_Conditional_4_For_1_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 7);
  }
}
function NgbDatepickerNavigation_Conditional_4_For_1_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 7);
  }
}
function NgbDatepickerNavigation_Conditional_4_For_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbDatepickerNavigation_Conditional_4_For_1_Conditional_0_Template, 1, 0, "div", 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbDatepickerNavigation_Conditional_4_For_1_Conditional_3_Template, 1, 0, "div", 7);
  }
  if (rf & 2) {
    const month_r3 = ctx.$implicit;
    const i_r4 = ctx.$index;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, i_r4 > 0 ? 0 : -1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx_r1.i18n.getMonthLabel(month_r3.firstDate), " ");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, i_r4 !== ctx_r1.months.length - 1 ? 3 : -1);
  }
}
function NgbDatepickerNavigation_Conditional_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](0, NgbDatepickerNavigation_Conditional_4_For_1_Template, 4, 3, null, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx_r1.months);
  }
}
function NgbDatepickerMonth_Conditional_0_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.i18n.getWeekLabel());
  }
}
function NgbDatepickerMonth_Conditional_0_For_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const weekday_r2 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](weekday_r2);
  }
}
function NgbDatepickerMonth_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbDatepickerMonth_Conditional_0_Conditional_1_Template, 2, 1, "div", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](2, NgbDatepickerMonth_Conditional_0_For_3_Template, 2, 1, "div", 2, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx_r0.datepicker.showWeekNumbers ? 1 : -1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx_r0.viewModel.weekdays);
  }
}
function NgbDatepickerMonth_For_2_Conditional_0_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const week_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2).$implicit;
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.i18n.getWeekNumerals(week_r3.number));
  }
}
function NgbDatepickerMonth_For_2_Conditional_0_For_3_Conditional_1_ng_template_0_Template(rf, ctx) {}
function NgbDatepickerMonth_For_2_Conditional_0_For_3_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbDatepickerMonth_For_2_Conditional_0_For_3_Conditional_1_ng_template_0_Template, 0, 0, "ng-template", 7);
  }
  if (rf & 2) {
    const day_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.datepicker.dayTemplate)("ngTemplateOutletContext", day_r5.context);
  }
}
function NgbDatepickerMonth_For_2_Conditional_0_For_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 6);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbDatepickerMonth_For_2_Conditional_0_For_3_Template_div_click_0_listener($event) {
      const day_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4).$implicit;
      const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
      ctx_r0.doSelect(day_r5);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbDatepickerMonth_For_2_Conditional_0_For_3_Conditional_1_Template, 1, 2, null, 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const day_r5 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", day_r5.context.disabled)("hidden", day_r5.hidden)("ngb-dp-today", day_r5.context.today);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("tabindex", day_r5.tabindex);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-label", day_r5.ariaLabel);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, !day_r5.hidden ? 1 : -1);
  }
}
function NgbDatepickerMonth_For_2_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbDatepickerMonth_For_2_Conditional_0_Conditional_1_Template, 2, 1, "div", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](2, NgbDatepickerMonth_For_2_Conditional_0_For_3_Template, 2, 9, "div", 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const week_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx_r0.datepicker.showWeekNumbers ? 1 : -1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](week_r3.days);
  }
}
function NgbDatepickerMonth_For_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbDatepickerMonth_For_2_Conditional_0_Template, 4, 1, "div", 3);
  }
  if (rf & 2) {
    const week_r3 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, !week_r3.collapsed ? 0 : -1);
  }
}
const _c4 = ["defaultDayTemplate"];
const _c5 = ["content"];
const _c6 = a0 => ({
  $implicit: a0
});
function NgbDatepicker_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 8);
  }
  if (rf & 2) {
    const date_r1 = ctx.date;
    const currentMonth_r2 = ctx.currentMonth;
    const selected_r3 = ctx.selected;
    const disabled_r4 = ctx.disabled;
    const focused_r5 = ctx.focused;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("date", date_r1)("currentMonth", currentMonth_r2)("selected", selected_r3)("disabled", disabled_r4)("focused", focused_r5);
  }
}
function NgbDatepicker_ng_template_2_For_1_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const month_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"](" ", ctx_r6.i18n.getMonthLabel(month_r6.firstDate), " ");
  }
}
function NgbDatepicker_ng_template_2_For_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbDatepicker_ng_template_2_For_1_Conditional_1_Template, 2, 1, "div", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](2, "ngb-datepicker-month", 11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const month_r6 = ctx.$implicit;
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx_r6.navigation === "none" || ctx_r6.displayMonths > 1 && ctx_r6.navigation === "select" ? 1 : -1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("month", month_r6.firstDate);
  }
}
function NgbDatepicker_ng_template_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](0, NgbDatepicker_ng_template_2_For_1_Template, 3, 2, "div", 9, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
  }
  if (rf & 2) {
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx_r6.model.months);
  }
}
function NgbDatepicker_Conditional_5_Template(rf, ctx) {
  if (rf & 1) {
    const _r8 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "ngb-datepicker-navigation", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("navigate", function NgbDatepicker_Conditional_5_Template_ngb_datepicker_navigation_navigate_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r6.onNavigateEvent($event));
    })("select", function NgbDatepicker_Conditional_5_Template_ngb_datepicker_navigation_select_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r6.onNavigateDateSelect($event));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("date", ctx_r6.model.firstDate)("months", ctx_r6.model.months)("disabled", ctx_r6.model.disabled)("showSelect", ctx_r6.model.navigation === "select")("prevDisabled", ctx_r6.model.prevDisabled)("nextDisabled", ctx_r6.model.nextDisabled)("selectBoxes", ctx_r6.model.selectBoxes);
  }
}
function NgbDatepicker_ng_template_8_Template(rf, ctx) {}
function NgbDatepicker_ng_template_9_Template(rf, ctx) {}
const _c7 = ["dialog"];
const _c8 = ["ngbNavOutlet", ""];
function NgbNavOutlet_For_1_Conditional_0_ng_template_1_Template(rf, ctx) {}
function NgbNavOutlet_For_1_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbNavOutlet_For_1_Conditional_0_ng_template_1_Template, 0, 0, "ng-template", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const item_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("item", item_r1)("nav", ctx_r1.nav)("role", ctx_r1.paneRole);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (item_r1.contentTpl == null ? null : item_r1.contentTpl.templateRef) || null)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](5, _c6, item_r1.active || ctx_r1.isPanelTransitioning(item_r1)));
  }
}
function NgbNavOutlet_For_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbNavOutlet_For_1_Conditional_0_Template, 2, 7, "div", 0);
  }
  if (rf & 2) {
    const item_r1 = ctx.$implicit;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, item_r1.isPanelInDom() || ctx_r1.isPanelTransitioning(item_r1) ? 0 : -1);
  }
}
const _c9 = (a0, a1, a2) => ({
  $implicit: a0,
  pages: a1,
  disabled: a2
});
const _c10 = a0 => ({
  disabled: true,
  currentPage: a0
});
const _c11 = (a0, a1, a2) => ({
  disabled: a0,
  $implicit: a1,
  currentPage: a2
});
const _c12 = (a0, a1) => ({
  disabled: a0,
  currentPage: a1
});
const _c13 = a0 => ({
  disabled: a0
});
function NgbPagination_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function NgbPagination_ng_template_2_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function NgbPagination_ng_template_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function NgbPagination_ng_template_6_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 13);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
}
function NgbPagination_ng_template_8_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0, "...");
  }
}
function NgbPagination_ng_template_10_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
  }
  if (rf & 2) {
    const page_r1 = ctx.$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](page_r1);
  }
}
function NgbPagination_ng_template_12_For_1_Conditional_1_ng_template_1_Template(rf, ctx) {}
function NgbPagination_ng_template_12_For_1_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "a", 16);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbPagination_ng_template_12_For_1_Conditional_1_ng_template_1_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const page_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2).$implicit;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const ellipsis_r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](9);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplEllipsis == null ? null : ctx_r2.tplEllipsis.templateRef) || ellipsis_r4)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](2, _c10, page_r2));
  }
}
function NgbPagination_ng_template_12_For_1_Conditional_2_ng_template_1_Template(rf, ctx) {}
function NgbPagination_ng_template_12_For_1_Conditional_2_Template(rf, ctx) {
  if (rf & 1) {
    const _r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "a", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbPagination_ng_template_12_For_1_Conditional_2_Template_a_click_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r5);
      const pageNumber_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      ctx_r2.selectPage(pageNumber_r6);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbPagination_ng_template_12_For_1_Conditional_2_ng_template_1_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const pageNumber_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const page_r2 = ctx_r6.$implicit;
    const disabled_r8 = ctx_r6.disabled;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const defaultNumber_r9 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](11);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("tabindex", disabled_r8 ? "-1" : null)("aria-disabled", disabled_r8 ? "true" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplNumber == null ? null : ctx_r2.tplNumber.templateRef) || defaultNumber_r9)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction3"](4, _c11, disabled_r8, pageNumber_r6, page_r2));
  }
}
function NgbPagination_ng_template_12_For_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "li", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbPagination_ng_template_12_For_1_Conditional_1_Template, 2, 4, "a", 16)(2, NgbPagination_ng_template_12_For_1_Conditional_2_Template, 2, 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const pageNumber_r6 = ctx.$implicit;
    const ctx_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const page_r2 = ctx_r6.$implicit;
    const disabled_r8 = ctx_r6.disabled;
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("active", pageNumber_r6 === page_r2)("disabled", ctx_r2.isEllipsis(pageNumber_r6) || disabled_r8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-current", pageNumber_r6 === page_r2 ? "page" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx_r2.isEllipsis(pageNumber_r6) ? 1 : 2);
  }
}
function NgbPagination_ng_template_12_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](0, NgbPagination_ng_template_12_For_1_Template, 3, 6, "li", 14, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
  }
  if (rf & 2) {
    const pages_r10 = ctx.pages;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](pages_r10);
  }
}
function NgbPagination_Conditional_15_ng_template_2_Template(rf, ctx) {}
function NgbPagination_Conditional_15_Template(rf, ctx) {
  if (rf & 1) {
    const _r11 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "li", 15)(1, "a", 18);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbPagination_Conditional_15_Template_a_click_1_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r11);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r2.selectPage(1);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, NgbPagination_Conditional_15_ng_template_2_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const first_r12 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx_r2.previousDisabled());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("tabindex", ctx_r2.previousDisabled() ? "-1" : null)("aria-disabled", ctx_r2.previousDisabled() ? "true" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplFirst == null ? null : ctx_r2.tplFirst.templateRef) || first_r12)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction2"](6, _c12, ctx_r2.previousDisabled(), ctx_r2.page));
  }
}
function NgbPagination_Conditional_16_ng_template_2_Template(rf, ctx) {}
function NgbPagination_Conditional_16_Template(rf, ctx) {
  if (rf & 1) {
    const _r13 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "li", 15)(1, "a", 19);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbPagination_Conditional_16_Template_a_click_1_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r13);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r2.selectPage(ctx_r2.page - 1);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, NgbPagination_Conditional_16_ng_template_2_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const previous_r14 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx_r2.previousDisabled());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("tabindex", ctx_r2.previousDisabled() ? "-1" : null)("aria-disabled", ctx_r2.previousDisabled() ? "true" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplPrevious == null ? null : ctx_r2.tplPrevious.templateRef) || previous_r14)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](6, _c13, ctx_r2.previousDisabled()));
  }
}
function NgbPagination_ng_template_17_Template(rf, ctx) {}
function NgbPagination_Conditional_18_ng_template_2_Template(rf, ctx) {}
function NgbPagination_Conditional_18_Template(rf, ctx) {
  if (rf & 1) {
    const _r15 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "li", 15)(1, "a", 20);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbPagination_Conditional_18_Template_a_click_1_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r15);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r2.selectPage(ctx_r2.page + 1);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, NgbPagination_Conditional_18_ng_template_2_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const next_r16 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx_r2.nextDisabled());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("tabindex", ctx_r2.nextDisabled() ? "-1" : null)("aria-disabled", ctx_r2.nextDisabled() ? "true" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplNext == null ? null : ctx_r2.tplNext.templateRef) || next_r16)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction2"](6, _c12, ctx_r2.nextDisabled(), ctx_r2.page));
  }
}
function NgbPagination_Conditional_19_ng_template_2_Template(rf, ctx) {}
function NgbPagination_Conditional_19_Template(rf, ctx) {
  if (rf & 1) {
    const _r17 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "li", 15)(1, "a", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbPagination_Conditional_19_Template_a_click_1_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r17);
      const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r2.selectPage(ctx_r2.pageCount);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, NgbPagination_Conditional_19_ng_template_2_Template, 0, 0, "ng-template", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const last_r18 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx_r2.nextDisabled());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("tabindex", ctx_r2.nextDisabled() ? "-1" : null)("aria-disabled", ctx_r2.nextDisabled() ? "true" : null);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx_r2.tplLast == null ? null : ctx_r2.tplLast.templateRef) || last_r18)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction2"](6, _c12, ctx_r2.nextDisabled(), ctx_r2.page));
  }
}
function NgbPopoverWindow_Conditional_1_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.title);
  }
}
function NgbPopoverWindow_Conditional_1_ng_template_3_Template(rf, ctx) {}
function NgbPopoverWindow_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "h3", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbPopoverWindow_Conditional_1_ng_template_1_Template, 1, 1, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgbPopoverWindow_Conditional_1_ng_template_3_Template, 0, 0, "ng-template", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const simpleTitle_r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.isTitleTemplate() ? ctx_r0.title : simpleTitle_r2)("ngTemplateOutletContext", ctx_r0.context);
  }
}
function NgbProgressbar_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipe"](2, "percent");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nExp"](_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpipeBind1"](2, 1, ctx_r0.getValue() / ctx_r0.max));
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nApply"](1);
  }
}
function NgbRating_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
  }
  if (rf & 2) {
    const fill_r1 = ctx.fill;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](fill_r1 === 100 ? "\u2605" : "\u2606");
  }
}
function NgbRating_For_3_ng_template_3_Template(rf, ctx) {}
function NgbRating_For_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mouseenter", function NgbRating_For_3_Template_span_mouseenter_2_listener() {
      const index_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2).$index;
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.enter(index_r3 + 1));
    })("click", function NgbRating_For_3_Template_span_click_2_listener() {
      const index_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2).$index;
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.handleClick(index_r3 + 1));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbRating_For_3_ng_template_3_Template, 0, 0, "ng-template", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const index_r3 = ctx.$index;
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const t_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"]("(", index_r3 < ctx_r3.nextRate ? "*" : " ", ")");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("cursor", ctx_r3.isInteractive() ? "pointer" : "default");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.starTemplate || ctx_r3.starTemplateFromContent || t_r5)("ngTemplateOutletContext", ctx_r3.contexts[index_r3]);
  }
}
function NgbTimepicker_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_3_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeHour(ctx_r1.hourStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 16);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_5_Template(rf, ctx) {
  if (rf & 1) {
    const _r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_5_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r3);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeHour(-ctx_r1.hourStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 18);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_9_Template(rf, ctx) {
  if (rf & 1) {
    const _r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_9_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeMinute(ctx_r1.minuteStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 16);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_11_Template(rf, ctx) {
  if (rf & 1) {
    const _r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_11_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r5);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeMinute(-ctx_r1.minuteStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 18);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_12_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r7 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_12_Conditional_3_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r7);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeSecond(ctx_r1.secondStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 16);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_12_Conditional_5_Template(rf, ctx) {
  if (rf & 1) {
    const _r8 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 15);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_12_Conditional_5_Template_button_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.changeSecond(-ctx_r1.secondStep));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](1, "span", 18);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "span", 17);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](3, 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
  }
}
function NgbTimepicker_Conditional_12_Template(rf, ctx) {
  if (rf & 1) {
    const _r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1, ":");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "div", 19);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbTimepicker_Conditional_12_Conditional_3_Template, 4, 7, "button", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "input", 20);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function NgbTimepicker_Conditional_12_Template_input_change_4_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.updateSecond($event.target.value));
    })("blur", function NgbTimepicker_Conditional_12_Template_input_blur_4_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.handleBlur());
    })("input", function NgbTimepicker_Conditional_12_Template_input_input_4_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.formatInput($event.target));
    })("keydown.ArrowUp", function NgbTimepicker_Conditional_12_Template_input_keydown_ArrowUp_4_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r1.changeSecond(ctx_r1.secondStep);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    })("keydown.ArrowDown", function NgbTimepicker_Conditional_12_Template_input_keydown_ArrowDown_4_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r6);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      ctx_r1.changeSecond(-ctx_r1.secondStep);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.preventDefault());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](5, NgbTimepicker_Conditional_12_Conditional_5_Template, 4, 7, "button", 10);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, ctx_r1.spinners ? 3 : -1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("form-control-sm", ctx_r1.isSmallSize)("form-control-lg", ctx_r1.isLargeSize);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("value", ctx_r1.formatMinSec(ctx_r1.model == null ? null : ctx_r1.model.second))("readOnly", ctx_r1.readonlyInputs)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](5, ctx_r1.spinners ? 5 : -1);
  }
}
function NgbTimepicker_Conditional_13_Conditional_3_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18n"](1, 6);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nExp"](ctx_r1.i18n.getAfternoonPeriod());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵi18nApply"](1);
  }
}
function NgbTimepicker_Conditional_13_Conditional_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r1.i18n.getMorningPeriod());
  }
}
function NgbTimepicker_Conditional_13_Template(rf, ctx) {
  if (rf & 1) {
    const _r9 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 21)(2, "button", 22);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbTimepicker_Conditional_13_Template_button_click_2_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r9);
      const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r1.toggleMeridian());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbTimepicker_Conditional_13_Conditional_3_Template, 2, 1, "ng-container")(4, NgbTimepicker_Conditional_13_Conditional_4_Template, 2, 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("btn-sm", ctx_r1.isSmallSize)("btn-lg", ctx_r1.isLargeSize)("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx_r1.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, ctx_r1.model && ctx_r1.model.hour >= 12 ? 3 : 4);
  }
}
function NgbToast_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "strong", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r0.header);
  }
}
function NgbToast_Conditional_2_ng_template_1_Template(rf, ctx) {}
function NgbToast_Conditional_2_Template(rf, ctx) {
  if (rf & 1) {
    const _r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbToast_Conditional_2_ng_template_1_Template, 0, 0, "ng-template", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "button", 5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbToast_Conditional_2_Template_button_click_2_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2);
      const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r0.hide());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const headerTpl_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.contentHeaderTpl || headerTpl_r3);
  }
}
function NgbHighlight_For_1_Conditional_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const part_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"](ctx_r1.highlightClass);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](part_r1);
  }
}
function NgbHighlight_For_1_Conditional_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const part_r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](part_r1);
  }
}
function NgbHighlight_For_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbHighlight_For_1_Conditional_0_Template, 2, 4, "span", 0)(1, NgbHighlight_For_1_Conditional_1_Template, 2, 1);
  }
  if (rf & 2) {
    const ɵ$index_1_r3 = ctx.$index;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, ɵ$index_1_r3 % 2 !== 0 ? 0 : 1);
  }
}
const _c14 = (a0, a1, a2) => ({
  result: a0,
  term: a1,
  formatter: a2
});
function NgbTypeaheadWindow_ng_template_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "ngb-highlight", 2);
  }
  if (rf & 2) {
    const result_r1 = ctx.result;
    const term_r2 = ctx.term;
    const formatter_r3 = ctx.formatter;
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("result", formatter_r3(result_r1))("term", term_r2);
  }
}
function NgbTypeaheadWindow_For_3_ng_template_1_Template(rf, ctx) {}
function NgbTypeaheadWindow_For_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r4 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "button", 3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mouseenter", function NgbTypeaheadWindow_For_3_Template_button_mouseenter_0_listener() {
      const idx_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4).$index;
      const ctx_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r5.markActive(idx_r5));
    })("click", function NgbTypeaheadWindow_For_3_Template_button_click_0_listener() {
      const result_r7 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r4).$implicit;
      const ctx_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r5.select(result_r7));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbTypeaheadWindow_For_3_ng_template_1_Template, 0, 0, "ng-template", 4);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const result_r7 = ctx.$implicit;
    const idx_r5 = ctx.$index;
    const ctx_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    const rt_r8 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("active", idx_r5 === ctx_r5.activeIdx);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("id", ctx_r5.id + "-" + idx_r5);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r5.resultTemplate || rt_r8)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction3"](5, _c14, result_r7, ctx_r5.term, ctx_r5.formatter));
  }
}
const environment = {
  animation: true,
  transitionTimerDelayMs: 5
};

/**
 * Global ng-bootstrap config
 *
 * @since 8.0.0
 */
class NgbConfig {
  constructor() {
    this.animation = environment.animation;
  }
  static {
    this.ɵfac = function NgbConfig_Factory(t) {
      return new (t || NgbConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbConfig,
      factory: NgbConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbAccordionDirective`](#/components/accordion/api#NgbAccordionDirective).
 *
 * You can inject this service, typically in your root component, and customize its properties
 * to provide default values for all accordions used in the application.
 */
class NgbAccordionConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.closeOthers = false;
    this.destroyOnHide = true;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbAccordionConfig_Factory(t) {
      return new (t || NgbAccordionConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbAccordionConfig,
      factory: NgbAccordionConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function getTransitionDurationMs(element) {
  const {
    transitionDelay,
    transitionDuration
  } = window.getComputedStyle(element);
  const transitionDelaySec = parseFloat(transitionDelay);
  const transitionDurationSec = parseFloat(transitionDuration);
  return (transitionDelaySec + transitionDurationSec) * 1000;
}
function toInteger(value) {
  return parseInt(`${value}`, 10);
}
function toString(value) {
  return value !== undefined && value !== null ? `${value}` : '';
}
function getValueInRange(value, max, min = 0) {
  return Math.max(Math.min(value, max), min);
}
function isString(value) {
  return typeof value === 'string';
}
function isNumber(value) {
  return !isNaN(toInteger(value));
}
function isInteger(value) {
  return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
}
function isDefined(value) {
  return value !== undefined && value !== null;
}
function isPromise(v) {
  return v && v.then;
}
function padNumber(value) {
  if (isNumber(value)) {
    return `0${value}`.slice(-2);
  } else {
    return '';
  }
}
function regExpEscape(text) {
  return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
}
function closest(element, selector) {
  if (!selector) {
    return null;
  }
  /*
   * In certain browsers (e.g. Edge 44.18362.449.0) HTMLDocument does
   * not support `Element.prototype.closest`. To emulate the correct behaviour
   * we return null when the method is missing.
   *
   * Note that in evergreen browsers `closest(document.documentElement, 'html')`
   * will return the document element whilst in Edge null will be returned. This
   * compromise was deemed good enough.
   */
  if (typeof element.closest === 'undefined') {
    return null;
  }
  return element.closest(selector);
}
/**
 * Force a browser reflow
 * @param element element where to apply the reflow
 */
function reflow(element) {
  return (element || document.body).getBoundingClientRect();
}
/**
 * Creates an observable where all callbacks are executed inside a given zone
 *
 * @param zone
 */
function runInZone(zone) {
  return source => {
    return new rxjs__WEBPACK_IMPORTED_MODULE_1__.Observable(observer => {
      const next = value => zone.run(() => observer.next(value));
      const error = e => zone.run(() => observer.error(e));
      const complete = () => zone.run(() => observer.complete());
      return source.subscribe({
        next,
        error,
        complete
      });
    });
  };
}
function removeAccents(str) {
  return str.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
}
/**
 * Returns the active element in the given root.
 * If the active element is inside a shadow root, it is searched recursively.
 */
function getActiveElement(root = document) {
  const activeEl = root?.activeElement;
  if (!activeEl) {
    return null;
  }
  return activeEl.shadowRoot ? getActiveElement(activeEl.shadowRoot) : activeEl;
}
const noopFn = () => {};
const {
  transitionTimerDelayMs
} = environment;
const runningTransitions = new Map();
const ngbRunTransition = (zone, element, startFn, options) => {
  // Getting initial context from options
  let context = options.context || {};
  // Checking if there are already running transitions on the given element.
  const running = runningTransitions.get(element);
  if (running) {
    switch (options.runningTransition) {
      // If there is one running and we want for it to 'continue' to run, we have to cancel the new one.
      // We're not emitting any values, but simply completing the observable (EMPTY).
      case 'continue':
        return rxjs__WEBPACK_IMPORTED_MODULE_2__.EMPTY;
      // If there is one running and we want for it to 'stop', we have to complete the running one.
      // We're simply completing the running one and not emitting any values and merging newly provided context
      // with the one coming from currently running transition.
      case 'stop':
        zone.run(() => running.transition$.complete());
        context = Object.assign(running.context, context);
        runningTransitions.delete(element);
    }
  }
  // Running the start function
  const endFn = startFn(element, options.animation, context) || noopFn;
  // If 'prefer-reduced-motion' is enabled, the 'transition' will be set to 'none'.
  // If animations are disabled, we have to emit a value and complete the observable
  // In this case we have to call the end function, but can finish immediately by emitting a value,
  // completing the observable and executing end functions synchronously.
  if (!options.animation || window.getComputedStyle(element).transitionProperty === 'none') {
    zone.run(() => endFn());
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(undefined).pipe(runInZone(zone));
  }
  // Starting a new transition
  const transition$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
  const finishTransition$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
  const stop$ = transition$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.endWith)(true));
  runningTransitions.set(element, {
    transition$,
    complete: () => {
      finishTransition$.next();
      finishTransition$.complete();
    },
    context
  });
  const transitionDurationMs = getTransitionDurationMs(element);
  // 1. We have to both listen for the 'transitionend' event and have a 'just-in-case' timer,
  // because 'transitionend' event might not be fired in some browsers, if the transitioning
  // element becomes invisible (ex. when scrolling, making browser tab inactive, etc.). The timer
  // guarantees, that we'll release the DOM element and complete 'ngbRunTransition'.
  // 2. We need to filter transition end events, because they might bubble from shorter transitions
  // on inner DOM elements. We're only interested in the transition on the 'element' itself.
  zone.runOutsideAngular(() => {
    const transitionEnd$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(element, 'transitionend').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stop$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(({
      target
    }) => target === element));
    const timer$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.timer)(transitionDurationMs + transitionTimerDelayMs).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stop$));
    (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.race)(timer$, transitionEnd$, finishTransition$).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stop$)).subscribe(() => {
      runningTransitions.delete(element);
      zone.run(() => {
        endFn();
        transition$.next();
        transition$.complete();
      });
    });
  });
  return transition$.asObservable();
};
const ngbCompleteTransition = element => {
  runningTransitions.get(element)?.complete();
};
function measureCollapsingElementDimensionPx(element, dimension) {
  // SSR fix for without injecting the PlatformId
  if (typeof navigator === 'undefined') {
    return '0px';
  }
  const {
    classList
  } = element;
  const hasShownClass = classList.contains('show');
  if (!hasShownClass) {
    classList.add('show');
  }
  element.style[dimension] = '';
  const dimensionSize = element.getBoundingClientRect()[dimension] + 'px';
  if (!hasShownClass) {
    classList.remove('show');
  }
  return dimensionSize;
}
const ngbCollapsingTransition = (element, animation, context) => {
  let {
    direction,
    maxSize,
    dimension
  } = context;
  const {
    classList
  } = element;
  function setInitialClasses() {
    classList.add('collapse');
    if (direction === 'show') {
      classList.add('show');
    } else {
      classList.remove('show');
    }
  }
  // without animations we just need to set initial classes
  if (!animation) {
    setInitialClasses();
    return;
  }
  // No maxHeight -> running the transition for the first time
  if (!maxSize) {
    maxSize = measureCollapsingElementDimensionPx(element, dimension);
    context.maxSize = maxSize;
    // Fix the height before starting the animation
    element.style[dimension] = direction !== 'show' ? maxSize : '0px';
    classList.remove('collapse');
    classList.remove('collapsing');
    classList.remove('show');
    reflow(element);
    // Start the animation
    classList.add('collapsing');
  }
  // Start or revert the animation
  element.style[dimension] = direction === 'show' ? maxSize : '0px';
  return () => {
    setInitialClasses();
    classList.remove('collapsing');
    element.style[dimension] = '';
  };
};

/**
 * A configuration service for the [NgbCollapse](#/components/collapse/api#NgbCollapse) component.
 *
 * You can inject this service, typically in your root component, and customize its properties
 * to provide default values for all collapses used in the application.
 */
class NgbCollapseConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.horizontal = false;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbCollapseConfig_Factory(t) {
      return new (t || NgbCollapseConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCollapseConfig,
      factory: NgbCollapseConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCollapseConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A directive to provide a simple way of hiding and showing elements on the
 * page.
 */
class NgbCollapse {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCollapseConfig);
    this._element = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    /**
     * If `true`, collapse will be animated.
     *
     * Animation is triggered only when clicked on triggering element
     * or via the `.toggle()` function
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * Flag used to track if the collapse setter is invoked during initialization
     * or not. This distinction is made in order to avoid running the transition during initialization.
     */
    this._afterInit = false;
    this._isCollapsed = false;
    this.ngbCollapseChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * If `true`, will collapse horizontally.
     *
     * @since 13.1.0
     */
    this.horizontal = this._config.horizontal;
    /**
     * An event emitted when the collapse element is shown, after the transition.
     * It has no payload.
     *
     * @since 8.0.0
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the collapse element is hidden, after the transition.
     * It has no payload.
     *
     * @since 8.0.0
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  /**
   * If `true`, will collapse the element or show it otherwise.
   */
  set collapsed(isCollapsed) {
    if (this._isCollapsed !== isCollapsed) {
      this._isCollapsed = isCollapsed;
      if (this._afterInit) {
        this._runTransitionWithEvents(isCollapsed, this.animation);
      }
    }
  }
  ngOnInit() {
    this._runTransition(this._isCollapsed, false);
    this._afterInit = true;
  }
  /**
   * Triggers collapsing programmatically.
   *
   * If there is a collapsing transition running already, it will be reversed.
   * If the animations are turned off this happens synchronously.
   *
   * @since 8.0.0
   */
  toggle(open = this._isCollapsed) {
    this.collapsed = !open;
    this.ngbCollapseChange.next(this._isCollapsed);
  }
  _runTransition(collapsed, animation) {
    return ngbRunTransition(this._zone, this._element.nativeElement, ngbCollapsingTransition, {
      animation,
      runningTransition: 'stop',
      context: {
        direction: collapsed ? 'hide' : 'show',
        dimension: this.horizontal ? 'width' : 'height'
      }
    });
  }
  _runTransitionWithEvents(collapsed, animation) {
    this._runTransition(collapsed, animation).subscribe(() => {
      if (collapsed) {
        this.hidden.emit();
      } else {
        this.shown.emit();
      }
    });
  }
  static {
    this.ɵfac = function NgbCollapse_Factory(t) {
      return new (t || NgbCollapse)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbCollapse,
      selectors: [["", "ngbCollapse", ""]],
      hostVars: 2,
      hostBindings: function NgbCollapse_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("collapse-horizontal", ctx.horizontal);
        }
      },
      inputs: {
        animation: "animation",
        collapsed: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbCollapse", "collapsed"],
        horizontal: "horizontal"
      },
      outputs: {
        ngbCollapseChange: "ngbCollapseChange",
        shown: "shown",
        hidden: "hidden"
      },
      exportAs: ["ngbCollapse"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCollapse, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbCollapse]',
      exportAs: 'ngbCollapse',
      standalone: true,
      host: {
        '[class.collapse-horizontal]': 'horizontal'
      }
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    collapsed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbCollapse']
    }],
    ngbCollapseChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    horizontal: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
let nextId$3 = 0;
/**
 * A directive that wraps the content of an accordion item's collapsible body.
 *
 * The actual content is provided in a child `ng-template` element.
 * Depending on the state of the accordion, the template will be either inserted or removed from the DOM.
 *
 * @since 14.1.0
 */
class NgbAccordionBody {
  constructor() {
    this._vcr = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef);
    this._element = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionItem);
    this._viewRef = null;
  }
  ngAfterContentChecked() {
    if (this._bodyTpl) {
      if (this._item._shouldBeInDOM) {
        this._createViewIfNotExists();
      } else {
        this._destroyViewIfExists();
      }
    }
  }
  ngOnDestroy() {
    this._destroyViewIfExists();
  }
  _destroyViewIfExists() {
    if (this._viewRef) {
      this._viewRef.destroy();
      this._viewRef = null;
    }
  }
  _createViewIfNotExists() {
    if (!this._viewRef) {
      this._viewRef = this._vcr.createEmbeddedView(this._bodyTpl);
      this._viewRef.detectChanges();
      for (const node of this._viewRef.rootNodes) {
        this._element.appendChild(node);
      }
    }
  }
  static {
    this.ɵfac = function NgbAccordionBody_Factory(t) {
      return new (t || NgbAccordionBody)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionBody,
      selectors: [["", "ngbAccordionBody", ""]],
      contentQueries: function NgbAccordionBody_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._bodyTpl = _t.first);
        }
      },
      hostVars: 2,
      hostBindings: function NgbAccordionBody_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion-body", true);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionBody, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbAccordionBody]',
      standalone: true,
      host: {
        '[class.accordion-body]': 'true'
      }
    }]
  }], null, {
    _bodyTpl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef, {
        static: true
      }]
    }]
  });
})();
/**
 * A directive that wraps the collapsible item's content of the accordion.
 *
 * Internally it reuses the [`NgbCollapse` directive](#/components/collapse)
 *
 * @since 14.1.0
 */
class NgbAccordionCollapse {
  constructor() {
    this.item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionItem);
    this.ngbCollapse = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCollapse);
  }
  static {
    this.ɵfac = function NgbAccordionCollapse_Factory(t) {
      return new (t || NgbAccordionCollapse)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionCollapse,
      selectors: [["", "ngbAccordionCollapse", ""]],
      hostAttrs: ["role", "region"],
      hostVars: 4,
      hostBindings: function NgbAccordionCollapse_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.item.collapseId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-labelledby", ctx.item.toggleId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion-collapse", true);
        }
      },
      exportAs: ["ngbAccordionCollapse"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵHostDirectivesFeature"]([NgbCollapse])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionCollapse, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      exportAs: 'ngbAccordionCollapse',
      standalone: true,
      selector: '[ngbAccordionCollapse]',
      host: {
        role: 'region',
        '[class.accordion-collapse]': 'true',
        '[id]': 'item.collapseId',
        '[attr.aria-labelledby]': 'item.toggleId'
      },
      hostDirectives: [NgbCollapse]
    }]
  }], null, null);
})();
/**
 * A directive to put on a toggling element inside the accordion item's header.
 * It will register click handlers that toggle the associated panel and will handle accessibility attributes.
 *
 * This directive is used internally by the [`NgbAccordionButton` directive](#/components/accordion/api#NgbAccordionButton).
 *
 * @since 14.1.0
 */
class NgbAccordionToggle {
  constructor() {
    this.item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionItem);
    this.accordion = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionDirective);
  }
  static {
    this.ɵfac = function NgbAccordionToggle_Factory(t) {
      return new (t || NgbAccordionToggle)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionToggle,
      selectors: [["", "ngbAccordionToggle", ""]],
      hostVars: 5,
      hostBindings: function NgbAccordionToggle_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbAccordionToggle_click_HostBindingHandler() {
            return !ctx.item.disabled && ctx.accordion.toggle(ctx.item.id);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.item.toggleId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-controls", ctx.item.collapseId)("aria-expanded", !ctx.item.collapsed);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("collapsed", ctx.item.collapsed);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionToggle, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbAccordionToggle]',
      standalone: true,
      host: {
        '[id]': 'item.toggleId',
        '[class.collapsed]': 'item.collapsed',
        '[attr.aria-controls]': 'item.collapseId',
        '[attr.aria-expanded]': '!item.collapsed',
        '(click)': '!item.disabled && accordion.toggle(item.id)'
      }
    }]
  }], null, null);
})();
/**
 * A directive to put on a button element inside an accordion item's header.
 *
 * If you want a custom markup for the header, you can also use the [`NgbAccordionToggle` directive](#/components/accordion/api#NgbAccordionToggle).
 *
 * @since 14.1.0
 */
class NgbAccordionButton {
  constructor() {
    this.item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionItem);
  }
  static {
    this.ɵfac = function NgbAccordionButton_Factory(t) {
      return new (t || NgbAccordionButton)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionButton,
      selectors: [["button", "ngbAccordionButton", ""]],
      hostAttrs: ["type", "button"],
      hostVars: 3,
      hostBindings: function NgbAccordionButton_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("disabled", ctx.item.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion-button", true);
        }
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵHostDirectivesFeature"]([NgbAccordionToggle])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionButton, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'button[ngbAccordionButton]',
      standalone: true,
      host: {
        '[disabled]': 'item.disabled',
        '[class.accordion-button]': 'true',
        type: 'button'
      },
      hostDirectives: [NgbAccordionToggle]
    }]
  }], null, null);
})();
/**
 * A directive that wraps an accordion item's header.
 *
 * @since 14.1.0
 */
class NgbAccordionHeader {
  constructor() {
    this.item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionItem);
  }
  static {
    this.ɵfac = function NgbAccordionHeader_Factory(t) {
      return new (t || NgbAccordionHeader)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionHeader,
      selectors: [["", "ngbAccordionHeader", ""]],
      hostAttrs: ["role", "heading"],
      hostVars: 4,
      hostBindings: function NgbAccordionHeader_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion-header", true)("collapsed", ctx.item.collapsed);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionHeader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbAccordionHeader]',
      standalone: true,
      host: {
        role: 'heading',
        '[class.accordion-header]': 'true',
        '[class.collapsed]': 'item.collapsed'
      }
    }]
  }], null, null);
})();
/**
 * A directive that wraps an accordion item: a toggleable header + body that collapses.
 *
 * You can get hold of the `NgbAccordionItem` instance in the template with `#item="ngbAccordionItem"`.
 * It allows to check if the item is collapsed or not, toggle the collapse state, etc.
 *
 * Every accordion item has a string ID that is automatically generated in the `ngb-accordion-item-XX` format, unless provided explicitly.
 *
 * @since 14.1.0
 */
class NgbAccordionItem {
  constructor() {
    this._accordion = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionDirective);
    this._cd = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._collapsed = true;
    this._id = `ngb-accordion-item-${nextId$3++}`;
    this._collapseAnimationRunning = false;
    /**
     * If `true`, the accordion item will be disabled.
     * It won't react to user's clicks, but still will be toggelable programmatically.
     */
    this.disabled = false;
    /**
     * Event emitted before the expanding animation starts. It has no payload.
     *
     * @since 15.1.0
     */
    this.show = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted when the expanding animation is finished. It has no payload.
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted before the collapsing animation starts. It has no payload.
     *
     * @since 15.1.0
     */
    this.hide = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted when the collapsing animation is finished and before the content is removed from DOM.
     * It has no payload.
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  /**
   * Sets the custom ID of the accordion item. It must be unique for the document.
   *
   * @param id The ID of the accordion item, must be a non-empty string
   */
  set id(id) {
    if (isString(id) && id !== '') {
      this._id = id;
    }
  }
  /**
   * If `true`, the content of the accordion item's body will be removed from the DOM. It will be just hidden otherwise.
   *
   * This property can also be set up on the parent [`NgbAccordion` directive](#/components/accordion/api#NgbAccordionDirective).
   */
  set destroyOnHide(destroyOnHide) {
    this._destroyOnHide = destroyOnHide;
  }
  get destroyOnHide() {
    return this._destroyOnHide === undefined ? this._accordion.destroyOnHide : this._destroyOnHide;
  }
  /**
   *	If `true`, the accordion item will be collapsed. Otherwise, it will be expanded.
   *
   * @param collapsed New state of the accordion item.
   */
  set collapsed(collapsed) {
    if (collapsed) {
      this.collapse();
    } else {
      this.expand();
    }
  }
  get collapsed() {
    return this._collapsed;
  }
  get id() {
    return `${this._id}`;
  }
  get toggleId() {
    return `${this.id}-toggle`;
  }
  get collapseId() {
    return `${this.id}-collapse`;
  }
  get _shouldBeInDOM() {
    return !this.collapsed || this._collapseAnimationRunning || !this.destroyOnHide;
  }
  ngAfterContentInit() {
    const {
      ngbCollapse
    } = this._collapse;
    // we need to disable the animation for the first init
    ngbCollapse.animation = false;
    ngbCollapse.collapsed = this.collapsed;
    // we set the animation to the default of the accordion
    ngbCollapse.animation = this._accordion.animation;
    // event forwarding from 'ngbCollapse' to 'ngbAccordion'
    ngbCollapse.hidden.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(() => {
      // when the animation finishes we can remove the template from DOM
      this._collapseAnimationRunning = false;
      this.hidden.emit();
      this._accordion.hidden.emit(this.id);
    });
    ngbCollapse.shown.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(() => {
      this.shown.emit();
      this._accordion.shown.emit(this.id);
    });
  }
  /**
   * Toggles an accordion item.
   */
  toggle() {
    this.collapsed = !this.collapsed;
  }
  /**
   * Expands an accordion item.
   */
  expand() {
    if (this.collapsed) {
      // checking if accordion allows to expand the panel in respect to 'closeOthers' flag
      if (!this._accordion._ensureCanExpand(this)) {
        return;
      }
      this._collapsed = false;
      // need if the accordion is used inside a component having OnPush change detection strategy
      this._cd.markForCheck();
      // we need force CD to get template into DOM before starting animation to calculate its height correctly
      // this will synchronously put the item body into DOM, because `this._collapsed` was flipped to `false`
      this._cd.detectChanges();
      // firing events before starting animations
      this.show.emit();
      this._accordion.show.emit(this.id);
      // we also need to make sure 'animation' flag is up-to- date
      this._collapse.ngbCollapse.animation = this._accordion.animation;
      this._collapse.ngbCollapse.collapsed = false;
    }
  }
  /**
   * Collapses an accordion item.
   */
  collapse() {
    if (!this.collapsed) {
      this._collapsed = true;
      this._collapseAnimationRunning = true;
      // need if the accordion is used inside a component having OnPush change detection strategy
      this._cd.markForCheck();
      // firing events before starting animations
      this.hide.emit();
      this._accordion.hide.emit(this.id);
      // we also need to make sure 'animation' flag is up-to- date
      this._collapse.ngbCollapse.animation = this._accordion.animation;
      this._collapse.ngbCollapse.collapsed = true;
    }
  }
  static {
    this.ɵfac = function NgbAccordionItem_Factory(t) {
      return new (t || NgbAccordionItem)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionItem,
      selectors: [["", "ngbAccordionItem", ""]],
      contentQueries: function NgbAccordionItem_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbAccordionCollapse, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._collapse = _t.first);
        }
      },
      hostVars: 3,
      hostBindings: function NgbAccordionItem_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion-item", true);
        }
      },
      inputs: {
        id: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbAccordionItem", "id"],
        destroyOnHide: "destroyOnHide",
        disabled: "disabled",
        collapsed: "collapsed"
      },
      outputs: {
        show: "show",
        shown: "shown",
        hide: "hide",
        hidden: "hidden"
      },
      exportAs: ["ngbAccordionItem"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionItem, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbAccordionItem]',
      exportAs: 'ngbAccordionItem',
      standalone: true,
      host: {
        '[class.accordion-item]': 'true',
        '[id]': 'id'
      }
    }]
  }], null, {
    _collapse: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbAccordionCollapse, {
        static: true
      }]
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbAccordionItem']
    }],
    destroyOnHide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    collapsed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    show: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
/**
 * Accordion is a stack of cards that have a header and collapsible body.
 *
 * This directive is a container for these items and provides an API to handle them.
 *
 * @since 14.1.0
 */
class NgbAccordionDirective {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAccordionConfig);
    this._anItemWasAlreadyExpandedDuringInitialisation = false;
    /**
     * If `true`, accordion will be animated.
     */
    this.animation = this._config.animation;
    /**
     * If `true`, only one item at the time can stay open.
     */
    this.closeOthers = this._config.closeOthers;
    /**
     * If `true`, the content of the accordion items body will be removed from the DOM. It will be just hidden otherwise.
     *
     * This property can be overwritten at the [`NgbAccordionItem`](#/components/accordion/api#NgbAccordionItem) level
     */
    this.destroyOnHide = this._config.destroyOnHide;
    /**
     * Event emitted before expanding animation starts. The payload is the id of shown accordion item.
     *
     * @since 15.1.0
     */
    this.show = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted when the expanding animation is finished. The payload is the id of shown accordion item.
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted before the collapsing animation starts. The payload is the id of hidden accordion item.
     *
     * @since 15.1.0
     */
    this.hide = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted when the collapsing animation is finished and before the content is removed from DOM.
     * The payload is the id of hidden accordion item.
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  /**
   * Toggles an item with the given id.
   *
   * It will toggle an item, even if it is disabled.
   *
   * @param itemId The id of the item to toggle.
   */
  toggle(itemId) {
    this._getItem(itemId)?.toggle();
  }
  /**
   * Expands an item with the given id.
   *
   * If `closeOthers` is `true`, it will collapse other panels.
   *
   * @param itemId The id of the item to expand.
   */
  expand(itemId) {
    this._getItem(itemId)?.expand();
  }
  /**
   * Expands all items.
   *
   * If `closeOthers` is `true` and all items are closed, it will open the first one. Otherwise, it will keep the opened one.
   */
  expandAll() {
    if (this._items) {
      if (this.closeOthers) {
        // we check if there is an item open and if it is not we can expand the first item
        // (otherwise we toggle nothing)
        if (!this._items.find(item => !item.collapsed)) {
          this._items.first.expand();
        }
      } else {
        this._items.forEach(item => item.expand());
      }
    }
  }
  /**
   * Collapses an item with the given id.
   *
   * Has no effect if the `itemId` does not correspond to any item.
   *
   * @param itemId The id of the item to collapse.
   */
  collapse(itemId) {
    this._getItem(itemId)?.collapse();
  }
  /**
   * Collapses all items.
   */
  collapseAll() {
    this._items?.forEach(item => item.collapse());
  }
  /**
   * Checks if an item with the given id is expanded.
   *
   * If the `itemId` does not correspond to any item, it returns `false`.
   *
   * @param itemId The id of the item to check.
   */
  isExpanded(itemId) {
    const item = this._getItem(itemId);
    return item ? !item.collapsed : false;
  }
  /**
   * It checks, if the item can be expanded in the current state of the accordion.
   * With `closeOthers` there can be only one expanded item at a time.
   *
   * @internal
   */
  _ensureCanExpand(toExpand) {
    if (!this.closeOthers) {
      return true;
    }
    // special case during the initialization of the [collapse]="false" inputs
    // `this._items` QueryList is not yet initialized, but we need to ensure only one item can be expanded at a time
    if (!this._items) {
      if (!this._anItemWasAlreadyExpandedDuringInitialisation) {
        this._anItemWasAlreadyExpandedDuringInitialisation = true;
        return true;
      }
      return false;
    }
    // if there is an expanded item, we need to collapse it first
    this._items.find(item => !item.collapsed && toExpand !== item)?.collapse();
    return true;
  }
  _getItem(itemId) {
    return this._items?.find(item => item.id === itemId);
  }
  static {
    this.ɵfac = function NgbAccordionDirective_Factory(t) {
      return new (t || NgbAccordionDirective)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbAccordionDirective,
      selectors: [["", "ngbAccordion", ""]],
      contentQueries: function NgbAccordionDirective_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbAccordionItem, 4);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._items = _t);
        }
      },
      hostVars: 2,
      hostBindings: function NgbAccordionDirective_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("accordion", true);
        }
      },
      inputs: {
        animation: "animation",
        closeOthers: "closeOthers",
        destroyOnHide: "destroyOnHide"
      },
      outputs: {
        show: "show",
        shown: "shown",
        hide: "hide",
        hidden: "hidden"
      },
      exportAs: ["ngbAccordion"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbAccordion]',
      standalone: true,
      exportAs: 'ngbAccordion',
      host: {
        '[class.accordion]': 'true'
      }
    }]
  }], null, {
    _items: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbAccordionItem, {
        descendants: false
      }]
    }],
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    closeOthers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    destroyOnHide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    show: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
const NGB_ACCORDION_DIRECTIVES = [NgbAccordionButton, NgbAccordionDirective, NgbAccordionItem, NgbAccordionHeader, NgbAccordionToggle, NgbAccordionBody, NgbAccordionCollapse];
class NgbAccordionModule {
  static {
    this.ɵfac = function NgbAccordionModule_Factory(t) {
      return new (t || NgbAccordionModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbAccordionModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAccordionModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: NGB_ACCORDION_DIRECTIVES,
      exports: NGB_ACCORDION_DIRECTIVES
    }]
  }], null, null);
})();

/**
 * A configuration service for the [NgbAlert](#/components/alert/api#NgbAlert) component.
 *
 * You can inject this service, typically in your root component, and customize its properties
 * to provide default values for all alerts used in the application.
 */
class NgbAlertConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.dismissible = true;
    this.type = 'warning';
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbAlertConfig_Factory(t) {
      return new (t || NgbAlertConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbAlertConfig,
      factory: NgbAlertConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAlertConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const ngbAlertFadingTransition = ({
  classList
}) => {
  classList.remove('show');
};

/**
 * Alert is a component to provide contextual feedback messages for user.
 *
 * It supports several alert types and can be dismissed.
 */
class NgbAlert {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbAlertConfig);
    this._elementRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    /**
     * If `true`, alert closing will be animated.
     *
     * Animation is triggered only when clicked on the close button (×)
     * or via the `.close()` function
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * If `true`, alert can be dismissed by the user.
     *
     * The close button (×) will be displayed and you can be notified
     * of the event with the `(closed)` output.
     */
    this.dismissible = this._config.dismissible;
    /**
     * Type of the alert.
     *
     * Bootstrap provides styles for the following types: `'success'`, `'info'`, `'warning'`, `'danger'`, `'primary'`,
     * `'secondary'`, `'light'` and `'dark'`.
     */
    this.type = this._config.type;
    /**
     * An event emitted when the close button is clicked. It has no payload and only relevant for dismissible alerts.
     *
     * @since 8.0.0
     */
    this.closed = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  /**
   * Triggers alert closing programmatically (same as clicking on the close button (×)).
   *
   * The returned observable will emit and be completed once the closing transition has finished.
   * If the animations are turned off this happens synchronously.
   *
   * Alternatively you could listen or subscribe to the `(closed)` output
   *
   * @since 8.0.0
   */
  close() {
    const transition = ngbRunTransition(this._zone, this._elementRef.nativeElement, ngbAlertFadingTransition, {
      animation: this.animation,
      runningTransition: 'continue'
    });
    transition.subscribe(() => this.closed.emit());
    return transition;
  }
  static {
    this.ɵfac = function NgbAlert_Factory(t) {
      return new (t || NgbAlert)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbAlert,
      selectors: [["ngb-alert"]],
      hostAttrs: ["role", "alert"],
      hostVars: 6,
      hostBindings: function NgbAlert_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("alert show" + (ctx.type ? " alert-" + ctx.type : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.animation)("alert-dismissible", ctx.dismissible);
        }
      },
      inputs: {
        animation: "animation",
        dismissible: "dismissible",
        type: "type"
      },
      outputs: {
        closed: "closed"
      },
      exportAs: ["ngbAlert"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 2,
      vars: 1,
      consts: () => {
        let i18n_0;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_0 = goog.getMsg("Close");
          i18n_0 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_0;
        } else {
          i18n_0 = $localize`:@@ngb.alert.close:Close`;
        }
        return [["type", "button", "aria-label", i18n_0, 1, "btn-close"], ["type", "button", "aria-label", i18n_0, 1, "btn-close", 3, "click"]];
      },
      template: function NgbAlert_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbAlert_Conditional_1_Template, 1, 0, "button", 0);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx.dismissible ? 1 : -1);
        }
      },
      styles: ["ngb-alert{display:block}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAlert, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-alert',
      exportAs: 'ngbAlert',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        role: 'alert',
        '[class]': '"alert show" + (type ? " alert-" + type : "")',
        '[class.fade]': 'animation',
        '[class.alert-dismissible]': 'dismissible'
      },
      template: `
		<ng-content />
		@if (dismissible) {
			<button
				type="button"
				class="btn-close"
				aria-label="Close"
				i18n-aria-label="@@ngb.alert.close"
				(click)="close()"
			></button>
		}
	`,
      styles: ["ngb-alert{display:block}\n"]
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dismissible: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    type: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    closed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbAlertModule {
  static {
    this.ɵfac = function NgbAlertModule_Factory(t) {
      return new (t || NgbAlertModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbAlertModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbAlertModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbAlert],
      exports: [NgbAlert]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [NgbCarousel](#/components/carousel/api#NgbCarousel) component.
 *
 * You can inject this service, typically in your root component, and customize its properties
 * to provide default values for all carousels used in the application.
 */
class NgbCarouselConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.interval = 5000;
    this.wrap = true;
    this.keyboard = true;
    this.pauseOnHover = true;
    this.pauseOnFocus = true;
    this.showNavigationArrows = true;
    this.showNavigationIndicators = true;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbCarouselConfig_Factory(t) {
      return new (t || NgbCarouselConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCarouselConfig,
      factory: NgbCarouselConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCarouselConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * Defines the carousel slide transition direction.
 */
var NgbSlideEventDirection;
(function (NgbSlideEventDirection) {
  NgbSlideEventDirection["START"] = "start";
  NgbSlideEventDirection["END"] = "end";
})(NgbSlideEventDirection || (NgbSlideEventDirection = {}));
const isBeingAnimated = ({
  classList
}) => {
  return classList.contains('carousel-item-start') || classList.contains('carousel-item-end');
};
const removeDirectionClasses = classList => {
  classList.remove('carousel-item-start');
  classList.remove('carousel-item-end');
};
const removeClasses = classList => {
  removeDirectionClasses(classList);
  classList.remove('carousel-item-prev');
  classList.remove('carousel-item-next');
};
const ngbCarouselTransitionIn = (element, animation, {
  direction
}) => {
  const {
    classList
  } = element;
  if (!animation) {
    removeDirectionClasses(classList);
    removeClasses(classList);
    classList.add('active');
    return;
  }
  if (isBeingAnimated(element)) {
    // Revert the transition
    removeDirectionClasses(classList);
  } else {
    // For the 'in' transition, a 'pre-class' is applied to the element to ensure its visibility
    classList.add('carousel-item-' + (direction === NgbSlideEventDirection.START ? 'next' : 'prev'));
    reflow(element);
    classList.add('carousel-item-' + direction);
  }
  return () => {
    removeClasses(classList);
    classList.add('active');
  };
};
const ngbCarouselTransitionOut = (element, animation, {
  direction
}) => {
  const {
    classList
  } = element;
  if (!animation) {
    removeDirectionClasses(classList);
    removeClasses(classList);
    classList.remove('active');
    return;
  }
  //  direction is left or right, depending on the way the slide goes out.
  if (isBeingAnimated(element)) {
    // Revert the transition
    removeDirectionClasses(classList);
  } else {
    classList.add('carousel-item-' + direction);
  }
  return () => {
    removeClasses(classList);
    classList.remove('active');
  };
};
let nextId$2 = 0;
let carouselId = 0;
/**
 * A directive that wraps the individual carousel slide.
 */
class NgbSlide {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
    /**
     * Slide id that must be unique for the entire document.
     *
     * If not provided, will be generated in the `ngb-slide-xx` format.
     */
    this.id = `ngb-slide-${nextId$2++}`;
    /**
     * An event emitted when the slide transition is finished
     *
     * @since 8.0.0
     */
    this.slid = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  static {
    this.ɵfac = function NgbSlide_Factory(t) {
      return new (t || NgbSlide)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbSlide,
      selectors: [["ng-template", "ngbSlide", ""]],
      inputs: {
        id: "id"
      },
      outputs: {
        slid: "slid"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbSlide, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbSlide]',
      standalone: true
    }]
  }], null, {
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    slid: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
/**
 * Carousel is a component to easily create and control slideshows.
 *
 * Allows to set intervals, change the way user interacts with the slides and provides a programmatic API.
 */
class NgbCarousel {
  constructor() {
    this.NgbSlideEventSource = NgbSlideEventSource;
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCarouselConfig);
    this._platformId = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._cd = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._container = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._interval$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(this._config.interval);
    this._mouseHover$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(false);
    this._focused$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(false);
    this._pauseOnHover$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(this._config.pauseOnHover);
    this._pauseOnFocus$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(this._config.pauseOnFocus);
    this._pause$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(false);
    this._wrap$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(this._config.wrap);
    this.id = `ngb-carousel-${carouselId++}`;
    /**
     * A flag to enable/disable the animations.
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * If `true`, allows to interact with carousel using keyboard 'arrow left' and 'arrow right'.
     */
    this.keyboard = this._config.keyboard;
    /**
     * If `true`, 'previous' and 'next' navigation arrows will be visible on the slide.
     *
     * @since 2.2.0
     */
    this.showNavigationArrows = this._config.showNavigationArrows;
    /**
     * If `true`, navigation indicators at the bottom of the slide will be visible.
     *
     * @since 2.2.0
     */
    this.showNavigationIndicators = this._config.showNavigationIndicators;
    /**
     * An event emitted just before the slide transition starts.
     *
     * See [`NgbSlideEvent`](#/components/carousel/api#NgbSlideEvent) for payload details.
     */
    this.slide = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted right after the slide transition is completed.
     *
     * See [`NgbSlideEvent`](#/components/carousel/api#NgbSlideEvent) for payload details.
     *
     * @since 8.0.0
     */
    this.slid = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /*
     * Keep the ids of the panels currently transitionning
     * in order to allow only the transition revertion
     */
    this._transitionIds = null;
  }
  /**
   * Time in milliseconds before the next slide is shown.
   */
  set interval(value) {
    this._interval$.next(value);
  }
  get interval() {
    return this._interval$.value;
  }
  /**
   * If `true`, will 'wrap' the carousel by switching from the last slide back to the first.
   */
  set wrap(value) {
    this._wrap$.next(value);
  }
  get wrap() {
    return this._wrap$.value;
  }
  /**
   * If `true`, will pause slide switching when mouse cursor hovers the slide.
   *
   * @since 2.2.0
   */
  set pauseOnHover(value) {
    this._pauseOnHover$.next(value);
  }
  get pauseOnHover() {
    return this._pauseOnHover$.value;
  }
  /**
   * If `true`, will pause slide switching when the focus is inside the carousel.
   */
  set pauseOnFocus(value) {
    this._pauseOnFocus$.next(value);
  }
  get pauseOnFocus() {
    return this._pauseOnFocus$.value;
  }
  set mouseHover(value) {
    this._mouseHover$.next(value);
  }
  get mouseHover() {
    return this._mouseHover$.value;
  }
  set focused(value) {
    this._focused$.next(value);
  }
  get focused() {
    return this._focused$.value;
  }
  arrowLeft() {
    this.focus();
    this.prev(NgbSlideEventSource.ARROW_LEFT);
  }
  arrowRight() {
    this.focus();
    this.next(NgbSlideEventSource.ARROW_RIGHT);
  }
  ngAfterContentInit() {
    // setInterval() doesn't play well with SSR and protractor,
    // so we should run it in the browser and outside Angular
    if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.isPlatformBrowser)(this._platformId)) {
      this._ngZone.runOutsideAngular(() => {
        const hasNextSlide$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_14__.combineLatest)([this.slide.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(slideEvent => slideEvent.current), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.startWith)(this.activeId)), this._wrap$, this.slides.changes.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.startWith)(null))]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(([currentSlideId, wrap]) => {
          const slideArr = this.slides.toArray();
          const currentSlideIdx = this._getSlideIdxById(currentSlideId);
          return wrap ? slideArr.length > 1 : currentSlideIdx < slideArr.length - 1;
        }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.distinctUntilChanged)());
        (0,rxjs__WEBPACK_IMPORTED_MODULE_14__.combineLatest)([this._pause$, this._pauseOnHover$, this._mouseHover$, this._pauseOnFocus$, this._focused$, this._interval$, hasNextSlide$]).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(([pause, pauseOnHover, mouseHover, pauseOnFocus, focused, interval, hasNextSlide]) => pause || pauseOnHover && mouseHover || pauseOnFocus && focused || !hasNextSlide ? 0 : interval), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.distinctUntilChanged)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_18__.switchMap)(interval => interval > 0 ? (0,rxjs__WEBPACK_IMPORTED_MODULE_9__.timer)(interval, interval) : rxjs__WEBPACK_IMPORTED_MODULE_19__.NEVER), (0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(() => this._ngZone.run(() => this.next(NgbSlideEventSource.TIMER)));
      });
    }
    this.slides.changes.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(() => {
      this._transitionIds?.forEach(id => ngbCompleteTransition(this._getSlideElement(id)));
      this._transitionIds = null;
      this._cd.markForCheck();
      // The following code need to be done asynchronously, after the dom becomes stable,
      // otherwise all changes will be undone.
      this._ngZone.onStable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
        for (const {
          id
        } of this.slides) {
          const element = this._getSlideElement(id);
          if (id === this.activeId) {
            element.classList.add('active');
          } else {
            element.classList.remove('active');
          }
        }
      });
    });
  }
  ngAfterContentChecked() {
    let activeSlide = this._getSlideById(this.activeId);
    this.activeId = activeSlide ? activeSlide.id : this.slides.length ? this.slides.first.id : '';
  }
  ngAfterViewInit() {
    // Initialize the 'active' class (not managed by the template)
    if (this.activeId) {
      const element = this._getSlideElement(this.activeId);
      if (element) {
        element.classList.add('active');
      }
    }
  }
  /**
   * Navigates to a slide with the specified identifier.
   */
  select(slideId, source) {
    this._cycleToSelected(slideId, this._getSlideEventDirection(this.activeId, slideId), source);
  }
  /**
   * Navigates to the previous slide.
   */
  prev(source) {
    this._cycleToSelected(this._getPrevSlide(this.activeId), NgbSlideEventDirection.END, source);
  }
  /**
   * Navigates to the next slide.
   */
  next(source) {
    this._cycleToSelected(this._getNextSlide(this.activeId), NgbSlideEventDirection.START, source);
  }
  /**
   * Pauses cycling through the slides.
   */
  pause() {
    this._pause$.next(true);
  }
  /**
   * Restarts cycling through the slides from start to end.
   */
  cycle() {
    this._pause$.next(false);
  }
  /**
   * Set the focus on the carousel.
   */
  focus() {
    this._container.nativeElement.focus();
  }
  _cycleToSelected(slideIdx, direction, source) {
    const transitionIds = this._transitionIds;
    if (transitionIds && (transitionIds[0] !== slideIdx || transitionIds[1] !== this.activeId)) {
      // Revert prevented
      return;
    }
    let selectedSlide = this._getSlideById(slideIdx);
    if (selectedSlide && selectedSlide.id !== this.activeId) {
      this._transitionIds = [this.activeId, slideIdx];
      this.slide.emit({
        prev: this.activeId,
        current: selectedSlide.id,
        direction: direction,
        paused: this._pause$.value,
        source
      });
      const options = {
        animation: this.animation,
        runningTransition: 'stop',
        context: {
          direction
        }
      };
      const transitions = [];
      const activeSlide = this._getSlideById(this.activeId);
      if (activeSlide) {
        const activeSlideTransition = ngbRunTransition(this._ngZone, this._getSlideElement(activeSlide.id), ngbCarouselTransitionOut, options);
        activeSlideTransition.subscribe(() => {
          activeSlide.slid.emit({
            isShown: false,
            direction,
            source
          });
        });
        transitions.push(activeSlideTransition);
      }
      const previousId = this.activeId;
      this.activeId = selectedSlide.id;
      const nextSlide = this._getSlideById(this.activeId);
      const transition = ngbRunTransition(this._ngZone, this._getSlideElement(selectedSlide.id), ngbCarouselTransitionIn, options);
      transition.subscribe(() => {
        nextSlide?.slid.emit({
          isShown: true,
          direction,
          source
        });
      });
      transitions.push(transition);
      (0,rxjs__WEBPACK_IMPORTED_MODULE_21__.zip)(...transitions).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
        this._transitionIds = null;
        this.slid.emit({
          prev: previousId,
          current: selectedSlide.id,
          direction: direction,
          paused: this._pause$.value,
          source
        });
      });
    }
    // we get here after the interval fires or any external API call like next(), prev() or select()
    this._cd.markForCheck();
  }
  _getSlideEventDirection(currentActiveSlideId, nextActiveSlideId) {
    const currentActiveSlideIdx = this._getSlideIdxById(currentActiveSlideId);
    const nextActiveSlideIdx = this._getSlideIdxById(nextActiveSlideId);
    return currentActiveSlideIdx > nextActiveSlideIdx ? NgbSlideEventDirection.END : NgbSlideEventDirection.START;
  }
  _getSlideById(slideId) {
    return this.slides.find(slide => slide.id === slideId) || null;
  }
  _getSlideIdxById(slideId) {
    const slide = this._getSlideById(slideId);
    return slide != null ? this.slides.toArray().indexOf(slide) : -1;
  }
  _getNextSlide(currentSlideId) {
    const slideArr = this.slides.toArray();
    const currentSlideIdx = this._getSlideIdxById(currentSlideId);
    const isLastSlide = currentSlideIdx === slideArr.length - 1;
    return isLastSlide ? this.wrap ? slideArr[0].id : slideArr[slideArr.length - 1].id : slideArr[currentSlideIdx + 1].id;
  }
  _getPrevSlide(currentSlideId) {
    const slideArr = this.slides.toArray();
    const currentSlideIdx = this._getSlideIdxById(currentSlideId);
    const isFirstSlide = currentSlideIdx === 0;
    return isFirstSlide ? this.wrap ? slideArr[slideArr.length - 1].id : slideArr[0].id : slideArr[currentSlideIdx - 1].id;
  }
  _getSlideElement(slideId) {
    return this._container.nativeElement.querySelector(`#slide-${slideId}`);
  }
  static {
    this.ɵfac = function NgbCarousel_Factory(t) {
      return new (t || NgbCarousel)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbCarousel,
      selectors: [["ngb-carousel"]],
      contentQueries: function NgbCarousel_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbSlide, 4);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.slides = _t);
        }
      },
      hostAttrs: ["tabIndex", "0", 1, "carousel", "slide"],
      hostVars: 3,
      hostBindings: function NgbCarousel_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("keydown.arrowLeft", function NgbCarousel_keydown_arrowLeft_HostBindingHandler() {
            return ctx.keyboard && ctx.arrowLeft();
          })("keydown.arrowRight", function NgbCarousel_keydown_arrowRight_HostBindingHandler() {
            return ctx.keyboard && ctx.arrowRight();
          })("mouseenter", function NgbCarousel_mouseenter_HostBindingHandler() {
            return ctx.mouseHover = true;
          })("mouseleave", function NgbCarousel_mouseleave_HostBindingHandler() {
            return ctx.mouseHover = false;
          })("focusin", function NgbCarousel_focusin_HostBindingHandler() {
            return ctx.focused = true;
          })("focusout", function NgbCarousel_focusout_HostBindingHandler() {
            return ctx.focused = false;
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-activedescendant", "slide-" + ctx.activeId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("display", "block");
        }
      },
      inputs: {
        animation: "animation",
        activeId: "activeId",
        interval: "interval",
        wrap: "wrap",
        keyboard: "keyboard",
        pauseOnHover: "pauseOnHover",
        pauseOnFocus: "pauseOnFocus",
        showNavigationArrows: "showNavigationArrows",
        showNavigationIndicators: "showNavigationIndicators"
      },
      outputs: {
        slide: "slide",
        slid: "slid"
      },
      exportAs: ["ngbCarousel"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 7,
      vars: 3,
      consts: () => {
        let i18n_1;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @desc Currently selected slide number read by screen reader
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_1 = goog.getMsg(" Slide {$interpolation} of {$interpolation_1} ", {
            "interpolation": "\uFFFD0\uFFFD",
            "interpolation_1": "\uFFFD1\uFFFD"
          }, {
            original_code: {
              "interpolation": "{{ i + 1 }}",
              "interpolation_1": "{{ c }}"
            }
          });
          i18n_1 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_1;
        } else {
          i18n_1 = $localize`:Currently selected slide number read by screen reader@@ngb.carousel.slide-number: Slide ${"\uFFFD0\uFFFD"}:INTERPOLATION: of ${"\uFFFD1\uFFFD"}:INTERPOLATION_1: `;
        }
        let i18n_2;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_2 = goog.getMsg("Previous");
          i18n_2 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_2;
        } else {
          i18n_2 = $localize`:@@ngb.carousel.previous:Previous`;
        }
        let i18n_3;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_3 = goog.getMsg("Next");
          i18n_3 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_3;
        } else {
          i18n_3 = $localize`:@@ngb.carousel.next:Next`;
        }
        return [i18n_1, i18n_2, i18n_3, ["role", "tablist", 1, "carousel-indicators"], ["type", "button", "data-bs-target", "", "role", "tab", 3, "active"], [1, "carousel-inner"], ["role", "tabpanel", 1, "carousel-item", 3, "id"], ["type", "button", "data-bs-target", "", "role", "tab", 3, "click"], [1, "visually-hidden"], [3, "ngTemplateOutlet"], ["type", "button", 1, "carousel-control-prev", 3, "click"], ["aria-hidden", "true", 1, "carousel-control-prev-icon"], [1, "visually-hidden", 3, "id"], ["type", "button", 1, "carousel-control-next", 3, "click"], ["aria-hidden", "true", 1, "carousel-control-next-icon"]];
      },
      template: function NgbCarousel_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](1, NgbCarousel_For_2_Template, 1, 5, "button", 4, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](3, "div", 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](4, NgbCarousel_For_5_Template, 4, 4, "div", 6, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](6, NgbCarousel_Conditional_6_Template, 8, 4);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("visually-hidden", !ctx.showNavigationIndicators);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.slides);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.slides);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](6, ctx.showNavigationArrows ? 6 : -1);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCarousel, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-carousel',
      exportAs: 'ngbCarousel',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        class: 'carousel slide',
        '[style.display]': '"block"',
        tabIndex: '0',
        '(keydown.arrowLeft)': 'keyboard && arrowLeft()',
        '(keydown.arrowRight)': 'keyboard && arrowRight()',
        '(mouseenter)': 'mouseHover = true',
        '(mouseleave)': 'mouseHover = false',
        '(focusin)': 'focused = true',
        '(focusout)': 'focused = false',
        '[attr.aria-activedescendant]': `'slide-' + activeId`
      },
      template: `
		<div class="carousel-indicators" [class.visually-hidden]="!showNavigationIndicators" role="tablist">
			@for (slide of slides; track slide) {
				<button
					type="button"
					data-bs-target
					[class.active]="slide.id === activeId"
					role="tab"
					[attr.aria-labelledby]="'slide-' + slide.id"
					[attr.aria-controls]="'slide-' + slide.id"
					[attr.aria-selected]="slide.id === activeId"
					(click)="focus(); select(slide.id, NgbSlideEventSource.INDICATOR)"
				></button>
			}
		</div>
		<div class="carousel-inner">
			@for (slide of slides; track slide; let i = $index; let c = $count) {
				<div class="carousel-item" [id]="'slide-' + slide.id" role="tabpanel">
					<span
						class="visually-hidden"
						i18n="Currently selected slide number read by screen reader@@ngb.carousel.slide-number"
					>
						Slide {{ i + 1 }} of {{ c }}
					</span>
					<ng-template [ngTemplateOutlet]="slide.templateRef" />
				</div>
			}
		</div>
		@if (showNavigationArrows) {
			<button
				class="carousel-control-prev"
				type="button"
				(click)="arrowLeft()"
				[attr.aria-labelledby]="id + '-previous'"
			>
				<span class="carousel-control-prev-icon" aria-hidden="true"></span>
				<span class="visually-hidden" i18n="@@ngb.carousel.previous" [id]="id + '-previous'">Previous</span>
			</button>
			<button class="carousel-control-next" type="button" (click)="arrowRight()" [attr.aria-labelledby]="id + '-next'">
				<span class="carousel-control-next-icon" aria-hidden="true"></span>
				<span class="visually-hidden" i18n="@@ngb.carousel.next" [id]="id + '-next'">Next</span>
			</button>
		}
	`
    }]
  }], null, {
    slides: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbSlide]
    }],
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    activeId: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    interval: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    wrap: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    keyboard: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    pauseOnHover: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    pauseOnFocus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showNavigationArrows: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showNavigationIndicators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    slide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    slid: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
var NgbSlideEventSource;
(function (NgbSlideEventSource) {
  NgbSlideEventSource["TIMER"] = "timer";
  NgbSlideEventSource["ARROW_LEFT"] = "arrowLeft";
  NgbSlideEventSource["ARROW_RIGHT"] = "arrowRight";
  NgbSlideEventSource["INDICATOR"] = "indicator";
})(NgbSlideEventSource || (NgbSlideEventSource = {}));
class NgbCarouselModule {
  static {
    this.ɵfac = function NgbCarouselModule_Factory(t) {
      return new (t || NgbCarouselModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbCarouselModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCarouselModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbCarousel, NgbSlide],
      exports: [NgbCarousel, NgbSlide]
    }]
  }], null, null);
})();
class NgbCollapseModule {
  static {
    this.ɵfac = function NgbCollapseModule_Factory(t) {
      return new (t || NgbCollapseModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbCollapseModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCollapseModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbCollapse],
      exports: [NgbCollapse]
    }]
  }], null, null);
})();

/**
 * A simple class that represents a date that datepicker also uses internally.
 *
 * It is the implementation of the `NgbDateStruct` interface that adds some convenience methods,
 * like `.equals()`, `.before()`, etc.
 *
 * All datepicker APIs consume `NgbDateStruct`, but return `NgbDate`.
 *
 * In many cases it is simpler to manipulate these objects together with
 * [`NgbCalendar`](#/components/datepicker/api#NgbCalendar) than native JS Dates.
 *
 * See the [date format overview](#/components/datepicker/overview#date-model) for more details.
 *
 * @since 3.0.0
 */
class NgbDate {
  /**
   * A **static method** that creates a new date object from the `NgbDateStruct`,
   *
   * ex. `NgbDate.from({year: 2000, month: 5, day: 1})`.
   *
   * If the `date` is already of `NgbDate` type, the method will return the same object.
   */
  static from(date) {
    if (date instanceof NgbDate) {
      return date;
    }
    return date ? new NgbDate(date.year, date.month, date.day) : null;
  }
  constructor(year, month, day) {
    this.year = isInteger(year) ? year : null;
    this.month = isInteger(month) ? month : null;
    this.day = isInteger(day) ? day : null;
  }
  /**
   * Checks if the current date is equal to another date.
   */
  equals(other) {
    return other != null && this.year === other.year && this.month === other.month && this.day === other.day;
  }
  /**
   * Checks if the current date is before another date.
   */
  before(other) {
    if (!other) {
      return false;
    }
    if (this.year === other.year) {
      if (this.month === other.month) {
        return this.day === other.day ? false : this.day < other.day;
      } else {
        return this.month < other.month;
      }
    } else {
      return this.year < other.year;
    }
  }
  /**
   * Checks if the current date is after another date.
   */
  after(other) {
    if (!other) {
      return false;
    }
    if (this.year === other.year) {
      if (this.month === other.month) {
        return this.day === other.day ? false : this.day > other.day;
      } else {
        return this.month > other.month;
      }
    } else {
      return this.year > other.year;
    }
  }
}
function fromJSDate(jsDate) {
  return new NgbDate(jsDate.getFullYear(), jsDate.getMonth() + 1, jsDate.getDate());
}
function toJSDate(date) {
  const jsDate = new Date(date.year, date.month - 1, date.day, 12);
  // this is done avoid 30 -> 1930 conversion
  if (!isNaN(jsDate.getTime())) {
    jsDate.setFullYear(date.year);
  }
  return jsDate;
}
function NGB_DATEPICKER_CALENDAR_FACTORY() {
  return new NgbCalendarGregorian();
}
/**
 * A service that represents the calendar used by the datepicker.
 *
 * The default implementation uses the Gregorian calendar. You can inject it in your own
 * implementations if necessary to simplify `NgbDate` calculations.
 */
class NgbCalendar {
  static {
    this.ɵfac = function NgbCalendar_Factory(t) {
      return new (t || NgbCalendar)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendar,
      factory: () => NGB_DATEPICKER_CALENDAR_FACTORY(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendar, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: NGB_DATEPICKER_CALENDAR_FACTORY
    }]
  }], null, null);
})();
class NgbCalendarGregorian extends NgbCalendar {
  getDaysPerWeek() {
    return 7;
  }
  getMonths() {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  }
  getWeeksPerMonth() {
    return 6;
  }
  getNext(date, period = 'd', number = 1) {
    let jsDate = toJSDate(date);
    let checkMonth = true;
    let expectedMonth = jsDate.getMonth();
    switch (period) {
      case 'y':
        jsDate.setFullYear(jsDate.getFullYear() + number);
        break;
      case 'm':
        expectedMonth += number;
        jsDate.setMonth(expectedMonth);
        expectedMonth = expectedMonth % 12;
        if (expectedMonth < 0) {
          expectedMonth = expectedMonth + 12;
        }
        break;
      case 'd':
        jsDate.setDate(jsDate.getDate() + number);
        checkMonth = false;
        break;
      default:
        return date;
    }
    if (checkMonth && jsDate.getMonth() !== expectedMonth) {
      // this means the destination month has less days than the initial month
      // let's go back to the end of the previous month:
      jsDate.setDate(0);
    }
    return fromJSDate(jsDate);
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    let jsDate = toJSDate(date);
    let day = jsDate.getDay();
    // in JS Date Sun=0, in ISO 8601 Sun=7
    return day === 0 ? 7 : day;
  }
  getWeekNumber(week, firstDayOfWeek) {
    // in JS Date Sun=0, in ISO 8601 Sun=7
    if (firstDayOfWeek === 7) {
      firstDayOfWeek = 0;
    }
    const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
    let date = week[thursdayIndex];
    const jsDate = toJSDate(date);
    jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
    const time = jsDate.getTime();
    jsDate.setMonth(0); // Compare with Jan 1
    jsDate.setDate(1);
    return Math.floor(Math.round((time - jsDate.getTime()) / 86400000) / 7) + 1;
  }
  getToday() {
    return fromJSDate(new Date());
  }
  isValid(date) {
    if (!date || !isInteger(date.year) || !isInteger(date.month) || !isInteger(date.day)) {
      return false;
    }
    // year 0 doesn't exist in Gregorian calendar
    if (date.year === 0) {
      return false;
    }
    const jsDate = toJSDate(date);
    return !isNaN(jsDate.getTime()) && jsDate.getFullYear() === date.year && jsDate.getMonth() + 1 === date.month && jsDate.getDate() === date.day;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarGregorian_BaseFactory;
      return function NgbCalendarGregorian_Factory(t) {
        return (ɵNgbCalendarGregorian_BaseFactory || (ɵNgbCalendarGregorian_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarGregorian)))(t || NgbCalendarGregorian);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarGregorian,
      factory: NgbCalendarGregorian.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarGregorian, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
function isChangedDate(prev, next) {
  return !dateComparator(prev, next);
}
function isChangedMonth(prev, next) {
  return !prev && !next ? false : !prev || !next ? true : prev.year !== next.year || prev.month !== next.month;
}
function dateComparator(prev, next) {
  return !prev && !next || !!prev && !!next && prev.equals(next);
}
function checkMinBeforeMax(minDate, maxDate) {
  if (maxDate && minDate && maxDate.before(minDate)) {
    throw new Error(`'maxDate' ${maxDate} should be greater than 'minDate' ${minDate}`);
  }
}
function checkDateInRange(date, minDate, maxDate) {
  if (date && minDate && date.before(minDate)) {
    return minDate;
  }
  if (date && maxDate && date.after(maxDate)) {
    return maxDate;
  }
  return date || null;
}
function isDateSelectable(date, state) {
  const {
    minDate,
    maxDate,
    disabled,
    markDisabled
  } = state;
  return !(date === null || date === undefined || disabled || markDisabled && markDisabled(date, {
    year: date.year,
    month: date.month
  }) || minDate && date.before(minDate) || maxDate && date.after(maxDate));
}
function generateSelectBoxMonths(calendar, date, minDate, maxDate) {
  if (!date) {
    return [];
  }
  let months = calendar.getMonths(date.year);
  if (minDate && date.year === minDate.year) {
    const index = months.findIndex(month => month === minDate.month);
    months = months.slice(index);
  }
  if (maxDate && date.year === maxDate.year) {
    const index = months.findIndex(month => month === maxDate.month);
    months = months.slice(0, index + 1);
  }
  return months;
}
function generateSelectBoxYears(date, minDate, maxDate) {
  if (!date) {
    return [];
  }
  const start = minDate ? Math.max(minDate.year, date.year - 500) : date.year - 10;
  const end = maxDate ? Math.min(maxDate.year, date.year + 500) : date.year + 10;
  const length = end - start + 1;
  const numbers = Array(length);
  for (let i = 0; i < length; i++) {
    numbers[i] = start + i;
  }
  return numbers;
}
function nextMonthDisabled(calendar, date, maxDate) {
  const nextDate = Object.assign(calendar.getNext(date, 'm'), {
    day: 1
  });
  return maxDate != null && nextDate.after(maxDate);
}
function prevMonthDisabled(calendar, date, minDate) {
  const prevDate = Object.assign(calendar.getPrev(date, 'm'), {
    day: 1
  });
  return minDate != null && (prevDate.year === minDate.year && prevDate.month < minDate.month || prevDate.year < minDate.year && minDate.month === 1);
}
function buildMonths(calendar, date, state, i18n, force) {
  const {
    displayMonths,
    months
  } = state;
  // move old months to a temporary array
  const monthsToReuse = months.splice(0, months.length);
  // generate new first dates, nullify or reuse months
  const firstDates = Array.from({
    length: displayMonths
  }, (_, i) => {
    const firstDate = Object.assign(calendar.getNext(date, 'm', i), {
      day: 1
    });
    months[i] = null;
    if (!force) {
      const reusedIndex = monthsToReuse.findIndex(month => month.firstDate.equals(firstDate));
      // move reused month back to months
      if (reusedIndex !== -1) {
        months[i] = monthsToReuse.splice(reusedIndex, 1)[0];
      }
    }
    return firstDate;
  });
  // rebuild nullified months
  firstDates.forEach((firstDate, i) => {
    if (months[i] === null) {
      months[i] = buildMonth(calendar, firstDate, state, i18n, monthsToReuse.shift() || {});
    }
  });
  return months;
}
function buildMonth(calendar, date, state, i18n, month = {}) {
  const {
    dayTemplateData,
    minDate,
    maxDate,
    firstDayOfWeek,
    markDisabled,
    outsideDays,
    weekdayWidth,
    weekdaysVisible
  } = state;
  const calendarToday = calendar.getToday();
  month.firstDate = null;
  month.lastDate = null;
  month.number = date.month;
  month.year = date.year;
  month.weeks = month.weeks || [];
  month.weekdays = month.weekdays || [];
  date = getFirstViewDate(calendar, date, firstDayOfWeek);
  // clearing weekdays, if not visible
  if (!weekdaysVisible) {
    month.weekdays.length = 0;
  }
  // month has weeks
  for (let week = 0; week < calendar.getWeeksPerMonth(); week++) {
    let weekObject = month.weeks[week];
    if (!weekObject) {
      weekObject = month.weeks[week] = {
        number: 0,
        days: [],
        collapsed: true
      };
    }
    const days = weekObject.days;
    // week has days
    for (let day = 0; day < calendar.getDaysPerWeek(); day++) {
      if (week === 0 && weekdaysVisible) {
        month.weekdays[day] = i18n.getWeekdayLabel(calendar.getWeekday(date), weekdayWidth);
      }
      const newDate = new NgbDate(date.year, date.month, date.day);
      const nextDate = calendar.getNext(newDate);
      const ariaLabel = i18n.getDayAriaLabel(newDate);
      // marking date as disabled
      let disabled = !!(minDate && newDate.before(minDate) || maxDate && newDate.after(maxDate));
      if (!disabled && markDisabled) {
        disabled = markDisabled(newDate, {
          month: month.number,
          year: month.year
        });
      }
      // today
      let today = newDate.equals(calendarToday);
      // adding user-provided data to the context
      let contextUserData = dayTemplateData ? dayTemplateData(newDate, {
        month: month.number,
        year: month.year
      }) : undefined;
      // saving first date of the month
      if (month.firstDate === null && newDate.month === month.number) {
        month.firstDate = newDate;
      }
      // saving last date of the month
      if (newDate.month === month.number && nextDate.month !== month.number) {
        month.lastDate = newDate;
      }
      let dayObject = days[day];
      if (!dayObject) {
        dayObject = days[day] = {};
      }
      dayObject.date = newDate;
      dayObject.context = Object.assign(dayObject.context || {}, {
        $implicit: newDate,
        date: newDate,
        data: contextUserData,
        currentMonth: month.number,
        currentYear: month.year,
        disabled,
        focused: false,
        selected: false,
        today
      });
      dayObject.tabindex = -1;
      dayObject.ariaLabel = ariaLabel;
      dayObject.hidden = false;
      date = nextDate;
    }
    weekObject.number = calendar.getWeekNumber(days.map(day => day.date), firstDayOfWeek);
    // marking week as collapsed
    weekObject.collapsed = outsideDays === 'collapsed' && days[0].date.month !== month.number && days[days.length - 1].date.month !== month.number;
  }
  return month;
}
function getFirstViewDate(calendar, date, firstDayOfWeek) {
  const daysPerWeek = calendar.getDaysPerWeek();
  const firstMonthDate = new NgbDate(date.year, date.month, 1);
  const dayOfWeek = calendar.getWeekday(firstMonthDate) % daysPerWeek;
  return calendar.getPrev(firstMonthDate, 'd', (daysPerWeek + dayOfWeek - firstDayOfWeek) % daysPerWeek);
}

/**
 * A service supplying i18n data to the datepicker component.
 *
 * The default implementation of this service uses the Angular locale and registered locale data for
 * weekdays and month names (as explained in the Angular i18n guide).
 *
 * It also provides a way to i18n data that depends on calendar calculations, like aria labels, day, week and year
 * numerals. For other static labels the datepicker uses the default Angular i18n.
 *
 * See the [i18n demo](#/components/datepicker/examples#i18n) and
 * [Hebrew calendar demo](#/components/datepicker/calendars#hebrew) on how to extend this class and define
 * a custom provider for i18n.
 */
class NgbDatepickerI18n {
  /**
   * Returns the text label to display above the day view.
   *
   * @since 9.1.0
   */
  getMonthLabel(date) {
    return `${this.getMonthFullName(date.month, date.year)} ${this.getYearNumerals(date.year)}`;
  }
  /**
   * Returns the textual representation of a day that is rendered in a day cell.
   *
   * @since 3.0.0
   */
  getDayNumerals(date) {
    return `${date.day}`;
  }
  /**
   * Returns the textual representation of a week number rendered by datepicker.
   *
   * @since 3.0.0
   */
  getWeekNumerals(weekNumber) {
    return `${weekNumber}`;
  }
  /**
   * Returns the textual representation of a year that is rendered in the datepicker year select box.
   *
   * @since 3.0.0
   */
  getYearNumerals(year) {
    return `${year}`;
  }
  /**
   * Returns the week label to display in the heading of the month view.
   *
   * @since 9.1.0
   */
  getWeekLabel() {
    return '';
  }
  static {
    this.ɵfac = function NgbDatepickerI18n_Factory(t) {
      return new (t || NgbDatepickerI18n)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerI18n,
      factory: () => (() => new NgbDatepickerI18nDefault())(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerI18n, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => new NgbDatepickerI18nDefault()
    }]
  }], null, null);
})();
/**
 * A service providing default implementation for the datepicker i18n.
 * It can be used as a base implementation if necessary.
 *
 * @since 9.1.0
 */
class NgbDatepickerI18nDefault extends NgbDatepickerI18n {
  constructor() {
    super(...arguments);
    this._locale = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID);
    this._monthsShort = (0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.getLocaleMonthNames)(this._locale, _angular_common__WEBPACK_IMPORTED_MODULE_13__.FormStyle.Standalone, _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Abbreviated);
    this._monthsFull = (0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.getLocaleMonthNames)(this._locale, _angular_common__WEBPACK_IMPORTED_MODULE_13__.FormStyle.Standalone, _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Wide);
  }
  getWeekdayLabel(weekday, width) {
    const weekdaysStartingOnSunday = (0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.getLocaleDayNames)(this._locale, _angular_common__WEBPACK_IMPORTED_MODULE_13__.FormStyle.Standalone, width === undefined ? _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Short : width);
    const weekdays = weekdaysStartingOnSunday.map((day, index) => weekdaysStartingOnSunday[(index + 1) % 7]);
    return weekdays[weekday - 1] || '';
  }
  getMonthShortName(month) {
    return this._monthsShort[month - 1] || '';
  }
  getMonthFullName(month) {
    return this._monthsFull[month - 1] || '';
  }
  getDayAriaLabel(date) {
    const jsDate = new Date(date.year, date.month - 1, date.day);
    return (0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.formatDate)(jsDate, 'fullDate', this._locale);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDatepickerI18nDefault_BaseFactory;
      return function NgbDatepickerI18nDefault_Factory(t) {
        return (ɵNgbDatepickerI18nDefault_BaseFactory || (ɵNgbDatepickerI18nDefault_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDatepickerI18nDefault)))(t || NgbDatepickerI18nDefault);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerI18nDefault,
      factory: NgbDatepickerI18nDefault.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerI18nDefault, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
class NgbDatepickerService {
  constructor() {
    this._VALIDATORS = {
      dayTemplateData: dayTemplateData => {
        if (this._state.dayTemplateData !== dayTemplateData) {
          return {
            dayTemplateData
          };
        }
      },
      displayMonths: displayMonths => {
        displayMonths = toInteger(displayMonths);
        if (isInteger(displayMonths) && displayMonths > 0 && this._state.displayMonths !== displayMonths) {
          return {
            displayMonths
          };
        }
      },
      disabled: disabled => {
        if (this._state.disabled !== disabled) {
          return {
            disabled
          };
        }
      },
      firstDayOfWeek: firstDayOfWeek => {
        firstDayOfWeek = toInteger(firstDayOfWeek);
        if (isInteger(firstDayOfWeek) && firstDayOfWeek >= 0 && this._state.firstDayOfWeek !== firstDayOfWeek) {
          return {
            firstDayOfWeek
          };
        }
      },
      focusVisible: focusVisible => {
        if (this._state.focusVisible !== focusVisible && !this._state.disabled) {
          return {
            focusVisible
          };
        }
      },
      markDisabled: markDisabled => {
        if (this._state.markDisabled !== markDisabled) {
          return {
            markDisabled
          };
        }
      },
      maxDate: date => {
        const maxDate = this.toValidDate(date, null);
        if (isChangedDate(this._state.maxDate, maxDate)) {
          return {
            maxDate
          };
        }
      },
      minDate: date => {
        const minDate = this.toValidDate(date, null);
        if (isChangedDate(this._state.minDate, minDate)) {
          return {
            minDate
          };
        }
      },
      navigation: navigation => {
        if (this._state.navigation !== navigation) {
          return {
            navigation
          };
        }
      },
      outsideDays: outsideDays => {
        if (this._state.outsideDays !== outsideDays) {
          return {
            outsideDays
          };
        }
      },
      weekdays: weekdays => {
        const weekdayWidth = weekdays === true || weekdays === false ? _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Short : weekdays;
        const weekdaysVisible = weekdays === true || weekdays === false ? weekdays : true;
        if (this._state.weekdayWidth !== weekdayWidth || this._state.weekdaysVisible !== weekdaysVisible) {
          return {
            weekdayWidth,
            weekdaysVisible
          };
        }
      }
    };
    this._calendar = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCalendar);
    this._i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
    this._model$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._dateSelect$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._state = {
      dayTemplateData: null,
      markDisabled: null,
      maxDate: null,
      minDate: null,
      disabled: false,
      displayMonths: 1,
      firstDate: null,
      firstDayOfWeek: 1,
      lastDate: null,
      focusDate: null,
      focusVisible: false,
      months: [],
      navigation: 'select',
      outsideDays: 'visible',
      prevDisabled: false,
      nextDisabled: false,
      selectedDate: null,
      selectBoxes: {
        years: [],
        months: []
      },
      weekdayWidth: _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Short,
      weekdaysVisible: true
    };
  }
  get model$() {
    return this._model$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(model => model.months.length > 0));
  }
  get dateSelect$() {
    return this._dateSelect$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(date => date !== null));
  }
  set(options) {
    let patch = Object.keys(options).map(key => this._VALIDATORS[key](options[key])).reduce((obj, part) => ({
      ...obj,
      ...part
    }), {});
    if (Object.keys(patch).length > 0) {
      this._nextState(patch);
    }
  }
  focus(date) {
    const focusedDate = this.toValidDate(date, null);
    if (focusedDate != null && !this._state.disabled && isChangedDate(this._state.focusDate, focusedDate)) {
      this._nextState({
        focusDate: date
      });
    }
  }
  focusSelect() {
    if (isDateSelectable(this._state.focusDate, this._state)) {
      this.select(this._state.focusDate, {
        emitEvent: true
      });
    }
  }
  open(date) {
    const firstDate = this.toValidDate(date, this._calendar.getToday());
    if (firstDate != null && !this._state.disabled && (!this._state.firstDate || isChangedMonth(this._state.firstDate, firstDate))) {
      this._nextState({
        firstDate
      });
    }
  }
  select(date, options = {}) {
    const selectedDate = this.toValidDate(date, null);
    if (selectedDate != null && !this._state.disabled) {
      if (isChangedDate(this._state.selectedDate, selectedDate)) {
        this._nextState({
          selectedDate
        });
      }
      if (options.emitEvent && isDateSelectable(selectedDate, this._state)) {
        this._dateSelect$.next(selectedDate);
      }
    }
  }
  toValidDate(date, defaultValue) {
    const ngbDate = NgbDate.from(date);
    if (defaultValue === undefined) {
      defaultValue = this._calendar.getToday();
    }
    return this._calendar.isValid(ngbDate) ? ngbDate : defaultValue;
  }
  getMonth(struct) {
    for (let month of this._state.months) {
      if (struct.month === month.number && struct.year === month.year) {
        return month;
      }
    }
    throw new Error(`month ${struct.month} of year ${struct.year} not found`);
  }
  _nextState(patch) {
    const newState = this._updateState(patch);
    this._patchContexts(newState);
    this._state = newState;
    this._model$.next(this._state);
  }
  _patchContexts(state) {
    const {
      months,
      displayMonths,
      selectedDate,
      focusDate,
      focusVisible,
      disabled,
      outsideDays
    } = state;
    state.months.forEach(month => {
      month.weeks.forEach(week => {
        week.days.forEach(day => {
          // patch focus flag
          if (focusDate) {
            day.context.focused = focusDate.equals(day.date) && focusVisible;
          }
          // calculating tabindex
          day.tabindex = !disabled && focusDate && day.date.equals(focusDate) && focusDate.month === month.number ? 0 : -1;
          // override context disabled
          if (disabled === true) {
            day.context.disabled = true;
          }
          // patch selection flag
          if (selectedDate !== undefined) {
            day.context.selected = selectedDate !== null && selectedDate.equals(day.date);
          }
          // visibility
          if (month.number !== day.date.month) {
            day.hidden = outsideDays === 'hidden' || outsideDays === 'collapsed' || displayMonths > 1 && day.date.after(months[0].firstDate) && day.date.before(months[displayMonths - 1].lastDate);
          }
        });
      });
    });
  }
  _updateState(patch) {
    // patching fields
    const state = Object.assign({}, this._state, patch);
    let startDate = state.firstDate;
    // min/max dates changed
    if ('minDate' in patch || 'maxDate' in patch) {
      checkMinBeforeMax(state.minDate, state.maxDate);
      state.focusDate = checkDateInRange(state.focusDate, state.minDate, state.maxDate);
      state.firstDate = checkDateInRange(state.firstDate, state.minDate, state.maxDate);
      startDate = state.focusDate;
    }
    // disabled
    if ('disabled' in patch) {
      state.focusVisible = false;
    }
    // initial rebuild via 'select()'
    if ('selectedDate' in patch && this._state.months.length === 0) {
      startDate = state.selectedDate;
    }
    // terminate early if only focus visibility was changed
    if ('focusVisible' in patch) {
      return state;
    }
    // focus date changed
    if ('focusDate' in patch) {
      state.focusDate = checkDateInRange(state.focusDate, state.minDate, state.maxDate);
      startDate = state.focusDate;
      // nothing to rebuild if only focus changed and it is still visible
      if (state.months.length !== 0 && state.focusDate && !state.focusDate.before(state.firstDate) && !state.focusDate.after(state.lastDate)) {
        return state;
      }
    }
    // first date changed
    if ('firstDate' in patch) {
      state.firstDate = checkDateInRange(state.firstDate, state.minDate, state.maxDate);
      startDate = state.firstDate;
    }
    // rebuilding months
    if (startDate) {
      const forceRebuild = 'dayTemplateData' in patch || 'firstDayOfWeek' in patch || 'markDisabled' in patch || 'minDate' in patch || 'maxDate' in patch || 'disabled' in patch || 'outsideDays' in patch || 'weekdaysVisible' in patch;
      const months = buildMonths(this._calendar, startDate, state, this._i18n, forceRebuild);
      // updating months and boundary dates
      state.months = months;
      state.firstDate = months[0].firstDate;
      state.lastDate = months[months.length - 1].lastDate;
      // reset selected date if 'markDisabled' returns true
      if ('selectedDate' in patch && !isDateSelectable(state.selectedDate, state)) {
        state.selectedDate = null;
      }
      // adjusting focus after months were built
      if ('firstDate' in patch) {
        if (!state.focusDate || state.focusDate.before(state.firstDate) || state.focusDate.after(state.lastDate)) {
          state.focusDate = startDate;
        }
      }
      // adjusting months/years for the select box navigation
      const yearChanged = !this._state.firstDate || this._state.firstDate.year !== state.firstDate.year;
      const monthChanged = !this._state.firstDate || this._state.firstDate.month !== state.firstDate.month;
      if (state.navigation === 'select') {
        // years ->  boundaries (min/max were changed)
        if ('minDate' in patch || 'maxDate' in patch || state.selectBoxes.years.length === 0 || yearChanged) {
          state.selectBoxes.years = generateSelectBoxYears(state.firstDate, state.minDate, state.maxDate);
        }
        // months -> when current year or boundaries change
        if ('minDate' in patch || 'maxDate' in patch || state.selectBoxes.months.length === 0 || yearChanged) {
          state.selectBoxes.months = generateSelectBoxMonths(this._calendar, state.firstDate, state.minDate, state.maxDate);
        }
      } else {
        state.selectBoxes = {
          years: [],
          months: []
        };
      }
      // updating navigation arrows -> boundaries change (min/max) or month/year changes
      if ((state.navigation === 'arrows' || state.navigation === 'select') && (monthChanged || yearChanged || 'minDate' in patch || 'maxDate' in patch || 'disabled' in patch)) {
        state.prevDisabled = state.disabled || prevMonthDisabled(this._calendar, state.firstDate, state.minDate);
        state.nextDisabled = state.disabled || nextMonthDisabled(this._calendar, state.lastDate, state.maxDate);
      }
    }
    return state;
  }
  static {
    this.ɵfac = function NgbDatepickerService_Factory(t) {
      return new (t || NgbDatepickerService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerService,
      factory: NgbDatepickerService.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
var NavigationEvent;
(function (NavigationEvent) {
  NavigationEvent[NavigationEvent["PREV"] = 0] = "PREV";
  NavigationEvent[NavigationEvent["NEXT"] = 1] = "NEXT";
})(NavigationEvent || (NavigationEvent = {}));

/**
 * A configuration service for the [`NgbDatepicker`](#/components/datepicker/api#NgbDatepicker) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the datepickers used in the application.
 */
class NgbDatepickerConfig {
  constructor() {
    this.displayMonths = 1;
    this.firstDayOfWeek = 1;
    this.navigation = 'select';
    this.outsideDays = 'visible';
    this.showWeekNumbers = false;
    this.weekdays = _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Short;
  }
  static {
    this.ɵfac = function NgbDatepickerConfig_Factory(t) {
      return new (t || NgbDatepickerConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerConfig,
      factory: NgbDatepickerConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function NGB_DATEPICKER_DATE_ADAPTER_FACTORY() {
  return new NgbDateStructAdapter();
}
/**
 * An abstract service that does the conversion between the internal datepicker `NgbDateStruct` model and
 * any provided user date model `D`, ex. a string, a native date, etc.
 *
 * The adapter is used **only** for conversion when binding datepicker to a form control,
 * ex. `[(ngModel)]="userDateModel"`. Here `userDateModel` can be of any type.
 *
 * The default datepicker implementation assumes we use `NgbDateStruct` as a user model.
 *
 * See the [date format overview](#/components/datepicker/overview#date-model) for more details
 * and the [custom adapter demo](#/components/datepicker/examples#adapter) for an example.
 */
class NgbDateAdapter {
  static {
    this.ɵfac = function NgbDateAdapter_Factory(t) {
      return new (t || NgbDateAdapter)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateAdapter,
      factory: () => NGB_DATEPICKER_DATE_ADAPTER_FACTORY(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: NGB_DATEPICKER_DATE_ADAPTER_FACTORY
    }]
  }], null, null);
})();
class NgbDateStructAdapter extends NgbDateAdapter {
  /**
   * Converts a NgbDateStruct value into NgbDateStruct value
   */
  fromModel(date) {
    return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) ? {
      year: date.year,
      month: date.month,
      day: date.day
    } : null;
  }
  /**
   * Converts a NgbDateStruct value into NgbDateStruct value
   */
  toModel(date) {
    return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) ? {
      year: date.year,
      month: date.month,
      day: date.day
    } : null;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDateStructAdapter_BaseFactory;
      return function NgbDateStructAdapter_Factory(t) {
        return (ɵNgbDateStructAdapter_BaseFactory || (ɵNgbDateStructAdapter_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDateStructAdapter)))(t || NgbDateStructAdapter);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateStructAdapter,
      factory: NgbDateStructAdapter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateStructAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
var Key;
(function (Key) {
  Key[Key["Tab"] = 9] = "Tab";
  Key[Key["Enter"] = 13] = "Enter";
  Key[Key["Escape"] = 27] = "Escape";
  Key[Key["Space"] = 32] = "Space";
  Key[Key["PageUp"] = 33] = "PageUp";
  Key[Key["PageDown"] = 34] = "PageDown";
  Key[Key["End"] = 35] = "End";
  Key[Key["Home"] = 36] = "Home";
  Key[Key["ArrowLeft"] = 37] = "ArrowLeft";
  Key[Key["ArrowUp"] = 38] = "ArrowUp";
  Key[Key["ArrowRight"] = 39] = "ArrowRight";
  Key[Key["ArrowDown"] = 40] = "ArrowDown";
})(Key || (Key = {}));

/**
 * A service that represents the keyboard navigation.
 *
 * Default keyboard shortcuts [are documented in the overview](#/components/datepicker/overview#keyboard-shortcuts)
 *
 * @since 5.2.0
 */
class NgbDatepickerKeyboardService {
  /**
   * Processes a keyboard event.
   */
  processKey(event, datepicker) {
    const {
      state,
      calendar
    } = datepicker;
    /* eslint-disable-next-line deprecation/deprecation */
    switch (event.which) {
      case Key.PageUp:
        datepicker.focusDate(calendar.getPrev(state.focusedDate, event.shiftKey ? 'y' : 'm', 1));
        break;
      case Key.PageDown:
        datepicker.focusDate(calendar.getNext(state.focusedDate, event.shiftKey ? 'y' : 'm', 1));
        break;
      case Key.End:
        datepicker.focusDate(event.shiftKey ? state.maxDate : state.lastDate);
        break;
      case Key.Home:
        datepicker.focusDate(event.shiftKey ? state.minDate : state.firstDate);
        break;
      case Key.ArrowLeft:
        datepicker.focusDate(calendar.getPrev(state.focusedDate, 'd', 1));
        break;
      case Key.ArrowUp:
        datepicker.focusDate(calendar.getPrev(state.focusedDate, 'd', calendar.getDaysPerWeek()));
        break;
      case Key.ArrowRight:
        datepicker.focusDate(calendar.getNext(state.focusedDate, 'd', 1));
        break;
      case Key.ArrowDown:
        datepicker.focusDate(calendar.getNext(state.focusedDate, 'd', calendar.getDaysPerWeek()));
        break;
      case Key.Enter:
      case Key.Space:
        datepicker.focusSelect();
        break;
      default:
        return;
    }
    event.preventDefault();
    event.stopPropagation();
  }
  static {
    this.ɵfac = function NgbDatepickerKeyboardService_Factory(t) {
      return new (t || NgbDatepickerKeyboardService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerKeyboardService,
      factory: NgbDatepickerKeyboardService.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerKeyboardService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class NgbDatepickerDayView {
  constructor() {
    this.i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
  }
  isMuted() {
    return !this.selected && (this.date.month !== this.currentMonth || this.disabled);
  }
  static {
    this.ɵfac = function NgbDatepickerDayView_Factory(t) {
      return new (t || NgbDatepickerDayView)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbDatepickerDayView,
      selectors: [["", "ngbDatepickerDayView", ""]],
      hostAttrs: [1, "btn-light"],
      hostVars: 10,
      hostBindings: function NgbDatepickerDayView_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("bg-primary", ctx.selected)("text-white", ctx.selected)("text-muted", ctx.isMuted())("outside", ctx.isMuted())("active", ctx.focused);
        }
      },
      inputs: {
        currentMonth: "currentMonth",
        date: "date",
        disabled: "disabled",
        focused: "focused",
        selected: "selected"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      attrs: _c1,
      decls: 1,
      vars: 1,
      template: function NgbDatepickerDayView_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](0);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx.i18n.getDayNumerals(ctx.date));
        }
      },
      styles: ["[ngbDatepickerDayView]{text-align:center;width:2rem;height:2rem;line-height:2rem;border-radius:.25rem;background:transparent}[ngbDatepickerDayView]:hover:not(.bg-primary),[ngbDatepickerDayView].active:not(.bg-primary){background-color:var(--bs-tertiary-bg);outline:1px solid var(--bs-border-color)}[ngbDatepickerDayView].outside{opacity:.5}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerDayView, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: '[ngbDatepickerDayView]',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        class: 'btn-light',
        '[class.bg-primary]': 'selected',
        '[class.text-white]': 'selected',
        '[class.text-muted]': 'isMuted()',
        '[class.outside]': 'isMuted()',
        '[class.active]': 'focused'
      },
      template: `{{ i18n.getDayNumerals(date) }}`,
      styles: ["[ngbDatepickerDayView]{text-align:center;width:2rem;height:2rem;line-height:2rem;border-radius:.25rem;background:transparent}[ngbDatepickerDayView]:hover:not(.bg-primary),[ngbDatepickerDayView].active:not(.bg-primary){background-color:var(--bs-tertiary-bg);outline:1px solid var(--bs-border-color)}[ngbDatepickerDayView].outside{opacity:.5}\n"]
    }]
  }], null, {
    currentMonth: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    date: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    focused: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selected: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class NgbDatepickerNavigationSelect {
  constructor() {
    this._month = -1;
    this._year = -1;
    this.i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
    this.select = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  changeMonth(month) {
    this.select.emit(new NgbDate(this.date.year, toInteger(month), 1));
  }
  changeYear(year) {
    this.select.emit(new NgbDate(toInteger(year), this.date.month, 1));
  }
  ngAfterViewChecked() {
    if (this.date) {
      if (this.date.month !== this._month) {
        this._month = this.date.month;
        this.monthSelect.nativeElement.value = `${this._month}`;
      }
      if (this.date.year !== this._year) {
        this._year = this.date.year;
        this.yearSelect.nativeElement.value = `${this._year}`;
      }
    }
  }
  static {
    this.ɵfac = function NgbDatepickerNavigationSelect_Factory(t) {
      return new (t || NgbDatepickerNavigationSelect)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbDatepickerNavigationSelect,
      selectors: [["ngb-datepicker-navigation-select"]],
      viewQuery: function NgbDatepickerNavigationSelect_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c2, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c3, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.monthSelect = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.yearSelect = _t.first);
        }
      },
      inputs: {
        date: "date",
        disabled: "disabled",
        months: "months",
        years: "years"
      },
      outputs: {
        select: "select"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 8,
      vars: 2,
      consts: () => {
        let i18n_4;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_4 = goog.getMsg("Select month");
          i18n_4 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_4;
        } else {
          i18n_4 = $localize`:@@ngb.datepicker.select-month:Select month`;
        }
        let i18n_5;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_5 = goog.getMsg("Select month");
          i18n_5 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_5;
        } else {
          i18n_5 = $localize`:@@ngb.datepicker.select-month:Select month`;
        }
        let i18n_6;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_6 = goog.getMsg("Select year");
          i18n_6 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_6;
        } else {
          i18n_6 = $localize`:@@ngb.datepicker.select-year:Select year`;
        }
        let i18n_7;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_7 = goog.getMsg("Select year");
          i18n_7 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_7;
        } else {
          i18n_7 = $localize`:@@ngb.datepicker.select-year:Select year`;
        }
        return [["month", ""], ["year", ""], ["aria-label", i18n_4, "title", i18n_5, 1, "form-select", 3, "change", "disabled"], [3, "value"], ["aria-label", i18n_6, "title", i18n_7, 1, "form-select", 3, "change", "disabled"]];
      },
      template: function NgbDatepickerNavigationSelect_Template(rf, ctx) {
        if (rf & 1) {
          const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "select", 2, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function NgbDatepickerNavigationSelect_Template_select_change_0_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.changeMonth($event.target.value));
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](2, NgbDatepickerNavigationSelect_For_3_Template, 2, 3, "option", 3, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "select", 4, 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function NgbDatepickerNavigationSelect_Template_select_change_4_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.changeYear($event.target.value));
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](6, NgbDatepickerNavigationSelect_For_7_Template, 2, 2, "option", 3, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.months);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.years);
        }
      },
      styles: ["ngb-datepicker-navigation-select>.form-select{flex:1 1 auto;padding:0 .5rem;font-size:.875rem;height:1.85rem}ngb-datepicker-navigation-select>.form-select:focus{z-index:1}ngb-datepicker-navigation-select>.form-select::-ms-value{background-color:transparent!important}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerNavigationSelect, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-datepicker-navigation-select',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: `
		<select
			#month
			[disabled]="disabled"
			class="form-select"
			i18n-aria-label="@@ngb.datepicker.select-month"
			aria-label="Select month"
			i18n-title="@@ngb.datepicker.select-month"
			title="Select month"
			(change)="changeMonth($any($event).target.value)"
		>
			@for (m of months; track m) {
				<option [attr.aria-label]="i18n.getMonthFullName(m, date.year)" [value]="m">{{
					i18n.getMonthShortName(m, date.year)
				}}</option>
			}</select
		><select
			#year
			[disabled]="disabled"
			class="form-select"
			i18n-aria-label="@@ngb.datepicker.select-year"
			aria-label="Select year"
			i18n-title="@@ngb.datepicker.select-year"
			title="Select year"
			(change)="changeYear($any($event).target.value)"
		>
			@for (y of years; track y) {
				<option [value]="y">{{ i18n.getYearNumerals(y) }}</option>
			}
		</select>
	`,
      styles: ["ngb-datepicker-navigation-select>.form-select{flex:1 1 auto;padding:0 .5rem;font-size:.875rem;height:1.85rem}ngb-datepicker-navigation-select>.form-select:focus{z-index:1}ngb-datepicker-navigation-select>.form-select::-ms-value{background-color:transparent!important}\n"]
    }]
  }], null, {
    date: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    months: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    years: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    select: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    monthSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['month', {
        static: true,
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
      }]
    }],
    yearSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['year', {
        static: true,
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
      }]
    }]
  });
})();
class NgbDatepickerNavigation {
  constructor() {
    this.navigation = NavigationEvent;
    this.i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
    this.months = [];
    this.navigate = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.select = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  onClickPrev(event) {
    event.currentTarget.focus();
    this.navigate.emit(this.navigation.PREV);
  }
  onClickNext(event) {
    event.currentTarget.focus();
    this.navigate.emit(this.navigation.NEXT);
  }
  static {
    this.ɵfac = function NgbDatepickerNavigation_Factory(t) {
      return new (t || NgbDatepickerNavigation)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbDatepickerNavigation,
      selectors: [["ngb-datepicker-navigation"]],
      inputs: {
        date: "date",
        disabled: "disabled",
        months: "months",
        showSelect: "showSelect",
        prevDisabled: "prevDisabled",
        nextDisabled: "nextDisabled",
        selectBoxes: "selectBoxes"
      },
      outputs: {
        navigate: "navigate",
        select: "select"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 8,
      vars: 4,
      consts: () => {
        let i18n_8;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_8 = goog.getMsg("Previous month");
          i18n_8 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_8;
        } else {
          i18n_8 = $localize`:@@ngb.datepicker.previous-month:Previous month`;
        }
        let i18n_9;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_9 = goog.getMsg("Previous month");
          i18n_9 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_9;
        } else {
          i18n_9 = $localize`:@@ngb.datepicker.previous-month:Previous month`;
        }
        let i18n_10;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_10 = goog.getMsg("Next month");
          i18n_10 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_10;
        } else {
          i18n_10 = $localize`:@@ngb.datepicker.next-month:Next month`;
        }
        let i18n_11;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_11 = goog.getMsg("Next month");
          i18n_11 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_11;
        } else {
          i18n_11 = $localize`:@@ngb.datepicker.next-month:Next month`;
        }
        return [[1, "ngb-dp-arrow", "ngb-dp-arrow-prev"], ["type", "button", "aria-label", i18n_8, "title", i18n_9, 1, "btn", "btn-link", "ngb-dp-arrow-btn", 3, "click", "disabled"], [1, "ngb-dp-navigation-chevron"], [1, "ngb-dp-navigation-select", 3, "date", "disabled", "months", "years"], [1, "ngb-dp-arrow", "ngb-dp-arrow-next"], ["type", "button", "aria-label", i18n_10, "title", i18n_11, 1, "btn", "btn-link", "ngb-dp-arrow-btn", 3, "click", "disabled"], [1, "ngb-dp-navigation-select", 3, "select", "date", "disabled", "months", "years"], [1, "ngb-dp-arrow"], [1, "ngb-dp-month-name"]];
      },
      template: function NgbDatepickerNavigation_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 0)(1, "button", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbDatepickerNavigation_Template_button_click_1_listener($event) {
            return ctx.onClickPrev($event);
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](2, "span", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbDatepickerNavigation_Conditional_3_Template, 1, 4, "ngb-datepicker-navigation-select", 3)(4, NgbDatepickerNavigation_Conditional_4_Template, 2, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](5, "div", 4)(6, "button", 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbDatepickerNavigation_Template_button_click_6_listener($event) {
            return ctx.onClickNext($event);
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](7, "span", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx.prevDisabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, ctx.showSelect ? 3 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](4, !ctx.showSelect ? 4 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx.nextDisabled);
        }
      },
      dependencies: [NgbDatepickerNavigationSelect],
      styles: ["ngb-datepicker-navigation{display:flex;align-items:center}.ngb-dp-navigation-chevron{border-style:solid;border-width:.2em .2em 0 0;display:inline-block;width:.75em;height:.75em;margin-left:.25em;margin-right:.15em;transform:rotate(-135deg)}.ngb-dp-arrow{display:flex;flex:1 1 auto;padding-right:0;padding-left:0;margin:0;width:2rem;height:2rem}.ngb-dp-arrow-next{justify-content:flex-end}.ngb-dp-arrow-next .ngb-dp-navigation-chevron{transform:rotate(45deg);margin-left:.15em;margin-right:.25em}.ngb-dp-arrow-btn{padding:0 .25rem;margin:0 .5rem;border:none;background-color:transparent;z-index:1}.ngb-dp-arrow-btn:focus{outline-width:1px;outline-style:auto}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.ngb-dp-arrow-btn:focus{outline-style:solid}}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center}.ngb-dp-navigation-select{display:flex;flex:1 1 9rem}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerNavigation, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-datepicker-navigation',
      standalone: true,
      imports: [NgbDatepickerNavigationSelect],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: `
		<div class="ngb-dp-arrow ngb-dp-arrow-prev">
			<button
				type="button"
				class="btn btn-link ngb-dp-arrow-btn"
				(click)="onClickPrev($event)"
				[disabled]="prevDisabled"
				i18n-aria-label="@@ngb.datepicker.previous-month"
				aria-label="Previous month"
				i18n-title="@@ngb.datepicker.previous-month"
				title="Previous month"
			>
				<span class="ngb-dp-navigation-chevron"></span>
			</button>
		</div>
		@if (showSelect) {
			<ngb-datepicker-navigation-select
				class="ngb-dp-navigation-select"
				[date]="date"
				[disabled]="disabled"
				[months]="selectBoxes.months"
				[years]="selectBoxes.years"
				(select)="select.emit($event)"
			/>
		}

		@if (!showSelect) {
			@for (month of months; track month; let i = $index) {
				@if (i > 0) {
					<div class="ngb-dp-arrow"></div>
				}
				<div class="ngb-dp-month-name">
					{{ i18n.getMonthLabel(month.firstDate) }}
				</div>
				@if (i !== months.length - 1) {
					<div class="ngb-dp-arrow"></div>
				}
			}
		}
		<div class="ngb-dp-arrow ngb-dp-arrow-next">
			<button
				type="button"
				class="btn btn-link ngb-dp-arrow-btn"
				(click)="onClickNext($event)"
				[disabled]="nextDisabled"
				i18n-aria-label="@@ngb.datepicker.next-month"
				aria-label="Next month"
				i18n-title="@@ngb.datepicker.next-month"
				title="Next month"
			>
				<span class="ngb-dp-navigation-chevron"></span>
			</button>
		</div>
	`,
      styles: ["ngb-datepicker-navigation{display:flex;align-items:center}.ngb-dp-navigation-chevron{border-style:solid;border-width:.2em .2em 0 0;display:inline-block;width:.75em;height:.75em;margin-left:.25em;margin-right:.15em;transform:rotate(-135deg)}.ngb-dp-arrow{display:flex;flex:1 1 auto;padding-right:0;padding-left:0;margin:0;width:2rem;height:2rem}.ngb-dp-arrow-next{justify-content:flex-end}.ngb-dp-arrow-next .ngb-dp-navigation-chevron{transform:rotate(45deg);margin-left:.15em;margin-right:.25em}.ngb-dp-arrow-btn{padding:0 .25rem;margin:0 .5rem;border:none;background-color:transparent;z-index:1}.ngb-dp-arrow-btn:focus{outline-width:1px;outline-style:auto}@media all and (-ms-high-contrast: none),(-ms-high-contrast: active){.ngb-dp-arrow-btn:focus{outline-style:solid}}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center}.ngb-dp-navigation-select{display:flex;flex:1 1 9rem}\n"]
    }]
  }], null, {
    date: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    months: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    prevDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    nextDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectBoxes: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    navigate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    select: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();

/**
 * A directive that marks the content template that customizes the way datepicker months are displayed
 *
 * @since 5.3.0
 */
class NgbDatepickerContent {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbDatepickerContent_Factory(t) {
      return new (t || NgbDatepickerContent)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDatepickerContent,
      selectors: [["ng-template", "ngbDatepickerContent", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerContent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbDatepickerContent]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A component that renders one month including all the days, weekdays and week numbers. Can be used inside
 * the `<ng-template ngbDatepickerMonths></ng-template>` when you want to customize months layout.
 *
 * For a usage example, see [custom month layout demo](#/components/datepicker/examples#custommonth)
 *
 * @since 5.3.0
 */
class NgbDatepickerMonth {
  constructor() {
    this._keyboardService = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerKeyboardService);
    this._service = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerService);
    this.i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
    this.datepicker = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepicker);
  }
  /**
   * The first date of month to be rendered.
   *
   * This month must one of the months present in the
   * [datepicker state](#/components/datepicker/api#NgbDatepickerState).
   */
  set month(month) {
    this.viewModel = this._service.getMonth(month);
  }
  onKeyDown(event) {
    this._keyboardService.processKey(event, this.datepicker);
  }
  doSelect(day) {
    if (!day.context.disabled && !day.hidden) {
      this.datepicker.onDateSelect(day.date);
    }
  }
  static {
    this.ɵfac = function NgbDatepickerMonth_Factory(t) {
      return new (t || NgbDatepickerMonth)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbDatepickerMonth,
      selectors: [["ngb-datepicker-month"]],
      hostAttrs: ["role", "grid"],
      hostBindings: function NgbDatepickerMonth_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("keydown", function NgbDatepickerMonth_keydown_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          });
        }
      },
      inputs: {
        month: "month"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 3,
      vars: 1,
      consts: [["role", "row", 1, "ngb-dp-week", "ngb-dp-weekdays"], [1, "ngb-dp-weekday", "ngb-dp-showweek", "small"], ["role", "columnheader", 1, "ngb-dp-weekday", "small"], ["role", "row", 1, "ngb-dp-week"], [1, "ngb-dp-week-number", "small", "text-muted"], ["role", "gridcell", 1, "ngb-dp-day", 3, "disabled", "tabindex", "hidden", "ngb-dp-today"], ["role", "gridcell", 1, "ngb-dp-day", 3, "click", "tabindex"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
      template: function NgbDatepickerMonth_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbDatepickerMonth_Conditional_0_Template, 4, 1, "div", 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](1, NgbDatepickerMonth_For_2_Template, 1, 1, null, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](0, ctx.viewModel.weekdays.length > 0 ? 0 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.viewModel.weeks);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      styles: ["ngb-datepicker-month{display:block}.ngb-dp-weekday,.ngb-dp-week-number{line-height:2rem;text-align:center;font-style:italic}.ngb-dp-weekday{color:var(--bs-info)}.ngb-dp-week{border-radius:.25rem;display:flex}.ngb-dp-weekdays{border-bottom:1px solid var(--bs-border-color);border-radius:0;background-color:var(--bs-tertiary-bg)}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:2rem;height:2rem}.ngb-dp-day{cursor:pointer}.ngb-dp-day.disabled,.ngb-dp-day.hidden{cursor:default;pointer-events:none}.ngb-dp-day[tabindex=\"0\"]{z-index:1}\n"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerMonth, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-datepicker-month',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      host: {
        role: 'grid',
        '(keydown)': 'onKeyDown($event)'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: `
		@if (viewModel.weekdays.length > 0) {
			<div class="ngb-dp-week ngb-dp-weekdays" role="row">
				@if (datepicker.showWeekNumbers) {
					<div class="ngb-dp-weekday ngb-dp-showweek small">{{ i18n.getWeekLabel() }}</div>
				}
				@for (weekday of viewModel.weekdays; track weekday) {
					<div class="ngb-dp-weekday small" role="columnheader">{{ weekday }}</div>
				}
			</div>
		}
		@for (week of viewModel.weeks; track week) {
			@if (!week.collapsed) {
				<div class="ngb-dp-week" role="row">
					@if (datepicker.showWeekNumbers) {
						<div class="ngb-dp-week-number small text-muted">{{ i18n.getWeekNumerals(week.number) }}</div>
					}
					@for (day of week.days; track day) {
						<div
							(click)="doSelect(day); $event.preventDefault()"
							class="ngb-dp-day"
							role="gridcell"
							[class.disabled]="day.context.disabled"
							[tabindex]="day.tabindex"
							[class.hidden]="day.hidden"
							[class.ngb-dp-today]="day.context.today"
							[attr.aria-label]="day.ariaLabel"
						>
							@if (!day.hidden) {
								<ng-template [ngTemplateOutlet]="datepicker.dayTemplate" [ngTemplateOutletContext]="day.context" />
							}
						</div>
					}
				</div>
			}
		}
	`,
      styles: ["ngb-datepicker-month{display:block}.ngb-dp-weekday,.ngb-dp-week-number{line-height:2rem;text-align:center;font-style:italic}.ngb-dp-weekday{color:var(--bs-info)}.ngb-dp-week{border-radius:.25rem;display:flex}.ngb-dp-weekdays{border-bottom:1px solid var(--bs-border-color);border-radius:0;background-color:var(--bs-tertiary-bg)}.ngb-dp-day,.ngb-dp-weekday,.ngb-dp-week-number{width:2rem;height:2rem}.ngb-dp-day{cursor:pointer}.ngb-dp-day.disabled,.ngb-dp-day.hidden{cursor:default;pointer-events:none}.ngb-dp-day[tabindex=\"0\"]{z-index:1}\n"]
    }]
  }], null, {
    month: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * A highly configurable component that helps you with selecting calendar dates.
 *
 * `NgbDatepicker` is meant to be displayed inline on a page or put inside a popup.
 */
class NgbDatepicker {
  constructor() {
    this.injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._service = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerService);
    this._calendar = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCalendar);
    this._i18n = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerI18n);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDatepickerConfig);
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._ngbDateAdapter = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDateAdapter);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._controlValue = null;
    this._publicState = {};
    /**
     * The reference to a custom template for the day.
     *
     * Allows to completely override the way a day 'cell' in the calendar is displayed.
     *
     * See [`DayTemplateContext`](#/components/datepicker/api#DayTemplateContext) for the data you get inside.
     */
    this.dayTemplate = this._config.dayTemplate;
    /**
     * The callback to pass any arbitrary data to the template cell via the
     * [`DayTemplateContext`](#/components/datepicker/api#DayTemplateContext)'s `data` parameter.
     *
     * `current` is the month that is currently displayed by the datepicker.
     *
     * @since 3.3.0
     */
    this.dayTemplateData = this._config.dayTemplateData;
    /**
     * The number of months to display.
     */
    this.displayMonths = this._config.displayMonths;
    /**
     * The first day of the week.
     *
     * With default calendar we use ISO 8601: 'weekday' is 1=Mon ... 7=Sun.
     */
    this.firstDayOfWeek = this._config.firstDayOfWeek;
    /**
     * The reference to the custom template for the datepicker footer.
     *
     * @since 3.3.0
     */
    this.footerTemplate = this._config.footerTemplate;
    /**
     * The callback to mark some dates as disabled.
     *
     * It is called for each new date when navigating to a different month.
     *
     * `current` is the month that is currently displayed by the datepicker.
     */
    this.markDisabled = this._config.markDisabled;
    /**
     * The latest date that can be displayed or selected.
     *
     * If not provided, 'year' select box will display 10 years after the current month.
     */
    this.maxDate = this._config.maxDate;
    /**
     * The earliest date that can be displayed or selected.
     *
     * If not provided, 'year' select box will display 10 years before the current month.
     */
    this.minDate = this._config.minDate;
    /**
     * Navigation type.
     *
     * * `"select"` - select boxes for month and navigation arrows
     * * `"arrows"` - only navigation arrows
     * * `"none"` - no navigation visible at all
     */
    this.navigation = this._config.navigation;
    /**
     * The way of displaying days that don't belong to the current month.
     *
     * * `"visible"` - days are visible
     * * `"hidden"` - days are hidden, white space preserved
     * * `"collapsed"` - days are collapsed, so the datepicker height might change between months
     *
     * For the 2+ months view, days in between months are never shown.
     */
    this.outsideDays = this._config.outsideDays;
    /**
     * If `true`, week numbers will be displayed.
     */
    this.showWeekNumbers = this._config.showWeekNumbers;
    /**
     * The date to open calendar with.
     *
     * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
     * If nothing or invalid date is provided, calendar will open with current month.
     *
     * You could use `navigateTo(date)` method as an alternative.
     */
    this.startDate = this._config.startDate;
    /**
     * The way weekdays should be displayed.
     *
     * * `true` - weekdays are displayed using default width
     * * `false` - weekdays are not displayed
     * * `TranslationWidth` - weekdays are displayed using specified width
     *
     * @since 9.1.0
     */
    this.weekdays = this._config.weekdays;
    /**
     * An event emitted right before the navigation happens and displayed month changes.
     *
     * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info.
     */
    this.navigate = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when user selects a date using keyboard or mouse.
     *
     * The payload of the event is currently selected `NgbDate`.
     *
     * @since 5.2.0
     */
    this.dateSelect = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.onChange = _ => {};
    this.onTouched = () => {};
    const cd = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._service.dateSelect$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)()).subscribe(date => {
      this.dateSelect.emit(date);
    });
    this._service.model$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)()).subscribe(model => {
      const newDate = model.firstDate;
      const oldDate = this.model ? this.model.firstDate : null;
      // update public state
      this._publicState = {
        maxDate: model.maxDate,
        minDate: model.minDate,
        firstDate: model.firstDate,
        lastDate: model.lastDate,
        focusedDate: model.focusDate,
        months: model.months.map(viewModel => viewModel.firstDate)
      };
      let navigationPrevented = false;
      // emitting navigation event if the first month changes
      if (!newDate.equals(oldDate)) {
        this.navigate.emit({
          current: oldDate ? {
            year: oldDate.year,
            month: oldDate.month
          } : null,
          next: {
            year: newDate.year,
            month: newDate.month
          },
          preventDefault: () => navigationPrevented = true
        });
        // can't prevent the very first navigation
        if (navigationPrevented && oldDate !== null) {
          this._service.open(oldDate);
          return;
        }
      }
      const newSelectedDate = model.selectedDate;
      const newFocusedDate = model.focusDate;
      const oldFocusedDate = this.model ? this.model.focusDate : null;
      this.model = model;
      // handling selection change
      if (isChangedDate(newSelectedDate, this._controlValue)) {
        this._controlValue = newSelectedDate;
        this.onTouched();
        this.onChange(this._ngbDateAdapter.toModel(newSelectedDate));
      }
      // handling focus change
      if (isChangedDate(newFocusedDate, oldFocusedDate) && oldFocusedDate && model.focusVisible) {
        this.focus();
      }
      cd.markForCheck();
    });
  }
  /**
   *  Returns the readonly public state of the datepicker
   *
   * @since 5.2.0
   */
  get state() {
    return this._publicState;
  }
  /**
   *  Returns the calendar service used in the specific datepicker instance.
   *
   *  @since 5.3.0
   */
  get calendar() {
    return this._calendar;
  }
  /**
   * Returns the i18n service used in the specific datepicker instance.
   *
   * @since 14.2.0
   */
  get i18n() {
    return this._i18n;
  }
  /**
   *  Focuses on given date.
   */
  focusDate(date) {
    this._service.focus(NgbDate.from(date));
  }
  /**
   *  Selects focused date.
   */
  focusSelect() {
    this._service.focusSelect();
  }
  focus() {
    this._ngZone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => this._nativeElement.querySelector('div.ngb-dp-day[tabindex="0"]')?.focus());
  }
  /**
   * Navigates to the provided date.
   *
   * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
   * If nothing or invalid date provided calendar will open current month.
   *
   * Use the `[startDate]` input as an alternative.
   */
  navigateTo(date) {
    this._service.open(NgbDate.from(date ? date.day ? date : {
      ...date,
      day: 1
    } : null));
  }
  ngAfterViewInit() {
    this._ngZone.runOutsideAngular(() => {
      const focusIns$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(this._contentEl.nativeElement, 'focusin');
      const focusOuts$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(this._contentEl.nativeElement, 'focusout');
      // we're changing 'focusVisible' only when entering or leaving months view
      // and ignoring all focus events where both 'target' and 'related' target are day cells
      (0,rxjs__WEBPACK_IMPORTED_MODULE_22__.merge)(focusIns$, focusOuts$).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(focusEvent => {
        const target = focusEvent.target;
        const relatedTarget = focusEvent.relatedTarget;
        return !(target?.classList.contains('ngb-dp-day') && relatedTarget?.classList.contains('ngb-dp-day') && this._nativeElement.contains(target) && this._nativeElement.contains(relatedTarget));
      }), (0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(({
        type
      }) => this._ngZone.run(() => this._service.set({
        focusVisible: type === 'focusin'
      })));
    });
  }
  ngOnInit() {
    if (this.model === undefined) {
      const inputs = {};
      ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate', 'outsideDays', 'weekdays'].forEach(name => inputs[name] = this[name]);
      this._service.set(inputs);
      this.navigateTo(this.startDate);
    }
    if (!this.dayTemplate) {
      this.dayTemplate = this._defaultDayTemplate;
    }
  }
  ngOnChanges(changes) {
    const inputs = {};
    ['dayTemplateData', 'displayMonths', 'markDisabled', 'firstDayOfWeek', 'navigation', 'minDate', 'maxDate', 'outsideDays', 'weekdays'].filter(name => name in changes).forEach(name => inputs[name] = this[name]);
    this._service.set(inputs);
    if ('startDate' in changes) {
      const {
        currentValue,
        previousValue
      } = changes.startDate;
      if (isChangedMonth(previousValue, currentValue)) {
        this.navigateTo(this.startDate);
      }
    }
  }
  onDateSelect(date) {
    this._service.focus(date);
    this._service.select(date, {
      emitEvent: true
    });
  }
  onNavigateDateSelect(date) {
    this._service.open(date);
  }
  onNavigateEvent(event) {
    switch (event) {
      case NavigationEvent.PREV:
        this._service.open(this._calendar.getPrev(this.model.firstDate, 'm', 1));
        break;
      case NavigationEvent.NEXT:
        this._service.open(this._calendar.getNext(this.model.firstDate, 'm', 1));
        break;
    }
  }
  registerOnChange(fn) {
    this.onChange = fn;
  }
  registerOnTouched(fn) {
    this.onTouched = fn;
  }
  setDisabledState(disabled) {
    this._service.set({
      disabled
    });
  }
  writeValue(value) {
    this._controlValue = NgbDate.from(this._ngbDateAdapter.fromModel(value));
    this._service.select(this._controlValue);
  }
  static {
    this.ɵfac = function NgbDatepicker_Factory(t) {
      return new (t || NgbDatepicker)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbDatepicker,
      selectors: [["ngb-datepicker"]],
      contentQueries: function NgbDatepicker_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbDatepickerContent, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.contentTemplateFromContent = _t.first);
        }
      },
      viewQuery: function NgbDatepicker_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c4, 7);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c5, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._defaultDayTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._contentEl = _t.first);
        }
      },
      hostVars: 2,
      hostBindings: function NgbDatepicker_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx.model.disabled);
        }
      },
      inputs: {
        contentTemplate: "contentTemplate",
        dayTemplate: "dayTemplate",
        dayTemplateData: "dayTemplateData",
        displayMonths: "displayMonths",
        firstDayOfWeek: "firstDayOfWeek",
        footerTemplate: "footerTemplate",
        markDisabled: "markDisabled",
        maxDate: "maxDate",
        minDate: "minDate",
        navigation: "navigation",
        outsideDays: "outsideDays",
        showWeekNumbers: "showWeekNumbers",
        startDate: "startDate",
        weekdays: "weekdays"
      },
      outputs: {
        navigate: "navigate",
        dateSelect: "dateSelect"
      },
      exportAs: ["ngbDatepicker"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbDatepicker),
        multi: true
      }, NgbDatepickerService]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 10,
      vars: 9,
      consts: [["defaultDayTemplate", ""], ["defaultContentTemplate", ""], ["content", ""], [1, "ngb-dp-header"], [3, "date", "months", "disabled", "showSelect", "prevDisabled", "nextDisabled", "selectBoxes"], [1, "ngb-dp-content"], [3, "ngTemplateOutlet", "ngTemplateOutletContext", "ngTemplateOutletInjector"], [3, "ngTemplateOutlet"], ["ngbDatepickerDayView", "", 3, "date", "currentMonth", "selected", "disabled", "focused"], [1, "ngb-dp-month"], [1, "ngb-dp-month-name"], [3, "month"], [3, "navigate", "select", "date", "months", "disabled", "showSelect", "prevDisabled", "nextDisabled", "selectBoxes"]],
      template: function NgbDatepicker_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbDatepicker_ng_template_0_Template, 1, 5, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(2, NgbDatepicker_ng_template_2_Template, 2, 0, "ng-template", null, 1, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "div", 3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](5, NgbDatepicker_Conditional_5_Template, 1, 7, "ngb-datepicker-navigation", 4);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "div", 5, 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](8, NgbDatepicker_ng_template_8_Template, 0, 0, "ng-template", 6);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](9, NgbDatepicker_ng_template_9_Template, 0, 0, "ng-template", 7);
        }
        if (rf & 2) {
          const defaultContentTemplate_r9 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](5, ctx.navigation !== "none" ? 5 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ngb-dp-months", !ctx.contentTemplate);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx.contentTemplate || (ctx.contentTemplateFromContent == null ? null : ctx.contentTemplateFromContent.templateRef) || defaultContentTemplate_r9)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](7, _c6, ctx))("ngTemplateOutletInjector", ctx.injector);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx.footerTemplate);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet, NgbDatepickerDayView, NgbDatepickerMonth, NgbDatepickerNavigation],
      styles: ["ngb-datepicker{border:1px solid var(--bs-border-color);border-radius:.25rem;display:inline-block}ngb-datepicker-month{pointer-events:auto}ngb-datepicker.dropdown-menu{padding:0}ngb-datepicker.disabled .ngb-dp-weekday,ngb-datepicker.disabled .ngb-dp-week-number,ngb-datepicker.disabled .ngb-dp-month-name{color:var(--bs-text-muted)}.ngb-dp-body{z-index:1055}.ngb-dp-header{border-bottom:0;border-radius:.25rem .25rem 0 0;padding-top:.25rem;background-color:var(--bs-tertiary-bg)}.ngb-dp-months{display:flex}.ngb-dp-month{pointer-events:none}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center;background-color:var(--bs-tertiary-bg)}.ngb-dp-month+.ngb-dp-month .ngb-dp-month-name,.ngb-dp-month+.ngb-dp-month .ngb-dp-week{padding-left:1rem}.ngb-dp-month:last-child .ngb-dp-week{padding-right:.25rem}.ngb-dp-month:first-child .ngb-dp-week{padding-left:.25rem}.ngb-dp-month .ngb-dp-week:last-child{padding-bottom:.25rem}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepicker, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      exportAs: 'ngbDatepicker',
      selector: 'ngb-datepicker',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet, NgbDatepickerDayView, NgbDatepickerMonth, NgbDatepickerNavigation],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        '[class.disabled]': 'model.disabled'
      },
      template: `
		<ng-template
			#defaultDayTemplate
			let-date="date"
			let-currentMonth="currentMonth"
			let-selected="selected"
			let-disabled="disabled"
			let-focused="focused"
		>
			<div
				ngbDatepickerDayView
				[date]="date"
				[currentMonth]="currentMonth"
				[selected]="selected"
				[disabled]="disabled"
				[focused]="focused"
			>
			</div>
		</ng-template>

		<ng-template #defaultContentTemplate>
			@for (month of model.months; track month; let i = $index) {
				<div class="ngb-dp-month">
					@if (navigation === 'none' || (displayMonths > 1 && navigation === 'select')) {
						<div class="ngb-dp-month-name">
							{{ i18n.getMonthLabel(month.firstDate) }}
						</div>
					}
					<ngb-datepicker-month [month]="month.firstDate" />
				</div>
			}
		</ng-template>

		<div class="ngb-dp-header">
			@if (navigation !== 'none') {
				<ngb-datepicker-navigation
					[date]="model.firstDate!"
					[months]="model.months"
					[disabled]="model.disabled"
					[showSelect]="model.navigation === 'select'"
					[prevDisabled]="model.prevDisabled"
					[nextDisabled]="model.nextDisabled"
					[selectBoxes]="model.selectBoxes"
					(navigate)="onNavigateEvent($event)"
					(select)="onNavigateDateSelect($event)"
				/>
			}
		</div>

		<div class="ngb-dp-content" [class.ngb-dp-months]="!contentTemplate" #content>
			<ng-template
				[ngTemplateOutlet]="contentTemplate || contentTemplateFromContent?.templateRef || defaultContentTemplate"
				[ngTemplateOutletContext]="{ $implicit: this }"
				[ngTemplateOutletInjector]="injector"
			/>
		</div>

		<ng-template [ngTemplateOutlet]="footerTemplate" />
	`,
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbDatepicker),
        multi: true
      }, NgbDatepickerService],
      styles: ["ngb-datepicker{border:1px solid var(--bs-border-color);border-radius:.25rem;display:inline-block}ngb-datepicker-month{pointer-events:auto}ngb-datepicker.dropdown-menu{padding:0}ngb-datepicker.disabled .ngb-dp-weekday,ngb-datepicker.disabled .ngb-dp-week-number,ngb-datepicker.disabled .ngb-dp-month-name{color:var(--bs-text-muted)}.ngb-dp-body{z-index:1055}.ngb-dp-header{border-bottom:0;border-radius:.25rem .25rem 0 0;padding-top:.25rem;background-color:var(--bs-tertiary-bg)}.ngb-dp-months{display:flex}.ngb-dp-month{pointer-events:none}.ngb-dp-month-name{font-size:larger;height:2rem;line-height:2rem;text-align:center;background-color:var(--bs-tertiary-bg)}.ngb-dp-month+.ngb-dp-month .ngb-dp-month-name,.ngb-dp-month+.ngb-dp-month .ngb-dp-week{padding-left:1rem}.ngb-dp-month:last-child .ngb-dp-week{padding-right:.25rem}.ngb-dp-month:first-child .ngb-dp-week{padding-left:.25rem}.ngb-dp-month .ngb-dp-week:last-child{padding-bottom:.25rem}\n"]
    }]
  }], () => [], {
    _defaultDayTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['defaultDayTemplate', {
        static: true
      }]
    }],
    _contentEl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['content', {
        static: true
      }]
    }],
    contentTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    contentTemplateFromContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbDatepickerContent, {
        static: true
      }]
    }],
    dayTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dayTemplateData: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    displayMonths: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    firstDayOfWeek: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    footerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    markDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    maxDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    minDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    navigation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    outsideDays: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showWeekNumbers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    startDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    weekdays: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    navigate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dateSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
const isContainedIn = (element, array) => array ? array.some(item => item.contains(element)) : false;
const matchesSelectorIfAny = (element, selector) => !selector || closest(element, selector) != null;
// we have to add a more significant delay to avoid re-opening when handling (click) on a toggling element
// TODO: use proper Angular platform detection when NgbAutoClose becomes a service and we can inject PLATFORM_ID
const isMobile = (() => {
  const isIOS = () => /iPad|iPhone|iPod/.test(navigator.userAgent) || /Macintosh/.test(navigator.userAgent) && navigator.maxTouchPoints && navigator.maxTouchPoints > 2;
  const isAndroid = () => /Android/.test(navigator.userAgent);
  return typeof navigator !== 'undefined' ? !!navigator.userAgent && (isIOS() || isAndroid()) : false;
})();
// setting 'ngbAutoClose' synchronously on mobile results in immediate popup closing
// when tapping on the triggering element
const wrapAsyncForMobile = fn => isMobile ? () => setTimeout(() => fn(), 100) : fn;
function ngbAutoClose(zone, document, type, close, closed$, insideElements, ignoreElements, insideSelector) {
  // closing on ESC and outside clicks
  if (type) {
    zone.runOutsideAngular(wrapAsyncForMobile(() => {
      const shouldCloseOnClick = event => {
        const element = event.target;
        if (event.button === 2 || isContainedIn(element, ignoreElements)) {
          return false;
        }
        if (type === 'inside') {
          return isContainedIn(element, insideElements) && matchesSelectorIfAny(element, insideSelector);
        } else if (type === 'outside') {
          return !isContainedIn(element, insideElements);
        } /* if (type === true) */else {
          return matchesSelectorIfAny(element, insideSelector) || !isContainedIn(element, insideElements);
        }
      };
      const escapes$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(document, 'keydown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(closed$), /* eslint-disable-next-line deprecation/deprecation */
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(e => e.which === Key.Escape), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.tap)(e => e.preventDefault()));
      // we have to pre-calculate 'shouldCloseOnClick' on 'mousedown',
      // because on 'mouseup' DOM nodes might be detached
      const mouseDowns$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(document, 'mousedown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(shouldCloseOnClick), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(closed$));
      const closeableClicks$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(document, 'mouseup').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.withLatestFrom)(mouseDowns$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(([_, shouldClose]) => shouldClose), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_26__.delay)(0), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(closed$));
      (0,rxjs__WEBPACK_IMPORTED_MODULE_10__.race)([escapes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(_ => 0 /* SOURCE.ESCAPE */)), closeableClicks$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(_ => 1 /* SOURCE.CLICK */))]).subscribe(source => zone.run(() => close(source)));
    }));
  }
}
const FOCUSABLE_ELEMENTS_SELECTOR = ['a[href]', 'button:not([disabled])', 'input:not([disabled]):not([type="hidden"])', 'select:not([disabled])', 'textarea:not([disabled])', '[contenteditable]', '[tabindex]:not([tabindex="-1"])'].join(', ');
/**
 * Returns first and last focusable elements inside of a given element based on specific CSS selector
 */
function getFocusableBoundaryElements(element) {
  const list = Array.from(element.querySelectorAll(FOCUSABLE_ELEMENTS_SELECTOR)).filter(el => el.tabIndex !== -1);
  return [list[0], list[list.length - 1]];
}
/**
 * Function that enforces browser focus to be trapped inside a DOM element.
 *
 * Works only for clicks inside the element and navigation with 'Tab', ignoring clicks outside of the element
 *
 * @param zone Angular zone
 * @param element The element around which focus will be trapped inside
 * @param stopFocusTrap$ The observable stream. When completed the focus trap will clean up listeners
 * and free internal resources
 * @param refocusOnClick Put the focus back to the last focused element whenever a click occurs on element (default to
 * false)
 */
const ngbFocusTrap = (zone, element, stopFocusTrap$, refocusOnClick = false) => {
  zone.runOutsideAngular(() => {
    // last focused element
    const lastFocusedElement$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(element, 'focusin').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stopFocusTrap$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(e => e.target));
    // 'tab' / 'shift+tab' stream
    (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(element, 'keydown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stopFocusTrap$), /* eslint-disable-next-line deprecation/deprecation */
    (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(e => e.which === Key.Tab), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.withLatestFrom)(lastFocusedElement$)).subscribe(([tabEvent, focusedElement]) => {
      const [first, last] = getFocusableBoundaryElements(element);
      if ((focusedElement === first || focusedElement === element) && tabEvent.shiftKey) {
        last.focus();
        tabEvent.preventDefault();
      }
      if (focusedElement === last && !tabEvent.shiftKey) {
        first.focus();
        tabEvent.preventDefault();
      }
    });
    // inside click
    if (refocusOnClick) {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(element, 'click').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(stopFocusTrap$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_25__.withLatestFrom)(lastFocusedElement$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)(arr => arr[1])).subscribe(lastFocusedElement => lastFocusedElement.focus());
    }
  });
};
class NgbRTL {
  constructor() {
    this._element = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT).documentElement;
  }
  isRTL() {
    return (this._element.getAttribute('dir') || '').toLowerCase() === 'rtl';
  }
  static {
    this.ɵfac = function NgbRTL_Factory(t) {
      return new (t || NgbRTL)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbRTL,
      factory: NgbRTL.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbRTL, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const placementSeparator = /\s+/;
const spacesRegExp = /  +/gi;
/**
 * Matching classes from the Bootstrap ones to the poppers ones.
 * The first index of each array is used for the left to right direction,
 * the second one is used for the right to left, defaulting to the first index (when LTR and RTL lead to the same class)
 *
 * See [Bootstrap alignments](https://getbootstrap.com/docs/5.1/components/dropdowns/#alignment-options)
 * and [Popper placements](https://popper.js.org/docs/v2/constructors/#options)
 */
const bootstrapPopperMatches = {
  top: ['top'],
  bottom: ['bottom'],
  start: ['left', 'right'],
  left: ['left'],
  end: ['right', 'left'],
  right: ['right'],
  'top-start': ['top-start', 'top-end'],
  'top-left': ['top-start'],
  'top-end': ['top-end', 'top-start'],
  'top-right': ['top-end'],
  'bottom-start': ['bottom-start', 'bottom-end'],
  'bottom-left': ['bottom-start'],
  'bottom-end': ['bottom-end', 'bottom-start'],
  'bottom-right': ['bottom-end'],
  'start-top': ['left-start', 'right-start'],
  'left-top': ['left-start'],
  'start-bottom': ['left-end', 'right-end'],
  'left-bottom': ['left-end'],
  'end-top': ['right-start', 'left-start'],
  'right-top': ['right-start'],
  'end-bottom': ['right-end', 'left-end'],
  'right-bottom': ['right-end']
};
function getPopperClassPlacement(placement, isRTL) {
  const [leftClass, rightClass] = bootstrapPopperMatches[placement];
  return isRTL ? rightClass || leftClass : leftClass;
}
const popperStartPrimaryPlacement = /^left/;
const popperEndPrimaryPlacement = /^right/;
const popperStartSecondaryPlacement = /^start/;
const popperEndSecondaryPlacement = /^end/;
function getBootstrapBaseClassPlacement(baseClass, placement) {
  let [primary, secondary] = placement.split('-');
  const newPrimary = primary.replace(popperStartPrimaryPlacement, 'start').replace(popperEndPrimaryPlacement, 'end');
  let classnames = [newPrimary];
  if (secondary) {
    let newSecondary = secondary;
    if (primary === 'left' || primary === 'right') {
      newSecondary = newSecondary.replace(popperStartSecondaryPlacement, 'top').replace(popperEndSecondaryPlacement, 'bottom');
    }
    classnames.push(`${newPrimary}-${newSecondary}`);
  }
  if (baseClass) {
    classnames = classnames.map(classname => `${baseClass}-${classname}`);
  }
  return classnames.join(' ');
}
/*
 * Accept the placement array and applies the appropriate placement dependent on the viewport.
 * Returns the applied placement.
 * In case of auto placement, placements are selected in order
 *   'top', 'bottom', 'start', 'end',
 *   'top-start', 'top-end',
 *   'bottom-start', 'bottom-end',
 *   'start-top', 'start-bottom',
 *   'end-top', 'end-bottom'.
 * */
function getPopperOptions({
  placement,
  baseClass
}, rtl) {
  let placementVals = Array.isArray(placement) ? placement : placement.split(placementSeparator);
  // No need to consider left and right here, as start and end are enough, and it is used for 'auto' placement only
  const allowedPlacements = ['top', 'bottom', 'start', 'end', 'top-start', 'top-end', 'bottom-start', 'bottom-end', 'start-top', 'start-bottom', 'end-top', 'end-bottom'];
  // replace auto placement with other placements
  let hasAuto = placementVals.findIndex(val => val === 'auto');
  if (hasAuto >= 0) {
    allowedPlacements.forEach(function (obj) {
      if (placementVals.find(val => val.search('^' + obj) !== -1) == null) {
        placementVals.splice(hasAuto++, 1, obj);
      }
    });
  }
  const popperPlacements = placementVals.map(_placement => {
    return getPopperClassPlacement(_placement, rtl.isRTL());
  });
  let mainPlacement = popperPlacements.shift();
  const bsModifier = {
    name: 'bootstrapClasses',
    enabled: !!baseClass,
    phase: 'write',
    fn({
      state
    }) {
      const bsClassRegExp = new RegExp(baseClass + '(-[a-z]+)*', 'gi');
      const popperElement = state.elements.popper;
      const popperPlacement = state.placement;
      let className = popperElement.className;
      // Remove old bootstrap classes
      className = className.replace(bsClassRegExp, '');
      // Add current placements
      className += ` ${getBootstrapBaseClassPlacement(baseClass, popperPlacement)}`;
      // Remove multiple spaces
      className = className.trim().replace(spacesRegExp, ' ');
      // Reassign
      popperElement.className = className;
    }
  };
  return {
    placement: mainPlacement,
    modifiers: [bsModifier, _popperjs_core__WEBPACK_IMPORTED_MODULE_27__["default"], _popperjs_core__WEBPACK_IMPORTED_MODULE_28__["default"], _popperjs_core__WEBPACK_IMPORTED_MODULE_29__["default"], {
      enabled: true,
      name: 'flip',
      options: {
        fallbackPlacements: popperPlacements
      }
    }, {
      enabled: true,
      name: 'preventOverflow',
      phase: 'main',
      fn: function () {}
    }]
  };
}
function noop(arg) {
  return arg;
}
function ngbPositioning() {
  const rtl = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbRTL);
  let popperInstance = null;
  return {
    createPopper(positioningOption) {
      if (!popperInstance) {
        const updatePopperOptions = positioningOption.updatePopperOptions || noop;
        let popperOptions = updatePopperOptions(getPopperOptions(positioningOption, rtl));
        popperInstance = (0,_popperjs_core__WEBPACK_IMPORTED_MODULE_30__.createPopper)(positioningOption.hostElement, positioningOption.targetElement, popperOptions);
      }
    },
    update() {
      if (popperInstance) {
        popperInstance.update();
      }
    },
    setOptions(positioningOption) {
      if (popperInstance) {
        const updatePopperOptions = positioningOption.updatePopperOptions || noop;
        let popperOptions = updatePopperOptions(getPopperOptions(positioningOption, rtl));
        popperInstance.setOptions(popperOptions);
      }
    },
    destroy() {
      if (popperInstance) {
        popperInstance.destroy();
        popperInstance = null;
      }
    }
  };
}
function NGB_DATEPICKER_PARSER_FORMATTER_FACTORY() {
  return new NgbDateISOParserFormatter();
}
/**
 * An abstract service for parsing and formatting dates for the
 * [`NgbInputDatepicker`](#/components/datepicker/api#NgbInputDatepicker) directive.
 * Converts between the internal `NgbDateStruct` model presentation and a `string` that is displayed in the
 * input element.
 *
 * When user types something in the input this service attempts to parse it into a `NgbDateStruct` object.
 * And vice versa, when users selects a date in the calendar with the mouse, it must be displayed as a `string`
 * in the input.
 *
 * Default implementation uses the ISO 8601 format, but you can provide another implementation via DI
 * to use an alternative string format or a custom parsing logic.
 *
 * See the [date format overview](#/components/datepicker/overview#date-model) for more details.
 */
class NgbDateParserFormatter {
  static {
    this.ɵfac = function NgbDateParserFormatter_Factory(t) {
      return new (t || NgbDateParserFormatter)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateParserFormatter,
      factory: () => NGB_DATEPICKER_PARSER_FORMATTER_FACTORY(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateParserFormatter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: NGB_DATEPICKER_PARSER_FORMATTER_FACTORY
    }]
  }], null, null);
})();
class NgbDateISOParserFormatter extends NgbDateParserFormatter {
  parse(value) {
    if (value != null) {
      const dateParts = value.trim().split('-');
      if (dateParts.length === 1 && isNumber(dateParts[0])) {
        return {
          year: toInteger(dateParts[0]),
          month: null,
          day: null
        };
      } else if (dateParts.length === 2 && isNumber(dateParts[0]) && isNumber(dateParts[1])) {
        return {
          year: toInteger(dateParts[0]),
          month: toInteger(dateParts[1]),
          day: null
        };
      } else if (dateParts.length === 3 && isNumber(dateParts[0]) && isNumber(dateParts[1]) && isNumber(dateParts[2])) {
        return {
          year: toInteger(dateParts[0]),
          month: toInteger(dateParts[1]),
          day: toInteger(dateParts[2])
        };
      }
    }
    return null;
  }
  format(date) {
    return date ? `${date.year}-${isNumber(date.month) ? padNumber(date.month) : ''}-${isNumber(date.day) ? padNumber(date.day) : ''}` : '';
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDateISOParserFormatter_BaseFactory;
      return function NgbDateISOParserFormatter_Factory(t) {
        return (ɵNgbDateISOParserFormatter_BaseFactory || (ɵNgbDateISOParserFormatter_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDateISOParserFormatter)))(t || NgbDateISOParserFormatter);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateISOParserFormatter,
      factory: NgbDateISOParserFormatter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateISOParserFormatter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * A configuration service for the [`NgbDatepickerInput`](#/components/datepicker/api#NgbDatepicker) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the datepicker inputs used in the application.
 *
 * @since 5.2.0
 */
class NgbInputDatepickerConfig extends NgbDatepickerConfig {
  constructor() {
    super(...arguments);
    this.autoClose = true;
    this.placement = ['bottom-start', 'bottom-end', 'top-start', 'top-end'];
    this.popperOptions = options => options;
    this.restoreFocus = true;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbInputDatepickerConfig_BaseFactory;
      return function NgbInputDatepickerConfig_Factory(t) {
        return (ɵNgbInputDatepickerConfig_BaseFactory || (ɵNgbInputDatepickerConfig_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbInputDatepickerConfig)))(t || NgbInputDatepickerConfig);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbInputDatepickerConfig,
      factory: NgbInputDatepickerConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbInputDatepickerConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function addPopperOffset(offset$1) {
  return options => {
    options.modifiers.push(_popperjs_core__WEBPACK_IMPORTED_MODULE_31__["default"], {
      name: 'offset',
      options: {
        offset: () => offset$1
      }
    });
    return options;
  };
}

/**
 * A directive that allows to stick a datepicker popup to an input field.
 *
 * Manages interaction with the input field itself, does value formatting and provides forms integration.
 */
class NgbInputDatepicker {
  constructor() {
    this._parserFormatter = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDateParserFormatter);
    this._elRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._vcRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._calendar = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbCalendar);
    this._dateAdapter = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDateAdapter);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbInputDatepickerConfig);
    this._cRef = null;
    this._disabled = false;
    this._elWithFocus = null;
    this._model = null;
    this._positioning = ngbPositioning();
    this._destroyCloseHandlers$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    /**
     * Indicates whether the datepicker popup should be closed automatically after date selection / outside click or not.
     *
     * * `true` - the popup will close on both date selection and outside click.
     * * `false` - the popup can only be closed manually via `close()` or `toggle()` methods.
     * * `"inside"` - the popup will close on date selection, but not outside clicks.
     * * `"outside"` - the popup will close only on the outside click and not on date selection/inside clicks.
     *
     * @since 3.0.0
     */
    this.autoClose = this._config.autoClose;
    /**
     * The preferred placement of the datepicker popup, among the [possible values](#/guides/positioning#api).
     *
     * The default order of preference is `"bottom-start bottom-end top-start top-end"`
     *
     * Please see the [positioning overview](#/positioning) for more details.
     */
    this.placement = this._config.placement;
    /**
     * Allows to change default Popper options when positioning the popup.
     * Receives current popper options and returns modified ones.
     *
     * @since 13.1.0
     */
    this.popperOptions = this._config.popperOptions;
    /**
     * A selector specifying the element the datepicker popup should be appended to.
     *
     * Currently only supports `"body"`.
     */
    this.container = this._config.container;
    /**
     * A css selector or html element specifying the element the datepicker popup should be positioned against.
     *
     * By default the input is used as a target.
     *
     * @since 4.2.0
     */
    this.positionTarget = this._config.positionTarget;
    /**
     * An event emitted when user selects a date using keyboard or mouse.
     *
     * The payload of the event is currently selected `NgbDate`.
     *
     * @since 1.1.1
     */
    this.dateSelect = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * Event emitted right after the navigation happens and displayed month changes.
     *
     * See [`NgbDatepickerNavigateEvent`](#/components/datepicker/api#NgbDatepickerNavigateEvent) for the payload info.
     */
    this.navigate = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event fired after closing datepicker window.
     *
     * @since 4.2.0
     */
    this.closed = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._onChange = _ => {};
    this._onTouched = () => {};
    this._validatorChange = () => {};
  }
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    this._disabled = value === '' || value && value !== 'false';
    if (this.isOpen()) {
      this._cRef.instance.setDisabledState(this._disabled);
    }
  }
  registerOnChange(fn) {
    this._onChange = fn;
  }
  registerOnTouched(fn) {
    this._onTouched = fn;
  }
  registerOnValidatorChange(fn) {
    this._validatorChange = fn;
  }
  setDisabledState(isDisabled) {
    this.disabled = isDisabled;
  }
  validate(c) {
    const {
      value
    } = c;
    if (value != null) {
      const ngbDate = this._fromDateStruct(this._dateAdapter.fromModel(value));
      if (!ngbDate) {
        return {
          ngbDate: {
            invalid: value
          }
        };
      }
      if (this.minDate && ngbDate.before(NgbDate.from(this.minDate))) {
        return {
          ngbDate: {
            minDate: {
              minDate: this.minDate,
              actual: value
            }
          }
        };
      }
      if (this.maxDate && ngbDate.after(NgbDate.from(this.maxDate))) {
        return {
          ngbDate: {
            maxDate: {
              maxDate: this.maxDate,
              actual: value
            }
          }
        };
      }
    }
    return null;
  }
  writeValue(value) {
    this._model = this._fromDateStruct(this._dateAdapter.fromModel(value));
    this._writeModelValue(this._model);
  }
  manualDateChange(value, updateView = false) {
    const inputValueChanged = value !== this._inputValue;
    if (inputValueChanged) {
      this._inputValue = value;
      this._model = this._fromDateStruct(this._parserFormatter.parse(value));
    }
    if (inputValueChanged || !updateView) {
      this._onChange(this._model ? this._dateAdapter.toModel(this._model) : value === '' ? null : value);
    }
    if (updateView && this._model) {
      this._writeModelValue(this._model);
    }
  }
  isOpen() {
    return !!this._cRef;
  }
  /**
   * Opens the datepicker popup.
   *
   * If the related form control contains a valid date, the corresponding month will be opened.
   */
  open() {
    if (!this.isOpen()) {
      this._cRef = this._vcRef.createComponent(NgbDatepicker);
      this._applyPopupStyling(this._cRef.location.nativeElement);
      this._applyDatepickerInputs(this._cRef);
      this._subscribeForDatepickerOutputs(this._cRef.instance);
      this._cRef.instance.ngOnInit();
      this._cRef.instance.writeValue(this._dateAdapter.toModel(this._model));
      // date selection event handling
      this._cRef.instance.registerOnChange(selectedDate => {
        this.writeValue(selectedDate);
        this._onChange(selectedDate);
        this._onTouched();
      });
      this._cRef.changeDetectorRef.detectChanges();
      this._cRef.instance.setDisabledState(this.disabled);
      if (this.container === 'body') {
        this._document.querySelector(this.container)?.appendChild(this._cRef.location.nativeElement);
      }
      // focus handling
      this._elWithFocus = this._document.activeElement;
      ngbFocusTrap(this._ngZone, this._cRef.location.nativeElement, this.closed, true);
      setTimeout(() => this._cRef?.instance.focus());
      let hostElement;
      if (isString(this.positionTarget)) {
        hostElement = this._document.querySelector(this.positionTarget);
      } else if (this.positionTarget instanceof HTMLElement) {
        hostElement = this.positionTarget;
      } else {
        hostElement = this._elRef.nativeElement;
      }
      if (this.positionTarget && !hostElement) {
        throw new Error('ngbDatepicker could not find element declared in [positionTarget] to position against.');
      }
      // Setting up popper and scheduling updates when zone is stable
      this._ngZone.runOutsideAngular(() => {
        if (this._cRef && hostElement) {
          this._positioning.createPopper({
            hostElement,
            targetElement: this._cRef.location.nativeElement,
            placement: this.placement,
            appendToBody: this.container === 'body',
            updatePopperOptions: options => this.popperOptions(addPopperOffset([0, 2])(options))
          });
          this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positioning.update());
        }
      });
      this._setCloseHandlers();
    }
  }
  /**
   * Closes the datepicker popup.
   */
  close() {
    if (this.isOpen()) {
      this._vcRef.remove(this._vcRef.indexOf(this._cRef.hostView));
      this._cRef = null;
      this._positioning.destroy();
      this._zoneSubscription?.unsubscribe();
      this._destroyCloseHandlers$.next();
      this.closed.emit();
      this._changeDetector.markForCheck();
      // restore focus
      let elementToFocus = this._elWithFocus;
      if (isString(this.restoreFocus)) {
        elementToFocus = this._document.querySelector(this.restoreFocus);
      } else if (this.restoreFocus !== undefined) {
        elementToFocus = this.restoreFocus;
      }
      // in IE document.activeElement can contain an object without 'focus()' sometimes
      if (elementToFocus && elementToFocus['focus']) {
        elementToFocus.focus();
      } else {
        this._document.body.focus();
      }
    }
  }
  /**
   * Toggles the datepicker popup.
   */
  toggle() {
    if (this.isOpen()) {
      this.close();
    } else {
      this.open();
    }
  }
  /**
   * Navigates to the provided date.
   *
   * With the default calendar we use ISO 8601: 'month' is 1=Jan ... 12=Dec.
   * If nothing or invalid date provided calendar will open current month.
   *
   * Use the `[startDate]` input as an alternative.
   */
  navigateTo(date) {
    if (this.isOpen()) {
      this._cRef.instance.navigateTo(date);
    }
  }
  onBlur() {
    this._onTouched();
  }
  onFocus() {
    this._elWithFocus = this._elRef.nativeElement;
  }
  ngOnChanges(changes) {
    if (changes['minDate'] || changes['maxDate']) {
      this._validatorChange();
      if (this.isOpen()) {
        if (changes['minDate']) {
          this._cRef.setInput('minDate', this.minDate);
        }
        if (changes['maxDate']) {
          this._cRef.setInput('maxDate', this.maxDate);
        }
      }
    }
    if (changes['datepickerClass']) {
      const {
        currentValue,
        previousValue
      } = changes['datepickerClass'];
      this._applyPopupClass(currentValue, previousValue);
    }
    if (changes['autoClose'] && this.isOpen()) {
      this._setCloseHandlers();
    }
  }
  ngOnDestroy() {
    this.close();
  }
  _applyDatepickerInputs(datepickerComponentRef) {
    ['contentTemplate', 'dayTemplate', 'dayTemplateData', 'displayMonths', 'firstDayOfWeek', 'footerTemplate', 'markDisabled', 'minDate', 'maxDate', 'navigation', 'outsideDays', 'showNavigation', 'showWeekNumbers', 'weekdays'].forEach(inputName => {
      if (this[inputName] !== undefined) {
        datepickerComponentRef.setInput(inputName, this[inputName]);
      }
    });
    datepickerComponentRef.setInput('startDate', this.startDate || this._model);
  }
  _applyPopupClass(newClass, oldClass) {
    const popupEl = this._cRef?.location.nativeElement;
    if (popupEl) {
      if (newClass) {
        popupEl.classList.add(newClass);
      }
      if (oldClass) {
        popupEl.classList.remove(oldClass);
      }
    }
  }
  _applyPopupStyling(nativeElement) {
    nativeElement.classList.add('dropdown-menu', 'show');
    if (this.container === 'body') {
      nativeElement.classList.add('ngb-dp-body');
    }
    this._applyPopupClass(this.datepickerClass);
  }
  _subscribeForDatepickerOutputs(datepickerInstance) {
    datepickerInstance.navigate.subscribe(navigateEvent => this.navigate.emit(navigateEvent));
    datepickerInstance.dateSelect.subscribe(date => {
      this.dateSelect.emit(date);
      if (this.autoClose === true || this.autoClose === 'inside') {
        this.close();
      }
    });
  }
  _writeModelValue(model) {
    const value = this._parserFormatter.format(model);
    this._inputValue = value;
    this._elRef.nativeElement.value = value;
    if (this.isOpen()) {
      this._cRef.instance.writeValue(this._dateAdapter.toModel(model));
      this._onTouched();
    }
  }
  _fromDateStruct(date) {
    const ngbDate = date ? new NgbDate(date.year, date.month, date.day) : null;
    return this._calendar.isValid(ngbDate) ? ngbDate : null;
  }
  _setCloseHandlers() {
    this._destroyCloseHandlers$.next();
    ngbAutoClose(this._ngZone, this._document, this.autoClose, () => this.close(), this._destroyCloseHandlers$, [], [this._elRef.nativeElement, this._cRef.location.nativeElement]);
  }
  static {
    this.ɵfac = function NgbInputDatepicker_Factory(t) {
      return new (t || NgbInputDatepicker)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbInputDatepicker,
      selectors: [["input", "ngbDatepicker", ""]],
      hostVars: 1,
      hostBindings: function NgbInputDatepicker_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function NgbInputDatepicker_input_HostBindingHandler($event) {
            return ctx.manualDateChange($event.target.value);
          })("change", function NgbInputDatepicker_change_HostBindingHandler($event) {
            return ctx.manualDateChange($event.target.value, true);
          })("focus", function NgbInputDatepicker_focus_HostBindingHandler() {
            return ctx.onFocus();
          })("blur", function NgbInputDatepicker_blur_HostBindingHandler() {
            return ctx.onBlur();
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("disabled", ctx.disabled);
        }
      },
      inputs: {
        autoClose: "autoClose",
        contentTemplate: "contentTemplate",
        datepickerClass: "datepickerClass",
        dayTemplate: "dayTemplate",
        dayTemplateData: "dayTemplateData",
        displayMonths: "displayMonths",
        firstDayOfWeek: "firstDayOfWeek",
        footerTemplate: "footerTemplate",
        markDisabled: "markDisabled",
        minDate: "minDate",
        maxDate: "maxDate",
        navigation: "navigation",
        outsideDays: "outsideDays",
        placement: "placement",
        popperOptions: "popperOptions",
        restoreFocus: "restoreFocus",
        showWeekNumbers: "showWeekNumbers",
        startDate: "startDate",
        container: "container",
        positionTarget: "positionTarget",
        weekdays: "weekdays",
        disabled: "disabled"
      },
      outputs: {
        dateSelect: "dateSelect",
        navigate: "navigate",
        closed: "closed"
      },
      exportAs: ["ngbDatepicker"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbInputDatepicker),
        multi: true
      }, {
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALIDATORS,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbInputDatepicker),
        multi: true
      }, {
        provide: NgbDatepickerConfig,
        useExisting: NgbInputDatepickerConfig
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbInputDatepicker, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[ngbDatepicker]',
      exportAs: 'ngbDatepicker',
      standalone: true,
      host: {
        '(input)': 'manualDateChange($event.target.value)',
        '(change)': 'manualDateChange($event.target.value, true)',
        '(focus)': 'onFocus()',
        '(blur)': 'onBlur()',
        '[disabled]': 'disabled'
      },
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbInputDatepicker),
        multi: true
      }, {
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALIDATORS,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbInputDatepicker),
        multi: true
      }, {
        provide: NgbDatepickerConfig,
        useExisting: NgbInputDatepickerConfig
      }]
    }]
  }], null, {
    autoClose: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    contentTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    datepickerClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dayTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dayTemplateData: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    displayMonths: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    firstDayOfWeek: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    footerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    markDisabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    minDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    maxDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    navigation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    outsideDays: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    placement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popperOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    restoreFocus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showWeekNumbers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    startDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    positionTarget: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    weekdays: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dateSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    navigate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    closed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class NgbCalendarHijri extends NgbCalendar {
  getDaysPerWeek() {
    return 7;
  }
  getMonths() {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  }
  getWeeksPerMonth() {
    return 6;
  }
  getNext(date, period = 'd', number = 1) {
    date = new NgbDate(date.year, date.month, date.day);
    switch (period) {
      case 'y':
        date = this._setYear(date, date.year + number);
        date.month = 1;
        date.day = 1;
        return date;
      case 'm':
        date = this._setMonth(date, date.month + number);
        date.day = 1;
        return date;
      case 'd':
        return this._setDay(date, date.day + number);
      default:
        return date;
    }
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    const day = this.toGregorian(date).getDay();
    // in JS Date Sun=0, in ISO 8601 Sun=7
    return day === 0 ? 7 : day;
  }
  getWeekNumber(week, firstDayOfWeek) {
    // in JS Date Sun=0, in ISO 8601 Sun=7
    if (firstDayOfWeek === 7) {
      firstDayOfWeek = 0;
    }
    const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
    const date = week[thursdayIndex];
    const jsDate = this.toGregorian(date);
    jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
    const time = jsDate.getTime();
    const MuhDate = this.toGregorian(new NgbDate(date.year, 1, 1)); // Compare with Muharram 1
    return Math.floor(Math.round((time - MuhDate.getTime()) / 86400000) / 7) + 1;
  }
  getToday() {
    return this.fromGregorian(new Date());
  }
  isValid(date) {
    return date != null && isNumber(date.year) && isNumber(date.month) && isNumber(date.day) && !isNaN(this.toGregorian(date).getTime());
  }
  _setDay(date, day) {
    day = +day;
    let mDays = this.getDaysPerMonth(date.month, date.year);
    if (day <= 0) {
      while (day <= 0) {
        date = this._setMonth(date, date.month - 1);
        mDays = this.getDaysPerMonth(date.month, date.year);
        day += mDays;
      }
    } else if (day > mDays) {
      while (day > mDays) {
        day -= mDays;
        date = this._setMonth(date, date.month + 1);
        mDays = this.getDaysPerMonth(date.month, date.year);
      }
    }
    date.day = day;
    return date;
  }
  _setMonth(date, month) {
    month = +month;
    date.year = date.year + Math.floor((month - 1) / 12);
    date.month = Math.floor(((month - 1) % 12 + 12) % 12) + 1;
    return date;
  }
  _setYear(date, year) {
    date.year = +year;
    return date;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarHijri_BaseFactory;
      return function NgbCalendarHijri_Factory(t) {
        return (ɵNgbCalendarHijri_BaseFactory || (ɵNgbCalendarHijri_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarHijri)))(t || NgbCalendarHijri);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarHijri,
      factory: NgbCalendarHijri.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarHijri, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Checks if islamic year is a leap year
 */
function isIslamicLeapYear(hYear) {
  return (14 + 11 * hYear) % 30 < 11;
}
/**
 * Checks if gregorian years is a leap year
 */
function isGregorianLeapYear$1(gDate) {
  const year = gDate.getFullYear();
  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
/**
 * Returns the start of Hijri Month.
 * `hMonth` is 0 for Muharram, 1 for Safar, etc.
 * `hYear` is any Hijri hYear.
 */
function getIslamicMonthStart(hYear, hMonth) {
  return Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30.0);
}
/**
 * Returns the start of Hijri year.
 * `year` is any Hijri year.
 */
function getIslamicYearStart(year) {
  return (year - 1) * 354 + Math.floor((3 + 11 * year) / 30.0);
}
function mod$1(a, b) {
  return a - b * Math.floor(a / b);
}
/**
 * The civil calendar is one type of Hijri calendars used in islamic countries.
 * Uses a fixed cycle of alternating 29- and 30-day months,
 * with a leap day added to the last month of 11 out of every 30 years.
 * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types
 * All the calculations here are based on the equations from "Calendrical Calculations" By Edward M. Reingold, Nachum
 * Dershowitz.
 */
const GREGORIAN_EPOCH$1 = 1721425.5;
const ISLAMIC_EPOCH = 1948439.5;
class NgbCalendarIslamicCivil extends NgbCalendarHijri {
  /**
   * Returns the equivalent islamic(civil) date value for a give input Gregorian date.
   * `gDate` is a JS Date to be converted to Hijri.
   */
  fromGregorian(gDate) {
    const gYear = gDate.getFullYear(),
      gMonth = gDate.getMonth(),
      gDay = gDate.getDate();
    let julianDay = GREGORIAN_EPOCH$1 - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) + -Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) + Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear$1(gDate) ? -1 : -2) + gDay);
    julianDay = Math.floor(julianDay) + 0.5;
    const days = julianDay - ISLAMIC_EPOCH;
    const hYear = Math.floor((30 * days + 10646) / 10631.0);
    let hMonth = Math.ceil((days - 29 - getIslamicYearStart(hYear)) / 29.5);
    hMonth = Math.min(hMonth, 11);
    const hDay = Math.ceil(days - getIslamicMonthStart(hYear, hMonth)) + 1;
    return new NgbDate(hYear, hMonth + 1, hDay);
  }
  /**
   * Returns the equivalent JS date value for a give input islamic(civil) date.
   * `hDate` is an islamic(civil) date to be converted to Gregorian.
   */
  toGregorian(hDate) {
    const hYear = hDate.year;
    const hMonth = hDate.month - 1;
    const hDay = hDate.day;
    const julianDay = hDay + Math.ceil(29.5 * hMonth) + (hYear - 1) * 354 + Math.floor((3 + 11 * hYear) / 30) + ISLAMIC_EPOCH - 1;
    const wjd = Math.floor(julianDay - 0.5) + 0.5,
      depoch = wjd - GREGORIAN_EPOCH$1,
      quadricent = Math.floor(depoch / 146097),
      dqc = mod$1(depoch, 146097),
      cent = Math.floor(dqc / 36524),
      dcent = mod$1(dqc, 36524),
      quad = Math.floor(dcent / 1461),
      dquad = mod$1(dcent, 1461),
      yindex = Math.floor(dquad / 365);
    let year = quadricent * 400 + cent * 100 + quad * 4 + yindex;
    if (!(cent === 4 || yindex === 4)) {
      year++;
    }
    const gYearStart = GREGORIAN_EPOCH$1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400);
    const yearday = wjd - gYearStart;
    const tjd = GREGORIAN_EPOCH$1 - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor(739 / 12 + (isGregorianLeapYear$1(new Date(year, 3, 1)) ? -1 : -2) + 1);
    const leapadj = wjd < tjd ? 0 : isGregorianLeapYear$1(new Date(year, 3, 1)) ? 1 : 2;
    const month = Math.floor(((yearday + leapadj) * 12 + 373) / 367);
    const tjd2 = GREGORIAN_EPOCH$1 - 1 + 365 * (year - 1) + Math.floor((year - 1) / 4) - Math.floor((year - 1) / 100) + Math.floor((year - 1) / 400) + Math.floor((367 * month - 362) / 12 + (month <= 2 ? 0 : isGregorianLeapYear$1(new Date(year, month - 1, 1)) ? -1 : -2) + 1);
    const day = wjd - tjd2 + 1;
    return new Date(year, month - 1, day);
  }
  /**
   * Returns the number of days in a specific Hijri month.
   * `month` is 1 for Muharram, 2 for Safar, etc.
   * `year` is any Hijri year.
   */
  getDaysPerMonth(month, year) {
    year = year + Math.floor(month / 13);
    month = (month - 1) % 12 + 1;
    let length = 29 + month % 2;
    if (month === 12 && isIslamicLeapYear(year)) {
      length++;
    }
    return length;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarIslamicCivil_BaseFactory;
      return function NgbCalendarIslamicCivil_Factory(t) {
        return (ɵNgbCalendarIslamicCivil_BaseFactory || (ɵNgbCalendarIslamicCivil_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarIslamicCivil)))(t || NgbCalendarIslamicCivil);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarIslamicCivil,
      factory: NgbCalendarIslamicCivil.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarIslamicCivil, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Umalqura calendar is one type of Hijri calendars used in islamic countries.
 * This Calendar is used by Saudi Arabia for administrative purpose.
 * Unlike tabular calendars, the algorithm involves astronomical calculation, but it's still deterministic.
 * http://cldr.unicode.org/development/development-process/design-proposals/islamic-calendar-types
 */
const GREGORIAN_FIRST_DATE = new Date(1882, 10, 12);
const GREGORIAN_LAST_DATE = new Date(2174, 10, 25);
const HIJRI_BEGIN = 1300;
const HIJRI_END = 1600;
const ONE_DAY = 1000 * 60 * 60 * 24;
const MONTH_LENGTH = [
// 1300-1304
'101010101010', '110101010100', '111011001001', '011011010100', '011011101010',
// 1305-1309
'001101101100', '101010101101', '010101010101', '011010101001', '011110010010',
// 1310-1314
'101110101001', '010111010100', '101011011010', '010101011100', '110100101101',
// 1315-1319
'011010010101', '011101001010', '101101010100', '101101101010', '010110101101',
// 1320-1324
'010010101110', '101001001111', '010100010111', '011010001011', '011010100101',
// 1325-1329
'101011010101', '001011010110', '100101011011', '010010011101', '101001001101',
// 1330-1334
'110100100110', '110110010101', '010110101100', '100110110110', '001010111010',
// 1335-1339
'101001011011', '010100101011', '101010010101', '011011001010', '101011101001',
// 1340-1344
'001011110100', '100101110110', '001010110110', '100101010110', '101011001010',
// 1345-1349
'101110100100', '101111010010', '010111011001', '001011011100', '100101101101',
// 1350-1354
'010101001101', '101010100101', '101101010010', '101110100101', '010110110100',
// 1355-1359
'100110110110', '010101010111', '001010010111', '010101001011', '011010100011',
// 1360-1364
'011101010010', '101101100101', '010101101010', '101010101011', '010100101011',
// 1365-1369
'110010010101', '110101001010', '110110100101', '010111001010', '101011010110',
// 1370-1374
'100101010111', '010010101011', '100101001011', '101010100101', '101101010010',
// 1375-1379
'101101101010', '010101110101', '001001110110', '100010110111', '010001011011',
// 1380-1384
'010101010101', '010110101001', '010110110100', '100111011010', '010011011101',
// 1385-1389
'001001101110', '100100110110', '101010101010', '110101010100', '110110110010',
// 1390-1394
'010111010101', '001011011010', '100101011011', '010010101011', '101001010101',
// 1395-1399
'101101001001', '101101100100', '101101110001', '010110110100', '101010110101',
// 1400-1404
'101001010101', '110100100101', '111010010010', '111011001001', '011011010100',
// 1405-1409
'101011101001', '100101101011', '010010101011', '101010010011', '110101001001',
// 1410-1414
'110110100100', '110110110010', '101010111001', '010010111010', '101001011011',
// 1415-1419
'010100101011', '101010010101', '101100101010', '101101010101', '010101011100',
// 1420-1424
'010010111101', '001000111101', '100100011101', '101010010101', '101101001010',
// 1425-1429
'101101011010', '010101101101', '001010110110', '100100111011', '010010011011',
// 1430-1434
'011001010101', '011010101001', '011101010100', '101101101010', '010101101100',
// 1435-1439
'101010101101', '010101010101', '101100101001', '101110010010', '101110101001',
// 1440-1444
'010111010100', '101011011010', '010101011010', '101010101011', '010110010101',
// 1445-1449
'011101001001', '011101100100', '101110101010', '010110110101', '001010110110',
// 1450-1454
'101001010110', '111001001101', '101100100101', '101101010010', '101101101010',
// 1455-1459
'010110101101', '001010101110', '100100101111', '010010010111', '011001001011',
// 1460-1464
'011010100101', '011010101100', '101011010110', '010101011101', '010010011101',
// 1465-1469
'101001001101', '110100010110', '110110010101', '010110101010', '010110110101',
// 1470-1474
'001011011010', '100101011011', '010010101101', '010110010101', '011011001010',
// 1475-1479
'011011100100', '101011101010', '010011110101', '001010110110', '100101010110',
// 1480-1484
'101010101010', '101101010100', '101111010010', '010111011001', '001011101010',
// 1485-1489
'100101101101', '010010101101', '101010010101', '101101001010', '101110100101',
// 1490-1494
'010110110010', '100110110101', '010011010110', '101010010111', '010101000111',
// 1495-1499
'011010010011', '011101001001', '101101010101', '010101101010', '101001101011',
// 1500-1504
'010100101011', '101010001011', '110101000110', '110110100011', '010111001010',
// 1505-1509
'101011010110', '010011011011', '001001101011', '100101001011', '101010100101',
// 1510-1514
'101101010010', '101101101001', '010101110101', '000101110110', '100010110111',
// 1515-1519
'001001011011', '010100101011', '010101100101', '010110110100', '100111011010',
// 1520-1524
'010011101101', '000101101101', '100010110110', '101010100110', '110101010010',
// 1525-1529
'110110101001', '010111010100', '101011011010', '100101011011', '010010101011',
// 1530-1534
'011001010011', '011100101001', '011101100010', '101110101001', '010110110010',
// 1535-1539
'101010110101', '010101010101', '101100100101', '110110010010', '111011001001',
// 1540-1544
'011011010010', '101011101001', '010101101011', '010010101011', '101001010101',
// 1545-1549
'110100101001', '110101010100', '110110101010', '100110110101', '010010111010',
// 1550-1554
'101000111011', '010010011011', '101001001101', '101010101010', '101011010101',
// 1555-1559
'001011011010', '100101011101', '010001011110', '101000101110', '110010011010',
// 1560-1564
'110101010101', '011010110010', '011010111001', '010010111010', '101001011101',
// 1565-1569
'010100101101', '101010010101', '101101010010', '101110101000', '101110110100',
// 1570-1574
'010110111001', '001011011010', '100101011010', '101101001010', '110110100100',
// 1575-1579
'111011010001', '011011101000', '101101101010', '010101101101', '010100110101',
// 1580-1584
'011010010101', '110101001010', '110110101000', '110111010100', '011011011010',
// 1585-1589
'010101011011', '001010011101', '011000101011', '101100010101', '101101001010',
// 1590-1594
'101110010101', '010110101010', '101010101110', '100100101110', '110010001111',
// 1595-1599
'010100100111', '011010010101', '011010101010', '101011010110', '010101011101',
// 1600
'001010011101'];
function getDaysDiff(date1, date2) {
  // Ignores the time part in date1 and date2:
  const time1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate());
  const time2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate());
  const diff = Math.abs(time1 - time2);
  return Math.round(diff / ONE_DAY);
}
class NgbCalendarIslamicUmalqura extends NgbCalendarIslamicCivil {
  /**
   * Returns the equivalent islamic(Umalqura) date value for a give input Gregorian date.
   * `gdate` is s JS Date to be converted to Hijri.
   */
  fromGregorian(gDate) {
    let hDay = 1,
      hMonth = 0,
      hYear = 1300;
    let daysDiff = getDaysDiff(gDate, GREGORIAN_FIRST_DATE);
    if (gDate.getTime() - GREGORIAN_FIRST_DATE.getTime() >= 0 && gDate.getTime() - GREGORIAN_LAST_DATE.getTime() <= 0) {
      let year = 1300;
      for (let i = 0; i < MONTH_LENGTH.length; i++, year++) {
        for (let j = 0; j < 12; j++) {
          let numOfDays = +MONTH_LENGTH[i][j] + 29;
          if (daysDiff <= numOfDays) {
            hDay = daysDiff + 1;
            if (hDay > numOfDays) {
              hDay = 1;
              j++;
            }
            if (j > 11) {
              j = 0;
              year++;
            }
            hMonth = j;
            hYear = year;
            return new NgbDate(hYear, hMonth + 1, hDay);
          }
          daysDiff = daysDiff - numOfDays;
        }
      }
      return null;
    } else {
      return super.fromGregorian(gDate);
    }
  }
  /**
   * Converts the current Hijri date to Gregorian.
   */
  toGregorian(hDate) {
    const hYear = hDate.year;
    const hMonth = hDate.month - 1;
    const hDay = hDate.day;
    let gDate = new Date(GREGORIAN_FIRST_DATE);
    let dayDiff = hDay - 1;
    if (hYear >= HIJRI_BEGIN && hYear <= HIJRI_END) {
      for (let y = 0; y < hYear - HIJRI_BEGIN; y++) {
        for (let m = 0; m < 12; m++) {
          dayDiff += +MONTH_LENGTH[y][m] + 29;
        }
      }
      for (let m = 0; m < hMonth; m++) {
        dayDiff += +MONTH_LENGTH[hYear - HIJRI_BEGIN][m] + 29;
      }
      gDate.setDate(GREGORIAN_FIRST_DATE.getDate() + dayDiff);
    } else {
      gDate = super.toGregorian(hDate);
    }
    return gDate;
  }
  /**
   * Returns the number of days in a specific Hijri hMonth.
   * `hMonth` is 1 for Muharram, 2 for Safar, etc.
   * `hYear` is any Hijri hYear.
   */
  getDaysPerMonth(hMonth, hYear) {
    if (hYear >= HIJRI_BEGIN && hYear <= HIJRI_END) {
      const pos = hYear - HIJRI_BEGIN;
      return +MONTH_LENGTH[pos][hMonth - 1] + 29;
    }
    return super.getDaysPerMonth(hMonth, hYear);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarIslamicUmalqura_BaseFactory;
      return function NgbCalendarIslamicUmalqura_Factory(t) {
        return (ɵNgbCalendarIslamicUmalqura_BaseFactory || (ɵNgbCalendarIslamicUmalqura_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarIslamicUmalqura)))(t || NgbCalendarIslamicUmalqura);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarIslamicUmalqura,
      factory: NgbCalendarIslamicUmalqura.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarIslamicUmalqura, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Returns the equivalent JS date value for a give input Jalali date.
 * `jalaliDate` is an Jalali date to be converted to Gregorian.
 */
function toGregorian$3(jalaliDate) {
  let jdn = jalaliToJulian(jalaliDate.year, jalaliDate.month, jalaliDate.day);
  let date = julianToGregorian$1(jdn);
  date.setHours(6, 30, 3, 200);
  return date;
}
/**
 * Returns the equivalent jalali date value for a give input Gregorian date.
 * `gdate` is a JS Date to be converted to jalali.
 * utc to local
 */
function fromGregorian$3(gdate) {
  let g2d = gregorianToJulian$1(gdate.getFullYear(), gdate.getMonth() + 1, gdate.getDate());
  return julianToJalali(g2d);
}
function setJalaliYear(date, yearValue) {
  date.year = +yearValue;
  return date;
}
function setJalaliMonth(date, month) {
  month = +month;
  date.year = date.year + Math.floor((month - 1) / 12);
  date.month = Math.floor(((month - 1) % 12 + 12) % 12) + 1;
  return date;
}
function setJalaliDay(date, day) {
  let mDays = getDaysPerMonth$1(date.month, date.year);
  if (day <= 0) {
    while (day <= 0) {
      date = setJalaliMonth(date, date.month - 1);
      mDays = getDaysPerMonth$1(date.month, date.year);
      day += mDays;
    }
  } else if (day > mDays) {
    while (day > mDays) {
      day -= mDays;
      date = setJalaliMonth(date, date.month + 1);
      mDays = getDaysPerMonth$1(date.month, date.year);
    }
  }
  date.day = day;
  return date;
}
function mod(a, b) {
  return a - b * Math.floor(a / b);
}
function div(a, b) {
  return Math.trunc(a / b);
}
/*
 This function determines if the Jalali (Persian) year is
 leap (366-day long) or is the common year (365 days), and
 finds the day in March (Gregorian calendar) of the first
 day of the Jalali year (jalaliYear).
 @param jalaliYear Jalali calendar year (-61 to 3177)
 @return
 leap: number of years since the last leap year (0 to 4)
 gYear: Gregorian year of the beginning of Jalali year
 march: the March day of Farvardin the 1st (1st day of jalaliYear)
 @see: http://www.astro.uni.torun.pl/~kb/Papers/EMP/PersianC-EMP.htm
 @see: http://www.fourmilab.ch/documents/calendar/
 */
function jalCal(jalaliYear) {
  // Jalali years starting the 33-year rule.
  let breaks = [-61, 9, 38, 199, 426, 686, 756, 818, 1111, 1181, 1210, 1635, 2060, 2097, 2192, 2262, 2324, 2394, 2456, 3178];
  const breaksLength = breaks.length;
  const gYear = jalaliYear + 621;
  let leapJ = -14;
  let jp = breaks[0];
  if (jalaliYear < jp || jalaliYear >= breaks[breaksLength - 1]) {
    throw new Error('Invalid Jalali year ' + jalaliYear);
  }
  // Find the limiting years for the Jalali year jalaliYear.
  let jump;
  for (let i = 1; i < breaksLength; i += 1) {
    const jm = breaks[i];
    jump = jm - jp;
    if (jalaliYear < jm) {
      break;
    }
    leapJ = leapJ + div(jump, 33) * 8 + div(mod(jump, 33), 4);
    jp = jm;
  }
  let n = jalaliYear - jp;
  // Find the number of leap years from AD 621 to the beginning
  // of the current Jalali year in the Persian calendar.
  leapJ = leapJ + div(n, 33) * 8 + div(mod(n, 33) + 3, 4);
  if (mod(jump, 33) === 4 && jump - n === 4) {
    leapJ += 1;
  }
  // And the same in the Gregorian calendar (until the year gYear).
  const leapG = div(gYear, 4) - div((div(gYear, 100) + 1) * 3, 4) - 150;
  // Determine the Gregorian date of Farvardin the 1st.
  const march = 20 + leapJ - leapG;
  // Find how many years have passed since the last leap year.
  if (jump - n < 6) {
    n = n - jump + div(jump + 4, 33) * 33;
  }
  let leap = mod(mod(n + 1, 33) - 1, 4);
  if (leap === -1) {
    leap = 4;
  }
  return {
    leap: leap,
    gy: gYear,
    march: march
  };
}
/*
 Calculates Gregorian and Julian calendar dates from the Julian Day number
 (jdn) for the period since jdn=-34839655 (i.e. the year -100100 of both
 calendars) to some millions years ahead of the present.
 @param jdn Julian Day number
 @return
 gYear: Calendar year (years BC numbered 0, -1, -2, ...)
 gMonth: Calendar month (1 to 12)
 gDay: Calendar day of the month M (1 to 28/29/30/31)
 */
function julianToGregorian$1(julianDayNumber) {
  let j = 4 * julianDayNumber + 139361631;
  j = j + div(div(4 * julianDayNumber + 183187720, 146097) * 3, 4) * 4 - 3908;
  const i = div(mod(j, 1461), 4) * 5 + 308;
  const gDay = div(mod(i, 153), 5) + 1;
  const gMonth = mod(div(i, 153), 12) + 1;
  const gYear = div(j, 1461) - 100100 + div(8 - gMonth, 6);
  return new Date(gYear, gMonth - 1, gDay);
}
/*
 Converts a date of the Jalali calendar to the Julian Day number.
 @param jy Jalali year (1 to 3100)
 @param jm Jalali month (1 to 12)
 @param jd Jalali day (1 to 29/31)
 @return Julian Day number
 */
function gregorianToJulian$1(gy, gm, gd) {
  let d = div((gy + div(gm - 8, 6) + 100100) * 1461, 4) + div(153 * mod(gm + 9, 12) + 2, 5) + gd - 34840408;
  d = d - div(div(gy + 100100 + div(gm - 8, 6), 100) * 3, 4) + 752;
  return d;
}
/*
 Converts the Julian Day number to a date in the Jalali calendar.
 @param julianDayNumber Julian Day number
 @return
 jalaliYear: Jalali year (1 to 3100)
 jalaliMonth: Jalali month (1 to 12)
 jalaliDay: Jalali day (1 to 29/31)
 */
function julianToJalali(julianDayNumber) {
  let gy = julianToGregorian$1(julianDayNumber).getFullYear(),
    // Calculate Gregorian year (gy).
    jalaliYear = gy - 621,
    r = jalCal(jalaliYear),
    gregorianDay = gregorianToJulian$1(gy, 3, r.march),
    jalaliDay,
    jalaliMonth,
    numberOfDays;
  // Find number of days that passed since 1 Farvardin.
  numberOfDays = julianDayNumber - gregorianDay;
  if (numberOfDays >= 0) {
    if (numberOfDays <= 185) {
      // The first 6 months.
      jalaliMonth = 1 + div(numberOfDays, 31);
      jalaliDay = mod(numberOfDays, 31) + 1;
      return new NgbDate(jalaliYear, jalaliMonth, jalaliDay);
    } else {
      // The remaining months.
      numberOfDays -= 186;
    }
  } else {
    // Previous Jalali year.
    jalaliYear -= 1;
    numberOfDays += 179;
    if (r.leap === 1) {
      numberOfDays += 1;
    }
  }
  jalaliMonth = 7 + div(numberOfDays, 30);
  jalaliDay = mod(numberOfDays, 30) + 1;
  return new NgbDate(jalaliYear, jalaliMonth, jalaliDay);
}
/*
 Converts a date of the Jalali calendar to the Julian Day number.
 @param jYear Jalali year (1 to 3100)
 @param jMonth Jalali month (1 to 12)
 @param jDay Jalali day (1 to 29/31)
 @return Julian Day number
 */
function jalaliToJulian(jYear, jMonth, jDay) {
  let r = jalCal(jYear);
  return gregorianToJulian$1(r.gy, 3, r.march) + (jMonth - 1) * 31 - div(jMonth, 7) * (jMonth - 7) + jDay - 1;
}
/**
 * Returns the number of days in a specific jalali month.
 */
function getDaysPerMonth$1(month, year) {
  if (month <= 6) {
    return 31;
  }
  if (month <= 11) {
    return 30;
  }
  if (jalCal(year).leap === 0) {
    return 30;
  }
  return 29;
}
class NgbCalendarPersian extends NgbCalendar {
  getDaysPerWeek() {
    return 7;
  }
  getMonths() {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
  }
  getWeeksPerMonth() {
    return 6;
  }
  getNext(date, period = 'd', number = 1) {
    date = new NgbDate(date.year, date.month, date.day);
    switch (period) {
      case 'y':
        date = setJalaliYear(date, date.year + number);
        date.month = 1;
        date.day = 1;
        return date;
      case 'm':
        date = setJalaliMonth(date, date.month + number);
        date.day = 1;
        return date;
      case 'd':
        return setJalaliDay(date, date.day + number);
      default:
        return date;
    }
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    const day = toGregorian$3(date).getDay();
    // in JS Date Sun=0, in ISO 8601 Sun=7
    return day === 0 ? 7 : day;
  }
  getWeekNumber(week, firstDayOfWeek) {
    // in JS Date Sun=0, in ISO 8601 Sun=7
    if (firstDayOfWeek === 7) {
      firstDayOfWeek = 0;
    }
    const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
    const date = week[thursdayIndex];
    const jsDate = toGregorian$3(date);
    jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
    const time = jsDate.getTime();
    const startDate = toGregorian$3(new NgbDate(date.year, 1, 1));
    return Math.floor(Math.round((time - startDate.getTime()) / 86400000) / 7) + 1;
  }
  getToday() {
    return fromGregorian$3(new Date());
  }
  isValid(date) {
    return date != null && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) && !isNaN(toGregorian$3(date).getTime());
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarPersian_BaseFactory;
      return function NgbCalendarPersian_Factory(t) {
        return (ɵNgbCalendarPersian_BaseFactory || (ɵNgbCalendarPersian_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarPersian)))(t || NgbCalendarPersian);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarPersian,
      factory: NgbCalendarPersian.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarPersian, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const PARTS_PER_HOUR = 1080;
const PARTS_PER_DAY = 24 * PARTS_PER_HOUR;
const PARTS_FRACTIONAL_MONTH = 12 * PARTS_PER_HOUR + 793;
const PARTS_PER_MONTH = 29 * PARTS_PER_DAY + PARTS_FRACTIONAL_MONTH;
const BAHARAD = 11 * PARTS_PER_HOUR + 204;
const HEBREW_DAY_ON_JAN_1_1970 = 2092591;
const GREGORIAN_EPOCH = 1721425.5;
function isGregorianLeapYear(year) {
  return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
}
function numberOfFirstDayInYear(year) {
  let monthsBeforeYear = Math.floor((235 * year - 234) / 19);
  let fractionalMonthsBeforeYear = monthsBeforeYear * PARTS_FRACTIONAL_MONTH + BAHARAD;
  let dayNumber = monthsBeforeYear * 29 + Math.floor(fractionalMonthsBeforeYear / PARTS_PER_DAY);
  let timeOfDay = fractionalMonthsBeforeYear % PARTS_PER_DAY;
  let dayOfWeek = dayNumber % 7; // 0 == Monday
  if (dayOfWeek === 2 || dayOfWeek === 4 || dayOfWeek === 6) {
    dayNumber++;
    dayOfWeek = dayNumber % 7;
  }
  if (dayOfWeek === 1 && timeOfDay > 15 * PARTS_PER_HOUR + 204 && !isHebrewLeapYear(year)) {
    dayNumber += 2;
  } else if (dayOfWeek === 0 && timeOfDay > 21 * PARTS_PER_HOUR + 589 && isHebrewLeapYear(year - 1)) {
    dayNumber++;
  }
  return dayNumber;
}
function getDaysInGregorianMonth(month, year) {
  let days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  if (isGregorianLeapYear(year)) {
    days[1]++;
  }
  return days[month - 1];
}
function getHebrewMonths(year) {
  return isHebrewLeapYear(year) ? 13 : 12;
}
/**
 * Returns the number of days in a specific Hebrew year.
 * `year` is any Hebrew year.
 */
function getDaysInHebrewYear(year) {
  return numberOfFirstDayInYear(year + 1) - numberOfFirstDayInYear(year);
}
function isHebrewLeapYear(year) {
  if (year != null) {
    let b = (year * 12 + 17) % 19;
    return b >= (b < 0 ? -7 : 12);
  }
  return false;
}
/**
 * Returns the number of days in a specific Hebrew month.
 * `month` is 1 for Nisan, 2 for Iyar etc. Note: Hebrew leap year contains 13 months.
 * `year` is any Hebrew year.
 */
function getDaysInHebrewMonth(month, year) {
  let yearLength = numberOfFirstDayInYear(year + 1) - numberOfFirstDayInYear(year);
  let yearType = (yearLength <= 380 ? yearLength : yearLength - 30) - 353;
  let leapYear = isHebrewLeapYear(year);
  let daysInMonth = leapYear ? [30, 29, 29, 29, 30, 30, 29, 30, 29, 30, 29, 30, 29] : [30, 29, 29, 29, 30, 29, 30, 29, 30, 29, 30, 29];
  if (yearType > 0) {
    daysInMonth[2]++; // Kislev gets an extra day in normal or complete years.
  }
  if (yearType > 1) {
    daysInMonth[1]++; // Heshvan gets an extra day in complete years only.
  }
  return daysInMonth[month - 1];
}
function getDayNumberInHebrewYear(date) {
  let numberOfDay = 0;
  for (let i = 1; i < date.month; i++) {
    numberOfDay += getDaysInHebrewMonth(i, date.year);
  }
  return numberOfDay + date.day;
}
function setHebrewMonth(date, val) {
  let after = val >= 0;
  if (!after) {
    val = -val;
  }
  while (val > 0) {
    if (after) {
      if (val > getHebrewMonths(date.year) - date.month) {
        val -= getHebrewMonths(date.year) - date.month + 1;
        date.year++;
        date.month = 1;
      } else {
        date.month += val;
        val = 0;
      }
    } else {
      if (val >= date.month) {
        date.year--;
        val -= date.month;
        date.month = getHebrewMonths(date.year);
      } else {
        date.month -= val;
        val = 0;
      }
    }
  }
  return date;
}
function setHebrewDay(date, val) {
  let after = val >= 0;
  if (!after) {
    val = -val;
  }
  while (val > 0) {
    if (after) {
      if (val > getDaysInHebrewYear(date.year) - getDayNumberInHebrewYear(date)) {
        val -= getDaysInHebrewYear(date.year) - getDayNumberInHebrewYear(date) + 1;
        date.year++;
        date.month = 1;
        date.day = 1;
      } else if (val > getDaysInHebrewMonth(date.month, date.year) - date.day) {
        val -= getDaysInHebrewMonth(date.month, date.year) - date.day + 1;
        date.month++;
        date.day = 1;
      } else {
        date.day += val;
        val = 0;
      }
    } else {
      if (val >= date.day) {
        val -= date.day;
        date.month--;
        if (date.month === 0) {
          date.year--;
          date.month = getHebrewMonths(date.year);
        }
        date.day = getDaysInHebrewMonth(date.month, date.year);
      } else {
        date.day -= val;
        val = 0;
      }
    }
  }
  return date;
}
/**
 * Returns the equivalent Hebrew date value for a give input Gregorian date.
 * `gdate` is a JS Date to be converted to Hebrew date.
 */
function fromGregorian$2(gdate) {
  const date = new Date(gdate);
  const gYear = date.getFullYear(),
    gMonth = date.getMonth(),
    gDay = date.getDate();
  let julianDay = GREGORIAN_EPOCH - 1 + 365 * (gYear - 1) + Math.floor((gYear - 1) / 4) - Math.floor((gYear - 1) / 100) + Math.floor((gYear - 1) / 400) + Math.floor((367 * (gMonth + 1) - 362) / 12 + (gMonth + 1 <= 2 ? 0 : isGregorianLeapYear(gYear) ? -1 : -2) + gDay);
  julianDay = Math.floor(julianDay + 0.5);
  let daysSinceHebEpoch = julianDay - 347997;
  let monthsSinceHebEpoch = Math.floor(daysSinceHebEpoch * PARTS_PER_DAY / PARTS_PER_MONTH);
  let hYear = Math.floor((monthsSinceHebEpoch * 19 + 234) / 235) + 1;
  let firstDayOfThisYear = numberOfFirstDayInYear(hYear);
  let dayOfYear = daysSinceHebEpoch - firstDayOfThisYear;
  while (dayOfYear < 1) {
    hYear--;
    firstDayOfThisYear = numberOfFirstDayInYear(hYear);
    dayOfYear = daysSinceHebEpoch - firstDayOfThisYear;
  }
  let hMonth = 1;
  let hDay = dayOfYear;
  while (hDay > getDaysInHebrewMonth(hMonth, hYear)) {
    hDay -= getDaysInHebrewMonth(hMonth, hYear);
    hMonth++;
  }
  return new NgbDate(hYear, hMonth, hDay);
}
/**
 * Returns the equivalent JS date value for a given Hebrew date.
 * `hebrewDate` is an Hebrew date to be converted to Gregorian.
 */
function toGregorian$2(hebrewDate) {
  const hYear = hebrewDate.year;
  const hMonth = hebrewDate.month;
  const hDay = hebrewDate.day;
  let days = numberOfFirstDayInYear(hYear);
  for (let i = 1; i < hMonth; i++) {
    days += getDaysInHebrewMonth(i, hYear);
  }
  days += hDay;
  let diffDays = days - HEBREW_DAY_ON_JAN_1_1970;
  let after = diffDays >= 0;
  if (!after) {
    diffDays = -diffDays;
  }
  let gYear = 1970;
  let gMonth = 1;
  let gDay = 1;
  while (diffDays > 0) {
    if (after) {
      if (diffDays >= (isGregorianLeapYear(gYear) ? 366 : 365)) {
        diffDays -= isGregorianLeapYear(gYear) ? 366 : 365;
        gYear++;
      } else if (diffDays >= getDaysInGregorianMonth(gMonth, gYear)) {
        diffDays -= getDaysInGregorianMonth(gMonth, gYear);
        gMonth++;
      } else {
        gDay += diffDays;
        diffDays = 0;
      }
    } else {
      if (diffDays >= (isGregorianLeapYear(gYear - 1) ? 366 : 365)) {
        diffDays -= isGregorianLeapYear(gYear - 1) ? 366 : 365;
        gYear--;
      } else {
        if (gMonth > 1) {
          gMonth--;
        } else {
          gMonth = 12;
          gYear--;
        }
        if (diffDays >= getDaysInGregorianMonth(gMonth, gYear)) {
          diffDays -= getDaysInGregorianMonth(gMonth, gYear);
        } else {
          gDay = getDaysInGregorianMonth(gMonth, gYear) - diffDays + 1;
          diffDays = 0;
        }
      }
    }
  }
  return new Date(gYear, gMonth - 1, gDay);
}
function hebrewNumerals(numerals) {
  if (!numerals) {
    return '';
  }
  const hArray0_9 = ['', '\u05d0', '\u05d1', '\u05d2', '\u05d3', '\u05d4', '\u05d5', '\u05d6', '\u05d7', '\u05d8'];
  const hArray10_19 = ['\u05d9', '\u05d9\u05d0', '\u05d9\u05d1', '\u05d9\u05d2', '\u05d9\u05d3', '\u05d8\u05d5', '\u05d8\u05d6', '\u05d9\u05d6', '\u05d9\u05d7', '\u05d9\u05d8'];
  const hArray20_90 = ['', '', '\u05db', '\u05dc', '\u05de', '\u05e0', '\u05e1', '\u05e2', '\u05e4', '\u05e6'];
  const hArray100_900 = ['', '\u05e7', '\u05e8', '\u05e9', '\u05ea', '\u05ea\u05e7', '\u05ea\u05e8', '\u05ea\u05e9', '\u05ea\u05ea', '\u05ea\u05ea\u05e7'];
  const hArray1000_9000 = ['', '\u05d0', '\u05d1', '\u05d1\u05d0', '\u05d1\u05d1', '\u05d4', '\u05d4\u05d0', '\u05d4\u05d1', '\u05d4\u05d1\u05d0', '\u05d4\u05d1\u05d1'];
  const geresh = '\u05f3',
    gershaim = '\u05f4';
  let mem = 0;
  let result = [];
  let step = 0;
  while (numerals > 0) {
    let m = numerals % 10;
    if (step === 0) {
      mem = m;
    } else if (step === 1) {
      if (m !== 1) {
        result.unshift(hArray20_90[m], hArray0_9[mem]);
      } else {
        result.unshift(hArray10_19[mem]);
      }
    } else if (step === 2) {
      result.unshift(hArray100_900[m]);
    } else {
      if (m !== 5) {
        result.unshift(hArray1000_9000[m], geresh, ' ');
      }
      break;
    }
    numerals = Math.floor(numerals / 10);
    if (step === 0 && numerals === 0) {
      result.unshift(hArray0_9[m]);
    }
    step++;
  }
  result = result.join('').split('');
  if (result.length === 1) {
    result.push(geresh);
  } else if (result.length > 1) {
    result.splice(result.length - 1, 0, gershaim);
  }
  return result.join('');
}

/**
 * @since 3.2.0
 */
class NgbCalendarHebrew extends NgbCalendar {
  getDaysPerWeek() {
    return 7;
  }
  getMonths(year) {
    if (year && isHebrewLeapYear(year)) {
      return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
    } else {
      return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
    }
  }
  getWeeksPerMonth() {
    return 6;
  }
  isValid(date) {
    if (date != null) {
      let b = isNumber(date.year) && isNumber(date.month) && isNumber(date.day);
      b = b && date.month > 0 && date.month <= (isHebrewLeapYear(date.year) ? 13 : 12);
      b = b && date.day > 0 && date.day <= getDaysInHebrewMonth(date.month, date.year);
      return b && !isNaN(toGregorian$2(date).getTime());
    }
    return false;
  }
  getNext(date, period = 'd', number = 1) {
    date = new NgbDate(date.year, date.month, date.day);
    switch (period) {
      case 'y':
        date.year += number;
        date.month = 1;
        date.day = 1;
        return date;
      case 'm':
        date = setHebrewMonth(date, number);
        date.day = 1;
        return date;
      case 'd':
        return setHebrewDay(date, number);
      default:
        return date;
    }
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    const day = toGregorian$2(date).getDay();
    // in JS Date Sun=0, in ISO 8601 Sun=7
    return day === 0 ? 7 : day;
  }
  getWeekNumber(week, firstDayOfWeek) {
    const date = week[week.length - 1];
    return Math.ceil(getDayNumberInHebrewYear(date) / 7);
  }
  getToday() {
    return fromGregorian$2(new Date());
  }
  /**
   * @since 3.4.0
   */
  toGregorian(date) {
    return fromJSDate(toGregorian$2(date));
  }
  /**
   * @since 3.4.0
   */
  fromGregorian(date) {
    return fromGregorian$2(toJSDate(date));
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarHebrew_BaseFactory;
      return function NgbCalendarHebrew_Factory(t) {
        return (ɵNgbCalendarHebrew_BaseFactory || (ɵNgbCalendarHebrew_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarHebrew)))(t || NgbCalendarHebrew);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarHebrew,
      factory: NgbCalendarHebrew.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarHebrew, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const WEEKDAYS$1 = ['שני', 'שלישי', 'רביעי', 'חמישי', 'שישי', 'שבת', 'ראשון'];
const MONTHS$1 = ['תשרי', 'חשון', 'כסלו', 'טבת', 'שבט', 'אדר', 'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול'];
const MONTHS_LEAP = ['תשרי', 'חשון', 'כסלו', 'טבת', 'שבט', 'אדר א׳', 'אדר ב׳', 'ניסן', 'אייר', 'סיון', 'תמוז', 'אב', 'אלול'];
/**
 * @since 3.2.0
 */
class NgbDatepickerI18nHebrew extends NgbDatepickerI18n {
  getMonthShortName(month, year) {
    return this.getMonthFullName(month, year);
  }
  getMonthFullName(month, year) {
    return isHebrewLeapYear(year) ? MONTHS_LEAP[month - 1] || '' : MONTHS$1[month - 1] || '';
  }
  getWeekdayLabel(weekday, width) {
    return WEEKDAYS$1[weekday - 1] || '';
  }
  getDayAriaLabel(date) {
    return `${hebrewNumerals(date.day)} ${this.getMonthFullName(date.month, date.year)} ${hebrewNumerals(date.year)}`;
  }
  getDayNumerals(date) {
    return hebrewNumerals(date.day);
  }
  getWeekNumerals(weekNumber) {
    return hebrewNumerals(weekNumber);
  }
  getYearNumerals(year) {
    return hebrewNumerals(year);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDatepickerI18nHebrew_BaseFactory;
      return function NgbDatepickerI18nHebrew_Factory(t) {
        return (ɵNgbDatepickerI18nHebrew_BaseFactory || (ɵNgbDatepickerI18nHebrew_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDatepickerI18nHebrew)))(t || NgbDatepickerI18nHebrew);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerI18nHebrew,
      factory: NgbDatepickerI18nHebrew.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerI18nHebrew, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Returns the equivalent JS date value for a give input Buddhist date.
 * `date` is an Buddhist date to be converted to Gregorian.
 */
function toGregorian$1(date) {
  return new Date(date.year - 543, date.month - 1, date.day);
}
/**
 * Returns the equivalent Buddhist date value for a give input Gregorian date.
 * `gdate` is a JS Date to be converted to Buddhist.
 * utc to local
 */
function fromGregorian$1(gdate) {
  return new NgbDate(gdate.getFullYear() + 543, gdate.getMonth() + 1, gdate.getDate());
}

/**
 * @since 9.1.0
 */
class NgbCalendarBuddhist extends NgbCalendarGregorian {
  getToday() {
    return fromGregorian$1(new Date());
  }
  getNext(date, period = 'd', number = 1) {
    let jsDate = toGregorian$1(date);
    let checkMonth = true;
    let expectedMonth = jsDate.getMonth();
    switch (period) {
      case 'y':
        jsDate.setFullYear(jsDate.getFullYear() + number);
        break;
      case 'm':
        expectedMonth += number;
        jsDate.setMonth(expectedMonth);
        expectedMonth = expectedMonth % 12;
        if (expectedMonth < 0) {
          expectedMonth = expectedMonth + 12;
        }
        break;
      case 'd':
        jsDate.setDate(jsDate.getDate() + number);
        checkMonth = false;
        break;
      default:
        return date;
    }
    if (checkMonth && jsDate.getMonth() !== expectedMonth) {
      // this means the destination month has less days than the initial month
      // let's go back to the end of the previous month:
      jsDate.setDate(0);
    }
    return fromGregorian$1(jsDate);
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    let jsDate = toGregorian$1(date);
    let day = jsDate.getDay();
    // in JS Date Sun=0, in ISO 8601 Sun=7
    return day === 0 ? 7 : day;
  }
  getWeekNumber(week, firstDayOfWeek) {
    // in JS Date Sun=0, in ISO 8601 Sun=7
    if (firstDayOfWeek === 7) {
      firstDayOfWeek = 0;
    }
    const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
    let date = week[thursdayIndex];
    const jsDate = toGregorian$1(date);
    jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
    const time = jsDate.getTime();
    jsDate.setMonth(0); // Compare with Jan 1
    jsDate.setDate(1);
    return Math.floor(Math.round((time - jsDate.getTime()) / 86400000) / 7) + 1;
  }
  isValid(date) {
    if (!date || !isInteger(date.year) || !isInteger(date.month) || !isInteger(date.day)) {
      return false;
    }
    // year 0 doesn't exist in Gregorian calendar
    if (date.year === 0) {
      return false;
    }
    const jsDate = toGregorian$1(date);
    return !isNaN(jsDate.getTime()) && jsDate.getFullYear() === date.year - 543 && jsDate.getMonth() + 1 === date.month && jsDate.getDate() === date.day;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarBuddhist_BaseFactory;
      return function NgbCalendarBuddhist_Factory(t) {
        return (ɵNgbCalendarBuddhist_BaseFactory || (ɵNgbCalendarBuddhist_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarBuddhist)))(t || NgbCalendarBuddhist);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarBuddhist,
      factory: NgbCalendarBuddhist.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarBuddhist, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const JD_EPOCH = 1724220.5;
const DAYSPERMONTH = [30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 5];
/**
 * Determine whether this date is in a leap year.
 * * `year` is the year to examine
 * returns boolean - true if this is a leap year, false if not
 * */
function isEthiopianLeapYear(year) {
  if (year != null) {
    return year % 4 == 3 || year % 4 == -1;
  }
  return false;
}
/**
 * Sets the Ethiopian year.
 * * `date` is Ethiopian date
 * * `yearValue` incremented year
 * returns NgbDate - ethiopian date
 * */
function setEthiopianYear(date, yearValue) {
  date.year = +yearValue;
  return date;
}
/**
 * Sets the Ethiopian month.
 * * `date` is Ethiopian date
 * * `val` incremented month
 * returns NgbDate - Ethiopian date
 * */
function setEthiopianMonth(date, val) {
  val = +val;
  date.year = date.year + Math.floor((val - 1) / 13);
  date.month = Math.floor(((val - 1) % 13 + 13) % 13) + 1;
  return date;
}
/**
 * Sets the Ethiopian day.
 * * `date` is Ethiopian date
 * * `day` incremented day
 * returns NgbDate - Ethiopian date
 * */
function setEthiopianDay(date, day) {
  let mDays = getDaysPerMonth(date.month, date.year);
  if (day <= 0) {
    while (day <= 0) {
      date = setEthiopianMonth(date, date.month - 1);
      mDays = getDaysPerMonth(date.month, date.year);
      day += mDays;
    }
  } else if (day > mDays) {
    while (day > mDays) {
      day -= mDays;
      date = setEthiopianMonth(date, date.month + 1);
      mDays = getDaysPerMonth(date.month, date.year);
    }
  }
  date.day = day;
  return date;
}
function getDaysPerMonth(month, year) {
  let leapYear = isEthiopianLeapYear(year);
  return DAYSPERMONTH[month - 1] + (month === 13 && leapYear ? 1 : 0);
}
function toGregorian(ethiopianDate) {
  let jdn = ethiopianToJulian(ethiopianDate.year, ethiopianDate.month, ethiopianDate.day);
  let date = julianToGregorian(jdn);
  date.setHours(6, 30, 3, 200);
  return date;
}
function fromGregorian(gdate) {
  let g2d = gregorianToJulian(gdate.getFullYear(), gdate.getMonth() + 1, gdate.getDate());
  return juilianToEthiopia(g2d);
}
function ethiopianToJulian(year, month, day) {
  if (year < 0) {
    year++;
  } // No year zero
  return day + (month - 1) * 30 + (year - 1) * 365 + Math.floor(year / 4) + JD_EPOCH - 1;
}
function juilianToEthiopia(jd) {
  let c = Math.floor(jd) + 0.5 - JD_EPOCH;
  let year = Math.floor((c - Math.floor((c + 366) / 1461)) / 365) + 1;
  if (year <= 0) {
    year--;
  } // No year zero
  c = Math.floor(jd) + 0.5 - ethiopianToJulian(year, 1, 1);
  let month = Math.floor(c / 30) + 1;
  let day = c - (month - 1) * 30 + 1;
  return new NgbDate(year, month, day);
}
function julianToGregorian(jd) {
  let z = Math.floor(jd + 0.5);
  let a = Math.floor((z - 1867216.25) / 36524.25);
  a = z + 1 + a - Math.floor(a / 4);
  let b = a + 1524;
  let c = Math.floor((b - 122.1) / 365.25);
  let d = Math.floor(365.25 * c);
  let e = Math.floor((b - d) / 30.6001);
  let day = b - d - Math.floor(e * 30.6001);
  let month = e - (e > 13.5 ? 13 : 1);
  let year = c - (month > 2.5 ? 4716 : 4715);
  if (year <= 0) {
    year--;
  } // No year zero
  return new Date(year, month, day);
}
function gregorianToJulian(year, month, day) {
  if (year < 0) {
    year++;
  } // No year zero
  // Jean Meeus algorithm, "Astronomical Algorithms", 1991
  if (month < 3) {
    month += 12;
    year--;
  }
  let a = Math.floor(year / 100);
  let b = 2 - a + Math.floor(a / 4);
  return Math.floor(365.25 * (year + 4716)) + Math.floor(30.6001 * (month + 1)) + day + b - 1524.5;
}

/**
 * @since 16.0.0
 */
class NgbCalendarEthiopian extends NgbCalendar {
  getDaysPerWeek() {
    return 7;
  }
  getMonths(year) {
    return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
  }
  getNext(date, period = 'd', number = 1) {
    date = new NgbDate(date.year, date.month, date.day);
    switch (period) {
      case 'y':
        date = setEthiopianYear(date, date.year + number);
        date.month = 1;
        date.day = 1;
        return date;
      case 'm':
        date = setEthiopianMonth(date, date.month + number);
        date.day = 1;
        return date;
      case 'd':
        return setEthiopianDay(date, date.day + number);
      default:
        return date;
    }
  }
  getPrev(date, period = 'd', number = 1) {
    return this.getNext(date, period, -number);
  }
  getWeekday(date) {
    const dt = Math.floor(ethiopianToJulian(date.year, date.month, date.day) + 3) % 7;
    return dt === 0 ? 7 : dt;
  }
  getWeekNumber(week, firstDayOfWeek) {
    if (firstDayOfWeek === 7) {
      firstDayOfWeek = 0;
    }
    const thursdayIndex = (4 + 7 - firstDayOfWeek) % 7;
    const date = week[thursdayIndex];
    const jsDate = toGregorian(date);
    jsDate.setDate(jsDate.getDate() + 4 - (jsDate.getDay() || 7)); // Thursday
    const time = jsDate.getTime();
    const startDate = toGregorian(new NgbDate(date.year, 1, 1));
    return Math.floor(Math.round((time - startDate.getTime()) / 86400000) / 7) + 1;
  }
  getWeeksPerMonth() {
    return 6;
  }
  getToday() {
    return fromGregorian(new Date());
  }
  isValid(date) {
    return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) && !isNaN(toGregorian(date).getTime());
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbCalendarEthiopian_BaseFactory;
      return function NgbCalendarEthiopian_Factory(t) {
        return (ɵNgbCalendarEthiopian_BaseFactory || (ɵNgbCalendarEthiopian_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbCalendarEthiopian)))(t || NgbCalendarEthiopian);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbCalendarEthiopian,
      factory: NgbCalendarEthiopian.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbCalendarEthiopian, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const WEEKDAYS = ['እሑድ', 'ሰኞ', 'ማክሰኞ', 'ረቡዕ', 'ሓሙስ', 'ዓርብ', 'ቅዳሜ'];
const MONTHS = ['መስከረም', 'ጥቅምት', 'ኅዳር', 'ታህሣሥ', 'ጥር', 'የካቲት', 'መጋቢት', 'ሚያዝያ', 'ግንቦት', 'ሰኔ', 'ሐምሌ', 'ነሐሴ', 'ጳጉሜ'];
/**
 * @since 16.0.0
 */
class NgbDatepickerI18nAmharic extends NgbDatepickerI18n {
  getMonthShortName(month, year) {
    return this.getMonthFullName(month, year);
  }
  getMonthFullName(month, year) {
    return MONTHS[month - 1];
  }
  getWeekdayLabel(weekday, width) {
    return WEEKDAYS[weekday - 1];
  }
  getDayAriaLabel(date) {
    return `${date.day} ${this.getMonthFullName(date.month, date.year)} ${date.year}`;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDatepickerI18nAmharic_BaseFactory;
      return function NgbDatepickerI18nAmharic_Factory(t) {
        return (ɵNgbDatepickerI18nAmharic_BaseFactory || (ɵNgbDatepickerI18nAmharic_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDatepickerI18nAmharic)))(t || NgbDatepickerI18nAmharic);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDatepickerI18nAmharic,
      factory: NgbDatepickerI18nAmharic.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerI18nAmharic, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * [`NgbDateAdapter`](#/components/datepicker/api#NgbDateAdapter) implementation that uses
 * native javascript dates as a user date model.
 */
class NgbDateNativeAdapter extends NgbDateAdapter {
  /**
   * Converts a native `Date` to a `NgbDateStruct`.
   */
  fromModel(date) {
    return date instanceof Date && !isNaN(date.getTime()) ? this._fromNativeDate(date) : null;
  }
  /**
   * Converts a `NgbDateStruct` to a native `Date`.
   */
  toModel(date) {
    return date && isInteger(date.year) && isInteger(date.month) && isInteger(date.day) ? this._toNativeDate(date) : null;
  }
  _fromNativeDate(date) {
    return {
      year: date.getFullYear(),
      month: date.getMonth() + 1,
      day: date.getDate()
    };
  }
  _toNativeDate(date) {
    const jsDate = new Date(date.year, date.month - 1, date.day, 12);
    // avoid 30 -> 1930 conversion
    jsDate.setFullYear(date.year);
    return jsDate;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDateNativeAdapter_BaseFactory;
      return function NgbDateNativeAdapter_Factory(t) {
        return (ɵNgbDateNativeAdapter_BaseFactory || (ɵNgbDateNativeAdapter_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDateNativeAdapter)))(t || NgbDateNativeAdapter);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateNativeAdapter,
      factory: NgbDateNativeAdapter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateNativeAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Same as [`NgbDateNativeAdapter`](#/components/datepicker/api#NgbDateNativeAdapter), but with UTC dates.
 *
 * @since 3.2.0
 */
class NgbDateNativeUTCAdapter extends NgbDateNativeAdapter {
  _fromNativeDate(date) {
    return {
      year: date.getUTCFullYear(),
      month: date.getUTCMonth() + 1,
      day: date.getUTCDate()
    };
  }
  _toNativeDate(date) {
    const jsDate = new Date(Date.UTC(date.year, date.month - 1, date.day));
    // avoid 30 -> 1930 conversion
    jsDate.setUTCFullYear(date.year);
    return jsDate;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDateNativeUTCAdapter_BaseFactory;
      return function NgbDateNativeUTCAdapter_Factory(t) {
        return (ɵNgbDateNativeUTCAdapter_BaseFactory || (ɵNgbDateNativeUTCAdapter_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDateNativeUTCAdapter)))(t || NgbDateNativeUTCAdapter);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDateNativeUTCAdapter,
      factory: NgbDateNativeUTCAdapter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDateNativeUTCAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const NGB_DATEPICKER_DIRECTIVES = [NgbDatepicker, NgbDatepickerContent, NgbInputDatepicker, NgbDatepickerMonth];
class NgbDatepickerModule {
  static {
    this.ɵfac = function NgbDatepickerModule_Factory(t) {
      return new (t || NgbDatepickerModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbDatepickerModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDatepickerModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: NGB_DATEPICKER_DIRECTIVES,
      imports: NGB_DATEPICKER_DIRECTIVES
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbDropdown`](#/components/dropdown/api#NgbDropdown) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the dropdowns used in the application.
 */
class NgbDropdownConfig {
  constructor() {
    this.autoClose = true;
    this.placement = ['bottom-start', 'bottom-end', 'top-start', 'top-end'];
    this.popperOptions = options => options;
    this.container = null;
  }
  static {
    this.ɵfac = function NgbDropdownConfig_Factory(t) {
      return new (t || NgbDropdownConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbDropdownConfig,
      factory: NgbDropdownConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A directive you should put on a dropdown item to enable keyboard navigation.
 * Arrow keys will move focus between items marked with this directive.
 *
 * @since 4.1.0
 */
class NgbDropdownItem {
  constructor() {
    this._disabled = false;
    this.nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this.tabindex = 0;
  }
  set disabled(value) {
    this._disabled = value === '' || value === true; // accept an empty attribute as true
  }
  get disabled() {
    return this._disabled;
  }
  static {
    this.ɵfac = function NgbDropdownItem_Factory(t) {
      return new (t || NgbDropdownItem)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdownItem,
      selectors: [["", "ngbDropdownItem", ""]],
      hostAttrs: [1, "dropdown-item"],
      hostVars: 3,
      hostBindings: function NgbDropdownItem_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("tabIndex", ctx.disabled ? -1 : ctx.tabindex);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx.disabled);
        }
      },
      inputs: {
        tabindex: "tabindex",
        disabled: "disabled"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownItem, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbDropdownItem]',
      standalone: true,
      host: {
        class: 'dropdown-item',
        '[class.disabled]': 'disabled',
        '[tabIndex]': 'disabled ? -1 : tabindex'
      }
    }]
  }], null, {
    tabindex: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * A directive that will be applied if dropdown item is a button.
 * It will only set the disabled property.
 */
class NgbDropdownButtonItem {
  constructor() {
    this.item = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDropdownItem);
  }
  static {
    this.ɵfac = function NgbDropdownButtonItem_Factory(t) {
      return new (t || NgbDropdownButtonItem)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdownButtonItem,
      selectors: [["button", "ngbDropdownItem", ""]],
      hostVars: 1,
      hostBindings: function NgbDropdownButtonItem_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("disabled", ctx.item.disabled);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownButtonItem, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'button[ngbDropdownItem]',
      standalone: true,
      host: {
        '[disabled]': 'item.disabled'
      }
    }]
  }], null, null);
})();
/**
 * A directive that wraps dropdown menu content and dropdown items.
 */
class NgbDropdownMenu {
  constructor() {
    this.dropdown = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDropdown);
    this.nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
  }
  static {
    this.ɵfac = function NgbDropdownMenu_Factory(t) {
      return new (t || NgbDropdownMenu)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdownMenu,
      selectors: [["", "ngbDropdownMenu", ""]],
      contentQueries: function NgbDropdownMenu_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbDropdownItem, 4);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.menuItems = _t);
        }
      },
      hostVars: 4,
      hostBindings: function NgbDropdownMenu_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("keydown.ArrowUp", function NgbDropdownMenu_keydown_ArrowUp_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.ArrowDown", function NgbDropdownMenu_keydown_ArrowDown_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Home", function NgbDropdownMenu_keydown_Home_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.End", function NgbDropdownMenu_keydown_End_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Enter", function NgbDropdownMenu_keydown_Enter_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Space", function NgbDropdownMenu_keydown_Space_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Tab", function NgbDropdownMenu_keydown_Tab_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Shift.Tab", function NgbDropdownMenu_keydown_Shift_Tab_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("dropdown-menu", true)("show", ctx.dropdown.isOpen());
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownMenu, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbDropdownMenu]',
      standalone: true,
      host: {
        '[class.dropdown-menu]': 'true',
        '[class.show]': 'dropdown.isOpen()',
        '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
        '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
        '(keydown.Home)': 'dropdown.onKeyDown($event)',
        '(keydown.End)': 'dropdown.onKeyDown($event)',
        '(keydown.Enter)': 'dropdown.onKeyDown($event)',
        '(keydown.Space)': 'dropdown.onKeyDown($event)',
        '(keydown.Tab)': 'dropdown.onKeyDown($event)',
        '(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)'
      }
    }]
  }], null, {
    menuItems: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbDropdownItem]
    }]
  });
})();
/**
 * A directive to mark an element to which dropdown menu will be anchored.
 *
 * This is a simple version of the `NgbDropdownToggle` directive.
 * It plays the same role, but doesn't listen to click events to toggle dropdown menu thus enabling support
 * for events other than click.
 *
 * @since 1.1.0
 */
class NgbDropdownAnchor {
  constructor() {
    this.dropdown = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDropdown);
    this.nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
  }
  static {
    this.ɵfac = function NgbDropdownAnchor_Factory(t) {
      return new (t || NgbDropdownAnchor)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdownAnchor,
      selectors: [["", "ngbDropdownAnchor", ""]],
      hostAttrs: [1, "dropdown-toggle"],
      hostVars: 3,
      hostBindings: function NgbDropdownAnchor_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-expanded", ctx.dropdown.isOpen());
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("show", ctx.dropdown.isOpen());
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownAnchor, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbDropdownAnchor]',
      standalone: true,
      host: {
        class: 'dropdown-toggle',
        '[class.show]': 'dropdown.isOpen()',
        '[attr.aria-expanded]': 'dropdown.isOpen()'
      }
    }]
  }], null, null);
})();
/**
 * A directive to mark an element that will toggle dropdown via the `click` event.
 *
 * You can also use `NgbDropdownAnchor` as an alternative.
 */
class NgbDropdownToggle extends NgbDropdownAnchor {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbDropdownToggle_BaseFactory;
      return function NgbDropdownToggle_Factory(t) {
        return (ɵNgbDropdownToggle_BaseFactory || (ɵNgbDropdownToggle_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbDropdownToggle)))(t || NgbDropdownToggle);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdownToggle,
      selectors: [["", "ngbDropdownToggle", ""]],
      hostAttrs: [1, "dropdown-toggle"],
      hostVars: 3,
      hostBindings: function NgbDropdownToggle_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbDropdownToggle_click_HostBindingHandler() {
            return ctx.dropdown.toggle();
          })("keydown.ArrowUp", function NgbDropdownToggle_keydown_ArrowUp_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.ArrowDown", function NgbDropdownToggle_keydown_ArrowDown_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Home", function NgbDropdownToggle_keydown_Home_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.End", function NgbDropdownToggle_keydown_End_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Tab", function NgbDropdownToggle_keydown_Tab_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          })("keydown.Shift.Tab", function NgbDropdownToggle_keydown_Shift_Tab_HostBindingHandler($event) {
            return ctx.dropdown.onKeyDown($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-expanded", ctx.dropdown.isOpen());
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("show", ctx.dropdown.isOpen());
        }
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: NgbDropdownAnchor,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbDropdownToggle)
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownToggle, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbDropdownToggle]',
      standalone: true,
      host: {
        class: 'dropdown-toggle',
        '[class.show]': 'dropdown.isOpen()',
        '[attr.aria-expanded]': 'dropdown.isOpen()',
        '(click)': 'dropdown.toggle()',
        '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)',
        '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)',
        '(keydown.Home)': 'dropdown.onKeyDown($event)',
        '(keydown.End)': 'dropdown.onKeyDown($event)',
        '(keydown.Tab)': 'dropdown.onKeyDown($event)',
        '(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)'
      },
      providers: [{
        provide: NgbDropdownAnchor,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbDropdownToggle)
      }]
    }]
  }], null, null);
})();
/**
 * A directive that provides contextual overlays for displaying lists of links and more.
 */
class NgbDropdown {
  constructor() {
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbDropdownConfig);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._destroyCloseHandlers$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._bodyContainer = null;
    this._positioning = ngbPositioning();
    /**
     * Indicates whether the dropdown should be closed when clicking one of dropdown items or pressing ESC.
     *
     * * `true` - the dropdown will close on both outside and inside (menu) clicks.
     * * `false` - the dropdown can only be closed manually via `close()` or `toggle()` methods.
     * * `"inside"` - the dropdown will close on inside menu clicks, but not outside clicks.
     * * `"outside"` - the dropdown will close only on the outside clicks and not on menu clicks.
     */
    this.autoClose = this._config.autoClose;
    /**
     * Defines whether or not the dropdown menu is opened initially.
     */
    this._open = false;
    /**
     * The preferred placement of the dropdown, among the [possible values](#/guides/positioning#api).
     *
     * The default order of preference is `"bottom-start bottom-end top-start top-end"`
     *
     * Please see the [positioning overview](#/positioning) for more details.
     */
    this.placement = this._config.placement;
    /**
     * Allows to change default Popper options when positioning the dropdown.
     * Receives current popper options and returns modified ones.
     *
     * @since 13.1.0
     */
    this.popperOptions = this._config.popperOptions;
    /**
     * A selector specifying the element the dropdown should be appended to.
     * Currently only supports "body".
     *
     * @since 4.1.0
     */
    this.container = this._config.container;
    /**
     * An event fired when the dropdown is opened or closed.
     *
     * The event payload is a `boolean`:
     * * `true` - the dropdown was opened
     * * `false` - the dropdown was closed
     */
    this.openChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  ngOnInit() {
    if (!this.display) {
      this.display = this._nativeElement.closest('.navbar') ? 'static' : 'dynamic';
    }
  }
  ngAfterContentInit() {
    this._ngZone.onStable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      this._applyPlacementClasses();
      if (this._open) {
        this._setCloseHandlers();
      }
    });
  }
  ngOnChanges(changes) {
    if (changes.container && this._open) {
      this._applyContainer(this.container);
    }
    if (changes.placement && !changes.placement.firstChange) {
      this._positioning.setOptions({
        hostElement: this._anchor.nativeElement,
        targetElement: this._bodyContainer || this._menu.nativeElement,
        placement: this.placement,
        appendToBody: this.container === 'body'
      });
      this._applyPlacementClasses();
    }
    if (changes.dropdownClass) {
      const {
        currentValue,
        previousValue
      } = changes.dropdownClass;
      this._applyCustomDropdownClass(currentValue, previousValue);
    }
    if (changes.autoClose && this._open) {
      this.autoClose = changes.autoClose.currentValue;
      this._setCloseHandlers();
    }
  }
  /**
   * Checks if the dropdown menu is open.
   */
  isOpen() {
    return this._open;
  }
  /**
   * Opens the dropdown menu.
   */
  open() {
    if (!this._open) {
      this._open = true;
      this._applyContainer(this.container);
      this.openChange.emit(true);
      this._setCloseHandlers();
      if (this._anchor) {
        this._anchor.nativeElement.focus();
        if (this.display === 'dynamic') {
          this._ngZone.runOutsideAngular(() => {
            this._positioning.createPopper({
              hostElement: this._anchor.nativeElement,
              targetElement: this._bodyContainer || this._menu.nativeElement,
              placement: this.placement,
              appendToBody: this.container === 'body',
              updatePopperOptions: options => this.popperOptions(addPopperOffset([0, 2])(options))
            });
            this._applyPlacementClasses();
            this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positionMenu());
          });
        }
      }
    }
  }
  _setCloseHandlers() {
    this._destroyCloseHandlers$.next(); // destroy any existing close handlers
    ngbAutoClose(this._ngZone, this._document, this.autoClose, source => {
      this.close();
      if (source === 0 /* SOURCE.ESCAPE */) {
        this._anchor.nativeElement.focus();
      }
    }, this._destroyCloseHandlers$, this._menu ? [this._menu.nativeElement] : [], this._anchor ? [this._anchor.nativeElement] : [], '.dropdown-item,.dropdown-divider');
  }
  /**
   * Closes the dropdown menu.
   */
  close() {
    if (this._open) {
      this._open = false;
      this._resetContainer();
      this._positioning.destroy();
      this._zoneSubscription?.unsubscribe();
      this._destroyCloseHandlers$.next();
      this.openChange.emit(false);
      this._changeDetector.markForCheck();
    }
  }
  /**
   * Toggles the dropdown menu.
   */
  toggle() {
    if (this.isOpen()) {
      this.close();
    } else {
      this.open();
    }
  }
  ngOnDestroy() {
    this.close();
  }
  onKeyDown(event) {
    /* eslint-disable-next-line deprecation/deprecation */
    const key = event.which;
    const itemElements = this._getMenuElements();
    let position = -1;
    let itemElement = null;
    const isEventFromToggle = this._isEventFromToggle(event);
    if (!isEventFromToggle && itemElements.length) {
      itemElements.forEach((item, index) => {
        if (item.contains(event.target)) {
          itemElement = item;
        }
        if (item === getActiveElement(this._document)) {
          position = index;
        }
      });
    }
    // closing on Enter / Space
    if (key === Key.Space || key === Key.Enter) {
      if (itemElement && (this.autoClose === true || this.autoClose === 'inside')) {
        // Item is either a button or a link, so click will be triggered by the browser on Enter or Space.
        // So we have to register a one-time click handler that will fire after any user defined click handlers
        // to close the dropdown
        (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(itemElement, 'click').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => this.close());
      }
      return;
    }
    if (key === Key.Tab) {
      if (event.target && this.isOpen() && this.autoClose) {
        if (this._anchor.nativeElement === event.target) {
          if (this.container === 'body' && !event.shiftKey) {
            /* This case is special: user is using [Tab] from the anchor/toggle.
            User expects the next focusable element in the dropdown menu to get focus.
            But the menu is not a sibling to anchor/toggle, it is at the end of the body.
            Trick is to synchronously focus the menu element, and let the [keydown.Tab] go
            so that browser will focus the proper element (first one focusable in the menu) */
            this._menu.nativeElement.setAttribute('tabindex', '0');
            this._menu.nativeElement.focus();
            this._menu.nativeElement.removeAttribute('tabindex');
          } else if (event.shiftKey) {
            this.close();
          }
          return;
        } else if (this.container === 'body') {
          const focusableElements = this._menu.nativeElement.querySelectorAll(FOCUSABLE_ELEMENTS_SELECTOR);
          if (event.shiftKey && event.target === focusableElements[0]) {
            this._anchor.nativeElement.focus();
            event.preventDefault();
          } else if (!event.shiftKey && event.target === focusableElements[focusableElements.length - 1]) {
            this._anchor.nativeElement.focus();
            this.close();
          }
        } else {
          (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(event.target, 'focusout').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(({
            relatedTarget
          }) => {
            if (!this._nativeElement.contains(relatedTarget)) {
              this.close();
            }
          });
        }
      }
      return;
    }
    // opening / navigating
    if (isEventFromToggle || itemElement) {
      this.open();
      if (itemElements.length) {
        switch (key) {
          case Key.ArrowDown:
            position = Math.min(position + 1, itemElements.length - 1);
            break;
          case Key.ArrowUp:
            if (this._isDropup() && position === -1) {
              position = itemElements.length - 1;
              break;
            }
            position = Math.max(position - 1, 0);
            break;
          case Key.Home:
            position = 0;
            break;
          case Key.End:
            position = itemElements.length - 1;
            break;
        }
        itemElements[position].focus();
      }
      event.preventDefault();
    }
  }
  _isDropup() {
    return this._nativeElement.classList.contains('dropup');
  }
  _isEventFromToggle(event) {
    return this._anchor.nativeElement.contains(event.target);
  }
  _getMenuElements() {
    return this._menu ? this._menu.menuItems.filter(({
      disabled
    }) => !disabled).map(({
      nativeElement
    }) => nativeElement) : [];
  }
  _positionMenu() {
    const menu = this._menu;
    if (this.isOpen() && menu) {
      if (this.display === 'dynamic') {
        this._positioning.update();
        this._applyPlacementClasses();
      } else {
        this._applyPlacementClasses(this._getFirstPlacement(this.placement));
      }
    }
  }
  _getFirstPlacement(placement) {
    return Array.isArray(placement) ? placement[0] : placement.split(' ')[0];
  }
  _resetContainer() {
    if (this._menu) {
      this._nativeElement.appendChild(this._menu.nativeElement);
    }
    if (this._bodyContainer) {
      this._document.body.removeChild(this._bodyContainer);
      this._bodyContainer = null;
    }
  }
  _applyContainer(container = null) {
    this._resetContainer();
    if (container === 'body') {
      const dropdownMenuElement = this._menu.nativeElement;
      const bodyContainer = this._bodyContainer = this._bodyContainer || this._document.createElement('div');
      // Override some styles to have the positioning working
      bodyContainer.style.position = 'absolute';
      dropdownMenuElement.style.position = 'static';
      bodyContainer.style.zIndex = '1055';
      bodyContainer.appendChild(dropdownMenuElement);
      this._document.body.appendChild(bodyContainer);
    }
    this._applyCustomDropdownClass(this.dropdownClass);
  }
  _applyCustomDropdownClass(newClass, oldClass) {
    const targetElement = this.container === 'body' ? this._bodyContainer : this._nativeElement;
    if (targetElement) {
      if (oldClass) {
        targetElement.classList.remove(oldClass);
      }
      if (newClass) {
        targetElement.classList.add(newClass);
      }
    }
  }
  _applyPlacementClasses(placement) {
    if (this._menu) {
      if (!placement) {
        placement = this._getFirstPlacement(this.placement);
      }
      // remove the current placement classes
      this._nativeElement.classList.remove('dropup', 'dropdown');
      if (this.display === 'static') {
        this._menu.nativeElement.setAttribute('data-bs-popper', 'static');
      } else {
        this._menu.nativeElement.removeAttribute('data-bs-popper');
      }
      /*
       * apply the new placement
       * in case of top use up-arrow or down-arrow otherwise
       */
      const dropdownClass = placement.search('^top') !== -1 ? 'dropup' : 'dropdown';
      this._nativeElement.classList.add(dropdownClass);
      if (this._bodyContainer) {
        this._bodyContainer.classList.remove('dropup', 'dropdown');
        this._bodyContainer.classList.add(dropdownClass);
      }
    }
  }
  static {
    this.ɵfac = function NgbDropdown_Factory(t) {
      return new (t || NgbDropdown)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbDropdown,
      selectors: [["", "ngbDropdown", ""]],
      contentQueries: function NgbDropdown_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbDropdownMenu, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbDropdownAnchor, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._menu = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._anchor = _t.first);
        }
      },
      hostVars: 2,
      hostBindings: function NgbDropdown_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("show", ctx.isOpen());
        }
      },
      inputs: {
        autoClose: "autoClose",
        dropdownClass: "dropdownClass",
        _open: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "open", "_open"],
        placement: "placement",
        popperOptions: "popperOptions",
        container: "container",
        display: "display"
      },
      outputs: {
        openChange: "openChange"
      },
      exportAs: ["ngbDropdown"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdown, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbDropdown]',
      exportAs: 'ngbDropdown',
      standalone: true,
      host: {
        '[class.show]': 'isOpen()'
      }
    }]
  }], null, {
    _menu: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbDropdownMenu, {
        static: false
      }]
    }],
    _anchor: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbDropdownAnchor, {
        static: false
      }]
    }],
    autoClose: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dropdownClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    _open: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['open']
    }],
    placement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popperOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    display: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    openChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
const NGB_DROPDOWN_DIRECTIVES = [NgbDropdown, NgbDropdownAnchor, NgbDropdownToggle, NgbDropdownMenu, NgbDropdownItem, NgbDropdownButtonItem];
class NgbDropdownModule {
  static {
    this.ɵfac = function NgbDropdownModule_Factory(t) {
      return new (t || NgbDropdownModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbDropdownModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbDropdownModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: NGB_DROPDOWN_DIRECTIVES,
      exports: NGB_DROPDOWN_DIRECTIVES
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbModal`](#/components/modal/api#NgbModal) service.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all modals used in the application.
 *
 * @since 3.1.0
 */
class NgbModalConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.backdrop = true;
    this.fullscreen = false;
    this.keyboard = true;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbModalConfig_Factory(t) {
      return new (t || NgbModalConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbModalConfig,
      factory: NgbModalConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModalConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class ContentRef {
  constructor(nodes, viewRef, componentRef) {
    this.nodes = nodes;
    this.viewRef = viewRef;
    this.componentRef = componentRef;
  }
}
class PopupService {
  constructor(_componentType) {
    this._componentType = _componentType;
    this._windowRef = null;
    this._contentRef = null;
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._applicationRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef);
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._viewContainerRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewContainerRef);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  }
  open(content, templateContext, animation = false) {
    if (!this._windowRef) {
      this._contentRef = this._getContentRef(content, templateContext);
      this._windowRef = this._viewContainerRef.createComponent(this._componentType, {
        injector: this._injector,
        projectableNodes: this._contentRef.nodes
      });
    }
    const {
      nativeElement
    } = this._windowRef.location;
    const transition$ = this._ngZone.onStable.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_32__.mergeMap)(() => ngbRunTransition(this._ngZone, nativeElement, ({
      classList
    }) => classList.add('show'), {
      animation,
      runningTransition: 'continue'
    })));
    return {
      windowRef: this._windowRef,
      transition$
    };
  }
  close(animation = false) {
    if (!this._windowRef) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(undefined);
    }
    return ngbRunTransition(this._ngZone, this._windowRef.location.nativeElement, ({
      classList
    }) => classList.remove('show'), {
      animation,
      runningTransition: 'stop'
    }).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.tap)(() => {
      if (this._windowRef) {
        // this is required because of the container='body' option
        this._viewContainerRef.remove(this._viewContainerRef.indexOf(this._windowRef.hostView));
        this._windowRef = null;
      }
      if (this._contentRef?.viewRef) {
        this._applicationRef.detachView(this._contentRef.viewRef);
        this._contentRef.viewRef.destroy();
        this._contentRef = null;
      }
    }));
  }
  _getContentRef(content, templateContext) {
    if (!content) {
      return new ContentRef([]);
    } else if (content instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef) {
      const viewRef = content.createEmbeddedView(templateContext);
      this._applicationRef.attachView(viewRef);
      return new ContentRef([viewRef.rootNodes], viewRef);
    } else {
      return new ContentRef([[this._document.createTextNode(`${content}`)]]);
    }
  }
}

/**
 * Utility to handle the scrollbar.
 *
 * It allows to hide the scrollbar and compensate the lack of a vertical scrollbar
 * by adding an equivalent padding on the right of the body, and to revert this change.
 */
class ScrollBar {
  constructor() {
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
  }
  /**
   * To be called to hide a potential vertical scrollbar:
   * - if a scrollbar is there and has a width greater than 0, adds some compensation
   * padding to the body to keep the same layout as when the scrollbar is there
   * - adds overflow: hidden
   *
   * @return a callback used to revert the change
   */
  hide() {
    const scrollbarWidth = Math.abs(window.innerWidth - this._document.documentElement.clientWidth);
    const body = this._document.body;
    const bodyStyle = body.style;
    const {
      overflow,
      paddingRight
    } = bodyStyle;
    if (scrollbarWidth > 0) {
      const actualPadding = parseFloat(window.getComputedStyle(body).paddingRight);
      bodyStyle.paddingRight = `${actualPadding + scrollbarWidth}px`;
    }
    bodyStyle.overflow = 'hidden';
    return () => {
      if (scrollbarWidth > 0) {
        bodyStyle.paddingRight = paddingRight;
      }
      bodyStyle.overflow = overflow;
    };
  }
  static {
    this.ɵfac = function ScrollBar_Factory(t) {
      return new (t || ScrollBar)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ScrollBar,
      factory: ScrollBar.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ScrollBar, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class NgbModalBackdrop {
  constructor() {
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  }
  ngOnInit() {
    this._zone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      ngbRunTransition(this._zone, this._nativeElement, (element, animation) => {
        if (animation) {
          reflow(element);
        }
        element.classList.add('show');
      }, {
        animation: this.animation,
        runningTransition: 'continue'
      });
    });
  }
  hide() {
    return ngbRunTransition(this._zone, this._nativeElement, ({
      classList
    }) => classList.remove('show'), {
      animation: this.animation,
      runningTransition: 'stop'
    });
  }
  static {
    this.ɵfac = function NgbModalBackdrop_Factory(t) {
      return new (t || NgbModalBackdrop)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbModalBackdrop,
      selectors: [["ngb-modal-backdrop"]],
      hostAttrs: [2, "z-index", "1055"],
      hostVars: 6,
      hostBindings: function NgbModalBackdrop_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("modal-backdrop" + (ctx.backdropClass ? " " + ctx.backdropClass : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("show", !ctx.animation)("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        backdropClass: "backdropClass"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 0,
      vars: 0,
      template: function NgbModalBackdrop_Template(rf, ctx) {},
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModalBackdrop, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-modal-backdrop',
      standalone: true,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: '',
      host: {
        '[class]': '"modal-backdrop" + (backdropClass ? " " + backdropClass : "")',
        '[class.show]': '!animation',
        '[class.fade]': 'animation',
        style: 'z-index: 1055'
      }
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    backdropClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();

/**
 * A reference to the currently opened (active) modal.
 *
 * Instances of this class can be injected into your component passed as modal content.
 * So you can `.update()`, `.close()` or `.dismiss()` the modal window from your component.
 */
class NgbActiveModal {
  /**
   * Updates options of an opened modal.
   *
   * @since 14.2.0
   */
  update(options) {}
  /**
   * Closes the modal with an optional `result` value.
   *
   * The `NgbModalRef.result` promise will be resolved with the provided value.
   */
  close(result) {}
  /**
   * Dismisses the modal with an optional `reason` value.
   *
   * The `NgbModalRef.result` promise will be rejected with the provided value.
   */
  dismiss(reason) {}
}
const WINDOW_ATTRIBUTES = ['animation', 'ariaLabelledBy', 'ariaDescribedBy', 'backdrop', 'centered', 'fullscreen', 'keyboard', 'scrollable', 'size', 'windowClass', 'modalDialogClass'];
const BACKDROP_ATTRIBUTES = ['animation', 'backdropClass'];
/**
 * A reference to the newly opened modal returned by the `NgbModal.open()` method.
 */
class NgbModalRef {
  _applyWindowOptions(windowInstance, options) {
    WINDOW_ATTRIBUTES.forEach(optionName => {
      if (isDefined(options[optionName])) {
        windowInstance[optionName] = options[optionName];
      }
    });
  }
  _applyBackdropOptions(backdropInstance, options) {
    BACKDROP_ATTRIBUTES.forEach(optionName => {
      if (isDefined(options[optionName])) {
        backdropInstance[optionName] = options[optionName];
      }
    });
  }
  /**
   * Updates options of an opened modal.
   *
   * @since 14.2.0
   */
  update(options) {
    this._applyWindowOptions(this._windowCmptRef.instance, options);
    if (this._backdropCmptRef && this._backdropCmptRef.instance) {
      this._applyBackdropOptions(this._backdropCmptRef.instance, options);
    }
  }
  /**
   * The instance of a component used for the modal content.
   *
   * When a `TemplateRef` is used as the content or when the modal is closed, will return `undefined`.
   */
  get componentInstance() {
    if (this._contentRef && this._contentRef.componentRef) {
      return this._contentRef.componentRef.instance;
    }
  }
  /**
   * The observable that emits when the modal is closed via the `.close()` method.
   *
   * It will emit the result passed to the `.close()` method.
   *
   * @since 8.0.0
   */
  get closed() {
    return this._closed.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._hidden));
  }
  /**
   * The observable that emits when the modal is dismissed via the `.dismiss()` method.
   *
   * It will emit the reason passed to the `.dismissed()` method by the user, or one of the internal
   * reasons like backdrop click or ESC key press.
   *
   * @since 8.0.0
   */
  get dismissed() {
    return this._dismissed.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._hidden));
  }
  /**
   * The observable that emits when both modal window and backdrop are closed and animations were finished.
   * At this point modal and backdrop elements will be removed from the DOM tree.
   *
   * This observable will be completed after emitting.
   *
   * @since 8.0.0
   */
  get hidden() {
    return this._hidden.asObservable();
  }
  /**
   * The observable that emits when modal is fully visible and animation was finished.
   * Modal DOM element is always available synchronously after calling 'modal.open()' service.
   *
   * This observable will be completed after emitting.
   * It will not emit, if modal is closed before open animation is finished.
   *
   * @since 8.0.0
   */
  get shown() {
    return this._windowCmptRef.instance.shown.asObservable();
  }
  constructor(_windowCmptRef, _contentRef, _backdropCmptRef, _beforeDismiss) {
    this._windowCmptRef = _windowCmptRef;
    this._contentRef = _contentRef;
    this._backdropCmptRef = _backdropCmptRef;
    this._beforeDismiss = _beforeDismiss;
    this._closed = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._dismissed = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._hidden = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    _windowCmptRef.instance.dismissEvent.subscribe(reason => {
      this.dismiss(reason);
    });
    this.result = new Promise((resolve, reject) => {
      this._resolve = resolve;
      this._reject = reject;
    });
    this.result.then(null, () => {});
  }
  /**
   * Closes the modal with an optional `result` value.
   *
   * The `NgbMobalRef.result` promise will be resolved with the provided value.
   */
  close(result) {
    if (this._windowCmptRef) {
      this._closed.next(result);
      this._resolve(result);
      this._removeModalElements();
    }
  }
  _dismiss(reason) {
    this._dismissed.next(reason);
    this._reject(reason);
    this._removeModalElements();
  }
  /**
   * Dismisses the modal with an optional `reason` value.
   *
   * The `NgbModalRef.result` promise will be rejected with the provided value.
   */
  dismiss(reason) {
    if (this._windowCmptRef) {
      if (!this._beforeDismiss) {
        this._dismiss(reason);
      } else {
        const dismiss = this._beforeDismiss();
        if (isPromise(dismiss)) {
          dismiss.then(result => {
            if (result !== false) {
              this._dismiss(reason);
            }
          }, () => {});
        } else if (dismiss !== false) {
          this._dismiss(reason);
        }
      }
    }
  }
  _removeModalElements() {
    const windowTransition$ = this._windowCmptRef.instance.hide();
    const backdropTransition$ = this._backdropCmptRef ? this._backdropCmptRef.instance.hide() : (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(undefined);
    // hiding window
    windowTransition$.subscribe(() => {
      const {
        nativeElement
      } = this._windowCmptRef.location;
      nativeElement.parentNode.removeChild(nativeElement);
      this._windowCmptRef.destroy();
      if (this._contentRef && this._contentRef.viewRef) {
        this._contentRef.viewRef.destroy();
      }
      this._windowCmptRef = null;
      this._contentRef = null;
    });
    // hiding backdrop
    backdropTransition$.subscribe(() => {
      if (this._backdropCmptRef) {
        const {
          nativeElement
        } = this._backdropCmptRef.location;
        nativeElement.parentNode.removeChild(nativeElement);
        this._backdropCmptRef.destroy();
        this._backdropCmptRef = null;
      }
    });
    // all done
    (0,rxjs__WEBPACK_IMPORTED_MODULE_21__.zip)(windowTransition$, backdropTransition$).subscribe(() => {
      this._hidden.next();
      this._hidden.complete();
    });
  }
}
var ModalDismissReasons;
(function (ModalDismissReasons) {
  ModalDismissReasons[ModalDismissReasons["BACKDROP_CLICK"] = 0] = "BACKDROP_CLICK";
  ModalDismissReasons[ModalDismissReasons["ESC"] = 1] = "ESC";
})(ModalDismissReasons || (ModalDismissReasons = {}));
class NgbModalWindow {
  constructor() {
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._elRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._closed$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._elWithFocus = null; // element that is focused prior to modal opening
    this.backdrop = true;
    this.keyboard = true;
    this.dismissEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.shown = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this.hidden = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
  }
  get fullscreenClass() {
    return this.fullscreen === true ? ' modal-fullscreen' : isString(this.fullscreen) ? ` modal-fullscreen-${this.fullscreen}-down` : '';
  }
  dismiss(reason) {
    this.dismissEvent.emit(reason);
  }
  ngOnInit() {
    this._elWithFocus = this._document.activeElement;
    this._zone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      this._show();
    });
  }
  ngOnDestroy() {
    this._disableEventHandling();
  }
  hide() {
    const {
      nativeElement
    } = this._elRef;
    const context = {
      animation: this.animation,
      runningTransition: 'stop'
    };
    const windowTransition$ = ngbRunTransition(this._zone, nativeElement, () => nativeElement.classList.remove('show'), context);
    const dialogTransition$ = ngbRunTransition(this._zone, this._dialogEl.nativeElement, () => {}, context);
    const transitions$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_21__.zip)(windowTransition$, dialogTransition$);
    transitions$.subscribe(() => {
      this.hidden.next();
      this.hidden.complete();
    });
    this._disableEventHandling();
    this._restoreFocus();
    return transitions$;
  }
  _show() {
    const context = {
      animation: this.animation,
      runningTransition: 'continue'
    };
    const windowTransition$ = ngbRunTransition(this._zone, this._elRef.nativeElement, (element, animation) => {
      if (animation) {
        reflow(element);
      }
      element.classList.add('show');
    }, context);
    const dialogTransition$ = ngbRunTransition(this._zone, this._dialogEl.nativeElement, () => {}, context);
    (0,rxjs__WEBPACK_IMPORTED_MODULE_21__.zip)(windowTransition$, dialogTransition$).subscribe(() => {
      this.shown.next();
      this.shown.complete();
    });
    this._enableEventHandling();
    this._setFocus();
  }
  _enableEventHandling() {
    const {
      nativeElement
    } = this._elRef;
    this._zone.runOutsideAngular(() => {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(nativeElement, 'keydown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._closed$), /* eslint-disable-next-line deprecation/deprecation */
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(e => e.which === Key.Escape)).subscribe(event => {
        if (this.keyboard) {
          requestAnimationFrame(() => {
            if (!event.defaultPrevented) {
              this._zone.run(() => this.dismiss(ModalDismissReasons.ESC));
            }
          });
        } else if (this.backdrop === 'static') {
          this._bumpBackdrop();
        }
      });
      // We're listening to 'mousedown' and 'mouseup' to prevent modal from closing when pressing the mouse
      // inside the modal dialog and releasing it outside
      let preventClose = false;
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(this._dialogEl.nativeElement, 'mousedown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._closed$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.tap)(() => preventClose = false), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_18__.switchMap)(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(nativeElement, 'mouseup').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._closed$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1))), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(({
        target
      }) => nativeElement === target)).subscribe(() => {
        preventClose = true;
      });
      // We're listening to 'click' to dismiss modal on modal window click, except when:
      // 1. clicking on modal dialog itself
      // 2. closing was prevented by mousedown/up handlers
      // 3. clicking on scrollbar when the viewport is too small and modal doesn't fit (click is not triggered at all)
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(nativeElement, 'click').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._closed$)).subscribe(({
        target
      }) => {
        if (nativeElement === target) {
          if (this.backdrop === 'static') {
            this._bumpBackdrop();
          } else if (this.backdrop === true && !preventClose) {
            this._zone.run(() => this.dismiss(ModalDismissReasons.BACKDROP_CLICK));
          }
        }
        preventClose = false;
      });
    });
  }
  _disableEventHandling() {
    this._closed$.next();
  }
  _setFocus() {
    const {
      nativeElement
    } = this._elRef;
    if (!nativeElement.contains(document.activeElement)) {
      const autoFocusable = nativeElement.querySelector(`[ngbAutofocus]`);
      const firstFocusable = getFocusableBoundaryElements(nativeElement)[0];
      const elementToFocus = autoFocusable || firstFocusable || nativeElement;
      elementToFocus.focus();
    }
  }
  _restoreFocus() {
    const body = this._document.body;
    const elWithFocus = this._elWithFocus;
    let elementToFocus;
    if (elWithFocus && elWithFocus['focus'] && body.contains(elWithFocus)) {
      elementToFocus = elWithFocus;
    } else {
      elementToFocus = body;
    }
    this._zone.runOutsideAngular(() => {
      setTimeout(() => elementToFocus.focus());
      this._elWithFocus = null;
    });
  }
  _bumpBackdrop() {
    if (this.backdrop === 'static') {
      ngbRunTransition(this._zone, this._elRef.nativeElement, ({
        classList
      }) => {
        classList.add('modal-static');
        return () => classList.remove('modal-static');
      }, {
        animation: this.animation,
        runningTransition: 'continue'
      });
    }
  }
  static {
    this.ɵfac = function NgbModalWindow_Factory(t) {
      return new (t || NgbModalWindow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbModalWindow,
      selectors: [["ngb-modal-window"]],
      viewQuery: function NgbModalWindow_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c7, 7);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._dialogEl = _t.first);
        }
      },
      hostAttrs: ["role", "dialog", "tabindex", "-1"],
      hostVars: 7,
      hostBindings: function NgbModalWindow_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-modal", true)("aria-labelledby", ctx.ariaLabelledBy)("aria-describedby", ctx.ariaDescribedBy);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("modal d-block" + (ctx.windowClass ? " " + ctx.windowClass : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        ariaLabelledBy: "ariaLabelledBy",
        ariaDescribedBy: "ariaDescribedBy",
        backdrop: "backdrop",
        centered: "centered",
        fullscreen: "fullscreen",
        keyboard: "keyboard",
        scrollable: "scrollable",
        size: "size",
        windowClass: "windowClass",
        modalDialogClass: "modalDialogClass"
      },
      outputs: {
        dismissEvent: "dismiss"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 4,
      vars: 2,
      consts: [["dialog", ""], ["role", "document"], [1, "modal-content"]],
      template: function NgbModalWindow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 1, 0)(2, "div", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("modal-dialog" + (ctx.size ? " modal-" + ctx.size : "") + (ctx.centered ? " modal-dialog-centered" : "") + ctx.fullscreenClass + (ctx.scrollable ? " modal-dialog-scrollable" : "") + (ctx.modalDialogClass ? " " + ctx.modalDialogClass : ""));
        }
      },
      styles: ["ngb-modal-window .component-host-scrollable{display:flex;flex-direction:column;overflow:hidden}\n"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModalWindow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-modal-window',
      standalone: true,
      host: {
        '[class]': '"modal d-block" + (windowClass ? " " + windowClass : "")',
        '[class.fade]': 'animation',
        role: 'dialog',
        tabindex: '-1',
        '[attr.aria-modal]': 'true',
        '[attr.aria-labelledby]': 'ariaLabelledBy',
        '[attr.aria-describedby]': 'ariaDescribedBy'
      },
      template: `
		<div
			#dialog
			[class]="
				'modal-dialog' +
				(size ? ' modal-' + size : '') +
				(centered ? ' modal-dialog-centered' : '') +
				fullscreenClass +
				(scrollable ? ' modal-dialog-scrollable' : '') +
				(modalDialogClass ? ' ' + modalDialogClass : '')
			"
			role="document"
		>
			<div class="modal-content"><ng-content /></div>
		</div>
	`,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      styles: ["ngb-modal-window .component-host-scrollable{display:flex;flex-direction:column;overflow:hidden}\n"]
    }]
  }], null, {
    _dialogEl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['dialog', {
        static: true
      }]
    }],
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaLabelledBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaDescribedBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    backdrop: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    centered: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    fullscreen: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    keyboard: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    scrollable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    size: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    windowClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    modalDialogClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dismissEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['dismiss']
    }]
  });
})();
class NgbModalStack {
  constructor() {
    this._applicationRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef);
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._environmentInjector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._scrollBar = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ScrollBar);
    this._activeWindowCmptHasChanged = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._ariaHiddenValues = new Map();
    this._scrollBarRestoreFn = null;
    this._modalRefs = [];
    this._windowCmpts = [];
    this._activeInstances = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    const ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    // Trap focus on active WindowCmpt
    this._activeWindowCmptHasChanged.subscribe(() => {
      if (this._windowCmpts.length) {
        const activeWindowCmpt = this._windowCmpts[this._windowCmpts.length - 1];
        ngbFocusTrap(ngZone, activeWindowCmpt.location.nativeElement, this._activeWindowCmptHasChanged);
        this._revertAriaHidden();
        this._setAriaHidden(activeWindowCmpt.location.nativeElement);
      }
    });
  }
  _restoreScrollBar() {
    const scrollBarRestoreFn = this._scrollBarRestoreFn;
    if (scrollBarRestoreFn) {
      this._scrollBarRestoreFn = null;
      scrollBarRestoreFn();
    }
  }
  _hideScrollBar() {
    if (!this._scrollBarRestoreFn) {
      this._scrollBarRestoreFn = this._scrollBar.hide();
    }
  }
  open(contentInjector, content, options) {
    const containerEl = options.container instanceof HTMLElement ? options.container : isDefined(options.container) ? this._document.querySelector(options.container) : this._document.body;
    if (!containerEl) {
      throw new Error(`The specified modal container "${options.container || 'body'}" was not found in the DOM.`);
    }
    this._hideScrollBar();
    const activeModal = new NgbActiveModal();
    contentInjector = options.injector || contentInjector;
    const environmentInjector = contentInjector.get(_angular_core__WEBPACK_IMPORTED_MODULE_0__.EnvironmentInjector, null) || this._environmentInjector;
    const contentRef = this._getContentRef(contentInjector, environmentInjector, content, activeModal, options);
    let backdropCmptRef = options.backdrop !== false ? this._attachBackdrop(containerEl) : undefined;
    let windowCmptRef = this._attachWindowComponent(containerEl, contentRef.nodes);
    let ngbModalRef = new NgbModalRef(windowCmptRef, contentRef, backdropCmptRef, options.beforeDismiss);
    this._registerModalRef(ngbModalRef);
    this._registerWindowCmpt(windowCmptRef);
    // We have to cleanup DOM after the last modal when BOTH 'hidden' was emitted and 'result' promise was resolved:
    // - with animations OFF, 'hidden' emits synchronously, then 'result' is resolved asynchronously
    // - with animations ON, 'result' is resolved asynchronously, then 'hidden' emits asynchronously
    ngbModalRef.hidden.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => Promise.resolve(true).then(() => {
      if (!this._modalRefs.length) {
        this._document.body.classList.remove('modal-open');
        this._restoreScrollBar();
        this._revertAriaHidden();
      }
    }));
    activeModal.close = result => {
      ngbModalRef.close(result);
    };
    activeModal.dismiss = reason => {
      ngbModalRef.dismiss(reason);
    };
    activeModal.update = options => {
      ngbModalRef.update(options);
    };
    ngbModalRef.update(options);
    if (this._modalRefs.length === 1) {
      this._document.body.classList.add('modal-open');
    }
    if (backdropCmptRef && backdropCmptRef.instance) {
      backdropCmptRef.changeDetectorRef.detectChanges();
    }
    windowCmptRef.changeDetectorRef.detectChanges();
    return ngbModalRef;
  }
  get activeInstances() {
    return this._activeInstances;
  }
  dismissAll(reason) {
    this._modalRefs.forEach(ngbModalRef => ngbModalRef.dismiss(reason));
  }
  hasOpenModals() {
    return this._modalRefs.length > 0;
  }
  _attachBackdrop(containerEl) {
    let backdropCmptRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(NgbModalBackdrop, {
      environmentInjector: this._applicationRef.injector,
      elementInjector: this._injector
    });
    this._applicationRef.attachView(backdropCmptRef.hostView);
    containerEl.appendChild(backdropCmptRef.location.nativeElement);
    return backdropCmptRef;
  }
  _attachWindowComponent(containerEl, projectableNodes) {
    let windowCmptRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(NgbModalWindow, {
      environmentInjector: this._applicationRef.injector,
      elementInjector: this._injector,
      projectableNodes
    });
    this._applicationRef.attachView(windowCmptRef.hostView);
    containerEl.appendChild(windowCmptRef.location.nativeElement);
    return windowCmptRef;
  }
  _getContentRef(contentInjector, environmentInjector, content, activeModal, options) {
    if (!content) {
      return new ContentRef([]);
    } else if (content instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef) {
      return this._createFromTemplateRef(content, activeModal);
    } else if (isString(content)) {
      return this._createFromString(content);
    } else {
      return this._createFromComponent(contentInjector, environmentInjector, content, activeModal, options);
    }
  }
  _createFromTemplateRef(templateRef, activeModal) {
    const context = {
      $implicit: activeModal,
      close(result) {
        activeModal.close(result);
      },
      dismiss(reason) {
        activeModal.dismiss(reason);
      }
    };
    const viewRef = templateRef.createEmbeddedView(context);
    this._applicationRef.attachView(viewRef);
    return new ContentRef([viewRef.rootNodes], viewRef);
  }
  _createFromString(content) {
    const component = this._document.createTextNode(`${content}`);
    return new ContentRef([[component]]);
  }
  _createFromComponent(contentInjector, environmentInjector, componentType, context, options) {
    const elementInjector = _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector.create({
      providers: [{
        provide: NgbActiveModal,
        useValue: context
      }],
      parent: contentInjector
    });
    const componentRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(componentType, {
      environmentInjector,
      elementInjector
    });
    const componentNativeEl = componentRef.location.nativeElement;
    if (options.scrollable) {
      componentNativeEl.classList.add('component-host-scrollable');
    }
    this._applicationRef.attachView(componentRef.hostView);
    // FIXME: we should here get rid of the component nativeElement
    // and use `[Array.from(componentNativeEl.childNodes)]` instead and remove the above CSS class.
    return new ContentRef([[componentNativeEl]], componentRef.hostView, componentRef);
  }
  _setAriaHidden(element) {
    const parent = element.parentElement;
    if (parent && element !== this._document.body) {
      Array.from(parent.children).forEach(sibling => {
        if (sibling !== element && sibling.nodeName !== 'SCRIPT') {
          this._ariaHiddenValues.set(sibling, sibling.getAttribute('aria-hidden'));
          sibling.setAttribute('aria-hidden', 'true');
        }
      });
      this._setAriaHidden(parent);
    }
  }
  _revertAriaHidden() {
    this._ariaHiddenValues.forEach((value, element) => {
      if (value) {
        element.setAttribute('aria-hidden', value);
      } else {
        element.removeAttribute('aria-hidden');
      }
    });
    this._ariaHiddenValues.clear();
  }
  _registerModalRef(ngbModalRef) {
    const unregisterModalRef = () => {
      const index = this._modalRefs.indexOf(ngbModalRef);
      if (index > -1) {
        this._modalRefs.splice(index, 1);
        this._activeInstances.emit(this._modalRefs);
      }
    };
    this._modalRefs.push(ngbModalRef);
    this._activeInstances.emit(this._modalRefs);
    ngbModalRef.result.then(unregisterModalRef, unregisterModalRef);
  }
  _registerWindowCmpt(ngbWindowCmpt) {
    this._windowCmpts.push(ngbWindowCmpt);
    this._activeWindowCmptHasChanged.next();
    ngbWindowCmpt.onDestroy(() => {
      const index = this._windowCmpts.indexOf(ngbWindowCmpt);
      if (index > -1) {
        this._windowCmpts.splice(index, 1);
        this._activeWindowCmptHasChanged.next();
      }
    });
  }
  static {
    this.ɵfac = function NgbModalStack_Factory(t) {
      return new (t || NgbModalStack)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbModalStack,
      factory: NgbModalStack.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModalStack, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();

/**
 * A service for opening modal windows.
 *
 * Creating a modal is straightforward: create a component or a template and pass it as an argument to
 * the `.open()` method.
 */
class NgbModal {
  constructor() {
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._modalStack = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbModalStack);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbModalConfig);
  }
  /**
   * Opens a new modal window with the specified content and supplied options.
   *
   * Content can be provided as a `TemplateRef` or a component type. If you pass a component type as content,
   * then instances of those components can be injected with an instance of the `NgbActiveModal` class. You can then
   * use `NgbActiveModal` methods to close / dismiss modals from "inside" of your component.
   *
   * Also see the [`NgbModalOptions`](#/components/modal/api#NgbModalOptions) for the list of supported options.
   */
  open(content, options = {}) {
    const combinedOptions = {
      ...this._config,
      animation: this._config.animation,
      ...options
    };
    return this._modalStack.open(this._injector, content, combinedOptions);
  }
  /**
   * Returns an observable that holds the active modal instances.
   */
  get activeInstances() {
    return this._modalStack.activeInstances;
  }
  /**
   * Dismisses all currently displayed modal windows with the supplied reason.
   *
   * @since 3.1.0
   */
  dismissAll(reason) {
    this._modalStack.dismissAll(reason);
  }
  /**
   * Indicates if there are currently any open modal windows in the application.
   *
   * @since 3.3.0
   */
  hasOpenModals() {
    return this._modalStack.hasOpenModals();
  }
  static {
    this.ɵfac = function NgbModal_Factory(t) {
      return new (t || NgbModal)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbModal,
      factory: NgbModal.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModal, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class NgbModalModule {
  static {
    this.ɵfac = function NgbModalModule_Factory(t) {
      return new (t || NgbModalModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbModalModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: [NgbModal]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModalModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      providers: [NgbModal]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbNav`](#/components/nav/api#NgbNav) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the navs used in the application.
 *
 * @since 5.2.0
 */
class NgbNavConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.destroyOnHide = true;
    this.orientation = 'horizontal';
    this.roles = 'tablist';
    this.keyboard = true;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbNavConfig_Factory(t) {
      return new (t || NgbNavConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbNavConfig,
      factory: NgbNavConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const isValidNavId = id => isDefined(id) && id !== '';
let navCounter = 0;
/**
 * This directive must be used to wrap content to be displayed in the nav.
 *
 * @since 5.2.0
 */
class NgbNavContent {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbNavContent_Factory(t) {
      return new (t || NgbNavContent)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavContent,
      selectors: [["ng-template", "ngbNavContent", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavContent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbNavContent]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * This directive applies a specific role on a non-container based ngbNavItem.
 *
 * @since 14.1.0
 */
class NgbNavItemRole {
  constructor(role) {
    this.role = role;
    this.nav = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbNav);
  }
  static {
    this.ɵfac = function NgbNavItemRole_Factory(t) {
      return new (t || NgbNavItemRole)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('role'));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavItemRole,
      selectors: [["", "ngbNavItem", "", 5, "ng-container"]],
      hostVars: 1,
      hostBindings: function NgbNavItemRole_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("role", ctx.role ? ctx.role : ctx.nav.roles ? "presentation" : undefined);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavItemRole, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbNavItem]:not(ng-container)',
      standalone: true,
      host: {
        '[attr.role]': `role ? role : nav.roles ? 'presentation' : undefined`
      }
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['role']
    }]
  }], null);
})();
/**
 * The directive used to group nav link and related nav content. As well as set nav identifier and some options.
 *
 * @since 5.2.0
 */
class NgbNavItem {
  constructor() {
    this._nav = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbNav);
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    /**
     * If `true`, the current nav item is disabled and can't be toggled by user.
     *
     * Nevertheless disabled nav can be selected programmatically via the `.select()` method and the `[activeId]` binding.
     */
    this.disabled = false;
    /**
     * An event emitted when the fade in transition is finished on the related nav content
     *
     * @since 8.0.0
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the fade out transition is finished on the related nav content
     *
     * @since 8.0.0
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  ngAfterContentChecked() {
    // We are using @ContentChildren instead of @ContentChild as in the Angular version being used
    // only @ContentChildren allows us to specify the {descendants: false} option.
    // Without {descendants: false} we are hitting bugs described in:
    // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240
    this.contentTpl = this.contentTpls.first;
  }
  ngOnInit() {
    if (!isDefined(this.domId)) {
      this.domId = `ngb-nav-${navCounter++}`;
    }
  }
  get active() {
    return this._nav.activeId === this.id;
  }
  get id() {
    return isValidNavId(this._id) ? this._id : this.domId;
  }
  get panelDomId() {
    return `${this.domId}-panel`;
  }
  isPanelInDom() {
    return (isDefined(this.destroyOnHide) ? !this.destroyOnHide : !this._nav.destroyOnHide) || this.active;
  }
  /**
   * @internal
   */
  isNgContainer() {
    return this._nativeElement.nodeType === Node.COMMENT_NODE;
  }
  static {
    this.ɵfac = function NgbNavItem_Factory(t) {
      return new (t || NgbNavItem)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavItem,
      selectors: [["", "ngbNavItem", ""]],
      contentQueries: function NgbNavItem_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbNavContent, 4);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.contentTpls = _t);
        }
      },
      hostVars: 2,
      hostBindings: function NgbNavItem_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("nav-item", true);
        }
      },
      inputs: {
        destroyOnHide: "destroyOnHide",
        disabled: "disabled",
        domId: "domId",
        _id: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbNavItem", "_id"]
      },
      outputs: {
        shown: "shown",
        hidden: "hidden"
      },
      exportAs: ["ngbNavItem"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavItem, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbNavItem]',
      exportAs: 'ngbNavItem',
      standalone: true,
      host: {
        '[class.nav-item]': 'true'
      }
    }]
  }], null, {
    destroyOnHide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    domId: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    _id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbNavItem']
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    contentTpls: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbNavContent, {
        descendants: false
      }]
    }]
  });
})();
/**
 * A nav directive that helps with implementing tabbed navigation components.
 *
 * @since 5.2.0
 */
class NgbNav {
  constructor(role) {
    this.role = role;
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbNavConfig);
    this._cd = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this.destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._navigatingWithKeyboard = false;
    /**
     * The event emitted after the active nav changes
     * The payload of the event is the newly active nav id
     *
     * If you want to prevent nav change, you should use `(navChange)` event
     */
    this.activeIdChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * If `true`, nav change will be animated.
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * If `true`, non-active nav content will be removed from DOM
     * Otherwise it will just be hidden
     */
    this.destroyOnHide = this._config.destroyOnHide;
    /**
     * The orientation of navs.
     *
     * Using `vertical` will also add the `aria-orientation` attribute
     */
    this.orientation = this._config.orientation;
    /**
     * Role attribute generating strategy:
     * - `false` - no role attributes will be generated
     * - `'tablist'` - 'tablist', 'tab' and 'tabpanel' will be generated (default)
     */
    this.roles = this._config.roles;
    /**
     * Keyboard support for nav focus/selection using arrow keys.
     *
     * * `true` - navs will be focused using keyboard arrow keys
     * * `false` - no keyboard support
     * * `'changeWithArrows'` -  nav will be selected using keyboard arrow keys
     *
     * See the [list of available keyboard shortcuts](#/components/nav/overview#keyboard-shortcuts).
     *
     * @since 6.1.0
     */
    this.keyboard = this._config.keyboard;
    /**
     * An event emitted when the fade in transition is finished for one of the items.
     *
     * Payload of the event is the nav id that was just shown.
     *
     * @since 8.0.0
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the fade out transition is finished for one of the items.
     *
     * Payload of the event is the nav id that was just hidden.
     *
     * @since 8.0.0
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.navItemChange$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    /**
     * The nav change event emitted right before the nav change happens on user click.
     *
     * This event won't be emitted if nav is changed programmatically via `[activeId]` or `.select()`.
     *
     * See [`NgbNavChangeEvent`](#/components/nav/api#NgbNavChangeEvent) for payload details.
     */
    this.navChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  click(item) {
    if (!item.disabled) {
      this._updateActiveId(item.id);
    }
  }
  onFocusout({
    relatedTarget
  }) {
    if (!this._nativeElement.contains(relatedTarget)) {
      this._navigatingWithKeyboard = false;
    }
  }
  onKeyDown(event) {
    if (this.roles !== 'tablist' || !this.keyboard) {
      return;
    }
    /* eslint-disable-next-line deprecation/deprecation */
    const key = event.which;
    const enabledLinks = this.links.filter(link => !link.navItem.disabled);
    const {
      length
    } = enabledLinks;
    let position = -1;
    enabledLinks.forEach((link, index) => {
      if (link.nativeElement === this._document.activeElement) {
        position = index;
      }
    });
    if (length) {
      switch (key) {
        case Key.ArrowUp:
        case Key.ArrowLeft:
          position = (position - 1 + length) % length;
          break;
        case Key.ArrowRight:
        case Key.ArrowDown:
          position = (position + 1) % length;
          break;
        case Key.Home:
          position = 0;
          break;
        case Key.End:
          position = length - 1;
          break;
      }
      if (this.keyboard === 'changeWithArrows') {
        this.select(enabledLinks[position].navItem.id);
      }
      enabledLinks[position].nativeElement.focus();
      this._navigatingWithKeyboard = true;
      event.preventDefault();
    }
  }
  /**
   * Selects the nav with the given id and shows its associated pane.
   * Any other nav that was previously selected becomes unselected and its associated pane is hidden.
   */
  select(id) {
    this._updateActiveId(id, false);
  }
  ngAfterContentInit() {
    if (!isDefined(this.activeId)) {
      const nextId = this.items.first ? this.items.first.id : null;
      if (isValidNavId(nextId)) {
        this._updateActiveId(nextId, false);
        this._cd.detectChanges();
      }
    }
    this.items.changes.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this.destroyRef)).subscribe(() => this._notifyItemChanged(this.activeId));
  }
  ngOnChanges({
    activeId
  }) {
    if (activeId && !activeId.firstChange) {
      this._notifyItemChanged(activeId.currentValue);
    }
  }
  _updateActiveId(nextId, emitNavChange = true) {
    if (this.activeId !== nextId) {
      let defaultPrevented = false;
      if (emitNavChange) {
        this.navChange.emit({
          activeId: this.activeId,
          nextId,
          preventDefault: () => {
            defaultPrevented = true;
          }
        });
      }
      if (!defaultPrevented) {
        this.activeId = nextId;
        this.activeIdChange.emit(nextId);
        this._notifyItemChanged(nextId);
      }
    }
  }
  _notifyItemChanged(nextItemId) {
    this.navItemChange$.next(this._getItemById(nextItemId));
  }
  _getItemById(itemId) {
    return this.items && this.items.find(item => item.id === itemId) || null;
  }
  static {
    this.ɵfac = function NgbNav_Factory(t) {
      return new (t || NgbNav)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('role'));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNav,
      selectors: [["", "ngbNav", ""]],
      contentQueries: function NgbNav_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbNavItem, 4);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbNavLinkBase, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.items = _t);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.links = _t);
        }
      },
      hostVars: 6,
      hostBindings: function NgbNav_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("keydown.arrowLeft", function NgbNav_keydown_arrowLeft_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("keydown.arrowRight", function NgbNav_keydown_arrowRight_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("keydown.arrowDown", function NgbNav_keydown_arrowDown_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("keydown.arrowUp", function NgbNav_keydown_arrowUp_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("keydown.Home", function NgbNav_keydown_Home_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("keydown.End", function NgbNav_keydown_End_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          })("focusout", function NgbNav_focusout_HostBindingHandler($event) {
            return ctx.onFocusout($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-orientation", ctx.orientation === "vertical" && ctx.roles === "tablist" ? "vertical" : undefined)("role", ctx.role ? ctx.role : ctx.roles ? "tablist" : undefined);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("nav", true)("flex-column", ctx.orientation === "vertical");
        }
      },
      inputs: {
        activeId: "activeId",
        animation: "animation",
        destroyOnHide: "destroyOnHide",
        orientation: "orientation",
        roles: "roles",
        keyboard: "keyboard"
      },
      outputs: {
        activeIdChange: "activeIdChange",
        shown: "shown",
        hidden: "hidden",
        navChange: "navChange"
      },
      exportAs: ["ngbNav"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNav, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbNav]',
      exportAs: 'ngbNav',
      standalone: true,
      host: {
        '[class.nav]': 'true',
        '[class.flex-column]': `orientation === 'vertical'`,
        '[attr.aria-orientation]': `orientation === 'vertical' && roles === 'tablist' ? 'vertical' : undefined`,
        '[attr.role]': `role ? role : roles ? 'tablist' : undefined`,
        '(keydown.arrowLeft)': 'onKeyDown($event)',
        '(keydown.arrowRight)': 'onKeyDown($event)',
        '(keydown.arrowDown)': 'onKeyDown($event)',
        '(keydown.arrowUp)': 'onKeyDown($event)',
        '(keydown.Home)': 'onKeyDown($event)',
        '(keydown.End)': 'onKeyDown($event)',
        '(focusout)': 'onFocusout($event)'
      }
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['role']
    }]
  }], {
    activeId: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    activeIdChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    destroyOnHide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    orientation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    roles: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    keyboard: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    items: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbNavItem]
    }],
    links: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbNavLinkBase), {
        descendants: true
      }]
    }],
    navChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbNavLinkBase {
  constructor(role) {
    this.role = role;
    this.navItem = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbNavItem);
    this.nav = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbNav);
    this.nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
  }
  get tabindex() {
    if (this.nav.keyboard === false) {
      return this.navItem.disabled ? -1 : undefined;
    }
    if (this.nav._navigatingWithKeyboard) {
      return -1;
    }
    return this.navItem.disabled || !this.navItem.active ? -1 : undefined;
  }
  static {
    this.ɵfac = function NgbNavLinkBase_Factory(t) {
      return new (t || NgbNavLinkBase)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('role'));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavLinkBase,
      selectors: [["", "ngbNavLink", ""]],
      hostVars: 14,
      hostBindings: function NgbNavLinkBase_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.navItem.domId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("role", ctx.role ? ctx.role : ctx.nav.roles ? "tab" : undefined)("tabindex", ctx.tabindex)("aria-controls", ctx.navItem.isPanelInDom() ? ctx.navItem.panelDomId : null)("aria-selected", ctx.navItem.active)("aria-disabled", ctx.navItem.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("nav-link", true)("nav-item", ctx.navItem.isNgContainer())("active", ctx.navItem.active)("disabled", ctx.navItem.disabled);
        }
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavLinkBase, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbNavLink]',
      standalone: true,
      host: {
        '[id]': 'navItem.domId',
        '[class.nav-link]': 'true',
        '[class.nav-item]': 'navItem.isNgContainer()',
        '[attr.role]': `role ? role : nav.roles ? 'tab' : undefined`,
        '[class.active]': 'navItem.active',
        '[class.disabled]': 'navItem.disabled',
        '[attr.tabindex]': 'tabindex',
        '[attr.aria-controls]': 'navItem.isPanelInDom() ? navItem.panelDomId : null',
        '[attr.aria-selected]': 'navItem.active',
        '[attr.aria-disabled]': 'navItem.disabled'
      }
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['role']
    }]
  }], null);
})();
/**
 * A directive to mark the nav link when used on a button element.
 */
class NgbNavLinkButton extends NgbNavLinkBase {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbNavLinkButton_BaseFactory;
      return function NgbNavLinkButton_Factory(t) {
        return (ɵNgbNavLinkButton_BaseFactory || (ɵNgbNavLinkButton_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbNavLinkButton)))(t || NgbNavLinkButton);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavLinkButton,
      selectors: [["button", "ngbNavLink", ""]],
      hostAttrs: ["type", "button"],
      hostVars: 1,
      hostBindings: function NgbNavLinkButton_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbNavLinkButton_click_HostBindingHandler() {
            return ctx.nav.click(ctx.navItem);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("disabled", ctx.navItem.disabled);
        }
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavLinkButton, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'button[ngbNavLink]',
      standalone: true,
      host: {
        type: 'button',
        '[disabled]': 'navItem.disabled',
        '(click)': 'nav.click(navItem)'
      }
    }]
  }], null, null);
})();
/**
 * A directive to mark the nav link when used on a link element.
 *
 * @since 5.2.0
 */
class NgbNavLink extends NgbNavLinkBase {
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbNavLink_BaseFactory;
      return function NgbNavLink_Factory(t) {
        return (ɵNgbNavLink_BaseFactory || (ɵNgbNavLink_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbNavLink)))(t || NgbNavLink);
      };
    })();
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavLink,
      selectors: [["a", "ngbNavLink", ""]],
      hostAttrs: ["href", ""],
      hostBindings: function NgbNavLink_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbNavLink_click_HostBindingHandler($event) {
            ctx.nav.click(ctx.navItem);
            return $event.preventDefault();
          });
        }
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInheritDefinitionFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavLink, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'a[ngbNavLink]',
      standalone: true,
      host: {
        href: '',
        '(click)': 'nav.click(navItem); $event.preventDefault()'
      }
    }]
  }], null, null);
})();
const ngbNavFadeOutTransition = ({
  classList
}) => {
  classList.remove('show');
  return () => classList.remove('active');
};
const ngbNavFadeInTransition = (element, animation) => {
  if (animation) {
    reflow(element);
  }
  element.classList.add('show');
};
class NgbNavPane {
  constructor() {
    this.nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
  }
  static {
    this.ɵfac = function NgbNavPane_Factory(t) {
      return new (t || NgbNavPane)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbNavPane,
      selectors: [["", "ngbNavPane", ""]],
      hostAttrs: [1, "tab-pane"],
      hostVars: 5,
      hostBindings: function NgbNavPane_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.item.panelDomId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("role", ctx.role ? ctx.role : ctx.nav.roles ? "tabpanel" : undefined)("aria-labelledby", ctx.item.domId);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.nav.animation);
        }
      },
      inputs: {
        item: "item",
        nav: "nav",
        role: "role"
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavPane, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbNavPane]',
      standalone: true,
      host: {
        '[id]': 'item.panelDomId',
        class: 'tab-pane',
        '[class.fade]': 'nav.animation',
        '[attr.role]': 'role ? role : nav.roles ? "tabpanel" : undefined',
        '[attr.aria-labelledby]': 'item.domId'
      }
    }]
  }], null, {
    item: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    nav: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    role: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * The outlet where currently active nav content will be displayed.
 *
 * @since 5.2.0
 */
class NgbNavOutlet {
  constructor() {
    this._cd = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._activePane = null;
  }
  isPanelTransitioning(item) {
    return this._activePane?.item === item;
  }
  ngAfterViewInit() {
    // initial display
    this._updateActivePane();
    // this will be emitted for all 3 types of nav changes: .select(), [activeId] or (click)
    this.nav.navItemChange$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this.nav.destroyRef), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.startWith)(this._activePane?.item || null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.distinctUntilChanged)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_33__.skip)(1)).subscribe(nextItem => {
      const options = {
        animation: this.nav.animation,
        runningTransition: 'stop'
      };
      // next panel we're switching to will only appear in DOM after the change detection is done
      // and `this._panes` will be updated
      this._cd.detectChanges();
      // fading out
      if (this._activePane) {
        ngbRunTransition(this._ngZone, this._activePane.nativeElement, ngbNavFadeOutTransition, options).subscribe(() => {
          const activeItem = this._activePane?.item;
          this._activePane = this._getPaneForItem(nextItem);
          // mark for check when transition finishes as outlet or parent containers might be OnPush
          // without this the panes that have "faded out" will stay in DOM
          this._cd.markForCheck();
          // fading in
          if (this._activePane) {
            // we have to add the '.active' class before running the transition,
            // because it should be in place before `ngbRunTransition` does `reflow()`
            this._activePane.nativeElement.classList.add('active');
            ngbRunTransition(this._ngZone, this._activePane.nativeElement, ngbNavFadeInTransition, options).subscribe(() => {
              if (nextItem) {
                nextItem.shown.emit();
                this.nav.shown.emit(nextItem.id);
              }
            });
          }
          if (activeItem) {
            activeItem.hidden.emit();
            this.nav.hidden.emit(activeItem.id);
          }
        });
      } else {
        this._updateActivePane();
      }
    });
  }
  _updateActivePane() {
    this._activePane = this._getActivePane();
    this._activePane?.nativeElement.classList.add('show');
    this._activePane?.nativeElement.classList.add('active');
  }
  _getPaneForItem(item) {
    return this._panes && this._panes.find(pane => pane.item === item) || null;
  }
  _getActivePane() {
    return this._panes && this._panes.find(pane => pane.item.active) || null;
  }
  static {
    this.ɵfac = function NgbNavOutlet_Factory(t) {
      return new (t || NgbNavOutlet)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbNavOutlet,
      selectors: [["", "ngbNavOutlet", ""]],
      viewQuery: function NgbNavOutlet_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](NgbNavPane, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._panes = _t);
        }
      },
      hostVars: 2,
      hostBindings: function NgbNavOutlet_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("tab-content", true);
        }
      },
      inputs: {
        paneRole: "paneRole",
        nav: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbNavOutlet", "nav"]
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      attrs: _c8,
      decls: 2,
      vars: 0,
      consts: [["ngbNavPane", "", 3, "item", "nav", "role"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
      template: function NgbNavOutlet_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](0, NgbNavOutlet_For_1_Template, 1, 1, null, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.nav.items);
        }
      },
      dependencies: [NgbNavPane, _angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavOutlet, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: '[ngbNavOutlet]',
      standalone: true,
      imports: [NgbNavPane, _angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      host: {
        '[class.tab-content]': 'true'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      template: `
		@for (item of nav.items; track item) {
			@if (item.isPanelInDom() || isPanelTransitioning(item)) {
				<div ngbNavPane [item]="item" [nav]="nav" [role]="paneRole">
					<ng-template
						[ngTemplateOutlet]="item.contentTpl?.templateRef || null"
						[ngTemplateOutletContext]="{ $implicit: item.active || isPanelTransitioning(item) }"
					/>
				</div>
			}
		}
	`
    }]
  }], null, {
    _panes: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChildren,
      args: [NgbNavPane]
    }],
    paneRole: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    nav: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbNavOutlet']
    }]
  });
})();
const NGB_NAV_DIRECTIVES = [NgbNavContent, NgbNav, NgbNavItem, NgbNavItemRole, NgbNavLink, NgbNavLinkButton, NgbNavLinkBase, NgbNavOutlet, NgbNavPane];
class NgbNavModule {
  static {
    this.ɵfac = function NgbNavModule_Factory(t) {
      return new (t || NgbNavModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbNavModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbNavModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: NGB_NAV_DIRECTIVES,
      exports: NGB_NAV_DIRECTIVES
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbPagination`](#/components/pagination/api#NgbPagination) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the paginations used in the application.
 */
class NgbPaginationConfig {
  constructor() {
    this.disabled = false;
    this.boundaryLinks = false;
    this.directionLinks = true;
    this.ellipses = true;
    this.maxSize = 0;
    this.pageSize = 10;
    this.rotate = false;
  }
  static {
    this.ɵfac = function NgbPaginationConfig_Factory(t) {
      return new (t || NgbPaginationConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbPaginationConfig,
      factory: NgbPaginationConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A directive to match the 'ellipsis' link template
 *
 * @since 4.1.0
 */
class NgbPaginationEllipsis {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationEllipsis_Factory(t) {
      return new (t || NgbPaginationEllipsis)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationEllipsis,
      selectors: [["ng-template", "ngbPaginationEllipsis", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationEllipsis, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationEllipsis]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the 'first' link template
 *
 * @since 4.1.0
 */
class NgbPaginationFirst {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationFirst_Factory(t) {
      return new (t || NgbPaginationFirst)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationFirst,
      selectors: [["ng-template", "ngbPaginationFirst", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationFirst, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationFirst]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the 'last' link template
 *
 * @since 4.1.0
 */
class NgbPaginationLast {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationLast_Factory(t) {
      return new (t || NgbPaginationLast)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationLast,
      selectors: [["ng-template", "ngbPaginationLast", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationLast, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationLast]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the 'next' link template
 *
 * @since 4.1.0
 */
class NgbPaginationNext {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationNext_Factory(t) {
      return new (t || NgbPaginationNext)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationNext,
      selectors: [["ng-template", "ngbPaginationNext", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationNext, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationNext]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the page 'number' link template
 *
 * @since 4.1.0
 */
class NgbPaginationNumber {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationNumber_Factory(t) {
      return new (t || NgbPaginationNumber)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationNumber,
      selectors: [["ng-template", "ngbPaginationNumber", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationNumber, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationNumber]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the 'previous' link template
 *
 * @since 4.1.0
 */
class NgbPaginationPrevious {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationPrevious_Factory(t) {
      return new (t || NgbPaginationPrevious)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationPrevious,
      selectors: [["ng-template", "ngbPaginationPrevious", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationPrevious, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationPrevious]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A directive to match the 'pages' whole content
 *
 * @since 9.1.0
 */
class NgbPaginationPages {
  constructor() {
    this.templateRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
  }
  static {
    this.ɵfac = function NgbPaginationPages_Factory(t) {
      return new (t || NgbPaginationPages)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPaginationPages,
      selectors: [["ng-template", "ngbPaginationPages", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationPages, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'ng-template[ngbPaginationPages]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * A component that displays page numbers and allows to customize them in several ways.
 */
class NgbPagination {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbPaginationConfig);
    this.pageCount = 0;
    this.pages = [];
    /**
     * If `true`, pagination links will be disabled.
     */
    this.disabled = this._config.disabled;
    /**
     * If `true`, the "First" and "Last" page links are shown.
     */
    this.boundaryLinks = this._config.boundaryLinks;
    /**
     * If `true`, the "Next" and "Previous" page links are shown.
     */
    this.directionLinks = this._config.directionLinks;
    /**
     * If `true`, the ellipsis symbols and first/last page numbers will be shown when `maxSize` > number of pages.
     */
    this.ellipses = this._config.ellipses;
    /**
     * Whether to rotate pages when `maxSize` > number of pages.
     *
     * The current page always stays in the middle if `true`.
     */
    this.rotate = this._config.rotate;
    /**
     *  The maximum number of pages to display.
     */
    this.maxSize = this._config.maxSize;
    /**
     *  The current page.
     *
     *  Page numbers start with `1`.
     */
    this.page = 1;
    /**
     *  The number of items per page.
     */
    this.pageSize = this._config.pageSize;
    /**
     *  An event fired when the page is changed. Will fire only if collection size is set and all values are valid.
     *
     *  Event payload is the number of the newly selected page.
     *
     *  Page numbers start with `1`.
     */
    this.pageChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter(true);
    /**
     * The pagination display size.
     *
     * Bootstrap currently supports small and large sizes.
     *
     * If the passed value is a string (ex. 'custom'), it will just add the `pagination-custom` css class
     */
    this.size = this._config.size;
  }
  hasPrevious() {
    return this.page > 1;
  }
  hasNext() {
    return this.page < this.pageCount;
  }
  nextDisabled() {
    return !this.hasNext() || this.disabled;
  }
  previousDisabled() {
    return !this.hasPrevious() || this.disabled;
  }
  selectPage(pageNumber) {
    this._updatePages(pageNumber);
  }
  ngOnChanges(changes) {
    this._updatePages(this.page);
  }
  isEllipsis(pageNumber) {
    return pageNumber === -1;
  }
  /**
   * Appends ellipses and first/last page number to the displayed pages
   */
  _applyEllipses(start, end) {
    if (this.ellipses) {
      if (start > 0) {
        // The first page will always be included. If the displayed range
        // starts after the third page, then add ellipsis. But if the range
        // starts on the third page, then add the second page instead of
        // an ellipsis, because the ellipsis would only hide a single page.
        if (start > 2) {
          this.pages.unshift(-1);
        } else if (start === 2) {
          this.pages.unshift(2);
        }
        this.pages.unshift(1);
      }
      if (end < this.pageCount) {
        // The last page will always be included. If the displayed range
        // ends before the third-last page, then add ellipsis. But if the range
        // ends on third-last page, then add the second-last page instead of
        // an ellipsis, because the ellipsis would only hide a single page.
        if (end < this.pageCount - 2) {
          this.pages.push(-1);
        } else if (end === this.pageCount - 2) {
          this.pages.push(this.pageCount - 1);
        }
        this.pages.push(this.pageCount);
      }
    }
  }
  /**
   * Rotates page numbers based on maxSize items visible.
   * Currently selected page stays in the middle:
   *
   * Ex. for selected page = 6:
   * [5,*6*,7] for maxSize = 3
   * [4,5,*6*,7] for maxSize = 4
   */
  _applyRotation() {
    let start = 0;
    let end = this.pageCount;
    let leftOffset = Math.floor(this.maxSize / 2);
    let rightOffset = this.maxSize % 2 === 0 ? leftOffset - 1 : leftOffset;
    if (this.page <= leftOffset) {
      // very beginning, no rotation -> [0..maxSize]
      end = this.maxSize;
    } else if (this.pageCount - this.page < leftOffset) {
      // very end, no rotation -> [len-maxSize..len]
      start = this.pageCount - this.maxSize;
    } else {
      // rotate
      start = this.page - leftOffset - 1;
      end = this.page + rightOffset;
    }
    return [start, end];
  }
  /**
   * Paginates page numbers based on maxSize items per page.
   */
  _applyPagination() {
    let page = Math.ceil(this.page / this.maxSize) - 1;
    let start = page * this.maxSize;
    let end = start + this.maxSize;
    return [start, end];
  }
  _setPageInRange(newPageNo) {
    const prevPageNo = this.page;
    this.page = getValueInRange(newPageNo, this.pageCount, 1);
    if (this.page !== prevPageNo && isNumber(this.collectionSize)) {
      this.pageChange.emit(this.page);
    }
  }
  _updatePages(newPage) {
    this.pageCount = Math.ceil(this.collectionSize / this.pageSize);
    if (!isNumber(this.pageCount)) {
      this.pageCount = 0;
    }
    // fill-in model needed to render pages
    this.pages.length = 0;
    for (let i = 1; i <= this.pageCount; i++) {
      this.pages.push(i);
    }
    // set page within 1..max range
    this._setPageInRange(newPage);
    // apply maxSize if necessary
    if (this.maxSize > 0 && this.pageCount > this.maxSize) {
      let start = 0;
      let end = this.pageCount;
      // either paginating or rotating page numbers
      if (this.rotate) {
        [start, end] = this._applyRotation();
      } else {
        [start, end] = this._applyPagination();
      }
      this.pages = this.pages.slice(start, end);
      // adding ellipses
      this._applyEllipses(start, end);
    }
  }
  static {
    this.ɵfac = function NgbPagination_Factory(t) {
      return new (t || NgbPagination)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbPagination,
      selectors: [["ngb-pagination"]],
      contentQueries: function NgbPagination_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationEllipsis, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationFirst, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationLast, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationNext, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationNumber, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationPrevious, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbPaginationPages, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplEllipsis = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplFirst = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplLast = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplNext = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplNumber = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplPrevious = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tplPages = _t.first);
        }
      },
      hostAttrs: ["role", "navigation"],
      inputs: {
        disabled: "disabled",
        boundaryLinks: "boundaryLinks",
        directionLinks: "directionLinks",
        ellipses: "ellipses",
        rotate: "rotate",
        collectionSize: "collectionSize",
        maxSize: "maxSize",
        page: "page",
        pageSize: "pageSize",
        size: "size"
      },
      outputs: {
        pageChange: "pageChange"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 20,
      vars: 12,
      consts: () => {
        let i18n_12;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_12 = goog.getMsg("\xAB\xAB");
          i18n_12 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_12;
        } else {
          i18n_12 = $localize`:@@ngb.pagination.first:««`;
        }
        let i18n_13;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_13 = goog.getMsg("\xAB");
          i18n_13 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_13;
        } else {
          i18n_13 = $localize`:@@ngb.pagination.previous:«`;
        }
        let i18n_14;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_14 = goog.getMsg("\xBB");
          i18n_14 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_14;
        } else {
          i18n_14 = $localize`:@@ngb.pagination.next:»`;
        }
        let i18n_15;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_15 = goog.getMsg("\xBB\xBB");
          i18n_15 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_15;
        } else {
          i18n_15 = $localize`:@@ngb.pagination.last:»»`;
        }
        let i18n_16;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_16 = goog.getMsg("First");
          i18n_16 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_16;
        } else {
          i18n_16 = $localize`:@@ngb.pagination.first-aria:First`;
        }
        let i18n_17;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_17 = goog.getMsg("Previous");
          i18n_17 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_17;
        } else {
          i18n_17 = $localize`:@@ngb.pagination.previous-aria:Previous`;
        }
        let i18n_18;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_18 = goog.getMsg("Next");
          i18n_18 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_18;
        } else {
          i18n_18 = $localize`:@@ngb.pagination.next-aria:Next`;
        }
        let i18n_19;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_19 = goog.getMsg("Last");
          i18n_19 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_19;
        } else {
          i18n_19 = $localize`:@@ngb.pagination.last-aria:Last`;
        }
        return [["first", ""], ["previous", ""], ["next", ""], ["last", ""], ["ellipsis", ""], ["defaultNumber", ""], ["defaultPages", ""], i18n_12, i18n_13, i18n_14, i18n_15, [1, "page-item", 3, "disabled"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], ["aria-hidden", "true"], [1, "page-item", 3, "active", "disabled"], [1, "page-item"], ["tabindex", "-1", "aria-disabled", "true", 1, "page-link"], ["href", "", 1, "page-link", 3, "click"], ["aria-label", i18n_16, "href", "", 1, "page-link", 3, "click"], ["aria-label", i18n_17, "href", "", 1, "page-link", 3, "click"], ["aria-label", i18n_18, "href", "", 1, "page-link", 3, "click"], ["aria-label", i18n_19, "href", "", 1, "page-link", 3, "click"]];
      },
      template: function NgbPagination_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbPagination_ng_template_0_Template, 2, 0, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(2, NgbPagination_ng_template_2_Template, 2, 0, "ng-template", null, 1, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(4, NgbPagination_ng_template_4_Template, 2, 0, "ng-template", null, 2, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(6, NgbPagination_ng_template_6_Template, 2, 0, "ng-template", null, 3, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(8, NgbPagination_ng_template_8_Template, 1, 0, "ng-template", null, 4, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(10, NgbPagination_ng_template_10_Template, 1, 1, "ng-template", null, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(12, NgbPagination_ng_template_12_Template, 2, 0, "ng-template", null, 6, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](14, "ul");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](15, NgbPagination_Conditional_15_Template, 3, 9, "li", 11)(16, NgbPagination_Conditional_16_Template, 3, 8, "li", 11)(17, NgbPagination_ng_template_17_Template, 0, 0, "ng-template", 12)(18, NgbPagination_Conditional_18_Template, 3, 9, "li", 11)(19, NgbPagination_Conditional_19_Template, 3, 9, "li", 11);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          const defaultPages_r19 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](13);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](14);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("pagination" + (ctx.size ? " pagination-" + ctx.size : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](15, ctx.boundaryLinks ? 15 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](16, ctx.directionLinks ? 16 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", (ctx.tplPages == null ? null : ctx.tplPages.templateRef) || defaultPages_r19)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction3"](8, _c9, ctx.page, ctx.pages, ctx.disabled));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](18, ctx.directionLinks ? 18 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](19, ctx.boundaryLinks ? 19 : -1);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPagination, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-pagination',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      host: {
        role: 'navigation'
      },
      template: `
		<ng-template #first><span aria-hidden="true" i18n="@@ngb.pagination.first">&laquo;&laquo;</span></ng-template>
		<ng-template #previous><span aria-hidden="true" i18n="@@ngb.pagination.previous">&laquo;</span></ng-template>
		<ng-template #next><span aria-hidden="true" i18n="@@ngb.pagination.next">&raquo;</span></ng-template>
		<ng-template #last><span aria-hidden="true" i18n="@@ngb.pagination.last">&raquo;&raquo;</span></ng-template>
		<ng-template #ellipsis>...</ng-template>
		<ng-template #defaultNumber let-page let-currentPage="currentPage">{{ page }}</ng-template>
		<ng-template #defaultPages let-page let-pages="pages" let-disabled="disabled">
			@for (pageNumber of pages; track pageNumber) {
				<li
					class="page-item"
					[class.active]="pageNumber === page"
					[class.disabled]="isEllipsis(pageNumber) || disabled"
					[attr.aria-current]="pageNumber === page ? 'page' : null"
				>
					@if (isEllipsis(pageNumber)) {
						<a class="page-link" tabindex="-1" aria-disabled="true">
							<ng-template
								[ngTemplateOutlet]="tplEllipsis?.templateRef || ellipsis"
								[ngTemplateOutletContext]="{ disabled: true, currentPage: page }"
							/>
						</a>
					} @else {
						<a
							class="page-link"
							href
							(click)="selectPage(pageNumber); $event.preventDefault()"
							[attr.tabindex]="disabled ? '-1' : null"
							[attr.aria-disabled]="disabled ? 'true' : null"
						>
							<ng-template
								[ngTemplateOutlet]="tplNumber?.templateRef || defaultNumber"
								[ngTemplateOutletContext]="{ disabled: disabled, $implicit: pageNumber, currentPage: page }"
							/>
						</a>
					}
				</li>
			}
		</ng-template>
		<ul [class]="'pagination' + (size ? ' pagination-' + size : '')">
			@if (boundaryLinks) {
				<li class="page-item" [class.disabled]="previousDisabled()">
					<a
						aria-label="First"
						i18n-aria-label="@@ngb.pagination.first-aria"
						class="page-link"
						href
						(click)="selectPage(1); $event.preventDefault()"
						[attr.tabindex]="previousDisabled() ? '-1' : null"
						[attr.aria-disabled]="previousDisabled() ? 'true' : null"
					>
						<ng-template
							[ngTemplateOutlet]="tplFirst?.templateRef || first"
							[ngTemplateOutletContext]="{ disabled: previousDisabled(), currentPage: page }"
						/>
					</a>
				</li>
			}
			@if (directionLinks) {
				<li class="page-item" [class.disabled]="previousDisabled()">
					<a
						aria-label="Previous"
						i18n-aria-label="@@ngb.pagination.previous-aria"
						class="page-link"
						href
						(click)="selectPage(page - 1); $event.preventDefault()"
						[attr.tabindex]="previousDisabled() ? '-1' : null"
						[attr.aria-disabled]="previousDisabled() ? 'true' : null"
					>
						<ng-template
							[ngTemplateOutlet]="tplPrevious?.templateRef || previous"
							[ngTemplateOutletContext]="{ disabled: previousDisabled() }"
						/>
					</a>
				</li>
			}
			<ng-template
				[ngTemplateOutlet]="tplPages?.templateRef || defaultPages"
				[ngTemplateOutletContext]="{ $implicit: page, pages: pages, disabled: disabled }"
			/>
			@if (directionLinks) {
				<li class="page-item" [class.disabled]="nextDisabled()">
					<a
						aria-label="Next"
						i18n-aria-label="@@ngb.pagination.next-aria"
						class="page-link"
						href
						(click)="selectPage(page + 1); $event.preventDefault()"
						[attr.tabindex]="nextDisabled() ? '-1' : null"
						[attr.aria-disabled]="nextDisabled() ? 'true' : null"
					>
						<ng-template
							[ngTemplateOutlet]="tplNext?.templateRef || next"
							[ngTemplateOutletContext]="{ disabled: nextDisabled(), currentPage: page }"
						/>
					</a>
				</li>
			}
			@if (boundaryLinks) {
				<li class="page-item" [class.disabled]="nextDisabled()">
					<a
						aria-label="Last"
						i18n-aria-label="@@ngb.pagination.last-aria"
						class="page-link"
						href
						(click)="selectPage(pageCount); $event.preventDefault()"
						[attr.tabindex]="nextDisabled() ? '-1' : null"
						[attr.aria-disabled]="nextDisabled() ? 'true' : null"
					>
						<ng-template
							[ngTemplateOutlet]="tplLast?.templateRef || last"
							[ngTemplateOutletContext]="{ disabled: nextDisabled(), currentPage: page }"
						/>
					</a>
				</li>
			}
		</ul>
	`
    }]
  }], null, {
    tplEllipsis: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationEllipsis, {
        static: false
      }]
    }],
    tplFirst: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationFirst, {
        static: false
      }]
    }],
    tplLast: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationLast, {
        static: false
      }]
    }],
    tplNext: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationNext, {
        static: false
      }]
    }],
    tplNumber: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationNumber, {
        static: false
      }]
    }],
    tplPrevious: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationPrevious, {
        static: false
      }]
    }],
    tplPages: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbPaginationPages, {
        static: false
      }]
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    boundaryLinks: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    directionLinks: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ellipses: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    rotate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    collectionSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true
      }]
    }],
    maxSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    page: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    pageSize: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    pageChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    size: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
const NGB_PAGINATION_DIRECTIVES = [NgbPagination, NgbPaginationEllipsis, NgbPaginationFirst, NgbPaginationLast, NgbPaginationNext, NgbPaginationNumber, NgbPaginationPrevious, NgbPaginationPages];
class NgbPaginationModule {
  static {
    this.ɵfac = function NgbPaginationModule_Factory(t) {
      return new (t || NgbPaginationModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbPaginationModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPaginationModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: NGB_PAGINATION_DIRECTIVES,
      exports: NGB_PAGINATION_DIRECTIVES
    }]
  }], null, null);
})();
const ALIASES = {
  hover: ['mouseenter', 'mouseleave'],
  focus: ['focusin', 'focusout']
};
function parseTriggers(triggers) {
  const trimmedTriggers = (triggers || '').trim();
  if (trimmedTriggers.length === 0) {
    return [];
  }
  const parsedTriggers = trimmedTriggers.split(/\s+/).map(trigger => trigger.split(':')).map(triggerPair => ALIASES[triggerPair[0]] || triggerPair);
  const manualTriggers = parsedTriggers.filter(triggerPair => triggerPair.includes('manual'));
  if (manualTriggers.length > 1) {
    throw `Triggers parse error: only one manual trigger is allowed`;
  }
  if (manualTriggers.length === 1 && parsedTriggers.length > 1) {
    throw `Triggers parse error: manual trigger can't be mixed with other triggers`;
  }
  return manualTriggers.length ? [] : parsedTriggers;
}
function listenToTriggers(element, triggers, isOpenedFn, openFn, closeFn, openDelayMs = 0, closeDelayMs = 0) {
  const parsedTriggers = parseTriggers(triggers);
  if (parsedTriggers.length === 0) {
    return () => {};
  }
  const activeOpenTriggers = new Set();
  const cleanupFns = [];
  let timeout;
  function addEventListener(name, listener) {
    element.addEventListener(name, listener);
    cleanupFns.push(() => element.removeEventListener(name, listener));
  }
  function withDelay(fn, delayMs) {
    clearTimeout(timeout);
    if (delayMs > 0) {
      timeout = setTimeout(fn, delayMs);
    } else {
      fn();
    }
  }
  for (const [openTrigger, closeTrigger] of parsedTriggers) {
    if (!closeTrigger) {
      addEventListener(openTrigger, () => isOpenedFn() ? withDelay(closeFn, closeDelayMs) : withDelay(openFn, openDelayMs));
    } else {
      addEventListener(openTrigger, () => {
        activeOpenTriggers.add(openTrigger);
        withDelay(() => activeOpenTriggers.size > 0 && openFn(), openDelayMs);
      });
      addEventListener(closeTrigger, () => {
        activeOpenTriggers.delete(openTrigger);
        withDelay(() => activeOpenTriggers.size === 0 && closeFn(), closeDelayMs);
      });
    }
  }
  return () => cleanupFns.forEach(cleanupFn => cleanupFn());
}

/**
 * A configuration service for the [`NgbPopover`](#/components/popover/api#NgbPopover) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the popovers used in the application.
 */
class NgbPopoverConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.autoClose = true;
    this.placement = 'auto';
    this.popperOptions = options => options;
    this.triggers = 'click';
    this.disablePopover = false;
    this.openDelay = 0;
    this.closeDelay = 0;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbPopoverConfig_Factory(t) {
      return new (t || NgbPopoverConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbPopoverConfig,
      factory: NgbPopoverConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPopoverConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
let nextId$1 = 0;
class NgbPopoverWindow {
  isTitleTemplate() {
    return this.title instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef;
  }
  static {
    this.ɵfac = function NgbPopoverWindow_Factory(t) {
      return new (t || NgbPopoverWindow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbPopoverWindow,
      selectors: [["ngb-popover-window"]],
      hostAttrs: ["role", "tooltip", 2, "position", "absolute"],
      hostVars: 5,
      hostBindings: function NgbPopoverWindow_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("popover" + (ctx.popoverClass ? " " + ctx.popoverClass : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        title: "title",
        id: "id",
        popoverClass: "popoverClass",
        context: "context"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 4,
      vars: 1,
      consts: [["simpleTitle", ""], ["data-popper-arrow", "", 1, "popover-arrow"], [1, "popover-header"], [1, "popover-body"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
      template: function NgbPopoverWindow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbPopoverWindow_Conditional_1_Template, 4, 2, "h3", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](2, "div", 3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx.title ? 1 : -1);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPopoverWindow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-popover-window',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        '[class]': '"popover" + (popoverClass ? " " + popoverClass : "")',
        '[class.fade]': 'animation',
        role: 'tooltip',
        '[id]': 'id',
        style: 'position: absolute;'
      },
      template: `
		<div class="popover-arrow" data-popper-arrow></div>
		@if (title) {
			<h3 class="popover-header">
				<ng-template #simpleTitle>{{ title }}</ng-template>
				<ng-template
					[ngTemplateOutlet]="isTitleTemplate() ? $any(title) : simpleTitle"
					[ngTemplateOutletContext]="context"
				/>
			</h3>
		}
		<div class="popover-body">
			<ng-content />
		</div>
	`
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    title: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popoverClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    context: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * A lightweight and extensible directive for fancy popover creation.
 */
class NgbPopover {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbPopoverConfig);
    /**
     * If `true`, popover opening and closing will be animated.
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * Indicates whether the popover should be closed on `Escape` key and inside/outside clicks:
     *
     * * `true` - closes on both outside and inside clicks as well as `Escape` presses
     * * `false` - disables the autoClose feature (NB: triggers still apply)
     * * `"inside"` - closes on inside clicks as well as Escape presses
     * * `"outside"` - closes on outside clicks (sometimes also achievable through triggers)
     * as well as `Escape` presses
     *
     * @since 3.0.0
     */
    this.autoClose = this._config.autoClose;
    /**
     * The preferred placement of the popover, among the [possible values](#/guides/positioning#api).
     *
     * The default order of preference is `"auto"`.
     *
     * Please see the [positioning overview](#/positioning) for more details.
     */
    this.placement = this._config.placement;
    /**
     * Allows to change default Popper options when positioning the popover.
     * Receives current popper options and returns modified ones.
     *
     * @since 13.1.0
     */
    this.popperOptions = this._config.popperOptions;
    /**
     * Specifies events that should trigger the tooltip.
     *
     * Supports a space separated list of event names.
     * For more details see the [triggers demo](#/components/popover/examples#triggers).
     */
    this.triggers = this._config.triggers;
    /**
     * A selector specifying the element the popover should be appended to.
     *
     * Currently only supports `body`.
     */
    this.container = this._config.container;
    /**
     * If `true`, popover is disabled and won't be displayed.
     *
     * @since 1.1.0
     */
    this.disablePopover = this._config.disablePopover;
    /**
     * An optional class applied to the popover window element.
     *
     * @since 2.2.0
     */
    this.popoverClass = this._config.popoverClass;
    /**
     * The opening delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
     *
     * @since 4.1.0
     */
    this.openDelay = this._config.openDelay;
    /**
     * The closing delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
     *
     * @since 4.1.0
     */
    this.closeDelay = this._config.closeDelay;
    /**
     * An event emitted when the popover opening animation has finished. Contains no payload.
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the popover closing animation has finished. Contains no payload.
     *
     * At this point popover is not in the DOM anymore.
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._ngbPopoverWindowId = `ngb-popover-${nextId$1++}`;
    this._popupService = new PopupService(NgbPopoverWindow);
    this._windowRef = null;
    this._positioning = ngbPositioning();
  }
  /**
   * Opens the popover.
   *
   * This is considered to be a "manual" triggering.
   * The `context` is an optional value to be injected into the popover template when it is created.
   */
  open(context) {
    if (!this._windowRef && !this._isDisabled()) {
      // this type assertion is safe because otherwise _isDisabled would return true
      const {
        windowRef,
        transition$
      } = this._popupService.open(this.ngbPopover, context ?? this.popoverContext, this.animation);
      this._windowRef = windowRef;
      this._windowRef.setInput('animation', this.animation);
      this._windowRef.setInput('title', this.popoverTitle);
      this._windowRef.setInput('context', context ?? this.popoverContext);
      this._windowRef.setInput('popoverClass', this.popoverClass);
      this._windowRef.setInput('id', this._ngbPopoverWindowId);
      this._getPositionTargetElement().setAttribute('aria-describedby', this._ngbPopoverWindowId);
      if (this.container === 'body') {
        this._document.body.appendChild(this._windowRef.location.nativeElement);
      }
      // We need to detect changes, because we don't know where .open() might be called from.
      // Ex. opening popover from one of lifecycle hooks that run after the CD
      // (say from ngAfterViewInit) will result in 'ExpressionHasChanged' exception
      this._windowRef.changeDetectorRef.detectChanges();
      // We need to mark for check, because popover won't work inside the OnPush component.
      // Ex. when we use expression like `{{ popover.isOpen() : 'opened' : 'closed' }}`
      // inside the template of an OnPush component and we change the popover from
      // open -> closed, the expression in question won't be updated unless we explicitly
      // mark the parent component to be checked.
      this._windowRef.changeDetectorRef.markForCheck();
      // Setting up popper and scheduling updates when zone is stable
      this._ngZone.runOutsideAngular(() => {
        this._positioning.createPopper({
          hostElement: this._getPositionTargetElement(),
          targetElement: this._windowRef.location.nativeElement,
          placement: this.placement,
          appendToBody: this.container === 'body',
          baseClass: 'bs-popover',
          updatePopperOptions: options => this.popperOptions(addPopperOffset([0, 8])(options))
        });
        Promise.resolve().then(() => {
          // This update is required for correct arrow placement
          this._positioning.update();
          this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positioning.update());
        });
      });
      ngbAutoClose(this._ngZone, this._document, this.autoClose, () => this.close(), this.hidden, [this._windowRef.location.nativeElement]);
      transition$.subscribe(() => this.shown.emit());
    }
  }
  /**
   * Closes the popover.
   *
   * This is considered to be a "manual" triggering of the popover.
   */
  close(animation = this.animation) {
    if (this._windowRef) {
      this._getPositionTargetElement().removeAttribute('aria-describedby');
      this._popupService.close(animation).subscribe(() => {
        this._windowRef = null;
        this._positioning.destroy();
        this._zoneSubscription?.unsubscribe();
        this.hidden.emit();
        this._changeDetector.markForCheck();
      });
    }
  }
  /**
   * Toggles the popover.
   *
   * This is considered to be a "manual" triggering of the popover.
   */
  toggle() {
    if (this._windowRef) {
      this.close();
    } else {
      this.open();
    }
  }
  /**
   * Returns `true`, if the popover is currently shown.
   */
  isOpen() {
    return this._windowRef != null;
  }
  ngOnInit() {
    this._unregisterListenersFn = listenToTriggers(this._nativeElement, this.triggers, this.isOpen.bind(this), this.open.bind(this), this.close.bind(this), +this.openDelay, +this.closeDelay);
  }
  ngOnChanges({
    ngbPopover,
    popoverTitle,
    disablePopover,
    popoverClass
  }) {
    if (popoverClass && this.isOpen()) {
      this._windowRef.setInput('popoverClass', popoverClass.currentValue);
    }
    // close popover if title and content become empty, or disablePopover set to true
    if ((ngbPopover || popoverTitle || disablePopover) && this._isDisabled()) {
      this.close();
    }
  }
  ngOnDestroy() {
    this.close(false);
    // This check is needed as it might happen that ngOnDestroy is called before ngOnInit
    // under certain conditions, see: https://github.com/ng-bootstrap/ng-bootstrap/issues/2199
    this._unregisterListenersFn?.();
  }
  _isDisabled() {
    return this.disablePopover ? true : !this.ngbPopover && !this.popoverTitle;
  }
  _getPositionTargetElement() {
    return (isString(this.positionTarget) ? this._document.querySelector(this.positionTarget) : this.positionTarget) || this._nativeElement;
  }
  static {
    this.ɵfac = function NgbPopover_Factory(t) {
      return new (t || NgbPopover)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbPopover,
      selectors: [["", "ngbPopover", ""]],
      inputs: {
        animation: "animation",
        autoClose: "autoClose",
        ngbPopover: "ngbPopover",
        popoverTitle: "popoverTitle",
        placement: "placement",
        popperOptions: "popperOptions",
        triggers: "triggers",
        positionTarget: "positionTarget",
        container: "container",
        disablePopover: "disablePopover",
        popoverClass: "popoverClass",
        popoverContext: "popoverContext",
        openDelay: "openDelay",
        closeDelay: "closeDelay"
      },
      outputs: {
        shown: "shown",
        hidden: "hidden"
      },
      exportAs: ["ngbPopover"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPopover, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbPopover]',
      exportAs: 'ngbPopover',
      standalone: true
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    autoClose: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngbPopover: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popoverTitle: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    placement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popperOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    triggers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    positionTarget: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disablePopover: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popoverClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popoverContext: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    openDelay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    closeDelay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbPopoverModule {
  static {
    this.ɵfac = function NgbPopoverModule_Factory(t) {
      return new (t || NgbPopoverModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbPopoverModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbPopoverModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbPopover],
      exports: [NgbPopover]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbProgressbar`](#/components/progressbar/api#NgbProgressbar) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the progress bars used in the application.
 */
class NgbProgressbarConfig {
  constructor() {
    this.max = 100;
    this.animated = false;
    this.ariaLabel = 'progress bar';
    this.striped = false;
    this.showValue = false;
  }
  static {
    this.ɵfac = function NgbProgressbarConfig_Factory(t) {
      return new (t || NgbProgressbarConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbProgressbarConfig,
      factory: NgbProgressbarConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbProgressbarConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A directive that provides feedback on the progress of a workflow or an action.
 */
class NgbProgressbar {
  /**
   * The maximal value to be displayed in the progress bar.
   *
   * Should be a positive number. Will default to 100 otherwise.
   */
  set max(max) {
    this._max = !isNumber(max) || max <= 0 ? 100 : max;
  }
  get max() {
    return this._max;
  }
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbProgressbarConfig);
    this.stacked = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbProgressbarStacked, {
      optional: true
    });
    /**
     * If `true`, the stripes on the progress bar are animated.
     *
     * Takes effect only for browsers supporting CSS3 animations, and if `striped` is `true`.
     */
    this.animated = this._config.animated;
    /**
     * The accessible progress bar name.
     *
     * @since 13.1.0
     */
    this.ariaLabel = this._config.ariaLabel;
    /**
     * If `true`, the progress bars will be displayed as striped.
     */
    this.striped = this._config.striped;
    /**
     * If `true`, the current percentage will be shown in the `xx%` format.
     */
    this.showValue = this._config.showValue;
    /**
     * Optional text variant type of the progress bar.
     *
     * Supports types based on Bootstrap background color variants, like:
     *  `"success"`, `"info"`, `"warning"`, `"danger"`, `"primary"`, `"secondary"`, `"dark"` and so on.
     *
     * @since 5.2.0
     */
    this.textType = this._config.textType;
    /**
     * The type of the progress bar.
     *
     * Supports types based on Bootstrap background color variants, like:
     *  `"success"`, `"info"`, `"warning"`, `"danger"`, `"primary"`, `"secondary"`, `"dark"` and so on.
     */
    this.type = this._config.type;
    /**
     * The current value for the progress bar.
     *
     * Should be in the `[0, max]` range.
     */
    this.value = 0;
    /**
     * The height of the progress bar.
     *
     * Accepts any valid CSS height values, ex. `"2rem"`
     */
    this.height = this._config.height;
    this.max = this._config.max;
  }
  getValue() {
    return getValueInRange(this.value, this.max);
  }
  getPercentValue() {
    return 100 * this.getValue() / this.max;
  }
  static {
    this.ɵfac = function NgbProgressbar_Factory(t) {
      return new (t || NgbProgressbar)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbProgressbar,
      selectors: [["ngb-progressbar"]],
      hostAttrs: ["role", "progressbar", "aria-valuemin", "0", 1, "progress"],
      hostVars: 7,
      hostBindings: function NgbProgressbar_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-valuenow", ctx.getValue())("aria-valuemax", ctx.max)("aria-label", ctx.ariaLabel);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("width", ctx.stacked ? ctx.getPercentValue() : null, "%")("height", ctx.height);
        }
      },
      inputs: {
        max: "max",
        animated: "animated",
        ariaLabel: "ariaLabel",
        striped: "striped",
        showValue: "showValue",
        textType: "textType",
        type: "type",
        value: "value",
        height: "height"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 3,
      vars: 11,
      consts: () => {
        let i18n_20;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_20 = goog.getMsg("{$interpolation}", {
            "interpolation": "\uFFFD0\uFFFD"
          }, {
            original_code: {
              "interpolation": "{{ getValue() / max | percent }}"
            }
          });
          i18n_20 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_20;
        } else {
          i18n_20 = $localize`:@@ngb.progressbar.value:${"\uFFFD0\uFFFD"}:INTERPOLATION:`;
        }
        return [i18n_20];
      },
      template: function NgbProgressbar_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgbProgressbar_Conditional_1_Template, 3, 3, "span");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMapInterpolate2"]("progress-bar", ctx.type ? ctx.textType ? " bg-" + ctx.type : " text-bg-" + ctx.type : "", "", ctx.textType ? " text-" + ctx.textType : "", "");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵstyleProp"]("width", !ctx.stacked ? ctx.getPercentValue() : null, "%");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("progress-bar-animated", ctx.animated)("progress-bar-striped", ctx.striped);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](1, ctx.showValue ? 1 : -1);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.PercentPipe],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbProgressbar, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-progressbar',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.PercentPipe],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        class: 'progress',
        role: 'progressbar',
        '[attr.aria-valuenow]': 'getValue()',
        'aria-valuemin': '0',
        '[attr.aria-valuemax]': 'max',
        '[attr.aria-label]': 'ariaLabel',
        '[style.width.%]': 'stacked ? getPercentValue() : null'
      },
      template: `
		<div
			class="progress-bar{{ type ? (textType ? ' bg-' + type : ' text-bg-' + type) : '' }}{{
				textType ? ' text-' + textType : ''
			}}"
			[class.progress-bar-animated]="animated"
			[class.progress-bar-striped]="striped"
			[style.width.%]="!stacked ? getPercentValue() : null"
		>
			@if (showValue) {
				<span i18n="@@ngb.progressbar.value">{{ getValue() / max | percent }}</span>
			}
			<ng-content />
		</div>
	`
    }]
  }], () => [], {
    max: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    animated: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaLabel: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    striped: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    textType: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    type: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true
      }]
    }],
    height: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['style.height']
    }]
  });
})();
/**
 * A directive that allow to stack progress bars.
 *
 * @since 16.0.0
 */
class NgbProgressbarStacked {
  static {
    this.ɵfac = function NgbProgressbarStacked_Factory(t) {
      return new (t || NgbProgressbarStacked)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbProgressbarStacked,
      selectors: [["ngb-progressbar-stacked"]],
      hostAttrs: [1, "progress-stacked"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 1,
      vars: 0,
      template: function NgbProgressbarStacked_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
        }
      },
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbProgressbarStacked, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-progressbar-stacked',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        class: 'progress-stacked'
      },
      template: `<ng-content></ng-content>`
    }]
  }], null, null);
})();
class NgbProgressbarModule {
  static {
    this.ɵfac = function NgbProgressbarModule_Factory(t) {
      return new (t || NgbProgressbarModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbProgressbarModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbProgressbarModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbProgressbar, NgbProgressbarStacked],
      exports: [NgbProgressbar, NgbProgressbarStacked]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbRating`](#/components/rating/api#NgbRating) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the ratings used in the application.
 */
class NgbRatingConfig {
  constructor() {
    this.max = 10;
    this.readonly = false;
    this.resettable = false;
    this.tabindex = 0;
  }
  static {
    this.ɵfac = function NgbRatingConfig_Factory(t) {
      return new (t || NgbRatingConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbRatingConfig,
      factory: NgbRatingConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbRatingConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A directive that helps visualising and interacting with a star rating bar.
 */
class NgbRating {
  constructor() {
    this.contexts = [];
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbRatingConfig);
    this._changeDetectorRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    /**
     * If `true`, the rating can't be changed or focused.
     */
    this.disabled = false;
    /**
     * The maximal rating that can be given.
     */
    this.max = this._config.max;
    /**
     * If `true`, the rating can't be changed.
     */
    this.readonly = this._config.readonly;
    /**
     * If `true`, the rating can be reset to `0` by mouse clicking currently set rating.
     */
    this.resettable = this._config.resettable;
    /**
     * Allows setting a custom rating tabindex.
     * If the component is disabled, `tabindex` will still be set to `-1`.
     *
     * @since 13.1.0
     */
    this.tabindex = this._config.tabindex;
    /**
     * An event emitted when the user is hovering over a given rating.
     *
     * Event payload equals to the rating being hovered over.
     */
    this.hover = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the user stops hovering over a given rating.
     *
     * Event payload equals to the rating of the last item being hovered over.
     */
    this.leave = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the rating is changed.
     *
     * Event payload equals to the newly selected rating.
     */
    this.rateChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter(true);
    this.onChange = _ => {};
    this.onTouched = () => {};
  }
  /**
   * Allows to provide a function to set a custom aria-valuetext
   *
   * @since 14.1.0
   */
  ariaValueText(current, max) {
    return `${current} out of ${max}`;
  }
  isInteractive() {
    return !this.readonly && !this.disabled;
  }
  enter(value) {
    if (this.isInteractive()) {
      this._updateState(value);
    }
    this.hover.emit(value);
  }
  handleBlur() {
    this.onTouched();
  }
  handleClick(value) {
    if (this.isInteractive()) {
      this.update(this.resettable && this.rate === value ? 0 : value);
    }
  }
  handleKeyDown(event) {
    /* eslint-disable-next-line deprecation/deprecation */
    switch (event.which) {
      case Key.ArrowDown:
      case Key.ArrowLeft:
        this.update(this.rate - 1);
        break;
      case Key.ArrowUp:
      case Key.ArrowRight:
        this.update(this.rate + 1);
        break;
      case Key.Home:
        this.update(0);
        break;
      case Key.End:
        this.update(this.max);
        break;
      default:
        return;
    }
    // note 'return' in default case
    event.preventDefault();
  }
  ngOnChanges(changes) {
    if (changes['rate']) {
      this.update(this.rate);
    }
    if (changes['max']) {
      this._updateMax();
    }
  }
  ngOnInit() {
    this._setupContexts();
    this._updateState(this.rate);
  }
  registerOnChange(fn) {
    this.onChange = fn;
  }
  registerOnTouched(fn) {
    this.onTouched = fn;
  }
  reset() {
    this.leave.emit(this.nextRate);
    this._updateState(this.rate);
  }
  setDisabledState(isDisabled) {
    this.disabled = isDisabled;
  }
  update(value, internalChange = true) {
    const newRate = getValueInRange(value, this.max, 0);
    if (this.isInteractive() && this.rate !== newRate) {
      this.rate = newRate;
      this.rateChange.emit(this.rate);
    }
    if (internalChange) {
      this.onChange(this.rate);
      this.onTouched();
    }
    this._updateState(this.rate);
  }
  writeValue(value) {
    this.update(value, false);
    this._changeDetectorRef.markForCheck();
  }
  _updateState(nextValue) {
    this.nextRate = nextValue;
    this.contexts.forEach((context, index) => context.fill = Math.round(getValueInRange(nextValue - index, 1, 0) * 100));
  }
  _updateMax() {
    if (this.max > 0) {
      this._setupContexts();
      this.update(this.rate);
    }
  }
  _setupContexts() {
    this.contexts = Array.from({
      length: this.max
    }, (v, k) => ({
      fill: 0,
      index: k
    }));
  }
  static {
    this.ɵfac = function NgbRating_Factory(t) {
      return new (t || NgbRating)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbRating,
      selectors: [["ngb-rating"]],
      contentQueries: function NgbRating_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.starTemplateFromContent = _t.first);
        }
      },
      hostAttrs: ["role", "slider", "aria-valuemin", "0", 1, "d-inline-flex"],
      hostVars: 6,
      hostBindings: function NgbRating_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("blur", function NgbRating_blur_HostBindingHandler() {
            return ctx.handleBlur();
          })("keydown", function NgbRating_keydown_HostBindingHandler($event) {
            return ctx.handleKeyDown($event);
          })("mouseleave", function NgbRating_mouseleave_HostBindingHandler() {
            return ctx.reset();
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("tabindex", ctx.disabled ? -1 : ctx.tabindex);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-valuemax", ctx.max)("aria-valuenow", ctx.nextRate)("aria-valuetext", ctx.ariaValueText(ctx.nextRate, ctx.max))("aria-readonly", ctx.readonly && !ctx.disabled ? true : null)("aria-disabled", ctx.disabled ? true : null);
        }
      },
      inputs: {
        disabled: "disabled",
        max: "max",
        rate: "rate",
        readonly: "readonly",
        resettable: "resettable",
        starTemplate: "starTemplate",
        tabindex: "tabindex",
        ariaValueText: "ariaValueText"
      },
      outputs: {
        hover: "hover",
        leave: "leave",
        rateChange: "rateChange"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbRating),
        multi: true
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 4,
      vars: 0,
      consts: [["t", ""], [1, "visually-hidden"], [3, "mouseenter", "click"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
      template: function NgbRating_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbRating_ng_template_0_Template, 1, 1, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](2, NgbRating_For_3_Template, 4, 5, null, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.contexts);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbRating, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-rating',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        class: 'd-inline-flex',
        '[tabindex]': 'disabled ? -1 : tabindex',
        role: 'slider',
        'aria-valuemin': '0',
        '[attr.aria-valuemax]': 'max',
        '[attr.aria-valuenow]': 'nextRate',
        '[attr.aria-valuetext]': 'ariaValueText(nextRate, max)',
        '[attr.aria-readonly]': 'readonly && !disabled ? true : null',
        '[attr.aria-disabled]': 'disabled ? true : null',
        '(blur)': 'handleBlur()',
        '(keydown)': 'handleKeyDown($event)',
        '(mouseleave)': 'reset()'
      },
      template: `
		<ng-template #t let-fill="fill">{{ fill === 100 ? '&#9733;' : '&#9734;' }}</ng-template>
		@for (_ of contexts; track _; let index = $index) {
			<span class="visually-hidden">({{ index < nextRate ? '*' : ' ' }})</span>
			<span
				(mouseenter)="enter(index + 1)"
				(click)="handleClick(index + 1)"
				[style.cursor]="isInteractive() ? 'pointer' : 'default'"
			>
				<ng-template
					[ngTemplateOutlet]="starTemplate || starTemplateFromContent || t"
					[ngTemplateOutletContext]="contexts[index]"
				/>
			</span>
		}
	`,
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbRating),
        multi: true
      }]
    }]
  }], null, {
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    max: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    rate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    readonly: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    resettable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    starTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    starTemplateFromContent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef, {
        static: false
      }]
    }],
    tabindex: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaValueText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hover: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    leave: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    rateChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbRatingModule {
  static {
    this.ɵfac = function NgbRatingModule_Factory(t) {
      return new (t || NgbRatingModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbRatingModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbRatingModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbRating],
      exports: [NgbRating]
    }]
  }], null, null);
})();
function toFragmentElement(container, id) {
  if (!container || id == null) {
    return null;
  }
  return isString(id) ? container.querySelector(`#${CSS.escape(id)}`) : id;
}
function getOrderedFragments(container, fragments) {
  const selector = [...fragments].map(({
    id
  }) => `#${CSS.escape(id)}`).join(',');
  return Array.from(container.querySelectorAll(selector));
}
const defaultProcessChanges = (state, changeActive, ctx) => {
  const {
    rootElement,
    fragments,
    scrollSpy,
    options,
    entries
  } = state;
  const orderedFragments = getOrderedFragments(rootElement, fragments);
  if (!ctx.initialized) {
    ctx.initialized = true;
    ctx.gapFragment = null;
    ctx.visibleFragments = new Set();
    // special case when one of the fragments was pre-selected
    const preSelectedFragment = toFragmentElement(rootElement, options?.initialFragment);
    if (preSelectedFragment) {
      scrollSpy.scrollTo(preSelectedFragment);
      return;
    }
  }
  for (const entry of entries) {
    const {
      isIntersecting,
      target: fragment
    } = entry;
    // 1. an entry became visible
    if (isIntersecting) {
      // if we were in-between two elements, we have to clear it up
      if (ctx.gapFragment) {
        ctx.visibleFragments.delete(ctx.gapFragment);
        ctx.gapFragment = null;
      }
      ctx.visibleFragments.add(fragment);
    }
    // 2. an entry became invisible
    else {
      ctx.visibleFragments.delete(fragment);
      // nothing is visible anymore, but something just was actually
      if (ctx.visibleFragments.size === 0 && scrollSpy.active !== '') {
        // 2.1 scrolling down - keeping the same element
        if (entry.boundingClientRect.top < entry.rootBounds.top) {
          ctx.gapFragment = fragment;
          ctx.visibleFragments.add(ctx.gapFragment);
        }
        // 2.2 scrolling up - getting the previous element
        else {
          // scrolling up and no more fragments above
          if (fragment === orderedFragments[0]) {
            ctx.gapFragment = null;
            ctx.visibleFragments.clear();
            changeActive('');
            return;
          }
          // getting previous fragment
          else {
            const fragmentIndex = orderedFragments.indexOf(fragment);
            ctx.gapFragment = orderedFragments[fragmentIndex - 1] || null;
            if (ctx.gapFragment) {
              ctx.visibleFragments.add(ctx.gapFragment);
            }
          }
        }
      }
    }
  }
  // getting the first visible element in the DOM order of the fragments
  for (const fragment of orderedFragments) {
    if (ctx.visibleFragments.has(fragment)) {
      changeActive(fragment.id);
      break;
    }
  }
};

/**
 * A configuration service for the [`NgbScrollSpyService`](#/components/scrollspy/api#NgbScrollSpyService).
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all scrollspies used in the application.
 *
 * @since 15.1.0
 */
class NgbScrollSpyConfig {
  constructor() {
    this.scrollBehavior = 'smooth';
    this.processChanges = defaultProcessChanges;
  }
  static {
    this.ɵfac = function NgbScrollSpyConfig_Factory(t) {
      return new (t || NgbScrollSpyConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbScrollSpyConfig,
      factory: NgbScrollSpyConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const MATCH_THRESHOLD = 3;
/**
 * A scrollspy service that allows tracking of elements scrolling in and out of view.
 *
 * It can be instantiated manually, or automatically by the `ngbScrollSpy` directive.
 *
 * @since 15.1.0
 */
class NgbScrollSpyService {
  constructor() {
    this._observer = null;
    this._containerElement = null;
    this._fragments = new Set();
    this._preRegisteredFragments = new Set();
    this._active$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._distinctActive$ = this._active$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.distinctUntilChanged)());
    this._active = '';
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpyConfig);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._platformId = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID);
    this._scrollBehavior = this._config.scrollBehavior;
    this._diChangeDetectorRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef, {
      optional: true
    });
    this._changeDetectorRef = this._diChangeDetectorRef;
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._distinctActive$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)()).subscribe(active => {
      this._active = active;
      this._changeDetectorRef?.markForCheck();
    });
  }
  /**
   * Getter for the currently active fragment id. Returns empty string if none.
   */
  get active() {
    return this._active;
  }
  /**
   * An observable emitting the currently active fragment. Emits empty string if none.
   */
  get active$() {
    return this._distinctActive$;
  }
  /**
   * Starts the scrollspy service and observes specified fragments.
   *
   * You can specify a list of options to pass, like the root element, initial fragment, scroll behavior, etc.
   * See the [`NgbScrollSpyOptions`](#/components/scrollspy/api#NgbScrollSpyOptions) interface for more details.
   */
  start(options) {
    if ((0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.isPlatformBrowser)(this._platformId)) {
      this._cleanup();
      const {
        root,
        rootMargin,
        scrollBehavior,
        threshold,
        fragments,
        changeDetectorRef,
        processChanges
      } = {
        ...options
      };
      this._containerElement = root ?? this._document.documentElement;
      this._changeDetectorRef = changeDetectorRef ?? this._diChangeDetectorRef;
      this._scrollBehavior = scrollBehavior ?? this._config.scrollBehavior;
      const processChangesFn = processChanges ?? this._config.processChanges;
      const context = {};
      this._observer = new IntersectionObserver(entries => processChangesFn({
        entries,
        rootElement: this._containerElement,
        fragments: this._fragments,
        scrollSpy: this,
        options: {
          ...options
        }
      }, active => this._active$.next(active), context), {
        root: root ?? this._document,
        ...(rootMargin && {
          rootMargin
        }),
        ...(threshold && {
          threshold
        })
      });
      // merging fragments added before starting and the ones passed as options
      for (const element of [...this._preRegisteredFragments, ...(fragments ?? [])]) {
        this.observe(element);
      }
      this._preRegisteredFragments.clear();
    }
  }
  /**
   * Stops the service and unobserves all fragments.
   */
  stop() {
    this._cleanup();
    this._active$.next('');
  }
  /**
   * Scrolls to a fragment, it must be known to the service and contained in the root element.
   * An id or an element reference can be passed.
   *
   * [`NgbScrollToOptions`](#/components/scrollspy/api#NgbScrollToOptions) can be passed.
   */
  scrollTo(fragment, options) {
    const {
      behavior
    } = {
      behavior: this._scrollBehavior,
      ...options
    };
    if (this._containerElement) {
      const fragmentElement = toFragmentElement(this._containerElement, fragment);
      if (fragmentElement) {
        const heightPx = fragmentElement.offsetTop - this._containerElement.offsetTop;
        this._containerElement.scrollTo({
          top: heightPx,
          behavior
        });
        let lastOffset = this._containerElement.scrollTop;
        let matchCounter = 0;
        // we should update the active section only after scrolling is finished
        // and there is no clean way to do it at the moment
        const containerElement = this._containerElement;
        this._zone.runOutsideAngular(() => {
          const updateActiveWhenScrollingIsFinished = () => {
            const sameOffsetAsLastTime = lastOffset === containerElement.scrollTop;
            if (sameOffsetAsLastTime) {
              matchCounter++;
            } else {
              matchCounter = 0;
            }
            if (!sameOffsetAsLastTime || sameOffsetAsLastTime && matchCounter < MATCH_THRESHOLD) {
              lastOffset = containerElement.scrollTop;
              requestAnimationFrame(updateActiveWhenScrollingIsFinished);
            } else {
              this._zone.run(() => this._active$.next(fragmentElement.id));
            }
          };
          requestAnimationFrame(updateActiveWhenScrollingIsFinished);
        });
      }
    }
  }
  /**
   * Adds a fragment to observe. It must be contained in the root element.
   * An id or an element reference can be passed.
   */
  observe(fragment) {
    if (!this._observer) {
      this._preRegisteredFragments.add(fragment);
      return;
    }
    const fragmentElement = toFragmentElement(this._containerElement, fragment);
    if (fragmentElement && !this._fragments.has(fragmentElement)) {
      this._fragments.add(fragmentElement);
      this._observer.observe(fragmentElement);
    }
  }
  /**
   * Unobserves a fragment.
   * An id or an element reference can be passed.
   */
  unobserve(fragment) {
    if (!this._observer) {
      this._preRegisteredFragments.delete(fragment);
      return;
    }
    const fragmentElement = toFragmentElement(this._containerElement, fragment);
    if (fragmentElement) {
      this._fragments.delete(fragmentElement);
      // we're removing and re-adding all current fragments to recompute active one
      this._observer.disconnect();
      for (const fragment of this._fragments) {
        this._observer.observe(fragment);
      }
    }
  }
  ngOnDestroy() {
    this._cleanup();
  }
  _cleanup() {
    this._fragments.clear();
    this._observer?.disconnect();
    this._changeDetectorRef = this._diChangeDetectorRef;
    this._scrollBehavior = this._config.scrollBehavior;
    this._observer = null;
    this._containerElement = null;
  }
  static {
    this.ɵfac = function NgbScrollSpyService_Factory(t) {
      return new (t || NgbScrollSpyService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbScrollSpyService,
      factory: NgbScrollSpyService.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();

/**
 * A helper directive to that links menu items and fragments together.
 *
 * It will automatically add the `.active` class to the menu item when the associated fragment becomes active.
 *
 * @since 15.1.0
 */
class NgbScrollSpyItem {
  constructor() {
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._scrollSpyMenu = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpyMenu, {
      optional: true
    });
    this._scrollSpyAPI = this._scrollSpyMenu ?? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpyService);
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._isActive = false;
  }
  /**
   * References the scroll spy directive, the id of the associated fragment and the parent menu item.
   *
   * Can be used like:
   *  - `ngbScrollSpyItem="fragmentId"`
   *  - `[ngbScrollSpyItem]="scrollSpy" fragment="fragmentId"
   *  - `[ngbScrollSpyItem]="[scrollSpy, 'fragmentId']"` parent="parentId"`
   *  - `[ngbScrollSpyItem]="[scrollSpy, 'fragmentId', 'parentId']"`
   *
   *  As well as together with `[fragment]` and `[parent]` inputs.
   */
  set data(data) {
    if (Array.isArray(data)) {
      this._scrollSpyAPI = data[0];
      this.fragment = data[1];
      this.parent ??= data[2];
    } else if (data instanceof NgbScrollSpy) {
      this._scrollSpyAPI = data;
    } else if (isString(data)) {
      this.fragment = data;
    }
  }
  ngOnInit() {
    // if it is not a part of a bigger menu, it should handle activation itself
    if (!this._scrollSpyMenu) {
      this._scrollSpyAPI.active$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(active => {
        if (active === this.fragment) {
          this._activate();
        } else {
          this._deactivate();
        }
        this._changeDetector.markForCheck();
      });
    }
  }
  /**
   * @internal
   */
  _activate() {
    this._isActive = true;
    if (this._scrollSpyMenu) {
      this._scrollSpyMenu.getItem(this.parent ?? '')?._activate();
    }
  }
  /**
   * @internal
   */
  _deactivate() {
    this._isActive = false;
    if (this._scrollSpyMenu) {
      this._scrollSpyMenu.getItem(this.parent ?? '')?._deactivate();
    }
  }
  /**
   * Returns `true`, if the associated fragment is active.
   */
  isActive() {
    return this._isActive;
  }
  /**
   * Scrolls to the associated fragment.
   */
  scrollTo(options) {
    this._scrollSpyAPI.scrollTo(this.fragment, options);
  }
  static {
    this.ɵfac = function NgbScrollSpyItem_Factory(t) {
      return new (t || NgbScrollSpyItem)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbScrollSpyItem,
      selectors: [["", "ngbScrollSpyItem", ""]],
      hostVars: 2,
      hostBindings: function NgbScrollSpyItem_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgbScrollSpyItem_click_HostBindingHandler() {
            return ctx.scrollTo();
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("active", ctx.isActive());
        }
      },
      inputs: {
        data: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbScrollSpyItem", "data"],
        fragment: "fragment",
        parent: "parent"
      },
      exportAs: ["ngbScrollSpyItem"],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyItem, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbScrollSpyItem]',
      standalone: true,
      exportAs: 'ngbScrollSpyItem',
      host: {
        '[class.active]': 'isActive()',
        '(click)': 'scrollTo();'
      }
    }]
  }], null, {
    data: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbScrollSpyItem']
    }],
    fragment: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    parent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * An optional scroll spy menu directive to build hierarchical menus
 * and simplify the [`NgbScrollSpyItem`](#/components/scrollspy/api#NgbScrollSpyItem) configuration.
 *
 * @since 15.1.0
 */
class NgbScrollSpyMenu {
  constructor() {
    this._scrollSpyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpyService);
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._map = new Map();
    this._lastActiveItem = null;
  }
  set scrollSpy(scrollSpy) {
    this._scrollSpyRef = scrollSpy;
  }
  get active() {
    return this._scrollSpyRef.active;
  }
  get active$() {
    return this._scrollSpyRef.active$;
  }
  scrollTo(fragment, options) {
    this._scrollSpyRef.scrollTo(fragment, options);
  }
  getItem(id) {
    return this._map.get(id);
  }
  ngAfterViewInit() {
    this._items.changes.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(() => this._rebuildMap());
    this._rebuildMap();
    this._scrollSpyRef.active$.pipe((0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_11__.takeUntilDestroyed)(this._destroyRef)).subscribe(activeId => {
      this._lastActiveItem?._deactivate();
      const item = this._map.get(activeId);
      if (item) {
        item._activate();
        this._lastActiveItem = item;
      }
    });
  }
  _rebuildMap() {
    this._map.clear();
    for (let item of this._items) {
      this._map.set(item.fragment, item);
    }
  }
  static {
    this.ɵfac = function NgbScrollSpyMenu_Factory(t) {
      return new (t || NgbScrollSpyMenu)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbScrollSpyMenu,
      selectors: [["", "ngbScrollSpyMenu", ""]],
      contentQueries: function NgbScrollSpyMenu_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbScrollSpyItem, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx._items = _t);
        }
      },
      inputs: {
        scrollSpy: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbScrollSpyMenu", "scrollSpy"]
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyMenu, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbScrollSpyMenu]',
      standalone: true
    }]
  }], null, {
    _items: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgbScrollSpyItem, {
        descendants: true
      }]
    }],
    scrollSpy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbScrollSpyMenu']
    }]
  });
})();
/**
 * A directive to put on a scrollable container.
 *
 * It will instantiate a [`NgbScrollSpyService`](#/components/scrollspy/api#NgbScrollSpyService).
 *
 * @since 15.1.0
 */
class NgbScrollSpy {
  constructor() {
    this._initialFragment = null;
    this._service = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpyService);
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    /**
     * An event raised when the active section changes.
     *
     * Payload is the id of the new active section, empty string if none.
     */
    this.activeChange = this._service.active$;
  }
  set active(fragment) {
    this._initialFragment = fragment;
    this.scrollTo(fragment);
  }
  /**
   * Getter/setter for the currently active fragment id.
   */
  get active() {
    return this._service.active;
  }
  /**
   * Returns an observable that emits currently active section id.
   */
  get active$() {
    return this._service.active$;
  }
  ngAfterViewInit() {
    this._service.start({
      processChanges: this.processChanges,
      root: this._nativeElement,
      rootMargin: this.rootMargin,
      threshold: this.threshold,
      ...(this._initialFragment && {
        initialFragment: this._initialFragment
      })
    });
  }
  /**
   * @internal
   */
  _registerFragment(fragment) {
    this._service.observe(fragment.id);
  }
  /**
   * @internal
   */
  _unregisterFragment(fragment) {
    this._service.unobserve(fragment.id);
  }
  /**
   * Scrolls to a fragment that is identified by the `ngbScrollSpyFragment` directive.
   * An id or an element reference can be passed.
   */
  scrollTo(fragment, options) {
    this._service.scrollTo(fragment, {
      ...(this.scrollBehavior && {
        behavior: this.scrollBehavior
      }),
      ...options
    });
  }
  static {
    this.ɵfac = function NgbScrollSpy_Factory(t) {
      return new (t || NgbScrollSpy)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbScrollSpy,
      selectors: [["", "ngbScrollSpy", ""]],
      hostAttrs: ["tabindex", "0", 2, "overflow-y", "auto"],
      inputs: {
        processChanges: "processChanges",
        rootMargin: "rootMargin",
        scrollBehavior: "scrollBehavior",
        threshold: "threshold",
        active: "active"
      },
      outputs: {
        activeChange: "activeChange"
      },
      exportAs: ["ngbScrollSpy"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([NgbScrollSpyService])]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpy, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbScrollSpy]',
      standalone: true,
      exportAs: 'ngbScrollSpy',
      host: {
        tabindex: '0',
        style: 'overflow-y: auto'
      },
      providers: [NgbScrollSpyService]
    }]
  }], null, {
    processChanges: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    rootMargin: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    scrollBehavior: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    threshold: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    active: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    activeChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
/**
 * A directive to put on a fragment observed inside a scrollspy container.
 *
 * @since 15.1.0
 */
class NgbScrollSpyFragment {
  constructor() {
    this._destroyRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.DestroyRef);
    this._scrollSpy = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbScrollSpy);
  }
  ngAfterViewInit() {
    this._scrollSpy._registerFragment(this);
    this._destroyRef.onDestroy(() => this._scrollSpy._unregisterFragment(this));
  }
  static {
    this.ɵfac = function NgbScrollSpyFragment_Factory(t) {
      return new (t || NgbScrollSpyFragment)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbScrollSpyFragment,
      selectors: [["", "ngbScrollSpyFragment", ""]],
      hostVars: 1,
      hostBindings: function NgbScrollSpyFragment_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
        }
      },
      inputs: {
        id: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵInputFlags"].None, "ngbScrollSpyFragment", "id"]
      },
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyFragment, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbScrollSpyFragment]',
      standalone: true,
      host: {
        '[id]': 'id'
      }
    }]
  }], null, {
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: ['ngbScrollSpyFragment']
    }]
  });
})();
class NgbScrollSpyModule {
  static {
    this.ɵfac = function NgbScrollSpyModule_Factory(t) {
      return new (t || NgbScrollSpyModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbScrollSpyModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbScrollSpyModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbScrollSpy, NgbScrollSpyItem, NgbScrollSpyFragment, NgbScrollSpyMenu],
      exports: [NgbScrollSpy, NgbScrollSpyItem, NgbScrollSpyFragment, NgbScrollSpyMenu]
    }]
  }], null, null);
})();
class NgbTime {
  constructor(hour, minute, second) {
    this.hour = toInteger(hour);
    this.minute = toInteger(minute);
    this.second = toInteger(second);
  }
  changeHour(step = 1) {
    this.updateHour((isNaN(this.hour) ? 0 : this.hour) + step);
  }
  updateHour(hour) {
    if (isNumber(hour)) {
      this.hour = (hour < 0 ? 24 + hour : hour) % 24;
    } else {
      this.hour = NaN;
    }
  }
  changeMinute(step = 1) {
    this.updateMinute((isNaN(this.minute) ? 0 : this.minute) + step);
  }
  updateMinute(minute) {
    if (isNumber(minute)) {
      this.minute = minute % 60 < 0 ? 60 + minute % 60 : minute % 60;
      this.changeHour(Math.floor(minute / 60));
    } else {
      this.minute = NaN;
    }
  }
  changeSecond(step = 1) {
    this.updateSecond((isNaN(this.second) ? 0 : this.second) + step);
  }
  updateSecond(second) {
    if (isNumber(second)) {
      this.second = second < 0 ? 60 + second % 60 : second % 60;
      this.changeMinute(Math.floor(second / 60));
    } else {
      this.second = NaN;
    }
  }
  isValid(checkSecs = true) {
    return isNumber(this.hour) && isNumber(this.minute) && (checkSecs ? isNumber(this.second) : true);
  }
  toString() {
    return `${this.hour || 0}:${this.minute || 0}:${this.second || 0}`;
  }
}

/**
 * A configuration service for the [`NgbTimepicker`](#/components/timepicker/api#NgbTimepicker) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the timepickers used in the application.
 */
class NgbTimepickerConfig {
  constructor() {
    this.meridian = false;
    this.spinners = true;
    this.seconds = false;
    this.hourStep = 1;
    this.minuteStep = 1;
    this.secondStep = 1;
    this.disabled = false;
    this.readonlyInputs = false;
    this.size = 'medium';
  }
  static {
    this.ɵfac = function NgbTimepickerConfig_Factory(t) {
      return new (t || NgbTimepickerConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTimepickerConfig,
      factory: NgbTimepickerConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimepickerConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
function NGB_DATEPICKER_TIME_ADAPTER_FACTORY() {
  return new NgbTimeStructAdapter();
}
/**
 * An abstract service that does the conversion between the internal timepicker `NgbTimeStruct` model and
 * any provided user time model `T`, ex. a string, a native date, etc.
 *
 * The adapter is used **only** for conversion when binding timepicker to a form control,
 * ex. `[(ngModel)]="userTimeModel"`. Here `userTimeModel` can be of any type.
 *
 * The default timepicker implementation assumes we use `NgbTimeStruct` as a user model.
 *
 * See the [custom time adapter demo](#/components/timepicker/examples#adapter) for an example.
 *
 * @since 2.2.0
 */
class NgbTimeAdapter {
  static {
    this.ɵfac = function NgbTimeAdapter_Factory(t) {
      return new (t || NgbTimeAdapter)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTimeAdapter,
      factory: () => NGB_DATEPICKER_TIME_ADAPTER_FACTORY(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimeAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: NGB_DATEPICKER_TIME_ADAPTER_FACTORY
    }]
  }], null, null);
})();
class NgbTimeStructAdapter extends NgbTimeAdapter {
  /**
   * Converts a NgbTimeStruct value into NgbTimeStruct value
   */
  fromModel(time) {
    return time && isInteger(time.hour) && isInteger(time.minute) ? {
      hour: time.hour,
      minute: time.minute,
      second: isInteger(time.second) ? time.second : null
    } : null;
  }
  /**
   * Converts a NgbTimeStruct value into NgbTimeStruct value
   */
  toModel(time) {
    return time && isInteger(time.hour) && isInteger(time.minute) ? {
      hour: time.hour,
      minute: time.minute,
      second: isInteger(time.second) ? time.second : null
    } : null;
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbTimeStructAdapter_BaseFactory;
      return function NgbTimeStructAdapter_Factory(t) {
        return (ɵNgbTimeStructAdapter_BaseFactory || (ɵNgbTimeStructAdapter_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbTimeStructAdapter)))(t || NgbTimeStructAdapter);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTimeStructAdapter,
      factory: NgbTimeStructAdapter.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimeStructAdapter, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();

/**
 * Type of the service supplying day periods (for example, 'AM' and 'PM') to NgbTimepicker component.
 * The default implementation of this service honors the Angular locale, and uses the registered locale data,
 * as explained in the Angular i18n guide.
 */
class NgbTimepickerI18n {
  static {
    this.ɵfac = function NgbTimepickerI18n_Factory(t) {
      return new (t || NgbTimepickerI18n)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTimepickerI18n,
      factory: () => (() => new NgbTimepickerI18nDefault())(),
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimepickerI18n, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root',
      useFactory: () => new NgbTimepickerI18nDefault()
    }]
  }], null, null);
})();
class NgbTimepickerI18nDefault extends NgbTimepickerI18n {
  constructor() {
    super(...arguments);
    this._periods = (0,_angular_common__WEBPACK_IMPORTED_MODULE_13__.getLocaleDayPeriods)((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.LOCALE_ID), _angular_common__WEBPACK_IMPORTED_MODULE_13__.FormStyle.Standalone, _angular_common__WEBPACK_IMPORTED_MODULE_13__.TranslationWidth.Narrow);
  }
  getMorningPeriod() {
    return this._periods[0];
  }
  getAfternoonPeriod() {
    return this._periods[1];
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgbTimepickerI18nDefault_BaseFactory;
      return function NgbTimepickerI18nDefault_Factory(t) {
        return (ɵNgbTimepickerI18nDefault_BaseFactory || (ɵNgbTimepickerI18nDefault_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](NgbTimepickerI18nDefault)))(t || NgbTimepickerI18nDefault);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTimepickerI18nDefault,
      factory: NgbTimepickerI18nDefault.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimepickerI18nDefault, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const FILTER_REGEX = /[^0-9]/g;
/**
 * A directive that helps with wth picking hours, minutes and seconds.
 */
class NgbTimepicker {
  /**
   * The number of hours to add/subtract when clicking hour spinners.
   */
  set hourStep(step) {
    this._hourStep = isInteger(step) ? step : this._config.hourStep;
  }
  get hourStep() {
    return this._hourStep;
  }
  /**
   * The number of minutes to add/subtract when clicking minute spinners.
   */
  set minuteStep(step) {
    this._minuteStep = isInteger(step) ? step : this._config.minuteStep;
  }
  get minuteStep() {
    return this._minuteStep;
  }
  /**
   * The number of seconds to add/subtract when clicking second spinners.
   */
  set secondStep(step) {
    this._secondStep = isInteger(step) ? step : this._config.secondStep;
  }
  get secondStep() {
    return this._secondStep;
  }
  constructor(_config, _ngbTimeAdapter, _cd, i18n) {
    this._config = _config;
    this._ngbTimeAdapter = _ngbTimeAdapter;
    this._cd = _cd;
    this.i18n = i18n;
    this.onChange = _ => {};
    this.onTouched = () => {};
    this.meridian = _config.meridian;
    this.spinners = _config.spinners;
    this.seconds = _config.seconds;
    this.hourStep = _config.hourStep;
    this.minuteStep = _config.minuteStep;
    this.secondStep = _config.secondStep;
    this.disabled = _config.disabled;
    this.readonlyInputs = _config.readonlyInputs;
    this.size = _config.size;
  }
  writeValue(value) {
    const structValue = this._ngbTimeAdapter.fromModel(value);
    this.model = structValue ? new NgbTime(structValue.hour, structValue.minute, structValue.second) : new NgbTime();
    if (!this.seconds && (!structValue || !isNumber(structValue.second))) {
      this.model.second = 0;
    }
    this._cd.markForCheck();
  }
  registerOnChange(fn) {
    this.onChange = fn;
  }
  registerOnTouched(fn) {
    this.onTouched = fn;
  }
  setDisabledState(isDisabled) {
    this.disabled = isDisabled;
  }
  /**
   * Increments the hours by the given step.
   */
  changeHour(step) {
    this.model?.changeHour(step);
    this.propagateModelChange();
  }
  /**
   * Increments the minutes by the given step.
   */
  changeMinute(step) {
    this.model?.changeMinute(step);
    this.propagateModelChange();
  }
  /**
   * Increments the seconds by the given step.
   */
  changeSecond(step) {
    this.model?.changeSecond(step);
    this.propagateModelChange();
  }
  /**
   * Update hours with the new value.
   */
  updateHour(newVal) {
    const isPM = this.model ? this.model.hour >= 12 : false;
    const enteredHour = toInteger(newVal);
    if (this.meridian && (isPM && enteredHour < 12 || !isPM && enteredHour === 12)) {
      this.model?.updateHour(enteredHour + 12);
    } else {
      this.model?.updateHour(enteredHour);
    }
    this.propagateModelChange();
  }
  /**
   * Update minutes with the new value.
   */
  updateMinute(newVal) {
    this.model?.updateMinute(toInteger(newVal));
    this.propagateModelChange();
  }
  /**
   * Update seconds with the new value.
   */
  updateSecond(newVal) {
    this.model?.updateSecond(toInteger(newVal));
    this.propagateModelChange();
  }
  toggleMeridian() {
    if (this.meridian) {
      this.changeHour(12);
    }
  }
  formatInput(input) {
    input.value = input.value.replace(FILTER_REGEX, '');
  }
  formatHour(value) {
    if (isNumber(value)) {
      if (this.meridian) {
        return padNumber(value % 12 === 0 ? 12 : value % 12);
      } else {
        return padNumber(value % 24);
      }
    } else {
      return padNumber(NaN);
    }
  }
  formatMinSec(value) {
    return padNumber(isNumber(value) ? value : NaN);
  }
  handleBlur() {
    this.onTouched();
  }
  get isSmallSize() {
    return this.size === 'small';
  }
  get isLargeSize() {
    return this.size === 'large';
  }
  ngOnChanges(changes) {
    if (changes['seconds'] && !this.seconds && this.model && !isNumber(this.model.second)) {
      this.model.second = 0;
      this.propagateModelChange(false);
    }
  }
  propagateModelChange(touched = true) {
    if (touched) {
      this.onTouched();
    }
    if (this.model?.isValid(this.seconds)) {
      this.onChange(this._ngbTimeAdapter.toModel({
        hour: this.model.hour,
        minute: this.model.minute,
        second: this.model.second
      }));
    } else {
      this.onChange(this._ngbTimeAdapter.toModel(null));
    }
  }
  static {
    this.ɵfac = function NgbTimepicker_Factory(t) {
      return new (t || NgbTimepicker)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgbTimepickerConfig), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgbTimeAdapter), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgbTimepickerI18n));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbTimepicker,
      selectors: [["ngb-timepicker"]],
      inputs: {
        meridian: "meridian",
        spinners: "spinners",
        seconds: "seconds",
        hourStep: "hourStep",
        minuteStep: "minuteStep",
        secondStep: "secondStep",
        readonlyInputs: "readonlyInputs",
        size: "size"
      },
      exportAs: ["ngbTimepicker"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbTimepicker),
        multi: true
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 14,
      vars: 23,
      consts: () => {
        let i18n_21;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_21 = goog.getMsg("HH");
          i18n_21 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_21;
        } else {
          i18n_21 = $localize`:@@ngb.timepicker.HH:HH`;
        }
        let i18n_22;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_22 = goog.getMsg("Hours");
          i18n_22 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_22;
        } else {
          i18n_22 = $localize`:@@ngb.timepicker.hours:Hours`;
        }
        let i18n_23;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_23 = goog.getMsg("MM");
          i18n_23 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_23;
        } else {
          i18n_23 = $localize`:@@ngb.timepicker.MM:MM`;
        }
        let i18n_24;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_24 = goog.getMsg("Minutes");
          i18n_24 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_24;
        } else {
          i18n_24 = $localize`:@@ngb.timepicker.minutes:Minutes`;
        }
        let i18n_25;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_25 = goog.getMsg("Increment hours");
          i18n_25 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_25;
        } else {
          i18n_25 = $localize`:@@ngb.timepicker.increment-hours:Increment hours`;
        }
        let i18n_26;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_26 = goog.getMsg("Decrement hours");
          i18n_26 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_26;
        } else {
          i18n_26 = $localize`:@@ngb.timepicker.decrement-hours:Decrement hours`;
        }
        let i18n_27;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_27 = goog.getMsg("Increment minutes");
          i18n_27 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_27;
        } else {
          i18n_27 = $localize`:@@ngb.timepicker.increment-minutes:Increment minutes`;
        }
        let i18n_28;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_28 = goog.getMsg("Decrement minutes");
          i18n_28 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_28;
        } else {
          i18n_28 = $localize`:@@ngb.timepicker.decrement-minutes:Decrement minutes`;
        }
        let i18n_29;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_29 = goog.getMsg("SS");
          i18n_29 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_29;
        } else {
          i18n_29 = $localize`:@@ngb.timepicker.SS:SS`;
        }
        let i18n_30;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_30 = goog.getMsg("Seconds");
          i18n_30 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_30;
        } else {
          i18n_30 = $localize`:@@ngb.timepicker.seconds:Seconds`;
        }
        let i18n_31;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_31 = goog.getMsg("Increment seconds");
          i18n_31 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_31;
        } else {
          i18n_31 = $localize`:@@ngb.timepicker.increment-seconds:Increment seconds`;
        }
        let i18n_32;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_32 = goog.getMsg("Decrement seconds");
          i18n_32 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_32;
        } else {
          i18n_32 = $localize`:@@ngb.timepicker.decrement-seconds:Decrement seconds`;
        }
        let i18n_33;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_33 = goog.getMsg("{$interpolation}", {
            "interpolation": "\uFFFD0\uFFFD"
          }, {
            original_code: {
              "interpolation": "{{ i18n.getAfternoonPeriod() }}"
            }
          });
          i18n_33 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_33;
        } else {
          i18n_33 = $localize`:@@ngb.timepicker.PM:${"\uFFFD0\uFFFD"}:INTERPOLATION:`;
        }
        return [i18n_25, i18n_26, i18n_27, i18n_28, i18n_31, i18n_32, i18n_33, [3, "disabled"], [1, "ngb-tp"], [1, "ngb-tp-input-container", "ngb-tp-hour"], ["tabindex", "-1", "type", "button", 1, "btn", "btn-link", 3, "btn-sm", "btn-lg", "disabled"], ["type", "text", "maxlength", "2", "inputmode", "numeric", "placeholder", i18n_21, "aria-label", i18n_22, 1, "ngb-tp-input", "form-control", 3, "change", "blur", "input", "keydown.ArrowUp", "keydown.ArrowDown", "value", "readOnly", "disabled"], [1, "ngb-tp-spacer"], [1, "ngb-tp-input-container", "ngb-tp-minute"], ["type", "text", "maxlength", "2", "inputmode", "numeric", "placeholder", i18n_23, "aria-label", i18n_24, 1, "ngb-tp-input", "form-control", 3, "change", "blur", "input", "keydown.ArrowUp", "keydown.ArrowDown", "value", "readOnly", "disabled"], ["tabindex", "-1", "type", "button", 1, "btn", "btn-link", 3, "click", "disabled"], [1, "chevron", "ngb-tp-chevron"], [1, "visually-hidden"], [1, "chevron", "ngb-tp-chevron", "bottom"], [1, "ngb-tp-input-container", "ngb-tp-second"], ["type", "text", "maxlength", "2", "inputmode", "numeric", "placeholder", i18n_29, "aria-label", i18n_30, 1, "ngb-tp-input", "form-control", 3, "change", "blur", "input", "keydown.ArrowUp", "keydown.ArrowDown", "value", "readOnly", "disabled"], [1, "ngb-tp-meridian"], ["type", "button", 1, "btn", "btn-outline-primary", 3, "click", "disabled"]];
      },
      template: function NgbTimepicker_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "fieldset", 7)(1, "div", 8)(2, "div", 9);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](3, NgbTimepicker_Conditional_3_Template, 4, 7, "button", 10);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](4, "input", 11);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function NgbTimepicker_Template_input_change_4_listener($event) {
            return ctx.updateHour($event.target.value);
          })("blur", function NgbTimepicker_Template_input_blur_4_listener() {
            return ctx.handleBlur();
          })("input", function NgbTimepicker_Template_input_input_4_listener($event) {
            return ctx.formatInput($event.target);
          })("keydown.ArrowUp", function NgbTimepicker_Template_input_keydown_ArrowUp_4_listener($event) {
            ctx.changeHour(ctx.hourStep);
            return $event.preventDefault();
          })("keydown.ArrowDown", function NgbTimepicker_Template_input_keydown_ArrowDown_4_listener($event) {
            ctx.changeHour(-ctx.hourStep);
            return $event.preventDefault();
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](5, NgbTimepicker_Conditional_5_Template, 4, 7, "button", 10);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "div", 12);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](7, ":");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](8, "div", 13);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](9, NgbTimepicker_Conditional_9_Template, 4, 7, "button", 10);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](10, "input", 14);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("change", function NgbTimepicker_Template_input_change_10_listener($event) {
            return ctx.updateMinute($event.target.value);
          })("blur", function NgbTimepicker_Template_input_blur_10_listener() {
            return ctx.handleBlur();
          })("input", function NgbTimepicker_Template_input_input_10_listener($event) {
            return ctx.formatInput($event.target);
          })("keydown.ArrowUp", function NgbTimepicker_Template_input_keydown_ArrowUp_10_listener($event) {
            ctx.changeMinute(ctx.minuteStep);
            return $event.preventDefault();
          })("keydown.ArrowDown", function NgbTimepicker_Template_input_keydown_ArrowDown_10_listener($event) {
            ctx.changeMinute(-ctx.minuteStep);
            return $event.preventDefault();
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](11, NgbTimepicker_Conditional_11_Template, 4, 7, "button", 10);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](12, NgbTimepicker_Conditional_12_Template, 6, 9)(13, NgbTimepicker_Conditional_13_Template, 5, 8);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](3, ctx.spinners ? 3 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("form-control-sm", ctx.isSmallSize)("form-control-lg", ctx.isLargeSize);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("value", ctx.formatHour(ctx.model == null ? null : ctx.model.hour))("readOnly", ctx.readonlyInputs)("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](5, ctx.spinners ? 5 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](4);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](9, ctx.spinners ? 9 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("form-control-sm", ctx.isSmallSize)("form-control-lg", ctx.isLargeSize);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("value", ctx.formatMinSec(ctx.model == null ? null : ctx.model.minute))("readOnly", ctx.readonlyInputs)("disabled", ctx.disabled);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](11, ctx.spinners ? 11 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](12, ctx.seconds ? 12 : -1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](13, ctx.meridian ? 13 : -1);
        }
      },
      styles: ["ngb-timepicker{font-size:1rem}.ngb-tp{display:flex;align-items:center}.ngb-tp-input-container{width:4em}.ngb-tp-chevron:before{border-style:solid;border-width:.29em .29em 0 0;content:\"\";display:inline-block;height:.69em;left:.05em;position:relative;top:.15em;transform:rotate(-45deg);vertical-align:middle;width:.69em}.ngb-tp-chevron.bottom:before{top:-.3em;transform:rotate(135deg)}.ngb-tp-input{text-align:center}.ngb-tp-hour,.ngb-tp-minute,.ngb-tp-second,.ngb-tp-meridian{display:flex;flex-direction:column;align-items:center;justify-content:space-around}.ngb-tp-spacer{width:1em;text-align:center}\n"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimepicker, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      exportAs: 'ngbTimepicker',
      selector: 'ngb-timepicker',
      standalone: true,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: `
		<fieldset [disabled]="disabled" [class.disabled]="disabled">
			<div class="ngb-tp">
				<div class="ngb-tp-input-container ngb-tp-hour">
					@if (spinners) {
						<button
							tabindex="-1"
							type="button"
							(click)="changeHour(hourStep)"
							class="btn btn-link"
							[class.btn-sm]="isSmallSize"
							[class.btn-lg]="isLargeSize"
							[class.disabled]="disabled"
							[disabled]="disabled"
						>
							<span class="chevron ngb-tp-chevron"></span>
							<span class="visually-hidden" i18n="@@ngb.timepicker.increment-hours">Increment hours</span>
						</button>
					}
					<input
						type="text"
						class="ngb-tp-input form-control"
						[class.form-control-sm]="isSmallSize"
						[class.form-control-lg]="isLargeSize"
						maxlength="2"
						inputmode="numeric"
						placeholder="HH"
						i18n-placeholder="@@ngb.timepicker.HH"
						[value]="formatHour(model?.hour)"
						(change)="updateHour($any($event).target.value)"
						[readOnly]="readonlyInputs"
						[disabled]="disabled"
						aria-label="Hours"
						i18n-aria-label="@@ngb.timepicker.hours"
						(blur)="handleBlur()"
						(input)="formatInput($any($event).target)"
						(keydown.ArrowUp)="changeHour(hourStep); $event.preventDefault()"
						(keydown.ArrowDown)="changeHour(-hourStep); $event.preventDefault()"
					/>
					@if (spinners) {
						<button
							tabindex="-1"
							type="button"
							(click)="changeHour(-hourStep)"
							class="btn btn-link"
							[class.btn-sm]="isSmallSize"
							[class.btn-lg]="isLargeSize"
							[class.disabled]="disabled"
							[disabled]="disabled"
						>
							<span class="chevron ngb-tp-chevron bottom"></span>
							<span class="visually-hidden" i18n="@@ngb.timepicker.decrement-hours">Decrement hours</span>
						</button>
					}
				</div>
				<div class="ngb-tp-spacer">:</div>
				<div class="ngb-tp-input-container ngb-tp-minute">
					@if (spinners) {
						<button
							tabindex="-1"
							type="button"
							(click)="changeMinute(minuteStep)"
							class="btn btn-link"
							[class.btn-sm]="isSmallSize"
							[class.btn-lg]="isLargeSize"
							[class.disabled]="disabled"
							[disabled]="disabled"
						>
							<span class="chevron ngb-tp-chevron"></span>
							<span class="visually-hidden" i18n="@@ngb.timepicker.increment-minutes">Increment minutes</span>
						</button>
					}
					<input
						type="text"
						class="ngb-tp-input form-control"
						[class.form-control-sm]="isSmallSize"
						[class.form-control-lg]="isLargeSize"
						maxlength="2"
						inputmode="numeric"
						placeholder="MM"
						i18n-placeholder="@@ngb.timepicker.MM"
						[value]="formatMinSec(model?.minute)"
						(change)="updateMinute($any($event).target.value)"
						[readOnly]="readonlyInputs"
						[disabled]="disabled"
						aria-label="Minutes"
						i18n-aria-label="@@ngb.timepicker.minutes"
						(blur)="handleBlur()"
						(input)="formatInput($any($event).target)"
						(keydown.ArrowUp)="changeMinute(minuteStep); $event.preventDefault()"
						(keydown.ArrowDown)="changeMinute(-minuteStep); $event.preventDefault()"
					/>
					@if (spinners) {
						<button
							tabindex="-1"
							type="button"
							(click)="changeMinute(-minuteStep)"
							class="btn btn-link"
							[class.btn-sm]="isSmallSize"
							[class.btn-lg]="isLargeSize"
							[class.disabled]="disabled"
							[disabled]="disabled"
						>
							<span class="chevron ngb-tp-chevron bottom"></span>
							<span class="visually-hidden" i18n="@@ngb.timepicker.decrement-minutes">Decrement minutes</span>
						</button>
					}
				</div>
				@if (seconds) {
					<div class="ngb-tp-spacer">:</div>
					<div class="ngb-tp-input-container ngb-tp-second">
						@if (spinners) {
							<button
								tabindex="-1"
								type="button"
								(click)="changeSecond(secondStep)"
								class="btn btn-link"
								[class.btn-sm]="isSmallSize"
								[class.btn-lg]="isLargeSize"
								[class.disabled]="disabled"
								[disabled]="disabled"
							>
								<span class="chevron ngb-tp-chevron"></span>
								<span class="visually-hidden" i18n="@@ngb.timepicker.increment-seconds">Increment seconds</span>
							</button>
						}
						<input
							type="text"
							class="ngb-tp-input form-control"
							[class.form-control-sm]="isSmallSize"
							[class.form-control-lg]="isLargeSize"
							maxlength="2"
							inputmode="numeric"
							placeholder="SS"
							i18n-placeholder="@@ngb.timepicker.SS"
							[value]="formatMinSec(model?.second)"
							(change)="updateSecond($any($event).target.value)"
							[readOnly]="readonlyInputs"
							[disabled]="disabled"
							aria-label="Seconds"
							i18n-aria-label="@@ngb.timepicker.seconds"
							(blur)="handleBlur()"
							(input)="formatInput($any($event).target)"
							(keydown.ArrowUp)="changeSecond(secondStep); $event.preventDefault()"
							(keydown.ArrowDown)="changeSecond(-secondStep); $event.preventDefault()"
						/>
						@if (spinners) {
							<button
								tabindex="-1"
								type="button"
								(click)="changeSecond(-secondStep)"
								class="btn btn-link"
								[class.btn-sm]="isSmallSize"
								[class.btn-lg]="isLargeSize"
								[class.disabled]="disabled"
								[disabled]="disabled"
							>
								<span class="chevron ngb-tp-chevron bottom"></span>
								<span class="visually-hidden" i18n="@@ngb.timepicker.decrement-seconds">Decrement seconds</span>
							</button>
						}
					</div>
				}
				@if (meridian) {
					<div class="ngb-tp-spacer"></div>
					<div class="ngb-tp-meridian">
						<button
							type="button"
							class="btn btn-outline-primary"
							[class.btn-sm]="isSmallSize"
							[class.btn-lg]="isLargeSize"
							[disabled]="disabled"
							[class.disabled]="disabled"
							(click)="toggleMeridian()"
						>
							@if (model && model.hour >= 12) {
								<ng-container i18n="@@ngb.timepicker.PM">{{ i18n.getAfternoonPeriod() }}</ng-container>
							} @else {
								<ng-container>{{ i18n.getMorningPeriod() }}</ng-container>
							}
						</button>
					</div>
				}
			</div>
		</fieldset>
	`,
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbTimepicker),
        multi: true
      }],
      styles: ["ngb-timepicker{font-size:1rem}.ngb-tp{display:flex;align-items:center}.ngb-tp-input-container{width:4em}.ngb-tp-chevron:before{border-style:solid;border-width:.29em .29em 0 0;content:\"\";display:inline-block;height:.69em;left:.05em;position:relative;top:.15em;transform:rotate(-45deg);vertical-align:middle;width:.69em}.ngb-tp-chevron.bottom:before{top:-.3em;transform:rotate(135deg)}.ngb-tp-input{text-align:center}.ngb-tp-hour,.ngb-tp-minute,.ngb-tp-second,.ngb-tp-meridian{display:flex;flex-direction:column;align-items:center;justify-content:space-around}.ngb-tp-spacer{width:1em;text-align:center}\n"]
    }]
  }], () => [{
    type: NgbTimepickerConfig
  }, {
    type: NgbTimeAdapter
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
  }, {
    type: NgbTimepickerI18n
  }], {
    meridian: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    spinners: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    seconds: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hourStep: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    minuteStep: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    secondStep: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    readonlyInputs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    size: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class NgbTimepickerModule {
  static {
    this.ɵfac = function NgbTimepickerModule_Factory(t) {
      return new (t || NgbTimepickerModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbTimepickerModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTimepickerModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbTimepicker],
      exports: [NgbTimepicker]
    }]
  }], null, null);
})();

/**
 * Configuration service for the NgbToast component. You can inject this service, typically in your root component,
 * and customize the values of its properties in order to provide default values for all the toasts used in the
 * application.
 *
 * @since 5.0.0
 */
class NgbToastConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.autohide = true;
    this.delay = 5000;
    this.ariaLive = 'polite';
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbToastConfig_Factory(t) {
      return new (t || NgbToastConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbToastConfig,
      factory: NgbToastConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbToastConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const ngbToastFadeInTransition = (element, animation) => {
  const {
    classList
  } = element;
  if (animation) {
    classList.add('fade');
  } else {
    classList.add('show');
    return;
  }
  reflow(element);
  classList.add('show', 'showing');
  return () => {
    classList.remove('showing');
  };
};
const ngbToastFadeOutTransition = ({
  classList
}) => {
  classList.add('showing');
  return () => {
    classList.remove('show', 'showing');
  };
};

/**
 * This directive allows the usage of HTML markup or other directives
 * inside of the toast's header.
 *
 * @since 5.0.0
 */
class NgbToastHeader {
  static {
    this.ɵfac = function NgbToastHeader_Factory(t) {
      return new (t || NgbToastHeader)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbToastHeader,
      selectors: [["", "ngbToastHeader", ""]],
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbToastHeader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbToastHeader]',
      standalone: true
    }]
  }], null, null);
})();
/**
 * Toasts provide feedback messages as notifications to the user.
 * Goal is to mimic the push notifications available both on mobile and desktop operating systems.
 *
 * @since 5.0.0
 */
class NgbToast {
  constructor(ariaLive) {
    this.ariaLive = ariaLive;
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbToastConfig);
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._element = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    /**
     * If `true`, toast opening and closing will be animated.
     *
     * Animation is triggered only when the `.hide()` or `.show()` functions are called
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * Delay after which the toast will hide (ms).
     * default: `500` (ms) (inherited from NgbToastConfig)
     */
    this.delay = this._config.delay;
    /**
     * Auto hide the toast after a delay in ms.
     * default: `true` (inherited from NgbToastConfig)
     */
    this.autohide = this._config.autohide;
    /**
     * A template like `<ng-template ngbToastHeader></ng-template>` can be
     * used in the projected content to allow markup usage.
     */
    this.contentHeaderTpl = null;
    /**
     * An event fired after the animation triggered by calling `.show()` method has finished.
     *
     * @since 8.0.0
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event fired after the animation triggered by calling `.hide()` method has finished.
     *
     * It can only occur in 2 different scenarios:
     * - `autohide` timeout fires
     * - user clicks on a closing cross
     *
     * Additionally this output is purely informative. The toast won't be removed from DOM automatically, it's up
     * to the user to take care of that.
     *
     * @since 8.0.0
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.ariaLive ??= this._config.ariaLive;
  }
  ngAfterContentInit() {
    this._zone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      this._init();
      this.show();
    });
  }
  ngOnChanges(changes) {
    if ('autohide' in changes) {
      this._clearTimeout();
      this._init();
    }
  }
  /**
   * Triggers toast closing programmatically.
   *
   * The returned observable will emit and be completed once the closing transition has finished.
   * If the animations are turned off this happens synchronously.
   *
   * Alternatively you could listen or subscribe to the `(hidden)` output
   *
   * @since 8.0.0
   */
  hide() {
    this._clearTimeout();
    const transition = ngbRunTransition(this._zone, this._element.nativeElement, ngbToastFadeOutTransition, {
      animation: this.animation,
      runningTransition: 'stop'
    });
    transition.subscribe(() => {
      this.hidden.emit();
    });
    return transition;
  }
  /**
   * Triggers toast opening programmatically.
   *
   * The returned observable will emit and be completed once the opening transition has finished.
   * If the animations are turned off this happens synchronously.
   *
   * Alternatively you could listen or subscribe to the `(shown)` output
   *
   * @since 8.0.0
   */
  show() {
    const transition = ngbRunTransition(this._zone, this._element.nativeElement, ngbToastFadeInTransition, {
      animation: this.animation,
      runningTransition: 'continue'
    });
    transition.subscribe(() => {
      this.shown.emit();
    });
    return transition;
  }
  _init() {
    if (this.autohide && !this._timeoutID) {
      this._timeoutID = setTimeout(() => this.hide(), this.delay);
    }
  }
  _clearTimeout() {
    if (this._timeoutID) {
      clearTimeout(this._timeoutID);
      this._timeoutID = null;
    }
  }
  static {
    this.ɵfac = function NgbToast_Factory(t) {
      return new (t || NgbToast)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('aria-live'));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbToast,
      selectors: [["ngb-toast"]],
      contentQueries: function NgbToast_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgbToastHeader, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.contentHeaderTpl = _t.first);
        }
      },
      hostAttrs: ["role", "alert", "aria-atomic", "true", 1, "toast"],
      hostVars: 3,
      hostBindings: function NgbToast_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-live", ctx.ariaLive);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        delay: "delay",
        autohide: "autohide",
        header: "header"
      },
      outputs: {
        shown: "shown",
        hidden: "hidden"
      },
      exportAs: ["ngbToast"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 5,
      vars: 1,
      consts: () => {
        let i18n_34;
        if (typeof ngI18nClosureMode !== "undefined" && ngI18nClosureMode) {
          /**
           * @suppress {msgDescriptions}
           */
          const MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_34 = goog.getMsg("Close");
          i18n_34 = MSG_C__DEPORTES87_DEPORTES_FE_NODE_MODULES__NG_BOOTSTRAP_NG_BOOTSTRAP_FESM2022_NG_BOOTSTRAP_MJS_34;
        } else {
          i18n_34 = $localize`:@@ngb.toast.close-aria:Close`;
        }
        return [["headerTpl", ""], [1, "toast-header"], [1, "toast-body"], [1, "me-auto"], [3, "ngTemplateOutlet"], ["type", "button", "aria-label", i18n_34, 1, "btn-close", 3, "click"]];
      },
      template: function NgbToast_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbToast_ng_template_0_Template, 2, 1, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(2, NgbToast_Conditional_2_Template, 3, 1, "div", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](3, "div", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](4);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵconditional"](2, ctx.contentHeaderTpl || ctx.header ? 2 : -1);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      styles: ["ngb-toast{display:block}ngb-toast .toast-header .close{margin-left:auto;margin-bottom:.25rem}\n"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbToast, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-toast',
      exportAs: 'ngbToast',
      standalone: true,
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        role: 'alert',
        '[attr.aria-live]': 'ariaLive',
        'aria-atomic': 'true',
        class: 'toast',
        '[class.fade]': 'animation'
      },
      template: `
		<ng-template #headerTpl>
			<strong class="me-auto">{{ header }}</strong>
		</ng-template>
		@if (contentHeaderTpl || header) {
			<div class="toast-header">
				<ng-template [ngTemplateOutlet]="contentHeaderTpl || headerTpl" />
				<button
					type="button"
					class="btn-close"
					aria-label="Close"
					i18n-aria-label="@@ngb.toast.close-aria"
					(click)="hide()"
				>
				</button>
			</div>
		}
		<div class="toast-body">
			<ng-content />
		</div>
	`,
      styles: ["ngb-toast{display:block}ngb-toast .toast-header .close{margin-left:auto;margin-bottom:.25rem}\n"]
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['aria-live']
    }]
  }], {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    delay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    autohide: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    header: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    contentHeaderTpl: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgbToastHeader, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef,
        static: true
      }]
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbToastModule {
  static {
    this.ɵfac = function NgbToastModule_Factory(t) {
      return new (t || NgbToastModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbToastModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbToastModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbToast, NgbToastHeader],
      exports: [NgbToast, NgbToastHeader]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbTooltip`](#/components/tooltip/api#NgbTooltip) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the tooltips used in the application.
 */
class NgbTooltipConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.autoClose = true;
    this.placement = 'auto';
    this.popperOptions = options => options;
    this.triggers = 'hover focus';
    this.disableTooltip = false;
    this.openDelay = 0;
    this.closeDelay = 0;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbTooltipConfig_Factory(t) {
      return new (t || NgbTooltipConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTooltipConfig,
      factory: NgbTooltipConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTooltipConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
let nextId = 0;
class NgbTooltipWindow {
  static {
    this.ɵfac = function NgbTooltipWindow_Factory(t) {
      return new (t || NgbTooltipWindow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbTooltipWindow,
      selectors: [["ngb-tooltip-window"]],
      hostAttrs: ["role", "tooltip"],
      hostVars: 5,
      hostBindings: function NgbTooltipWindow_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("tooltip" + (ctx.tooltipClass ? " " + ctx.tooltipClass : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        id: "id",
        tooltipClass: "tooltipClass"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 3,
      vars: 0,
      consts: [["data-popper-arrow", "", 1, "tooltip-arrow"], [1, "tooltip-inner"]],
      template: function NgbTooltipWindow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
        }
      },
      styles: ["ngb-tooltip-window{pointer-events:none;position:absolute}ngb-tooltip-window .tooltip-inner{pointer-events:auto}ngb-tooltip-window.bs-tooltip-top,ngb-tooltip-window.bs-tooltip-bottom{padding-left:0;padding-right:0}ngb-tooltip-window.bs-tooltip-start,ngb-tooltip-window.bs-tooltip-end{padding-top:0;padding-bottom:0}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTooltipWindow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-tooltip-window',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        '[class]': '"tooltip" + (tooltipClass ? " " + tooltipClass : "")',
        '[class.fade]': 'animation',
        role: 'tooltip',
        '[id]': 'id'
      },
      template: `
		<div class="tooltip-arrow" data-popper-arrow></div>
		<div class="tooltip-inner">
			<ng-content />
		</div>
	`,
      styles: ["ngb-tooltip-window{pointer-events:none;position:absolute}ngb-tooltip-window .tooltip-inner{pointer-events:auto}ngb-tooltip-window.bs-tooltip-top,ngb-tooltip-window.bs-tooltip-bottom{padding-left:0;padding-right:0}ngb-tooltip-window.bs-tooltip-start,ngb-tooltip-window.bs-tooltip-end{padding-top:0;padding-bottom:0}\n"]
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    tooltipClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
/**
 * A lightweight and extensible directive for fancy tooltip creation.
 */
class NgbTooltip {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbTooltipConfig);
    /**
     * If `true`, tooltip opening and closing will be animated.
     *
     * @since 8.0.0
     */
    this.animation = this._config.animation;
    /**
     * Indicates whether the tooltip should be closed on `Escape` key and inside/outside clicks:
     *
     * * `true` - closes on both outside and inside clicks as well as `Escape` presses
     * * `false` - disables the autoClose feature (NB: triggers still apply)
     * * `"inside"` - closes on inside clicks as well as Escape presses
     * * `"outside"` - closes on outside clicks (sometimes also achievable through triggers)
     * as well as `Escape` presses
     *
     * @since 3.0.0
     */
    this.autoClose = this._config.autoClose;
    /**
     * The preferred placement of the tooltip, among the [possible values](#/guides/positioning#api).
     *
     * The default order of preference is `"auto"`.
     *
     * Please see the [positioning overview](#/positioning) for more details.
     */
    this.placement = this._config.placement;
    /**
     * Allows to change default Popper options when positioning the tooltip.
     * Receives current popper options and returns modified ones.
     *
     * @since 13.1.0
     */
    this.popperOptions = this._config.popperOptions;
    /**
     * Specifies events that should trigger the tooltip.
     *
     * Supports a space separated list of event names.
     * For more details see the [triggers demo](#/components/tooltip/examples#triggers).
     */
    this.triggers = this._config.triggers;
    /**
     * A selector specifying the element the tooltip should be appended to.
     *
     * Currently only supports `"body"`.
     */
    this.container = this._config.container;
    /**
     * If `true`, tooltip is disabled and won't be displayed.
     *
     * @since 1.1.0
     */
    this.disableTooltip = this._config.disableTooltip;
    /**
     * An optional class applied to the tooltip window element.
     *
     * @since 3.2.0
     */
    this.tooltipClass = this._config.tooltipClass;
    /**
     * The opening delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
     *
     * @since 4.1.0
     */
    this.openDelay = this._config.openDelay;
    /**
     * The closing delay in ms. Works only for "non-manual" opening triggers defined by the `triggers` input.
     *
     * @since 4.1.0
     */
    this.closeDelay = this._config.closeDelay;
    /**
     * An event emitted when the tooltip opening animation has finished. Contains no payload.
     */
    this.shown = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    /**
     * An event emitted when the tooltip closing animation has finished. Contains no payload.
     */
    this.hidden = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._ngbTooltipWindowId = `ngb-tooltip-${nextId++}`;
    this._popupService = new PopupService(NgbTooltipWindow);
    this._windowRef = null;
    this._positioning = ngbPositioning();
  }
  /**
   * The string content or a `TemplateRef` for the content to be displayed in the tooltip.
   *
   * If the content if falsy, the tooltip won't open.
   */
  set ngbTooltip(value) {
    this._ngbTooltip = value;
    if (!value && this._windowRef) {
      this.close();
    }
  }
  get ngbTooltip() {
    return this._ngbTooltip;
  }
  /**
   * Opens the tooltip.
   *
   * This is considered to be a "manual" triggering.
   * The `context` is an optional value to be injected into the tooltip template when it is created.
   */
  open(context) {
    if (!this._windowRef && this._ngbTooltip && !this.disableTooltip) {
      const {
        windowRef,
        transition$
      } = this._popupService.open(this._ngbTooltip, context ?? this.tooltipContext, this.animation);
      this._windowRef = windowRef;
      this._windowRef.setInput('animation', this.animation);
      this._windowRef.setInput('tooltipClass', this.tooltipClass);
      this._windowRef.setInput('id', this._ngbTooltipWindowId);
      this._getPositionTargetElement().setAttribute('aria-describedby', this._ngbTooltipWindowId);
      if (this.container === 'body') {
        this._document.body.appendChild(this._windowRef.location.nativeElement);
      }
      // We need to detect changes, because we don't know where .open() might be called from.
      // Ex. opening tooltip from one of lifecycle hooks that run after the CD
      // (say from ngAfterViewInit) will result in 'ExpressionHasChanged' exception
      this._windowRef.changeDetectorRef.detectChanges();
      // We need to mark for check, because tooltip won't work inside the OnPush component.
      // Ex. when we use expression like `{{ tooltip.isOpen() : 'opened' : 'closed' }}`
      // inside the template of an OnPush component and we change the tooltip from
      // open -> closed, the expression in question won't be updated unless we explicitly
      // mark the parent component to be checked.
      this._windowRef.changeDetectorRef.markForCheck();
      // Setting up popper and scheduling updates when zone is stable
      this._ngZone.runOutsideAngular(() => {
        this._positioning.createPopper({
          hostElement: this._getPositionTargetElement(),
          targetElement: this._windowRef.location.nativeElement,
          placement: this.placement,
          appendToBody: this.container === 'body',
          baseClass: 'bs-tooltip',
          updatePopperOptions: options => this.popperOptions(addPopperOffset([0, 6])(options))
        });
        Promise.resolve().then(() => {
          // This update is required for correct arrow placement
          this._positioning.update();
          this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positioning.update());
        });
      });
      ngbAutoClose(this._ngZone, this._document, this.autoClose, () => this.close(), this.hidden, [this._windowRef.location.nativeElement], [this._nativeElement]);
      transition$.subscribe(() => this.shown.emit());
    }
  }
  /**
   * Closes the tooltip.
   *
   * This is considered to be a "manual" triggering of the tooltip.
   */
  close(animation = this.animation) {
    if (this._windowRef != null) {
      this._getPositionTargetElement().removeAttribute('aria-describedby');
      this._popupService.close(animation).subscribe(() => {
        this._windowRef = null;
        this._positioning.destroy();
        this._zoneSubscription?.unsubscribe();
        this.hidden.emit();
        this._changeDetector.markForCheck();
      });
    }
  }
  /**
   * Toggles the tooltip.
   *
   * This is considered to be a "manual" triggering of the tooltip.
   */
  toggle() {
    if (this._windowRef) {
      this.close();
    } else {
      this.open();
    }
  }
  /**
   * Returns `true`, if the popover is currently shown.
   */
  isOpen() {
    return this._windowRef != null;
  }
  ngOnInit() {
    this._unregisterListenersFn = listenToTriggers(this._nativeElement, this.triggers, this.isOpen.bind(this), this.open.bind(this), this.close.bind(this), +this.openDelay, +this.closeDelay);
  }
  ngOnChanges({
    tooltipClass
  }) {
    if (tooltipClass && this.isOpen()) {
      this._windowRef.setInput('tooltipClass', tooltipClass.currentValue);
    }
  }
  ngOnDestroy() {
    this.close(false);
    // This check is needed as it might happen that ngOnDestroy is called before ngOnInit
    // under certain conditions, see: https://github.com/ng-bootstrap/ng-bootstrap/issues/2199
    this._unregisterListenersFn?.();
  }
  _getPositionTargetElement() {
    return (isString(this.positionTarget) ? this._document.querySelector(this.positionTarget) : this.positionTarget) || this._nativeElement;
  }
  static {
    this.ɵfac = function NgbTooltip_Factory(t) {
      return new (t || NgbTooltip)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbTooltip,
      selectors: [["", "ngbTooltip", ""]],
      inputs: {
        animation: "animation",
        autoClose: "autoClose",
        placement: "placement",
        popperOptions: "popperOptions",
        triggers: "triggers",
        positionTarget: "positionTarget",
        container: "container",
        disableTooltip: "disableTooltip",
        tooltipClass: "tooltipClass",
        tooltipContext: "tooltipContext",
        openDelay: "openDelay",
        closeDelay: "closeDelay",
        ngbTooltip: "ngbTooltip"
      },
      outputs: {
        shown: "shown",
        hidden: "hidden"
      },
      exportAs: ["ngbTooltip"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTooltip, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngbTooltip]',
      standalone: true,
      exportAs: 'ngbTooltip'
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    autoClose: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    placement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popperOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    triggers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    positionTarget: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disableTooltip: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    tooltipClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    tooltipContext: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    openDelay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    closeDelay: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    shown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    hidden: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    ngbTooltip: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class NgbTooltipModule {
  static {
    this.ɵfac = function NgbTooltipModule_Factory(t) {
      return new (t || NgbTooltipModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbTooltipModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTooltipModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbTooltip],
      exports: [NgbTooltip]
    }]
  }], null, null);
})();

/**
 * A component that helps with text highlighting.
 *
 * It splits the `result` text into parts that contain the searched `term` and generates the HTML markup to simplify
 * highlighting:
 *
 * Ex. `result="Alaska"` and `term="as"` will produce `Al<span class="ngb-highlight">as</span>ka`.
 */
class NgbHighlight {
  constructor() {
    /**
     * The CSS class for `<span>` elements wrapping the `term` inside the `result`.
     */
    this.highlightClass = 'ngb-highlight';
    /**
     * Boolean option to determine if the highlighting should be sensitive to accents or not.
     *
     * This feature is only available for browsers that implement the `String.normalize` function
     * (typically not Internet Explorer).
     * If you want to use this feature in a browser that does not implement `String.normalize`,
     * you will have to include a polyfill in your application (`unorm` for example).
     *
     * @since 9.1.0
     */
    this.accentSensitive = true;
  }
  ngOnChanges(changes) {
    if (!this.accentSensitive && !String.prototype.normalize) {
      console.warn('The `accentSensitive` input in `ngb-highlight` cannot be set to `false` in a browser ' + 'that does not implement the `String.normalize` function. ' + 'You will have to include a polyfill in your application to use this feature in the current browser.');
      this.accentSensitive = true;
    }
    const result = toString(this.result);
    const terms = Array.isArray(this.term) ? this.term : [this.term];
    const prepareTerm = term => this.accentSensitive ? term : removeAccents(term);
    const escapedTerms = terms.map(term => regExpEscape(prepareTerm(toString(term)))).filter(term => term);
    const toSplit = this.accentSensitive ? result : removeAccents(result);
    const parts = escapedTerms.length ? toSplit.split(new RegExp(`(${escapedTerms.join('|')})`, 'gmi')) : [result];
    if (this.accentSensitive) {
      this.parts = parts;
    } else {
      let offset = 0;
      this.parts = parts.map(part => result.substring(offset, offset += part.length));
    }
  }
  static {
    this.ɵfac = function NgbHighlight_Factory(t) {
      return new (t || NgbHighlight)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbHighlight,
      selectors: [["ngb-highlight"]],
      inputs: {
        highlightClass: "highlightClass",
        result: "result",
        term: "term",
        accentSensitive: "accentSensitive"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 2,
      vars: 0,
      consts: [[3, "class"]],
      template: function NgbHighlight_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](0, NgbHighlight_For_1_Template, 2, 1, null, null, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.parts);
        }
      },
      styles: [".ngb-highlight{font-weight:700}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbHighlight, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-highlight',
      standalone: true,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: `
		@for (part of parts; track part; let odd = $odd) {
			@if (odd) {
				<span class="{{ highlightClass }}">{{ part }}</span>
			} @else {
				<ng-container>{{ part }}</ng-container>
			}
		}
	`,
      styles: [".ngb-highlight{font-weight:700}\n"]
    }]
  }], null, {
    highlightClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    result: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true
      }]
    }],
    term: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input,
      args: [{
        required: true
      }]
    }],
    accentSensitive: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
const ARIA_LIVE_DELAY = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('live announcer delay', {
  providedIn: 'root',
  factory: () => 100
});
function getLiveElement(document, lazyCreate = false) {
  let element = document.body.querySelector('#ngb-live');
  if (element == null && lazyCreate) {
    element = document.createElement('div');
    element.setAttribute('id', 'ngb-live');
    element.setAttribute('aria-live', 'polite');
    element.setAttribute('aria-atomic', 'true');
    element.classList.add('visually-hidden');
    document.body.appendChild(element);
  }
  return element;
}
class Live {
  constructor() {
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._delay = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ARIA_LIVE_DELAY);
  }
  ngOnDestroy() {
    const element = getLiveElement(this._document);
    if (element) {
      // if exists, it will always be attached to the <body>
      element.parentElement.removeChild(element);
    }
  }
  say(message) {
    const element = getLiveElement(this._document, true);
    const delay = this._delay;
    if (element != null) {
      element.textContent = '';
      const setText = () => element.textContent = message;
      if (delay === null) {
        setText();
      } else {
        setTimeout(setText, delay);
      }
    }
  }
  static {
    this.ɵfac = function Live_Factory(t) {
      return new (t || Live)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: Live,
      factory: Live.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Live, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbTypeahead`](#/components/typeahead/api#NgbTypeahead) component.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all the typeaheads used in the application.
 */
class NgbTypeaheadConfig {
  constructor() {
    this.editable = true;
    this.focusFirst = true;
    this.selectOnExact = false;
    this.showHint = false;
    this.placement = ['bottom-start', 'bottom-end', 'top-start', 'top-end'];
    this.popperOptions = options => options;
  }
  static {
    this.ɵfac = function NgbTypeaheadConfig_Factory(t) {
      return new (t || NgbTypeaheadConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbTypeaheadConfig,
      factory: NgbTypeaheadConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTypeaheadConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class NgbTypeaheadWindow {
  constructor() {
    this.activeIdx = 0;
    /**
     * Flag indicating if the first row should be active initially
     */
    this.focusFirst = true;
    /**
     * A function used to format a given result before display. This function should return a formatted string without any
     * HTML markup
     */
    this.formatter = toString;
    /**
     * Event raised when user selects a particular result row
     */
    this.selectEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.activeChangeEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  hasActive() {
    return this.activeIdx > -1 && this.activeIdx < this.results.length;
  }
  getActive() {
    return this.results[this.activeIdx];
  }
  markActive(activeIdx) {
    this.activeIdx = activeIdx;
    this._activeChanged();
  }
  next() {
    if (this.activeIdx === this.results.length - 1) {
      this.activeIdx = this.focusFirst ? (this.activeIdx + 1) % this.results.length : -1;
    } else {
      this.activeIdx++;
    }
    this._activeChanged();
  }
  prev() {
    if (this.activeIdx < 0) {
      this.activeIdx = this.results.length - 1;
    } else if (this.activeIdx === 0) {
      this.activeIdx = this.focusFirst ? this.results.length - 1 : -1;
    } else {
      this.activeIdx--;
    }
    this._activeChanged();
  }
  resetActive() {
    this.activeIdx = this.focusFirst ? 0 : -1;
    this._activeChanged();
  }
  select(item) {
    this.selectEvent.emit(item);
  }
  ngOnInit() {
    this.resetActive();
  }
  _activeChanged() {
    this.activeChangeEvent.emit(this.activeIdx >= 0 ? this.id + '-' + this.activeIdx : undefined);
  }
  static {
    this.ɵfac = function NgbTypeaheadWindow_Factory(t) {
      return new (t || NgbTypeaheadWindow)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbTypeaheadWindow,
      selectors: [["ngb-typeahead-window"]],
      hostAttrs: ["role", "listbox"],
      hostVars: 3,
      hostBindings: function NgbTypeaheadWindow_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mousedown", function NgbTypeaheadWindow_mousedown_HostBindingHandler($event) {
            return $event.preventDefault();
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("id", ctx.id);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("dropdown-menu show" + (ctx.popupClass ? " " + ctx.popupClass : ""));
        }
      },
      inputs: {
        id: "id",
        focusFirst: "focusFirst",
        results: "results",
        term: "term",
        formatter: "formatter",
        resultTemplate: "resultTemplate",
        popupClass: "popupClass"
      },
      outputs: {
        selectEvent: "select",
        activeChangeEvent: "activeChange"
      },
      exportAs: ["ngbTypeaheadWindow"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 4,
      vars: 0,
      consts: [["rt", ""], ["type", "button", "role", "option", 1, "dropdown-item", 3, "id", "active"], [3, "result", "term"], ["type", "button", "role", "option", 1, "dropdown-item", 3, "mouseenter", "click", "id"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"]],
      template: function NgbTypeaheadWindow_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgbTypeaheadWindow_ng_template_0_Template, 1, 2, "ng-template", null, 0, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"]);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterCreate"](2, NgbTypeaheadWindow_For_3_Template, 2, 9, "button", 1, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeaterTrackByIdentity"]);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrepeater"](ctx.results);
        }
      },
      dependencies: [NgbHighlight, _angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTypeaheadWindow, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-typeahead-window',
      exportAs: 'ngbTypeaheadWindow',
      standalone: true,
      imports: [NgbHighlight, _angular_common__WEBPACK_IMPORTED_MODULE_13__.NgTemplateOutlet],
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        '(mousedown)': '$event.preventDefault()',
        '[class]': '"dropdown-menu show" + (popupClass ? " " + popupClass : "")',
        role: 'listbox',
        '[id]': 'id'
      },
      template: `
		<ng-template #rt let-result="result" let-term="term" let-formatter="formatter">
			<ngb-highlight [result]="formatter(result)" [term]="term" />
		</ng-template>
		@for (result of results; track result; let idx = $index) {
			<button
				type="button"
				class="dropdown-item"
				role="option"
				[id]="id + '-' + idx"
				[class.active]="idx === activeIdx"
				(mouseenter)="markActive(idx)"
				(click)="select(result)"
			>
				<ng-template
					[ngTemplateOutlet]="resultTemplate || rt"
					[ngTemplateOutletContext]="{ result: result, term: term, formatter: formatter }"
				/>
			</button>
		}
	`
    }]
  }], null, {
    id: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    focusFirst: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    results: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    term: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    formatter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    resultTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popupClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['select']
    }],
    activeChangeEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['activeChange']
    }]
  });
})();
let nextWindowId = 0;
/**
 * A directive providing a simple way of creating powerful typeaheads from any text input.
 */
class NgbTypeahead {
  constructor() {
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbTypeaheadConfig);
    this._live = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(Live);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._changeDetector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef);
    this._popupService = new PopupService(NgbTypeaheadWindow);
    this._positioning = ngbPositioning();
    this._subscription = null;
    this._closed$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._inputValueBackup = null;
    this._inputValueForSelectOnExact = null;
    this._valueChanges$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(this._nativeElement, 'input').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.map)($event => $event.target.value));
    this._resubscribeTypeahead$ = new rxjs__WEBPACK_IMPORTED_MODULE_12__.BehaviorSubject(null);
    this._windowRef = null;
    /**
     * The value for the `autocomplete` attribute for the `<input>` element.
     *
     * Defaults to `"off"` to disable the native browser autocomplete, but you can override it if necessary.
     *
     * @since 2.1.0
     */
    this.autocomplete = 'off';
    /**
     * A selector specifying the element the typeahead popup will be appended to.
     *
     * Currently only supports `"body"`.
     */
    this.container = this._config.container;
    /**
     * If `true`, model values will not be restricted only to items selected from the popup.
     */
    this.editable = this._config.editable;
    /**
     * If `true`, the first item in the result list will always stay focused while typing.
     */
    this.focusFirst = this._config.focusFirst;
    /**
     * If `true`, automatically selects the item when it is the only one that exactly matches the user input
     *
     * @since 14.2.0
     */
    this.selectOnExact = this._config.selectOnExact;
    /**
     * If `true`, will show the hint in the `<input>` when an item in the result list matches.
     */
    this.showHint = this._config.showHint;
    /**
     * The preferred placement of the typeahead, among the [possible values](#/guides/positioning#api).
     *
     * The default order of preference is `"bottom-start bottom-end top-start top-end"`
     *
     * Please see the [positioning overview](#/positioning) for more details.
     */
    this.placement = this._config.placement;
    /**
     * Allows to change default Popper options when positioning the typeahead.
     * Receives current popper options and returns modified ones.
     *
     * @since 13.1.0
     */
    this.popperOptions = this._config.popperOptions;
    /**
     * An event emitted right before an item is selected from the result list.
     *
     * Event payload is of type [`NgbTypeaheadSelectItemEvent`](#/components/typeahead/api#NgbTypeaheadSelectItemEvent).
     */
    this.selectItem = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.activeDescendant = null;
    this.popupId = `ngb-typeahead-${nextWindowId++}`;
    this._onTouched = () => {};
    this._onChange = _ => {};
  }
  ngOnInit() {
    this._subscribeToUserInput();
  }
  ngOnChanges({
    ngbTypeahead
  }) {
    if (ngbTypeahead && !ngbTypeahead.firstChange) {
      this._unsubscribeFromUserInput();
      this._subscribeToUserInput();
    }
  }
  ngOnDestroy() {
    this._closePopup();
    this._unsubscribeFromUserInput();
  }
  registerOnChange(fn) {
    this._onChange = fn;
  }
  registerOnTouched(fn) {
    this._onTouched = fn;
  }
  writeValue(value) {
    this._writeInputValue(this._formatItemForInput(value));
    if (this.showHint) {
      this._inputValueBackup = value;
    }
  }
  setDisabledState(isDisabled) {
    this._nativeElement.disabled = isDisabled;
  }
  /**
   * Dismisses typeahead popup window
   */
  dismissPopup() {
    if (this.isPopupOpen()) {
      this._resubscribeTypeahead$.next(null);
      this._closePopup();
      if (this.showHint && this._inputValueBackup !== null) {
        this._writeInputValue(this._inputValueBackup);
      }
      this._changeDetector.markForCheck();
    }
  }
  /**
   * Returns true if the typeahead popup window is displayed
   */
  isPopupOpen() {
    return this._windowRef != null;
  }
  handleBlur() {
    this._resubscribeTypeahead$.next(null);
    this._onTouched();
  }
  handleKeyDown(event) {
    if (!this.isPopupOpen()) {
      return;
    }
    /* eslint-disable-next-line deprecation/deprecation */
    switch (event.which) {
      case Key.ArrowDown:
        event.preventDefault();
        this._windowRef.instance.next();
        this._showHint();
        break;
      case Key.ArrowUp:
        event.preventDefault();
        this._windowRef.instance.prev();
        this._showHint();
        break;
      case Key.Enter:
      case Key.Tab:
        {
          const result = this._windowRef.instance.getActive();
          if (isDefined(result)) {
            event.preventDefault();
            event.stopPropagation();
            this._selectResult(result);
          }
          this._closePopup();
          break;
        }
    }
  }
  _openPopup() {
    if (!this.isPopupOpen()) {
      this._inputValueBackup = this._nativeElement.value;
      const {
        windowRef
      } = this._popupService.open();
      this._windowRef = windowRef;
      this._windowRef.setInput('id', this.popupId);
      this._windowRef.setInput('popupClass', this.popupClass);
      this._windowRef.instance.selectEvent.subscribe(result => this._selectResultClosePopup(result));
      this._windowRef.instance.activeChangeEvent.subscribe(activeId => this.activeDescendant = activeId);
      if (this.container === 'body') {
        this._windowRef.location.nativeElement.style.zIndex = '1055';
        this._document.body.appendChild(this._windowRef.location.nativeElement);
      }
      this._changeDetector.markForCheck();
      // Setting up popper and scheduling updates when zone is stable
      this._ngZone.runOutsideAngular(() => {
        if (this._windowRef) {
          this._positioning.createPopper({
            hostElement: this._nativeElement,
            targetElement: this._windowRef.location.nativeElement,
            placement: this.placement,
            appendToBody: this.container === 'body',
            updatePopperOptions: options => this.popperOptions(addPopperOffset([0, 2])(options))
          });
          this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positioning.update());
        }
      });
      ngbAutoClose(this._ngZone, this._document, 'outside', () => this.dismissPopup(), this._closed$, [this._nativeElement, this._windowRef.location.nativeElement]);
    }
  }
  _closePopup() {
    this._popupService.close().subscribe(() => {
      this._positioning.destroy();
      this._zoneSubscription?.unsubscribe();
      this._closed$.next();
      this._windowRef = null;
      this.activeDescendant = null;
    });
  }
  _selectResult(result) {
    let defaultPrevented = false;
    this.selectItem.emit({
      item: result,
      preventDefault: () => {
        defaultPrevented = true;
      }
    });
    this._resubscribeTypeahead$.next(null);
    if (!defaultPrevented) {
      this.writeValue(result);
      this._onChange(result);
    }
  }
  _selectResultClosePopup(result) {
    this._selectResult(result);
    this._closePopup();
  }
  _showHint() {
    if (this.showHint && this._windowRef?.instance.hasActive() && this._inputValueBackup != null) {
      const userInputLowerCase = this._inputValueBackup.toLowerCase();
      const formattedVal = this._formatItemForInput(this._windowRef.instance.getActive());
      if (userInputLowerCase === formattedVal.substring(0, this._inputValueBackup.length).toLowerCase()) {
        this._writeInputValue(this._inputValueBackup + formattedVal.substring(this._inputValueBackup.length));
        this._nativeElement['setSelectionRange'].apply(this._nativeElement, [this._inputValueBackup.length, formattedVal.length]);
      } else {
        this._writeInputValue(formattedVal);
      }
    }
  }
  _formatItemForInput(item) {
    return item != null && this.inputFormatter ? this.inputFormatter(item) : toString(item);
  }
  _writeInputValue(value) {
    this._nativeElement.value = toString(value);
  }
  _subscribeToUserInput() {
    const results$ = this._valueChanges$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_24__.tap)(value => {
      this._inputValueBackup = this.showHint ? value : null;
      this._inputValueForSelectOnExact = this.selectOnExact ? value : null;
      this._onChange(this.editable ? value : undefined);
    }), this.ngbTypeahead ? this.ngbTypeahead : () => (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)([]));
    this._subscription = this._resubscribeTypeahead$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_18__.switchMap)(() => results$)).subscribe(results => {
      if (!results || results.length === 0) {
        this._closePopup();
      } else {
        // when there is only one result and this matches the input value
        if (this.selectOnExact && results.length === 1 && this._formatItemForInput(results[0]) === this._inputValueForSelectOnExact) {
          this._selectResult(results[0]);
          this._closePopup();
        } else {
          this._openPopup();
          this._windowRef.setInput('focusFirst', this.focusFirst);
          this._windowRef.setInput('results', results);
          this._windowRef.setInput('term', this._nativeElement.value);
          if (this.resultFormatter) {
            this._windowRef.setInput('formatter', this.resultFormatter);
          }
          if (this.resultTemplate) {
            this._windowRef.setInput('resultTemplate', this.resultTemplate);
          }
          this._windowRef.instance.resetActive();
          // The observable stream we are subscribing to might have async steps
          // and if a component containing typeahead is using the OnPush strategy
          // the change detection turn wouldn't be invoked automatically.
          this._windowRef.changeDetectorRef.detectChanges();
          this._showHint();
        }
      }
      // live announcer
      const count = results ? results.length : 0;
      this._live.say(count === 0 ? 'No results available' : `${count} result${count === 1 ? '' : 's'} available`);
    });
  }
  _unsubscribeFromUserInput() {
    if (this._subscription) {
      this._subscription.unsubscribe();
    }
    this._subscription = null;
  }
  static {
    this.ɵfac = function NgbTypeahead_Factory(t) {
      return new (t || NgbTypeahead)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgbTypeahead,
      selectors: [["input", "ngbTypeahead", ""]],
      hostAttrs: ["autocapitalize", "off", "autocorrect", "off", "role", "combobox"],
      hostVars: 7,
      hostBindings: function NgbTypeahead_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("blur", function NgbTypeahead_blur_HostBindingHandler() {
            return ctx.handleBlur();
          })("keydown", function NgbTypeahead_keydown_HostBindingHandler($event) {
            return ctx.handleKeyDown($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵhostProperty"]("autocomplete", ctx.autocomplete);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-autocomplete", ctx.showHint ? "both" : "list")("aria-activedescendant", ctx.activeDescendant)("aria-owns", ctx.isPopupOpen() ? ctx.popupId : null)("aria-expanded", ctx.isPopupOpen());
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("open", ctx.isPopupOpen());
        }
      },
      inputs: {
        autocomplete: "autocomplete",
        container: "container",
        editable: "editable",
        focusFirst: "focusFirst",
        inputFormatter: "inputFormatter",
        ngbTypeahead: "ngbTypeahead",
        resultFormatter: "resultFormatter",
        resultTemplate: "resultTemplate",
        selectOnExact: "selectOnExact",
        showHint: "showHint",
        placement: "placement",
        popperOptions: "popperOptions",
        popupClass: "popupClass"
      },
      outputs: {
        selectItem: "selectItem"
      },
      exportAs: ["ngbTypeahead"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbTypeahead),
        multi: true
      }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTypeahead, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: 'input[ngbTypeahead]',
      exportAs: 'ngbTypeahead',
      standalone: true,
      host: {
        '(blur)': 'handleBlur()',
        '[class.open]': 'isPopupOpen()',
        '(keydown)': 'handleKeyDown($event)',
        '[autocomplete]': 'autocomplete',
        autocapitalize: 'off',
        autocorrect: 'off',
        role: 'combobox',
        '[attr.aria-autocomplete]': 'showHint ? "both" : "list"',
        '[attr.aria-activedescendant]': 'activeDescendant',
        '[attr.aria-owns]': 'isPopupOpen() ? popupId : null',
        '[attr.aria-expanded]': 'isPopupOpen()'
      },
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_23__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgbTypeahead),
        multi: true
      }]
    }]
  }], null, {
    autocomplete: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    container: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    editable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    focusFirst: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    inputFormatter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ngbTypeahead: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    resultFormatter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    resultTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectOnExact: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    showHint: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    placement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popperOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    popupClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectItem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class NgbTypeaheadModule {
  static {
    this.ɵfac = function NgbTypeaheadModule_Factory(t) {
      return new (t || NgbTypeaheadModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbTypeaheadModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbTypeaheadModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [NgbHighlight, NgbTypeahead],
      exports: [NgbHighlight, NgbTypeahead]
    }]
  }], null, null);
})();

/**
 * A configuration service for the [`NgbOffcanvas`](#/components/offcanvas/api#NgbOffcanvas) service.
 *
 * You can inject this service, typically in your root component, and customize the values of its properties in
 * order to provide default values for all offcanvases used in the application.
 *
 * @since 12.1.0
 */
class NgbOffcanvasConfig {
  constructor() {
    this._ngbConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbConfig);
    this.backdrop = true;
    this.keyboard = true;
    this.position = 'start';
    this.scroll = false;
  }
  get animation() {
    return this._animation ?? this._ngbConfig.animation;
  }
  set animation(animation) {
    this._animation = animation;
  }
  static {
    this.ɵfac = function NgbOffcanvasConfig_Factory(t) {
      return new (t || NgbOffcanvasConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbOffcanvasConfig,
      factory: NgbOffcanvasConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvasConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();

/**
 * A reference to the currently opened (active) offcanvas.
 *
 * Instances of this class can be injected into your component passed as offcanvas content.
 * So you can `.close()` or `.dismiss()` the offcanvas window from your component.
 *
 * @since 12.1.0
 */
class NgbActiveOffcanvas {
  /**
   * Closes the offcanvas with an optional `result` value.
   *
   * The `NgbOffcanvasRef.result` promise will be resolved with the provided value.
   */
  close(result) {}
  /**
   * Dismisses the offcanvas with an optional `reason` value.
   *
   * The `NgbOffcanvasRef.result` promise will be rejected with the provided value.
   */
  dismiss(reason) {}
}
/**
 * A reference to the newly opened offcanvas returned by the `NgbOffcanvas.open()` method.
 *
 * @since 12.1.0
 */
class NgbOffcanvasRef {
  /**
   * The instance of a component used for the offcanvas content.
   *
   * When a `TemplateRef` is used as the content or when the offcanvas is closed, will return `undefined`.
   */
  get componentInstance() {
    if (this._contentRef && this._contentRef.componentRef) {
      return this._contentRef.componentRef.instance;
    }
  }
  /**
   * The observable that emits when the offcanvas is closed via the `.close()` method.
   *
   * It will emit the result passed to the `.close()` method.
   */
  get closed() {
    return this._closed.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._hidden));
  }
  /**
   * The observable that emits when the offcanvas is dismissed via the `.dismiss()` method.
   *
   * It will emit the reason passed to the `.dismissed()` method by the user, or one of the internal
   * reasons like backdrop click or ESC key press.
   */
  get dismissed() {
    return this._dismissed.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._hidden));
  }
  /**
   * The observable that emits when both offcanvas window and backdrop are closed and animations were finished.
   * At this point offcanvas and backdrop elements will be removed from the DOM tree.
   *
   * This observable will be completed after emitting.
   */
  get hidden() {
    return this._hidden.asObservable();
  }
  /**
   * The observable that emits when offcanvas is fully visible and animation was finished.
   * The offcanvas DOM element is always available synchronously after calling 'offcanvas.open()' service.
   *
   * This observable will be completed after emitting.
   * It will not emit, if offcanvas is closed before open animation is finished.
   */
  get shown() {
    return this._panelCmptRef.instance.shown.asObservable();
  }
  constructor(_panelCmptRef, _contentRef, _backdropCmptRef, _beforeDismiss) {
    this._panelCmptRef = _panelCmptRef;
    this._contentRef = _contentRef;
    this._backdropCmptRef = _backdropCmptRef;
    this._beforeDismiss = _beforeDismiss;
    this._closed = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._dismissed = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._hidden = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    _panelCmptRef.instance.dismissEvent.subscribe(reason => {
      this.dismiss(reason);
    });
    if (_backdropCmptRef) {
      _backdropCmptRef.instance.dismissEvent.subscribe(reason => {
        this.dismiss(reason);
      });
    }
    this.result = new Promise((resolve, reject) => {
      this._resolve = resolve;
      this._reject = reject;
    });
    this.result.then(null, () => {});
  }
  /**
   * Closes the offcanvas with an optional `result` value.
   *
   * The `NgbMobalRef.result` promise will be resolved with the provided value.
   */
  close(result) {
    if (this._panelCmptRef) {
      this._closed.next(result);
      this._resolve(result);
      this._removeOffcanvasElements();
    }
  }
  _dismiss(reason) {
    this._dismissed.next(reason);
    this._reject(reason);
    this._removeOffcanvasElements();
  }
  /**
   * Dismisses the offcanvas with an optional `reason` value.
   *
   * The `NgbOffcanvasRef.result` promise will be rejected with the provided value.
   */
  dismiss(reason) {
    if (this._panelCmptRef) {
      if (!this._beforeDismiss) {
        this._dismiss(reason);
      } else {
        const dismiss = this._beforeDismiss();
        if (isPromise(dismiss)) {
          dismiss.then(result => {
            if (result !== false) {
              this._dismiss(reason);
            }
          }, () => {});
        } else if (dismiss !== false) {
          this._dismiss(reason);
        }
      }
    }
  }
  _removeOffcanvasElements() {
    const panelTransition$ = this._panelCmptRef.instance.hide();
    const backdropTransition$ = this._backdropCmptRef ? this._backdropCmptRef.instance.hide() : (0,rxjs__WEBPACK_IMPORTED_MODULE_3__.of)(undefined);
    // hiding panel
    panelTransition$.subscribe(() => {
      const {
        nativeElement
      } = this._panelCmptRef.location;
      nativeElement.parentNode.removeChild(nativeElement);
      this._panelCmptRef.destroy();
      if (this._contentRef && this._contentRef.viewRef) {
        this._contentRef.viewRef.destroy();
      }
      this._panelCmptRef = null;
      this._contentRef = null;
    });
    // hiding backdrop
    backdropTransition$.subscribe(() => {
      if (this._backdropCmptRef) {
        const {
          nativeElement
        } = this._backdropCmptRef.location;
        nativeElement.parentNode.removeChild(nativeElement);
        this._backdropCmptRef.destroy();
        this._backdropCmptRef = null;
      }
    });
    // all done
    (0,rxjs__WEBPACK_IMPORTED_MODULE_21__.zip)(panelTransition$, backdropTransition$).subscribe(() => {
      this._hidden.next();
      this._hidden.complete();
    });
  }
}
var OffcanvasDismissReasons;
(function (OffcanvasDismissReasons) {
  OffcanvasDismissReasons[OffcanvasDismissReasons["BACKDROP_CLICK"] = 0] = "BACKDROP_CLICK";
  OffcanvasDismissReasons[OffcanvasDismissReasons["ESC"] = 1] = "ESC";
})(OffcanvasDismissReasons || (OffcanvasDismissReasons = {}));
class NgbOffcanvasBackdrop {
  constructor() {
    this._nativeElement = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef).nativeElement;
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this.dismissEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  }
  ngOnInit() {
    this._zone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      ngbRunTransition(this._zone, this._nativeElement, (element, animation) => {
        if (animation) {
          reflow(element);
        }
        element.classList.add('show');
      }, {
        animation: this.animation,
        runningTransition: 'continue'
      });
    });
  }
  hide() {
    return ngbRunTransition(this._zone, this._nativeElement, ({
      classList
    }) => classList.remove('show'), {
      animation: this.animation,
      runningTransition: 'stop'
    });
  }
  dismiss() {
    if (!this.static) {
      this.dismissEvent.emit(OffcanvasDismissReasons.BACKDROP_CLICK);
    }
  }
  static {
    this.ɵfac = function NgbOffcanvasBackdrop_Factory(t) {
      return new (t || NgbOffcanvasBackdrop)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbOffcanvasBackdrop,
      selectors: [["ngb-offcanvas-backdrop"]],
      hostVars: 6,
      hostBindings: function NgbOffcanvasBackdrop_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mousedown", function NgbOffcanvasBackdrop_mousedown_HostBindingHandler() {
            return ctx.dismiss();
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("offcanvas-backdrop" + (ctx.backdropClass ? " " + ctx.backdropClass : ""));
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("show", !ctx.animation)("fade", ctx.animation);
        }
      },
      inputs: {
        animation: "animation",
        backdropClass: "backdropClass",
        static: "static"
      },
      outputs: {
        dismissEvent: "dismiss"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      decls: 0,
      vars: 0,
      template: function NgbOffcanvasBackdrop_Template(rf, ctx) {},
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvasBackdrop, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-offcanvas-backdrop',
      standalone: true,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      template: '',
      host: {
        '[class]': '"offcanvas-backdrop" + (backdropClass ? " " + backdropClass : "")',
        '[class.show]': '!animation',
        '[class.fade]': 'animation',
        '(mousedown)': 'dismiss()'
      }
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    backdropClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    static: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dismissEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['dismiss']
    }]
  });
})();
class NgbOffcanvasPanel {
  constructor() {
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._elRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
    this._zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    this._closed$ = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._elWithFocus = null; // element that is focused prior to offcanvas opening
    this.keyboard = true;
    this.position = 'start';
    this.dismissEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.shown = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this.hidden = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
  }
  dismiss(reason) {
    this.dismissEvent.emit(reason);
  }
  ngOnInit() {
    this._elWithFocus = this._document.activeElement;
    this._zone.onStable.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.take)(1)).subscribe(() => {
      this._show();
    });
  }
  ngOnDestroy() {
    this._disableEventHandling();
  }
  hide() {
    const context = {
      animation: this.animation,
      runningTransition: 'stop'
    };
    const offcanvasTransition$ = ngbRunTransition(this._zone, this._elRef.nativeElement, element => {
      element.classList.remove('showing');
      element.classList.add('hiding');
      return () => element.classList.remove('show', 'hiding');
    }, context);
    offcanvasTransition$.subscribe(() => {
      this.hidden.next();
      this.hidden.complete();
    });
    this._disableEventHandling();
    this._restoreFocus();
    return offcanvasTransition$;
  }
  _show() {
    const context = {
      animation: this.animation,
      runningTransition: 'continue'
    };
    const offcanvasTransition$ = ngbRunTransition(this._zone, this._elRef.nativeElement, (element, animation) => {
      if (animation) {
        reflow(element);
      }
      element.classList.add('show', 'showing');
      return () => element.classList.remove('showing');
    }, context);
    offcanvasTransition$.subscribe(() => {
      this.shown.next();
      this.shown.complete();
    });
    this._enableEventHandling();
    this._setFocus();
  }
  _enableEventHandling() {
    const {
      nativeElement
    } = this._elRef;
    this._zone.runOutsideAngular(() => {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.fromEvent)(nativeElement, 'keydown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.takeUntil)(this._closed$), /* eslint-disable-next-line deprecation/deprecation */
      (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(e => e.which === Key.Escape)).subscribe(event => {
        if (this.keyboard) {
          requestAnimationFrame(() => {
            if (!event.defaultPrevented) {
              this._zone.run(() => this.dismiss(OffcanvasDismissReasons.ESC));
            }
          });
        }
      });
    });
  }
  _disableEventHandling() {
    this._closed$.next();
  }
  _setFocus() {
    const {
      nativeElement
    } = this._elRef;
    if (!nativeElement.contains(document.activeElement)) {
      const autoFocusable = nativeElement.querySelector(`[ngbAutofocus]`);
      const firstFocusable = getFocusableBoundaryElements(nativeElement)[0];
      const elementToFocus = autoFocusable || firstFocusable || nativeElement;
      elementToFocus.focus();
    }
  }
  _restoreFocus() {
    const body = this._document.body;
    const elWithFocus = this._elWithFocus;
    let elementToFocus;
    if (elWithFocus && elWithFocus['focus'] && body.contains(elWithFocus)) {
      elementToFocus = elWithFocus;
    } else {
      elementToFocus = body;
    }
    this._zone.runOutsideAngular(() => {
      setTimeout(() => elementToFocus.focus());
      this._elWithFocus = null;
    });
  }
  static {
    this.ɵfac = function NgbOffcanvasPanel_Factory(t) {
      return new (t || NgbOffcanvasPanel)();
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgbOffcanvasPanel,
      selectors: [["ngb-offcanvas-panel"]],
      hostAttrs: ["role", "dialog", "tabindex", "-1"],
      hostVars: 5,
      hostBindings: function NgbOffcanvasPanel_HostBindings(rf, ctx) {
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-modal", true)("aria-labelledby", ctx.ariaLabelledBy)("aria-describedby", ctx.ariaDescribedBy);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassMap"]("offcanvas offcanvas-" + ctx.position + (ctx.panelClass ? " " + ctx.panelClass : ""));
        }
      },
      inputs: {
        animation: "animation",
        ariaLabelledBy: "ariaLabelledBy",
        ariaDescribedBy: "ariaDescribedBy",
        keyboard: "keyboard",
        panelClass: "panelClass",
        position: "position"
      },
      outputs: {
        dismissEvent: "dismiss"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵStandaloneFeature"]],
      ngContentSelectors: _c0,
      decls: 1,
      vars: 0,
      template: function NgbOffcanvasPanel_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
        }
      },
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvasPanel, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngb-offcanvas-panel',
      standalone: true,
      template: '<ng-content />',
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      host: {
        '[class]': '"offcanvas offcanvas-" + position  + (panelClass ? " " + panelClass : "")',
        role: 'dialog',
        tabindex: '-1',
        '[attr.aria-modal]': 'true',
        '[attr.aria-labelledby]': 'ariaLabelledBy',
        '[attr.aria-describedby]': 'ariaDescribedBy'
      }
    }]
  }], null, {
    animation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaLabelledBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    ariaDescribedBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    keyboard: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    panelClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    position: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dismissEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['dismiss']
    }]
  });
})();
class NgbOffcanvasStack {
  constructor() {
    this._applicationRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ApplicationRef);
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_13__.DOCUMENT);
    this._scrollBar = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(ScrollBar);
    this._activePanelCmptHasChanged = new rxjs__WEBPACK_IMPORTED_MODULE_4__.Subject();
    this._scrollBarRestoreFn = null;
    this._backdropAttributes = ['animation', 'backdropClass'];
    this._panelAttributes = ['animation', 'ariaDescribedBy', 'ariaLabelledBy', 'keyboard', 'panelClass', 'position'];
    this._activeInstance = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    const ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
    // Trap focus on active PanelCmpt
    this._activePanelCmptHasChanged.subscribe(() => {
      if (this._panelCmpt) {
        ngbFocusTrap(ngZone, this._panelCmpt.location.nativeElement, this._activePanelCmptHasChanged);
      }
    });
  }
  _restoreScrollBar() {
    const scrollBarRestoreFn = this._scrollBarRestoreFn;
    if (scrollBarRestoreFn) {
      this._scrollBarRestoreFn = null;
      scrollBarRestoreFn();
    }
  }
  _hideScrollBar() {
    if (!this._scrollBarRestoreFn) {
      this._scrollBarRestoreFn = this._scrollBar.hide();
    }
  }
  open(contentInjector, content, options) {
    const containerEl = options.container instanceof HTMLElement ? options.container : isDefined(options.container) ? this._document.querySelector(options.container) : this._document.body;
    if (!containerEl) {
      throw new Error(`The specified offcanvas container "${options.container || 'body'}" was not found in the DOM.`);
    }
    if (!options.scroll) {
      this._hideScrollBar();
    }
    const activeOffcanvas = new NgbActiveOffcanvas();
    const contentRef = this._getContentRef(options.injector || contentInjector, content, activeOffcanvas);
    let backdropCmptRef = options.backdrop !== false ? this._attachBackdrop(containerEl) : undefined;
    let panelCmptRef = this._attachWindowComponent(containerEl, contentRef.nodes);
    let ngbOffcanvasRef = new NgbOffcanvasRef(panelCmptRef, contentRef, backdropCmptRef, options.beforeDismiss);
    this._registerOffcanvasRef(ngbOffcanvasRef);
    this._registerPanelCmpt(panelCmptRef);
    ngbOffcanvasRef.hidden.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_34__.finalize)(() => this._restoreScrollBar())).subscribe();
    activeOffcanvas.close = result => {
      ngbOffcanvasRef.close(result);
    };
    activeOffcanvas.dismiss = reason => {
      ngbOffcanvasRef.dismiss(reason);
    };
    this._applyPanelOptions(panelCmptRef.instance, options);
    if (backdropCmptRef && backdropCmptRef.instance) {
      this._applyBackdropOptions(backdropCmptRef.instance, options);
      backdropCmptRef.changeDetectorRef.detectChanges();
    }
    panelCmptRef.changeDetectorRef.detectChanges();
    return ngbOffcanvasRef;
  }
  get activeInstance() {
    return this._activeInstance;
  }
  dismiss(reason) {
    this._offcanvasRef?.dismiss(reason);
  }
  hasOpenOffcanvas() {
    return !!this._offcanvasRef;
  }
  _attachBackdrop(containerEl) {
    let backdropCmptRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(NgbOffcanvasBackdrop, {
      environmentInjector: this._applicationRef.injector,
      elementInjector: this._injector
    });
    this._applicationRef.attachView(backdropCmptRef.hostView);
    containerEl.appendChild(backdropCmptRef.location.nativeElement);
    return backdropCmptRef;
  }
  _attachWindowComponent(containerEl, projectableNodes) {
    let panelCmptRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(NgbOffcanvasPanel, {
      environmentInjector: this._applicationRef.injector,
      elementInjector: this._injector,
      projectableNodes
    });
    this._applicationRef.attachView(panelCmptRef.hostView);
    containerEl.appendChild(panelCmptRef.location.nativeElement);
    return panelCmptRef;
  }
  _applyPanelOptions(windowInstance, options) {
    this._panelAttributes.forEach(optionName => {
      if (isDefined(options[optionName])) {
        windowInstance[optionName] = options[optionName];
      }
    });
  }
  _applyBackdropOptions(backdropInstance, options) {
    this._backdropAttributes.forEach(optionName => {
      if (isDefined(options[optionName])) {
        backdropInstance[optionName] = options[optionName];
      }
    });
    backdropInstance.static = options.backdrop === 'static';
  }
  _getContentRef(contentInjector, content, activeOffcanvas) {
    if (!content) {
      return new ContentRef([]);
    } else if (content instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef) {
      return this._createFromTemplateRef(content, activeOffcanvas);
    } else if (isString(content)) {
      return this._createFromString(content);
    } else {
      return this._createFromComponent(contentInjector, content, activeOffcanvas);
    }
  }
  _createFromTemplateRef(templateRef, activeOffcanvas) {
    const context = {
      $implicit: activeOffcanvas,
      close(result) {
        activeOffcanvas.close(result);
      },
      dismiss(reason) {
        activeOffcanvas.dismiss(reason);
      }
    };
    const viewRef = templateRef.createEmbeddedView(context);
    this._applicationRef.attachView(viewRef);
    return new ContentRef([viewRef.rootNodes], viewRef);
  }
  _createFromString(content) {
    const component = this._document.createTextNode(`${content}`);
    return new ContentRef([[component]]);
  }
  _createFromComponent(contentInjector, componentType, context) {
    const elementInjector = _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector.create({
      providers: [{
        provide: NgbActiveOffcanvas,
        useValue: context
      }],
      parent: contentInjector
    });
    const componentRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.createComponent)(componentType, {
      environmentInjector: this._applicationRef.injector,
      elementInjector
    });
    const componentNativeEl = componentRef.location.nativeElement;
    this._applicationRef.attachView(componentRef.hostView);
    return new ContentRef([[componentNativeEl]], componentRef.hostView, componentRef);
  }
  _registerOffcanvasRef(ngbOffcanvasRef) {
    const unregisterOffcanvasRef = () => {
      this._offcanvasRef = undefined;
      this._activeInstance.emit(this._offcanvasRef);
    };
    this._offcanvasRef = ngbOffcanvasRef;
    this._activeInstance.emit(this._offcanvasRef);
    ngbOffcanvasRef.result.then(unregisterOffcanvasRef, unregisterOffcanvasRef);
  }
  _registerPanelCmpt(ngbPanelCmpt) {
    this._panelCmpt = ngbPanelCmpt;
    this._activePanelCmptHasChanged.next();
    ngbPanelCmpt.onDestroy(() => {
      this._panelCmpt = undefined;
      this._activePanelCmptHasChanged.next();
    });
  }
  static {
    this.ɵfac = function NgbOffcanvasStack_Factory(t) {
      return new (t || NgbOffcanvasStack)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbOffcanvasStack,
      factory: NgbOffcanvasStack.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvasStack, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [], null);
})();

/**
 * A service for opening an offcanvas.
 *
 * Creating an offcanvas is straightforward: create a component or a template and pass it as an argument to
 * the `.open()` method.
 *
 * @since 12.1.0
 */
class NgbOffcanvas {
  constructor() {
    this._injector = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Injector);
    this._offcanvasStack = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbOffcanvasStack);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(NgbOffcanvasConfig);
  }
  /**
   * Opens a new offcanvas panel with the specified content and supplied options.
   *
   * Content can be provided as a `TemplateRef` or a component type. If you pass a component type as content,
   * then instances of those components can be injected with an instance of the `NgbActiveOffcanvas` class. You can then
   * use `NgbActiveOffcanvas` methods to close / dismiss offcanvas from "inside" of your component.
   *
   * Also see the [`NgbOffcanvasOptions`](#/components/offcanvas/api#NgbOffcanvasOptions) for the list of supported
   * options.
   */
  open(content, options = {}) {
    const combinedOptions = {
      ...this._config,
      animation: this._config.animation,
      ...options
    };
    return this._offcanvasStack.open(this._injector, content, combinedOptions);
  }
  /**
   * Returns an observable that holds the active offcanvas instance.
   */
  get activeInstance() {
    return this._offcanvasStack.activeInstance;
  }
  /**
   * Dismisses the currently displayed offcanvas with the supplied reason.
   */
  dismiss(reason) {
    this._offcanvasStack.dismiss(reason);
  }
  /**
   * Indicates if there is currently an open offcanvas in the application.
   */
  hasOpenOffcanvas() {
    return this._offcanvasStack.hasOpenOffcanvas();
  }
  static {
    this.ɵfac = function NgbOffcanvas_Factory(t) {
      return new (t || NgbOffcanvas)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgbOffcanvas,
      factory: NgbOffcanvas.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvas, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class NgbOffcanvasModule {
  static {
    this.ɵfac = function NgbOffcanvasModule_Factory(t) {
      return new (t || NgbOffcanvasModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbOffcanvasModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbOffcanvasModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], null, null);
})();
const NGB_MODULES = [NgbAccordionModule, NgbAlertModule, NgbCarouselModule, NgbCollapseModule, NgbDatepickerModule, NgbDropdownModule, NgbModalModule, NgbNavModule, NgbOffcanvasModule, NgbPaginationModule, NgbPopoverModule, NgbProgressbarModule, NgbRatingModule, NgbScrollSpyModule, NgbTimepickerModule, NgbToastModule, NgbTooltipModule, NgbTypeaheadModule];
class NgbModule {
  static {
    this.ɵfac = function NgbModule_Factory(t) {
      return new (t || NgbModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgbModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      imports: [NGB_MODULES, NgbAccordionModule, NgbAlertModule, NgbCarouselModule, NgbCollapseModule, NgbDatepickerModule, NgbDropdownModule, NgbModalModule, NgbNavModule, NgbOffcanvasModule, NgbPaginationModule, NgbPopoverModule, NgbProgressbarModule, NgbRatingModule, NgbScrollSpyModule, NgbTimepickerModule, NgbToastModule, NgbTooltipModule, NgbTypeaheadModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgbModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: NGB_MODULES,
      exports: NGB_MODULES
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 62223:
/*!****************************************************************************!*\
  !*** ./node_modules/@ng-select/ng-select/fesm2022/ng-select-ng-select.mjs ***!
  \****************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   NgFooterTemplateDirective: () => (/* binding */ NgFooterTemplateDirective),
/* harmony export */   NgHeaderTemplateDirective: () => (/* binding */ NgHeaderTemplateDirective),
/* harmony export */   NgItemLabelDirective: () => (/* binding */ NgItemLabelDirective),
/* harmony export */   NgLabelTemplateDirective: () => (/* binding */ NgLabelTemplateDirective),
/* harmony export */   NgLoadingSpinnerTemplateDirective: () => (/* binding */ NgLoadingSpinnerTemplateDirective),
/* harmony export */   NgLoadingTextTemplateDirective: () => (/* binding */ NgLoadingTextTemplateDirective),
/* harmony export */   NgMultiLabelTemplateDirective: () => (/* binding */ NgMultiLabelTemplateDirective),
/* harmony export */   NgNotFoundTemplateDirective: () => (/* binding */ NgNotFoundTemplateDirective),
/* harmony export */   NgOptgroupTemplateDirective: () => (/* binding */ NgOptgroupTemplateDirective),
/* harmony export */   NgOptionComponent: () => (/* binding */ NgOptionComponent),
/* harmony export */   NgOptionTemplateDirective: () => (/* binding */ NgOptionTemplateDirective),
/* harmony export */   NgSelectComponent: () => (/* binding */ NgSelectComponent),
/* harmony export */   NgSelectConfig: () => (/* binding */ NgSelectConfig),
/* harmony export */   NgSelectModule: () => (/* binding */ NgSelectModule),
/* harmony export */   NgTagTemplateDirective: () => (/* binding */ NgTagTemplateDirective),
/* harmony export */   NgTypeToSearchTemplateDirective: () => (/* binding */ NgTypeToSearchTemplateDirective),
/* harmony export */   SELECTION_MODEL_FACTORY: () => (/* binding */ SELECTION_MODEL_FACTORY)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! @angular/forms */ 34456);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 32351);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 63037);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 52575);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 20614);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 67180);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 18537);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @angular/common */ 60316);







const _c0 = ["content"];
const _c1 = ["scroll"];
const _c2 = ["padding"];
const _c3 = ["*"];
const _c4 = a0 => ({
  searchTerm: a0
});
function NgDropdownPanelComponent_div_0_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 6);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](1, 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.headerTemplate)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](2, _c4, ctx_r0.filterValue));
  }
}
function NgDropdownPanelComponent_div_8_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 8);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainer"](1, 7);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r0 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r0.footerTemplate)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](2, _c4, ctx_r0.filterValue));
  }
}
const _c5 = ["searchInput"];
const _c6 = ["clearButton"];
const _c7 = (a0, a1, a2) => ({
  item: a0,
  clear: a1,
  label: a2
});
const _c8 = (a0, a1) => ({
  items: a0,
  clear: a1
});
const _c9 = (a0, a1, a2, a3) => ({
  item: a0,
  item$: a1,
  index: a2,
  searchTerm: a3
});
function NgSelectComponent_ng_container_4_div_1_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    const _r2 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 22);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgSelectComponent_ng_container_4_div_1_ng_template_1_Template_span_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r2);
      const item_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.unselect(item_r3));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1, "\xD7");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](2, "span", 23);
  }
  if (rf & 2) {
    const item_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngItemLabel", item_r3.label)("escape", ctx_r3.escapeHTML);
  }
}
function NgSelectComponent_ng_container_4_div_1_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_container_4_div_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 20);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_container_4_div_1_ng_template_1_Template, 3, 2, "ng-template", null, 1, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_container_4_div_1_ng_template_3_Template, 0, 0, "ng-template", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const item_r3 = ctx.$implicit;
    const defaultLabelTemplate_r5 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-value-disabled", item_r3.disabled);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.labelTemplate || defaultLabelTemplate_r5)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction3"](4, _c7, item_r3.value, ctx_r3.clearItem, item_r3.label));
  }
}
function NgSelectComponent_ng_container_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_container_4_div_1_Template, 4, 8, "div", 19);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx_r3.selectedItems)("ngForTrackBy", ctx_r3.trackByOption);
  }
}
function NgSelectComponent_5_ng_template_0_Template(rf, ctx) {}
function NgSelectComponent_5_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgSelectComponent_5_ng_template_0_Template, 0, 0, "ng-template", 21);
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.multiLabelTemplate)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction2"](2, _c8, ctx_r3.selectedValues, ctx_r3.clearItem));
  }
}
function NgSelectComponent_ng_container_9_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "div", 25);
  }
}
function NgSelectComponent_ng_container_9_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_container_9_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_container_9_ng_template_1_Template, 1, 0, "ng-template", null, 2, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_container_9_ng_template_3_Template, 0, 0, "ng-template", 24);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const defaultLoadingSpinnerTemplate_r7 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.loadingSpinnerTemplate || defaultLoadingSpinnerTemplate_r7);
  }
}
function NgSelectComponent_span_10_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span", 26, 3)(2, "span", 27);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](3, "\xD7");
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpropertyInterpolate"]("title", ctx_r3.clearAllText);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_div_2_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](0, "span", 32);
  }
  if (rf & 2) {
    const item_r10 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]().$implicit;
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngItemLabel", item_r10.label)("escape", ctx_r3.escapeHTML);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_div_2_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_dropdown_panel_13_div_2_Template(rf, ctx) {
  if (rf & 1) {
    const _r9 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 31);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("click", function NgSelectComponent_ng_dropdown_panel_13_div_2_Template_div_click_0_listener() {
      const item_r10 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r9).$implicit;
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.toggleItem(item_r10));
    })("mouseover", function NgSelectComponent_ng_dropdown_panel_13_div_2_Template_div_mouseover_0_listener() {
      const item_r10 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r9).$implicit;
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.onItemHover(item_r10));
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_dropdown_panel_13_div_2_ng_template_1_Template, 1, 2, "ng-template", null, 4, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_dropdown_panel_13_div_2_ng_template_3_Template, 0, 0, "ng-template", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const item_r10 = ctx.$implicit;
    const defaultOptionTemplate_r11 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-option-disabled", item_r10.disabled)("ng-option-selected", item_r10.selected)("ng-optgroup", item_r10.children)("ng-option", !item_r10.children)("ng-option-child", !!item_r10.parent)("ng-option-marked", item_r10 === ctx_r3.itemsList.markedItem);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("role", item_r10.children ? "group" : "option")("aria-selected", item_r10.selected)("id", item_r10 == null ? null : item_r10.htmlId);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", item_r10.children ? ctx_r3.optgroupTemplate || defaultOptionTemplate_r11 : ctx_r3.optionTemplate || defaultOptionTemplate_r11)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction4"](17, _c9, item_r10.value, item_r10, item_r10.index, ctx_r3.searchTerm));
  }
}
function NgSelectComponent_ng_dropdown_panel_13_div_3_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "span")(1, "span", 34);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r3.addTagText);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate1"]("\"", ctx_r3.searchTerm, "\"");
  }
}
function NgSelectComponent_ng_dropdown_panel_13_div_3_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_dropdown_panel_13_div_3_Template(rf, ctx) {
  if (rf & 1) {
    const _r12 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 33);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mouseover", function NgSelectComponent_ng_dropdown_panel_13_div_3_Template_div_mouseover_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r12);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.itemsList.unmarkItem());
    })("click", function NgSelectComponent_ng_dropdown_panel_13_div_3_Template_div_click_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r12);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.selectTag());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_dropdown_panel_13_div_3_ng_template_1_Template, 4, 2, "ng-template", null, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_dropdown_panel_13_div_3_ng_template_3_Template, 0, 0, "ng-template", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const defaultTagTemplate_r13 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-option-marked", !ctx_r3.itemsList.markedItem);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.tagTemplate || defaultTagTemplate_r13)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](4, _c4, ctx_r3.searchTerm));
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_4_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 35);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r3.notFoundText);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_4_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_4_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_dropdown_panel_13_ng_container_4_ng_template_1_Template, 2, 1, "ng-template", null, 6, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_dropdown_panel_13_ng_container_4_ng_template_3_Template, 0, 0, "ng-template", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const defaultNotFoundTemplate_r14 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.notFoundTemplate || defaultNotFoundTemplate_r14)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](2, _c4, ctx_r3.searchTerm));
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_5_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 35);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r3.typeToSearchText);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_5_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_5_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_dropdown_panel_13_ng_container_5_ng_template_1_Template, 2, 1, "ng-template", null, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_dropdown_panel_13_ng_container_5_ng_template_3_Template, 0, 0, "ng-template", 24);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const defaultTypeToSearchTemplate_r15 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.typeToSearchTemplate || defaultTypeToSearchTemplate_r15);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_6_ng_template_1_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 35);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx_r3.loadingText);
  }
}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_6_ng_template_3_Template(rf, ctx) {}
function NgSelectComponent_ng_dropdown_panel_13_ng_container_6_Template(rf, ctx) {
  if (rf & 1) {
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](0);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](1, NgSelectComponent_ng_dropdown_panel_13_ng_container_6_ng_template_1_Template, 2, 1, "ng-template", null, 8, _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplateRefExtractor"])(3, NgSelectComponent_ng_dropdown_panel_13_ng_container_6_ng_template_3_Template, 0, 0, "ng-template", 21);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
  }
  if (rf & 2) {
    const defaultLoadingTextTemplate_r16 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](2);
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngTemplateOutlet", ctx_r3.loadingTextTemplate || defaultLoadingTextTemplate_r16)("ngTemplateOutletContext", _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵpureFunction1"](2, _c4, ctx_r3.searchTerm));
  }
}
function NgSelectComponent_ng_dropdown_panel_13_Template(rf, ctx) {
  if (rf & 1) {
    const _r8 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "ng-dropdown-panel", 28);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("update", function NgSelectComponent_ng_dropdown_panel_13_Template_ng_dropdown_panel_update_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.viewPortItems = $event);
    })("scroll", function NgSelectComponent_ng_dropdown_panel_13_Template_ng_dropdown_panel_scroll_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.scroll.emit($event));
    })("scrollToEnd", function NgSelectComponent_ng_dropdown_panel_13_Template_ng_dropdown_panel_scrollToEnd_0_listener($event) {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.scrollToEnd.emit($event));
    })("outsideClick", function NgSelectComponent_ng_dropdown_panel_13_Template_ng_dropdown_panel_outsideClick_0_listener() {
      _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r8);
      const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
      return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx_r3.close());
    });
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerStart"](1);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](2, NgSelectComponent_ng_dropdown_panel_13_div_2_Template, 4, 22, "div", 29)(3, NgSelectComponent_ng_dropdown_panel_13_div_3_Template, 4, 6, "div", 30);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementContainerEnd"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](4, NgSelectComponent_ng_dropdown_panel_13_ng_container_4_Template, 4, 4, "ng-container", 12)(5, NgSelectComponent_ng_dropdown_panel_13_ng_container_5_Template, 4, 1, "ng-container", 12)(6, NgSelectComponent_ng_dropdown_panel_13_ng_container_6_Template, 4, 4, "ng-container", 12);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
  }
  if (rf & 2) {
    const ctx_r3 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵnextContext"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-select-multiple", ctx_r3.multiple);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("virtualScroll", ctx_r3.virtualScroll)("bufferAmount", ctx_r3.bufferAmount)("appendTo", ctx_r3.appendTo)("position", ctx_r3.dropdownPosition)("headerTemplate", ctx_r3.headerTemplate)("footerTemplate", ctx_r3.footerTemplate)("filterValue", ctx_r3.searchTerm)("items", ctx_r3.itemsList.filteredItems)("markedItem", ctx_r3.itemsList.markedItem)("ngClass", ctx_r3.appendTo ? ctx_r3.classes : null)("id", ctx_r3.dropdownId);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngForOf", ctx_r3.viewPortItems)("ngForTrackBy", ctx_r3.trackByOption);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r3.showAddTag);
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r3.showNoItemsFound());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r3.showTypeToSearch());
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
    _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx_r3.loading && ctx_r3.itemsList.filteredItems.length === 0);
  }
}
const unescapedHTMLExp = /[&<>"']/g;
const hasUnescapedHTMLExp = RegExp(unescapedHTMLExp.source);
const htmlEscapes = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  '\'': '&#39;'
};
function escapeHTML(value) {
  return value && hasUnescapedHTMLExp.test(value) ? value.replace(unescapedHTMLExp, chr => htmlEscapes[chr]) : value;
}
function isDefined(value) {
  return value !== undefined && value !== null;
}
function isObject(value) {
  return typeof value === 'object' && isDefined(value);
}
function isPromise(value) {
  return value instanceof Promise;
}
function isFunction(value) {
  return value instanceof Function;
}
class NgItemLabelDirective {
  constructor(element) {
    this.element = element;
    this.escape = true;
  }
  ngOnChanges(changes) {
    this.element.nativeElement.innerHTML = this.escape ? escapeHTML(this.ngItemLabel) : this.ngItemLabel;
  }
  static {
    this.ɵfac = function NgItemLabelDirective_Factory(t) {
      return new (t || NgItemLabelDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgItemLabelDirective,
      selectors: [["", "ngItemLabel", ""]],
      inputs: {
        ngItemLabel: "ngItemLabel",
        escape: "escape"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgItemLabelDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngItemLabel]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }], {
    ngItemLabel: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    escape: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgOptionTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgOptionTemplateDirective_Factory(t) {
      return new (t || NgOptionTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgOptionTemplateDirective,
      selectors: [["", "ng-option-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgOptionTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-option-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgOptgroupTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgOptgroupTemplateDirective_Factory(t) {
      return new (t || NgOptgroupTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgOptgroupTemplateDirective,
      selectors: [["", "ng-optgroup-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgOptgroupTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-optgroup-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgLabelTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgLabelTemplateDirective_Factory(t) {
      return new (t || NgLabelTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgLabelTemplateDirective,
      selectors: [["", "ng-label-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLabelTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-label-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgMultiLabelTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgMultiLabelTemplateDirective_Factory(t) {
      return new (t || NgMultiLabelTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgMultiLabelTemplateDirective,
      selectors: [["", "ng-multi-label-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgMultiLabelTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-multi-label-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgHeaderTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgHeaderTemplateDirective_Factory(t) {
      return new (t || NgHeaderTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgHeaderTemplateDirective,
      selectors: [["", "ng-header-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgHeaderTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-header-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgFooterTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgFooterTemplateDirective_Factory(t) {
      return new (t || NgFooterTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgFooterTemplateDirective,
      selectors: [["", "ng-footer-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgFooterTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-footer-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgNotFoundTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgNotFoundTemplateDirective_Factory(t) {
      return new (t || NgNotFoundTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgNotFoundTemplateDirective,
      selectors: [["", "ng-notfound-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgNotFoundTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-notfound-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgTypeToSearchTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgTypeToSearchTemplateDirective_Factory(t) {
      return new (t || NgTypeToSearchTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgTypeToSearchTemplateDirective,
      selectors: [["", "ng-typetosearch-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgTypeToSearchTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-typetosearch-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgLoadingTextTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgLoadingTextTemplateDirective_Factory(t) {
      return new (t || NgLoadingTextTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgLoadingTextTemplateDirective,
      selectors: [["", "ng-loadingtext-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLoadingTextTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-loadingtext-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgTagTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgTagTemplateDirective_Factory(t) {
      return new (t || NgTagTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgTagTemplateDirective,
      selectors: [["", "ng-tag-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgTagTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-tag-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
// eslint-disable-next-line @angular-eslint/directive-selector
class NgLoadingSpinnerTemplateDirective {
  constructor(template) {
    this.template = template;
  }
  static {
    this.ɵfac = function NgLoadingSpinnerTemplateDirective_Factory(t) {
      return new (t || NgLoadingSpinnerTemplateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef));
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
      type: NgLoadingSpinnerTemplateDirective,
      selectors: [["", "ng-loadingspinner-tmp", ""]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgLoadingSpinnerTemplateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ng-loadingspinner-tmp]'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
  }], null);
})();
function newId() {
  // First character is an 'a', it's good practice to tag id to begin with a letter
  return 'axxxxxxxxxxx'.replace(/[x]/g, () => {
    // eslint-disable-next-line no-bitwise
    const val = Math.random() * 16 | 0;
    return val.toString(16);
  });
}
const diacritics = {
  '\u24B6': 'A',
  '\uFF21': 'A',
  '\u00C0': 'A',
  '\u00C1': 'A',
  '\u00C2': 'A',
  '\u1EA6': 'A',
  '\u1EA4': 'A',
  '\u1EAA': 'A',
  '\u1EA8': 'A',
  '\u00C3': 'A',
  '\u0100': 'A',
  '\u0102': 'A',
  '\u1EB0': 'A',
  '\u1EAE': 'A',
  '\u1EB4': 'A',
  '\u1EB2': 'A',
  '\u0226': 'A',
  '\u01E0': 'A',
  '\u00C4': 'A',
  '\u01DE': 'A',
  '\u1EA2': 'A',
  '\u00C5': 'A',
  '\u01FA': 'A',
  '\u01CD': 'A',
  '\u0200': 'A',
  '\u0202': 'A',
  '\u1EA0': 'A',
  '\u1EAC': 'A',
  '\u1EB6': 'A',
  '\u1E00': 'A',
  '\u0104': 'A',
  '\u023A': 'A',
  '\u2C6F': 'A',
  '\uA732': 'AA',
  '\u00C6': 'AE',
  '\u01FC': 'AE',
  '\u01E2': 'AE',
  '\uA734': 'AO',
  '\uA736': 'AU',
  '\uA738': 'AV',
  '\uA73A': 'AV',
  '\uA73C': 'AY',
  '\u24B7': 'B',
  '\uFF22': 'B',
  '\u1E02': 'B',
  '\u1E04': 'B',
  '\u1E06': 'B',
  '\u0243': 'B',
  '\u0182': 'B',
  '\u0181': 'B',
  '\u24B8': 'C',
  '\uFF23': 'C',
  '\u0106': 'C',
  '\u0108': 'C',
  '\u010A': 'C',
  '\u010C': 'C',
  '\u00C7': 'C',
  '\u1E08': 'C',
  '\u0187': 'C',
  '\u023B': 'C',
  '\uA73E': 'C',
  '\u24B9': 'D',
  '\uFF24': 'D',
  '\u1E0A': 'D',
  '\u010E': 'D',
  '\u1E0C': 'D',
  '\u1E10': 'D',
  '\u1E12': 'D',
  '\u1E0E': 'D',
  '\u0110': 'D',
  '\u018B': 'D',
  '\u018A': 'D',
  '\u0189': 'D',
  '\uA779': 'D',
  '\u01F1': 'DZ',
  '\u01C4': 'DZ',
  '\u01F2': 'Dz',
  '\u01C5': 'Dz',
  '\u24BA': 'E',
  '\uFF25': 'E',
  '\u00C8': 'E',
  '\u00C9': 'E',
  '\u00CA': 'E',
  '\u1EC0': 'E',
  '\u1EBE': 'E',
  '\u1EC4': 'E',
  '\u1EC2': 'E',
  '\u1EBC': 'E',
  '\u0112': 'E',
  '\u1E14': 'E',
  '\u1E16': 'E',
  '\u0114': 'E',
  '\u0116': 'E',
  '\u00CB': 'E',
  '\u1EBA': 'E',
  '\u011A': 'E',
  '\u0204': 'E',
  '\u0206': 'E',
  '\u1EB8': 'E',
  '\u1EC6': 'E',
  '\u0228': 'E',
  '\u1E1C': 'E',
  '\u0118': 'E',
  '\u1E18': 'E',
  '\u1E1A': 'E',
  '\u0190': 'E',
  '\u018E': 'E',
  '\u24BB': 'F',
  '\uFF26': 'F',
  '\u1E1E': 'F',
  '\u0191': 'F',
  '\uA77B': 'F',
  '\u24BC': 'G',
  '\uFF27': 'G',
  '\u01F4': 'G',
  '\u011C': 'G',
  '\u1E20': 'G',
  '\u011E': 'G',
  '\u0120': 'G',
  '\u01E6': 'G',
  '\u0122': 'G',
  '\u01E4': 'G',
  '\u0193': 'G',
  '\uA7A0': 'G',
  '\uA77D': 'G',
  '\uA77E': 'G',
  '\u24BD': 'H',
  '\uFF28': 'H',
  '\u0124': 'H',
  '\u1E22': 'H',
  '\u1E26': 'H',
  '\u021E': 'H',
  '\u1E24': 'H',
  '\u1E28': 'H',
  '\u1E2A': 'H',
  '\u0126': 'H',
  '\u2C67': 'H',
  '\u2C75': 'H',
  '\uA78D': 'H',
  '\u24BE': 'I',
  '\uFF29': 'I',
  '\u00CC': 'I',
  '\u00CD': 'I',
  '\u00CE': 'I',
  '\u0128': 'I',
  '\u012A': 'I',
  '\u012C': 'I',
  '\u0130': 'I',
  '\u00CF': 'I',
  '\u1E2E': 'I',
  '\u1EC8': 'I',
  '\u01CF': 'I',
  '\u0208': 'I',
  '\u020A': 'I',
  '\u1ECA': 'I',
  '\u012E': 'I',
  '\u1E2C': 'I',
  '\u0197': 'I',
  '\u24BF': 'J',
  '\uFF2A': 'J',
  '\u0134': 'J',
  '\u0248': 'J',
  '\u24C0': 'K',
  '\uFF2B': 'K',
  '\u1E30': 'K',
  '\u01E8': 'K',
  '\u1E32': 'K',
  '\u0136': 'K',
  '\u1E34': 'K',
  '\u0198': 'K',
  '\u2C69': 'K',
  '\uA740': 'K',
  '\uA742': 'K',
  '\uA744': 'K',
  '\uA7A2': 'K',
  '\u24C1': 'L',
  '\uFF2C': 'L',
  '\u013F': 'L',
  '\u0139': 'L',
  '\u013D': 'L',
  '\u1E36': 'L',
  '\u1E38': 'L',
  '\u013B': 'L',
  '\u1E3C': 'L',
  '\u1E3A': 'L',
  '\u0141': 'L',
  '\u023D': 'L',
  '\u2C62': 'L',
  '\u2C60': 'L',
  '\uA748': 'L',
  '\uA746': 'L',
  '\uA780': 'L',
  '\u01C7': 'LJ',
  '\u01C8': 'Lj',
  '\u24C2': 'M',
  '\uFF2D': 'M',
  '\u1E3E': 'M',
  '\u1E40': 'M',
  '\u1E42': 'M',
  '\u2C6E': 'M',
  '\u019C': 'M',
  '\u24C3': 'N',
  '\uFF2E': 'N',
  '\u01F8': 'N',
  '\u0143': 'N',
  '\u00D1': 'N',
  '\u1E44': 'N',
  '\u0147': 'N',
  '\u1E46': 'N',
  '\u0145': 'N',
  '\u1E4A': 'N',
  '\u1E48': 'N',
  '\u0220': 'N',
  '\u019D': 'N',
  '\uA790': 'N',
  '\uA7A4': 'N',
  '\u01CA': 'NJ',
  '\u01CB': 'Nj',
  '\u24C4': 'O',
  '\uFF2F': 'O',
  '\u00D2': 'O',
  '\u00D3': 'O',
  '\u00D4': 'O',
  '\u1ED2': 'O',
  '\u1ED0': 'O',
  '\u1ED6': 'O',
  '\u1ED4': 'O',
  '\u00D5': 'O',
  '\u1E4C': 'O',
  '\u022C': 'O',
  '\u1E4E': 'O',
  '\u014C': 'O',
  '\u1E50': 'O',
  '\u1E52': 'O',
  '\u014E': 'O',
  '\u022E': 'O',
  '\u0230': 'O',
  '\u00D6': 'O',
  '\u022A': 'O',
  '\u1ECE': 'O',
  '\u0150': 'O',
  '\u01D1': 'O',
  '\u020C': 'O',
  '\u020E': 'O',
  '\u01A0': 'O',
  '\u1EDC': 'O',
  '\u1EDA': 'O',
  '\u1EE0': 'O',
  '\u1EDE': 'O',
  '\u1EE2': 'O',
  '\u1ECC': 'O',
  '\u1ED8': 'O',
  '\u01EA': 'O',
  '\u01EC': 'O',
  '\u00D8': 'O',
  '\u01FE': 'O',
  '\u0186': 'O',
  '\u019F': 'O',
  '\uA74A': 'O',
  '\uA74C': 'O',
  '\u01A2': 'OI',
  '\uA74E': 'OO',
  '\u0222': 'OU',
  '\u24C5': 'P',
  '\uFF30': 'P',
  '\u1E54': 'P',
  '\u1E56': 'P',
  '\u01A4': 'P',
  '\u2C63': 'P',
  '\uA750': 'P',
  '\uA752': 'P',
  '\uA754': 'P',
  '\u24C6': 'Q',
  '\uFF31': 'Q',
  '\uA756': 'Q',
  '\uA758': 'Q',
  '\u024A': 'Q',
  '\u24C7': 'R',
  '\uFF32': 'R',
  '\u0154': 'R',
  '\u1E58': 'R',
  '\u0158': 'R',
  '\u0210': 'R',
  '\u0212': 'R',
  '\u1E5A': 'R',
  '\u1E5C': 'R',
  '\u0156': 'R',
  '\u1E5E': 'R',
  '\u024C': 'R',
  '\u2C64': 'R',
  '\uA75A': 'R',
  '\uA7A6': 'R',
  '\uA782': 'R',
  '\u24C8': 'S',
  '\uFF33': 'S',
  '\u1E9E': 'S',
  '\u015A': 'S',
  '\u1E64': 'S',
  '\u015C': 'S',
  '\u1E60': 'S',
  '\u0160': 'S',
  '\u1E66': 'S',
  '\u1E62': 'S',
  '\u1E68': 'S',
  '\u0218': 'S',
  '\u015E': 'S',
  '\u2C7E': 'S',
  '\uA7A8': 'S',
  '\uA784': 'S',
  '\u24C9': 'T',
  '\uFF34': 'T',
  '\u1E6A': 'T',
  '\u0164': 'T',
  '\u1E6C': 'T',
  '\u021A': 'T',
  '\u0162': 'T',
  '\u1E70': 'T',
  '\u1E6E': 'T',
  '\u0166': 'T',
  '\u01AC': 'T',
  '\u01AE': 'T',
  '\u023E': 'T',
  '\uA786': 'T',
  '\uA728': 'TZ',
  '\u24CA': 'U',
  '\uFF35': 'U',
  '\u00D9': 'U',
  '\u00DA': 'U',
  '\u00DB': 'U',
  '\u0168': 'U',
  '\u1E78': 'U',
  '\u016A': 'U',
  '\u1E7A': 'U',
  '\u016C': 'U',
  '\u00DC': 'U',
  '\u01DB': 'U',
  '\u01D7': 'U',
  '\u01D5': 'U',
  '\u01D9': 'U',
  '\u1EE6': 'U',
  '\u016E': 'U',
  '\u0170': 'U',
  '\u01D3': 'U',
  '\u0214': 'U',
  '\u0216': 'U',
  '\u01AF': 'U',
  '\u1EEA': 'U',
  '\u1EE8': 'U',
  '\u1EEE': 'U',
  '\u1EEC': 'U',
  '\u1EF0': 'U',
  '\u1EE4': 'U',
  '\u1E72': 'U',
  '\u0172': 'U',
  '\u1E76': 'U',
  '\u1E74': 'U',
  '\u0244': 'U',
  '\u24CB': 'V',
  '\uFF36': 'V',
  '\u1E7C': 'V',
  '\u1E7E': 'V',
  '\u01B2': 'V',
  '\uA75E': 'V',
  '\u0245': 'V',
  '\uA760': 'VY',
  '\u24CC': 'W',
  '\uFF37': 'W',
  '\u1E80': 'W',
  '\u1E82': 'W',
  '\u0174': 'W',
  '\u1E86': 'W',
  '\u1E84': 'W',
  '\u1E88': 'W',
  '\u2C72': 'W',
  '\u24CD': 'X',
  '\uFF38': 'X',
  '\u1E8A': 'X',
  '\u1E8C': 'X',
  '\u24CE': 'Y',
  '\uFF39': 'Y',
  '\u1EF2': 'Y',
  '\u00DD': 'Y',
  '\u0176': 'Y',
  '\u1EF8': 'Y',
  '\u0232': 'Y',
  '\u1E8E': 'Y',
  '\u0178': 'Y',
  '\u1EF6': 'Y',
  '\u1EF4': 'Y',
  '\u01B3': 'Y',
  '\u024E': 'Y',
  '\u1EFE': 'Y',
  '\u24CF': 'Z',
  '\uFF3A': 'Z',
  '\u0179': 'Z',
  '\u1E90': 'Z',
  '\u017B': 'Z',
  '\u017D': 'Z',
  '\u1E92': 'Z',
  '\u1E94': 'Z',
  '\u01B5': 'Z',
  '\u0224': 'Z',
  '\u2C7F': 'Z',
  '\u2C6B': 'Z',
  '\uA762': 'Z',
  '\u24D0': 'a',
  '\uFF41': 'a',
  '\u1E9A': 'a',
  '\u00E0': 'a',
  '\u00E1': 'a',
  '\u00E2': 'a',
  '\u1EA7': 'a',
  '\u1EA5': 'a',
  '\u1EAB': 'a',
  '\u1EA9': 'a',
  '\u00E3': 'a',
  '\u0101': 'a',
  '\u0103': 'a',
  '\u1EB1': 'a',
  '\u1EAF': 'a',
  '\u1EB5': 'a',
  '\u1EB3': 'a',
  '\u0227': 'a',
  '\u01E1': 'a',
  '\u00E4': 'a',
  '\u01DF': 'a',
  '\u1EA3': 'a',
  '\u00E5': 'a',
  '\u01FB': 'a',
  '\u01CE': 'a',
  '\u0201': 'a',
  '\u0203': 'a',
  '\u1EA1': 'a',
  '\u1EAD': 'a',
  '\u1EB7': 'a',
  '\u1E01': 'a',
  '\u0105': 'a',
  '\u2C65': 'a',
  '\u0250': 'a',
  '\uA733': 'aa',
  '\u00E6': 'ae',
  '\u01FD': 'ae',
  '\u01E3': 'ae',
  '\uA735': 'ao',
  '\uA737': 'au',
  '\uA739': 'av',
  '\uA73B': 'av',
  '\uA73D': 'ay',
  '\u24D1': 'b',
  '\uFF42': 'b',
  '\u1E03': 'b',
  '\u1E05': 'b',
  '\u1E07': 'b',
  '\u0180': 'b',
  '\u0183': 'b',
  '\u0253': 'b',
  '\u24D2': 'c',
  '\uFF43': 'c',
  '\u0107': 'c',
  '\u0109': 'c',
  '\u010B': 'c',
  '\u010D': 'c',
  '\u00E7': 'c',
  '\u1E09': 'c',
  '\u0188': 'c',
  '\u023C': 'c',
  '\uA73F': 'c',
  '\u2184': 'c',
  '\u24D3': 'd',
  '\uFF44': 'd',
  '\u1E0B': 'd',
  '\u010F': 'd',
  '\u1E0D': 'd',
  '\u1E11': 'd',
  '\u1E13': 'd',
  '\u1E0F': 'd',
  '\u0111': 'd',
  '\u018C': 'd',
  '\u0256': 'd',
  '\u0257': 'd',
  '\uA77A': 'd',
  '\u01F3': 'dz',
  '\u01C6': 'dz',
  '\u24D4': 'e',
  '\uFF45': 'e',
  '\u00E8': 'e',
  '\u00E9': 'e',
  '\u00EA': 'e',
  '\u1EC1': 'e',
  '\u1EBF': 'e',
  '\u1EC5': 'e',
  '\u1EC3': 'e',
  '\u1EBD': 'e',
  '\u0113': 'e',
  '\u1E15': 'e',
  '\u1E17': 'e',
  '\u0115': 'e',
  '\u0117': 'e',
  '\u00EB': 'e',
  '\u1EBB': 'e',
  '\u011B': 'e',
  '\u0205': 'e',
  '\u0207': 'e',
  '\u1EB9': 'e',
  '\u1EC7': 'e',
  '\u0229': 'e',
  '\u1E1D': 'e',
  '\u0119': 'e',
  '\u1E19': 'e',
  '\u1E1B': 'e',
  '\u0247': 'e',
  '\u025B': 'e',
  '\u01DD': 'e',
  '\u24D5': 'f',
  '\uFF46': 'f',
  '\u1E1F': 'f',
  '\u0192': 'f',
  '\uA77C': 'f',
  '\u24D6': 'g',
  '\uFF47': 'g',
  '\u01F5': 'g',
  '\u011D': 'g',
  '\u1E21': 'g',
  '\u011F': 'g',
  '\u0121': 'g',
  '\u01E7': 'g',
  '\u0123': 'g',
  '\u01E5': 'g',
  '\u0260': 'g',
  '\uA7A1': 'g',
  '\u1D79': 'g',
  '\uA77F': 'g',
  '\u24D7': 'h',
  '\uFF48': 'h',
  '\u0125': 'h',
  '\u1E23': 'h',
  '\u1E27': 'h',
  '\u021F': 'h',
  '\u1E25': 'h',
  '\u1E29': 'h',
  '\u1E2B': 'h',
  '\u1E96': 'h',
  '\u0127': 'h',
  '\u2C68': 'h',
  '\u2C76': 'h',
  '\u0265': 'h',
  '\u0195': 'hv',
  '\u24D8': 'i',
  '\uFF49': 'i',
  '\u00EC': 'i',
  '\u00ED': 'i',
  '\u00EE': 'i',
  '\u0129': 'i',
  '\u012B': 'i',
  '\u012D': 'i',
  '\u00EF': 'i',
  '\u1E2F': 'i',
  '\u1EC9': 'i',
  '\u01D0': 'i',
  '\u0209': 'i',
  '\u020B': 'i',
  '\u1ECB': 'i',
  '\u012F': 'i',
  '\u1E2D': 'i',
  '\u0268': 'i',
  '\u0131': 'i',
  '\u24D9': 'j',
  '\uFF4A': 'j',
  '\u0135': 'j',
  '\u01F0': 'j',
  '\u0249': 'j',
  '\u24DA': 'k',
  '\uFF4B': 'k',
  '\u1E31': 'k',
  '\u01E9': 'k',
  '\u1E33': 'k',
  '\u0137': 'k',
  '\u1E35': 'k',
  '\u0199': 'k',
  '\u2C6A': 'k',
  '\uA741': 'k',
  '\uA743': 'k',
  '\uA745': 'k',
  '\uA7A3': 'k',
  '\u24DB': 'l',
  '\uFF4C': 'l',
  '\u0140': 'l',
  '\u013A': 'l',
  '\u013E': 'l',
  '\u1E37': 'l',
  '\u1E39': 'l',
  '\u013C': 'l',
  '\u1E3D': 'l',
  '\u1E3B': 'l',
  '\u017F': 'l',
  '\u0142': 'l',
  '\u019A': 'l',
  '\u026B': 'l',
  '\u2C61': 'l',
  '\uA749': 'l',
  '\uA781': 'l',
  '\uA747': 'l',
  '\u01C9': 'lj',
  '\u24DC': 'm',
  '\uFF4D': 'm',
  '\u1E3F': 'm',
  '\u1E41': 'm',
  '\u1E43': 'm',
  '\u0271': 'm',
  '\u026F': 'm',
  '\u24DD': 'n',
  '\uFF4E': 'n',
  '\u01F9': 'n',
  '\u0144': 'n',
  '\u00F1': 'n',
  '\u1E45': 'n',
  '\u0148': 'n',
  '\u1E47': 'n',
  '\u0146': 'n',
  '\u1E4B': 'n',
  '\u1E49': 'n',
  '\u019E': 'n',
  '\u0272': 'n',
  '\u0149': 'n',
  '\uA791': 'n',
  '\uA7A5': 'n',
  '\u01CC': 'nj',
  '\u24DE': 'o',
  '\uFF4F': 'o',
  '\u00F2': 'o',
  '\u00F3': 'o',
  '\u00F4': 'o',
  '\u1ED3': 'o',
  '\u1ED1': 'o',
  '\u1ED7': 'o',
  '\u1ED5': 'o',
  '\u00F5': 'o',
  '\u1E4D': 'o',
  '\u022D': 'o',
  '\u1E4F': 'o',
  '\u014D': 'o',
  '\u1E51': 'o',
  '\u1E53': 'o',
  '\u014F': 'o',
  '\u022F': 'o',
  '\u0231': 'o',
  '\u00F6': 'o',
  '\u022B': 'o',
  '\u1ECF': 'o',
  '\u0151': 'o',
  '\u01D2': 'o',
  '\u020D': 'o',
  '\u020F': 'o',
  '\u01A1': 'o',
  '\u1EDD': 'o',
  '\u1EDB': 'o',
  '\u1EE1': 'o',
  '\u1EDF': 'o',
  '\u1EE3': 'o',
  '\u1ECD': 'o',
  '\u1ED9': 'o',
  '\u01EB': 'o',
  '\u01ED': 'o',
  '\u00F8': 'o',
  '\u01FF': 'o',
  '\u0254': 'o',
  '\uA74B': 'o',
  '\uA74D': 'o',
  '\u0275': 'o',
  '\u01A3': 'oi',
  '\u0223': 'ou',
  '\uA74F': 'oo',
  '\u24DF': 'p',
  '\uFF50': 'p',
  '\u1E55': 'p',
  '\u1E57': 'p',
  '\u01A5': 'p',
  '\u1D7D': 'p',
  '\uA751': 'p',
  '\uA753': 'p',
  '\uA755': 'p',
  '\u24E0': 'q',
  '\uFF51': 'q',
  '\u024B': 'q',
  '\uA757': 'q',
  '\uA759': 'q',
  '\u24E1': 'r',
  '\uFF52': 'r',
  '\u0155': 'r',
  '\u1E59': 'r',
  '\u0159': 'r',
  '\u0211': 'r',
  '\u0213': 'r',
  '\u1E5B': 'r',
  '\u1E5D': 'r',
  '\u0157': 'r',
  '\u1E5F': 'r',
  '\u024D': 'r',
  '\u027D': 'r',
  '\uA75B': 'r',
  '\uA7A7': 'r',
  '\uA783': 'r',
  '\u24E2': 's',
  '\uFF53': 's',
  '\u00DF': 's',
  '\u015B': 's',
  '\u1E65': 's',
  '\u015D': 's',
  '\u1E61': 's',
  '\u0161': 's',
  '\u1E67': 's',
  '\u1E63': 's',
  '\u1E69': 's',
  '\u0219': 's',
  '\u015F': 's',
  '\u023F': 's',
  '\uA7A9': 's',
  '\uA785': 's',
  '\u1E9B': 's',
  '\u24E3': 't',
  '\uFF54': 't',
  '\u1E6B': 't',
  '\u1E97': 't',
  '\u0165': 't',
  '\u1E6D': 't',
  '\u021B': 't',
  '\u0163': 't',
  '\u1E71': 't',
  '\u1E6F': 't',
  '\u0167': 't',
  '\u01AD': 't',
  '\u0288': 't',
  '\u2C66': 't',
  '\uA787': 't',
  '\uA729': 'tz',
  '\u24E4': 'u',
  '\uFF55': 'u',
  '\u00F9': 'u',
  '\u00FA': 'u',
  '\u00FB': 'u',
  '\u0169': 'u',
  '\u1E79': 'u',
  '\u016B': 'u',
  '\u1E7B': 'u',
  '\u016D': 'u',
  '\u00FC': 'u',
  '\u01DC': 'u',
  '\u01D8': 'u',
  '\u01D6': 'u',
  '\u01DA': 'u',
  '\u1EE7': 'u',
  '\u016F': 'u',
  '\u0171': 'u',
  '\u01D4': 'u',
  '\u0215': 'u',
  '\u0217': 'u',
  '\u01B0': 'u',
  '\u1EEB': 'u',
  '\u1EE9': 'u',
  '\u1EEF': 'u',
  '\u1EED': 'u',
  '\u1EF1': 'u',
  '\u1EE5': 'u',
  '\u1E73': 'u',
  '\u0173': 'u',
  '\u1E77': 'u',
  '\u1E75': 'u',
  '\u0289': 'u',
  '\u24E5': 'v',
  '\uFF56': 'v',
  '\u1E7D': 'v',
  '\u1E7F': 'v',
  '\u028B': 'v',
  '\uA75F': 'v',
  '\u028C': 'v',
  '\uA761': 'vy',
  '\u24E6': 'w',
  '\uFF57': 'w',
  '\u1E81': 'w',
  '\u1E83': 'w',
  '\u0175': 'w',
  '\u1E87': 'w',
  '\u1E85': 'w',
  '\u1E98': 'w',
  '\u1E89': 'w',
  '\u2C73': 'w',
  '\u24E7': 'x',
  '\uFF58': 'x',
  '\u1E8B': 'x',
  '\u1E8D': 'x',
  '\u24E8': 'y',
  '\uFF59': 'y',
  '\u1EF3': 'y',
  '\u00FD': 'y',
  '\u0177': 'y',
  '\u1EF9': 'y',
  '\u0233': 'y',
  '\u1E8F': 'y',
  '\u00FF': 'y',
  '\u1EF7': 'y',
  '\u1E99': 'y',
  '\u1EF5': 'y',
  '\u01B4': 'y',
  '\u024F': 'y',
  '\u1EFF': 'y',
  '\u24E9': 'z',
  '\uFF5A': 'z',
  '\u017A': 'z',
  '\u1E91': 'z',
  '\u017C': 'z',
  '\u017E': 'z',
  '\u1E93': 'z',
  '\u1E95': 'z',
  '\u01B6': 'z',
  '\u0225': 'z',
  '\u0240': 'z',
  '\u2C6C': 'z',
  '\uA763': 'z',
  '\u0386': '\u0391',
  '\u0388': '\u0395',
  '\u0389': '\u0397',
  '\u038A': '\u0399',
  '\u03AA': '\u0399',
  '\u038C': '\u039F',
  '\u038E': '\u03A5',
  '\u03AB': '\u03A5',
  '\u038F': '\u03A9',
  '\u03AC': '\u03B1',
  '\u03AD': '\u03B5',
  '\u03AE': '\u03B7',
  '\u03AF': '\u03B9',
  '\u03CA': '\u03B9',
  '\u0390': '\u03B9',
  '\u03CC': '\u03BF',
  '\u03CD': '\u03C5',
  '\u03CB': '\u03C5',
  '\u03B0': '\u03C5',
  '\u03C9': '\u03C9',
  '\u03C2': '\u03C3'
};
function stripSpecialChars(text) {
  const match = a => diacritics[a] || a;
  return text.replace(/[^\u0000-\u007E]/g, match);
}
class ItemsList {
  constructor(_ngSelect, _selectionModel) {
    this._ngSelect = _ngSelect;
    this._selectionModel = _selectionModel;
    this._items = [];
    this._filteredItems = [];
    this._markedIndex = -1;
  }
  get items() {
    return this._items;
  }
  get filteredItems() {
    return this._filteredItems;
  }
  get markedIndex() {
    return this._markedIndex;
  }
  get selectedItems() {
    return this._selectionModel.value;
  }
  get markedItem() {
    return this._filteredItems[this._markedIndex];
  }
  get noItemsToSelect() {
    return this._ngSelect.hideSelected && this._items.length === this.selectedItems.length;
  }
  get maxItemsSelected() {
    return this._ngSelect.multiple && this._ngSelect.maxSelectedItems <= this.selectedItems.length;
  }
  get lastSelectedItem() {
    let i = this.selectedItems.length - 1;
    for (; i >= 0; i--) {
      const item = this.selectedItems[i];
      if (!item.disabled) {
        return item;
      }
    }
    return null;
  }
  setItems(items) {
    this._items = items.map((item, index) => this.mapItem(item, index));
    if (this._ngSelect.groupBy) {
      this._groups = this._groupBy(this._items, this._ngSelect.groupBy);
      this._items = this._flatten(this._groups);
    } else {
      this._groups = new Map();
      this._groups.set(undefined, this._items);
    }
    this._filteredItems = [...this._items];
  }
  select(item) {
    if (item.selected || this.maxItemsSelected) {
      return;
    }
    const multiple = this._ngSelect.multiple;
    if (!multiple) {
      this.clearSelected();
    }
    this._selectionModel.select(item, multiple, this._ngSelect.selectableGroupAsModel);
    if (this._ngSelect.hideSelected) {
      this._hideSelected(item);
    }
  }
  unselect(item) {
    if (!item.selected) {
      return;
    }
    this._selectionModel.unselect(item, this._ngSelect.multiple);
    if (this._ngSelect.hideSelected && isDefined(item.index) && this._ngSelect.multiple) {
      this._showSelected(item);
    }
  }
  findItem(value) {
    let findBy;
    if (this._ngSelect.compareWith) {
      findBy = item => this._ngSelect.compareWith(item.value, value);
    } else if (this._ngSelect.bindValue) {
      findBy = item => !item.children && this.resolveNested(item.value, this._ngSelect.bindValue) === value;
    } else {
      findBy = item => item.value === value || !item.children && item.label && item.label === this.resolveNested(value, this._ngSelect.bindLabel);
    }
    return this._items.find(item => findBy(item));
  }
  addItem(item) {
    const option = this.mapItem(item, this._items.length);
    this._items.push(option);
    this._filteredItems.push(option);
    return option;
  }
  clearSelected(keepDisabled = false) {
    this._selectionModel.clear(keepDisabled);
    this._items.forEach(item => {
      item.selected = keepDisabled && item.selected && item.disabled;
      item.marked = false;
    });
    if (this._ngSelect.hideSelected) {
      this.resetFilteredItems();
    }
  }
  findByLabel(term) {
    term = stripSpecialChars(term).toLocaleLowerCase();
    return this.filteredItems.find(item => {
      const label = stripSpecialChars(item.label).toLocaleLowerCase();
      return label.substr(0, term.length) === term;
    });
  }
  filter(term) {
    if (!term) {
      this.resetFilteredItems();
      return;
    }
    this._filteredItems = [];
    term = this._ngSelect.searchFn ? term : stripSpecialChars(term).toLocaleLowerCase();
    const match = this._ngSelect.searchFn || this._defaultSearchFn;
    const hideSelected = this._ngSelect.hideSelected;
    for (const key of Array.from(this._groups.keys())) {
      const matchedItems = [];
      for (const item of this._groups.get(key)) {
        if (hideSelected && (item.parent && item.parent.selected || item.selected)) {
          continue;
        }
        const searchItem = this._ngSelect.searchFn ? item.value : item;
        if (match(term, searchItem)) {
          matchedItems.push(item);
        }
      }
      if (matchedItems.length > 0) {
        const [last] = matchedItems.slice(-1);
        if (last.parent) {
          const head = this._items.find(x => x === last.parent);
          this._filteredItems.push(head);
        }
        this._filteredItems.push(...matchedItems);
      }
    }
  }
  resetFilteredItems() {
    if (this._filteredItems.length === this._items.length) {
      return;
    }
    if (this._ngSelect.hideSelected && this.selectedItems.length > 0) {
      this._filteredItems = this._items.filter(x => !x.selected);
    } else {
      this._filteredItems = this._items;
    }
  }
  unmarkItem() {
    this._markedIndex = -1;
  }
  markNextItem() {
    this._stepToItem(+1);
  }
  markPreviousItem() {
    this._stepToItem(-1);
  }
  markItem(item) {
    this._markedIndex = this._filteredItems.indexOf(item);
  }
  markSelectedOrDefault(markDefault) {
    if (this._filteredItems.length === 0) {
      return;
    }
    const lastMarkedIndex = this._getLastMarkedIndex();
    if (lastMarkedIndex > -1) {
      this._markedIndex = lastMarkedIndex;
    } else {
      this._markedIndex = markDefault ? this.filteredItems.findIndex(x => !x.disabled) : -1;
    }
  }
  resolveNested(option, key) {
    if (!isObject(option)) {
      return option;
    }
    if (key.indexOf('.') === -1) {
      return option[key];
    } else {
      const keys = key.split('.');
      let value = option;
      for (let i = 0, len = keys.length; i < len; ++i) {
        if (value == null) {
          return null;
        }
        value = value[keys[i]];
      }
      return value;
    }
  }
  mapItem(item, index) {
    const label = isDefined(item.$ngOptionLabel) ? item.$ngOptionLabel : this.resolveNested(item, this._ngSelect.bindLabel);
    const value = isDefined(item.$ngOptionValue) ? item.$ngOptionValue : item;
    return {
      index,
      label: isDefined(label) ? label.toString() : '',
      value,
      disabled: item.disabled,
      htmlId: `${this._ngSelect.dropdownId}-${index}`
    };
  }
  mapSelectedItems() {
    const multiple = this._ngSelect.multiple;
    for (const selected of this.selectedItems) {
      const value = this._ngSelect.bindValue ? this.resolveNested(selected.value, this._ngSelect.bindValue) : selected.value;
      const item = isDefined(value) ? this.findItem(value) : null;
      this._selectionModel.unselect(selected, multiple);
      this._selectionModel.select(item || selected, multiple, this._ngSelect.selectableGroupAsModel);
    }
    if (this._ngSelect.hideSelected) {
      this._filteredItems = this.filteredItems.filter(x => this.selectedItems.indexOf(x) === -1);
    }
  }
  _showSelected(item) {
    this._filteredItems.push(item);
    if (item.parent) {
      const parent = item.parent;
      const parentExists = this._filteredItems.find(x => x === parent);
      if (!parentExists) {
        this._filteredItems.push(parent);
      }
    } else if (item.children) {
      for (const child of item.children) {
        child.selected = false;
        this._filteredItems.push(child);
      }
    }
    this._filteredItems = [...this._filteredItems.sort((a, b) => a.index - b.index)];
  }
  _hideSelected(item) {
    this._filteredItems = this._filteredItems.filter(x => x !== item);
    if (item.parent) {
      const children = item.parent.children;
      if (children.every(x => x.selected)) {
        this._filteredItems = this._filteredItems.filter(x => x !== item.parent);
      }
    } else if (item.children) {
      this._filteredItems = this.filteredItems.filter(x => x.parent !== item);
    }
  }
  _defaultSearchFn(search, opt) {
    const label = stripSpecialChars(opt.label).toLocaleLowerCase();
    return label.indexOf(search) > -1;
  }
  _getNextItemIndex(steps) {
    if (steps > 0) {
      return this._markedIndex >= this._filteredItems.length - 1 ? 0 : this._markedIndex + 1;
    }
    return this._markedIndex <= 0 ? this._filteredItems.length - 1 : this._markedIndex - 1;
  }
  _stepToItem(steps) {
    if (this._filteredItems.length === 0 || this._filteredItems.every(x => x.disabled)) {
      return;
    }
    this._markedIndex = this._getNextItemIndex(steps);
    if (this.markedItem.disabled) {
      this._stepToItem(steps);
    }
  }
  _getLastMarkedIndex() {
    if (this._ngSelect.hideSelected) {
      return -1;
    }
    if (this._markedIndex > -1 && this.markedItem === undefined) {
      return -1;
    }
    const selectedIndex = this._filteredItems.indexOf(this.lastSelectedItem);
    if (this.lastSelectedItem && selectedIndex < 0) {
      return -1;
    }
    return Math.max(this.markedIndex, selectedIndex);
  }
  _groupBy(items, prop) {
    const groups = new Map();
    if (items.length === 0) {
      return groups;
    }
    // Check if items are already grouped by given key.
    if (Array.isArray(items[0].value[prop])) {
      for (const item of items) {
        const children = (item.value[prop] || []).map((x, index) => this.mapItem(x, index));
        groups.set(item, children);
      }
      return groups;
    }
    const isFnKey = isFunction(this._ngSelect.groupBy);
    const keyFn = item => {
      const key = isFnKey ? prop(item.value) : item.value[prop];
      return isDefined(key) ? key : undefined;
    };
    // Group items by key.
    for (const item of items) {
      const key = keyFn(item);
      const group = groups.get(key);
      if (group) {
        group.push(item);
      } else {
        groups.set(key, [item]);
      }
    }
    return groups;
  }
  _flatten(groups) {
    const isGroupByFn = isFunction(this._ngSelect.groupBy);
    const items = [];
    for (const key of Array.from(groups.keys())) {
      let i = items.length;
      if (key === undefined) {
        const withoutGroup = groups.get(undefined) || [];
        items.push(...withoutGroup.map(x => {
          x.index = i++;
          return x;
        }));
        continue;
      }
      const isObjectKey = isObject(key);
      const parent = {
        label: isObjectKey ? '' : String(key),
        children: undefined,
        parent: null,
        index: i++,
        disabled: !this._ngSelect.selectableGroup,
        htmlId: newId()
      };
      const groupKey = isGroupByFn ? this._ngSelect.bindLabel : this._ngSelect.groupBy;
      const groupValue = this._ngSelect.groupValue || (() => {
        if (isObjectKey) {
          return key.value;
        }
        return {
          [groupKey]: key
        };
      });
      const children = groups.get(key).map(x => {
        x.parent = parent;
        x.children = undefined;
        x.index = i++;
        return x;
      });
      parent.children = children;
      parent.value = groupValue(key, children.map(x => x.value));
      items.push(parent);
      items.push(...children);
    }
    return items;
  }
}
var KeyCode;
(function (KeyCode) {
  KeyCode[KeyCode["Tab"] = 9] = "Tab";
  KeyCode[KeyCode["Enter"] = 13] = "Enter";
  KeyCode[KeyCode["Esc"] = 27] = "Esc";
  KeyCode[KeyCode["Space"] = 32] = "Space";
  KeyCode[KeyCode["ArrowUp"] = 38] = "ArrowUp";
  KeyCode[KeyCode["ArrowDown"] = 40] = "ArrowDown";
  KeyCode[KeyCode["Backspace"] = 8] = "Backspace";
})(KeyCode || (KeyCode = {}));
class NgDropdownPanelService {
  constructor() {
    this._dimensions = {
      itemHeight: 0,
      panelHeight: 0,
      itemsPerViewport: 0
    };
  }
  get dimensions() {
    return this._dimensions;
  }
  calculateItems(scrollPos, itemsLength, buffer) {
    const d = this._dimensions;
    const scrollHeight = d.itemHeight * itemsLength;
    const scrollTop = Math.max(0, scrollPos);
    const indexByScrollTop = scrollTop / scrollHeight * itemsLength;
    let end = Math.min(itemsLength, Math.ceil(indexByScrollTop) + (d.itemsPerViewport + 1));
    const maxStartEnd = end;
    const maxStart = Math.max(0, maxStartEnd - d.itemsPerViewport);
    let start = Math.min(maxStart, Math.floor(indexByScrollTop));
    let topPadding = d.itemHeight * Math.ceil(start) - d.itemHeight * Math.min(start, buffer);
    topPadding = !isNaN(topPadding) ? topPadding : 0;
    start = !isNaN(start) ? start : -1;
    end = !isNaN(end) ? end : -1;
    start -= buffer;
    start = Math.max(0, start);
    end += buffer;
    end = Math.min(itemsLength, end);
    return {
      topPadding,
      scrollHeight,
      start,
      end
    };
  }
  setDimensions(itemHeight, panelHeight) {
    const itemsPerViewport = Math.max(1, Math.floor(panelHeight / itemHeight));
    this._dimensions = {
      itemHeight,
      panelHeight,
      itemsPerViewport
    };
  }
  getScrollTo(itemTop, itemHeight, lastScroll) {
    const {
      panelHeight
    } = this.dimensions;
    const itemBottom = itemTop + itemHeight;
    const top = lastScroll;
    const bottom = top + panelHeight;
    if (panelHeight >= itemBottom && lastScroll === itemTop) {
      return null;
    }
    if (itemBottom > bottom) {
      return top + itemBottom - bottom;
    } else if (itemTop <= top) {
      return itemTop;
    }
    return null;
  }
  static {
    this.ɵfac = function NgDropdownPanelService_Factory(t) {
      return new (t || NgDropdownPanelService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgDropdownPanelService,
      factory: NgDropdownPanelService.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgDropdownPanelService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const CSS_POSITIONS = ['top', 'right', 'bottom', 'left'];
const SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? rxjs__WEBPACK_IMPORTED_MODULE_1__.animationFrameScheduler : rxjs__WEBPACK_IMPORTED_MODULE_2__.asapScheduler;
class NgDropdownPanelComponent {
  constructor(_renderer, _zone, _panelService, _elementRef, _document) {
    this._renderer = _renderer;
    this._zone = _zone;
    this._panelService = _panelService;
    this._document = _document;
    this.items = [];
    this.position = 'auto';
    this.virtualScroll = false;
    this.filterValue = null;
    this.update = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.scroll = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.scrollToEnd = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.outsideClick = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this._destroy$ = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this._scrollToEndFired = false;
    this._updateScrollHeight = false;
    this._lastScrollPosition = 0;
    this._dropdown = _elementRef.nativeElement;
  }
  get currentPosition() {
    return this._currentPosition;
  }
  get itemsLength() {
    return this._itemsLength;
  }
  set itemsLength(value) {
    if (value !== this._itemsLength) {
      this._itemsLength = value;
      this._onItemsLengthChanged();
    }
  }
  get _startOffset() {
    if (this.markedItem) {
      const {
        itemHeight,
        panelHeight
      } = this._panelService.dimensions;
      const offset = this.markedItem.index * itemHeight;
      return panelHeight > offset ? 0 : offset;
    }
    return 0;
  }
  ngOnInit() {
    this._select = this._dropdown.parentElement;
    this._virtualPadding = this.paddingElementRef.nativeElement;
    this._scrollablePanel = this.scrollElementRef.nativeElement;
    this._contentPanel = this.contentElementRef.nativeElement;
    this._handleScroll();
    this._handleOutsideClick();
    this._appendDropdown();
    this._setupMousedownListener();
  }
  ngOnChanges(changes) {
    if (changes.items) {
      const change = changes.items;
      this._onItemsChange(change.currentValue, change.firstChange);
    }
  }
  ngOnDestroy() {
    this._destroy$.next();
    this._destroy$.complete();
    this._destroy$.unsubscribe();
    if (this.appendTo) {
      this._renderer.removeChild(this._dropdown.parentNode, this._dropdown);
    }
  }
  scrollTo(option, startFromOption = false) {
    if (!option) {
      return;
    }
    const index = this.items.indexOf(option);
    if (index < 0 || index >= this.itemsLength) {
      return;
    }
    let scrollTo;
    if (this.virtualScroll) {
      const itemHeight = this._panelService.dimensions.itemHeight;
      scrollTo = this._panelService.getScrollTo(index * itemHeight, itemHeight, this._lastScrollPosition);
    } else {
      const item = this._dropdown.querySelector(`#${option.htmlId}`);
      const lastScroll = startFromOption ? item.offsetTop : this._lastScrollPosition;
      scrollTo = this._panelService.getScrollTo(item.offsetTop, item.clientHeight, lastScroll);
    }
    if (isDefined(scrollTo)) {
      this._scrollablePanel.scrollTop = scrollTo;
    }
  }
  scrollToTag() {
    const panel = this._scrollablePanel;
    panel.scrollTop = panel.scrollHeight - panel.clientHeight;
  }
  adjustPosition() {
    this._updateYPosition();
  }
  _handleDropdownPosition() {
    this._currentPosition = this._calculateCurrentPosition(this._dropdown);
    if (CSS_POSITIONS.includes(this._currentPosition)) {
      this._updateDropdownClass(this._currentPosition);
    } else {
      this._updateDropdownClass('bottom');
    }
    if (this.appendTo) {
      this._updateYPosition();
    }
    this._dropdown.style.opacity = '1';
  }
  _updateDropdownClass(currentPosition) {
    CSS_POSITIONS.forEach(position => {
      const REMOVE_CSS_CLASS = `ng-select-${position}`;
      this._renderer.removeClass(this._dropdown, REMOVE_CSS_CLASS);
      this._renderer.removeClass(this._select, REMOVE_CSS_CLASS);
    });
    const ADD_CSS_CLASS = `ng-select-${currentPosition}`;
    this._renderer.addClass(this._dropdown, ADD_CSS_CLASS);
    this._renderer.addClass(this._select, ADD_CSS_CLASS);
  }
  _handleScroll() {
    this._zone.runOutsideAngular(() => {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.fromEvent)(this.scrollElementRef.nativeElement, 'scroll').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this._destroy$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.auditTime)(0, SCROLL_SCHEDULER)).subscribe(e => {
        const path = e.path || e.composedPath && e.composedPath();
        if (!path || path.length === 0 && !e.target) {
          return;
        }
        const scrollTop = !path || path.length === 0 ? e.target.scrollTop : path[0].scrollTop;
        this._onContentScrolled(scrollTop);
      });
    });
  }
  _handleOutsideClick() {
    if (!this._document) {
      return;
    }
    this._zone.runOutsideAngular(() => {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.merge)((0,rxjs__WEBPACK_IMPORTED_MODULE_4__.fromEvent)(this._document, 'touchstart', {
        capture: true
      }), (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.fromEvent)(this._document, 'mousedown', {
        capture: true
      })).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this._destroy$)).subscribe($event => this._checkToClose($event));
    });
  }
  _checkToClose($event) {
    if (this._select.contains($event.target) || this._dropdown.contains($event.target)) {
      return;
    }
    const path = $event.path || $event.composedPath && $event.composedPath();
    if ($event.target && $event.target.shadowRoot && path && path[0] && this._select.contains(path[0])) {
      return;
    }
    this._zone.run(() => this.outsideClick.emit());
  }
  _onItemsChange(items, firstChange) {
    this.items = items || [];
    this._scrollToEndFired = false;
    this.itemsLength = items.length;
    if (this.virtualScroll) {
      this._updateItemsRange(firstChange);
    } else {
      this._setVirtualHeight();
      this._updateItems(firstChange);
    }
  }
  _updateItems(firstChange) {
    this.update.emit(this.items);
    if (firstChange === false) {
      return;
    }
    this._zone.runOutsideAngular(() => {
      Promise.resolve().then(() => {
        const panelHeight = this._scrollablePanel.clientHeight;
        this._panelService.setDimensions(0, panelHeight);
        this._handleDropdownPosition();
        this.scrollTo(this.markedItem, firstChange);
      });
    });
  }
  _updateItemsRange(firstChange) {
    this._zone.runOutsideAngular(() => {
      this._measureDimensions().then(() => {
        if (firstChange) {
          this._renderItemsRange(this._startOffset);
          this._handleDropdownPosition();
        } else {
          this._renderItemsRange();
        }
      });
    });
  }
  _onContentScrolled(scrollTop) {
    if (this.virtualScroll) {
      this._renderItemsRange(scrollTop);
    }
    this._lastScrollPosition = scrollTop;
    this._fireScrollToEnd(scrollTop);
  }
  _updateVirtualHeight(height) {
    if (this._updateScrollHeight) {
      this._virtualPadding.style.height = `${height}px`;
      this._updateScrollHeight = false;
    }
  }
  _setVirtualHeight() {
    if (!this._virtualPadding) {
      return;
    }
    this._virtualPadding.style.height = `0px`;
  }
  _onItemsLengthChanged() {
    this._updateScrollHeight = true;
  }
  _renderItemsRange(scrollTop = null) {
    if (scrollTop && this._lastScrollPosition === scrollTop) {
      return;
    }
    scrollTop = scrollTop || this._scrollablePanel.scrollTop;
    const range = this._panelService.calculateItems(scrollTop, this.itemsLength, this.bufferAmount);
    this._updateVirtualHeight(range.scrollHeight);
    this._contentPanel.style.transform = `translateY(${range.topPadding}px)`;
    this._zone.run(() => {
      this.update.emit(this.items.slice(range.start, range.end));
      this.scroll.emit({
        start: range.start,
        end: range.end
      });
    });
    if (isDefined(scrollTop) && this._lastScrollPosition === 0) {
      this._scrollablePanel.scrollTop = scrollTop;
      this._lastScrollPosition = scrollTop;
    }
  }
  _measureDimensions() {
    if (this._panelService.dimensions.itemHeight > 0 || this.itemsLength === 0) {
      return Promise.resolve(this._panelService.dimensions);
    }
    const [first] = this.items;
    this.update.emit([first]);
    return Promise.resolve().then(() => {
      const option = this._dropdown.querySelector(`#${first.htmlId}`);
      const optionHeight = option.clientHeight;
      this._virtualPadding.style.height = `${optionHeight * this.itemsLength}px`;
      const panelHeight = this._scrollablePanel.clientHeight;
      this._panelService.setDimensions(optionHeight, panelHeight);
      return this._panelService.dimensions;
    });
  }
  _fireScrollToEnd(scrollTop) {
    if (this._scrollToEndFired || scrollTop === 0) {
      return;
    }
    const padding = this.virtualScroll ? this._virtualPadding : this._contentPanel;
    if (scrollTop + this._dropdown.clientHeight >= padding.clientHeight - 1) {
      this._zone.run(() => this.scrollToEnd.emit());
      this._scrollToEndFired = true;
    }
  }
  _calculateCurrentPosition(dropdownEl) {
    if (this.position !== 'auto') {
      return this.position;
    }
    const selectRect = this._select.getBoundingClientRect();
    const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
    const offsetTop = selectRect.top + window.pageYOffset;
    const height = selectRect.height;
    const dropdownHeight = dropdownEl.getBoundingClientRect().height;
    if (offsetTop + height + dropdownHeight > scrollTop + document.documentElement.clientHeight) {
      return 'top';
    } else {
      return 'bottom';
    }
  }
  _appendDropdown() {
    if (!this.appendTo) {
      return;
    }
    this._parent = document.querySelector(this.appendTo);
    if (!this._parent) {
      throw new Error(`appendTo selector ${this.appendTo} did not found any parent element`);
    }
    this._updateXPosition();
    this._parent.appendChild(this._dropdown);
  }
  _updateXPosition() {
    const select = this._select.getBoundingClientRect();
    const parent = this._parent.getBoundingClientRect();
    const offsetLeft = select.left - parent.left;
    this._dropdown.style.left = offsetLeft + 'px';
    this._dropdown.style.width = select.width + 'px';
    this._dropdown.style.minWidth = select.width + 'px';
  }
  _updateYPosition() {
    const select = this._select.getBoundingClientRect();
    const parent = this._parent.getBoundingClientRect();
    const delta = select.height;
    if (this._currentPosition === 'top') {
      const offsetBottom = parent.bottom - select.bottom;
      this._dropdown.style.bottom = offsetBottom + delta + 'px';
      this._dropdown.style.top = 'auto';
    } else if (this._currentPosition === 'bottom') {
      const offsetTop = select.top - parent.top;
      this._dropdown.style.top = offsetTop + delta + 'px';
      this._dropdown.style.bottom = 'auto';
    }
  }
  _setupMousedownListener() {
    this._zone.runOutsideAngular(() => {
      (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.fromEvent)(this._dropdown, 'mousedown').pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this._destroy$)).subscribe(event => {
        const target = event.target;
        if (target.tagName === 'INPUT') {
          return;
        }
        event.preventDefault();
      });
    });
  }
  static {
    this.ɵfac = function NgDropdownPanelComponent_Factory(t) {
      return new (t || NgDropdownPanelComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgDropdownPanelService), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT, 8));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgDropdownPanelComponent,
      selectors: [["ng-dropdown-panel"]],
      viewQuery: function NgDropdownPanelComponent_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c0, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c1, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c2, 7, _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.contentElementRef = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.scrollElementRef = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.paddingElementRef = _t.first);
        }
      },
      inputs: {
        items: "items",
        markedItem: "markedItem",
        position: "position",
        appendTo: "appendTo",
        bufferAmount: "bufferAmount",
        virtualScroll: "virtualScroll",
        headerTemplate: "headerTemplate",
        footerTemplate: "footerTemplate",
        filterValue: "filterValue"
      },
      outputs: {
        update: "update",
        scroll: "scroll",
        scrollToEnd: "scrollToEnd",
        outsideClick: "outsideClick"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
      ngContentSelectors: _c3,
      decls: 9,
      vars: 6,
      consts: [["scroll", ""], ["padding", ""], ["content", ""], ["class", "ng-dropdown-header", 4, "ngIf"], ["role", "listbox", 1, "ng-dropdown-panel-items", "scroll-host"], ["class", "ng-dropdown-footer", 4, "ngIf"], [1, "ng-dropdown-header"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], [1, "ng-dropdown-footer"]],
      template: function NgDropdownPanelComponent_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](0, NgDropdownPanelComponent_div_0_Template, 2, 4, "div", 3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 4, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](3, "div", null, 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](5, "div", null, 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](7);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](8, NgDropdownPanelComponent_div_8_Template, 2, 4, "div", 5);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.headerTemplate);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("total-padding", ctx.virtualScroll);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("scrollable-content", ctx.virtualScroll && ctx.items.length);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.footerTemplate);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_8__.NgTemplateOutlet],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgDropdownPanelComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      selector: 'ng-dropdown-panel',
      template: `
        <div *ngIf="headerTemplate" class="ng-dropdown-header">
            <ng-container [ngTemplateOutlet]="headerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
        </div>
        <div #scroll role="listbox" class="ng-dropdown-panel-items scroll-host">
            <div #padding [class.total-padding]="virtualScroll"></div>
            <div #content [class.scrollable-content]="virtualScroll && items.length">
                <ng-content></ng-content>
            </div>
        </div>
        <div *ngIf="footerTemplate" class="ng-dropdown-footer">
            <ng-container [ngTemplateOutlet]="footerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
        </div>
    `
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: NgDropdownPanelService
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.DOCUMENT]
    }]
  }], {
    items: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    markedItem: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    position: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    appendTo: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    bufferAmount: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualScroll: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    headerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    footerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    filterValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    update: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    scroll: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    scrollToEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    outsideClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    contentElementRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['content', {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef,
        static: true
      }]
    }],
    scrollElementRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['scroll', {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef,
        static: true
      }]
    }],
    paddingElementRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['padding', {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef,
        static: true
      }]
    }]
  });
})();
class NgOptionComponent {
  get disabled() {
    return this._disabled;
  }
  set disabled(value) {
    this._disabled = this._isDisabled(value);
  }
  constructor(elementRef) {
    this.elementRef = elementRef;
    this.stateChange$ = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this._disabled = false;
  }
  get label() {
    return (this.elementRef.nativeElement.textContent || '').trim();
  }
  ngOnChanges(changes) {
    if (changes.disabled) {
      this.stateChange$.next({
        value: this.value,
        disabled: this._disabled
      });
    }
  }
  ngAfterViewChecked() {
    if (this.label !== this._previousLabel) {
      this._previousLabel = this.label;
      this.stateChange$.next({
        value: this.value,
        disabled: this._disabled,
        label: this.elementRef.nativeElement.innerHTML
      });
    }
  }
  ngOnDestroy() {
    this.stateChange$.complete();
  }
  _isDisabled(value) {
    return value != null && `${value}` !== 'false';
  }
  static {
    this.ɵfac = function NgOptionComponent_Factory(t) {
      return new (t || NgOptionComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgOptionComponent,
      selectors: [["ng-option"]],
      inputs: {
        value: "value",
        disabled: "disabled"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
      ngContentSelectors: _c3,
      decls: 1,
      vars: 0,
      template: function NgOptionComponent_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
        }
      },
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgOptionComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ng-option',
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      template: `<ng-content></ng-content>`
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }], {
    value: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }]
  });
})();
class NgSelectConfig {
  constructor() {
    this.notFoundText = 'No items found';
    this.typeToSearchText = 'Type to search';
    this.addTagText = 'Add item';
    this.loadingText = 'Loading...';
    this.clearAllText = 'Clear all';
    this.disableVirtualScroll = true;
    this.openOnEnter = true;
    this.appearance = 'underline';
  }
  static {
    this.ɵfac = function NgSelectConfig_Factory(t) {
      return new (t || NgSelectConfig)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: NgSelectConfig,
      factory: NgSelectConfig.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSelectConfig, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class ConsoleService {
  warn(message) {
    console.warn(message);
  }
  static {
    this.ɵfac = function ConsoleService_Factory(t) {
      return new (t || ConsoleService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: ConsoleService,
      factory: ConsoleService.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ConsoleService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
const SELECTION_MODEL_FACTORY = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('ng-select-selection-model');
class NgSelectComponent {
  get items() {
    return this._items;
  }
  set items(value) {
    if (value === null) {
      value = [];
    }
    this._itemsAreUsed = true;
    this._items = value;
  }
  get compareWith() {
    return this._compareWith;
  }
  set compareWith(fn) {
    if (fn !== undefined && fn !== null && !isFunction(fn)) {
      throw Error('`compareWith` must be a function.');
    }
    this._compareWith = fn;
  }
  get clearSearchOnAdd() {
    if (isDefined(this._clearSearchOnAdd)) {
      return this._clearSearchOnAdd;
    } else if (isDefined(this.config.clearSearchOnAdd)) {
      return this.config.clearSearchOnAdd;
    }
    return this.closeOnSelect;
  }
  set clearSearchOnAdd(value) {
    this._clearSearchOnAdd = value;
  }
  get deselectOnClick() {
    if (isDefined(this._deselectOnClick)) {
      return this._deselectOnClick;
    } else if (isDefined(this.config.deselectOnClick)) {
      return this.config.deselectOnClick;
    }
    return this.multiple;
  }
  set deselectOnClick(value) {
    this._deselectOnClick = value;
  }
  get disabled() {
    return this.readonly || this._disabled;
  }
  get filtered() {
    return !!this.searchTerm && this.searchable || this._isComposing;
  }
  get single() {
    return !this.multiple;
  }
  get _editableSearchTerm() {
    return this.editableSearchTerm && !this.multiple;
  }
  constructor(classes, autoFocus, config, newSelectionModel, _elementRef, _cd, _console) {
    this.classes = classes;
    this.autoFocus = autoFocus;
    this.config = config;
    this._cd = _cd;
    this._console = _console;
    this.markFirst = true;
    this.dropdownPosition = 'auto';
    this.loading = false;
    this.closeOnSelect = true;
    this.hideSelected = false;
    this.selectOnTab = false;
    this.bufferAmount = 4;
    this.selectableGroup = false;
    this.selectableGroupAsModel = true;
    this.searchFn = null;
    this.trackByFn = null;
    this.clearOnBackspace = true;
    this.labelForId = null;
    this.inputAttrs = {};
    this.readonly = false;
    this.searchWhileComposing = true;
    this.minTermLength = 0;
    this.editableSearchTerm = false;
    this.keyDownFn = _ => true;
    this.multiple = false;
    this.addTag = false;
    this.searchable = true;
    this.clearable = true;
    this.isOpen = false;
    // output events
    this.blurEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.focusEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.changeEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.openEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.closeEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.searchEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.clearEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.addEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.removeEvent = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.scroll = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.scrollToEnd = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
    this.useDefaultClass = true;
    this.viewPortItems = [];
    this.searchTerm = null;
    this.dropdownId = newId();
    this.escapeHTML = true;
    this._items = [];
    this._defaultLabel = 'label';
    this._pressedKeys = [];
    this._isComposing = false;
    this._destroy$ = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this._keyPress$ = new rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject();
    this._onChange = _ => {};
    this._onTouched = () => {};
    this.clearItem = item => {
      const option = this.selectedItems.find(x => x.value === item);
      this.unselect(option);
    };
    this.trackByOption = (_, item) => {
      if (this.trackByFn) {
        return this.trackByFn(item.value);
      }
      return item;
    };
    this._mergeGlobalConfig(config);
    this.itemsList = new ItemsList(this, newSelectionModel());
    this.element = _elementRef.nativeElement;
  }
  get selectedItems() {
    return this.itemsList.selectedItems;
  }
  get selectedValues() {
    return this.selectedItems.map(x => x.value);
  }
  get hasValue() {
    return this.selectedItems.length > 0;
  }
  get currentPanelPosition() {
    if (this.dropdownPanel) {
      return this.dropdownPanel.currentPosition;
    }
    return undefined;
  }
  ngOnInit() {
    this._handleKeyPresses();
    this._setInputAttributes();
  }
  ngOnChanges(changes) {
    if (changes.multiple) {
      this.itemsList.clearSelected();
    }
    if (changes.items) {
      this._setItems(changes.items.currentValue || []);
    }
    if (changes.isOpen) {
      this._manualOpen = isDefined(changes.isOpen.currentValue);
    }
  }
  ngAfterViewInit() {
    if (!this._itemsAreUsed) {
      this.escapeHTML = false;
      this._setItemsFromNgOptions();
    }
    if (isDefined(this.autoFocus)) {
      this.focus();
    }
  }
  ngOnDestroy() {
    this._destroy$.next();
    this._destroy$.complete();
  }
  handleKeyDown($event) {
    const keyCode = KeyCode[$event.which];
    if (keyCode) {
      if (this.keyDownFn($event) === false) {
        return;
      }
      this.handleKeyCode($event);
    } else if ($event.key && $event.key.length === 1) {
      this._keyPress$.next($event.key.toLocaleLowerCase());
    }
  }
  handleKeyCode($event) {
    const target = $event.target;
    if (this.clearButton && this.clearButton.nativeElement === target) {
      this.handleKeyCodeClear($event);
    } else {
      this.handleKeyCodeInput($event);
    }
  }
  handleKeyCodeInput($event) {
    switch ($event.which) {
      case KeyCode.ArrowDown:
        this._handleArrowDown($event);
        break;
      case KeyCode.ArrowUp:
        this._handleArrowUp($event);
        break;
      case KeyCode.Space:
        this._handleSpace($event);
        break;
      case KeyCode.Enter:
        this._handleEnter($event);
        break;
      case KeyCode.Tab:
        this._handleTab($event);
        break;
      case KeyCode.Esc:
        this.close();
        $event.preventDefault();
        break;
      case KeyCode.Backspace:
        this._handleBackspace();
        break;
    }
  }
  handleKeyCodeClear($event) {
    switch ($event.which) {
      case KeyCode.Enter:
        this.handleClearClick();
        $event.preventDefault();
        break;
    }
  }
  handleMousedown($event) {
    const target = $event.target;
    if (target.tagName !== 'INPUT') {
      $event.preventDefault();
    }
    if (target.classList.contains('ng-clear-wrapper')) {
      this.handleClearClick();
      return;
    }
    if (target.classList.contains('ng-arrow-wrapper')) {
      this.handleArrowClick();
      return;
    }
    if (target.classList.contains('ng-value-icon')) {
      return;
    }
    if (!this.focused) {
      this.focus();
    }
    if (this.searchable) {
      this.open();
    } else {
      this.toggle();
    }
  }
  handleArrowClick() {
    if (this.isOpen) {
      this.close();
    } else {
      this.open();
    }
  }
  handleClearClick() {
    if (this.hasValue) {
      this.itemsList.clearSelected(true);
      this._updateNgModel();
    }
    this._clearSearch();
    this.focus();
    this.clearEvent.emit();
    this._onSelectionChanged();
  }
  clearModel() {
    if (!this.clearable) {
      return;
    }
    this.itemsList.clearSelected();
    this._updateNgModel();
  }
  writeValue(value) {
    this.itemsList.clearSelected();
    this._handleWriteValue(value);
    this._cd.markForCheck();
  }
  registerOnChange(fn) {
    this._onChange = fn;
  }
  registerOnTouched(fn) {
    this._onTouched = fn;
  }
  setDisabledState(state) {
    this._disabled = state;
    this._cd.markForCheck();
  }
  toggle() {
    if (!this.isOpen) {
      this.open();
    } else {
      this.close();
    }
  }
  open() {
    if (this.disabled || this.isOpen || this._manualOpen) {
      return;
    }
    if (!this._isTypeahead && !this.addTag && this.itemsList.noItemsToSelect) {
      return;
    }
    this.isOpen = true;
    this.itemsList.markSelectedOrDefault(this.markFirst);
    this.openEvent.emit();
    if (!this.searchTerm) {
      this.focus();
    }
    this.detectChanges();
  }
  close() {
    if (!this.isOpen || this._manualOpen) {
      return;
    }
    this.isOpen = false;
    this._isComposing = false;
    if (!this._editableSearchTerm) {
      this._clearSearch();
    } else {
      this.itemsList.resetFilteredItems();
    }
    this.itemsList.unmarkItem();
    this._onTouched();
    this.closeEvent.emit();
    this._cd.markForCheck();
  }
  toggleItem(item) {
    if (!item || item.disabled || this.disabled) {
      return;
    }
    if (this.deselectOnClick && item.selected) {
      this.unselect(item);
    } else {
      this.select(item);
    }
    if (this._editableSearchTerm) {
      this._setSearchTermFromItems();
    }
    this._onSelectionChanged();
  }
  select(item) {
    if (!item.selected) {
      this.itemsList.select(item);
      if (this.clearSearchOnAdd && !this._editableSearchTerm) {
        this._clearSearch();
      }
      this._updateNgModel();
      if (this.multiple) {
        this.addEvent.emit(item.value);
      }
    }
    if (this.closeOnSelect || this.itemsList.noItemsToSelect) {
      this.close();
    }
  }
  focus() {
    this.searchInput.nativeElement.focus();
  }
  blur() {
    this.searchInput.nativeElement.blur();
  }
  unselect(item) {
    if (!item) {
      return;
    }
    this.itemsList.unselect(item);
    this.focus();
    this._updateNgModel();
    this.removeEvent.emit(item.value);
  }
  selectTag() {
    let tag;
    if (isFunction(this.addTag)) {
      tag = this.addTag(this.searchTerm);
    } else {
      tag = this._primitive ? this.searchTerm : {
        [this.bindLabel]: this.searchTerm
      };
    }
    const handleTag = item => this._isTypeahead || !this.isOpen ? this.itemsList.mapItem(item, null) : this.itemsList.addItem(item);
    if (isPromise(tag)) {
      tag.then(item => this.select(handleTag(item))).catch(() => {});
    } else if (tag) {
      this.select(handleTag(tag));
    }
  }
  showClear() {
    return this.clearable && (this.hasValue || this.searchTerm) && !this.disabled;
  }
  focusOnClear() {
    this.blur();
    if (this.clearButton) {
      this.clearButton.nativeElement.focus();
    }
  }
  get showAddTag() {
    if (!this._validTerm) {
      return false;
    }
    const term = this.searchTerm.toLowerCase().trim();
    return this.addTag && !this.itemsList.filteredItems.some(x => x.label.toLowerCase() === term) && (!this.hideSelected && this.isOpen || !this.selectedItems.some(x => x.label.toLowerCase() === term)) && !this.loading;
  }
  showNoItemsFound() {
    const empty = this.itemsList.filteredItems.length === 0;
    return (empty && !this._isTypeahead && !this.loading || empty && this._isTypeahead && this._validTerm && !this.loading) && !this.showAddTag;
  }
  showTypeToSearch() {
    const empty = this.itemsList.filteredItems.length === 0;
    return empty && this._isTypeahead && !this._validTerm && !this.loading;
  }
  onCompositionStart() {
    this._isComposing = true;
  }
  onCompositionEnd(term) {
    this._isComposing = false;
    if (this.searchWhileComposing) {
      return;
    }
    this.filter(term);
  }
  filter(term) {
    if (this._isComposing && !this.searchWhileComposing) {
      return;
    }
    this.searchTerm = term;
    if (this._isTypeahead && (this._validTerm || this.minTermLength === 0)) {
      this.typeahead.next(term);
    }
    if (!this._isTypeahead) {
      this.itemsList.filter(this.searchTerm);
      if (this.isOpen) {
        this.itemsList.markSelectedOrDefault(this.markFirst);
      }
    }
    this.searchEvent.emit({
      term,
      items: this.itemsList.filteredItems.map(x => x.value)
    });
    this.open();
  }
  onInputFocus($event) {
    if (this.focused) {
      return;
    }
    if (this._editableSearchTerm) {
      this._setSearchTermFromItems();
    }
    this.element.classList.add('ng-select-focused');
    this.focusEvent.emit($event);
    this.focused = true;
  }
  onInputBlur($event) {
    this.element.classList.remove('ng-select-focused');
    this.blurEvent.emit($event);
    if (!this.isOpen && !this.disabled) {
      this._onTouched();
    }
    if (this._editableSearchTerm) {
      this._setSearchTermFromItems();
    }
    this.focused = false;
  }
  onItemHover(item) {
    if (item.disabled) {
      return;
    }
    this.itemsList.markItem(item);
  }
  detectChanges() {
    if (!this._cd.destroyed) {
      this._cd.detectChanges();
    }
  }
  _setSearchTermFromItems() {
    const selected = this.selectedItems && this.selectedItems[0];
    this.searchTerm = selected && selected.label || null;
  }
  _setItems(items) {
    const firstItem = items[0];
    this.bindLabel = this.bindLabel || this._defaultLabel;
    this._primitive = isDefined(firstItem) ? !isObject(firstItem) : this._primitive || this.bindLabel === this._defaultLabel;
    this.itemsList.setItems(items);
    if (items.length > 0 && this.hasValue) {
      this.itemsList.mapSelectedItems();
    }
    if (this.isOpen && isDefined(this.searchTerm) && !this._isTypeahead) {
      this.itemsList.filter(this.searchTerm);
    }
    if (this._isTypeahead || this.isOpen) {
      this.itemsList.markSelectedOrDefault(this.markFirst);
    }
  }
  _setItemsFromNgOptions() {
    const mapNgOptions = options => {
      this.items = options.map(option => ({
        $ngOptionValue: option.value,
        $ngOptionLabel: option.elementRef.nativeElement.innerHTML,
        disabled: option.disabled
      }));
      this.itemsList.setItems(this.items);
      if (this.hasValue) {
        this.itemsList.mapSelectedItems();
      }
      this.detectChanges();
    };
    const handleOptionChange = () => {
      const changedOrDestroyed = (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.merge)(this.ngOptions.changes, this._destroy$);
      (0,rxjs__WEBPACK_IMPORTED_MODULE_7__.merge)(...this.ngOptions.map(option => option.stateChange$)).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(changedOrDestroyed)).subscribe(option => {
        const item = this.itemsList.findItem(option.value);
        item.disabled = option.disabled;
        item.label = option.label || item.label;
        this._cd.detectChanges();
      });
    };
    this.ngOptions.changes.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.startWith)(this.ngOptions), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this._destroy$)).subscribe(options => {
      this.bindLabel = this._defaultLabel;
      mapNgOptions(options);
      handleOptionChange();
    });
  }
  _isValidWriteValue(value) {
    if (!isDefined(value) || this.multiple && value === '' || Array.isArray(value) && value.length === 0) {
      return false;
    }
    const validateBinding = item => {
      if (!isDefined(this.compareWith) && isObject(item) && this.bindValue) {
        this._console.warn(`Setting object(${JSON.stringify(item)}) as your model with bindValue is not allowed unless [compareWith] is used.`);
        return false;
      }
      return true;
    };
    if (this.multiple) {
      if (!Array.isArray(value)) {
        this._console.warn('Multiple select ngModel should be array.');
        return false;
      }
      return value.every(item => validateBinding(item));
    } else {
      return validateBinding(value);
    }
  }
  _handleWriteValue(ngModel) {
    if (!this._isValidWriteValue(ngModel)) {
      return;
    }
    const select = val => {
      let item = this.itemsList.findItem(val);
      if (item) {
        this.itemsList.select(item);
      } else {
        const isValObject = isObject(val);
        const isPrimitive = !isValObject && !this.bindValue;
        if (isValObject || isPrimitive) {
          this.itemsList.select(this.itemsList.mapItem(val, null));
        } else if (this.bindValue) {
          item = {
            [this.bindLabel]: null,
            [this.bindValue]: val
          };
          this.itemsList.select(this.itemsList.mapItem(item, null));
        }
      }
    };
    if (this.multiple) {
      ngModel.forEach(item => select(item));
    } else {
      select(ngModel);
    }
  }
  _handleKeyPresses() {
    if (this.searchable) {
      return;
    }
    this._keyPress$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.takeUntil)(this._destroy$), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.tap)(letter => this._pressedKeys.push(letter)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.debounceTime)(200), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.filter)(() => this._pressedKeys.length > 0), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.map)(() => this._pressedKeys.join(''))).subscribe(term => {
      const item = this.itemsList.findByLabel(term);
      if (item) {
        if (this.isOpen) {
          this.itemsList.markItem(item);
          this._scrollToMarked();
          this._cd.markForCheck();
        } else {
          this.select(item);
        }
      }
      this._pressedKeys = [];
    });
  }
  _setInputAttributes() {
    const input = this.searchInput.nativeElement;
    const attributes = {
      type: 'text',
      autocorrect: 'off',
      autocapitalize: 'off',
      autocomplete: this.labelForId ? 'off' : this.dropdownId,
      ...this.inputAttrs
    };
    for (const key of Object.keys(attributes)) {
      input.setAttribute(key, attributes[key]);
    }
  }
  _updateNgModel() {
    const model = [];
    for (const item of this.selectedItems) {
      if (this.bindValue) {
        let value = null;
        if (item.children) {
          const groupKey = this.groupValue ? this.bindValue : this.groupBy;
          value = item.value[groupKey || this.groupBy];
        } else {
          value = this.itemsList.resolveNested(item.value, this.bindValue);
        }
        model.push(value);
      } else {
        model.push(item.value);
      }
    }
    const selected = this.selectedItems.map(x => x.value);
    if (this.multiple) {
      this._onChange(model);
      this.changeEvent.emit(selected);
    } else {
      this._onChange(isDefined(model[0]) ? model[0] : null);
      this.changeEvent.emit(selected[0]);
    }
    this._cd.markForCheck();
  }
  _clearSearch() {
    if (!this.searchTerm) {
      return;
    }
    this._changeSearch(null);
    this.itemsList.resetFilteredItems();
  }
  _changeSearch(searchTerm) {
    this.searchTerm = searchTerm;
    if (this._isTypeahead) {
      this.typeahead.next(searchTerm);
    }
  }
  _scrollToMarked() {
    if (!this.isOpen || !this.dropdownPanel) {
      return;
    }
    this.dropdownPanel.scrollTo(this.itemsList.markedItem);
  }
  _scrollToTag() {
    if (!this.isOpen || !this.dropdownPanel) {
      return;
    }
    this.dropdownPanel.scrollToTag();
  }
  _onSelectionChanged() {
    if (this.isOpen && this.deselectOnClick && this.appendTo) {
      // Make sure items are rendered.
      this._cd.detectChanges();
      this.dropdownPanel.adjustPosition();
    }
  }
  _handleTab($event) {
    if (this.isOpen === false) {
      if (this.showClear()) {
        this.focusOnClear();
        $event.preventDefault();
      } else if (!this.addTag) {
        return;
      }
    }
    if (this.selectOnTab) {
      if (this.itemsList.markedItem) {
        this.toggleItem(this.itemsList.markedItem);
        $event.preventDefault();
      } else if (this.showAddTag) {
        this.selectTag();
        $event.preventDefault();
      } else {
        this.close();
      }
    } else {
      this.close();
    }
  }
  _handleEnter($event) {
    if (this.isOpen || this._manualOpen) {
      if (this.itemsList.markedItem) {
        this.toggleItem(this.itemsList.markedItem);
      } else if (this.showAddTag) {
        this.selectTag();
      }
    } else if (this.openOnEnter) {
      this.open();
    } else {
      return;
    }
    $event.preventDefault();
  }
  _handleSpace($event) {
    if (this.isOpen || this._manualOpen) {
      return;
    }
    this.open();
    $event.preventDefault();
  }
  _handleArrowDown($event) {
    if (this._nextItemIsTag(+1)) {
      this.itemsList.unmarkItem();
      this._scrollToTag();
    } else {
      this.itemsList.markNextItem();
      this._scrollToMarked();
    }
    this.open();
    $event.preventDefault();
  }
  _handleArrowUp($event) {
    if (!this.isOpen) {
      return;
    }
    if (this._nextItemIsTag(-1)) {
      this.itemsList.unmarkItem();
      this._scrollToTag();
    } else {
      this.itemsList.markPreviousItem();
      this._scrollToMarked();
    }
    $event.preventDefault();
  }
  _nextItemIsTag(nextStep) {
    const nextIndex = this.itemsList.markedIndex + nextStep;
    return this.addTag && this.searchTerm && this.itemsList.markedItem && (nextIndex < 0 || nextIndex === this.itemsList.filteredItems.length);
  }
  _handleBackspace() {
    if (this.searchTerm || !this.clearable || !this.clearOnBackspace || !this.hasValue) {
      return;
    }
    if (this.multiple) {
      this.unselect(this.itemsList.lastSelectedItem);
    } else {
      this.clearModel();
    }
  }
  get _isTypeahead() {
    return this.typeahead && this.typeahead.observers.length > 0;
  }
  get _validTerm() {
    const term = this.searchTerm && this.searchTerm.trim();
    return term && term.length >= this.minTermLength;
  }
  _mergeGlobalConfig(config) {
    this.placeholder = this.placeholder || config.placeholder;
    this.notFoundText = this.notFoundText || config.notFoundText;
    this.typeToSearchText = this.typeToSearchText || config.typeToSearchText;
    this.addTagText = this.addTagText || config.addTagText;
    this.loadingText = this.loadingText || config.loadingText;
    this.clearAllText = this.clearAllText || config.clearAllText;
    this.virtualScroll = isDefined(this.virtualScroll) ? this.virtualScroll : isDefined(config.disableVirtualScroll) ? !config.disableVirtualScroll : false;
    this.openOnEnter = isDefined(this.openOnEnter) ? this.openOnEnter : config.openOnEnter;
    this.appendTo = this.appendTo || config.appendTo;
    this.bindValue = this.bindValue || config.bindValue;
    this.bindLabel = this.bindLabel || config.bindLabel;
    this.appearance = this.appearance || config.appearance;
  }
  static {
    this.ɵfac = function NgSelectComponent_Factory(t) {
      return new (t || NgSelectComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('class'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinjectAttribute"]('autofocus'), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](NgSelectConfig), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](SELECTION_MODEL_FACTORY), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](ConsoleService));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
      type: NgSelectComponent,
      selectors: [["ng-select"]],
      contentQueries: function NgSelectComponent_ContentQueries(rf, ctx, dirIndex) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgOptionTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgOptgroupTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgLabelTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgMultiLabelTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgHeaderTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgFooterTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgNotFoundTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgTypeToSearchTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgLoadingTextTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgTagTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgLoadingSpinnerTemplateDirective, 5, _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, NgOptionComponent, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.optionTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.optgroupTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.labelTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.multiLabelTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.headerTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.footerTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.notFoundTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.typeToSearchTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.loadingTextTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.tagTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.loadingSpinnerTemplate = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.ngOptions = _t);
        }
      },
      viewQuery: function NgSelectComponent_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](NgDropdownPanelComponent, 5);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c5, 7);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵviewQuery"](_c6, 5);
        }
        if (rf & 2) {
          let _t;
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.dropdownPanel = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.searchInput = _t.first);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.clearButton = _t.first);
        }
      },
      hostVars: 20,
      hostBindings: function NgSelectComponent_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("keydown", function NgSelectComponent_keydown_HostBindingHandler($event) {
            return ctx.handleKeyDown($event);
          });
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-select-typeahead", ctx.typeahead)("ng-select-multiple", ctx.multiple)("ng-select-taggable", ctx.addTag)("ng-select-searchable", ctx.searchable)("ng-select-clearable", ctx.clearable)("ng-select-opened", ctx.isOpen)("ng-select", ctx.useDefaultClass)("ng-select-disabled", ctx.disabled)("ng-select-filtered", ctx.filtered)("ng-select-single", ctx.single);
        }
      },
      inputs: {
        bindLabel: "bindLabel",
        bindValue: "bindValue",
        markFirst: "markFirst",
        placeholder: "placeholder",
        notFoundText: "notFoundText",
        typeToSearchText: "typeToSearchText",
        addTagText: "addTagText",
        loadingText: "loadingText",
        clearAllText: "clearAllText",
        appearance: "appearance",
        dropdownPosition: "dropdownPosition",
        appendTo: "appendTo",
        loading: "loading",
        closeOnSelect: "closeOnSelect",
        hideSelected: "hideSelected",
        selectOnTab: "selectOnTab",
        openOnEnter: "openOnEnter",
        maxSelectedItems: "maxSelectedItems",
        groupBy: "groupBy",
        groupValue: "groupValue",
        bufferAmount: "bufferAmount",
        virtualScroll: "virtualScroll",
        selectableGroup: "selectableGroup",
        selectableGroupAsModel: "selectableGroupAsModel",
        searchFn: "searchFn",
        trackByFn: "trackByFn",
        clearOnBackspace: "clearOnBackspace",
        labelForId: "labelForId",
        inputAttrs: "inputAttrs",
        tabIndex: "tabIndex",
        readonly: "readonly",
        searchWhileComposing: "searchWhileComposing",
        minTermLength: "minTermLength",
        editableSearchTerm: "editableSearchTerm",
        keyDownFn: "keyDownFn",
        typeahead: "typeahead",
        multiple: "multiple",
        addTag: "addTag",
        searchable: "searchable",
        clearable: "clearable",
        isOpen: "isOpen",
        items: "items",
        compareWith: "compareWith",
        clearSearchOnAdd: "clearSearchOnAdd",
        deselectOnClick: "deselectOnClick"
      },
      outputs: {
        blurEvent: "blur",
        focusEvent: "focus",
        changeEvent: "change",
        openEvent: "open",
        closeEvent: "close",
        searchEvent: "search",
        clearEvent: "clear",
        addEvent: "add",
        removeEvent: "remove",
        scroll: "scroll",
        scrollToEnd: "scrollToEnd"
      },
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_14__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgSelectComponent),
        multi: true
      }, NgDropdownPanelService]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
      decls: 14,
      vars: 19,
      consts: [["searchInput", ""], ["defaultLabelTemplate", ""], ["defaultLoadingSpinnerTemplate", ""], ["clearButton", ""], ["defaultOptionTemplate", ""], ["defaultTagTemplate", ""], ["defaultNotFoundTemplate", ""], ["defaultTypeToSearchTemplate", ""], ["defaultLoadingTextTemplate", ""], [1, "ng-select-container", 3, "mousedown"], [1, "ng-value-container"], [1, "ng-placeholder"], [4, "ngIf"], ["role", "combobox", "aria-haspopup", "listbox", 1, "ng-input"], ["aria-autocomplete", "list", 3, "input", "compositionstart", "compositionend", "focus", "blur", "change", "readOnly", "disabled", "value"], ["class", "ng-clear-wrapper", "tabindex", "0", 3, "title", 4, "ngIf"], [1, "ng-arrow-wrapper"], [1, "ng-arrow"], ["class", "ng-dropdown-panel", "role", "listbox", "aria-label", "Options list", 3, "virtualScroll", "bufferAmount", "appendTo", "position", "headerTemplate", "footerTemplate", "filterValue", "items", "markedItem", "ng-select-multiple", "ngClass", "id", "update", "scroll", "scrollToEnd", "outsideClick", 4, "ngIf"], ["class", "ng-value", 3, "ng-value-disabled", 4, "ngFor", "ngForOf", "ngForTrackBy"], [1, "ng-value"], [3, "ngTemplateOutlet", "ngTemplateOutletContext"], ["aria-hidden", "true", 1, "ng-value-icon", "left", 3, "click"], [1, "ng-value-label", 3, "ngItemLabel", "escape"], [3, "ngTemplateOutlet"], [1, "ng-spinner-loader"], ["tabindex", "0", 1, "ng-clear-wrapper", 3, "title"], ["aria-hidden", "true", 1, "ng-clear"], ["role", "listbox", "aria-label", "Options list", 1, "ng-dropdown-panel", 3, "update", "scroll", "scrollToEnd", "outsideClick", "virtualScroll", "bufferAmount", "appendTo", "position", "headerTemplate", "footerTemplate", "filterValue", "items", "markedItem", "ngClass", "id"], ["class", "ng-option", 3, "ng-option-disabled", "ng-option-selected", "ng-optgroup", "ng-option", "ng-option-child", "ng-option-marked", "click", "mouseover", 4, "ngFor", "ngForOf", "ngForTrackBy"], ["class", "ng-option", "role", "option", 3, "ng-option-marked", "mouseover", "click", 4, "ngIf"], [1, "ng-option", 3, "click", "mouseover"], [1, "ng-option-label", 3, "ngItemLabel", "escape"], ["role", "option", 1, "ng-option", 3, "mouseover", "click"], [1, "ng-tag-label"], [1, "ng-option", "ng-option-disabled"]],
      template: function NgSelectComponent_Template(rf, ctx) {
        if (rf & 1) {
          const _r1 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetCurrentView"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](0, "div", 9);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("mousedown", function NgSelectComponent_Template_div_mousedown_0_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.handleMousedown($event));
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](1, "div", 10)(2, "div", 11);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtext"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](4, NgSelectComponent_ng_container_4_Template, 2, 2, "ng-container", 12)(5, NgSelectComponent_5_Template, 1, 5, null, 12);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](6, "div", 13)(7, "input", 14, 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("input", function NgSelectComponent_Template_input_input_7_listener() {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            const searchInput_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](8);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.filter(searchInput_r6.value));
          })("compositionstart", function NgSelectComponent_Template_input_compositionstart_7_listener() {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.onCompositionStart());
          })("compositionend", function NgSelectComponent_Template_input_compositionend_7_listener() {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            const searchInput_r6 = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵreference"](8);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.onCompositionEnd(searchInput_r6.value));
          })("focus", function NgSelectComponent_Template_input_focus_7_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.onInputFocus($event));
          })("blur", function NgSelectComponent_Template_input_blur_7_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"](ctx.onInputBlur($event));
          })("change", function NgSelectComponent_Template_input_change_7_listener($event) {
            _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵrestoreView"](_r1);
            return _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵresetView"]($event.stopPropagation());
          });
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()()();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](9, NgSelectComponent_ng_container_9_Template, 4, 1, "ng-container", 12)(10, NgSelectComponent_span_10_Template, 4, 1, "span", 15);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementStart"](11, "span", 16);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelement"](12, "span", 17);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵelementEnd"]()();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtemplate"](13, NgSelectComponent_ng_dropdown_panel_13_Template, 7, 19, "ng-dropdown-panel", 18);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵclassProp"]("ng-appearance-outline", ctx.appearance === "outline")("ng-has-value", ctx.hasValue);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵtextInterpolate"](ctx.placeholder);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", (!ctx.multiLabelTemplate || !ctx.multiple) && ctx.selectedItems.length > 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.multiple && ctx.multiLabelTemplate && ctx.selectedValues.length > 0);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("aria-expanded", ctx.isOpen)("aria-owns", ctx.isOpen ? ctx.dropdownId : null);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("readOnly", !ctx.searchable || ctx.itemsList.maxItemsSelected)("disabled", ctx.disabled)("value", ctx.searchTerm ? ctx.searchTerm : "");
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("id", ctx.labelForId)("tabindex", ctx.tabIndex)("aria-activedescendant", ctx.isOpen ? ctx.itemsList == null ? null : ctx.itemsList.markedItem == null ? null : ctx.itemsList.markedItem.htmlId : null)("aria-controls", ctx.isOpen ? ctx.dropdownId : null);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](2);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.loading);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.showClear());
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵadvance"](3);
          _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵproperty"]("ngIf", ctx.isOpen);
        }
      },
      dependencies: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.NgClass, _angular_common__WEBPACK_IMPORTED_MODULE_8__.NgForOf, _angular_common__WEBPACK_IMPORTED_MODULE_8__.NgIf, _angular_common__WEBPACK_IMPORTED_MODULE_8__.NgTemplateOutlet, NgDropdownPanelComponent, NgItemLabelDirective],
      styles: ["@charset \"UTF-8\";.ng-select{position:relative;display:block;box-sizing:border-box}.ng-select div,.ng-select input,.ng-select span{box-sizing:border-box}.ng-select [hidden]{display:none}.ng-select.ng-select-searchable .ng-select-container .ng-value-container .ng-input{opacity:1}.ng-select.ng-select-opened .ng-select-container{z-index:1001}.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-placeholder,.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-value{-webkit-user-select:none;user-select:none;cursor:default}.ng-select.ng-select-disabled .ng-arrow-wrapper{cursor:default}.ng-select.ng-select-filtered .ng-placeholder{display:none}.ng-select .ng-select-container{cursor:default;display:flex;outline:none;overflow:hidden;position:relative;width:100%}.ng-select .ng-select-container .ng-value-container{display:flex;flex:1}.ng-select .ng-select-container .ng-value-container .ng-input{opacity:0}.ng-select .ng-select-container .ng-value-container .ng-input>input{box-sizing:content-box;background:none transparent;border:0 none;box-shadow:none;outline:none;padding:0;cursor:default;width:100%}.ng-select .ng-select-container .ng-value-container .ng-input>input::-ms-clear{display:none}.ng-select .ng-select-container .ng-value-container .ng-input>input[readonly]{-webkit-user-select:none;user-select:none;width:0;padding:0}.ng-select.ng-select-single.ng-select-filtered .ng-select-container .ng-value-container .ng-value{visibility:hidden}.ng-select.ng-select-single .ng-select-container .ng-value-container,.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{position:absolute;left:0;width:100%}.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container{flex-wrap:wrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{position:absolute}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{white-space:nowrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon{cursor:pointer}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input{flex:1;z-index:2}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{z-index:1}.ng-select .ng-clear-wrapper{cursor:pointer;position:relative;width:17px;-webkit-user-select:none;user-select:none}.ng-select .ng-clear-wrapper .ng-clear{display:inline-block;font-size:18px;line-height:1;pointer-events:none}.ng-select .ng-spinner-loader{border-radius:50%;width:17px;height:17px;margin-right:5px;font-size:10px;position:relative;text-indent:-9999em;border-top:2px solid rgba(66,66,66,.2);border-right:2px solid rgba(66,66,66,.2);border-bottom:2px solid rgba(66,66,66,.2);border-left:2px solid #424242;transform:translateZ(0);animation:load8 .8s infinite linear}.ng-select .ng-spinner-loader:after{border-radius:50%;width:17px;height:17px}@keyframes load8{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ng-select .ng-arrow-wrapper{cursor:pointer;position:relative;text-align:center;-webkit-user-select:none;user-select:none}.ng-select .ng-arrow-wrapper .ng-arrow{pointer-events:none;display:inline-block;height:0;width:0;position:relative}.ng-dropdown-panel{box-sizing:border-box;position:absolute;opacity:0;width:100%;z-index:1050;-webkit-overflow-scrolling:touch}.ng-dropdown-panel .ng-dropdown-panel-items{display:block;height:auto;box-sizing:border-box;max-height:240px;overflow-y:auto}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{box-sizing:border-box;cursor:pointer;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-option-label:empty:before{content:\"\\200b\"}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .highlighted{font-weight:700;text-decoration:underline}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.disabled{cursor:default}.ng-dropdown-panel .scroll-host{overflow:hidden;overflow-y:auto;position:relative;display:block;-webkit-overflow-scrolling:touch}.ng-dropdown-panel .scrollable-content{top:0;left:0;width:100%;height:100%;position:absolute}.ng-dropdown-panel .total-padding{width:1px;opacity:0}\n"],
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSelectComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ng-select',
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_14__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgSelectComponent),
        multi: true
      }, NgDropdownPanelService],
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewEncapsulation.None,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectionStrategy.OnPush,
      template: "<div\n    (mousedown)=\"handleMousedown($event)\"\n    [class.ng-appearance-outline]=\"appearance === 'outline'\"\n    [class.ng-has-value]=\"hasValue\"\n    class=\"ng-select-container\">\n\n    <div class=\"ng-value-container\">\n        <div class=\"ng-placeholder\">{{placeholder}}</div>\n\n        <ng-container *ngIf=\"(!multiLabelTemplate  || !multiple ) && selectedItems.length > 0\">\n            <div [class.ng-value-disabled]=\"item.disabled\" class=\"ng-value\" *ngFor=\"let item of selectedItems; trackBy: trackByOption\">\n                <ng-template #defaultLabelTemplate>\n                    <span class=\"ng-value-icon left\" (click)=\"unselect(item);\" aria-hidden=\"true\">\u00D7</span>\n                    <span class=\"ng-value-label\" [ngItemLabel]=\"item.label\" [escape]=\"escapeHTML\"></span>\n                </ng-template>\n\n                <ng-template\n                    [ngTemplateOutlet]=\"labelTemplate || defaultLabelTemplate\"\n                    [ngTemplateOutletContext]=\"{ item: item.value, clear: clearItem, label: item.label }\">\n                </ng-template>\n            </div>\n        </ng-container>\n\n        <ng-template *ngIf=\"multiple && multiLabelTemplate && selectedValues.length > 0\"\n                [ngTemplateOutlet]=\"multiLabelTemplate\"\n                [ngTemplateOutletContext]=\"{ items: selectedValues, clear: clearItem }\">\n        </ng-template>\n\n        <div class=\"ng-input\"\n            role=\"combobox\" \n            [attr.aria-expanded]=\"isOpen\" \n            [attr.aria-owns]=\"isOpen ? dropdownId : null\" \n            aria-haspopup=\"listbox\">\n\n            <input #searchInput\n                   [attr.id]=\"labelForId\"\n                   [attr.tabindex]=\"tabIndex\"\n                   [readOnly]=\"!searchable || itemsList.maxItemsSelected\"\n                   [disabled]=\"disabled\"\n                   [value]=\"searchTerm ? searchTerm : ''\"\n                   (input)=\"filter(searchInput.value)\"\n                   (compositionstart)=\"onCompositionStart()\"\n                   (compositionend)=\"onCompositionEnd(searchInput.value)\"\n                   (focus)=\"onInputFocus($event)\"\n                   (blur)=\"onInputBlur($event)\"\n                   (change)=\"$event.stopPropagation()\"\n                   [attr.aria-activedescendant]=\"isOpen ? itemsList?.markedItem?.htmlId : null\"\n                   aria-autocomplete=\"list\"\n                   [attr.aria-controls]=\"isOpen ? dropdownId : null\">\n        </div>\n    </div>\n\n    <ng-container *ngIf=\"loading\">\n        <ng-template #defaultLoadingSpinnerTemplate>\n            <div class=\"ng-spinner-loader\"></div>\n        </ng-template>\n\n        <ng-template\n            [ngTemplateOutlet]=\"loadingSpinnerTemplate || defaultLoadingSpinnerTemplate\">\n        </ng-template>\n    </ng-container>\n\n    <span *ngIf=\"showClear()\" class=\"ng-clear-wrapper\" tabindex=\"0\" title=\"{{clearAllText}}\" #clearButton>\n        <span class=\"ng-clear\" aria-hidden=\"true\">\u00D7</span>\n    </span>\n\n    <span class=\"ng-arrow-wrapper\">\n        <span class=\"ng-arrow\"></span>\n    </span>\n</div>\n\n<ng-dropdown-panel *ngIf=\"isOpen\"\n                   class=\"ng-dropdown-panel\"\n                   [virtualScroll]=\"virtualScroll\"\n                   [bufferAmount]=\"bufferAmount\"\n                   [appendTo]=\"appendTo\"\n                   [position]=\"dropdownPosition\"\n                   [headerTemplate]=\"headerTemplate\"\n                   [footerTemplate]=\"footerTemplate\"\n                   [filterValue]=\"searchTerm\"\n                   [items]=\"itemsList.filteredItems\"\n                   [markedItem]=\"itemsList.markedItem\"\n                   (update)=\"viewPortItems = $event\"\n                   (scroll)=\"scroll.emit($event)\"\n                   (scrollToEnd)=\"scrollToEnd.emit($event)\"\n                   (outsideClick)=\"close()\"\n                   [class.ng-select-multiple]=\"multiple\"\n                   [ngClass]=\"appendTo ? classes : null\"\n                   [id]=\"dropdownId\"\n                   role=\"listbox\"\n                   aria-label=\"Options list\">\n\n    <ng-container>\n        <div class=\"ng-option\" [attr.role]=\"item.children ? 'group' : 'option'\" (click)=\"toggleItem(item)\" (mouseover)=\"onItemHover(item)\"\n                *ngFor=\"let item of viewPortItems; trackBy: trackByOption\"\n                [class.ng-option-disabled]=\"item.disabled\"\n                [class.ng-option-selected]=\"item.selected\"\n                [class.ng-optgroup]=\"item.children\"\n                [class.ng-option]=\"!item.children\"\n                [class.ng-option-child]=\"!!item.parent\"\n                [class.ng-option-marked]=\"item === itemsList.markedItem\"\n                [attr.aria-selected]=\"item.selected\"\n                [attr.id]=\"item?.htmlId\">\n\n            <ng-template #defaultOptionTemplate>\n                <span class=\"ng-option-label\" [ngItemLabel]=\"item.label\" [escape]=\"escapeHTML\"></span>\n            </ng-template>\n\n            <ng-template\n                [ngTemplateOutlet]=\"item.children ? (optgroupTemplate || defaultOptionTemplate) : (optionTemplate || defaultOptionTemplate)\"\n                [ngTemplateOutletContext]=\"{ item: item.value, item$:item, index: item.index, searchTerm: searchTerm }\">\n            </ng-template>\n        </div>\n\n        <div class=\"ng-option\" [class.ng-option-marked]=\"!itemsList.markedItem\" (mouseover)=\"itemsList.unmarkItem()\" role=\"option\" (click)=\"selectTag()\" *ngIf=\"showAddTag\">\n            <ng-template #defaultTagTemplate>\n                <span><span class=\"ng-tag-label\">{{addTagText}}</span>\"{{searchTerm}}\"</span>\n            </ng-template>\n\n            <ng-template\n                [ngTemplateOutlet]=\"tagTemplate || defaultTagTemplate\"\n                [ngTemplateOutletContext]=\"{ searchTerm: searchTerm }\">\n            </ng-template>\n        </div>\n    </ng-container>\n\n    <ng-container *ngIf=\"showNoItemsFound()\">\n        <ng-template #defaultNotFoundTemplate>\n            <div class=\"ng-option ng-option-disabled\">{{notFoundText}}</div>\n        </ng-template>\n\n        <ng-template\n            [ngTemplateOutlet]=\"notFoundTemplate || defaultNotFoundTemplate\"\n            [ngTemplateOutletContext]=\"{ searchTerm: searchTerm }\">\n        </ng-template>\n    </ng-container>\n\n    <ng-container *ngIf=\"showTypeToSearch()\">\n        <ng-template #defaultTypeToSearchTemplate>\n            <div class=\"ng-option ng-option-disabled\">{{typeToSearchText}}</div>\n        </ng-template>\n\n        <ng-template\n            [ngTemplateOutlet]=\"typeToSearchTemplate || defaultTypeToSearchTemplate\">\n        </ng-template>\n    </ng-container>\n\n    <ng-container *ngIf=\"loading && itemsList.filteredItems.length === 0\">\n        <ng-template #defaultLoadingTextTemplate>\n            <div class=\"ng-option ng-option-disabled\">{{loadingText}}</div>\n        </ng-template>\n\n        <ng-template\n            [ngTemplateOutlet]=\"loadingTextTemplate || defaultLoadingTextTemplate\"\n            [ngTemplateOutletContext]=\"{ searchTerm: searchTerm }\">\n        </ng-template>\n    </ng-container>\n\n</ng-dropdown-panel>\n",
      styles: ["@charset \"UTF-8\";.ng-select{position:relative;display:block;box-sizing:border-box}.ng-select div,.ng-select input,.ng-select span{box-sizing:border-box}.ng-select [hidden]{display:none}.ng-select.ng-select-searchable .ng-select-container .ng-value-container .ng-input{opacity:1}.ng-select.ng-select-opened .ng-select-container{z-index:1001}.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-placeholder,.ng-select.ng-select-disabled .ng-select-container .ng-value-container .ng-value{-webkit-user-select:none;user-select:none;cursor:default}.ng-select.ng-select-disabled .ng-arrow-wrapper{cursor:default}.ng-select.ng-select-filtered .ng-placeholder{display:none}.ng-select .ng-select-container{cursor:default;display:flex;outline:none;overflow:hidden;position:relative;width:100%}.ng-select .ng-select-container .ng-value-container{display:flex;flex:1}.ng-select .ng-select-container .ng-value-container .ng-input{opacity:0}.ng-select .ng-select-container .ng-value-container .ng-input>input{box-sizing:content-box;background:none transparent;border:0 none;box-shadow:none;outline:none;padding:0;cursor:default;width:100%}.ng-select .ng-select-container .ng-value-container .ng-input>input::-ms-clear{display:none}.ng-select .ng-select-container .ng-value-container .ng-input>input[readonly]{-webkit-user-select:none;user-select:none;width:0;padding:0}.ng-select.ng-select-single.ng-select-filtered .ng-select-container .ng-value-container .ng-value{visibility:hidden}.ng-select.ng-select-single .ng-select-container .ng-value-container,.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-single .ng-select-container .ng-value-container .ng-input{position:absolute;left:0;width:100%}.ng-select.ng-select-multiple.ng-select-disabled>.ng-select-container .ng-value-container .ng-value .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container{flex-wrap:wrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{position:absolute}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value{white-space:nowrap}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value.ng-value-disabled .ng-value-icon{display:none}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-value .ng-value-icon{cursor:pointer}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-input{flex:1;z-index:2}.ng-select.ng-select-multiple .ng-select-container .ng-value-container .ng-placeholder{z-index:1}.ng-select .ng-clear-wrapper{cursor:pointer;position:relative;width:17px;-webkit-user-select:none;user-select:none}.ng-select .ng-clear-wrapper .ng-clear{display:inline-block;font-size:18px;line-height:1;pointer-events:none}.ng-select .ng-spinner-loader{border-radius:50%;width:17px;height:17px;margin-right:5px;font-size:10px;position:relative;text-indent:-9999em;border-top:2px solid rgba(66,66,66,.2);border-right:2px solid rgba(66,66,66,.2);border-bottom:2px solid rgba(66,66,66,.2);border-left:2px solid #424242;transform:translateZ(0);animation:load8 .8s infinite linear}.ng-select .ng-spinner-loader:after{border-radius:50%;width:17px;height:17px}@keyframes load8{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.ng-select .ng-arrow-wrapper{cursor:pointer;position:relative;text-align:center;-webkit-user-select:none;user-select:none}.ng-select .ng-arrow-wrapper .ng-arrow{pointer-events:none;display:inline-block;height:0;width:0;position:relative}.ng-dropdown-panel{box-sizing:border-box;position:absolute;opacity:0;width:100%;z-index:1050;-webkit-overflow-scrolling:touch}.ng-dropdown-panel .ng-dropdown-panel-items{display:block;height:auto;box-sizing:border-box;max-height:240px;overflow-y:auto}.ng-dropdown-panel .ng-dropdown-panel-items .ng-optgroup{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option{box-sizing:border-box;cursor:pointer;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .ng-option-label:empty:before{content:\"\\200b\"}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option .highlighted{font-weight:700;text-decoration:underline}.ng-dropdown-panel .ng-dropdown-panel-items .ng-option.disabled{cursor:default}.ng-dropdown-panel .scroll-host{overflow:hidden;overflow-y:auto;position:relative;display:block;-webkit-overflow-scrolling:touch}.ng-dropdown-panel .scrollable-content{top:0;left:0;width:100%;height:100%;position:absolute}.ng-dropdown-panel .total-padding{width:1px;opacity:0}\n"]
    }]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['class']
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Attribute,
      args: ['autofocus']
    }]
  }, {
    type: NgSelectConfig
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [SELECTION_MODEL_FACTORY]
    }]
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ChangeDetectorRef
  }, {
    type: ConsoleService
  }], {
    bindLabel: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    bindValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    markFirst: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    placeholder: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    notFoundText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    typeToSearchText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    addTagText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    loadingText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    clearAllText: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    appearance: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dropdownPosition: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    appendTo: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    loading: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    closeOnSelect: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    hideSelected: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectOnTab: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    openOnEnter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    maxSelectedItems: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    groupBy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    groupValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    bufferAmount: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    virtualScroll: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectableGroup: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    selectableGroupAsModel: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    searchFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    trackByFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    clearOnBackspace: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    labelForId: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    inputAttrs: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    tabIndex: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    readonly: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    searchWhileComposing: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    minTermLength: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    editableSearchTerm: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    keyDownFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    typeahead: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-typeahead']
    }],
    multiple: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-multiple']
    }],
    addTag: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-taggable']
    }],
    searchable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-searchable']
    }],
    clearable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-clearable']
    }],
    isOpen: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-opened']
    }],
    items: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    compareWith: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    clearSearchOnAdd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    deselectOnClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    blurEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['blur']
    }],
    focusEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['focus']
    }],
    changeEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['change']
    }],
    openEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['open']
    }],
    closeEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['close']
    }],
    searchEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['search']
    }],
    clearEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['clear']
    }],
    addEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['add']
    }],
    removeEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['remove']
    }],
    scroll: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['scroll']
    }],
    scrollToEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output,
      args: ['scrollToEnd']
    }],
    optionTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgOptionTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    optgroupTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgOptgroupTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    labelTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgLabelTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    multiLabelTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgMultiLabelTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    headerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgHeaderTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    footerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgFooterTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    notFoundTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgNotFoundTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    typeToSearchTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgTypeToSearchTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    loadingTextTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgLoadingTextTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    tagTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgTagTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    loadingSpinnerTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [NgLoadingSpinnerTemplateDirective, {
        read: _angular_core__WEBPACK_IMPORTED_MODULE_0__.TemplateRef
      }]
    }],
    dropdownPanel: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: [(0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => NgDropdownPanelComponent)]
    }],
    searchInput: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['searchInput', {
        static: true
      }]
    }],
    clearButton: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ViewChild,
      args: ['clearButton']
    }],
    ngOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChildren,
      args: [NgOptionComponent, {
        descendants: true
      }]
    }],
    useDefaultClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select']
    }],
    disabled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-disabled']
    }],
    filtered: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-filtered']
    }],
    single: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['class.ng-select-single']
    }],
    handleKeyDown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['keydown', ['$event']]
    }]
  });
})();
function DefaultSelectionModelFactory() {
  return new DefaultSelectionModel();
}
class DefaultSelectionModel {
  constructor() {
    this._selected = [];
  }
  get value() {
    return this._selected;
  }
  select(item, multiple, groupAsModel) {
    item.selected = true;
    if (!item.children || !multiple && groupAsModel) {
      this._selected.push(item);
    }
    if (multiple) {
      if (item.parent) {
        const childrenCount = item.parent.children.length;
        const selectedCount = item.parent.children.filter(x => x.selected).length;
        item.parent.selected = childrenCount === selectedCount;
      } else if (item.children) {
        this._setChildrenSelectedState(item.children, true);
        this._removeChildren(item);
        if (groupAsModel && this._activeChildren(item)) {
          this._selected = [...this._selected.filter(x => x.parent !== item), item];
        } else {
          this._selected = [...this._selected, ...item.children.filter(x => !x.disabled)];
        }
      }
    }
  }
  unselect(item, multiple) {
    this._selected = this._selected.filter(x => x !== item);
    item.selected = false;
    if (multiple) {
      if (item.parent && item.parent.selected) {
        const children = item.parent.children;
        this._removeParent(item.parent);
        this._removeChildren(item.parent);
        this._selected.push(...children.filter(x => x !== item && !x.disabled));
        item.parent.selected = false;
      } else if (item.children) {
        this._setChildrenSelectedState(item.children, false);
        this._removeChildren(item);
      }
    }
  }
  clear(keepDisabled) {
    this._selected = keepDisabled ? this._selected.filter(x => x.disabled) : [];
  }
  _setChildrenSelectedState(children, selected) {
    for (const child of children) {
      if (child.disabled) {
        continue;
      }
      child.selected = selected;
    }
  }
  _removeChildren(parent) {
    this._selected = [...this._selected.filter(x => x.parent !== parent), ...parent.children.filter(x => x.parent === parent && x.disabled && x.selected)];
  }
  _removeParent(parent) {
    this._selected = this._selected.filter(x => x !== parent);
  }
  _activeChildren(item) {
    return item.children.every(x => !x.disabled || x.selected);
  }
}
class NgSelectModule {
  static {
    this.ɵfac = function NgSelectModule_Factory(t) {
      return new (t || NgSelectModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: NgSelectModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
      providers: [{
        provide: SELECTION_MODEL_FACTORY,
        useValue: DefaultSelectionModelFactory
      }],
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.CommonModule]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgSelectModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: [NgDropdownPanelComponent, NgOptionComponent, NgSelectComponent, NgOptgroupTemplateDirective, NgOptionTemplateDirective, NgLabelTemplateDirective, NgMultiLabelTemplateDirective, NgHeaderTemplateDirective, NgFooterTemplateDirective, NgNotFoundTemplateDirective, NgTypeToSearchTemplateDirective, NgLoadingTextTemplateDirective, NgTagTemplateDirective, NgLoadingSpinnerTemplateDirective, NgItemLabelDirective],
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_8__.CommonModule],
      exports: [NgSelectComponent, NgOptionComponent, NgOptgroupTemplateDirective, NgOptionTemplateDirective, NgLabelTemplateDirective, NgMultiLabelTemplateDirective, NgHeaderTemplateDirective, NgFooterTemplateDirective, NgNotFoundTemplateDirective, NgTypeToSearchTemplateDirective, NgLoadingTextTemplateDirective, NgTagTemplateDirective, NgLoadingSpinnerTemplateDirective],
      providers: [{
        provide: SELECTION_MODEL_FACTORY,
        useValue: DefaultSelectionModelFactory
      }]
    }]
  }], null, null);
})();

/*
 * Public API Surface of ng-select
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 70347:
/*!**************************************************************!*\
  !*** ./node_modules/@ngrx/effects/fesm2022/ngrx-effects.mjs ***!
  \**************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   Actions: () => (/* binding */ Actions),
/* harmony export */   EFFECTS_ERROR_HANDLER: () => (/* binding */ EFFECTS_ERROR_HANDLER),
/* harmony export */   EffectSources: () => (/* binding */ EffectSources),
/* harmony export */   EffectsFeatureModule: () => (/* binding */ EffectsFeatureModule),
/* harmony export */   EffectsModule: () => (/* binding */ EffectsModule),
/* harmony export */   EffectsRootModule: () => (/* binding */ EffectsRootModule),
/* harmony export */   EffectsRunner: () => (/* binding */ EffectsRunner),
/* harmony export */   ROOT_EFFECTS_INIT: () => (/* binding */ ROOT_EFFECTS_INIT),
/* harmony export */   USER_PROVIDED_EFFECTS: () => (/* binding */ USER_PROVIDED_EFFECTS),
/* harmony export */   act: () => (/* binding */ act),
/* harmony export */   concatLatestFrom: () => (/* binding */ concatLatestFrom),
/* harmony export */   createEffect: () => (/* binding */ createEffect),
/* harmony export */   defaultEffectsErrorHandler: () => (/* binding */ defaultEffectsErrorHandler),
/* harmony export */   getEffectsMetadata: () => (/* binding */ getEffectsMetadata),
/* harmony export */   mergeEffects: () => (/* binding */ mergeEffects),
/* harmony export */   ofType: () => (/* binding */ ofType),
/* harmony export */   provideEffects: () => (/* binding */ provideEffects),
/* harmony export */   rootEffectsInit: () => (/* binding */ rootEffectsInit)
/* harmony export */ });
/* harmony import */ var _ngrx_operators__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! @ngrx/operators */ 72743);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs */ 137);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs/operators */ 7242);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 79176);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 61318);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 78615);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 13255);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 67953);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs/operators */ 6449);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs/operators */ 89475);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _ngrx_store__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @ngrx/store */ 81383);








const DEFAULT_EFFECT_CONFIG = {
  dispatch: true,
  functional: false,
  useEffectsErrorHandler: true
};
const CREATE_EFFECT_METADATA_KEY = '__@ngrx/effects_create__';

/**
 * @description
 *
 * Creates an effect from a source and an `EffectConfig`.
 *
 * @param source A function which returns an observable or observable factory.
 * @param config A `EffectConfig` to configure the effect. By default,
 * `dispatch` is true, `functional` is false, and `useEffectsErrorHandler` is
 * true.
 * @returns If `EffectConfig`#`functional` is true, returns the source function.
 * Else, returns the source function result. When `EffectConfig`#`dispatch` is
 * true, the source function result needs to be `Observable<Action>`.
 *
 * @usageNotes
 *
 * ### Class Effects
 *
 * ```ts
 * @Injectable()
 * export class FeatureEffects {
 *   // mapping to a different action
 *   readonly effect1$ = createEffect(
 *     () => this.actions$.pipe(
 *       ofType(FeatureActions.actionOne),
 *       map(() => FeatureActions.actionTwo())
 *     )
 *   );
 *
 *   // non-dispatching effect
 *   readonly effect2$ = createEffect(
 *     () => this.actions$.pipe(
 *       ofType(FeatureActions.actionTwo),
 *       tap(() => console.log('Action Two Dispatched'))
 *     ),
 *     { dispatch: false } // FeatureActions.actionTwo is not dispatched
 *   );
 *
 *   constructor(private readonly actions$: Actions) {}
 * }
 * ```
 *
 * ### Functional Effects
 *
 * ```ts
 * // mapping to a different action
 * export const loadUsers = createEffect(
 *   (actions$ = inject(Actions), usersService = inject(UsersService)) => {
 *     return actions$.pipe(
 *       ofType(UsersPageActions.opened),
 *       exhaustMap(() => {
 *         return usersService.getAll().pipe(
 *           map((users) => UsersApiActions.usersLoadedSuccess({ users })),
 *           catchError((error) =>
 *             of(UsersApiActions.usersLoadedFailure({ error }))
 *           )
 *         );
 *       })
 *     );
 *   },
 *   { functional: true }
 * );
 *
 * // non-dispatching functional effect
 * export const logDispatchedActions = createEffect(
 *   () => inject(Actions).pipe(tap(console.log)),
 *   { functional: true, dispatch: false }
 * );
 * ```
 */
function createEffect(source, config = {}) {
  const effect = config.functional ? source : source();
  const value = {
    ...DEFAULT_EFFECT_CONFIG,
    ...config // Overrides any defaults if values are provided
  };
  Object.defineProperty(effect, CREATE_EFFECT_METADATA_KEY, {
    value
  });
  return effect;
}
function getCreateEffectMetadata(instance) {
  const propertyNames = Object.getOwnPropertyNames(instance);
  const metadata = propertyNames.filter(propertyName => {
    if (instance[propertyName] && instance[propertyName].hasOwnProperty(CREATE_EFFECT_METADATA_KEY)) {
      // If the property type has overridden `hasOwnProperty` we need to ensure
      // that the metadata is valid (containing a `dispatch` property)
      // https://github.com/ngrx/platform/issues/2975
      const property = instance[propertyName];
      return property[CREATE_EFFECT_METADATA_KEY].hasOwnProperty('dispatch');
    }
    return false;
  }).map(propertyName => {
    const metaData = instance[propertyName][CREATE_EFFECT_METADATA_KEY];
    return {
      propertyName,
      ...metaData
    };
  });
  return metadata;
}
function getEffectsMetadata(instance) {
  return getSourceMetadata(instance).reduce((acc, {
    propertyName,
    dispatch,
    useEffectsErrorHandler
  }) => {
    acc[propertyName] = {
      dispatch,
      useEffectsErrorHandler
    };
    return acc;
  }, {});
}
function getSourceMetadata(instance) {
  return getCreateEffectMetadata(instance);
}
function getSourceForInstance(instance) {
  return Object.getPrototypeOf(instance);
}
function isClassInstance(obj) {
  return !!obj.constructor && obj.constructor.name !== 'Object' && obj.constructor.name !== 'Function';
}
function isClass(classOrRecord) {
  return typeof classOrRecord === 'function';
}
function getClasses(classesAndRecords) {
  return classesAndRecords.filter(isClass);
}
function isToken(tokenOrRecord) {
  return tokenOrRecord instanceof _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken || isClass(tokenOrRecord);
}
function mergeEffects(sourceInstance, globalErrorHandler, effectsErrorHandler) {
  const source = getSourceForInstance(sourceInstance);
  const isClassBasedEffect = !!source && source.constructor.name !== 'Object';
  const sourceName = isClassBasedEffect ? source.constructor.name : null;
  const observables$ = getSourceMetadata(sourceInstance).map(({
    propertyName,
    dispatch,
    useEffectsErrorHandler
  }) => {
    const observable$ = typeof sourceInstance[propertyName] === 'function' ? sourceInstance[propertyName]() : sourceInstance[propertyName];
    const effectAction$ = useEffectsErrorHandler ? effectsErrorHandler(observable$, globalErrorHandler) : observable$;
    if (dispatch === false) {
      return effectAction$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_1__.ignoreElements)());
    }
    const materialized$ = effectAction$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.materialize)());
    return materialized$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(notification => ({
      effect: sourceInstance[propertyName],
      notification,
      propertyName,
      sourceName,
      sourceInstance
    })));
  });
  return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.merge)(...observables$);
}
const MAX_NUMBER_OF_RETRY_ATTEMPTS = 10;
function defaultEffectsErrorHandler(observable$, errorHandler, retryAttemptLeft = MAX_NUMBER_OF_RETRY_ATTEMPTS) {
  return observable$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.catchError)(error => {
    if (errorHandler) errorHandler.handleError(error);
    if (retryAttemptLeft <= 1) {
      return observable$; // last attempt
    }
    // Return observable that produces this particular effect
    return defaultEffectsErrorHandler(observable$, errorHandler, retryAttemptLeft - 1);
  }));
}
class Actions extends rxjs__WEBPACK_IMPORTED_MODULE_6__.Observable {
  constructor(source) {
    super();
    if (source) {
      this.source = source;
    }
  }
  lift(operator) {
    const observable = new Actions();
    observable.source = this;
    observable.operator = operator;
    return observable;
  }
  /** @nocollapse */
  static {
    this.ɵfac = function Actions_Factory(t) {
      return new (t || Actions)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.ScannedActionsSubject));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: Actions,
      factory: Actions.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](Actions, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: rxjs__WEBPACK_IMPORTED_MODULE_6__.Observable,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.ScannedActionsSubject]
    }]
  }], null);
})();
/**
 * `ofType` filters an Observable of `Actions` into an Observable of the actions
 * whose type strings are passed to it.
 *
 * For example, if `actions` has type `Actions<AdditionAction|SubstractionAction>`, and
 * the type of the `Addition` action is `add`, then
 * `actions.pipe(ofType('add'))` returns an `Observable<AdditionAction>`.
 *
 * Properly typing this function is hard and requires some advanced TS tricks
 * below.
 *
 * Type narrowing automatically works, as long as your `actions` object
 * starts with a `Actions<SomeUnionOfActions>` instead of generic `Actions`.
 *
 * For backwards compatibility, when one passes a single type argument
 * `ofType<T>('something')` the result is an `Observable<T>`. Note, that `T`
 * completely overrides any possible inference from 'something'.
 *
 * Unfortunately, for unknown 'actions: Actions' these types will produce
 * 'Observable<never>'. In such cases one has to manually set the generic type
 * like `actions.ofType<AdditionAction>('add')`.
 *
 * @usageNotes
 *
 * Filter the Actions stream on the "customers page loaded" action
 *
 * ```ts
 * import { ofType } from '@ngrx/effects';
 * import * fromCustomers from '../customers';
 *
 * this.actions$.pipe(
 *  ofType(fromCustomers.pageLoaded)
 * )
 * ```
 */
function ofType(...allowedTypes) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(action => allowedTypes.some(typeOrActionCreator => {
    if (typeof typeOrActionCreator === 'string') {
      // Comparing the string to type
      return typeOrActionCreator === action.type;
    }
    // We are filtering by ActionCreator
    return typeOrActionCreator.type === action.type;
  }));
}
const _ROOT_EFFECTS_GUARD = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Internal Root Guard');
const USER_PROVIDED_EFFECTS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects User Provided Effects');
const _ROOT_EFFECTS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Internal Root Effects');
const _ROOT_EFFECTS_INSTANCES = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Internal Root Effects Instances');
const _FEATURE_EFFECTS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Internal Feature Effects');
const _FEATURE_EFFECTS_INSTANCE_GROUPS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Internal Feature Effects Instance Groups');
const EFFECTS_ERROR_HANDLER = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/effects Effects Error Handler', {
  providedIn: 'root',
  factory: () => defaultEffectsErrorHandler
});
const ROOT_EFFECTS_INIT = '@ngrx/effects/init';
const rootEffectsInit = (0,_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.createAction)(ROOT_EFFECTS_INIT);
function reportInvalidActions(output, reporter) {
  if (output.notification.kind === 'N') {
    const action = output.notification.value;
    const isInvalidAction = !isAction(action);
    if (isInvalidAction) {
      reporter.handleError(new Error(`Effect ${getEffectName(output)} dispatched an invalid action: ${stringify(action)}`));
    }
  }
}
function isAction(action) {
  return typeof action !== 'function' && action && action.type && typeof action.type === 'string';
}
function getEffectName({
  propertyName,
  sourceInstance,
  sourceName
}) {
  const isMethod = typeof sourceInstance[propertyName] === 'function';
  const isClassBasedEffect = !!sourceName;
  return isClassBasedEffect ? `"${sourceName}.${String(propertyName)}${isMethod ? '()' : ''}"` : `"${String(propertyName)}()"`;
}
function stringify(action) {
  try {
    return JSON.stringify(action);
  } catch {
    return action;
  }
}
const onIdentifyEffectsKey = 'ngrxOnIdentifyEffects';
function isOnIdentifyEffects(instance) {
  return isFunction(instance, onIdentifyEffectsKey);
}
const onRunEffectsKey = 'ngrxOnRunEffects';
function isOnRunEffects(instance) {
  return isFunction(instance, onRunEffectsKey);
}
const onInitEffects = 'ngrxOnInitEffects';
function isOnInitEffects(instance) {
  return isFunction(instance, onInitEffects);
}
function isFunction(instance, functionName) {
  return instance && functionName in instance && typeof instance[functionName] === 'function';
}
class EffectSources extends rxjs__WEBPACK_IMPORTED_MODULE_9__.Subject {
  constructor(errorHandler, effectsErrorHandler) {
    super();
    this.errorHandler = errorHandler;
    this.effectsErrorHandler = effectsErrorHandler;
  }
  addEffects(effectSourceInstance) {
    this.next(effectSourceInstance);
  }
  /**
   * @internal
   */
  toActions() {
    return this.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.groupBy)(effectsInstance => isClassInstance(effectsInstance) ? getSourceForInstance(effectsInstance) : effectsInstance), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(source$ => {
      return source$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.groupBy)(effectsInstance));
    }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.mergeMap)(source$ => {
      const effect$ = source$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.exhaustMap)(sourceInstance => {
        return resolveEffectSource(this.errorHandler, this.effectsErrorHandler)(sourceInstance);
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(output => {
        reportInvalidActions(output, this.errorHandler);
        return output.notification;
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(notification => notification.kind === 'N' && notification.value != null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.dematerialize)());
      // start the stream with an INIT action
      // do this only for the first Effect instance
      const init$ = source$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.take)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(isOnInitEffects), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(instance => instance.ngrxOnInitEffects()));
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.merge)(effect$, init$);
    }));
  }
  /** @nocollapse */
  static {
    this.ɵfac = function EffectSources_Factory(t) {
      return new (t || EffectSources)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ErrorHandler), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](EFFECTS_ERROR_HANDLER));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: EffectSources,
      factory: EffectSources.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EffectSources, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ErrorHandler
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [EFFECTS_ERROR_HANDLER]
    }]
  }], null);
})();
function effectsInstance(sourceInstance) {
  if (isOnIdentifyEffects(sourceInstance)) {
    return sourceInstance.ngrxOnIdentifyEffects();
  }
  return '';
}
function resolveEffectSource(errorHandler, effectsErrorHandler) {
  return sourceInstance => {
    const mergedEffects$ = mergeEffects(sourceInstance, errorHandler, effectsErrorHandler);
    if (isOnRunEffects(sourceInstance)) {
      return sourceInstance.ngrxOnRunEffects(mergedEffects$);
    }
    return mergedEffects$;
  };
}
class EffectsRunner {
  get isStarted() {
    return !!this.effectsSubscription;
  }
  constructor(effectSources, store) {
    this.effectSources = effectSources;
    this.store = store;
    this.effectsSubscription = null;
  }
  start() {
    if (!this.effectsSubscription) {
      this.effectsSubscription = this.effectSources.toActions().subscribe(this.store);
    }
  }
  ngOnDestroy() {
    if (this.effectsSubscription) {
      this.effectsSubscription.unsubscribe();
      this.effectsSubscription = null;
    }
  }
  /** @nocollapse */
  static {
    this.ɵfac = function EffectsRunner_Factory(t) {
      return new (t || EffectsRunner)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](EffectSources), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.Store));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: EffectsRunner,
      factory: EffectsRunner.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EffectsRunner, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: EffectSources
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.Store
  }], null);
})();
class EffectsRootModule {
  constructor(sources, runner, store, rootEffectsInstances, storeRootModule, storeFeatureModule, guard) {
    this.sources = sources;
    runner.start();
    for (const effectsInstance of rootEffectsInstances) {
      sources.addEffects(effectsInstance);
    }
    store.dispatch({
      type: ROOT_EFFECTS_INIT
    });
  }
  addEffects(effectsInstance) {
    this.sources.addEffects(effectsInstance);
  }
  /** @nocollapse */
  static {
    this.ɵfac = function EffectsRootModule_Factory(t) {
      return new (t || EffectsRootModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](EffectSources), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](EffectsRunner), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.Store), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ROOT_EFFECTS_INSTANCES), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreRootModule, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreFeatureModule, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ROOT_EFFECTS_GUARD, 8));
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: EffectsRootModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EffectsRootModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], () => [{
    type: EffectSources
  }, {
    type: EffectsRunner
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.Store
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_ROOT_EFFECTS_INSTANCES]
    }]
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreRootModule,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreFeatureModule,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_ROOT_EFFECTS_GUARD]
    }]
  }], null);
})();
class EffectsFeatureModule {
  constructor(effectsRootModule, effectsInstanceGroups, storeRootModule, storeFeatureModule) {
    const effectsInstances = effectsInstanceGroups.flat();
    for (const effectsInstance of effectsInstances) {
      effectsRootModule.addEffects(effectsInstance);
    }
  }
  /** @nocollapse */
  static {
    this.ɵfac = function EffectsFeatureModule_Factory(t) {
      return new (t || EffectsFeatureModule)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](EffectsRootModule), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_FEATURE_EFFECTS_INSTANCE_GROUPS), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreRootModule, 8), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreFeatureModule, 8));
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: EffectsFeatureModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EffectsFeatureModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], () => [{
    type: EffectsRootModule
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_FEATURE_EFFECTS_INSTANCE_GROUPS]
    }]
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreRootModule,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_7__.StoreFeatureModule,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Optional
    }]
  }], null);
})();
class EffectsModule {
  static forFeature(...featureEffects) {
    const effects = featureEffects.flat();
    const effectsClasses = getClasses(effects);
    return {
      ngModule: EffectsFeatureModule,
      providers: [effectsClasses, {
        provide: _FEATURE_EFFECTS,
        multi: true,
        useValue: effects
      }, {
        provide: USER_PROVIDED_EFFECTS,
        multi: true,
        useValue: []
      }, {
        provide: _FEATURE_EFFECTS_INSTANCE_GROUPS,
        multi: true,
        useFactory: createEffectsInstances,
        deps: [_FEATURE_EFFECTS, USER_PROVIDED_EFFECTS]
      }]
    };
  }
  static forRoot(...rootEffects) {
    const effects = rootEffects.flat();
    const effectsClasses = getClasses(effects);
    return {
      ngModule: EffectsRootModule,
      providers: [effectsClasses, {
        provide: _ROOT_EFFECTS,
        useValue: [effects]
      }, {
        provide: _ROOT_EFFECTS_GUARD,
        useFactory: _provideForRootGuard
      }, {
        provide: USER_PROVIDED_EFFECTS,
        multi: true,
        useValue: []
      }, {
        provide: _ROOT_EFFECTS_INSTANCES,
        useFactory: createEffectsInstances,
        deps: [_ROOT_EFFECTS, USER_PROVIDED_EFFECTS]
      }]
    };
  }
  /** @nocollapse */
  static {
    this.ɵfac = function EffectsModule_Factory(t) {
      return new (t || EffectsModule)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: EffectsModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EffectsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], null, null);
})();
function createEffectsInstances(effectsGroups, userProvidedEffectsGroups) {
  const effects = [];
  for (const effectsGroup of effectsGroups) {
    effects.push(...effectsGroup);
  }
  for (const userProvidedEffectsGroup of userProvidedEffectsGroups) {
    effects.push(...userProvidedEffectsGroup);
  }
  return effects.map(effectsTokenOrRecord => isToken(effectsTokenOrRecord) ? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(effectsTokenOrRecord) : effectsTokenOrRecord);
}
function _provideForRootGuard() {
  const runner = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(EffectsRunner, {
    optional: true,
    skipSelf: true
  });
  const rootEffects = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_ROOT_EFFECTS, {
    self: true
  });
  // check whether any effects are actually passed
  const hasEffects = !(rootEffects.length === 1 && rootEffects[0].length === 0);
  if (hasEffects && runner) {
    throw new TypeError(`EffectsModule.forRoot() called twice. Feature modules should use EffectsModule.forFeature() instead.`);
  }
  return 'guarded';
}

/**
 * Wraps project fn with error handling making it safe to use in Effects.
 * Takes either a config with named properties that represent different possible
 * callbacks or project/error callbacks that are required.
 */
function act(/** Allow to take either config object or project/error functions */
configOrProject, errorFn) {
  const {
    project,
    error,
    complete,
    operator,
    unsubscribe
  } = typeof configOrProject === 'function' ? {
    project: configOrProject,
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    error: errorFn,
    operator: rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap,
    complete: undefined,
    unsubscribe: undefined
  } : {
    ...configOrProject,
    operator: configOrProject.operator || rxjs_operators__WEBPACK_IMPORTED_MODULE_15__.concatMap
  };
  return source => (0,rxjs__WEBPACK_IMPORTED_MODULE_16__.defer)(() => {
    const subject = new rxjs__WEBPACK_IMPORTED_MODULE_9__.Subject();
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_4__.merge)(source.pipe(operator((input, index) => (0,rxjs__WEBPACK_IMPORTED_MODULE_16__.defer)(() => {
      let completed = false;
      let errored = false;
      let projectedCount = 0;
      return project(input, index).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.materialize)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.map)(notification => {
        switch (notification.kind) {
          case 'E':
            errored = true;
            return {
              kind: 'N',
              value: error(notification.error, input)
            };
          case 'C':
            completed = true;
            return complete ? {
              kind: 'N',
              value: complete(projectedCount, input)
            } : undefined;
          default:
            ++projectedCount;
            return notification;
        }
      }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.filter)(n => n != null), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.dematerialize)(), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.finalize)(() => {
        if (!completed && !errored && unsubscribe) {
          subject.next(unsubscribe(projectedCount, input));
        }
      }));
    }))), subject);
  });
}

/**
 * @usageNotes
 *
 * ### Providing effects at the root level
 *
 * ```ts
 * bootstrapApplication(AppComponent, {
 *   providers: [provideEffects(RouterEffects)],
 * });
 * ```
 *
 * ### Providing effects at the feature level
 *
 * ```ts
 * const booksRoutes: Route[] = [
 *   {
 *     path: '',
 *     providers: [provideEffects(BooksApiEffects)],
 *     children: [
 *       { path: '', component: BookListComponent },
 *       { path: ':id', component: BookDetailsComponent },
 *     ],
 *   },
 * ];
 * ```
 */
function provideEffects(...effects) {
  const effectsClassesAndRecords = effects.flat();
  const effectsClasses = getClasses(effectsClassesAndRecords);
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.makeEnvironmentProviders)([effectsClasses, {
    provide: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ENVIRONMENT_INITIALIZER,
    multi: true,
    useValue: () => {
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.ROOT_STORE_PROVIDER);
      (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.FEATURE_STATE_PROVIDER, {
        optional: true
      });
      const effectsRunner = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(EffectsRunner);
      const effectSources = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(EffectSources);
      const shouldInitEffects = !effectsRunner.isStarted;
      if (shouldInitEffects) {
        effectsRunner.start();
      }
      for (const effectsClassOrRecord of effectsClassesAndRecords) {
        const effectsInstance = isClass(effectsClassOrRecord) ? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(effectsClassOrRecord) : effectsClassOrRecord;
        effectSources.addEffects(effectsInstance);
      }
      if (shouldInitEffects) {
        const store = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_ngrx_store__WEBPACK_IMPORTED_MODULE_7__.Store);
        store.dispatch(rootEffectsInit());
      }
    }
  }]);
}

/**
 * @deprecated Use `concatLatestFrom` from `@ngrx/operators` instead.
 */
const concatLatestFrom = _ngrx_operators__WEBPACK_IMPORTED_MODULE_18__.concatLatestFrom;

/**
 * DO NOT EDIT
 *
 * This file is automatically generated at build
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 72743:
/*!******************************************************************!*\
  !*** ./node_modules/@ngrx/operators/fesm2022/ngrx-operators.mjs ***!
  \******************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   concatLatestFrom: () => (/* binding */ concatLatestFrom),
/* harmony export */   tapResponse: () => (/* binding */ tapResponse)
/* harmony export */ });
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 59400);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 15842);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 98764);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 61318);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 89475);



/**
 * `concatLatestFrom` combines the source value
 * and the last available value from a lazily evaluated Observable
 * in a new array
 *
 * @usageNotes
 *
 * Select the active customer from the NgRx Store
 *
 * ```ts
 * import { concatLatestFrom } from '@ngrx/effects';
 * import * as fromCustomers from '../customers';
 *
 * this.actions$.pipe(
 *  concatLatestFrom(() => this.store.select(fromCustomers.selectActiveCustomer))
 * )
 * ```
 *
 * Select a customer from the NgRx Store by its id that is available on the action
 *
 * ```ts
 * import { concatLatestFrom } from '@ngrx/effects';
 * import * fromCustomers from '../customers';
 *
 * this.actions$.pipe(
 *  concatLatestFrom((action) => this.store.select(fromCustomers.selectCustomer(action.customerId)))
 * )
 * ```
 */
function concatLatestFrom(observablesFactory) {
  return (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_0__.concatMap)(value => {
    const observables = observablesFactory(value);
    const observablesAsArray = Array.isArray(observables) ? observables : [observables];
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_1__.of)(value).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.withLatestFrom)(...observablesAsArray));
  });
}

/**
 * Handles the response in ComponentStore effects in a safe way, without
 * additional boilerplate. It enforces that the error case is handled and
 * that the effect would still be running should an error occur.
 *
 * Takes optional callbacks for `complete` and `finalize`.
 *
 * @usageNotes
 *
 * ```ts
 * readonly dismissAlert = this.effect<Alert>((alert$) => {
 *   return alert$.pipe(
 *     concatMap(
 *       (alert) => this.alertsService.dismissAlert(alert).pipe(
 *         tapResponse(
 *           (dismissedAlert) => this.alertDismissed(dismissedAlert),
 *           (error: { message: string }) => this.logError(error.message)
 *         )
 *       )
 *     )
 *   );
 * });
 *
 * readonly loadUsers = this.effect<void>((trigger$) => {
 *   return trigger$.pipe(
 *     tap(() => this.patchState({ loading: true })),
 *     exhaustMap(() =>
 *       this.usersService.getAll().pipe(
 *         tapResponse({
 *           next: (users) => this.patchState({ users }),
 *           error: (error: HttpErrorResponse) => this.logError(error.message),
 *           finalize: () => this.patchState({ loading: false }),
 *         })
 *       )
 *     )
 *   );
 * });
 * ```
 */
function tapResponse(observerOrNext, error, complete) {
  const observer = typeof observerOrNext === 'function' ? {
    next: observerOrNext,
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    error: error,
    complete
  } : observerOrNext;
  return source => source.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.tap)({
    next: observer.next,
    complete: observer.complete
  }), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.catchError)(error => {
    observer.error(error);
    return rxjs__WEBPACK_IMPORTED_MODULE_5__.EMPTY;
  }), observer.finalize ? (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.finalize)(observer.finalize) : source$ => source$);
}

/**
 * DO NOT EDIT
 *
 * This file is automatically generated at build
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 11925:
/*!****************************************************************************!*\
  !*** ./node_modules/@ngrx/store-devtools/fesm2022/ngrx-store-devtools.mjs ***!
  \****************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   INITIAL_OPTIONS: () => (/* binding */ INITIAL_OPTIONS),
/* harmony export */   RECOMPUTE: () => (/* binding */ RECOMPUTE),
/* harmony export */   REDUX_DEVTOOLS_EXTENSION: () => (/* binding */ REDUX_DEVTOOLS_EXTENSION),
/* harmony export */   StoreDevtools: () => (/* binding */ StoreDevtools),
/* harmony export */   StoreDevtoolsConfig: () => (/* binding */ StoreDevtoolsConfig),
/* harmony export */   StoreDevtoolsModule: () => (/* binding */ StoreDevtoolsModule),
/* harmony export */   provideStoreDevtools: () => (/* binding */ provideStoreDevtools)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _ngrx_store__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @ngrx/store */ 81383);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 59400);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! rxjs */ 63617);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! rxjs */ 67046);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! rxjs */ 56042);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 71870);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs/operators */ 51567);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs/operators */ 72354);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 52575);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 61318);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! rxjs/operators */ 33900);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! rxjs/operators */ 36647);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! rxjs/operators */ 47470);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! rxjs/operators */ 74304);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! rxjs/operators */ 15842);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! rxjs/operators */ 32112);
/* harmony import */ var _angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! @angular/core/rxjs-interop */ 49074);







const PERFORM_ACTION = 'PERFORM_ACTION';
const REFRESH = 'REFRESH';
const RESET = 'RESET';
const ROLLBACK = 'ROLLBACK';
const COMMIT = 'COMMIT';
const SWEEP = 'SWEEP';
const TOGGLE_ACTION = 'TOGGLE_ACTION';
const SET_ACTIONS_ACTIVE = 'SET_ACTIONS_ACTIVE';
const JUMP_TO_STATE = 'JUMP_TO_STATE';
const JUMP_TO_ACTION = 'JUMP_TO_ACTION';
const IMPORT_STATE = 'IMPORT_STATE';
const LOCK_CHANGES = 'LOCK_CHANGES';
const PAUSE_RECORDING = 'PAUSE_RECORDING';
class PerformAction {
  constructor(action, timestamp) {
    this.action = action;
    this.timestamp = timestamp;
    this.type = PERFORM_ACTION;
    if (typeof action.type === 'undefined') {
      throw new Error('Actions may not have an undefined "type" property. ' + 'Have you misspelled a constant?');
    }
  }
}
class Refresh {
  constructor() {
    this.type = REFRESH;
  }
}
class Reset {
  constructor(timestamp) {
    this.timestamp = timestamp;
    this.type = RESET;
  }
}
class Rollback {
  constructor(timestamp) {
    this.timestamp = timestamp;
    this.type = ROLLBACK;
  }
}
class Commit {
  constructor(timestamp) {
    this.timestamp = timestamp;
    this.type = COMMIT;
  }
}
class Sweep {
  constructor() {
    this.type = SWEEP;
  }
}
class ToggleAction {
  constructor(id) {
    this.id = id;
    this.type = TOGGLE_ACTION;
  }
}
class SetActionsActive {
  constructor(start, end, active = true) {
    this.start = start;
    this.end = end;
    this.active = active;
    this.type = SET_ACTIONS_ACTIVE;
  }
}
class JumpToState {
  constructor(index) {
    this.index = index;
    this.type = JUMP_TO_STATE;
  }
}
class JumpToAction {
  constructor(actionId) {
    this.actionId = actionId;
    this.type = JUMP_TO_ACTION;
  }
}
class ImportState {
  constructor(nextLiftedState) {
    this.nextLiftedState = nextLiftedState;
    this.type = IMPORT_STATE;
  }
}
class LockChanges {
  constructor(status) {
    this.status = status;
    this.type = LOCK_CHANGES;
  }
}
class PauseRecording {
  constructor(status) {
    this.status = status;
    this.type = PAUSE_RECORDING;
  }
}

/**
 * Chrome extension documentation
 * @see https://github.com/reduxjs/redux-devtools/blob/main/extension/docs/API/Arguments.md
 * Firefox extension documentation
 * @see https://github.com/zalmoxisus/redux-devtools-extension/blob/master/docs/API/Arguments.md
 */
class StoreDevtoolsConfig {
  constructor() {
    /**
     * Maximum allowed actions to be stored in the history tree (default: `false`)
     */
    this.maxAge = false;
  }
}
const STORE_DEVTOOLS_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/store-devtools Options');
/**
 * Used to provide a `StoreDevtoolsConfig` for the store-devtools.
 */
const INITIAL_OPTIONS = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/store-devtools Initial Config');
function noMonitor() {
  return null;
}
const DEFAULT_NAME = 'NgRx Store DevTools';
function createConfig(optionsInput) {
  const DEFAULT_OPTIONS = {
    maxAge: false,
    monitor: noMonitor,
    actionSanitizer: undefined,
    stateSanitizer: undefined,
    name: DEFAULT_NAME,
    serialize: false,
    logOnly: false,
    autoPause: false,
    trace: false,
    traceLimit: 75,
    // Add all features explicitly. This prevent buggy behavior for
    // options like "lock" which might otherwise not show up.
    features: {
      pause: true,
      // Start/pause recording of dispatched actions
      lock: true,
      // Lock/unlock dispatching actions and side effects
      persist: true,
      // Persist states on page reloading
      export: true,
      // Export history of actions in a file
      import: 'custom',
      // Import history of actions from a file
      jump: true,
      // Jump back and forth (time travelling)
      skip: true,
      // Skip (cancel) actions
      reorder: true,
      // Drag and drop actions in the history list
      dispatch: true,
      // Dispatch custom actions or action creators
      test: true // Generate tests for the selected actions
    },
    connectInZone: false
  };
  const options = typeof optionsInput === 'function' ? optionsInput() : optionsInput;
  const logOnly = options.logOnly ? {
    pause: true,
    export: true,
    test: true
  } : false;
  const features = options.features || logOnly || DEFAULT_OPTIONS.features;
  if (features.import === true) {
    features.import = 'custom';
  }
  const config = Object.assign({}, DEFAULT_OPTIONS, {
    features
  }, options);
  if (config.maxAge && config.maxAge < 2) {
    throw new Error(`Devtools 'maxAge' cannot be less than 2, got ${config.maxAge}`);
  }
  return config;
}
function difference(first, second) {
  return first.filter(item => second.indexOf(item) < 0);
}
/**
 * Provides an app's view into the state of the lifted store.
 */
function unliftState(liftedState) {
  const {
    computedStates,
    currentStateIndex
  } = liftedState;
  // At start up NgRx dispatches init actions,
  // When these init actions are being filtered out by the predicate or safe/block list options
  // we don't have a complete computed states yet.
  // At this point it could happen that we're out of bounds, when this happens we fall back to the last known state
  if (currentStateIndex >= computedStates.length) {
    const {
      state
    } = computedStates[computedStates.length - 1];
    return state;
  }
  const {
    state
  } = computedStates[currentStateIndex];
  return state;
}
function unliftAction(liftedState) {
  return liftedState.actionsById[liftedState.nextActionId - 1];
}
/**
 * Lifts an app's action into an action on the lifted store.
 */
function liftAction(action) {
  return new PerformAction(action, +Date.now());
}
/**
 * Sanitizes given actions with given function.
 */
function sanitizeActions(actionSanitizer, actions) {
  return Object.keys(actions).reduce((sanitizedActions, actionIdx) => {
    const idx = Number(actionIdx);
    sanitizedActions[idx] = sanitizeAction(actionSanitizer, actions[idx], idx);
    return sanitizedActions;
  }, {});
}
/**
 * Sanitizes given action with given function.
 */
function sanitizeAction(actionSanitizer, action, actionIdx) {
  return {
    ...action,
    action: actionSanitizer(action.action, actionIdx)
  };
}
/**
 * Sanitizes given states with given function.
 */
function sanitizeStates(stateSanitizer, states) {
  return states.map((computedState, idx) => ({
    state: sanitizeState(stateSanitizer, computedState.state, idx),
    error: computedState.error
  }));
}
/**
 * Sanitizes given state with given function.
 */
function sanitizeState(stateSanitizer, state, stateIdx) {
  return stateSanitizer(state, stateIdx);
}
/**
 * Read the config and tell if actions should be filtered
 */
function shouldFilterActions(config) {
  return config.predicate || config.actionsSafelist || config.actionsBlocklist;
}
/**
 * Return a full filtered lifted state
 */
function filterLiftedState(liftedState, predicate, safelist, blocklist) {
  const filteredStagedActionIds = [];
  const filteredActionsById = {};
  const filteredComputedStates = [];
  liftedState.stagedActionIds.forEach((id, idx) => {
    const liftedAction = liftedState.actionsById[id];
    if (!liftedAction) return;
    if (idx && isActionFiltered(liftedState.computedStates[idx], liftedAction, predicate, safelist, blocklist)) {
      return;
    }
    filteredActionsById[id] = liftedAction;
    filteredStagedActionIds.push(id);
    filteredComputedStates.push(liftedState.computedStates[idx]);
  });
  return {
    ...liftedState,
    stagedActionIds: filteredStagedActionIds,
    actionsById: filteredActionsById,
    computedStates: filteredComputedStates
  };
}
/**
 * Return true is the action should be ignored
 */
function isActionFiltered(state, action, predicate, safelist, blockedlist) {
  const predicateMatch = predicate && !predicate(state, action.action);
  const safelistMatch = safelist && !action.action.type.match(safelist.map(s => escapeRegExp(s)).join('|'));
  const blocklistMatch = blockedlist && action.action.type.match(blockedlist.map(s => escapeRegExp(s)).join('|'));
  return predicateMatch || safelistMatch || blocklistMatch;
}
/**
 * Return string with escaped RegExp special characters
 * https://stackoverflow.com/a/6969486/1337347
 */
function escapeRegExp(s) {
  return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function injectZoneConfig(connectInZone) {
  const ngZone = connectInZone ? (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone) : null;
  return {
    ngZone,
    connectInZone
  };
}
class DevtoolsDispatcher extends _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ActionsSubject {
  /** @nocollapse */static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵDevtoolsDispatcher_BaseFactory;
      return function DevtoolsDispatcher_Factory(t) {
        return (ɵDevtoolsDispatcher_BaseFactory || (ɵDevtoolsDispatcher_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](DevtoolsDispatcher)))(t || DevtoolsDispatcher);
      };
    })();
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: DevtoolsDispatcher,
      factory: DevtoolsDispatcher.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DevtoolsDispatcher, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], null, null);
})();
const ExtensionActionTypes = {
  START: 'START',
  DISPATCH: 'DISPATCH',
  STOP: 'STOP',
  ACTION: 'ACTION'
};
const REDUX_DEVTOOLS_EXTENSION = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/store-devtools Redux Devtools Extension');
class DevtoolsExtension {
  constructor(devtoolsExtension, config, dispatcher) {
    this.config = config;
    this.dispatcher = dispatcher;
    this.zoneConfig = injectZoneConfig(this.config.connectInZone);
    this.devtoolsExtension = devtoolsExtension;
    this.createActionStreams();
  }
  notify(action, state) {
    if (!this.devtoolsExtension) {
      return;
    }
    // Check to see if the action requires a full update of the liftedState.
    // If it is a simple action generated by the user's app and the recording
    // is not locked/paused, only send the action and the current state (fast).
    //
    // A full liftedState update (slow: serializes the entire liftedState) is
    // only required when:
    //   a) redux-devtools-extension fires the @@Init action (ignored by
    //      @ngrx/store-devtools)
    //   b) an action is generated by an @ngrx module (e.g. @ngrx/effects/init
    //      or @ngrx/store/update-reducers)
    //   c) the state has been recomputed due to time-traveling
    //   d) any action that is not a PerformAction to err on the side of
    //      caution.
    if (action.type === PERFORM_ACTION) {
      if (state.isLocked || state.isPaused) {
        return;
      }
      const currentState = unliftState(state);
      if (shouldFilterActions(this.config) && isActionFiltered(currentState, action, this.config.predicate, this.config.actionsSafelist, this.config.actionsBlocklist)) {
        return;
      }
      const sanitizedState = this.config.stateSanitizer ? sanitizeState(this.config.stateSanitizer, currentState, state.currentStateIndex) : currentState;
      const sanitizedAction = this.config.actionSanitizer ? sanitizeAction(this.config.actionSanitizer, action, state.nextActionId) : action;
      this.sendToReduxDevtools(() => this.extensionConnection.send(sanitizedAction, sanitizedState));
    } else {
      // Requires full state update
      const sanitizedLiftedState = {
        ...state,
        stagedActionIds: state.stagedActionIds,
        actionsById: this.config.actionSanitizer ? sanitizeActions(this.config.actionSanitizer, state.actionsById) : state.actionsById,
        computedStates: this.config.stateSanitizer ? sanitizeStates(this.config.stateSanitizer, state.computedStates) : state.computedStates
      };
      this.sendToReduxDevtools(() => this.devtoolsExtension.send(null, sanitizedLiftedState, this.getExtensionConfig(this.config)));
    }
  }
  createChangesObservable() {
    if (!this.devtoolsExtension) {
      return rxjs__WEBPACK_IMPORTED_MODULE_2__.EMPTY;
    }
    return new rxjs__WEBPACK_IMPORTED_MODULE_3__.Observable(subscriber => {
      const connection = this.zoneConfig.connectInZone ?
      // To reduce change detection cycles, we need to run the `connect` method
      // outside of the Angular zone. The `connect` method adds a `message`
      // event listener to communicate with an extension using `window.postMessage`
      // and handle message events.
      this.zoneConfig.ngZone.runOutsideAngular(() => this.devtoolsExtension.connect(this.getExtensionConfig(this.config))) : this.devtoolsExtension.connect(this.getExtensionConfig(this.config));
      this.extensionConnection = connection;
      connection.init();
      connection.subscribe(change => subscriber.next(change));
      return connection.unsubscribe;
    });
  }
  createActionStreams() {
    // Listens to all changes
    const changes$ = this.createChangesObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.share)());
    // Listen for the start action
    const start$ = changes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(change => change.type === ExtensionActionTypes.START));
    // Listen for the stop action
    const stop$ = changes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(change => change.type === ExtensionActionTypes.STOP));
    // Listen for lifted actions
    const liftedActions$ = changes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(change => change.type === ExtensionActionTypes.DISPATCH), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(change => this.unwrapAction(change.payload)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.concatMap)(action => {
      if (action.type === IMPORT_STATE) {
        // State imports may happen in two situations:
        // 1. Explicitly by user
        // 2. User activated the "persist state accross reloads" option
        //    and now the state is imported during reload.
        // Because of option 2, we need to give possible
        // lazy loaded reducers time to instantiate.
        // As soon as there is no UPDATE action within 1 second,
        // it is assumed that all reducers are loaded.
        return this.dispatcher.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(action => action.type === _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.UPDATE), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_8__.timeout)(1000), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.debounceTime)(1000), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(() => action), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.catchError)(() => (0,rxjs__WEBPACK_IMPORTED_MODULE_11__.of)(action)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_12__.take)(1));
      } else {
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_11__.of)(action);
      }
    }));
    // Listen for unlifted actions
    const actions$ = changes$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_5__.filter)(change => change.type === ExtensionActionTypes.ACTION), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(change => this.unwrapAction(change.payload)));
    const actionsUntilStop$ = actions$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.takeUntil)(stop$));
    const liftedUntilStop$ = liftedActions$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.takeUntil)(stop$));
    this.start$ = start$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_13__.takeUntil)(stop$));
    // Only take the action sources between the start/stop events
    this.actions$ = this.start$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.switchMap)(() => actionsUntilStop$));
    this.liftedActions$ = this.start$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_14__.switchMap)(() => liftedUntilStop$));
  }
  unwrapAction(action) {
    // indirect eval according to https://esbuild.github.io/content-types/#direct-eval
    return typeof action === 'string' ? (0, eval)(`(${action})`) : action;
  }
  getExtensionConfig(config) {
    const extensionOptions = {
      name: config.name,
      features: config.features,
      serialize: config.serialize,
      autoPause: config.autoPause ?? false,
      trace: config.trace ?? false,
      traceLimit: config.traceLimit ?? 75
      // The action/state sanitizers are not added to the config
      // because sanitation is done in this class already.
      // It is done before sending it to the devtools extension for consistency:
      // - If we call extensionConnection.send(...),
      //   the extension would call the sanitizers.
      // - If we call devtoolsExtension.send(...) (aka full state update),
      //   the extension would NOT call the sanitizers, so we have to do it ourselves.
    };
    if (config.maxAge !== false /* support === 0 */) {
      extensionOptions.maxAge = config.maxAge;
    }
    return extensionOptions;
  }
  sendToReduxDevtools(send) {
    try {
      send();
    } catch (err) {
      console.warn('@ngrx/store-devtools: something went wrong inside the redux devtools', err);
    }
  }
  /** @nocollapse */
  static {
    this.ɵfac = function DevtoolsExtension_Factory(t) {
      return new (t || DevtoolsExtension)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](REDUX_DEVTOOLS_EXTENSION), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](STORE_DEVTOOLS_CONFIG), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](DevtoolsDispatcher));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: DevtoolsExtension,
      factory: DevtoolsExtension.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DevtoolsExtension, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [REDUX_DEVTOOLS_EXTENSION]
    }]
  }, {
    type: StoreDevtoolsConfig,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [STORE_DEVTOOLS_CONFIG]
    }]
  }, {
    type: DevtoolsDispatcher
  }], null);
})();
const INIT_ACTION = {
  type: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.INIT
};
const RECOMPUTE = '@ngrx/store-devtools/recompute';
const RECOMPUTE_ACTION = {
  type: RECOMPUTE
};
/**
 * Computes the next entry in the log by applying an action.
 */
function computeNextEntry(reducer, action, state, error, errorHandler) {
  if (error) {
    return {
      state,
      error: 'Interrupted by an error up the chain'
    };
  }
  let nextState = state;
  let nextError;
  try {
    nextState = reducer(state, action);
  } catch (err) {
    nextError = err.toString();
    errorHandler.handleError(err);
  }
  return {
    state: nextState,
    error: nextError
  };
}
/**
 * Runs the reducer on invalidated actions to get a fresh computation log.
 */
function recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused) {
  // Optimization: exit early and return the same reference
  // if we know nothing could have changed.
  if (minInvalidatedStateIndex >= computedStates.length && computedStates.length === stagedActionIds.length) {
    return computedStates;
  }
  const nextComputedStates = computedStates.slice(0, minInvalidatedStateIndex);
  // If the recording is paused, recompute all states up until the pause state,
  // else recompute all states.
  const lastIncludedActionId = stagedActionIds.length - (isPaused ? 1 : 0);
  for (let i = minInvalidatedStateIndex; i < lastIncludedActionId; i++) {
    const actionId = stagedActionIds[i];
    const action = actionsById[actionId].action;
    const previousEntry = nextComputedStates[i - 1];
    const previousState = previousEntry ? previousEntry.state : committedState;
    const previousError = previousEntry ? previousEntry.error : undefined;
    const shouldSkip = skippedActionIds.indexOf(actionId) > -1;
    const entry = shouldSkip ? previousEntry : computeNextEntry(reducer, action, previousState, previousError, errorHandler);
    nextComputedStates.push(entry);
  }
  // If the recording is paused, the last state will not be recomputed,
  // because it's essentially not part of the state history.
  if (isPaused) {
    nextComputedStates.push(computedStates[computedStates.length - 1]);
  }
  return nextComputedStates;
}
function liftInitialState(initialCommittedState, monitorReducer) {
  return {
    monitorState: monitorReducer(undefined, {}),
    nextActionId: 1,
    actionsById: {
      0: liftAction(INIT_ACTION)
    },
    stagedActionIds: [0],
    skippedActionIds: [],
    committedState: initialCommittedState,
    currentStateIndex: 0,
    computedStates: [],
    isLocked: false,
    isPaused: false
  };
}
/**
 * Creates a history state reducer from an app's reducer.
 */
function liftReducerWith(initialCommittedState, initialLiftedState, errorHandler, monitorReducer, options = {}) {
  /**
   * Manages how the history actions modify the history state.
   */
  return reducer => (liftedState, liftedAction) => {
    let {
      monitorState,
      actionsById,
      nextActionId,
      stagedActionIds,
      skippedActionIds,
      committedState,
      currentStateIndex,
      computedStates,
      isLocked,
      isPaused
    } = liftedState || initialLiftedState;
    if (!liftedState) {
      // Prevent mutating initialLiftedState
      actionsById = Object.create(actionsById);
    }
    function commitExcessActions(n) {
      // Auto-commits n-number of excess actions.
      let excess = n;
      let idsToDelete = stagedActionIds.slice(1, excess + 1);
      for (let i = 0; i < idsToDelete.length; i++) {
        if (computedStates[i + 1].error) {
          // Stop if error is found. Commit actions up to error.
          excess = i;
          idsToDelete = stagedActionIds.slice(1, excess + 1);
          break;
        } else {
          delete actionsById[idsToDelete[i]];
        }
      }
      skippedActionIds = skippedActionIds.filter(id => idsToDelete.indexOf(id) === -1);
      stagedActionIds = [0, ...stagedActionIds.slice(excess + 1)];
      committedState = computedStates[excess].state;
      computedStates = computedStates.slice(excess);
      currentStateIndex = currentStateIndex > excess ? currentStateIndex - excess : 0;
    }
    function commitChanges() {
      // Consider the last committed state the new starting point.
      // Squash any staged actions into a single committed state.
      actionsById = {
        0: liftAction(INIT_ACTION)
      };
      nextActionId = 1;
      stagedActionIds = [0];
      skippedActionIds = [];
      committedState = computedStates[currentStateIndex].state;
      currentStateIndex = 0;
      computedStates = [];
    }
    // By default, aggressively recompute every state whatever happens.
    // This has O(n) performance, so we'll override this to a sensible
    // value whenever we feel like we don't have to recompute the states.
    let minInvalidatedStateIndex = 0;
    switch (liftedAction.type) {
      case LOCK_CHANGES:
        {
          isLocked = liftedAction.status;
          minInvalidatedStateIndex = Infinity;
          break;
        }
      case PAUSE_RECORDING:
        {
          isPaused = liftedAction.status;
          if (isPaused) {
            // Add a pause action to signal the devtools-user the recording is paused.
            // The corresponding state will be overwritten on each update to always contain
            // the latest state (see Actions.PERFORM_ACTION).
            stagedActionIds = [...stagedActionIds, nextActionId];
            actionsById[nextActionId] = new PerformAction({
              type: '@ngrx/devtools/pause'
            }, +Date.now());
            nextActionId++;
            minInvalidatedStateIndex = stagedActionIds.length - 1;
            computedStates = computedStates.concat(computedStates[computedStates.length - 1]);
            if (currentStateIndex === stagedActionIds.length - 2) {
              currentStateIndex++;
            }
            minInvalidatedStateIndex = Infinity;
          } else {
            commitChanges();
          }
          break;
        }
      case RESET:
        {
          // Get back to the state the store was created with.
          actionsById = {
            0: liftAction(INIT_ACTION)
          };
          nextActionId = 1;
          stagedActionIds = [0];
          skippedActionIds = [];
          committedState = initialCommittedState;
          currentStateIndex = 0;
          computedStates = [];
          break;
        }
      case COMMIT:
        {
          commitChanges();
          break;
        }
      case ROLLBACK:
        {
          // Forget about any staged actions.
          // Start again from the last committed state.
          actionsById = {
            0: liftAction(INIT_ACTION)
          };
          nextActionId = 1;
          stagedActionIds = [0];
          skippedActionIds = [];
          currentStateIndex = 0;
          computedStates = [];
          break;
        }
      case TOGGLE_ACTION:
        {
          // Toggle whether an action with given ID is skipped.
          // Being skipped means it is a no-op during the computation.
          const {
            id: actionId
          } = liftedAction;
          const index = skippedActionIds.indexOf(actionId);
          if (index === -1) {
            skippedActionIds = [actionId, ...skippedActionIds];
          } else {
            skippedActionIds = skippedActionIds.filter(id => id !== actionId);
          }
          // Optimization: we know history before this action hasn't changed
          minInvalidatedStateIndex = stagedActionIds.indexOf(actionId);
          break;
        }
      case SET_ACTIONS_ACTIVE:
        {
          // Toggle whether an action with given ID is skipped.
          // Being skipped means it is a no-op during the computation.
          const {
            start,
            end,
            active
          } = liftedAction;
          const actionIds = [];
          for (let i = start; i < end; i++) actionIds.push(i);
          if (active) {
            skippedActionIds = difference(skippedActionIds, actionIds);
          } else {
            skippedActionIds = [...skippedActionIds, ...actionIds];
          }
          // Optimization: we know history before this action hasn't changed
          minInvalidatedStateIndex = stagedActionIds.indexOf(start);
          break;
        }
      case JUMP_TO_STATE:
        {
          // Without recomputing anything, move the pointer that tell us
          // which state is considered the current one. Useful for sliders.
          currentStateIndex = liftedAction.index;
          // Optimization: we know the history has not changed.
          minInvalidatedStateIndex = Infinity;
          break;
        }
      case JUMP_TO_ACTION:
        {
          // Jumps to a corresponding state to a specific action.
          // Useful when filtering actions.
          const index = stagedActionIds.indexOf(liftedAction.actionId);
          if (index !== -1) currentStateIndex = index;
          minInvalidatedStateIndex = Infinity;
          break;
        }
      case SWEEP:
        {
          // Forget any actions that are currently being skipped.
          stagedActionIds = difference(stagedActionIds, skippedActionIds);
          skippedActionIds = [];
          currentStateIndex = Math.min(currentStateIndex, stagedActionIds.length - 1);
          break;
        }
      case PERFORM_ACTION:
        {
          // Ignore action and return state as is if recording is locked
          if (isLocked) {
            return liftedState || initialLiftedState;
          }
          if (isPaused || liftedState && isActionFiltered(liftedState.computedStates[currentStateIndex], liftedAction, options.predicate, options.actionsSafelist, options.actionsBlocklist)) {
            // If recording is paused or if the action should be ignored, overwrite the last state
            // (corresponds to the pause action) and keep everything else as is.
            // This way, the app gets the new current state while the devtools
            // do not record another action.
            const lastState = computedStates[computedStates.length - 1];
            computedStates = [...computedStates.slice(0, -1), computeNextEntry(reducer, liftedAction.action, lastState.state, lastState.error, errorHandler)];
            minInvalidatedStateIndex = Infinity;
            break;
          }
          // Auto-commit as new actions come in.
          if (options.maxAge && stagedActionIds.length === options.maxAge) {
            commitExcessActions(1);
          }
          if (currentStateIndex === stagedActionIds.length - 1) {
            currentStateIndex++;
          }
          const actionId = nextActionId++;
          // Mutation! This is the hottest path, and we optimize on purpose.
          // It is safe because we set a new key in a cache dictionary.
          actionsById[actionId] = liftedAction;
          stagedActionIds = [...stagedActionIds, actionId];
          // Optimization: we know that only the new action needs computing.
          minInvalidatedStateIndex = stagedActionIds.length - 1;
          break;
        }
      case IMPORT_STATE:
        {
          // Completely replace everything.
          ({
            monitorState,
            actionsById,
            nextActionId,
            stagedActionIds,
            skippedActionIds,
            committedState,
            currentStateIndex,
            computedStates,
            isLocked,
            isPaused
          } = liftedAction.nextLiftedState);
          break;
        }
      case _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.INIT:
        {
          // Always recompute states on hot reload and init.
          minInvalidatedStateIndex = 0;
          if (options.maxAge && stagedActionIds.length > options.maxAge) {
            // States must be recomputed before committing excess.
            computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
            commitExcessActions(stagedActionIds.length - options.maxAge);
            // Avoid double computation.
            minInvalidatedStateIndex = Infinity;
          }
          break;
        }
      case _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.UPDATE:
        {
          const stateHasErrors = computedStates.filter(state => state.error).length > 0;
          if (stateHasErrors) {
            // Recompute all states
            minInvalidatedStateIndex = 0;
            if (options.maxAge && stagedActionIds.length > options.maxAge) {
              // States must be recomputed before committing excess.
              computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
              commitExcessActions(stagedActionIds.length - options.maxAge);
              // Avoid double computation.
              minInvalidatedStateIndex = Infinity;
            }
          } else {
            // If not paused/locked, add a new action to signal devtools-user
            // that there was a reducer update.
            if (!isPaused && !isLocked) {
              if (currentStateIndex === stagedActionIds.length - 1) {
                currentStateIndex++;
              }
              // Add a new action to only recompute state
              const actionId = nextActionId++;
              actionsById[actionId] = new PerformAction(liftedAction, +Date.now());
              stagedActionIds = [...stagedActionIds, actionId];
              minInvalidatedStateIndex = stagedActionIds.length - 1;
              computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
            }
            // Recompute state history with latest reducer and update action
            computedStates = computedStates.map(cmp => ({
              ...cmp,
              state: reducer(cmp.state, RECOMPUTE_ACTION)
            }));
            currentStateIndex = stagedActionIds.length - 1;
            if (options.maxAge && stagedActionIds.length > options.maxAge) {
              commitExcessActions(stagedActionIds.length - options.maxAge);
            }
            // Avoid double computation.
            minInvalidatedStateIndex = Infinity;
          }
          break;
        }
      default:
        {
          // If the action is not recognized, it's a monitor action.
          // Optimization: a monitor action can't change history.
          minInvalidatedStateIndex = Infinity;
          break;
        }
    }
    computedStates = recomputeStates(computedStates, minInvalidatedStateIndex, reducer, committedState, actionsById, stagedActionIds, skippedActionIds, errorHandler, isPaused);
    monitorState = monitorReducer(monitorState, liftedAction);
    return {
      monitorState,
      actionsById,
      nextActionId,
      stagedActionIds,
      skippedActionIds,
      committedState,
      currentStateIndex,
      computedStates,
      isLocked,
      isPaused
    };
  };
}
class StoreDevtools {
  constructor(dispatcher, actions$, reducers$, extension, scannedActions, errorHandler, initialState, config) {
    const liftedInitialState = liftInitialState(initialState, config.monitor);
    const liftReducer = liftReducerWith(initialState, liftedInitialState, errorHandler, config.monitor, config);
    const liftedAction$ = (0,rxjs__WEBPACK_IMPORTED_MODULE_15__.merge)((0,rxjs__WEBPACK_IMPORTED_MODULE_15__.merge)(actions$.asObservable().pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_16__.skip)(1)), extension.actions$).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(liftAction)), dispatcher, extension.liftedActions$).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_17__.observeOn)(rxjs__WEBPACK_IMPORTED_MODULE_18__.queueScheduler));
    const liftedReducer$ = reducers$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(liftReducer));
    const zoneConfig = injectZoneConfig(config.connectInZone);
    const liftedStateSubject = new rxjs__WEBPACK_IMPORTED_MODULE_19__.ReplaySubject(1);
    this.liftedStateSubscription = liftedAction$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_20__.withLatestFrom)(liftedReducer$),
    // The extension would post messages back outside of the Angular zone
    // because we call `connect()` wrapped with `runOutsideAngular`. We run change
    // detection only once at the end after all the required asynchronous tasks have
    // been processed (for instance, `setInterval` scheduled by the `timeout` operator).
    // We have to re-enter the Angular zone before the `scan` since it runs the reducer
    // which must be run within the Angular zone.
    emitInZone(zoneConfig), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_21__.scan)(({
      state: liftedState
    }, [action, reducer]) => {
      let reducedLiftedState = reducer(liftedState, action);
      // On full state update
      // If we have actions filters, we must filter completely our lifted state to be sync with the extension
      if (action.type !== PERFORM_ACTION && shouldFilterActions(config)) {
        reducedLiftedState = filterLiftedState(reducedLiftedState, config.predicate, config.actionsSafelist, config.actionsBlocklist);
      }
      // Extension should be sent the sanitized lifted state
      extension.notify(action, reducedLiftedState);
      return {
        state: reducedLiftedState,
        action
      };
    }, {
      state: liftedInitialState,
      action: null
    })).subscribe(({
      state,
      action
    }) => {
      liftedStateSubject.next(state);
      if (action.type === PERFORM_ACTION) {
        const unliftedAction = action.action;
        scannedActions.next(unliftedAction);
      }
    });
    this.extensionStartSubscription = extension.start$.pipe(emitInZone(zoneConfig)).subscribe(() => {
      this.refresh();
    });
    const liftedState$ = liftedStateSubject.asObservable();
    const state$ = liftedState$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.map)(unliftState));
    Object.defineProperty(state$, 'state', {
      value: (0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_22__.toSignal)(state$, {
        manualCleanup: true,
        requireSync: true
      })
    });
    this.dispatcher = dispatcher;
    this.liftedState = liftedState$;
    this.state = state$;
  }
  ngOnDestroy() {
    // Even though the store devtools plugin is recommended to be
    // used only in development mode, it can still cause a memory leak
    // in microfrontend applications that are being created and destroyed
    // multiple times during development. This results in excessive memory
    // consumption, as it prevents entire apps from being garbage collected.
    this.liftedStateSubscription.unsubscribe();
    this.extensionStartSubscription.unsubscribe();
  }
  dispatch(action) {
    this.dispatcher.next(action);
  }
  next(action) {
    this.dispatcher.next(action);
  }
  error(error) {}
  complete() {}
  performAction(action) {
    this.dispatch(new PerformAction(action, +Date.now()));
  }
  refresh() {
    this.dispatch(new Refresh());
  }
  reset() {
    this.dispatch(new Reset(+Date.now()));
  }
  rollback() {
    this.dispatch(new Rollback(+Date.now()));
  }
  commit() {
    this.dispatch(new Commit(+Date.now()));
  }
  sweep() {
    this.dispatch(new Sweep());
  }
  toggleAction(id) {
    this.dispatch(new ToggleAction(id));
  }
  jumpToAction(actionId) {
    this.dispatch(new JumpToAction(actionId));
  }
  jumpToState(index) {
    this.dispatch(new JumpToState(index));
  }
  importState(nextLiftedState) {
    this.dispatch(new ImportState(nextLiftedState));
  }
  lockChanges(status) {
    this.dispatch(new LockChanges(status));
  }
  pauseRecording(status) {
    this.dispatch(new PauseRecording(status));
  }
  /** @nocollapse */
  static {
    this.ɵfac = function StoreDevtools_Factory(t) {
      return new (t || StoreDevtools)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](DevtoolsDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ReducerObservable), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](DevtoolsExtension), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ScannedActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ErrorHandler), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](_ngrx_store__WEBPACK_IMPORTED_MODULE_1__.INITIAL_STATE), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵinject"](STORE_DEVTOOLS_CONFIG));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjectable"]({
      token: StoreDevtools,
      factory: StoreDevtools.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](StoreDevtools, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Injectable
  }], () => [{
    type: DevtoolsDispatcher
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ActionsSubject
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ReducerObservable
  }, {
    type: DevtoolsExtension
  }, {
    type: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ScannedActionsSubject
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ErrorHandler
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [_ngrx_store__WEBPACK_IMPORTED_MODULE_1__.INITIAL_STATE]
    }]
  }, {
    type: StoreDevtoolsConfig,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Inject,
      args: [STORE_DEVTOOLS_CONFIG]
    }]
  }], null);
})();
/**
 * If the devtools extension is connected out of the Angular zone,
 * this operator will emit all events within the zone.
 */
function emitInZone({
  ngZone,
  connectInZone
}) {
  return source => connectInZone ? new rxjs__WEBPACK_IMPORTED_MODULE_3__.Observable(subscriber => source.subscribe({
    next: value => ngZone.run(() => subscriber.next(value)),
    error: error => ngZone.run(() => subscriber.error(error)),
    complete: () => ngZone.run(() => subscriber.complete())
  })) : source;
}
const IS_EXTENSION_OR_MONITOR_PRESENT = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.InjectionToken('@ngrx/store-devtools Is Devtools Extension or Monitor Present');
function createIsExtensionOrMonitorPresent(extension, config) {
  return Boolean(extension) || config.monitor !== noMonitor;
}
function createReduxDevtoolsExtension() {
  const extensionKey = '__REDUX_DEVTOOLS_EXTENSION__';
  if (typeof window === 'object' && typeof window[extensionKey] !== 'undefined') {
    return window[extensionKey];
  } else {
    return null;
  }
}
/**
 * Provides developer tools and instrumentation for `Store`.
 *
 * @usageNotes
 *
 * ```ts
 * bootstrapApplication(AppComponent, {
 *   providers: [
 *     provideStoreDevtools({
 *       maxAge: 25,
 *       logOnly: !isDevMode(),
 *     }),
 *   ],
 * });
 * ```
 */
function provideStoreDevtools(options = {}) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.makeEnvironmentProviders)([DevtoolsExtension, DevtoolsDispatcher, StoreDevtools, {
    provide: INITIAL_OPTIONS,
    useValue: options
  }, {
    provide: IS_EXTENSION_OR_MONITOR_PRESENT,
    deps: [REDUX_DEVTOOLS_EXTENSION, STORE_DEVTOOLS_CONFIG],
    useFactory: createIsExtensionOrMonitorPresent
  }, {
    provide: REDUX_DEVTOOLS_EXTENSION,
    useFactory: createReduxDevtoolsExtension
  }, {
    provide: STORE_DEVTOOLS_CONFIG,
    deps: [INITIAL_OPTIONS],
    useFactory: createConfig
  }, {
    provide: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.StateObservable,
    deps: [StoreDevtools],
    useFactory: createStateObservable
  }, {
    provide: _ngrx_store__WEBPACK_IMPORTED_MODULE_1__.ReducerManagerDispatcher,
    useExisting: DevtoolsDispatcher
  }]);
}
function createStateObservable(devtools) {
  return devtools.state;
}
class StoreDevtoolsModule {
  static instrument(options = {}) {
    return {
      ngModule: StoreDevtoolsModule,
      providers: [provideStoreDevtools(options)]
    };
  }
  /** @nocollapse */
  static {
    this.ɵfac = function StoreDevtoolsModule_Factory(t) {
      return new (t || StoreDevtoolsModule)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
      type: StoreDevtoolsModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](StoreDevtoolsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{}]
  }], null, null);
})();

/**
 * DO NOT EDIT
 *
 * This file is automatically generated at build
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 81383:
/*!**********************************************************!*\
  !*** ./node_modules/@ngrx/store/fesm2022/ngrx-store.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ACTIVE_RUNTIME_CHECKS: () => (/* binding */ ACTIVE_RUNTIME_CHECKS),
/* harmony export */   ActionsSubject: () => (/* binding */ ActionsSubject),
/* harmony export */   FEATURE_REDUCERS: () => (/* binding */ FEATURE_REDUCERS),
/* harmony export */   FEATURE_STATE_PROVIDER: () => (/* binding */ FEATURE_STATE_PROVIDER),
/* harmony export */   INIT: () => (/* binding */ INIT),
/* harmony export */   INITIAL_REDUCERS: () => (/* binding */ INITIAL_REDUCERS),
/* harmony export */   INITIAL_STATE: () => (/* binding */ INITIAL_STATE),
/* harmony export */   META_REDUCERS: () => (/* binding */ META_REDUCERS),
/* harmony export */   REDUCER_FACTORY: () => (/* binding */ REDUCER_FACTORY),
/* harmony export */   ROOT_STORE_PROVIDER: () => (/* binding */ ROOT_STORE_PROVIDER),
/* harmony export */   ReducerManager: () => (/* binding */ ReducerManager),
/* harmony export */   ReducerManagerDispatcher: () => (/* binding */ ReducerManagerDispatcher),
/* harmony export */   ReducerObservable: () => (/* binding */ ReducerObservable),
/* harmony export */   STORE_FEATURES: () => (/* binding */ STORE_FEATURES),
/* harmony export */   ScannedActionsSubject: () => (/* binding */ ScannedActionsSubject),
/* harmony export */   State: () => (/* binding */ State),
/* harmony export */   StateObservable: () => (/* binding */ StateObservable),
/* harmony export */   Store: () => (/* binding */ Store),
/* harmony export */   StoreFeatureModule: () => (/* binding */ StoreFeatureModule),
/* harmony export */   StoreModule: () => (/* binding */ StoreModule),
/* harmony export */   StoreRootModule: () => (/* binding */ StoreRootModule),
/* harmony export */   UPDATE: () => (/* binding */ UPDATE),
/* harmony export */   USER_PROVIDED_META_REDUCERS: () => (/* binding */ USER_PROVIDED_META_REDUCERS),
/* harmony export */   USER_RUNTIME_CHECKS: () => (/* binding */ USER_RUNTIME_CHECKS),
/* harmony export */   combineReducers: () => (/* binding */ combineReducers),
/* harmony export */   compose: () => (/* binding */ compose),
/* harmony export */   createAction: () => (/* binding */ createAction),
/* harmony export */   createActionGroup: () => (/* binding */ createActionGroup),
/* harmony export */   createFeature: () => (/* binding */ createFeature),
/* harmony export */   createFeatureSelector: () => (/* binding */ createFeatureSelector),
/* harmony export */   createReducer: () => (/* binding */ createReducer),
/* harmony export */   createReducerFactory: () => (/* binding */ createReducerFactory),
/* harmony export */   createSelector: () => (/* binding */ createSelector),
/* harmony export */   createSelectorFactory: () => (/* binding */ createSelectorFactory),
/* harmony export */   defaultMemoize: () => (/* binding */ defaultMemoize),
/* harmony export */   defaultStateFn: () => (/* binding */ defaultStateFn),
/* harmony export */   emptyProps: () => (/* binding */ emptyProps),
/* harmony export */   isNgrxMockEnvironment: () => (/* binding */ isNgrxMockEnvironment),
/* harmony export */   on: () => (/* binding */ on),
/* harmony export */   props: () => (/* binding */ props),
/* harmony export */   provideState: () => (/* binding */ provideState),
/* harmony export */   provideStore: () => (/* binding */ provideStore),
/* harmony export */   reduceState: () => (/* binding */ reduceState),
/* harmony export */   resultMemoize: () => (/* binding */ resultMemoize),
/* harmony export */   select: () => (/* binding */ select),
/* harmony export */   setNgrxMockEnvironment: () => (/* binding */ setNgrxMockEnvironment),
/* harmony export */   union: () => (/* binding */ union)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 75797);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs */ 43942);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 10819);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 67046);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 74304);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs/operators */ 15842);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 32112);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs/operators */ 15424);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! rxjs/operators */ 91817);
/* harmony import */ var _angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @angular/core/rxjs-interop */ 49074);





const REGISTERED_ACTION_TYPES = {};
function resetRegisteredActionTypes() {
  for (const key of Object.keys(REGISTERED_ACTION_TYPES)) {
    delete REGISTERED_ACTION_TYPES[key];
  }
}

/**
 * @description
 * Creates a configured `Creator` function that, when called, returns an object in the shape of the `Action` interface.
 *
 * Action creators reduce the explicitness of class-based action creators.
 *
 * @param type Describes the action that will be dispatched
 * @param config Additional metadata needed for the handling of the action.  See {@link createAction#usage-notes Usage Notes}.
 *
 * @usageNotes
 *
 * **Declaring an action creator**
 *
 * Without additional metadata:
 * ```ts
 * export const increment = createAction('[Counter] Increment');
 * ```
 * With additional metadata:
 * ```ts
 * export const loginSuccess = createAction(
 *   '[Auth/API] Login Success',
 *   props<{ user: User }>()
 * );
 * ```
 * With a function:
 * ```ts
 * export const loginSuccess = createAction(
 *   '[Auth/API] Login Success',
 *   (response: Response) => response.user
 * );
 * ```
 *
 * **Dispatching an action**
 *
 * Without additional metadata:
 * ```ts
 * store.dispatch(increment());
 * ```
 * With additional metadata:
 * ```ts
 * store.dispatch(loginSuccess({ user: newUser }));
 * ```
 *
 * **Referencing an action in a reducer**
 *
 * Using a switch statement:
 * ```ts
 * switch (action.type) {
 *   // ...
 *   case AuthApiActions.loginSuccess.type: {
 *     return {
 *       ...state,
 *       user: action.user
 *     };
 *   }
 * }
 * ```
 * Using a reducer creator:
 * ```ts
 * on(AuthApiActions.loginSuccess, (state, { user }) => ({ ...state, user }))
 * ```
 *
 *  **Referencing an action in an effect**
 * ```ts
 * effectName$ = createEffect(
 *   () => this.actions$.pipe(
 *     ofType(AuthApiActions.loginSuccess),
 *     // ...
 *   )
 * );
 * ```
 */
function createAction(type, config) {
  REGISTERED_ACTION_TYPES[type] = (REGISTERED_ACTION_TYPES[type] || 0) + 1;
  if (typeof config === 'function') {
    return defineType(type, (...args) => ({
      ...config(...args),
      type
    }));
  }
  const as = config ? config._as : 'empty';
  switch (as) {
    case 'empty':
      return defineType(type, () => ({
        type
      }));
    case 'props':
      return defineType(type, props => ({
        ...props,
        type
      }));
    default:
      throw new Error('Unexpected config.');
  }
}
function props() {
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  return {
    _as: 'props',
    _p: undefined
  };
}
function union(creators) {
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
  return undefined;
}
function defineType(type, creator) {
  return Object.defineProperty(creator, 'type', {
    value: type,
    writable: false
  });
}
function capitalize(text) {
  return text.charAt(0).toUpperCase() + text.substring(1);
}
function uncapitalize(text) {
  return text.charAt(0).toLowerCase() + text.substring(1);
}

/**
 * @description
 * A function that creates a group of action creators with the same source.
 *
 * @param config An object that contains a source and dictionary of events.
 * An event is a key-value pair of an event name and event props.
 * @returns A dictionary of action creators.
 * The name of each action creator is created by camel casing the event name.
 * The type of each action is created using the "[Source] Event Name" pattern.
 *
 * @usageNotes
 *
 * ```ts
 * const authApiActions = createActionGroup({
 *   source: 'Auth API',
 *   events: {
 *     // defining events with payload using the `props` function
 *     'Login Success': props<{ userId: number; token: string }>(),
 *     'Login Failure': props<{ error: string }>(),
 *
 *     // defining an event without payload using the `emptyProps` function
 *     'Logout Success': emptyProps(),
 *
 *     // defining an event with payload using the props factory
 *     'Logout Failure': (error: Error) => ({ error }),
 *   },
 * });
 *
 * // action type: "[Auth API] Login Success"
 * authApiActions.loginSuccess({ userId: 10, token: 'ngrx' });
 *
 * // action type: "[Auth API] Login Failure"
 * authApiActions.loginFailure({ error: 'Login Failure!' });
 *
 * // action type: "[Auth API] Logout Success"
 * authApiActions.logoutSuccess();
 *
 * // action type: "[Auth API] Logout Failure";
 * authApiActions.logoutFailure(new Error('Logout Failure!'));
 * ```
 */
function createActionGroup(config) {
  const {
    source,
    events
  } = config;
  return Object.keys(events).reduce((actionGroup, eventName) => ({
    ...actionGroup,
    [toActionName(eventName)]: createAction(toActionType(source, eventName), events[eventName])
  }), {});
}
function emptyProps() {
  return props();
}
function toActionName(eventName) {
  return eventName.trim().split(' ').map((word, i) => i === 0 ? uncapitalize(word) : capitalize(word)).join('');
}
function toActionType(source, eventName) {
  return `[${source}] ${eventName}`;
}
const INIT = '@ngrx/store/init';
class ActionsSubject extends rxjs__WEBPACK_IMPORTED_MODULE_0__.BehaviorSubject {
  constructor() {
    super({
      type: INIT
    });
  }
  next(action) {
    if (typeof action === 'function') {
      throw new TypeError(`
        Dispatch expected an object, instead it received a function.
        If you're using the createAction function, make sure to invoke the function
        before dispatching the action. For example, someAction should be someAction().`);
    } else if (typeof action === 'undefined') {
      throw new TypeError(`Actions must be objects`);
    } else if (typeof action.type === 'undefined') {
      throw new TypeError(`Actions must have a type property`);
    }
    super.next(action);
  }
  complete() {
    /* noop */
  }
  ngOnDestroy() {
    super.complete();
  }
  /** @nocollapse */
  static {
    this.ɵfac = function ActionsSubject_Factory(t) {
      return new (t || ActionsSubject)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: ActionsSubject,
      factory: ActionsSubject.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](ActionsSubject, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [], null);
})();
const ACTIONS_SUBJECT_PROVIDERS = [ActionsSubject];
const _ROOT_STORE_GUARD = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Root Guard');
const _INITIAL_STATE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Initial State');
const INITIAL_STATE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Initial State');
const REDUCER_FACTORY = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Reducer Factory');
const _REDUCER_FACTORY = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Reducer Factory Provider');
const INITIAL_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Initial Reducers');
const _INITIAL_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Initial Reducers');
const STORE_FEATURES = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Store Features');
const _STORE_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Store Reducers');
const _FEATURE_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Feature Reducers');
const _FEATURE_CONFIGS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Feature Configs');
const _STORE_FEATURES = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Store Features');
const _FEATURE_REDUCERS_TOKEN = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Feature Reducers Token');
const FEATURE_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Feature Reducers');
/**
 * User-defined meta reducers from StoreModule.forRoot()
 */
const USER_PROVIDED_META_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store User Provided Meta Reducers');
/**
 * Meta reducers defined either internally by @ngrx/store or by library authors
 */
const META_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Meta Reducers');
/**
 * Concats the user provided meta reducers and the meta reducers provided on the multi
 * injection token
 */
const _RESOLVED_META_REDUCERS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Resolved Meta Reducers');
/**
 * Runtime checks defined by the user via an InjectionToken
 * Defaults to `_USER_RUNTIME_CHECKS`
 */
const USER_RUNTIME_CHECKS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store User Runtime Checks Config');
/**
 * Runtime checks defined by the user via forRoot()
 */
const _USER_RUNTIME_CHECKS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal User Runtime Checks Config');
/**
 * Runtime checks currently in use
 */
const ACTIVE_RUNTIME_CHECKS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Internal Runtime Checks');
const _ACTION_TYPE_UNIQUENESS_CHECK = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Check if Action types are unique');
/**
 * InjectionToken that registers the global Store.
 * Mainly used to provide a hook that can be injected
 * to ensure the root state is loaded before something
 * that depends on it.
 */
const ROOT_STORE_PROVIDER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Root Store Provider');
/**
 * InjectionToken that registers feature states.
 * Mainly used to provide a hook that can be injected
 * to ensure feature state is loaded before something
 * that depends on it.
 */
const FEATURE_STATE_PROVIDER = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('@ngrx/store Feature State Provider');

/**
 * @description
 * Combines reducers for individual features into a single reducer.
 *
 * You can use this function to delegate handling of state transitions to multiple reducers, each acting on their
 * own sub-state within the root state.
 *
 * @param reducers An object mapping keys of the root state to their corresponding feature reducer.
 * @param initialState Provides a state value if the current state is `undefined`, as it is initially.
 * @returns A reducer function.
 *
 * @usageNotes
 *
 * **Example combining two feature reducers into one "root" reducer**
 *
 * ```ts
 * export const reducer = combineReducers({
 *   featureA: featureAReducer,
 *   featureB: featureBReducer
 * });
 * ```
 *
 * You can also override the initial states of the sub-features:
 * ```ts
 * export const reducer = combineReducers({
 *   featureA: featureAReducer,
 *   featureB: featureBReducer
 * }, {
 *   featureA: { counterA: 13 },
 *   featureB: { counterB: 37 }
 * });
 * ```
 */
function combineReducers(reducers, initialState = {}) {
  const reducerKeys = Object.keys(reducers);
  const finalReducers = {};
  for (let i = 0; i < reducerKeys.length; i++) {
    const key = reducerKeys[i];
    if (typeof reducers[key] === 'function') {
      finalReducers[key] = reducers[key];
    }
  }
  const finalReducerKeys = Object.keys(finalReducers);
  return function combination(state, action) {
    state = state === undefined ? initialState : state;
    let hasChanged = false;
    const nextState = {};
    for (let i = 0; i < finalReducerKeys.length; i++) {
      const key = finalReducerKeys[i];
      const reducer = finalReducers[key];
      const previousStateForKey = state[key];
      const nextStateForKey = reducer(previousStateForKey, action);
      nextState[key] = nextStateForKey;
      hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
    }
    return hasChanged ? nextState : state;
  };
}
function omit(object, keyToRemove) {
  return Object.keys(object).filter(key => key !== keyToRemove).reduce((result, key) => Object.assign(result, {
    [key]: object[key]
  }), {});
}
function compose(...functions) {
  return function (arg) {
    if (functions.length === 0) {
      return arg;
    }
    const last = functions[functions.length - 1];
    const rest = functions.slice(0, -1);
    return rest.reduceRight((composed, fn) => fn(composed), last(arg));
  };
}
function createReducerFactory(reducerFactory, metaReducers) {
  if (Array.isArray(metaReducers) && metaReducers.length > 0) {
    reducerFactory = compose.apply(null, [...metaReducers, reducerFactory]);
  }
  return (reducers, initialState) => {
    const reducer = reducerFactory(reducers);
    return (state, action) => {
      state = state === undefined ? initialState : state;
      return reducer(state, action);
    };
  };
}
function createFeatureReducerFactory(metaReducers) {
  const reducerFactory = Array.isArray(metaReducers) && metaReducers.length > 0 ? compose(...metaReducers) : r => r;
  return (reducer, initialState) => {
    reducer = reducerFactory(reducer);
    return (state, action) => {
      state = state === undefined ? initialState : state;
      return reducer(state, action);
    };
  };
}
class ReducerObservable extends rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable {}
class ReducerManagerDispatcher extends ActionsSubject {}
const UPDATE = '@ngrx/store/update-reducers';
class ReducerManager extends rxjs__WEBPACK_IMPORTED_MODULE_0__.BehaviorSubject {
  get currentReducers() {
    return this.reducers;
  }
  constructor(dispatcher, initialState, reducers, reducerFactory) {
    super(reducerFactory(reducers, initialState));
    this.dispatcher = dispatcher;
    this.initialState = initialState;
    this.reducers = reducers;
    this.reducerFactory = reducerFactory;
  }
  addFeature(feature) {
    this.addFeatures([feature]);
  }
  addFeatures(features) {
    const reducers = features.reduce((reducerDict, {
      reducers,
      reducerFactory,
      metaReducers,
      initialState,
      key
    }) => {
      const reducer = typeof reducers === 'function' ? createFeatureReducerFactory(metaReducers)(reducers, initialState) : createReducerFactory(reducerFactory, metaReducers)(reducers, initialState);
      reducerDict[key] = reducer;
      return reducerDict;
    }, {});
    this.addReducers(reducers);
  }
  removeFeature(feature) {
    this.removeFeatures([feature]);
  }
  removeFeatures(features) {
    this.removeReducers(features.map(p => p.key));
  }
  addReducer(key, reducer) {
    this.addReducers({
      [key]: reducer
    });
  }
  addReducers(reducers) {
    this.reducers = {
      ...this.reducers,
      ...reducers
    };
    this.updateReducers(Object.keys(reducers));
  }
  removeReducer(featureKey) {
    this.removeReducers([featureKey]);
  }
  removeReducers(featureKeys) {
    featureKeys.forEach(key => {
      this.reducers = omit(this.reducers, key) /*TODO(#823)*/;
    });
    this.updateReducers(featureKeys);
  }
  updateReducers(featureKeys) {
    this.next(this.reducerFactory(this.reducers, this.initialState));
    this.dispatcher.next({
      type: UPDATE,
      features: featureKeys
    });
  }
  ngOnDestroy() {
    this.complete();
  }
  /** @nocollapse */
  static {
    this.ɵfac = function ReducerManager_Factory(t) {
      return new (t || ReducerManager)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ReducerManagerDispatcher), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](INITIAL_STATE), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](INITIAL_REDUCERS), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](REDUCER_FACTORY));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: ReducerManager,
      factory: ReducerManager.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](ReducerManager, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: ReducerManagerDispatcher
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [INITIAL_STATE]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [INITIAL_REDUCERS]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [REDUCER_FACTORY]
    }]
  }], null);
})();
const REDUCER_MANAGER_PROVIDERS = [ReducerManager, {
  provide: ReducerObservable,
  useExisting: ReducerManager
}, {
  provide: ReducerManagerDispatcher,
  useExisting: ActionsSubject
}];
class ScannedActionsSubject extends rxjs__WEBPACK_IMPORTED_MODULE_3__.Subject {
  ngOnDestroy() {
    this.complete();
  }
  /** @nocollapse */
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵScannedActionsSubject_BaseFactory;
      return function ScannedActionsSubject_Factory(t) {
        return (ɵScannedActionsSubject_BaseFactory || (ɵScannedActionsSubject_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](ScannedActionsSubject)))(t || ScannedActionsSubject);
      };
    })();
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: ScannedActionsSubject,
      factory: ScannedActionsSubject.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](ScannedActionsSubject, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
const SCANNED_ACTIONS_SUBJECT_PROVIDERS = [ScannedActionsSubject];
class StateObservable extends rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable {}
class State extends rxjs__WEBPACK_IMPORTED_MODULE_0__.BehaviorSubject {
  static {
    this.INIT = INIT;
  }
  constructor(actions$, reducer$, scannedActions, initialState) {
    super(initialState);
    const actionsOnQueue$ = actions$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.observeOn)(rxjs__WEBPACK_IMPORTED_MODULE_5__.queueScheduler));
    const withLatestReducer$ = actionsOnQueue$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_6__.withLatestFrom)(reducer$));
    const seed = {
      state: initialState
    };
    const stateAndAction$ = withLatestReducer$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.scan)(reduceState, seed));
    this.stateSubscription = stateAndAction$.subscribe(({
      state,
      action
    }) => {
      this.next(state);
      scannedActions.next(action);
    });
    this.state = (0,_angular_core_rxjs_interop__WEBPACK_IMPORTED_MODULE_8__.toSignal)(this, {
      manualCleanup: true,
      requireSync: true
    });
  }
  ngOnDestroy() {
    this.stateSubscription.unsubscribe();
    this.complete();
  }
  /** @nocollapse */
  static {
    this.ɵfac = function State_Factory(t) {
      return new (t || State)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ReducerObservable), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ScannedActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](INITIAL_STATE));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: State,
      factory: State.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](State, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: ActionsSubject
  }, {
    type: ReducerObservable
  }, {
    type: ScannedActionsSubject
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [INITIAL_STATE]
    }]
  }], null);
})();
function reduceState(stateActionPair = {
  state: undefined
}, [action, reducer]) {
  const {
    state
  } = stateActionPair;
  return {
    state: reducer(state, action),
    action
  };
}
const STATE_PROVIDERS = [State, {
  provide: StateObservable,
  useExisting: State
}];

// disabled because we have lowercase generics for `select`
class Store extends rxjs__WEBPACK_IMPORTED_MODULE_2__.Observable {
  constructor(state$, actionsObserver, reducerManager) {
    super();
    this.actionsObserver = actionsObserver;
    this.reducerManager = reducerManager;
    this.source = state$;
    this.state = state$.state;
  }
  select(pathOrMapFn, ...paths) {
    return select.call(null, pathOrMapFn, ...paths)(this);
  }
  /**
   * Returns a signal of the provided selector.
   *
   * @param selector selector function
   * @param options select signal options
   */
  selectSignal(selector, options) {
    return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.computed)(() => selector(this.state()), options);
  }
  lift(operator) {
    const store = new Store(this, this.actionsObserver, this.reducerManager);
    store.operator = operator;
    return store;
  }
  dispatch(action) {
    this.actionsObserver.next(action);
  }
  next(action) {
    this.actionsObserver.next(action);
  }
  error(err) {
    this.actionsObserver.error(err);
  }
  complete() {
    this.actionsObserver.complete();
  }
  addReducer(key, reducer) {
    this.reducerManager.addReducer(key, reducer);
  }
  removeReducer(key) {
    this.reducerManager.removeReducer(key);
  }
  /** @nocollapse */
  static {
    this.ɵfac = function Store_Factory(t) {
      return new (t || Store)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](StateObservable), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ReducerManager));
    };
  }
  /** @nocollapse */
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: Store,
      factory: Store.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](Store, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], () => [{
    type: StateObservable
  }, {
    type: ActionsSubject
  }, {
    type: ReducerManager
  }], null);
})();
const STORE_PROVIDERS = [Store];
function select(pathOrMapFn, propsOrPath, ...paths) {
  return function selectOperator(source$) {
    let mapped$;
    if (typeof pathOrMapFn === 'string') {
      const pathSlices = [propsOrPath, ...paths].filter(Boolean);
      mapped$ = source$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_9__.pluck)(pathOrMapFn, ...pathSlices));
    } else if (typeof pathOrMapFn === 'function') {
      mapped$ = source$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.map)(source => pathOrMapFn(source, propsOrPath)));
    } else {
      throw new TypeError(`Unexpected type '${typeof pathOrMapFn}' in select operator,` + ` expected 'string' or 'function'`);
    }
    return mapped$.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_11__.distinctUntilChanged)());
  };
}
const RUNTIME_CHECK_URL = 'https://ngrx.io/guide/store/configuration/runtime-checks';
function isUndefined(target) {
  return target === undefined;
}
function isNull(target) {
  return target === null;
}
function isArray(target) {
  return Array.isArray(target);
}
function isString(target) {
  return typeof target === 'string';
}
function isBoolean(target) {
  return typeof target === 'boolean';
}
function isNumber(target) {
  return typeof target === 'number';
}
function isObjectLike(target) {
  return typeof target === 'object' && target !== null;
}
function isObject(target) {
  return isObjectLike(target) && !isArray(target);
}
function isPlainObject(target) {
  if (!isObject(target)) {
    return false;
  }
  const targetPrototype = Object.getPrototypeOf(target);
  return targetPrototype === Object.prototype || targetPrototype === null;
}
function isFunction(target) {
  return typeof target === 'function';
}
function isComponent(target) {
  return isFunction(target) && target.hasOwnProperty('ɵcmp');
}
function hasOwnProperty(target, propertyName) {
  return Object.prototype.hasOwnProperty.call(target, propertyName);
}
let _ngrxMockEnvironment = false;
function setNgrxMockEnvironment(value) {
  _ngrxMockEnvironment = value;
}
function isNgrxMockEnvironment() {
  return _ngrxMockEnvironment;
}
function isEqualCheck(a, b) {
  return a === b;
}
function isArgumentsChanged(args, lastArguments, comparator) {
  for (let i = 0; i < args.length; i++) {
    if (!comparator(args[i], lastArguments[i])) {
      return true;
    }
  }
  return false;
}
function resultMemoize(projectionFn, isResultEqual) {
  return defaultMemoize(projectionFn, isEqualCheck, isResultEqual);
}
function defaultMemoize(projectionFn, isArgumentsEqual = isEqualCheck, isResultEqual = isEqualCheck) {
  let lastArguments = null;
  // eslint-disable-next-line @typescript-eslint/no-explicit-any, , , , ,
  let lastResult = null;
  let overrideResult;
  function reset() {
    lastArguments = null;
    lastResult = null;
  }
  function setResult(result = undefined) {
    overrideResult = {
      result
    };
  }
  function clearResult() {
    overrideResult = undefined;
  }
  /* eslint-disable prefer-rest-params, prefer-spread */
  // disabled because of the use of `arguments`
  function memoized() {
    if (overrideResult !== undefined) {
      return overrideResult.result;
    }
    if (!lastArguments) {
      lastResult = projectionFn.apply(null, arguments);
      lastArguments = arguments;
      return lastResult;
    }
    if (!isArgumentsChanged(arguments, lastArguments, isArgumentsEqual)) {
      return lastResult;
    }
    const newResult = projectionFn.apply(null, arguments);
    lastArguments = arguments;
    if (isResultEqual(lastResult, newResult)) {
      return lastResult;
    }
    lastResult = newResult;
    return newResult;
  }
  return {
    memoized,
    reset,
    setResult,
    clearResult
  };
}
function createSelector(...input) {
  return createSelectorFactory(defaultMemoize)(...input);
}
function defaultStateFn(state, selectors, props, memoizedProjector) {
  if (props === undefined) {
    const args = selectors.map(fn => fn(state));
    return memoizedProjector.memoized.apply(null, args);
  }
  const args = selectors.map(fn => fn(state, props));
  return memoizedProjector.memoized.apply(null, [...args, props]);
}
/**
 *
 * @param memoize The function used to memoize selectors
 * @param options Config Object that may include a `stateFn` function defining how to return the selector's value, given the entire `Store`'s state, parent `Selector`s, `Props`, and a `MemoizedProjection`
 *
 * @usageNotes
 *
 * **Creating a Selector Factory Where Array Order Does Not Matter**
 *
 * ```ts
 * function removeMatch(arr: string[], target: string): string[] {
 *   const matchIndex = arr.indexOf(target);
 *   return [...arr.slice(0, matchIndex), ...arr.slice(matchIndex + 1)];
 * }
 *
 * function orderDoesNotMatterComparer(a: any, b: any): boolean {
 *   if (!Array.isArray(a) || !Array.isArray(b)) {
 *     return a === b;
 *   }
 *   if (a.length !== b.length) {
 *     return false;
 *   }
 *   let tempB = [...b];
 *   function reduceToDetermineIfArraysContainSameContents(
 *     previousCallResult: boolean,
 *     arrayMember: any
 *   ): boolean {
 *     if (previousCallResult === false) {
 *       return false;
 *     }
 *     if (tempB.includes(arrayMember)) {
 *       tempB = removeMatch(tempB, arrayMember);
 *       return true;
 *     }
 *     return false;
 *   }
 *   return a.reduce(reduceToDetermineIfArraysContainSameContents, true);
 * }
 *
 * export const createOrderDoesNotMatterSelector = createSelectorFactory(
 *   (projectionFun) => defaultMemoize(
 *     projectionFun,
 *     orderDoesNotMatterComparer,
 *     orderDoesNotMatterComparer
 *   )
 * );
 * ```
 *
 * **Creating an Alternative Memoization Strategy**
 *
 * ```ts
 * function serialize(x: any): string {
 *   return JSON.stringify(x);
 * }
 *
 * export const createFullHistorySelector = createSelectorFactory(
 *  (projectionFunction) => {
 *    const cache = {};
 *
 *    function memoized() {
 *      const serializedArguments = serialize(...arguments);
 *       if (cache[serializedArguments] != null) {
 *         cache[serializedArguments] = projectionFunction.apply(null, arguments);
 *       }
 *       return cache[serializedArguments];
 *     }
 *     return {
 *       memoized,
 *       reset: () => {},
 *       setResult: () => {},
 *       clearResult: () => {},
 *     };
 *   }
 * );
 * ```
 */
function createSelectorFactory(memoize, options = {
  stateFn: defaultStateFn
}) {
  return function (...input) {
    let args = input;
    if (Array.isArray(args[0])) {
      const [head, ...tail] = args;
      args = [...head, ...tail];
    } else if (args.length === 1 && isSelectorsDictionary(args[0])) {
      args = extractArgsFromSelectorsDictionary(args[0]);
    }
    const selectors = args.slice(0, args.length - 1);
    const projector = args[args.length - 1];
    const memoizedSelectors = selectors.filter(selector => selector.release && typeof selector.release === 'function');
    const memoizedProjector = memoize(function (...selectors) {
      return projector.apply(null, selectors);
    });
    const memoizedState = defaultMemoize(function (state, props) {
      return options.stateFn.apply(null, [state, selectors, props, memoizedProjector]);
    });
    function release() {
      memoizedState.reset();
      memoizedProjector.reset();
      memoizedSelectors.forEach(selector => selector.release());
    }
    return Object.assign(memoizedState.memoized, {
      release,
      projector: memoizedProjector.memoized,
      setResult: memoizedState.setResult,
      clearResult: memoizedState.clearResult
    });
  };
}
function createFeatureSelector(featureName) {
  return createSelector(state => {
    const featureState = state[featureName];
    if (!isNgrxMockEnvironment() && (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)() && !(featureName in state)) {
      console.warn(`@ngrx/store: The feature name "${featureName}" does ` + 'not exist in the state, therefore createFeatureSelector ' + 'cannot access it.  Be sure it is imported in a loaded module ' + `using StoreModule.forRoot('${featureName}', ...) or ` + `StoreModule.forFeature('${featureName}', ...).  If the default ` + 'state is intended to be undefined, as is the case with router ' + 'state, this development-only warning message can be ignored.');
    }
    return featureState;
  }, featureState => featureState);
}
function isSelectorsDictionary(selectors) {
  return !!selectors && typeof selectors === 'object' && Object.values(selectors).every(selector => typeof selector === 'function');
}
function extractArgsFromSelectorsDictionary(selectorsDictionary) {
  const selectors = Object.values(selectorsDictionary);
  const resultKeys = Object.keys(selectorsDictionary);
  const projector = (...selectorResults) => resultKeys.reduce((result, key, index) => ({
    ...result,
    [key]: selectorResults[index]
  }), {});
  return [...selectors, projector];
}

/**
 * @description
 * A function that accepts a feature name and a feature reducer, and creates
 * a feature selector and a selector for each feature state property.
 * This function also provides the ability to add extra selectors to
 * the feature object.
 *
 * @param featureConfig An object that contains a feature name and a feature
 * reducer as required, and extra selectors factory as an optional argument.
 * @returns An object that contains a feature name, a feature reducer,
 * a feature selector, a selector for each feature state property, and extra
 * selectors.
 *
 * @usageNotes
 *
 * ```ts
 * interface ProductsState {
 *   products: Product[];
 *   selectedId: string | null;
 * }
 *
 * const initialState: ProductsState = {
 *   products: [],
 *   selectedId: null,
 * };
 *
 * const productsFeature = createFeature({
 *   name: 'products',
 *   reducer: createReducer(
 *     initialState,
 *     on(ProductsApiActions.loadSuccess(state, { products }) => ({
 *       ...state,
 *       products,
 *     }),
 *   ),
 * });
 *
 * const {
 *   name,
 *   reducer,
 *   // feature selector
 *   selectProductsState, // type: MemoizedSelector<Record<string, any>, ProductsState>
 *   // feature state properties selectors
 *   selectProducts, // type: MemoizedSelector<Record<string, any>, Product[]>
 *   selectSelectedId, // type: MemoizedSelector<Record<string, any>, string | null>
 * } = productsFeature;
 * ```
 *
 * **Creating Feature with Extra Selectors**
 *
 * ```ts
 * type CallState = 'init' | 'loading' | 'loaded' | { error: string };
 *
 * interface State extends EntityState<Product> {
 *   callState: CallState;
 * }
 *
 * const adapter = createEntityAdapter<Product>();
 * const initialState: State = adapter.getInitialState({
 *   callState: 'init',
 * });
 *
 * export const productsFeature = createFeature({
 *   name: 'products',
 *   reducer: createReducer(initialState),
 *   extraSelectors: ({ selectProductsState, selectCallState }) => ({
 *     ...adapter.getSelectors(selectProductsState),
 *     ...getCallStateSelectors(selectCallState)
 *   }),
 * });
 *
 * const {
 *   name,
 *   reducer,
 *   // feature selector
 *   selectProductsState,
 *   // feature state properties selectors
 *   selectIds,
 *   selectEntities,
 *   selectCallState,
 *   // selectors returned by `adapter.getSelectors`
 *   selectAll,
 *   selectTotal,
 *   // selectors returned by `getCallStateSelectors`
 *   selectIsLoading,
 *   selectIsLoaded,
 *   selectError,
 * } = productsFeature;
 * ```
 */
function createFeature(featureConfig) {
  const {
    name,
    reducer,
    extraSelectors: extraSelectorsFactory
  } = featureConfig;
  const featureSelector = createFeatureSelector(name);
  const nestedSelectors = createNestedSelectors(featureSelector, reducer);
  const baseSelectors = {
    [`select${capitalize(name)}State`]: featureSelector,
    ...nestedSelectors
  };
  const extraSelectors = extraSelectorsFactory ? extraSelectorsFactory(baseSelectors) : {};
  return {
    name,
    reducer,
    ...baseSelectors,
    ...extraSelectors
  };
}
function createNestedSelectors(featureSelector, reducer) {
  const initialState = getInitialState(reducer);
  const nestedKeys = isPlainObject(initialState) ? Object.keys(initialState) : [];
  return nestedKeys.reduce((nestedSelectors, nestedKey) => ({
    ...nestedSelectors,
    [`select${capitalize(nestedKey)}`]: createSelector(featureSelector, parentState => parentState?.[nestedKey])
  }), {});
}
function getInitialState(reducer) {
  return reducer(undefined, {
    type: '@ngrx/feature/init'
  });
}
function _createStoreReducers(reducers) {
  return reducers instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken ? (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(reducers) : reducers;
}
function _createFeatureStore(configs, featureStores) {
  return featureStores.map((feat, index) => {
    if (configs[index] instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken) {
      const conf = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(configs[index]);
      return {
        key: feat.key,
        reducerFactory: conf.reducerFactory ? conf.reducerFactory : combineReducers,
        metaReducers: conf.metaReducers ? conf.metaReducers : [],
        initialState: conf.initialState
      };
    }
    return feat;
  });
}
function _createFeatureReducers(reducerCollection) {
  return reducerCollection.map(reducer => {
    return reducer instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken ? (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(reducer) : reducer;
  });
}
function _initialStateFactory(initialState) {
  if (typeof initialState === 'function') {
    return initialState();
  }
  return initialState;
}
function _concatMetaReducers(metaReducers, userProvidedMetaReducers) {
  return metaReducers.concat(userProvidedMetaReducers);
}
function _provideForRootGuard() {
  const store = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(Store, {
    optional: true,
    skipSelf: true
  });
  if (store) {
    throw new TypeError(`The root Store has been provided more than once. Feature modules should provide feature states instead.`);
  }
  return 'guarded';
}
function immutabilityCheckMetaReducer(reducer, checks) {
  return function (state, action) {
    const act = checks.action(action) ? freeze(action) : action;
    const nextState = reducer(state, act);
    return checks.state() ? freeze(nextState) : nextState;
  };
}
function freeze(target) {
  Object.freeze(target);
  const targetIsFunction = isFunction(target);
  Object.getOwnPropertyNames(target).forEach(prop => {
    // Ignore Ivy properties, ref: https://github.com/ngrx/platform/issues/2109#issuecomment-582689060
    if (prop.startsWith('ɵ')) {
      return;
    }
    if (hasOwnProperty(target, prop) && (targetIsFunction ? prop !== 'caller' && prop !== 'callee' && prop !== 'arguments' : true)) {
      const propValue = target[prop];
      if ((isObjectLike(propValue) || isFunction(propValue)) && !Object.isFrozen(propValue)) {
        freeze(propValue);
      }
    }
  });
  return target;
}
function serializationCheckMetaReducer(reducer, checks) {
  return function (state, action) {
    if (checks.action(action)) {
      const unserializableAction = getUnserializable(action);
      throwIfUnserializable(unserializableAction, 'action');
    }
    const nextState = reducer(state, action);
    if (checks.state()) {
      const unserializableState = getUnserializable(nextState);
      throwIfUnserializable(unserializableState, 'state');
    }
    return nextState;
  };
}
function getUnserializable(target, path = []) {
  // Guard against undefined and null, e.g. a reducer that returns undefined
  if ((isUndefined(target) || isNull(target)) && path.length === 0) {
    return {
      path: ['root'],
      value: target
    };
  }
  const keys = Object.keys(target);
  return keys.reduce((result, key) => {
    if (result) {
      return result;
    }
    const value = target[key];
    // Ignore Ivy components
    if (isComponent(value)) {
      return result;
    }
    if (isUndefined(value) || isNull(value) || isNumber(value) || isBoolean(value) || isString(value) || isArray(value)) {
      return false;
    }
    if (isPlainObject(value)) {
      return getUnserializable(value, [...path, key]);
    }
    return {
      path: [...path, key],
      value
    };
  }, false);
}
function throwIfUnserializable(unserializable, context) {
  if (unserializable === false) {
    return;
  }
  const unserializablePath = unserializable.path.join('.');
  const error = new Error(`Detected unserializable ${context} at "${unserializablePath}". ${RUNTIME_CHECK_URL}#strict${context}serializability`);
  error.value = unserializable.value;
  error.unserializablePath = unserializablePath;
  throw error;
}
function inNgZoneAssertMetaReducer(reducer, checks) {
  return function (state, action) {
    if (checks.action(action) && !_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone.isInAngularZone()) {
      throw new Error(`Action '${action.type}' running outside NgZone. ${RUNTIME_CHECK_URL}#strictactionwithinngzone`);
    }
    return reducer(state, action);
  };
}
function createActiveRuntimeChecks(runtimeChecks) {
  if ((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.isDevMode)()) {
    return {
      strictStateSerializability: false,
      strictActionSerializability: false,
      strictStateImmutability: true,
      strictActionImmutability: true,
      strictActionWithinNgZone: false,
      strictActionTypeUniqueness: false,
      ...runtimeChecks
    };
  }
  return {
    strictStateSerializability: false,
    strictActionSerializability: false,
    strictStateImmutability: false,
    strictActionImmutability: false,
    strictActionWithinNgZone: false,
    strictActionTypeUniqueness: false
  };
}
function createSerializationCheckMetaReducer({
  strictActionSerializability,
  strictStateSerializability
}) {
  return reducer => strictActionSerializability || strictStateSerializability ? serializationCheckMetaReducer(reducer, {
    action: action => strictActionSerializability && !ignoreNgrxAction(action),
    state: () => strictStateSerializability
  }) : reducer;
}
function createImmutabilityCheckMetaReducer({
  strictActionImmutability,
  strictStateImmutability
}) {
  return reducer => strictActionImmutability || strictStateImmutability ? immutabilityCheckMetaReducer(reducer, {
    action: action => strictActionImmutability && !ignoreNgrxAction(action),
    state: () => strictStateImmutability
  }) : reducer;
}
function ignoreNgrxAction(action) {
  return action.type.startsWith('@ngrx');
}
function createInNgZoneCheckMetaReducer({
  strictActionWithinNgZone
}) {
  return reducer => strictActionWithinNgZone ? inNgZoneAssertMetaReducer(reducer, {
    action: action => strictActionWithinNgZone && !ignoreNgrxAction(action)
  }) : reducer;
}
function provideRuntimeChecks(runtimeChecks) {
  return [{
    provide: _USER_RUNTIME_CHECKS,
    useValue: runtimeChecks
  }, {
    provide: USER_RUNTIME_CHECKS,
    useFactory: _runtimeChecksFactory,
    deps: [_USER_RUNTIME_CHECKS]
  }, {
    provide: ACTIVE_RUNTIME_CHECKS,
    deps: [USER_RUNTIME_CHECKS],
    useFactory: createActiveRuntimeChecks
  }, {
    provide: META_REDUCERS,
    multi: true,
    deps: [ACTIVE_RUNTIME_CHECKS],
    useFactory: createImmutabilityCheckMetaReducer
  }, {
    provide: META_REDUCERS,
    multi: true,
    deps: [ACTIVE_RUNTIME_CHECKS],
    useFactory: createSerializationCheckMetaReducer
  }, {
    provide: META_REDUCERS,
    multi: true,
    deps: [ACTIVE_RUNTIME_CHECKS],
    useFactory: createInNgZoneCheckMetaReducer
  }];
}
function checkForActionTypeUniqueness() {
  return [{
    provide: _ACTION_TYPE_UNIQUENESS_CHECK,
    multi: true,
    deps: [ACTIVE_RUNTIME_CHECKS],
    useFactory: _actionTypeUniquenessCheck
  }];
}
function _runtimeChecksFactory(runtimeChecks) {
  return runtimeChecks;
}
function _actionTypeUniquenessCheck(config) {
  if (!config.strictActionTypeUniqueness) {
    return;
  }
  const duplicates = Object.entries(REGISTERED_ACTION_TYPES).filter(([, registrations]) => registrations > 1).map(([type]) => type);
  if (duplicates.length) {
    throw new Error(`Action types are registered more than once, ${duplicates.map(type => `"${type}"`).join(', ')}. ${RUNTIME_CHECK_URL}#strictactiontypeuniqueness`);
  }
}

/**
 * Provides additional slices of state in the Store.
 * These providers cannot be used at the component level.
 *
 * @usageNotes
 *
 * ### Providing Store Features
 *
 * ```ts
 * const booksRoutes: Route[] = [
 *   {
 *     path: '',
 *     providers: [provideState('books', booksReducer)],
 *     children: [
 *       { path: '', component: BookListComponent },
 *       { path: ':id', component: BookDetailsComponent },
 *     ],
 *   },
 * ];
 * ```
 */
function provideState(featureNameOrSlice, reducers, config = {}) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.makeEnvironmentProviders)([..._provideState(featureNameOrSlice, reducers, config), ENVIRONMENT_STATE_PROVIDER]);
}
function _provideStore(reducers = {}, config = {}) {
  return [{
    provide: _ROOT_STORE_GUARD,
    useFactory: _provideForRootGuard
  }, {
    provide: _INITIAL_STATE,
    useValue: config.initialState
  }, {
    provide: INITIAL_STATE,
    useFactory: _initialStateFactory,
    deps: [_INITIAL_STATE]
  }, {
    provide: _INITIAL_REDUCERS,
    useValue: reducers
  }, {
    provide: _STORE_REDUCERS,
    useExisting: reducers instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken ? reducers : _INITIAL_REDUCERS
  }, {
    provide: INITIAL_REDUCERS,
    deps: [_INITIAL_REDUCERS, [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject(_STORE_REDUCERS)]],
    useFactory: _createStoreReducers
  }, {
    provide: USER_PROVIDED_META_REDUCERS,
    useValue: config.metaReducers ? config.metaReducers : []
  }, {
    provide: _RESOLVED_META_REDUCERS,
    deps: [META_REDUCERS, USER_PROVIDED_META_REDUCERS],
    useFactory: _concatMetaReducers
  }, {
    provide: _REDUCER_FACTORY,
    useValue: config.reducerFactory ? config.reducerFactory : combineReducers
  }, {
    provide: REDUCER_FACTORY,
    deps: [_REDUCER_FACTORY, _RESOLVED_META_REDUCERS],
    useFactory: createReducerFactory
  }, ACTIONS_SUBJECT_PROVIDERS, REDUCER_MANAGER_PROVIDERS, SCANNED_ACTIONS_SUBJECT_PROVIDERS, STATE_PROVIDERS, STORE_PROVIDERS, provideRuntimeChecks(config.runtimeChecks), checkForActionTypeUniqueness()];
}
function rootStoreProviderFactory() {
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ActionsSubject);
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ReducerObservable);
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ScannedActionsSubject);
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(Store);
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_ROOT_STORE_GUARD, {
    optional: true
  });
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_ACTION_TYPE_UNIQUENESS_CHECK, {
    optional: true
  });
}
/**
 * Environment Initializer used in the root
 * providers to initialize the Store
 */
const ENVIRONMENT_STORE_PROVIDER = [{
  provide: ROOT_STORE_PROVIDER,
  useFactory: rootStoreProviderFactory
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ENVIRONMENT_INITIALIZER,
  multi: true,
  useFactory() {
    return () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ROOT_STORE_PROVIDER);
  }
}];
/**
 * Provides the global Store providers and initializes
 * the Store.
 * These providers cannot be used at the component level.
 *
 * @usageNotes
 *
 * ### Providing the Global Store
 *
 * ```ts
 * bootstrapApplication(AppComponent, {
 *   providers: [provideStore()],
 * });
 * ```
 */
function provideStore(reducers, config) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.makeEnvironmentProviders)([..._provideStore(reducers, config), ENVIRONMENT_STORE_PROVIDER]);
}
function featureStateProviderFactory() {
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ROOT_STORE_PROVIDER);
  const features = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_STORE_FEATURES);
  const featureReducers = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(FEATURE_REDUCERS);
  const reducerManager = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(ReducerManager);
  (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_ACTION_TYPE_UNIQUENESS_CHECK, {
    optional: true
  });
  const feats = features.map((feature, index) => {
    const featureReducerCollection = featureReducers.shift();
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    const reducers = featureReducerCollection /*TODO(#823)*/[index];
    return {
      ...feature,
      reducers,
      initialState: _initialStateFactory(feature.initialState)
    };
  });
  reducerManager.addFeatures(feats);
}
/**
 * Environment Initializer used in the feature
 * providers to register state features
 */
const ENVIRONMENT_STATE_PROVIDER = [{
  provide: FEATURE_STATE_PROVIDER,
  useFactory: featureStateProviderFactory
}, {
  provide: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ENVIRONMENT_INITIALIZER,
  multi: true,
  useFactory() {
    return () => (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(FEATURE_STATE_PROVIDER);
  }
}];
function _provideState(featureNameOrSlice, reducers, config = {}) {
  return [{
    provide: _FEATURE_CONFIGS,
    multi: true,
    useValue: featureNameOrSlice instanceof Object ? {} : config
  }, {
    provide: STORE_FEATURES,
    multi: true,
    useValue: {
      key: featureNameOrSlice instanceof Object ? featureNameOrSlice.name : featureNameOrSlice,
      reducerFactory: !(config instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken) && config.reducerFactory ? config.reducerFactory : combineReducers,
      metaReducers: !(config instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken) && config.metaReducers ? config.metaReducers : [],
      initialState: !(config instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken) && config.initialState ? config.initialState : undefined
    }
  }, {
    provide: _STORE_FEATURES,
    deps: [_FEATURE_CONFIGS, STORE_FEATURES],
    useFactory: _createFeatureStore
  }, {
    provide: _FEATURE_REDUCERS,
    multi: true,
    useValue: featureNameOrSlice instanceof Object ? featureNameOrSlice.reducer : reducers
  }, {
    provide: _FEATURE_REDUCERS_TOKEN,
    multi: true,
    useExisting: reducers instanceof _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken ? reducers : _FEATURE_REDUCERS
  }, {
    provide: FEATURE_REDUCERS,
    multi: true,
    deps: [_FEATURE_REDUCERS, [new _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject(_FEATURE_REDUCERS_TOKEN)]],
    useFactory: _createFeatureReducers
  }, checkForActionTypeUniqueness()];
}
class StoreRootModule {
  constructor(actions$, reducer$, scannedActions$, store, guard, actionCheck) {}
  /** @nocollapse */
  static {
    this.ɵfac = function StoreRootModule_Factory(t) {
      return new (t || StoreRootModule)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ReducerObservable), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ScannedActionsSubject), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](Store), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_ROOT_STORE_GUARD, 8), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_ACTION_TYPE_UNIQUENESS_CHECK, 8));
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: StoreRootModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](StoreRootModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{}]
  }], () => [{
    type: ActionsSubject
  }, {
    type: ReducerObservable
  }, {
    type: ScannedActionsSubject
  }, {
    type: Store
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_ROOT_STORE_GUARD]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_ACTION_TYPE_UNIQUENESS_CHECK]
    }]
  }], null);
})();
class StoreFeatureModule {
  constructor(features, featureReducers, reducerManager, root, actionCheck) {
    this.features = features;
    this.featureReducers = featureReducers;
    this.reducerManager = reducerManager;
    const feats = features.map((feature, index) => {
      const featureReducerCollection = featureReducers.shift();
      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      const reducers = featureReducerCollection /*TODO(#823)*/[index];
      return {
        ...feature,
        reducers,
        initialState: _initialStateFactory(feature.initialState)
      };
    });
    reducerManager.addFeatures(feats);
  }
  // eslint-disable-next-line @angular-eslint/contextual-lifecycle
  ngOnDestroy() {
    this.reducerManager.removeFeatures(this.features);
  }
  /** @nocollapse */
  static {
    this.ɵfac = function StoreFeatureModule_Factory(t) {
      return new (t || StoreFeatureModule)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_STORE_FEATURES), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](FEATURE_REDUCERS), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](ReducerManager), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](StoreRootModule), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_ACTION_TYPE_UNIQUENESS_CHECK, 8));
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: StoreFeatureModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](StoreFeatureModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{}]
  }], () => [{
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_STORE_FEATURES]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [FEATURE_REDUCERS]
    }]
  }, {
    type: ReducerManager
  }, {
    type: StoreRootModule
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Optional
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_ACTION_TYPE_UNIQUENESS_CHECK]
    }]
  }], null);
})();
class StoreModule {
  static forRoot(reducers, config) {
    return {
      ngModule: StoreRootModule,
      providers: [..._provideStore(reducers, config)]
    };
  }
  static forFeature(featureNameOrSlice, reducers, config = {}) {
    return {
      ngModule: StoreFeatureModule,
      providers: [..._provideState(featureNameOrSlice, reducers, config)]
    };
  }
  /** @nocollapse */
  static {
    this.ɵfac = function StoreModule_Factory(t) {
      return new (t || StoreModule)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: StoreModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](StoreModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{}]
  }], null, null);
})();

/**
 * @description
 * Associates actions with a given state change function.
 * A state change function must be provided as the last parameter.
 *
 * @param args `ActionCreator`'s followed by a state change function.
 *
 * @returns an association of action types with a state change function.
 *
 * @usageNotes
 * ```ts
 * on(AuthApiActions.loginSuccess, (state, { user }) => ({ ...state, user }))
 * ```
 */
function on(...args) {
  const reducer = args.pop();
  const types = args.map(creator => creator.type);
  return {
    reducer,
    types
  };
}
/**
 * @description
 * Creates a reducer function to handle state transitions.
 *
 * Reducer creators reduce the explicitness of reducer functions with switch statements.
 *
 * @param initialState Provides a state value if the current state is `undefined`, as it is initially.
 * @param ons Associations between actions and state changes.
 * @returns A reducer function.
 *
 * @usageNotes
 *
 * - Must be used with `ActionCreator`'s (returned by `createAction`). Cannot be used with class-based action creators.
 * - The returned `ActionReducer` does not require being wrapped with another function.
 *
 * **Declaring a reducer creator**
 *
 * ```ts
 * export const reducer = createReducer(
 *   initialState,
 *   on(
 *     featureActions.actionOne,
 *     featureActions.actionTwo,
 *     (state, { updatedValue }) => ({ ...state, prop: updatedValue })
 *   ),
 *   on(featureActions.actionThree, () => initialState);
 * );
 * ```
 */
function createReducer(initialState, ...ons) {
  const map = new Map();
  for (const on of ons) {
    for (const type of on.types) {
      const existingReducer = map.get(type);
      if (existingReducer) {
        const newReducer = (state, action) => on.reducer(existingReducer(state, action), action);
        map.set(type, newReducer);
      } else {
        map.set(type, on.reducer);
      }
    }
  }
  return function (state = initialState, action) {
    const reducer = map.get(action.type);
    return reducer ? reducer(state, action) : state;
  };
}

/**
 * DO NOT EDIT
 *
 * This file is automatically generated at build
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 90852:
/*!*******************************************************************************!*\
  !*** ./node_modules/@ngx-translate/core/dist/fesm2022/ngx-translate-core.mjs ***!
  \*******************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   DEFAULT_LANGUAGE: () => (/* binding */ DEFAULT_LANGUAGE),
/* harmony export */   FakeMissingTranslationHandler: () => (/* binding */ FakeMissingTranslationHandler),
/* harmony export */   MissingTranslationHandler: () => (/* binding */ MissingTranslationHandler),
/* harmony export */   TranslateCompiler: () => (/* binding */ TranslateCompiler),
/* harmony export */   TranslateDefaultParser: () => (/* binding */ TranslateDefaultParser),
/* harmony export */   TranslateDirective: () => (/* binding */ TranslateDirective),
/* harmony export */   TranslateFakeCompiler: () => (/* binding */ TranslateFakeCompiler),
/* harmony export */   TranslateFakeLoader: () => (/* binding */ TranslateFakeLoader),
/* harmony export */   TranslateLoader: () => (/* binding */ TranslateLoader),
/* harmony export */   TranslateModule: () => (/* binding */ TranslateModule),
/* harmony export */   TranslateParser: () => (/* binding */ TranslateParser),
/* harmony export */   TranslatePipe: () => (/* binding */ TranslatePipe),
/* harmony export */   TranslateService: () => (/* binding */ TranslateService),
/* harmony export */   TranslateStore: () => (/* binding */ TranslateStore),
/* harmony export */   USE_DEFAULT_LANG: () => (/* binding */ USE_DEFAULT_LANG),
/* harmony export */   USE_EXTEND: () => (/* binding */ USE_EXTEND),
/* harmony export */   USE_STORE: () => (/* binding */ USE_STORE)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! rxjs */ 59452);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! rxjs */ 72551);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! rxjs */ 61873);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! rxjs */ 44665);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! rxjs */ 137);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rxjs/operators */ 64334);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs/operators */ 86301);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! rxjs/operators */ 70271);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! rxjs/operators */ 51903);
/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! rxjs/operators */ 36647);




class TranslateLoader {}
/**
 * This loader is just a placeholder that does nothing, in case you don't need a loader at all
 */
class TranslateFakeLoader extends TranslateLoader {
  getTranslation(lang) {
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)({});
  }
  static ɵfac = /* @__PURE__ */(() => {
    let ɵTranslateFakeLoader_BaseFactory;
    return function TranslateFakeLoader_Factory(t) {
      return (ɵTranslateFakeLoader_BaseFactory || (ɵTranslateFakeLoader_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](TranslateFakeLoader)))(t || TranslateFakeLoader);
    };
  })();
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: TranslateFakeLoader,
    factory: TranslateFakeLoader.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateFakeLoader, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
class MissingTranslationHandler {}
/**
 * This handler is just a placeholder that does nothing, in case you don't need a missing translation handler at all
 */
class FakeMissingTranslationHandler {
  handle(params) {
    return params.key;
  }
  static ɵfac = function FakeMissingTranslationHandler_Factory(t) {
    return new (t || FakeMissingTranslationHandler)();
  };
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: FakeMissingTranslationHandler,
    factory: FakeMissingTranslationHandler.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FakeMissingTranslationHandler, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();

/* tslint:disable */
/**
 * Determines if two objects or two values are equivalent.
 *
 * Two objects or values are considered equivalent if at least one of the following is true:
 *
 * * Both objects or values pass `===` comparison.
 * * Both objects or values are of the same type and all of their properties are equal by
 *   comparing them with `equals`.
 *
 * @param o1 Object or value to compare.
 * @param o2 Object or value to compare.
 * @returns true if arguments are equal.
 */
function equals(o1, o2) {
  if (o1 === o2) return true;
  if (o1 === null || o2 === null) return false;
  if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
  let t1 = typeof o1,
    t2 = typeof o2,
    length,
    key,
    keySet;
  if (t1 == t2 && t1 == 'object') {
    if (Array.isArray(o1)) {
      if (!Array.isArray(o2)) return false;
      if ((length = o1.length) == o2.length) {
        for (key = 0; key < length; key++) {
          if (!equals(o1[key], o2[key])) return false;
        }
        return true;
      }
    } else {
      if (Array.isArray(o2)) {
        return false;
      }
      keySet = Object.create(null);
      for (key in o1) {
        if (!equals(o1[key], o2[key])) {
          return false;
        }
        keySet[key] = true;
      }
      for (key in o2) {
        if (!(key in keySet) && typeof o2[key] !== 'undefined') {
          return false;
        }
      }
      return true;
    }
  }
  return false;
}
/* tslint:enable */
function isDefined(value) {
  return typeof value !== 'undefined' && value !== null;
}
function isObject(item) {
  return item && typeof item === 'object' && !Array.isArray(item);
}
function mergeDeep(target, source) {
  let output = Object.assign({}, target);
  if (isObject(target) && isObject(source)) {
    Object.keys(source).forEach(key => {
      if (isObject(source[key])) {
        if (!(key in target)) {
          Object.assign(output, {
            [key]: source[key]
          });
        } else {
          output[key] = mergeDeep(target[key], source[key]);
        }
      } else {
        Object.assign(output, {
          [key]: source[key]
        });
      }
    });
  }
  return output;
}
class TranslateParser {}
class TranslateDefaultParser extends TranslateParser {
  templateMatcher = /{{\s?([^{}\s]*)\s?}}/g;
  interpolate(expr, params) {
    let result;
    if (typeof expr === 'string') {
      result = this.interpolateString(expr, params);
    } else if (typeof expr === 'function') {
      result = this.interpolateFunction(expr, params);
    } else {
      // this should not happen, but an unrelated TranslateService test depends on it
      result = expr;
    }
    return result;
  }
  getValue(target, key) {
    let keys = typeof key === 'string' ? key.split('.') : [key];
    key = '';
    do {
      key += keys.shift();
      if (isDefined(target) && isDefined(target[key]) && (typeof target[key] === 'object' || !keys.length)) {
        target = target[key];
        key = '';
      } else if (!keys.length) {
        target = undefined;
      } else {
        key += '.';
      }
    } while (keys.length);
    return target;
  }
  interpolateFunction(fn, params) {
    return fn(params);
  }
  interpolateString(expr, params) {
    if (!params) {
      return expr;
    }
    return expr.replace(this.templateMatcher, (substring, b) => {
      let r = this.getValue(params, b);
      return isDefined(r) ? r : substring;
    });
  }
  static ɵfac = /* @__PURE__ */(() => {
    let ɵTranslateDefaultParser_BaseFactory;
    return function TranslateDefaultParser_Factory(t) {
      return (ɵTranslateDefaultParser_BaseFactory || (ɵTranslateDefaultParser_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](TranslateDefaultParser)))(t || TranslateDefaultParser);
    };
  })();
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: TranslateDefaultParser,
    factory: TranslateDefaultParser.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateDefaultParser, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
class TranslateCompiler {}
/**
 * This compiler is just a placeholder that does nothing, in case you don't need a compiler at all
 */
class TranslateFakeCompiler extends TranslateCompiler {
  compile(value, lang) {
    return value;
  }
  compileTranslations(translations, lang) {
    return translations;
  }
  static ɵfac = /* @__PURE__ */(() => {
    let ɵTranslateFakeCompiler_BaseFactory;
    return function TranslateFakeCompiler_Factory(t) {
      return (ɵTranslateFakeCompiler_BaseFactory || (ɵTranslateFakeCompiler_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](TranslateFakeCompiler)))(t || TranslateFakeCompiler);
    };
  })();
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: TranslateFakeCompiler,
    factory: TranslateFakeCompiler.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateFakeCompiler, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
class TranslateStore {
  /**
   * The default lang to fallback when translations are missing on the current lang
   */
  defaultLang;
  /**
   * The lang currently used
   */
  currentLang = this.defaultLang;
  /**
   * a list of translations per lang
   */
  translations = {};
  /**
   * an array of langs
   */
  langs = [];
  /**
   * An EventEmitter to listen to translation change events
   * onTranslationChange.subscribe((params: TranslationChangeEvent) => {
     *     // do something
     * });
   */
  onTranslationChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  /**
   * An EventEmitter to listen to lang change events
   * onLangChange.subscribe((params: LangChangeEvent) => {
     *     // do something
     * });
   */
  onLangChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  /**
   * An EventEmitter to listen to default lang change events
   * onDefaultLangChange.subscribe((params: DefaultLangChangeEvent) => {
     *     // do something
     * });
   */
  onDefaultLangChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
}
const USE_STORE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('USE_STORE');
const USE_DEFAULT_LANG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('USE_DEFAULT_LANG');
const DEFAULT_LANGUAGE = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('DEFAULT_LANGUAGE');
const USE_EXTEND = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('USE_EXTEND');
class TranslateService {
  store;
  currentLoader;
  compiler;
  parser;
  missingTranslationHandler;
  useDefaultLang;
  isolate;
  extend;
  loadingTranslations;
  pending = false;
  _onTranslationChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  _onLangChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  _onDefaultLangChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  _defaultLang;
  _currentLang;
  _langs = [];
  _translations = {};
  _translationRequests = {};
  /**
   * An EventEmitter to listen to translation change events
   * onTranslationChange.subscribe((params: TranslationChangeEvent) => {
     *     // do something
     * });
   */
  get onTranslationChange() {
    return this.isolate ? this._onTranslationChange : this.store.onTranslationChange;
  }
  /**
   * An EventEmitter to listen to lang change events
   * onLangChange.subscribe((params: LangChangeEvent) => {
     *     // do something
     * });
   */
  get onLangChange() {
    return this.isolate ? this._onLangChange : this.store.onLangChange;
  }
  /**
   * An EventEmitter to listen to default lang change events
   * onDefaultLangChange.subscribe((params: DefaultLangChangeEvent) => {
     *     // do something
     * });
   */
  get onDefaultLangChange() {
    return this.isolate ? this._onDefaultLangChange : this.store.onDefaultLangChange;
  }
  /**
   * The default lang to fallback when translations are missing on the current lang
   */
  get defaultLang() {
    return this.isolate ? this._defaultLang : this.store.defaultLang;
  }
  set defaultLang(defaultLang) {
    if (this.isolate) {
      this._defaultLang = defaultLang;
    } else {
      this.store.defaultLang = defaultLang;
    }
  }
  /**
   * The lang currently used
   */
  get currentLang() {
    return this.isolate ? this._currentLang : this.store.currentLang;
  }
  set currentLang(currentLang) {
    if (this.isolate) {
      this._currentLang = currentLang;
    } else {
      this.store.currentLang = currentLang;
    }
  }
  /**
   * an array of langs
   */
  get langs() {
    return this.isolate ? this._langs : this.store.langs;
  }
  set langs(langs) {
    if (this.isolate) {
      this._langs = langs;
    } else {
      this.store.langs = langs;
    }
  }
  /**
   * a list of translations per lang
   */
  get translations() {
    return this.isolate ? this._translations : this.store.translations;
  }
  set translations(translations) {
    if (this.isolate) {
      this._translations = translations;
    } else {
      this.store.translations = translations;
    }
  }
  /**
   *
   * @param store an instance of the store (that is supposed to be unique)
   * @param currentLoader An instance of the loader currently used
   * @param compiler An instance of the compiler currently used
   * @param parser An instance of the parser currently used
   * @param missingTranslationHandler A handler for missing translations.
   * @param useDefaultLang whether we should use default language translation when current language translation is missing.
   * @param isolate whether this service should use the store or not
   * @param extend To make a child module extend (and use) translations from parent modules.
   * @param defaultLanguage Set the default language using configuration
   */
  constructor(store, currentLoader, compiler, parser, missingTranslationHandler, useDefaultLang = true, isolate = false, extend = false, defaultLanguage) {
    this.store = store;
    this.currentLoader = currentLoader;
    this.compiler = compiler;
    this.parser = parser;
    this.missingTranslationHandler = missingTranslationHandler;
    this.useDefaultLang = useDefaultLang;
    this.isolate = isolate;
    this.extend = extend;
    /** set the default language from configuration */
    if (defaultLanguage) {
      this.setDefaultLang(defaultLanguage);
    }
  }
  /**
   * Sets the default language to use as a fallback
   */
  setDefaultLang(lang) {
    if (lang === this.defaultLang) {
      return;
    }
    let pending = this.retrieveTranslations(lang);
    if (typeof pending !== "undefined") {
      // on init set the defaultLang immediately
      if (this.defaultLang == null) {
        this.defaultLang = lang;
      }
      pending.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.take)(1)).subscribe(res => {
        this.changeDefaultLang(lang);
      });
    } else {
      // we already have this language
      this.changeDefaultLang(lang);
    }
  }
  /**
   * Gets the default language used
   */
  getDefaultLang() {
    return this.defaultLang;
  }
  /**
   * Changes the lang currently used
   */
  use(lang) {
    // don't change the language if the language given is already selected
    if (lang === this.currentLang) {
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(this.translations[lang]);
    }
    let pending = this.retrieveTranslations(lang);
    if (typeof pending !== "undefined") {
      // on init set the currentLang immediately
      if (!this.currentLang) {
        this.currentLang = lang;
      }
      pending.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.take)(1)).subscribe(res => {
        this.changeLang(lang);
      });
      return pending;
    } else {
      // we have this language, return an Observable
      this.changeLang(lang);
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(this.translations[lang]);
    }
  }
  /**
   * Retrieves the given translations
   */
  retrieveTranslations(lang) {
    let pending;
    // if this language is unavailable or extend is true, ask for it
    if (typeof this.translations[lang] === "undefined" || this.extend) {
      this._translationRequests[lang] = this._translationRequests[lang] || this.getTranslation(lang);
      pending = this._translationRequests[lang];
    }
    return pending;
  }
  /**
   * Gets an object of translations for a given language with the current loader
   * and passes it through the compiler
   */
  getTranslation(lang) {
    this.pending = true;
    const loadingTranslations = this.currentLoader.getTranslation(lang).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.shareReplay)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.take)(1));
    this.loadingTranslations = loadingTranslations.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(res => this.compiler.compileTranslations(res, lang)), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_3__.shareReplay)(1), (0,rxjs_operators__WEBPACK_IMPORTED_MODULE_2__.take)(1));
    this.loadingTranslations.subscribe({
      next: res => {
        this.translations[lang] = this.extend && this.translations[lang] ? {
          ...res,
          ...this.translations[lang]
        } : res;
        this.updateLangs();
        this.pending = false;
      },
      error: err => {
        this.pending = false;
      }
    });
    return loadingTranslations;
  }
  /**
   * Manually sets an object of translations for a given language
   * after passing it through the compiler
   */
  setTranslation(lang, translations, shouldMerge = false) {
    translations = this.compiler.compileTranslations(translations, lang);
    if ((shouldMerge || this.extend) && this.translations[lang]) {
      this.translations[lang] = mergeDeep(this.translations[lang], translations);
    } else {
      this.translations[lang] = translations;
    }
    this.updateLangs();
    this.onTranslationChange.emit({
      lang: lang,
      translations: this.translations[lang]
    });
  }
  /**
   * Returns an array of currently available langs
   */
  getLangs() {
    return this.langs;
  }
  /**
   * Add available langs
   */
  addLangs(langs) {
    langs.forEach(lang => {
      if (this.langs.indexOf(lang) === -1) {
        this.langs.push(lang);
      }
    });
  }
  /**
   * Update the list of available langs
   */
  updateLangs() {
    this.addLangs(Object.keys(this.translations));
  }
  /**
   * Returns the parsed result of the translations
   */
  getParsedResult(translations, key, interpolateParams) {
    let res;
    if (key instanceof Array) {
      let result = {},
        observables = false;
      for (let k of key) {
        result[k] = this.getParsedResult(translations, k, interpolateParams);
        if ((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(result[k])) {
          observables = true;
        }
      }
      if (observables) {
        const sources = key.map(k => (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(result[k]) ? result[k] : (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(result[k]));
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_6__.forkJoin)(sources).pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_4__.map)(arr => {
          let obj = {};
          arr.forEach((value, index) => {
            obj[key[index]] = value;
          });
          return obj;
        }));
      }
      return result;
    }
    if (translations) {
      res = this.parser.interpolate(this.parser.getValue(translations, key), interpolateParams);
    }
    if (typeof res === "undefined" && this.defaultLang != null && this.defaultLang !== this.currentLang && this.useDefaultLang) {
      res = this.parser.interpolate(this.parser.getValue(this.translations[this.defaultLang], key), interpolateParams);
    }
    if (typeof res === "undefined") {
      let params = {
        key,
        translateService: this
      };
      if (typeof interpolateParams !== 'undefined') {
        params.interpolateParams = interpolateParams;
      }
      res = this.missingTranslationHandler.handle(params);
    }
    return typeof res !== "undefined" ? res : key;
  }
  /**
   * Gets the translated value of a key (or an array of keys)
   * @returns the translated key, or an object of translated keys
   */
  get(key, interpolateParams) {
    if (!isDefined(key) || !key.length) {
      throw new Error(`Parameter "key" required`);
    }
    // check if we are loading a new translation to use
    if (this.pending) {
      return this.loadingTranslations.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_7__.concatMap)(res => {
        res = this.getParsedResult(res, key, interpolateParams);
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res) ? res : (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(res);
      }));
    } else {
      let res = this.getParsedResult(this.translations[this.currentLang], key, interpolateParams);
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res) ? res : (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(res);
    }
  }
  /**
   * Returns a stream of translated values of a key (or an array of keys) which updates
   * whenever the translation changes.
   * @returns A stream of the translated key, or an object of translated keys
   */
  getStreamOnTranslationChange(key, interpolateParams) {
    if (!isDefined(key) || !key.length) {
      throw new Error(`Parameter "key" required`);
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.concat)((0,rxjs__WEBPACK_IMPORTED_MODULE_9__.defer)(() => this.get(key, interpolateParams)), this.onTranslationChange.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.switchMap)(event => {
      const res = this.getParsedResult(event.translations, key, interpolateParams);
      if (typeof res.subscribe === 'function') {
        return res;
      } else {
        return (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(res);
      }
    })));
  }
  /**
   * Returns a stream of translated values of a key (or an array of keys) which updates
   * whenever the language changes.
   * @returns A stream of the translated key, or an object of translated keys
   */
  stream(key, interpolateParams) {
    if (!isDefined(key) || !key.length) {
      throw new Error(`Parameter "key" required`);
    }
    return (0,rxjs__WEBPACK_IMPORTED_MODULE_8__.concat)((0,rxjs__WEBPACK_IMPORTED_MODULE_9__.defer)(() => this.get(key, interpolateParams)), this.onLangChange.pipe((0,rxjs_operators__WEBPACK_IMPORTED_MODULE_10__.switchMap)(event => {
      const res = this.getParsedResult(event.translations, key, interpolateParams);
      return (0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res) ? res : (0,rxjs__WEBPACK_IMPORTED_MODULE_0__.of)(res);
    })));
  }
  /**
   * Returns a translation instantly from the internal state of loaded translation.
   * All rules regarding the current language, the preferred language of even fallback languages will be used except any promise handling.
   */
  instant(key, interpolateParams) {
    if (!isDefined(key) || !key.length) {
      throw new Error(`Parameter "key" required`);
    }
    let res = this.getParsedResult(this.translations[this.currentLang], key, interpolateParams);
    if ((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res)) {
      if (key instanceof Array) {
        let obj = {};
        key.forEach((value, index) => {
          obj[key[index]] = key[index];
        });
        return obj;
      }
      return key;
    } else {
      return res;
    }
  }
  /**
   * Sets the translated value of a key, after compiling it
   */
  set(key, value, lang = this.currentLang) {
    this.translations[lang][key] = this.compiler.compile(value, lang);
    this.updateLangs();
    this.onTranslationChange.emit({
      lang: lang,
      translations: this.translations[lang]
    });
  }
  /**
   * Changes the current lang
   */
  changeLang(lang) {
    this.currentLang = lang;
    this.onLangChange.emit({
      lang: lang,
      translations: this.translations[lang]
    });
    // if there is no default lang, use the one that we just set
    if (this.defaultLang == null) {
      this.changeDefaultLang(lang);
    }
  }
  /**
   * Changes the default lang
   */
  changeDefaultLang(lang) {
    this.defaultLang = lang;
    this.onDefaultLangChange.emit({
      lang: lang,
      translations: this.translations[lang]
    });
  }
  /**
   * Allows to reload the lang file from the file
   */
  reloadLang(lang) {
    this.resetLang(lang);
    return this.getTranslation(lang);
  }
  /**
   * Deletes inner translation
   */
  resetLang(lang) {
    this._translationRequests[lang] = undefined;
    this.translations[lang] = undefined;
  }
  /**
   * Returns the language code name from the browser, e.g. "de"
   */
  getBrowserLang() {
    if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
      return undefined;
    }
    let browserLang = window.navigator.languages ? window.navigator.languages[0] : null;
    browserLang = browserLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
    if (typeof browserLang === 'undefined') {
      return undefined;
    }
    if (browserLang.indexOf('-') !== -1) {
      browserLang = browserLang.split('-')[0];
    }
    if (browserLang.indexOf('_') !== -1) {
      browserLang = browserLang.split('_')[0];
    }
    return browserLang;
  }
  /**
   * Returns the culture language code name from the browser, e.g. "de-DE"
   */
  getBrowserCultureLang() {
    if (typeof window === 'undefined' || typeof window.navigator === 'undefined') {
      return undefined;
    }
    let browserCultureLang = window.navigator.languages ? window.navigator.languages[0] : null;
    browserCultureLang = browserCultureLang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;
    return browserCultureLang;
  }
  static ɵfac = function TranslateService_Factory(t) {
    return new (t || TranslateService)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](TranslateStore), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](TranslateLoader), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](TranslateCompiler), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](TranslateParser), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](MissingTranslationHandler), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](USE_DEFAULT_LANG), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](USE_STORE), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](USE_EXTEND), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](DEFAULT_LANGUAGE));
  };
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: TranslateService,
    factory: TranslateService.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], function () {
    return [{
      type: TranslateStore
    }, {
      type: TranslateLoader
    }, {
      type: TranslateCompiler
    }, {
      type: TranslateParser
    }, {
      type: MissingTranslationHandler
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [USE_DEFAULT_LANG]
      }]
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [USE_STORE]
      }]
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [USE_EXTEND]
      }]
    }, {
      type: undefined,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [DEFAULT_LANGUAGE]
      }]
    }];
  }, null);
})();
class TranslateDirective {
  translateService;
  element;
  _ref;
  key;
  lastParams;
  currentParams;
  onLangChangeSub;
  onDefaultLangChangeSub;
  onTranslationChangeSub;
  set translate(key) {
    if (key) {
      this.key = key;
      this.checkNodes();
    }
  }
  set translateParams(params) {
    if (!equals(this.currentParams, params)) {
      this.currentParams = params;
      this.checkNodes(true);
    }
  }
  constructor(translateService, element, _ref) {
    this.translateService = translateService;
    this.element = element;
    this._ref = _ref;
    // subscribe to onTranslationChange event, in case the translations of the current lang change
    if (!this.onTranslationChangeSub) {
      this.onTranslationChangeSub = this.translateService.onTranslationChange.subscribe(event => {
        if (event.lang === this.translateService.currentLang) {
          this.checkNodes(true, event.translations);
        }
      });
    }
    // subscribe to onLangChange event, in case the language changes
    if (!this.onLangChangeSub) {
      this.onLangChangeSub = this.translateService.onLangChange.subscribe(event => {
        this.checkNodes(true, event.translations);
      });
    }
    // subscribe to onDefaultLangChange event, in case the default language changes
    if (!this.onDefaultLangChangeSub) {
      this.onDefaultLangChangeSub = this.translateService.onDefaultLangChange.subscribe(event => {
        this.checkNodes(true);
      });
    }
  }
  ngAfterViewChecked() {
    this.checkNodes();
  }
  checkNodes(forceUpdate = false, translations) {
    let nodes = this.element.nativeElement.childNodes;
    // if the element is empty
    if (!nodes.length) {
      // we add the key as content
      this.setContent(this.element.nativeElement, this.key);
      nodes = this.element.nativeElement.childNodes;
    }
    for (let i = 0; i < nodes.length; ++i) {
      let node = nodes[i];
      if (node.nodeType === 3) {
        // node type 3 is a text node
        let key;
        if (forceUpdate) {
          node.lastKey = null;
        }
        if (isDefined(node.lookupKey)) {
          key = node.lookupKey;
        } else if (this.key) {
          key = this.key;
        } else {
          let content = this.getContent(node);
          let trimmedContent = content.trim();
          if (trimmedContent.length) {
            node.lookupKey = trimmedContent;
            // we want to use the content as a key, not the translation value
            if (content !== node.currentValue) {
              key = trimmedContent;
              // the content was changed from the user, we'll use it as a reference if needed
              node.originalContent = content || node.originalContent;
            } else if (node.originalContent) {
              // the content seems ok, but the lang has changed
              // the current content is the translation, not the key, use the last real content as key
              key = node.originalContent.trim();
            } else if (content !== node.currentValue) {
              // we want to use the content as a key, not the translation value
              key = trimmedContent;
              // the content was changed from the user, we'll use it as a reference if needed
              node.originalContent = content || node.originalContent;
            }
          }
        }
        this.updateValue(key, node, translations);
      }
    }
  }
  updateValue(key, node, translations) {
    if (key) {
      if (node.lastKey === key && this.lastParams === this.currentParams) {
        return;
      }
      this.lastParams = this.currentParams;
      let onTranslation = res => {
        if (res !== key) {
          node.lastKey = key;
        }
        if (!node.originalContent) {
          node.originalContent = this.getContent(node);
        }
        node.currentValue = isDefined(res) ? res : node.originalContent || key;
        // we replace in the original content to preserve spaces that we might have trimmed
        this.setContent(node, this.key ? node.currentValue : node.originalContent.replace(key, node.currentValue));
        this._ref.markForCheck();
      };
      if (isDefined(translations)) {
        let res = this.translateService.getParsedResult(translations, key, this.currentParams);
        if ((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res)) {
          res.subscribe({
            next: onTranslation
          });
        } else {
          onTranslation(res);
        }
      } else {
        this.translateService.get(key, this.currentParams).subscribe(onTranslation);
      }
    }
  }
  getContent(node) {
    return isDefined(node.textContent) ? node.textContent : node.data;
  }
  setContent(node, content) {
    if (isDefined(node.textContent)) {
      node.textContent = content;
    } else {
      node.data = content;
    }
  }
  ngOnDestroy() {
    if (this.onLangChangeSub) {
      this.onLangChangeSub.unsubscribe();
    }
    if (this.onDefaultLangChangeSub) {
      this.onDefaultLangChangeSub.unsubscribe();
    }
    if (this.onTranslationChangeSub) {
      this.onTranslationChangeSub.unsubscribe();
    }
  }
  static ɵfac = function TranslateDirective_Factory(t) {
    return new (t || TranslateDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](TranslateService), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef));
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
    type: TranslateDirective,
    selectors: [["", "translate", ""], ["", "ngx-translate", ""]],
    inputs: {
      translate: "translate",
      translateParams: "translateParams"
    }
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[translate],[ngx-translate]'
    }]
  }], function () {
    return [{
      type: TranslateService
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef
    }];
  }, {
    translate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    translateParams: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }]
  });
})();
class TranslatePipe {
  translate;
  _ref;
  value = '';
  lastKey = null;
  lastParams = [];
  onTranslationChange;
  onLangChange;
  onDefaultLangChange;
  constructor(translate, _ref) {
    this.translate = translate;
    this._ref = _ref;
  }
  updateValue(key, interpolateParams, translations) {
    let onTranslation = res => {
      this.value = res !== undefined ? res : key;
      this.lastKey = key;
      this._ref.markForCheck();
    };
    if (translations) {
      let res = this.translate.getParsedResult(translations, key, interpolateParams);
      if ((0,rxjs__WEBPACK_IMPORTED_MODULE_5__.isObservable)(res.subscribe)) {
        res.subscribe(onTranslation);
      } else {
        onTranslation(res);
      }
    }
    this.translate.get(key, interpolateParams).subscribe(onTranslation);
  }
  transform(query, ...args) {
    if (!query || !query.length) {
      return query;
    }
    // if we ask another time for the same key, return the last value
    if (equals(query, this.lastKey) && equals(args, this.lastParams)) {
      return this.value;
    }
    let interpolateParams = undefined;
    if (isDefined(args[0]) && args.length) {
      if (typeof args[0] === 'string' && args[0].length) {
        // we accept objects written in the template such as {n:1}, {'n':1}, {n:'v'}
        // which is why we might need to change it to real JSON objects such as {"n":1} or {"n":"v"}
        let validArgs = args[0].replace(/(\')?([a-zA-Z0-9_]+)(\')?(\s)?:/g, '"$2":').replace(/:(\s)?(\')(.*?)(\')/g, ':"$3"');
        try {
          interpolateParams = JSON.parse(validArgs);
        } catch (e) {
          throw new SyntaxError(`Wrong parameter in TranslatePipe. Expected a valid Object, received: ${args[0]}`);
        }
      } else if (typeof args[0] === 'object' && !Array.isArray(args[0])) {
        interpolateParams = args[0];
      }
    }
    // store the query, in case it changes
    this.lastKey = query;
    // store the params, in case they change
    this.lastParams = args;
    // set the value
    this.updateValue(query, interpolateParams);
    // if there is a subscription to onLangChange, clean it
    this._dispose();
    // subscribe to onTranslationChange event, in case the translations change
    if (!this.onTranslationChange) {
      this.onTranslationChange = this.translate.onTranslationChange.subscribe(event => {
        if (this.lastKey && event.lang === this.translate.currentLang) {
          this.lastKey = null;
          this.updateValue(query, interpolateParams, event.translations);
        }
      });
    }
    // subscribe to onLangChange event, in case the language changes
    if (!this.onLangChange) {
      this.onLangChange = this.translate.onLangChange.subscribe(event => {
        if (this.lastKey) {
          this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
          this.updateValue(query, interpolateParams, event.translations);
        }
      });
    }
    // subscribe to onDefaultLangChange event, in case the default language changes
    if (!this.onDefaultLangChange) {
      this.onDefaultLangChange = this.translate.onDefaultLangChange.subscribe(() => {
        if (this.lastKey) {
          this.lastKey = null; // we want to make sure it doesn't return the same value until it's been updated
          this.updateValue(query, interpolateParams);
        }
      });
    }
    return this.value;
  }
  /**
   * Clean any existing subscription to change events
   */
  _dispose() {
    if (typeof this.onTranslationChange !== 'undefined') {
      this.onTranslationChange.unsubscribe();
      this.onTranslationChange = undefined;
    }
    if (typeof this.onLangChange !== 'undefined') {
      this.onLangChange.unsubscribe();
      this.onLangChange = undefined;
    }
    if (typeof this.onDefaultLangChange !== 'undefined') {
      this.onDefaultLangChange.unsubscribe();
      this.onDefaultLangChange = undefined;
    }
  }
  ngOnDestroy() {
    this._dispose();
  }
  static ɵfac = function TranslatePipe_Factory(t) {
    return new (t || TranslatePipe)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](TranslateService, 16), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef, 16));
  };
  static ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefinePipe"]({
    name: "translate",
    type: TranslatePipe,
    pure: false
  });
  static ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
    token: TranslatePipe,
    factory: TranslatePipe.ɵfac
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslatePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Pipe,
    args: [{
      name: 'translate',
      pure: false // required to update the value when the promise is resolved
    }]
  }], function () {
    return [{
      type: TranslateService
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectorRef
    }];
  }, null);
})();
class TranslateModule {
  /**
   * Use this method in your root module to provide the TranslateService
   */
  static forRoot(config = {}) {
    return {
      ngModule: TranslateModule,
      providers: [config.loader || {
        provide: TranslateLoader,
        useClass: TranslateFakeLoader
      }, config.compiler || {
        provide: TranslateCompiler,
        useClass: TranslateFakeCompiler
      }, config.parser || {
        provide: TranslateParser,
        useClass: TranslateDefaultParser
      }, config.missingTranslationHandler || {
        provide: MissingTranslationHandler,
        useClass: FakeMissingTranslationHandler
      }, TranslateStore, {
        provide: USE_STORE,
        useValue: config.isolate
      }, {
        provide: USE_DEFAULT_LANG,
        useValue: config.useDefaultLang
      }, {
        provide: USE_EXTEND,
        useValue: config.extend
      }, {
        provide: DEFAULT_LANGUAGE,
        useValue: config.defaultLanguage
      }, TranslateService]
    };
  }
  /**
   * Use this method in your other (non root) modules to import the directive/pipe
   */
  static forChild(config = {}) {
    return {
      ngModule: TranslateModule,
      providers: [config.loader || {
        provide: TranslateLoader,
        useClass: TranslateFakeLoader
      }, config.compiler || {
        provide: TranslateCompiler,
        useClass: TranslateFakeCompiler
      }, config.parser || {
        provide: TranslateParser,
        useClass: TranslateDefaultParser
      }, config.missingTranslationHandler || {
        provide: MissingTranslationHandler,
        useClass: FakeMissingTranslationHandler
      }, {
        provide: USE_STORE,
        useValue: config.isolate
      }, {
        provide: USE_DEFAULT_LANG,
        useValue: config.useDefaultLang
      }, {
        provide: USE_EXTEND,
        useValue: config.extend
      }, {
        provide: DEFAULT_LANGUAGE,
        useValue: config.defaultLanguage
      }, TranslateService]
    };
  }
  static ɵfac = function TranslateModule_Factory(t) {
    return new (t || TranslateModule)();
  };
  static ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
    type: TranslateModule
  });
  static ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](TranslateModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      declarations: [TranslatePipe, TranslateDirective],
      exports: [TranslatePipe, TranslateDirective]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 18952:
/*!*********************************************************************************************!*\
  !*** ./node_modules/@ngx-translate/http-loader/dist/fesm2022/ngx-translate-http-loader.mjs ***!
  \*********************************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   TranslateHttpLoader: () => (/* binding */ TranslateHttpLoader)
/* harmony export */ });
class TranslateHttpLoader {
  http;
  prefix;
  suffix;
  constructor(http, prefix = "/assets/i18n/", suffix = ".json") {
    this.http = http;
    this.prefix = prefix;
    this.suffix = suffix;
  }
  /**
   * Gets the translations from the server
   */
  getTranslation(lang) {
    return this.http.get(`${this.prefix}${lang}${this.suffix}`);
  }
}

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 51595:
/*!*************************************************************************!*\
  !*** ./node_modules/angularx-flatpickr/fesm2020/angularx-flatpickr.mjs ***!
  \*************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   FlatpickrDefaults: () => (/* binding */ FlatpickrDefaults),
/* harmony export */   FlatpickrDirective: () => (/* binding */ FlatpickrDirective),
/* harmony export */   FlatpickrModule: () => (/* binding */ FlatpickrModule),
/* harmony export */   USER_DEFAULTS: () => (/* binding */ USER_DEFAULTS),
/* harmony export */   defaultsFactory: () => (/* binding */ defaultsFactory)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/forms */ 34456);
/* harmony import */ var flatpickr__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! flatpickr */ 61788);




class FlatpickrDefaults {
  constructor() {
    /**
     * Exactly the same as date format, but for the altInput field.
     */
    this.altFormat = 'F j, Y';
    /**
     * 	Show the user a readable date (as per altFormat), but return something totally different to the server.
     */
    this.altInput = false;
    /**
     * This class will be added to the input element created by the altInput option.
     * Note that `altInput` already inherits classes from the original input.
     */
    this.altInputClass = '';
    /**
     * Allows the user to enter a date directly input the input field. By default, direct entry is disabled.
     */
    this.allowInput = false;
    /**
     * Allows the preloading of an invalid date. When disabled, the field will be cleared if the provided date is invalid
     */
    this.allowInvalidPreload = false;
    /**
     * Instead of `body`, appends the calendar to the specified node instead.
     */
    this.appendTo = undefined;
    /**
     * Defines how the date will be formatted in the aria-label for calendar days, using the same tokens as dateFormat. If you change this, you should choose a value that will make sense if a screen reader reads it out loud.
     */
    this.ariaDateFormat = 'F j, Y';
    /**
     * Whether clicking on the input should open the picker.
     * You could disable this if you wish to open the calendar manually `with.open()`.
     */
    this.clickOpens = true;
    /**
     * A string of characters which are used to define how the date will be displayed in the input box.
     * The supported characters are defined in the table below.
     */
    this.dateFormat = 'Y-m-d';
    /**
     * Initial value of the hour element.
     */
    this.defaultHour = 12;
    /**
     * Initial value of the minute element.
     */
    this.defaultMinute = 0;
    /**
     * Initial value of the seconds element.
     */
    this.defaultSeconds = 0;
    /**
     * See <a href="https://chmln.github.io/flatpickr/examples/#disabling-specific-dates">disabling dates</a>.
     */
    this.disable = [];
    /**
     * Set disableMobile to true to always use the non-native picker.
     * By default, Flatpickr utilizes native datetime widgets unless certain options (e.g. disable) are used.
     */
    this.disableMobile = false;
    /**
     * Enables time picker.
     */
    this.enableTime = false;
    /**
     * Enables seconds in the time picker.
     */
    this.enableSeconds = false;
    /**
     * Allows using a custom date formatting function instead of the built-in handling for date formats using dateFormat, altFormat, etc.
     */
    this.formatDate = undefined;
    /**
     * Adjusts the step for the hour input (incl. scrolling).
     */
    this.hourIncrement = 1;
    /**
     * Displays the calendar inline.
     */
    this.inline = false;
    /**
     * The maximum date that a user can pick to (inclusive).
     */
    this.maxDate = undefined;
    /**
     * The minimum date that a user can start picking from (inclusive).
     */
    this.minDate = undefined;
    /**
     * The maximum time that a user can pick to (inclusive).
     */
    this.maxTime = undefined;
    /**
     * The minimum time that a user can start picking from (inclusive).
     */
    this.minTime = undefined;
    /**
     * Adjusts the step for the minute input (incl. scrolling).
     */
    this.minuteIncrement = 5;
    /**
     * Select a single date, multiple dates or a date range.
     */
    this.mode = 'single';
    /**
     * HTML for the arrow icon, used to switch months.
     */
    this.nextArrow = '>';
    /**
     * Hides the day selection in calendar. Use it along with `enableTime` to create a time picker.
     */
    this.noCalendar = false;
    /**
     * Default now to the current date
     */
    this.now = new Date();
    /**
     * HTML for the left arrow icon.
     */
    this.prevArrow = '<';
    /**
     * Show the month using the shorthand version (ie, Sep instead of September).
     */
    this.shorthandCurrentMonth = false;
    /**
     * Position the calendar inside the wrapper and next to the input element. (Leave `false` unless you know what you're doing).
     */
    this.static = false;
    /**
     * Displays time picker in 24 hour mode without AM/PM selection when enabled.
     */
    this.time24hr = false;
    /**
     * When true, dates will parsed, formatted, and displayed in UTC.
     * It's recommended that date strings contain the timezone, but not necessary.
     */
    this.utc = false;
    /**
     * Enables display of week numbers in calendar.
     */
    this.weekNumbers = false;
    /**
     * Custom elements and input groups.
     */
    this.wrap = false;
    /**
     * Array of plugin instances to use.
     */
    this.plugins = [];
    /**
     * The locale object or string to use for the locale.
     */
    this.locale = 'default';
    /**
     * Auto convert the ngModel value from a string to a date / array of dates / from - to date object depending on the `mode`
     */
    this.convertModelValue = false;
    /**
     * The number of months shown.
     */
    this.showMonths = 1;
    /**
     * How the month should be displayed in the header of the calendar.
     */
    this.monthSelectorType = 'static';
    /**
     * Array of HTML elements that should not close the picker on click.
     */
    this.ignoredFocusElements = [];
  }
}
FlatpickrDefaults.ɵfac = function FlatpickrDefaults_Factory(t) {
  return new (t || FlatpickrDefaults)();
};
FlatpickrDefaults.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
  token: FlatpickrDefaults,
  factory: FlatpickrDefaults.ɵfac
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FlatpickrDefaults, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
const FLATPICKR_CONTROL_VALUE_ACCESSOR = {
  provide: _angular_forms__WEBPACK_IMPORTED_MODULE_2__.NG_VALUE_ACCESSOR,
  useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.forwardRef)(() => FlatpickrDirective),
  multi: true
};
class FlatpickrDirective {
  constructor(elm, defaults, renderer) {
    this.elm = elm;
    this.defaults = defaults;
    this.renderer = renderer;
    /**
     * Object-options that can be user for multiple instances of Flatpickr.
     * Option from this object is applied only if specific option is not specified.
     * Example:
     * ```typescript
     * options: FlatpickrDefaultsInterface = {
     *      altFormat: 'd/m/Y',   // will be ignored since altFormat is provided via specific attribute
     *      altInput: true        // will be used since specific attribute is not provided
     * };
     * ```
     * ```html
     * <input
     *   class="form-control"
     *   type="text"
     *   mwlFlatpickr
     *   [options]="options"
     *   altFormat="d/m/Y">
     * ```
     */
    this.options = {};
    /**
     * Array of HTML elements that should not close the picker on click.
     */
    this.ignoredFocusElements = [];
    /**
     * Gets triggered once the calendar is in a ready state
     */
    this.flatpickrReady = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the user selects a date, or changes the time on a selected date.
     */
    this.flatpickrChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the input value is updated with a new date string.
     */
    this.flatpickrValueUpdate = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the calendar is opened.
     */
    this.flatpickrOpen = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the calendar is closed.
     */
    this.flatpickrClose = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the month is changed, either by the user or programmatically.
     */
    this.flatpickrMonthChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Gets triggered when the year is changed, either by the user or programmatically.
     */
    this.flatpickrYearChange = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    /**
     * Take full control of every date cell with this output
     */
    this.flatpickrDayCreate = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.isDisabled = false;
    this.onChangeFn = () => {};
    this.onTouchedFn = () => {};
  }
  ngAfterViewInit() {
    const options = {
      altFormat: this.altFormat,
      altInput: this.altInput,
      altInputClass: this.altInputClass,
      allowInput: this.allowInput,
      allowInvalidPreload: this.allowInvalidPreload,
      appendTo: this.appendTo,
      ariaDateFormat: this.ariaDateFormat,
      clickOpens: this.clickOpens,
      dateFormat: this.dateFormat,
      defaultHour: this.defaultHour,
      defaultMinute: this.defaultMinute,
      defaultSeconds: this.defaultSeconds,
      disable: this.disable,
      disableMobile: this.disableMobile,
      enable: this.enable,
      enableTime: this.enableTime,
      enableSeconds: this.enableSeconds,
      formatDate: this.formatDate,
      hourIncrement: this.hourIncrement,
      defaultDate: this.initialValue,
      inline: this.inline,
      maxDate: this.maxDate,
      minDate: this.minDate,
      maxTime: this.maxTime,
      minTime: this.minTime,
      minuteIncrement: this.minuteIncrement,
      mode: this.mode,
      nextArrow: this.nextArrow,
      noCalendar: this.noCalendar,
      now: this.now,
      parseDate: this.parseDate,
      prevArrow: this.prevArrow,
      shorthandCurrentMonth: this.shorthandCurrentMonth,
      showMonths: this.showMonths,
      monthSelectorType: this.monthSelectorType,
      static: this.static,
      time24hr: this.time24hr,
      weekNumbers: this.weekNumbers,
      getWeek: this.getWeek,
      wrap: this.wrap,
      plugins: this.plugins,
      locale: this.locale,
      ignoredFocusElements: this.ignoredFocusElements,
      onChange: (selectedDates, dateString, instance) => {
        this.flatpickrChange.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onOpen: (selectedDates, dateString, instance) => {
        this.flatpickrOpen.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onClose: (selectedDates, dateString, instance) => {
        this.flatpickrClose.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onMonthChange: (selectedDates, dateString, instance) => {
        this.flatpickrMonthChange.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onYearChange: (selectedDates, dateString, instance) => {
        this.flatpickrYearChange.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onReady: (selectedDates, dateString, instance) => {
        this.flatpickrReady.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onValueUpdate: (selectedDates, dateString, instance) => {
        this.flatpickrValueUpdate.emit({
          selectedDates,
          dateString,
          instance
        });
      },
      onDayCreate: (selectedDates, dateString, instance, dayElement) => {
        this.flatpickrDayCreate.emit({
          selectedDates,
          dateString,
          instance,
          dayElement
        });
      }
    };
    Object.keys(options).forEach(key => {
      if (typeof options[key] === 'undefined') {
        if (typeof this.options[key] !== 'undefined') {
          options[key] = this.options[key];
        } else {
          options[key] = this.defaults[key];
        }
      }
    });
    // @ts-ignore
    options.time_24hr = options.time24hr;
    // workaround bug in flatpickr 4.6 where it doesn't copy the classes across
    // TODO - remove once fix in https://github.com/flatpickr/flatpickr/issues/1860 is released
    options.altInputClass = (options.altInputClass || '') + ' ' + this.elm.nativeElement.className;
    if (!options.enable) {
      delete options.enable;
    }
    this.instance = (0,flatpickr__WEBPACK_IMPORTED_MODULE_0__["default"])(this.elm.nativeElement, options);
    this.setDisabledState(this.isDisabled);
  }
  ngOnChanges(changes) {
    if (this.instance) {
      Object.keys(changes).forEach(inputKey => {
        this.instance.set(inputKey, this[inputKey]);
      });
    }
  }
  ngOnDestroy() {
    if (this.instance) {
      this.instance.destroy();
    }
  }
  writeValue(value) {
    let convertedValue = value;
    if (this.convertModelValue && this.mode === 'range' && value) {
      convertedValue = [value.from, value.to];
    }
    if (this.instance) {
      this.instance.setDate(convertedValue);
    } else {
      // flatpickr hasn't been initialised yet, store the value for later use
      this.initialValue = convertedValue;
    }
  }
  registerOnChange(fn) {
    this.onChangeFn = fn;
  }
  registerOnTouched(fn) {
    this.onTouchedFn = fn;
  }
  setDisabledState(isDisabled) {
    this.isDisabled = isDisabled;
    if (this.instance) {
      if (this.isDisabled) {
        this.renderer.setProperty(this.instance._input, 'disabled', 'disabled');
      } else {
        this.renderer.removeAttribute(this.instance._input, 'disabled');
      }
    }
  }
  inputChanged() {
    const value = this.elm.nativeElement.value;
    if (this.convertModelValue && typeof value === 'string') {
      switch (this.mode) {
        case 'multiple':
          const dates = value.split('; ').map(str => this.instance.parseDate(str, this.instance.config.dateFormat, !this.instance.config.enableTime));
          this.onChangeFn(dates);
          break;
        case 'range':
          const [from, to] = value.split(this.instance.l10n.rangeSeparator).map(str => this.instance.parseDate(str, this.instance.config.dateFormat, !this.instance.config.enableTime));
          this.onChangeFn({
            from,
            to
          });
          break;
        case 'single':
        default:
          this.onChangeFn(this.instance.parseDate(value, this.instance.config.dateFormat, !this.instance.config.enableTime));
      }
    } else {
      this.onChangeFn(value);
    }
  }
}
FlatpickrDirective.ɵfac = function FlatpickrDirective_Factory(t) {
  return new (t || FlatpickrDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](FlatpickrDefaults), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2));
};
FlatpickrDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
  type: FlatpickrDirective,
  selectors: [["", "mwlFlatpickr", ""]],
  hostBindings: function FlatpickrDirective_HostBindings(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("blur", function FlatpickrDirective_blur_HostBindingHandler() {
        return ctx.onTouchedFn();
      })("input", function FlatpickrDirective_input_HostBindingHandler() {
        return ctx.inputChanged();
      });
    }
  },
  inputs: {
    options: "options",
    altFormat: "altFormat",
    altInput: "altInput",
    altInputClass: "altInputClass",
    allowInput: "allowInput",
    allowInvalidPreload: "allowInvalidPreload",
    appendTo: "appendTo",
    ariaDateFormat: "ariaDateFormat",
    clickOpens: "clickOpens",
    dateFormat: "dateFormat",
    defaultHour: "defaultHour",
    defaultMinute: "defaultMinute",
    defaultSeconds: "defaultSeconds",
    disable: "disable",
    disableMobile: "disableMobile",
    enable: "enable",
    enableTime: "enableTime",
    enableSeconds: "enableSeconds",
    formatDate: "formatDate",
    hourIncrement: "hourIncrement",
    inline: "inline",
    maxDate: "maxDate",
    minDate: "minDate",
    maxTime: "maxTime",
    minTime: "minTime",
    minuteIncrement: "minuteIncrement",
    mode: "mode",
    nextArrow: "nextArrow",
    noCalendar: "noCalendar",
    now: "now",
    parseDate: "parseDate",
    prevArrow: "prevArrow",
    shorthandCurrentMonth: "shorthandCurrentMonth",
    showMonths: "showMonths",
    static: "static",
    time24hr: "time24hr",
    weekNumbers: "weekNumbers",
    getWeek: "getWeek",
    wrap: "wrap",
    plugins: "plugins",
    locale: "locale",
    convertModelValue: "convertModelValue",
    monthSelectorType: "monthSelectorType",
    ignoredFocusElements: "ignoredFocusElements"
  },
  outputs: {
    flatpickrReady: "flatpickrReady",
    flatpickrChange: "flatpickrChange",
    flatpickrValueUpdate: "flatpickrValueUpdate",
    flatpickrOpen: "flatpickrOpen",
    flatpickrClose: "flatpickrClose",
    flatpickrMonthChange: "flatpickrMonthChange",
    flatpickrYearChange: "flatpickrYearChange",
    flatpickrDayCreate: "flatpickrDayCreate"
  },
  exportAs: ["mwlFlatpickr"],
  features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([FLATPICKR_CONTROL_VALUE_ACCESSOR]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FlatpickrDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[mwlFlatpickr]',
      providers: [FLATPICKR_CONTROL_VALUE_ACCESSOR],
      exportAs: 'mwlFlatpickr'
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: FlatpickrDefaults
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2
    }];
  }, {
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    altFormat: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    altInput: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    altInputClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    allowInput: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    allowInvalidPreload: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    appendTo: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    ariaDateFormat: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    clickOpens: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    dateFormat: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    defaultHour: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    defaultMinute: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    defaultSeconds: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    disable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    disableMobile: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    enable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    enableTime: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    enableSeconds: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    formatDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    hourIncrement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    inline: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    maxDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    minDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    maxTime: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    minTime: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    minuteIncrement: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    mode: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    nextArrow: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    noCalendar: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    now: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    parseDate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    prevArrow: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    shorthandCurrentMonth: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    showMonths: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    static: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    time24hr: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    weekNumbers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    getWeek: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    wrap: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    plugins: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    locale: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    convertModelValue: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    monthSelectorType: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    ignoredFocusElements: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    flatpickrReady: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrValueUpdate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrOpen: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrClose: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrMonthChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrYearChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    flatpickrDayCreate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    onTouchedFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['blur']
    }],
    inputChanged: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['input']
    }]
  });
})();
const USER_DEFAULTS = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('flatpickr defaults');
function defaultsFactory(userDefaults) {
  const defaults = new FlatpickrDefaults();
  Object.assign(defaults, userDefaults);
  return defaults;
}
class FlatpickrModule {
  static forRoot(userDefaults = {}) {
    return {
      ngModule: FlatpickrModule,
      providers: [{
        provide: USER_DEFAULTS,
        useValue: userDefaults
      }, {
        provide: FlatpickrDefaults,
        useFactory: defaultsFactory,
        deps: [USER_DEFAULTS]
      }]
    };
  }
}
FlatpickrModule.ɵfac = function FlatpickrModule_Factory(t) {
  return new (t || FlatpickrModule)();
};
FlatpickrModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
  type: FlatpickrModule
});
FlatpickrModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FlatpickrModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      declarations: [FlatpickrDirective],
      exports: [FlatpickrDirective]
    }]
  }], null, null);
})();

/*
 * Public API Surface of angularx-flatpickr
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 87160:
/*!********************************************************!*\
  !*** ./node_modules/date-fns/_lib/addLeadingZeros.mjs ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   addLeadingZeros: () => (/* binding */ addLeadingZeros)
/* harmony export */ });
function addLeadingZeros(number, targetLength) {
  const sign = number < 0 ? "-" : "";
  const output = Math.abs(number).toString().padStart(targetLength, "0");
  return sign + output;
}

/***/ }),

/***/ 19857:
/*!*******************************************************!*\
  !*** ./node_modules/date-fns/_lib/defaultOptions.mjs ***!
  \*******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   getDefaultOptions: () => (/* binding */ getDefaultOptions),
/* harmony export */   setDefaultOptions: () => (/* binding */ setDefaultOptions)
/* harmony export */ });
let defaultOptions = {};
function getDefaultOptions() {
  return defaultOptions;
}
function setDefaultOptions(newOptions) {
  defaultOptions = newOptions;
}

/***/ }),

/***/ 70223:
/*!**********************************************************!*\
  !*** ./node_modules/date-fns/_lib/format/formatters.mjs ***!
  \**********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatters: () => (/* binding */ formatters)
/* harmony export */ });
/* harmony import */ var _getDayOfYear_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../getDayOfYear.mjs */ 57);
/* harmony import */ var _getISOWeek_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../getISOWeek.mjs */ 27308);
/* harmony import */ var _getISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../getISOWeekYear.mjs */ 31359);
/* harmony import */ var _getWeek_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../getWeek.mjs */ 88245);
/* harmony import */ var _getWeekYear_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../getWeekYear.mjs */ 21598);
/* harmony import */ var _addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../addLeadingZeros.mjs */ 87160);
/* harmony import */ var _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./lightFormatters.mjs */ 91115);







const dayPeriodEnum = {
  am: "am",
  pm: "pm",
  midnight: "midnight",
  noon: "noon",
  morning: "morning",
  afternoon: "afternoon",
  evening: "evening",
  night: "night"
};

/*
 * |     | Unit                           |     | Unit                           |
 * |-----|--------------------------------|-----|--------------------------------|
 * |  a  | AM, PM                         |  A* | Milliseconds in day            |
 * |  b  | AM, PM, noon, midnight         |  B  | Flexible day period            |
 * |  c  | Stand-alone local day of week  |  C* | Localized hour w/ day period   |
 * |  d  | Day of month                   |  D  | Day of year                    |
 * |  e  | Local day of week              |  E  | Day of week                    |
 * |  f  |                                |  F* | Day of week in month           |
 * |  g* | Modified Julian day            |  G  | Era                            |
 * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |
 * |  i! | ISO day of week                |  I! | ISO week of year               |
 * |  j* | Localized hour w/ day period   |  J* | Localized hour w/o day period  |
 * |  k  | Hour [1-24]                    |  K  | Hour [0-11]                    |
 * |  l* | (deprecated)                   |  L  | Stand-alone month              |
 * |  m  | Minute                         |  M  | Month                          |
 * |  n  |                                |  N  |                                |
 * |  o! | Ordinal number modifier        |  O  | Timezone (GMT)                 |
 * |  p! | Long localized time            |  P! | Long localized date            |
 * |  q  | Stand-alone quarter            |  Q  | Quarter                        |
 * |  r* | Related Gregorian year         |  R! | ISO week-numbering year        |
 * |  s  | Second                         |  S  | Fraction of second             |
 * |  t! | Seconds timestamp              |  T! | Milliseconds timestamp         |
 * |  u  | Extended year                  |  U* | Cyclic year                    |
 * |  v* | Timezone (generic non-locat.)  |  V* | Timezone (location)            |
 * |  w  | Local week of year             |  W* | Week of month                  |
 * |  x  | Timezone (ISO-8601 w/o Z)      |  X  | Timezone (ISO-8601)            |
 * |  y  | Year (abs)                     |  Y  | Local week-numbering year      |
 * |  z  | Timezone (specific non-locat.) |  Z* | Timezone (aliases)             |
 *
 * Letters marked by * are not implemented but reserved by Unicode standard.
 *
 * Letters marked by ! are non-standard, but implemented by date-fns:
 * - `o` modifies the previous token to turn it into an ordinal (see `format` docs)
 * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,
 *   i.e. 7 for Sunday, 1 for Monday, etc.
 * - `I` is ISO week of year, as opposed to `w` which is local week of year.
 * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.
 *   `R` is supposed to be used in conjunction with `I` and `i`
 *   for universal ISO week-numbering date, whereas
 *   `Y` is supposed to be used in conjunction with `w` and `e`
 *   for week-numbering date specific to the locale.
 * - `P` is long localized date format
 * - `p` is long localized time format
 */

const formatters = {
  // Era
  G: function (date, token, localize) {
    const era = date.getFullYear() > 0 ? 1 : 0;
    switch (token) {
      // AD, BC
      case "G":
      case "GG":
      case "GGG":
        return localize.era(era, {
          width: "abbreviated"
        });
      // A, B
      case "GGGGG":
        return localize.era(era, {
          width: "narrow"
        });
      // Anno Domini, Before Christ
      case "GGGG":
      default:
        return localize.era(era, {
          width: "wide"
        });
    }
  },
  // Year
  y: function (date, token, localize) {
    // Ordinal number
    if (token === "yo") {
      const signedYear = date.getFullYear();
      // Returns 1 for 1 BC (which is year 0 in JavaScript)
      const year = signedYear > 0 ? signedYear : 1 - signedYear;
      return localize.ordinalNumber(year, {
        unit: "year"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.y(date, token);
  },
  // Local week-numbering year
  Y: function (date, token, localize, options) {
    const signedWeekYear = (0,_getWeekYear_mjs__WEBPACK_IMPORTED_MODULE_1__.getWeekYear)(date, options);
    // Returns 1 for 1 BC (which is year 0 in JavaScript)
    const weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear;

    // Two digit year
    if (token === "YY") {
      const twoDigitYear = weekYear % 100;
      return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(twoDigitYear, 2);
    }

    // Ordinal number
    if (token === "Yo") {
      return localize.ordinalNumber(weekYear, {
        unit: "year"
      });
    }

    // Padding
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(weekYear, token.length);
  },
  // ISO week-numbering year
  R: function (date, token) {
    const isoWeekYear = (0,_getISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_3__.getISOWeekYear)(date);

    // Padding
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(isoWeekYear, token.length);
  },
  // Extended year. This is a single number designating the year of this calendar system.
  // The main difference between `y` and `u` localizers are B.C. years:
  // | Year | `y` | `u` |
  // |------|-----|-----|
  // | AC 1 |   1 |   1 |
  // | BC 1 |   1 |   0 |
  // | BC 2 |   2 |  -1 |
  // Also `yy` always returns the last two digits of a year,
  // while `uu` pads single digit years to 2 characters and returns other years unchanged.
  u: function (date, token) {
    const year = date.getFullYear();
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(year, token.length);
  },
  // Quarter
  Q: function (date, token, localize) {
    const quarter = Math.ceil((date.getMonth() + 1) / 3);
    switch (token) {
      // 1, 2, 3, 4
      case "Q":
        return String(quarter);
      // 01, 02, 03, 04
      case "QQ":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(quarter, 2);
      // 1st, 2nd, 3rd, 4th
      case "Qo":
        return localize.ordinalNumber(quarter, {
          unit: "quarter"
        });
      // Q1, Q2, Q3, Q4
      case "QQQ":
        return localize.quarter(quarter, {
          width: "abbreviated",
          context: "formatting"
        });
      // 1, 2, 3, 4 (narrow quarter; could be not numerical)
      case "QQQQQ":
        return localize.quarter(quarter, {
          width: "narrow",
          context: "formatting"
        });
      // 1st quarter, 2nd quarter, ...
      case "QQQQ":
      default:
        return localize.quarter(quarter, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // Stand-alone quarter
  q: function (date, token, localize) {
    const quarter = Math.ceil((date.getMonth() + 1) / 3);
    switch (token) {
      // 1, 2, 3, 4
      case "q":
        return String(quarter);
      // 01, 02, 03, 04
      case "qq":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(quarter, 2);
      // 1st, 2nd, 3rd, 4th
      case "qo":
        return localize.ordinalNumber(quarter, {
          unit: "quarter"
        });
      // Q1, Q2, Q3, Q4
      case "qqq":
        return localize.quarter(quarter, {
          width: "abbreviated",
          context: "standalone"
        });
      // 1, 2, 3, 4 (narrow quarter; could be not numerical)
      case "qqqqq":
        return localize.quarter(quarter, {
          width: "narrow",
          context: "standalone"
        });
      // 1st quarter, 2nd quarter, ...
      case "qqqq":
      default:
        return localize.quarter(quarter, {
          width: "wide",
          context: "standalone"
        });
    }
  },
  // Month
  M: function (date, token, localize) {
    const month = date.getMonth();
    switch (token) {
      case "M":
      case "MM":
        return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.M(date, token);
      // 1st, 2nd, ..., 12th
      case "Mo":
        return localize.ordinalNumber(month + 1, {
          unit: "month"
        });
      // Jan, Feb, ..., Dec
      case "MMM":
        return localize.month(month, {
          width: "abbreviated",
          context: "formatting"
        });
      // J, F, ..., D
      case "MMMMM":
        return localize.month(month, {
          width: "narrow",
          context: "formatting"
        });
      // January, February, ..., December
      case "MMMM":
      default:
        return localize.month(month, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // Stand-alone month
  L: function (date, token, localize) {
    const month = date.getMonth();
    switch (token) {
      // 1, 2, ..., 12
      case "L":
        return String(month + 1);
      // 01, 02, ..., 12
      case "LL":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(month + 1, 2);
      // 1st, 2nd, ..., 12th
      case "Lo":
        return localize.ordinalNumber(month + 1, {
          unit: "month"
        });
      // Jan, Feb, ..., Dec
      case "LLL":
        return localize.month(month, {
          width: "abbreviated",
          context: "standalone"
        });
      // J, F, ..., D
      case "LLLLL":
        return localize.month(month, {
          width: "narrow",
          context: "standalone"
        });
      // January, February, ..., December
      case "LLLL":
      default:
        return localize.month(month, {
          width: "wide",
          context: "standalone"
        });
    }
  },
  // Local week of year
  w: function (date, token, localize, options) {
    const week = (0,_getWeek_mjs__WEBPACK_IMPORTED_MODULE_4__.getWeek)(date, options);
    if (token === "wo") {
      return localize.ordinalNumber(week, {
        unit: "week"
      });
    }
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(week, token.length);
  },
  // ISO week of year
  I: function (date, token, localize) {
    const isoWeek = (0,_getISOWeek_mjs__WEBPACK_IMPORTED_MODULE_5__.getISOWeek)(date);
    if (token === "Io") {
      return localize.ordinalNumber(isoWeek, {
        unit: "week"
      });
    }
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(isoWeek, token.length);
  },
  // Day of the month
  d: function (date, token, localize) {
    if (token === "do") {
      return localize.ordinalNumber(date.getDate(), {
        unit: "date"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.d(date, token);
  },
  // Day of year
  D: function (date, token, localize) {
    const dayOfYear = (0,_getDayOfYear_mjs__WEBPACK_IMPORTED_MODULE_6__.getDayOfYear)(date);
    if (token === "Do") {
      return localize.ordinalNumber(dayOfYear, {
        unit: "dayOfYear"
      });
    }
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(dayOfYear, token.length);
  },
  // Day of week
  E: function (date, token, localize) {
    const dayOfWeek = date.getDay();
    switch (token) {
      // Tue
      case "E":
      case "EE":
      case "EEE":
        return localize.day(dayOfWeek, {
          width: "abbreviated",
          context: "formatting"
        });
      // T
      case "EEEEE":
        return localize.day(dayOfWeek, {
          width: "narrow",
          context: "formatting"
        });
      // Tu
      case "EEEEEE":
        return localize.day(dayOfWeek, {
          width: "short",
          context: "formatting"
        });
      // Tuesday
      case "EEEE":
      default:
        return localize.day(dayOfWeek, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // Local day of week
  e: function (date, token, localize, options) {
    const dayOfWeek = date.getDay();
    const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
    switch (token) {
      // Numerical value (Nth day of week with current locale or weekStartsOn)
      case "e":
        return String(localDayOfWeek);
      // Padded numerical value
      case "ee":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(localDayOfWeek, 2);
      // 1st, 2nd, ..., 7th
      case "eo":
        return localize.ordinalNumber(localDayOfWeek, {
          unit: "day"
        });
      case "eee":
        return localize.day(dayOfWeek, {
          width: "abbreviated",
          context: "formatting"
        });
      // T
      case "eeeee":
        return localize.day(dayOfWeek, {
          width: "narrow",
          context: "formatting"
        });
      // Tu
      case "eeeeee":
        return localize.day(dayOfWeek, {
          width: "short",
          context: "formatting"
        });
      // Tuesday
      case "eeee":
      default:
        return localize.day(dayOfWeek, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // Stand-alone local day of week
  c: function (date, token, localize, options) {
    const dayOfWeek = date.getDay();
    const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;
    switch (token) {
      // Numerical value (same as in `e`)
      case "c":
        return String(localDayOfWeek);
      // Padded numerical value
      case "cc":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(localDayOfWeek, token.length);
      // 1st, 2nd, ..., 7th
      case "co":
        return localize.ordinalNumber(localDayOfWeek, {
          unit: "day"
        });
      case "ccc":
        return localize.day(dayOfWeek, {
          width: "abbreviated",
          context: "standalone"
        });
      // T
      case "ccccc":
        return localize.day(dayOfWeek, {
          width: "narrow",
          context: "standalone"
        });
      // Tu
      case "cccccc":
        return localize.day(dayOfWeek, {
          width: "short",
          context: "standalone"
        });
      // Tuesday
      case "cccc":
      default:
        return localize.day(dayOfWeek, {
          width: "wide",
          context: "standalone"
        });
    }
  },
  // ISO day of week
  i: function (date, token, localize) {
    const dayOfWeek = date.getDay();
    const isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;
    switch (token) {
      // 2
      case "i":
        return String(isoDayOfWeek);
      // 02
      case "ii":
        return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(isoDayOfWeek, token.length);
      // 2nd
      case "io":
        return localize.ordinalNumber(isoDayOfWeek, {
          unit: "day"
        });
      // Tue
      case "iii":
        return localize.day(dayOfWeek, {
          width: "abbreviated",
          context: "formatting"
        });
      // T
      case "iiiii":
        return localize.day(dayOfWeek, {
          width: "narrow",
          context: "formatting"
        });
      // Tu
      case "iiiiii":
        return localize.day(dayOfWeek, {
          width: "short",
          context: "formatting"
        });
      // Tuesday
      case "iiii":
      default:
        return localize.day(dayOfWeek, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // AM or PM
  a: function (date, token, localize) {
    const hours = date.getHours();
    const dayPeriodEnumValue = hours / 12 >= 1 ? "pm" : "am";
    switch (token) {
      case "a":
      case "aa":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "abbreviated",
          context: "formatting"
        });
      case "aaa":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "abbreviated",
          context: "formatting"
        }).toLowerCase();
      case "aaaaa":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "narrow",
          context: "formatting"
        });
      case "aaaa":
      default:
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // AM, PM, midnight, noon
  b: function (date, token, localize) {
    const hours = date.getHours();
    let dayPeriodEnumValue;
    if (hours === 12) {
      dayPeriodEnumValue = dayPeriodEnum.noon;
    } else if (hours === 0) {
      dayPeriodEnumValue = dayPeriodEnum.midnight;
    } else {
      dayPeriodEnumValue = hours / 12 >= 1 ? "pm" : "am";
    }
    switch (token) {
      case "b":
      case "bb":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "abbreviated",
          context: "formatting"
        });
      case "bbb":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "abbreviated",
          context: "formatting"
        }).toLowerCase();
      case "bbbbb":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "narrow",
          context: "formatting"
        });
      case "bbbb":
      default:
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // in the morning, in the afternoon, in the evening, at night
  B: function (date, token, localize) {
    const hours = date.getHours();
    let dayPeriodEnumValue;
    if (hours >= 17) {
      dayPeriodEnumValue = dayPeriodEnum.evening;
    } else if (hours >= 12) {
      dayPeriodEnumValue = dayPeriodEnum.afternoon;
    } else if (hours >= 4) {
      dayPeriodEnumValue = dayPeriodEnum.morning;
    } else {
      dayPeriodEnumValue = dayPeriodEnum.night;
    }
    switch (token) {
      case "B":
      case "BB":
      case "BBB":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "abbreviated",
          context: "formatting"
        });
      case "BBBBB":
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "narrow",
          context: "formatting"
        });
      case "BBBB":
      default:
        return localize.dayPeriod(dayPeriodEnumValue, {
          width: "wide",
          context: "formatting"
        });
    }
  },
  // Hour [1-12]
  h: function (date, token, localize) {
    if (token === "ho") {
      let hours = date.getHours() % 12;
      if (hours === 0) hours = 12;
      return localize.ordinalNumber(hours, {
        unit: "hour"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.h(date, token);
  },
  // Hour [0-23]
  H: function (date, token, localize) {
    if (token === "Ho") {
      return localize.ordinalNumber(date.getHours(), {
        unit: "hour"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.H(date, token);
  },
  // Hour [0-11]
  K: function (date, token, localize) {
    const hours = date.getHours() % 12;
    if (token === "Ko") {
      return localize.ordinalNumber(hours, {
        unit: "hour"
      });
    }
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(hours, token.length);
  },
  // Hour [1-24]
  k: function (date, token, localize) {
    let hours = date.getHours();
    if (hours === 0) hours = 24;
    if (token === "ko") {
      return localize.ordinalNumber(hours, {
        unit: "hour"
      });
    }
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(hours, token.length);
  },
  // Minute
  m: function (date, token, localize) {
    if (token === "mo") {
      return localize.ordinalNumber(date.getMinutes(), {
        unit: "minute"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.m(date, token);
  },
  // Second
  s: function (date, token, localize) {
    if (token === "so") {
      return localize.ordinalNumber(date.getSeconds(), {
        unit: "second"
      });
    }
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.s(date, token);
  },
  // Fraction of second
  S: function (date, token) {
    return _lightFormatters_mjs__WEBPACK_IMPORTED_MODULE_0__.lightFormatters.S(date, token);
  },
  // Timezone (ISO-8601. If offset is 0, output is always `'Z'`)
  X: function (date, token, _localize) {
    const timezoneOffset = date.getTimezoneOffset();
    if (timezoneOffset === 0) {
      return "Z";
    }
    switch (token) {
      // Hours and optional minutes
      case "X":
        return formatTimezoneWithOptionalMinutes(timezoneOffset);

      // Hours, minutes and optional seconds without `:` delimiter
      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
      // so this token always has the same output as `XX`
      case "XXXX":
      case "XX":
        // Hours and minutes without `:` delimiter
        return formatTimezone(timezoneOffset);

      // Hours, minutes and optional seconds with `:` delimiter
      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
      // so this token always has the same output as `XXX`
      case "XXXXX":
      case "XXX": // Hours and minutes with `:` delimiter
      default:
        return formatTimezone(timezoneOffset, ":");
    }
  },
  // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)
  x: function (date, token, _localize) {
    const timezoneOffset = date.getTimezoneOffset();
    switch (token) {
      // Hours and optional minutes
      case "x":
        return formatTimezoneWithOptionalMinutes(timezoneOffset);

      // Hours, minutes and optional seconds without `:` delimiter
      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
      // so this token always has the same output as `xx`
      case "xxxx":
      case "xx":
        // Hours and minutes without `:` delimiter
        return formatTimezone(timezoneOffset);

      // Hours, minutes and optional seconds with `:` delimiter
      // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets
      // so this token always has the same output as `xxx`
      case "xxxxx":
      case "xxx": // Hours and minutes with `:` delimiter
      default:
        return formatTimezone(timezoneOffset, ":");
    }
  },
  // Timezone (GMT)
  O: function (date, token, _localize) {
    const timezoneOffset = date.getTimezoneOffset();
    switch (token) {
      // Short
      case "O":
      case "OO":
      case "OOO":
        return "GMT" + formatTimezoneShort(timezoneOffset, ":");
      // Long
      case "OOOO":
      default:
        return "GMT" + formatTimezone(timezoneOffset, ":");
    }
  },
  // Timezone (specific non-location)
  z: function (date, token, _localize) {
    const timezoneOffset = date.getTimezoneOffset();
    switch (token) {
      // Short
      case "z":
      case "zz":
      case "zzz":
        return "GMT" + formatTimezoneShort(timezoneOffset, ":");
      // Long
      case "zzzz":
      default:
        return "GMT" + formatTimezone(timezoneOffset, ":");
    }
  },
  // Seconds timestamp
  t: function (date, token, _localize) {
    const timestamp = Math.trunc(date.getTime() / 1000);
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(timestamp, token.length);
  },
  // Milliseconds timestamp
  T: function (date, token, _localize) {
    const timestamp = date.getTime();
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(timestamp, token.length);
  }
};
function formatTimezoneShort(offset, delimiter = "") {
  const sign = offset > 0 ? "-" : "+";
  const absOffset = Math.abs(offset);
  const hours = Math.trunc(absOffset / 60);
  const minutes = absOffset % 60;
  if (minutes === 0) {
    return sign + String(hours);
  }
  return sign + String(hours) + delimiter + (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(minutes, 2);
}
function formatTimezoneWithOptionalMinutes(offset, delimiter) {
  if (offset % 60 === 0) {
    const sign = offset > 0 ? "-" : "+";
    return sign + (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(Math.abs(offset) / 60, 2);
  }
  return formatTimezone(offset, delimiter);
}
function formatTimezone(offset, delimiter = "") {
  const sign = offset > 0 ? "-" : "+";
  const absOffset = Math.abs(offset);
  const hours = (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(Math.trunc(absOffset / 60), 2);
  const minutes = (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_2__.addLeadingZeros)(absOffset % 60, 2);
  return sign + hours + delimiter + minutes;
}

/***/ }),

/***/ 91115:
/*!***************************************************************!*\
  !*** ./node_modules/date-fns/_lib/format/lightFormatters.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   lightFormatters: () => (/* binding */ lightFormatters)
/* harmony export */ });
/* harmony import */ var _addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../addLeadingZeros.mjs */ 87160);


/*
 * |     | Unit                           |     | Unit                           |
 * |-----|--------------------------------|-----|--------------------------------|
 * |  a  | AM, PM                         |  A* |                                |
 * |  d  | Day of month                   |  D  |                                |
 * |  h  | Hour [1-12]                    |  H  | Hour [0-23]                    |
 * |  m  | Minute                         |  M  | Month                          |
 * |  s  | Second                         |  S  | Fraction of second             |
 * |  y  | Year (abs)                     |  Y  |                                |
 *
 * Letters marked by * are not implemented but reserved by Unicode standard.
 */

const lightFormatters = {
  // Year
  y(date, token) {
    // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens
    // | Year     |     y | yy |   yyy |  yyyy | yyyyy |
    // |----------|-------|----|-------|-------|-------|
    // | AD 1     |     1 | 01 |   001 |  0001 | 00001 |
    // | AD 12    |    12 | 12 |   012 |  0012 | 00012 |
    // | AD 123   |   123 | 23 |   123 |  0123 | 00123 |
    // | AD 1234  |  1234 | 34 |  1234 |  1234 | 01234 |
    // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |

    const signedYear = date.getFullYear();
    // Returns 1 for 1 BC (which is year 0 in JavaScript)
    const year = signedYear > 0 ? signedYear : 1 - signedYear;
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(token === "yy" ? year % 100 : year, token.length);
  },
  // Month
  M(date, token) {
    const month = date.getMonth();
    return token === "M" ? String(month + 1) : (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(month + 1, 2);
  },
  // Day of the month
  d(date, token) {
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(date.getDate(), token.length);
  },
  // AM or PM
  a(date, token) {
    const dayPeriodEnumValue = date.getHours() / 12 >= 1 ? "pm" : "am";
    switch (token) {
      case "a":
      case "aa":
        return dayPeriodEnumValue.toUpperCase();
      case "aaa":
        return dayPeriodEnumValue;
      case "aaaaa":
        return dayPeriodEnumValue[0];
      case "aaaa":
      default:
        return dayPeriodEnumValue === "am" ? "a.m." : "p.m.";
    }
  },
  // Hour [1-12]
  h(date, token) {
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(date.getHours() % 12 || 12, token.length);
  },
  // Hour [0-23]
  H(date, token) {
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(date.getHours(), token.length);
  },
  // Minute
  m(date, token) {
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(date.getMinutes(), token.length);
  },
  // Second
  s(date, token) {
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(date.getSeconds(), token.length);
  },
  // Fraction of second
  S(date, token) {
    const numberOfDigits = token.length;
    const milliseconds = date.getMilliseconds();
    const fractionalSeconds = Math.trunc(milliseconds * Math.pow(10, numberOfDigits - 3));
    return (0,_addLeadingZeros_mjs__WEBPACK_IMPORTED_MODULE_0__.addLeadingZeros)(fractionalSeconds, token.length);
  }
};

/***/ }),

/***/ 47913:
/*!**************************************************************!*\
  !*** ./node_modules/date-fns/_lib/format/longFormatters.mjs ***!
  \**************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   longFormatters: () => (/* binding */ longFormatters)
/* harmony export */ });
const dateLongFormatter = (pattern, formatLong) => {
  switch (pattern) {
    case "P":
      return formatLong.date({
        width: "short"
      });
    case "PP":
      return formatLong.date({
        width: "medium"
      });
    case "PPP":
      return formatLong.date({
        width: "long"
      });
    case "PPPP":
    default:
      return formatLong.date({
        width: "full"
      });
  }
};
const timeLongFormatter = (pattern, formatLong) => {
  switch (pattern) {
    case "p":
      return formatLong.time({
        width: "short"
      });
    case "pp":
      return formatLong.time({
        width: "medium"
      });
    case "ppp":
      return formatLong.time({
        width: "long"
      });
    case "pppp":
    default:
      return formatLong.time({
        width: "full"
      });
  }
};
const dateTimeLongFormatter = (pattern, formatLong) => {
  const matchResult = pattern.match(/(P+)(p+)?/) || [];
  const datePattern = matchResult[1];
  const timePattern = matchResult[2];
  if (!timePattern) {
    return dateLongFormatter(pattern, formatLong);
  }
  let dateTimeFormat;
  switch (datePattern) {
    case "P":
      dateTimeFormat = formatLong.dateTime({
        width: "short"
      });
      break;
    case "PP":
      dateTimeFormat = formatLong.dateTime({
        width: "medium"
      });
      break;
    case "PPP":
      dateTimeFormat = formatLong.dateTime({
        width: "long"
      });
      break;
    case "PPPP":
    default:
      dateTimeFormat = formatLong.dateTime({
        width: "full"
      });
      break;
  }
  return dateTimeFormat.replace("{{date}}", dateLongFormatter(datePattern, formatLong)).replace("{{time}}", timeLongFormatter(timePattern, formatLong));
};
const longFormatters = {
  p: timeLongFormatter,
  P: dateTimeLongFormatter
};

/***/ }),

/***/ 88889:
/*!************************************************************************!*\
  !*** ./node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.mjs ***!
  \************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   getTimezoneOffsetInMilliseconds: () => (/* binding */ getTimezoneOffsetInMilliseconds)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../toDate.mjs */ 58700);


/**
 * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.
 * They usually appear for dates that denote time before the timezones were introduced
 * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891
 * and GMT+01:00:00 after that date)
 *
 * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,
 * which would lead to incorrect calculations.
 *
 * This function returns the timezone offset in milliseconds that takes seconds in account.
 */
function getTimezoneOffsetInMilliseconds(date) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const utcDate = new Date(Date.UTC(_date.getFullYear(), _date.getMonth(), _date.getDate(), _date.getHours(), _date.getMinutes(), _date.getSeconds(), _date.getMilliseconds()));
  utcDate.setUTCFullYear(_date.getFullYear());
  return +date - +utcDate;
}

/***/ }),

/***/ 21454:
/*!********************************************************!*\
  !*** ./node_modules/date-fns/_lib/protectedTokens.mjs ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   isProtectedDayOfYearToken: () => (/* binding */ isProtectedDayOfYearToken),
/* harmony export */   isProtectedWeekYearToken: () => (/* binding */ isProtectedWeekYearToken),
/* harmony export */   warnOrThrowProtectedError: () => (/* binding */ warnOrThrowProtectedError)
/* harmony export */ });
const dayOfYearTokenRE = /^D+$/;
const weekYearTokenRE = /^Y+$/;
const throwTokens = ["D", "DD", "YY", "YYYY"];
function isProtectedDayOfYearToken(token) {
  return dayOfYearTokenRE.test(token);
}
function isProtectedWeekYearToken(token) {
  return weekYearTokenRE.test(token);
}
function warnOrThrowProtectedError(token, format, input) {
  const _message = message(token, format, input);
  console.warn(_message);
  if (throwTokens.includes(token)) throw new RangeError(_message);
}
function message(token, format, input) {
  const subject = token[0] === "Y" ? "years" : "days of the month";
  return `Use \`${token.toLowerCase()}\` instead of \`${token}\` (in \`${format}\`) for formatting ${subject} to the input \`${input}\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`;
}

/***/ }),

/***/ 28797:
/*!*******************************************!*\
  !*** ./node_modules/date-fns/addDays.mjs ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   addDays: () => (/* binding */ addDays),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);



/**
 * @name addDays
 * @category Day Helpers
 * @summary Add the specified number of days to the given date.
 *
 * @description
 * Add the specified number of days to the given date.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The date to be changed
 * @param amount - The amount of days to be added.
 *
 * @returns The new date with the days added
 *
 * @example
 * // Add 10 days to 1 September 2014:
 * const result = addDays(new Date(2014, 8, 1), 10)
 * //=> Thu Sep 11 2014 00:00:00
 */
function addDays(date, amount) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  if (isNaN(amount)) return (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__.constructFrom)(date, NaN);
  if (!amount) {
    // If 0 days, no-op to avoid changing times in the hour before end of DST
    return _date;
  }
  _date.setDate(_date.getDate() + amount);
  return _date;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (addDays);

/***/ }),

/***/ 87870:
/*!*********************************************!*\
  !*** ./node_modules/date-fns/constants.mjs ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   daysInWeek: () => (/* binding */ daysInWeek),
/* harmony export */   daysInYear: () => (/* binding */ daysInYear),
/* harmony export */   maxTime: () => (/* binding */ maxTime),
/* harmony export */   millisecondsInDay: () => (/* binding */ millisecondsInDay),
/* harmony export */   millisecondsInHour: () => (/* binding */ millisecondsInHour),
/* harmony export */   millisecondsInMinute: () => (/* binding */ millisecondsInMinute),
/* harmony export */   millisecondsInSecond: () => (/* binding */ millisecondsInSecond),
/* harmony export */   millisecondsInWeek: () => (/* binding */ millisecondsInWeek),
/* harmony export */   minTime: () => (/* binding */ minTime),
/* harmony export */   minutesInDay: () => (/* binding */ minutesInDay),
/* harmony export */   minutesInHour: () => (/* binding */ minutesInHour),
/* harmony export */   minutesInMonth: () => (/* binding */ minutesInMonth),
/* harmony export */   minutesInYear: () => (/* binding */ minutesInYear),
/* harmony export */   monthsInQuarter: () => (/* binding */ monthsInQuarter),
/* harmony export */   monthsInYear: () => (/* binding */ monthsInYear),
/* harmony export */   quartersInYear: () => (/* binding */ quartersInYear),
/* harmony export */   secondsInDay: () => (/* binding */ secondsInDay),
/* harmony export */   secondsInHour: () => (/* binding */ secondsInHour),
/* harmony export */   secondsInMinute: () => (/* binding */ secondsInMinute),
/* harmony export */   secondsInMonth: () => (/* binding */ secondsInMonth),
/* harmony export */   secondsInQuarter: () => (/* binding */ secondsInQuarter),
/* harmony export */   secondsInWeek: () => (/* binding */ secondsInWeek),
/* harmony export */   secondsInYear: () => (/* binding */ secondsInYear)
/* harmony export */ });
/**
 * @module constants
 * @summary Useful constants
 * @description
 * Collection of useful date constants.
 *
 * The constants could be imported from `date-fns/constants`:
 *
 * ```ts
 * import { maxTime, minTime } from "./constants/date-fns/constants";
 *
 * function isAllowedTime(time) {
 *   return time <= maxTime && time >= minTime;
 * }
 * ```
 */

/**
 * @constant
 * @name daysInWeek
 * @summary Days in 1 week.
 */
const daysInWeek = 7;

/**
 * @constant
 * @name daysInYear
 * @summary Days in 1 year.
 *
 * @description
 * How many days in a year.
 *
 * One years equals 365.2425 days according to the formula:
 *
 * > Leap year occures every 4 years, except for years that are divisable by 100 and not divisable by 400.
 * > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days
 */
const daysInYear = 365.2425;

/**
 * @constant
 * @name maxTime
 * @summary Maximum allowed time.
 *
 * @example
 * import { maxTime } from "./constants/date-fns/constants";
 *
 * const isValid = 8640000000000001 <= maxTime;
 * //=> false
 *
 * new Date(8640000000000001);
 * //=> Invalid Date
 */
const maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;

/**
 * @constant
 * @name minTime
 * @summary Minimum allowed time.
 *
 * @example
 * import { minTime } from "./constants/date-fns/constants";
 *
 * const isValid = -8640000000000001 >= minTime;
 * //=> false
 *
 * new Date(-8640000000000001)
 * //=> Invalid Date
 */
const minTime = -maxTime;

/**
 * @constant
 * @name millisecondsInWeek
 * @summary Milliseconds in 1 week.
 */
const millisecondsInWeek = 604800000;

/**
 * @constant
 * @name millisecondsInDay
 * @summary Milliseconds in 1 day.
 */
const millisecondsInDay = 86400000;

/**
 * @constant
 * @name millisecondsInMinute
 * @summary Milliseconds in 1 minute
 */
const millisecondsInMinute = 60000;

/**
 * @constant
 * @name millisecondsInHour
 * @summary Milliseconds in 1 hour
 */
const millisecondsInHour = 3600000;

/**
 * @constant
 * @name millisecondsInSecond
 * @summary Milliseconds in 1 second
 */
const millisecondsInSecond = 1000;

/**
 * @constant
 * @name minutesInYear
 * @summary Minutes in 1 year.
 */
const minutesInYear = 525600;

/**
 * @constant
 * @name minutesInMonth
 * @summary Minutes in 1 month.
 */
const minutesInMonth = 43200;

/**
 * @constant
 * @name minutesInDay
 * @summary Minutes in 1 day.
 */
const minutesInDay = 1440;

/**
 * @constant
 * @name minutesInHour
 * @summary Minutes in 1 hour.
 */
const minutesInHour = 60;

/**
 * @constant
 * @name monthsInQuarter
 * @summary Months in 1 quarter.
 */
const monthsInQuarter = 3;

/**
 * @constant
 * @name monthsInYear
 * @summary Months in 1 year.
 */
const monthsInYear = 12;

/**
 * @constant
 * @name quartersInYear
 * @summary Quarters in 1 year
 */
const quartersInYear = 4;

/**
 * @constant
 * @name secondsInHour
 * @summary Seconds in 1 hour.
 */
const secondsInHour = 3600;

/**
 * @constant
 * @name secondsInMinute
 * @summary Seconds in 1 minute.
 */
const secondsInMinute = 60;

/**
 * @constant
 * @name secondsInDay
 * @summary Seconds in 1 day.
 */
const secondsInDay = secondsInHour * 24;

/**
 * @constant
 * @name secondsInWeek
 * @summary Seconds in 1 week.
 */
const secondsInWeek = secondsInDay * 7;

/**
 * @constant
 * @name secondsInYear
 * @summary Seconds in 1 year.
 */
const secondsInYear = secondsInDay * daysInYear;

/**
 * @constant
 * @name secondsInMonth
 * @summary Seconds in 1 month
 */
const secondsInMonth = secondsInYear / 12;

/**
 * @constant
 * @name secondsInQuarter
 * @summary Seconds in 1 quarter.
 */
const secondsInQuarter = secondsInMonth * 3;

/***/ }),

/***/ 56814:
/*!*************************************************!*\
  !*** ./node_modules/date-fns/constructFrom.mjs ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   constructFrom: () => (/* binding */ constructFrom),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * @name constructFrom
 * @category Generic Helpers
 * @summary Constructs a date using the reference date and the value
 *
 * @description
 * The function constructs a new date using the constructor from the reference
 * date and the given value. It helps to build generic functions that accept
 * date extensions.
 *
 * It defaults to `Date` if the passed reference date is a number or a string.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The reference date to take constructor from
 * @param value - The value to create the date
 *
 * @returns Date initialized using the given date and value
 *
 * @example
 * import { constructFrom } from 'date-fns'
 *
 * // A function that clones a date preserving the original type
 * function cloneDate<DateType extends Date(date: DateType): DateType {
 *   return constructFrom(
 *     date, // Use contrustor from the given date
 *     date.getTime() // Use the date value to create a new date
 *   )
 * }
 */
function constructFrom(date, value) {
  if (date instanceof Date) {
    return new date.constructor(value);
  } else {
    return new Date(value);
  }
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (constructFrom);

/***/ }),

/***/ 56248:
/*!************************************************************!*\
  !*** ./node_modules/date-fns/differenceInCalendarDays.mjs ***!
  \************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   differenceInCalendarDays: () => (/* binding */ differenceInCalendarDays)
/* harmony export */ });
/* harmony import */ var _constants_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants.mjs */ 87870);
/* harmony import */ var _startOfDay_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./startOfDay.mjs */ 33240);
/* harmony import */ var _lib_getTimezoneOffsetInMilliseconds_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_lib/getTimezoneOffsetInMilliseconds.mjs */ 88889);




/**
 * @name differenceInCalendarDays
 * @category Day Helpers
 * @summary Get the number of calendar days between the given dates.
 *
 * @description
 * Get the number of calendar days between the given dates. This means that the times are removed
 * from the dates and then the difference in days is calculated.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param dateLeft - The later date
 * @param dateRight - The earlier date
 *
 * @returns The number of calendar days
 *
 * @example
 * // How many calendar days are between
 * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?
 * const result = differenceInCalendarDays(
 *   new Date(2012, 6, 2, 0, 0),
 *   new Date(2011, 6, 2, 23, 0)
 * )
 * //=> 366
 * // How many calendar days are between
 * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?
 * const result = differenceInCalendarDays(
 *   new Date(2011, 6, 3, 0, 1),
 *   new Date(2011, 6, 2, 23, 59)
 * )
 * //=> 1
 */
function differenceInCalendarDays(dateLeft, dateRight) {
  const startOfDayLeft = (0,_startOfDay_mjs__WEBPACK_IMPORTED_MODULE_0__.startOfDay)(dateLeft);
  const startOfDayRight = (0,_startOfDay_mjs__WEBPACK_IMPORTED_MODULE_0__.startOfDay)(dateRight);
  const timestampLeft = +startOfDayLeft - (0,_lib_getTimezoneOffsetInMilliseconds_mjs__WEBPACK_IMPORTED_MODULE_1__.getTimezoneOffsetInMilliseconds)(startOfDayLeft);
  const timestampRight = +startOfDayRight - (0,_lib_getTimezoneOffsetInMilliseconds_mjs__WEBPACK_IMPORTED_MODULE_1__.getTimezoneOffsetInMilliseconds)(startOfDayRight);

  // Round the number of days to the nearest integer because the number of
  // milliseconds in a day is not constant (e.g. it's different in the week of
  // the daylight saving time clock shift).
  return Math.round((timestampLeft - timestampRight) / _constants_mjs__WEBPACK_IMPORTED_MODULE_2__.millisecondsInDay);
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (differenceInCalendarDays);

/***/ }),

/***/ 45726:
/*!******************************************!*\
  !*** ./node_modules/date-fns/format.mjs ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   format: () => (/* binding */ format),
/* harmony export */   formatDate: () => (/* binding */ format),
/* harmony export */   formatters: () => (/* reexport safe */ _lib_format_formatters_mjs__WEBPACK_IMPORTED_MODULE_0__.formatters),
/* harmony export */   longFormatters: () => (/* reexport safe */ _lib_format_longFormatters_mjs__WEBPACK_IMPORTED_MODULE_1__.longFormatters)
/* harmony export */ });
/* harmony import */ var _lib_defaultLocale_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_lib/defaultLocale.mjs */ 12302);
/* harmony import */ var _lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_lib/defaultOptions.mjs */ 19857);
/* harmony import */ var _lib_format_formatters_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_lib/format/formatters.mjs */ 70223);
/* harmony import */ var _lib_format_longFormatters_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_lib/format/longFormatters.mjs */ 47913);
/* harmony import */ var _lib_protectedTokens_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./_lib/protectedTokens.mjs */ 21454);
/* harmony import */ var _isValid_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./isValid.mjs */ 86211);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./toDate.mjs */ 58700);








// Rexports of internal for libraries to use.
// See: https://github.com/date-fns/date-fns/issues/3638#issuecomment-1877082874


// This RegExp consists of three parts separated by `|`:
// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token
//   (one of the certain letters followed by `o`)
// - (\w)\1* matches any sequences of the same letter
// - '' matches two quote characters in a row
// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),
//   except a single quote symbol, which ends the sequence.
//   Two quote characters do not end the sequence.
//   If there is no matching single quote
//   then the sequence will continue until the end of the string.
// - . matches any single character unmatched by previous parts of the RegExps
const formattingTokensRegExp = /[yYQqMLwIdDecihHKkms]o|(\w)\1*|''|'(''|[^'])+('|$)|./g;

// This RegExp catches symbols escaped by quotes, and also
// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`
const longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;
const escapedStringRegExp = /^'([^]*?)'?$/;
const doubleQuoteRegExp = /''/g;
const unescapedLatinCharacterRegExp = /[a-zA-Z]/;


/**
 * The {@link format} function options.
 */

/**
 * @name format
 * @alias formatDate
 * @category Common Helpers
 * @summary Format the date.
 *
 * @description
 * Return the formatted date string in the given format. The result may vary by locale.
 *
 * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.
 * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 *
 * The characters wrapped between two single quotes characters (') are escaped.
 * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.
 * (see the last example)
 *
 * Format of the string is based on Unicode Technical Standard #35:
 * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table
 * with a few additions (see note 7 below the table).
 *
 * Accepted patterns:
 * | Unit                            | Pattern | Result examples                   | Notes |
 * |---------------------------------|---------|-----------------------------------|-------|
 * | Era                             | G..GGG  | AD, BC                            |       |
 * |                                 | GGGG    | Anno Domini, Before Christ        | 2     |
 * |                                 | GGGGG   | A, B                              |       |
 * | Calendar year                   | y       | 44, 1, 1900, 2017                 | 5     |
 * |                                 | yo      | 44th, 1st, 0th, 17th              | 5,7   |
 * |                                 | yy      | 44, 01, 00, 17                    | 5     |
 * |                                 | yyy     | 044, 001, 1900, 2017              | 5     |
 * |                                 | yyyy    | 0044, 0001, 1900, 2017            | 5     |
 * |                                 | yyyyy   | ...                               | 3,5   |
 * | Local week-numbering year       | Y       | 44, 1, 1900, 2017                 | 5     |
 * |                                 | Yo      | 44th, 1st, 1900th, 2017th         | 5,7   |
 * |                                 | YY      | 44, 01, 00, 17                    | 5,8   |
 * |                                 | YYY     | 044, 001, 1900, 2017              | 5     |
 * |                                 | YYYY    | 0044, 0001, 1900, 2017            | 5,8   |
 * |                                 | YYYYY   | ...                               | 3,5   |
 * | ISO week-numbering year         | R       | -43, 0, 1, 1900, 2017             | 5,7   |
 * |                                 | RR      | -43, 00, 01, 1900, 2017           | 5,7   |
 * |                                 | RRR     | -043, 000, 001, 1900, 2017        | 5,7   |
 * |                                 | RRRR    | -0043, 0000, 0001, 1900, 2017     | 5,7   |
 * |                                 | RRRRR   | ...                               | 3,5,7 |
 * | Extended year                   | u       | -43, 0, 1, 1900, 2017             | 5     |
 * |                                 | uu      | -43, 01, 1900, 2017               | 5     |
 * |                                 | uuu     | -043, 001, 1900, 2017             | 5     |
 * |                                 | uuuu    | -0043, 0001, 1900, 2017           | 5     |
 * |                                 | uuuuu   | ...                               | 3,5   |
 * | Quarter (formatting)            | Q       | 1, 2, 3, 4                        |       |
 * |                                 | Qo      | 1st, 2nd, 3rd, 4th                | 7     |
 * |                                 | QQ      | 01, 02, 03, 04                    |       |
 * |                                 | QQQ     | Q1, Q2, Q3, Q4                    |       |
 * |                                 | QQQQ    | 1st quarter, 2nd quarter, ...     | 2     |
 * |                                 | QQQQQ   | 1, 2, 3, 4                        | 4     |
 * | Quarter (stand-alone)           | q       | 1, 2, 3, 4                        |       |
 * |                                 | qo      | 1st, 2nd, 3rd, 4th                | 7     |
 * |                                 | qq      | 01, 02, 03, 04                    |       |
 * |                                 | qqq     | Q1, Q2, Q3, Q4                    |       |
 * |                                 | qqqq    | 1st quarter, 2nd quarter, ...     | 2     |
 * |                                 | qqqqq   | 1, 2, 3, 4                        | 4     |
 * | Month (formatting)              | M       | 1, 2, ..., 12                     |       |
 * |                                 | Mo      | 1st, 2nd, ..., 12th               | 7     |
 * |                                 | MM      | 01, 02, ..., 12                   |       |
 * |                                 | MMM     | Jan, Feb, ..., Dec                |       |
 * |                                 | MMMM    | January, February, ..., December  | 2     |
 * |                                 | MMMMM   | J, F, ..., D                      |       |
 * | Month (stand-alone)             | L       | 1, 2, ..., 12                     |       |
 * |                                 | Lo      | 1st, 2nd, ..., 12th               | 7     |
 * |                                 | LL      | 01, 02, ..., 12                   |       |
 * |                                 | LLL     | Jan, Feb, ..., Dec                |       |
 * |                                 | LLLL    | January, February, ..., December  | 2     |
 * |                                 | LLLLL   | J, F, ..., D                      |       |
 * | Local week of year              | w       | 1, 2, ..., 53                     |       |
 * |                                 | wo      | 1st, 2nd, ..., 53th               | 7     |
 * |                                 | ww      | 01, 02, ..., 53                   |       |
 * | ISO week of year                | I       | 1, 2, ..., 53                     | 7     |
 * |                                 | Io      | 1st, 2nd, ..., 53th               | 7     |
 * |                                 | II      | 01, 02, ..., 53                   | 7     |
 * | Day of month                    | d       | 1, 2, ..., 31                     |       |
 * |                                 | do      | 1st, 2nd, ..., 31st               | 7     |
 * |                                 | dd      | 01, 02, ..., 31                   |       |
 * | Day of year                     | D       | 1, 2, ..., 365, 366               | 9     |
 * |                                 | Do      | 1st, 2nd, ..., 365th, 366th       | 7     |
 * |                                 | DD      | 01, 02, ..., 365, 366             | 9     |
 * |                                 | DDD     | 001, 002, ..., 365, 366           |       |
 * |                                 | DDDD    | ...                               | 3     |
 * | Day of week (formatting)        | E..EEE  | Mon, Tue, Wed, ..., Sun           |       |
 * |                                 | EEEE    | Monday, Tuesday, ..., Sunday      | 2     |
 * |                                 | EEEEE   | M, T, W, T, F, S, S               |       |
 * |                                 | EEEEEE  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
 * | ISO day of week (formatting)    | i       | 1, 2, 3, ..., 7                   | 7     |
 * |                                 | io      | 1st, 2nd, ..., 7th                | 7     |
 * |                                 | ii      | 01, 02, ..., 07                   | 7     |
 * |                                 | iii     | Mon, Tue, Wed, ..., Sun           | 7     |
 * |                                 | iiii    | Monday, Tuesday, ..., Sunday      | 2,7   |
 * |                                 | iiiii   | M, T, W, T, F, S, S               | 7     |
 * |                                 | iiiiii  | Mo, Tu, We, Th, Fr, Sa, Su        | 7     |
 * | Local day of week (formatting)  | e       | 2, 3, 4, ..., 1                   |       |
 * |                                 | eo      | 2nd, 3rd, ..., 1st                | 7     |
 * |                                 | ee      | 02, 03, ..., 01                   |       |
 * |                                 | eee     | Mon, Tue, Wed, ..., Sun           |       |
 * |                                 | eeee    | Monday, Tuesday, ..., Sunday      | 2     |
 * |                                 | eeeee   | M, T, W, T, F, S, S               |       |
 * |                                 | eeeeee  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
 * | Local day of week (stand-alone) | c       | 2, 3, 4, ..., 1                   |       |
 * |                                 | co      | 2nd, 3rd, ..., 1st                | 7     |
 * |                                 | cc      | 02, 03, ..., 01                   |       |
 * |                                 | ccc     | Mon, Tue, Wed, ..., Sun           |       |
 * |                                 | cccc    | Monday, Tuesday, ..., Sunday      | 2     |
 * |                                 | ccccc   | M, T, W, T, F, S, S               |       |
 * |                                 | cccccc  | Mo, Tu, We, Th, Fr, Sa, Su        |       |
 * | AM, PM                          | a..aa   | AM, PM                            |       |
 * |                                 | aaa     | am, pm                            |       |
 * |                                 | aaaa    | a.m., p.m.                        | 2     |
 * |                                 | aaaaa   | a, p                              |       |
 * | AM, PM, noon, midnight          | b..bb   | AM, PM, noon, midnight            |       |
 * |                                 | bbb     | am, pm, noon, midnight            |       |
 * |                                 | bbbb    | a.m., p.m., noon, midnight        | 2     |
 * |                                 | bbbbb   | a, p, n, mi                       |       |
 * | Flexible day period             | B..BBB  | at night, in the morning, ...     |       |
 * |                                 | BBBB    | at night, in the morning, ...     | 2     |
 * |                                 | BBBBB   | at night, in the morning, ...     |       |
 * | Hour [1-12]                     | h       | 1, 2, ..., 11, 12                 |       |
 * |                                 | ho      | 1st, 2nd, ..., 11th, 12th         | 7     |
 * |                                 | hh      | 01, 02, ..., 11, 12               |       |
 * | Hour [0-23]                     | H       | 0, 1, 2, ..., 23                  |       |
 * |                                 | Ho      | 0th, 1st, 2nd, ..., 23rd          | 7     |
 * |                                 | HH      | 00, 01, 02, ..., 23               |       |
 * | Hour [0-11]                     | K       | 1, 2, ..., 11, 0                  |       |
 * |                                 | Ko      | 1st, 2nd, ..., 11th, 0th          | 7     |
 * |                                 | KK      | 01, 02, ..., 11, 00               |       |
 * | Hour [1-24]                     | k       | 24, 1, 2, ..., 23                 |       |
 * |                                 | ko      | 24th, 1st, 2nd, ..., 23rd         | 7     |
 * |                                 | kk      | 24, 01, 02, ..., 23               |       |
 * | Minute                          | m       | 0, 1, ..., 59                     |       |
 * |                                 | mo      | 0th, 1st, ..., 59th               | 7     |
 * |                                 | mm      | 00, 01, ..., 59                   |       |
 * | Second                          | s       | 0, 1, ..., 59                     |       |
 * |                                 | so      | 0th, 1st, ..., 59th               | 7     |
 * |                                 | ss      | 00, 01, ..., 59                   |       |
 * | Fraction of second              | S       | 0, 1, ..., 9                      |       |
 * |                                 | SS      | 00, 01, ..., 99                   |       |
 * |                                 | SSS     | 000, 001, ..., 999                |       |
 * |                                 | SSSS    | ...                               | 3     |
 * | Timezone (ISO-8601 w/ Z)        | X       | -08, +0530, Z                     |       |
 * |                                 | XX      | -0800, +0530, Z                   |       |
 * |                                 | XXX     | -08:00, +05:30, Z                 |       |
 * |                                 | XXXX    | -0800, +0530, Z, +123456          | 2     |
 * |                                 | XXXXX   | -08:00, +05:30, Z, +12:34:56      |       |
 * | Timezone (ISO-8601 w/o Z)       | x       | -08, +0530, +00                   |       |
 * |                                 | xx      | -0800, +0530, +0000               |       |
 * |                                 | xxx     | -08:00, +05:30, +00:00            | 2     |
 * |                                 | xxxx    | -0800, +0530, +0000, +123456      |       |
 * |                                 | xxxxx   | -08:00, +05:30, +00:00, +12:34:56 |       |
 * | Timezone (GMT)                  | O...OOO | GMT-8, GMT+5:30, GMT+0            |       |
 * |                                 | OOOO    | GMT-08:00, GMT+05:30, GMT+00:00   | 2     |
 * | Timezone (specific non-locat.)  | z...zzz | GMT-8, GMT+5:30, GMT+0            | 6     |
 * |                                 | zzzz    | GMT-08:00, GMT+05:30, GMT+00:00   | 2,6   |
 * | Seconds timestamp               | t       | 512969520                         | 7     |
 * |                                 | tt      | ...                               | 3,7   |
 * | Milliseconds timestamp          | T       | 512969520900                      | 7     |
 * |                                 | TT      | ...                               | 3,7   |
 * | Long localized date             | P       | 04/29/1453                        | 7     |
 * |                                 | PP      | Apr 29, 1453                      | 7     |
 * |                                 | PPP     | April 29th, 1453                  | 7     |
 * |                                 | PPPP    | Friday, April 29th, 1453          | 2,7   |
 * | Long localized time             | p       | 12:00 AM                          | 7     |
 * |                                 | pp      | 12:00:00 AM                       | 7     |
 * |                                 | ppp     | 12:00:00 AM GMT+2                 | 7     |
 * |                                 | pppp    | 12:00:00 AM GMT+02:00             | 2,7   |
 * | Combination of date and time    | Pp      | 04/29/1453, 12:00 AM              | 7     |
 * |                                 | PPpp    | Apr 29, 1453, 12:00:00 AM         | 7     |
 * |                                 | PPPppp  | April 29th, 1453 at ...           | 7     |
 * |                                 | PPPPpppp| Friday, April 29th, 1453 at ...   | 2,7   |
 * Notes:
 * 1. "Formatting" units (e.g. formatting quarter) in the default en-US locale
 *    are the same as "stand-alone" units, but are different in some languages.
 *    "Formatting" units are declined according to the rules of the language
 *    in the context of a date. "Stand-alone" units are always nominative singular:
 *
 *    `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`
 *
 *    `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`
 *
 * 2. Any sequence of the identical letters is a pattern, unless it is escaped by
 *    the single quote characters (see below).
 *    If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)
 *    the output will be the same as default pattern for this unit, usually
 *    the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units
 *    are marked with "2" in the last column of the table.
 *
 *    `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`
 *
 *    `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`
 *
 *    `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`
 *
 *    `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`
 *
 *    `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`
 *
 * 3. Some patterns could be unlimited length (such as `yyyyyyyy`).
 *    The output will be padded with zeros to match the length of the pattern.
 *
 *    `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`
 *
 * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.
 *    These tokens represent the shortest form of the quarter.
 *
 * 5. The main difference between `y` and `u` patterns are B.C. years:
 *
 *    | Year | `y` | `u` |
 *    |------|-----|-----|
 *    | AC 1 |   1 |   1 |
 *    | BC 1 |   1 |   0 |
 *    | BC 2 |   2 |  -1 |
 *
 *    Also `yy` always returns the last two digits of a year,
 *    while `uu` pads single digit years to 2 characters and returns other years unchanged:
 *
 *    | Year | `yy` | `uu` |
 *    |------|------|------|
 *    | 1    |   01 |   01 |
 *    | 14   |   14 |   14 |
 *    | 376  |   76 |  376 |
 *    | 1453 |   53 | 1453 |
 *
 *    The same difference is true for local and ISO week-numbering years (`Y` and `R`),
 *    except local week-numbering years are dependent on `options.weekStartsOn`
 *    and `options.firstWeekContainsDate` (compare [getISOWeekYear](https://date-fns.org/docs/getISOWeekYear)
 *    and [getWeekYear](https://date-fns.org/docs/getWeekYear)).
 *
 * 6. Specific non-location timezones are currently unavailable in `date-fns`,
 *    so right now these tokens fall back to GMT timezones.
 *
 * 7. These patterns are not in the Unicode Technical Standard #35:
 *    - `i`: ISO day of week
 *    - `I`: ISO week of year
 *    - `R`: ISO week-numbering year
 *    - `t`: seconds timestamp
 *    - `T`: milliseconds timestamp
 *    - `o`: ordinal number modifier
 *    - `P`: long localized date
 *    - `p`: long localized time
 *
 * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.
 *    You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 *
 * 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month.
 *    You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 * @param format - The string of tokens
 * @param options - An object with options
 *
 * @returns The formatted date string
 *
 * @throws `date` must not be Invalid Date
 * @throws `options.locale` must contain `localize` property
 * @throws `options.locale` must contain `formatLong` property
 * @throws use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 * @throws use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 * @throws use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 * @throws use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md
 * @throws format string contains an unescaped latin alphabet character
 *
 * @example
 * // Represent 11 February 2014 in middle-endian format:
 * const result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')
 * //=> '02/11/2014'
 *
 * @example
 * // Represent 2 July 2014 in Esperanto:
 * import { eoLocale } from 'date-fns/locale/eo'
 * const result = format(new Date(2014, 6, 2), "do 'de' MMMM yyyy", {
 *   locale: eoLocale
 * })
 * //=> '2-a de julio 2014'
 *
 * @example
 * // Escape string by single quote characters:
 * const result = format(new Date(2014, 6, 2, 15), "h 'o''clock'")
 * //=> "3 o'clock"
 */
function format(date, formatStr, options) {
  const defaultOptions = (0,_lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_2__.getDefaultOptions)();
  const locale = options?.locale ?? defaultOptions.locale ?? _lib_defaultLocale_mjs__WEBPACK_IMPORTED_MODULE_3__.enUS;
  const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
  const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
  const originalDate = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_4__.toDate)(date);
  if (!(0,_isValid_mjs__WEBPACK_IMPORTED_MODULE_5__.isValid)(originalDate)) {
    throw new RangeError("Invalid time value");
  }
  let parts = formatStr.match(longFormattingTokensRegExp).map(substring => {
    const firstCharacter = substring[0];
    if (firstCharacter === "p" || firstCharacter === "P") {
      const longFormatter = _lib_format_longFormatters_mjs__WEBPACK_IMPORTED_MODULE_1__.longFormatters[firstCharacter];
      return longFormatter(substring, locale.formatLong);
    }
    return substring;
  }).join("").match(formattingTokensRegExp).map(substring => {
    // Replace two single quote characters with one single quote character
    if (substring === "''") {
      return {
        isToken: false,
        value: "'"
      };
    }
    const firstCharacter = substring[0];
    if (firstCharacter === "'") {
      return {
        isToken: false,
        value: cleanEscapedString(substring)
      };
    }
    if (_lib_format_formatters_mjs__WEBPACK_IMPORTED_MODULE_0__.formatters[firstCharacter]) {
      return {
        isToken: true,
        value: substring
      };
    }
    if (firstCharacter.match(unescapedLatinCharacterRegExp)) {
      throw new RangeError("Format string contains an unescaped latin alphabet character `" + firstCharacter + "`");
    }
    return {
      isToken: false,
      value: substring
    };
  });

  // invoke localize preprocessor (only for french locales at the moment)
  if (locale.localize.preprocessor) {
    parts = locale.localize.preprocessor(originalDate, parts);
  }
  const formatterOptions = {
    firstWeekContainsDate,
    weekStartsOn,
    locale
  };
  return parts.map(part => {
    if (!part.isToken) return part.value;
    const token = part.value;
    if (!options?.useAdditionalWeekYearTokens && (0,_lib_protectedTokens_mjs__WEBPACK_IMPORTED_MODULE_6__.isProtectedWeekYearToken)(token) || !options?.useAdditionalDayOfYearTokens && (0,_lib_protectedTokens_mjs__WEBPACK_IMPORTED_MODULE_6__.isProtectedDayOfYearToken)(token)) {
      (0,_lib_protectedTokens_mjs__WEBPACK_IMPORTED_MODULE_6__.warnOrThrowProtectedError)(token, formatStr, String(date));
    }
    const formatter = _lib_format_formatters_mjs__WEBPACK_IMPORTED_MODULE_0__.formatters[token[0]];
    return formatter(originalDate, token, locale.localize, formatterOptions);
  }).join("");
}
function cleanEscapedString(input) {
  const matched = input.match(escapedStringRegExp);
  if (!matched) {
    return input;
  }
  return matched[1].replace(doubleQuoteRegExp, "'");
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (format);

/***/ }),

/***/ 57:
/*!************************************************!*\
  !*** ./node_modules/date-fns/getDayOfYear.mjs ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getDayOfYear: () => (/* binding */ getDayOfYear)
/* harmony export */ });
/* harmony import */ var _differenceInCalendarDays_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./differenceInCalendarDays.mjs */ 56248);
/* harmony import */ var _startOfYear_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./startOfYear.mjs */ 99229);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);




/**
 * @name getDayOfYear
 * @category Day Helpers
 * @summary Get the day of the year of the given date.
 *
 * @description
 * Get the day of the year of the given date.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The given date
 *
 * @returns The day of year
 *
 * @example
 * // Which day of the year is 2 July 2014?
 * const result = getDayOfYear(new Date(2014, 6, 2))
 * //=> 183
 */
function getDayOfYear(date) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const diff = (0,_differenceInCalendarDays_mjs__WEBPACK_IMPORTED_MODULE_1__.differenceInCalendarDays)(_date, (0,_startOfYear_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfYear)(_date));
  const dayOfYear = diff + 1;
  return dayOfYear;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getDayOfYear);

/***/ }),

/***/ 27308:
/*!**********************************************!*\
  !*** ./node_modules/date-fns/getISOWeek.mjs ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getISOWeek: () => (/* binding */ getISOWeek)
/* harmony export */ });
/* harmony import */ var _constants_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./constants.mjs */ 87870);
/* harmony import */ var _startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./startOfISOWeek.mjs */ 47545);
/* harmony import */ var _startOfISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./startOfISOWeekYear.mjs */ 11050);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);





/**
 * @name getISOWeek
 * @category ISO Week Helpers
 * @summary Get the ISO week of the given date.
 *
 * @description
 * Get the ISO week of the given date.
 *
 * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The given date
 *
 * @returns The ISO week
 *
 * @example
 * // Which week of the ISO-week numbering year is 2 January 2005?
 * const result = getISOWeek(new Date(2005, 0, 2))
 * //=> 53
 */
function getISOWeek(date) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const diff = +(0,_startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_1__.startOfISOWeek)(_date) - +(0,_startOfISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfISOWeekYear)(_date);

  // Round the number of weeks to the nearest integer because the number of
  // milliseconds in a week is not constant (e.g. it's different in the week of
  // the daylight saving time clock shift).
  return Math.round(diff / _constants_mjs__WEBPACK_IMPORTED_MODULE_3__.millisecondsInWeek) + 1;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getISOWeek);

/***/ }),

/***/ 31359:
/*!**************************************************!*\
  !*** ./node_modules/date-fns/getISOWeekYear.mjs ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getISOWeekYear: () => (/* binding */ getISOWeekYear)
/* harmony export */ });
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);
/* harmony import */ var _startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./startOfISOWeek.mjs */ 47545);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);




/**
 * @name getISOWeekYear
 * @category ISO Week-Numbering Year Helpers
 * @summary Get the ISO week-numbering year of the given date.
 *
 * @description
 * Get the ISO week-numbering year of the given date,
 * which always starts 3 days before the year's first Thursday.
 *
 * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The given date
 *
 * @returns The ISO week-numbering year
 *
 * @example
 * // Which ISO-week numbering year is 2 January 2005?
 * const result = getISOWeekYear(new Date(2005, 0, 2))
 * //=> 2004
 */
function getISOWeekYear(date) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const year = _date.getFullYear();
  const fourthOfJanuaryOfNextYear = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__.constructFrom)(date, 0);
  fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);
  fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);
  const startOfNextYear = (0,_startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfISOWeek)(fourthOfJanuaryOfNextYear);
  const fourthOfJanuaryOfThisYear = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__.constructFrom)(date, 0);
  fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);
  fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);
  const startOfThisYear = (0,_startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfISOWeek)(fourthOfJanuaryOfThisYear);
  if (_date.getTime() >= startOfNextYear.getTime()) {
    return year + 1;
  } else if (_date.getTime() >= startOfThisYear.getTime()) {
    return year;
  } else {
    return year - 1;
  }
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getISOWeekYear);

/***/ }),

/***/ 88245:
/*!*******************************************!*\
  !*** ./node_modules/date-fns/getWeek.mjs ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getWeek: () => (/* binding */ getWeek)
/* harmony export */ });
/* harmony import */ var _constants_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./constants.mjs */ 87870);
/* harmony import */ var _startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./startOfWeek.mjs */ 90610);
/* harmony import */ var _startOfWeekYear_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./startOfWeekYear.mjs */ 58505);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);





/**
 * The {@link getWeek} function options.
 */

/**
 * @name getWeek
 * @category Week Helpers
 * @summary Get the local week index of the given date.
 *
 * @description
 * Get the local week index of the given date.
 * The exact calculation depends on the values of
 * `options.weekStartsOn` (which is the index of the first day of the week)
 * and `options.firstWeekContainsDate` (which is the day of January, which is always in
 * the first week of the week-numbering year)
 *
 * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The given date
 * @param options - An object with options
 *
 * @returns The week
 *
 * @example
 * // Which week of the local week numbering year is 2 January 2005 with default options?
 * const result = getWeek(new Date(2005, 0, 2))
 * //=> 2
 *
 * @example
 * // Which week of the local week numbering year is 2 January 2005,
 * // if Monday is the first day of the week,
 * // and the first week of the year always contains 4 January?
 * const result = getWeek(new Date(2005, 0, 2), {
 *   weekStartsOn: 1,
 *   firstWeekContainsDate: 4
 * })
 * //=> 53
 */

function getWeek(date, options) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const diff = +(0,_startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_1__.startOfWeek)(_date, options) - +(0,_startOfWeekYear_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfWeekYear)(_date, options);

  // Round the number of weeks to the nearest integer because the number of
  // milliseconds in a week is not constant (e.g. it's different in the week of
  // the daylight saving time clock shift).
  return Math.round(diff / _constants_mjs__WEBPACK_IMPORTED_MODULE_3__.millisecondsInWeek) + 1;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getWeek);

/***/ }),

/***/ 21598:
/*!***********************************************!*\
  !*** ./node_modules/date-fns/getWeekYear.mjs ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   getWeekYear: () => (/* binding */ getWeekYear)
/* harmony export */ });
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);
/* harmony import */ var _startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./startOfWeek.mjs */ 90610);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);
/* harmony import */ var _lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_lib/defaultOptions.mjs */ 19857);





/**
 * The {@link getWeekYear} function options.
 */

/**
 * @name getWeekYear
 * @category Week-Numbering Year Helpers
 * @summary Get the local week-numbering year of the given date.
 *
 * @description
 * Get the local week-numbering year of the given date.
 * The exact calculation depends on the values of
 * `options.weekStartsOn` (which is the index of the first day of the week)
 * and `options.firstWeekContainsDate` (which is the day of January, which is always in
 * the first week of the week-numbering year)
 *
 * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The given date
 * @param options - An object with options.
 *
 * @returns The local week-numbering year
 *
 * @example
 * // Which week numbering year is 26 December 2004 with the default settings?
 * const result = getWeekYear(new Date(2004, 11, 26))
 * //=> 2005
 *
 * @example
 * // Which week numbering year is 26 December 2004 if week starts on Saturday?
 * const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })
 * //=> 2004
 *
 * @example
 * // Which week numbering year is 26 December 2004 if the first week contains 4 January?
 * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })
 * //=> 2004
 */
function getWeekYear(date, options) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const year = _date.getFullYear();
  const defaultOptions = (0,_lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_1__.getDefaultOptions)();
  const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
  const firstWeekOfNextYear = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_2__.constructFrom)(date, 0);
  firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);
  firstWeekOfNextYear.setHours(0, 0, 0, 0);
  const startOfNextYear = (0,_startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_3__.startOfWeek)(firstWeekOfNextYear, options);
  const firstWeekOfThisYear = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_2__.constructFrom)(date, 0);
  firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);
  firstWeekOfThisYear.setHours(0, 0, 0, 0);
  const startOfThisYear = (0,_startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_3__.startOfWeek)(firstWeekOfThisYear, options);
  if (_date.getTime() >= startOfNextYear.getTime()) {
    return year + 1;
  } else if (_date.getTime() >= startOfThisYear.getTime()) {
    return year;
  } else {
    return year - 1;
  }
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getWeekYear);

/***/ }),

/***/ 55882:
/*!********************************************!*\
  !*** ./node_modules/date-fns/isBefore.mjs ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   isBefore: () => (/* binding */ isBefore)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);


/**
 * @name isBefore
 * @category Common Helpers
 * @summary Is the first date before the second one?
 *
 * @description
 * Is the first date before the second one?
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The date that should be before the other one to return true
 * @param dateToCompare - The date to compare with
 *
 * @returns The first date is before the second date
 *
 * @example
 * // Is 10 July 1989 before 11 February 1987?
 * const result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11))
 * //=> false
 */
function isBefore(date, dateToCompare) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const _dateToCompare = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(dateToCompare);
  return +_date < +_dateToCompare;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isBefore);

/***/ }),

/***/ 54859:
/*!******************************************!*\
  !*** ./node_modules/date-fns/isDate.mjs ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   isDate: () => (/* binding */ isDate)
/* harmony export */ });
/**
 * @name isDate
 * @category Common Helpers
 * @summary Is the given value a date?
 *
 * @description
 * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.
 *
 * @param value - The value to check
 *
 * @returns True if the given value is a date
 *
 * @example
 * // For a valid date:
 * const result = isDate(new Date())
 * //=> true
 *
 * @example
 * // For an invalid date:
 * const result = isDate(new Date(NaN))
 * //=> true
 *
 * @example
 * // For some value:
 * const result = isDate('2014-02-31')
 * //=> false
 *
 * @example
 * // For an object:
 * const result = isDate({})
 * //=> false
 */
function isDate(value) {
  return value instanceof Date || typeof value === "object" && Object.prototype.toString.call(value) === "[object Date]";
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isDate);

/***/ }),

/***/ 86211:
/*!*******************************************!*\
  !*** ./node_modules/date-fns/isValid.mjs ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   isValid: () => (/* binding */ isValid)
/* harmony export */ });
/* harmony import */ var _isDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isDate.mjs */ 54859);
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toDate.mjs */ 58700);



/**
 * @name isValid
 * @category Common Helpers
 * @summary Is the given date valid?
 *
 * @description
 * Returns false if argument is Invalid Date and true otherwise.
 * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)
 * Invalid Date is a Date, whose time value is NaN.
 *
 * Time value of Date: http://es5.github.io/#x15.9.1.1
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The date to check
 *
 * @returns The date is valid
 *
 * @example
 * // For the valid date:
 * const result = isValid(new Date(2014, 1, 31))
 * //=> true
 *
 * @example
 * // For the value, convertable into a date:
 * const result = isValid(1393804800000)
 * //=> true
 *
 * @example
 * // For the invalid date:
 * const result = isValid(new Date(''))
 * //=> false
 */
function isValid(date) {
  if (!(0,_isDate_mjs__WEBPACK_IMPORTED_MODULE_0__.isDate)(date) && typeof date !== "number") {
    return false;
  }
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_1__.toDate)(date);
  return !isNaN(Number(_date));
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isValid);

/***/ }),

/***/ 29226:
/*!*****************************************************************!*\
  !*** ./node_modules/date-fns/locale/_lib/buildFormatLongFn.mjs ***!
  \*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   buildFormatLongFn: () => (/* binding */ buildFormatLongFn)
/* harmony export */ });
function buildFormatLongFn(args) {
  return (options = {}) => {
    // TODO: Remove String()
    const width = options.width ? String(options.width) : args.defaultWidth;
    const format = args.formats[width] || args.formats[args.defaultWidth];
    return format;
  };
}

/***/ }),

/***/ 3872:
/*!***************************************************************!*\
  !*** ./node_modules/date-fns/locale/_lib/buildLocalizeFn.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   buildLocalizeFn: () => (/* binding */ buildLocalizeFn)
/* harmony export */ });
/* eslint-disable no-unused-vars */

/**
 * The localize function argument callback which allows to convert raw value to
 * the actual type.
 *
 * @param value - The value to convert
 *
 * @returns The converted value
 */

/**
 * The map of localized values for each width.
 */

/**
 * The index type of the locale unit value. It types conversion of units of
 * values that don't start at 0 (i.e. quarters).
 */

/**
 * Converts the unit value to the tuple of values.
 */

/**
 * The tuple of localized era values. The first element represents BC,
 * the second element represents AD.
 */

/**
 * The tuple of localized quarter values. The first element represents Q1.
 */

/**
 * The tuple of localized day values. The first element represents Sunday.
 */

/**
 * The tuple of localized month values. The first element represents January.
 */

function buildLocalizeFn(args) {
  return (value, options) => {
    const context = options?.context ? String(options.context) : "standalone";
    let valuesArray;
    if (context === "formatting" && args.formattingValues) {
      const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;
      const width = options?.width ? String(options.width) : defaultWidth;
      valuesArray = args.formattingValues[width] || args.formattingValues[defaultWidth];
    } else {
      const defaultWidth = args.defaultWidth;
      const width = options?.width ? String(options.width) : args.defaultWidth;
      valuesArray = args.values[width] || args.values[defaultWidth];
    }
    const index = args.argumentCallback ? args.argumentCallback(value) : value;

    // @ts-expect-error - For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!
    return valuesArray[index];
  };
}

/***/ }),

/***/ 80268:
/*!************************************************************!*\
  !*** ./node_modules/date-fns/locale/_lib/buildMatchFn.mjs ***!
  \************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   buildMatchFn: () => (/* binding */ buildMatchFn)
/* harmony export */ });
function buildMatchFn(args) {
  return (string, options = {}) => {
    const width = options.width;
    const matchPattern = width && args.matchPatterns[width] || args.matchPatterns[args.defaultMatchWidth];
    const matchResult = string.match(matchPattern);
    if (!matchResult) {
      return null;
    }
    const matchedString = matchResult[0];
    const parsePatterns = width && args.parsePatterns[width] || args.parsePatterns[args.defaultParseWidth];
    const key = Array.isArray(parsePatterns) ? findIndex(parsePatterns, pattern => pattern.test(matchedString)) :
    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I challange you to fix the type
    findKey(parsePatterns, pattern => pattern.test(matchedString));
    let value;
    value = args.valueCallback ? args.valueCallback(key) : key;
    value = options.valueCallback ?
    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I challange you to fix the type
    options.valueCallback(value) : value;
    const rest = string.slice(matchedString.length);
    return {
      value,
      rest
    };
  };
}
function findKey(object, predicate) {
  for (const key in object) {
    if (Object.prototype.hasOwnProperty.call(object, key) && predicate(object[key])) {
      return key;
    }
  }
  return undefined;
}
function findIndex(array, predicate) {
  for (let key = 0; key < array.length; key++) {
    if (predicate(array[key])) {
      return key;
    }
  }
  return undefined;
}

/***/ }),

/***/ 64162:
/*!*******************************************************************!*\
  !*** ./node_modules/date-fns/locale/_lib/buildMatchPatternFn.mjs ***!
  \*******************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   buildMatchPatternFn: () => (/* binding */ buildMatchPatternFn)
/* harmony export */ });
function buildMatchPatternFn(args) {
  return (string, options = {}) => {
    const matchResult = string.match(args.matchPattern);
    if (!matchResult) return null;
    const matchedString = matchResult[0];
    const parseResult = string.match(args.parsePattern);
    if (!parseResult) return null;
    let value = args.valueCallback ? args.valueCallback(parseResult[0]) : parseResult[0];

    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- I challange you to fix the type
    value = options.valueCallback ? options.valueCallback(value) : value;
    const rest = string.slice(matchedString.length);
    return {
      value,
      rest
    };
  };
}

/***/ }),

/***/ 12302:
/*!************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US.mjs ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   enUS: () => (/* binding */ enUS)
/* harmony export */ });
/* harmony import */ var _en_US_lib_formatDistance_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./en-US/_lib/formatDistance.mjs */ 99688);
/* harmony import */ var _en_US_lib_formatLong_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./en-US/_lib/formatLong.mjs */ 30303);
/* harmony import */ var _en_US_lib_formatRelative_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./en-US/_lib/formatRelative.mjs */ 53873);
/* harmony import */ var _en_US_lib_localize_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./en-US/_lib/localize.mjs */ 86361);
/* harmony import */ var _en_US_lib_match_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./en-US/_lib/match.mjs */ 36099);






/**
 * @category Locales
 * @summary English locale (United States).
 * @language English
 * @iso-639-2 eng
 * @author Sasha Koss [@kossnocorp](https://github.com/kossnocorp)
 * @author Lesha Koss [@leshakoss](https://github.com/leshakoss)
 */
const enUS = {
  code: "en-US",
  formatDistance: _en_US_lib_formatDistance_mjs__WEBPACK_IMPORTED_MODULE_0__.formatDistance,
  formatLong: _en_US_lib_formatLong_mjs__WEBPACK_IMPORTED_MODULE_1__.formatLong,
  formatRelative: _en_US_lib_formatRelative_mjs__WEBPACK_IMPORTED_MODULE_2__.formatRelative,
  localize: _en_US_lib_localize_mjs__WEBPACK_IMPORTED_MODULE_3__.localize,
  match: _en_US_lib_match_mjs__WEBPACK_IMPORTED_MODULE_4__.match,
  options: {
    weekStartsOn: 0 /* Sunday */,
    firstWeekContainsDate: 1
  }
};

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (enUS);

/***/ }),

/***/ 99688:
/*!********************************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US/_lib/formatDistance.mjs ***!
  \********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatDistance: () => (/* binding */ formatDistance)
/* harmony export */ });
const formatDistanceLocale = {
  lessThanXSeconds: {
    one: "less than a second",
    other: "less than {{count}} seconds"
  },
  xSeconds: {
    one: "1 second",
    other: "{{count}} seconds"
  },
  halfAMinute: "half a minute",
  lessThanXMinutes: {
    one: "less than a minute",
    other: "less than {{count}} minutes"
  },
  xMinutes: {
    one: "1 minute",
    other: "{{count}} minutes"
  },
  aboutXHours: {
    one: "about 1 hour",
    other: "about {{count}} hours"
  },
  xHours: {
    one: "1 hour",
    other: "{{count}} hours"
  },
  xDays: {
    one: "1 day",
    other: "{{count}} days"
  },
  aboutXWeeks: {
    one: "about 1 week",
    other: "about {{count}} weeks"
  },
  xWeeks: {
    one: "1 week",
    other: "{{count}} weeks"
  },
  aboutXMonths: {
    one: "about 1 month",
    other: "about {{count}} months"
  },
  xMonths: {
    one: "1 month",
    other: "{{count}} months"
  },
  aboutXYears: {
    one: "about 1 year",
    other: "about {{count}} years"
  },
  xYears: {
    one: "1 year",
    other: "{{count}} years"
  },
  overXYears: {
    one: "over 1 year",
    other: "over {{count}} years"
  },
  almostXYears: {
    one: "almost 1 year",
    other: "almost {{count}} years"
  }
};
const formatDistance = (token, count, options) => {
  let result;
  const tokenValue = formatDistanceLocale[token];
  if (typeof tokenValue === "string") {
    result = tokenValue;
  } else if (count === 1) {
    result = tokenValue.one;
  } else {
    result = tokenValue.other.replace("{{count}}", count.toString());
  }
  if (options?.addSuffix) {
    if (options.comparison && options.comparison > 0) {
      return "in " + result;
    } else {
      return result + " ago";
    }
  }
  return result;
};

/***/ }),

/***/ 30303:
/*!****************************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US/_lib/formatLong.mjs ***!
  \****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatLong: () => (/* binding */ formatLong)
/* harmony export */ });
/* harmony import */ var _lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildFormatLongFn.mjs */ 29226);

const dateFormats = {
  full: "EEEE, MMMM do, y",
  long: "MMMM do, y",
  medium: "MMM d, y",
  short: "MM/dd/yyyy"
};
const timeFormats = {
  full: "h:mm:ss a zzzz",
  long: "h:mm:ss a z",
  medium: "h:mm:ss a",
  short: "h:mm a"
};
const dateTimeFormats = {
  full: "{{date}} 'at' {{time}}",
  long: "{{date}} 'at' {{time}}",
  medium: "{{date}}, {{time}}",
  short: "{{date}}, {{time}}"
};
const formatLong = {
  date: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: dateFormats,
    defaultWidth: "full"
  }),
  time: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: timeFormats,
    defaultWidth: "full"
  }),
  dateTime: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: dateTimeFormats,
    defaultWidth: "full"
  })
};

/***/ }),

/***/ 53873:
/*!********************************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US/_lib/formatRelative.mjs ***!
  \********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatRelative: () => (/* binding */ formatRelative)
/* harmony export */ });
const formatRelativeLocale = {
  lastWeek: "'last' eeee 'at' p",
  yesterday: "'yesterday at' p",
  today: "'today at' p",
  tomorrow: "'tomorrow at' p",
  nextWeek: "eeee 'at' p",
  other: "P"
};
const formatRelative = (token, _date, _baseDate, _options) => formatRelativeLocale[token];

/***/ }),

/***/ 86361:
/*!**************************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US/_lib/localize.mjs ***!
  \**************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   localize: () => (/* binding */ localize)
/* harmony export */ });
/* harmony import */ var _lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildLocalizeFn.mjs */ 3872);

const eraValues = {
  narrow: ["B", "A"],
  abbreviated: ["BC", "AD"],
  wide: ["Before Christ", "Anno Domini"]
};
const quarterValues = {
  narrow: ["1", "2", "3", "4"],
  abbreviated: ["Q1", "Q2", "Q3", "Q4"],
  wide: ["1st quarter", "2nd quarter", "3rd quarter", "4th quarter"]
};

// Note: in English, the names of days of the week and months are capitalized.
// If you are making a new locale based on this one, check if the same is true for the language you're working on.
// Generally, formatted dates should look like they are in the middle of a sentence,
// e.g. in Spanish language the weekdays and months should be in the lowercase.
const monthValues = {
  narrow: ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"],
  abbreviated: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
  wide: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
};
const dayValues = {
  narrow: ["S", "M", "T", "W", "T", "F", "S"],
  short: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
  abbreviated: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  wide: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
};
const dayPeriodValues = {
  narrow: {
    am: "a",
    pm: "p",
    midnight: "mi",
    noon: "n",
    morning: "morning",
    afternoon: "afternoon",
    evening: "evening",
    night: "night"
  },
  abbreviated: {
    am: "AM",
    pm: "PM",
    midnight: "midnight",
    noon: "noon",
    morning: "morning",
    afternoon: "afternoon",
    evening: "evening",
    night: "night"
  },
  wide: {
    am: "a.m.",
    pm: "p.m.",
    midnight: "midnight",
    noon: "noon",
    morning: "morning",
    afternoon: "afternoon",
    evening: "evening",
    night: "night"
  }
};
const formattingDayPeriodValues = {
  narrow: {
    am: "a",
    pm: "p",
    midnight: "mi",
    noon: "n",
    morning: "in the morning",
    afternoon: "in the afternoon",
    evening: "in the evening",
    night: "at night"
  },
  abbreviated: {
    am: "AM",
    pm: "PM",
    midnight: "midnight",
    noon: "noon",
    morning: "in the morning",
    afternoon: "in the afternoon",
    evening: "in the evening",
    night: "at night"
  },
  wide: {
    am: "a.m.",
    pm: "p.m.",
    midnight: "midnight",
    noon: "noon",
    morning: "in the morning",
    afternoon: "in the afternoon",
    evening: "in the evening",
    night: "at night"
  }
};
const ordinalNumber = (dirtyNumber, _options) => {
  const number = Number(dirtyNumber);

  // If ordinal numbers depend on context, for example,
  // if they are different for different grammatical genders,
  // use `options.unit`.
  //
  // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',
  // 'day', 'hour', 'minute', 'second'.

  const rem100 = number % 100;
  if (rem100 > 20 || rem100 < 10) {
    switch (rem100 % 10) {
      case 1:
        return number + "st";
      case 2:
        return number + "nd";
      case 3:
        return number + "rd";
    }
  }
  return number + "th";
};
const localize = {
  ordinalNumber,
  era: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: eraValues,
    defaultWidth: "wide"
  }),
  quarter: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: quarterValues,
    defaultWidth: "wide",
    argumentCallback: quarter => quarter - 1
  }),
  month: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: monthValues,
    defaultWidth: "wide"
  }),
  day: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: dayValues,
    defaultWidth: "wide"
  }),
  dayPeriod: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: dayPeriodValues,
    defaultWidth: "wide",
    formattingValues: formattingDayPeriodValues,
    defaultFormattingWidth: "wide"
  })
};

/***/ }),

/***/ 36099:
/*!***********************************************************!*\
  !*** ./node_modules/date-fns/locale/en-US/_lib/match.mjs ***!
  \***********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   match: () => (/* binding */ match)
/* harmony export */ });
/* harmony import */ var _lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../_lib/buildMatchFn.mjs */ 80268);
/* harmony import */ var _lib_buildMatchPatternFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildMatchPatternFn.mjs */ 64162);


const matchOrdinalNumberPattern = /^(\d+)(th|st|nd|rd)?/i;
const parseOrdinalNumberPattern = /\d+/i;
const matchEraPatterns = {
  narrow: /^(b|a)/i,
  abbreviated: /^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,
  wide: /^(before christ|before common era|anno domini|common era)/i
};
const parseEraPatterns = {
  any: [/^b/i, /^(a|c)/i]
};
const matchQuarterPatterns = {
  narrow: /^[1234]/i,
  abbreviated: /^q[1234]/i,
  wide: /^[1234](th|st|nd|rd)? quarter/i
};
const parseQuarterPatterns = {
  any: [/1/i, /2/i, /3/i, /4/i]
};
const matchMonthPatterns = {
  narrow: /^[jfmasond]/i,
  abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,
  wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i
};
const parseMonthPatterns = {
  narrow: [/^j/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],
  any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i]
};
const matchDayPatterns = {
  narrow: /^[smtwf]/i,
  short: /^(su|mo|tu|we|th|fr|sa)/i,
  abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,
  wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i
};
const parseDayPatterns = {
  narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],
  any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i]
};
const matchDayPeriodPatterns = {
  narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,
  any: /^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i
};
const parseDayPeriodPatterns = {
  any: {
    am: /^a/i,
    pm: /^p/i,
    midnight: /^mi/i,
    noon: /^no/i,
    morning: /morning/i,
    afternoon: /afternoon/i,
    evening: /evening/i,
    night: /night/i
  }
};
const match = {
  ordinalNumber: (0,_lib_buildMatchPatternFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildMatchPatternFn)({
    matchPattern: matchOrdinalNumberPattern,
    parsePattern: parseOrdinalNumberPattern,
    valueCallback: value => parseInt(value, 10)
  }),
  era: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchEraPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseEraPatterns,
    defaultParseWidth: "any"
  }),
  quarter: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchQuarterPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseQuarterPatterns,
    defaultParseWidth: "any",
    valueCallback: index => index + 1
  }),
  month: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchMonthPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseMonthPatterns,
    defaultParseWidth: "any"
  }),
  day: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchDayPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseDayPatterns,
    defaultParseWidth: "any"
  }),
  dayPeriod: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchDayPeriodPatterns,
    defaultMatchWidth: "any",
    parsePatterns: parseDayPeriodPatterns,
    defaultParseWidth: "any"
  })
};

/***/ }),

/***/ 9616:
/*!*********************************************!*\
  !*** ./node_modules/date-fns/locale/es.mjs ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   es: () => (/* binding */ es)
/* harmony export */ });
/* harmony import */ var _es_lib_formatDistance_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./es/_lib/formatDistance.mjs */ 15850);
/* harmony import */ var _es_lib_formatLong_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./es/_lib/formatLong.mjs */ 57841);
/* harmony import */ var _es_lib_formatRelative_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./es/_lib/formatRelative.mjs */ 44119);
/* harmony import */ var _es_lib_localize_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./es/_lib/localize.mjs */ 20911);
/* harmony import */ var _es_lib_match_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./es/_lib/match.mjs */ 64813);






/**
 * @category Locales
 * @summary Spanish locale.
 * @language Spanish
 * @iso-639-2 spa
 * @author Juan Angosto [@juanangosto](https://github.com/juanangosto)
 * @author Guillermo Grau [@guigrpa](https://github.com/guigrpa)
 * @author Fernando Agüero [@fjaguero](https://github.com/fjaguero)
 * @author Gastón Haro [@harogaston](https://github.com/harogaston)
 * @author Yago Carballo [@YagoCarballo](https://github.com/YagoCarballo)
 */
const es = {
  code: "es",
  formatDistance: _es_lib_formatDistance_mjs__WEBPACK_IMPORTED_MODULE_0__.formatDistance,
  formatLong: _es_lib_formatLong_mjs__WEBPACK_IMPORTED_MODULE_1__.formatLong,
  formatRelative: _es_lib_formatRelative_mjs__WEBPACK_IMPORTED_MODULE_2__.formatRelative,
  localize: _es_lib_localize_mjs__WEBPACK_IMPORTED_MODULE_3__.localize,
  match: _es_lib_match_mjs__WEBPACK_IMPORTED_MODULE_4__.match,
  options: {
    weekStartsOn: 1 /* Monday */,
    firstWeekContainsDate: 1
  }
};

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (es);

/***/ }),

/***/ 15850:
/*!*****************************************************************!*\
  !*** ./node_modules/date-fns/locale/es/_lib/formatDistance.mjs ***!
  \*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatDistance: () => (/* binding */ formatDistance)
/* harmony export */ });
const formatDistanceLocale = {
  lessThanXSeconds: {
    one: "menos de un segundo",
    other: "menos de {{count}} segundos"
  },
  xSeconds: {
    one: "1 segundo",
    other: "{{count}} segundos"
  },
  halfAMinute: "medio minuto",
  lessThanXMinutes: {
    one: "menos de un minuto",
    other: "menos de {{count}} minutos"
  },
  xMinutes: {
    one: "1 minuto",
    other: "{{count}} minutos"
  },
  aboutXHours: {
    one: "alrededor de 1 hora",
    other: "alrededor de {{count}} horas"
  },
  xHours: {
    one: "1 hora",
    other: "{{count}} horas"
  },
  xDays: {
    one: "1 día",
    other: "{{count}} días"
  },
  aboutXWeeks: {
    one: "alrededor de 1 semana",
    other: "alrededor de {{count}} semanas"
  },
  xWeeks: {
    one: "1 semana",
    other: "{{count}} semanas"
  },
  aboutXMonths: {
    one: "alrededor de 1 mes",
    other: "alrededor de {{count}} meses"
  },
  xMonths: {
    one: "1 mes",
    other: "{{count}} meses"
  },
  aboutXYears: {
    one: "alrededor de 1 año",
    other: "alrededor de {{count}} años"
  },
  xYears: {
    one: "1 año",
    other: "{{count}} años"
  },
  overXYears: {
    one: "más de 1 año",
    other: "más de {{count}} años"
  },
  almostXYears: {
    one: "casi 1 año",
    other: "casi {{count}} años"
  }
};
const formatDistance = (token, count, options) => {
  let result;
  const tokenValue = formatDistanceLocale[token];
  if (typeof tokenValue === "string") {
    result = tokenValue;
  } else if (count === 1) {
    result = tokenValue.one;
  } else {
    result = tokenValue.other.replace("{{count}}", count.toString());
  }
  if (options?.addSuffix) {
    if (options.comparison && options.comparison > 0) {
      return "en " + result;
    } else {
      return "hace " + result;
    }
  }
  return result;
};

/***/ }),

/***/ 57841:
/*!*************************************************************!*\
  !*** ./node_modules/date-fns/locale/es/_lib/formatLong.mjs ***!
  \*************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatLong: () => (/* binding */ formatLong)
/* harmony export */ });
/* harmony import */ var _lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildFormatLongFn.mjs */ 29226);

const dateFormats = {
  full: "EEEE, d 'de' MMMM 'de' y",
  long: "d 'de' MMMM 'de' y",
  medium: "d MMM y",
  short: "dd/MM/y"
};
const timeFormats = {
  full: "HH:mm:ss zzzz",
  long: "HH:mm:ss z",
  medium: "HH:mm:ss",
  short: "HH:mm"
};
const dateTimeFormats = {
  full: "{{date}} 'a las' {{time}}",
  long: "{{date}} 'a las' {{time}}",
  medium: "{{date}}, {{time}}",
  short: "{{date}}, {{time}}"
};
const formatLong = {
  date: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: dateFormats,
    defaultWidth: "full"
  }),
  time: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: timeFormats,
    defaultWidth: "full"
  }),
  dateTime: (0,_lib_buildFormatLongFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildFormatLongFn)({
    formats: dateTimeFormats,
    defaultWidth: "full"
  })
};

/***/ }),

/***/ 44119:
/*!*****************************************************************!*\
  !*** ./node_modules/date-fns/locale/es/_lib/formatRelative.mjs ***!
  \*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   formatRelative: () => (/* binding */ formatRelative)
/* harmony export */ });
const formatRelativeLocale = {
  lastWeek: "'el' eeee 'pasado a la' p",
  yesterday: "'ayer a la' p",
  today: "'hoy a la' p",
  tomorrow: "'mañana a la' p",
  nextWeek: "eeee 'a la' p",
  other: "P"
};
const formatRelativeLocalePlural = {
  lastWeek: "'el' eeee 'pasado a las' p",
  yesterday: "'ayer a las' p",
  today: "'hoy a las' p",
  tomorrow: "'mañana a las' p",
  nextWeek: "eeee 'a las' p",
  other: "P"
};
const formatRelative = (token, date, _baseDate, _options) => {
  if (date.getHours() !== 1) {
    return formatRelativeLocalePlural[token];
  } else {
    return formatRelativeLocale[token];
  }
};

/***/ }),

/***/ 20911:
/*!***********************************************************!*\
  !*** ./node_modules/date-fns/locale/es/_lib/localize.mjs ***!
  \***********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   localize: () => (/* binding */ localize)
/* harmony export */ });
/* harmony import */ var _lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildLocalizeFn.mjs */ 3872);

const eraValues = {
  narrow: ["AC", "DC"],
  abbreviated: ["AC", "DC"],
  wide: ["antes de cristo", "después de cristo"]
};
const quarterValues = {
  narrow: ["1", "2", "3", "4"],
  abbreviated: ["T1", "T2", "T3", "T4"],
  wide: ["1º trimestre", "2º trimestre", "3º trimestre", "4º trimestre"]
};
const monthValues = {
  narrow: ["e", "f", "m", "a", "m", "j", "j", "a", "s", "o", "n", "d"],
  abbreviated: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"],
  wide: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
};
const dayValues = {
  narrow: ["d", "l", "m", "m", "j", "v", "s"],
  short: ["do", "lu", "ma", "mi", "ju", "vi", "sá"],
  abbreviated: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"],
  wide: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"]
};
const dayPeriodValues = {
  narrow: {
    am: "a",
    pm: "p",
    midnight: "mn",
    noon: "md",
    morning: "mañana",
    afternoon: "tarde",
    evening: "tarde",
    night: "noche"
  },
  abbreviated: {
    am: "AM",
    pm: "PM",
    midnight: "medianoche",
    noon: "mediodia",
    morning: "mañana",
    afternoon: "tarde",
    evening: "tarde",
    night: "noche"
  },
  wide: {
    am: "a.m.",
    pm: "p.m.",
    midnight: "medianoche",
    noon: "mediodia",
    morning: "mañana",
    afternoon: "tarde",
    evening: "tarde",
    night: "noche"
  }
};
const formattingDayPeriodValues = {
  narrow: {
    am: "a",
    pm: "p",
    midnight: "mn",
    noon: "md",
    morning: "de la mañana",
    afternoon: "de la tarde",
    evening: "de la tarde",
    night: "de la noche"
  },
  abbreviated: {
    am: "AM",
    pm: "PM",
    midnight: "medianoche",
    noon: "mediodia",
    morning: "de la mañana",
    afternoon: "de la tarde",
    evening: "de la tarde",
    night: "de la noche"
  },
  wide: {
    am: "a.m.",
    pm: "p.m.",
    midnight: "medianoche",
    noon: "mediodia",
    morning: "de la mañana",
    afternoon: "de la tarde",
    evening: "de la tarde",
    night: "de la noche"
  }
};
const ordinalNumber = (dirtyNumber, _options) => {
  const number = Number(dirtyNumber);
  return number + "º";
};
const localize = {
  ordinalNumber: ordinalNumber,
  era: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: eraValues,
    defaultWidth: "wide"
  }),
  quarter: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: quarterValues,
    defaultWidth: "wide",
    argumentCallback: quarter => Number(quarter) - 1
  }),
  month: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: monthValues,
    defaultWidth: "wide"
  }),
  day: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: dayValues,
    defaultWidth: "wide"
  }),
  dayPeriod: (0,_lib_buildLocalizeFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildLocalizeFn)({
    values: dayPeriodValues,
    defaultWidth: "wide",
    formattingValues: formattingDayPeriodValues,
    defaultFormattingWidth: "wide"
  })
};

/***/ }),

/***/ 64813:
/*!********************************************************!*\
  !*** ./node_modules/date-fns/locale/es/_lib/match.mjs ***!
  \********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   match: () => (/* binding */ match)
/* harmony export */ });
/* harmony import */ var _lib_buildMatchPatternFn_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../_lib/buildMatchPatternFn.mjs */ 64162);
/* harmony import */ var _lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../_lib/buildMatchFn.mjs */ 80268);


const matchOrdinalNumberPattern = /^(\d+)(º)?/i;
const parseOrdinalNumberPattern = /\d+/i;
const matchEraPatterns = {
  narrow: /^(ac|dc|a|d)/i,
  abbreviated: /^(a\.?\s?c\.?|a\.?\s?e\.?\s?c\.?|d\.?\s?c\.?|e\.?\s?c\.?)/i,
  wide: /^(antes de cristo|antes de la era com[uú]n|despu[eé]s de cristo|era com[uú]n)/i
};
const parseEraPatterns = {
  any: [/^ac/i, /^dc/i],
  wide: [/^(antes de cristo|antes de la era com[uú]n)/i, /^(despu[eé]s de cristo|era com[uú]n)/i]
};
const matchQuarterPatterns = {
  narrow: /^[1234]/i,
  abbreviated: /^T[1234]/i,
  wide: /^[1234](º)? trimestre/i
};
const parseQuarterPatterns = {
  any: [/1/i, /2/i, /3/i, /4/i]
};
const matchMonthPatterns = {
  narrow: /^[efmajsond]/i,
  abbreviated: /^(ene|feb|mar|abr|may|jun|jul|ago|sep|oct|nov|dic)/i,
  wide: /^(enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre)/i
};
const parseMonthPatterns = {
  narrow: [/^e/i, /^f/i, /^m/i, /^a/i, /^m/i, /^j/i, /^j/i, /^a/i, /^s/i, /^o/i, /^n/i, /^d/i],
  any: [/^en/i, /^feb/i, /^mar/i, /^abr/i, /^may/i, /^jun/i, /^jul/i, /^ago/i, /^sep/i, /^oct/i, /^nov/i, /^dic/i]
};
const matchDayPatterns = {
  narrow: /^[dlmjvs]/i,
  short: /^(do|lu|ma|mi|ju|vi|s[áa])/i,
  abbreviated: /^(dom|lun|mar|mi[ée]|jue|vie|s[áa]b)/i,
  wide: /^(domingo|lunes|martes|mi[ée]rcoles|jueves|viernes|s[áa]bado)/i
};
const parseDayPatterns = {
  narrow: [/^d/i, /^l/i, /^m/i, /^m/i, /^j/i, /^v/i, /^s/i],
  any: [/^do/i, /^lu/i, /^ma/i, /^mi/i, /^ju/i, /^vi/i, /^sa/i]
};
const matchDayPeriodPatterns = {
  narrow: /^(a|p|mn|md|(de la|a las) (mañana|tarde|noche))/i,
  any: /^([ap]\.?\s?m\.?|medianoche|mediodia|(de la|a las) (mañana|tarde|noche))/i
};
const parseDayPeriodPatterns = {
  any: {
    am: /^a/i,
    pm: /^p/i,
    midnight: /^mn/i,
    noon: /^md/i,
    morning: /mañana/i,
    afternoon: /tarde/i,
    evening: /tarde/i,
    night: /noche/i
  }
};
const match = {
  ordinalNumber: (0,_lib_buildMatchPatternFn_mjs__WEBPACK_IMPORTED_MODULE_0__.buildMatchPatternFn)({
    matchPattern: matchOrdinalNumberPattern,
    parsePattern: parseOrdinalNumberPattern,
    valueCallback: function (value) {
      return parseInt(value, 10);
    }
  }),
  era: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchEraPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseEraPatterns,
    defaultParseWidth: "any"
  }),
  quarter: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchQuarterPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseQuarterPatterns,
    defaultParseWidth: "any",
    valueCallback: index => index + 1
  }),
  month: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchMonthPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseMonthPatterns,
    defaultParseWidth: "any"
  }),
  day: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchDayPatterns,
    defaultMatchWidth: "wide",
    parsePatterns: parseDayPatterns,
    defaultParseWidth: "any"
  }),
  dayPeriod: (0,_lib_buildMatchFn_mjs__WEBPACK_IMPORTED_MODULE_1__.buildMatchFn)({
    matchPatterns: matchDayPeriodPatterns,
    defaultMatchWidth: "any",
    parsePatterns: parseDayPeriodPatterns,
    defaultParseWidth: "any"
  })
};

/***/ }),

/***/ 33240:
/*!**********************************************!*\
  !*** ./node_modules/date-fns/startOfDay.mjs ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfDay: () => (/* binding */ startOfDay)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);


/**
 * @name startOfDay
 * @category Day Helpers
 * @summary Return the start of a day for the given date.
 *
 * @description
 * Return the start of a day for the given date.
 * The result will be in the local timezone.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 *
 * @returns The start of a day
 *
 * @example
 * // The start of a day for 2 September 2014 11:55:00:
 * const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))
 * //=> Tue Sep 02 2014 00:00:00
 */
function startOfDay(date) {
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  _date.setHours(0, 0, 0, 0);
  return _date;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfDay);

/***/ }),

/***/ 47545:
/*!**************************************************!*\
  !*** ./node_modules/date-fns/startOfISOWeek.mjs ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfISOWeek: () => (/* binding */ startOfISOWeek)
/* harmony export */ });
/* harmony import */ var _startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./startOfWeek.mjs */ 90610);


/**
 * @name startOfISOWeek
 * @category ISO Week Helpers
 * @summary Return the start of an ISO week for the given date.
 *
 * @description
 * Return the start of an ISO week for the given date.
 * The result will be in the local timezone.
 *
 * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 *
 * @returns The start of an ISO week
 *
 * @example
 * // The start of an ISO week for 2 September 2014 11:55:00:
 * const result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))
 * //=> Mon Sep 01 2014 00:00:00
 */
function startOfISOWeek(date) {
  return (0,_startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_0__.startOfWeek)(date, {
    weekStartsOn: 1
  });
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfISOWeek);

/***/ }),

/***/ 11050:
/*!******************************************************!*\
  !*** ./node_modules/date-fns/startOfISOWeekYear.mjs ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfISOWeekYear: () => (/* binding */ startOfISOWeekYear)
/* harmony export */ });
/* harmony import */ var _getISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./getISOWeekYear.mjs */ 31359);
/* harmony import */ var _startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./startOfISOWeek.mjs */ 47545);
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);




/**
 * @name startOfISOWeekYear
 * @category ISO Week-Numbering Year Helpers
 * @summary Return the start of an ISO week-numbering year for the given date.
 *
 * @description
 * Return the start of an ISO week-numbering year,
 * which always starts 3 days before the year's first Thursday.
 * The result will be in the local timezone.
 *
 * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 *
 * @returns The start of an ISO week-numbering year
 *
 * @example
 * // The start of an ISO week-numbering year for 2 July 2005:
 * const result = startOfISOWeekYear(new Date(2005, 6, 2))
 * //=> Mon Jan 03 2005 00:00:00
 */
function startOfISOWeekYear(date) {
  const year = (0,_getISOWeekYear_mjs__WEBPACK_IMPORTED_MODULE_0__.getISOWeekYear)(date);
  const fourthOfJanuary = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__.constructFrom)(date, 0);
  fourthOfJanuary.setFullYear(year, 0, 4);
  fourthOfJanuary.setHours(0, 0, 0, 0);
  return (0,_startOfISOWeek_mjs__WEBPACK_IMPORTED_MODULE_2__.startOfISOWeek)(fourthOfJanuary);
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfISOWeekYear);

/***/ }),

/***/ 90610:
/*!***********************************************!*\
  !*** ./node_modules/date-fns/startOfWeek.mjs ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfWeek: () => (/* binding */ startOfWeek)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./toDate.mjs */ 58700);
/* harmony import */ var _lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_lib/defaultOptions.mjs */ 19857);



/**
 * The {@link startOfWeek} function options.
 */

/**
 * @name startOfWeek
 * @category Week Helpers
 * @summary Return the start of a week for the given date.
 *
 * @description
 * Return the start of a week for the given date.
 * The result will be in the local timezone.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 * @param options - An object with options
 *
 * @returns The start of a week
 *
 * @example
 * // The start of a week for 2 September 2014 11:55:00:
 * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))
 * //=> Sun Aug 31 2014 00:00:00
 *
 * @example
 * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:
 * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })
 * //=> Mon Sep 01 2014 00:00:00
 */
function startOfWeek(date, options) {
  const defaultOptions = (0,_lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_0__.getDefaultOptions)();
  const weekStartsOn = options?.weekStartsOn ?? options?.locale?.options?.weekStartsOn ?? defaultOptions.weekStartsOn ?? defaultOptions.locale?.options?.weekStartsOn ?? 0;
  const _date = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_1__.toDate)(date);
  const day = _date.getDay();
  const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;
  _date.setDate(_date.getDate() - diff);
  _date.setHours(0, 0, 0, 0);
  return _date;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfWeek);

/***/ }),

/***/ 58505:
/*!***************************************************!*\
  !*** ./node_modules/date-fns/startOfWeekYear.mjs ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfWeekYear: () => (/* binding */ startOfWeekYear)
/* harmony export */ });
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);
/* harmony import */ var _getWeekYear_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./getWeekYear.mjs */ 21598);
/* harmony import */ var _startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./startOfWeek.mjs */ 90610);
/* harmony import */ var _lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_lib/defaultOptions.mjs */ 19857);





/**
 * The {@link startOfWeekYear} function options.
 */

/**
 * @name startOfWeekYear
 * @category Week-Numbering Year Helpers
 * @summary Return the start of a local week-numbering year for the given date.
 *
 * @description
 * Return the start of a local week-numbering year.
 * The exact calculation depends on the values of
 * `options.weekStartsOn` (which is the index of the first day of the week)
 * and `options.firstWeekContainsDate` (which is the day of January, which is always in
 * the first week of the week-numbering year)
 *
 * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 * @param options - An object with options
 *
 * @returns The start of a week-numbering year
 *
 * @example
 * // The start of an a week-numbering year for 2 July 2005 with default settings:
 * const result = startOfWeekYear(new Date(2005, 6, 2))
 * //=> Sun Dec 26 2004 00:00:00
 *
 * @example
 * // The start of a week-numbering year for 2 July 2005
 * // if Monday is the first day of week
 * // and 4 January is always in the first week of the year:
 * const result = startOfWeekYear(new Date(2005, 6, 2), {
 *   weekStartsOn: 1,
 *   firstWeekContainsDate: 4
 * })
 * //=> Mon Jan 03 2005 00:00:00
 */
function startOfWeekYear(date, options) {
  const defaultOptions = (0,_lib_defaultOptions_mjs__WEBPACK_IMPORTED_MODULE_0__.getDefaultOptions)();
  const firstWeekContainsDate = options?.firstWeekContainsDate ?? options?.locale?.options?.firstWeekContainsDate ?? defaultOptions.firstWeekContainsDate ?? defaultOptions.locale?.options?.firstWeekContainsDate ?? 1;
  const year = (0,_getWeekYear_mjs__WEBPACK_IMPORTED_MODULE_1__.getWeekYear)(date, options);
  const firstWeek = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_2__.constructFrom)(date, 0);
  firstWeek.setFullYear(year, 0, firstWeekContainsDate);
  firstWeek.setHours(0, 0, 0, 0);
  const _date = (0,_startOfWeek_mjs__WEBPACK_IMPORTED_MODULE_3__.startOfWeek)(firstWeek, options);
  return _date;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfWeekYear);

/***/ }),

/***/ 99229:
/*!***********************************************!*\
  !*** ./node_modules/date-fns/startOfYear.mjs ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   startOfYear: () => (/* binding */ startOfYear)
/* harmony export */ });
/* harmony import */ var _toDate_mjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toDate.mjs */ 58700);
/* harmony import */ var _constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./constructFrom.mjs */ 56814);



/**
 * @name startOfYear
 * @category Year Helpers
 * @summary Return the start of a year for the given date.
 *
 * @description
 * Return the start of a year for the given date.
 * The result will be in the local timezone.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param date - The original date
 *
 * @returns The start of a year
 *
 * @example
 * // The start of a year for 2 September 2014 11:55:00:
 * const result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))
 * //=> Wed Jan 01 2014 00:00:00
 */
function startOfYear(date) {
  const cleanDate = (0,_toDate_mjs__WEBPACK_IMPORTED_MODULE_0__.toDate)(date);
  const _date = (0,_constructFrom_mjs__WEBPACK_IMPORTED_MODULE_1__.constructFrom)(date, 0);
  _date.setFullYear(cleanDate.getFullYear(), 0, 1);
  _date.setHours(0, 0, 0, 0);
  return _date;
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (startOfYear);

/***/ }),

/***/ 58700:
/*!******************************************!*\
  !*** ./node_modules/date-fns/toDate.mjs ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__),
/* harmony export */   toDate: () => (/* binding */ toDate)
/* harmony export */ });
/**
 * @name toDate
 * @category Common Helpers
 * @summary Convert the given argument to an instance of Date.
 *
 * @description
 * Convert the given argument to an instance of Date.
 *
 * If the argument is an instance of Date, the function returns its clone.
 *
 * If the argument is a number, it is treated as a timestamp.
 *
 * If the argument is none of the above, the function returns Invalid Date.
 *
 * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.
 *
 * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).
 *
 * @param argument - The value to convert
 *
 * @returns The parsed date in the local time zone
 *
 * @example
 * // Clone the date:
 * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))
 * //=> Tue Feb 11 2014 11:30:30
 *
 * @example
 * // Convert the timestamp to date:
 * const result = toDate(1392098430000)
 * //=> Tue Feb 11 2014 11:30:30
 */
function toDate(argument) {
  const argStr = Object.prototype.toString.call(argument);

  // Clone the date
  if (argument instanceof Date || typeof argument === "object" && argStr === "[object Date]") {
    // Prevent the date to lose the milliseconds when passed to new Date() in IE10
    return new argument.constructor(+argument);
  } else if (typeof argument === "number" || argStr === "[object Number]" || typeof argument === "string" || argStr === "[object String]") {
    // TODO: Can we get rid of as?
    return new Date(argument);
  } else {
    // TODO: Can we get rid of as?
    return new Date(NaN);
  }
}

// Fallback for modularized imports:
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toDate);

/***/ }),

/***/ 2726:
/*!******************************************************!*\
  !*** ./node_modules/html-entities/dist/esm/index.js ***!
  \******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   decode: () => (/* binding */ decode),
/* harmony export */   decodeEntity: () => (/* binding */ decodeEntity),
/* harmony export */   encode: () => (/* binding */ encode)
/* harmony export */ });
/* harmony import */ var _named_references_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./named-references.js */ 65766);
/* harmony import */ var _numeric_unicode_map_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./numeric-unicode-map.js */ 80708);
/* harmony import */ var _surrogate_pairs_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./surrogate-pairs.js */ 86200);
var __assign = undefined && undefined.__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];
      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    }
    return t;
  };
  return __assign.apply(this, arguments);
};



var allNamedReferences = __assign(__assign({}, _named_references_js__WEBPACK_IMPORTED_MODULE_0__.namedReferences), {
  all: _named_references_js__WEBPACK_IMPORTED_MODULE_0__.namedReferences.html5
});
var encodeRegExps = {
  specialChars: /[<>'"&]/g,
  nonAscii: /[<>'"&\u0080-\uD7FF\uE000-\uFFFF\uDC00-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g,
  nonAsciiPrintable: /[<>'"&\x01-\x08\x11-\x15\x17-\x1F\x7f-\uD7FF\uE000-\uFFFF\uDC00-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g,
  nonAsciiPrintableOnly: /[\x01-\x08\x11-\x15\x17-\x1F\x7f-\uD7FF\uE000-\uFFFF\uDC00-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g,
  extensive: /[\x01-\x0c\x0e-\x1f\x21-\x2c\x2e-\x2f\x3a-\x40\x5b-\x60\x7b-\x7d\x7f-\uD7FF\uE000-\uFFFF\uDC00-\uDFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]?/g
};
var defaultEncodeOptions = {
  mode: 'specialChars',
  level: 'all',
  numeric: 'decimal'
};
/** Encodes all the necessary (specified by `level`) characters in the text */
function encode(text, _a) {
  var _b = _a === void 0 ? defaultEncodeOptions : _a,
    _c = _b.mode,
    mode = _c === void 0 ? 'specialChars' : _c,
    _d = _b.numeric,
    numeric = _d === void 0 ? 'decimal' : _d,
    _e = _b.level,
    level = _e === void 0 ? 'all' : _e;
  if (!text) {
    return '';
  }
  var encodeRegExp = encodeRegExps[mode];
  var references = allNamedReferences[level].characters;
  var isHex = numeric === 'hexadecimal';
  return String.prototype.replace.call(text, encodeRegExp, function (input) {
    var result = references[input];
    if (!result) {
      var code = input.length > 1 ? (0,_surrogate_pairs_js__WEBPACK_IMPORTED_MODULE_2__.getCodePoint)(input, 0) : input.charCodeAt(0);
      result = (isHex ? '&#x' + code.toString(16) : '&#' + code) + ';';
    }
    return result;
  });
}
var defaultDecodeOptions = {
  scope: 'body',
  level: 'all'
};
var strict = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);/g;
var attribute = /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+)[;=]?/g;
var baseDecodeRegExps = {
  xml: {
    strict: strict,
    attribute: attribute,
    body: _named_references_js__WEBPACK_IMPORTED_MODULE_0__.bodyRegExps.xml
  },
  html4: {
    strict: strict,
    attribute: attribute,
    body: _named_references_js__WEBPACK_IMPORTED_MODULE_0__.bodyRegExps.html4
  },
  html5: {
    strict: strict,
    attribute: attribute,
    body: _named_references_js__WEBPACK_IMPORTED_MODULE_0__.bodyRegExps.html5
  }
};
var decodeRegExps = __assign(__assign({}, baseDecodeRegExps), {
  all: baseDecodeRegExps.html5
});
var fromCharCode = String.fromCharCode;
var outOfBoundsChar = fromCharCode(65533);
var defaultDecodeEntityOptions = {
  level: 'all'
};
function getDecodedEntity(entity, references, isAttribute, isStrict) {
  var decodeResult = entity;
  var decodeEntityLastChar = entity[entity.length - 1];
  if (isAttribute && decodeEntityLastChar === '=') {
    decodeResult = entity;
  } else if (isStrict && decodeEntityLastChar !== ';') {
    decodeResult = entity;
  } else {
    var decodeResultByReference = references[entity];
    if (decodeResultByReference) {
      decodeResult = decodeResultByReference;
    } else if (entity[0] === '&' && entity[1] === '#') {
      var decodeSecondChar = entity[2];
      var decodeCode = decodeSecondChar == 'x' || decodeSecondChar == 'X' ? parseInt(entity.substr(3), 16) : parseInt(entity.substr(2));
      decodeResult = decodeCode >= 0x10ffff ? outOfBoundsChar : decodeCode > 65535 ? (0,_surrogate_pairs_js__WEBPACK_IMPORTED_MODULE_2__.fromCodePoint)(decodeCode) : fromCharCode(_numeric_unicode_map_js__WEBPACK_IMPORTED_MODULE_1__.numericUnicodeMap[decodeCode] || decodeCode);
    }
  }
  return decodeResult;
}
/** Decodes a single entity */
function decodeEntity(entity, _a) {
  var _b = _a === void 0 ? defaultDecodeEntityOptions : _a,
    _c = _b.level,
    level = _c === void 0 ? 'all' : _c;
  if (!entity) {
    return '';
  }
  return getDecodedEntity(entity, allNamedReferences[level].entities, false, false);
}
/** Decodes all entities in the text */
function decode(text, _a) {
  var _b = _a === void 0 ? defaultDecodeOptions : _a,
    _c = _b.level,
    level = _c === void 0 ? 'all' : _c,
    _d = _b.scope,
    scope = _d === void 0 ? level === 'xml' ? 'strict' : 'body' : _d;
  if (!text) {
    return '';
  }
  var decodeRegExp = decodeRegExps[level][scope];
  var references = allNamedReferences[level].entities;
  var isAttribute = scope === 'attribute';
  var isStrict = scope === 'strict';
  return text.replace(decodeRegExp, function (entity) {
    return getDecodedEntity(entity, references, isAttribute, isStrict);
  });
}

/***/ }),

/***/ 65766:
/*!*****************************************************************!*\
  !*** ./node_modules/html-entities/dist/esm/named-references.js ***!
  \*****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   bodyRegExps: () => (/* binding */ bodyRegExps),
/* harmony export */   namedReferences: () => (/* binding */ namedReferences)
/* harmony export */ });
var __assign = undefined && undefined.__assign || function () {
  __assign = Object.assign || function (t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];
      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    }
    return t;
  };
  return __assign.apply(this, arguments);
};
// This file is autogenerated by tools/process-named-references.ts
var pairDivider = "~";
var blockDivider = "~~";
function generateNamedReferences(input, prev) {
  var entities = {};
  var characters = {};
  var blocks = input.split(blockDivider);
  var isOptionalBlock = false;
  for (var i = 0; blocks.length > i; i++) {
    var entries = blocks[i].split(pairDivider);
    for (var j = 0; j < entries.length; j += 2) {
      var entity = entries[j];
      var character = entries[j + 1];
      var fullEntity = '&' + entity + ';';
      entities[fullEntity] = character;
      if (isOptionalBlock) {
        entities['&' + entity] = character;
      }
      characters[character] = fullEntity;
    }
    isOptionalBlock = true;
  }
  return prev ? {
    entities: __assign(__assign({}, entities), prev.entities),
    characters: __assign(__assign({}, characters), prev.characters)
  } : {
    entities: entities,
    characters: characters
  };
}
var bodyRegExps = {
  xml: /&(?:#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g,
  html4: /&notin;|&(?:nbsp|iexcl|cent|pound|curren|yen|brvbar|sect|uml|copy|ordf|laquo|not|shy|reg|macr|deg|plusmn|sup2|sup3|acute|micro|para|middot|cedil|sup1|ordm|raquo|frac14|frac12|frac34|iquest|Agrave|Aacute|Acirc|Atilde|Auml|Aring|AElig|Ccedil|Egrave|Eacute|Ecirc|Euml|Igrave|Iacute|Icirc|Iuml|ETH|Ntilde|Ograve|Oacute|Ocirc|Otilde|Ouml|times|Oslash|Ugrave|Uacute|Ucirc|Uuml|Yacute|THORN|szlig|agrave|aacute|acirc|atilde|auml|aring|aelig|ccedil|egrave|eacute|ecirc|euml|igrave|iacute|icirc|iuml|eth|ntilde|ograve|oacute|ocirc|otilde|ouml|divide|oslash|ugrave|uacute|ucirc|uuml|yacute|thorn|yuml|quot|amp|lt|gt|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g,
  html5: /&centerdot;|&copysr;|&divideontimes;|&gtcc;|&gtcir;|&gtdot;|&gtlPar;|&gtquest;|&gtrapprox;|&gtrarr;|&gtrdot;|&gtreqless;|&gtreqqless;|&gtrless;|&gtrsim;|&ltcc;|&ltcir;|&ltdot;|&lthree;|&ltimes;|&ltlarr;|&ltquest;|&ltrPar;|&ltri;|&ltrie;|&ltrif;|&notin;|&notinE;|&notindot;|&notinva;|&notinvb;|&notinvc;|&notni;|&notniva;|&notnivb;|&notnivc;|&parallel;|&timesb;|&timesbar;|&timesd;|&(?:AElig|AMP|Aacute|Acirc|Agrave|Aring|Atilde|Auml|COPY|Ccedil|ETH|Eacute|Ecirc|Egrave|Euml|GT|Iacute|Icirc|Igrave|Iuml|LT|Ntilde|Oacute|Ocirc|Ograve|Oslash|Otilde|Ouml|QUOT|REG|THORN|Uacute|Ucirc|Ugrave|Uuml|Yacute|aacute|acirc|acute|aelig|agrave|amp|aring|atilde|auml|brvbar|ccedil|cedil|cent|copy|curren|deg|divide|eacute|ecirc|egrave|eth|euml|frac12|frac14|frac34|gt|iacute|icirc|iexcl|igrave|iquest|iuml|laquo|lt|macr|micro|middot|nbsp|not|ntilde|oacute|ocirc|ograve|ordf|ordm|oslash|otilde|ouml|para|plusmn|pound|quot|raquo|reg|sect|shy|sup1|sup2|sup3|szlig|thorn|times|uacute|ucirc|ugrave|uml|uuml|yacute|yen|yuml|#\d+|#[xX][\da-fA-F]+|[0-9a-zA-Z]+);?/g
};
var namedReferences = {};
namedReferences['xml'] = generateNamedReferences("lt~<~gt~>~quot~\"~apos~'~amp~&");
namedReferences['html4'] = generateNamedReferences("apos~'~OElig~Œ~oelig~œ~Scaron~Š~scaron~š~Yuml~Ÿ~circ~ˆ~tilde~˜~ensp~ ~emsp~ ~thinsp~ ~zwnj~‌~zwj~‍~lrm~‎~rlm~‏~ndash~–~mdash~—~lsquo~‘~rsquo~’~sbquo~‚~ldquo~“~rdquo~”~bdquo~„~dagger~†~Dagger~‡~permil~‰~lsaquo~‹~rsaquo~›~euro~€~fnof~ƒ~Alpha~Α~Beta~Β~Gamma~Γ~Delta~Δ~Epsilon~Ε~Zeta~Ζ~Eta~Η~Theta~Θ~Iota~Ι~Kappa~Κ~Lambda~Λ~Mu~Μ~Nu~Ν~Xi~Ξ~Omicron~Ο~Pi~Π~Rho~Ρ~Sigma~Σ~Tau~Τ~Upsilon~Υ~Phi~Φ~Chi~Χ~Psi~Ψ~Omega~Ω~alpha~α~beta~β~gamma~γ~delta~δ~epsilon~ε~zeta~ζ~eta~η~theta~θ~iota~ι~kappa~κ~lambda~λ~mu~μ~nu~ν~xi~ξ~omicron~ο~pi~π~rho~ρ~sigmaf~ς~sigma~σ~tau~τ~upsilon~υ~phi~φ~chi~χ~psi~ψ~omega~ω~thetasym~ϑ~upsih~ϒ~piv~ϖ~bull~•~hellip~…~prime~′~Prime~″~oline~‾~frasl~⁄~weierp~℘~image~ℑ~real~ℜ~trade~™~alefsym~ℵ~larr~←~uarr~↑~rarr~→~darr~↓~harr~↔~crarr~↵~lArr~⇐~uArr~⇑~rArr~⇒~dArr~⇓~hArr~⇔~forall~∀~part~∂~exist~∃~empty~∅~nabla~∇~isin~∈~notin~∉~ni~∋~prod~∏~sum~∑~minus~−~lowast~∗~radic~√~prop~∝~infin~∞~ang~∠~and~∧~or~∨~cap~∩~cup~∪~int~∫~there4~∴~sim~∼~cong~≅~asymp~≈~ne~≠~equiv~≡~le~≤~ge~≥~sub~⊂~sup~⊃~nsub~⊄~sube~⊆~supe~⊇~oplus~⊕~otimes~⊗~perp~⊥~sdot~⋅~lceil~⌈~rceil~⌉~lfloor~⌊~rfloor~⌋~lang~〈~rang~〉~loz~◊~spades~♠~clubs~♣~hearts~♥~diams~♦~~nbsp~ ~iexcl~¡~cent~¢~pound~£~curren~¤~yen~¥~brvbar~¦~sect~§~uml~¨~copy~©~ordf~ª~laquo~«~not~¬~shy~­~reg~®~macr~¯~deg~°~plusmn~±~sup2~²~sup3~³~acute~´~micro~µ~para~¶~middot~·~cedil~¸~sup1~¹~ordm~º~raquo~»~frac14~¼~frac12~½~frac34~¾~iquest~¿~Agrave~À~Aacute~Á~Acirc~Â~Atilde~Ã~Auml~Ä~Aring~Å~AElig~Æ~Ccedil~Ç~Egrave~È~Eacute~É~Ecirc~Ê~Euml~Ë~Igrave~Ì~Iacute~Í~Icirc~Î~Iuml~Ï~ETH~Ð~Ntilde~Ñ~Ograve~Ò~Oacute~Ó~Ocirc~Ô~Otilde~Õ~Ouml~Ö~times~×~Oslash~Ø~Ugrave~Ù~Uacute~Ú~Ucirc~Û~Uuml~Ü~Yacute~Ý~THORN~Þ~szlig~ß~agrave~à~aacute~á~acirc~â~atilde~ã~auml~ä~aring~å~aelig~æ~ccedil~ç~egrave~è~eacute~é~ecirc~ê~euml~ë~igrave~ì~iacute~í~icirc~î~iuml~ï~eth~ð~ntilde~ñ~ograve~ò~oacute~ó~ocirc~ô~otilde~õ~ouml~ö~divide~÷~oslash~ø~ugrave~ù~uacute~ú~ucirc~û~uuml~ü~yacute~ý~thorn~þ~yuml~ÿ~quot~\"~amp~&~lt~<~gt~>");
namedReferences['html5'] = generateNamedReferences("Abreve~Ă~Acy~А~Afr~𝔄~Amacr~Ā~And~⩓~Aogon~Ą~Aopf~𝔸~ApplyFunction~⁡~Ascr~𝒜~Assign~≔~Backslash~∖~Barv~⫧~Barwed~⌆~Bcy~Б~Because~∵~Bernoullis~ℬ~Bfr~𝔅~Bopf~𝔹~Breve~˘~Bscr~ℬ~Bumpeq~≎~CHcy~Ч~Cacute~Ć~Cap~⋒~CapitalDifferentialD~ⅅ~Cayleys~ℭ~Ccaron~Č~Ccirc~Ĉ~Cconint~∰~Cdot~Ċ~Cedilla~¸~CenterDot~·~Cfr~ℭ~CircleDot~⊙~CircleMinus~⊖~CirclePlus~⊕~CircleTimes~⊗~ClockwiseContourIntegral~∲~CloseCurlyDoubleQuote~”~CloseCurlyQuote~’~Colon~∷~Colone~⩴~Congruent~≡~Conint~∯~ContourIntegral~∮~Copf~ℂ~Coproduct~∐~CounterClockwiseContourIntegral~∳~Cross~⨯~Cscr~𝒞~Cup~⋓~CupCap~≍~DD~ⅅ~DDotrahd~⤑~DJcy~Ђ~DScy~Ѕ~DZcy~Џ~Darr~↡~Dashv~⫤~Dcaron~Ď~Dcy~Д~Del~∇~Dfr~𝔇~DiacriticalAcute~´~DiacriticalDot~˙~DiacriticalDoubleAcute~˝~DiacriticalGrave~`~DiacriticalTilde~˜~Diamond~⋄~DifferentialD~ⅆ~Dopf~𝔻~Dot~¨~DotDot~⃜~DotEqual~≐~DoubleContourIntegral~∯~DoubleDot~¨~DoubleDownArrow~⇓~DoubleLeftArrow~⇐~DoubleLeftRightArrow~⇔~DoubleLeftTee~⫤~DoubleLongLeftArrow~⟸~DoubleLongLeftRightArrow~⟺~DoubleLongRightArrow~⟹~DoubleRightArrow~⇒~DoubleRightTee~⊨~DoubleUpArrow~⇑~DoubleUpDownArrow~⇕~DoubleVerticalBar~∥~DownArrow~↓~DownArrowBar~⤓~DownArrowUpArrow~⇵~DownBreve~̑~DownLeftRightVector~⥐~DownLeftTeeVector~⥞~DownLeftVector~↽~DownLeftVectorBar~⥖~DownRightTeeVector~⥟~DownRightVector~⇁~DownRightVectorBar~⥗~DownTee~⊤~DownTeeArrow~↧~Downarrow~⇓~Dscr~𝒟~Dstrok~Đ~ENG~Ŋ~Ecaron~Ě~Ecy~Э~Edot~Ė~Efr~𝔈~Element~∈~Emacr~Ē~EmptySmallSquare~◻~EmptyVerySmallSquare~▫~Eogon~Ę~Eopf~𝔼~Equal~⩵~EqualTilde~≂~Equilibrium~⇌~Escr~ℰ~Esim~⩳~Exists~∃~ExponentialE~ⅇ~Fcy~Ф~Ffr~𝔉~FilledSmallSquare~◼~FilledVerySmallSquare~▪~Fopf~𝔽~ForAll~∀~Fouriertrf~ℱ~Fscr~ℱ~GJcy~Ѓ~Gammad~Ϝ~Gbreve~Ğ~Gcedil~Ģ~Gcirc~Ĝ~Gcy~Г~Gdot~Ġ~Gfr~𝔊~Gg~⋙~Gopf~𝔾~GreaterEqual~≥~GreaterEqualLess~⋛~GreaterFullEqual~≧~GreaterGreater~⪢~GreaterLess~≷~GreaterSlantEqual~⩾~GreaterTilde~≳~Gscr~𝒢~Gt~≫~HARDcy~Ъ~Hacek~ˇ~Hat~^~Hcirc~Ĥ~Hfr~ℌ~HilbertSpace~ℋ~Hopf~ℍ~HorizontalLine~─~Hscr~ℋ~Hstrok~Ħ~HumpDownHump~≎~HumpEqual~≏~IEcy~Е~IJlig~IJ~IOcy~Ё~Icy~И~Idot~İ~Ifr~ℑ~Im~ℑ~Imacr~Ī~ImaginaryI~ⅈ~Implies~⇒~Int~∬~Integral~∫~Intersection~⋂~InvisibleComma~⁣~InvisibleTimes~⁢~Iogon~Į~Iopf~𝕀~Iscr~ℐ~Itilde~Ĩ~Iukcy~І~Jcirc~Ĵ~Jcy~Й~Jfr~𝔍~Jopf~𝕁~Jscr~𝒥~Jsercy~Ј~Jukcy~Є~KHcy~Х~KJcy~Ќ~Kcedil~Ķ~Kcy~К~Kfr~𝔎~Kopf~𝕂~Kscr~𝒦~LJcy~Љ~Lacute~Ĺ~Lang~⟪~Laplacetrf~ℒ~Larr~↞~Lcaron~Ľ~Lcedil~Ļ~Lcy~Л~LeftAngleBracket~⟨~LeftArrow~←~LeftArrowBar~⇤~LeftArrowRightArrow~⇆~LeftCeiling~⌈~LeftDoubleBracket~⟦~LeftDownTeeVector~⥡~LeftDownVector~⇃~LeftDownVectorBar~⥙~LeftFloor~⌊~LeftRightArrow~↔~LeftRightVector~⥎~LeftTee~⊣~LeftTeeArrow~↤~LeftTeeVector~⥚~LeftTriangle~⊲~LeftTriangleBar~⧏~LeftTriangleEqual~⊴~LeftUpDownVector~⥑~LeftUpTeeVector~⥠~LeftUpVector~↿~LeftUpVectorBar~⥘~LeftVector~↼~LeftVectorBar~⥒~Leftarrow~⇐~Leftrightarrow~⇔~LessEqualGreater~⋚~LessFullEqual~≦~LessGreater~≶~LessLess~⪡~LessSlantEqual~⩽~LessTilde~≲~Lfr~𝔏~Ll~⋘~Lleftarrow~⇚~Lmidot~Ŀ~LongLeftArrow~⟵~LongLeftRightArrow~⟷~LongRightArrow~⟶~Longleftarrow~⟸~Longleftrightarrow~⟺~Longrightarrow~⟹~Lopf~𝕃~LowerLeftArrow~↙~LowerRightArrow~↘~Lscr~ℒ~Lsh~↰~Lstrok~Ł~Lt~≪~Map~⤅~Mcy~М~MediumSpace~ ~Mellintrf~ℳ~Mfr~𝔐~MinusPlus~∓~Mopf~𝕄~Mscr~ℳ~NJcy~Њ~Nacute~Ń~Ncaron~Ň~Ncedil~Ņ~Ncy~Н~NegativeMediumSpace~​~NegativeThickSpace~​~NegativeThinSpace~​~NegativeVeryThinSpace~​~NestedGreaterGreater~≫~NestedLessLess~≪~NewLine~\n~Nfr~𝔑~NoBreak~⁠~NonBreakingSpace~ ~Nopf~ℕ~Not~⫬~NotCongruent~≢~NotCupCap~≭~NotDoubleVerticalBar~∦~NotElement~∉~NotEqual~≠~NotEqualTilde~≂̸~NotExists~∄~NotGreater~≯~NotGreaterEqual~≱~NotGreaterFullEqual~≧̸~NotGreaterGreater~≫̸~NotGreaterLess~≹~NotGreaterSlantEqual~⩾̸~NotGreaterTilde~≵~NotHumpDownHump~≎̸~NotHumpEqual~≏̸~NotLeftTriangle~⋪~NotLeftTriangleBar~⧏̸~NotLeftTriangleEqual~⋬~NotLess~≮~NotLessEqual~≰~NotLessGreater~≸~NotLessLess~≪̸~NotLessSlantEqual~⩽̸~NotLessTilde~≴~NotNestedGreaterGreater~⪢̸~NotNestedLessLess~⪡̸~NotPrecedes~⊀~NotPrecedesEqual~⪯̸~NotPrecedesSlantEqual~⋠~NotReverseElement~∌~NotRightTriangle~⋫~NotRightTriangleBar~⧐̸~NotRightTriangleEqual~⋭~NotSquareSubset~⊏̸~NotSquareSubsetEqual~⋢~NotSquareSuperset~⊐̸~NotSquareSupersetEqual~⋣~NotSubset~⊂⃒~NotSubsetEqual~⊈~NotSucceeds~⊁~NotSucceedsEqual~⪰̸~NotSucceedsSlantEqual~⋡~NotSucceedsTilde~≿̸~NotSuperset~⊃⃒~NotSupersetEqual~⊉~NotTilde~≁~NotTildeEqual~≄~NotTildeFullEqual~≇~NotTildeTilde~≉~NotVerticalBar~∤~Nscr~𝒩~Ocy~О~Odblac~Ő~Ofr~𝔒~Omacr~Ō~Oopf~𝕆~OpenCurlyDoubleQuote~“~OpenCurlyQuote~‘~Or~⩔~Oscr~𝒪~Otimes~⨷~OverBar~‾~OverBrace~⏞~OverBracket~⎴~OverParenthesis~⏜~PartialD~∂~Pcy~П~Pfr~𝔓~PlusMinus~±~Poincareplane~ℌ~Popf~ℙ~Pr~⪻~Precedes~≺~PrecedesEqual~⪯~PrecedesSlantEqual~≼~PrecedesTilde~≾~Product~∏~Proportion~∷~Proportional~∝~Pscr~𝒫~Qfr~𝔔~Qopf~ℚ~Qscr~𝒬~RBarr~⤐~Racute~Ŕ~Rang~⟫~Rarr~↠~Rarrtl~⤖~Rcaron~Ř~Rcedil~Ŗ~Rcy~Р~Re~ℜ~ReverseElement~∋~ReverseEquilibrium~⇋~ReverseUpEquilibrium~⥯~Rfr~ℜ~RightAngleBracket~⟩~RightArrow~→~RightArrowBar~⇥~RightArrowLeftArrow~⇄~RightCeiling~⌉~RightDoubleBracket~⟧~RightDownTeeVector~⥝~RightDownVector~⇂~RightDownVectorBar~⥕~RightFloor~⌋~RightTee~⊢~RightTeeArrow~↦~RightTeeVector~⥛~RightTriangle~⊳~RightTriangleBar~⧐~RightTriangleEqual~⊵~RightUpDownVector~⥏~RightUpTeeVector~⥜~RightUpVector~↾~RightUpVectorBar~⥔~RightVector~⇀~RightVectorBar~⥓~Rightarrow~⇒~Ropf~ℝ~RoundImplies~⥰~Rrightarrow~⇛~Rscr~ℛ~Rsh~↱~RuleDelayed~⧴~SHCHcy~Щ~SHcy~Ш~SOFTcy~Ь~Sacute~Ś~Sc~⪼~Scedil~Ş~Scirc~Ŝ~Scy~С~Sfr~𝔖~ShortDownArrow~↓~ShortLeftArrow~←~ShortRightArrow~→~ShortUpArrow~↑~SmallCircle~∘~Sopf~𝕊~Sqrt~√~Square~□~SquareIntersection~⊓~SquareSubset~⊏~SquareSubsetEqual~⊑~SquareSuperset~⊐~SquareSupersetEqual~⊒~SquareUnion~⊔~Sscr~𝒮~Star~⋆~Sub~⋐~Subset~⋐~SubsetEqual~⊆~Succeeds~≻~SucceedsEqual~⪰~SucceedsSlantEqual~≽~SucceedsTilde~≿~SuchThat~∋~Sum~∑~Sup~⋑~Superset~⊃~SupersetEqual~⊇~Supset~⋑~TRADE~™~TSHcy~Ћ~TScy~Ц~Tab~\t~Tcaron~Ť~Tcedil~Ţ~Tcy~Т~Tfr~𝔗~Therefore~∴~ThickSpace~  ~ThinSpace~ ~Tilde~∼~TildeEqual~≃~TildeFullEqual~≅~TildeTilde~≈~Topf~𝕋~TripleDot~⃛~Tscr~𝒯~Tstrok~Ŧ~Uarr~↟~Uarrocir~⥉~Ubrcy~Ў~Ubreve~Ŭ~Ucy~У~Udblac~Ű~Ufr~𝔘~Umacr~Ū~UnderBar~_~UnderBrace~⏟~UnderBracket~⎵~UnderParenthesis~⏝~Union~⋃~UnionPlus~⊎~Uogon~Ų~Uopf~𝕌~UpArrow~↑~UpArrowBar~⤒~UpArrowDownArrow~⇅~UpDownArrow~↕~UpEquilibrium~⥮~UpTee~⊥~UpTeeArrow~↥~Uparrow~⇑~Updownarrow~⇕~UpperLeftArrow~↖~UpperRightArrow~↗~Upsi~ϒ~Uring~Ů~Uscr~𝒰~Utilde~Ũ~VDash~⊫~Vbar~⫫~Vcy~В~Vdash~⊩~Vdashl~⫦~Vee~⋁~Verbar~‖~Vert~‖~VerticalBar~∣~VerticalLine~|~VerticalSeparator~❘~VerticalTilde~≀~VeryThinSpace~ ~Vfr~𝔙~Vopf~𝕍~Vscr~𝒱~Vvdash~⊪~Wcirc~Ŵ~Wedge~⋀~Wfr~𝔚~Wopf~𝕎~Wscr~𝒲~Xfr~𝔛~Xopf~𝕏~Xscr~𝒳~YAcy~Я~YIcy~Ї~YUcy~Ю~Ycirc~Ŷ~Ycy~Ы~Yfr~𝔜~Yopf~𝕐~Yscr~𝒴~ZHcy~Ж~Zacute~Ź~Zcaron~Ž~Zcy~З~Zdot~Ż~ZeroWidthSpace~​~Zfr~ℨ~Zopf~ℤ~Zscr~𝒵~abreve~ă~ac~∾~acE~∾̳~acd~∿~acy~а~af~⁡~afr~𝔞~aleph~ℵ~amacr~ā~amalg~⨿~andand~⩕~andd~⩜~andslope~⩘~andv~⩚~ange~⦤~angle~∠~angmsd~∡~angmsdaa~⦨~angmsdab~⦩~angmsdac~⦪~angmsdad~⦫~angmsdae~⦬~angmsdaf~⦭~angmsdag~⦮~angmsdah~⦯~angrt~∟~angrtvb~⊾~angrtvbd~⦝~angsph~∢~angst~Å~angzarr~⍼~aogon~ą~aopf~𝕒~ap~≈~apE~⩰~apacir~⩯~ape~≊~apid~≋~approx~≈~approxeq~≊~ascr~𝒶~ast~*~asympeq~≍~awconint~∳~awint~⨑~bNot~⫭~backcong~≌~backepsilon~϶~backprime~‵~backsim~∽~backsimeq~⋍~barvee~⊽~barwed~⌅~barwedge~⌅~bbrk~⎵~bbrktbrk~⎶~bcong~≌~bcy~б~becaus~∵~because~∵~bemptyv~⦰~bepsi~϶~bernou~ℬ~beth~ℶ~between~≬~bfr~𝔟~bigcap~⋂~bigcirc~◯~bigcup~⋃~bigodot~⨀~bigoplus~⨁~bigotimes~⨂~bigsqcup~⨆~bigstar~★~bigtriangledown~▽~bigtriangleup~△~biguplus~⨄~bigvee~⋁~bigwedge~⋀~bkarow~⤍~blacklozenge~⧫~blacksquare~▪~blacktriangle~▴~blacktriangledown~▾~blacktriangleleft~◂~blacktriangleright~▸~blank~␣~blk12~▒~blk14~░~blk34~▓~block~█~bne~=⃥~bnequiv~≡⃥~bnot~⌐~bopf~𝕓~bot~⊥~bottom~⊥~bowtie~⋈~boxDL~╗~boxDR~╔~boxDl~╖~boxDr~╓~boxH~═~boxHD~╦~boxHU~╩~boxHd~╤~boxHu~╧~boxUL~╝~boxUR~╚~boxUl~╜~boxUr~╙~boxV~║~boxVH~╬~boxVL~╣~boxVR~╠~boxVh~╫~boxVl~╢~boxVr~╟~boxbox~⧉~boxdL~╕~boxdR~╒~boxdl~┐~boxdr~┌~boxh~─~boxhD~╥~boxhU~╨~boxhd~┬~boxhu~┴~boxminus~⊟~boxplus~⊞~boxtimes~⊠~boxuL~╛~boxuR~╘~boxul~┘~boxur~└~boxv~│~boxvH~╪~boxvL~╡~boxvR~╞~boxvh~┼~boxvl~┤~boxvr~├~bprime~‵~breve~˘~bscr~𝒷~bsemi~⁏~bsim~∽~bsime~⋍~bsol~\\~bsolb~⧅~bsolhsub~⟈~bullet~•~bump~≎~bumpE~⪮~bumpe~≏~bumpeq~≏~cacute~ć~capand~⩄~capbrcup~⩉~capcap~⩋~capcup~⩇~capdot~⩀~caps~∩︀~caret~⁁~caron~ˇ~ccaps~⩍~ccaron~č~ccirc~ĉ~ccups~⩌~ccupssm~⩐~cdot~ċ~cemptyv~⦲~centerdot~·~cfr~𝔠~chcy~ч~check~✓~checkmark~✓~cir~○~cirE~⧃~circeq~≗~circlearrowleft~↺~circlearrowright~↻~circledR~®~circledS~Ⓢ~circledast~⊛~circledcirc~⊚~circleddash~⊝~cire~≗~cirfnint~⨐~cirmid~⫯~cirscir~⧂~clubsuit~♣~colon~:~colone~≔~coloneq~≔~comma~,~commat~@~comp~∁~compfn~∘~complement~∁~complexes~ℂ~congdot~⩭~conint~∮~copf~𝕔~coprod~∐~copysr~℗~cross~✗~cscr~𝒸~csub~⫏~csube~⫑~csup~⫐~csupe~⫒~ctdot~⋯~cudarrl~⤸~cudarrr~⤵~cuepr~⋞~cuesc~⋟~cularr~↶~cularrp~⤽~cupbrcap~⩈~cupcap~⩆~cupcup~⩊~cupdot~⊍~cupor~⩅~cups~∪︀~curarr~↷~curarrm~⤼~curlyeqprec~⋞~curlyeqsucc~⋟~curlyvee~⋎~curlywedge~⋏~curvearrowleft~↶~curvearrowright~↷~cuvee~⋎~cuwed~⋏~cwconint~∲~cwint~∱~cylcty~⌭~dHar~⥥~daleth~ℸ~dash~‐~dashv~⊣~dbkarow~⤏~dblac~˝~dcaron~ď~dcy~д~dd~ⅆ~ddagger~‡~ddarr~⇊~ddotseq~⩷~demptyv~⦱~dfisht~⥿~dfr~𝔡~dharl~⇃~dharr~⇂~diam~⋄~diamond~⋄~diamondsuit~♦~die~¨~digamma~ϝ~disin~⋲~div~÷~divideontimes~⋇~divonx~⋇~djcy~ђ~dlcorn~⌞~dlcrop~⌍~dollar~$~dopf~𝕕~dot~˙~doteq~≐~doteqdot~≑~dotminus~∸~dotplus~∔~dotsquare~⊡~doublebarwedge~⌆~downarrow~↓~downdownarrows~⇊~downharpoonleft~⇃~downharpoonright~⇂~drbkarow~⤐~drcorn~⌟~drcrop~⌌~dscr~𝒹~dscy~ѕ~dsol~⧶~dstrok~đ~dtdot~⋱~dtri~▿~dtrif~▾~duarr~⇵~duhar~⥯~dwangle~⦦~dzcy~џ~dzigrarr~⟿~eDDot~⩷~eDot~≑~easter~⩮~ecaron~ě~ecir~≖~ecolon~≕~ecy~э~edot~ė~ee~ⅇ~efDot~≒~efr~𝔢~eg~⪚~egs~⪖~egsdot~⪘~el~⪙~elinters~⏧~ell~ℓ~els~⪕~elsdot~⪗~emacr~ē~emptyset~∅~emptyv~∅~emsp13~ ~emsp14~ ~eng~ŋ~eogon~ę~eopf~𝕖~epar~⋕~eparsl~⧣~eplus~⩱~epsi~ε~epsiv~ϵ~eqcirc~≖~eqcolon~≕~eqsim~≂~eqslantgtr~⪖~eqslantless~⪕~equals~=~equest~≟~equivDD~⩸~eqvparsl~⧥~erDot~≓~erarr~⥱~escr~ℯ~esdot~≐~esim~≂~excl~!~expectation~ℰ~exponentiale~ⅇ~fallingdotseq~≒~fcy~ф~female~♀~ffilig~ffi~fflig~ff~ffllig~ffl~ffr~𝔣~filig~fi~fjlig~fj~flat~♭~fllig~fl~fltns~▱~fopf~𝕗~fork~⋔~forkv~⫙~fpartint~⨍~frac13~⅓~frac15~⅕~frac16~⅙~frac18~⅛~frac23~⅔~frac25~⅖~frac35~⅗~frac38~⅜~frac45~⅘~frac56~⅚~frac58~⅝~frac78~⅞~frown~⌢~fscr~𝒻~gE~≧~gEl~⪌~gacute~ǵ~gammad~ϝ~gap~⪆~gbreve~ğ~gcirc~ĝ~gcy~г~gdot~ġ~gel~⋛~geq~≥~geqq~≧~geqslant~⩾~ges~⩾~gescc~⪩~gesdot~⪀~gesdoto~⪂~gesdotol~⪄~gesl~⋛︀~gesles~⪔~gfr~𝔤~gg~≫~ggg~⋙~gimel~ℷ~gjcy~ѓ~gl~≷~glE~⪒~gla~⪥~glj~⪤~gnE~≩~gnap~⪊~gnapprox~⪊~gne~⪈~gneq~⪈~gneqq~≩~gnsim~⋧~gopf~𝕘~grave~`~gscr~ℊ~gsim~≳~gsime~⪎~gsiml~⪐~gtcc~⪧~gtcir~⩺~gtdot~⋗~gtlPar~⦕~gtquest~⩼~gtrapprox~⪆~gtrarr~⥸~gtrdot~⋗~gtreqless~⋛~gtreqqless~⪌~gtrless~≷~gtrsim~≳~gvertneqq~≩︀~gvnE~≩︀~hairsp~ ~half~½~hamilt~ℋ~hardcy~ъ~harrcir~⥈~harrw~↭~hbar~ℏ~hcirc~ĥ~heartsuit~♥~hercon~⊹~hfr~𝔥~hksearow~⤥~hkswarow~⤦~hoarr~⇿~homtht~∻~hookleftarrow~↩~hookrightarrow~↪~hopf~𝕙~horbar~―~hscr~𝒽~hslash~ℏ~hstrok~ħ~hybull~⁃~hyphen~‐~ic~⁣~icy~и~iecy~е~iff~⇔~ifr~𝔦~ii~ⅈ~iiiint~⨌~iiint~∭~iinfin~⧜~iiota~℩~ijlig~ij~imacr~ī~imagline~ℐ~imagpart~ℑ~imath~ı~imof~⊷~imped~Ƶ~in~∈~incare~℅~infintie~⧝~inodot~ı~intcal~⊺~integers~ℤ~intercal~⊺~intlarhk~⨗~intprod~⨼~iocy~ё~iogon~į~iopf~𝕚~iprod~⨼~iscr~𝒾~isinE~⋹~isindot~⋵~isins~⋴~isinsv~⋳~isinv~∈~it~⁢~itilde~ĩ~iukcy~і~jcirc~ĵ~jcy~й~jfr~𝔧~jmath~ȷ~jopf~𝕛~jscr~𝒿~jsercy~ј~jukcy~є~kappav~ϰ~kcedil~ķ~kcy~к~kfr~𝔨~kgreen~ĸ~khcy~х~kjcy~ќ~kopf~𝕜~kscr~𝓀~lAarr~⇚~lAtail~⤛~lBarr~⤎~lE~≦~lEg~⪋~lHar~⥢~lacute~ĺ~laemptyv~⦴~lagran~ℒ~langd~⦑~langle~⟨~lap~⪅~larrb~⇤~larrbfs~⤟~larrfs~⤝~larrhk~↩~larrlp~↫~larrpl~⤹~larrsim~⥳~larrtl~↢~lat~⪫~latail~⤙~late~⪭~lates~⪭︀~lbarr~⤌~lbbrk~❲~lbrace~{~lbrack~[~lbrke~⦋~lbrksld~⦏~lbrkslu~⦍~lcaron~ľ~lcedil~ļ~lcub~{~lcy~л~ldca~⤶~ldquor~„~ldrdhar~⥧~ldrushar~⥋~ldsh~↲~leftarrow~←~leftarrowtail~↢~leftharpoondown~↽~leftharpoonup~↼~leftleftarrows~⇇~leftrightarrow~↔~leftrightarrows~⇆~leftrightharpoons~⇋~leftrightsquigarrow~↭~leftthreetimes~⋋~leg~⋚~leq~≤~leqq~≦~leqslant~⩽~les~⩽~lescc~⪨~lesdot~⩿~lesdoto~⪁~lesdotor~⪃~lesg~⋚︀~lesges~⪓~lessapprox~⪅~lessdot~⋖~lesseqgtr~⋚~lesseqqgtr~⪋~lessgtr~≶~lesssim~≲~lfisht~⥼~lfr~𝔩~lg~≶~lgE~⪑~lhard~↽~lharu~↼~lharul~⥪~lhblk~▄~ljcy~љ~ll~≪~llarr~⇇~llcorner~⌞~llhard~⥫~lltri~◺~lmidot~ŀ~lmoust~⎰~lmoustache~⎰~lnE~≨~lnap~⪉~lnapprox~⪉~lne~⪇~lneq~⪇~lneqq~≨~lnsim~⋦~loang~⟬~loarr~⇽~lobrk~⟦~longleftarrow~⟵~longleftrightarrow~⟷~longmapsto~⟼~longrightarrow~⟶~looparrowleft~↫~looparrowright~↬~lopar~⦅~lopf~𝕝~loplus~⨭~lotimes~⨴~lowbar~_~lozenge~◊~lozf~⧫~lpar~(~lparlt~⦓~lrarr~⇆~lrcorner~⌟~lrhar~⇋~lrhard~⥭~lrtri~⊿~lscr~𝓁~lsh~↰~lsim~≲~lsime~⪍~lsimg~⪏~lsqb~[~lsquor~‚~lstrok~ł~ltcc~⪦~ltcir~⩹~ltdot~⋖~lthree~⋋~ltimes~⋉~ltlarr~⥶~ltquest~⩻~ltrPar~⦖~ltri~◃~ltrie~⊴~ltrif~◂~lurdshar~⥊~luruhar~⥦~lvertneqq~≨︀~lvnE~≨︀~mDDot~∺~male~♂~malt~✠~maltese~✠~map~↦~mapsto~↦~mapstodown~↧~mapstoleft~↤~mapstoup~↥~marker~▮~mcomma~⨩~mcy~м~measuredangle~∡~mfr~𝔪~mho~℧~mid~∣~midast~*~midcir~⫰~minusb~⊟~minusd~∸~minusdu~⨪~mlcp~⫛~mldr~…~mnplus~∓~models~⊧~mopf~𝕞~mp~∓~mscr~𝓂~mstpos~∾~multimap~⊸~mumap~⊸~nGg~⋙̸~nGt~≫⃒~nGtv~≫̸~nLeftarrow~⇍~nLeftrightarrow~⇎~nLl~⋘̸~nLt~≪⃒~nLtv~≪̸~nRightarrow~⇏~nVDash~⊯~nVdash~⊮~nacute~ń~nang~∠⃒~nap~≉~napE~⩰̸~napid~≋̸~napos~ʼn~napprox~≉~natur~♮~natural~♮~naturals~ℕ~nbump~≎̸~nbumpe~≏̸~ncap~⩃~ncaron~ň~ncedil~ņ~ncong~≇~ncongdot~⩭̸~ncup~⩂~ncy~н~neArr~⇗~nearhk~⤤~nearr~↗~nearrow~↗~nedot~≐̸~nequiv~≢~nesear~⤨~nesim~≂̸~nexist~∄~nexists~∄~nfr~𝔫~ngE~≧̸~nge~≱~ngeq~≱~ngeqq~≧̸~ngeqslant~⩾̸~nges~⩾̸~ngsim~≵~ngt~≯~ngtr~≯~nhArr~⇎~nharr~↮~nhpar~⫲~nis~⋼~nisd~⋺~niv~∋~njcy~њ~nlArr~⇍~nlE~≦̸~nlarr~↚~nldr~‥~nle~≰~nleftarrow~↚~nleftrightarrow~↮~nleq~≰~nleqq~≦̸~nleqslant~⩽̸~nles~⩽̸~nless~≮~nlsim~≴~nlt~≮~nltri~⋪~nltrie~⋬~nmid~∤~nopf~𝕟~notinE~⋹̸~notindot~⋵̸~notinva~∉~notinvb~⋷~notinvc~⋶~notni~∌~notniva~∌~notnivb~⋾~notnivc~⋽~npar~∦~nparallel~∦~nparsl~⫽⃥~npart~∂̸~npolint~⨔~npr~⊀~nprcue~⋠~npre~⪯̸~nprec~⊀~npreceq~⪯̸~nrArr~⇏~nrarr~↛~nrarrc~⤳̸~nrarrw~↝̸~nrightarrow~↛~nrtri~⋫~nrtrie~⋭~nsc~⊁~nsccue~⋡~nsce~⪰̸~nscr~𝓃~nshortmid~∤~nshortparallel~∦~nsim~≁~nsime~≄~nsimeq~≄~nsmid~∤~nspar~∦~nsqsube~⋢~nsqsupe~⋣~nsubE~⫅̸~nsube~⊈~nsubset~⊂⃒~nsubseteq~⊈~nsubseteqq~⫅̸~nsucc~⊁~nsucceq~⪰̸~nsup~⊅~nsupE~⫆̸~nsupe~⊉~nsupset~⊃⃒~nsupseteq~⊉~nsupseteqq~⫆̸~ntgl~≹~ntlg~≸~ntriangleleft~⋪~ntrianglelefteq~⋬~ntriangleright~⋫~ntrianglerighteq~⋭~num~#~numero~№~numsp~ ~nvDash~⊭~nvHarr~⤄~nvap~≍⃒~nvdash~⊬~nvge~≥⃒~nvgt~>⃒~nvinfin~⧞~nvlArr~⤂~nvle~≤⃒~nvlt~<⃒~nvltrie~⊴⃒~nvrArr~⤃~nvrtrie~⊵⃒~nvsim~∼⃒~nwArr~⇖~nwarhk~⤣~nwarr~↖~nwarrow~↖~nwnear~⤧~oS~Ⓢ~oast~⊛~ocir~⊚~ocy~о~odash~⊝~odblac~ő~odiv~⨸~odot~⊙~odsold~⦼~ofcir~⦿~ofr~𝔬~ogon~˛~ogt~⧁~ohbar~⦵~ohm~Ω~oint~∮~olarr~↺~olcir~⦾~olcross~⦻~olt~⧀~omacr~ō~omid~⦶~ominus~⊖~oopf~𝕠~opar~⦷~operp~⦹~orarr~↻~ord~⩝~order~ℴ~orderof~ℴ~origof~⊶~oror~⩖~orslope~⩗~orv~⩛~oscr~ℴ~osol~⊘~otimesas~⨶~ovbar~⌽~par~∥~parallel~∥~parsim~⫳~parsl~⫽~pcy~п~percnt~%~period~.~pertenk~‱~pfr~𝔭~phiv~ϕ~phmmat~ℳ~phone~☎~pitchfork~⋔~planck~ℏ~planckh~ℎ~plankv~ℏ~plus~+~plusacir~⨣~plusb~⊞~pluscir~⨢~plusdo~∔~plusdu~⨥~pluse~⩲~plussim~⨦~plustwo~⨧~pm~±~pointint~⨕~popf~𝕡~pr~≺~prE~⪳~prap~⪷~prcue~≼~pre~⪯~prec~≺~precapprox~⪷~preccurlyeq~≼~preceq~⪯~precnapprox~⪹~precneqq~⪵~precnsim~⋨~precsim~≾~primes~ℙ~prnE~⪵~prnap~⪹~prnsim~⋨~profalar~⌮~profline~⌒~profsurf~⌓~propto~∝~prsim~≾~prurel~⊰~pscr~𝓅~puncsp~ ~qfr~𝔮~qint~⨌~qopf~𝕢~qprime~⁗~qscr~𝓆~quaternions~ℍ~quatint~⨖~quest~?~questeq~≟~rAarr~⇛~rAtail~⤜~rBarr~⤏~rHar~⥤~race~∽̱~racute~ŕ~raemptyv~⦳~rangd~⦒~range~⦥~rangle~⟩~rarrap~⥵~rarrb~⇥~rarrbfs~⤠~rarrc~⤳~rarrfs~⤞~rarrhk~↪~rarrlp~↬~rarrpl~⥅~rarrsim~⥴~rarrtl~↣~rarrw~↝~ratail~⤚~ratio~∶~rationals~ℚ~rbarr~⤍~rbbrk~❳~rbrace~}~rbrack~]~rbrke~⦌~rbrksld~⦎~rbrkslu~⦐~rcaron~ř~rcedil~ŗ~rcub~}~rcy~р~rdca~⤷~rdldhar~⥩~rdquor~”~rdsh~↳~realine~ℛ~realpart~ℜ~reals~ℝ~rect~▭~rfisht~⥽~rfr~𝔯~rhard~⇁~rharu~⇀~rharul~⥬~rhov~ϱ~rightarrow~→~rightarrowtail~↣~rightharpoondown~⇁~rightharpoonup~⇀~rightleftarrows~⇄~rightleftharpoons~⇌~rightrightarrows~⇉~rightsquigarrow~↝~rightthreetimes~⋌~ring~˚~risingdotseq~≓~rlarr~⇄~rlhar~⇌~rmoust~⎱~rmoustache~⎱~rnmid~⫮~roang~⟭~roarr~⇾~robrk~⟧~ropar~⦆~ropf~𝕣~roplus~⨮~rotimes~⨵~rpar~)~rpargt~⦔~rppolint~⨒~rrarr~⇉~rscr~𝓇~rsh~↱~rsqb~]~rsquor~’~rthree~⋌~rtimes~⋊~rtri~▹~rtrie~⊵~rtrif~▸~rtriltri~⧎~ruluhar~⥨~rx~℞~sacute~ś~sc~≻~scE~⪴~scap~⪸~sccue~≽~sce~⪰~scedil~ş~scirc~ŝ~scnE~⪶~scnap~⪺~scnsim~⋩~scpolint~⨓~scsim~≿~scy~с~sdotb~⊡~sdote~⩦~seArr~⇘~searhk~⤥~searr~↘~searrow~↘~semi~;~seswar~⤩~setminus~∖~setmn~∖~sext~✶~sfr~𝔰~sfrown~⌢~sharp~♯~shchcy~щ~shcy~ш~shortmid~∣~shortparallel~∥~sigmav~ς~simdot~⩪~sime~≃~simeq~≃~simg~⪞~simgE~⪠~siml~⪝~simlE~⪟~simne~≆~simplus~⨤~simrarr~⥲~slarr~←~smallsetminus~∖~smashp~⨳~smeparsl~⧤~smid~∣~smile~⌣~smt~⪪~smte~⪬~smtes~⪬︀~softcy~ь~sol~/~solb~⧄~solbar~⌿~sopf~𝕤~spadesuit~♠~spar~∥~sqcap~⊓~sqcaps~⊓︀~sqcup~⊔~sqcups~⊔︀~sqsub~⊏~sqsube~⊑~sqsubset~⊏~sqsubseteq~⊑~sqsup~⊐~sqsupe~⊒~sqsupset~⊐~sqsupseteq~⊒~squ~□~square~□~squarf~▪~squf~▪~srarr~→~sscr~𝓈~ssetmn~∖~ssmile~⌣~sstarf~⋆~star~☆~starf~★~straightepsilon~ϵ~straightphi~ϕ~strns~¯~subE~⫅~subdot~⪽~subedot~⫃~submult~⫁~subnE~⫋~subne~⊊~subplus~⪿~subrarr~⥹~subset~⊂~subseteq~⊆~subseteqq~⫅~subsetneq~⊊~subsetneqq~⫋~subsim~⫇~subsub~⫕~subsup~⫓~succ~≻~succapprox~⪸~succcurlyeq~≽~succeq~⪰~succnapprox~⪺~succneqq~⪶~succnsim~⋩~succsim~≿~sung~♪~supE~⫆~supdot~⪾~supdsub~⫘~supedot~⫄~suphsol~⟉~suphsub~⫗~suplarr~⥻~supmult~⫂~supnE~⫌~supne~⊋~supplus~⫀~supset~⊃~supseteq~⊇~supseteqq~⫆~supsetneq~⊋~supsetneqq~⫌~supsim~⫈~supsub~⫔~supsup~⫖~swArr~⇙~swarhk~⤦~swarr~↙~swarrow~↙~swnwar~⤪~target~⌖~tbrk~⎴~tcaron~ť~tcedil~ţ~tcy~т~tdot~⃛~telrec~⌕~tfr~𝔱~therefore~∴~thetav~ϑ~thickapprox~≈~thicksim~∼~thkap~≈~thksim~∼~timesb~⊠~timesbar~⨱~timesd~⨰~tint~∭~toea~⤨~top~⊤~topbot~⌶~topcir~⫱~topf~𝕥~topfork~⫚~tosa~⤩~tprime~‴~triangle~▵~triangledown~▿~triangleleft~◃~trianglelefteq~⊴~triangleq~≜~triangleright~▹~trianglerighteq~⊵~tridot~◬~trie~≜~triminus~⨺~triplus~⨹~trisb~⧍~tritime~⨻~trpezium~⏢~tscr~𝓉~tscy~ц~tshcy~ћ~tstrok~ŧ~twixt~≬~twoheadleftarrow~↞~twoheadrightarrow~↠~uHar~⥣~ubrcy~ў~ubreve~ŭ~ucy~у~udarr~⇅~udblac~ű~udhar~⥮~ufisht~⥾~ufr~𝔲~uharl~↿~uharr~↾~uhblk~▀~ulcorn~⌜~ulcorner~⌜~ulcrop~⌏~ultri~◸~umacr~ū~uogon~ų~uopf~𝕦~uparrow~↑~updownarrow~↕~upharpoonleft~↿~upharpoonright~↾~uplus~⊎~upsi~υ~upuparrows~⇈~urcorn~⌝~urcorner~⌝~urcrop~⌎~uring~ů~urtri~◹~uscr~𝓊~utdot~⋰~utilde~ũ~utri~▵~utrif~▴~uuarr~⇈~uwangle~⦧~vArr~⇕~vBar~⫨~vBarv~⫩~vDash~⊨~vangrt~⦜~varepsilon~ϵ~varkappa~ϰ~varnothing~∅~varphi~ϕ~varpi~ϖ~varpropto~∝~varr~↕~varrho~ϱ~varsigma~ς~varsubsetneq~⊊︀~varsubsetneqq~⫋︀~varsupsetneq~⊋︀~varsupsetneqq~⫌︀~vartheta~ϑ~vartriangleleft~⊲~vartriangleright~⊳~vcy~в~vdash~⊢~vee~∨~veebar~⊻~veeeq~≚~vellip~⋮~verbar~|~vert~|~vfr~𝔳~vltri~⊲~vnsub~⊂⃒~vnsup~⊃⃒~vopf~𝕧~vprop~∝~vrtri~⊳~vscr~𝓋~vsubnE~⫋︀~vsubne~⊊︀~vsupnE~⫌︀~vsupne~⊋︀~vzigzag~⦚~wcirc~ŵ~wedbar~⩟~wedge~∧~wedgeq~≙~wfr~𝔴~wopf~𝕨~wp~℘~wr~≀~wreath~≀~wscr~𝓌~xcap~⋂~xcirc~◯~xcup~⋃~xdtri~▽~xfr~𝔵~xhArr~⟺~xharr~⟷~xlArr~⟸~xlarr~⟵~xmap~⟼~xnis~⋻~xodot~⨀~xopf~𝕩~xoplus~⨁~xotime~⨂~xrArr~⟹~xrarr~⟶~xscr~𝓍~xsqcup~⨆~xuplus~⨄~xutri~△~xvee~⋁~xwedge~⋀~yacy~я~ycirc~ŷ~ycy~ы~yfr~𝔶~yicy~ї~yopf~𝕪~yscr~𝓎~yucy~ю~zacute~ź~zcaron~ž~zcy~з~zdot~ż~zeetrf~ℨ~zfr~𝔷~zhcy~ж~zigrarr~⇝~zopf~𝕫~zscr~𝓏~~AMP~&~COPY~©~GT~>~LT~<~QUOT~\"~REG~®", namedReferences['html4']);

/***/ }),

/***/ 80708:
/*!********************************************************************!*\
  !*** ./node_modules/html-entities/dist/esm/numeric-unicode-map.js ***!
  \********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   numericUnicodeMap: () => (/* binding */ numericUnicodeMap)
/* harmony export */ });
var numericUnicodeMap = {
  0: 65533,
  128: 8364,
  130: 8218,
  131: 402,
  132: 8222,
  133: 8230,
  134: 8224,
  135: 8225,
  136: 710,
  137: 8240,
  138: 352,
  139: 8249,
  140: 338,
  142: 381,
  145: 8216,
  146: 8217,
  147: 8220,
  148: 8221,
  149: 8226,
  150: 8211,
  151: 8212,
  152: 732,
  153: 8482,
  154: 353,
  155: 8250,
  156: 339,
  158: 382,
  159: 376
};

/***/ }),

/***/ 86200:
/*!****************************************************************!*\
  !*** ./node_modules/html-entities/dist/esm/surrogate-pairs.js ***!
  \****************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   fromCodePoint: () => (/* binding */ fromCodePoint),
/* harmony export */   getCodePoint: () => (/* binding */ getCodePoint),
/* harmony export */   highSurrogateFrom: () => (/* binding */ highSurrogateFrom),
/* harmony export */   highSurrogateTo: () => (/* binding */ highSurrogateTo)
/* harmony export */ });
var fromCodePoint = String.fromCodePoint || function (astralCodePoint) {
  return String.fromCharCode(Math.floor((astralCodePoint - 0x10000) / 0x400) + 0xd800, (astralCodePoint - 0x10000) % 0x400 + 0xdc00);
};
// @ts-expect-error - String.prototype.codePointAt might not exist in older node versions
var getCodePoint = String.prototype.codePointAt ? function (input, position) {
  return input.codePointAt(position);
} : function (input, position) {
  return (input.charCodeAt(position) - 0xd800) * 0x400 + input.charCodeAt(position + 1) - 0xdc00 + 0x10000;
};
var highSurrogateFrom = 0xd800;
var highSurrogateTo = 0xdbff;

/***/ }),

/***/ 60794:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_DataView.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_root.js */ 911);



/* Built-in method references that are verified to be native. */
var DataView = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_root_js__WEBPACK_IMPORTED_MODULE_1__["default"], 'DataView');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (DataView);

/***/ }),

/***/ 69279:
/*!*****************************************!*\
  !*** ./node_modules/lodash-es/_Hash.js ***!
  \*****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _hashClear_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_hashClear.js */ 18982);
/* harmony import */ var _hashDelete_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_hashDelete.js */ 88624);
/* harmony import */ var _hashGet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_hashGet.js */ 39059);
/* harmony import */ var _hashHas_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_hashHas.js */ 32479);
/* harmony import */ var _hashSet_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_hashSet.js */ 48119);






/**
 * Creates a hash object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function Hash(entries) {
  var index = -1,
    length = entries == null ? 0 : entries.length;
  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `Hash`.
Hash.prototype.clear = _hashClear_js__WEBPACK_IMPORTED_MODULE_0__["default"];
Hash.prototype['delete'] = _hashDelete_js__WEBPACK_IMPORTED_MODULE_1__["default"];
Hash.prototype.get = _hashGet_js__WEBPACK_IMPORTED_MODULE_2__["default"];
Hash.prototype.has = _hashHas_js__WEBPACK_IMPORTED_MODULE_3__["default"];
Hash.prototype.set = _hashSet_js__WEBPACK_IMPORTED_MODULE_4__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Hash);

/***/ }),

/***/ 30213:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_ListCache.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _listCacheClear_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_listCacheClear.js */ 55272);
/* harmony import */ var _listCacheDelete_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_listCacheDelete.js */ 4958);
/* harmony import */ var _listCacheGet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_listCacheGet.js */ 70729);
/* harmony import */ var _listCacheHas_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_listCacheHas.js */ 40773);
/* harmony import */ var _listCacheSet_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_listCacheSet.js */ 1901);






/**
 * Creates an list cache object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function ListCache(entries) {
  var index = -1,
    length = entries == null ? 0 : entries.length;
  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `ListCache`.
ListCache.prototype.clear = _listCacheClear_js__WEBPACK_IMPORTED_MODULE_0__["default"];
ListCache.prototype['delete'] = _listCacheDelete_js__WEBPACK_IMPORTED_MODULE_1__["default"];
ListCache.prototype.get = _listCacheGet_js__WEBPACK_IMPORTED_MODULE_2__["default"];
ListCache.prototype.has = _listCacheHas_js__WEBPACK_IMPORTED_MODULE_3__["default"];
ListCache.prototype.set = _listCacheSet_js__WEBPACK_IMPORTED_MODULE_4__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ListCache);

/***/ }),

/***/ 55297:
/*!****************************************!*\
  !*** ./node_modules/lodash-es/_Map.js ***!
  \****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_root.js */ 911);



/* Built-in method references that are verified to be native. */
var Map = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_root_js__WEBPACK_IMPORTED_MODULE_1__["default"], 'Map');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Map);

/***/ }),

/***/ 7531:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_MapCache.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _mapCacheClear_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_mapCacheClear.js */ 33578);
/* harmony import */ var _mapCacheDelete_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_mapCacheDelete.js */ 23948);
/* harmony import */ var _mapCacheGet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_mapCacheGet.js */ 47423);
/* harmony import */ var _mapCacheHas_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_mapCacheHas.js */ 98019);
/* harmony import */ var _mapCacheSet_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_mapCacheSet.js */ 955);






/**
 * Creates a map cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function MapCache(entries) {
  var index = -1,
    length = entries == null ? 0 : entries.length;
  this.clear();
  while (++index < length) {
    var entry = entries[index];
    this.set(entry[0], entry[1]);
  }
}

// Add methods to `MapCache`.
MapCache.prototype.clear = _mapCacheClear_js__WEBPACK_IMPORTED_MODULE_0__["default"];
MapCache.prototype['delete'] = _mapCacheDelete_js__WEBPACK_IMPORTED_MODULE_1__["default"];
MapCache.prototype.get = _mapCacheGet_js__WEBPACK_IMPORTED_MODULE_2__["default"];
MapCache.prototype.has = _mapCacheHas_js__WEBPACK_IMPORTED_MODULE_3__["default"];
MapCache.prototype.set = _mapCacheSet_js__WEBPACK_IMPORTED_MODULE_4__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (MapCache);

/***/ }),

/***/ 49973:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_Promise.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_root.js */ 911);



/* Built-in method references that are verified to be native. */
var Promise = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_root_js__WEBPACK_IMPORTED_MODULE_1__["default"], 'Promise');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Promise);

/***/ }),

/***/ 50679:
/*!****************************************!*\
  !*** ./node_modules/lodash-es/_Set.js ***!
  \****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_root.js */ 911);



/* Built-in method references that are verified to be native. */
var Set = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_root_js__WEBPACK_IMPORTED_MODULE_1__["default"], 'Set');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Set);

/***/ }),

/***/ 72359:
/*!******************************************!*\
  !*** ./node_modules/lodash-es/_Stack.js ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ListCache_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_ListCache.js */ 30213);
/* harmony import */ var _stackClear_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_stackClear.js */ 48686);
/* harmony import */ var _stackDelete_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_stackDelete.js */ 54504);
/* harmony import */ var _stackGet_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_stackGet.js */ 84331);
/* harmony import */ var _stackHas_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_stackHas.js */ 16391);
/* harmony import */ var _stackSet_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./_stackSet.js */ 97039);







/**
 * Creates a stack cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */
function Stack(entries) {
  var data = this.__data__ = new _ListCache_js__WEBPACK_IMPORTED_MODULE_0__["default"](entries);
  this.size = data.size;
}

// Add methods to `Stack`.
Stack.prototype.clear = _stackClear_js__WEBPACK_IMPORTED_MODULE_1__["default"];
Stack.prototype['delete'] = _stackDelete_js__WEBPACK_IMPORTED_MODULE_2__["default"];
Stack.prototype.get = _stackGet_js__WEBPACK_IMPORTED_MODULE_3__["default"];
Stack.prototype.has = _stackHas_js__WEBPACK_IMPORTED_MODULE_4__["default"];
Stack.prototype.set = _stackSet_js__WEBPACK_IMPORTED_MODULE_5__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Stack);

/***/ }),

/***/ 9091:
/*!*******************************************!*\
  !*** ./node_modules/lodash-es/_Symbol.js ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);


/** Built-in value references. */
var Symbol = _root_js__WEBPACK_IMPORTED_MODULE_0__["default"].Symbol;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Symbol);

/***/ }),

/***/ 66270:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_Uint8Array.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);


/** Built-in value references. */
var Uint8Array = _root_js__WEBPACK_IMPORTED_MODULE_0__["default"].Uint8Array;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Uint8Array);

/***/ }),

/***/ 18569:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_WeakMap.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_root.js */ 911);



/* Built-in method references that are verified to be native. */
var WeakMap = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_root_js__WEBPACK_IMPORTED_MODULE_1__["default"], 'WeakMap');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (WeakMap);

/***/ }),

/***/ 45839:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_arrayEach.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * A specialized version of `_.forEach` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */
function arrayEach(array, iteratee) {
  var index = -1,
    length = array == null ? 0 : array.length;
  while (++index < length) {
    if (iteratee(array[index], index, array) === false) {
      break;
    }
  }
  return array;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayEach);

/***/ }),

/***/ 84948:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_arrayFilter.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * A specialized version of `_.filter` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */
function arrayFilter(array, predicate) {
  var index = -1,
    length = array == null ? 0 : array.length,
    resIndex = 0,
    result = [];
  while (++index < length) {
    var value = array[index];
    if (predicate(value, index, array)) {
      result[resIndex++] = value;
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayFilter);

/***/ }),

/***/ 58165:
/*!**************************************************!*\
  !*** ./node_modules/lodash-es/_arrayLikeKeys.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseTimes_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_baseTimes.js */ 8670);
/* harmony import */ var _isArguments_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isArguments.js */ 38826);
/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isArray.js */ 19247);
/* harmony import */ var _isBuffer_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isBuffer.js */ 47618);
/* harmony import */ var _isIndex_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./_isIndex.js */ 60123);
/* harmony import */ var _isTypedArray_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./isTypedArray.js */ 18449);







/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Creates an array of the enumerable property names of the array-like `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @param {boolean} inherited Specify returning inherited property names.
 * @returns {Array} Returns the array of property names.
 */
function arrayLikeKeys(value, inherited) {
  var isArr = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value),
    isArg = !isArr && (0,_isArguments_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value),
    isBuff = !isArr && !isArg && (0,_isBuffer_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value),
    isType = !isArr && !isArg && !isBuff && (0,_isTypedArray_js__WEBPACK_IMPORTED_MODULE_3__["default"])(value),
    skipIndexes = isArr || isArg || isBuff || isType,
    result = skipIndexes ? (0,_baseTimes_js__WEBPACK_IMPORTED_MODULE_4__["default"])(value.length, String) : [],
    length = result.length;
  for (var key in value) {
    if ((inherited || hasOwnProperty.call(value, key)) && !(skipIndexes && (
    // Safari 9 has enumerable `arguments.length` in strict mode.
    key == 'length' ||
    // Node.js 0.10 has enumerable non-index properties on buffers.
    isBuff && (key == 'offset' || key == 'parent') ||
    // PhantomJS 2 has enumerable non-index properties on typed arrays.
    isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset') ||
    // Skip index properties.
    (0,_isIndex_js__WEBPACK_IMPORTED_MODULE_5__["default"])(key, length)))) {
      result.push(key);
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayLikeKeys);

/***/ }),

/***/ 59126:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_arrayPush.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Appends the elements of `values` to `array`.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {Array} values The values to append.
 * @returns {Array} Returns `array`.
 */
function arrayPush(array, values) {
  var index = -1,
    length = values.length,
    offset = array.length;
  while (++index < length) {
    array[offset + index] = values[index];
  }
  return array;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (arrayPush);

/***/ }),

/***/ 16545:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_assignValue.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseAssignValue_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseAssignValue.js */ 11878);
/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./eq.js */ 97622);



/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Assigns `value` to `key` of `object` if the existing value is not equivalent
 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function assignValue(object, key, value) {
  var objValue = object[key];
  if (!(hasOwnProperty.call(object, key) && (0,_eq_js__WEBPACK_IMPORTED_MODULE_0__["default"])(objValue, value)) || value === undefined && !(key in object)) {
    (0,_baseAssignValue_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object, key, value);
  }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (assignValue);

/***/ }),

/***/ 23491:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_assocIndexOf.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _eq_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./eq.js */ 97622);


/**
 * Gets the index at which the `key` is found in `array` of key-value pairs.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} key The key to search for.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */
function assocIndexOf(array, key) {
  var length = array.length;
  while (length--) {
    if ((0,_eq_js__WEBPACK_IMPORTED_MODULE_0__["default"])(array[length][0], key)) {
      return length;
    }
  }
  return -1;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (assocIndexOf);

/***/ }),

/***/ 67467:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_baseAssign.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _copyObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_copyObject.js */ 61893);
/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./keys.js */ 29892);



/**
 * The base implementation of `_.assign` without support for multiple sources
 * or `customizer` functions.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @returns {Object} Returns `object`.
 */
function baseAssign(object, source) {
  return object && (0,_copyObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(source, (0,_keys_js__WEBPACK_IMPORTED_MODULE_1__["default"])(source), object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseAssign);

/***/ }),

/***/ 56408:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_baseAssignIn.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _copyObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_copyObject.js */ 61893);
/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./keysIn.js */ 75243);



/**
 * The base implementation of `_.assignIn` without support for multiple sources
 * or `customizer` functions.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @returns {Object} Returns `object`.
 */
function baseAssignIn(object, source) {
  return object && (0,_copyObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(source, (0,_keysIn_js__WEBPACK_IMPORTED_MODULE_1__["default"])(source), object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseAssignIn);

/***/ }),

/***/ 11878:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_baseAssignValue.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_defineProperty.js */ 17797);


/**
 * The base implementation of `assignValue` and `assignMergeValue` without
 * value checks.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */
function baseAssignValue(object, key, value) {
  if (key == '__proto__' && _defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"]) {
    (0,_defineProperty_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object, key, {
      'configurable': true,
      'enumerable': true,
      'value': value,
      'writable': true
    });
  } else {
    object[key] = value;
  }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseAssignValue);

/***/ }),

/***/ 95365:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_baseClone.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Stack_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./_Stack.js */ 72359);
/* harmony import */ var _arrayEach_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./_arrayEach.js */ 45839);
/* harmony import */ var _assignValue_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./_assignValue.js */ 16545);
/* harmony import */ var _baseAssign_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./_baseAssign.js */ 67467);
/* harmony import */ var _baseAssignIn_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./_baseAssignIn.js */ 56408);
/* harmony import */ var _cloneBuffer_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./_cloneBuffer.js */ 99424);
/* harmony import */ var _copyArray_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_copyArray.js */ 80905);
/* harmony import */ var _copySymbols_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./_copySymbols.js */ 9873);
/* harmony import */ var _copySymbolsIn_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./_copySymbolsIn.js */ 95130);
/* harmony import */ var _getAllKeys_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./_getAllKeys.js */ 86340);
/* harmony import */ var _getAllKeysIn_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./_getAllKeysIn.js */ 63147);
/* harmony import */ var _getTag_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_getTag.js */ 11139);
/* harmony import */ var _initCloneArray_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_initCloneArray.js */ 15147);
/* harmony import */ var _initCloneByTag_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./_initCloneByTag.js */ 16941);
/* harmony import */ var _initCloneObject_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./_initCloneObject.js */ 13195);
/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isArray.js */ 19247);
/* harmony import */ var _isBuffer_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./isBuffer.js */ 47618);
/* harmony import */ var _isMap_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./isMap.js */ 43144);
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);
/* harmony import */ var _isSet_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./isSet.js */ 11186);
/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./keys.js */ 29892);
/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./keysIn.js */ 75243);























/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
  CLONE_FLAT_FLAG = 2,
  CLONE_SYMBOLS_FLAG = 4;

/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
  arrayTag = '[object Array]',
  boolTag = '[object Boolean]',
  dateTag = '[object Date]',
  errorTag = '[object Error]',
  funcTag = '[object Function]',
  genTag = '[object GeneratorFunction]',
  mapTag = '[object Map]',
  numberTag = '[object Number]',
  objectTag = '[object Object]',
  regexpTag = '[object RegExp]',
  setTag = '[object Set]',
  stringTag = '[object String]',
  symbolTag = '[object Symbol]',
  weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
  dataViewTag = '[object DataView]',
  float32Tag = '[object Float32Array]',
  float64Tag = '[object Float64Array]',
  int8Tag = '[object Int8Array]',
  int16Tag = '[object Int16Array]',
  int32Tag = '[object Int32Array]',
  uint8Tag = '[object Uint8Array]',
  uint8ClampedTag = '[object Uint8ClampedArray]',
  uint16Tag = '[object Uint16Array]',
  uint32Tag = '[object Uint32Array]';

/** Used to identify `toStringTag` values supported by `_.clone`. */
var cloneableTags = {};
cloneableTags[argsTag] = cloneableTags[arrayTag] = cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = cloneableTags[boolTag] = cloneableTags[dateTag] = cloneableTags[float32Tag] = cloneableTags[float64Tag] = cloneableTags[int8Tag] = cloneableTags[int16Tag] = cloneableTags[int32Tag] = cloneableTags[mapTag] = cloneableTags[numberTag] = cloneableTags[objectTag] = cloneableTags[regexpTag] = cloneableTags[setTag] = cloneableTags[stringTag] = cloneableTags[symbolTag] = cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;
cloneableTags[errorTag] = cloneableTags[funcTag] = cloneableTags[weakMapTag] = false;

/**
 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
 * traversed objects.
 *
 * @private
 * @param {*} value The value to clone.
 * @param {boolean} bitmask The bitmask flags.
 *  1 - Deep clone
 *  2 - Flatten inherited properties
 *  4 - Clone symbols
 * @param {Function} [customizer] The function to customize cloning.
 * @param {string} [key] The key of `value`.
 * @param {Object} [object] The parent object of `value`.
 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
 * @returns {*} Returns the cloned value.
 */
function baseClone(value, bitmask, customizer, key, object, stack) {
  var result,
    isDeep = bitmask & CLONE_DEEP_FLAG,
    isFlat = bitmask & CLONE_FLAT_FLAG,
    isFull = bitmask & CLONE_SYMBOLS_FLAG;
  if (customizer) {
    result = object ? customizer(value, key, object, stack) : customizer(value);
  }
  if (result !== undefined) {
    return result;
  }
  if (!(0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value)) {
    return value;
  }
  var isArr = (0,_isArray_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value);
  if (isArr) {
    result = (0,_initCloneArray_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value);
    if (!isDeep) {
      return (0,_copyArray_js__WEBPACK_IMPORTED_MODULE_3__["default"])(value, result);
    }
  } else {
    var tag = (0,_getTag_js__WEBPACK_IMPORTED_MODULE_4__["default"])(value),
      isFunc = tag == funcTag || tag == genTag;
    if ((0,_isBuffer_js__WEBPACK_IMPORTED_MODULE_5__["default"])(value)) {
      return (0,_cloneBuffer_js__WEBPACK_IMPORTED_MODULE_6__["default"])(value, isDeep);
    }
    if (tag == objectTag || tag == argsTag || isFunc && !object) {
      result = isFlat || isFunc ? {} : (0,_initCloneObject_js__WEBPACK_IMPORTED_MODULE_7__["default"])(value);
      if (!isDeep) {
        return isFlat ? (0,_copySymbolsIn_js__WEBPACK_IMPORTED_MODULE_8__["default"])(value, (0,_baseAssignIn_js__WEBPACK_IMPORTED_MODULE_9__["default"])(result, value)) : (0,_copySymbols_js__WEBPACK_IMPORTED_MODULE_10__["default"])(value, (0,_baseAssign_js__WEBPACK_IMPORTED_MODULE_11__["default"])(result, value));
      }
    } else {
      if (!cloneableTags[tag]) {
        return object ? value : {};
      }
      result = (0,_initCloneByTag_js__WEBPACK_IMPORTED_MODULE_12__["default"])(value, tag, isDeep);
    }
  }
  // Check for circular references and return its corresponding clone.
  stack || (stack = new _Stack_js__WEBPACK_IMPORTED_MODULE_13__["default"]());
  var stacked = stack.get(value);
  if (stacked) {
    return stacked;
  }
  stack.set(value, result);
  if ((0,_isSet_js__WEBPACK_IMPORTED_MODULE_14__["default"])(value)) {
    value.forEach(function (subValue) {
      result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack));
    });
  } else if ((0,_isMap_js__WEBPACK_IMPORTED_MODULE_15__["default"])(value)) {
    value.forEach(function (subValue, key) {
      result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack));
    });
  }
  var keysFunc = isFull ? isFlat ? _getAllKeysIn_js__WEBPACK_IMPORTED_MODULE_16__["default"] : _getAllKeys_js__WEBPACK_IMPORTED_MODULE_17__["default"] : isFlat ? _keysIn_js__WEBPACK_IMPORTED_MODULE_18__["default"] : _keys_js__WEBPACK_IMPORTED_MODULE_19__["default"];
  var props = isArr ? undefined : keysFunc(value);
  (0,_arrayEach_js__WEBPACK_IMPORTED_MODULE_20__["default"])(props || value, function (subValue, key) {
    if (props) {
      key = subValue;
      subValue = value[key];
    }
    // Recursively populate clone (susceptible to call stack limits).
    (0,_assignValue_js__WEBPACK_IMPORTED_MODULE_21__["default"])(result, key, baseClone(subValue, bitmask, customizer, key, value, stack));
  });
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseClone);

/***/ }),

/***/ 49934:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_baseCreate.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);


/** Built-in value references. */
var objectCreate = Object.create;

/**
 * The base implementation of `_.create` without support for assigning
 * properties to the created object.
 *
 * @private
 * @param {Object} proto The object to inherit from.
 * @returns {Object} Returns the new object.
 */
var baseCreate = function () {
  function object() {}
  return function (proto) {
    if (!(0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(proto)) {
      return {};
    }
    if (objectCreate) {
      return objectCreate(proto);
    }
    object.prototype = proto;
    var result = new object();
    object.prototype = undefined;
    return result;
  };
}();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseCreate);

/***/ }),

/***/ 58705:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_baseGetAllKeys.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_arrayPush.js */ 59126);
/* harmony import */ var _isArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isArray.js */ 19247);



/**
 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
 * symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @param {Function} symbolsFunc The function to get the symbols of `object`.
 * @returns {Array} Returns the array of property names and symbols.
 */
function baseGetAllKeys(object, keysFunc, symbolsFunc) {
  var result = keysFunc(object);
  return (0,_isArray_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object) ? result : (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__["default"])(result, symbolsFunc(object));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetAllKeys);

/***/ }),

/***/ 14478:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_baseGetTag.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Symbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_Symbol.js */ 9091);
/* harmony import */ var _getRawTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_getRawTag.js */ 96133);
/* harmony import */ var _objectToString_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_objectToString.js */ 92880);




/** `Object#toString` result references. */
var nullTag = '[object Null]',
  undefinedTag = '[object Undefined]';

/** Built-in value references. */
var symToStringTag = _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"] ? _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"].toStringTag : undefined;

/**
 * The base implementation of `getTag` without fallbacks for buggy environments.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
function baseGetTag(value) {
  if (value == null) {
    return value === undefined ? undefinedTag : nullTag;
  }
  return symToStringTag && symToStringTag in Object(value) ? (0,_getRawTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) : (0,_objectToString_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseGetTag);

/***/ }),

/***/ 1244:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_baseIsArguments.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);



/** `Object#toString` result references. */
var argsTag = '[object Arguments]';

/**
 * The base implementation of `_.isArguments`.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
 */
function baseIsArguments(value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) == argsTag;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseIsArguments);

/***/ }),

/***/ 99842:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_baseIsMap.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_getTag.js */ 11139);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);



/** `Object#toString` result references. */
var mapTag = '[object Map]';

/**
 * The base implementation of `_.isMap` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
 */
function baseIsMap(value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && (0,_getTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) == mapTag;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseIsMap);

/***/ }),

/***/ 46069:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_baseIsNative.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isFunction_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./isFunction.js */ 68104);
/* harmony import */ var _isMasked_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_isMasked.js */ 56498);
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);
/* harmony import */ var _toSource_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_toSource.js */ 16275);





/**
 * Used to match `RegExp`
 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
 */
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

/** Used to detect host constructors (Safari). */
var reIsHostCtor = /^\[object .+?Constructor\]$/;

/** Used for built-in method references. */
var funcProto = Function.prototype,
  objectProto = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Used to detect if a method is native. */
var reIsNative = RegExp('^' + funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');

/**
 * The base implementation of `_.isNative` without bad shim checks.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a native function,
 *  else `false`.
 */
function baseIsNative(value) {
  if (!(0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) || (0,_isMasked_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value)) {
    return false;
  }
  var pattern = (0,_isFunction_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value) ? reIsNative : reIsHostCtor;
  return pattern.test((0,_toSource_js__WEBPACK_IMPORTED_MODULE_3__["default"])(value));
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseIsNative);

/***/ }),

/***/ 78392:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_baseIsSet.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_getTag.js */ 11139);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);



/** `Object#toString` result references. */
var setTag = '[object Set]';

/**
 * The base implementation of `_.isSet` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
 */
function baseIsSet(value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && (0,_getTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) == setTag;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseIsSet);

/***/ }),

/***/ 39423:
/*!*****************************************************!*\
  !*** ./node_modules/lodash-es/_baseIsTypedArray.js ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isLength.js */ 26872);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);




/** `Object#toString` result references. */
var argsTag = '[object Arguments]',
  arrayTag = '[object Array]',
  boolTag = '[object Boolean]',
  dateTag = '[object Date]',
  errorTag = '[object Error]',
  funcTag = '[object Function]',
  mapTag = '[object Map]',
  numberTag = '[object Number]',
  objectTag = '[object Object]',
  regexpTag = '[object RegExp]',
  setTag = '[object Set]',
  stringTag = '[object String]',
  weakMapTag = '[object WeakMap]';
var arrayBufferTag = '[object ArrayBuffer]',
  dataViewTag = '[object DataView]',
  float32Tag = '[object Float32Array]',
  float64Tag = '[object Float64Array]',
  int8Tag = '[object Int8Array]',
  int16Tag = '[object Int16Array]',
  int32Tag = '[object Int32Array]',
  uint8Tag = '[object Uint8Array]',
  uint8ClampedTag = '[object Uint8ClampedArray]',
  uint16Tag = '[object Uint16Array]',
  uint32Tag = '[object Uint32Array]';

/** Used to identify `toStringTag` values of typed arrays. */
var typedArrayTags = {};
typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true;
typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false;

/**
 * The base implementation of `_.isTypedArray` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
 */
function baseIsTypedArray(value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value.length) && !!typedArrayTags[(0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value)];
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseIsTypedArray);

/***/ }),

/***/ 43934:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_baseKeys.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isPrototype_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_isPrototype.js */ 29641);
/* harmony import */ var _nativeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_nativeKeys.js */ 25920);



/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
function baseKeys(object) {
  if (!(0,_isPrototype_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object)) {
    return (0,_nativeKeys_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object);
  }
  var result = [];
  for (var key in Object(object)) {
    if (hasOwnProperty.call(object, key) && key != 'constructor') {
      result.push(key);
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseKeys);

/***/ }),

/***/ 97225:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_baseKeysIn.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);
/* harmony import */ var _isPrototype_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_isPrototype.js */ 29641);
/* harmony import */ var _nativeKeysIn_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_nativeKeysIn.js */ 94767);




/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
function baseKeysIn(object) {
  if (!(0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object)) {
    return (0,_nativeKeysIn_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object);
  }
  var isProto = (0,_isPrototype_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object),
    result = [];
  for (var key in object) {
    if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
      result.push(key);
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseKeysIn);

/***/ }),

/***/ 8670:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_baseTimes.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * The base implementation of `_.times` without support for iteratee shorthands
 * or max array length checks.
 *
 * @private
 * @param {number} n The number of times to invoke `iteratee`.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the array of results.
 */
function baseTimes(n, iteratee) {
  var index = -1,
    result = Array(n);
  while (++index < n) {
    result[index] = iteratee(index);
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseTimes);

/***/ }),

/***/ 80106:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_baseTrim.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _trimmedEndIndex_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_trimmedEndIndex.js */ 59782);


/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;

/**
 * The base implementation of `_.trim`.
 *
 * @private
 * @param {string} string The string to trim.
 * @returns {string} Returns the trimmed string.
 */
function baseTrim(string) {
  return string ? string.slice(0, (0,_trimmedEndIndex_js__WEBPACK_IMPORTED_MODULE_0__["default"])(string) + 1).replace(reTrimStart, '') : string;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseTrim);

/***/ }),

/***/ 45583:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_baseUnary.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * The base implementation of `_.unary` without support for storing metadata.
 *
 * @private
 * @param {Function} func The function to cap arguments for.
 * @returns {Function} Returns the new capped function.
 */
function baseUnary(func) {
  return function (value) {
    return func(value);
  };
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (baseUnary);

/***/ }),

/***/ 62279:
/*!*****************************************************!*\
  !*** ./node_modules/lodash-es/_cloneArrayBuffer.js ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Uint8Array_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_Uint8Array.js */ 66270);


/**
 * Creates a clone of `arrayBuffer`.
 *
 * @private
 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
 * @returns {ArrayBuffer} Returns the cloned array buffer.
 */
function cloneArrayBuffer(arrayBuffer) {
  var result = new arrayBuffer.constructor(arrayBuffer.byteLength);
  new _Uint8Array_js__WEBPACK_IMPORTED_MODULE_0__["default"](result).set(new _Uint8Array_js__WEBPACK_IMPORTED_MODULE_0__["default"](arrayBuffer));
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneArrayBuffer);

/***/ }),

/***/ 99424:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_cloneBuffer.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);


/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;

/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;

/** Built-in value references. */
var Buffer = moduleExports ? _root_js__WEBPACK_IMPORTED_MODULE_0__["default"].Buffer : undefined,
  allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined;

/**
 * Creates a clone of  `buffer`.
 *
 * @private
 * @param {Buffer} buffer The buffer to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Buffer} Returns the cloned buffer.
 */
function cloneBuffer(buffer, isDeep) {
  if (isDeep) {
    return buffer.slice();
  }
  var length = buffer.length,
    result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(length);
  buffer.copy(result);
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneBuffer);

/***/ }),

/***/ 33823:
/*!**************************************************!*\
  !*** ./node_modules/lodash-es/_cloneDataView.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_cloneArrayBuffer.js */ 62279);


/**
 * Creates a clone of `dataView`.
 *
 * @private
 * @param {Object} dataView The data view to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned data view.
 */
function cloneDataView(dataView, isDeep) {
  var buffer = isDeep ? (0,_cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__["default"])(dataView.buffer) : dataView.buffer;
  return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneDataView);

/***/ }),

/***/ 52591:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_cloneRegExp.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used to match `RegExp` flags from their coerced string values. */
var reFlags = /\w*$/;

/**
 * Creates a clone of `regexp`.
 *
 * @private
 * @param {Object} regexp The regexp to clone.
 * @returns {Object} Returns the cloned regexp.
 */
function cloneRegExp(regexp) {
  var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));
  result.lastIndex = regexp.lastIndex;
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneRegExp);

/***/ }),

/***/ 40610:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_cloneSymbol.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Symbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_Symbol.js */ 9091);


/** Used to convert symbols to primitives and strings. */
var symbolProto = _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"] ? _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"].prototype : undefined,
  symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;

/**
 * Creates a clone of the `symbol` object.
 *
 * @private
 * @param {Object} symbol The symbol object to clone.
 * @returns {Object} Returns the cloned symbol object.
 */
function cloneSymbol(symbol) {
  return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneSymbol);

/***/ }),

/***/ 28295:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_cloneTypedArray.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_cloneArrayBuffer.js */ 62279);


/**
 * Creates a clone of `typedArray`.
 *
 * @private
 * @param {Object} typedArray The typed array to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned typed array.
 */
function cloneTypedArray(typedArray, isDeep) {
  var buffer = isDeep ? (0,_cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__["default"])(typedArray.buffer) : typedArray.buffer;
  return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneTypedArray);

/***/ }),

/***/ 80905:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_copyArray.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Copies the values of `source` to `array`.
 *
 * @private
 * @param {Array} source The array to copy values from.
 * @param {Array} [array=[]] The array to copy values to.
 * @returns {Array} Returns `array`.
 */
function copyArray(source, array) {
  var index = -1,
    length = source.length;
  array || (array = Array(length));
  while (++index < length) {
    array[index] = source[index];
  }
  return array;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (copyArray);

/***/ }),

/***/ 61893:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_copyObject.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _assignValue_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_assignValue.js */ 16545);
/* harmony import */ var _baseAssignValue_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_baseAssignValue.js */ 11878);



/**
 * Copies properties of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy properties from.
 * @param {Array} props The property identifiers to copy.
 * @param {Object} [object={}] The object to copy properties to.
 * @param {Function} [customizer] The function to customize copied values.
 * @returns {Object} Returns `object`.
 */
function copyObject(source, props, object, customizer) {
  var isNew = !object;
  object || (object = {});
  var index = -1,
    length = props.length;
  while (++index < length) {
    var key = props[index];
    var newValue = customizer ? customizer(object[key], source[key], key, object, source) : undefined;
    if (newValue === undefined) {
      newValue = source[key];
    }
    if (isNew) {
      (0,_baseAssignValue_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object, key, newValue);
    } else {
      (0,_assignValue_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object, key, newValue);
    }
  }
  return object;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (copyObject);

/***/ }),

/***/ 9873:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_copySymbols.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _copyObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_copyObject.js */ 61893);
/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_getSymbols.js */ 27482);



/**
 * Copies own symbols of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy symbols from.
 * @param {Object} [object={}] The object to copy symbols to.
 * @returns {Object} Returns `object`.
 */
function copySymbols(source, object) {
  return (0,_copyObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(source, (0,_getSymbols_js__WEBPACK_IMPORTED_MODULE_1__["default"])(source), object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (copySymbols);

/***/ }),

/***/ 95130:
/*!**************************************************!*\
  !*** ./node_modules/lodash-es/_copySymbolsIn.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _copyObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_copyObject.js */ 61893);
/* harmony import */ var _getSymbolsIn_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_getSymbolsIn.js */ 89309);



/**
 * Copies own and inherited symbols of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy symbols from.
 * @param {Object} [object={}] The object to copy symbols to.
 * @returns {Object} Returns `object`.
 */
function copySymbolsIn(source, object) {
  return (0,_copyObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(source, (0,_getSymbolsIn_js__WEBPACK_IMPORTED_MODULE_1__["default"])(source), object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (copySymbolsIn);

/***/ }),

/***/ 53251:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_coreJsData.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);


/** Used to detect overreaching core-js shims. */
var coreJsData = _root_js__WEBPACK_IMPORTED_MODULE_0__["default"]['__core-js_shared__'];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (coreJsData);

/***/ }),

/***/ 17797:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_defineProperty.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);

var defineProperty = function () {
  try {
    var func = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(Object, 'defineProperty');
    func({}, '', {});
    return func;
  } catch (e) {}
}();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (defineProperty);

/***/ }),

/***/ 59210:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_freeGlobal.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Detect free variable `global` from Node.js. */
var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (freeGlobal);

/***/ }),

/***/ 86340:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_getAllKeys.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_baseGetAllKeys.js */ 58705);
/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_getSymbols.js */ 27482);
/* harmony import */ var _keys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./keys.js */ 29892);




/**
 * Creates an array of own enumerable property names and symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */
function getAllKeys(object) {
  return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object, _keys_js__WEBPACK_IMPORTED_MODULE_1__["default"], _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__["default"]);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeys);

/***/ }),

/***/ 63147:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_getAllKeysIn.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_baseGetAllKeys.js */ 58705);
/* harmony import */ var _getSymbolsIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_getSymbolsIn.js */ 89309);
/* harmony import */ var _keysIn_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./keysIn.js */ 75243);




/**
 * Creates an array of own and inherited enumerable property names and
 * symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */
function getAllKeysIn(object) {
  return (0,_baseGetAllKeys_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object, _keysIn_js__WEBPACK_IMPORTED_MODULE_1__["default"], _getSymbolsIn_js__WEBPACK_IMPORTED_MODULE_2__["default"]);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getAllKeysIn);

/***/ }),

/***/ 59333:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_getMapData.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isKeyable_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_isKeyable.js */ 27848);


/**
 * Gets the data for `map`.
 *
 * @private
 * @param {Object} map The map to query.
 * @param {string} key The reference key.
 * @returns {*} Returns the map data.
 */
function getMapData(map, key) {
  var data = map.__data__;
  return (0,_isKeyable_js__WEBPACK_IMPORTED_MODULE_0__["default"])(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getMapData);

/***/ }),

/***/ 74740:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_getNative.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseIsNative_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseIsNative.js */ 46069);
/* harmony import */ var _getValue_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getValue.js */ 18606);



/**
 * Gets the native function at `key` of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {string} key The key of the method to get.
 * @returns {*} Returns the function if it's native, else `undefined`.
 */
function getNative(object, key) {
  var value = (0,_getValue_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object, key);
  return (0,_baseIsNative_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) ? value : undefined;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getNative);

/***/ }),

/***/ 32549:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_getPrototype.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _overArg_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_overArg.js */ 69093);


/** Built-in value references. */
var getPrototype = (0,_overArg_js__WEBPACK_IMPORTED_MODULE_0__["default"])(Object.getPrototypeOf, Object);
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getPrototype);

/***/ }),

/***/ 96133:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_getRawTag.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Symbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_Symbol.js */ 9091);


/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString = objectProto.toString;

/** Built-in value references. */
var symToStringTag = _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"] ? _Symbol_js__WEBPACK_IMPORTED_MODULE_0__["default"].toStringTag : undefined;

/**
 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the raw `toStringTag`.
 */
function getRawTag(value) {
  var isOwn = hasOwnProperty.call(value, symToStringTag),
    tag = value[symToStringTag];
  try {
    value[symToStringTag] = undefined;
    var unmasked = true;
  } catch (e) {}
  var result = nativeObjectToString.call(value);
  if (unmasked) {
    if (isOwn) {
      value[symToStringTag] = tag;
    } else {
      delete value[symToStringTag];
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getRawTag);

/***/ }),

/***/ 27482:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_getSymbols.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_arrayFilter.js */ 84948);
/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./stubArray.js */ 71971);



/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Built-in value references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols = Object.getOwnPropertySymbols;

/**
 * Creates an array of the own enumerable symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of symbols.
 */
var getSymbols = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__["default"] : function (object) {
  if (object == null) {
    return [];
  }
  object = Object(object);
  return (0,_arrayFilter_js__WEBPACK_IMPORTED_MODULE_1__["default"])(nativeGetSymbols(object), function (symbol) {
    return propertyIsEnumerable.call(object, symbol);
  });
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbols);

/***/ }),

/***/ 89309:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_getSymbolsIn.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _arrayPush_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_arrayPush.js */ 59126);
/* harmony import */ var _getPrototype_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_getPrototype.js */ 32549);
/* harmony import */ var _getSymbols_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_getSymbols.js */ 27482);
/* harmony import */ var _stubArray_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./stubArray.js */ 71971);





/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeGetSymbols = Object.getOwnPropertySymbols;

/**
 * Creates an array of the own and inherited enumerable symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of symbols.
 */
var getSymbolsIn = !nativeGetSymbols ? _stubArray_js__WEBPACK_IMPORTED_MODULE_0__["default"] : function (object) {
  var result = [];
  while (object) {
    (0,_arrayPush_js__WEBPACK_IMPORTED_MODULE_1__["default"])(result, (0,_getSymbols_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object));
    object = (0,_getPrototype_js__WEBPACK_IMPORTED_MODULE_3__["default"])(object);
  }
  return result;
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getSymbolsIn);

/***/ }),

/***/ 11139:
/*!*******************************************!*\
  !*** ./node_modules/lodash-es/_getTag.js ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _DataView_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_DataView.js */ 60794);
/* harmony import */ var _Map_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_Map.js */ 55297);
/* harmony import */ var _Promise_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_Promise.js */ 49973);
/* harmony import */ var _Set_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_Set.js */ 50679);
/* harmony import */ var _WeakMap_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./_WeakMap.js */ 18569);
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _toSource_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_toSource.js */ 16275);








/** `Object#toString` result references. */
var mapTag = '[object Map]',
  objectTag = '[object Object]',
  promiseTag = '[object Promise]',
  setTag = '[object Set]',
  weakMapTag = '[object WeakMap]';
var dataViewTag = '[object DataView]';

/** Used to detect maps, sets, and weakmaps. */
var dataViewCtorString = (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_DataView_js__WEBPACK_IMPORTED_MODULE_1__["default"]),
  mapCtorString = (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_Map_js__WEBPACK_IMPORTED_MODULE_2__["default"]),
  promiseCtorString = (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_Promise_js__WEBPACK_IMPORTED_MODULE_3__["default"]),
  setCtorString = (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_Set_js__WEBPACK_IMPORTED_MODULE_4__["default"]),
  weakMapCtorString = (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(_WeakMap_js__WEBPACK_IMPORTED_MODULE_5__["default"]);

/**
 * Gets the `toStringTag` of `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */
var getTag = _baseGetTag_js__WEBPACK_IMPORTED_MODULE_6__["default"];

// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.
if (_DataView_js__WEBPACK_IMPORTED_MODULE_1__["default"] && getTag(new _DataView_js__WEBPACK_IMPORTED_MODULE_1__["default"](new ArrayBuffer(1))) != dataViewTag || _Map_js__WEBPACK_IMPORTED_MODULE_2__["default"] && getTag(new _Map_js__WEBPACK_IMPORTED_MODULE_2__["default"]()) != mapTag || _Promise_js__WEBPACK_IMPORTED_MODULE_3__["default"] && getTag(_Promise_js__WEBPACK_IMPORTED_MODULE_3__["default"].resolve()) != promiseTag || _Set_js__WEBPACK_IMPORTED_MODULE_4__["default"] && getTag(new _Set_js__WEBPACK_IMPORTED_MODULE_4__["default"]()) != setTag || _WeakMap_js__WEBPACK_IMPORTED_MODULE_5__["default"] && getTag(new _WeakMap_js__WEBPACK_IMPORTED_MODULE_5__["default"]()) != weakMapTag) {
  getTag = function (value) {
    var result = (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_6__["default"])(value),
      Ctor = result == objectTag ? value.constructor : undefined,
      ctorString = Ctor ? (0,_toSource_js__WEBPACK_IMPORTED_MODULE_0__["default"])(Ctor) : '';
    if (ctorString) {
      switch (ctorString) {
        case dataViewCtorString:
          return dataViewTag;
        case mapCtorString:
          return mapTag;
        case promiseCtorString:
          return promiseTag;
        case setCtorString:
          return setTag;
        case weakMapCtorString:
          return weakMapTag;
      }
    }
    return result;
  };
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getTag);

/***/ }),

/***/ 18606:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_getValue.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Gets the value at `key` of `object`.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {string} key The key of the property to get.
 * @returns {*} Returns the property value.
 */
function getValue(object, key) {
  return object == null ? undefined : object[key];
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (getValue);

/***/ }),

/***/ 18982:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_hashClear.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nativeCreate.js */ 97016);


/**
 * Removes all key-value entries from the hash.
 *
 * @private
 * @name clear
 * @memberOf Hash
 */
function hashClear() {
  this.__data__ = _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__["default"] ? (0,_nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__["default"])(null) : {};
  this.size = 0;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hashClear);

/***/ }),

/***/ 88624:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_hashDelete.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Removes `key` and its value from the hash.
 *
 * @private
 * @name delete
 * @memberOf Hash
 * @param {Object} hash The hash to modify.
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function hashDelete(key) {
  var result = this.has(key) && delete this.__data__[key];
  this.size -= result ? 1 : 0;
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hashDelete);

/***/ }),

/***/ 39059:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_hashGet.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nativeCreate.js */ 97016);


/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Gets the hash value for `key`.
 *
 * @private
 * @name get
 * @memberOf Hash
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function hashGet(key) {
  var data = this.__data__;
  if (_nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__["default"]) {
    var result = data[key];
    return result === HASH_UNDEFINED ? undefined : result;
  }
  return hasOwnProperty.call(data, key) ? data[key] : undefined;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hashGet);

/***/ }),

/***/ 32479:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_hashHas.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nativeCreate.js */ 97016);


/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Checks if a hash value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Hash
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function hashHas(key) {
  var data = this.__data__;
  return _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__["default"] ? data[key] !== undefined : hasOwnProperty.call(data, key);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hashHas);

/***/ }),

/***/ 48119:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_hashSet.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nativeCreate.js */ 97016);


/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';

/**
 * Sets the hash `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Hash
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the hash instance.
 */
function hashSet(key, value) {
  var data = this.__data__;
  this.size += this.has(key) ? 0 : 1;
  data[key] = _nativeCreate_js__WEBPACK_IMPORTED_MODULE_0__["default"] && value === undefined ? HASH_UNDEFINED : value;
  return this;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (hashSet);

/***/ }),

/***/ 15147:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_initCloneArray.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/**
 * Initializes an array clone.
 *
 * @private
 * @param {Array} array The array to clone.
 * @returns {Array} Returns the initialized clone.
 */
function initCloneArray(array) {
  var length = array.length,
    result = new array.constructor(length);

  // Add properties assigned by `RegExp#exec`.
  if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {
    result.index = array.index;
    result.input = array.input;
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (initCloneArray);

/***/ }),

/***/ 16941:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_initCloneByTag.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_cloneArrayBuffer.js */ 62279);
/* harmony import */ var _cloneDataView_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_cloneDataView.js */ 33823);
/* harmony import */ var _cloneRegExp_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./_cloneRegExp.js */ 52591);
/* harmony import */ var _cloneSymbol_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./_cloneSymbol.js */ 40610);
/* harmony import */ var _cloneTypedArray_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_cloneTypedArray.js */ 28295);






/** `Object#toString` result references. */
var boolTag = '[object Boolean]',
  dateTag = '[object Date]',
  mapTag = '[object Map]',
  numberTag = '[object Number]',
  regexpTag = '[object RegExp]',
  setTag = '[object Set]',
  stringTag = '[object String]',
  symbolTag = '[object Symbol]';
var arrayBufferTag = '[object ArrayBuffer]',
  dataViewTag = '[object DataView]',
  float32Tag = '[object Float32Array]',
  float64Tag = '[object Float64Array]',
  int8Tag = '[object Int8Array]',
  int16Tag = '[object Int16Array]',
  int32Tag = '[object Int32Array]',
  uint8Tag = '[object Uint8Array]',
  uint8ClampedTag = '[object Uint8ClampedArray]',
  uint16Tag = '[object Uint16Array]',
  uint32Tag = '[object Uint32Array]';

/**
 * Initializes an object clone based on its `toStringTag`.
 *
 * **Note:** This function only supports cloning values with tags of
 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
 *
 * @private
 * @param {Object} object The object to clone.
 * @param {string} tag The `toStringTag` of the object to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the initialized clone.
 */
function initCloneByTag(object, tag, isDeep) {
  var Ctor = object.constructor;
  switch (tag) {
    case arrayBufferTag:
      return (0,_cloneArrayBuffer_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object);
    case boolTag:
    case dateTag:
      return new Ctor(+object);
    case dataViewTag:
      return (0,_cloneDataView_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object, isDeep);
    case float32Tag:
    case float64Tag:
    case int8Tag:
    case int16Tag:
    case int32Tag:
    case uint8Tag:
    case uint8ClampedTag:
    case uint16Tag:
    case uint32Tag:
      return (0,_cloneTypedArray_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object, isDeep);
    case mapTag:
      return new Ctor();
    case numberTag:
    case stringTag:
      return new Ctor(object);
    case regexpTag:
      return (0,_cloneRegExp_js__WEBPACK_IMPORTED_MODULE_3__["default"])(object);
    case setTag:
      return new Ctor();
    case symbolTag:
      return (0,_cloneSymbol_js__WEBPACK_IMPORTED_MODULE_4__["default"])(object);
  }
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (initCloneByTag);

/***/ }),

/***/ 13195:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_initCloneObject.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseCreate_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseCreate.js */ 49934);
/* harmony import */ var _getPrototype_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_getPrototype.js */ 32549);
/* harmony import */ var _isPrototype_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_isPrototype.js */ 29641);




/**
 * Initializes an object clone.
 *
 * @private
 * @param {Object} object The object to clone.
 * @returns {Object} Returns the initialized clone.
 */
function initCloneObject(object) {
  return typeof object.constructor == 'function' && !(0,_isPrototype_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object) ? (0,_baseCreate_js__WEBPACK_IMPORTED_MODULE_1__["default"])((0,_getPrototype_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object)) : {};
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (initCloneObject);

/***/ }),

/***/ 60123:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_isIndex.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;

/** Used to detect unsigned integer values. */
var reIsUint = /^(?:0|[1-9]\d*)$/;

/**
 * Checks if `value` is a valid array-like index.
 *
 * @private
 * @param {*} value The value to check.
 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
 */
function isIndex(value, length) {
  var type = typeof value;
  length = length == null ? MAX_SAFE_INTEGER : length;
  return !!length && (type == 'number' || type != 'symbol' && reIsUint.test(value)) && value > -1 && value % 1 == 0 && value < length;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isIndex);

/***/ }),

/***/ 27848:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/_isKeyable.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Checks if `value` is suitable for use as unique object key.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
 */
function isKeyable(value) {
  var type = typeof value;
  return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isKeyable);

/***/ }),

/***/ 56498:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_isMasked.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _coreJsData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_coreJsData.js */ 53251);


/** Used to detect methods masquerading as native. */
var maskSrcKey = function () {
  var uid = /[^.]+$/.exec(_coreJsData_js__WEBPACK_IMPORTED_MODULE_0__["default"] && _coreJsData_js__WEBPACK_IMPORTED_MODULE_0__["default"].keys && _coreJsData_js__WEBPACK_IMPORTED_MODULE_0__["default"].keys.IE_PROTO || '');
  return uid ? 'Symbol(src)_1.' + uid : '';
}();

/**
 * Checks if `func` has its source masked.
 *
 * @private
 * @param {Function} func The function to check.
 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
 */
function isMasked(func) {
  return !!maskSrcKey && maskSrcKey in func;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isMasked);

/***/ }),

/***/ 29641:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_isPrototype.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Checks if `value` is likely a prototype object.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
 */
function isPrototype(value) {
  var Ctor = value && value.constructor,
    proto = typeof Ctor == 'function' && Ctor.prototype || objectProto;
  return value === proto;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isPrototype);

/***/ }),

/***/ 55272:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_listCacheClear.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Removes all key-value entries from the list cache.
 *
 * @private
 * @name clear
 * @memberOf ListCache
 */
function listCacheClear() {
  this.__data__ = [];
  this.size = 0;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (listCacheClear);

/***/ }),

/***/ 4958:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_listCacheDelete.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_assocIndexOf.js */ 23491);


/** Used for built-in method references. */
var arrayProto = Array.prototype;

/** Built-in value references. */
var splice = arrayProto.splice;

/**
 * Removes `key` and its value from the list cache.
 *
 * @private
 * @name delete
 * @memberOf ListCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function listCacheDelete(key) {
  var data = this.__data__,
    index = (0,_assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__["default"])(data, key);
  if (index < 0) {
    return false;
  }
  var lastIndex = data.length - 1;
  if (index == lastIndex) {
    data.pop();
  } else {
    splice.call(data, index, 1);
  }
  --this.size;
  return true;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (listCacheDelete);

/***/ }),

/***/ 70729:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_listCacheGet.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_assocIndexOf.js */ 23491);


/**
 * Gets the list cache value for `key`.
 *
 * @private
 * @name get
 * @memberOf ListCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function listCacheGet(key) {
  var data = this.__data__,
    index = (0,_assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__["default"])(data, key);
  return index < 0 ? undefined : data[index][1];
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (listCacheGet);

/***/ }),

/***/ 40773:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_listCacheHas.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_assocIndexOf.js */ 23491);


/**
 * Checks if a list cache value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf ListCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function listCacheHas(key) {
  return (0,_assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this.__data__, key) > -1;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (listCacheHas);

/***/ }),

/***/ 1901:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_listCacheSet.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_assocIndexOf.js */ 23491);


/**
 * Sets the list cache `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf ListCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the list cache instance.
 */
function listCacheSet(key, value) {
  var data = this.__data__,
    index = (0,_assocIndexOf_js__WEBPACK_IMPORTED_MODULE_0__["default"])(data, key);
  if (index < 0) {
    ++this.size;
    data.push([key, value]);
  } else {
    data[index][1] = value;
  }
  return this;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (listCacheSet);

/***/ }),

/***/ 33578:
/*!**************************************************!*\
  !*** ./node_modules/lodash-es/_mapCacheClear.js ***!
  \**************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _Hash_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_Hash.js */ 69279);
/* harmony import */ var _ListCache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_ListCache.js */ 30213);
/* harmony import */ var _Map_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_Map.js */ 55297);




/**
 * Removes all key-value entries from the map.
 *
 * @private
 * @name clear
 * @memberOf MapCache
 */
function mapCacheClear() {
  this.size = 0;
  this.__data__ = {
    'hash': new _Hash_js__WEBPACK_IMPORTED_MODULE_0__["default"](),
    'map': new (_Map_js__WEBPACK_IMPORTED_MODULE_1__["default"] || _ListCache_js__WEBPACK_IMPORTED_MODULE_2__["default"])(),
    'string': new _Hash_js__WEBPACK_IMPORTED_MODULE_0__["default"]()
  };
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (mapCacheClear);

/***/ }),

/***/ 23948:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_mapCacheDelete.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getMapData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getMapData.js */ 59333);


/**
 * Removes `key` and its value from the map.
 *
 * @private
 * @name delete
 * @memberOf MapCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function mapCacheDelete(key) {
  var result = (0,_getMapData_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, key)['delete'](key);
  this.size -= result ? 1 : 0;
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (mapCacheDelete);

/***/ }),

/***/ 47423:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_mapCacheGet.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getMapData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getMapData.js */ 59333);


/**
 * Gets the map value for `key`.
 *
 * @private
 * @name get
 * @memberOf MapCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function mapCacheGet(key) {
  return (0,_getMapData_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, key).get(key);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (mapCacheGet);

/***/ }),

/***/ 98019:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_mapCacheHas.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getMapData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getMapData.js */ 59333);


/**
 * Checks if a map value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf MapCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function mapCacheHas(key) {
  return (0,_getMapData_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, key).has(key);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (mapCacheHas);

/***/ }),

/***/ 955:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_mapCacheSet.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getMapData_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getMapData.js */ 59333);


/**
 * Sets the map `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf MapCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the map cache instance.
 */
function mapCacheSet(key, value) {
  var data = (0,_getMapData_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this, key),
    size = data.size;
  data.set(key, value);
  this.size += data.size == size ? 0 : 1;
  return this;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (mapCacheSet);

/***/ }),

/***/ 97016:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_nativeCreate.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _getNative_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_getNative.js */ 74740);


/* Built-in method references that are verified to be native. */
var nativeCreate = (0,_getNative_js__WEBPACK_IMPORTED_MODULE_0__["default"])(Object, 'create');
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (nativeCreate);

/***/ }),

/***/ 25920:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_nativeKeys.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _overArg_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_overArg.js */ 69093);


/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeKeys = (0,_overArg_js__WEBPACK_IMPORTED_MODULE_0__["default"])(Object.keys, Object);
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (nativeKeys);

/***/ }),

/***/ 94767:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/_nativeKeysIn.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * This function is like
 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * except that it includes inherited enumerable properties.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */
function nativeKeysIn(object) {
  var result = [];
  if (object != null) {
    for (var key in Object(object)) {
      result.push(key);
    }
  }
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (nativeKeysIn);

/***/ }),

/***/ 64695:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_nodeUtil.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_freeGlobal.js */ 59210);


/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;

/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;

/** Detect free variable `process` from Node.js. */
var freeProcess = moduleExports && _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__["default"].process;

/** Used to access faster Node.js helpers. */
var nodeUtil = function () {
  try {
    // Use `util.types` for Node.js 10+.
    var types = freeModule && freeModule.require && freeModule.require('util').types;
    if (types) {
      return types;
    }

    // Legacy `process.binding('util')` for Node.js < 10.
    return freeProcess && freeProcess.binding && freeProcess.binding('util');
  } catch (e) {}
}();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (nodeUtil);

/***/ }),

/***/ 92880:
/*!***************************************************!*\
  !*** ./node_modules/lodash-es/_objectToString.js ***!
  \***************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used for built-in method references. */
var objectProto = Object.prototype;

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */
var nativeObjectToString = objectProto.toString;

/**
 * Converts `value` to a string using `Object.prototype.toString`.
 *
 * @private
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 */
function objectToString(value) {
  return nativeObjectToString.call(value);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (objectToString);

/***/ }),

/***/ 69093:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/_overArg.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Creates a unary function that invokes `func` with its argument transformed.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {Function} transform The argument transform.
 * @returns {Function} Returns the new function.
 */
function overArg(func, transform) {
  return function (arg) {
    return func(transform(arg));
  };
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (overArg);

/***/ }),

/***/ 911:
/*!*****************************************!*\
  !*** ./node_modules/lodash-es/_root.js ***!
  \*****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_freeGlobal.js */ 59210);


/** Detect free variable `self`. */
var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

/** Used as a reference to the global object. */
var root = _freeGlobal_js__WEBPACK_IMPORTED_MODULE_0__["default"] || freeSelf || Function('return this')();
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (root);

/***/ }),

/***/ 48686:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/_stackClear.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ListCache_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_ListCache.js */ 30213);


/**
 * Removes all key-value entries from the stack.
 *
 * @private
 * @name clear
 * @memberOf Stack
 */
function stackClear() {
  this.__data__ = new _ListCache_js__WEBPACK_IMPORTED_MODULE_0__["default"]();
  this.size = 0;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stackClear);

/***/ }),

/***/ 54504:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/_stackDelete.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Removes `key` and its value from the stack.
 *
 * @private
 * @name delete
 * @memberOf Stack
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */
function stackDelete(key) {
  var data = this.__data__,
    result = data['delete'](key);
  this.size = data.size;
  return result;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stackDelete);

/***/ }),

/***/ 84331:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_stackGet.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Gets the stack value for `key`.
 *
 * @private
 * @name get
 * @memberOf Stack
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */
function stackGet(key) {
  return this.__data__.get(key);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stackGet);

/***/ }),

/***/ 16391:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_stackHas.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Checks if a stack value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Stack
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */
function stackHas(key) {
  return this.__data__.has(key);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stackHas);

/***/ }),

/***/ 97039:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_stackSet.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _ListCache_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_ListCache.js */ 30213);
/* harmony import */ var _Map_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_Map.js */ 55297);
/* harmony import */ var _MapCache_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_MapCache.js */ 7531);




/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;

/**
 * Sets the stack `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Stack
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the stack cache instance.
 */
function stackSet(key, value) {
  var data = this.__data__;
  if (data instanceof _ListCache_js__WEBPACK_IMPORTED_MODULE_0__["default"]) {
    var pairs = data.__data__;
    if (!_Map_js__WEBPACK_IMPORTED_MODULE_1__["default"] || pairs.length < LARGE_ARRAY_SIZE - 1) {
      pairs.push([key, value]);
      this.size = ++data.size;
      return this;
    }
    data = this.__data__ = new _MapCache_js__WEBPACK_IMPORTED_MODULE_2__["default"](pairs);
  }
  data.set(key, value);
  this.size = data.size;
  return this;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stackSet);

/***/ }),

/***/ 16275:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/_toSource.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used for built-in method references. */
var funcProto = Function.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/**
 * Converts `func` to its source code.
 *
 * @private
 * @param {Function} func The function to convert.
 * @returns {string} Returns the source code.
 */
function toSource(func) {
  if (func != null) {
    try {
      return funcToString.call(func);
    } catch (e) {}
    try {
      return func + '';
    } catch (e) {}
  }
  return '';
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toSource);

/***/ }),

/***/ 59782:
/*!****************************************************!*\
  !*** ./node_modules/lodash-es/_trimmedEndIndex.js ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used to match a single whitespace character. */
var reWhitespace = /\s/;

/**
 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 * character of `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the index of the last non-whitespace character.
 */
function trimmedEndIndex(string) {
  var index = string.length;
  while (index-- && reWhitespace.test(string.charAt(index))) {}
  return index;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (trimmedEndIndex);

/***/ }),

/***/ 60105:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/cloneDeepWith.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseClone_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_baseClone.js */ 95365);


/** Used to compose bitmasks for cloning. */
var CLONE_DEEP_FLAG = 1,
  CLONE_SYMBOLS_FLAG = 4;

/**
 * This method is like `_.cloneWith` except that it recursively clones `value`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to recursively clone.
 * @param {Function} [customizer] The function to customize cloning.
 * @returns {*} Returns the deep cloned value.
 * @see _.cloneWith
 * @example
 *
 * function customizer(value) {
 *   if (_.isElement(value)) {
 *     return value.cloneNode(true);
 *   }
 * }
 *
 * var el = _.cloneDeepWith(document.body, customizer);
 *
 * console.log(el === document.body);
 * // => false
 * console.log(el.nodeName);
 * // => 'BODY'
 * console.log(el.childNodes.length);
 * // => 20
 */
function cloneDeepWith(value, customizer) {
  customizer = typeof customizer == 'function' ? customizer : undefined;
  return (0,_baseClone_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, customizer);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (cloneDeepWith);

/***/ }),

/***/ 50763:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/debounce.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isObject.js */ 23151);
/* harmony import */ var _now_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./now.js */ 55170);
/* harmony import */ var _toNumber_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./toNumber.js */ 90820);




/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeMax = Math.max,
  nativeMin = Math.min;

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */
function debounce(func, wait, options) {
  var lastArgs,
    lastThis,
    maxWait,
    result,
    timerId,
    lastCallTime,
    lastInvokeTime = 0,
    leading = false,
    maxing = false,
    trailing = true;
  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  wait = (0,_toNumber_js__WEBPACK_IMPORTED_MODULE_0__["default"])(wait) || 0;
  if ((0,_isObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(options)) {
    leading = !!options.leading;
    maxing = 'maxWait' in options;
    maxWait = maxing ? nativeMax((0,_toNumber_js__WEBPACK_IMPORTED_MODULE_0__["default"])(options.maxWait) || 0, wait) : maxWait;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }
  function invokeFunc(time) {
    var args = lastArgs,
      thisArg = lastThis;
    lastArgs = lastThis = undefined;
    lastInvokeTime = time;
    result = func.apply(thisArg, args);
    return result;
  }
  function leadingEdge(time) {
    // Reset any `maxWait` timer.
    lastInvokeTime = time;
    // Start the timer for the trailing edge.
    timerId = setTimeout(timerExpired, wait);
    // Invoke the leading edge.
    return leading ? invokeFunc(time) : result;
  }
  function remainingWait(time) {
    var timeSinceLastCall = time - lastCallTime,
      timeSinceLastInvoke = time - lastInvokeTime,
      timeWaiting = wait - timeSinceLastCall;
    return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting;
  }
  function shouldInvoke(time) {
    var timeSinceLastCall = time - lastCallTime,
      timeSinceLastInvoke = time - lastInvokeTime;

    // Either this is the first call, activity has stopped and we're at the
    // trailing edge, the system time has gone backwards and we're treating
    // it as the trailing edge, or we've hit the `maxWait` limit.
    return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait;
  }
  function timerExpired() {
    var time = (0,_now_js__WEBPACK_IMPORTED_MODULE_2__["default"])();
    if (shouldInvoke(time)) {
      return trailingEdge(time);
    }
    // Restart the timer.
    timerId = setTimeout(timerExpired, remainingWait(time));
  }
  function trailingEdge(time) {
    timerId = undefined;

    // Only invoke if we have `lastArgs` which means `func` has been
    // debounced at least once.
    if (trailing && lastArgs) {
      return invokeFunc(time);
    }
    lastArgs = lastThis = undefined;
    return result;
  }
  function cancel() {
    if (timerId !== undefined) {
      clearTimeout(timerId);
    }
    lastInvokeTime = 0;
    lastArgs = lastCallTime = lastThis = timerId = undefined;
  }
  function flush() {
    return timerId === undefined ? result : trailingEdge((0,_now_js__WEBPACK_IMPORTED_MODULE_2__["default"])());
  }
  function debounced() {
    var time = (0,_now_js__WEBPACK_IMPORTED_MODULE_2__["default"])(),
      isInvoking = shouldInvoke(time);
    lastArgs = arguments;
    lastThis = this;
    lastCallTime = time;
    if (isInvoking) {
      if (timerId === undefined) {
        return leadingEdge(lastCallTime);
      }
      if (maxing) {
        // Handle invocations in a tight loop.
        clearTimeout(timerId);
        timerId = setTimeout(timerExpired, wait);
        return invokeFunc(lastCallTime);
      }
    }
    if (timerId === undefined) {
      timerId = setTimeout(timerExpired, wait);
    }
    return result;
  }
  debounced.cancel = cancel;
  debounced.flush = flush;
  return debounced;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (debounce);

/***/ }),

/***/ 97622:
/*!**************************************!*\
  !*** ./node_modules/lodash-es/eq.js ***!
  \**************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Performs a
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * comparison between two values to determine if they are equivalent.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 * @example
 *
 * var object = { 'a': 1 };
 * var other = { 'a': 1 };
 *
 * _.eq(object, object);
 * // => true
 *
 * _.eq(object, other);
 * // => false
 *
 * _.eq('a', 'a');
 * // => true
 *
 * _.eq('a', Object('a'));
 * // => false
 *
 * _.eq(NaN, NaN);
 * // => true
 */
function eq(value, other) {
  return value === other || value !== value && other !== other;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (eq);

/***/ }),

/***/ 38826:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/isArguments.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseIsArguments_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_baseIsArguments.js */ 1244);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);



/** Used for built-in method references. */
var objectProto = Object.prototype;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Built-in value references. */
var propertyIsEnumerable = objectProto.propertyIsEnumerable;

/**
 * Checks if `value` is likely an `arguments` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
 *  else `false`.
 * @example
 *
 * _.isArguments(function() { return arguments; }());
 * // => true
 *
 * _.isArguments([1, 2, 3]);
 * // => false
 */
var isArguments = (0,_baseIsArguments_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function () {
  return arguments;
}()) ? _baseIsArguments_js__WEBPACK_IMPORTED_MODULE_0__["default"] : function (value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) && hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee');
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isArguments);

/***/ }),

/***/ 19247:
/*!*******************************************!*\
  !*** ./node_modules/lodash-es/isArray.js ***!
  \*******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */
var isArray = Array.isArray;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isArray);

/***/ }),

/***/ 38200:
/*!***********************************************!*\
  !*** ./node_modules/lodash-es/isArrayLike.js ***!
  \***********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isFunction_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isFunction.js */ 68104);
/* harmony import */ var _isLength_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isLength.js */ 26872);



/**
 * Checks if `value` is array-like. A value is considered array-like if it's
 * not a function and has a `value.length` that's an integer greater than or
 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
 * @example
 *
 * _.isArrayLike([1, 2, 3]);
 * // => true
 *
 * _.isArrayLike(document.body.children);
 * // => true
 *
 * _.isArrayLike('abc');
 * // => true
 *
 * _.isArrayLike(_.noop);
 * // => false
 */
function isArrayLike(value) {
  return value != null && (0,_isLength_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value.length) && !(0,_isFunction_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isArrayLike);

/***/ }),

/***/ 47618:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/isBuffer.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);
/* harmony import */ var _stubFalse_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./stubFalse.js */ 59793);



/** Detect free variable `exports`. */
var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;

/** Detect free variable `module`. */
var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;

/** Detect the popular CommonJS extension `module.exports`. */
var moduleExports = freeModule && freeModule.exports === freeExports;

/** Built-in value references. */
var Buffer = moduleExports ? _root_js__WEBPACK_IMPORTED_MODULE_0__["default"].Buffer : undefined;

/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined;

/**
 * Checks if `value` is a buffer.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.
 * @example
 *
 * _.isBuffer(new Buffer(2));
 * // => true
 *
 * _.isBuffer(new Uint8Array(2));
 * // => false
 */
var isBuffer = nativeIsBuffer || _stubFalse_js__WEBPACK_IMPORTED_MODULE_1__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isBuffer);

/***/ }),

/***/ 4134:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/isElement.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);
/* harmony import */ var _isPlainObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isPlainObject.js */ 20317);



/**
 * Checks if `value` is likely a DOM element.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`.
 * @example
 *
 * _.isElement(document.body);
 * // => true
 *
 * _.isElement('<body>');
 * // => false
 */
function isElement(value) {
  return (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && value.nodeType === 1 && !(0,_isPlainObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isElement);

/***/ }),

/***/ 68104:
/*!**********************************************!*\
  !*** ./node_modules/lodash-es/isFunction.js ***!
  \**********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);



/** `Object#toString` result references. */
var asyncTag = '[object AsyncFunction]',
  funcTag = '[object Function]',
  genTag = '[object GeneratorFunction]',
  proxyTag = '[object Proxy]';

/**
 * Checks if `value` is classified as a `Function` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
 * @example
 *
 * _.isFunction(_);
 * // => true
 *
 * _.isFunction(/abc/);
 * // => false
 */
function isFunction(value) {
  if (!(0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value)) {
    return false;
  }
  // The use of `Object#toString` avoids issues with the `typeof` operator
  // in Safari 9 which returns 'object' for typed arrays and other constructors.
  var tag = (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value);
  return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isFunction);

/***/ }),

/***/ 26872:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/isLength.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/** Used as references for various `Number` constants. */
var MAX_SAFE_INTEGER = 9007199254740991;

/**
 * Checks if `value` is a valid array-like length.
 *
 * **Note:** This method is loosely based on
 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
 * @example
 *
 * _.isLength(3);
 * // => true
 *
 * _.isLength(Number.MIN_VALUE);
 * // => false
 *
 * _.isLength(Infinity);
 * // => false
 *
 * _.isLength('3');
 * // => false
 */
function isLength(value) {
  return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isLength);

/***/ }),

/***/ 43144:
/*!*****************************************!*\
  !*** ./node_modules/lodash-es/isMap.js ***!
  \*****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseIsMap_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseIsMap.js */ 99842);
/* harmony import */ var _baseUnary_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseUnary.js */ 45583);
/* harmony import */ var _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nodeUtil.js */ 64695);




/* Node.js helper references. */
var nodeIsMap = _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"] && _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"].isMap;

/**
 * Checks if `value` is classified as a `Map` object.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
 * @example
 *
 * _.isMap(new Map);
 * // => true
 *
 * _.isMap(new WeakMap);
 * // => false
 */
var isMap = nodeIsMap ? (0,_baseUnary_js__WEBPACK_IMPORTED_MODULE_1__["default"])(nodeIsMap) : _baseIsMap_js__WEBPACK_IMPORTED_MODULE_2__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isMap);

/***/ }),

/***/ 23151:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/isObject.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */
function isObject(value) {
  var type = typeof value;
  return value != null && (type == 'object' || type == 'function');
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isObject);

/***/ }),

/***/ 85528:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/isObjectLike.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */
function isObjectLike(value) {
  return value != null && typeof value == 'object';
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isObjectLike);

/***/ }),

/***/ 20317:
/*!*************************************************!*\
  !*** ./node_modules/lodash-es/isPlainObject.js ***!
  \*************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _getPrototype_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_getPrototype.js */ 32549);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);




/** `Object#toString` result references. */
var objectTag = '[object Object]';

/** Used for built-in method references. */
var funcProto = Function.prototype,
  objectProto = Object.prototype;

/** Used to resolve the decompiled source of functions. */
var funcToString = funcProto.toString;

/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;

/** Used to infer the `Object` constructor. */
var objectCtorString = funcToString.call(Object);

/**
 * Checks if `value` is a plain object, that is, an object created by the
 * `Object` constructor or one with a `[[Prototype]]` of `null`.
 *
 * @static
 * @memberOf _
 * @since 0.8.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 * }
 *
 * _.isPlainObject(new Foo);
 * // => false
 *
 * _.isPlainObject([1, 2, 3]);
 * // => false
 *
 * _.isPlainObject({ 'x': 0, 'y': 0 });
 * // => true
 *
 * _.isPlainObject(Object.create(null));
 * // => true
 */
function isPlainObject(value) {
  if (!(0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) || (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) != objectTag) {
    return false;
  }
  var proto = (0,_getPrototype_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value);
  if (proto === null) {
    return true;
  }
  var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor;
  return typeof Ctor == 'function' && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isPlainObject);

/***/ }),

/***/ 11186:
/*!*****************************************!*\
  !*** ./node_modules/lodash-es/isSet.js ***!
  \*****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseIsSet_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseIsSet.js */ 78392);
/* harmony import */ var _baseUnary_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseUnary.js */ 45583);
/* harmony import */ var _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nodeUtil.js */ 64695);




/* Node.js helper references. */
var nodeIsSet = _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"] && _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"].isSet;

/**
 * Checks if `value` is classified as a `Set` object.
 *
 * @static
 * @memberOf _
 * @since 4.3.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
 * @example
 *
 * _.isSet(new Set);
 * // => true
 *
 * _.isSet(new WeakSet);
 * // => false
 */
var isSet = nodeIsSet ? (0,_baseUnary_js__WEBPACK_IMPORTED_MODULE_1__["default"])(nodeIsSet) : _baseIsSet_js__WEBPACK_IMPORTED_MODULE_2__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSet);

/***/ }),

/***/ 31200:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/isSymbol.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseGetTag.js */ 14478);
/* harmony import */ var _isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObjectLike.js */ 85528);



/** `Object#toString` result references. */
var symbolTag = '[object Symbol]';

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */
function isSymbol(value) {
  return typeof value == 'symbol' || (0,_isObjectLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value) && (0,_baseGetTag_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value) == symbolTag;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isSymbol);

/***/ }),

/***/ 18449:
/*!************************************************!*\
  !*** ./node_modules/lodash-es/isTypedArray.js ***!
  \************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseIsTypedArray_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseIsTypedArray.js */ 39423);
/* harmony import */ var _baseUnary_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_baseUnary.js */ 45583);
/* harmony import */ var _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_nodeUtil.js */ 64695);




/* Node.js helper references. */
var nodeIsTypedArray = _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"] && _nodeUtil_js__WEBPACK_IMPORTED_MODULE_0__["default"].isTypedArray;

/**
 * Checks if `value` is classified as a typed array.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
 * @example
 *
 * _.isTypedArray(new Uint8Array);
 * // => true
 *
 * _.isTypedArray([]);
 * // => false
 */
var isTypedArray = nodeIsTypedArray ? (0,_baseUnary_js__WEBPACK_IMPORTED_MODULE_1__["default"])(nodeIsTypedArray) : _baseIsTypedArray_js__WEBPACK_IMPORTED_MODULE_2__["default"];
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (isTypedArray);

/***/ }),

/***/ 29892:
/*!****************************************!*\
  !*** ./node_modules/lodash-es/keys.js ***!
  \****************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_arrayLikeKeys.js */ 58165);
/* harmony import */ var _baseKeys_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseKeys.js */ 43934);
/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isArrayLike.js */ 38200);




/**
 * Creates an array of the own enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects. See the
 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * for more details.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keys(new Foo);
 * // => ['a', 'b'] (iteration order is not guaranteed)
 *
 * _.keys('hi');
 * // => ['0', '1']
 */
function keys(object) {
  return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object) : (0,_baseKeys_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keys);

/***/ }),

/***/ 75243:
/*!******************************************!*\
  !*** ./node_modules/lodash-es/keysIn.js ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./_arrayLikeKeys.js */ 58165);
/* harmony import */ var _baseKeysIn_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseKeysIn.js */ 97225);
/* harmony import */ var _isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isArrayLike.js */ 38200);




/**
 * Creates an array of the own and inherited enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keysIn(new Foo);
 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
 */
function keysIn(object) {
  return (0,_isArrayLike_js__WEBPACK_IMPORTED_MODULE_0__["default"])(object) ? (0,_arrayLikeKeys_js__WEBPACK_IMPORTED_MODULE_1__["default"])(object, true) : (0,_baseKeysIn_js__WEBPACK_IMPORTED_MODULE_2__["default"])(object);
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (keysIn);

/***/ }),

/***/ 55170:
/*!***************************************!*\
  !*** ./node_modules/lodash-es/now.js ***!
  \***************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _root_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./_root.js */ 911);


/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */
var now = function () {
  return _root_js__WEBPACK_IMPORTED_MODULE_0__["default"].Date.now();
};
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (now);

/***/ }),

/***/ 71971:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/stubArray.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * This method returns a new empty array.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {Array} Returns the new empty array.
 * @example
 *
 * var arrays = _.times(2, _.stubArray);
 *
 * console.log(arrays);
 * // => [[], []]
 *
 * console.log(arrays[0] === arrays[1]);
 * // => false
 */
function stubArray() {
  return [];
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubArray);

/***/ }),

/***/ 59793:
/*!*********************************************!*\
  !*** ./node_modules/lodash-es/stubFalse.js ***!
  \*********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/**
 * This method returns `false`.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {boolean} Returns `false`.
 * @example
 *
 * _.times(2, _.stubFalse);
 * // => [false, false]
 */
function stubFalse() {
  return false;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (stubFalse);

/***/ }),

/***/ 57156:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/throttle.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _debounce_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./debounce.js */ 50763);
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isObject.js */ 23151);



/** Error message constants. */
var FUNC_ERROR_TEXT = 'Expected a function';

/**
 * Creates a throttled function that only invokes `func` at most once per
 * every `wait` milliseconds. The throttled function comes with a `cancel`
 * method to cancel delayed `func` invocations and a `flush` method to
 * immediately invoke them. Provide `options` to indicate whether `func`
 * should be invoked on the leading and/or trailing edge of the `wait`
 * timeout. The `func` is invoked with the last arguments provided to the
 * throttled function. Subsequent calls to the throttled function return the
 * result of the last `func` invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the throttled function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.throttle` and `_.debounce`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to throttle.
 * @param {number} [wait=0] The number of milliseconds to throttle invocations to.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=true]
 *  Specify invoking on the leading edge of the timeout.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new throttled function.
 * @example
 *
 * // Avoid excessively updating the position while scrolling.
 * jQuery(window).on('scroll', _.throttle(updatePosition, 100));
 *
 * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.
 * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
 * jQuery(element).on('click', throttled);
 *
 * // Cancel the trailing throttled invocation.
 * jQuery(window).on('popstate', throttled.cancel);
 */
function throttle(func, wait, options) {
  var leading = true,
    trailing = true;
  if (typeof func != 'function') {
    throw new TypeError(FUNC_ERROR_TEXT);
  }
  if ((0,_isObject_js__WEBPACK_IMPORTED_MODULE_0__["default"])(options)) {
    leading = 'leading' in options ? !!options.leading : leading;
    trailing = 'trailing' in options ? !!options.trailing : trailing;
  }
  return (0,_debounce_js__WEBPACK_IMPORTED_MODULE_1__["default"])(func, wait, {
    'leading': leading,
    'maxWait': wait,
    'trailing': trailing
  });
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (throttle);

/***/ }),

/***/ 90820:
/*!********************************************!*\
  !*** ./node_modules/lodash-es/toNumber.js ***!
  \********************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var _baseTrim_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./_baseTrim.js */ 80106);
/* harmony import */ var _isObject_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./isObject.js */ 23151);
/* harmony import */ var _isSymbol_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./isSymbol.js */ 31200);




/** Used as references for various `Number` constants. */
var NAN = 0 / 0;

/** Used to detect bad signed hexadecimal string values. */
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

/** Used to detect binary string values. */
var reIsBinary = /^0b[01]+$/i;

/** Used to detect octal string values. */
var reIsOctal = /^0o[0-7]+$/i;

/** Built-in method references without a dependency on `root`. */
var freeParseInt = parseInt;

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */
function toNumber(value) {
  if (typeof value == 'number') {
    return value;
  }
  if ((0,_isSymbol_js__WEBPACK_IMPORTED_MODULE_0__["default"])(value)) {
    return NAN;
  }
  if ((0,_isObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(value)) {
    var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
    value = (0,_isObject_js__WEBPACK_IMPORTED_MODULE_1__["default"])(other) ? other + '' : other;
  }
  if (typeof value != 'string') {
    return value === 0 ? value : +value;
  }
  value = (0,_baseTrim_js__WEBPACK_IMPORTED_MODULE_2__["default"])(value);
  var isBinary = reIsBinary.test(value);
  return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
}
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (toNumber);

/***/ }),

/***/ 33117:
/*!***************************************************************!*\
  !*** ./node_modules/ng-apexcharts/fesm2022/ng-apexcharts.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ChartComponent: () => (/* binding */ ChartComponent),
/* harmony export */   NgApexchartsModule: () => (/* binding */ NgApexchartsModule)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! rxjs */ 67180);





const _c0 = ["chart"];
class ChartComponent {
  constructor() {
    this.chart = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.annotations = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.colors = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.dataLabels = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.series = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.stroke = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.labels = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.legend = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.markers = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.noData = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.parsing = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.fill = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.tooltip = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.plotOptions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.responsive = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.xaxis = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.yaxis = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.forecastDataPoints = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.grid = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.states = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.title = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.subtitle = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.theme = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)();
    this.autoUpdateSeries = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.input)(true);
    this.chartReady = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.output)();
    // If consumers need to capture the `chartInstance` for use, consumers
    // can access the component instance through `viewChild` and use `computed`
    // or `effect` on `component.chartInstance()` to monitor its changes and
    // recompute effects or computations whenever `chartInstance` is updated.
    this.chartInstance = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.signal)(null);
    this.chartElement = _angular_core__WEBPACK_IMPORTED_MODULE_1__.viewChild.required("chart");
    this.ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone);
    this.isBrowser = (0,_angular_common__WEBPACK_IMPORTED_MODULE_2__.isPlatformBrowser)((0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID));
  }
  ngOnChanges(changes) {
    if (!this.isBrowser) return;
    this.ngZone.runOutsideAngular(() => {
      rxjs__WEBPACK_IMPORTED_MODULE_3__.asapScheduler.schedule(() => this.hydrate(changes));
    });
  }
  ngOnDestroy() {
    this.destroy();
  }
  hydrate(changes) {
    const shouldUpdateSeries = this.autoUpdateSeries() && Object.keys(changes).filter(c => c !== "series").length === 0;
    if (shouldUpdateSeries) {
      this.updateSeries(this.series(), true);
      return;
    }
    this.createElement();
  }
  createElement() {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      const {
        default: ApexCharts
      } = yield __webpack_require__.e(/*! import() */ "node_modules_apexcharts_dist_apexcharts_common_js").then(__webpack_require__.t.bind(__webpack_require__, /*! apexcharts */ 31633, 19));
      window.ApexCharts ||= ApexCharts;
      const options = {};
      const properties = ["annotations", "chart", "colors", "dataLabels", "series", "stroke", "labels", "legend", "fill", "tooltip", "plotOptions", "responsive", "markers", "noData", "parsing", "xaxis", "yaxis", "forecastDataPoints", "grid", "states", "title", "subtitle", "theme"];
      properties.forEach(property => {
        const value = _this[property]();
        if (value) {
          options[property] = value;
        }
      });
      _this.destroy();
      const chartInstance = _this.ngZone.runOutsideAngular(() => new ApexCharts(_this.chartElement().nativeElement, options));
      _this.chartInstance.set(chartInstance);
      _this.render();
      _this.chartReady.emit({
        chartObj: chartInstance
      });
    })();
  }
  render() {
    return this.ngZone.runOutsideAngular(() => this.chartInstance()?.render());
  }
  updateOptions(options, redrawPaths, animate, updateSyncedCharts) {
    return this.ngZone.runOutsideAngular(() => this.chartInstance()?.updateOptions(options, redrawPaths, animate, updateSyncedCharts));
  }
  updateSeries(newSeries, animate) {
    return this.ngZone.runOutsideAngular(() => this.chartInstance()?.updateSeries(newSeries, animate));
  }
  appendSeries(newSeries, animate) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.appendSeries(newSeries, animate));
  }
  appendData(newData) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.appendData(newData));
  }
  highlightSeries(seriesName) {
    return this.ngZone.runOutsideAngular(() => this.chartInstance()?.highlightSeries(seriesName));
  }
  toggleSeries(seriesName) {
    return this.ngZone.runOutsideAngular(() => this.chartInstance()?.toggleSeries(seriesName));
  }
  showSeries(seriesName) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.showSeries(seriesName));
  }
  hideSeries(seriesName) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.hideSeries(seriesName));
  }
  resetSeries() {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.resetSeries());
  }
  zoomX(min, max) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.zoomX(min, max));
  }
  toggleDataPointSelection(seriesIndex, dataPointIndex) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.toggleDataPointSelection(seriesIndex, dataPointIndex));
  }
  destroy() {
    this.chartInstance()?.destroy();
    this.chartInstance.set(null);
  }
  setLocale(localeName) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.setLocale(localeName));
  }
  paper() {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.paper());
  }
  addXaxisAnnotation(options, pushToMemory, context) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.addXaxisAnnotation(options, pushToMemory, context));
  }
  addYaxisAnnotation(options, pushToMemory, context) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.addYaxisAnnotation(options, pushToMemory, context));
  }
  addPointAnnotation(options, pushToMemory, context) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.addPointAnnotation(options, pushToMemory, context));
  }
  removeAnnotation(id, options) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.removeAnnotation(id, options));
  }
  clearAnnotations(options) {
    this.ngZone.runOutsideAngular(() => this.chartInstance()?.clearAnnotations(options));
  }
  dataURI(options) {
    return this.chartInstance()?.dataURI(options);
  }
  /** @nocollapse */
  static {
    this.ɵfac = function ChartComponent_Factory(t) {
      return new (t || ChartComponent)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: ChartComponent,
      selectors: [["apx-chart"]],
      viewQuery: function ChartComponent_Query(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵviewQuerySignal"](ctx.chartElement, _c0, 5);
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵqueryAdvance"]();
        }
      },
      inputs: {
        chart: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "chart"],
        annotations: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "annotations"],
        colors: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "colors"],
        dataLabels: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "dataLabels"],
        series: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "series"],
        stroke: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "stroke"],
        labels: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "labels"],
        legend: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "legend"],
        markers: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "markers"],
        noData: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "noData"],
        parsing: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "parsing"],
        fill: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "fill"],
        tooltip: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "tooltip"],
        plotOptions: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "plotOptions"],
        responsive: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "responsive"],
        xaxis: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "xaxis"],
        yaxis: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "yaxis"],
        forecastDataPoints: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "forecastDataPoints"],
        grid: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "grid"],
        states: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "states"],
        title: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "title"],
        subtitle: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "subtitle"],
        theme: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "theme"],
        autoUpdateSeries: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].SignalBased, "autoUpdateSeries"]
      },
      outputs: {
        chartReady: "chartReady"
      },
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"], _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵStandaloneFeature"]],
      decls: 2,
      vars: 0,
      consts: [["chart", ""]],
      template: function ChartComponent_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](0, "div", null, 0);
        }
      },
      encapsulation: 2,
      changeDetection: 0
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](ChartComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: "apx-chart",
      template: `<div #chart></div>`,
      changeDetection: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ChangeDetectionStrategy.OnPush,
      standalone: true
    }]
  }], null, null);
})();
const declarations = [ChartComponent];
class NgApexchartsModule {
  /** @nocollapse */static {
    this.ɵfac = function NgApexchartsModule_Factory(t) {
      return new (t || NgApexchartsModule)();
    };
  }
  /** @nocollapse */
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: NgApexchartsModule
    });
  }
  /** @nocollapse */
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgApexchartsModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      imports: [declarations],
      exports: [declarations]
    }]
  }], null, null);
})();

/*
 * Public API Surface of ng-apexcharts
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 39213:
/*!*************************************************************************!*\
  !*** ./node_modules/ngx-cookie-service/fesm2022/ngx-cookie-service.mjs ***!
  \*************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CookieService: () => (/* binding */ CookieService)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/common */ 60316);




// This service is based on the `ng2-cookies` package which sadly is not a service and does
// not use `DOCUMENT` injection and therefore doesn't work well with AoT production builds.
// Package: https://github.com/BCJTI/ng2-cookies
class CookieService {
  constructor(document,
  // Get the `PLATFORM_ID` so we can check if we're in a browser.
  platformId) {
    this.document = document;
    this.platformId = platformId;
    this.documentIsAccessible = (0,_angular_common__WEBPACK_IMPORTED_MODULE_0__.isPlatformBrowser)(this.platformId);
  }
  /**
   * Get cookie Regular Expression
   *
   * @param name Cookie name
   * @returns property RegExp
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  static getCookieRegExp(name) {
    const escapedName = name.replace(/([\[\]{}()|=;+?,.*^$])/gi, '\\$1');
    return new RegExp('(?:^' + escapedName + '|;\\s*' + escapedName + ')=(.*?)(?:;|$)', 'g');
  }
  /**
   * Gets the unencoded version of an encoded component of a Uniform Resource Identifier (URI).
   *
   * @param encodedURIComponent A value representing an encoded URI component.
   *
   * @returns The unencoded version of an encoded component of a Uniform Resource Identifier (URI).
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  static safeDecodeURIComponent(encodedURIComponent) {
    try {
      return decodeURIComponent(encodedURIComponent);
    } catch {
      // probably it is not uri encoded. return as is
      return encodedURIComponent;
    }
  }
  /**
   * Return `true` if {@link Document} is accessible, otherwise return `false`
   *
   * @param name Cookie name
   * @returns boolean - whether cookie with specified name exists
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  check(name) {
    if (!this.documentIsAccessible) {
      return false;
    }
    name = encodeURIComponent(name);
    const regExp = CookieService.getCookieRegExp(name);
    return regExp.test(this.document.cookie);
  }
  /**
   * Get cookies by name
   *
   * @param name Cookie name
   * @returns property value
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  get(name) {
    if (this.documentIsAccessible && this.check(name)) {
      name = encodeURIComponent(name);
      const regExp = CookieService.getCookieRegExp(name);
      const result = regExp.exec(this.document.cookie);
      return result[1] ? CookieService.safeDecodeURIComponent(result[1]) : '';
    } else {
      return '';
    }
  }
  /**
   * Get all cookies in JSON format
   *
   * @returns all the cookies in json
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  getAll() {
    if (!this.documentIsAccessible) {
      return {};
    }
    const cookies = {};
    const document = this.document;
    if (document.cookie && document.cookie !== '') {
      document.cookie.split(';').forEach(currentCookie => {
        const [cookieName, cookieValue] = currentCookie.split('=');
        cookies[CookieService.safeDecodeURIComponent(cookieName.replace(/^ /, ''))] = CookieService.safeDecodeURIComponent(cookieValue);
      });
    }
    return cookies;
  }
  set(name, value, expiresOrOptions, path, domain, secure, sameSite, partitioned) {
    if (!this.documentIsAccessible) {
      return;
    }
    if (typeof expiresOrOptions === 'number' || expiresOrOptions instanceof Date || path || domain || secure || sameSite) {
      const optionsBody = {
        expires: expiresOrOptions,
        path,
        domain,
        secure,
        sameSite: sameSite ? sameSite : 'Lax',
        partitioned
      };
      this.set(name, value, optionsBody);
      return;
    }
    let cookieString = encodeURIComponent(name) + '=' + encodeURIComponent(value) + ';';
    const options = expiresOrOptions ? expiresOrOptions : {};
    if (options.expires) {
      if (typeof options.expires === 'number') {
        const dateExpires = new Date(new Date().getTime() + options.expires * 1000 * 60 * 60 * 24);
        cookieString += 'expires=' + dateExpires.toUTCString() + ';';
      } else {
        cookieString += 'expires=' + options.expires.toUTCString() + ';';
      }
    }
    if (options.path) {
      cookieString += 'path=' + options.path + ';';
    }
    if (options.domain) {
      cookieString += 'domain=' + options.domain + ';';
    }
    if (options.secure === false && options.sameSite === 'None') {
      options.secure = true;
      console.warn(`[ngx-cookie-service] Cookie ${name} was forced with secure flag because sameSite=None.` + `More details : https://github.com/stevermeister/ngx-cookie-service/issues/86#issuecomment-597720130`);
    }
    if (options.secure) {
      cookieString += 'secure;';
    }
    if (!options.sameSite) {
      options.sameSite = 'Lax';
    }
    cookieString += 'sameSite=' + options.sameSite + ';';
    if (options.partitioned) {
      cookieString += 'Partitioned;';
    }
    this.document.cookie = cookieString;
  }
  /**
   * Delete cookie by name
   *
   * @param name   Cookie name
   * @param path   Cookie path
   * @param domain Cookie domain
   * @param secure Cookie secure flag
   * @param sameSite Cookie sameSite flag - https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  delete(name, path, domain, secure, sameSite = 'Lax') {
    if (!this.documentIsAccessible) {
      return;
    }
    const expiresDate = new Date('Thu, 01 Jan 1970 00:00:01 GMT');
    this.set(name, '', {
      expires: expiresDate,
      path,
      domain,
      secure,
      sameSite
    });
  }
  /**
   * Delete all cookies
   *
   * @param path   Cookie path
   * @param domain Cookie domain
   * @param secure Is the Cookie secure
   * @param sameSite Is the cookie same site
   *
   * @author: Stepan Suvorov
   * @since: 1.0.0
   */
  deleteAll(path, domain, secure, sameSite = 'Lax') {
    if (!this.documentIsAccessible) {
      return;
    }
    const cookies = this.getAll();
    for (const cookieName in cookies) {
      if (cookies.hasOwnProperty(cookieName)) {
        this.delete(cookieName, path, domain, secure, sameSite);
      }
    }
  }
  static {
    this.ɵfac = function CookieService_Factory(t) {
      return new (t || CookieService)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵinject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID));
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: CookieService,
      factory: CookieService.ɵfac,
      providedIn: 'root'
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CookieService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], () => [{
    type: Document,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_common__WEBPACK_IMPORTED_MODULE_0__.DOCUMENT]
    }]
  }, {
    type: undefined,
    decorators: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
      args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
    }]
  }], null);
})();

/*
 * Public API Surface of ngx-cookie-service
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 67305:
/*!***********************************************************!*\
  !*** ./node_modules/ngx-countup/fesm2020/ngx-countup.mjs ***!
  \***********************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CountUpDirective: () => (/* binding */ CountUpDirective),
/* harmony export */   CountUpModule: () => (/* binding */ CountUpModule)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var countup_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! countup.js */ 37627);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 60316);




class CountUpDirective {
  constructor(el, zone, platformId) {
    this.el = el;
    this.zone = zone;
    this.platformId = platformId;
    this.options = {};
    this.reanimateOnClick = true;
    // eslint-disable-next-line @angular-eslint/no-output-native
    this.complete = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
  }
  // Re-animate if preference is set.
  onClick() {
    if (this.reanimateOnClick) {
      this.animate();
    }
  }
  ngOnChanges(changes) {
    // don't animate server-side (universal)
    if (!(0,_angular_common__WEBPACK_IMPORTED_MODULE_2__.isPlatformBrowser)(this.platformId)) {
      return;
    }
    const {
      options,
      endVal
    } = changes;
    if (this.countUp) {
      if (options?.currentValue !== undefined || endVal?.currentValue !== undefined) {
        // If options have changed, reinitialize
        if (options?.currentValue !== undefined) {
          this.initAndRun();
        } else {
          // Only endVal has changed, update with current options
          if (!this.options.startVal) {
            this.options.startVal = this.countUp.frameVal;
          }
          this.zone.runOutsideAngular(() => {
            this.countUp.update(this.endVal);
          });
        }
      }
    } else {
      this.initAndRun();
    }
  }
  animate() {
    this.zone.runOutsideAngular(() => {
      this.countUp.reset();
      this.countUp.start(() => {
        this.zone.run(() => {
          this.complete.emit();
        });
      });
    });
  }
  initAndRun() {
    this.zone.runOutsideAngular(() => {
      this.countUp = new countup_js__WEBPACK_IMPORTED_MODULE_0__.CountUp(this.el.nativeElement, this.endVal, this.options);
      if (!this.options.enableScrollSpy) {
        this.animate();
      }
    });
  }
}
CountUpDirective.ɵfac = function CountUpDirective_Factory(t) {
  return new (t || CountUpDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID));
};
CountUpDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
  type: CountUpDirective,
  selectors: [["", "countUp", ""]],
  hostBindings: function CountUpDirective_HostBindings(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function CountUpDirective_click_HostBindingHandler() {
        return ctx.onClick();
      });
    }
  },
  inputs: {
    endVal: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "countUp", "endVal"],
    options: "options",
    reanimateOnClick: "reanimateOnClick"
  },
  outputs: {
    complete: "complete"
  },
  features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CountUpDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[countUp]'
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
    }, {
      type: Object,
      decorators: [{
        type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Inject,
        args: [_angular_core__WEBPACK_IMPORTED_MODULE_1__.PLATFORM_ID]
      }]
    }];
  }, {
    endVal: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['countUp']
    }],
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    reanimateOnClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    complete: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    onClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['click']
    }]
  });
})();
class CountUpModule {}
CountUpModule.ɵfac = function CountUpModule_Factory(t) {
  return new (t || CountUpModule)();
};
CountUpModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
  type: CountUpModule
});
CountUpModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({
  imports: [[]]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](CountUpModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      imports: [],
      declarations: [CountUpDirective],
      exports: [CountUpDirective]
    }]
  }], null, null);
})();

/*
 * Public API Surface of count-up
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 53935:
/*!***************************************************************!*\
  !*** ./node_modules/ngx-drag-drop/fesm2022/ngx-drag-drop.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   DndDragImageRefDirective: () => (/* binding */ DndDragImageRefDirective),
/* harmony export */   DndDraggableDirective: () => (/* binding */ DndDraggableDirective),
/* harmony export */   DndDropzoneDirective: () => (/* binding */ DndDropzoneDirective),
/* harmony export */   DndHandleDirective: () => (/* binding */ DndHandleDirective),
/* harmony export */   DndModule: () => (/* binding */ DndModule),
/* harmony export */   DndPlaceholderRefDirective: () => (/* binding */ DndPlaceholderRefDirective)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);


const DROP_EFFECTS = ['move', 'copy', 'link'];
const CUSTOM_MIME_TYPE = 'application/x-dnd';
const JSON_MIME_TYPE = 'application/json';
const MSIE_MIME_TYPE = 'Text';
function mimeTypeIsCustom(mimeType) {
  return mimeType.substr(0, CUSTOM_MIME_TYPE.length) === CUSTOM_MIME_TYPE;
}
function getWellKnownMimeType(event) {
  if (event.dataTransfer) {
    const types = event.dataTransfer.types;
    // IE 9 workaround.
    if (!types) {
      return MSIE_MIME_TYPE;
    }
    for (let i = 0; i < types.length; i++) {
      if (types[i] === MSIE_MIME_TYPE || types[i] === JSON_MIME_TYPE || mimeTypeIsCustom(types[i])) {
        return types[i];
      }
    }
  }
  return null;
}
function setDragData(event, data, effectAllowed) {
  // Internet Explorer and Microsoft Edge don't support custom mime types, see design doc:
  // https://github.com/marceljuenemann/angular-drag-and-drop-lists/wiki/Data-Transfer-Design
  const mimeType = CUSTOM_MIME_TYPE + (data.type ? '-' + data.type : '');
  const dataString = JSON.stringify(data);
  try {
    event.dataTransfer?.setData(mimeType, dataString);
  } catch (e) {
    //   Setting a custom MIME type did not work, we are probably in IE or Edge.
    try {
      event.dataTransfer?.setData(JSON_MIME_TYPE, dataString);
    } catch (e) {
      //   We are in Internet Explorer and can only use the Text MIME type. Also note that IE
      //   does not allow changing the cursor in the dragover event, therefore we have to choose
      //   the one we want to display now by setting effectAllowed.
      const effectsAllowed = filterEffects(DROP_EFFECTS, effectAllowed);
      if (event.dataTransfer) {
        event.dataTransfer.effectAllowed = effectsAllowed[0];
      }
      event.dataTransfer?.setData(MSIE_MIME_TYPE, dataString);
    }
  }
}
function getDropData(event, dragIsExternal) {
  // check if the mime type is well known
  const mimeType = getWellKnownMimeType(event);
  // drag did not originate from [dndDraggable]
  if (dragIsExternal === true) {
    if (mimeType !== null && mimeTypeIsCustom(mimeType)) {
      // the type of content is well known and safe to handle
      return JSON.parse(event.dataTransfer?.getData(mimeType) ?? '{}');
    }
    // the contained data is unknown, let user handle it
    return {};
  }
  if (mimeType !== null) {
    // the type of content is well known and safe to handle
    return JSON.parse(event.dataTransfer?.getData(mimeType) ?? '{}');
  }
  // the contained data is unknown, let user handle it
  return {};
}
function filterEffects(effects, allowed) {
  if (allowed === 'all' || allowed === 'uninitialized') {
    return effects;
  }
  return effects.filter(function (effect) {
    return allowed.toLowerCase().indexOf(effect) !== -1;
  });
}
function getDirectChildElement(parentElement, childElement) {
  let directChild = childElement;
  while (directChild.parentNode !== parentElement) {
    // reached root node without finding given parent
    if (!directChild.parentNode) {
      return null;
    }
    directChild = directChild.parentNode;
  }
  return directChild;
}
function shouldPositionPlaceholderBeforeElement(event, element, horizontal) {
  const bounds = element.getBoundingClientRect();
  // If the pointer is in the upper half of the list item element,
  // we position the placeholder before the list item, otherwise after it.
  if (horizontal) {
    return event.clientX < bounds.left + bounds.width / 2;
  }
  return event.clientY < bounds.top + bounds.height / 2;
}
function calculateDragImageOffset(event, dragImage) {
  const dragImageComputedStyle = window.getComputedStyle(dragImage);
  const paddingTop = parseFloat(dragImageComputedStyle.paddingTop) || 0;
  const paddingLeft = parseFloat(dragImageComputedStyle.paddingLeft) || 0;
  const borderTop = parseFloat(dragImageComputedStyle.borderTopWidth) || 0;
  const borderLeft = parseFloat(dragImageComputedStyle.borderLeftWidth) || 0;
  return {
    x: event.offsetX + paddingLeft + borderLeft,
    y: event.offsetY + paddingTop + borderTop
  };
}
function setDragImage(event, dragImage, offsetFunction) {
  const offset = offsetFunction(event, dragImage) || {
    x: 0,
    y: 0
  };
  event.dataTransfer.setDragImage(dragImage, offset.x, offset.y);
}
const _dndState = {
  isDragging: false,
  dropEffect: 'none',
  effectAllowed: 'all',
  type: undefined
};
function startDrag(event, effectAllowed, type) {
  _dndState.isDragging = true;
  _dndState.dropEffect = 'none';
  _dndState.effectAllowed = effectAllowed;
  _dndState.type = type;
  if (event.dataTransfer) {
    event.dataTransfer.effectAllowed = effectAllowed;
  }
}
function endDrag() {
  _dndState.isDragging = false;
  _dndState.dropEffect = undefined;
  _dndState.effectAllowed = undefined;
  _dndState.type = undefined;
}
function setDropEffect(event, dropEffect) {
  if (_dndState.isDragging === true) {
    _dndState.dropEffect = dropEffect;
  }
  if (event.dataTransfer) {
    event.dataTransfer.dropEffect = dropEffect;
  }
}
function getDropEffect(event, effectAllowed) {
  const dataTransferEffectAllowed = event.dataTransfer ? event.dataTransfer.effectAllowed : 'uninitialized';
  let effects = filterEffects(DROP_EFFECTS, dataTransferEffectAllowed);
  if (_dndState.isDragging === true) {
    effects = filterEffects(effects, _dndState.effectAllowed);
  }
  if (effectAllowed) {
    effects = filterEffects(effects, effectAllowed);
  }
  // MacOS automatically filters dataTransfer.effectAllowed depending on the modifier keys,
  // therefore the following modifier keys will only affect other operating systems.
  if (effects.length === 0) {
    return 'none';
  }
  if (event.ctrlKey && effects.indexOf('copy') !== -1) {
    return 'copy';
  }
  if (event.altKey && effects.indexOf('link') !== -1) {
    return 'link';
  }
  return effects[0];
}
function getDndType(event) {
  if (_dndState.isDragging === true) {
    return _dndState.type;
  }
  const mimeType = getWellKnownMimeType(event);
  if (mimeType === null) {
    return undefined;
  }
  if (mimeType === MSIE_MIME_TYPE || mimeType === JSON_MIME_TYPE) {
    return undefined;
  }
  return mimeType.substr(CUSTOM_MIME_TYPE.length + 1) || undefined;
}
function isExternalDrag() {
  return _dndState.isDragging === false;
}
const dndState = _dndState;
class DndDragImageRefDirective {
  dndDraggableDirective = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => DndDraggableDirective));
  elementRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
  ngOnInit() {
    this.dndDraggableDirective.registerDragImage(this.elementRef);
  }
  static ɵfac = function DndDragImageRefDirective_Factory(t) {
    return new (t || DndDragImageRefDirective)();
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: DndDragImageRefDirective,
    selectors: [["", "dndDragImageRef", ""]],
    standalone: true
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndDragImageRefDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dndDragImageRef]',
      standalone: true
    }]
  }], null, null);
})();
class DndDraggableDirective {
  dndDraggable;
  dndEffectAllowed = 'copy';
  dndType;
  dndDraggingClass = 'dndDragging';
  dndDraggingSourceClass = 'dndDraggingSource';
  dndDraggableDisabledClass = 'dndDraggableDisabled';
  dndDragImageOffsetFunction = calculateDragImageOffset;
  dndStart = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndDrag = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndEnd = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndMoved = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndCopied = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndLinked = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndCanceled = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  draggable = true;
  dndHandle;
  dndDragImageElementRef;
  dragImage;
  isDragStarted = false;
  elementRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
  renderer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2);
  ngZone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  set dndDisableIf(value) {
    this.draggable = !value;
    if (this.draggable) {
      this.renderer.removeClass(this.elementRef.nativeElement, this.dndDraggableDisabledClass);
    } else {
      this.renderer.addClass(this.elementRef.nativeElement, this.dndDraggableDisabledClass);
    }
  }
  set dndDisableDragIf(value) {
    this.dndDisableIf = value;
  }
  ngAfterViewInit() {
    this.ngZone.runOutsideAngular(() => {
      this.elementRef.nativeElement.addEventListener('drag', this.dragEventHandler);
    });
  }
  ngOnDestroy() {
    this.elementRef.nativeElement.removeEventListener('drag', this.dragEventHandler);
    if (this.isDragStarted) {
      endDrag();
    }
  }
  onDragStart(event) {
    if (!this.draggable) {
      return false;
    }
    // check if there is dnd handle and if the dnd handle was used to start the drag
    if (this.dndHandle != null && event._dndUsingHandle == null) {
      event.stopPropagation();
      return false;
    }
    // initialize global state
    startDrag(event, this.dndEffectAllowed, this.dndType);
    this.isDragStarted = true;
    setDragData(event, {
      data: this.dndDraggable,
      type: this.dndType
    }, dndState.effectAllowed);
    this.dragImage = this.determineDragImage();
    // set dragging css class prior to setDragImage so styles are applied before
    // TODO breaking change: add class to elementRef rather than drag image which could be another element
    this.renderer.addClass(this.dragImage, this.dndDraggingClass);
    // set custom dragimage if present
    // set dragimage if drag is started from dndHandle
    if (this.dndDragImageElementRef != null || event._dndUsingHandle != null) {
      setDragImage(event, this.dragImage, this.dndDragImageOffsetFunction);
    }
    // add dragging source css class on first drag event
    const unregister = this.renderer.listen(this.elementRef.nativeElement, 'drag', () => {
      this.renderer.addClass(this.elementRef.nativeElement, this.dndDraggingSourceClass);
      unregister();
    });
    this.dndStart.emit(event);
    event.stopPropagation();
    setTimeout(() => {
      this.renderer.setStyle(this.dragImage, 'pointer-events', 'none');
    }, 100);
    return true;
  }
  onDrag(event) {
    this.dndDrag.emit(event);
  }
  onDragEnd(event) {
    if (!this.draggable || !this.isDragStarted) {
      return;
    }
    // get drop effect from custom stored state as its not reliable across browsers
    const dropEffect = dndState.dropEffect;
    this.renderer.setStyle(this.dragImage, 'pointer-events', 'unset');
    let dropEffectEmitter;
    switch (dropEffect) {
      case 'copy':
        dropEffectEmitter = this.dndCopied;
        break;
      case 'link':
        dropEffectEmitter = this.dndLinked;
        break;
      case 'move':
        dropEffectEmitter = this.dndMoved;
        break;
      default:
        dropEffectEmitter = this.dndCanceled;
        break;
    }
    dropEffectEmitter.emit(event);
    this.dndEnd.emit(event);
    // reset global state
    endDrag();
    this.isDragStarted = false;
    this.renderer.removeClass(this.dragImage, this.dndDraggingClass);
    // IE9 special hammering
    window.setTimeout(() => {
      this.renderer.removeClass(this.elementRef.nativeElement, this.dndDraggingSourceClass);
    }, 0);
    event.stopPropagation();
  }
  registerDragHandle(handle) {
    this.dndHandle = handle;
  }
  registerDragImage(elementRef) {
    this.dndDragImageElementRef = elementRef;
  }
  dragEventHandler = event => this.onDrag(event);
  determineDragImage() {
    // evaluate custom drag image existence
    if (typeof this.dndDragImageElementRef !== 'undefined') {
      return this.dndDragImageElementRef.nativeElement;
    } else {
      return this.elementRef.nativeElement;
    }
  }
  static ɵfac = function DndDraggableDirective_Factory(t) {
    return new (t || DndDraggableDirective)();
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: DndDraggableDirective,
    selectors: [["", "dndDraggable", ""]],
    hostVars: 1,
    hostBindings: function DndDraggableDirective_HostBindings(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("dragstart", function DndDraggableDirective_dragstart_HostBindingHandler($event) {
          return ctx.onDragStart($event);
        })("dragend", function DndDraggableDirective_dragend_HostBindingHandler($event) {
          return ctx.onDragEnd($event);
        });
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("draggable", ctx.draggable);
      }
    },
    inputs: {
      dndDraggable: "dndDraggable",
      dndEffectAllowed: "dndEffectAllowed",
      dndType: "dndType",
      dndDraggingClass: "dndDraggingClass",
      dndDraggingSourceClass: "dndDraggingSourceClass",
      dndDraggableDisabledClass: "dndDraggableDisabledClass",
      dndDragImageOffsetFunction: "dndDragImageOffsetFunction",
      dndDisableIf: "dndDisableIf",
      dndDisableDragIf: "dndDisableDragIf"
    },
    outputs: {
      dndStart: "dndStart",
      dndDrag: "dndDrag",
      dndEnd: "dndEnd",
      dndMoved: "dndMoved",
      dndCopied: "dndCopied",
      dndLinked: "dndLinked",
      dndCanceled: "dndCanceled"
    },
    standalone: true
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndDraggableDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dndDraggable]',
      standalone: true
    }]
  }], null, {
    dndDraggable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndEffectAllowed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndType: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDraggingClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDraggingSourceClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDraggableDisabledClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDragImageOffsetFunction: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndStart: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndDrag: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndMoved: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndCopied: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndLinked: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndCanceled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    draggable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['attr.draggable']
    }],
    dndDisableIf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDisableDragIf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    onDragStart: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['dragstart', ['$event']]
    }],
    onDragEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['dragend', ['$event']]
    }]
  });
})();
class DndPlaceholderRefDirective {
  elementRef;
  constructor(elementRef) {
    this.elementRef = elementRef;
  }
  ngOnInit() {
    // placeholder has to be "invisible" to the cursor, or it would interfere with the dragover detection for the same dropzone
    this.elementRef.nativeElement.style.pointerEvents = 'none';
  }
  static ɵfac = function DndPlaceholderRefDirective_Factory(t) {
    return new (t || DndPlaceholderRefDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef));
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: DndPlaceholderRefDirective,
    selectors: [["", "dndPlaceholderRef", ""]],
    standalone: true
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndPlaceholderRefDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dndPlaceholderRef]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }], null);
})();
class DndDropzoneDirective {
  ngZone;
  elementRef;
  renderer;
  dndDropzone = '';
  dndEffectAllowed = 'uninitialized';
  dndAllowExternal = false;
  dndHorizontal = false;
  dndDragoverClass = 'dndDragover';
  dndDropzoneDisabledClass = 'dndDropzoneDisabled';
  dndDragover = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndDrop = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  dndPlaceholderRef;
  placeholder = null;
  disabled = false;
  constructor(ngZone, elementRef, renderer) {
    this.ngZone = ngZone;
    this.elementRef = elementRef;
    this.renderer = renderer;
  }
  set dndDisableIf(value) {
    this.disabled = value;
    if (this.disabled) {
      this.renderer.addClass(this.elementRef.nativeElement, this.dndDropzoneDisabledClass);
    } else {
      this.renderer.removeClass(this.elementRef.nativeElement, this.dndDropzoneDisabledClass);
    }
  }
  set dndDisableDropIf(value) {
    this.dndDisableIf = value;
  }
  ngAfterViewInit() {
    this.placeholder = this.tryGetPlaceholder();
    this.removePlaceholderFromDOM();
    this.ngZone.runOutsideAngular(() => {
      this.elementRef.nativeElement.addEventListener('dragenter', this.dragEnterEventHandler);
      this.elementRef.nativeElement.addEventListener('dragover', this.dragOverEventHandler);
      this.elementRef.nativeElement.addEventListener('dragleave', this.dragLeaveEventHandler);
    });
  }
  ngOnDestroy() {
    this.elementRef.nativeElement.removeEventListener('dragenter', this.dragEnterEventHandler);
    this.elementRef.nativeElement.removeEventListener('dragover', this.dragOverEventHandler);
    this.elementRef.nativeElement.removeEventListener('dragleave', this.dragLeaveEventHandler);
  }
  onDragEnter(event) {
    // check if another dropzone is activated
    if (event._dndDropzoneActive === true) {
      this.cleanupDragoverState();
      return;
    }
    // set as active if the target element is inside this dropzone
    if (event._dndDropzoneActive == null) {
      const newTarget = document.elementFromPoint(event.clientX, event.clientY);
      if (this.elementRef.nativeElement.contains(newTarget)) {
        event._dndDropzoneActive = true;
      }
    }
    // check if this drag event is allowed to drop on this dropzone
    const type = getDndType(event);
    if (!this.isDropAllowed(type)) {
      return;
    }
    // allow the dragenter
    event.preventDefault();
  }
  onDragOver(event) {
    // With nested dropzones, we want to ignore this event if a child dropzone
    // has already handled a dragover.  Historically, event.stopPropagation() was
    // used to prevent this bubbling, but that prevents any dragovers outside the
    // ngx-drag-drop component, and stops other use cases such as scrolling on drag.
    // Instead, we can check if the event was already prevented by a child and bail early.
    if (event.defaultPrevented) {
      return;
    }
    // check if this drag event is allowed to drop on this dropzone
    const type = getDndType(event);
    if (!this.isDropAllowed(type)) {
      return;
    }
    this.checkAndUpdatePlaceholderPosition(event);
    const dropEffect = getDropEffect(event, this.dndEffectAllowed);
    if (dropEffect === 'none') {
      this.cleanupDragoverState();
      return;
    }
    // allow the dragover
    event.preventDefault();
    // set the drop effect
    setDropEffect(event, dropEffect);
    this.dndDragover.emit(event);
    this.renderer.addClass(this.elementRef.nativeElement, this.dndDragoverClass);
  }
  onDrop(event) {
    try {
      // check if this drag event is allowed to drop on this dropzone
      const type = getDndType(event);
      if (!this.isDropAllowed(type)) {
        return;
      }
      const data = getDropData(event, isExternalDrag());
      if (!this.isDropAllowed(data.type)) {
        return;
      }
      // signal custom drop handling
      event.preventDefault();
      const dropEffect = getDropEffect(event);
      setDropEffect(event, dropEffect);
      if (dropEffect === 'none') {
        return;
      }
      const dropIndex = this.getPlaceholderIndex();
      // if for whatever reason the placeholder is not present in the DOM but it should be there
      // we don't allow/emit the drop event since it breaks the contract
      // seems to only happen if drag and drop is executed faster than the DOM updates
      if (dropIndex === -1) {
        return;
      }
      this.dndDrop.emit({
        event: event,
        dropEffect: dropEffect,
        isExternal: isExternalDrag(),
        data: data.data,
        index: dropIndex,
        type: type
      });
      event.stopPropagation();
    } finally {
      this.cleanupDragoverState();
    }
  }
  onDragLeave(event) {
    event.preventDefault();
    event.stopPropagation();
    // check if still inside this dropzone and not yet handled by another dropzone
    if (event._dndDropzoneActive == null) {
      if (this.elementRef.nativeElement.contains(event.relatedTarget)) {
        event._dndDropzoneActive = true;
        return;
      }
    }
    this.cleanupDragoverState();
    // cleanup drop effect when leaving dropzone
    setDropEffect(event, 'none');
  }
  dragEnterEventHandler = event => this.onDragEnter(event);
  dragOverEventHandler = event => this.onDragOver(event);
  dragLeaveEventHandler = event => this.onDragLeave(event);
  isDropAllowed(type) {
    // dropzone is disabled -> deny it
    if (this.disabled) {
      return false;
    }
    // if drag did not start from our directive
    // and external drag sources are not allowed -> deny it
    if (isExternalDrag() && !this.dndAllowExternal) {
      return false;
    }
    // no filtering by types -> allow it
    if (!this.dndDropzone) {
      return true;
    }
    // no type set -> allow it
    if (!type) {
      return true;
    }
    if (!Array.isArray(this.dndDropzone)) {
      throw new Error('dndDropzone: bound value to [dndDropzone] must be an array!');
    }
    // if dropzone contains type -> allow it
    return this.dndDropzone.indexOf(type) !== -1;
  }
  tryGetPlaceholder() {
    if (typeof this.dndPlaceholderRef !== 'undefined') {
      return this.dndPlaceholderRef.elementRef.nativeElement;
    }
    // TODO nasty workaround needed because if ng-container / template is used @ContentChild() or DI will fail because
    // of wrong context see angular bug https://github.com/angular/angular/issues/13517
    return this.elementRef.nativeElement.querySelector('[dndPlaceholderRef]');
  }
  removePlaceholderFromDOM() {
    if (this.placeholder !== null && this.placeholder.parentNode !== null) {
      this.placeholder.parentNode.removeChild(this.placeholder);
    }
  }
  checkAndUpdatePlaceholderPosition(event) {
    if (this.placeholder === null) {
      return;
    }
    // make sure the placeholder is in the DOM
    if (this.placeholder.parentNode !== this.elementRef.nativeElement) {
      this.renderer.appendChild(this.elementRef.nativeElement, this.placeholder);
    }
    // update the position if the event originates from a child element of the dropzone
    const directChild = getDirectChildElement(this.elementRef.nativeElement, event.target);
    // early exit if no direct child or direct child is placeholder
    if (directChild === null || directChild === this.placeholder) {
      return;
    }
    const positionPlaceholderBeforeDirectChild = shouldPositionPlaceholderBeforeElement(event, directChild, this.dndHorizontal);
    if (positionPlaceholderBeforeDirectChild) {
      // do insert before only if necessary
      if (directChild.previousSibling !== this.placeholder) {
        this.renderer.insertBefore(this.elementRef.nativeElement, this.placeholder, directChild);
      }
    } else {
      // do insert after only if necessary
      if (directChild.nextSibling !== this.placeholder) {
        this.renderer.insertBefore(this.elementRef.nativeElement, this.placeholder, directChild.nextSibling);
      }
    }
  }
  getPlaceholderIndex() {
    if (this.placeholder === null) {
      return undefined;
    }
    const element = this.elementRef.nativeElement;
    return Array.prototype.indexOf.call(element.children, this.placeholder);
  }
  cleanupDragoverState() {
    this.renderer.removeClass(this.elementRef.nativeElement, this.dndDragoverClass);
    this.removePlaceholderFromDOM();
  }
  static ɵfac = function DndDropzoneDirective_Factory(t) {
    return new (t || DndDropzoneDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2));
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: DndDropzoneDirective,
    selectors: [["", "dndDropzone", ""]],
    contentQueries: function DndDropzoneDirective_ContentQueries(rf, ctx, dirIndex) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵcontentQuery"](dirIndex, DndPlaceholderRefDirective, 5);
      }
      if (rf & 2) {
        let _t;
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵqueryRefresh"](_t = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵloadQuery"]()) && (ctx.dndPlaceholderRef = _t.first);
      }
    },
    hostBindings: function DndDropzoneDirective_HostBindings(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("drop", function DndDropzoneDirective_drop_HostBindingHandler($event) {
          return ctx.onDrop($event);
        });
      }
    },
    inputs: {
      dndDropzone: "dndDropzone",
      dndEffectAllowed: "dndEffectAllowed",
      dndAllowExternal: "dndAllowExternal",
      dndHorizontal: "dndHorizontal",
      dndDragoverClass: "dndDragoverClass",
      dndDropzoneDisabledClass: "dndDropzoneDisabledClass",
      dndDisableIf: "dndDisableIf",
      dndDisableDropIf: "dndDisableDropIf"
    },
    outputs: {
      dndDragover: "dndDragover",
      dndDrop: "dndDrop"
    },
    standalone: true
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndDropzoneDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dndDropzone]',
      standalone: true
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2
  }], {
    dndDropzone: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndEffectAllowed: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndAllowExternal: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndHorizontal: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDragoverClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDropzoneDisabledClass: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDragover: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndDrop: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    dndPlaceholderRef: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.ContentChild,
      args: [DndPlaceholderRefDirective]
    }],
    dndDisableIf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    dndDisableDropIf: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    onDrop: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['drop', ['$event']]
    }]
  });
})();
class DndHandleDirective {
  draggable = true;
  dndDraggableDirective = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(DndDraggableDirective);
  ngOnInit() {
    this.dndDraggableDirective.registerDragHandle(this);
  }
  onDragEvent(event) {
    event._dndUsingHandle = true;
  }
  static ɵfac = function DndHandleDirective_Factory(t) {
    return new (t || DndHandleDirective)();
  };
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: DndHandleDirective,
    selectors: [["", "dndHandle", ""]],
    hostVars: 1,
    hostBindings: function DndHandleDirective_HostBindings(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵlistener"]("dragstart", function DndHandleDirective_dragstart_HostBindingHandler($event) {
          return ctx.onDragEvent($event);
        })("dragend", function DndHandleDirective_dragend_HostBindingHandler($event) {
          return ctx.onDragEvent($event);
        });
      }
      if (rf & 2) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵattribute"]("draggable", ctx.draggable);
      }
    },
    standalone: true
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndHandleDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[dndHandle]',
      standalone: true
    }]
  }], null, {
    draggable: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostBinding,
      args: ['attr.draggable']
    }],
    onDragEvent: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['dragstart', ['$event']]
    }, {
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.HostListener,
      args: ['dragend', ['$event']]
    }]
  });
})();
class DndModule {
  static ɵfac = function DndModule_Factory(t) {
    return new (t || DndModule)();
  };
  static ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
    type: DndModule
  });
  static ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DndModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: [DndDraggableDirective, DndDropzoneDirective, DndHandleDirective, DndPlaceholderRefDirective, DndDragImageRefDirective],
      imports: [DndDragImageRefDirective, DndDropzoneDirective, DndHandleDirective, DndPlaceholderRefDirective, DndDraggableDirective]
    }]
  }], null, null);
})();

/*
 * Public API Surface of dnd
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 67227:
/*!***************************************************************!*\
  !*** ./node_modules/ngx-filesaver/fesm2020/ngx-filesaver.mjs ***!
  \***************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   FileSaverDirective: () => (/* binding */ FileSaverDirective),
/* harmony export */   FileSaverModule: () => (/* binding */ FileSaverModule),
/* harmony export */   FileSaverService: () => (/* binding */ FileSaverService)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var file_saver__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! file-saver */ 85841);
/* harmony import */ var _angular_common_http__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common/http */ 46443);





class FileSaverService {
  get isFileSaverSupported() {
    try {
      return !!new Blob();
    } catch (e) {
      return false;
    }
  }
  genType(fileName) {
    if (!fileName || fileName.lastIndexOf('.') === -1) {
      return 'text/plain';
    }
    const type = fileName.substr(fileName.lastIndexOf('.') + 1);
    switch (type) {
      case 'txt':
        return 'text/plain';
      case 'xml':
      case 'html':
        return `text/${type}`;
      case 'json':
        return 'octet/stream';
      default:
        return `application/${type}`;
    }
  }
  save(blob, fileName, filtType, option) {
    if (!blob) {
      throw new Error('Data argument should be a blob instance');
    }
    const file = new Blob([blob], {
      type: filtType || blob.type || this.genType(fileName)
    });
    (0,file_saver__WEBPACK_IMPORTED_MODULE_0__.saveAs)(file, decodeURI(fileName || 'download'), option);
  }
  saveText(txt, fileName, option) {
    const blob = new Blob([txt]);
    this.save(blob, fileName, undefined, option);
  }
}
FileSaverService.ɵfac = function FileSaverService_Factory(t) {
  return new (t || FileSaverService)();
};
FileSaverService.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
  token: FileSaverService,
  factory: FileSaverService.ɵfac,
  providedIn: 'root'
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FileSaverService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable,
    args: [{
      providedIn: 'root'
    }]
  }], null, null);
})();
class FileSaverDirective {
  constructor(el, fss, httpClient) {
    this.el = el;
    this.fss = fss;
    this.httpClient = httpClient;
    this.method = 'GET';
    this.success = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this.error = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    if (!fss.isFileSaverSupported) {
      el.nativeElement.classList.add(`filesaver__not-support`);
    }
  }
  getName(res) {
    return decodeURI(this.fileName || res.headers.get('filename') || res.headers.get('x-filename') || '');
  }
  _click() {
    if (!this.fss.isFileSaverSupported) {
      return;
    }
    let req = this.http;
    if (!req) {
      let params = new _angular_common_http__WEBPACK_IMPORTED_MODULE_2__.HttpParams();
      const query = this.query || {};
      // tslint:disable-next-line:forin
      for (const item in query) {
        params = params.set(item, query[item]);
      }
      req = this.httpClient.request(this.method, this.url, {
        observe: 'response',
        responseType: 'blob',
        headers: this.header,
        params
      });
    }
    this.setDisabled(true);
    req.subscribe(res => {
      if (res.status !== 200 || res.body.size <= 0) {
        this.error.emit(res);
        return;
      }
      this.fss.save(res.body, this.getName(res), undefined, this.fsOptions);
      this.success.emit(res);
    }, err => this.error.emit(err), () => this.setDisabled(false));
  }
  setDisabled(status) {
    const el = this.el.nativeElement;
    el.disabled = status;
    el.classList[status ? 'add' : 'remove'](`filesaver__disabled`);
  }
}
FileSaverDirective.ɵfac = function FileSaverDirective_Factory(t) {
  return new (t || FileSaverDirective)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](FileSaverService), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_common_http__WEBPACK_IMPORTED_MODULE_2__.HttpClient));
};
FileSaverDirective.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
  type: FileSaverDirective,
  selectors: [["", "fileSaver", ""]],
  hostBindings: function FileSaverDirective_HostBindings(rf, ctx) {
    if (rf & 1) {
      _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("click", function FileSaverDirective_click_HostBindingHandler() {
        return ctx._click();
      });
    }
  },
  inputs: {
    method: "method",
    http: "http",
    query: "query",
    header: "header",
    url: "url",
    fileName: "fileName",
    fsOptions: "fsOptions"
  },
  outputs: {
    success: "success",
    error: "error"
  },
  exportAs: ["fileSaver"],
  standalone: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FileSaverDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: '[fileSaver]',
      exportAs: 'fileSaver',
      standalone: true
    }]
  }], function () {
    return [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
    }, {
      type: FileSaverService
    }, {
      type: _angular_common_http__WEBPACK_IMPORTED_MODULE_2__.HttpClient
    }];
  }, {
    method: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    http: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    query: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    header: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    url: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    fileName: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    fsOptions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    success: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    error: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    _click: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['click']
    }]
  });
})();
class FileSaverModule {}
FileSaverModule.ɵfac = function FileSaverModule_Factory(t) {
  return new (t || FileSaverModule)();
};
FileSaverModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
  type: FileSaverModule
});
FileSaverModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](FileSaverModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      imports: [FileSaverDirective],
      exports: [FileSaverDirective]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 86769:
/*!*****************************************************!*\
  !*** ./node_modules/ngx-mask/fesm2022/ngx-mask.mjs ***!
  \*****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   INITIAL_CONFIG: () => (/* binding */ INITIAL_CONFIG),
/* harmony export */   NEW_CONFIG: () => (/* binding */ NEW_CONFIG),
/* harmony export */   NGX_MASK_CONFIG: () => (/* binding */ NGX_MASK_CONFIG),
/* harmony export */   NgxMaskDirective: () => (/* binding */ NgxMaskDirective),
/* harmony export */   NgxMaskPipe: () => (/* binding */ NgxMaskPipe),
/* harmony export */   NgxMaskService: () => (/* binding */ NgxMaskService),
/* harmony export */   initialConfig: () => (/* binding */ initialConfig),
/* harmony export */   provideEnvironmentNgxMask: () => (/* binding */ provideEnvironmentNgxMask),
/* harmony export */   provideNgxMask: () => (/* binding */ provideNgxMask),
/* harmony export */   timeMasks: () => (/* binding */ timeMasks),
/* harmony export */   withoutValidation: () => (/* binding */ withoutValidation)
/* harmony export */ });
/* harmony import */ var C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js */ 89204);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @angular/forms */ 34456);





const NGX_MASK_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('ngx-mask config');
const NEW_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('new ngx-mask config');
const INITIAL_CONFIG = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.InjectionToken('initial ngx-mask config');
const initialConfig = {
  suffix: '',
  prefix: '',
  thousandSeparator: ' ',
  decimalMarker: ['.', ','],
  clearIfNotMatch: false,
  showTemplate: false,
  showMaskTyped: false,
  placeHolderCharacter: '_',
  dropSpecialCharacters: true,
  hiddenInput: undefined,
  shownMaskExpression: '',
  separatorLimit: '',
  allowNegativeNumbers: false,
  validation: true,
  // eslint-disable-next-line @typescript-eslint/quotes
  specialCharacters: ['-', '/', '(', ')', '.', ':', ' ', '+', ',', '@', '[', ']', '"', "'"],
  leadZeroDateTime: false,
  apm: false,
  leadZero: false,
  keepCharacterPositions: false,
  triggerOnMaskChange: false,
  inputTransformFn: value => value,
  outputTransformFn: value => value,
  maskFilled: new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter(),
  patterns: {
    '0': {
      pattern: new RegExp('\\d')
    },
    '9': {
      pattern: new RegExp('\\d'),
      optional: true
    },
    X: {
      pattern: new RegExp('\\d'),
      symbol: '*'
    },
    A: {
      pattern: new RegExp('[a-zA-Z0-9]')
    },
    S: {
      pattern: new RegExp('[a-zA-Z]')
    },
    U: {
      pattern: new RegExp('[A-Z]')
    },
    L: {
      pattern: new RegExp('[a-z]')
    },
    d: {
      pattern: new RegExp('\\d')
    },
    m: {
      pattern: new RegExp('\\d')
    },
    M: {
      pattern: new RegExp('\\d')
    },
    H: {
      pattern: new RegExp('\\d')
    },
    h: {
      pattern: new RegExp('\\d')
    },
    s: {
      pattern: new RegExp('\\d')
    }
  }
};
const timeMasks = ["Hh:m0:s0" /* MaskExpression.HOURS_MINUTES_SECONDS */, "Hh:m0" /* MaskExpression.HOURS_MINUTES */, "m0:s0" /* MaskExpression.MINUTES_SECONDS */];
const withoutValidation = ["percent" /* MaskExpression.PERCENT */, "Hh" /* MaskExpression.HOURS_HOUR */, "s0" /* MaskExpression.SECONDS */, "m0" /* MaskExpression.MINUTES */, "separator" /* MaskExpression.SEPARATOR */, "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */, "d0/M0" /* MaskExpression.DAYS_MONTHS */, "d0" /* MaskExpression.DAYS */, "M0" /* MaskExpression.MONTHS */];
class NgxMaskApplierService {
  constructor() {
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_MASK_CONFIG);
    this.dropSpecialCharacters = this._config.dropSpecialCharacters;
    this.hiddenInput = this._config.hiddenInput;
    this.clearIfNotMatch = this._config.clearIfNotMatch;
    this.specialCharacters = this._config.specialCharacters;
    this.patterns = this._config.patterns;
    this.prefix = this._config.prefix;
    this.suffix = this._config.suffix;
    this.thousandSeparator = this._config.thousandSeparator;
    this.decimalMarker = this._config.decimalMarker;
    this.showMaskTyped = this._config.showMaskTyped;
    this.placeHolderCharacter = this._config.placeHolderCharacter;
    this.validation = this._config.validation;
    this.separatorLimit = this._config.separatorLimit;
    this.allowNegativeNumbers = this._config.allowNegativeNumbers;
    this.leadZeroDateTime = this._config.leadZeroDateTime;
    this.leadZero = this._config.leadZero;
    this.apm = this._config.apm;
    this.inputTransformFn = this._config.inputTransformFn;
    this.outputTransformFn = this._config.outputTransformFn;
    this.keepCharacterPositions = this._config.keepCharacterPositions;
    this._shift = new Set();
    this.plusOnePosition = false;
    this.maskExpression = '';
    this.actualValue = '';
    this.showKeepCharacterExp = '';
    this.shownMaskExpression = '';
    this.deletedSpecialCharacter = false;
    this._formatWithSeparators = (str, thousandSeparatorChar, decimalChars, precision) => {
      let x = [];
      let decimalChar = '';
      if (Array.isArray(decimalChars)) {
        const regExp = new RegExp(decimalChars.map(v => '[\\^$.|?*+()'.indexOf(v) >= 0 ? `\\${v}` : v).join('|'));
        x = str.split(regExp);
        decimalChar = str.match(regExp)?.[0] ?? "" /* MaskExpression.EMPTY_STRING */;
      } else {
        x = str.split(decimalChars);
        decimalChar = decimalChars;
      }
      const decimals = x.length > 1 ? `${decimalChar}${x[1]}` : "" /* MaskExpression.EMPTY_STRING */;
      let res = x[0] ?? "" /* MaskExpression.EMPTY_STRING */;
      const separatorLimit = this.separatorLimit.replace(/\s/g, "" /* MaskExpression.EMPTY_STRING */);
      if (separatorLimit && +separatorLimit) {
        if (res[0] === "-" /* MaskExpression.MINUS */) {
          res = `-${res.slice(1, res.length).slice(0, separatorLimit.length)}`;
        } else {
          res = res.slice(0, separatorLimit.length);
        }
      }
      const rgx = /(\d+)(\d{3})/;
      while (thousandSeparatorChar && rgx.test(res)) {
        res = res.replace(rgx, '$1' + thousandSeparatorChar + '$2');
      }
      if (precision === undefined) {
        return res + decimals;
      } else if (precision === 0) {
        return res;
      }
      return res + decimals.substring(0, precision + 1);
    };
    this.percentage = str => {
      const sanitizedStr = str.replace(',', '.');
      const value = Number(this.allowNegativeNumbers && str.includes("-" /* MaskExpression.MINUS */) ? sanitizedStr.slice(1, str.length) : sanitizedStr);
      return !isNaN(value) && value >= 0 && value <= 100;
    };
    this.getPrecision = maskExpression => {
      const x = maskExpression.split("." /* MaskExpression.DOT */);
      if (x.length > 1) {
        return Number(x[x.length - 1]);
      }
      return Infinity;
    };
    this.checkAndRemoveSuffix = inputValue => {
      for (let i = this.suffix?.length - 1; i >= 0; i--) {
        const substr = this.suffix.substring(i, this.suffix?.length);
        if (inputValue.includes(substr) && i !== this.suffix?.length - 1 && (i - 1 < 0 || !inputValue.includes(this.suffix.substring(i - 1, this.suffix?.length)))) {
          return inputValue.replace(substr, "" /* MaskExpression.EMPTY_STRING */);
        }
      }
      return inputValue;
    };
    this.checkInputPrecision = (inputValue, precision, decimalMarker) => {
      if (precision < Infinity) {
        // TODO need think about decimalMarker
        if (Array.isArray(decimalMarker)) {
          const marker = decimalMarker.find(dm => dm !== this.thousandSeparator);
          // eslint-disable-next-line no-param-reassign
          decimalMarker = marker ? marker : decimalMarker[0];
        }
        const precisionRegEx = new RegExp(this._charToRegExpExpression(decimalMarker) + `\\d{${precision}}.*$`);
        const precisionMatch = inputValue.match(precisionRegEx);
        const precisionMatchLength = (precisionMatch && precisionMatch[0]?.length) ?? 0;
        if (precisionMatchLength - 1 > precision) {
          const diff = precisionMatchLength - 1 - precision;
          // eslint-disable-next-line no-param-reassign
          inputValue = inputValue.substring(0, inputValue.length - diff);
        }
        if (precision === 0 && this._compareOrIncludes(inputValue[inputValue.length - 1], decimalMarker, this.thousandSeparator)) {
          // eslint-disable-next-line no-param-reassign
          inputValue = inputValue.substring(0, inputValue.length - 1);
        }
      }
      return inputValue;
    };
  }
  applyMaskWithPattern(inputValue, maskAndPattern) {
    const [mask, customPattern] = maskAndPattern;
    this.customPattern = customPattern;
    return this.applyMask(inputValue, mask);
  }
  applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  cb = () => {}) {
    if (!maskExpression || typeof inputValue !== 'string') {
      return "" /* MaskExpression.EMPTY_STRING */;
    }
    let cursor = 0;
    let result = '';
    let multi = false;
    let backspaceShift = false;
    let shift = 1;
    let stepBack = false;
    if (inputValue.slice(0, this.prefix.length) === this.prefix) {
      // eslint-disable-next-line no-param-reassign
      inputValue = inputValue.slice(this.prefix.length, inputValue.length);
    }
    if (!!this.suffix && inputValue?.length > 0) {
      // eslint-disable-next-line no-param-reassign
      inputValue = this.checkAndRemoveSuffix(inputValue);
    }
    if (inputValue === '(' && this.prefix) {
      // eslint-disable-next-line no-param-reassign
      inputValue = '';
    }
    const inputArray = inputValue.toString().split("" /* MaskExpression.EMPTY_STRING */);
    if (this.allowNegativeNumbers && inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */) {
      result += inputValue.slice(cursor, cursor + 1);
    }
    if (maskExpression === "IP" /* MaskExpression.IP */) {
      const valuesIP = inputValue.split("." /* MaskExpression.DOT */);
      this.ipError = this._validIP(valuesIP);
      // eslint-disable-next-line no-param-reassign
      maskExpression = '099.099.099.099';
    }
    const arr = [];
    for (let i = 0; i < inputValue.length; i++) {
      if (inputValue[i]?.match('\\d')) {
        arr.push(inputValue[i] ?? "" /* MaskExpression.EMPTY_STRING */);
      }
    }
    if (maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
      this.cpfCnpjError = arr.length !== 11 && arr.length !== 14;
      if (arr.length > 11) {
        // eslint-disable-next-line no-param-reassign
        maskExpression = '00.000.000/0000-00';
      } else {
        // eslint-disable-next-line no-param-reassign
        maskExpression = '000.000.000-00';
      }
    }
    if (maskExpression.startsWith("percent" /* MaskExpression.PERCENT */)) {
      if (inputValue.match('[a-z]|[A-Z]') ||
      // eslint-disable-next-line no-useless-escape
      inputValue.match(/[-!$%^&*()_+|~=`{}\[\]:";'<>?,\/.]/) && !backspaced) {
        // eslint-disable-next-line no-param-reassign
        inputValue = this._stripToDecimal(inputValue);
        const precision = this.getPrecision(maskExpression);
        // eslint-disable-next-line no-param-reassign
        inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker);
      }
      const decimalMarker = typeof this.decimalMarker === 'string' ? this.decimalMarker : "." /* MaskExpression.DOT */;
      if (inputValue.indexOf(decimalMarker) > 0 && !this.percentage(inputValue.substring(0, inputValue.indexOf(decimalMarker)))) {
        let base = inputValue.substring(0, inputValue.indexOf(decimalMarker) - 1);
        if (this.allowNegativeNumbers && inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */ && !backspaced) {
          base = inputValue.substring(0, inputValue.indexOf(decimalMarker));
        }
        // eslint-disable-next-line no-param-reassign
        inputValue = `${base}${inputValue.substring(inputValue.indexOf(decimalMarker), inputValue.length)}`;
      }
      let value = '';
      this.allowNegativeNumbers && inputValue.slice(cursor, cursor + 1) === "-" /* MaskExpression.MINUS */ ? value = `${"-" /* MaskExpression.MINUS */}${inputValue.slice(cursor + 1, cursor + inputValue.length)}` : value = inputValue;
      if (this.percentage(value)) {
        result = this._splitPercentZero(inputValue);
      } else {
        result = this._splitPercentZero(inputValue.substring(0, inputValue.length - 1));
      }
    } else if (maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
      if (inputValue.match('[wа-яА-Я]') || inputValue.match('[ЁёА-я]') || inputValue.match('[a-z]|[A-Z]') || inputValue.match(/[-@#!$%\\^&*()_£¬'+|~=`{}\]:";<>.?/]/) || inputValue.match('[^A-Za-z0-9,]')) {
        // eslint-disable-next-line no-param-reassign
        inputValue = this._stripToDecimal(inputValue);
      }
      const precision = this.getPrecision(maskExpression);
      const decimalMarker = Array.isArray(this.decimalMarker) ? "." /* MaskExpression.DOT */ : this.decimalMarker;
      if (precision === 0) {
        // eslint-disable-next-line no-param-reassign
        inputValue = this.allowNegativeNumbers ? inputValue.length > 2 && inputValue[0] === "-" /* MaskExpression.MINUS */ && inputValue[1] === "0" /* MaskExpression.NUMBER_ZERO */ && inputValue[2] !== this.thousandSeparator && inputValue[2] !== "," /* MaskExpression.COMMA */ && inputValue[2] !== "." /* MaskExpression.DOT */ ? '-' + inputValue.slice(2, inputValue.length) : inputValue[0] === "0" /* MaskExpression.NUMBER_ZERO */ && inputValue.length > 1 && inputValue[1] !== this.thousandSeparator && inputValue[1] !== "," /* MaskExpression.COMMA */ && inputValue[1] !== "." /* MaskExpression.DOT */ ? inputValue.slice(1, inputValue.length) : inputValue : inputValue.length > 1 && inputValue[0] === "0" /* MaskExpression.NUMBER_ZERO */ && inputValue[1] !== this.thousandSeparator && inputValue[1] !== "," /* MaskExpression.COMMA */ && inputValue[1] !== "." /* MaskExpression.DOT */ ? inputValue.slice(1, inputValue.length) : inputValue;
      } else {
        if (inputValue[0] === decimalMarker && inputValue.length > 1) {
          // eslint-disable-next-line no-param-reassign
          inputValue = "0" /* MaskExpression.NUMBER_ZERO */ + inputValue.slice(0, inputValue.length + 1);
          this.plusOnePosition = true;
        }
        if (inputValue[0] === "0" /* MaskExpression.NUMBER_ZERO */ && inputValue[1] !== decimalMarker && inputValue[1] !== this.thousandSeparator) {
          // eslint-disable-next-line no-param-reassign
          inputValue = inputValue.length > 1 ? inputValue.slice(0, 1) + decimalMarker + inputValue.slice(1, inputValue.length + 1) : inputValue;
          this.plusOnePosition = true;
        }
        if (this.allowNegativeNumbers && inputValue[0] === "-" /* MaskExpression.MINUS */ && (inputValue[1] === decimalMarker || inputValue[1] === "0" /* MaskExpression.NUMBER_ZERO */)) {
          // eslint-disable-next-line no-param-reassign
          inputValue = inputValue[1] === decimalMarker && inputValue.length > 2 ? inputValue.slice(0, 1) + "0" /* MaskExpression.NUMBER_ZERO */ + inputValue.slice(1, inputValue.length) : inputValue[1] === "0" /* MaskExpression.NUMBER_ZERO */ && inputValue.length > 2 && inputValue[2] !== decimalMarker ? inputValue.slice(0, 2) + decimalMarker + inputValue.slice(2, inputValue.length) : inputValue;
          this.plusOnePosition = true;
        }
      }
      if (backspaced) {
        const inputValueAfterZero = inputValue.slice(this._findFirstNonZeroDigitIndex(inputValue), inputValue.length);
        const positionOfZeroOrDecimalMarker = inputValue[position] === "0" /* MaskExpression.NUMBER_ZERO */ || inputValue[position] === decimalMarker;
        const zeroIndexNumberZero = inputValue[0] === "0" /* MaskExpression.NUMBER_ZERO */;
        const zeroIndexMinus = inputValue[0] === "-" /* MaskExpression.MINUS */;
        const zeroIndexThousand = inputValue[0] === this.thousandSeparator;
        const firstIndexDecimalMarker = inputValue[1] === decimalMarker;
        const firstIndexNumberZero = inputValue[1] === "0" /* MaskExpression.NUMBER_ZERO */;
        const secondIndexDecimalMarker = inputValue[2] === decimalMarker;
        if (zeroIndexNumberZero && firstIndexDecimalMarker && positionOfZeroOrDecimalMarker && position < 2) {
          // eslint-disable-next-line no-param-reassign
          inputValue = inputValueAfterZero;
        }
        if (zeroIndexMinus && firstIndexNumberZero && secondIndexDecimalMarker && positionOfZeroOrDecimalMarker && position < 3) {
          // eslint-disable-next-line no-param-reassign
          inputValue = "-" /* MaskExpression.MINUS */ + inputValueAfterZero;
        }
        if (inputValueAfterZero !== "-" /* MaskExpression.MINUS */ && (position === 0 && (zeroIndexNumberZero || zeroIndexThousand) || this.allowNegativeNumbers && position === 1 && zeroIndexMinus && !firstIndexNumberZero)) {
          // eslint-disable-next-line no-param-reassign
          inputValue = zeroIndexMinus ? "-" /* MaskExpression.MINUS */ + inputValueAfterZero : inputValueAfterZero;
        }
      }
      // TODO: we had different rexexps here for the different cases... but tests dont seam to bother - check this
      //  separator: no COMMA, dot-sep: no SPACE, COMMA OK, comma-sep: no SPACE, COMMA OK
      const thousandSeparatorCharEscaped = this._charToRegExpExpression(this.thousandSeparator);
      let invalidChars = '@#!$%^&*()_+|~=`{}\\[\\]:\\s,\\.";<>?\\/'.replace(thousandSeparatorCharEscaped, '');
      //.replace(decimalMarkerEscaped, '');
      if (Array.isArray(this.decimalMarker)) {
        for (const marker of this.decimalMarker) {
          invalidChars = invalidChars.replace(this._charToRegExpExpression(marker), "" /* MaskExpression.EMPTY_STRING */);
        }
      } else {
        invalidChars = invalidChars.replace(this._charToRegExpExpression(this.decimalMarker), '');
      }
      const invalidCharRegexp = new RegExp('[' + invalidChars + ']');
      if (inputValue.match(invalidCharRegexp)) {
        // eslint-disable-next-line no-param-reassign
        inputValue = inputValue.substring(0, inputValue.length - 1);
      }
      // eslint-disable-next-line no-param-reassign
      inputValue = this.checkInputPrecision(inputValue, precision, this.decimalMarker);
      const strForSep = inputValue.replace(new RegExp(thousandSeparatorCharEscaped, 'g'), '');
      result = this._formatWithSeparators(strForSep, this.thousandSeparator, this.decimalMarker, precision);
      const commaShift = result.indexOf("," /* MaskExpression.COMMA */) - inputValue.indexOf("," /* MaskExpression.COMMA */);
      const shiftStep = result.length - inputValue.length;
      if (result[position - 1] === this.thousandSeparator && this.prefix && backspaced) {
        // eslint-disable-next-line no-param-reassign
        position = position - 1;
      } else if (shiftStep > 0 && result[position] !== this.thousandSeparator) {
        backspaceShift = true;
        let _shift = 0;
        do {
          this._shift.add(position + _shift);
          _shift++;
        } while (_shift < shiftStep);
      } else if (result[position - 1] === this.decimalMarker || shiftStep === -4 || shiftStep === -3 || result[position] === this.thousandSeparator) {
        this._shift.clear();
        this._shift.add(position - 1);
      } else if (commaShift !== 0 && position > 0 && !(result.indexOf("," /* MaskExpression.COMMA */) >= position && position > 3) || !(result.indexOf("." /* MaskExpression.DOT */) >= position && position > 3) && shiftStep <= 0) {
        this._shift.clear();
        backspaceShift = true;
        shift = shiftStep;
        // eslint-disable-next-line no-param-reassign
        position += shiftStep;
        this._shift.add(position);
      } else {
        this._shift.clear();
      }
    } else {
      for (let i = 0, inputSymbol = inputArray[0]; i < inputArray.length; i++, inputSymbol = inputArray[i] ?? "" /* MaskExpression.EMPTY_STRING */) {
        if (cursor === maskExpression.length) {
          break;
        }
        const symbolStarInPattern = "*" /* MaskExpression.SYMBOL_STAR */ in this.patterns;
        if (this._checkSymbolMask(inputSymbol, maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */) && maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */) {
          result += inputSymbol;
          cursor += 2;
        } else if (maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ && multi && this._checkSymbolMask(inputSymbol, maskExpression[cursor + 2] ?? "" /* MaskExpression.EMPTY_STRING */)) {
          result += inputSymbol;
          cursor += 3;
          multi = false;
        } else if (this._checkSymbolMask(inputSymbol, maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */) && maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ && !symbolStarInPattern) {
          result += inputSymbol;
          multi = true;
        } else if (maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */ && this._checkSymbolMask(inputSymbol, maskExpression[cursor + 2] ?? "" /* MaskExpression.EMPTY_STRING */)) {
          result += inputSymbol;
          cursor += 3;
        } else if (this._checkSymbolMask(inputSymbol, maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */)) {
          if (maskExpression[cursor] === "H" /* MaskExpression.HOURS */) {
            if (this.apm ? Number(inputSymbol) > 9 : Number(inputSymbol) > 2) {
              // eslint-disable-next-line no-param-reassign
              position = !this.leadZeroDateTime ? position + 1 : position;
              cursor += 1;
              this._shiftStep(maskExpression, cursor, inputArray.length);
              i--;
              if (this.leadZeroDateTime) {
                result += '0';
              }
              continue;
            }
          }
          if (maskExpression[cursor] === "h" /* MaskExpression.HOUR */) {
            if (this.apm ? result.length === 1 && Number(result) > 1 || result === '1' && Number(inputSymbol) > 2 || inputValue.slice(cursor - 1, cursor).length === 1 && Number(inputValue.slice(cursor - 1, cursor)) > 2 || inputValue.slice(cursor - 1, cursor) === '1' && Number(inputSymbol) > 2 : result === '2' && Number(inputSymbol) > 3 || (result.slice(cursor - 2, cursor) === '2' || result.slice(cursor - 3, cursor) === '2' || result.slice(cursor - 4, cursor) === '2' || result.slice(cursor - 1, cursor) === '2') && Number(inputSymbol) > 3 && cursor > 10) {
              // eslint-disable-next-line no-param-reassign
              position = position + 1;
              cursor += 1;
              i--;
              continue;
            }
          }
          if (maskExpression[cursor] === "m" /* MaskExpression.MINUTE */ || maskExpression[cursor] === "s" /* MaskExpression.SECOND */) {
            if (Number(inputSymbol) > 5) {
              // eslint-disable-next-line no-param-reassign
              position = !this.leadZeroDateTime ? position + 1 : position;
              cursor += 1;
              this._shiftStep(maskExpression, cursor, inputArray.length);
              i--;
              if (this.leadZeroDateTime) {
                result += '0';
              }
              continue;
            }
          }
          const daysCount = 31;
          const inputValueCursor = inputValue[cursor];
          const inputValueCursorPlusOne = inputValue[cursor + 1];
          const inputValueCursorPlusTwo = inputValue[cursor + 2];
          const inputValueCursorMinusOne = inputValue[cursor - 1];
          const inputValueCursorMinusTwo = inputValue[cursor - 2];
          const inputValueSliceMinusThreeMinusOne = inputValue.slice(cursor - 3, cursor - 1);
          const inputValueSliceMinusOnePlusOne = inputValue.slice(cursor - 1, cursor + 1);
          const inputValueSliceCursorPlusTwo = inputValue.slice(cursor, cursor + 2);
          const inputValueSliceMinusTwoCursor = inputValue.slice(cursor - 2, cursor);
          if (maskExpression[cursor] === "d" /* MaskExpression.DAY */) {
            const maskStartWithMonth = maskExpression.slice(0, 2) === "M0" /* MaskExpression.MONTHS */;
            const startWithMonthInput = maskExpression.slice(0, 2) === "M0" /* MaskExpression.MONTHS */ && this.specialCharacters.includes(inputValueCursorMinusTwo);
            if (Number(inputSymbol) > 3 && this.leadZeroDateTime || !maskStartWithMonth && (Number(inputValueSliceCursorPlusTwo) > daysCount || Number(inputValueSliceMinusOnePlusOne) > daysCount || this.specialCharacters.includes(inputValueCursorPlusOne)) || (startWithMonthInput ? Number(inputValueSliceMinusOnePlusOne) > daysCount || !this.specialCharacters.includes(inputValueCursor) && this.specialCharacters.includes(inputValueCursorPlusTwo) || this.specialCharacters.includes(inputValueCursor) : Number(inputValueSliceCursorPlusTwo) > daysCount || this.specialCharacters.includes(inputValueCursorPlusOne))) {
              // eslint-disable-next-line no-param-reassign
              position = !this.leadZeroDateTime ? position + 1 : position;
              cursor += 1;
              this._shiftStep(maskExpression, cursor, inputArray.length);
              i--;
              if (this.leadZeroDateTime) {
                result += '0';
              }
              continue;
            }
          }
          if (maskExpression[cursor] === "M" /* MaskExpression.MONTH */) {
            const monthsCount = 12;
            // mask without day
            const withoutDays = cursor === 0 && (Number(inputSymbol) > 2 || Number(inputValueSliceCursorPlusTwo) > monthsCount || this.specialCharacters.includes(inputValueCursorPlusOne) && !backspaced);
            // day<10 && month<12 for input
            const specialChart = maskExpression.slice(cursor + 2, cursor + 3);
            const day1monthInput = inputValueSliceMinusThreeMinusOne.includes(specialChart) && maskExpression.includes('d0') && (this.specialCharacters.includes(inputValueCursorMinusTwo) && Number(inputValueSliceMinusOnePlusOne) > monthsCount && !this.specialCharacters.includes(inputValueCursor) || this.specialCharacters.includes(inputValueCursor));
            //  month<12 && day<10 for input
            const day2monthInput = Number(inputValueSliceMinusThreeMinusOne) <= daysCount && !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) && this.specialCharacters.includes(inputValueCursorMinusOne) && (Number(inputValueSliceCursorPlusTwo) > monthsCount || this.specialCharacters.includes(inputValueCursorPlusOne));
            // cursor === 5 && without days
            const day2monthInputDot = Number(inputValueSliceCursorPlusTwo) > monthsCount && cursor === 5 || this.specialCharacters.includes(inputValueCursorPlusOne) && cursor === 5;
            // // day<10 && month<12 for paste whole data
            const day1monthPaste = Number(inputValueSliceMinusThreeMinusOne) > daysCount && !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) && !this.specialCharacters.includes(inputValueSliceMinusTwoCursor) && Number(inputValueSliceMinusTwoCursor) > monthsCount && maskExpression.includes('d0');
            // 10<day<31 && month<12 for paste whole data
            const day2monthPaste = Number(inputValueSliceMinusThreeMinusOne) <= daysCount && !this.specialCharacters.includes(inputValueSliceMinusThreeMinusOne) && !this.specialCharacters.includes(inputValueCursorMinusOne) && Number(inputValueSliceMinusOnePlusOne) > monthsCount;
            if (Number(inputSymbol) > 1 && this.leadZeroDateTime || withoutDays || day1monthInput || day2monthPaste || day1monthPaste || day2monthInput || day2monthInputDot && !this.leadZeroDateTime) {
              // eslint-disable-next-line no-param-reassign
              position = !this.leadZeroDateTime ? position + 1 : position;
              cursor += 1;
              this._shiftStep(maskExpression, cursor, inputArray.length);
              i--;
              if (this.leadZeroDateTime) {
                result += '0';
              }
              continue;
            }
          }
          result += inputSymbol;
          cursor++;
        } else if (this.specialCharacters.includes(inputSymbol) && maskExpression[cursor] === inputSymbol) {
          result += inputSymbol;
          cursor++;
        } else if (this.specialCharacters.indexOf(maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */) !== -1) {
          result += maskExpression[cursor];
          cursor++;
          this._shiftStep(maskExpression, cursor, inputArray.length);
          i--;
        } else if (maskExpression[cursor] === "9" /* MaskExpression.NUMBER_NINE */ && this.showMaskTyped) {
          this._shiftStep(maskExpression, cursor, inputArray.length);
        } else if (this.patterns[maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */] && this.patterns[maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */]?.optional) {
          if (!!inputArray[cursor] && maskExpression !== '099.099.099.099' && maskExpression !== '000.000.000-00' && maskExpression !== '00.000.000/0000-00' && !maskExpression.match(/^9+\.0+$/) && !this.patterns[maskExpression[cursor] ?? "" /* MaskExpression.EMPTY_STRING */]?.optional) {
            result += inputArray[cursor];
          }
          if (maskExpression.includes("9" /* MaskExpression.NUMBER_NINE */ + "*" /* MaskExpression.SYMBOL_STAR */) && maskExpression.includes("0" /* MaskExpression.NUMBER_ZERO */ + "*" /* MaskExpression.SYMBOL_STAR */)) {
            cursor++;
          }
          cursor++;
          i--;
        } else if (this.maskExpression[cursor + 1] === "*" /* MaskExpression.SYMBOL_STAR */ && this._findSpecialChar(this.maskExpression[cursor + 2] ?? "" /* MaskExpression.EMPTY_STRING */) && this._findSpecialChar(inputSymbol) === this.maskExpression[cursor + 2] && multi) {
          cursor += 3;
          result += inputSymbol;
        } else if (this.maskExpression[cursor + 1] === "?" /* MaskExpression.SYMBOL_QUESTION */ && this._findSpecialChar(this.maskExpression[cursor + 2] ?? "" /* MaskExpression.EMPTY_STRING */) && this._findSpecialChar(inputSymbol) === this.maskExpression[cursor + 2] && multi) {
          cursor += 3;
          result += inputSymbol;
        } else if (this.showMaskTyped && this.specialCharacters.indexOf(inputSymbol) < 0 && inputSymbol !== this.placeHolderCharacter && this.placeHolderCharacter.length === 1) {
          stepBack = true;
        }
      }
    }
    if (result.length + 1 === maskExpression.length && this.specialCharacters.indexOf(maskExpression[maskExpression.length - 1] ?? "" /* MaskExpression.EMPTY_STRING */) !== -1) {
      result += maskExpression[maskExpression.length - 1];
    }
    let newPosition = position + 1;
    while (this._shift.has(newPosition)) {
      shift++;
      newPosition++;
    }
    let actualShift = justPasted && !maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) ? cursor : this._shift.has(position) ? shift : 0;
    if (stepBack) {
      actualShift--;
    }
    cb(actualShift, backspaceShift);
    if (shift < 0) {
      this._shift.clear();
    }
    let onlySpecial = false;
    if (backspaced) {
      onlySpecial = inputArray.every(char => this.specialCharacters.includes(char));
    }
    let res = `${this.prefix}${onlySpecial ? "" /* MaskExpression.EMPTY_STRING */ : result}${this.showMaskTyped ? '' : this.suffix}`;
    if (result.length === 0) {
      res = !this.dropSpecialCharacters ? `${this.prefix}${result}` : `${result}`;
    }
    const isSpecialCharacterMaskFirstSymbol = inputValue.length === 1 && this.specialCharacters.includes(maskExpression[0]) && inputValue !== maskExpression[0];
    if (!this._checkSymbolMask(inputValue, maskExpression[1]) && isSpecialCharacterMaskFirstSymbol) {
      return '';
    }
    if (result.includes("-" /* MaskExpression.MINUS */) && this.prefix && this.allowNegativeNumbers) {
      if (backspaced && result === "-" /* MaskExpression.MINUS */) {
        return '';
      }
      res = `${"-" /* MaskExpression.MINUS */}${this.prefix}${result.split("-" /* MaskExpression.MINUS */).join("" /* MaskExpression.EMPTY_STRING */)}${this.suffix}`;
    }
    return res;
  }
  _findDropSpecialChar(inputSymbol) {
    if (Array.isArray(this.dropSpecialCharacters)) {
      return this.dropSpecialCharacters.find(val => val === inputSymbol);
    }
    return this._findSpecialChar(inputSymbol);
  }
  _findSpecialChar(inputSymbol) {
    return this.specialCharacters.find(val => val === inputSymbol);
  }
  _checkSymbolMask(inputSymbol, maskSymbol) {
    this.patterns = this.customPattern ? this.customPattern : this.patterns;
    return (this.patterns[maskSymbol]?.pattern && this.patterns[maskSymbol]?.pattern.test(inputSymbol)) ?? false;
  }
  _stripToDecimal(str) {
    return str.split("" /* MaskExpression.EMPTY_STRING */).filter((i, idx) => {
      const isDecimalMarker = typeof this.decimalMarker === 'string' ? i === this.decimalMarker :
      // TODO (inepipenko) use utility type
      this.decimalMarker.includes(i);
      return i.match('^-?\\d') || i === this.thousandSeparator || isDecimalMarker || i === "-" /* MaskExpression.MINUS */ && idx === 0 && this.allowNegativeNumbers;
    }).join("" /* MaskExpression.EMPTY_STRING */);
  }
  _charToRegExpExpression(char) {
    // if (Array.isArray(char)) {
    // 	return char.map((v) => ('[\\^$.|?*+()'.indexOf(v) >= 0 ? `\\${v}` : v)).join('|');
    // }
    if (char) {
      const charsToEscape = '[\\^$.|?*+()';
      return char === ' ' ? '\\s' : charsToEscape.indexOf(char) >= 0 ? `\\${char}` : char;
    }
    return char;
  }
  _shiftStep(maskExpression, cursor, inputLength) {
    const shiftStep = /[*?]/g.test(maskExpression.slice(0, cursor)) ? inputLength : cursor;
    this._shift.add(shiftStep + this.prefix.length || 0);
  }
  _compareOrIncludes(value, comparedValue, excludedValue) {
    return Array.isArray(comparedValue) ? comparedValue.filter(v => v !== excludedValue).includes(value) : value === comparedValue;
  }
  _validIP(valuesIP) {
    return !(valuesIP.length === 4 && !valuesIP.some((value, index) => {
      if (valuesIP.length !== index + 1) {
        return value === "" /* MaskExpression.EMPTY_STRING */ || Number(value) > 255;
      }
      return value === "" /* MaskExpression.EMPTY_STRING */ || Number(value.substring(0, 3)) > 255;
    }));
  }
  _splitPercentZero(value) {
    if (value === "-" /* MaskExpression.MINUS */ && this.allowNegativeNumbers) {
      return value;
    }
    const decimalIndex = typeof this.decimalMarker === 'string' ? value.indexOf(this.decimalMarker) : value.indexOf("." /* MaskExpression.DOT */);
    const emptyOrMinus = this.allowNegativeNumbers && value.includes("-" /* MaskExpression.MINUS */) ? '-' : '';
    if (decimalIndex === -1) {
      const parsedValue = parseInt(emptyOrMinus ? value.slice(1, value.length) : value, 10);
      return isNaN(parsedValue) ? "" /* MaskExpression.EMPTY_STRING */ : `${emptyOrMinus}${parsedValue}`;
    } else {
      const integerPart = parseInt(value.replace('-', '').substring(0, decimalIndex), 10);
      const decimalPart = value.substring(decimalIndex + 1);
      const integerString = isNaN(integerPart) ? '' : integerPart.toString();
      const decimal = typeof this.decimalMarker === 'string' ? this.decimalMarker : "." /* MaskExpression.DOT */;
      return integerString === "" /* MaskExpression.EMPTY_STRING */ ? "" /* MaskExpression.EMPTY_STRING */ : `${emptyOrMinus}${integerString}${decimal}${decimalPart}`;
    }
  }
  _findFirstNonZeroDigitIndex(inputString) {
    for (let i = 0; i < inputString.length; i++) {
      const char = inputString[i];
      if (char && char >= '1' && char <= '9') {
        return i;
      }
    }
    return -1;
  }
  static {
    this.ɵfac = function NgxMaskApplierService_Factory(t) {
      return new (t || NgxMaskApplierService)();
    };
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: NgxMaskApplierService,
      factory: NgxMaskApplierService.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxMaskApplierService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();
class NgxMaskService extends NgxMaskApplierService {
  constructor() {
    super(...arguments);
    this.isNumberValue = false;
    this.maskIsShown = '';
    this.selStart = null;
    this.selEnd = null;
    /**
     * Whether we are currently in writeValue function, in this case when applying the mask we don't want to trigger onChange function,
     * since writeValue should be a one way only process of writing the DOM value based on the Angular model value.
     */
    this.writingValue = false;
    this.maskChanged = false;
    this._maskExpressionArray = [];
    this.triggerOnMaskChange = false;
    this._previousValue = '';
    this._currentValue = '';
    this._emitValue = false;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    this.onChange = _ => {};
    this._elementRef = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef, {
      optional: true
    });
    this.document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT);
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_MASK_CONFIG);
    this._renderer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_1__.Renderer2, {
      optional: true
    });
  }
  applyMask(inputValue, maskExpression, position = 0, justPasted = false, backspaced = false,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  cb = () => {}) {
    if (!maskExpression) {
      return inputValue !== this.actualValue ? this.actualValue : inputValue;
    }
    this.maskIsShown = this.showMaskTyped ? this.showMaskInInput() : "" /* MaskExpression.EMPTY_STRING */;
    if (this.maskExpression === "IP" /* MaskExpression.IP */ && this.showMaskTyped) {
      this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
    }
    if (this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */ && this.showMaskTyped) {
      this.maskIsShown = this.showMaskInInput(inputValue || "#" /* MaskExpression.HASH */);
    }
    if (!inputValue && this.showMaskTyped) {
      this.formControlResult(this.prefix);
      return `${this.prefix}${this.maskIsShown}${this.suffix}`;
    }
    const getSymbol = !!inputValue && typeof this.selStart === 'number' ? inputValue[this.selStart] ?? "" /* MaskExpression.EMPTY_STRING */ : "" /* MaskExpression.EMPTY_STRING */;
    let newInputValue = '';
    if (this.hiddenInput !== undefined && !this.writingValue) {
      let actualResult = inputValue && inputValue.length === 1 ? inputValue.split("" /* MaskExpression.EMPTY_STRING */) : this.actualValue.split("" /* MaskExpression.EMPTY_STRING */);
      // eslint-disable  @typescript-eslint/no-unused-expressions
      if (typeof this.selStart === 'object' && typeof this.selEnd === 'object') {
        this.selStart = Number(this.selStart);
        this.selEnd = Number(this.selEnd);
      } else {
        inputValue !== "" /* MaskExpression.EMPTY_STRING */ && actualResult.length ? typeof this.selStart === 'number' && typeof this.selEnd === 'number' ? inputValue.length > actualResult.length ? actualResult.splice(this.selStart, 0, getSymbol) : inputValue.length < actualResult.length ? actualResult.length - inputValue.length === 1 ? backspaced ? actualResult.splice(this.selStart - 1, 1) : actualResult.splice(inputValue.length - 1, 1) : actualResult.splice(this.selStart, this.selEnd - this.selStart) : null : null : actualResult = [];
      }
      if (this.showMaskTyped) {
        if (!this.hiddenInput) {
          // eslint-disable-next-line no-param-reassign
          inputValue = this.removeMask(inputValue);
        }
      }
      // eslint-enable  @typescript-eslint/no-unused-expressions
      newInputValue = this.actualValue.length && actualResult.length <= inputValue.length ? this.shiftTypedSymbols(actualResult.join("" /* MaskExpression.EMPTY_STRING */)) : inputValue;
    }
    if (justPasted && (this.hiddenInput || !this.hiddenInput)) {
      newInputValue = inputValue;
    }
    if (backspaced && this.specialCharacters.indexOf(this.maskExpression[position] ?? "" /* MaskExpression.EMPTY_STRING */) !== -1 && this.showMaskTyped && !this.prefix) {
      newInputValue = this._currentValue;
    }
    if (this.deletedSpecialCharacter && position) {
      if (this.specialCharacters.includes(this.actualValue.slice(position, position + 1))) {
        // eslint-disable-next-line no-param-reassign
        position = position + 1;
      } else if (maskExpression.slice(position - 1, position + 1) !== "M0" /* MaskExpression.MONTHS */) {
        // eslint-disable-next-line no-param-reassign
        position = position - 2;
      }
      this.deletedSpecialCharacter = false;
    }
    if (this.showMaskTyped && this.placeHolderCharacter.length === 1 && !this.leadZeroDateTime) {
      // eslint-disable-next-line no-param-reassign
      inputValue = this.removeMask(inputValue);
    }
    if (this.maskChanged) {
      newInputValue = inputValue;
    } else {
      newInputValue = Boolean(newInputValue) && newInputValue.length ? newInputValue : inputValue;
    }
    if (this.showMaskTyped && this.keepCharacterPositions && this.actualValue && !justPasted && !this.writingValue) {
      const value = this.dropSpecialCharacters ? this.removeMask(this.actualValue) : this.actualValue;
      this.formControlResult(value);
      return this.actualValue ? this.actualValue : `${this.prefix}${this.maskIsShown}${this.suffix}`;
    }
    const result = super.applyMask(newInputValue, maskExpression, position, justPasted, backspaced, cb);
    this.actualValue = this.getActualValue(result);
    // handle some separator implications:
    // a.) adjust decimalMarker default (. -> ,) if thousandSeparator is a dot
    if (this.thousandSeparator === "." /* MaskExpression.DOT */ && this.decimalMarker === "." /* MaskExpression.DOT */) {
      this.decimalMarker = "," /* MaskExpression.COMMA */;
    }
    // b) remove decimal marker from list of special characters to mask
    if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && this.dropSpecialCharacters === true) {
      this.specialCharacters = this.specialCharacters.filter(item => !this._compareOrIncludes(item, this.decimalMarker, this.thousandSeparator) //item !== this.decimalMarker, // !
      );
    }
    if (result || result === '') {
      this._previousValue = this._currentValue;
      this._currentValue = result;
      this._emitValue = this._previousValue !== this._currentValue || this.maskChanged || this._previousValue === this._currentValue && justPasted;
    }
    this._emitValue ? this.writingValue && this.triggerOnMaskChange ? requestAnimationFrame(() => this.formControlResult(result)) : this.formControlResult(result) : '';
    if (!this.showMaskTyped || this.showMaskTyped && this.hiddenInput) {
      if (this.hiddenInput) {
        if (backspaced) {
          return this.hideInput(result, this.maskExpression);
        }
        return `${this.hideInput(result, this.maskExpression)}${this.maskIsShown.slice(result.length)}`;
      }
      return result;
    }
    const resLen = result.length;
    const prefNmask = `${this.prefix}${this.maskIsShown}${this.suffix}`;
    if (this.maskExpression.includes("H" /* MaskExpression.HOURS */)) {
      const countSkipedSymbol = this._numberSkipedSymbols(result);
      return `${result}${prefNmask.slice(resLen + countSkipedSymbol)}`;
    } else if (this.maskExpression === "IP" /* MaskExpression.IP */ || this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
      return `${result}${prefNmask}`;
    }
    return `${result}${prefNmask.slice(resLen)}`;
  }
  // get the number of characters that were shifted
  _numberSkipedSymbols(value) {
    const regex = /(^|\D)(\d\D)/g;
    let match = regex.exec(value);
    let countSkipedSymbol = 0;
    while (match != null) {
      countSkipedSymbol += 1;
      match = regex.exec(value);
    }
    return countSkipedSymbol;
  }
  applyValueChanges(position, justPasted, backspaced,
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  cb = () => {}) {
    const formElement = this._elementRef?.nativeElement;
    if (!formElement) {
      return;
    }
    formElement.value = this.applyMask(formElement.value, this.maskExpression, position, justPasted, backspaced, cb);
    if (formElement === this._getActiveElement()) {
      return;
    }
    this.clearIfNotMatchFn();
  }
  hideInput(inputValue, maskExpression) {
    return inputValue.split("" /* MaskExpression.EMPTY_STRING */).map((curr, index) => {
      if (this.patterns && this.patterns[maskExpression[index] ?? "" /* MaskExpression.EMPTY_STRING */] && this.patterns[maskExpression[index] ?? "" /* MaskExpression.EMPTY_STRING */]?.symbol) {
        return this.patterns[maskExpression[index] ?? "" /* MaskExpression.EMPTY_STRING */]?.symbol;
      }
      return curr;
    }).join("" /* MaskExpression.EMPTY_STRING */);
  }
  // this function is not necessary, it checks result against maskExpression
  getActualValue(res) {
    const compare = res.split("" /* MaskExpression.EMPTY_STRING */).filter((symbol, i) => {
      const maskChar = this.maskExpression[i] ?? "" /* MaskExpression.EMPTY_STRING */;
      return this._checkSymbolMask(symbol, maskChar) || this.specialCharacters.includes(maskChar) && symbol === maskChar;
    });
    if (compare.join("" /* MaskExpression.EMPTY_STRING */) === res) {
      return compare.join("" /* MaskExpression.EMPTY_STRING */);
    }
    return res;
  }
  shiftTypedSymbols(inputValue) {
    let symbolToReplace = '';
    const newInputValue = inputValue && inputValue.split("" /* MaskExpression.EMPTY_STRING */).map((currSymbol, index) => {
      if (this.specialCharacters.includes(inputValue[index + 1] ?? "" /* MaskExpression.EMPTY_STRING */) && inputValue[index + 1] !== this.maskExpression[index + 1]) {
        symbolToReplace = currSymbol;
        return inputValue[index + 1];
      }
      if (symbolToReplace.length) {
        const replaceSymbol = symbolToReplace;
        symbolToReplace = "" /* MaskExpression.EMPTY_STRING */;
        return replaceSymbol;
      }
      return currSymbol;
    }) || [];
    return newInputValue.join("" /* MaskExpression.EMPTY_STRING */);
  }
  /**
   * Convert number value to string
   * 3.1415 -> '3.1415'
   * 1e-7 -> '0.0000001'
   */
  numberToString(value) {
    if (!value && value !== 0 || this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && (this.leadZero || !this.dropSpecialCharacters) || this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && this.separatorLimit.length > 14 && String(value).length > 14) {
      return String(value);
    }
    return Number(value).toLocaleString('fullwide', {
      useGrouping: false,
      maximumFractionDigits: 20
    }).replace(`/${"-" /* MaskExpression.MINUS */}/`, "-" /* MaskExpression.MINUS */);
  }
  showMaskInInput(inputVal) {
    if (this.showMaskTyped && !!this.shownMaskExpression) {
      if (this.maskExpression.length !== this.shownMaskExpression.length) {
        throw new Error('Mask expression must match mask placeholder length');
      } else {
        return this.shownMaskExpression;
      }
    } else if (this.showMaskTyped) {
      if (inputVal) {
        if (this.maskExpression === "IP" /* MaskExpression.IP */) {
          return this._checkForIp(inputVal);
        }
        if (this.maskExpression === "CPF_CNPJ" /* MaskExpression.CPF_CNPJ */) {
          return this._checkForCpfCnpj(inputVal);
        }
      }
      if (this.placeHolderCharacter.length === this.maskExpression.length) {
        return this.placeHolderCharacter;
      }
      return this.maskExpression.replace(/\w/g, this.placeHolderCharacter);
    }
    return '';
  }
  clearIfNotMatchFn() {
    const formElement = this._elementRef?.nativeElement;
    if (!formElement) {
      return;
    }
    if (this.clearIfNotMatch && this.prefix.length + this.maskExpression.length + this.suffix.length !== formElement.value.replace(this.placeHolderCharacter, "" /* MaskExpression.EMPTY_STRING */).length) {
      this.formElementProperty = ['value', "" /* MaskExpression.EMPTY_STRING */];
      this.applyMask('', this.maskExpression);
    }
  }
  set formElementProperty([name, value]) {
    if (!this._renderer || !this._elementRef) {
      return;
    }
    //[TODO]: andriikamaldinov1 find better solution
    Promise.resolve().then(() => this._renderer?.setProperty(this._elementRef?.nativeElement, name, value));
  }
  checkDropSpecialCharAmount(mask) {
    const chars = mask.split("" /* MaskExpression.EMPTY_STRING */).filter(item => this._findDropSpecialChar(item));
    return chars.length;
  }
  removeMask(inputValue) {
    return this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.specialCharacters.concat('_').concat(this.placeHolderCharacter));
  }
  _checkForIp(inputVal) {
    if (inputVal === "#" /* MaskExpression.HASH */) {
      return `${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}`;
    }
    const arr = [];
    for (let i = 0; i < inputVal.length; i++) {
      const value = inputVal[i] ?? "" /* MaskExpression.EMPTY_STRING */;
      if (!value) {
        continue;
      }
      if (value.match('\\d')) {
        arr.push(value);
      }
    }
    if (arr.length <= 3) {
      return `${this.placeHolderCharacter}.${this.placeHolderCharacter}.${this.placeHolderCharacter}`;
    }
    if (arr.length > 3 && arr.length <= 6) {
      return `${this.placeHolderCharacter}.${this.placeHolderCharacter}`;
    }
    if (arr.length > 6 && arr.length <= 9) {
      return this.placeHolderCharacter;
    }
    if (arr.length > 9 && arr.length <= 12) {
      return '';
    }
    return '';
  }
  _checkForCpfCnpj(inputVal) {
    const cpf = `${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `.${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `.${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `-${this.placeHolderCharacter}${this.placeHolderCharacter}`;
    const cnpj = `${this.placeHolderCharacter}${this.placeHolderCharacter}` + `.${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `.${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `/${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}${this.placeHolderCharacter}` + `-${this.placeHolderCharacter}${this.placeHolderCharacter}`;
    if (inputVal === "#" /* MaskExpression.HASH */) {
      return cpf;
    }
    const arr = [];
    for (let i = 0; i < inputVal.length; i++) {
      const value = inputVal[i] ?? "" /* MaskExpression.EMPTY_STRING */;
      if (!value) {
        continue;
      }
      if (value.match('\\d')) {
        arr.push(value);
      }
    }
    if (arr.length <= 3) {
      return cpf.slice(arr.length, cpf.length);
    }
    if (arr.length > 3 && arr.length <= 6) {
      return cpf.slice(arr.length + 1, cpf.length);
    }
    if (arr.length > 6 && arr.length <= 9) {
      return cpf.slice(arr.length + 2, cpf.length);
    }
    if (arr.length > 9 && arr.length < 11) {
      return cpf.slice(arr.length + 3, cpf.length);
    }
    if (arr.length === 11) {
      return '';
    }
    if (arr.length === 12) {
      if (inputVal.length === 17) {
        return cnpj.slice(16, cnpj.length);
      }
      return cnpj.slice(15, cnpj.length);
    }
    if (arr.length > 12 && arr.length <= 14) {
      return cnpj.slice(arr.length + 4, cnpj.length);
    }
    return '';
  }
  /**
   * Recursively determine the current active element by navigating the Shadow DOM until the Active Element is found.
   */
  _getActiveElement(document = this.document) {
    const shadowRootEl = document?.activeElement?.shadowRoot;
    if (!shadowRootEl?.activeElement) {
      return document.activeElement;
    } else {
      return this._getActiveElement(shadowRootEl);
    }
  }
  /**
   * Propogates the input value back to the Angular model by triggering the onChange function. It won't do this if writingValue
   * is true. If that is true it means we are currently in the writeValue function, which is supposed to only update the actual
   * DOM element based on the Angular model value. It should be a one way process, i.e. writeValue should not be modifying the Angular
   * model value too. Therefore, we don't trigger onChange in this scenario.
   * @param inputValue the current form input value
   */
  formControlResult(inputValue) {
    if (this.writingValue || !this.triggerOnMaskChange && this.maskChanged) {
      this.triggerOnMaskChange && this.maskChanged ? this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue)))))) : '';
      this.maskChanged = false;
      return;
    }
    if (Array.isArray(this.dropSpecialCharacters)) {
      this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeMask(this._removeSuffix(this._removePrefix(inputValue)), this.dropSpecialCharacters)))));
    } else if (this.dropSpecialCharacters || !this.dropSpecialCharacters && this.prefix === inputValue) {
      this.onChange(this.outputTransformFn(this._toNumber(this._checkSymbols(this._removeSuffix(this._removePrefix(inputValue))))));
    } else {
      this.onChange(this.outputTransformFn(this._toNumber(inputValue)));
    }
  }
  _toNumber(value) {
    if (!this.isNumberValue || value === "" /* MaskExpression.EMPTY_STRING */) {
      return value;
    }
    if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && (this.leadZero || !this.dropSpecialCharacters)) {
      return value;
    }
    if (String(value).length > 16 && this.separatorLimit.length > 14) {
      return String(value);
    }
    const num = Number(value);
    if (this.maskExpression.startsWith("separator" /* MaskExpression.SEPARATOR */) && Number.isNaN(num)) {
      const val = String(value).replace(',', '.');
      return Number(val);
    }
    return Number.isNaN(num) ? value : num;
  }
  _removeMask(value, specialCharactersForRemove) {
    if (this.maskExpression.startsWith("percent" /* MaskExpression.PERCENT */) && value.includes("." /* MaskExpression.DOT */)) {
      return value;
    }
    return value ? value.replace(this._regExpForRemove(specialCharactersForRemove), "" /* MaskExpression.EMPTY_STRING */) : value;
  }
  _removePrefix(value) {
    if (!this.prefix) {
      return value;
    }
    return value ? value.replace(this.prefix, "" /* MaskExpression.EMPTY_STRING */) : value;
  }
  _removeSuffix(value) {
    if (!this.suffix) {
      return value;
    }
    return value ? value.replace(this.suffix, "" /* MaskExpression.EMPTY_STRING */) : value;
  }
  _retrieveSeparatorValue(result) {
    let specialCharacters = Array.isArray(this.dropSpecialCharacters) ? this.specialCharacters.filter(v => {
      return this.dropSpecialCharacters.includes(v);
    }) : this.specialCharacters;
    if (!this.deletedSpecialCharacter && this._checkPatternForSpace() && result.includes(" " /* MaskExpression.WHITE_SPACE */) && this.maskExpression.includes("*" /* MaskExpression.SYMBOL_STAR */)) {
      specialCharacters = specialCharacters.filter(char => char !== " " /* MaskExpression.WHITE_SPACE */);
    }
    return this._removeMask(result, specialCharacters);
  }
  _regExpForRemove(specialCharactersForRemove) {
    return new RegExp(specialCharactersForRemove.map(item => `\\${item}`).join('|'), 'gi');
  }
  _replaceDecimalMarkerToDot(value) {
    const markers = Array.isArray(this.decimalMarker) ? this.decimalMarker : [this.decimalMarker];
    return value.replace(this._regExpForRemove(markers), "." /* MaskExpression.DOT */);
  }
  _checkSymbols(result) {
    if (result === "" /* MaskExpression.EMPTY_STRING */) {
      return result;
    }
    if (this.maskExpression.startsWith("percent" /* MaskExpression.PERCENT */) && this.decimalMarker === "," /* MaskExpression.COMMA */) {
      // eslint-disable-next-line no-param-reassign
      result = result.replace("," /* MaskExpression.COMMA */, "." /* MaskExpression.DOT */);
    }
    const separatorPrecision = this._retrieveSeparatorPrecision(this.maskExpression);
    const separatorValue = this._replaceDecimalMarkerToDot(this._retrieveSeparatorValue(result));
    if (!this.isNumberValue) {
      return separatorValue;
    }
    if (separatorPrecision) {
      if (result === this.decimalMarker) {
        return null;
      }
      if (this.separatorLimit.length > 14) {
        return String(separatorValue);
      }
      return this._checkPrecision(this.maskExpression, separatorValue);
    } else {
      return separatorValue;
    }
  }
  _checkPatternForSpace() {
    for (const key in this.patterns) {
      // eslint-disable-next-line no-prototype-builtins
      if (this.patterns[key] && this.patterns[key]?.hasOwnProperty('pattern')) {
        const patternString = this.patterns[key]?.pattern.toString();
        const pattern = this.patterns[key]?.pattern;
        if (patternString?.includes(" " /* MaskExpression.WHITE_SPACE */) && pattern?.test(this.maskExpression)) {
          return true;
        }
      }
    }
    return false;
  }
  // TODO should think about helpers or separting decimal precision to own property
  _retrieveSeparatorPrecision(maskExpretion) {
    const matcher = maskExpretion.match(new RegExp(`^separator\\.([^d]*)`));
    return matcher ? Number(matcher[1]) : null;
  }
  _checkPrecision(separatorExpression, separatorValue) {
    const separatorPrecision = separatorExpression.slice(10, 11);
    if (separatorExpression.indexOf('2') > 0 || this.leadZero && Number(separatorPrecision) > 0) {
      if (this.decimalMarker === "," /* MaskExpression.COMMA */ && this.leadZero) {
        // eslint-disable-next-line no-param-reassign
        separatorValue = separatorValue.replace(',', '.');
      }
      return this.leadZero ? Number(separatorValue).toFixed(Number(separatorPrecision)) : Number(separatorValue).toFixed(2);
    }
    return this.numberToString(separatorValue);
  }
  _repeatPatternSymbols(maskExp) {
    return maskExp.match(/{[0-9]+}/) && maskExp.split("" /* MaskExpression.EMPTY_STRING */).reduce((accum, currVal, index) => {
      this._start = currVal === "{" /* MaskExpression.CURLY_BRACKETS_LEFT */ ? index : this._start;
      if (currVal !== "}" /* MaskExpression.CURLY_BRACKETS_RIGHT */) {
        return this._findSpecialChar(currVal) ? accum + currVal : accum;
      }
      this._end = index;
      const repeatNumber = Number(maskExp.slice(this._start + 1, this._end));
      const replaceWith = new Array(repeatNumber + 1).join(maskExp[this._start - 1]);
      if (maskExp.slice(0, this._start).length > 1 && maskExp.includes("S" /* MaskExpression.LETTER_S */)) {
        const symbols = maskExp.slice(0, this._start - 1);
        return symbols.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) ? accum + replaceWith : symbols + accum + replaceWith;
      } else {
        return accum + replaceWith;
      }
    }, '') || maskExp;
  }
  currentLocaleDecimalMarker() {
    return 1.1.toLocaleString().substring(1, 2);
  }
  static {
    this.ɵfac = /* @__PURE__ */(() => {
      let ɵNgxMaskService_BaseFactory;
      return function NgxMaskService_Factory(t) {
        return (ɵNgxMaskService_BaseFactory || (ɵNgxMaskService_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵgetInheritedFactory"](NgxMaskService)))(t || NgxMaskService);
      };
    })();
  }
  static {
    this.ɵprov = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjectable"]({
      token: NgxMaskService,
      factory: NgxMaskService.ɵfac
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxMaskService, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Injectable
  }], null, null);
})();

/**
 * @internal
 */
function _configFactory() {
  const initConfig = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(INITIAL_CONFIG);
  const configValue = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NEW_CONFIG);
  return configValue instanceof Function ? {
    ...initConfig,
    ...configValue()
  } : {
    ...initConfig,
    ...configValue
  };
}
function provideNgxMask(configValue) {
  return [{
    provide: NEW_CONFIG,
    useValue: configValue
  }, {
    provide: INITIAL_CONFIG,
    useValue: initialConfig
  }, {
    provide: NGX_MASK_CONFIG,
    useFactory: _configFactory
  }, NgxMaskService];
}
function provideEnvironmentNgxMask(configValue) {
  return (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.makeEnvironmentProviders)(provideNgxMask(configValue));
}
class NgxMaskDirective {
  constructor() {
    this.maskExpression = '';
    this.specialCharacters = [];
    this.patterns = {};
    this.prefix = '';
    this.suffix = '';
    this.thousandSeparator = ' ';
    this.decimalMarker = '.';
    this.dropSpecialCharacters = null;
    this.hiddenInput = null;
    this.showMaskTyped = null;
    this.placeHolderCharacter = null;
    this.shownMaskExpression = null;
    this.showTemplate = null;
    this.clearIfNotMatch = null;
    this.validation = null;
    this.separatorLimit = null;
    this.allowNegativeNumbers = null;
    this.leadZeroDateTime = null;
    this.leadZero = null;
    this.triggerOnMaskChange = null;
    this.apm = null;
    this.inputTransformFn = null;
    this.outputTransformFn = null;
    this.keepCharacterPositions = null;
    this.maskFilled = new _angular_core__WEBPACK_IMPORTED_MODULE_1__.EventEmitter();
    this._maskValue = '';
    this._position = null;
    this._maskExpressionArray = [];
    this._allowFewMaskChangeMask = false;
    this._justPasted = false;
    this._isFocused = false;
    /**For IME composition event */
    this._isComposing = false;
    this.document = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(_angular_common__WEBPACK_IMPORTED_MODULE_2__.DOCUMENT);
    this._maskService = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NgxMaskService, {
      self: true
    });
    this._config = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_MASK_CONFIG);
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    this.onChange = _ => {};
    this.onTouch = () => {};
  }
  ngOnChanges(changes) {
    const {
      maskExpression,
      specialCharacters,
      patterns,
      prefix,
      suffix,
      thousandSeparator,
      decimalMarker,
      dropSpecialCharacters,
      hiddenInput,
      showMaskTyped,
      placeHolderCharacter,
      shownMaskExpression,
      showTemplate,
      clearIfNotMatch,
      validation,
      separatorLimit,
      allowNegativeNumbers,
      leadZeroDateTime,
      leadZero,
      triggerOnMaskChange,
      apm,
      inputTransformFn,
      outputTransformFn,
      keepCharacterPositions
    } = changes;
    if (maskExpression) {
      if (maskExpression.currentValue !== maskExpression.previousValue && !maskExpression.firstChange) {
        this._maskService.maskChanged = true;
      }
      if (maskExpression.currentValue && maskExpression.currentValue.split("||" /* MaskExpression.OR */).length > 1) {
        this._maskExpressionArray = maskExpression.currentValue.split("||" /* MaskExpression.OR */).sort((a, b) => {
          return a.length - b.length;
        });
        this._setMask();
      } else {
        this._maskExpressionArray = [];
        this._maskValue = maskExpression.currentValue || "" /* MaskExpression.EMPTY_STRING */;
        this._maskService.maskExpression = this._maskValue;
      }
    }
    if (specialCharacters) {
      if (!specialCharacters.currentValue || !Array.isArray(specialCharacters.currentValue)) {
        return;
      } else {
        this._maskService.specialCharacters = specialCharacters.currentValue || [];
      }
    }
    if (allowNegativeNumbers) {
      this._maskService.allowNegativeNumbers = allowNegativeNumbers.currentValue;
      if (this._maskService.allowNegativeNumbers) {
        this._maskService.specialCharacters = this._maskService.specialCharacters.filter(c => c !== "-" /* MaskExpression.MINUS */);
      }
    }
    // Only overwrite the mask available patterns if a pattern has actually been passed in
    if (patterns && patterns.currentValue) {
      this._maskService.patterns = patterns.currentValue;
    }
    if (apm && apm.currentValue) {
      this._maskService.apm = apm.currentValue;
    }
    if (prefix) {
      this._maskService.prefix = prefix.currentValue;
    }
    if (suffix) {
      this._maskService.suffix = suffix.currentValue;
    }
    if (thousandSeparator) {
      this._maskService.thousandSeparator = thousandSeparator.currentValue;
    }
    if (decimalMarker) {
      this._maskService.decimalMarker = decimalMarker.currentValue;
    }
    if (dropSpecialCharacters) {
      this._maskService.dropSpecialCharacters = dropSpecialCharacters.currentValue;
    }
    if (hiddenInput) {
      this._maskService.hiddenInput = hiddenInput.currentValue;
    }
    if (showMaskTyped) {
      this._maskService.showMaskTyped = showMaskTyped.currentValue;
      if (showMaskTyped.previousValue === false && showMaskTyped.currentValue === true && this._isFocused) {
        requestAnimationFrame(() => {
          this._maskService._elementRef?.nativeElement.click();
        });
      }
    }
    if (placeHolderCharacter) {
      this._maskService.placeHolderCharacter = placeHolderCharacter.currentValue;
    }
    if (shownMaskExpression) {
      this._maskService.shownMaskExpression = shownMaskExpression.currentValue;
    }
    if (showTemplate) {
      this._maskService.showTemplate = showTemplate.currentValue;
    }
    if (clearIfNotMatch) {
      this._maskService.clearIfNotMatch = clearIfNotMatch.currentValue;
    }
    if (validation) {
      this._maskService.validation = validation.currentValue;
    }
    if (separatorLimit) {
      this._maskService.separatorLimit = separatorLimit.currentValue;
    }
    if (leadZeroDateTime) {
      this._maskService.leadZeroDateTime = leadZeroDateTime.currentValue;
    }
    if (leadZero) {
      this._maskService.leadZero = leadZero.currentValue;
    }
    if (triggerOnMaskChange) {
      this._maskService.triggerOnMaskChange = triggerOnMaskChange.currentValue;
    }
    if (inputTransformFn) {
      this._maskService.inputTransformFn = inputTransformFn.currentValue;
    }
    if (outputTransformFn) {
      this._maskService.outputTransformFn = outputTransformFn.currentValue;
    }
    if (keepCharacterPositions) {
      this._maskService.keepCharacterPositions = keepCharacterPositions.currentValue;
    }
    this._applyMask();
  }
  validate({
    value
  }) {
    if (!this._maskService.validation || !this._maskValue) {
      return null;
    }
    if (this._maskService.ipError) {
      return this._createValidationError(value);
    }
    if (this._maskService.cpfCnpjError) {
      return this._createValidationError(value);
    }
    if (this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
      return null;
    }
    if (withoutValidation.includes(this._maskValue)) {
      return null;
    }
    if (this._maskService.clearIfNotMatch) {
      return null;
    }
    if (timeMasks.includes(this._maskValue)) {
      return this._validateTime(value);
    }
    if (value && value.toString().length >= 1) {
      let counterOfOpt = 0;
      if (this._maskValue.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) && this._maskValue.includes("}" /* MaskExpression.CURLY_BRACKETS_RIGHT */)) {
        const lengthInsideCurlyBrackets = this._maskValue.slice(this._maskValue.indexOf("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) + 1, this._maskValue.indexOf("}" /* MaskExpression.CURLY_BRACKETS_RIGHT */));
        return lengthInsideCurlyBrackets === String(value.length) ? null : this._createValidationError(value);
      }
      if (this._maskValue.startsWith("percent" /* MaskExpression.PERCENT */)) {
        return null;
      }
      for (const key in this._maskService.patterns) {
        if (this._maskService.patterns[key]?.optional) {
          if (this._maskValue.indexOf(key) !== this._maskValue.lastIndexOf(key)) {
            const opt = this._maskValue.split("" /* MaskExpression.EMPTY_STRING */).filter(i => i === key).join("" /* MaskExpression.EMPTY_STRING */);
            counterOfOpt += opt.length;
          } else if (this._maskValue.indexOf(key) !== -1) {
            counterOfOpt++;
          }
          if (this._maskValue.indexOf(key) !== -1 && value.toString().length >= this._maskValue.indexOf(key)) {
            return null;
          }
          if (counterOfOpt === this._maskValue.length) {
            return null;
          }
        }
      }
      if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) > 1 && value.toString().length < this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) || this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) > 1 && value.toString().length < this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */)) {
        return this._createValidationError(value);
      }
      if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === -1 || this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === -1) {
        // eslint-disable-next-line no-param-reassign
        value = typeof value === 'number' ? String(value) : value;
        const array = this._maskValue.split('*');
        const length = this._maskService.dropSpecialCharacters ? this._maskValue.length - this._maskService.checkDropSpecialCharAmount(this._maskValue) - counterOfOpt : this.prefix ? this._maskValue.length + this.prefix.length - counterOfOpt : this._maskValue.length - counterOfOpt;
        if (array.length === 1) {
          if (value.toString().length < length) {
            return this._createValidationError(value);
          }
        }
        if (array.length > 1) {
          const lastIndexArray = array[array.length - 1];
          if (lastIndexArray && this._maskService.specialCharacters.includes(lastIndexArray[0]) && String(value).includes(lastIndexArray[0] ?? '') && !this.dropSpecialCharacters) {
            const special = value.split(lastIndexArray[0]);
            return special[special.length - 1].length === lastIndexArray.length - 1 ? null : this._createValidationError(value);
          } else if ((lastIndexArray && !this._maskService.specialCharacters.includes(lastIndexArray[0]) || !lastIndexArray || this._maskService.dropSpecialCharacters) && value.length >= length - 1) {
            return null;
          } else {
            return this._createValidationError(value);
          }
        }
      }
      if (this._maskValue.indexOf("*" /* MaskExpression.SYMBOL_STAR */) === 1 || this._maskValue.indexOf("?" /* MaskExpression.SYMBOL_QUESTION */) === 1) {
        return null;
      }
    }
    if (value) {
      this.maskFilled.emit();
      return null;
    }
    return null;
  }
  onPaste() {
    this._justPasted = true;
  }
  onFocus() {
    this._isFocused = true;
  }
  onModelChange(value) {
    // on form reset we need to update the actualValue
    if ((value === "" /* MaskExpression.EMPTY_STRING */ || value === null || value === undefined) && this._maskService.actualValue) {
      this._maskService.actualValue = this._maskService.getActualValue("" /* MaskExpression.EMPTY_STRING */);
    }
  }
  onInput(e) {
    // If IME is composing text, we wait for the composed text.
    if (this._isComposing) return;
    const el = e.target;
    const transformedValue = this._maskService.inputTransformFn(el.value);
    if (el.type !== 'number') {
      if (typeof transformedValue === 'string' || typeof transformedValue === 'number') {
        el.value = transformedValue.toString();
        this._inputValue = el.value;
        this._setMask();
        if (!this._maskValue) {
          this.onChange(el.value);
          return;
        }
        let position = el.selectionStart === 1 ? el.selectionStart + this._maskService.prefix.length : el.selectionStart;
        if (this.showMaskTyped && this.keepCharacterPositions && this._maskService.placeHolderCharacter.length === 1) {
          const inputSymbol = el.value.slice(position - 1, position);
          const prefixLength = this.prefix.length;
          const checkSymbols = this._maskService._checkSymbolMask(inputSymbol, this._maskService.maskExpression[position - 1 - prefixLength] ?? "" /* MaskExpression.EMPTY_STRING */);
          const checkSpecialCharacter = this._maskService._checkSymbolMask(inputSymbol, this._maskService.maskExpression[position + 1 - prefixLength] ?? "" /* MaskExpression.EMPTY_STRING */);
          const selectRangeBackspace = this._maskService.selStart === this._maskService.selEnd;
          const selStart = Number(this._maskService.selStart) - prefixLength;
          const selEnd = Number(this._maskService.selEnd) - prefixLength;
          if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
            if (!selectRangeBackspace) {
              if (this._maskService.selStart === prefixLength) {
                this._maskService.actualValue = `${this.prefix}${this._maskService.maskIsShown.slice(0, selEnd)}${this._inputValue.split(this.prefix).join('')}`;
              } else if (this._maskService.selStart === this._maskService.maskIsShown.length + prefixLength) {
                this._maskService.actualValue = `${this._inputValue}${this._maskService.maskIsShown.slice(selStart, selEnd)}`;
              } else {
                this._maskService.actualValue = `${this.prefix}${this._inputValue.split(this.prefix).join('').slice(0, selStart)}${this._maskService.maskIsShown.slice(selStart, selEnd)}${this._maskService.actualValue.slice(selEnd + prefixLength, this._maskService.maskIsShown.length + prefixLength)}${this.suffix}`;
              }
            } else if (!this._maskService.specialCharacters.includes(this._maskService.maskExpression.slice(position - this.prefix.length, position + 1 - this.prefix.length)) && selectRangeBackspace) {
              if (selStart === 1 && this.prefix) {
                this._maskService.actualValue = `${this.prefix}${this._maskService.placeHolderCharacter}${el.value.split(this.prefix).join('').split(this.suffix).join('')}${this.suffix}`;
                position = position - 1;
              } else {
                const part1 = el.value.substring(0, position);
                const part2 = el.value.substring(position);
                this._maskService.actualValue = `${part1}${this._maskService.placeHolderCharacter}${part2}`;
              }
            }
          }
          if (this._code !== "Backspace" /* MaskExpression.BACKSPACE */) {
            if (!checkSymbols && !checkSpecialCharacter && selectRangeBackspace) {
              position = Number(el.selectionStart) - 1;
            } else if (this._maskService.specialCharacters.includes(el.value.slice(position, position + 1)) && checkSpecialCharacter && !this._maskService.specialCharacters.includes(el.value.slice(position + 1, position + 2))) {
              this._maskService.actualValue = `${el.value.slice(0, position - 1)}${el.value.slice(position, position + 1)}${inputSymbol}${el.value.slice(position + 2)}`;
              position = position + 1;
            } else if (checkSymbols) {
              if (el.value.length === 1 && position === 1) {
                this._maskService.actualValue = `${this.prefix}${inputSymbol}${this._maskService.maskIsShown.slice(1, this._maskService.maskIsShown.length)}${this.suffix}`;
              } else {
                this._maskService.actualValue = `${el.value.slice(0, position - 1)}${inputSymbol}${el.value.slice(position + 1).split(this.suffix).join('')}${this.suffix}`;
              }
            } else if (this.prefix && el.value.length === 1 && position - prefixLength === 1 && this._maskService._checkSymbolMask(el.value, this._maskService.maskExpression[position - 1 - prefixLength] ?? "" /* MaskExpression.EMPTY_STRING */)) {
              this._maskService.actualValue = `${this.prefix}${el.value}${this._maskService.maskIsShown.slice(1, this._maskService.maskIsShown.length)}${this.suffix}`;
            }
          }
        }
        let caretShift = 0;
        let backspaceShift = false;
        if (this._code === "Delete" /* MaskExpression.DELETE */ && "separator" /* MaskExpression.SEPARATOR */) {
          this._maskService.deletedSpecialCharacter = true;
        }
        if (this._inputValue.length >= this._maskService.maskExpression.length - 1 && this._code !== "Backspace" /* MaskExpression.BACKSPACE */ && this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ && position < 10) {
          const inputSymbol = this._inputValue.slice(position - 1, position);
          el.value = this._inputValue.slice(0, position - 1) + inputSymbol + this._inputValue.slice(position + 1);
        }
        if (this._maskService.maskExpression === "d0/M0/0000" /* MaskExpression.DAYS_MONTHS_YEARS */ && this.leadZeroDateTime) {
          if (position < 3 && Number(el.value) > 31 && Number(el.value) < 40 || position === 5 && Number(el.value.slice(3, 5)) > 12) {
            position = position + 2;
          }
        }
        if (this._maskService.maskExpression === "Hh:m0:s0" /* MaskExpression.HOURS_MINUTES_SECONDS */ && this.apm) {
          if (this._justPasted && el.value.slice(0, 2) === "00" /* MaskExpression.DOUBLE_ZERO */) {
            el.value = el.value.slice(1, 2) + el.value.slice(2, el.value.length);
          }
          el.value = el.value === "00" /* MaskExpression.DOUBLE_ZERO */ ? "0" /* MaskExpression.NUMBER_ZERO */ : el.value;
        }
        this._maskService.applyValueChanges(position, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */, (shift, _backspaceShift) => {
          this._justPasted = false;
          caretShift = shift;
          backspaceShift = _backspaceShift;
        });
        // only set the selection if the element is active
        if (this._getActiveElement() !== el) {
          return;
        }
        if (this._maskService.plusOnePosition) {
          position = position + 1;
          this._maskService.plusOnePosition = false;
        }
        // update position after applyValueChanges to prevent cursor on wrong position when it has an array of maskExpression
        if (this._maskExpressionArray.length) {
          if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
            const specialChartMinusOne = this.specialCharacters.includes(this._maskService.actualValue.slice(position - 1, position));
            const specialChartPlusOne = this.specialCharacters.includes(this._maskService.actualValue.slice(position, position + 1));
            if (this._allowFewMaskChangeMask && !specialChartPlusOne) {
              position = el.selectionStart + 1;
              this._allowFewMaskChangeMask = false;
            } else {
              position = specialChartMinusOne ? position - 1 : position;
            }
          } else {
            position = el.selectionStart === 1 ? el.selectionStart + this._maskService.prefix.length : el.selectionStart;
          }
        }
        this._position = this._position === 1 && this._inputValue.length === 1 ? null : this._position;
        let positionToApply = this._position ? this._inputValue.length + position + caretShift : position + (this._code === "Backspace" /* MaskExpression.BACKSPACE */ && !backspaceShift ? 0 : caretShift);
        if (positionToApply > this._getActualInputLength()) {
          positionToApply = el.value === this._maskService.decimalMarker && el.value.length === 1 ? this._getActualInputLength() + 1 : this._getActualInputLength();
        }
        if (positionToApply < 0) {
          positionToApply = 0;
        }
        el.setSelectionRange(positionToApply, positionToApply);
        this._position = null;
      } else {
        console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof transformedValue);
      }
    } else {
      if (!this._maskValue) {
        this.onChange(el.value);
        return;
      }
      this._maskService.applyValueChanges(el.value.length, this._justPasted, this._code === "Backspace" /* MaskExpression.BACKSPACE */ || this._code === "Delete" /* MaskExpression.DELETE */);
    }
  }
  // IME starts
  onCompositionStart() {
    this._isComposing = true;
  }
  // IME completes
  onCompositionEnd(e) {
    this._isComposing = false;
    this._justPasted = true;
    this.onInput(e);
  }
  onBlur(e) {
    if (this._maskValue) {
      const el = e.target;
      if (this.leadZero && el.value.length > 0 && typeof this.decimalMarker === 'string') {
        const maskExpression = this._maskService.maskExpression;
        const precision = Number(this._maskService.maskExpression.slice(maskExpression.length - 1, maskExpression.length));
        if (precision > 0) {
          el.value = this.suffix ? el.value.split(this.suffix).join('') : el.value;
          const decimalPart = el.value.split(this.decimalMarker)[1];
          el.value = el.value.includes(this.decimalMarker) ? el.value + "0" /* MaskExpression.NUMBER_ZERO */.repeat(precision - decimalPart.length) + this.suffix : el.value + this.decimalMarker + "0" /* MaskExpression.NUMBER_ZERO */.repeat(precision) + this.suffix;
          this._maskService.actualValue = el.value;
        }
      }
      this._maskService.clearIfNotMatchFn();
    }
    this._isFocused = false;
    this.onTouch();
  }
  onClick(e) {
    if (!this._maskValue) {
      return;
    }
    const el = e.target;
    const posStart = 0;
    const posEnd = 0;
    if (el !== null && el.selectionStart !== null && el.selectionStart === el.selectionEnd && el.selectionStart > this._maskService.prefix.length &&
    // eslint-disable-next-line
    e.keyCode !== 38) {
      if (this._maskService.showMaskTyped && !this.keepCharacterPositions) {
        // We are showing the mask in the input
        this._maskService.maskIsShown = this._maskService.showMaskInInput();
        if (el.setSelectionRange && this._maskService.prefix + this._maskService.maskIsShown === el.value) {
          // the input ONLY contains the mask, so position the cursor at the start
          el.focus();
          el.setSelectionRange(posStart, posEnd);
        } else {
          // the input contains some characters already
          if (el.selectionStart > this._maskService.actualValue.length) {
            // if the user clicked beyond our value's length, position the cursor at the end of our value
            el.setSelectionRange(this._maskService.actualValue.length, this._maskService.actualValue.length);
          }
        }
      }
    }
    const nextValue = el && (el.value === this._maskService.prefix ? this._maskService.prefix + this._maskService.maskIsShown : el.value);
    /** Fix of cursor position jumping to end in most browsers no matter where cursor is inserted onFocus */
    if (el && el.value !== nextValue) {
      el.value = nextValue;
    }
    /** fix of cursor position with prefix when mouse click occur */
    if (el && el.type !== 'number' && (el.selectionStart || el.selectionEnd) <= this._maskService.prefix.length) {
      el.selectionStart = this._maskService.prefix.length;
      return;
    }
    /** select only inserted text */
    if (el && el.selectionEnd > this._getActualInputLength()) {
      el.selectionEnd = this._getActualInputLength();
    }
  }
  onKeyDown(e) {
    if (!this._maskValue) {
      return;
    }
    if (this._isComposing) {
      // User finalize their choice from IME composition, so trigger onInput() for the composed text.
      if (e.key === 'Enter') this.onCompositionEnd(e);
      return;
    }
    this._code = e.code ? e.code : e.key;
    const el = e.target;
    this._inputValue = el.value;
    this._setMask();
    if (el.type !== 'number') {
      if (e.key === "ArrowUp" /* MaskExpression.ARROW_UP */) {
        e.preventDefault();
      }
      if (e.key === "ArrowLeft" /* MaskExpression.ARROW_LEFT */ || e.key === "Backspace" /* MaskExpression.BACKSPACE */ || e.key === "Delete" /* MaskExpression.DELETE */) {
        if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.value.length === 0) {
          el.selectionStart = el.selectionEnd;
        }
        if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && el.selectionStart !== 0) {
          // If specialChars is false, (shouldn't ever happen) then set to the defaults
          this.specialCharacters = this.specialCharacters?.length ? this.specialCharacters : this._config.specialCharacters;
          if (this.prefix.length > 1 && el.selectionStart <= this.prefix.length) {
            el.setSelectionRange(this.prefix.length, el.selectionEnd);
          } else {
            if (this._inputValue.length !== el.selectionStart && el.selectionStart !== 1) {
              while (this.specialCharacters.includes((this._inputValue[el.selectionStart - 1] ?? "" /* MaskExpression.EMPTY_STRING */).toString()) && (this.prefix.length >= 1 && el.selectionStart > this.prefix.length || this.prefix.length === 0)) {
                el.setSelectionRange(el.selectionStart - 1, el.selectionEnd);
              }
            }
          }
        }
        this.checkSelectionOnDeletion(el);
        if (this._maskService.prefix.length && el.selectionStart <= this._maskService.prefix.length && el.selectionEnd <= this._maskService.prefix.length) {
          e.preventDefault();
        }
        const cursorStart = el.selectionStart;
        if (e.key === "Backspace" /* MaskExpression.BACKSPACE */ && !el.readOnly && cursorStart === 0 && el.selectionEnd === el.value.length && el.value.length !== 0) {
          this._position = this._maskService.prefix ? this._maskService.prefix.length : 0;
          this._maskService.applyMask(this._maskService.prefix, this._maskService.maskExpression, this._position);
        }
      }
      if (!!this.suffix && this.suffix.length > 1 && this._inputValue.length - this.suffix.length < el.selectionStart) {
        el.setSelectionRange(this._inputValue.length - this.suffix.length, this._inputValue.length);
      } else if (e.code === 'KeyA' && e.ctrlKey || e.code === 'KeyA' && e.metaKey // Cmd + A (Mac)
      ) {
        el.setSelectionRange(0, this._getActualInputLength());
        e.preventDefault();
      }
      this._maskService.selStart = el.selectionStart;
      this._maskService.selEnd = el.selectionEnd;
    }
  }
  /** It writes the value in the input */
  writeValue(controlValue) {
    var _this = this;
    return (0,C_deportes87_deportes_fe_node_modules_babel_runtime_helpers_esm_asyncToGenerator_js__WEBPACK_IMPORTED_MODULE_0__["default"])(function* () {
      if (typeof controlValue === 'object' && controlValue !== null && 'value' in controlValue) {
        if ('disable' in controlValue) {
          _this.setDisabledState(Boolean(controlValue.disable));
        }
        // eslint-disable-next-line no-param-reassign
        controlValue = controlValue.value;
      }
      if (controlValue !== null) {
        // eslint-disable-next-line no-param-reassign
        controlValue = _this.inputTransformFn ? _this.inputTransformFn(controlValue) : controlValue;
      }
      if (typeof controlValue === 'string' || typeof controlValue === 'number' || controlValue === null || controlValue === undefined) {
        if (controlValue === null || controlValue === undefined || controlValue === '') {
          _this._maskService._currentValue = '';
          _this._maskService._previousValue = '';
        }
        let inputValue = controlValue;
        if (typeof inputValue === 'number' || _this._maskValue.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
          inputValue = String(inputValue);
          const localeDecimalMarker = _this._maskService.currentLocaleDecimalMarker();
          if (!Array.isArray(_this._maskService.decimalMarker)) {
            inputValue = _this._maskService.decimalMarker !== localeDecimalMarker ? inputValue.replace(localeDecimalMarker, _this._maskService.decimalMarker) : inputValue;
          }
          if (_this._maskService.leadZero && inputValue && _this.maskExpression && _this.dropSpecialCharacters !== false) {
            inputValue = _this._maskService._checkPrecision(_this._maskService.maskExpression, inputValue);
          }
          if (_this.decimalMarker === "," /* MaskExpression.COMMA */ || Array.isArray(_this._maskService.decimalMarker) && _this.thousandSeparator === "." /* MaskExpression.DOT */) {
            inputValue = inputValue.toString().replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
          }
          if (_this.maskExpression?.startsWith("separator" /* MaskExpression.SEPARATOR */) && _this.leadZero) {
            requestAnimationFrame(() => {
              _this._maskService.applyMask(inputValue?.toString() ?? '', _this._maskService.maskExpression);
            });
          }
          _this._maskService.isNumberValue = true;
        }
        if (typeof inputValue !== 'string') {
          inputValue = '';
        }
        _this._inputValue = inputValue;
        _this._setMask();
        if (inputValue && _this._maskService.maskExpression || _this._maskService.maskExpression && (_this._maskService.prefix || _this._maskService.showMaskTyped)) {
          // Let the service we know we are writing value so that triggering onChange function won't happen during applyMask
          typeof _this.inputTransformFn !== 'function' ? _this._maskService.writingValue = true : '';
          _this._maskService.formElementProperty = ['value', _this._maskService.applyMask(inputValue, _this._maskService.maskExpression)];
          // Let the service know we've finished writing value
          typeof _this.inputTransformFn !== 'function' ? _this._maskService.writingValue = false : '';
        } else {
          _this._maskService.formElementProperty = ['value', inputValue];
        }
        _this._inputValue = inputValue;
      } else {
        console.warn('Ngx-mask writeValue work with string | number, your current value:', typeof controlValue);
      }
    })();
  }
  registerOnChange(fn) {
    this._maskService.onChange = this.onChange = fn;
  }
  registerOnTouched(fn) {
    this.onTouch = fn;
  }
  _getActiveElement(document = this.document) {
    const shadowRootEl = document?.activeElement?.shadowRoot;
    if (!shadowRootEl?.activeElement) {
      return document.activeElement;
    } else {
      return this._getActiveElement(shadowRootEl);
    }
  }
  checkSelectionOnDeletion(el) {
    el.selectionStart = Math.min(Math.max(this.prefix.length, el.selectionStart), this._inputValue.length - this.suffix.length);
    el.selectionEnd = Math.min(Math.max(this.prefix.length, el.selectionEnd), this._inputValue.length - this.suffix.length);
  }
  /** It disables the input element */
  setDisabledState(isDisabled) {
    this._maskService.formElementProperty = ['disabled', isDisabled];
  }
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  _applyMask() {
    this._maskService.maskExpression = this._maskService._repeatPatternSymbols(this._maskValue || '');
    this._maskService.formElementProperty = ['value', this._maskService.applyMask(this._inputValue, this._maskService.maskExpression)];
  }
  _validateTime(value) {
    const rowMaskLen = this._maskValue.split("" /* MaskExpression.EMPTY_STRING */).filter(s => s !== ':').length;
    if (!value) {
      return null; // Don't validate empty values to allow for optional form control
    }
    if (+(value[value.length - 1] ?? -1) === 0 && value.length < rowMaskLen || value.length <= rowMaskLen - 2) {
      return this._createValidationError(value);
    }
    return null;
  }
  _getActualInputLength() {
    return this._maskService.actualValue.length || this._maskService.actualValue.length + this._maskService.prefix.length;
  }
  _createValidationError(actualValue) {
    return {
      mask: {
        requiredMask: this._maskValue,
        actualValue
      }
    };
  }
  _setMask() {
    this._maskExpressionArray.some(mask => {
      const specialChart = mask.split("" /* MaskExpression.EMPTY_STRING */).some(char => this._maskService.specialCharacters.includes(char));
      if (specialChart && this._inputValue && this._areAllCharactersInEachStringSame(this._maskExpressionArray) || mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)) {
        const test = this._maskService.removeMask(this._inputValue)?.length <= this._maskService.removeMask(mask)?.length;
        if (test) {
          this._maskValue = this.maskExpression = this._maskService.maskExpression = mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) ? this._maskService._repeatPatternSymbols(mask) : mask;
          return test;
        } else {
          if (this._code === "Backspace" /* MaskExpression.BACKSPACE */) {
            this._allowFewMaskChangeMask = true;
          }
          const expression = this._maskExpressionArray[this._maskExpressionArray.length - 1] ?? "" /* MaskExpression.EMPTY_STRING */;
          this._maskValue = this.maskExpression = this._maskService.maskExpression = expression.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */) ? this._maskService._repeatPatternSymbols(expression) : expression;
        }
      } else {
        const check = this._maskService.removeMask(this._inputValue)?.split("" /* MaskExpression.EMPTY_STRING */).every((character, index) => {
          const indexMask = mask.charAt(index);
          return this._maskService._checkSymbolMask(character, indexMask);
        });
        if (check || this._justPasted) {
          this._maskValue = this.maskExpression = this._maskService.maskExpression = mask;
          return check;
        }
      }
    });
  }
  _areAllCharactersInEachStringSame(array) {
    const specialCharacters = this._maskService.specialCharacters;
    function removeSpecialCharacters(str) {
      const regex = new RegExp(`[${specialCharacters.map(ch => `\\${ch}`).join('')}]`, 'g');
      return str.replace(regex, '');
    }
    const processedArr = array.map(removeSpecialCharacters);
    return processedArr.every(str => {
      const uniqueCharacters = new Set(str);
      return uniqueCharacters.size === 1;
    });
  }
  static {
    this.ɵfac = function NgxMaskDirective_Factory(t) {
      return new (t || NgxMaskDirective)();
    };
  }
  static {
    this.ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineDirective"]({
      type: NgxMaskDirective,
      selectors: [["input", "mask", ""], ["textarea", "mask", ""]],
      hostBindings: function NgxMaskDirective_HostBindings(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵlistener"]("paste", function NgxMaskDirective_paste_HostBindingHandler() {
            return ctx.onPaste();
          })("focus", function NgxMaskDirective_focus_HostBindingHandler($event) {
            return ctx.onFocus($event);
          })("ngModelChange", function NgxMaskDirective_ngModelChange_HostBindingHandler($event) {
            return ctx.onModelChange($event);
          })("input", function NgxMaskDirective_input_HostBindingHandler($event) {
            return ctx.onInput($event);
          })("compositionstart", function NgxMaskDirective_compositionstart_HostBindingHandler($event) {
            return ctx.onCompositionStart($event);
          })("compositionend", function NgxMaskDirective_compositionend_HostBindingHandler($event) {
            return ctx.onCompositionEnd($event);
          })("blur", function NgxMaskDirective_blur_HostBindingHandler($event) {
            return ctx.onBlur($event);
          })("click", function NgxMaskDirective_click_HostBindingHandler($event) {
            return ctx.onClick($event);
          })("keydown", function NgxMaskDirective_keydown_HostBindingHandler($event) {
            return ctx.onKeyDown($event);
          });
        }
      },
      inputs: {
        maskExpression: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵInputFlags"].None, "mask", "maskExpression"],
        specialCharacters: "specialCharacters",
        patterns: "patterns",
        prefix: "prefix",
        suffix: "suffix",
        thousandSeparator: "thousandSeparator",
        decimalMarker: "decimalMarker",
        dropSpecialCharacters: "dropSpecialCharacters",
        hiddenInput: "hiddenInput",
        showMaskTyped: "showMaskTyped",
        placeHolderCharacter: "placeHolderCharacter",
        shownMaskExpression: "shownMaskExpression",
        showTemplate: "showTemplate",
        clearIfNotMatch: "clearIfNotMatch",
        validation: "validation",
        separatorLimit: "separatorLimit",
        allowNegativeNumbers: "allowNegativeNumbers",
        leadZeroDateTime: "leadZeroDateTime",
        leadZero: "leadZero",
        triggerOnMaskChange: "triggerOnMaskChange",
        apm: "apm",
        inputTransformFn: "inputTransformFn",
        outputTransformFn: "outputTransformFn",
        keepCharacterPositions: "keepCharacterPositions"
      },
      outputs: {
        maskFilled: "maskFilled"
      },
      exportAs: ["mask", "ngxMask"],
      standalone: true,
      features: [_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵProvidersFeature"]([{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_3__.NG_VALUE_ACCESSOR,
        useExisting: NgxMaskDirective,
        multi: true
      }, {
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_3__.NG_VALIDATORS,
        useExisting: NgxMaskDirective,
        multi: true
      }, NgxMaskService]), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵNgOnChangesFeature"]]
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxMaskDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Directive,
    args: [{
      selector: 'input[mask], textarea[mask]',
      standalone: true,
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_3__.NG_VALUE_ACCESSOR,
        useExisting: NgxMaskDirective,
        multi: true
      }, {
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_3__.NG_VALIDATORS,
        useExisting: NgxMaskDirective,
        multi: true
      }, NgxMaskService],
      exportAs: 'mask,ngxMask'
    }]
  }], null, {
    maskExpression: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['mask']
    }],
    specialCharacters: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    patterns: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    prefix: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    suffix: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    thousandSeparator: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    decimalMarker: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    dropSpecialCharacters: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    hiddenInput: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    showMaskTyped: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    placeHolderCharacter: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    shownMaskExpression: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    showTemplate: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    clearIfNotMatch: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    validation: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    separatorLimit: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    allowNegativeNumbers: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    leadZeroDateTime: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    leadZero: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    triggerOnMaskChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    apm: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    inputTransformFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    outputTransformFn: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    keepCharacterPositions: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input
    }],
    maskFilled: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Output
    }],
    onPaste: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['paste']
    }],
    onFocus: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['focus', ['$event']]
    }],
    onModelChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['ngModelChange', ['$event']]
    }],
    onInput: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['input', ['$event']]
    }],
    onCompositionStart: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['compositionstart', ['$event']]
    }],
    onCompositionEnd: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['compositionend', ['$event']]
    }],
    onBlur: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['blur', ['$event']]
    }],
    onClick: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['click', ['$event']]
    }],
    onKeyDown: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.HostListener,
      args: ['keydown', ['$event']]
    }]
  });
})();
class NgxMaskPipe {
  constructor() {
    this.defaultOptions = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NGX_MASK_CONFIG);
    this._maskService = (0,_angular_core__WEBPACK_IMPORTED_MODULE_1__.inject)(NgxMaskService);
    this._maskExpressionArray = [];
    this.mask = '';
  }
  transform(value, mask, {
    patterns,
    ...config
  } = {}) {
    const currentConfig = {
      maskExpression: mask,
      ...this.defaultOptions,
      ...config,
      patterns: {
        ...this._maskService.patterns,
        ...patterns
      }
    };
    Object.entries(currentConfig).forEach(([key, value]) => {
      //eslint-disable-next-line  @typescript-eslint/no-explicit-any
      this._maskService[key] = value;
    });
    if (mask.includes('||')) {
      if (mask.split('||').length > 1) {
        this._maskExpressionArray = mask.split('||').sort((a, b) => {
          return a.length - b.length;
        });
        this._setMask(value);
        return this._maskService.applyMask(`${value}`, this.mask);
      } else {
        this._maskExpressionArray = [];
        return this._maskService.applyMask(`${value}`, this.mask);
      }
    }
    if (mask.includes("{" /* MaskExpression.CURLY_BRACKETS_LEFT */)) {
      return this._maskService.applyMask(`${value}`, this._maskService._repeatPatternSymbols(mask));
    }
    if (mask.startsWith("separator" /* MaskExpression.SEPARATOR */)) {
      if (config.decimalMarker) {
        this._maskService.decimalMarker = config.decimalMarker;
      }
      if (config.thousandSeparator) {
        this._maskService.thousandSeparator = config.thousandSeparator;
      }
      if (config.leadZero) {
        // eslint-disable-next-line no-param-reassign
        this._maskService.leadZero = config.leadZero;
      }
      // eslint-disable-next-line no-param-reassign
      value = String(value);
      const localeDecimalMarker = this._maskService.currentLocaleDecimalMarker();
      if (!Array.isArray(this._maskService.decimalMarker)) {
        // eslint-disable-next-line no-param-reassign
        value = this._maskService.decimalMarker !== localeDecimalMarker ? value.replace(localeDecimalMarker, this._maskService.decimalMarker) : value;
      }
      if (this._maskService.leadZero && value && this._maskService.dropSpecialCharacters !== false) {
        // eslint-disable-next-line no-param-reassign
        value = this._maskService._checkPrecision(mask, value);
      }
      if (this._maskService.decimalMarker === "," /* MaskExpression.COMMA */) {
        // eslint-disable-next-line no-param-reassign
        value = value.toString().replace("." /* MaskExpression.DOT */, "," /* MaskExpression.COMMA */);
      }
      this._maskService.isNumberValue = true;
    }
    if (value === null || value === undefined) {
      return this._maskService.applyMask('', mask);
    }
    return this._maskService.applyMask(`${value}`, mask);
  }
  _setMask(value) {
    if (this._maskExpressionArray.length > 0) {
      this._maskExpressionArray.some(mask => {
        const test = this._maskService.removeMask(value)?.length <= this._maskService.removeMask(mask)?.length;
        if (value && test) {
          this.mask = mask;
          return test;
        } else {
          const expression = this._maskExpressionArray[this._maskExpressionArray.length - 1] ?? "" /* MaskExpression.EMPTY_STRING */;
          this.mask = expression;
        }
      });
    }
  }
  static {
    this.ɵfac = function NgxMaskPipe_Factory(t) {
      return new (t || NgxMaskPipe)();
    };
  }
  static {
    this.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefinePipe"]({
      name: "mask",
      type: NgxMaskPipe,
      pure: true,
      standalone: true
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](NgxMaskPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Pipe,
    args: [{
      name: 'mask',
      pure: true,
      standalone: true
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 60315:
/*!*******************************************************!*\
  !*** ./node_modules/ngx-pipes/fesm2020/ngx-pipes.mjs ***!
  \*******************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   AorAnPipe: () => (/* binding */ AorAnPipe),
/* harmony export */   BOOLEAN_PIPES: () => (/* binding */ BOOLEAN_PIPES),
/* harmony export */   BytesPipe: () => (/* binding */ BytesPipe),
/* harmony export */   CamelizePipe: () => (/* binding */ CamelizePipe),
/* harmony export */   CeilPipe: () => (/* binding */ CeilPipe),
/* harmony export */   ChunkPipe: () => (/* binding */ ChunkPipe),
/* harmony export */   DATE_PIPES: () => (/* binding */ DATE_PIPES),
/* harmony export */   DegreesPipe: () => (/* binding */ DegreesPipe),
/* harmony export */   DiffObjPipe: () => (/* binding */ DiffObjPipe),
/* harmony export */   DiffPipe: () => (/* binding */ DiffPipe),
/* harmony export */   EveryPipe: () => (/* binding */ EveryPipe),
/* harmony export */   FilterByImpurePipe: () => (/* binding */ FilterByImpurePipe),
/* harmony export */   FilterByPipe: () => (/* binding */ FilterByPipe),
/* harmony export */   FlattenPipe: () => (/* binding */ FlattenPipe),
/* harmony export */   FloorPipe: () => (/* binding */ FloorPipe),
/* harmony export */   FromPairsPipe: () => (/* binding */ FromPairsPipe),
/* harmony export */   GroupByImpurePipe: () => (/* binding */ GroupByImpurePipe),
/* harmony export */   GroupByPipe: () => (/* binding */ GroupByPipe),
/* harmony export */   InitialPipe: () => (/* binding */ InitialPipe),
/* harmony export */   IntersectionPipe: () => (/* binding */ IntersectionPipe),
/* harmony export */   InvertByPipe: () => (/* binding */ InvertByPipe),
/* harmony export */   InvertPipe: () => (/* binding */ InvertPipe),
/* harmony export */   IsArrayPipe: () => (/* binding */ IsArrayPipe),
/* harmony export */   IsDefinedPipe: () => (/* binding */ IsDefinedPipe),
/* harmony export */   IsEqualToPipe: () => (/* binding */ IsEqualToPipe),
/* harmony export */   IsFunctionPipe: () => (/* binding */ IsFunctionPipe),
/* harmony export */   IsGreaterEqualThanPipe: () => (/* binding */ IsGreaterEqualThanPipe),
/* harmony export */   IsGreaterThanPipe: () => (/* binding */ IsGreaterThanPipe),
/* harmony export */   IsIdenticalToPipe: () => (/* binding */ IsIdenticalToPipe),
/* harmony export */   IsLessEqualThanPipe: () => (/* binding */ IsLessEqualThanPipe),
/* harmony export */   IsLessThanPipe: () => (/* binding */ IsLessThanPipe),
/* harmony export */   IsNotEqualToPipe: () => (/* binding */ IsNotEqualToPipe),
/* harmony export */   IsNotIdenticalToPipe: () => (/* binding */ IsNotIdenticalToPipe),
/* harmony export */   IsNullPipe: () => (/* binding */ IsNullPipe),
/* harmony export */   IsNumberPipe: () => (/* binding */ IsNumberPipe),
/* harmony export */   IsObjectPipe: () => (/* binding */ IsObjectPipe),
/* harmony export */   IsStringPipe: () => (/* binding */ IsStringPipe),
/* harmony export */   IsUndefinedPipe: () => (/* binding */ IsUndefinedPipe),
/* harmony export */   KeysPipe: () => (/* binding */ KeysPipe),
/* harmony export */   LatinisePipe: () => (/* binding */ LatinisePipe),
/* harmony export */   LeftPadPipe: () => (/* binding */ LeftPadPipe),
/* harmony export */   LeftTrimPipe: () => (/* binding */ LeftTrimPipe),
/* harmony export */   LinesPipe: () => (/* binding */ LinesPipe),
/* harmony export */   MATH_PIPES: () => (/* binding */ MATH_PIPES),
/* harmony export */   MakePluralStringPipe: () => (/* binding */ MakePluralStringPipe),
/* harmony export */   MatchPipe: () => (/* binding */ MatchPipe),
/* harmony export */   MaxPipe: () => (/* binding */ MaxPipe),
/* harmony export */   MinPipe: () => (/* binding */ MinPipe),
/* harmony export */   NgArrayPipesModule: () => (/* binding */ NgArrayPipesModule),
/* harmony export */   NgBooleanPipesModule: () => (/* binding */ NgBooleanPipesModule),
/* harmony export */   NgDatePipesModule: () => (/* binding */ NgDatePipesModule),
/* harmony export */   NgMathPipesModule: () => (/* binding */ NgMathPipesModule),
/* harmony export */   NgObjectPipesModule: () => (/* binding */ NgObjectPipesModule),
/* harmony export */   NgPipesModule: () => (/* binding */ NgPipesModule),
/* harmony export */   NgStringPipesModule: () => (/* binding */ NgStringPipesModule),
/* harmony export */   OmitPipe: () => (/* binding */ OmitPipe),
/* harmony export */   OrderByImpurePipe: () => (/* binding */ OrderByImpurePipe),
/* harmony export */   OrderByPipe: () => (/* binding */ OrderByPipe),
/* harmony export */   PairsPipe: () => (/* binding */ PairsPipe),
/* harmony export */   PercentagePipe: () => (/* binding */ PercentagePipe),
/* harmony export */   PickPipe: () => (/* binding */ PickPipe),
/* harmony export */   PluckPipe: () => (/* binding */ PluckPipe),
/* harmony export */   PowerPipe: () => (/* binding */ PowerPipe),
/* harmony export */   RadiansPipe: () => (/* binding */ RadiansPipe),
/* harmony export */   RangePipe: () => (/* binding */ RangePipe),
/* harmony export */   RepeatPipe: () => (/* binding */ RepeatPipe),
/* harmony export */   ReversePipe: () => (/* binding */ ReversePipe),
/* harmony export */   RightPadPipe: () => (/* binding */ RightPadPipe),
/* harmony export */   RightTrimPipe: () => (/* binding */ RightTrimPipe),
/* harmony export */   RoundPipe: () => (/* binding */ RoundPipe),
/* harmony export */   STRING_PIPES: () => (/* binding */ STRING_PIPES),
/* harmony export */   SamplePipe: () => (/* binding */ SamplePipe),
/* harmony export */   ScanPipe: () => (/* binding */ ScanPipe),
/* harmony export */   ShortenPipe: () => (/* binding */ ShortenPipe),
/* harmony export */   ShufflePipe: () => (/* binding */ ShufflePipe),
/* harmony export */   SlugifyPipe: () => (/* binding */ SlugifyPipe),
/* harmony export */   SomePipe: () => (/* binding */ SomePipe),
/* harmony export */   SqrtPipe: () => (/* binding */ SqrtPipe),
/* harmony export */   StripTagsPipe: () => (/* binding */ StripTagsPipe),
/* harmony export */   SumPipe: () => (/* binding */ SumPipe),
/* harmony export */   TailPipe: () => (/* binding */ TailPipe),
/* harmony export */   TestPipe: () => (/* binding */ TestPipe),
/* harmony export */   TimeAgoPipe: () => (/* binding */ TimeAgoPipe),
/* harmony export */   TrimPipe: () => (/* binding */ TrimPipe),
/* harmony export */   TrurthifyPipe: () => (/* binding */ TrurthifyPipe),
/* harmony export */   UcFirstPipe: () => (/* binding */ UcFirstPipe),
/* harmony export */   UcWordsPipe: () => (/* binding */ UcWordsPipe),
/* harmony export */   UnderscorePipe: () => (/* binding */ UnderscorePipe),
/* harmony export */   UnionPipe: () => (/* binding */ UnionPipe),
/* harmony export */   UniquePipe: () => (/* binding */ UniquePipe),
/* harmony export */   ValuesPipe: () => (/* binding */ ValuesPipe),
/* harmony export */   WithoutPipe: () => (/* binding */ WithoutPipe),
/* harmony export */   WrapPipe: () => (/* binding */ WrapPipe)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);


class DiffPipe {
  transform(input, ...args) {
    if (!Array.isArray(input)) {
      return input;
    }
    // tslint:disable-next-line no-bitwise
    return args.reduce((d, c) => d.filter(e => !~c.indexOf(e)), input);
  }
}
DiffPipe.ɵfac = function DiffPipe_Factory(t) {
  return new (t || DiffPipe)();
};
DiffPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "diff",
  type: DiffPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DiffPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'diff'
    }]
  }], null, null);
})();
class InitialPipe {
  transform(input, num = 0) {
    return Array.isArray(input) ? input.slice(0, input.length - num) : input;
  }
}
InitialPipe.ɵfac = function InitialPipe_Factory(t) {
  return new (t || InitialPipe)();
};
InitialPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "initial",
  type: InitialPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InitialPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'initial'
    }]
  }], null, null);
})();
class FlattenPipe {
  transform(input, shallow = false) {
    if (!Array.isArray(input)) {
      return input;
    }
    return shallow ? [].concat.apply([], input) : this.flatten(input);
  }
  flatten(array) {
    return array.reduce((arr, elm) => {
      if (Array.isArray(elm)) {
        return arr.concat(this.flatten(elm));
      }
      return arr.concat(elm);
    }, []);
  }
}
FlattenPipe.ɵfac = function FlattenPipe_Factory(t) {
  return new (t || FlattenPipe)();
};
FlattenPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "flatten",
  type: FlattenPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FlattenPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'flatten'
    }]
  }], null, null);
})();
class IntersectionPipe {
  transform(input, ...args) {
    if (!Array.isArray(input)) {
      return input;
    }
    // tslint:disable-next-line no-bitwise
    return args.reduce((n, c) => n.filter(e => !!~c.indexOf(e)), input);
  }
}
IntersectionPipe.ɵfac = function IntersectionPipe_Factory(t) {
  return new (t || IntersectionPipe)();
};
IntersectionPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "intersection",
  type: IntersectionPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IntersectionPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'intersection'
    }]
  }], null, null);
})();
function isUndefined(value) {
  return typeof value === 'undefined';
}
function isNull(value) {
  return value === null;
}
function isFunction(value) {
  return typeof value === 'function';
}
function isNumber(value) {
  return typeof value === 'number';
}
function isString(value) {
  return typeof value === 'string';
}
function isBoolean(value) {
  return typeof value === 'boolean';
}
function isObject(value) {
  return value !== null && typeof value === 'object';
}
function isNumberFinite(value) {
  return isNumber(value) && isFinite(value);
}
function isVowel(letter) {
  const vowels = ['a', 'e', 'i', 'o', 'u'];
  return vowels.indexOf(letter) !== -1;
}
function ucFirst(text) {
  const [part, ...split] = text.split(/\s/g);
  const ucd = part.toLowerCase().split(/(?=['|-])/g).map(word => word.indexOf('-') + word.indexOf("'") > -2 ? word.slice(0, 2).toUpperCase() + word.slice(2) : word.slice(0, 1).toUpperCase() + word.slice(1)).join('');
  return [ucd, ...split].join(' ');
}
function applyPrecision(num, precision) {
  if (precision <= 0) {
    return Math.round(num);
  }
  const tho = 10 ** precision;
  return Math.round(num * tho) / tho;
}
function extractDeepPropertyByMapKey(obj, map) {
  const keys = map.split('.');
  const head = keys.shift();
  return keys.reduce((prop, key) => {
    return !isUndefined(prop) && !isNull(prop) && !isUndefined(prop[key]) ? prop[key] : undefined;
  }, obj[head || '']);
}
function extractDeepPropertyByParentMapKey(obj, map) {
  const keys = map.split('.');
  const tail = keys.pop();
  const props = extractDeepPropertyByMapKey(obj, keys.join('.'));
  return {
    props,
    tail
  };
}
function getKeysTwoObjects(obj, other) {
  return [...Object.keys(obj), ...Object.keys(other)].filter((key, index, array) => array.indexOf(key) === index);
}
function isDeepEqual(obj, other) {
  if (!isObject(obj) || !isObject(other)) {
    return obj === other;
  }
  return getKeysTwoObjects(obj, other).every(key => {
    if (!isObject(obj[key]) && !isObject(other[key])) {
      return obj[key] === other[key];
    }
    if (!isObject(obj[key]) || !isObject(other[key])) {
      return false;
    }
    return isDeepEqual(obj[key], other[key]);
  });
}
class ReversePipe {
  transform(input) {
    if (isString(input)) {
      return input.split('').reverse().join('');
    }
    return Array.isArray(input) ? input.slice().reverse() : input;
  }
}
ReversePipe.ɵfac = function ReversePipe_Factory(t) {
  return new (t || ReversePipe)();
};
ReversePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "reverse",
  type: ReversePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ReversePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'reverse'
    }]
  }], null, null);
})();
class TailPipe {
  transform(input, num = 0) {
    return Array.isArray(input) ? input.slice(num) : input;
  }
}
TailPipe.ɵfac = function TailPipe_Factory(t) {
  return new (t || TailPipe)();
};
TailPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "tail",
  type: TailPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TailPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'tail'
    }]
  }], null, null);
})();
class TrurthifyPipe {
  transform(input) {
    return Array.isArray(input) ? input.filter(e => !!e) : input;
  }
}
TrurthifyPipe.ɵfac = function TrurthifyPipe_Factory(t) {
  return new (t || TrurthifyPipe)();
};
TrurthifyPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "truthify",
  type: TrurthifyPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TrurthifyPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'truthify'
    }]
  }], null, null);
})();
class UnionPipe {
  transform(input, args = []) {
    if (!Array.isArray(input) || !Array.isArray(args)) {
      return input;
    }
    return args.reduce((newArr, currArr) => {
      return newArr.concat(currArr.reduce((noDupArr, curr) => {
        // tslint:disable-next-line:no-bitwise
        return !~noDupArr.indexOf(curr) && !~newArr.indexOf(curr) ? noDupArr.concat([curr]) : noDupArr;
      }, []));
    }, input);
  }
}
UnionPipe.ɵfac = function UnionPipe_Factory(t) {
  return new (t || UnionPipe)();
};
UnionPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "union",
  type: UnionPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UnionPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'union'
    }]
  }], null, null);
})();
class UniquePipe {
  transform(input, propertyName) {
    const uniques = [];
    return Array.isArray(input) ? isUndefined(propertyName) ? input.filter((e, i) => input.indexOf(e) === i) : input.filter((e, i) => {
      let value = extractDeepPropertyByMapKey(e, propertyName);
      value = isObject(value) ? JSON.stringify(value) : value;
      if (isUndefined(value) || uniques[value]) {
        return false;
      }
      uniques[value] = true;
      return true;
    }) : input;
  }
}
UniquePipe.ɵfac = function UniquePipe_Factory(t) {
  return new (t || UniquePipe)();
};
UniquePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "unique",
  type: UniquePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UniquePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'unique'
    }]
  }], null, null);
})();
class WithoutPipe {
  transform(input, args = []) {
    return Array.isArray(input) ?
    // tslint:disable-next-line:no-bitwise
    input.filter(e => !~args.indexOf(e)) : input;
  }
}
WithoutPipe.ɵfac = function WithoutPipe_Factory(t) {
  return new (t || WithoutPipe)();
};
WithoutPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "without",
  type: WithoutPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](WithoutPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'without'
    }]
  }], null, null);
})();
class PluckPipe {
  transform(input, map) {
    if (Array.isArray(input)) {
      return input.map(e => extractDeepPropertyByMapKey(e, map));
    }
    return isObject(input) ? extractDeepPropertyByMapKey(input, map) : input;
  }
}
PluckPipe.ɵfac = function PluckPipe_Factory(t) {
  return new (t || PluckPipe)();
};
PluckPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "pluck",
  type: PluckPipe,
  pure: false
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PluckPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'pluck',
      pure: false
    }]
  }], null, null);
})();
class ShufflePipe {
  // Using a version of the Fisher-Yates shuffle algorithm
  // https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
  transform(input) {
    if (!Array.isArray(input)) {
      return input;
    }
    const shuffled = [...input];
    const n = input.length - 1;
    for (let i = 0; i < n; ++i) {
      const j = Math.floor(Math.random() * (n - i + 1)) + i;
      [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
    }
    return shuffled;
  }
}
ShufflePipe.ɵfac = function ShufflePipe_Factory(t) {
  return new (t || ShufflePipe)();
};
ShufflePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "shuffle",
  type: ShufflePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ShufflePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'shuffle'
    }]
  }], null, null);
})();
class EveryPipe {
  transform(input, predicate) {
    return Array.isArray(input) ? input.every(predicate) : false;
  }
}
EveryPipe.ɵfac = function EveryPipe_Factory(t) {
  return new (t || EveryPipe)();
};
EveryPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "every",
  type: EveryPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](EveryPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'every'
    }]
  }], null, null);
})();
class SomePipe {
  transform(input, predicate) {
    return Array.isArray(input) ? input.some(predicate) : input;
  }
}
SomePipe.ɵfac = function SomePipe_Factory(t) {
  return new (t || SomePipe)();
};
SomePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "some",
  type: SomePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SomePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'some'
    }]
  }], null, null);
})();
class SamplePipe {
  transform(input, len = 1) {
    if (!Array.isArray(input)) {
      return input;
    }
    let sample = [];
    const tmp = [...input];
    const l = len < tmp.length ? len : tmp.length;
    for (let i = 0; i < l; ++i) {
      sample = sample.concat(tmp.splice(Math.floor(Math.random() * tmp.length), 1));
    }
    return sample;
  }
}
SamplePipe.ɵfac = function SamplePipe_Factory(t) {
  return new (t || SamplePipe)();
};
SamplePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "sample",
  type: SamplePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SamplePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'sample'
    }]
  }], null, null);
})();
class GroupByPipe {
  transform(input, discriminator = [], delimiter = '|') {
    if (!Array.isArray(input)) {
      return input;
    }
    return this.groupBy(input, discriminator, delimiter);
  }
  groupBy(list, discriminator, delimiter) {
    return list.reduce((acc, payload) => {
      const key = this.extractKeyByDiscriminator(discriminator, payload, delimiter);
      acc[key] = Array.isArray(acc[key]) ? acc[key].concat([payload]) : [payload];
      return acc;
    }, {});
  }
  extractKeyByDiscriminator(discriminator, payload, delimiter) {
    if (isFunction(discriminator)) {
      return discriminator(payload);
    }
    if (Array.isArray(discriminator)) {
      return discriminator.map(k => extractDeepPropertyByMapKey(payload, k)).join(delimiter);
    }
    return extractDeepPropertyByMapKey(payload, discriminator);
  }
}
GroupByPipe.ɵfac = function GroupByPipe_Factory(t) {
  return new (t || GroupByPipe)();
};
GroupByPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "groupBy",
  type: GroupByPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](GroupByPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'groupBy'
    }]
  }], null, null);
})();

// tslint:disable no-bitwise
class FilterByPipe {
  transform(input, props, search = '', strict = false) {
    if (!Array.isArray(input) || !Array.isArray(search) && !isString(search) && !isNumberFinite(search) && !isBoolean(search)) {
      return input;
    }
    const terms = String(search).toLowerCase().split(',');
    return input.filter(obj => {
      return props.some(prop => {
        return terms.some(term => {
          const value = extractDeepPropertyByMapKey(obj, prop);
          /* tslint:disable */
          const {
            props,
            tail
          } = extractDeepPropertyByParentMapKey(obj, prop);
          if (isUndefined(value) && !isUndefined(props) && Array.isArray(props)) {
            return props.some(parent => {
              const str = String(parent[tail]).toLowerCase();
              return strict ? str === term : !!~str.indexOf(term);
            });
          }
          if (isUndefined(value)) {
            return false;
          }
          const strValue = String(value).toLowerCase();
          return strict ? term === strValue : !!~strValue.indexOf(term);
        });
      });
    });
  }
}
FilterByPipe.ɵfac = function FilterByPipe_Factory(t) {
  return new (t || FilterByPipe)();
};
FilterByPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "filterBy",
  type: FilterByPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FilterByPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'filterBy'
    }]
  }], null, null);
})();
class OrderByPipe {
  transform(input, config) {
    if (!Array.isArray(input)) {
      return input;
    }
    const out = [...input];
    // sort by multiple properties
    if (Array.isArray(config)) {
      return out.sort((a, b) => {
        const l = config.length;
        for (let i = 0; i < l; ++i) {
          const [prop, asc] = OrderByPipe.extractFromConfig(config[i]);
          const pos = OrderByPipe.orderCompare(prop, asc, a, b);
          if (pos !== 0) {
            return pos;
          }
        }
        return 0;
      });
    }
    // sort by a single property value
    if (isString(config)) {
      const [prop, asc, sign] = OrderByPipe.extractFromConfig(config);
      if (config.length === 1) {
        // tslint:disable-next-line:switch-default
        switch (sign) {
          case '+':
            return out.sort(OrderByPipe.simpleSort.bind(this));
          case '-':
            return out.sort(OrderByPipe.simpleSort.bind(this)).reverse();
        }
      }
      return out.sort(OrderByPipe.orderCompare.bind(this, prop, asc));
    }
    // default sort by value
    return out.sort(OrderByPipe.simpleSort.bind(this));
  }
  static simpleSort(a, b) {
    return isString(a) && isString(b) ? a.toLowerCase().localeCompare(b.toLowerCase()) : a - b;
  }
  static orderCompare(prop, asc, a, b) {
    const first = extractDeepPropertyByMapKey(a, prop);
    const second = extractDeepPropertyByMapKey(b, prop);
    if (first === second) {
      return 0;
    }
    if (isUndefined(first) || first === '') {
      return 1;
    }
    if (isUndefined(second) || second === '') {
      return -1;
    }
    if (isString(first) && isString(second)) {
      const pos = first.toLowerCase().localeCompare(second.toLowerCase());
      return asc ? pos : -pos;
    }
    return asc ? first - second : second - first;
  }
  static extractFromConfig(config) {
    const sign = config.substr(0, 1);
    const prop = config.replace(/^[-+]/, '');
    const asc = sign !== '-';
    return [prop, asc, sign];
  }
}
OrderByPipe.ɵfac = function OrderByPipe_Factory(t) {
  return new (t || OrderByPipe)();
};
OrderByPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "orderBy",
  type: OrderByPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](OrderByPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'orderBy'
    }]
  }], null, null);
})();

// tslint:disable use-pipe-transform-interface
class GroupByImpurePipe extends GroupByPipe {}
GroupByImpurePipe.ɵfac = /* @__PURE__ */(() => {
  let ɵGroupByImpurePipe_BaseFactory;
  return function GroupByImpurePipe_Factory(t) {
    return (ɵGroupByImpurePipe_BaseFactory || (ɵGroupByImpurePipe_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](GroupByImpurePipe)))(t || GroupByImpurePipe);
  };
})();
GroupByImpurePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "groupByImpure",
  type: GroupByImpurePipe,
  pure: false
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](GroupByImpurePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'groupByImpure',
      pure: false
    }]
  }], null, null);
})();

// tslint:disable use-pipe-transform-interface
class FilterByImpurePipe extends FilterByPipe {}
FilterByImpurePipe.ɵfac = /* @__PURE__ */(() => {
  let ɵFilterByImpurePipe_BaseFactory;
  return function FilterByImpurePipe_Factory(t) {
    return (ɵFilterByImpurePipe_BaseFactory || (ɵFilterByImpurePipe_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](FilterByImpurePipe)))(t || FilterByImpurePipe);
  };
})();
FilterByImpurePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "filterByImpure",
  type: FilterByImpurePipe,
  pure: false
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FilterByImpurePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'filterByImpure',
      pure: false
    }]
  }], null, null);
})();

// tslint:disable use-pipe-transform-interface
class OrderByImpurePipe extends OrderByPipe {}
OrderByImpurePipe.ɵfac = /* @__PURE__ */(() => {
  let ɵOrderByImpurePipe_BaseFactory;
  return function OrderByImpurePipe_Factory(t) {
    return (ɵOrderByImpurePipe_BaseFactory || (ɵOrderByImpurePipe_BaseFactory = _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵgetInheritedFactory"](OrderByImpurePipe)))(t || OrderByImpurePipe);
  };
})();
OrderByImpurePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "orderByImpure",
  type: OrderByImpurePipe,
  pure: false
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](OrderByImpurePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'orderByImpure',
      pure: false
    }]
  }], null, null);
})();
class RangePipe {
  transform(start = 1, count = 0, step = 1) {
    return Array(count).fill('').map((v, i) => step * i + start);
  }
}
RangePipe.ɵfac = function RangePipe_Factory(t) {
  return new (t || RangePipe)();
};
RangePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "range",
  type: RangePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RangePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'range'
    }]
  }], null, null);
})();
class ChunkPipe {
  transform(input, size = 1) {
    if (isString(input)) {
      return this.chunk(input.split(''), size);
    }
    return Array.isArray(input) ? this.chunk(input, size) : input;
  }
  chunk(input, size) {
    return Array(Math.ceil(input.length / size)).fill([]).map((_, index) => index * size).map(begin => input.slice(begin, begin + size));
  }
}
ChunkPipe.ɵfac = function ChunkPipe_Factory(t) {
  return new (t || ChunkPipe)();
};
ChunkPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "chunk",
  type: ChunkPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ChunkPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'chunk'
    }]
  }], null, null);
})();
class FromPairsPipe {
  transform(input) {
    if (!Array.isArray(input)) {
      return input;
    }
    return input.reduce((obj, arr) => {
      if (!Array.isArray(arr)) {
        return obj;
      }
      const [prop, val] = arr;
      obj[prop] = val;
      return obj;
    }, {});
  }
}
FromPairsPipe.ɵfac = function FromPairsPipe_Factory(t) {
  return new (t || FromPairsPipe)();
};
FromPairsPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "fromPairs",
  type: FromPairsPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FromPairsPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'fromPairs'
    }]
  }], null, null);
})();
const ARRAY_PIPES = [DiffPipe, FlattenPipe, InitialPipe, IntersectionPipe, ReversePipe, TailPipe, TrurthifyPipe, UnionPipe, UniquePipe, WithoutPipe, PluckPipe, ShufflePipe, EveryPipe, SomePipe, SamplePipe, GroupByPipe, GroupByImpurePipe, FilterByPipe, FilterByImpurePipe, OrderByPipe, OrderByImpurePipe, RangePipe, ChunkPipe, FromPairsPipe];
class NgArrayPipesModule {}
NgArrayPipesModule.ɵfac = function NgArrayPipesModule_Factory(t) {
  return new (t || NgArrayPipesModule)();
};
NgArrayPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgArrayPipesModule
});
NgArrayPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgArrayPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: ARRAY_PIPES,
      imports: [],
      exports: ARRAY_PIPES
    }]
  }], null, null);
})();
class KeysPipe {
  transform(obj) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.keys(obj);
  }
}
KeysPipe.ɵfac = function KeysPipe_Factory(t) {
  return new (t || KeysPipe)();
};
KeysPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "keys",
  type: KeysPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](KeysPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'keys'
    }]
  }], null, null);
})();
class ValuesPipe {
  transform(obj) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.keys(obj).map(k => obj[k]);
  }
}
ValuesPipe.ɵfac = function ValuesPipe_Factory(t) {
  return new (t || ValuesPipe)();
};
ValuesPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "values",
  type: ValuesPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ValuesPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'values'
    }]
  }], null, null);
})();
class PairsPipe {
  transform(obj) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.entries(obj);
  }
}
PairsPipe.ɵfac = function PairsPipe_Factory(t) {
  return new (t || PairsPipe)();
};
PairsPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "pairs",
  type: PairsPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PairsPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'pairs'
    }]
  }], null, null);
})();
class PickPipe {
  transform(obj, ...args) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return args.reduce((o, k) => {
      return Object.assign(o, {
        [k]: obj[k]
      });
    }, {});
  }
}
PickPipe.ɵfac = function PickPipe_Factory(t) {
  return new (t || PickPipe)();
};
PickPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "pick",
  type: PickPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PickPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'pick'
    }]
  }], null, null);
})();
class OmitPipe {
  transform(obj, ...args) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.keys(obj)
    // tslint:disable-next-line:no-bitwise
    .filter(k => !~args.indexOf(k)).reduce((o, k) => {
      return Object.assign(o, {
        [k]: obj[k]
      });
    }, {});
  }
}
OmitPipe.ɵfac = function OmitPipe_Factory(t) {
  return new (t || OmitPipe)();
};
OmitPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "omit",
  type: OmitPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](OmitPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'omit'
    }]
  }], null, null);
})();
class InvertPipe {
  transform(obj) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.keys(obj).reduce((o, k) => {
      return Object.assign(o, {
        [obj[k]]: k
      });
    }, {});
  }
}
InvertPipe.ɵfac = function InvertPipe_Factory(t) {
  return new (t || InvertPipe)();
};
InvertPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "invert",
  type: InvertPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InvertPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'invert'
    }]
  }], null, null);
})();
class InvertByPipe {
  transform(obj, cb) {
    if (Array.isArray(obj) || !isObject(obj)) {
      return obj;
    }
    return Object.keys(obj).reduce((o, k) => {
      const key = cb ? cb(obj[k]) : obj[k];
      return Array.isArray(o[key]) ? (o[key].push(k), o) : Object.assign(o, {
        [key]: [k]
      });
    }, {});
  }
}
InvertByPipe.ɵfac = function InvertByPipe_Factory(t) {
  return new (t || InvertByPipe)();
};
InvertByPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "invertBy",
  type: InvertByPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](InvertByPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'invertBy'
    }]
  }], null, null);
})();
class DiffObjPipe {
  transform(obj, original = {}) {
    if (Array.isArray(obj) || Array.isArray(original) || !isObject(obj) || !isObject(original)) {
      return {};
    }
    return getKeysTwoObjects(obj, original).reduce((diff, key) => {
      if (!isDeepEqual(original[key], obj[key])) {
        diff[key] = obj[key];
      }
      return diff;
    }, {});
  }
}
DiffObjPipe.ɵfac = function DiffObjPipe_Factory(t) {
  return new (t || DiffObjPipe)();
};
DiffObjPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "diffObj",
  type: DiffObjPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DiffObjPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'diffObj'
    }]
  }], null, null);
})();
const OBJECT_PIPES = [KeysPipe, ValuesPipe, PairsPipe, PickPipe, InvertPipe, InvertByPipe, OmitPipe, DiffObjPipe];
class NgObjectPipesModule {}
NgObjectPipesModule.ɵfac = function NgObjectPipesModule_Factory(t) {
  return new (t || NgObjectPipesModule)();
};
NgObjectPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgObjectPipesModule
});
NgObjectPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgObjectPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: OBJECT_PIPES,
      imports: [],
      exports: OBJECT_PIPES
    }]
  }], null, null);
})();

/**
 * Takes a string and returns the string prepended by 'a' or 'an'.
 * Uses both naive and holdout-list approaches.
 * @constructor
 * @param {string} stringEntity - Entity to prepend 'a' or 'an' to.
 */
class AorAnPipe {
  constructor() {
    this.irregularMap = {
      herb: 'an',
      honor: 'an',
      honorable: 'an',
      hour: 'an',
      mba: 'an',
      msc: 'an',
      'm.sc.': 'an',
      unicorn: 'a'
    };
  }
  transform(stringEntity) {
    if (!stringEntity || stringEntity === '') {
      return '';
    } else {
      const firstWord = stringEntity.trim().split(' ')[0];
      if (this.irregularMap[firstWord.toLocaleLowerCase()]) {
        return `${this.irregularMap[firstWord.toLocaleLowerCase()]} ${stringEntity}`;
      } else {
        return isVowel(stringEntity[0]) ? `an ${stringEntity}` : `a ${stringEntity}`;
      }
    }
  }
}
AorAnPipe.ɵfac = function AorAnPipe_Factory(t) {
  return new (t || AorAnPipe)();
};
AorAnPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "aOrAn",
  type: AorAnPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](AorAnPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'aOrAn'
    }]
  }], null, null);
})();
class UcWordsPipe {
  transform(text) {
    if (isString(text)) {
      return text.split(' ').map(sub => ucFirst(sub)).join(' ');
    }
    return text;
  }
}
UcWordsPipe.ɵfac = function UcWordsPipe_Factory(t) {
  return new (t || UcWordsPipe)();
};
UcWordsPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "ucwords",
  type: UcWordsPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UcWordsPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'ucwords'
    }]
  }], null, null);
})();
class LeftTrimPipe {
  transform(text, chars = '\\s') {
    return isString(text) ? text.replace(new RegExp(`^[${chars}]+`), '') : text;
  }
}
LeftTrimPipe.ɵfac = function LeftTrimPipe_Factory(t) {
  return new (t || LeftTrimPipe)();
};
LeftTrimPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "ltrim",
  type: LeftTrimPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LeftTrimPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'ltrim'
    }]
  }], null, null);
})();
class RepeatPipe {
  transform(str, n = 1, separator = '') {
    if (n <= 0) {
      throw new RangeError();
    }
    return n === 1 ? str : this.repeat(str, n - 1, separator);
  }
  repeat(str, n, separator) {
    return isString(str) ? n === 0 ? str : str + separator + this.repeat(str, n - 1, separator) : str;
  }
}
RepeatPipe.ɵfac = function RepeatPipe_Factory(t) {
  return new (t || RepeatPipe)();
};
RepeatPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "repeat",
  type: RepeatPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RepeatPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'repeat'
    }]
  }], null, null);
})();
class RightTrimPipe {
  transform(text, chars = '\\s') {
    return isString(text) ? text.replace(new RegExp(`[${chars}]+$`), '') : text;
  }
}
RightTrimPipe.ɵfac = function RightTrimPipe_Factory(t) {
  return new (t || RightTrimPipe)();
};
RightTrimPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "rtrim",
  type: RightTrimPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RightTrimPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'rtrim'
    }]
  }], null, null);
})();
class ScanPipe {
  transform(text, args = []) {
    return isString(text) ? text.replace(/\{(\d+)}/g, (match, index) => !isUndefined(args[index]) ? args[index] : match) : text;
  }
}
ScanPipe.ɵfac = function ScanPipe_Factory(t) {
  return new (t || ScanPipe)();
};
ScanPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "scan",
  type: ScanPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ScanPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'scan'
    }]
  }], null, null);
})();
class ShortenPipe {
  transform(text, length = 0, suffix = '', wordBreak = true) {
    if (!isString(text)) {
      return text;
    }
    if (text.length > length) {
      if (wordBreak) {
        return text.slice(0, length) + suffix;
      }
      // tslint:disable-next-line:no-bitwise
      if (!!~text.indexOf(' ', length)) {
        return text.slice(0, text.indexOf(' ', length)) + suffix;
      }
    }
    return text;
  }
}
ShortenPipe.ɵfac = function ShortenPipe_Factory(t) {
  return new (t || ShortenPipe)();
};
ShortenPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "shorten",
  type: ShortenPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](ShortenPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'shorten'
    }]
  }], null, null);
})();
class StripTagsPipe {
  transform(text, ...allowedTags) {
    return allowedTags.length > 0 ? text.replace(new RegExp(`<(?!\/?(${allowedTags.join('|')})\s*\/?)[^>]+>`, 'g'), '') : text.replace(/<(?:.|\s)*?>/g, '');
  }
}
StripTagsPipe.ɵfac = function StripTagsPipe_Factory(t) {
  return new (t || StripTagsPipe)();
};
StripTagsPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "stripTags",
  type: StripTagsPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](StripTagsPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'stripTags'
    }]
  }], null, null);
})();
class TrimPipe {
  transform(text, chars = '\\s') {
    return isString(text) ? text.replace(new RegExp(`^[${chars}]+|[${chars}]+$`, 'g'), '') : text;
  }
}
TrimPipe.ɵfac = function TrimPipe_Factory(t) {
  return new (t || TrimPipe)();
};
TrimPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "trim",
  type: TrimPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TrimPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'trim'
    }]
  }], null, null);
})();
class UcFirstPipe {
  transform(text) {
    return isString(text) ? ucFirst(text) : text;
  }
}
UcFirstPipe.ɵfac = function UcFirstPipe_Factory(t) {
  return new (t || UcFirstPipe)();
};
UcFirstPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "ucfirst",
  type: UcFirstPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UcFirstPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'ucfirst'
    }]
  }], null, null);
})();
class SlugifyPipe {
  transform(str) {
    return isString(str) ? str.toLowerCase().trim().replace(/[^\w\-]+/g, ' ').replace(/\s+/g, '-') : str;
  }
}
SlugifyPipe.ɵfac = function SlugifyPipe_Factory(t) {
  return new (t || SlugifyPipe)();
};
SlugifyPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "slugify",
  type: SlugifyPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlugifyPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'slugify'
    }]
  }], null, null);
})();
class CamelizePipe {
  transform(text, chars = '\\s') {
    if (!isString(text)) {
      return text;
    }
    return text.toLowerCase().split(/[-_\s]/g).filter(v => !!v).map((word, key) => {
      return !key ? word : word.slice(0, 1).toUpperCase() + word.slice(1);
    }).join('');
  }
}
CamelizePipe.ɵfac = function CamelizePipe_Factory(t) {
  return new (t || CamelizePipe)();
};
CamelizePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "camelize",
  type: CamelizePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CamelizePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'camelize'
    }]
  }], null, null);
})();
class LatinisePipe {
  constructor() {
    // Source: http://semplicewebsites.com/removing-accents-javascript
    // tslint:disable-next-line whitespace max-line-length object-literal-key-quotes
    this.latinMap = {
      'Á': 'A',
      'Ă': 'A',
      'Ắ': 'A',
      'Ặ': 'A',
      'Ằ': 'A',
      'Ẳ': 'A',
      'Ẵ': 'A',
      'Ǎ': 'A',
      'Â': 'A',
      'Ấ': 'A',
      'Ậ': 'A',
      'Ầ': 'A',
      'Ẩ': 'A',
      'Ẫ': 'A',
      'Ä': 'A',
      'Ǟ': 'A',
      'Ȧ': 'A',
      'Ǡ': 'A',
      'Ạ': 'A',
      'Ȁ': 'A',
      'À': 'A',
      'Ả': 'A',
      'Ȃ': 'A',
      'Ā': 'A',
      'Ą': 'A',
      'Å': 'A',
      'Ǻ': 'A',
      'Ḁ': 'A',
      'Ⱥ': 'A',
      'Ã': 'A',
      'Ꜳ': 'AA',
      'Æ': 'AE',
      'Ǽ': 'AE',
      'Ǣ': 'AE',
      'Ꜵ': 'AO',
      'Ꜷ': 'AU',
      'Ꜹ': 'AV',
      'Ꜻ': 'AV',
      'Ꜽ': 'AY',
      'Ḃ': 'B',
      'Ḅ': 'B',
      'Ɓ': 'B',
      'Ḇ': 'B',
      'Ƀ': 'B',
      'Ƃ': 'B',
      'Ć': 'C',
      'Č': 'C',
      'Ç': 'C',
      'Ḉ': 'C',
      'Ĉ': 'C',
      'Ċ': 'C',
      'Ƈ': 'C',
      'Ȼ': 'C',
      'Ď': 'D',
      'Ḑ': 'D',
      'Ḓ': 'D',
      'Ḋ': 'D',
      'Ḍ': 'D',
      'Ɗ': 'D',
      'Ḏ': 'D',
      'Dz': 'D',
      'Dž': 'D',
      'Đ': 'D',
      'Ƌ': 'D',
      'DZ': 'DZ',
      'DŽ': 'DZ',
      'É': 'E',
      'Ĕ': 'E',
      'Ě': 'E',
      'Ȩ': 'E',
      'Ḝ': 'E',
      'Ê': 'E',
      'Ế': 'E',
      'Ệ': 'E',
      'Ề': 'E',
      'Ể': 'E',
      'Ễ': 'E',
      'Ḙ': 'E',
      'Ë': 'E',
      'Ė': 'E',
      'Ẹ': 'E',
      'Ȅ': 'E',
      'È': 'E',
      'Ẻ': 'E',
      'Ȇ': 'E',
      'Ē': 'E',
      'Ḗ': 'E',
      'Ḕ': 'E',
      'Ę': 'E',
      'Ɇ': 'E',
      'Ẽ': 'E',
      'Ḛ': 'E',
      'Ꝫ': 'ET',
      'Ḟ': 'F',
      'Ƒ': 'F',
      'Ǵ': 'G',
      'Ğ': 'G',
      'Ǧ': 'G',
      'Ģ': 'G',
      'Ĝ': 'G',
      'Ġ': 'G',
      'Ɠ': 'G',
      'Ḡ': 'G',
      'Ǥ': 'G',
      'Ḫ': 'H',
      'Ȟ': 'H',
      'Ḩ': 'H',
      'Ĥ': 'H',
      'Ⱨ': 'H',
      'Ḧ': 'H',
      'Ḣ': 'H',
      'Ḥ': 'H',
      'Ħ': 'H',
      'Í': 'I',
      'Ĭ': 'I',
      'Ǐ': 'I',
      'Î': 'I',
      'Ï': 'I',
      'Ḯ': 'I',
      'İ': 'I',
      'Ị': 'I',
      'Ȉ': 'I',
      'Ì': 'I',
      'Ỉ': 'I',
      'Ȋ': 'I',
      'Ī': 'I',
      'Į': 'I',
      'Ɨ': 'I',
      'Ĩ': 'I',
      'Ḭ': 'I',
      'Ꝺ': 'D',
      'Ꝼ': 'F',
      'Ᵹ': 'G',
      'Ꞃ': 'R',
      'Ꞅ': 'S',
      'Ꞇ': 'T',
      'Ꝭ': 'IS',
      'Ĵ': 'J',
      'Ɉ': 'J',
      'Ḱ': 'K',
      'Ǩ': 'K',
      'Ķ': 'K',
      'Ⱪ': 'K',
      'Ꝃ': 'K',
      'Ḳ': 'K',
      'Ƙ': 'K',
      'Ḵ': 'K',
      'Ꝁ': 'K',
      'Ꝅ': 'K',
      'Ĺ': 'L',
      'Ƚ': 'L',
      'Ľ': 'L',
      'Ļ': 'L',
      'Ḽ': 'L',
      'Ḷ': 'L',
      'Ḹ': 'L',
      'Ⱡ': 'L',
      'Ꝉ': 'L',
      'Ḻ': 'L',
      'Ŀ': 'L',
      'Ɫ': 'L',
      'Lj': 'L',
      'Ł': 'L',
      'LJ': 'LJ',
      'Ḿ': 'M',
      'Ṁ': 'M',
      'Ṃ': 'M',
      'Ɱ': 'M',
      'Ń': 'N',
      'Ň': 'N',
      'Ņ': 'N',
      'Ṋ': 'N',
      'Ṅ': 'N',
      'Ṇ': 'N',
      'Ǹ': 'N',
      'Ɲ': 'N',
      'Ṉ': 'N',
      'Ƞ': 'N',
      'Nj': 'N',
      'Ñ': 'N',
      'NJ': 'NJ',
      'Ó': 'O',
      'Ŏ': 'O',
      'Ǒ': 'O',
      'Ô': 'O',
      'Ố': 'O',
      'Ộ': 'O',
      'Ồ': 'O',
      'Ổ': 'O',
      'Ỗ': 'O',
      'Ö': 'O',
      'Ȫ': 'O',
      'Ȯ': 'O',
      'Ȱ': 'O',
      'Ọ': 'O',
      'Ő': 'O',
      'Ȍ': 'O',
      'Ò': 'O',
      'Ỏ': 'O',
      'Ơ': 'O',
      'Ớ': 'O',
      'Ợ': 'O',
      'Ờ': 'O',
      'Ở': 'O',
      'Ỡ': 'O',
      'Ȏ': 'O',
      'Ꝋ': 'O',
      'Ꝍ': 'O',
      'Ō': 'O',
      'Ṓ': 'O',
      'Ṑ': 'O',
      'Ɵ': 'O',
      'Ǫ': 'O',
      'Ǭ': 'O',
      'Ø': 'O',
      'Ǿ': 'O',
      'Õ': 'O',
      'Ṍ': 'O',
      'Ṏ': 'O',
      'Ȭ': 'O',
      'Ƣ': 'OI',
      'Ꝏ': 'OO',
      'Ɛ': 'E',
      'Ɔ': 'O',
      'Ȣ': 'OU',
      'Ṕ': 'P',
      'Ṗ': 'P',
      'Ꝓ': 'P',
      'Ƥ': 'P',
      'Ꝕ': 'P',
      'Ᵽ': 'P',
      'Ꝑ': 'P',
      'Ꝙ': 'Q',
      'Ꝗ': 'Q',
      'Ŕ': 'R',
      'Ř': 'R',
      'Ŗ': 'R',
      'Ṙ': 'R',
      'Ṛ': 'R',
      'Ṝ': 'R',
      'Ȑ': 'R',
      'Ȓ': 'R',
      'Ṟ': 'R',
      'Ɍ': 'R',
      'Ɽ': 'R',
      'Ꜿ': 'C',
      'Ǝ': 'E',
      'Ś': 'S',
      'Ṥ': 'S',
      'Š': 'S',
      'Ṧ': 'S',
      'Ş': 'S',
      'Ŝ': 'S',
      'Ș': 'S',
      'Ṡ': 'S',
      'Ṣ': 'S',
      'Ṩ': 'S',
      'ẞ': 'SS',
      'Ť': 'T',
      'Ţ': 'T',
      'Ṱ': 'T',
      'Ț': 'T',
      'Ⱦ': 'T',
      'Ṫ': 'T',
      'Ṭ': 'T',
      'Ƭ': 'T',
      'Ṯ': 'T',
      'Ʈ': 'T',
      'Ŧ': 'T',
      'Ɐ': 'A',
      'Ꞁ': 'L',
      'Ɯ': 'M',
      'Ʌ': 'V',
      'Ꜩ': 'TZ',
      'Ú': 'U',
      'Ŭ': 'U',
      'Ǔ': 'U',
      'Û': 'U',
      'Ṷ': 'U',
      'Ü': 'U',
      'Ǘ': 'U',
      'Ǚ': 'U',
      'Ǜ': 'U',
      'Ǖ': 'U',
      'Ṳ': 'U',
      'Ụ': 'U',
      'Ű': 'U',
      'Ȕ': 'U',
      'Ù': 'U',
      'Ủ': 'U',
      'Ư': 'U',
      'Ứ': 'U',
      'Ự': 'U',
      'Ừ': 'U',
      'Ử': 'U',
      'Ữ': 'U',
      'Ȗ': 'U',
      'Ū': 'U',
      'Ṻ': 'U',
      'Ų': 'U',
      'Ů': 'U',
      'Ũ': 'U',
      'Ṹ': 'U',
      'Ṵ': 'U',
      'Ꝟ': 'V',
      'Ṿ': 'V',
      'Ʋ': 'V',
      'Ṽ': 'V',
      'Ꝡ': 'VY',
      'Ẃ': 'W',
      'Ŵ': 'W',
      'Ẅ': 'W',
      'Ẇ': 'W',
      'Ẉ': 'W',
      'Ẁ': 'W',
      'Ⱳ': 'W',
      'Ẍ': 'X',
      'Ẋ': 'X',
      'Ý': 'Y',
      'Ŷ': 'Y',
      'Ÿ': 'Y',
      'Ẏ': 'Y',
      'Ỵ': 'Y',
      'Ỳ': 'Y',
      'Ƴ': 'Y',
      'Ỷ': 'Y',
      'Ỿ': 'Y',
      'Ȳ': 'Y',
      'Ɏ': 'Y',
      'Ỹ': 'Y',
      'Ź': 'Z',
      'Ž': 'Z',
      'Ẑ': 'Z',
      'Ⱬ': 'Z',
      'Ż': 'Z',
      'Ẓ': 'Z',
      'Ȥ': 'Z',
      'Ẕ': 'Z',
      'Ƶ': 'Z',
      'IJ': 'IJ',
      'Œ': 'OE',
      'ᴀ': 'A',
      'ᴁ': 'AE',
      'ʙ': 'B',
      'ᴃ': 'B',
      'ᴄ': 'C',
      'ᴅ': 'D',
      'ᴇ': 'E',
      'ꜰ': 'F',
      'ɢ': 'G',
      'ʛ': 'G',
      'ʜ': 'H',
      'ɪ': 'I',
      'ʁ': 'R',
      'ᴊ': 'J',
      'ᴋ': 'K',
      'ʟ': 'L',
      'ᴌ': 'L',
      'ᴍ': 'M',
      'ɴ': 'N',
      'ᴏ': 'O',
      'ɶ': 'OE',
      'ᴐ': 'O',
      'ᴕ': 'OU',
      'ᴘ': 'P',
      'ʀ': 'R',
      'ᴎ': 'N',
      'ᴙ': 'R',
      'ꜱ': 'S',
      'ᴛ': 'T',
      'ⱻ': 'E',
      'ᴚ': 'R',
      'ᴜ': 'U',
      'ᴠ': 'V',
      'ᴡ': 'W',
      'ʏ': 'Y',
      'ᴢ': 'Z',
      'á': 'a',
      'ă': 'a',
      'ắ': 'a',
      'ặ': 'a',
      'ằ': 'a',
      'ẳ': 'a',
      'ẵ': 'a',
      'ǎ': 'a',
      'â': 'a',
      'ấ': 'a',
      'ậ': 'a',
      'ầ': 'a',
      'ẩ': 'a',
      'ẫ': 'a',
      'ä': 'a',
      'ǟ': 'a',
      'ȧ': 'a',
      'ǡ': 'a',
      'ạ': 'a',
      'ȁ': 'a',
      'à': 'a',
      'ả': 'a',
      'ȃ': 'a',
      'ā': 'a',
      'ą': 'a',
      'ᶏ': 'a',
      'ẚ': 'a',
      'å': 'a',
      'ǻ': 'a',
      'ḁ': 'a',
      'ⱥ': 'a',
      'ã': 'a',
      'ꜳ': 'aa',
      'æ': 'ae',
      'ǽ': 'ae',
      'ǣ': 'ae',
      'ꜵ': 'ao',
      'ꜷ': 'au',
      'ꜹ': 'av',
      'ꜻ': 'av',
      'ꜽ': 'ay',
      'ḃ': 'b',
      'ḅ': 'b',
      'ɓ': 'b',
      'ḇ': 'b',
      'ᵬ': 'b',
      'ᶀ': 'b',
      'ƀ': 'b',
      'ƃ': 'b',
      'ɵ': 'o',
      'ć': 'c',
      'č': 'c',
      'ç': 'c',
      'ḉ': 'c',
      'ĉ': 'c',
      'ɕ': 'c',
      'ċ': 'c',
      'ƈ': 'c',
      'ȼ': 'c',
      'ď': 'd',
      'ḑ': 'd',
      'ḓ': 'd',
      'ȡ': 'd',
      'ḋ': 'd',
      'ḍ': 'd',
      'ɗ': 'd',
      'ᶑ': 'd',
      'ḏ': 'd',
      'ᵭ': 'd',
      'ᶁ': 'd',
      'đ': 'd',
      'ɖ': 'd',
      'ƌ': 'd',
      'ı': 'i',
      'ȷ': 'j',
      'ɟ': 'j',
      'ʄ': 'j',
      'dz': 'dz',
      'dž': 'dz',
      'é': 'e',
      'ĕ': 'e',
      'ě': 'e',
      'ȩ': 'e',
      'ḝ': 'e',
      'ê': 'e',
      'ế': 'e',
      'ệ': 'e',
      'ề': 'e',
      'ể': 'e',
      'ễ': 'e',
      'ḙ': 'e',
      'ë': 'e',
      'ė': 'e',
      'ẹ': 'e',
      'ȅ': 'e',
      'è': 'e',
      'ẻ': 'e',
      'ȇ': 'e',
      'ē': 'e',
      'ḗ': 'e',
      'ḕ': 'e',
      'ⱸ': 'e',
      'ę': 'e',
      'ᶒ': 'e',
      'ɇ': 'e',
      'ẽ': 'e',
      'ḛ': 'e',
      'ꝫ': 'et',
      'ḟ': 'f',
      'ƒ': 'f',
      'ᵮ': 'f',
      'ᶂ': 'f',
      'ǵ': 'g',
      'ğ': 'g',
      'ǧ': 'g',
      'ģ': 'g',
      'ĝ': 'g',
      'ġ': 'g',
      'ɠ': 'g',
      'ḡ': 'g',
      'ᶃ': 'g',
      'ǥ': 'g',
      'ḫ': 'h',
      'ȟ': 'h',
      'ḩ': 'h',
      'ĥ': 'h',
      'ⱨ': 'h',
      'ḧ': 'h',
      'ḣ': 'h',
      'ḥ': 'h',
      'ɦ': 'h',
      'ẖ': 'h',
      'ħ': 'h',
      'ƕ': 'hv',
      'í': 'i',
      'ĭ': 'i',
      'ǐ': 'i',
      'î': 'i',
      'ï': 'i',
      'ḯ': 'i',
      'ị': 'i',
      'ȉ': 'i',
      'ì': 'i',
      'ỉ': 'i',
      'ȋ': 'i',
      'ī': 'i',
      'į': 'i',
      'ᶖ': 'i',
      'ɨ': 'i',
      'ĩ': 'i',
      'ḭ': 'i',
      'ꝺ': 'd',
      'ꝼ': 'f',
      'ᵹ': 'g',
      'ꞃ': 'r',
      'ꞅ': 's',
      'ꞇ': 't',
      'ꝭ': 'is',
      'ǰ': 'j',
      'ĵ': 'j',
      'ʝ': 'j',
      'ɉ': 'j',
      'ḱ': 'k',
      'ǩ': 'k',
      'ķ': 'k',
      'ⱪ': 'k',
      'ꝃ': 'k',
      'ḳ': 'k',
      'ƙ': 'k',
      'ḵ': 'k',
      'ᶄ': 'k',
      'ꝁ': 'k',
      'ꝅ': 'k',
      'ĺ': 'l',
      'ƚ': 'l',
      'ɬ': 'l',
      'ľ': 'l',
      'ļ': 'l',
      'ḽ': 'l',
      'ȴ': 'l',
      'ḷ': 'l',
      'ḹ': 'l',
      'ⱡ': 'l',
      'ꝉ': 'l',
      'ḻ': 'l',
      'ŀ': 'l',
      'ɫ': 'l',
      'ᶅ': 'l',
      'ɭ': 'l',
      'ł': 'l',
      'lj': 'lj',
      'ſ': 's',
      'ẜ': 's',
      'ẛ': 's',
      'ẝ': 's',
      'ḿ': 'm',
      'ṁ': 'm',
      'ṃ': 'm',
      'ɱ': 'm',
      'ᵯ': 'm',
      'ᶆ': 'm',
      'ń': 'n',
      'ň': 'n',
      'ņ': 'n',
      'ṋ': 'n',
      'ȵ': 'n',
      'ṅ': 'n',
      'ṇ': 'n',
      'ǹ': 'n',
      'ɲ': 'n',
      'ṉ': 'n',
      'ƞ': 'n',
      'ᵰ': 'n',
      'ᶇ': 'n',
      'ɳ': 'n',
      'ñ': 'n',
      'nj': 'nj',
      'ó': 'o',
      'ŏ': 'o',
      'ǒ': 'o',
      'ô': 'o',
      'ố': 'o',
      'ộ': 'o',
      'ồ': 'o',
      'ổ': 'o',
      'ỗ': 'o',
      'ö': 'o',
      'ȫ': 'o',
      'ȯ': 'o',
      'ȱ': 'o',
      'ọ': 'o',
      'ő': 'o',
      'ȍ': 'o',
      'ò': 'o',
      'ỏ': 'o',
      'ơ': 'o',
      'ớ': 'o',
      'ợ': 'o',
      'ờ': 'o',
      'ở': 'o',
      'ỡ': 'o',
      'ȏ': 'o',
      'ꝋ': 'o',
      'ꝍ': 'o',
      'ⱺ': 'o',
      'ō': 'o',
      'ṓ': 'o',
      'ṑ': 'o',
      'ǫ': 'o',
      'ǭ': 'o',
      'ø': 'o',
      'ǿ': 'o',
      'õ': 'o',
      'ṍ': 'o',
      'ṏ': 'o',
      'ȭ': 'o',
      'ƣ': 'oi',
      'ꝏ': 'oo',
      'ɛ': 'e',
      'ᶓ': 'e',
      'ɔ': 'o',
      'ᶗ': 'o',
      'ȣ': 'ou',
      'ṕ': 'p',
      'ṗ': 'p',
      'ꝓ': 'p',
      'ƥ': 'p',
      'ᵱ': 'p',
      'ᶈ': 'p',
      'ꝕ': 'p',
      'ᵽ': 'p',
      'ꝑ': 'p',
      'ꝙ': 'q',
      'ʠ': 'q',
      'ɋ': 'q',
      'ꝗ': 'q',
      'ŕ': 'r',
      'ř': 'r',
      'ŗ': 'r',
      'ṙ': 'r',
      'ṛ': 'r',
      'ṝ': 'r',
      'ȑ': 'r',
      'ɾ': 'r',
      'ᵳ': 'r',
      'ȓ': 'r',
      'ṟ': 'r',
      'ɼ': 'r',
      'ᵲ': 'r',
      'ᶉ': 'r',
      'ɍ': 'r',
      'ɽ': 'r',
      'ↄ': 'c',
      'ꜿ': 'c',
      'ɘ': 'e',
      'ɿ': 'r',
      'ś': 's',
      'ṥ': 's',
      'š': 's',
      'ṧ': 's',
      'ş': 's',
      'ŝ': 's',
      'ș': 's',
      'ṡ': 's',
      'ṣ': 's',
      'ṩ': 's',
      'ʂ': 's',
      'ᵴ': 's',
      'ᶊ': 's',
      'ȿ': 's',
      'ɡ': 'g',
      'ß': 'ss',
      'ᴑ': 'o',
      'ᴓ': 'o',
      'ᴝ': 'u',
      'ť': 't',
      'ţ': 't',
      'ṱ': 't',
      'ț': 't',
      'ȶ': 't',
      'ẗ': 't',
      'ⱦ': 't',
      'ṫ': 't',
      'ṭ': 't',
      'ƭ': 't',
      'ṯ': 't',
      'ᵵ': 't',
      'ƫ': 't',
      'ʈ': 't',
      'ŧ': 't',
      'ᵺ': 'th',
      'ɐ': 'a',
      'ᴂ': 'ae',
      'ǝ': 'e',
      'ᵷ': 'g',
      'ɥ': 'h',
      'ʮ': 'h',
      'ʯ': 'h',
      'ᴉ': 'i',
      'ʞ': 'k',
      'ꞁ': 'l',
      'ɯ': 'm',
      'ɰ': 'm',
      'ᴔ': 'oe',
      'ɹ': 'r',
      'ɻ': 'r',
      'ɺ': 'r',
      'ⱹ': 'r',
      'ʇ': 't',
      'ʌ': 'v',
      'ʍ': 'w',
      'ʎ': 'y',
      'ꜩ': 'tz',
      'ú': 'u',
      'ŭ': 'u',
      'ǔ': 'u',
      'û': 'u',
      'ṷ': 'u',
      'ü': 'u',
      'ǘ': 'u',
      'ǚ': 'u',
      'ǜ': 'u',
      'ǖ': 'u',
      'ṳ': 'u',
      'ụ': 'u',
      'ű': 'u',
      'ȕ': 'u',
      'ù': 'u',
      'ủ': 'u',
      'ư': 'u',
      'ứ': 'u',
      'ự': 'u',
      'ừ': 'u',
      'ử': 'u',
      'ữ': 'u',
      'ȗ': 'u',
      'ū': 'u',
      'ṻ': 'u',
      'ų': 'u',
      'ᶙ': 'u',
      'ů': 'u',
      'ũ': 'u',
      'ṹ': 'u',
      'ṵ': 'u',
      'ᵫ': 'ue',
      'ꝸ': 'um',
      'ⱴ': 'v',
      'ꝟ': 'v',
      'ṿ': 'v',
      'ʋ': 'v',
      'ᶌ': 'v',
      'ⱱ': 'v',
      'ṽ': 'v',
      'ꝡ': 'vy',
      'ẃ': 'w',
      'ŵ': 'w',
      'ẅ': 'w',
      'ẇ': 'w',
      'ẉ': 'w',
      'ẁ': 'w',
      'ⱳ': 'w',
      'ẘ': 'w',
      'ẍ': 'x',
      'ẋ': 'x',
      'ᶍ': 'x',
      'ý': 'y',
      'ŷ': 'y',
      'ÿ': 'y',
      'ẏ': 'y',
      'ỵ': 'y',
      'ỳ': 'y',
      'ƴ': 'y',
      'ỷ': 'y',
      'ỿ': 'y',
      'ȳ': 'y',
      'ẙ': 'y',
      'ɏ': 'y',
      'ỹ': 'y',
      'ź': 'z',
      'ž': 'z',
      'ẑ': 'z',
      'ʑ': 'z',
      'ⱬ': 'z',
      'ż': 'z',
      'ẓ': 'z',
      'ȥ': 'z',
      'ẕ': 'z',
      'ᵶ': 'z',
      'ᶎ': 'z',
      'ʐ': 'z',
      'ƶ': 'z',
      'ɀ': 'z',
      'ff': 'ff',
      'ffi': 'ffi',
      'ffl': 'ffl',
      'fi': 'fi',
      'fl': 'fl',
      'ij': 'ij',
      'œ': 'oe',
      'st': 'st',
      'ₐ': 'a',
      'ₑ': 'e',
      'ᵢ': 'i',
      'ⱼ': 'j',
      'ₒ': 'o',
      'ᵣ': 'r',
      'ᵤ': 'u',
      'ᵥ': 'v',
      'ₓ': 'x'
    };
  }
  transform(text, chars = '\\s') {
    return isString(text) ? text.replace(/[^A-Za-z0-9]/g, key => {
      return this.latinMap[key] || key;
    }) : text;
  }
}
LatinisePipe.ɵfac = function LatinisePipe_Factory(t) {
  return new (t || LatinisePipe)();
};
LatinisePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "latinise",
  type: LatinisePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LatinisePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'latinise'
    }]
  }], null, null);
})();
class LinesPipe {
  transform(text, chars = '\\s') {
    return isString(text) ? text.replace(/\r\n/g, '\n').split('\n') : text;
  }
}
LinesPipe.ɵfac = function LinesPipe_Factory(t) {
  return new (t || LinesPipe)();
};
LinesPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "lines",
  type: LinesPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LinesPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'lines'
    }]
  }], null, null);
})();
class UnderscorePipe {
  transform(text, chars = '\\s') {
    return isString(text) ? text.trim().replace(/\s+/g, '').replace(/[A-Z]/g, (c, k) => {
      return k ? `_${c.toLowerCase()}` : c.toLowerCase();
    }) : text;
  }
}
UnderscorePipe.ɵfac = function UnderscorePipe_Factory(t) {
  return new (t || UnderscorePipe)();
};
UnderscorePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "underscore",
  type: UnderscorePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](UnderscorePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'underscore'
    }]
  }], null, null);
})();
class MatchPipe {
  transform(text, pattern, flags) {
    if (!isString(text)) {
      return text;
    }
    return text.match(new RegExp(pattern, flags));
  }
}
MatchPipe.ɵfac = function MatchPipe_Factory(t) {
  return new (t || MatchPipe)();
};
MatchPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "match",
  type: MatchPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MatchPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'match'
    }]
  }], null, null);
})();
class TestPipe {
  transform(text, pattern, flags) {
    if (!isString(text)) {
      return text;
    }
    return new RegExp(pattern, flags).test(text);
  }
}
TestPipe.ɵfac = function TestPipe_Factory(t) {
  return new (t || TestPipe)();
};
TestPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "test",
  type: TestPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TestPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'test'
    }]
  }], null, null);
})();
class LeftPadPipe {
  transform(str, length, padCharacter = ' ') {
    if (!isString(str) || str.length >= length) {
      return str;
    }
    while (str.length < length) {
      str = padCharacter + str;
    }
    return str;
  }
}
LeftPadPipe.ɵfac = function LeftPadPipe_Factory(t) {
  return new (t || LeftPadPipe)();
};
LeftPadPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "lpad",
  type: LeftPadPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](LeftPadPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'lpad'
    }]
  }], null, null);
})();
class RightPadPipe {
  transform(str, length = 1, padCharacter = ' ') {
    if (!isString(str) || str.length >= length) {
      return str;
    }
    while (str.length < length) {
      str = str + padCharacter;
    }
    return str;
  }
}
RightPadPipe.ɵfac = function RightPadPipe_Factory(t) {
  return new (t || RightPadPipe)();
};
RightPadPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "rpad",
  type: RightPadPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RightPadPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'rpad'
    }]
  }], null, null);
})();

/**
 * Takes a singular entity string and pluralizes it.
 * Uses both naive and holdout-list approaches.
 * If several words appear in the string, only the last word is pluralized -- this
 * means that if "your story" was passed in, "your stories" would be passed out.
 *
 * @param {string} singularEntity - Entity to pluralize. Pass as a singular ('story' or 'house').
 *          NOTE: The last word is examined. So you can pass in e.g. 'my story'.
 * @param {number} [quantity=0] quantity - How many of the entity are there? If left blank, this will
 *          pluralize the string (e.g. 'story' -> 'stories', 'house' -> 'houses'). If given a value,
 *          this will pluralize appropriately (e.g. ('story', 1) -> 'story', ('story', 2) -> 'stories').
 */
class MakePluralStringPipe {
  constructor() {
    this.irregularMap = {
      addendum: 'addenda',
      alga: 'algae',
      alumna: 'alumnae',
      alumnus: 'alumni',
      analysis: 'analyses',
      antenna: 'antennae',
      appendix: 'appendices',
      aquarium: 'aquaria',
      arch: 'arches',
      axe: 'axes',
      axis: 'axes',
      bacillus: 'bacilli',
      bacterium: 'bacteria',
      basis: 'bases',
      batch: 'batches',
      beach: 'beaches',
      beau: 'beaux',
      bison: 'bison',
      brush: 'brushes',
      buffalo: 'buffaloes',
      bureau: 'bureaus',
      bus: 'busses',
      cactus: 'cacti',
      calf: 'calves',
      chateau: 'chateaux',
      cherry: 'cherries',
      child: 'children',
      church: 'churches',
      circus: 'circuses',
      cod: 'cod',
      corps: 'corps',
      corpus: 'corpora',
      crisis: 'crises',
      criterion: 'criteria',
      curriculum: 'curricula',
      datum: 'data',
      deer: 'deer',
      diagnosis: 'diagnoses',
      die: 'dice',
      domino: 'dominoes',
      dwarf: 'dwarves',
      echo: 'echoes',
      elf: 'elves',
      ellipsis: 'ellipses',
      embargo: 'embargoes',
      emphasis: 'emphases',
      erratum: 'errata',
      fax: 'faxes',
      fireman: 'firemen',
      fish: 'fish',
      flush: 'flushes',
      focus: 'foci',
      foot: 'feet',
      formula: 'formulas',
      fungus: 'fungi',
      genus: 'genera',
      goose: 'geese',
      grafito: 'grafiti',
      half: 'halves',
      hero: 'heroes',
      hoax: 'hoaxes',
      hoof: 'hooves',
      hypothesis: 'hypotheses',
      index: 'indices',
      kiss: 'kisses',
      knife: 'knives',
      leaf: 'leaves',
      life: 'lives',
      loaf: 'loaves',
      louse: 'lice',
      man: 'men',
      mango: 'mangoes',
      matrix: 'matrices',
      means: 'means',
      medium: 'media',
      memorandum: 'memoranda',
      millennium: 'milennia',
      moose: 'moose',
      mosquito: 'mosquitoes',
      motto: 'mottoes',
      mouse: 'mice',
      nebula: 'nebulae',
      neurosis: 'neuroses',
      nucleus: 'nuclei',
      oasis: 'oases',
      octopus: 'octopodes',
      ovum: 'ova',
      ox: 'oxen',
      paralysis: 'paralyses',
      parenthesis: 'parentheses',
      person: 'people',
      phenomenon: 'phenomena',
      plateau: 'plateaux',
      potato: 'potatoes',
      quiz: 'quizzes',
      radius: 'radii',
      reflex: 'reflexes',
      'runner-up': 'runners-up',
      scampo: 'scampi',
      scarf: 'scarves',
      scissors: 'scissors',
      scratch: 'scratches',
      self: 'selves',
      series: 'series',
      sheaf: 'sheaves',
      sheep: 'sheep',
      shelf: 'shelves',
      'son-in-law': 'sons-in-law',
      species: 'species',
      splash: 'splashes',
      stimulus: 'stimuli',
      stitch: 'stitches',
      stratum: 'strata',
      syllabus: 'syllabi',
      symposium: 'symposia',
      synopsis: 'synopses',
      synthesis: 'syntheses',
      tableau: 'tableaux',
      tax: 'taxes',
      that: 'those',
      thesis: 'theses',
      thief: 'thieves',
      this: 'these',
      tomato: 'tomatoes',
      tooth: 'teeth',
      tornado: 'tornadoes',
      torpedo: 'torpedoes',
      vertebra: 'vertebrae',
      veto: 'vetoes',
      vita: 'vitae',
      volcano: 'volcanoes',
      waltz: 'waltzes',
      wash: 'washes',
      watch: 'watches',
      wharf: 'wharves',
      wife: 'wives',
      wolf: 'wolves',
      woman: 'women',
      zero: 'zeroes'
    };
  }
  transform(singularEntity, quantity = 0) {
    if (!singularEntity || singularEntity === '') {
      return '';
    }
    if (quantity === 1) {
      return singularEntity;
    } else {
      const lastWord = singularEntity.trim().split(' ')[singularEntity.trim().split(' ').length - 1];
      if (this.irregularMap[lastWord.toLocaleLowerCase()]) {
        if (lastWord[0] === lastWord[0].toLocaleUpperCase()) {
          return singularEntity.replace(lastWord, this.irregularMap[lastWord.toLocaleLowerCase()].replace(this.irregularMap[lastWord.toLocaleLowerCase()][0], this.irregularMap[lastWord.toLocaleLowerCase()][0].toLocaleUpperCase()));
        }
        return singularEntity.replace(lastWord, this.irregularMap[lastWord.toLocaleLowerCase()]);
      } else if (lastWord[lastWord.length - 1] === 'y') {
        // Naive approach:
        // consonant+y = word - 'y' +'ies'
        // vowel+y = word + 's'
        return isVowel(lastWord[lastWord.length - 2]) ? singularEntity + 's' : singularEntity.replace(lastWord, lastWord.slice(0, -1) + 'ies');
      } else if (lastWord[lastWord.length - 1] === 's') {
        return singularEntity + 'es';
      } else {
        return singularEntity + 's';
      }
    }
  }
}
MakePluralStringPipe.ɵfac = function MakePluralStringPipe_Factory(t) {
  return new (t || MakePluralStringPipe)();
};
MakePluralStringPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "makePluralString",
  type: MakePluralStringPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MakePluralStringPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'makePluralString'
    }]
  }], null, null);
})();
class WrapPipe {
  transform(str, prefix = '', suffix = '') {
    if (!isString(str)) {
      return str;
    }
    return (!!prefix && isString(prefix) ? prefix : '') + str + (!!suffix && isString(suffix) ? suffix : '');
  }
}
WrapPipe.ɵfac = function WrapPipe_Factory(t) {
  return new (t || WrapPipe)();
};
WrapPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "wrap",
  type: WrapPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](WrapPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'wrap'
    }]
  }], null, null);
})();
const STRING_PIPES = [AorAnPipe, LeftTrimPipe, RepeatPipe, RightTrimPipe, ScanPipe, ShortenPipe, StripTagsPipe, TrimPipe, UcFirstPipe, UcWordsPipe, SlugifyPipe, CamelizePipe, LatinisePipe, LinesPipe, UnderscorePipe, MatchPipe, TestPipe, LeftPadPipe, RightPadPipe, MakePluralStringPipe, WrapPipe];
class NgStringPipesModule {}
NgStringPipesModule.ɵfac = function NgStringPipesModule_Factory(t) {
  return new (t || NgStringPipesModule)();
};
NgStringPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgStringPipesModule
});
NgStringPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgStringPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: STRING_PIPES,
      imports: [],
      exports: STRING_PIPES
    }]
  }], null, null);
})();
class MaxPipe {
  transform(arr) {
    return Array.isArray(arr) ? Math.max(...arr) : arr;
  }
}
MaxPipe.ɵfac = function MaxPipe_Factory(t) {
  return new (t || MaxPipe)();
};
MaxPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "max",
  type: MaxPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MaxPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'max'
    }]
  }], null, null);
})();
class MinPipe {
  transform(arr) {
    return Array.isArray(arr) ? Math.min(...arr) : arr;
  }
}
MinPipe.ɵfac = function MinPipe_Factory(t) {
  return new (t || MinPipe)();
};
MinPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "min",
  type: MinPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](MinPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'min'
    }]
  }], null, null);
})();
class PercentagePipe {
  transform(num, total = 100, floor = false) {
    if (isNaN(num)) {
      return num;
    }
    const percent = num * 100 / total;
    return floor ? Math.floor(percent) : percent;
  }
}
PercentagePipe.ɵfac = function PercentagePipe_Factory(t) {
  return new (t || PercentagePipe)();
};
PercentagePipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "percentage",
  type: PercentagePipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PercentagePipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'percentage'
    }]
  }], null, null);
})();
class SumPipe {
  transform(arr) {
    return Array.isArray(arr) ? arr.reduce((sum, curr) => sum + curr, 0) : arr;
  }
}
SumPipe.ɵfac = function SumPipe_Factory(t) {
  return new (t || SumPipe)();
};
SumPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "sum",
  type: SumPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SumPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'sum'
    }]
  }], null, null);
})();
class FloorPipe {
  transform(num, precision = 0) {
    if (precision <= 0) {
      return Math.floor(num);
    }
    const tho = 10 ** precision;
    return Math.floor(num * tho) / tho;
  }
}
FloorPipe.ɵfac = function FloorPipe_Factory(t) {
  return new (t || FloorPipe)();
};
FloorPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "floor",
  type: FloorPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](FloorPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'floor'
    }]
  }], null, null);
})();
class RoundPipe {
  transform(num, precision = 0) {
    return applyPrecision(num, precision);
  }
}
RoundPipe.ɵfac = function RoundPipe_Factory(t) {
  return new (t || RoundPipe)();
};
RoundPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "round",
  type: RoundPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RoundPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'round'
    }]
  }], null, null);
})();
class SqrtPipe {
  transform(num) {
    return !isNaN(num) ? Math.sqrt(num) : num;
  }
}
SqrtPipe.ɵfac = function SqrtPipe_Factory(t) {
  return new (t || SqrtPipe)();
};
SqrtPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "sqrt",
  type: SqrtPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SqrtPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'sqrt'
    }]
  }], null, null);
})();
class PowerPipe {
  transform(num, power = 2) {
    return !isNaN(num) ? num ** power : num;
  }
}
PowerPipe.ɵfac = function PowerPipe_Factory(t) {
  return new (t || PowerPipe)();
};
PowerPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "pow",
  type: PowerPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](PowerPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'pow'
    }]
  }], null, null);
})();
class CeilPipe {
  transform(num, precision = 0) {
    if (precision <= 0) {
      return Math.ceil(num);
    }
    const tho = 10 ** precision;
    return Math.ceil(num * tho) / tho;
  }
}
CeilPipe.ɵfac = function CeilPipe_Factory(t) {
  return new (t || CeilPipe)();
};
CeilPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "ceil",
  type: CeilPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](CeilPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'ceil'
    }]
  }], null, null);
})();
class DegreesPipe {
  transform(radians) {
    if (!isNumberFinite(radians)) {
      return NaN;
    }
    return radians * 180 / Math.PI;
  }
}
DegreesPipe.ɵfac = function DegreesPipe_Factory(t) {
  return new (t || DegreesPipe)();
};
DegreesPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "degrees",
  type: DegreesPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](DegreesPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'degrees'
    }]
  }], null, null);
})();
class BytesPipe {
  constructor() {
    this.dictionary = [{
      max: 1024,
      type: 'B'
    }, {
      max: 1048576,
      type: 'KB'
    }, {
      max: 1073741824,
      type: 'MB'
    }, {
      max: 1.0995116e12,
      type: 'GB'
    }];
  }
  transform(value, precision) {
    if (!isNumberFinite(value)) {
      return NaN;
    }
    const format = this.dictionary.find(d => value < d.max) || this.dictionary[this.dictionary.length - 1];
    const calc = value / (format.max / 1024);
    const num = isUndefined(precision) ? calc : applyPrecision(calc, precision);
    return `${num} ${format.type}`;
  }
}
BytesPipe.ɵfac = function BytesPipe_Factory(t) {
  return new (t || BytesPipe)();
};
BytesPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "bytes",
  type: BytesPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](BytesPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'bytes'
    }]
  }], null, null);
})();
class RadiansPipe {
  transform(degrees) {
    if (!isNumberFinite(degrees)) {
      return NaN;
    }
    return degrees * Math.PI / 180;
  }
}
RadiansPipe.ɵfac = function RadiansPipe_Factory(t) {
  return new (t || RadiansPipe)();
};
RadiansPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "radians",
  type: RadiansPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](RadiansPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'radians'
    }]
  }], null, null);
})();
const MATH_PIPES = [MaxPipe, MinPipe, PercentagePipe, SumPipe, FloorPipe, RoundPipe, SqrtPipe, PowerPipe, CeilPipe, DegreesPipe, BytesPipe, RadiansPipe];
class NgMathPipesModule {}
NgMathPipesModule.ɵfac = function NgMathPipesModule_Factory(t) {
  return new (t || NgMathPipesModule)();
};
NgMathPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgMathPipesModule
});
NgMathPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgMathPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: MATH_PIPES,
      imports: [],
      exports: MATH_PIPES
    }]
  }], null, null);
})();
class IsDefinedPipe {
  transform(input) {
    return !isUndefined(input);
  }
}
IsDefinedPipe.ɵfac = function IsDefinedPipe_Factory(t) {
  return new (t || IsDefinedPipe)();
};
IsDefinedPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isDefined",
  type: IsDefinedPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsDefinedPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isDefined'
    }]
  }], null, null);
})();
class IsNullPipe {
  transform(input) {
    return input === null;
  }
}
IsNullPipe.ɵfac = function IsNullPipe_Factory(t) {
  return new (t || IsNullPipe)();
};
IsNullPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isNull",
  type: IsNullPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsNullPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isNull'
    }]
  }], null, null);
})();
class IsUndefinedPipe {
  transform(input) {
    return isUndefined(input);
  }
}
IsUndefinedPipe.ɵfac = function IsUndefinedPipe_Factory(t) {
  return new (t || IsUndefinedPipe)();
};
IsUndefinedPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isUndefined",
  type: IsUndefinedPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsUndefinedPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isUndefined'
    }]
  }], null, null);
})();
class IsStringPipe {
  transform(input) {
    return isString(input);
  }
}
IsStringPipe.ɵfac = function IsStringPipe_Factory(t) {
  return new (t || IsStringPipe)();
};
IsStringPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isString",
  type: IsStringPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsStringPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isString'
    }]
  }], null, null);
})();
class IsFunctionPipe {
  transform(input) {
    return isFunction(input);
  }
}
IsFunctionPipe.ɵfac = function IsFunctionPipe_Factory(t) {
  return new (t || IsFunctionPipe)();
};
IsFunctionPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isFunction",
  type: IsFunctionPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsFunctionPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isFunction'
    }]
  }], null, null);
})();
class IsNumberPipe {
  transform(input) {
    return isNumber(input);
  }
}
IsNumberPipe.ɵfac = function IsNumberPipe_Factory(t) {
  return new (t || IsNumberPipe)();
};
IsNumberPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isNumber",
  type: IsNumberPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsNumberPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isNumber'
    }]
  }], null, null);
})();
class IsArrayPipe {
  transform(input) {
    return Array.isArray(input);
  }
}
IsArrayPipe.ɵfac = function IsArrayPipe_Factory(t) {
  return new (t || IsArrayPipe)();
};
IsArrayPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isArray",
  type: IsArrayPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsArrayPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isArray'
    }]
  }], null, null);
})();
class IsObjectPipe {
  transform(input) {
    return isObject(input);
  }
}
IsObjectPipe.ɵfac = function IsObjectPipe_Factory(t) {
  return new (t || IsObjectPipe)();
};
IsObjectPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isObject",
  type: IsObjectPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsObjectPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isObject'
    }]
  }], null, null);
})();
class IsGreaterEqualThanPipe {
  transform(input, other) {
    return input >= other;
  }
}
IsGreaterEqualThanPipe.ɵfac = function IsGreaterEqualThanPipe_Factory(t) {
  return new (t || IsGreaterEqualThanPipe)();
};
IsGreaterEqualThanPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isGreaterEqualThan",
  type: IsGreaterEqualThanPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsGreaterEqualThanPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isGreaterEqualThan'
    }]
  }], null, null);
})();
class IsGreaterThanPipe {
  transform(input, other) {
    return input > other;
  }
}
IsGreaterThanPipe.ɵfac = function IsGreaterThanPipe_Factory(t) {
  return new (t || IsGreaterThanPipe)();
};
IsGreaterThanPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isGreaterThan",
  type: IsGreaterThanPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsGreaterThanPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isGreaterThan'
    }]
  }], null, null);
})();
class IsLessEqualThanPipe {
  transform(input, other) {
    return input <= other;
  }
}
IsLessEqualThanPipe.ɵfac = function IsLessEqualThanPipe_Factory(t) {
  return new (t || IsLessEqualThanPipe)();
};
IsLessEqualThanPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isLessEqualThan",
  type: IsLessEqualThanPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsLessEqualThanPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isLessEqualThan'
    }]
  }], null, null);
})();
class IsEqualToPipe {
  transform(input, other) {
    // tslint:disable-next-line:triple-equals
    return input == other;
  }
}
IsEqualToPipe.ɵfac = function IsEqualToPipe_Factory(t) {
  return new (t || IsEqualToPipe)();
};
IsEqualToPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isEqualTo",
  type: IsEqualToPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsEqualToPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isEqualTo'
    }]
  }], null, null);
})();
class IsNotEqualToPipe {
  transform(input, other) {
    // tslint:disable-next-line:triple-equals
    return input != other;
  }
}
IsNotEqualToPipe.ɵfac = function IsNotEqualToPipe_Factory(t) {
  return new (t || IsNotEqualToPipe)();
};
IsNotEqualToPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isNotEqualTo",
  type: IsNotEqualToPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsNotEqualToPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isNotEqualTo'
    }]
  }], null, null);
})();
class IsIdenticalToPipe {
  transform(input, other) {
    return input === other;
  }
}
IsIdenticalToPipe.ɵfac = function IsIdenticalToPipe_Factory(t) {
  return new (t || IsIdenticalToPipe)();
};
IsIdenticalToPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isIdenticalTo",
  type: IsIdenticalToPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsIdenticalToPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isIdenticalTo'
    }]
  }], null, null);
})();
class IsNotIdenticalToPipe {
  transform(input, other) {
    return input !== other;
  }
}
IsNotIdenticalToPipe.ɵfac = function IsNotIdenticalToPipe_Factory(t) {
  return new (t || IsNotIdenticalToPipe)();
};
IsNotIdenticalToPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isNotIdenticalTo",
  type: IsNotIdenticalToPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsNotIdenticalToPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isNotIdenticalTo'
    }]
  }], null, null);
})();
class IsLessThanPipe {
  transform(input, other) {
    return input < other;
  }
}
IsLessThanPipe.ɵfac = function IsLessThanPipe_Factory(t) {
  return new (t || IsLessThanPipe)();
};
IsLessThanPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "isLessThan",
  type: IsLessThanPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](IsLessThanPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'isLessThan'
    }]
  }], null, null);
})();
const BOOLEAN_PIPES = [IsDefinedPipe, IsNullPipe, IsUndefinedPipe, IsStringPipe, IsFunctionPipe, IsNumberPipe, IsArrayPipe, IsObjectPipe, IsGreaterEqualThanPipe, IsGreaterThanPipe, IsLessEqualThanPipe, IsLessEqualThanPipe, IsEqualToPipe, IsNotEqualToPipe, IsIdenticalToPipe, IsNotIdenticalToPipe, IsLessThanPipe];
class NgBooleanPipesModule {}
NgBooleanPipesModule.ɵfac = function NgBooleanPipesModule_Factory(t) {
  return new (t || NgBooleanPipesModule)();
};
NgBooleanPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgBooleanPipesModule
});
NgBooleanPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgBooleanPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: BOOLEAN_PIPES,
      imports: [],
      exports: BOOLEAN_PIPES
    }]
  }], null, null);
})();
class TimeAgoPipe {
  /**
   * @param inputDate: Date | Moment - not included as TypeScript interface,
   * in order to keep `ngx-pipes` "pure" from dependencies!
   */
  transform(inputDate) {
    if (!inputDate || !inputDate.getTime && !inputDate.toDate) {
      return 'Invalid date';
    }
    const past = inputDate.toDate ? inputDate.toDate() : inputDate.getTime();
    const now = +new Date();
    if (past > now) {
      return 'in the future';
    }
    for (let i = 0, l = TimeAgoPipe.MAPPER.length, ms = now - past, div = TimeAgoPipe.YEAR_MS; i < l; ++i) {
      const elm = TimeAgoPipe.MAPPER[i];
      const unit = Math.floor(ms / (div /= elm.div));
      if (unit >= 1) {
        return unit === 1 ? elm.single : `${unit} ${elm.many} ago`;
      }
    }
    return 'just now';
  }
}
TimeAgoPipe.YEAR_MS = 1000 * 60 * 60 * 24 * 7 * 4 * 12;
TimeAgoPipe.MAPPER = [{
  single: 'last year',
  many: 'years',
  div: 1
}, {
  single: 'last month',
  many: 'months',
  div: 12
}, {
  single: 'last week',
  many: 'weeks',
  div: 4
}, {
  single: 'yesterday',
  many: 'days',
  div: 7
}, {
  single: 'an hour ago',
  many: 'hours',
  div: 24
}, {
  single: 'just now',
  many: 'minutes',
  div: 60
}];
TimeAgoPipe.ɵfac = function TimeAgoPipe_Factory(t) {
  return new (t || TimeAgoPipe)();
};
TimeAgoPipe.ɵpipe = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefinePipe"]({
  name: "timeAgo",
  type: TimeAgoPipe,
  pure: true
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](TimeAgoPipe, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Pipe,
    args: [{
      name: 'timeAgo'
    }]
  }], null, null);
})();
const DATE_PIPES = [TimeAgoPipe];
class NgDatePipesModule {}
NgDatePipesModule.ɵfac = function NgDatePipesModule_Factory(t) {
  return new (t || NgDatePipesModule)();
};
NgDatePipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgDatePipesModule
});
NgDatePipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgDatePipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      declarations: DATE_PIPES,
      imports: [],
      exports: DATE_PIPES
    }]
  }], null, null);
})();
class NgPipesModule {}
NgPipesModule.ɵfac = function NgPipesModule_Factory(t) {
  return new (t || NgPipesModule)();
};
NgPipesModule.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
  type: NgPipesModule
});
NgPipesModule.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
  imports: [NgArrayPipesModule, NgStringPipesModule, NgMathPipesModule, NgBooleanPipesModule, NgObjectPipesModule, NgDatePipesModule]
});
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](NgPipesModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      exports: [NgArrayPipesModule, NgStringPipesModule, NgMathPipesModule, NgBooleanPipesModule, NgObjectPipesModule, NgDatePipesModule]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 49953:
/*!*************************************************************************!*\
  !*** ./node_modules/ngx-slick-carousel/fesm2022/ngx-slick-carousel.mjs ***!
  \*************************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   SlickCarouselComponent: () => (/* binding */ SlickCarouselComponent),
/* harmony export */   SlickCarouselModule: () => (/* binding */ SlickCarouselModule),
/* harmony export */   SlickItemDirective: () => (/* binding */ SlickItemDirective)
/* harmony export */ });
/* harmony import */ var _angular_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/common */ 60316);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var _angular_forms__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @angular/forms */ 34456);





/**
 * Slick component
 */
const _c0 = ["*"];
class SlickCarouselComponent {
  config;
  afterChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  beforeChange = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  breakpoint = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  destroy = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  init = new _angular_core__WEBPACK_IMPORTED_MODULE_0__.EventEmitter();
  $instance;
  // access from parent component can be a problem with change detection timing. Please use afterChange output
  currentIndex = 0;
  slides = [];
  initialized = false;
  _removedSlides = [];
  _addedSlides = [];
  el = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
  zone = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.NgZone);
  isServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformServer)((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID));
  /**
   * On component destroy
   */
  ngOnDestroy() {
    this.unslick();
  }
  ngAfterViewInit() {
    this.ngAfterViewChecked();
  }
  /**
   * On component view checked
   */
  ngAfterViewChecked() {
    if (this.isServer) {
      return;
    }
    if (this._addedSlides.length > 0 || this._removedSlides.length > 0) {
      const nextSlidesLength = this.slides.length - this._removedSlides.length + this._addedSlides.length;
      if (!this.initialized) {
        if (nextSlidesLength > 0) {
          this.initSlick();
        }
        // if nextSlidesLength is zere, do nothing
      } else if (nextSlidesLength === 0) {
        // unslick case
        this.unslick();
      } else {
        this._addedSlides.forEach(slickItem => {
          this.slides.push(slickItem);
          this.zone.runOutsideAngular(() => {
            this.$instance.slick('slickAdd', slickItem.el.nativeElement);
          });
        });
        this._addedSlides = [];
        this._removedSlides.forEach(slickItem => {
          const idx = this.slides.indexOf(slickItem);
          this.slides = this.slides.filter(s => s !== slickItem);
          this.zone.runOutsideAngular(() => {
            this.$instance.slick('slickRemove', idx);
          });
        });
        this._removedSlides = [];
      }
    }
  }
  /**
   * init slick
   */
  initSlick() {
    this.slides = this._addedSlides;
    this._addedSlides = [];
    this._removedSlides = [];
    this.zone.runOutsideAngular(() => {
      this.$instance = jQuery(this.el.nativeElement);
      this.$instance.on('init', (event, slick) => {
        this.zone.run(() => {
          this.init.emit({
            event,
            slick
          });
        });
      });
      this.$instance.slick(this.config);
      this.zone.run(() => {
        this.initialized = true;
        this.currentIndex = this.config?.initialSlide || 0;
      });
      this.$instance.on('afterChange', (event, slick, currentSlide) => {
        this.zone.run(() => {
          this.afterChange.emit({
            event,
            slick,
            currentSlide,
            first: currentSlide === 0,
            last: slick.$slides.length === currentSlide + slick.options.slidesToScroll
          });
          this.currentIndex = currentSlide;
        });
      });
      this.$instance.on('beforeChange', (event, slick, currentSlide, nextSlide) => {
        this.zone.run(() => {
          this.beforeChange.emit({
            event,
            slick,
            currentSlide,
            nextSlide
          });
          this.currentIndex = nextSlide;
        });
      });
      this.$instance.on('breakpoint', (event, slick, breakpoint) => {
        this.zone.run(() => {
          this.breakpoint.emit({
            event,
            slick,
            breakpoint
          });
        });
      });
      this.$instance.on('destroy', (event, slick) => {
        this.zone.run(() => {
          this.destroy.emit({
            event,
            slick
          });
          this.initialized = false;
        });
      });
    });
  }
  addSlide(slickItem) {
    this._addedSlides.push(slickItem);
  }
  removeSlide(slickItem) {
    this._removedSlides.push(slickItem);
  }
  /**
   * Slick Method
   */
  slickGoTo(index) {
    this.zone.runOutsideAngular(() => {
      this.$instance.slick('slickGoTo', index);
    });
  }
  slickNext() {
    this.zone.runOutsideAngular(() => {
      this.$instance.slick('slickNext');
    });
  }
  slickPrev() {
    this.zone.runOutsideAngular(() => {
      this.$instance.slick('slickPrev');
    });
  }
  slickPause() {
    this.zone.runOutsideAngular(() => {
      this.$instance.slick('slickPause');
    });
  }
  slickPlay() {
    this.zone.runOutsideAngular(() => {
      this.$instance.slick('slickPlay');
    });
  }
  unslick() {
    if (this.$instance) {
      this.zone.runOutsideAngular(() => {
        this.$instance.slick('unslick');
      });
      this.$instance = undefined;
    }
    this.initialized = false;
  }
  ngOnChanges(changes) {
    if (this.initialized) {
      const config = changes['config'];
      if (config.previousValue !== config.currentValue && config.currentValue !== undefined) {
        const refresh = config.currentValue['refresh'];
        const newOptions = Object.assign({}, config.currentValue);
        delete newOptions['refresh'];
        this.zone.runOutsideAngular(() => {
          this.$instance.slick('slickSetOption', newOptions, refresh);
        });
      }
    }
  }
  /** @nocollapse */
  static ɵfac = function SlickCarouselComponent_Factory(t) {
    return new (t || SlickCarouselComponent)();
  };
  /** @nocollapse */
  static ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineComponent"]({
    type: SlickCarouselComponent,
    selectors: [["ngx-slick-carousel"]],
    inputs: {
      config: "config"
    },
    outputs: {
      afterChange: "afterChange",
      beforeChange: "beforeChange",
      breakpoint: "breakpoint",
      destroy: "destroy",
      init: "init"
    },
    exportAs: ["slick-carousel"],
    features: [_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵProvidersFeature"]([{
      provide: _angular_forms__WEBPACK_IMPORTED_MODULE_2__.NG_VALUE_ACCESSOR,
      useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SlickCarouselComponent),
      multi: true
    }]), _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵNgOnChangesFeature"]],
    ngContentSelectors: _c0,
    decls: 1,
    vars: 0,
    template: function SlickCarouselComponent_Template(rf, ctx) {
      if (rf & 1) {
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojectionDef"]();
        _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵprojection"](0);
      }
    },
    encapsulation: 2
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlickCarouselComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Component,
    args: [{
      selector: 'ngx-slick-carousel',
      exportAs: 'slick-carousel',
      providers: [{
        provide: _angular_forms__WEBPACK_IMPORTED_MODULE_2__.NG_VALUE_ACCESSOR,
        useExisting: (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.forwardRef)(() => SlickCarouselComponent),
        multi: true
      }],
      template: '<ng-content></ng-content>'
    }]
  }], null, {
    config: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Input
    }],
    afterChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    beforeChange: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    breakpoint: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    destroy: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }],
    init: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Output
    }]
  });
})();
class SlickItemDirective {
  carousel = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(SlickCarouselComponent, {
    host: true
  });
  renderer = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.Renderer2);
  el = (0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.ElementRef);
  isServer = (0,_angular_common__WEBPACK_IMPORTED_MODULE_1__.isPlatformServer)((0,_angular_core__WEBPACK_IMPORTED_MODULE_0__.inject)(_angular_core__WEBPACK_IMPORTED_MODULE_0__.PLATFORM_ID));
  ngOnInit() {
    this.carousel.addSlide(this);
    if (this.isServer && this.carousel.slides.length > 0) {
      // Do not show other slides in server side rendering (broken ui can be affacted to Core Web Vitals)
      this.renderer.setStyle(this.el, 'display', 'none');
    }
  }
  ngOnDestroy() {
    this.carousel.removeSlide(this);
  }
  /** @nocollapse */
  static ɵfac = function SlickItemDirective_Factory(t) {
    return new (t || SlickItemDirective)();
  };
  /** @nocollapse */
  static ɵdir = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineDirective"]({
    type: SlickItemDirective,
    selectors: [["", "ngxSlickItem", ""]]
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlickItemDirective, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.Directive,
    args: [{
      selector: '[ngxSlickItem]'
    }]
  }], null, null);
})();
class SlickCarouselModule {
  /** @nocollapse */static ɵfac = function SlickCarouselModule_Factory(t) {
    return new (t || SlickCarouselModule)();
  };
  /** @nocollapse */
  static ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineNgModule"]({
    type: SlickCarouselModule
  });
  /** @nocollapse */
  static ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵɵdefineInjector"]({
    imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule]
  });
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_0__["ɵsetClassMetadata"](SlickCarouselModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_0__.NgModule,
    args: [{
      imports: [_angular_common__WEBPACK_IMPORTED_MODULE_1__.CommonModule],
      declarations: [SlickCarouselComponent, SlickItemDirective],
      exports: [SlickCarouselComponent, SlickItemDirective]
    }]
  }], null, null);
})();

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 67363:
/*!***********************************************************************!*\
  !*** ./node_modules/simplebar-angular/fesm2022/simplebar-angular.mjs ***!
  \***********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   SimplebarAngularComponent: () => (/* binding */ SimplebarAngularComponent),
/* harmony export */   SimplebarAngularModule: () => (/* binding */ SimplebarAngularModule)
/* harmony export */ });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ 37580);
/* harmony import */ var simplebar_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! simplebar-core */ 88451);



const _c0 = ["*"];
class SimplebarAngularComponent {
  constructor(elRef, zone) {
    this.zone = zone;
    this.options = {};
    this.elRef = elRef;
  }
  ngOnInit() {
    this.ariaLabel = this.options.ariaLabel || simplebar_core__WEBPACK_IMPORTED_MODULE_0__["default"].defaultOptions.ariaLabel;
    this.tabIndex = (this.options.tabIndex || simplebar_core__WEBPACK_IMPORTED_MODULE_0__["default"].defaultOptions.tabIndex).toString();
  }
  ngAfterViewInit() {
    this.zone.runOutsideAngular(() => {
      this.SimpleBar = new simplebar_core__WEBPACK_IMPORTED_MODULE_0__["default"](this.elRef.nativeElement, this.options || {});
    });
  }
  ngOnDestroy() {
    this.SimpleBar?.unMount();
    this.SimpleBar = null;
  }
  static {
    this.ɵfac = function SimplebarAngularComponent_Factory(t) {
      return new (t || SimplebarAngularComponent)(_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef), _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdirectiveInject"](_angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone));
    };
  }
  static {
    this.ɵcmp = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineComponent"]({
      type: SimplebarAngularComponent,
      selectors: [["ngx-simplebar"]],
      hostAttrs: ["data-simplebar", "init"],
      inputs: {
        options: "options"
      },
      ngContentSelectors: _c0,
      decls: 13,
      vars: 2,
      consts: [[1, "simplebar-wrapper"], [1, "simplebar-height-auto-observer-wrapper"], [1, "simplebar-height-auto-observer"], [1, "simplebar-mask"], [1, "simplebar-offset"], ["role", "region", 1, "simplebar-content-wrapper"], [1, "simplebar-content"], [1, "simplebar-placeholder"], [1, "simplebar-track", "simplebar-horizontal"], [1, "simplebar-scrollbar"], [1, "simplebar-track", "simplebar-vertical"]],
      template: function SimplebarAngularComponent_Template(rf, ctx) {
        if (rf & 1) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojectionDef"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](0, "div", 0)(1, "div", 1);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](2, "div", 2);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](3, "div", 3)(4, "div", 4)(5, "div", 5)(6, "div", 6);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵprojection"](7);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]()()()();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](8, "div", 7);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](9, "div", 8);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](10, "div", 9);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementStart"](11, "div", 10);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelement"](12, "div", 9);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵelementEnd"]();
        }
        if (rf & 2) {
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵadvance"](5);
          _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵattribute"]("tabIndex", ctx.tabIndex)("aria-label", ctx.ariaLabel);
        }
      },
      styles: ["[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;inset:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;inset:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{display:none;width:0;height:0}.simplebar-content:before,.simplebar-content:after{content:\" \";display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging,[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:\"\";background:#000;border-radius:7px;left:2px;right:2px;opacity:0;transition:opacity .2s .5s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition-delay:0s;transition-duration:0s}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-scrollbar:before{inset:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{inset:0 auto 0 0;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.simplebar-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:scrollbar!important}.simplebar-dummy-scrollbar-size>div{width:200%;height:200%;margin:10px 0}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}\n", "ngx-simplebar{display:block}\n"],
      encapsulation: 2
    });
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](SimplebarAngularComponent, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Component,
    args: [{
      selector: 'ngx-simplebar',
      host: {
        'data-simplebar': 'init'
      },
      encapsulation: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ViewEncapsulation.None,
      template: "<div class=\"simplebar-wrapper\">\n  <div class=\"simplebar-height-auto-observer-wrapper\">\n    <div class=\"simplebar-height-auto-observer\"></div>\n  </div>\n  <div class=\"simplebar-mask\">\n    <div class=\"simplebar-offset\">\n      <div class=\"simplebar-content-wrapper\" [attr.tabIndex]=\"tabIndex\" role=\"region\" [attr.aria-label]=\"ariaLabel\">\n        <div class=\"simplebar-content\">\n          <ng-content></ng-content>\n        </div>\n      </div>\n    </div>\n  </div>\n  <div class=\"simplebar-placeholder\"></div>\n</div>\n<div class=\"simplebar-track simplebar-horizontal\">\n  <div class=\"simplebar-scrollbar\"></div>\n</div>\n<div class=\"simplebar-track simplebar-vertical\">\n  <div class=\"simplebar-scrollbar\"></div>\n</div>\n",
      styles: ["[data-simplebar]{position:relative;flex-direction:column;flex-wrap:wrap;justify-content:flex-start;align-content:flex-start;align-items:flex-start}.simplebar-wrapper{overflow:hidden;width:inherit;height:inherit;max-width:inherit;max-height:inherit}.simplebar-mask{direction:inherit;position:absolute;overflow:hidden;padding:0;margin:0;inset:0;width:auto!important;height:auto!important;z-index:0}.simplebar-offset{direction:inherit!important;box-sizing:inherit!important;resize:none!important;position:absolute;inset:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.simplebar-content-wrapper{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:auto;max-width:100%;max-height:100%;overflow:auto;scrollbar-width:none;-ms-overflow-style:none}.simplebar-content-wrapper::-webkit-scrollbar,.simplebar-hide-scrollbar::-webkit-scrollbar{display:none;width:0;height:0}.simplebar-content:before,.simplebar-content:after{content:\" \";display:table}.simplebar-placeholder{max-height:100%;max-width:100%;width:100%;pointer-events:none}.simplebar-height-auto-observer-wrapper{box-sizing:inherit!important;height:100%;width:100%;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.simplebar-height-auto-observer{box-sizing:inherit;display:block;opacity:0;position:absolute;top:0;left:0;height:1000%;width:1000%;min-height:1px;min-width:1px;overflow:hidden;pointer-events:none;z-index:-1}.simplebar-track{z-index:1;position:absolute;right:0;bottom:0;pointer-events:none;overflow:hidden}[data-simplebar].simplebar-dragging,[data-simplebar].simplebar-dragging .simplebar-content{pointer-events:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}[data-simplebar].simplebar-dragging .simplebar-track{pointer-events:all}.simplebar-scrollbar{position:absolute;left:0;right:0;min-height:10px}.simplebar-scrollbar:before{position:absolute;content:\"\";background:#000;border-radius:7px;left:2px;right:2px;opacity:0;transition:opacity .2s .5s linear}.simplebar-scrollbar.simplebar-visible:before{opacity:.5;transition-delay:0s;transition-duration:0s}.simplebar-track.simplebar-vertical{top:0;width:11px}.simplebar-scrollbar:before{inset:2px}.simplebar-track.simplebar-horizontal{left:0;height:11px}.simplebar-track.simplebar-horizontal .simplebar-scrollbar{inset:0 auto 0 0;min-height:0;min-width:10px;width:auto}[data-simplebar-direction=rtl] .simplebar-track.simplebar-vertical{right:auto;left:0}.simplebar-dummy-scrollbar-size{direction:rtl;position:fixed;opacity:0;visibility:hidden;height:500px;width:500px;overflow-y:hidden;overflow-x:scroll;-ms-overflow-style:scrollbar!important}.simplebar-dummy-scrollbar-size>div{width:200%;height:200%;margin:10px 0}.simplebar-hide-scrollbar{position:fixed;left:0;visibility:hidden;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none}\n", "ngx-simplebar{display:block}\n"]
    }]
  }], () => [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.ElementRef
  }, {
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgZone
  }], {
    options: [{
      type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.Input,
      args: ['options']
    }]
  });
})();
class SimplebarAngularModule {
  static {
    this.ɵfac = function SimplebarAngularModule_Factory(t) {
      return new (t || SimplebarAngularModule)();
    };
  }
  static {
    this.ɵmod = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineNgModule"]({
      type: SimplebarAngularModule
    });
  }
  static {
    this.ɵinj = /* @__PURE__ */_angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵɵdefineInjector"]({});
  }
}
(() => {
  (typeof ngDevMode === "undefined" || ngDevMode) && _angular_core__WEBPACK_IMPORTED_MODULE_1__["ɵsetClassMetadata"](SimplebarAngularModule, [{
    type: _angular_core__WEBPACK_IMPORTED_MODULE_1__.NgModule,
    args: [{
      declarations: [SimplebarAngularComponent],
      imports: [],
      exports: [SimplebarAngularComponent],
      schemas: []
    }]
  }], null, null);
})();

/*
 * Public API Surface of simplebar-angular
 */

/**
 * Generated bundle index. Do not edit.
 */



/***/ }),

/***/ 88451:
/*!****************************************************!*\
  !*** ./node_modules/simplebar-core/dist/index.mjs ***!
  \****************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ SimpleBarCore)
/* harmony export */ });
/* harmony import */ var lodash_es_debounce_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lodash-es/debounce.js */ 50763);
/* harmony import */ var lodash_es_throttle_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lodash-es/throttle.js */ 57156);
/**
 * simplebar-core - v1.3.2
 * Scrollbars, simpler.
 * https://grsmto.github.io/simplebar/
 *
 * Made by Adrien Denat from a fork by Jonathan Nicol
 * Under MIT License
 */




/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */

var __assign = function () {
  __assign = Object.assign || function __assign(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];
      for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    }
    return t;
  };
  return __assign.apply(this, arguments);
};
function getElementWindow$1(element) {
  if (!element || !element.ownerDocument || !element.ownerDocument.defaultView) {
    return window;
  }
  return element.ownerDocument.defaultView;
}
function getElementDocument$1(element) {
  if (!element || !element.ownerDocument) {
    return document;
  }
  return element.ownerDocument;
}
// Helper function to retrieve options from element attributes
var getOptions$1 = function (obj) {
  var initialObj = {};
  var options = Array.prototype.reduce.call(obj, function (acc, attribute) {
    var option = attribute.name.match(/data-simplebar-(.+)/);
    if (option) {
      var key = option[1].replace(/\W+(.)/g, function (_, chr) {
        return chr.toUpperCase();
      });
      switch (attribute.value) {
        case 'true':
          acc[key] = true;
          break;
        case 'false':
          acc[key] = false;
          break;
        case undefined:
          acc[key] = true;
          break;
        default:
          acc[key] = attribute.value;
      }
    }
    return acc;
  }, initialObj);
  return options;
};
function addClasses$1(el, classes) {
  var _a;
  if (!el) return;
  (_a = el.classList).add.apply(_a, classes.split(' '));
}
function removeClasses$1(el, classes) {
  if (!el) return;
  classes.split(' ').forEach(function (className) {
    el.classList.remove(className);
  });
}
function classNamesToQuery$1(classNames) {
  return ".".concat(classNames.split(' ').join('.'));
}
var canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
var helpers = /*#__PURE__*/Object.freeze({
  __proto__: null,
  addClasses: addClasses$1,
  canUseDOM: canUseDOM,
  classNamesToQuery: classNamesToQuery$1,
  getElementDocument: getElementDocument$1,
  getElementWindow: getElementWindow$1,
  getOptions: getOptions$1,
  removeClasses: removeClasses$1
});
var cachedScrollbarWidth = null;
var cachedDevicePixelRatio = null;
if (canUseDOM) {
  window.addEventListener('resize', function () {
    if (cachedDevicePixelRatio !== window.devicePixelRatio) {
      cachedDevicePixelRatio = window.devicePixelRatio;
      cachedScrollbarWidth = null;
    }
  });
}
function scrollbarWidth() {
  if (cachedScrollbarWidth === null) {
    if (typeof document === 'undefined') {
      cachedScrollbarWidth = 0;
      return cachedScrollbarWidth;
    }
    var body = document.body;
    var box = document.createElement('div');
    box.classList.add('simplebar-hide-scrollbar');
    body.appendChild(box);
    var width = box.getBoundingClientRect().right;
    body.removeChild(box);
    cachedScrollbarWidth = width;
  }
  return cachedScrollbarWidth;
}
var getElementWindow = getElementWindow$1,
  getElementDocument = getElementDocument$1,
  getOptions = getOptions$1,
  addClasses = addClasses$1,
  removeClasses = removeClasses$1,
  classNamesToQuery = classNamesToQuery$1;
var SimpleBarCore = /** @class */function () {
  function SimpleBarCore(element, options) {
    if (options === void 0) {
      options = {};
    }
    var _this = this;
    this.removePreventClickId = null;
    this.minScrollbarWidth = 20;
    this.stopScrollDelay = 175;
    this.isScrolling = false;
    this.isMouseEntering = false;
    this.isDragging = false;
    this.scrollXTicking = false;
    this.scrollYTicking = false;
    this.wrapperEl = null;
    this.contentWrapperEl = null;
    this.contentEl = null;
    this.offsetEl = null;
    this.maskEl = null;
    this.placeholderEl = null;
    this.heightAutoObserverWrapperEl = null;
    this.heightAutoObserverEl = null;
    this.rtlHelpers = null;
    this.scrollbarWidth = 0;
    this.resizeObserver = null;
    this.mutationObserver = null;
    this.elStyles = null;
    this.isRtl = null;
    this.mouseX = 0;
    this.mouseY = 0;
    this.onMouseMove = function () {};
    this.onWindowResize = function () {};
    this.onStopScrolling = function () {};
    this.onMouseEntered = function () {};
    /**
     * On scroll event handling
     */
    this.onScroll = function () {
      var elWindow = getElementWindow(_this.el);
      if (!_this.scrollXTicking) {
        elWindow.requestAnimationFrame(_this.scrollX);
        _this.scrollXTicking = true;
      }
      if (!_this.scrollYTicking) {
        elWindow.requestAnimationFrame(_this.scrollY);
        _this.scrollYTicking = true;
      }
      if (!_this.isScrolling) {
        _this.isScrolling = true;
        addClasses(_this.el, _this.classNames.scrolling);
      }
      _this.showScrollbar('x');
      _this.showScrollbar('y');
      _this.onStopScrolling();
    };
    this.scrollX = function () {
      if (_this.axis.x.isOverflowing) {
        _this.positionScrollbar('x');
      }
      _this.scrollXTicking = false;
    };
    this.scrollY = function () {
      if (_this.axis.y.isOverflowing) {
        _this.positionScrollbar('y');
      }
      _this.scrollYTicking = false;
    };
    this._onStopScrolling = function () {
      removeClasses(_this.el, _this.classNames.scrolling);
      if (_this.options.autoHide) {
        _this.hideScrollbar('x');
        _this.hideScrollbar('y');
      }
      _this.isScrolling = false;
    };
    this.onMouseEnter = function () {
      if (!_this.isMouseEntering) {
        addClasses(_this.el, _this.classNames.mouseEntered);
        _this.showScrollbar('x');
        _this.showScrollbar('y');
        _this.isMouseEntering = true;
      }
      _this.onMouseEntered();
    };
    this._onMouseEntered = function () {
      removeClasses(_this.el, _this.classNames.mouseEntered);
      if (_this.options.autoHide) {
        _this.hideScrollbar('x');
        _this.hideScrollbar('y');
      }
      _this.isMouseEntering = false;
    };
    this._onMouseMove = function (e) {
      _this.mouseX = e.clientX;
      _this.mouseY = e.clientY;
      if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
        _this.onMouseMoveForAxis('x');
      }
      if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
        _this.onMouseMoveForAxis('y');
      }
    };
    this.onMouseLeave = function () {
      _this.onMouseMove.cancel();
      if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
        _this.onMouseLeaveForAxis('x');
      }
      if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
        _this.onMouseLeaveForAxis('y');
      }
      _this.mouseX = -1;
      _this.mouseY = -1;
    };
    this._onWindowResize = function () {
      // Recalculate scrollbarWidth in case it's a zoom
      _this.scrollbarWidth = _this.getScrollbarWidth();
      _this.hideNativeScrollbar();
    };
    this.onPointerEvent = function (e) {
      if (!_this.axis.x.track.el || !_this.axis.y.track.el || !_this.axis.x.scrollbar.el || !_this.axis.y.scrollbar.el) return;
      var isWithinTrackXBounds, isWithinTrackYBounds;
      _this.axis.x.track.rect = _this.axis.x.track.el.getBoundingClientRect();
      _this.axis.y.track.rect = _this.axis.y.track.el.getBoundingClientRect();
      if (_this.axis.x.isOverflowing || _this.axis.x.forceVisible) {
        isWithinTrackXBounds = _this.isWithinBounds(_this.axis.x.track.rect);
      }
      if (_this.axis.y.isOverflowing || _this.axis.y.forceVisible) {
        isWithinTrackYBounds = _this.isWithinBounds(_this.axis.y.track.rect);
      }
      // If any pointer event is called on the scrollbar
      if (isWithinTrackXBounds || isWithinTrackYBounds) {
        // Prevent event leaking
        e.stopPropagation();
        if (e.type === 'pointerdown' && e.pointerType !== 'touch') {
          if (isWithinTrackXBounds) {
            _this.axis.x.scrollbar.rect = _this.axis.x.scrollbar.el.getBoundingClientRect();
            if (_this.isWithinBounds(_this.axis.x.scrollbar.rect)) {
              _this.onDragStart(e, 'x');
            } else {
              _this.onTrackClick(e, 'x');
            }
          }
          if (isWithinTrackYBounds) {
            _this.axis.y.scrollbar.rect = _this.axis.y.scrollbar.el.getBoundingClientRect();
            if (_this.isWithinBounds(_this.axis.y.scrollbar.rect)) {
              _this.onDragStart(e, 'y');
            } else {
              _this.onTrackClick(e, 'y');
            }
          }
        }
      }
    };
    /**
     * Drag scrollbar handle
     */
    this.drag = function (e) {
      var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
      if (!_this.draggedAxis || !_this.contentWrapperEl) return;
      var eventOffset;
      var track = _this.axis[_this.draggedAxis].track;
      var trackSize = (_b = (_a = track.rect) === null || _a === void 0 ? void 0 : _a[_this.axis[_this.draggedAxis].sizeAttr]) !== null && _b !== void 0 ? _b : 0;
      var scrollbar = _this.axis[_this.draggedAxis].scrollbar;
      var contentSize = (_d = (_c = _this.contentWrapperEl) === null || _c === void 0 ? void 0 : _c[_this.axis[_this.draggedAxis].scrollSizeAttr]) !== null && _d !== void 0 ? _d : 0;
      var hostSize = parseInt((_f = (_e = _this.elStyles) === null || _e === void 0 ? void 0 : _e[_this.axis[_this.draggedAxis].sizeAttr]) !== null && _f !== void 0 ? _f : '0px', 10);
      e.preventDefault();
      e.stopPropagation();
      if (_this.draggedAxis === 'y') {
        eventOffset = e.pageY;
      } else {
        eventOffset = e.pageX;
      }
      // Calculate how far the user's mouse is from the top/left of the scrollbar (minus the dragOffset).
      var dragPos = eventOffset - ((_h = (_g = track.rect) === null || _g === void 0 ? void 0 : _g[_this.axis[_this.draggedAxis].offsetAttr]) !== null && _h !== void 0 ? _h : 0) - _this.axis[_this.draggedAxis].dragOffset;
      dragPos = _this.draggedAxis === 'x' && _this.isRtl ? ((_k = (_j = track.rect) === null || _j === void 0 ? void 0 : _j[_this.axis[_this.draggedAxis].sizeAttr]) !== null && _k !== void 0 ? _k : 0) - scrollbar.size - dragPos : dragPos;
      // Convert the mouse position into a percentage of the scrollbar height/width.
      var dragPerc = dragPos / (trackSize - scrollbar.size);
      // Scroll the content by the same percentage.
      var scrollPos = dragPerc * (contentSize - hostSize);
      // Fix browsers inconsistency on RTL
      if (_this.draggedAxis === 'x' && _this.isRtl) {
        scrollPos = ((_l = SimpleBarCore.getRtlHelpers()) === null || _l === void 0 ? void 0 : _l.isScrollingToNegative) ? -scrollPos : scrollPos;
      }
      _this.contentWrapperEl[_this.axis[_this.draggedAxis].scrollOffsetAttr] = scrollPos;
    };
    /**
     * End scroll handle drag
     */
    this.onEndDrag = function (e) {
      _this.isDragging = false;
      var elDocument = getElementDocument(_this.el);
      var elWindow = getElementWindow(_this.el);
      e.preventDefault();
      e.stopPropagation();
      removeClasses(_this.el, _this.classNames.dragging);
      _this.onStopScrolling();
      elDocument.removeEventListener('mousemove', _this.drag, true);
      elDocument.removeEventListener('mouseup', _this.onEndDrag, true);
      _this.removePreventClickId = elWindow.setTimeout(function () {
        // Remove these asynchronously so we still suppress click events
        // generated simultaneously with mouseup.
        elDocument.removeEventListener('click', _this.preventClick, true);
        elDocument.removeEventListener('dblclick', _this.preventClick, true);
        _this.removePreventClickId = null;
      });
    };
    /**
     * Handler to ignore click events during drag
     */
    this.preventClick = function (e) {
      e.preventDefault();
      e.stopPropagation();
    };
    this.el = element;
    this.options = __assign(__assign({}, SimpleBarCore.defaultOptions), options);
    this.classNames = __assign(__assign({}, SimpleBarCore.defaultOptions.classNames), options.classNames);
    this.axis = {
      x: {
        scrollOffsetAttr: 'scrollLeft',
        sizeAttr: 'width',
        scrollSizeAttr: 'scrollWidth',
        offsetSizeAttr: 'offsetWidth',
        offsetAttr: 'left',
        overflowAttr: 'overflowX',
        dragOffset: 0,
        isOverflowing: true,
        forceVisible: false,
        track: {
          size: null,
          el: null,
          rect: null,
          isVisible: false
        },
        scrollbar: {
          size: null,
          el: null,
          rect: null,
          isVisible: false
        }
      },
      y: {
        scrollOffsetAttr: 'scrollTop',
        sizeAttr: 'height',
        scrollSizeAttr: 'scrollHeight',
        offsetSizeAttr: 'offsetHeight',
        offsetAttr: 'top',
        overflowAttr: 'overflowY',
        dragOffset: 0,
        isOverflowing: true,
        forceVisible: false,
        track: {
          size: null,
          el: null,
          rect: null,
          isVisible: false
        },
        scrollbar: {
          size: null,
          el: null,
          rect: null,
          isVisible: false
        }
      }
    };
    if (typeof this.el !== 'object' || !this.el.nodeName) {
      throw new Error("Argument passed to SimpleBar must be an HTML element instead of ".concat(this.el));
    }
    this.onMouseMove = (0,lodash_es_throttle_js__WEBPACK_IMPORTED_MODULE_0__["default"])(this._onMouseMove, 64);
    this.onWindowResize = (0,lodash_es_debounce_js__WEBPACK_IMPORTED_MODULE_1__["default"])(this._onWindowResize, 64, {
      leading: true
    });
    this.onStopScrolling = (0,lodash_es_debounce_js__WEBPACK_IMPORTED_MODULE_1__["default"])(this._onStopScrolling, this.stopScrollDelay);
    this.onMouseEntered = (0,lodash_es_debounce_js__WEBPACK_IMPORTED_MODULE_1__["default"])(this._onMouseEntered, this.stopScrollDelay);
    this.init();
  }
  /**
   * Helper to fix browsers inconsistency on RTL:
   *  - Firefox inverts the scrollbar initial position
   *  - IE11 inverts both scrollbar position and scrolling offset
   * Directly inspired by @KingSora's OverlayScrollbars https://github.com/KingSora/OverlayScrollbars/blob/master/js/OverlayScrollbars.js#L1634
   */
  SimpleBarCore.getRtlHelpers = function () {
    if (SimpleBarCore.rtlHelpers) {
      return SimpleBarCore.rtlHelpers;
    }
    var dummyDiv = document.createElement('div');
    dummyDiv.innerHTML = '<div class="simplebar-dummy-scrollbar-size"><div></div></div>';
    var scrollbarDummyEl = dummyDiv.firstElementChild;
    var dummyChild = scrollbarDummyEl === null || scrollbarDummyEl === void 0 ? void 0 : scrollbarDummyEl.firstElementChild;
    if (!dummyChild) return null;
    document.body.appendChild(scrollbarDummyEl);
    scrollbarDummyEl.scrollLeft = 0;
    var dummyContainerOffset = SimpleBarCore.getOffset(scrollbarDummyEl);
    var dummyChildOffset = SimpleBarCore.getOffset(dummyChild);
    scrollbarDummyEl.scrollLeft = -999;
    var dummyChildOffsetAfterScroll = SimpleBarCore.getOffset(dummyChild);
    document.body.removeChild(scrollbarDummyEl);
    SimpleBarCore.rtlHelpers = {
      // determines if the scrolling is responding with negative values
      isScrollOriginAtZero: dummyContainerOffset.left !== dummyChildOffset.left,
      // determines if the origin scrollbar position is inverted or not (positioned on left or right)
      isScrollingToNegative: dummyChildOffset.left !== dummyChildOffsetAfterScroll.left
    };
    return SimpleBarCore.rtlHelpers;
  };
  SimpleBarCore.prototype.getScrollbarWidth = function () {
    // Try/catch for FF 56 throwing on undefined computedStyles
    try {
      // Detect browsers supporting CSS scrollbar styling and do not calculate
      if (this.contentWrapperEl && getComputedStyle(this.contentWrapperEl, '::-webkit-scrollbar').display === 'none' || 'scrollbarWidth' in document.documentElement.style || '-ms-overflow-style' in document.documentElement.style) {
        return 0;
      } else {
        return scrollbarWidth();
      }
    } catch (e) {
      return scrollbarWidth();
    }
  };
  SimpleBarCore.getOffset = function (el) {
    var rect = el.getBoundingClientRect();
    var elDocument = getElementDocument(el);
    var elWindow = getElementWindow(el);
    return {
      top: rect.top + (elWindow.pageYOffset || elDocument.documentElement.scrollTop),
      left: rect.left + (elWindow.pageXOffset || elDocument.documentElement.scrollLeft)
    };
  };
  SimpleBarCore.prototype.init = function () {
    // We stop here on server-side
    if (canUseDOM) {
      this.initDOM();
      this.rtlHelpers = SimpleBarCore.getRtlHelpers();
      this.scrollbarWidth = this.getScrollbarWidth();
      this.recalculate();
      this.initListeners();
    }
  };
  SimpleBarCore.prototype.initDOM = function () {
    var _a, _b;
    // assume that element has his DOM already initiated
    this.wrapperEl = this.el.querySelector(classNamesToQuery(this.classNames.wrapper));
    this.contentWrapperEl = this.options.scrollableNode || this.el.querySelector(classNamesToQuery(this.classNames.contentWrapper));
    this.contentEl = this.options.contentNode || this.el.querySelector(classNamesToQuery(this.classNames.contentEl));
    this.offsetEl = this.el.querySelector(classNamesToQuery(this.classNames.offset));
    this.maskEl = this.el.querySelector(classNamesToQuery(this.classNames.mask));
    this.placeholderEl = this.findChild(this.wrapperEl, classNamesToQuery(this.classNames.placeholder));
    this.heightAutoObserverWrapperEl = this.el.querySelector(classNamesToQuery(this.classNames.heightAutoObserverWrapperEl));
    this.heightAutoObserverEl = this.el.querySelector(classNamesToQuery(this.classNames.heightAutoObserverEl));
    this.axis.x.track.el = this.findChild(this.el, "".concat(classNamesToQuery(this.classNames.track)).concat(classNamesToQuery(this.classNames.horizontal)));
    this.axis.y.track.el = this.findChild(this.el, "".concat(classNamesToQuery(this.classNames.track)).concat(classNamesToQuery(this.classNames.vertical)));
    this.axis.x.scrollbar.el = ((_a = this.axis.x.track.el) === null || _a === void 0 ? void 0 : _a.querySelector(classNamesToQuery(this.classNames.scrollbar))) || null;
    this.axis.y.scrollbar.el = ((_b = this.axis.y.track.el) === null || _b === void 0 ? void 0 : _b.querySelector(classNamesToQuery(this.classNames.scrollbar))) || null;
    if (!this.options.autoHide) {
      addClasses(this.axis.x.scrollbar.el, this.classNames.visible);
      addClasses(this.axis.y.scrollbar.el, this.classNames.visible);
    }
  };
  SimpleBarCore.prototype.initListeners = function () {
    var _this = this;
    var _a;
    var elWindow = getElementWindow(this.el);
    // Event listeners
    this.el.addEventListener('mouseenter', this.onMouseEnter);
    this.el.addEventListener('pointerdown', this.onPointerEvent, true);
    this.el.addEventListener('mousemove', this.onMouseMove);
    this.el.addEventListener('mouseleave', this.onMouseLeave);
    (_a = this.contentWrapperEl) === null || _a === void 0 ? void 0 : _a.addEventListener('scroll', this.onScroll);
    // Browser zoom triggers a window resize
    elWindow.addEventListener('resize', this.onWindowResize);
    if (!this.contentEl) return;
    if (window.ResizeObserver) {
      // Hack for https://github.com/WICG/ResizeObserver/issues/38
      var resizeObserverStarted_1 = false;
      var resizeObserver = elWindow.ResizeObserver || ResizeObserver;
      this.resizeObserver = new resizeObserver(function () {
        if (!resizeObserverStarted_1) return;
        elWindow.requestAnimationFrame(function () {
          _this.recalculate();
        });
      });
      this.resizeObserver.observe(this.el);
      this.resizeObserver.observe(this.contentEl);
      elWindow.requestAnimationFrame(function () {
        resizeObserverStarted_1 = true;
      });
    }
    // This is required to detect horizontal scroll. Vertical scroll only needs the resizeObserver.
    this.mutationObserver = new elWindow.MutationObserver(function () {
      elWindow.requestAnimationFrame(function () {
        _this.recalculate();
      });
    });
    this.mutationObserver.observe(this.contentEl, {
      childList: true,
      subtree: true,
      characterData: true
    });
  };
  SimpleBarCore.prototype.recalculate = function () {
    if (!this.heightAutoObserverEl || !this.contentEl || !this.contentWrapperEl || !this.wrapperEl || !this.placeholderEl) return;
    var elWindow = getElementWindow(this.el);
    this.elStyles = elWindow.getComputedStyle(this.el);
    this.isRtl = this.elStyles.direction === 'rtl';
    var contentElOffsetWidth = this.contentEl.offsetWidth;
    var isHeightAuto = this.heightAutoObserverEl.offsetHeight <= 1;
    var isWidthAuto = this.heightAutoObserverEl.offsetWidth <= 1 || contentElOffsetWidth > 0;
    var contentWrapperElOffsetWidth = this.contentWrapperEl.offsetWidth;
    var elOverflowX = this.elStyles.overflowX;
    var elOverflowY = this.elStyles.overflowY;
    this.contentEl.style.padding = "".concat(this.elStyles.paddingTop, " ").concat(this.elStyles.paddingRight, " ").concat(this.elStyles.paddingBottom, " ").concat(this.elStyles.paddingLeft);
    this.wrapperEl.style.margin = "-".concat(this.elStyles.paddingTop, " -").concat(this.elStyles.paddingRight, " -").concat(this.elStyles.paddingBottom, " -").concat(this.elStyles.paddingLeft);
    var contentElScrollHeight = this.contentEl.scrollHeight;
    var contentElScrollWidth = this.contentEl.scrollWidth;
    this.contentWrapperEl.style.height = isHeightAuto ? 'auto' : '100%';
    // Determine placeholder size
    this.placeholderEl.style.width = isWidthAuto ? "".concat(contentElOffsetWidth || contentElScrollWidth, "px") : 'auto';
    this.placeholderEl.style.height = "".concat(contentElScrollHeight, "px");
    var contentWrapperElOffsetHeight = this.contentWrapperEl.offsetHeight;
    this.axis.x.isOverflowing = contentElOffsetWidth !== 0 && contentElScrollWidth > contentElOffsetWidth;
    this.axis.y.isOverflowing = contentElScrollHeight > contentWrapperElOffsetHeight;
    // Set isOverflowing to false if user explicitely set hidden overflow
    this.axis.x.isOverflowing = elOverflowX === 'hidden' ? false : this.axis.x.isOverflowing;
    this.axis.y.isOverflowing = elOverflowY === 'hidden' ? false : this.axis.y.isOverflowing;
    this.axis.x.forceVisible = this.options.forceVisible === 'x' || this.options.forceVisible === true;
    this.axis.y.forceVisible = this.options.forceVisible === 'y' || this.options.forceVisible === true;
    this.hideNativeScrollbar();
    // Set isOverflowing to false if scrollbar is not necessary (content is shorter than offset)
    var offsetForXScrollbar = this.axis.x.isOverflowing ? this.scrollbarWidth : 0;
    var offsetForYScrollbar = this.axis.y.isOverflowing ? this.scrollbarWidth : 0;
    this.axis.x.isOverflowing = this.axis.x.isOverflowing && contentElScrollWidth > contentWrapperElOffsetWidth - offsetForYScrollbar;
    this.axis.y.isOverflowing = this.axis.y.isOverflowing && contentElScrollHeight > contentWrapperElOffsetHeight - offsetForXScrollbar;
    this.axis.x.scrollbar.size = this.getScrollbarSize('x');
    this.axis.y.scrollbar.size = this.getScrollbarSize('y');
    if (this.axis.x.scrollbar.el) this.axis.x.scrollbar.el.style.width = "".concat(this.axis.x.scrollbar.size, "px");
    if (this.axis.y.scrollbar.el) this.axis.y.scrollbar.el.style.height = "".concat(this.axis.y.scrollbar.size, "px");
    this.positionScrollbar('x');
    this.positionScrollbar('y');
    this.toggleTrackVisibility('x');
    this.toggleTrackVisibility('y');
  };
  /**
   * Calculate scrollbar size
   */
  SimpleBarCore.prototype.getScrollbarSize = function (axis) {
    var _a, _b;
    if (axis === void 0) {
      axis = 'y';
    }
    if (!this.axis[axis].isOverflowing || !this.contentEl) {
      return 0;
    }
    var contentSize = this.contentEl[this.axis[axis].scrollSizeAttr];
    var trackSize = (_b = (_a = this.axis[axis].track.el) === null || _a === void 0 ? void 0 : _a[this.axis[axis].offsetSizeAttr]) !== null && _b !== void 0 ? _b : 0;
    var scrollbarRatio = trackSize / contentSize;
    var scrollbarSize;
    // Calculate new height/position of drag handle.
    scrollbarSize = Math.max(~~(scrollbarRatio * trackSize), this.options.scrollbarMinSize);
    if (this.options.scrollbarMaxSize) {
      scrollbarSize = Math.min(scrollbarSize, this.options.scrollbarMaxSize);
    }
    return scrollbarSize;
  };
  SimpleBarCore.prototype.positionScrollbar = function (axis) {
    var _a, _b, _c;
    if (axis === void 0) {
      axis = 'y';
    }
    var scrollbar = this.axis[axis].scrollbar;
    if (!this.axis[axis].isOverflowing || !this.contentWrapperEl || !scrollbar.el || !this.elStyles) {
      return;
    }
    var contentSize = this.contentWrapperEl[this.axis[axis].scrollSizeAttr];
    var trackSize = ((_a = this.axis[axis].track.el) === null || _a === void 0 ? void 0 : _a[this.axis[axis].offsetSizeAttr]) || 0;
    var hostSize = parseInt(this.elStyles[this.axis[axis].sizeAttr], 10);
    var scrollOffset = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr];
    scrollOffset = axis === 'x' && this.isRtl && ((_b = SimpleBarCore.getRtlHelpers()) === null || _b === void 0 ? void 0 : _b.isScrollOriginAtZero) ? -scrollOffset : scrollOffset;
    if (axis === 'x' && this.isRtl) {
      scrollOffset = ((_c = SimpleBarCore.getRtlHelpers()) === null || _c === void 0 ? void 0 : _c.isScrollingToNegative) ? scrollOffset : -scrollOffset;
    }
    var scrollPourcent = scrollOffset / (contentSize - hostSize);
    var handleOffset = ~~((trackSize - scrollbar.size) * scrollPourcent);
    handleOffset = axis === 'x' && this.isRtl ? -handleOffset + (trackSize - scrollbar.size) : handleOffset;
    scrollbar.el.style.transform = axis === 'x' ? "translate3d(".concat(handleOffset, "px, 0, 0)") : "translate3d(0, ".concat(handleOffset, "px, 0)");
  };
  SimpleBarCore.prototype.toggleTrackVisibility = function (axis) {
    if (axis === void 0) {
      axis = 'y';
    }
    var track = this.axis[axis].track.el;
    var scrollbar = this.axis[axis].scrollbar.el;
    if (!track || !scrollbar || !this.contentWrapperEl) return;
    if (this.axis[axis].isOverflowing || this.axis[axis].forceVisible) {
      track.style.visibility = 'visible';
      this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'scroll';
      this.el.classList.add("".concat(this.classNames.scrollable, "-").concat(axis));
    } else {
      track.style.visibility = 'hidden';
      this.contentWrapperEl.style[this.axis[axis].overflowAttr] = 'hidden';
      this.el.classList.remove("".concat(this.classNames.scrollable, "-").concat(axis));
    }
    // Even if forceVisible is enabled, scrollbar itself should be hidden
    if (this.axis[axis].isOverflowing) {
      scrollbar.style.display = 'block';
    } else {
      scrollbar.style.display = 'none';
    }
  };
  SimpleBarCore.prototype.showScrollbar = function (axis) {
    if (axis === void 0) {
      axis = 'y';
    }
    if (this.axis[axis].isOverflowing && !this.axis[axis].scrollbar.isVisible) {
      addClasses(this.axis[axis].scrollbar.el, this.classNames.visible);
      this.axis[axis].scrollbar.isVisible = true;
    }
  };
  SimpleBarCore.prototype.hideScrollbar = function (axis) {
    if (axis === void 0) {
      axis = 'y';
    }
    if (this.isDragging) return;
    if (this.axis[axis].isOverflowing && this.axis[axis].scrollbar.isVisible) {
      removeClasses(this.axis[axis].scrollbar.el, this.classNames.visible);
      this.axis[axis].scrollbar.isVisible = false;
    }
  };
  SimpleBarCore.prototype.hideNativeScrollbar = function () {
    if (!this.offsetEl) return;
    this.offsetEl.style[this.isRtl ? 'left' : 'right'] = this.axis.y.isOverflowing || this.axis.y.forceVisible ? "-".concat(this.scrollbarWidth, "px") : '0px';
    this.offsetEl.style.bottom = this.axis.x.isOverflowing || this.axis.x.forceVisible ? "-".concat(this.scrollbarWidth, "px") : '0px';
  };
  SimpleBarCore.prototype.onMouseMoveForAxis = function (axis) {
    if (axis === void 0) {
      axis = 'y';
    }
    var currentAxis = this.axis[axis];
    if (!currentAxis.track.el || !currentAxis.scrollbar.el) return;
    currentAxis.track.rect = currentAxis.track.el.getBoundingClientRect();
    currentAxis.scrollbar.rect = currentAxis.scrollbar.el.getBoundingClientRect();
    if (this.isWithinBounds(currentAxis.track.rect)) {
      this.showScrollbar(axis);
      addClasses(currentAxis.track.el, this.classNames.hover);
      if (this.isWithinBounds(currentAxis.scrollbar.rect)) {
        addClasses(currentAxis.scrollbar.el, this.classNames.hover);
      } else {
        removeClasses(currentAxis.scrollbar.el, this.classNames.hover);
      }
    } else {
      removeClasses(currentAxis.track.el, this.classNames.hover);
      if (this.options.autoHide) {
        this.hideScrollbar(axis);
      }
    }
  };
  SimpleBarCore.prototype.onMouseLeaveForAxis = function (axis) {
    if (axis === void 0) {
      axis = 'y';
    }
    removeClasses(this.axis[axis].track.el, this.classNames.hover);
    removeClasses(this.axis[axis].scrollbar.el, this.classNames.hover);
    if (this.options.autoHide) {
      this.hideScrollbar(axis);
    }
  };
  /**
   * on scrollbar handle drag movement starts
   */
  SimpleBarCore.prototype.onDragStart = function (e, axis) {
    var _a;
    if (axis === void 0) {
      axis = 'y';
    }
    this.isDragging = true;
    var elDocument = getElementDocument(this.el);
    var elWindow = getElementWindow(this.el);
    var scrollbar = this.axis[axis].scrollbar;
    // Measure how far the user's mouse is from the top of the scrollbar drag handle.
    var eventOffset = axis === 'y' ? e.pageY : e.pageX;
    this.axis[axis].dragOffset = eventOffset - (((_a = scrollbar.rect) === null || _a === void 0 ? void 0 : _a[this.axis[axis].offsetAttr]) || 0);
    this.draggedAxis = axis;
    addClasses(this.el, this.classNames.dragging);
    elDocument.addEventListener('mousemove', this.drag, true);
    elDocument.addEventListener('mouseup', this.onEndDrag, true);
    if (this.removePreventClickId === null) {
      elDocument.addEventListener('click', this.preventClick, true);
      elDocument.addEventListener('dblclick', this.preventClick, true);
    } else {
      elWindow.clearTimeout(this.removePreventClickId);
      this.removePreventClickId = null;
    }
  };
  SimpleBarCore.prototype.onTrackClick = function (e, axis) {
    var _this = this;
    var _a, _b, _c, _d;
    if (axis === void 0) {
      axis = 'y';
    }
    var currentAxis = this.axis[axis];
    if (!this.options.clickOnTrack || !currentAxis.scrollbar.el || !this.contentWrapperEl) return;
    // Preventing the event's default to trigger click underneath
    e.preventDefault();
    var elWindow = getElementWindow(this.el);
    this.axis[axis].scrollbar.rect = currentAxis.scrollbar.el.getBoundingClientRect();
    var scrollbar = this.axis[axis].scrollbar;
    var scrollbarOffset = (_b = (_a = scrollbar.rect) === null || _a === void 0 ? void 0 : _a[this.axis[axis].offsetAttr]) !== null && _b !== void 0 ? _b : 0;
    var hostSize = parseInt((_d = (_c = this.elStyles) === null || _c === void 0 ? void 0 : _c[this.axis[axis].sizeAttr]) !== null && _d !== void 0 ? _d : '0px', 10);
    var scrolled = this.contentWrapperEl[this.axis[axis].scrollOffsetAttr];
    var t = axis === 'y' ? this.mouseY - scrollbarOffset : this.mouseX - scrollbarOffset;
    var dir = t < 0 ? -1 : 1;
    var scrollSize = dir === -1 ? scrolled - hostSize : scrolled + hostSize;
    var speed = 40;
    var scrollTo = function () {
      if (!_this.contentWrapperEl) return;
      if (dir === -1) {
        if (scrolled > scrollSize) {
          scrolled -= speed;
          _this.contentWrapperEl[_this.axis[axis].scrollOffsetAttr] = scrolled;
          elWindow.requestAnimationFrame(scrollTo);
        }
      } else {
        if (scrolled < scrollSize) {
          scrolled += speed;
          _this.contentWrapperEl[_this.axis[axis].scrollOffsetAttr] = scrolled;
          elWindow.requestAnimationFrame(scrollTo);
        }
      }
    };
    scrollTo();
  };
  /**
   * Getter for content element
   */
  SimpleBarCore.prototype.getContentElement = function () {
    return this.contentEl;
  };
  /**
   * Getter for original scrolling element
   */
  SimpleBarCore.prototype.getScrollElement = function () {
    return this.contentWrapperEl;
  };
  SimpleBarCore.prototype.removeListeners = function () {
    var elWindow = getElementWindow(this.el);
    // Event listeners
    this.el.removeEventListener('mouseenter', this.onMouseEnter);
    this.el.removeEventListener('pointerdown', this.onPointerEvent, true);
    this.el.removeEventListener('mousemove', this.onMouseMove);
    this.el.removeEventListener('mouseleave', this.onMouseLeave);
    if (this.contentWrapperEl) {
      this.contentWrapperEl.removeEventListener('scroll', this.onScroll);
    }
    elWindow.removeEventListener('resize', this.onWindowResize);
    if (this.mutationObserver) {
      this.mutationObserver.disconnect();
    }
    if (this.resizeObserver) {
      this.resizeObserver.disconnect();
    }
    // Cancel all debounced functions
    this.onMouseMove.cancel();
    this.onWindowResize.cancel();
    this.onStopScrolling.cancel();
    this.onMouseEntered.cancel();
  };
  /**
   * Remove all listeners from DOM nodes
   */
  SimpleBarCore.prototype.unMount = function () {
    this.removeListeners();
  };
  /**
   * Check if mouse is within bounds
   */
  SimpleBarCore.prototype.isWithinBounds = function (bbox) {
    return this.mouseX >= bbox.left && this.mouseX <= bbox.left + bbox.width && this.mouseY >= bbox.top && this.mouseY <= bbox.top + bbox.height;
  };
  /**
   * Find element children matches query
   */
  SimpleBarCore.prototype.findChild = function (el, query) {
    var matches = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
    return Array.prototype.filter.call(el.children, function (child) {
      return matches.call(child, query);
    })[0];
  };
  SimpleBarCore.rtlHelpers = null;
  SimpleBarCore.defaultOptions = {
    forceVisible: false,
    clickOnTrack: true,
    scrollbarMinSize: 25,
    scrollbarMaxSize: 0,
    ariaLabel: 'scrollable content',
    tabIndex: 0,
    classNames: {
      contentEl: 'simplebar-content',
      contentWrapper: 'simplebar-content-wrapper',
      offset: 'simplebar-offset',
      mask: 'simplebar-mask',
      wrapper: 'simplebar-wrapper',
      placeholder: 'simplebar-placeholder',
      scrollbar: 'simplebar-scrollbar',
      track: 'simplebar-track',
      heightAutoObserverWrapperEl: 'simplebar-height-auto-observer-wrapper',
      heightAutoObserverEl: 'simplebar-height-auto-observer',
      visible: 'simplebar-visible',
      horizontal: 'simplebar-horizontal',
      vertical: 'simplebar-vertical',
      hover: 'simplebar-hover',
      dragging: 'simplebar-dragging',
      scrolling: 'simplebar-scrolling',
      scrollable: 'simplebar-scrollable',
      mouseEntered: 'simplebar-mouse-entered'
    },
    scrollableNode: null,
    contentNode: null,
    autoHide: true
  };
  /**
   * Static functions
   */
  SimpleBarCore.getOptions = getOptions;
  SimpleBarCore.helpers = helpers;
  return SimpleBarCore;
}();


/***/ }),

/***/ 13857:
/*!************************************!*\
  !*** ./node_modules/xlsx/xlsx.mjs ***!
  \************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   CFB: () => (/* binding */ CFB),
/* harmony export */   SSF: () => (/* binding */ SSF),
/* harmony export */   parse_xlscfb: () => (/* binding */ parse_xlscfb),
/* harmony export */   parse_zip: () => (/* binding */ parse_zip),
/* harmony export */   read: () => (/* binding */ readSync),
/* harmony export */   readFile: () => (/* binding */ readFileSync),
/* harmony export */   readFileSync: () => (/* binding */ readFileSync),
/* harmony export */   set_cptable: () => (/* binding */ set_cptable),
/* harmony export */   set_fs: () => (/* binding */ set_fs),
/* harmony export */   stream: () => (/* binding */ __stream),
/* harmony export */   utils: () => (/* binding */ utils),
/* harmony export */   version: () => (/* binding */ version),
/* harmony export */   write: () => (/* binding */ writeSync),
/* harmony export */   writeFile: () => (/* binding */ writeFileSync),
/* harmony export */   writeFileAsync: () => (/* binding */ writeFileAsync),
/* harmony export */   writeFileSync: () => (/* binding */ writeFileSync),
/* harmony export */   writeFileXLSX: () => (/* binding */ writeFileSyncXLSX),
/* harmony export */   writeXLSX: () => (/* binding */ writeSyncXLSX)
/* harmony export */ });
/*! xlsx.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*exported XLSX */
/*global process:false, Buffer:false, ArrayBuffer:false, DataView:false, Deno:false */
var XLSX = {};
XLSX.version = '0.18.5';
var current_codepage = 1200,
  current_ansi = 1252;
var VALID_ANSI = [874, 932, 936, 949, 950, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1257, 1258, 10000];
/* ECMA-376 Part I 18.4.1 charset to codepage mapping */
var CS2CP = {
  /*::[*/0 /*::]*/: 1252,
  /* ANSI */
  /*::[*/1 /*::]*/: 65001,
  /* DEFAULT */
  /*::[*/2 /*::]*/: 65001,
  /* SYMBOL */
  /*::[*/77 /*::]*/: 10000,
  /* MAC */
  /*::[*/128 /*::]*/: 932,
  /* SHIFTJIS */
  /*::[*/129 /*::]*/: 949,
  /* HANGUL */
  /*::[*/130 /*::]*/: 1361,
  /* JOHAB */
  /*::[*/134 /*::]*/: 936,
  /* GB2312 */
  /*::[*/136 /*::]*/: 950,
  /* CHINESEBIG5 */
  /*::[*/161 /*::]*/: 1253,
  /* GREEK */
  /*::[*/162 /*::]*/: 1254,
  /* TURKISH */
  /*::[*/163 /*::]*/: 1258,
  /* VIETNAMESE */
  /*::[*/177 /*::]*/: 1255,
  /* HEBREW */
  /*::[*/178 /*::]*/: 1256,
  /* ARABIC */
  /*::[*/186 /*::]*/: 1257,
  /* BALTIC */
  /*::[*/204 /*::]*/: 1251,
  /* RUSSIAN */
  /*::[*/222 /*::]*/: 874,
  /* THAI */
  /*::[*/238 /*::]*/: 1250,
  /* EASTEUROPE */
  /*::[*/255 /*::]*/: 1252,
  /* OEM */
  /*::[*/69 /*::]*/: 6969 /* MISC */
} /*:any*/;
var set_ansi = function (cp /*:number*/) {
  if (VALID_ANSI.indexOf(cp) == -1) return;
  current_ansi = CS2CP[0] = cp;
};
function reset_ansi() {
  set_ansi(1252);
}
var set_cp = function (cp /*:number*/) {
  current_codepage = cp;
  set_ansi(cp);
};
function reset_cp() {
  set_cp(1200);
  reset_ansi();
}
function char_codes(data /*:string*/) /*:Array<number>*/{
  var o /*:Array<number>*/ = [];
  for (var i = 0, len = data.length; i < len; ++i) o[i] = data.charCodeAt(i);
  return o;
}
function utf16leread(data /*:string*/) /*:string*/{
  var o /*:Array<string>*/ = [];
  for (var i = 0; i < data.length >> 1; ++i) o[i] = String.fromCharCode(data.charCodeAt(2 * i) + (data.charCodeAt(2 * i + 1) << 8));
  return o.join("");
}
function utf16beread(data /*:string*/) /*:string*/{
  var o /*:Array<string>*/ = [];
  for (var i = 0; i < data.length >> 1; ++i) o[i] = String.fromCharCode(data.charCodeAt(2 * i + 1) + (data.charCodeAt(2 * i) << 8));
  return o.join("");
}
var debom = function (data /*:string*/) /*:string*/{
  var c1 = data.charCodeAt(0),
    c2 = data.charCodeAt(1);
  if (c1 == 0xFF && c2 == 0xFE) return utf16leread(data.slice(2));
  if (c1 == 0xFE && c2 == 0xFF) return utf16beread(data.slice(2));
  if (c1 == 0xFEFF) return data.slice(1);
  return data;
};
var _getchar = function _gc1(x /*:number*/) /*:string*/{
  return String.fromCharCode(x);
};
var _getansi = function _ga1(x /*:number*/) /*:string*/{
  return String.fromCharCode(x);
};
var $cptable;
function set_cptable(cptable) {
  $cptable = cptable;
  set_cp = function (cp /*:number*/) {
    current_codepage = cp;
    set_ansi(cp);
  };
  debom = function (data /*:string*/) {
    if (data.charCodeAt(0) === 0xFF && data.charCodeAt(1) === 0xFE) {
      return $cptable.utils.decode(1200, char_codes(data.slice(2)));
    }
    return data;
  };
  _getchar = function _gc2(x /*:number*/) /*:string*/{
    if (current_codepage === 1200) return String.fromCharCode(x);
    return $cptable.utils.decode(current_codepage, [x & 255, x >> 8])[0];
  };
  _getansi = function _ga2(x /*:number*/) /*:string*/{
    return $cptable.utils.decode(current_ansi, [x])[0];
  };
  cpdoit();
}

var DENSE = null;
var DIF_XL = true;
var Base64_map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function Base64_encode(input) {
  var o = "";
  var c1 = 0,
    c2 = 0,
    c3 = 0,
    e1 = 0,
    e2 = 0,
    e3 = 0,
    e4 = 0;
  for (var i = 0; i < input.length;) {
    c1 = input.charCodeAt(i++);
    e1 = c1 >> 2;
    c2 = input.charCodeAt(i++);
    e2 = (c1 & 3) << 4 | c2 >> 4;
    c3 = input.charCodeAt(i++);
    e3 = (c2 & 15) << 2 | c3 >> 6;
    e4 = c3 & 63;
    if (isNaN(c2)) {
      e3 = e4 = 64;
    } else if (isNaN(c3)) {
      e4 = 64;
    }
    o += Base64_map.charAt(e1) + Base64_map.charAt(e2) + Base64_map.charAt(e3) + Base64_map.charAt(e4);
  }
  return o;
}
function Base64_decode(input) {
  var o = "";
  var c1 = 0,
    c2 = 0,
    c3 = 0,
    e1 = 0,
    e2 = 0,
    e3 = 0,
    e4 = 0;
  input = input.replace(/[^\w\+\/\=]/g, "");
  for (var i = 0; i < input.length;) {
    e1 = Base64_map.indexOf(input.charAt(i++));
    e2 = Base64_map.indexOf(input.charAt(i++));
    c1 = e1 << 2 | e2 >> 4;
    o += String.fromCharCode(c1);
    e3 = Base64_map.indexOf(input.charAt(i++));
    c2 = (e2 & 15) << 4 | e3 >> 2;
    if (e3 !== 64) {
      o += String.fromCharCode(c2);
    }
    e4 = Base64_map.indexOf(input.charAt(i++));
    c3 = (e3 & 3) << 6 | e4;
    if (e4 !== 64) {
      o += String.fromCharCode(c3);
    }
  }
  return o;
}
var has_buf = /*#__PURE__*/function () {
  return typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && !!process.versions.node;
}();
var Buffer_from = /*#__PURE__*/function () {
  if (typeof Buffer !== 'undefined') {
    var nbfs = !Buffer.from;
    if (!nbfs) try {
      Buffer.from("foo", "utf8");
    } catch (e) {
      nbfs = true;
    }
    return nbfs ? function (buf, enc) {
      return enc ? new Buffer(buf, enc) : new Buffer(buf);
    } : Buffer.from.bind(Buffer);
  }
  return function () {};
}();
function new_raw_buf(len /*:number*/) {
  /* jshint -W056 */
  if (has_buf) return Buffer.alloc ? Buffer.alloc(len) : new Buffer(len);
  return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
  /* jshint +W056 */
}
function new_unsafe_buf(len /*:number*/) {
  /* jshint -W056 */
  if (has_buf) return Buffer.allocUnsafe ? Buffer.allocUnsafe(len) : new Buffer(len);
  return typeof Uint8Array != "undefined" ? new Uint8Array(len) : new Array(len);
  /* jshint +W056 */
}
var s2a = function s2a(s /*:string*/) /*:any*/{
  if (has_buf) return Buffer_from(s, "binary");
  return s.split("").map(function (x /*:string*/) /*:number*/{
    return x.charCodeAt(0) & 0xff;
  });
};
function s2ab(s /*:string*/) /*:any*/{
  if (typeof ArrayBuffer === 'undefined') return s2a(s);
  var buf = new ArrayBuffer(s.length),
    view = new Uint8Array(buf);
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
}
function a2s(data /*:any*/) /*:string*/{
  if (Array.isArray(data)) return data.map(function (c) {
    return String.fromCharCode(c);
  }).join("");
  var o /*:Array<string>*/ = [];
  for (var i = 0; i < data.length; ++i) o[i] = String.fromCharCode(data[i]);
  return o.join("");
}
function a2u(data /*:Array<number>*/) /*:Uint8Array*/{
  if (typeof Uint8Array === 'undefined') throw new Error("Unsupported");
  return new Uint8Array(data);
}
function ab2a(data /*:ArrayBuffer|Uint8Array*/) /*:Array<number>*/{
  if (typeof ArrayBuffer == 'undefined') throw new Error("Unsupported");
  if (data instanceof ArrayBuffer) return ab2a(new Uint8Array(data));
  /*:: if(data instanceof ArrayBuffer) throw new Error("unreachable"); */
  var o = new Array(data.length);
  for (var i = 0; i < data.length; ++i) o[i] = data[i];
  return o;
}
var bconcat = has_buf ? function (bufs) {
  return Buffer.concat(bufs.map(function (buf) {
    return Buffer.isBuffer(buf) ? buf : Buffer_from(buf);
  }));
} : function (bufs) {
  if (typeof Uint8Array !== "undefined") {
    var i = 0,
      maxlen = 0;
    for (i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;
    var o = new Uint8Array(maxlen);
    var len = 0;
    for (i = 0, maxlen = 0; i < bufs.length; maxlen += len, ++i) {
      len = bufs[i].length;
      if (bufs[i] instanceof Uint8Array) o.set(bufs[i], maxlen);else if (typeof bufs[i] == "string") {
        throw "wtf";
      } else o.set(new Uint8Array(bufs[i]), maxlen);
    }
    return o;
  }
  return [].concat.apply([], bufs.map(function (buf) {
    return Array.isArray(buf) ? buf : [].slice.call(buf);
  }));
};
function utf8decode(content /*:string*/) {
  var out = [],
    widx = 0,
    L = content.length + 250;
  var o = new_raw_buf(content.length + 255);
  for (var ridx = 0; ridx < content.length; ++ridx) {
    var c = content.charCodeAt(ridx);
    if (c < 0x80) o[widx++] = c;else if (c < 0x800) {
      o[widx++] = 192 | c >> 6 & 31;
      o[widx++] = 128 | c & 63;
    } else if (c >= 0xD800 && c < 0xE000) {
      c = (c & 1023) + 64;
      var d = content.charCodeAt(++ridx) & 1023;
      o[widx++] = 240 | c >> 8 & 7;
      o[widx++] = 128 | c >> 2 & 63;
      o[widx++] = 128 | d >> 6 & 15 | (c & 3) << 4;
      o[widx++] = 128 | d & 63;
    } else {
      o[widx++] = 224 | c >> 12 & 15;
      o[widx++] = 128 | c >> 6 & 63;
      o[widx++] = 128 | c & 63;
    }
    if (widx > L) {
      out.push(o.slice(0, widx));
      widx = 0;
      o = new_raw_buf(65535);
      L = 65530;
    }
  }
  out.push(o.slice(0, widx));
  return bconcat(out);
}
var chr0 = /\u0000/g,
  chr1 = /[\u0001-\u0006]/g;
/*::
declare type Block = any;
declare type BufArray = {
	newblk(sz:number):Block;
	next(sz:number):Block;
	end():any;
	push(buf:Block):void;
};

type RecordHopperCB = {(d:any, Rn:string, RT:number):?boolean;};

type EvertType = {[string]:string};
type EvertNumType = {[string]:number};
type EvertArrType = {[string]:Array<string>};

type StringConv = {(string):string};

*/
/* ssf.js (C) 2013-present SheetJS -- http://sheetjs.com */
/*jshint -W041 */
function _strrev(x /*:string*/) /*:string*/{
  var o = "",
    i = x.length - 1;
  while (i >= 0) o += x.charAt(i--);
  return o;
}
function pad0(v /*:any*/, d /*:number*/) /*:string*/{
  var t = "" + v;
  return t.length >= d ? t : fill('0', d - t.length) + t;
}
function pad_(v /*:any*/, d /*:number*/) /*:string*/{
  var t = "" + v;
  return t.length >= d ? t : fill(' ', d - t.length) + t;
}
function rpad_(v /*:any*/, d /*:number*/) /*:string*/{
  var t = "" + v;
  return t.length >= d ? t : t + fill(' ', d - t.length);
}
function pad0r1(v /*:any*/, d /*:number*/) /*:string*/{
  var t = "" + Math.round(v);
  return t.length >= d ? t : fill('0', d - t.length) + t;
}
function pad0r2(v /*:any*/, d /*:number*/) /*:string*/{
  var t = "" + v;
  return t.length >= d ? t : fill('0', d - t.length) + t;
}
var p2_32 = /*#__PURE__*/Math.pow(2, 32);
function pad0r(v /*:any*/, d /*:number*/) /*:string*/{
  if (v > p2_32 || v < -p2_32) return pad0r1(v, d);
  var i = Math.round(v);
  return pad0r2(i, d);
}
/* yes, in 2022 this is still faster than string compare */
function SSF_isgeneral(s /*:string*/, i /*:?number*/) /*:boolean*/{
  i = i || 0;
  return s.length >= 7 + i && (s.charCodeAt(i) | 32) === 103 && (s.charCodeAt(i + 1) | 32) === 101 && (s.charCodeAt(i + 2) | 32) === 110 && (s.charCodeAt(i + 3) | 32) === 101 && (s.charCodeAt(i + 4) | 32) === 114 && (s.charCodeAt(i + 5) | 32) === 97 && (s.charCodeAt(i + 6) | 32) === 108;
}
var days /*:Array<Array<string> >*/ = [['Sun', 'Sunday'], ['Mon', 'Monday'], ['Tue', 'Tuesday'], ['Wed', 'Wednesday'], ['Thu', 'Thursday'], ['Fri', 'Friday'], ['Sat', 'Saturday']];
var months /*:Array<Array<string> >*/ = [['J', 'Jan', 'January'], ['F', 'Feb', 'February'], ['M', 'Mar', 'March'], ['A', 'Apr', 'April'], ['M', 'May', 'May'], ['J', 'Jun', 'June'], ['J', 'Jul', 'July'], ['A', 'Aug', 'August'], ['S', 'Sep', 'September'], ['O', 'Oct', 'October'], ['N', 'Nov', 'November'], ['D', 'Dec', 'December']];
function SSF_init_table(t /*:any*/) {
  if (!t) t = {};
  t[0] = 'General';
  t[1] = '0';
  t[2] = '0.00';
  t[3] = '#,##0';
  t[4] = '#,##0.00';
  t[9] = '0%';
  t[10] = '0.00%';
  t[11] = '0.00E+00';
  t[12] = '# ?/?';
  t[13] = '# ??/??';
  t[14] = 'm/d/yy';
  t[15] = 'd-mmm-yy';
  t[16] = 'd-mmm';
  t[17] = 'mmm-yy';
  t[18] = 'h:mm AM/PM';
  t[19] = 'h:mm:ss AM/PM';
  t[20] = 'h:mm';
  t[21] = 'h:mm:ss';
  t[22] = 'm/d/yy h:mm';
  t[37] = '#,##0 ;(#,##0)';
  t[38] = '#,##0 ;[Red](#,##0)';
  t[39] = '#,##0.00;(#,##0.00)';
  t[40] = '#,##0.00;[Red](#,##0.00)';
  t[45] = 'mm:ss';
  t[46] = '[h]:mm:ss';
  t[47] = 'mmss.0';
  t[48] = '##0.0E+0';
  t[49] = '@';
  t[56] = '"上午/下午 "hh"時"mm"分"ss"秒 "';
  return t;
}
/* repeated to satiate webpack */
var table_fmt = {
  0: 'General',
  1: '0',
  2: '0.00',
  3: '#,##0',
  4: '#,##0.00',
  9: '0%',
  10: '0.00%',
  11: '0.00E+00',
  12: '# ?/?',
  13: '# ??/??',
  14: 'm/d/yy',
  15: 'd-mmm-yy',
  16: 'd-mmm',
  17: 'mmm-yy',
  18: 'h:mm AM/PM',
  19: 'h:mm:ss AM/PM',
  20: 'h:mm',
  21: 'h:mm:ss',
  22: 'm/d/yy h:mm',
  37: '#,##0 ;(#,##0)',
  38: '#,##0 ;[Red](#,##0)',
  39: '#,##0.00;(#,##0.00)',
  40: '#,##0.00;[Red](#,##0.00)',
  45: 'mm:ss',
  46: '[h]:mm:ss',
  47: 'mmss.0',
  48: '##0.0E+0',
  49: '@',
  56: '"上午/下午 "hh"時"mm"分"ss"秒 "'
};

/* Defaults determined by systematically testing in Excel 2019 */

/* These formats appear to default to other formats in the table */
var SSF_default_map = {
  5: 37,
  6: 38,
  7: 39,
  8: 40,
  //  5 -> 37 ...  8 -> 40

  23: 0,
  24: 0,
  25: 0,
  26: 0,
  // 23 ->  0 ... 26 ->  0

  27: 14,
  28: 14,
  29: 14,
  30: 14,
  31: 14,
  // 27 -> 14 ... 31 -> 14

  50: 14,
  51: 14,
  52: 14,
  53: 14,
  54: 14,
  // 50 -> 14 ... 58 -> 14
  55: 14,
  56: 14,
  57: 14,
  58: 14,
  59: 1,
  60: 2,
  61: 3,
  62: 4,
  // 59 ->  1 ... 62 ->  4

  67: 9,
  68: 10,
  // 67 ->  9 ... 68 -> 10
  69: 12,
  70: 13,
  71: 14,
  // 69 -> 12 ... 71 -> 14
  72: 14,
  73: 15,
  74: 16,
  75: 17,
  // 72 -> 14 ... 75 -> 17
  76: 20,
  77: 21,
  78: 22,
  // 76 -> 20 ... 78 -> 22
  79: 45,
  80: 46,
  81: 47,
  // 79 -> 45 ... 81 -> 47
  82: 0 // 82 ->  0 ... 65536 -> 0 (omitted)
};

/* These formats technically refer to Accounting formats with no equivalent */
var SSF_default_str = {
  //  5 -- Currency,   0 decimal, black negative
  5: '"$"#,##0_);\\("$"#,##0\\)',
  63: '"$"#,##0_);\\("$"#,##0\\)',
  //  6 -- Currency,   0 decimal, red   negative
  6: '"$"#,##0_);[Red]\\("$"#,##0\\)',
  64: '"$"#,##0_);[Red]\\("$"#,##0\\)',
  //  7 -- Currency,   2 decimal, black negative
  7: '"$"#,##0.00_);\\("$"#,##0.00\\)',
  65: '"$"#,##0.00_);\\("$"#,##0.00\\)',
  //  8 -- Currency,   2 decimal, red   negative
  8: '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
  66: '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
  // 41 -- Accounting, 0 decimal, No Symbol
  41: '_(* #,##0_);_(* \\(#,##0\\);_(* "-"_);_(@_)',
  // 42 -- Accounting, 0 decimal, $  Symbol
  42: '_("$"* #,##0_);_("$"* \\(#,##0\\);_("$"* "-"_);_(@_)',
  // 43 -- Accounting, 2 decimal, No Symbol
  43: '_(* #,##0.00_);_(* \\(#,##0.00\\);_(* "-"??_);_(@_)',
  // 44 -- Accounting, 2 decimal, $  Symbol
  44: '_("$"* #,##0.00_);_("$"* \\(#,##0.00\\);_("$"* "-"??_);_(@_)'
};
function SSF_frac(x /*:number*/, D /*:number*/, mixed /*:?boolean*/) /*:Array<number>*/{
  var sgn = x < 0 ? -1 : 1;
  var B = x * sgn;
  var P_2 = 0,
    P_1 = 1,
    P = 0;
  var Q_2 = 1,
    Q_1 = 0,
    Q = 0;
  var A = Math.floor(B);
  while (Q_1 < D) {
    A = Math.floor(B);
    P = A * P_1 + P_2;
    Q = A * Q_1 + Q_2;
    if (B - A < 0.00000005) break;
    B = 1 / (B - A);
    P_2 = P_1;
    P_1 = P;
    Q_2 = Q_1;
    Q_1 = Q;
  }
  if (Q > D) {
    if (Q_1 > D) {
      Q = Q_2;
      P = P_2;
    } else {
      Q = Q_1;
      P = P_1;
    }
  }
  if (!mixed) return [0, sgn * P, Q];
  var q = Math.floor(sgn * P / Q);
  return [q, sgn * P - q * Q, Q];
}
function SSF_parse_date_code(v /*:number*/, opts /*:?any*/, b2 /*:?boolean*/) {
  if (v > 2958465 || v < 0) return null;
  var date = v | 0,
    time = Math.floor(86400 * (v - date)),
    dow = 0;
  var dout = [];
  var out = {
    D: date,
    T: time,
    u: 86400 * (v - date) - time,
    y: 0,
    m: 0,
    d: 0,
    H: 0,
    M: 0,
    S: 0,
    q: 0
  };
  if (Math.abs(out.u) < 1e-6) out.u = 0;
  if (opts && opts.date1904) date += 1462;
  if (out.u > 0.9999) {
    out.u = 0;
    if (++time == 86400) {
      out.T = time = 0;
      ++date;
      ++out.D;
    }
  }
  if (date === 60) {
    dout = b2 ? [1317, 10, 29] : [1900, 2, 29];
    dow = 3;
  } else if (date === 0) {
    dout = b2 ? [1317, 8, 29] : [1900, 1, 0];
    dow = 6;
  } else {
    if (date > 60) --date;
    /* 1 = Jan 1 1900 in Gregorian */
    var d = new Date(1900, 0, 1);
    d.setDate(d.getDate() + date - 1);
    dout = [d.getFullYear(), d.getMonth() + 1, d.getDate()];
    dow = d.getDay();
    if (date < 60) dow = (dow + 6) % 7;
    if (b2) dow = SSF_fix_hijri(d, dout);
  }
  out.y = dout[0];
  out.m = dout[1];
  out.d = dout[2];
  out.S = time % 60;
  time = Math.floor(time / 60);
  out.M = time % 60;
  time = Math.floor(time / 60);
  out.H = time;
  out.q = dow;
  return out;
}
var SSFbasedate = /*#__PURE__*/new Date(1899, 11, 31, 0, 0, 0);
var SSFdnthresh = /*#__PURE__*/SSFbasedate.getTime();
var SSFbase1904 = /*#__PURE__*/new Date(1900, 2, 1, 0, 0, 0);
function datenum_local(v /*:Date*/, date1904 /*:?boolean*/) /*:number*/{
  var epoch = /*#__PURE__*/v.getTime();
  if (date1904) epoch -= 1461 * 24 * 60 * 60 * 1000;else if (v >= SSFbase1904) epoch += 24 * 60 * 60 * 1000;
  return (epoch - (SSFdnthresh + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/SSFbasedate.getTimezoneOffset()) * 60000)) / (24 * 60 * 60 * 1000);
}
/* ECMA-376 18.8.30 numFmt*/
/* Note: `toPrecision` uses standard form when prec > E and E >= -6 */
/* exponent >= -9 and <= 9 */
function SSF_strip_decimal(o /*:string*/) /*:string*/{
  return o.indexOf(".") == -1 ? o : o.replace(/(?:\.0*|(\.\d*[1-9])0+)$/, "$1");
}

/* General Exponential always shows 2 digits exp and trims the mantissa */
function SSF_normalize_exp(o /*:string*/) /*:string*/{
  if (o.indexOf("E") == -1) return o;
  return o.replace(/(?:\.0*|(\.\d*[1-9])0+)[Ee]/, "$1E").replace(/(E[+-])(\d)$/, "$10$2");
}

/* exponent >= -9 and <= 9 */
function SSF_small_exp(v /*:number*/) /*:string*/{
  var w = v < 0 ? 12 : 11;
  var o = SSF_strip_decimal(v.toFixed(12));
  if (o.length <= w) return o;
  o = v.toPrecision(10);
  if (o.length <= w) return o;
  return v.toExponential(5);
}

/* exponent >= 11 or <= -10 likely exponential */
function SSF_large_exp(v /*:number*/) /*:string*/{
  var o = SSF_strip_decimal(v.toFixed(11));
  return o.length > (v < 0 ? 12 : 11) || o === "0" || o === "-0" ? v.toPrecision(6) : o;
}
function SSF_general_num(v /*:number*/) /*:string*/{
  var V = Math.floor(Math.log(Math.abs(v)) * Math.LOG10E),
    o;
  if (V >= -4 && V <= -1) o = v.toPrecision(10 + V);else if (Math.abs(V) <= 9) o = SSF_small_exp(v);else if (V === 10) o = v.toFixed(10).substr(0, 12);else o = SSF_large_exp(v);
  return SSF_strip_decimal(SSF_normalize_exp(o.toUpperCase()));
}

/*
	"General" rules:
	- text is passed through ("@")
	- booleans are rendered as TRUE/FALSE
	- "up to 11 characters" displayed for numbers
	- Default date format (code 14) used for Dates

	The longest 32-bit integer text is "-2147483648", exactly 11 chars
	TODO: technically the display depends on the width of the cell
*/
function SSF_general(v /*:any*/, opts /*:any*/) {
  switch (typeof v) {
    case 'string':
      return v;
    case 'boolean':
      return v ? "TRUE" : "FALSE";
    case 'number':
      return (v | 0) === v ? v.toString(10) : SSF_general_num(v);
    case 'undefined':
      return "";
    case 'object':
      if (v == null) return "";
      if (v instanceof Date) return SSF_format(14, datenum_local(v, opts && opts.date1904), opts);
  }
  throw new Error("unsupported value in General format: " + v);
}
function SSF_fix_hijri(date /*:Date*/, o /*:[number, number, number]*/) {
  /* TODO: properly adjust y/m/d and  */
  o[0] -= 581;
  var dow = date.getDay();
  if (date < 60) dow = (dow + 6) % 7;
  return dow;
}
//var THAI_DIGITS = "\u0E50\u0E51\u0E52\u0E53\u0E54\u0E55\u0E56\u0E57\u0E58\u0E59".split("");
function SSF_write_date(type /*:number*/, fmt /*:string*/, val, ss0 /*:?number*/) /*:string*/{
  var o = "",
    ss = 0,
    tt = 0,
    y = val.y,
    out,
    outl = 0;
  switch (type) {
    case 98:
      /* 'b' buddhist year */
      y = val.y + 543;
    /* falls through */
    case 121:
      /* 'y' year */
      switch (fmt.length) {
        case 1:
        case 2:
          out = y % 100;
          outl = 2;
          break;
        default:
          out = y % 10000;
          outl = 4;
          break;
      }
      break;
    case 109:
      /* 'm' month */
      switch (fmt.length) {
        case 1:
        case 2:
          out = val.m;
          outl = fmt.length;
          break;
        case 3:
          return months[val.m - 1][1];
        case 5:
          return months[val.m - 1][0];
        default:
          return months[val.m - 1][2];
      }
      break;
    case 100:
      /* 'd' day */
      switch (fmt.length) {
        case 1:
        case 2:
          out = val.d;
          outl = fmt.length;
          break;
        case 3:
          return days[val.q][0];
        default:
          return days[val.q][1];
      }
      break;
    case 104:
      /* 'h' 12-hour */
      switch (fmt.length) {
        case 1:
        case 2:
          out = 1 + (val.H + 11) % 12;
          outl = fmt.length;
          break;
        default:
          throw 'bad hour format: ' + fmt;
      }
      break;
    case 72:
      /* 'H' 24-hour */
      switch (fmt.length) {
        case 1:
        case 2:
          out = val.H;
          outl = fmt.length;
          break;
        default:
          throw 'bad hour format: ' + fmt;
      }
      break;
    case 77:
      /* 'M' minutes */
      switch (fmt.length) {
        case 1:
        case 2:
          out = val.M;
          outl = fmt.length;
          break;
        default:
          throw 'bad minute format: ' + fmt;
      }
      break;
    case 115:
      /* 's' seconds */
      if (fmt != 's' && fmt != 'ss' && fmt != '.0' && fmt != '.00' && fmt != '.000') throw 'bad second format: ' + fmt;
      if (val.u === 0 && (fmt == "s" || fmt == "ss")) return pad0(val.S, fmt.length);
      /*::if(!ss0) ss0 = 0; */
      if (ss0 >= 2) tt = ss0 === 3 ? 1000 : 100;else tt = ss0 === 1 ? 10 : 1;
      ss = Math.round(tt * (val.S + val.u));
      if (ss >= 60 * tt) ss = 0;
      if (fmt === 's') return ss === 0 ? "0" : "" + ss / tt;
      o = pad0(ss, 2 + ss0);
      if (fmt === 'ss') return o.substr(0, 2);
      return "." + o.substr(2, fmt.length - 1);
    case 90:
      /* 'Z' absolute time */
      switch (fmt) {
        case '[h]':
        case '[hh]':
          out = val.D * 24 + val.H;
          break;
        case '[m]':
        case '[mm]':
          out = (val.D * 24 + val.H) * 60 + val.M;
          break;
        case '[s]':
        case '[ss]':
          out = ((val.D * 24 + val.H) * 60 + val.M) * 60 + Math.round(val.S + val.u);
          break;
        default:
          throw 'bad abstime format: ' + fmt;
      }
      outl = fmt.length === 3 ? 1 : 2;
      break;
    case 101:
      /* 'e' era */
      out = y;
      outl = 1;
      break;
  }
  var outstr = outl > 0 ? pad0(out, outl) : "";
  return outstr;
}

/*jshint -W086 */
/*jshint +W086 */
function commaify(s /*:string*/) /*:string*/{
  var w = 3;
  if (s.length <= w) return s;
  var j = s.length % w,
    o = s.substr(0, j);
  for (; j != s.length; j += w) o += (o.length > 0 ? "," : "") + s.substr(j, w);
  return o;
}
var pct1 = /%/g;
function write_num_pct(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  var sfmt = fmt.replace(pct1, ""),
    mul = fmt.length - sfmt.length;
  return write_num(type, sfmt, val * Math.pow(10, 2 * mul)) + fill("%", mul);
}
function write_num_cm(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  var idx = fmt.length - 1;
  while (fmt.charCodeAt(idx - 1) === 44) --idx;
  return write_num(type, fmt.substr(0, idx), val / Math.pow(10, 3 * (fmt.length - idx)));
}
function write_num_exp(fmt /*:string*/, val /*:number*/) /*:string*/{
  var o /*:string*/;
  var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
  if (fmt.match(/^#+0.0E\+0$/)) {
    if (val == 0) return "0.0E+0";else if (val < 0) return "-" + write_num_exp(fmt, -val);
    var period = fmt.indexOf(".");
    if (period === -1) period = fmt.indexOf('E');
    var ee = Math.floor(Math.log(val) * Math.LOG10E) % period;
    if (ee < 0) ee += period;
    o = (val / Math.pow(10, ee)).toPrecision(idx + 1 + (period + ee) % period);
    if (o.indexOf("e") === -1) {
      var fakee = Math.floor(Math.log(val) * Math.LOG10E);
      if (o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length + ee);else o += "E+" + (fakee - ee);
      while (o.substr(0, 2) === "0.") {
        o = o.charAt(0) + o.substr(2, period) + "." + o.substr(2 + period);
        o = o.replace(/^0+([1-9])/, "$1").replace(/^0+\./, "0.");
      }
      o = o.replace(/\+-/, "-");
    }
    o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/, function ($$, $1, $2, $3) {
      return $1 + $2 + $3.substr(0, (period + ee) % period) + "." + $3.substr(ee) + "E";
    });
  } else o = val.toExponential(idx);
  if (fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0, o.length - 1) + "0" + o.charAt(o.length - 1);
  if (fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/, "e");
  return o.replace("e", "E");
}
var frac1 = /# (\?+)( ?)\/( ?)(\d+)/;
function write_num_f1(r /*:Array<string>*/, aval /*:number*/, sign /*:string*/) /*:string*/{
  var den = parseInt(r[4], 10),
    rr = Math.round(aval * den),
    base = Math.floor(rr / den);
  var myn = rr - base * den,
    myd = den;
  return sign + (base === 0 ? "" : "" + base) + " " + (myn === 0 ? fill(" ", r[1].length + 1 + r[4].length) : pad_(myn, r[1].length) + r[2] + "/" + r[3] + pad0(myd, r[4].length));
}
function write_num_f2(r /*:Array<string>*/, aval /*:number*/, sign /*:string*/) /*:string*/{
  return sign + (aval === 0 ? "" : "" + aval) + fill(" ", r[1].length + 2 + r[4].length);
}
var dec1 = /^#*0*\.([0#]+)/;
var closeparen = /\).*[0#]/;
var phone = /\(###\) ###\\?-####/;
function hashq(str /*:string*/) /*:string*/{
  var o = "",
    cc;
  for (var i = 0; i != str.length; ++i) switch (cc = str.charCodeAt(i)) {
    case 35:
      break;
    case 63:
      o += " ";
      break;
    case 48:
      o += "0";
      break;
    default:
      o += String.fromCharCode(cc);
  }
  return o;
}
function rnd(val /*:number*/, d /*:number*/) /*:string*/{
  var dd = Math.pow(10, d);
  return "" + Math.round(val * dd) / dd;
}
function dec(val /*:number*/, d /*:number*/) /*:number*/{
  var _frac = val - Math.floor(val),
    dd = Math.pow(10, d);
  if (d < ('' + Math.round(_frac * dd)).length) return 0;
  return Math.round(_frac * dd);
}
function carry(val /*:number*/, d /*:number*/) /*:number*/{
  if (d < ('' + Math.round((val - Math.floor(val)) * Math.pow(10, d))).length) {
    return 1;
  }
  return 0;
}
function flr(val /*:number*/) /*:string*/{
  if (val < 2147483647 && val > -2147483648) return "" + (val >= 0 ? val | 0 : val - 1 | 0);
  return "" + Math.floor(val);
}
function write_num_flt(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  if (type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
    var ffmt = fmt.replace(/\( */, "").replace(/ \)/, "").replace(/\)/, "");
    if (val >= 0) return write_num_flt('n', ffmt, val);
    return '(' + write_num_flt('n', ffmt, -val) + ')';
  }
  if (fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm(type, fmt, val);
  if (fmt.indexOf('%') !== -1) return write_num_pct(type, fmt, val);
  if (fmt.indexOf('E') !== -1) return write_num_exp(fmt, val);
  if (fmt.charCodeAt(0) === 36) return "$" + write_num_flt(type, fmt.substr(fmt.charAt(1) == ' ' ? 2 : 1), val);
  var o;
  var r /*:?Array<string>*/,
    ri,
    ff,
    aval = Math.abs(val),
    sign = val < 0 ? "-" : "";
  if (fmt.match(/^00+$/)) return sign + pad0r(aval, fmt.length);
  if (fmt.match(/^[#?]+$/)) {
    o = pad0r(val, 0);
    if (o === "0") o = "";
    return o.length > fmt.length ? o : hashq(fmt.substr(0, fmt.length - o.length)) + o;
  }
  if (r = fmt.match(frac1)) return write_num_f1(r, aval, sign);
  if (fmt.match(/^#+0+$/)) return sign + pad0r(aval, fmt.length - fmt.indexOf("0"));
  if (r = fmt.match(dec1)) {
    o = rnd(val, r[1].length).replace(/^([^\.]+)$/, "$1." + hashq(r[1])).replace(/\.$/, "." + hashq(r[1])).replace(/\.(\d*)$/, function ($$, $1) {
      return "." + $1 + fill("0", hashq(/*::(*/r /*::||[""])*/[1]).length - $1.length);
    });
    return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./, ".");
  }
  fmt = fmt.replace(/^#+([0.])/, "$1");
  if (r = fmt.match(/^(0*)\.(#*)$/)) {
    return sign + rnd(aval, r[2].length).replace(/\.(\d*[1-9])0*$/, ".$1").replace(/^(-?\d*)$/, "$1.").replace(/^0\./, r[1].length ? "0." : ".");
  }
  if (r = fmt.match(/^#{1,3},##0(\.?)$/)) return sign + commaify(pad0r(aval, 0));
  if (r = fmt.match(/^#,##0\.([#0]*0)$/)) {
    return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify("" + (Math.floor(val) + carry(val, r[1].length))) + "." + pad0(dec(val, r[1].length), r[1].length);
  }
  if (r = fmt.match(/^#,#*,#0/)) return write_num_flt(type, fmt.replace(/^#,#*,/, ""), val);
  if (r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) {
    o = _strrev(write_num_flt(type, fmt.replace(/[\\-]/g, ""), val));
    ri = 0;
    return _strrev(_strrev(fmt.replace(/\\/g, "")).replace(/[0#]/g, function (x) {
      return ri < o.length ? o.charAt(ri++) : x === '0' ? '0' : "";
    }));
  }
  if (fmt.match(phone)) {
    o = write_num_flt(type, "##########", val);
    return "(" + o.substr(0, 3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
  }
  var oa = "";
  if (r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) {
    ri = Math.min(/*::String(*/r[4] /*::)*/.length, 7);
    ff = SSF_frac(aval, Math.pow(10, ri) - 1, false);
    o = "" + sign;
    oa = write_num("n", /*::String(*/r[1] /*::)*/, ff[1]);
    if (oa.charAt(oa.length - 1) == " ") oa = oa.substr(0, oa.length - 1) + "0";
    o += oa + /*::String(*/r[2] /*::)*/ + "/" + /*::String(*/r[3] /*::)*/;
    oa = rpad_(ff[2], ri);
    if (oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length - oa.length)) + oa;
    o += oa;
    return o;
  }
  if (r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) {
    ri = Math.min(Math.max(r[1].length, r[4].length), 7);
    ff = SSF_frac(aval, Math.pow(10, ri) - 1, true);
    return sign + (ff[0] || (ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1], ri) + r[2] + "/" + r[3] + rpad_(ff[2], ri) : fill(" ", 2 * ri + 1 + r[2].length + r[3].length));
  }
  if (r = fmt.match(/^[#0?]+$/)) {
    o = pad0r(val, 0);
    if (fmt.length <= o.length) return o;
    return hashq(fmt.substr(0, fmt.length - o.length)) + o;
  }
  if (r = fmt.match(/^([#0?]+)\.([#0]+)$/)) {
    o = "" + val.toFixed(Math.min(r[2].length, 10)).replace(/([^0])0+$/, "$1");
    ri = o.indexOf(".");
    var lres = fmt.indexOf(".") - ri,
      rres = fmt.length - o.length - lres;
    return hashq(fmt.substr(0, lres) + o + fmt.substr(fmt.length - rres));
  }
  if (r = fmt.match(/^00,000\.([#0]*0)$/)) {
    ri = dec(val, r[1].length);
    return val < 0 ? "-" + write_num_flt(type, fmt, -val) : commaify(flr(val)).replace(/^\d,\d{3}$/, "0$&").replace(/^\d*$/, function ($$) {
      return "00," + ($$.length < 3 ? pad0(0, 3 - $$.length) : "") + $$;
    }) + "." + pad0(ri, r[1].length);
  }
  switch (fmt) {
    case "###,##0.00":
      return write_num_flt(type, "#,##0.00", val);
    case "###,###":
    case "##,###":
    case "#,###":
      var x = commaify(pad0r(aval, 0));
      return x !== "0" ? sign + x : "";
    case "###,###.00":
      return write_num_flt(type, "###,##0.00", val).replace(/^0\./, ".");
    case "#,###.00":
      return write_num_flt(type, "#,##0.00", val).replace(/^0\./, ".");
    default:
  }
  throw new Error("unsupported format |" + fmt + "|");
}
function write_num_cm2(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  var idx = fmt.length - 1;
  while (fmt.charCodeAt(idx - 1) === 44) --idx;
  return write_num(type, fmt.substr(0, idx), val / Math.pow(10, 3 * (fmt.length - idx)));
}
function write_num_pct2(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  var sfmt = fmt.replace(pct1, ""),
    mul = fmt.length - sfmt.length;
  return write_num(type, sfmt, val * Math.pow(10, 2 * mul)) + fill("%", mul);
}
function write_num_exp2(fmt /*:string*/, val /*:number*/) /*:string*/{
  var o /*:string*/;
  var idx = fmt.indexOf("E") - fmt.indexOf(".") - 1;
  if (fmt.match(/^#+0.0E\+0$/)) {
    if (val == 0) return "0.0E+0";else if (val < 0) return "-" + write_num_exp2(fmt, -val);
    var period = fmt.indexOf(".");
    if (period === -1) period = fmt.indexOf('E');
    var ee = Math.floor(Math.log(val) * Math.LOG10E) % period;
    if (ee < 0) ee += period;
    o = (val / Math.pow(10, ee)).toPrecision(idx + 1 + (period + ee) % period);
    if (!o.match(/[Ee]/)) {
      var fakee = Math.floor(Math.log(val) * Math.LOG10E);
      if (o.indexOf(".") === -1) o = o.charAt(0) + "." + o.substr(1) + "E+" + (fakee - o.length + ee);else o += "E+" + (fakee - ee);
      o = o.replace(/\+-/, "-");
    }
    o = o.replace(/^([+-]?)(\d*)\.(\d*)[Ee]/, function ($$, $1, $2, $3) {
      return $1 + $2 + $3.substr(0, (period + ee) % period) + "." + $3.substr(ee) + "E";
    });
  } else o = val.toExponential(idx);
  if (fmt.match(/E\+00$/) && o.match(/e[+-]\d$/)) o = o.substr(0, o.length - 1) + "0" + o.charAt(o.length - 1);
  if (fmt.match(/E\-/) && o.match(/e\+/)) o = o.replace(/e\+/, "e");
  return o.replace("e", "E");
}
function write_num_int(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  if (type.charCodeAt(0) === 40 && !fmt.match(closeparen)) {
    var ffmt = fmt.replace(/\( */, "").replace(/ \)/, "").replace(/\)/, "");
    if (val >= 0) return write_num_int('n', ffmt, val);
    return '(' + write_num_int('n', ffmt, -val) + ')';
  }
  if (fmt.charCodeAt(fmt.length - 1) === 44) return write_num_cm2(type, fmt, val);
  if (fmt.indexOf('%') !== -1) return write_num_pct2(type, fmt, val);
  if (fmt.indexOf('E') !== -1) return write_num_exp2(fmt, val);
  if (fmt.charCodeAt(0) === 36) return "$" + write_num_int(type, fmt.substr(fmt.charAt(1) == ' ' ? 2 : 1), val);
  var o;
  var r /*:?Array<string>*/,
    ri,
    ff,
    aval = Math.abs(val),
    sign = val < 0 ? "-" : "";
  if (fmt.match(/^00+$/)) return sign + pad0(aval, fmt.length);
  if (fmt.match(/^[#?]+$/)) {
    o = "" + val;
    if (val === 0) o = "";
    return o.length > fmt.length ? o : hashq(fmt.substr(0, fmt.length - o.length)) + o;
  }
  if (r = fmt.match(frac1)) return write_num_f2(r, aval, sign);
  if (fmt.match(/^#+0+$/)) return sign + pad0(aval, fmt.length - fmt.indexOf("0"));
  if (r = fmt.match(dec1)) {
    /*:: if(!Array.isArray(r)) throw new Error("unreachable"); */
    o = ("" + val).replace(/^([^\.]+)$/, "$1." + hashq(r[1])).replace(/\.$/, "." + hashq(r[1]));
    o = o.replace(/\.(\d*)$/, function ($$, $1) {
      /*:: if(!Array.isArray(r)) throw new Error("unreachable"); */
      return "." + $1 + fill("0", hashq(r[1]).length - $1.length);
    });
    return fmt.indexOf("0.") !== -1 ? o : o.replace(/^0\./, ".");
  }
  fmt = fmt.replace(/^#+([0.])/, "$1");
  if (r = fmt.match(/^(0*)\.(#*)$/)) {
    return sign + ("" + aval).replace(/\.(\d*[1-9])0*$/, ".$1").replace(/^(-?\d*)$/, "$1.").replace(/^0\./, r[1].length ? "0." : ".");
  }
  if (r = fmt.match(/^#{1,3},##0(\.?)$/)) return sign + commaify("" + aval);
  if (r = fmt.match(/^#,##0\.([#0]*0)$/)) {
    return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify("" + val) + "." + fill('0', r[1].length);
  }
  if (r = fmt.match(/^#,#*,#0/)) return write_num_int(type, fmt.replace(/^#,#*,/, ""), val);
  if (r = fmt.match(/^([0#]+)(\\?-([0#]+))+$/)) {
    o = _strrev(write_num_int(type, fmt.replace(/[\\-]/g, ""), val));
    ri = 0;
    return _strrev(_strrev(fmt.replace(/\\/g, "")).replace(/[0#]/g, function (x) {
      return ri < o.length ? o.charAt(ri++) : x === '0' ? '0' : "";
    }));
  }
  if (fmt.match(phone)) {
    o = write_num_int(type, "##########", val);
    return "(" + o.substr(0, 3) + ") " + o.substr(3, 3) + "-" + o.substr(6);
  }
  var oa = "";
  if (r = fmt.match(/^([#0?]+)( ?)\/( ?)([#0?]+)/)) {
    ri = Math.min(/*::String(*/r[4] /*::)*/.length, 7);
    ff = SSF_frac(aval, Math.pow(10, ri) - 1, false);
    o = "" + sign;
    oa = write_num("n", /*::String(*/r[1] /*::)*/, ff[1]);
    if (oa.charAt(oa.length - 1) == " ") oa = oa.substr(0, oa.length - 1) + "0";
    o += oa + /*::String(*/r[2] /*::)*/ + "/" + /*::String(*/r[3] /*::)*/;
    oa = rpad_(ff[2], ri);
    if (oa.length < r[4].length) oa = hashq(r[4].substr(r[4].length - oa.length)) + oa;
    o += oa;
    return o;
  }
  if (r = fmt.match(/^# ([#0?]+)( ?)\/( ?)([#0?]+)/)) {
    ri = Math.min(Math.max(r[1].length, r[4].length), 7);
    ff = SSF_frac(aval, Math.pow(10, ri) - 1, true);
    return sign + (ff[0] || (ff[1] ? "" : "0")) + " " + (ff[1] ? pad_(ff[1], ri) + r[2] + "/" + r[3] + rpad_(ff[2], ri) : fill(" ", 2 * ri + 1 + r[2].length + r[3].length));
  }
  if (r = fmt.match(/^[#0?]+$/)) {
    o = "" + val;
    if (fmt.length <= o.length) return o;
    return hashq(fmt.substr(0, fmt.length - o.length)) + o;
  }
  if (r = fmt.match(/^([#0]+)\.([#0]+)$/)) {
    o = "" + val.toFixed(Math.min(r[2].length, 10)).replace(/([^0])0+$/, "$1");
    ri = o.indexOf(".");
    var lres = fmt.indexOf(".") - ri,
      rres = fmt.length - o.length - lres;
    return hashq(fmt.substr(0, lres) + o + fmt.substr(fmt.length - rres));
  }
  if (r = fmt.match(/^00,000\.([#0]*0)$/)) {
    return val < 0 ? "-" + write_num_int(type, fmt, -val) : commaify("" + val).replace(/^\d,\d{3}$/, "0$&").replace(/^\d*$/, function ($$) {
      return "00," + ($$.length < 3 ? pad0(0, 3 - $$.length) : "") + $$;
    }) + "." + pad0(0, r[1].length);
  }
  switch (fmt) {
    case "###,###":
    case "##,###":
    case "#,###":
      var x = commaify("" + aval);
      return x !== "0" ? sign + x : "";
    default:
      if (fmt.match(/\.[0#?]*$/)) return write_num_int(type, fmt.slice(0, fmt.lastIndexOf(".")), val) + hashq(fmt.slice(fmt.lastIndexOf(".")));
  }
  throw new Error("unsupported format |" + fmt + "|");
}
function write_num(type /*:string*/, fmt /*:string*/, val /*:number*/) /*:string*/{
  return (val | 0) === val ? write_num_int(type, fmt, val) : write_num_flt(type, fmt, val);
}
function SSF_split_fmt(fmt /*:string*/) /*:Array<string>*/{
  var out /*:Array<string>*/ = [];
  var in_str = false /*, cc*/;
  for (var i = 0, j = 0; i < fmt.length; ++i) switch ((/*cc=*/fmt.charCodeAt(i))) {
    case 34:
      /* '"' */
      in_str = !in_str;
      break;
    case 95:
    case 42:
    case 92:
      /* '_' '*' '\\' */
      ++i;
      break;
    case 59:
      /* ';' */
      out[out.length] = fmt.substr(j, i - j);
      j = i + 1;
  }
  out[out.length] = fmt.substr(j);
  if (in_str === true) throw new Error("Format |" + fmt + "| unterminated string ");
  return out;
}
var SSF_abstime = /\[[HhMmSs\u0E0A\u0E19\u0E17]*\]/;
function fmt_is_date(fmt /*:string*/) /*:boolean*/{
  var i = 0,
    /*cc = 0,*/c = "",
    o = "";
  while (i < fmt.length) {
    switch (c = fmt.charAt(i)) {
      case 'G':
        if (SSF_isgeneral(fmt, i)) i += 6;
        i++;
        break;
      case '"':
        for (; (/*cc=*/fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) {/*empty*/}
        ++i;
        break;
      case '\\':
        i += 2;
        break;
      case '_':
        i += 2;
        break;
      case '@':
        ++i;
        break;
      case 'B':
      case 'b':
        if (fmt.charAt(i + 1) === "1" || fmt.charAt(i + 1) === "2") return true;
      /* falls through */
      case 'M':
      case 'D':
      case 'Y':
      case 'H':
      case 'S':
      case 'E':
      /* falls through */
      case 'm':
      case 'd':
      case 'y':
      case 'h':
      case 's':
      case 'e':
      case 'g':
        return true;
      case 'A':
      case 'a':
      case '上':
        if (fmt.substr(i, 3).toUpperCase() === "A/P") return true;
        if (fmt.substr(i, 5).toUpperCase() === "AM/PM") return true;
        if (fmt.substr(i, 5).toUpperCase() === "上午/下午") return true;
        ++i;
        break;
      case '[':
        o = c;
        while (fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);
        if (o.match(SSF_abstime)) return true;
        break;
      case '.':
      /* falls through */
      case '0':
      case '#':
        while (i < fmt.length && ("0#?.,E+-%".indexOf(c = fmt.charAt(++i)) > -1 || c == '\\' && fmt.charAt(i + 1) == "-" && "0#".indexOf(fmt.charAt(i + 2)) > -1)) {/* empty */}
        break;
      case '?':
        while (fmt.charAt(++i) === c) {/* empty */}
        break;
      case '*':
        ++i;
        if (fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i;
        break;
      case '(':
      case ')':
        ++i;
        break;
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        while (i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) {/* empty */}
        break;
      case ' ':
        ++i;
        break;
      default:
        ++i;
        break;
    }
  }
  return false;
}
function eval_fmt(fmt /*:string*/, v /*:any*/, opts /*:any*/, flen /*:number*/) {
  var out = [],
    o = "",
    i = 0,
    c = "",
    lst = 't',
    dt,
    j,
    cc;
  var hr = 'H';
  /* Tokenize */
  while (i < fmt.length) {
    switch (c = fmt.charAt(i)) {
      case 'G':
        /* General */
        if (!SSF_isgeneral(fmt, i)) throw new Error('unrecognized character ' + c + ' in ' + fmt);
        out[out.length] = {
          t: 'G',
          v: 'General'
        };
        i += 7;
        break;
      case '"':
        /* Literal text */
        for (o = ""; (cc = fmt.charCodeAt(++i)) !== 34 && i < fmt.length;) o += String.fromCharCode(cc);
        out[out.length] = {
          t: 't',
          v: o
        };
        ++i;
        break;
      case '\\':
        var w = fmt.charAt(++i),
          t = w === "(" || w === ")" ? w : 't';
        out[out.length] = {
          t: t,
          v: w
        };
        ++i;
        break;
      case '_':
        out[out.length] = {
          t: 't',
          v: " "
        };
        i += 2;
        break;
      case '@':
        /* Text Placeholder */
        out[out.length] = {
          t: 'T',
          v: v
        };
        ++i;
        break;
      case 'B':
      case 'b':
        if (fmt.charAt(i + 1) === "1" || fmt.charAt(i + 1) === "2") {
          if (dt == null) {
            dt = SSF_parse_date_code(v, opts, fmt.charAt(i + 1) === "2");
            if (dt == null) return "";
          }
          out[out.length] = {
            t: 'X',
            v: fmt.substr(i, 2)
          };
          lst = c;
          i += 2;
          break;
        }
      /* falls through */
      case 'M':
      case 'D':
      case 'Y':
      case 'H':
      case 'S':
      case 'E':
        c = c.toLowerCase();
      /* falls through */
      case 'm':
      case 'd':
      case 'y':
      case 'h':
      case 's':
      case 'e':
      case 'g':
        if (v < 0) return "";
        if (dt == null) {
          dt = SSF_parse_date_code(v, opts);
          if (dt == null) return "";
        }
        o = c;
        while (++i < fmt.length && fmt.charAt(i).toLowerCase() === c) o += c;
        if (c === 'm' && lst.toLowerCase() === 'h') c = 'M';
        if (c === 'h') c = hr;
        out[out.length] = {
          t: c,
          v: o
        };
        lst = c;
        break;
      case 'A':
      case 'a':
      case '上':
        var q = {
          t: c,
          v: c
        };
        if (dt == null) dt = SSF_parse_date_code(v, opts);
        if (fmt.substr(i, 3).toUpperCase() === "A/P") {
          if (dt != null) q.v = dt.H >= 12 ? "P" : "A";
          q.t = 'T';
          hr = 'h';
          i += 3;
        } else if (fmt.substr(i, 5).toUpperCase() === "AM/PM") {
          if (dt != null) q.v = dt.H >= 12 ? "PM" : "AM";
          q.t = 'T';
          i += 5;
          hr = 'h';
        } else if (fmt.substr(i, 5).toUpperCase() === "上午/下午") {
          if (dt != null) q.v = dt.H >= 12 ? "下午" : "上午";
          q.t = 'T';
          i += 5;
          hr = 'h';
        } else {
          q.t = "t";
          ++i;
        }
        if (dt == null && q.t === 'T') return "";
        out[out.length] = q;
        lst = c;
        break;
      case '[':
        o = c;
        while (fmt.charAt(i++) !== ']' && i < fmt.length) o += fmt.charAt(i);
        if (o.slice(-1) !== ']') throw 'unterminated "[" block: |' + o + '|';
        if (o.match(SSF_abstime)) {
          if (dt == null) {
            dt = SSF_parse_date_code(v, opts);
            if (dt == null) return "";
          }
          out[out.length] = {
            t: 'Z',
            v: o.toLowerCase()
          };
          lst = o.charAt(1);
        } else if (o.indexOf("$") > -1) {
          o = (o.match(/\$([^-\[\]]*)/) || [])[1] || "$";
          if (!fmt_is_date(fmt)) out[out.length] = {
            t: 't',
            v: o
          };
        }
        break;
      /* Numbers */
      case '.':
        if (dt != null) {
          o = c;
          while (++i < fmt.length && (c = fmt.charAt(i)) === "0") o += c;
          out[out.length] = {
            t: 's',
            v: o
          };
          break;
        }
      /* falls through */
      case '0':
      case '#':
        o = c;
        while (++i < fmt.length && "0#?.,E+-%".indexOf(c = fmt.charAt(i)) > -1) o += c;
        out[out.length] = {
          t: 'n',
          v: o
        };
        break;
      case '?':
        o = c;
        while (fmt.charAt(++i) === c) o += c;
        out[out.length] = {
          t: c,
          v: o
        };
        lst = c;
        break;
      case '*':
        ++i;
        if (fmt.charAt(i) == ' ' || fmt.charAt(i) == '*') ++i;
        break;
      // **
      case '(':
      case ')':
        out[out.length] = {
          t: flen === 1 ? 't' : c,
          v: c
        };
        ++i;
        break;
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        o = c;
        while (i < fmt.length && "0123456789".indexOf(fmt.charAt(++i)) > -1) o += fmt.charAt(i);
        out[out.length] = {
          t: 'D',
          v: o
        };
        break;
      case ' ':
        out[out.length] = {
          t: c,
          v: c
        };
        ++i;
        break;
      case '$':
        out[out.length] = {
          t: 't',
          v: '$'
        };
        ++i;
        break;
      default:
        if (",$-+/():!^&'~{}<>=€acfijklopqrtuvwxzP".indexOf(c) === -1) throw new Error('unrecognized character ' + c + ' in ' + fmt);
        out[out.length] = {
          t: 't',
          v: c
        };
        ++i;
        break;
    }
  }

  /* Scan for date/time parts */
  var bt = 0,
    ss0 = 0,
    ssm;
  for (i = out.length - 1, lst = 't'; i >= 0; --i) {
    switch (out[i].t) {
      case 'h':
      case 'H':
        out[i].t = hr;
        lst = 'h';
        if (bt < 1) bt = 1;
        break;
      case 's':
        if (ssm = out[i].v.match(/\.0+$/)) ss0 = Math.max(ss0, ssm[0].length - 1);
        if (bt < 3) bt = 3;
      /* falls through */
      case 'd':
      case 'y':
      case 'M':
      case 'e':
        lst = out[i].t;
        break;
      case 'm':
        if (lst === 's') {
          out[i].t = 'M';
          if (bt < 2) bt = 2;
        }
        break;
      case 'X':
        /*if(out[i].v === "B2");*/
        break;
      case 'Z':
        if (bt < 1 && out[i].v.match(/[Hh]/)) bt = 1;
        if (bt < 2 && out[i].v.match(/[Mm]/)) bt = 2;
        if (bt < 3 && out[i].v.match(/[Ss]/)) bt = 3;
    }
  }
  /* time rounding depends on presence of minute / second / usec fields */
  switch (bt) {
    case 0:
      break;
    case 1:
      /*::if(!dt) break;*/
      if (dt.u >= 0.5) {
        dt.u = 0;
        ++dt.S;
      }
      if (dt.S >= 60) {
        dt.S = 0;
        ++dt.M;
      }
      if (dt.M >= 60) {
        dt.M = 0;
        ++dt.H;
      }
      break;
    case 2:
      /*::if(!dt) break;*/
      if (dt.u >= 0.5) {
        dt.u = 0;
        ++dt.S;
      }
      if (dt.S >= 60) {
        dt.S = 0;
        ++dt.M;
      }
      break;
  }

  /* replace fields */
  var nstr = "",
    jj;
  for (i = 0; i < out.length; ++i) {
    switch (out[i].t) {
      case 't':
      case 'T':
      case ' ':
      case 'D':
        break;
      case 'X':
        out[i].v = "";
        out[i].t = ";";
        break;
      case 'd':
      case 'm':
      case 'y':
      case 'h':
      case 'H':
      case 'M':
      case 's':
      case 'e':
      case 'b':
      case 'Z':
        /*::if(!dt) throw "unreachable"; */
        out[i].v = SSF_write_date(out[i].t.charCodeAt(0), out[i].v, dt, ss0);
        out[i].t = 't';
        break;
      case 'n':
      case '?':
        jj = i + 1;
        while (out[jj] != null && ((c = out[jj].t) === "?" || c === "D" || (c === " " || c === "t") && out[jj + 1] != null && (out[jj + 1].t === '?' || out[jj + 1].t === "t" && out[jj + 1].v === '/') || out[i].t === '(' && (c === ' ' || c === 'n' || c === ')') || c === 't' && (out[jj].v === '/' || out[jj].v === ' ' && out[jj + 1] != null && out[jj + 1].t == '?'))) {
          out[i].v += out[jj].v;
          out[jj] = {
            v: "",
            t: ";"
          };
          ++jj;
        }
        nstr += out[i].v;
        i = jj - 1;
        break;
      case 'G':
        out[i].t = 't';
        out[i].v = SSF_general(v, opts);
        break;
    }
  }
  var vv = "",
    myv,
    ostr;
  if (nstr.length > 0) {
    if (nstr.charCodeAt(0) == 40) /* '(' */{
        myv = v < 0 && nstr.charCodeAt(0) === 45 ? -v : v;
        ostr = write_num('n', nstr, myv);
      } else {
      myv = v < 0 && flen > 1 ? -v : v;
      ostr = write_num('n', nstr, myv);
      if (myv < 0 && out[0] && out[0].t == 't') {
        ostr = ostr.substr(1);
        out[0].v = "-" + out[0].v;
      }
    }
    jj = ostr.length - 1;
    var decpt = out.length;
    for (i = 0; i < out.length; ++i) if (out[i] != null && out[i].t != 't' && out[i].v.indexOf(".") > -1) {
      decpt = i;
      break;
    }
    var lasti = out.length;
    if (decpt === out.length && ostr.indexOf("E") === -1) {
      for (i = out.length - 1; i >= 0; --i) {
        if (out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
        if (jj >= out[i].v.length - 1) {
          jj -= out[i].v.length;
          out[i].v = ostr.substr(jj + 1, out[i].v.length);
        } else if (jj < 0) out[i].v = "";else {
          out[i].v = ostr.substr(0, jj + 1);
          jj = -1;
        }
        out[i].t = 't';
        lasti = i;
      }
      if (jj >= 0 && lasti < out.length) out[lasti].v = ostr.substr(0, jj + 1) + out[lasti].v;
    } else if (decpt !== out.length && ostr.indexOf("E") === -1) {
      jj = ostr.indexOf(".") - 1;
      for (i = decpt; i >= 0; --i) {
        if (out[i] == null || 'n?'.indexOf(out[i].t) === -1) continue;
        j = out[i].v.indexOf(".") > -1 && i === decpt ? out[i].v.indexOf(".") - 1 : out[i].v.length - 1;
        vv = out[i].v.substr(j + 1);
        for (; j >= 0; --j) {
          if (jj >= 0 && (out[i].v.charAt(j) === "0" || out[i].v.charAt(j) === "#")) vv = ostr.charAt(jj--) + vv;
        }
        out[i].v = vv;
        out[i].t = 't';
        lasti = i;
      }
      if (jj >= 0 && lasti < out.length) out[lasti].v = ostr.substr(0, jj + 1) + out[lasti].v;
      jj = ostr.indexOf(".") + 1;
      for (i = decpt; i < out.length; ++i) {
        if (out[i] == null || 'n?('.indexOf(out[i].t) === -1 && i !== decpt) continue;
        j = out[i].v.indexOf(".") > -1 && i === decpt ? out[i].v.indexOf(".") + 1 : 0;
        vv = out[i].v.substr(0, j);
        for (; j < out[i].v.length; ++j) {
          if (jj < ostr.length) vv += ostr.charAt(jj++);
        }
        out[i].v = vv;
        out[i].t = 't';
        lasti = i;
      }
    }
  }
  for (i = 0; i < out.length; ++i) if (out[i] != null && 'n?'.indexOf(out[i].t) > -1) {
    myv = flen > 1 && v < 0 && i > 0 && out[i - 1].v === "-" ? -v : v;
    out[i].v = write_num(out[i].t, out[i].v, myv);
    out[i].t = 't';
  }
  var retval = "";
  for (i = 0; i !== out.length; ++i) if (out[i] != null) retval += out[i].v;
  return retval;
}
var cfregex2 = /\[(=|>[=]?|<[>=]?)(-?\d+(?:\.\d*)?)\]/;
function chkcond(v, rr) {
  if (rr == null) return false;
  var thresh = parseFloat(rr[2]);
  switch (rr[1]) {
    case "=":
      if (v == thresh) return true;
      break;
    case ">":
      if (v > thresh) return true;
      break;
    case "<":
      if (v < thresh) return true;
      break;
    case "<>":
      if (v != thresh) return true;
      break;
    case ">=":
      if (v >= thresh) return true;
      break;
    case "<=":
      if (v <= thresh) return true;
      break;
  }
  return false;
}
function choose_fmt(f /*:string*/, v /*:any*/) {
  var fmt = SSF_split_fmt(f);
  var l = fmt.length,
    lat = fmt[l - 1].indexOf("@");
  if (l < 4 && lat > -1) --l;
  if (fmt.length > 4) throw new Error("cannot find right format for |" + fmt.join("|") + "|");
  if (typeof v !== "number") return [4, fmt.length === 4 || lat > -1 ? fmt[fmt.length - 1] : "@"];
  switch (fmt.length) {
    case 1:
      fmt = lat > -1 ? ["General", "General", "General", fmt[0]] : [fmt[0], fmt[0], fmt[0], "@"];
      break;
    case 2:
      fmt = lat > -1 ? [fmt[0], fmt[0], fmt[0], fmt[1]] : [fmt[0], fmt[1], fmt[0], "@"];
      break;
    case 3:
      fmt = lat > -1 ? [fmt[0], fmt[1], fmt[0], fmt[2]] : [fmt[0], fmt[1], fmt[2], "@"];
      break;
    case 4:
      break;
  }
  var ff = v > 0 ? fmt[0] : v < 0 ? fmt[1] : fmt[2];
  if (fmt[0].indexOf("[") === -1 && fmt[1].indexOf("[") === -1) return [l, ff];
  if (fmt[0].match(/\[[=<>]/) != null || fmt[1].match(/\[[=<>]/) != null) {
    var m1 = fmt[0].match(cfregex2);
    var m2 = fmt[1].match(cfregex2);
    return chkcond(v, m1) ? [l, fmt[0]] : chkcond(v, m2) ? [l, fmt[1]] : [l, fmt[m1 != null && m2 != null ? 2 : 1]];
  }
  return [l, ff];
}
function SSF_format(fmt /*:string|number*/, v /*:any*/, o /*:?any*/) {
  if (o == null) o = {};
  var sfmt = "";
  switch (typeof fmt) {
    case "string":
      if (fmt == "m/d/yy" && o.dateNF) sfmt = o.dateNF;else sfmt = fmt;
      break;
    case "number":
      if (fmt == 14 && o.dateNF) sfmt = o.dateNF;else sfmt = (o.table != null ? o.table /*:any*/ : table_fmt)[fmt];
      if (sfmt == null) sfmt = o.table && o.table[SSF_default_map[fmt]] || table_fmt[SSF_default_map[fmt]];
      if (sfmt == null) sfmt = SSF_default_str[fmt] || "General";
      break;
  }
  if (SSF_isgeneral(sfmt, 0)) return SSF_general(v, o);
  if (v instanceof Date) v = datenum_local(v, o.date1904);
  var f = choose_fmt(sfmt, v);
  if (SSF_isgeneral(f[1])) return SSF_general(v, o);
  if (v === true) v = "TRUE";else if (v === false) v = "FALSE";else if (v === "" || v == null) return "";
  return eval_fmt(f[1], v, o, f[0]);
}
function SSF_load(fmt /*:string*/, idx /*:?number*/) /*:number*/{
  if (typeof idx != 'number') {
    idx = +idx || -1;
    /*::if(typeof idx != 'number') return 0x188; */
    for (var i = 0; i < 0x0188; ++i) {
      /*::if(typeof idx != 'number') return 0x188; */
      if (table_fmt[i] == undefined) {
        if (idx < 0) idx = i;
        continue;
      }
      if (table_fmt[i] == fmt) {
        idx = i;
        break;
      }
    }
    /*::if(typeof idx != 'number') return 0x188; */
    if (idx < 0) idx = 0x187;
  }
  /*::if(typeof idx != 'number') return 0x188; */
  table_fmt[idx] = fmt;
  return idx;
}
function SSF_load_table(tbl /*:SSFTable*/) /*:void*/{
  for (var i = 0; i != 0x0188; ++i) if (tbl[i] !== undefined) SSF_load(tbl[i], i);
}
function make_ssf() {
  table_fmt = SSF_init_table();
}
var SSF = {
  format: SSF_format,
  load: SSF_load,
  _table: table_fmt,
  load_table: SSF_load_table,
  parse_date_code: SSF_parse_date_code,
  is_date: fmt_is_date,
  get_table: function get_table() {
    return SSF._table = table_fmt;
  }
};
var SSFImplicit /*{[number]:string}*/ = {
  "5": '"$"#,##0_);\\("$"#,##0\\)',
  "6": '"$"#,##0_);[Red]\\("$"#,##0\\)',
  "7": '"$"#,##0.00_);\\("$"#,##0.00\\)',
  "8": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
  "23": 'General',
  "24": 'General',
  "25": 'General',
  "26": 'General',
  "27": 'm/d/yy',
  "28": 'm/d/yy',
  "29": 'm/d/yy',
  "30": 'm/d/yy',
  "31": 'm/d/yy',
  "32": 'h:mm:ss',
  "33": 'h:mm:ss',
  "34": 'h:mm:ss',
  "35": 'h:mm:ss',
  "36": 'm/d/yy',
  "41": '_(* #,##0_);_(* \(#,##0\);_(* "-"_);_(@_)',
  "42": '_("$"* #,##0_);_("$"* \(#,##0\);_("$"* "-"_);_(@_)',
  "43": '_(* #,##0.00_);_(* \(#,##0.00\);_(* "-"??_);_(@_)',
  "44": '_("$"* #,##0.00_);_("$"* \(#,##0.00\);_("$"* "-"??_);_(@_)',
  "50": 'm/d/yy',
  "51": 'm/d/yy',
  "52": 'm/d/yy',
  "53": 'm/d/yy',
  "54": 'm/d/yy',
  "55": 'm/d/yy',
  "56": 'm/d/yy',
  "57": 'm/d/yy',
  "58": 'm/d/yy',
  "59": '0',
  "60": '0.00',
  "61": '#,##0',
  "62": '#,##0.00',
  "63": '"$"#,##0_);\\("$"#,##0\\)',
  "64": '"$"#,##0_);[Red]\\("$"#,##0\\)',
  "65": '"$"#,##0.00_);\\("$"#,##0.00\\)',
  "66": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
  "67": '0%',
  "68": '0.00%',
  "69": '# ?/?',
  "70": '# ??/??',
  "71": 'm/d/yy',
  "72": 'm/d/yy',
  "73": 'd-mmm-yy',
  "74": 'd-mmm',
  "75": 'mmm-yy',
  "76": 'h:mm',
  "77": 'h:mm:ss',
  "78": 'm/d/yy h:mm',
  "79": 'mm:ss',
  "80": '[h]:mm:ss',
  "81": 'mmss.0'
} /*:any*/;

/* dateNF parse TODO: move to SSF */
var dateNFregex = /[dD]+|[mM]+|[yYeE]+|[Hh]+|[Ss]+/g;
function dateNF_regex(dateNF /*:string|number*/) /*:RegExp*/{
  var fmt = typeof dateNF == "number" ? table_fmt[dateNF] : dateNF;
  fmt = fmt.replace(dateNFregex, "(\\d+)");
  return new RegExp("^" + fmt + "$");
}
function dateNF_fix(str /*:string*/, dateNF /*:string*/, match /*:Array<string>*/) /*:string*/{
  var Y = -1,
    m = -1,
    d = -1,
    H = -1,
    M = -1,
    S = -1;
  (dateNF.match(dateNFregex) || []).forEach(function (n, i) {
    var v = parseInt(match[i + 1], 10);
    switch (n.toLowerCase().charAt(0)) {
      case 'y':
        Y = v;
        break;
      case 'd':
        d = v;
        break;
      case 'h':
        H = v;
        break;
      case 's':
        S = v;
        break;
      case 'm':
        if (H >= 0) M = v;else m = v;
        break;
    }
  });
  if (S >= 0 && M == -1 && m >= 0) {
    M = m;
    m = -1;
  }
  var datestr = ("" + (Y >= 0 ? Y : new Date().getFullYear())).slice(-4) + "-" + ("00" + (m >= 1 ? m : 1)).slice(-2) + "-" + ("00" + (d >= 1 ? d : 1)).slice(-2);
  if (datestr.length == 7) datestr = "0" + datestr;
  if (datestr.length == 8) datestr = "20" + datestr;
  var timestr = ("00" + (H >= 0 ? H : 0)).slice(-2) + ":" + ("00" + (M >= 0 ? M : 0)).slice(-2) + ":" + ("00" + (S >= 0 ? S : 0)).slice(-2);
  if (H == -1 && M == -1 && S == -1) return datestr;
  if (Y == -1 && m == -1 && d == -1) return timestr;
  return datestr + "T" + timestr;
}

/*::
declare var ReadShift:any;
declare var CheckField:any;
declare var prep_blob:any;
declare var __readUInt32LE:any;
declare var __readInt32LE:any;
declare var __toBuffer:any;
declare var __utf16le:any;
declare var bconcat:any;
declare var s2a:any;
declare var chr0:any;
declare var chr1:any;
declare var has_buf:boolean;
declare var new_buf:any;
declare var new_raw_buf:any;
declare var new_unsafe_buf:any;
declare var Buffer_from:any;
*/
/* cfb.js (C) 2013-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*jshint eqnull:true */
/*exported CFB */
/*global Uint8Array:false, Uint16Array:false */

/*::
type SectorEntry = {
	name?:string;
	nodes?:Array<number>;
	data:RawBytes;
};
type SectorList = {
	[k:string|number]:SectorEntry;
	name:?string;
	fat_addrs:Array<number>;
	ssz:number;
}
type CFBFiles = {[n:string]:CFBEntry};
*/
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */
/* vim: set ts=2: */
/*exported CRC32 */
var CRC32 = /*#__PURE__*/function () {
  var CRC32 = {};
  CRC32.version = '1.2.0';
  /* see perf/crc32table.js */
  /*global Int32Array */
  function signed_crc_table() /*:any*/{
    var c = 0,
      table /*:Array<number>*/ = new Array(256);
    for (var n = 0; n != 256; ++n) {
      c = n;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      c = c & 1 ? -306674912 ^ c >>> 1 : c >>> 1;
      table[n] = c;
    }
    return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
  }
  var T0 = signed_crc_table();
  function slice_by_16_tables(T) {
    var c = 0,
      v = 0,
      n = 0,
      table /*:Array<number>*/ = typeof Int32Array !== 'undefined' ? new Int32Array(4096) : new Array(4096);
    for (n = 0; n != 256; ++n) table[n] = T[n];
    for (n = 0; n != 256; ++n) {
      v = T[n];
      for (c = 256 + n; c < 4096; c += 256) v = table[c] = v >>> 8 ^ T[v & 0xFF];
    }
    var out = [];
    for (n = 1; n != 16; ++n) out[n - 1] = typeof Int32Array !== 'undefined' ? table.subarray(n * 256, n * 256 + 256) : table.slice(n * 256, n * 256 + 256);
    return out;
  }
  var TT = slice_by_16_tables(T0);
  var T1 = TT[0],
    T2 = TT[1],
    T3 = TT[2],
    T4 = TT[3],
    T5 = TT[4];
  var T6 = TT[5],
    T7 = TT[6],
    T8 = TT[7],
    T9 = TT[8],
    Ta = TT[9];
  var Tb = TT[10],
    Tc = TT[11],
    Td = TT[12],
    Te = TT[13],
    Tf = TT[14];
  function crc32_bstr(bstr /*:string*/, seed /*:number*/) /*:number*/{
    var C = seed /*:: ? 0 : 0 */ ^ -1;
    for (var i = 0, L = bstr.length; i < L;) C = C >>> 8 ^ T0[(C ^ bstr.charCodeAt(i++)) & 0xFF];
    return ~C;
  }
  function crc32_buf(B /*:Uint8Array|Array<number>*/, seed /*:number*/) /*:number*/{
    var C = seed /*:: ? 0 : 0 */ ^ -1,
      L = B.length - 15,
      i = 0;
    for (; i < L;) C = Tf[B[i++] ^ C & 255] ^ Te[B[i++] ^ C >> 8 & 255] ^ Td[B[i++] ^ C >> 16 & 255] ^ Tc[B[i++] ^ C >>> 24] ^ Tb[B[i++]] ^ Ta[B[i++]] ^ T9[B[i++]] ^ T8[B[i++]] ^ T7[B[i++]] ^ T6[B[i++]] ^ T5[B[i++]] ^ T4[B[i++]] ^ T3[B[i++]] ^ T2[B[i++]] ^ T1[B[i++]] ^ T0[B[i++]];
    L += 15;
    while (i < L) C = C >>> 8 ^ T0[(C ^ B[i++]) & 0xFF];
    return ~C;
  }
  function crc32_str(str /*:string*/, seed /*:number*/) /*:number*/{
    var C = seed ^ -1;
    for (var i = 0, L = str.length, c = 0, d = 0; i < L;) {
      c = str.charCodeAt(i++);
      if (c < 0x80) {
        C = C >>> 8 ^ T0[(C ^ c) & 0xFF];
      } else if (c < 0x800) {
        C = C >>> 8 ^ T0[(C ^ (192 | c >> 6 & 31)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 0xFF];
      } else if (c >= 0xD800 && c < 0xE000) {
        c = (c & 1023) + 64;
        d = str.charCodeAt(i++) & 1023;
        C = C >>> 8 ^ T0[(C ^ (240 | c >> 8 & 7)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | c >> 2 & 63)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | d >> 6 & 15 | (c & 3) << 4)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | d & 63)) & 0xFF];
      } else {
        C = C >>> 8 ^ T0[(C ^ (224 | c >> 12 & 15)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | c >> 6 & 63)) & 0xFF];
        C = C >>> 8 ^ T0[(C ^ (128 | c & 63)) & 0xFF];
      }
    }
    return ~C;
  }
  CRC32.table = T0;
  CRC32.bstr = crc32_bstr;
  CRC32.buf = crc32_buf;
  CRC32.str = crc32_str;
  return CRC32;
}();
/* [MS-CFB] v20171201 */
var CFB = /*#__PURE__*/function _CFB() {
  var exports = {};
  exports.version = '1.2.1';
  /* [MS-CFB] 2.6.4 */
  function namecmp(l /*:string*/, r /*:string*/) /*:number*/{
    var L = l.split("/"),
      R = r.split("/");
    for (var i = 0, c = 0, Z = Math.min(L.length, R.length); i < Z; ++i) {
      if (c = L[i].length - R[i].length) return c;
      if (L[i] != R[i]) return L[i] < R[i] ? -1 : 1;
    }
    return L.length - R.length;
  }
  function dirname(p /*:string*/) /*:string*/{
    if (p.charAt(p.length - 1) == "/") return p.slice(0, -1).indexOf("/") === -1 ? p : dirname(p.slice(0, -1));
    var c = p.lastIndexOf("/");
    return c === -1 ? p : p.slice(0, c + 1);
  }
  function filename(p /*:string*/) /*:string*/{
    if (p.charAt(p.length - 1) == "/") return filename(p.slice(0, -1));
    var c = p.lastIndexOf("/");
    return c === -1 ? p : p.slice(c + 1);
  }
  /* -------------------------------------------------------------------------- */
  /* DOS Date format:
     high|YYYYYYYm.mmmddddd.HHHHHMMM.MMMSSSSS|low
     add 1980 to stored year
     stored second should be doubled
  */

  /* write JS date to buf as a DOS date */
  function write_dos_date(buf /*:CFBlob*/, date /*:Date|string*/) {
    if (typeof date === "string") date = new Date(date);
    var hms /*:number*/ = date.getHours();
    hms = hms << 6 | date.getMinutes();
    hms = hms << 5 | date.getSeconds() >>> 1;
    buf.write_shift(2, hms);
    var ymd /*:number*/ = date.getFullYear() - 1980;
    ymd = ymd << 4 | date.getMonth() + 1;
    ymd = ymd << 5 | date.getDate();
    buf.write_shift(2, ymd);
  }

  /* read four bytes from buf and interpret as a DOS date */
  function parse_dos_date(buf /*:CFBlob*/) /*:Date*/{
    var hms = buf.read_shift(2) & 0xFFFF;
    var ymd = buf.read_shift(2) & 0xFFFF;
    var val = new Date();
    var d = ymd & 0x1F;
    ymd >>>= 5;
    var m = ymd & 0x0F;
    ymd >>>= 4;
    val.setMilliseconds(0);
    val.setFullYear(ymd + 1980);
    val.setMonth(m - 1);
    val.setDate(d);
    var S = hms & 0x1F;
    hms >>>= 5;
    var M = hms & 0x3F;
    hms >>>= 6;
    val.setHours(hms);
    val.setMinutes(M);
    val.setSeconds(S << 1);
    return val;
  }
  function parse_extra_field(blob /*:CFBlob*/) /*:any*/{
    prep_blob(blob, 0);
    var o = /*::(*/{} /*:: :any)*/;
    var flags = 0;
    while (blob.l <= blob.length - 4) {
      var type = blob.read_shift(2);
      var sz = blob.read_shift(2),
        tgt = blob.l + sz;
      var p = {};
      switch (type) {
        /* UNIX-style Timestamps */
        case 0x5455:
          {
            flags = blob.read_shift(1);
            if (flags & 1) p.mtime = blob.read_shift(4);
            /* for some reason, CD flag corresponds to LFH */
            if (sz > 5) {
              if (flags & 2) p.atime = blob.read_shift(4);
              if (flags & 4) p.ctime = blob.read_shift(4);
            }
            if (p.mtime) p.mt = new Date(p.mtime * 1000);
          }
          break;
      }
      blob.l = tgt;
      o[type] = p;
    }
    return o;
  }
  var fs /*:: = require('fs'); */;
  function get_fs() {
    return fs || (fs = {});
  }
  function parse(file /*:RawBytes*/, options /*:CFBReadOpts*/) /*:CFBContainer*/{
    if (file[0] == 0x50 && file[1] == 0x4b) return parse_zip(file, options);
    if ((file[0] | 0x20) == 0x6d && (file[1] | 0x20) == 0x69) return parse_mad(file, options);
    if (file.length < 512) throw new Error("CFB file size " + file.length + " < 512");
    var mver = 3;
    var ssz = 512;
    var nmfs = 0; // number of mini FAT sectors
    var difat_sec_cnt = 0;
    var dir_start = 0;
    var minifat_start = 0;
    var difat_start = 0;
    var fat_addrs /*:Array<number>*/ = []; // locations of FAT sectors

    /* [MS-CFB] 2.2 Compound File Header */
    var blob /*:CFBlob*/ = /*::(*/file.slice(0, 512) /*:: :any)*/;
    prep_blob(blob, 0);

    /* major version */
    var mv = check_get_mver(blob);
    mver = mv[0];
    switch (mver) {
      case 3:
        ssz = 512;
        break;
      case 4:
        ssz = 4096;
        break;
      case 0:
        if (mv[1] == 0) return parse_zip(file, options);
      /* falls through */
      default:
        throw new Error("Major Version: Expected 3 or 4 saw " + mver);
    }

    /* reprocess header */
    if (ssz !== 512) {
      blob = /*::(*/file.slice(0, ssz) /*:: :any)*/;
      prep_blob(blob, 28 /* blob.l */);
    }
    /* Save header for final object */
    var header /*:RawBytes*/ = file.slice(0, ssz);
    check_shifts(blob, mver);

    // Number of Directory Sectors
    var dir_cnt /*:number*/ = blob.read_shift(4, 'i');
    if (mver === 3 && dir_cnt !== 0) throw new Error('# Directory Sectors: Expected 0 saw ' + dir_cnt);

    // Number of FAT Sectors
    blob.l += 4;

    // First Directory Sector Location
    dir_start = blob.read_shift(4, 'i');

    // Transaction Signature
    blob.l += 4;

    // Mini Stream Cutoff Size
    blob.chk('00100000', 'Mini Stream Cutoff Size: ');

    // First Mini FAT Sector Location
    minifat_start = blob.read_shift(4, 'i');

    // Number of Mini FAT Sectors
    nmfs = blob.read_shift(4, 'i');

    // First DIFAT sector location
    difat_start = blob.read_shift(4, 'i');

    // Number of DIFAT Sectors
    difat_sec_cnt = blob.read_shift(4, 'i');

    // Grab FAT Sector Locations
    for (var q = -1, j = 0; j < 109; ++j) {
      /* 109 = (512 - blob.l)>>>2; */
      q = blob.read_shift(4, 'i');
      if (q < 0) break;
      fat_addrs[j] = q;
    }

    /** Break the file up into sectors */
    var sectors /*:Array<RawBytes>*/ = sectorify(file, ssz);
    sleuth_fat(difat_start, difat_sec_cnt, sectors, ssz, fat_addrs);

    /** Chains */
    var sector_list /*:SectorList*/ = make_sector_list(sectors, dir_start, fat_addrs, ssz);
    sector_list[dir_start].name = "!Directory";
    if (nmfs > 0 && minifat_start !== ENDOFCHAIN) sector_list[minifat_start].name = "!MiniFAT";
    sector_list[fat_addrs[0]].name = "!FAT";
    sector_list.fat_addrs = fat_addrs;
    sector_list.ssz = ssz;

    /* [MS-CFB] 2.6.1 Compound File Directory Entry */
    var files /*:CFBFiles*/ = {},
      Paths /*:Array<string>*/ = [],
      FileIndex /*:CFBFileIndex*/ = [],
      FullPaths /*:Array<string>*/ = [];
    read_directory(dir_start, sector_list, sectors, Paths, nmfs, files, FileIndex, minifat_start);
    build_full_paths(FileIndex, FullPaths, Paths);
    Paths.shift();
    var o = {
      FileIndex: FileIndex,
      FullPaths: FullPaths
    };

    // $FlowIgnore
    if (options && options.raw) o.raw = {
      header: header,
      sectors: sectors
    };
    return o;
  } // parse

  /* [MS-CFB] 2.2 Compound File Header -- read up to major version */
  function check_get_mver(blob /*:CFBlob*/) /*:[number, number]*/{
    if (blob[blob.l] == 0x50 && blob[blob.l + 1] == 0x4b) return [0, 0];
    // header signature 8
    blob.chk(HEADER_SIGNATURE, 'Header Signature: ');

    // clsid 16
    //blob.chk(HEADER_CLSID, 'CLSID: ');
    blob.l += 16;

    // minor version 2
    var mver /*:number*/ = blob.read_shift(2, 'u');
    return [blob.read_shift(2, 'u'), mver];
  }
  function check_shifts(blob /*:CFBlob*/, mver /*:number*/) /*:void*/{
    var shift = 0x09;

    // Byte Order
    //blob.chk('feff', 'Byte Order: '); // note: some writers put 0xffff
    blob.l += 2;

    // Sector Shift
    switch (shift = blob.read_shift(2)) {
      case 0x09:
        if (mver != 3) throw new Error('Sector Shift: Expected 9 saw ' + shift);
        break;
      case 0x0c:
        if (mver != 4) throw new Error('Sector Shift: Expected 12 saw ' + shift);
        break;
      default:
        throw new Error('Sector Shift: Expected 9 or 12 saw ' + shift);
    }

    // Mini Sector Shift
    blob.chk('0600', 'Mini Sector Shift: ');

    // Reserved
    blob.chk('000000000000', 'Reserved: ');
  }

  /** Break the file up into sectors */
  function sectorify(file /*:RawBytes*/, ssz /*:number*/) /*:Array<RawBytes>*/{
    var nsectors = Math.ceil(file.length / ssz) - 1;
    var sectors /*:Array<RawBytes>*/ = [];
    for (var i = 1; i < nsectors; ++i) sectors[i - 1] = file.slice(i * ssz, (i + 1) * ssz);
    sectors[nsectors - 1] = file.slice(nsectors * ssz);
    return sectors;
  }

  /* [MS-CFB] 2.6.4 Red-Black Tree */
  function build_full_paths(FI /*:CFBFileIndex*/, FP /*:Array<string>*/, Paths /*:Array<string>*/) /*:void*/{
    var i = 0,
      L = 0,
      R = 0,
      C = 0,
      j = 0,
      pl = Paths.length;
    var dad /*:Array<number>*/ = [],
      q /*:Array<number>*/ = [];
    for (; i < pl; ++i) {
      dad[i] = q[i] = i;
      FP[i] = Paths[i];
    }
    for (; j < q.length; ++j) {
      i = q[j];
      L = FI[i].L;
      R = FI[i].R;
      C = FI[i].C;
      if (dad[i] === i) {
        if (L !== -1 /*NOSTREAM*/ && dad[L] !== L) dad[i] = dad[L];
        if (R !== -1 && dad[R] !== R) dad[i] = dad[R];
      }
      if (C !== -1 /*NOSTREAM*/) dad[C] = i;
      if (L !== -1 && i != dad[i]) {
        dad[L] = dad[i];
        if (q.lastIndexOf(L) < j) q.push(L);
      }
      if (R !== -1 && i != dad[i]) {
        dad[R] = dad[i];
        if (q.lastIndexOf(R) < j) q.push(R);
      }
    }
    for (i = 1; i < pl; ++i) if (dad[i] === i) {
      if (R !== -1 /*NOSTREAM*/ && dad[R] !== R) dad[i] = dad[R];else if (L !== -1 && dad[L] !== L) dad[i] = dad[L];
    }
    for (i = 1; i < pl; ++i) {
      if (FI[i].type === 0 /* unknown */) continue;
      j = i;
      if (j != dad[j]) do {
        j = dad[j];
        FP[i] = FP[j] + "/" + FP[i];
      } while (j !== 0 && -1 !== dad[j] && j != dad[j]);
      dad[i] = -1;
    }
    FP[0] += "/";
    for (i = 1; i < pl; ++i) {
      if (FI[i].type !== 2 /* stream */) FP[i] += "/";
    }
  }
  function get_mfat_entry(entry /*:CFBEntry*/, payload /*:RawBytes*/, mini /*:?RawBytes*/) /*:CFBlob*/{
    var start = entry.start,
      size = entry.size;
    //return (payload.slice(start*MSSZ, start*MSSZ + size)/*:any*/);
    var o = [];
    var idx = start;
    while (mini && size > 0 && idx >= 0) {
      o.push(payload.slice(idx * MSSZ, idx * MSSZ + MSSZ));
      size -= MSSZ;
      idx = __readInt32LE(mini, idx * 4);
    }
    if (o.length === 0) return new_buf(0) /*:any*/;
    return bconcat(o).slice(0, entry.size) /*:any*/;
  }

  /** Chase down the rest of the DIFAT chain to build a comprehensive list
      DIFAT chains by storing the next sector number as the last 32 bits */
  function sleuth_fat(idx /*:number*/, cnt /*:number*/, sectors /*:Array<RawBytes>*/, ssz /*:number*/, fat_addrs) /*:void*/{
    var q /*:number*/ = ENDOFCHAIN;
    if (idx === ENDOFCHAIN) {
      if (cnt !== 0) throw new Error("DIFAT chain shorter than expected");
    } else if (idx !== -1 /*FREESECT*/) {
      var sector = sectors[idx],
        m = (ssz >>> 2) - 1;
      if (!sector) return;
      for (var i = 0; i < m; ++i) {
        if ((q = __readInt32LE(sector, i * 4)) === ENDOFCHAIN) break;
        fat_addrs.push(q);
      }
      sleuth_fat(__readInt32LE(sector, ssz - 4), cnt - 1, sectors, ssz, fat_addrs);
    }
  }

  /** Follow the linked list of sectors for a given starting point */
  function get_sector_list(sectors /*:Array<RawBytes>*/, start /*:number*/, fat_addrs /*:Array<number>*/, ssz /*:number*/, chkd /*:?Array<boolean>*/) /*:SectorEntry*/{
    var buf /*:Array<number>*/ = [],
      buf_chain /*:Array<any>*/ = [];
    if (!chkd) chkd = [];
    var modulus = ssz - 1,
      j = 0,
      jj = 0;
    for (j = start; j >= 0;) {
      chkd[j] = true;
      buf[buf.length] = j;
      buf_chain.push(sectors[j]);
      var addr = fat_addrs[Math.floor(j * 4 / ssz)];
      jj = j * 4 & modulus;
      if (ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 " + ssz);
      if (!sectors[addr]) break;
      j = __readInt32LE(sectors[addr], jj);
    }
    return {
      nodes: buf,
      data: __toBuffer([buf_chain])
    };
  }

  /** Chase down the sector linked lists */
  function make_sector_list(sectors /*:Array<RawBytes>*/, dir_start /*:number*/, fat_addrs /*:Array<number>*/, ssz /*:number*/) /*:SectorList*/{
    var sl = sectors.length,
      sector_list /*:SectorList*/ = [] /*:any*/;
    var chkd /*:Array<boolean>*/ = [],
      buf /*:Array<number>*/ = [],
      buf_chain /*:Array<RawBytes>*/ = [];
    var modulus = ssz - 1,
      i = 0,
      j = 0,
      k = 0,
      jj = 0;
    for (i = 0; i < sl; ++i) {
      buf = [] /*:Array<number>*/;
      k = i + dir_start;
      if (k >= sl) k -= sl;
      if (chkd[k]) continue;
      buf_chain = [];
      var seen = [];
      for (j = k; j >= 0;) {
        seen[j] = true;
        chkd[j] = true;
        buf[buf.length] = j;
        buf_chain.push(sectors[j]);
        var addr /*:number*/ = fat_addrs[Math.floor(j * 4 / ssz)];
        jj = j * 4 & modulus;
        if (ssz < 4 + jj) throw new Error("FAT boundary crossed: " + j + " 4 " + ssz);
        if (!sectors[addr]) break;
        j = __readInt32LE(sectors[addr], jj);
        if (seen[j]) break;
      }
      sector_list[k] = {
        nodes: buf,
        data: __toBuffer([buf_chain])
      } /*:SectorEntry*/;
    }
    return sector_list;
  }

  /* [MS-CFB] 2.6.1 Compound File Directory Entry */
  function read_directory(dir_start /*:number*/, sector_list /*:SectorList*/, sectors /*:Array<RawBytes>*/, Paths /*:Array<string>*/, nmfs, files, FileIndex, mini) {
    var minifat_store = 0,
      pl = Paths.length ? 2 : 0;
    var sector = sector_list[dir_start].data;
    var i = 0,
      namelen = 0,
      name;
    for (; i < sector.length; i += 128) {
      var blob /*:CFBlob*/ = /*::(*/sector.slice(i, i + 128) /*:: :any)*/;
      prep_blob(blob, 64);
      namelen = blob.read_shift(2);
      name = __utf16le(blob, 0, namelen - pl);
      Paths.push(name);
      var o /*:CFBEntry*/ = {
        name: name,
        type: blob.read_shift(1),
        color: blob.read_shift(1),
        L: blob.read_shift(4, 'i'),
        R: blob.read_shift(4, 'i'),
        C: blob.read_shift(4, 'i'),
        clsid: blob.read_shift(16),
        state: blob.read_shift(4, 'i'),
        start: 0,
        size: 0
      };
      var ctime /*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
      if (ctime !== 0) o.ct = read_date(blob, blob.l - 8);
      var mtime /*:number*/ = blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2) + blob.read_shift(2);
      if (mtime !== 0) o.mt = read_date(blob, blob.l - 8);
      o.start = blob.read_shift(4, 'i');
      o.size = blob.read_shift(4, 'i');
      if (o.size < 0 && o.start < 0) {
        o.size = o.type = 0;
        o.start = ENDOFCHAIN;
        o.name = "";
      }
      if (o.type === 5) {
        /* root */
        minifat_store = o.start;
        if (nmfs > 0 && minifat_store !== ENDOFCHAIN) sector_list[minifat_store].name = "!StreamData";
        /*minifat_size = o.size;*/
      } else if (o.size >= 4096 /* MSCSZ */) {
        o.storage = 'fat';
        if (sector_list[o.start] === undefined) sector_list[o.start] = get_sector_list(sectors, o.start, sector_list.fat_addrs, sector_list.ssz);
        sector_list[o.start].name = o.name;
        o.content = sector_list[o.start].data.slice(0, o.size) /*:any*/;
      } else {
        o.storage = 'minifat';
        if (o.size < 0) o.size = 0;else if (minifat_store !== ENDOFCHAIN && o.start !== ENDOFCHAIN && sector_list[minifat_store]) {
          o.content = get_mfat_entry(o, sector_list[minifat_store].data, (sector_list[mini] || {}).data);
        }
      }
      if (o.content) prep_blob(o.content, 0);
      files[name] = o;
      FileIndex.push(o);
    }
  }
  function read_date(blob /*:RawBytes|CFBlob*/, offset /*:number*/) /*:Date*/{
    return new Date((__readUInt32LE(blob, offset + 4) / 1e7 * Math.pow(2, 32) + __readUInt32LE(blob, offset) / 1e7 - 11644473600) * 1000);
  }
  function read_file(filename /*:string*/, options /*:CFBReadOpts*/) {
    get_fs();
    return parse(fs.readFileSync(filename), options);
  }
  function read(blob /*:RawBytes|string*/, options /*:CFBReadOpts*/) {
    var type = options && options.type;
    if (!type) {
      if (has_buf && Buffer.isBuffer(blob)) type = "buffer";
    }
    switch (type || "base64") {
      case "file":
        /*:: if(typeof blob !== 'string') throw "Must pass a filename when type='file'"; */return read_file(blob, options);
      case "base64":
        /*:: if(typeof blob !== 'string') throw "Must pass a base64-encoded binary string when type='file'"; */return parse(s2a(Base64_decode(blob)), options);
      case "binary":
        /*:: if(typeof blob !== 'string') throw "Must pass a binary string when type='file'"; */return parse(s2a(blob), options);
    }
    return parse(/*::typeof blob == 'string' ? new Buffer(blob, 'utf-8') : */blob, options);
  }
  function init_cfb(cfb /*:CFBContainer*/, opts /*:?any*/) /*:void*/{
    var o = opts || {},
      root = o.root || "Root Entry";
    if (!cfb.FullPaths) cfb.FullPaths = [];
    if (!cfb.FileIndex) cfb.FileIndex = [];
    if (cfb.FullPaths.length !== cfb.FileIndex.length) throw new Error("inconsistent CFB structure");
    if (cfb.FullPaths.length === 0) {
      cfb.FullPaths[0] = root + "/";
      cfb.FileIndex[0] = {
        name: root,
        type: 5
      } /*:any*/;
    }
    if (o.CLSID) cfb.FileIndex[0].clsid = o.CLSID;
    seed_cfb(cfb);
  }
  function seed_cfb(cfb /*:CFBContainer*/) /*:void*/{
    var nm = "\u0001Sh33tJ5";
    if (CFB.find(cfb, "/" + nm)) return;
    var p = new_buf(4);
    p[0] = 55;
    p[1] = p[3] = 50;
    p[2] = 54;
    cfb.FileIndex.push({
      name: nm,
      type: 2,
      content: p,
      size: 4,
      L: 69,
      R: 69,
      C: 69
    } /*:any*/);
    cfb.FullPaths.push(cfb.FullPaths[0] + nm);
    rebuild_cfb(cfb);
  }
  function rebuild_cfb(cfb /*:CFBContainer*/, f /*:?boolean*/) /*:void*/{
    init_cfb(cfb);
    var gc = false,
      s = false;
    for (var i = cfb.FullPaths.length - 1; i >= 0; --i) {
      var _file = cfb.FileIndex[i];
      switch (_file.type) {
        case 0:
          if (s) gc = true;else {
            cfb.FileIndex.pop();
            cfb.FullPaths.pop();
          }
          break;
        case 1:
        case 2:
        case 5:
          s = true;
          if (isNaN(_file.R * _file.L * _file.C)) gc = true;
          if (_file.R > -1 && _file.L > -1 && _file.R == _file.L) gc = true;
          break;
        default:
          gc = true;
          break;
      }
    }
    if (!gc && !f) return;
    var now = new Date(1987, 1, 19),
      j = 0;
    // Track which names exist
    var fullPaths = Object.create ? Object.create(null) : {};
    var data /*:Array<[string, CFBEntry]>*/ = [];
    for (i = 0; i < cfb.FullPaths.length; ++i) {
      fullPaths[cfb.FullPaths[i]] = true;
      if (cfb.FileIndex[i].type === 0) continue;
      data.push([cfb.FullPaths[i], cfb.FileIndex[i]]);
    }
    for (i = 0; i < data.length; ++i) {
      var dad = dirname(data[i][0]);
      s = fullPaths[dad];
      if (!s) {
        data.push([dad, {
          name: filename(dad).replace("/", ""),
          type: 1,
          clsid: HEADER_CLSID,
          ct: now,
          mt: now,
          content: null
        } /*:any*/]);
        // Add name to set
        fullPaths[dad] = true;
      }
    }
    data.sort(function (x, y) {
      return namecmp(x[0], y[0]);
    });
    cfb.FullPaths = [];
    cfb.FileIndex = [];
    for (i = 0; i < data.length; ++i) {
      cfb.FullPaths[i] = data[i][0];
      cfb.FileIndex[i] = data[i][1];
    }
    for (i = 0; i < data.length; ++i) {
      var elt = cfb.FileIndex[i];
      var nm = cfb.FullPaths[i];
      elt.name = filename(nm).replace("/", "");
      elt.L = elt.R = elt.C = -(elt.color = 1);
      elt.size = elt.content ? elt.content.length : 0;
      elt.start = 0;
      elt.clsid = elt.clsid || HEADER_CLSID;
      if (i === 0) {
        elt.C = data.length > 1 ? 1 : -1;
        elt.size = 0;
        elt.type = 5;
      } else if (nm.slice(-1) == "/") {
        for (j = i + 1; j < data.length; ++j) if (dirname(cfb.FullPaths[j]) == nm) break;
        elt.C = j >= data.length ? -1 : j;
        for (j = i + 1; j < data.length; ++j) if (dirname(cfb.FullPaths[j]) == dirname(nm)) break;
        elt.R = j >= data.length ? -1 : j;
        elt.type = 1;
      } else {
        if (dirname(cfb.FullPaths[i + 1] || "") == dirname(nm)) elt.R = i + 1;
        elt.type = 2;
      }
    }
  }
  function _write(cfb /*:CFBContainer*/, options /*:CFBWriteOpts*/) /*:RawBytes|string*/{
    var _opts = options || {};
    /* MAD is order-sensitive, skip rebuild and sort */
    if (_opts.fileType == 'mad') return write_mad(cfb, _opts);
    rebuild_cfb(cfb);
    switch (_opts.fileType) {
      case 'zip':
        return write_zip(cfb, _opts);
      //case 'mad': return write_mad(cfb, _opts);
    }
    var L = function (cfb /*:CFBContainer*/) /*:Array<number>*/{
      var mini_size = 0,
        fat_size = 0;
      for (var i = 0; i < cfb.FileIndex.length; ++i) {
        var file = cfb.FileIndex[i];
        if (!file.content) continue;
        /*:: if(file.content == null) throw new Error("unreachable"); */
        var flen = file.content.length;
        if (flen > 0) {
          if (flen < 0x1000) mini_size += flen + 0x3F >> 6;else fat_size += flen + 0x01FF >> 9;
        }
      }
      var dir_cnt = cfb.FullPaths.length + 3 >> 2;
      var mini_cnt = mini_size + 7 >> 3;
      var mfat_cnt = mini_size + 0x7F >> 7;
      var fat_base = mini_cnt + fat_size + dir_cnt + mfat_cnt;
      var fat_cnt = fat_base + 0x7F >> 7;
      var difat_cnt = fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt - 109) / 0x7F);
      while (fat_base + fat_cnt + difat_cnt + 0x7F >> 7 > fat_cnt) difat_cnt = ++fat_cnt <= 109 ? 0 : Math.ceil((fat_cnt - 109) / 0x7F);
      var L = [1, difat_cnt, fat_cnt, mfat_cnt, dir_cnt, fat_size, mini_size, 0];
      cfb.FileIndex[0].size = mini_size << 6;
      L[7] = (cfb.FileIndex[0].start = L[0] + L[1] + L[2] + L[3] + L[4] + L[5]) + (L[6] + 7 >> 3);
      return L;
    }(cfb);
    var o = new_buf(L[7] << 9);
    var i = 0,
      T = 0;
    {
      for (i = 0; i < 8; ++i) o.write_shift(1, HEADER_SIG[i]);
      for (i = 0; i < 8; ++i) o.write_shift(2, 0);
      o.write_shift(2, 0x003E);
      o.write_shift(2, 0x0003);
      o.write_shift(2, 0xFFFE);
      o.write_shift(2, 0x0009);
      o.write_shift(2, 0x0006);
      for (i = 0; i < 3; ++i) o.write_shift(2, 0);
      o.write_shift(4, 0);
      o.write_shift(4, L[2]);
      o.write_shift(4, L[0] + L[1] + L[2] + L[3] - 1);
      o.write_shift(4, 0);
      o.write_shift(4, 1 << 12);
      o.write_shift(4, L[3] ? L[0] + L[1] + L[2] - 1 : ENDOFCHAIN);
      o.write_shift(4, L[3]);
      o.write_shift(-4, L[1] ? L[0] - 1 : ENDOFCHAIN);
      o.write_shift(4, L[1]);
      for (i = 0; i < 109; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
    }
    if (L[1]) {
      for (T = 0; T < L[1]; ++T) {
        for (; i < 236 + T * 127; ++i) o.write_shift(-4, i < L[2] ? L[1] + i : -1);
        o.write_shift(-4, T === L[1] - 1 ? ENDOFCHAIN : T + 1);
      }
    }
    var chainit = function (w /*:number*/) /*:void*/{
      for (T += w; i < T - 1; ++i) o.write_shift(-4, i + 1);
      if (w) {
        ++i;
        o.write_shift(-4, ENDOFCHAIN);
      }
    };
    T = i = 0;
    for (T += L[1]; i < T; ++i) o.write_shift(-4, consts.DIFSECT);
    for (T += L[2]; i < T; ++i) o.write_shift(-4, consts.FATSECT);
    chainit(L[3]);
    chainit(L[4]);
    var j /*:number*/ = 0,
      flen /*:number*/ = 0;
    var file /*:CFBEntry*/ = cfb.FileIndex[0];
    for (; j < cfb.FileIndex.length; ++j) {
      file = cfb.FileIndex[j];
      if (!file.content) continue;
      /*:: if(file.content == null) throw new Error("unreachable"); */
      flen = file.content.length;
      if (flen < 0x1000) continue;
      file.start = T;
      chainit(flen + 0x01FF >> 9);
    }
    chainit(L[6] + 7 >> 3);
    while (o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
    T = i = 0;
    for (j = 0; j < cfb.FileIndex.length; ++j) {
      file = cfb.FileIndex[j];
      if (!file.content) continue;
      /*:: if(file.content == null) throw new Error("unreachable"); */
      flen = file.content.length;
      if (!flen || flen >= 0x1000) continue;
      file.start = T;
      chainit(flen + 0x3F >> 6);
    }
    while (o.l & 0x1FF) o.write_shift(-4, consts.ENDOFCHAIN);
    for (i = 0; i < L[4] << 2; ++i) {
      var nm = cfb.FullPaths[i];
      if (!nm || nm.length === 0) {
        for (j = 0; j < 17; ++j) o.write_shift(4, 0);
        for (j = 0; j < 3; ++j) o.write_shift(4, -1);
        for (j = 0; j < 12; ++j) o.write_shift(4, 0);
        continue;
      }
      file = cfb.FileIndex[i];
      if (i === 0) file.start = file.size ? file.start - 1 : ENDOFCHAIN;
      var _nm /*:string*/ = i === 0 && _opts.root || file.name;
      flen = 2 * (_nm.length + 1);
      o.write_shift(64, _nm, "utf16le");
      o.write_shift(2, flen);
      o.write_shift(1, file.type);
      o.write_shift(1, file.color);
      o.write_shift(-4, file.L);
      o.write_shift(-4, file.R);
      o.write_shift(-4, file.C);
      if (!file.clsid) for (j = 0; j < 4; ++j) o.write_shift(4, 0);else o.write_shift(16, file.clsid, "hex");
      o.write_shift(4, file.state || 0);
      o.write_shift(4, 0);
      o.write_shift(4, 0);
      o.write_shift(4, 0);
      o.write_shift(4, 0);
      o.write_shift(4, file.start);
      o.write_shift(4, file.size);
      o.write_shift(4, 0);
    }
    for (i = 1; i < cfb.FileIndex.length; ++i) {
      file = cfb.FileIndex[i];
      /*:: if(!file.content) throw new Error("unreachable"); */
      if (file.size >= 0x1000) {
        o.l = file.start + 1 << 9;
        if (has_buf && Buffer.isBuffer(file.content)) {
          file.content.copy(o, o.l, 0, file.size);
          // o is a 0-filled Buffer so just set next offset
          o.l += file.size + 511 & -512;
        } else {
          for (j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
          for (; j & 0x1FF; ++j) o.write_shift(1, 0);
        }
      }
    }
    for (i = 1; i < cfb.FileIndex.length; ++i) {
      file = cfb.FileIndex[i];
      /*:: if(!file.content) throw new Error("unreachable"); */
      if (file.size > 0 && file.size < 0x1000) {
        if (has_buf && Buffer.isBuffer(file.content)) {
          file.content.copy(o, o.l, 0, file.size);
          // o is a 0-filled Buffer so just set next offset
          o.l += file.size + 63 & -64;
        } else {
          for (j = 0; j < file.size; ++j) o.write_shift(1, file.content[j]);
          for (; j & 0x3F; ++j) o.write_shift(1, 0);
        }
      }
    }
    if (has_buf) {
      o.l = o.length;
    } else {
      // When using Buffer, already 0-filled
      while (o.l < o.length) o.write_shift(1, 0);
    }
    return o;
  }
  /* [MS-CFB] 2.6.4 (Unicode 3.0.1 case conversion) */
  function find(cfb /*:CFBContainer*/, path /*:string*/) /*:?CFBEntry*/{
    var UCFullPaths /*:Array<string>*/ = cfb.FullPaths.map(function (x) {
      return x.toUpperCase();
    });
    var UCPaths /*:Array<string>*/ = UCFullPaths.map(function (x) {
      var y = x.split("/");
      return y[y.length - (x.slice(-1) == "/" ? 2 : 1)];
    });
    var k /*:boolean*/ = false;
    if (path.charCodeAt(0) === 47 /* "/" */) {
      k = true;
      path = UCFullPaths[0].slice(0, -1) + path;
    } else k = path.indexOf("/") !== -1;
    var UCPath /*:string*/ = path.toUpperCase();
    var w /*:number*/ = k === true ? UCFullPaths.indexOf(UCPath) : UCPaths.indexOf(UCPath);
    if (w !== -1) return cfb.FileIndex[w];
    var m = !UCPath.match(chr1);
    UCPath = UCPath.replace(chr0, '');
    if (m) UCPath = UCPath.replace(chr1, '!');
    for (w = 0; w < UCFullPaths.length; ++w) {
      if ((m ? UCFullPaths[w].replace(chr1, '!') : UCFullPaths[w]).replace(chr0, '') == UCPath) return cfb.FileIndex[w];
      if ((m ? UCPaths[w].replace(chr1, '!') : UCPaths[w]).replace(chr0, '') == UCPath) return cfb.FileIndex[w];
    }
    return null;
  }
  /** CFB Constants */
  var MSSZ = 64; /* Mini Sector Size = 1<<6 */
  //var MSCSZ = 4096; /* Mini Stream Cutoff Size */
  /* 2.1 Compound File Sector Numbers and Types */
  var ENDOFCHAIN = -2;
  /* 2.2 Compound File Header */
  var HEADER_SIGNATURE = 'd0cf11e0a1b11ae1';
  var HEADER_SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
  var HEADER_CLSID = '00000000000000000000000000000000';
  var consts = {
    /* 2.1 Compund File Sector Numbers and Types */
    MAXREGSECT: -6,
    DIFSECT: -4,
    FATSECT: -3,
    ENDOFCHAIN: ENDOFCHAIN,
    FREESECT: -1,
    /* 2.2 Compound File Header */
    HEADER_SIGNATURE: HEADER_SIGNATURE,
    HEADER_MINOR_VERSION: '3e00',
    MAXREGSID: -6,
    NOSTREAM: -1,
    HEADER_CLSID: HEADER_CLSID,
    /* 2.6.1 Compound File Directory Entry */
    EntryTypes: ['unknown', 'storage', 'stream', 'lockbytes', 'property', 'root']
  };
  function write_file(cfb /*:CFBContainer*/, filename /*:string*/, options /*:CFBWriteOpts*/) /*:void*/{
    get_fs();
    var o = _write(cfb, options);
    /*:: if(typeof Buffer == 'undefined' || !Buffer.isBuffer(o) || !(o instanceof Buffer)) throw new Error("unreachable"); */
    fs.writeFileSync(filename, o);
  }
  function a2s(o /*:RawBytes*/) /*:string*/{
    var out = new Array(o.length);
    for (var i = 0; i < o.length; ++i) out[i] = String.fromCharCode(o[i]);
    return out.join("");
  }
  function write(cfb /*:CFBContainer*/, options /*:CFBWriteOpts*/) /*:RawBytes|string*/{
    var o = _write(cfb, options);
    switch (options && options.type || "buffer") {
      case "file":
        get_fs();
        fs.writeFileSync(options.filename, o /*:any*/);
        return o;
      case "binary":
        return typeof o == "string" ? o : a2s(o);
      case "base64":
        return Base64_encode(typeof o == "string" ? o : a2s(o));
      case "buffer":
        if (has_buf) return Buffer.isBuffer(o) ? o : Buffer_from(o);
      /* falls through */
      case "array":
        return typeof o == "string" ? s2a(o) : o;
    }
    return o;
  }
  /* node < 8.1 zlib does not expose bytesRead, so default to pure JS */
  var _zlib;
  function use_zlib(zlib) {
    try {
      var InflateRaw = zlib.InflateRaw;
      var InflRaw = new InflateRaw();
      InflRaw._processChunk(new Uint8Array([3, 0]), InflRaw._finishFlushFlag);
      if (InflRaw.bytesRead) _zlib = zlib;else throw new Error("zlib does not expose bytesRead");
    } catch (e) {
      console.error("cannot use native zlib: " + (e.message || e));
    }
  }
  function _inflateRawSync(payload, usz) {
    if (!_zlib) return _inflate(payload, usz);
    var InflateRaw = _zlib.InflateRaw;
    var InflRaw = new InflateRaw();
    var out = InflRaw._processChunk(payload.slice(payload.l), InflRaw._finishFlushFlag);
    payload.l += InflRaw.bytesRead;
    return out;
  }
  function _deflateRawSync(payload) {
    return _zlib ? _zlib.deflateRawSync(payload) : _deflate(payload);
  }
  var CLEN_ORDER = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];

  /*  LEN_ID = [ 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285 ]; */
  var LEN_LN = [3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258];

  /*  DST_ID = [  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,  14,  15,  16,  17,  18,  19,   20,   21,   22,   23,   24,   25,   26,    27,    28,    29 ]; */
  var DST_LN = [1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577];
  function bit_swap_8(n) {
    var t = (n << 1 | n << 11) & 0x22110 | (n << 5 | n << 15) & 0x88440;
    return (t >> 16 | t >> 8 | t) & 0xFF;
  }
  var use_typed_arrays = typeof Uint8Array !== 'undefined';
  var bitswap8 = use_typed_arrays ? new Uint8Array(1 << 8) : [];
  for (var q = 0; q < 1 << 8; ++q) bitswap8[q] = bit_swap_8(q);
  function bit_swap_n(n, b) {
    var rev = bitswap8[n & 0xFF];
    if (b <= 8) return rev >>> 8 - b;
    rev = rev << 8 | bitswap8[n >> 8 & 0xFF];
    if (b <= 16) return rev >>> 16 - b;
    rev = rev << 8 | bitswap8[n >> 16 & 0xFF];
    return rev >>> 24 - b;
  }

  /* helpers for unaligned bit reads */
  function read_bits_2(buf, bl) {
    var w = bl & 7,
      h = bl >>> 3;
    return (buf[h] | (w <= 6 ? 0 : buf[h + 1] << 8)) >>> w & 0x03;
  }
  function read_bits_3(buf, bl) {
    var w = bl & 7,
      h = bl >>> 3;
    return (buf[h] | (w <= 5 ? 0 : buf[h + 1] << 8)) >>> w & 0x07;
  }
  function read_bits_4(buf, bl) {
    var w = bl & 7,
      h = bl >>> 3;
    return (buf[h] | (w <= 4 ? 0 : buf[h + 1] << 8)) >>> w & 0x0F;
  }
  function read_bits_5(buf, bl) {
    var w = bl & 7,
      h = bl >>> 3;
    return (buf[h] | (w <= 3 ? 0 : buf[h + 1] << 8)) >>> w & 0x1F;
  }
  function read_bits_7(buf, bl) {
    var w = bl & 7,
      h = bl >>> 3;
    return (buf[h] | (w <= 1 ? 0 : buf[h + 1] << 8)) >>> w & 0x7F;
  }

  /* works up to n = 3 * 8 + 1 = 25 */
  function read_bits_n(buf, bl, n) {
    var w = bl & 7,
      h = bl >>> 3,
      f = (1 << n) - 1;
    var v = buf[h] >>> w;
    if (n < 8 - w) return v & f;
    v |= buf[h + 1] << 8 - w;
    if (n < 16 - w) return v & f;
    v |= buf[h + 2] << 16 - w;
    if (n < 24 - w) return v & f;
    v |= buf[h + 3] << 24 - w;
    return v & f;
  }

  /* helpers for unaligned bit writes */
  function write_bits_3(buf, bl, v) {
    var w = bl & 7,
      h = bl >>> 3;
    if (w <= 5) buf[h] |= (v & 7) << w;else {
      buf[h] |= v << w & 0xFF;
      buf[h + 1] = (v & 7) >> 8 - w;
    }
    return bl + 3;
  }
  function write_bits_1(buf, bl, v) {
    var w = bl & 7,
      h = bl >>> 3;
    v = (v & 1) << w;
    buf[h] |= v;
    return bl + 1;
  }
  function write_bits_8(buf, bl, v) {
    var w = bl & 7,
      h = bl >>> 3;
    v <<= w;
    buf[h] |= v & 0xFF;
    v >>>= 8;
    buf[h + 1] = v;
    return bl + 8;
  }
  function write_bits_16(buf, bl, v) {
    var w = bl & 7,
      h = bl >>> 3;
    v <<= w;
    buf[h] |= v & 0xFF;
    v >>>= 8;
    buf[h + 1] = v & 0xFF;
    buf[h + 2] = v >>> 8;
    return bl + 16;
  }

  /* until ArrayBuffer#realloc is a thing, fake a realloc */
  function realloc(b, sz /*:number*/) {
    var L = b.length,
      M = 2 * L > sz ? 2 * L : sz + 5,
      i = 0;
    if (L >= sz) return b;
    if (has_buf) {
      var o = new_unsafe_buf(M);
      // $FlowIgnore
      if (b.copy) b.copy(o);else for (; i < b.length; ++i) o[i] = b[i];
      return o;
    } else if (use_typed_arrays) {
      var a = new Uint8Array(M);
      if (a.set) a.set(b);else for (; i < L; ++i) a[i] = b[i];
      return a;
    }
    b.length = M;
    return b;
  }

  /* zero-filled arrays for older browsers */
  function zero_fill_array(n) {
    var o = new Array(n);
    for (var i = 0; i < n; ++i) o[i] = 0;
    return o;
  }

  /* build tree (used for literals and lengths) */
  function build_tree(clens, cmap, MAX /*:number*/) /*:number*/{
    var maxlen = 1,
      w = 0,
      i = 0,
      j = 0,
      ccode = 0,
      L = clens.length;
    var bl_count = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
    for (i = 0; i < 32; ++i) bl_count[i] = 0;
    for (i = L; i < MAX; ++i) clens[i] = 0;
    L = clens.length;
    var ctree = use_typed_arrays ? new Uint16Array(L) : zero_fill_array(L); // []

    /* build code tree */
    for (i = 0; i < L; ++i) {
      bl_count[w = clens[i]]++;
      if (maxlen < w) maxlen = w;
      ctree[i] = 0;
    }
    bl_count[0] = 0;
    for (i = 1; i <= maxlen; ++i) bl_count[i + 16] = ccode = ccode + bl_count[i - 1] << 1;
    for (i = 0; i < L; ++i) {
      ccode = clens[i];
      if (ccode != 0) ctree[i] = bl_count[ccode + 16]++;
    }

    /* cmap[maxlen + 4 bits] = (off&15) + (lit<<4) reverse mapping */
    var cleni = 0;
    for (i = 0; i < L; ++i) {
      cleni = clens[i];
      if (cleni != 0) {
        ccode = bit_swap_n(ctree[i], maxlen) >> maxlen - cleni;
        for (j = (1 << maxlen + 4 - cleni) - 1; j >= 0; --j) cmap[ccode | j << cleni] = cleni & 15 | i << 4;
      }
    }
    return maxlen;
  }

  /* Fixed Huffman */
  var fix_lmap = use_typed_arrays ? new Uint16Array(512) : zero_fill_array(512);
  var fix_dmap = use_typed_arrays ? new Uint16Array(32) : zero_fill_array(32);
  if (!use_typed_arrays) {
    for (var i = 0; i < 512; ++i) fix_lmap[i] = 0;
    for (i = 0; i < 32; ++i) fix_dmap[i] = 0;
  }
  (function () {
    var dlens /*:Array<number>*/ = [];
    var i = 0;
    for (; i < 32; i++) dlens.push(5);
    build_tree(dlens, fix_dmap, 32);
    var clens /*:Array<number>*/ = [];
    i = 0;
    for (; i <= 143; i++) clens.push(8);
    for (; i <= 255; i++) clens.push(9);
    for (; i <= 279; i++) clens.push(7);
    for (; i <= 287; i++) clens.push(8);
    build_tree(clens, fix_lmap, 288);
  })();
  var _deflateRaw = /*#__PURE__*/function _deflateRawIIFE() {
    var DST_LN_RE = use_typed_arrays ? new Uint8Array(0x8000) : [];
    var j = 0,
      k = 0;
    for (; j < DST_LN.length - 1; ++j) {
      for (; k < DST_LN[j + 1]; ++k) DST_LN_RE[k] = j;
    }
    for (; k < 32768; ++k) DST_LN_RE[k] = 29;
    var LEN_LN_RE = use_typed_arrays ? new Uint8Array(0x103) : [];
    for (j = 0, k = 0; j < LEN_LN.length - 1; ++j) {
      for (; k < LEN_LN[j + 1]; ++k) LEN_LN_RE[k] = j;
    }
    function write_stored(data, out) {
      var boff = 0;
      while (boff < data.length) {
        var L = Math.min(0xFFFF, data.length - boff);
        var h = boff + L == data.length;
        out.write_shift(1, +h);
        out.write_shift(2, L);
        out.write_shift(2, ~L & 0xFFFF);
        while (L-- > 0) out[out.l++] = data[boff++];
      }
      return out.l;
    }

    /* Fixed Huffman */
    function write_huff_fixed(data, out) {
      var bl = 0;
      var boff = 0;
      var addrs = use_typed_arrays ? new Uint16Array(0x8000) : [];
      while (boff < data.length) {
        var L = /* data.length - boff; */Math.min(0xFFFF, data.length - boff);

        /* write a stored block for short data */
        if (L < 10) {
          bl = write_bits_3(out, bl, +!!(boff + L == data.length)); // jshint ignore:line
          if (bl & 7) bl += 8 - (bl & 7);
          out.l = bl / 8 | 0;
          out.write_shift(2, L);
          out.write_shift(2, ~L & 0xFFFF);
          while (L-- > 0) out[out.l++] = data[boff++];
          bl = out.l * 8;
          continue;
        }
        bl = write_bits_3(out, bl, +!!(boff + L == data.length) + 2); // jshint ignore:line
        var hash = 0;
        while (L-- > 0) {
          var d = data[boff];
          hash = (hash << 5 ^ d) & 0x7FFF;
          var match = -1,
            mlen = 0;
          if (match = addrs[hash]) {
            match |= boff & ~0x7FFF;
            if (match > boff) match -= 0x8000;
            if (match < boff) while (data[match + mlen] == data[boff + mlen] && mlen < 250) ++mlen;
          }
          if (mlen > 2) {
            /* Copy Token  */
            d = LEN_LN_RE[mlen];
            if (d <= 22) bl = write_bits_8(out, bl, bitswap8[d + 1] >> 1) - 1;else {
              write_bits_8(out, bl, 3);
              bl += 5;
              write_bits_8(out, bl, bitswap8[d - 23] >> 5);
              bl += 3;
            }
            var len_eb = d < 8 ? 0 : d - 4 >> 2;
            if (len_eb > 0) {
              write_bits_16(out, bl, mlen - LEN_LN[d]);
              bl += len_eb;
            }
            d = DST_LN_RE[boff - match];
            bl = write_bits_8(out, bl, bitswap8[d] >> 3);
            bl -= 3;
            var dst_eb = d < 4 ? 0 : d - 2 >> 1;
            if (dst_eb > 0) {
              write_bits_16(out, bl, boff - match - DST_LN[d]);
              bl += dst_eb;
            }
            for (var q = 0; q < mlen; ++q) {
              addrs[hash] = boff & 0x7FFF;
              hash = (hash << 5 ^ data[boff]) & 0x7FFF;
              ++boff;
            }
            L -= mlen - 1;
          } else {
            /* Literal Token */
            if (d <= 143) d = d + 48;else bl = write_bits_1(out, bl, 1);
            bl = write_bits_8(out, bl, bitswap8[d]);
            addrs[hash] = boff & 0x7FFF;
            ++boff;
          }
        }
        bl = write_bits_8(out, bl, 0) - 1;
      }
      out.l = (bl + 7) / 8 | 0;
      return out.l;
    }
    return function _deflateRaw(data, out) {
      if (data.length < 8) return write_stored(data, out);
      return write_huff_fixed(data, out);
    };
  }();
  function _deflate(data) {
    var buf = new_buf(50 + Math.floor(data.length * 1.1));
    var off = _deflateRaw(data, buf);
    return buf.slice(0, off);
  }
  /* modified inflate function also moves original read head */

  var dyn_lmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
  var dyn_dmap = use_typed_arrays ? new Uint16Array(32768) : zero_fill_array(32768);
  var dyn_cmap = use_typed_arrays ? new Uint16Array(128) : zero_fill_array(128);
  var dyn_len_1 = 1,
    dyn_len_2 = 1;

  /* 5.5.3 Expanding Huffman Codes */
  function dyn(data, boff /*:number*/) {
    /* nomenclature from RFC1951 refers to bit values; these are offset by the implicit constant */
    var _HLIT = read_bits_5(data, boff) + 257;
    boff += 5;
    var _HDIST = read_bits_5(data, boff) + 1;
    boff += 5;
    var _HCLEN = read_bits_4(data, boff) + 4;
    boff += 4;
    var w = 0;

    /* grab and store code lengths */
    var clens = use_typed_arrays ? new Uint8Array(19) : zero_fill_array(19);
    var ctree = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    var maxlen = 1;
    var bl_count = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
    var next_code = use_typed_arrays ? new Uint8Array(8) : zero_fill_array(8);
    var L = clens.length; /* 19 */
    for (var i = 0; i < _HCLEN; ++i) {
      clens[CLEN_ORDER[i]] = w = read_bits_3(data, boff);
      if (maxlen < w) maxlen = w;
      bl_count[w]++;
      boff += 3;
    }

    /* build code tree */
    var ccode = 0;
    bl_count[0] = 0;
    for (i = 1; i <= maxlen; ++i) next_code[i] = ccode = ccode + bl_count[i - 1] << 1;
    for (i = 0; i < L; ++i) if ((ccode = clens[i]) != 0) ctree[i] = next_code[ccode]++;
    /* cmap[7 bits from stream] = (off&7) + (lit<<3) */
    var cleni = 0;
    for (i = 0; i < L; ++i) {
      cleni = clens[i];
      if (cleni != 0) {
        ccode = bitswap8[ctree[i]] >> 8 - cleni;
        for (var j = (1 << 7 - cleni) - 1; j >= 0; --j) dyn_cmap[ccode | j << cleni] = cleni & 7 | i << 3;
      }
    }

    /* read literal and dist codes at once */
    var hcodes /*:Array<number>*/ = [];
    maxlen = 1;
    for (; hcodes.length < _HLIT + _HDIST;) {
      ccode = dyn_cmap[read_bits_7(data, boff)];
      boff += ccode & 7;
      switch (ccode >>>= 3) {
        case 16:
          w = 3 + read_bits_2(data, boff);
          boff += 2;
          ccode = hcodes[hcodes.length - 1];
          while (w-- > 0) hcodes.push(ccode);
          break;
        case 17:
          w = 3 + read_bits_3(data, boff);
          boff += 3;
          while (w-- > 0) hcodes.push(0);
          break;
        case 18:
          w = 11 + read_bits_7(data, boff);
          boff += 7;
          while (w-- > 0) hcodes.push(0);
          break;
        default:
          hcodes.push(ccode);
          if (maxlen < ccode) maxlen = ccode;
          break;
      }
    }

    /* build literal / length trees */
    var h1 = hcodes.slice(0, _HLIT),
      h2 = hcodes.slice(_HLIT);
    for (i = _HLIT; i < 286; ++i) h1[i] = 0;
    for (i = _HDIST; i < 30; ++i) h2[i] = 0;
    dyn_len_1 = build_tree(h1, dyn_lmap, 286);
    dyn_len_2 = build_tree(h2, dyn_dmap, 30);
    return boff;
  }

  /* return [ data, bytesRead ] */
  function inflate(data, usz /*:number*/) {
    /* shortcircuit for empty buffer [0x03, 0x00] */
    if (data[0] == 3 && !(data[1] & 0x3)) {
      return [new_raw_buf(usz), 2];
    }

    /* bit offset */
    var boff = 0;

    /* header includes final bit and type bits */
    var header = 0;
    var outbuf = new_unsafe_buf(usz ? usz : 1 << 18);
    var woff = 0;
    var OL = outbuf.length >>> 0;
    var max_len_1 = 0,
      max_len_2 = 0;
    while ((header & 1) == 0) {
      header = read_bits_3(data, boff);
      boff += 3;
      if (header >>> 1 == 0) {
        /* Stored block */
        if (boff & 7) boff += 8 - (boff & 7);
        /* 2 bytes sz, 2 bytes bit inverse */
        var sz = data[boff >>> 3] | data[(boff >>> 3) + 1] << 8;
        boff += 32;
        /* push sz bytes */
        if (sz > 0) {
          if (!usz && OL < woff + sz) {
            outbuf = realloc(outbuf, woff + sz);
            OL = outbuf.length;
          }
          while (sz-- > 0) {
            outbuf[woff++] = data[boff >>> 3];
            boff += 8;
          }
        }
        continue;
      } else if (header >> 1 == 1) {
        /* Fixed Huffman */
        max_len_1 = 9;
        max_len_2 = 5;
      } else {
        /* Dynamic Huffman */
        boff = dyn(data, boff);
        max_len_1 = dyn_len_1;
        max_len_2 = dyn_len_2;
      }
      for (;;) {
        // while(true) is apparently out of vogue in modern JS circles
        if (!usz && OL < woff + 32767) {
          outbuf = realloc(outbuf, woff + 32767);
          OL = outbuf.length;
        }
        /* ingest code and move read head */
        var bits = read_bits_n(data, boff, max_len_1);
        var code = header >>> 1 == 1 ? fix_lmap[bits] : dyn_lmap[bits];
        boff += code & 15;
        code >>>= 4;
        /* 0-255 are literals, 256 is end of block token, 257+ are copy tokens */
        if ((code >>> 8 & 0xFF) === 0) outbuf[woff++] = code;else if (code == 256) break;else {
          code -= 257;
          var len_eb = code < 8 ? 0 : code - 4 >> 2;
          if (len_eb > 5) len_eb = 0;
          var tgt = woff + LEN_LN[code];
          /* length extra bits */
          if (len_eb > 0) {
            tgt += read_bits_n(data, boff, len_eb);
            boff += len_eb;
          }

          /* dist code */
          bits = read_bits_n(data, boff, max_len_2);
          code = header >>> 1 == 1 ? fix_dmap[bits] : dyn_dmap[bits];
          boff += code & 15;
          code >>>= 4;
          var dst_eb = code < 4 ? 0 : code - 2 >> 1;
          var dst = DST_LN[code];
          /* dist extra bits */
          if (dst_eb > 0) {
            dst += read_bits_n(data, boff, dst_eb);
            boff += dst_eb;
          }

          /* in the common case, manual byte copy is faster than TA set / Buffer copy */
          if (!usz && OL < tgt) {
            outbuf = realloc(outbuf, tgt + 100);
            OL = outbuf.length;
          }
          while (woff < tgt) {
            outbuf[woff] = outbuf[woff - dst];
            ++woff;
          }
        }
      }
    }
    if (usz) return [outbuf, boff + 7 >>> 3];
    return [outbuf.slice(0, woff), boff + 7 >>> 3];
  }
  function _inflate(payload, usz) {
    var data = payload.slice(payload.l || 0);
    var out = inflate(data, usz);
    payload.l += out[1];
    return out[0];
  }
  function warn_or_throw(wrn, msg) {
    if (wrn) {
      if (typeof console !== 'undefined') console.error(msg);
    } else throw new Error(msg);
  }
  function parse_zip(file /*:RawBytes*/, options /*:CFBReadOpts*/) /*:CFBContainer*/{
    var blob /*:CFBlob*/ = /*::(*/file /*:: :any)*/;
    prep_blob(blob, 0);
    var FileIndex /*:CFBFileIndex*/ = [],
      FullPaths /*:Array<string>*/ = [];
    var o = {
      FileIndex: FileIndex,
      FullPaths: FullPaths
    };
    init_cfb(o, {
      root: options.root
    });

    /* find end of central directory, start just after signature */
    var i = blob.length - 4;
    while ((blob[i] != 0x50 || blob[i + 1] != 0x4b || blob[i + 2] != 0x05 || blob[i + 3] != 0x06) && i >= 0) --i;
    blob.l = i + 4;

    /* parse end of central directory */
    blob.l += 4;
    var fcnt = blob.read_shift(2);
    blob.l += 6;
    var start_cd = blob.read_shift(4);

    /* parse central directory */
    blob.l = start_cd;
    for (i = 0; i < fcnt; ++i) {
      /* trust local file header instead of CD entry */
      blob.l += 20;
      var csz = blob.read_shift(4);
      var usz = blob.read_shift(4);
      var namelen = blob.read_shift(2);
      var efsz = blob.read_shift(2);
      var fcsz = blob.read_shift(2);
      blob.l += 8;
      var offset = blob.read_shift(4);
      var EF = parse_extra_field(/*::(*/blob.slice(blob.l + namelen, blob.l + namelen + efsz) /*:: :any)*/);
      blob.l += namelen + efsz + fcsz;
      var L = blob.l;
      blob.l = offset + 4;
      parse_local_file(blob, csz, usz, o, EF);
      blob.l = L;
    }
    return o;
  }

  /* head starts just after local file header signature */
  function parse_local_file(blob /*:CFBlob*/, csz /*:number*/, usz /*:number*/, o /*:CFBContainer*/, EF) {
    /* [local file header] */
    blob.l += 2;
    var flags = blob.read_shift(2);
    var meth = blob.read_shift(2);
    var date = parse_dos_date(blob);
    if (flags & 0x2041) throw new Error("Unsupported ZIP encryption");
    var crc32 = blob.read_shift(4);
    var _csz = blob.read_shift(4);
    var _usz = blob.read_shift(4);
    var namelen = blob.read_shift(2);
    var efsz = blob.read_shift(2);

    // TODO: flags & (1<<11) // UTF8
    var name = "";
    for (var i = 0; i < namelen; ++i) name += String.fromCharCode(blob[blob.l++]);
    if (efsz) {
      var ef = parse_extra_field(/*::(*/blob.slice(blob.l, blob.l + efsz) /*:: :any)*/);
      if ((ef[0x5455] || {}).mt) date = ef[0x5455].mt;
      if (((EF || {})[0x5455] || {}).mt) date = EF[0x5455].mt;
    }
    blob.l += efsz;

    /* [encryption header] */

    /* [file data] */
    var data = blob.slice(blob.l, blob.l + _csz);
    switch (meth) {
      case 8:
        data = _inflateRawSync(blob, _usz);
        break;
      case 0:
        break;
      // TODO: scan for magic number
      default:
        throw new Error("Unsupported ZIP Compression method " + meth);
    }

    /* [data descriptor] */
    var wrn = false;
    if (flags & 8) {
      crc32 = blob.read_shift(4);
      if (crc32 == 0x08074b50) {
        crc32 = blob.read_shift(4);
        wrn = true;
      }
      _csz = blob.read_shift(4);
      _usz = blob.read_shift(4);
    }
    if (_csz != csz) warn_or_throw(wrn, "Bad compressed size: " + csz + " != " + _csz);
    if (_usz != usz) warn_or_throw(wrn, "Bad uncompressed size: " + usz + " != " + _usz);
    //var _crc32 = CRC32.buf(data, 0);
    //if((crc32>>0) != (_crc32>>0)) warn_or_throw(wrn, "Bad CRC32 checksum: " + crc32 + " != " + _crc32);
    cfb_add(o, name, data, {
      unsafe: true,
      mt: date
    });
  }
  function write_zip(cfb /*:CFBContainer*/, options /*:CFBWriteOpts*/) /*:RawBytes*/{
    var _opts = options || {};
    var out = [],
      cdirs = [];
    var o /*:CFBlob*/ = new_buf(1);
    var method = _opts.compression ? 8 : 0,
      flags = 0;
    var desc = false;
    if (desc) flags |= 8;
    var i = 0,
      j = 0;
    var start_cd = 0,
      fcnt = 0;
    var root = cfb.FullPaths[0],
      fp = root,
      fi = cfb.FileIndex[0];
    var crcs = [];
    var sz_cd = 0;
    for (i = 1; i < cfb.FullPaths.length; ++i) {
      fp = cfb.FullPaths[i].slice(root.length);
      fi = cfb.FileIndex[i];
      if (!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;
      var start = start_cd;

      /* TODO: CP437 filename */
      var namebuf = new_buf(fp.length);
      for (j = 0; j < fp.length; ++j) namebuf.write_shift(1, fp.charCodeAt(j) & 0x7F);
      namebuf = namebuf.slice(0, namebuf.l);
      crcs[fcnt] = CRC32.buf(/*::((*/fi.content /*::||[]):any)*/, 0);
      var outbuf = fi.content /*::||[]*/;
      if (method == 8) outbuf = _deflateRawSync(outbuf);

      /* local file header */
      o = new_buf(30);
      o.write_shift(4, 0x04034b50);
      o.write_shift(2, 20);
      o.write_shift(2, flags);
      o.write_shift(2, method);
      /* TODO: last mod file time/date */
      if (fi.mt) write_dos_date(o, fi.mt);else o.write_shift(4, 0);
      o.write_shift(-4, flags & 8 ? 0 : crcs[fcnt]);
      o.write_shift(4, flags & 8 ? 0 : outbuf.length);
      o.write_shift(4, flags & 8 ? 0 : /*::(*/fi.content /*::||[])*/.length);
      o.write_shift(2, namebuf.length);
      o.write_shift(2, 0);
      start_cd += o.length;
      out.push(o);
      start_cd += namebuf.length;
      out.push(namebuf);

      /* TODO: extra fields? */

      /* TODO: encryption header ? */

      start_cd += outbuf.length;
      out.push(outbuf);

      /* data descriptor */
      if (flags & 8) {
        o = new_buf(12);
        o.write_shift(-4, crcs[fcnt]);
        o.write_shift(4, outbuf.length);
        o.write_shift(4, /*::(*/fi.content /*::||[])*/.length);
        start_cd += o.l;
        out.push(o);
      }

      /* central directory */
      o = new_buf(46);
      o.write_shift(4, 0x02014b50);
      o.write_shift(2, 0);
      o.write_shift(2, 20);
      o.write_shift(2, flags);
      o.write_shift(2, method);
      o.write_shift(4, 0); /* TODO: last mod file time/date */
      o.write_shift(-4, crcs[fcnt]);
      o.write_shift(4, outbuf.length);
      o.write_shift(4, /*::(*/fi.content /*::||[])*/.length);
      o.write_shift(2, namebuf.length);
      o.write_shift(2, 0);
      o.write_shift(2, 0);
      o.write_shift(2, 0);
      o.write_shift(2, 0);
      o.write_shift(4, 0);
      o.write_shift(4, start);
      sz_cd += o.l;
      cdirs.push(o);
      sz_cd += namebuf.length;
      cdirs.push(namebuf);
      ++fcnt;
    }

    /* end of central directory */
    o = new_buf(22);
    o.write_shift(4, 0x06054b50);
    o.write_shift(2, 0);
    o.write_shift(2, 0);
    o.write_shift(2, fcnt);
    o.write_shift(2, fcnt);
    o.write_shift(4, sz_cd);
    o.write_shift(4, start_cd);
    o.write_shift(2, 0);
    return bconcat([bconcat(out /*:any*/), bconcat(cdirs), o] /*:any*/);
  }
  var ContentTypeMap = {
    "htm": "text/html",
    "xml": "text/xml",
    "gif": "image/gif",
    "jpg": "image/jpeg",
    "png": "image/png",
    "mso": "application/x-mso",
    "thmx": "application/vnd.ms-officetheme",
    "sh33tj5": "application/octet-stream"
  } /*:any*/;
  function get_content_type(fi /*:CFBEntry*/, fp /*:string*/) /*:string*/{
    if (fi.ctype) return fi.ctype;
    var ext = fi.name || "",
      m = ext.match(/\.([^\.]+)$/);
    if (m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
    if (fp) {
      m = (ext = fp).match(/[\.\\]([^\.\\])+$/);
      if (m && ContentTypeMap[m[1]]) return ContentTypeMap[m[1]];
    }
    return "application/octet-stream";
  }

  /* 76 character chunks TODO: intertwine encoding */
  function write_base64_76(bstr /*:string*/) /*:string*/{
    var data = Base64_encode(bstr);
    var o = [];
    for (var i = 0; i < data.length; i += 76) o.push(data.slice(i, i + 76));
    return o.join("\r\n") + "\r\n";
  }

  /*
  Rules for QP:
  	- escape =## applies for all non-display characters and literal "="
  	- space or tab at end of line must be encoded
  	- \r\n newlines can be preserved, but bare \r and \n must be escaped
  	- lines must not exceed 76 characters, use soft breaks =\r\n
  
  TODO: Some files from word appear to write line extensions with bare equals:
  
  ```
  <table class=3DMsoTableGrid border=3D1 cellspacing=3D0 cellpadding=3D0 width=
  ="70%"
  ```
  */
  function write_quoted_printable(text /*:string*/) /*:string*/{
    var encoded = text.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF=]/g, function (c) {
      var w = c.charCodeAt(0).toString(16).toUpperCase();
      return "=" + (w.length == 1 ? "0" + w : w);
    });
    encoded = encoded.replace(/ $/mg, "=20").replace(/\t$/mg, "=09");
    if (encoded.charAt(0) == "\n") encoded = "=0D" + encoded.slice(1);
    encoded = encoded.replace(/\r(?!\n)/mg, "=0D").replace(/\n\n/mg, "\n=0A").replace(/([^\r\n])\n/mg, "$1=0A");
    var o /*:Array<string>*/ = [],
      split = encoded.split("\r\n");
    for (var si = 0; si < split.length; ++si) {
      var str = split[si];
      if (str.length == 0) {
        o.push("");
        continue;
      }
      for (var i = 0; i < str.length;) {
        var end = 76;
        var tmp = str.slice(i, i + end);
        if (tmp.charAt(end - 1) == "=") end--;else if (tmp.charAt(end - 2) == "=") end -= 2;else if (tmp.charAt(end - 3) == "=") end -= 3;
        tmp = str.slice(i, i + end);
        i += end;
        if (i < str.length) tmp += "=";
        o.push(tmp);
      }
    }
    return o.join("\r\n");
  }
  function parse_quoted_printable(data /*:Array<string>*/) /*:RawBytes*/{
    var o = [];

    /* unify long lines */
    for (var di = 0; di < data.length; ++di) {
      var line = data[di];
      while (di <= data.length && line.charAt(line.length - 1) == "=") line = line.slice(0, line.length - 1) + data[++di];
      o.push(line);
    }

    /* decode */
    for (var oi = 0; oi < o.length; ++oi) o[oi] = o[oi].replace(/[=][0-9A-Fa-f]{2}/g, function ($$) {
      return String.fromCharCode(parseInt($$.slice(1), 16));
    });
    return s2a(o.join("\r\n"));
  }
  function parse_mime(cfb /*:CFBContainer*/, data /*:Array<string>*/, root /*:string*/) /*:void*/{
    var fname = "",
      cte = "",
      ctype = "",
      fdata;
    var di = 0;
    for (; di < 10; ++di) {
      var line = data[di];
      if (!line || line.match(/^\s*$/)) break;
      var m = line.match(/^(.*?):\s*([^\s].*)$/);
      if (m) switch (m[1].toLowerCase()) {
        case "content-location":
          fname = m[2].trim();
          break;
        case "content-type":
          ctype = m[2].trim();
          break;
        case "content-transfer-encoding":
          cte = m[2].trim();
          break;
      }
    }
    ++di;
    switch (cte.toLowerCase()) {
      case 'base64':
        fdata = s2a(Base64_decode(data.slice(di).join("")));
        break;
      case 'quoted-printable':
        fdata = parse_quoted_printable(data.slice(di));
        break;
      default:
        throw new Error("Unsupported Content-Transfer-Encoding " + cte);
    }
    var file = cfb_add(cfb, fname.slice(root.length), fdata, {
      unsafe: true
    });
    if (ctype) file.ctype = ctype;
  }
  function parse_mad(file /*:RawBytes*/, options /*:CFBReadOpts*/) /*:CFBContainer*/{
    if (a2s(file.slice(0, 13)).toLowerCase() != "mime-version:") throw new Error("Unsupported MAD header");
    var root = options && options.root || "";
    // $FlowIgnore
    var data = (has_buf && Buffer.isBuffer(file) ? file.toString("binary") : a2s(file)).split("\r\n");
    var di = 0,
      row = "";

    /* if root is not specified, scan for the common prefix */
    for (di = 0; di < data.length; ++di) {
      row = data[di];
      if (!/^Content-Location:/i.test(row)) continue;
      row = row.slice(row.indexOf("file"));
      if (!root) root = row.slice(0, row.lastIndexOf("/") + 1);
      if (row.slice(0, root.length) == root) continue;
      while (root.length > 0) {
        root = root.slice(0, root.length - 1);
        root = root.slice(0, root.lastIndexOf("/") + 1);
        if (row.slice(0, root.length) == root) break;
      }
    }
    var mboundary = (data[1] || "").match(/boundary="(.*?)"/);
    if (!mboundary) throw new Error("MAD cannot find boundary");
    var boundary = "--" + (mboundary[1] || "");
    var FileIndex /*:CFBFileIndex*/ = [],
      FullPaths /*:Array<string>*/ = [];
    var o = {
      FileIndex: FileIndex,
      FullPaths: FullPaths
    };
    init_cfb(o);
    var start_di,
      fcnt = 0;
    for (di = 0; di < data.length; ++di) {
      var line = data[di];
      if (line !== boundary && line !== boundary + "--") continue;
      if (fcnt++) parse_mime(o, data.slice(start_di, di), root);
      start_di = di;
    }
    return o;
  }
  function write_mad(cfb /*:CFBContainer*/, options /*:CFBWriteOpts*/) /*:string*/{
    var opts = options || {};
    var boundary = opts.boundary || "SheetJS";
    boundary = '------=' + boundary;
    var out = ['MIME-Version: 1.0', 'Content-Type: multipart/related; boundary="' + boundary.slice(2) + '"', '', '', ''];
    var root = cfb.FullPaths[0],
      fp = root,
      fi = cfb.FileIndex[0];
    for (var i = 1; i < cfb.FullPaths.length; ++i) {
      fp = cfb.FullPaths[i].slice(root.length);
      fi = cfb.FileIndex[i];
      if (!fi.size || !fi.content || fp == "\u0001Sh33tJ5") continue;

      /* Normalize filename */
      fp = fp.replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7E-\xFF]/g, function (c) {
        return "_x" + c.charCodeAt(0).toString(16) + "_";
      }).replace(/[\u0080-\uFFFF]/g, function (u) {
        return "_u" + u.charCodeAt(0).toString(16) + "_";
      });

      /* Extract content as binary string */
      var ca = fi.content;
      // $FlowIgnore
      var cstr = has_buf && Buffer.isBuffer(ca) ? ca.toString("binary") : a2s(ca);

      /* 4/5 of first 1024 chars ascii -> quoted printable, else base64 */
      var dispcnt = 0,
        L = Math.min(1024, cstr.length),
        cc = 0;
      for (var csl = 0; csl <= L; ++csl) if ((cc = cstr.charCodeAt(csl)) >= 0x20 && cc < 0x80) ++dispcnt;
      var qp = dispcnt >= L * 4 / 5;
      out.push(boundary);
      out.push('Content-Location: ' + (opts.root || 'file:///C:/SheetJS/') + fp);
      out.push('Content-Transfer-Encoding: ' + (qp ? 'quoted-printable' : 'base64'));
      out.push('Content-Type: ' + get_content_type(fi, fp));
      out.push('');
      out.push(qp ? write_quoted_printable(cstr) : write_base64_76(cstr));
    }
    out.push(boundary + '--\r\n');
    return out.join("\r\n");
  }
  function cfb_new(opts /*:?any*/) /*:CFBContainer*/{
    var o /*:CFBContainer*/ = {} /*:any*/;
    init_cfb(o, opts);
    return o;
  }
  function cfb_add(cfb /*:CFBContainer*/, name /*:string*/, content /*:?RawBytes*/, opts /*:?any*/) /*:CFBEntry*/{
    var unsafe = opts && opts.unsafe;
    if (!unsafe) init_cfb(cfb);
    var file = !unsafe && CFB.find(cfb, name);
    if (!file) {
      var fpath /*:string*/ = cfb.FullPaths[0];
      if (name.slice(0, fpath.length) == fpath) fpath = name;else {
        if (fpath.slice(-1) != "/") fpath += "/";
        fpath = (fpath + name).replace("//", "/");
      }
      file = {
        name: filename(name),
        type: 2
      } /*:any*/;
      cfb.FileIndex.push(file);
      cfb.FullPaths.push(fpath);
      if (!unsafe) CFB.utils.cfb_gc(cfb);
    }
    /*:: if(!file) throw new Error("unreachable"); */
    file.content = content /*:any*/;
    file.size = content ? content.length : 0;
    if (opts) {
      if (opts.CLSID) file.clsid = opts.CLSID;
      if (opts.mt) file.mt = opts.mt;
      if (opts.ct) file.ct = opts.ct;
    }
    return file;
  }
  function cfb_del(cfb /*:CFBContainer*/, name /*:string*/) /*:boolean*/{
    init_cfb(cfb);
    var file = CFB.find(cfb, name);
    if (file) for (var j = 0; j < cfb.FileIndex.length; ++j) if (cfb.FileIndex[j] == file) {
      cfb.FileIndex.splice(j, 1);
      cfb.FullPaths.splice(j, 1);
      return true;
    }
    return false;
  }
  function cfb_mov(cfb /*:CFBContainer*/, old_name /*:string*/, new_name /*:string*/) /*:boolean*/{
    init_cfb(cfb);
    var file = CFB.find(cfb, old_name);
    if (file) for (var j = 0; j < cfb.FileIndex.length; ++j) if (cfb.FileIndex[j] == file) {
      cfb.FileIndex[j].name = filename(new_name);
      cfb.FullPaths[j] = new_name;
      return true;
    }
    return false;
  }
  function cfb_gc(cfb /*:CFBContainer*/) /*:void*/{
    rebuild_cfb(cfb, true);
  }
  exports.find = find;
  exports.read = read;
  exports.parse = parse;
  exports.write = write;
  exports.writeFile = write_file;
  exports.utils = {
    cfb_new: cfb_new,
    cfb_add: cfb_add,
    cfb_del: cfb_del,
    cfb_mov: cfb_mov,
    cfb_gc: cfb_gc,
    ReadShift: ReadShift,
    CheckField: CheckField,
    prep_blob: prep_blob,
    bconcat: bconcat,
    use_zlib: use_zlib,
    _deflateRaw: _deflate,
    _inflateRaw: _inflate,
    consts: consts
  };
  return exports;
}();
let _fs = void 0;
function set_fs(fs) {
  _fs = fs;
}


/* normalize data for blob ctor */
function blobify(data) {
  if (typeof data === "string") return s2ab(data);
  if (Array.isArray(data)) return a2u(data);
  return data;
}
/* write or download file */
function write_dl(fname /*:string*/, payload /*:any*/, enc /*:?string*/) {
  /*global IE_SaveFile, Blob, navigator, saveAs, document, File, chrome */
  if (typeof _fs !== 'undefined' && _fs.writeFileSync) return enc ? _fs.writeFileSync(fname, payload, enc) : _fs.writeFileSync(fname, payload);
  if (typeof Deno !== 'undefined') {
    /* in this spot, it's safe to assume typed arrays and TextEncoder/TextDecoder exist */
    if (enc && typeof payload == "string") switch (enc) {
      case "utf8":
        payload = new TextEncoder(enc).encode(payload);
        break;
      case "binary":
        payload = s2ab(payload);
        break;
      /* TODO: binary equivalent */
      default:
        throw new Error("Unsupported encoding " + enc);
    }
    return Deno.writeFileSync(fname, payload);
  }
  var data = enc == "utf8" ? utf8write(payload) : payload;
  /*:: declare var IE_SaveFile: any; */
  if (typeof IE_SaveFile !== 'undefined') return IE_SaveFile(data, fname);
  if (typeof Blob !== 'undefined') {
    var blob = new Blob([blobify(data)], {
      type: "application/octet-stream"
    });
    /*:: declare var navigator: any; */
    if (typeof navigator !== 'undefined' && navigator.msSaveBlob) return navigator.msSaveBlob(blob, fname);
    /*:: declare var saveAs: any; */
    if (typeof saveAs !== 'undefined') return saveAs(blob, fname);
    if (typeof URL !== 'undefined' && typeof document !== 'undefined' && document.createElement && URL.createObjectURL) {
      var url = URL.createObjectURL(blob);
      /*:: declare var chrome: any; */
      if (typeof chrome === 'object' && typeof (chrome.downloads || {}).download == "function") {
        if (URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function () {
          URL.revokeObjectURL(url);
        }, 60000);
        return chrome.downloads.download({
          url: url,
          filename: fname,
          saveAs: true
        });
      }
      var a = document.createElement("a");
      if (a.download != null) {
        /*:: if(document.body == null) throw new Error("unreachable"); */
        a.download = fname;
        a.href = url;
        document.body.appendChild(a);
        a.click();
        /*:: if(document.body == null) throw new Error("unreachable"); */
        document.body.removeChild(a);
        if (URL.revokeObjectURL && typeof setTimeout !== 'undefined') setTimeout(function () {
          URL.revokeObjectURL(url);
        }, 60000);
        return url;
      }
    }
  }
  // $FlowIgnore
  if (typeof $ !== 'undefined' && typeof File !== 'undefined' && typeof Folder !== 'undefined') try {
    // extendscript
    // $FlowIgnore
    var out = File(fname);
    out.open("w");
    out.encoding = "binary";
    if (Array.isArray(payload)) payload = a2s(payload);
    out.write(payload);
    out.close();
    return payload;
  } catch (e) {
    if (!e.message || !e.message.match(/onstruct/)) throw e;
  }
  throw new Error("cannot save file " + fname);
}

/* read binary data from file */
function read_binary(path /*:string*/) {
  if (typeof _fs !== 'undefined') return _fs.readFileSync(path);
  if (typeof Deno !== 'undefined') return Deno.readFileSync(path);
  // $FlowIgnore
  if (typeof $ !== 'undefined' && typeof File !== 'undefined' && typeof Folder !== 'undefined') try {
    // extendscript
    // $FlowIgnore
    var infile = File(path);
    infile.open("r");
    infile.encoding = "binary";
    var data = infile.read();
    infile.close();
    return data;
  } catch (e) {
    if (!e.message || !e.message.match(/onstruct/)) throw e;
  }
  throw new Error("Cannot access file " + path);
}
function keys(o /*:any*/) /*:Array<any>*/{
  var ks = Object.keys(o),
    o2 = [];
  for (var i = 0; i < ks.length; ++i) if (Object.prototype.hasOwnProperty.call(o, ks[i])) o2.push(ks[i]);
  return o2;
}
function evert_key(obj /*:any*/, key /*:string*/) /*:EvertType*/{
  var o = [] /*:any*/,
    K = keys(obj);
  for (var i = 0; i !== K.length; ++i) if (o[obj[K[i]][key]] == null) o[obj[K[i]][key]] = K[i];
  return o;
}
function evert(obj /*:any*/) /*:EvertType*/{
  var o = [] /*:any*/,
    K = keys(obj);
  for (var i = 0; i !== K.length; ++i) o[obj[K[i]]] = K[i];
  return o;
}
function evert_num(obj /*:any*/) /*:EvertNumType*/{
  var o = [] /*:any*/,
    K = keys(obj);
  for (var i = 0; i !== K.length; ++i) o[obj[K[i]]] = parseInt(K[i], 10);
  return o;
}
function evert_arr(obj /*:any*/) /*:EvertArrType*/{
  var o /*:EvertArrType*/ = [] /*:any*/,
    K = keys(obj);
  for (var i = 0; i !== K.length; ++i) {
    if (o[obj[K[i]]] == null) o[obj[K[i]]] = [];
    o[obj[K[i]]].push(K[i]);
  }
  return o;
}
var basedate = /*#__PURE__*/new Date(1899, 11, 30, 0, 0, 0); // 2209161600000
function datenum(v /*:Date*/, date1904 /*:?boolean*/) /*:number*/{
  var epoch = /*#__PURE__*/v.getTime();
  if (date1904) epoch -= 1462 * 24 * 60 * 60 * 1000;
  var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/v.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
  return (epoch - dnthresh) / (24 * 60 * 60 * 1000);
}
var refdate = /*#__PURE__*/new Date();
var dnthresh = /*#__PURE__*/basedate.getTime() + (/*#__PURE__*/refdate.getTimezoneOffset() - /*#__PURE__*/basedate.getTimezoneOffset()) * 60000;
var refoffset = /*#__PURE__*/refdate.getTimezoneOffset();
function numdate(v /*:number*/) /*:Date*/{
  var out = new Date();
  out.setTime(v * 24 * 60 * 60 * 1000 + dnthresh);
  if (out.getTimezoneOffset() !== refoffset) {
    out.setTime(out.getTime() + (out.getTimezoneOffset() - refoffset) * 60000);
  }
  return out;
}

/* ISO 8601 Duration */
function parse_isodur(s) {
  var sec = 0,
    mt = 0,
    time = false;
  var m = s.match(/P([0-9\.]+Y)?([0-9\.]+M)?([0-9\.]+D)?T([0-9\.]+H)?([0-9\.]+M)?([0-9\.]+S)?/);
  if (!m) throw new Error("|" + s + "| is not an ISO8601 Duration");
  for (var i = 1; i != m.length; ++i) {
    if (!m[i]) continue;
    mt = 1;
    if (i > 3) time = true;
    switch (m[i].slice(m[i].length - 1)) {
      case 'Y':
        throw new Error("Unsupported ISO Duration Field: " + m[i].slice(m[i].length - 1));
      case 'D':
        mt *= 24;
      /* falls through */
      case 'H':
        mt *= 60;
      /* falls through */
      case 'M':
        if (!time) throw new Error("Unsupported ISO Duration Field: M");else mt *= 60;
      /* falls through */
      case 'S':
        break;
    }
    sec += mt * parseInt(m[i], 10);
  }
  return sec;
}
var good_pd_date_1 = /*#__PURE__*/new Date('2017-02-19T19:06:09.000Z');
var good_pd_date = /*#__PURE__*/isNaN(/*#__PURE__*/good_pd_date_1.getFullYear()) ? /*#__PURE__*/new Date('2/19/17') : good_pd_date_1;
var good_pd = /*#__PURE__*/good_pd_date.getFullYear() == 2017;
/* parses a date as a local date */
function parseDate(str /*:string|Date*/, fixdate /*:?number*/) /*:Date*/{
  var d = new Date(str);
  if (good_pd) {
    /*:: if(fixdate == null) fixdate = 0; */
    if (fixdate > 0) d.setTime(d.getTime() + d.getTimezoneOffset() * 60 * 1000);else if (fixdate < 0) d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);
    return d;
  }
  if (str instanceof Date) return str;
  if (good_pd_date.getFullYear() == 1917 && !isNaN(d.getFullYear())) {
    var s = d.getFullYear();
    if (str.indexOf("" + s) > -1) return d;
    d.setFullYear(d.getFullYear() + 100);
    return d;
  }
  var n = str.match(/\d+/g) || ["2017", "2", "19", "0", "0", "0"];
  var out = new Date(+n[0], +n[1] - 1, +n[2], +n[3] || 0, +n[4] || 0, +n[5] || 0);
  if (str.indexOf("Z") > -1) out = new Date(out.getTime() - out.getTimezoneOffset() * 60 * 1000);
  return out;
}
function cc2str(arr /*:Array<number>*/, debomit) /*:string*/{
  if (has_buf && Buffer.isBuffer(arr)) {
    if (debomit) {
      if (arr[0] == 0xFF && arr[1] == 0xFE) return utf8write(arr.slice(2).toString("utf16le"));
      if (arr[1] == 0xFE && arr[2] == 0xFF) return utf8write(utf16beread(arr.slice(2).toString("binary")));
    }
    return arr.toString("binary");
  }
  if (typeof TextDecoder !== "undefined") try {
    if (debomit) {
      if (arr[0] == 0xFF && arr[1] == 0xFE) return utf8write(new TextDecoder("utf-16le").decode(arr.slice(2)));
      if (arr[0] == 0xFE && arr[1] == 0xFF) return utf8write(new TextDecoder("utf-16be").decode(arr.slice(2)));
    }
    var rev = {
      "\u20ac": "\x80",
      "\u201a": "\x82",
      "\u0192": "\x83",
      "\u201e": "\x84",
      "\u2026": "\x85",
      "\u2020": "\x86",
      "\u2021": "\x87",
      "\u02c6": "\x88",
      "\u2030": "\x89",
      "\u0160": "\x8a",
      "\u2039": "\x8b",
      "\u0152": "\x8c",
      "\u017d": "\x8e",
      "\u2018": "\x91",
      "\u2019": "\x92",
      "\u201c": "\x93",
      "\u201d": "\x94",
      "\u2022": "\x95",
      "\u2013": "\x96",
      "\u2014": "\x97",
      "\u02dc": "\x98",
      "\u2122": "\x99",
      "\u0161": "\x9a",
      "\u203a": "\x9b",
      "\u0153": "\x9c",
      "\u017e": "\x9e",
      "\u0178": "\x9f"
    };
    if (Array.isArray(arr)) arr = new Uint8Array(arr);
    return new TextDecoder("latin1").decode(arr).replace(/[€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ]/g, function (c) {
      return rev[c] || c;
    });
  } catch (e) {}
  var o = [];
  for (var i = 0; i != arr.length; ++i) o.push(String.fromCharCode(arr[i]));
  return o.join("");
}
function dup(o /*:any*/) /*:any*/{
  if (typeof JSON != 'undefined' && !Array.isArray(o)) return JSON.parse(JSON.stringify(o));
  if (typeof o != 'object' || o == null) return o;
  if (o instanceof Date) return new Date(o.getTime());
  var out = {};
  for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) out[k] = dup(o[k]);
  return out;
}
function fill(c /*:string*/, l /*:number*/) /*:string*/{
  var o = "";
  while (o.length < l) o += c;
  return o;
}

/* TODO: stress test */
function fuzzynum(s /*:string*/) /*:number*/{
  var v /*:number*/ = Number(s);
  if (!isNaN(v)) return isFinite(v) ? v : NaN;
  if (!/\d/.test(s)) return v;
  var wt = 1;
  var ss = s.replace(/([\d]),([\d])/g, "$1$2").replace(/[$]/g, "").replace(/[%]/g, function () {
    wt *= 100;
    return "";
  });
  if (!isNaN(v = Number(ss))) return v / wt;
  ss = ss.replace(/[(](.*)[)]/, function ($$, $1) {
    wt = -wt;
    return $1;
  });
  if (!isNaN(v = Number(ss))) return v / wt;
  return v;
}
var lower_months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'];
function fuzzydate(s /*:string*/) /*:Date*/{
  var o = new Date(s),
    n = new Date(NaN);
  var y = o.getYear(),
    m = o.getMonth(),
    d = o.getDate();
  if (isNaN(d)) return n;
  var lower = s.toLowerCase();
  if (lower.match(/jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec/)) {
    lower = lower.replace(/[^a-z]/g, "").replace(/([^a-z]|^)[ap]m?([^a-z]|$)/, "");
    if (lower.length > 3 && lower_months.indexOf(lower) == -1) return n;
  } else if (lower.match(/[a-z]/)) return n;
  if (y < 0 || y > 8099) return n;
  if ((m > 0 || d > 1) && y != 101) return o;
  if (s.match(/[^-0-9:,\/\\]/)) return n;
  return o;
}
var split_regex = /*#__PURE__*/function () {
  var safe_split_regex = "abacaba".split(/(:?b)/i).length == 5;
  return function split_regex(str /*:string*/, re, def /*:string*/) /*:Array<string>*/{
    if (safe_split_regex || typeof re == "string") return str.split(re);
    var p = str.split(re),
      o = [p[0]];
    for (var i = 1; i < p.length; ++i) {
      o.push(def);
      o.push(p[i]);
    }
    return o;
  };
}();
function getdatastr(data) /*:?string*/{
  if (!data) return null;
  if (data.content && data.type) return cc2str(data.content, true);
  if (data.data) return debom(data.data);
  if (data.asNodeBuffer && has_buf) return debom(data.asNodeBuffer().toString('binary'));
  if (data.asBinary) return debom(data.asBinary());
  if (data._data && data._data.getContent) return debom(cc2str(Array.prototype.slice.call(data._data.getContent(), 0)));
  return null;
}
function getdatabin(data) {
  if (!data) return null;
  if (data.data) return char_codes(data.data);
  if (data.asNodeBuffer && has_buf) return data.asNodeBuffer();
  if (data._data && data._data.getContent) {
    var o = data._data.getContent();
    if (typeof o == "string") return char_codes(o);
    return Array.prototype.slice.call(o);
  }
  if (data.content && data.type) return data.content;
  return null;
}
function getdata(data) {
  return data && data.name.slice(-4) === ".bin" ? getdatabin(data) : getdatastr(data);
}

/* Part 2 Section 10.1.2 "Mapping Content Types" Names are case-insensitive */
/* OASIS does not comment on filename case sensitivity */
function safegetzipfile(zip, file /*:string*/) {
  var k = zip.FullPaths || keys(zip.files);
  var f = file.toLowerCase().replace(/[\/]/g, '\\'),
    g = f.replace(/\\/g, '\/');
  for (var i = 0; i < k.length; ++i) {
    var n = k[i].replace(/^Root Entry[\/]/, "").toLowerCase();
    if (f == n || g == n) return zip.files ? zip.files[k[i]] : zip.FileIndex[i];
  }
  return null;
}
function getzipfile(zip, file /*:string*/) {
  var o = safegetzipfile(zip, file);
  if (o == null) throw new Error("Cannot find file " + file + " in zip");
  return o;
}
function getzipdata(zip, file /*:string*/, safe /*:?boolean*/) /*:any*/{
  if (!safe) return getdata(getzipfile(zip, file));
  if (!file) return null;
  try {
    return getzipdata(zip, file);
  } catch (e) {
    return null;
  }
}
function getzipstr(zip, file /*:string*/, safe /*:?boolean*/) /*:?string*/{
  if (!safe) return getdatastr(getzipfile(zip, file));
  if (!file) return null;
  try {
    return getzipstr(zip, file);
  } catch (e) {
    return null;
  }
}
function getzipbin(zip, file /*:string*/, safe /*:?boolean*/) /*:any*/{
  if (!safe) return getdatabin(getzipfile(zip, file));
  if (!file) return null;
  try {
    return getzipbin(zip, file);
  } catch (e) {
    return null;
  }
}
function zipentries(zip) {
  var k = zip.FullPaths || keys(zip.files),
    o = [];
  for (var i = 0; i < k.length; ++i) if (k[i].slice(-1) != '/') o.push(k[i].replace(/^Root Entry[\/]/, ""));
  return o.sort();
}
function zip_add_file(zip, path, content) {
  if (zip.FullPaths) {
    if (typeof content == "string") {
      var res;
      if (has_buf) res = Buffer_from(content);
      /* TODO: investigate performance in Edge 13 */
      //else if(typeof TextEncoder !== "undefined") res = new TextEncoder().encode(content);
      else res = utf8decode(content);
      return CFB.utils.cfb_add(zip, path, res);
    }
    CFB.utils.cfb_add(zip, path, content);
  } else zip.file(path, content);
}
function zip_new() {
  return CFB.utils.cfb_new();
}
function zip_read(d, o) {
  switch (o.type) {
    case "base64":
      return CFB.read(d, {
        type: "base64"
      });
    case "binary":
      return CFB.read(d, {
        type: "binary"
      });
    case "buffer":
    case "array":
      return CFB.read(d, {
        type: "buffer"
      });
  }
  throw new Error("Unrecognized type " + o.type);
}
function resolve_path(path /*:string*/, base /*:string*/) /*:string*/{
  if (path.charAt(0) == "/") return path.slice(1);
  var result = base.split('/');
  if (base.slice(-1) != "/") result.pop(); // folder path
  var target = path.split('/');
  while (target.length !== 0) {
    var step = target.shift();
    if (step === '..') result.pop();else if (step !== '.') result.push(step);
  }
  return result.join('/');
}
var XML_HEADER = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\r\n';
var attregexg = /([^"\s?>\/]+)\s*=\s*((?:")([^"]*)(?:")|(?:')([^']*)(?:')|([^'">\s]+))/g;
var tagregex1 = /<[\/\?]?[a-zA-Z0-9:_-]+(?:\s+[^"\s?>\/]+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s=]+))*\s*[\/\?]?>/mg,
  tagregex2 = /<[^>]*>/g;
var tagregex = /*#__PURE__*/XML_HEADER.match(tagregex1) ? tagregex1 : tagregex2;
var nsregex = /<\w*:/,
  nsregex2 = /<(\/?)\w+:/;
function parsexmltag(tag /*:string*/, skip_root /*:?boolean*/, skip_LC /*:?boolean*/) /*:any*/{
  var z = {} /*:any*/;
  var eq = 0,
    c = 0;
  for (; eq !== tag.length; ++eq) if ((c = tag.charCodeAt(eq)) === 32 || c === 10 || c === 13) break;
  if (!skip_root) z[0] = tag.slice(0, eq);
  if (eq === tag.length) return z;
  var m = tag.match(attregexg),
    j = 0,
    v = "",
    i = 0,
    q = "",
    cc = "",
    quot = 1;
  if (m) for (i = 0; i != m.length; ++i) {
    cc = m[i];
    for (c = 0; c != cc.length; ++c) if (cc.charCodeAt(c) === 61) break;
    q = cc.slice(0, c).trim();
    while (cc.charCodeAt(c + 1) == 32) ++c;
    quot = (eq = cc.charCodeAt(c + 1)) == 34 || eq == 39 ? 1 : 0;
    v = cc.slice(c + 1 + quot, cc.length - quot);
    for (j = 0; j != q.length; ++j) if (q.charCodeAt(j) === 58) break;
    if (j === q.length) {
      if (q.indexOf("_") > 0) q = q.slice(0, q.indexOf("_")); // from ods
      z[q] = v;
      if (!skip_LC) z[q.toLowerCase()] = v;
    } else {
      var k = (j === 5 && q.slice(0, 5) === "xmlns" ? "xmlns" : "") + q.slice(j + 1);
      if (z[k] && q.slice(j - 3, j) == "ext") continue; // from ods
      z[k] = v;
      if (!skip_LC) z[k.toLowerCase()] = v;
    }
  }
  return z;
}
function strip_ns(x /*:string*/) /*:string*/{
  return x.replace(nsregex2, "<$1");
}
var encodings = {
  '&quot;': '"',
  '&apos;': "'",
  '&gt;': '>',
  '&lt;': '<',
  '&amp;': '&'
};
var rencoding = /*#__PURE__*/evert(encodings);
//var rencstr = "&<>'\"".split("");

// TODO: CP remap (need to read file version to determine OS)
var unescapexml /*:StringConv*/ = /*#__PURE__*/function () {
  /* 22.4.2.4 bstr (Basic String) */
  var encregex = /&(?:quot|apos|gt|lt|amp|#x?([\da-fA-F]+));/ig,
    coderegex = /_x([\da-fA-F]{4})_/ig;
  return function unescapexml(text /*:string*/) /*:string*/{
    var s = text + '',
      i = s.indexOf("<![CDATA[");
    if (i == -1) return s.replace(encregex, function ($$, $1) {
      return encodings[$$] || String.fromCharCode(parseInt($1, $$.indexOf("x") > -1 ? 16 : 10)) || $$;
    }).replace(coderegex, function (m, c) {
      return String.fromCharCode(parseInt(c, 16));
    });
    var j = s.indexOf("]]>");
    return unescapexml(s.slice(0, i)) + s.slice(i + 9, j) + unescapexml(s.slice(j + 3));
  };
}();
var decregex = /[&<>'"]/g,
  charegex = /[\u0000-\u0008\u000b-\u001f]/g;
function escapexml(text /*:string*/) /*:string*/{
  var s = text + '';
  return s.replace(decregex, function (y) {
    return rencoding[y];
  }).replace(charegex, function (s) {
    return "_x" + ("000" + s.charCodeAt(0).toString(16)).slice(-4) + "_";
  });
}
function escapexmltag(text /*:string*/) /*:string*/{
  return escapexml(text).replace(/ /g, "_x0020_");
}
var htmlcharegex = /[\u0000-\u001f]/g;
function escapehtml(text /*:string*/) /*:string*/{
  var s = text + '';
  return s.replace(decregex, function (y) {
    return rencoding[y];
  }).replace(/\n/g, "<br/>").replace(htmlcharegex, function (s) {
    return "&#x" + ("000" + s.charCodeAt(0).toString(16)).slice(-4) + ";";
  });
}
function escapexlml(text /*:string*/) /*:string*/{
  var s = text + '';
  return s.replace(decregex, function (y) {
    return rencoding[y];
  }).replace(htmlcharegex, function (s) {
    return "&#x" + s.charCodeAt(0).toString(16).toUpperCase() + ";";
  });
}

/* TODO: handle codepages */
var xlml_fixstr /*:StringConv*/ = /*#__PURE__*/function () {
  var entregex = /&#(\d+);/g;
  function entrepl($$ /*:string*/, $1 /*:string*/) /*:string*/{
    return String.fromCharCode(parseInt($1, 10));
  }
  return function xlml_fixstr(str /*:string*/) /*:string*/{
    return str.replace(entregex, entrepl);
  };
}();
function xlml_unfixstr(str /*:string*/) /*:string*/{
  return str.replace(/(\r\n|[\r\n])/g, "\&#10;");
}
function parsexmlbool(value /*:any*/) /*:boolean*/{
  switch (value) {
    case 1:
    case true:
    case '1':
    case 'true':
    case 'TRUE':
      return true;
    /* case '0': case 'false': case 'FALSE':*/
    default:
      return false;
  }
}
function utf8reada(orig /*:string*/) /*:string*/{
  var out = "",
    i = 0,
    c = 0,
    d = 0,
    e = 0,
    f = 0,
    w = 0;
  while (i < orig.length) {
    c = orig.charCodeAt(i++);
    if (c < 128) {
      out += String.fromCharCode(c);
      continue;
    }
    d = orig.charCodeAt(i++);
    if (c > 191 && c < 224) {
      f = (c & 31) << 6;
      f |= d & 63;
      out += String.fromCharCode(f);
      continue;
    }
    e = orig.charCodeAt(i++);
    if (c < 240) {
      out += String.fromCharCode((c & 15) << 12 | (d & 63) << 6 | e & 63);
      continue;
    }
    f = orig.charCodeAt(i++);
    w = ((c & 7) << 18 | (d & 63) << 12 | (e & 63) << 6 | f & 63) - 65536;
    out += String.fromCharCode(0xD800 + (w >>> 10 & 1023));
    out += String.fromCharCode(0xDC00 + (w & 1023));
  }
  return out;
}
function utf8readb(data) {
  var out = new_raw_buf(2 * data.length),
    w,
    i,
    j = 1,
    k = 0,
    ww = 0,
    c;
  for (i = 0; i < data.length; i += j) {
    j = 1;
    if ((c = data.charCodeAt(i)) < 128) w = c;else if (c < 224) {
      w = (c & 31) * 64 + (data.charCodeAt(i + 1) & 63);
      j = 2;
    } else if (c < 240) {
      w = (c & 15) * 4096 + (data.charCodeAt(i + 1) & 63) * 64 + (data.charCodeAt(i + 2) & 63);
      j = 3;
    } else {
      j = 4;
      w = (c & 7) * 262144 + (data.charCodeAt(i + 1) & 63) * 4096 + (data.charCodeAt(i + 2) & 63) * 64 + (data.charCodeAt(i + 3) & 63);
      w -= 65536;
      ww = 0xD800 + (w >>> 10 & 1023);
      w = 0xDC00 + (w & 1023);
    }
    if (ww !== 0) {
      out[k++] = ww & 255;
      out[k++] = ww >>> 8;
      ww = 0;
    }
    out[k++] = w % 256;
    out[k++] = w >>> 8;
  }
  return out.slice(0, k).toString('ucs2');
}
function utf8readc(data) {
  return Buffer_from(data, 'binary').toString('utf8');
}
var utf8corpus = "foo bar baz\u00e2\u0098\u0083\u00f0\u009f\u008d\u00a3";
var utf8read = has_buf && (/*#__PURE__*/utf8readc(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readc || /*#__PURE__*/utf8readb(utf8corpus) == /*#__PURE__*/utf8reada(utf8corpus) && utf8readb) || utf8reada;
var utf8write /*:StringConv*/ = has_buf ? function (data) {
  return Buffer_from(data, 'utf8').toString("binary");
} : function (orig /*:string*/) /*:string*/{
  var out /*:Array<string>*/ = [],
    i = 0,
    c = 0,
    d = 0;
  while (i < orig.length) {
    c = orig.charCodeAt(i++);
    switch (true) {
      case c < 128:
        out.push(String.fromCharCode(c));
        break;
      case c < 2048:
        out.push(String.fromCharCode(192 + (c >> 6)));
        out.push(String.fromCharCode(128 + (c & 63)));
        break;
      case c >= 55296 && c < 57344:
        c -= 55296;
        d = orig.charCodeAt(i++) - 56320 + (c << 10);
        out.push(String.fromCharCode(240 + (d >> 18 & 7)));
        out.push(String.fromCharCode(144 + (d >> 12 & 63)));
        out.push(String.fromCharCode(128 + (d >> 6 & 63)));
        out.push(String.fromCharCode(128 + (d & 63)));
        break;
      default:
        out.push(String.fromCharCode(224 + (c >> 12)));
        out.push(String.fromCharCode(128 + (c >> 6 & 63)));
        out.push(String.fromCharCode(128 + (c & 63)));
    }
  }
  return out.join("");
};

// matches <foo>...</foo> extracts content
var matchtag = /*#__PURE__*/function () {
  var mtcache /*:{[k:string]:RegExp}*/ = {} /*:any*/;
  return function matchtag(f /*:string*/, g /*:?string*/) /*:RegExp*/{
    var t = f + "|" + (g || "");
    if (mtcache[t]) return mtcache[t];
    return mtcache[t] = new RegExp('<(?:\\w+:)?' + f + '(?: xml:space="preserve")?(?:[^>]*)>([\\s\\S]*?)</(?:\\w+:)?' + f + '>', g || "" /*:any*/);
  };
}();
var htmldecode /*:{(s:string):string}*/ = /*#__PURE__*/function () {
  var entities /*:Array<[RegExp, string]>*/ = [['nbsp', ' '], ['middot', '·'], ['quot', '"'], ['apos', "'"], ['gt', '>'], ['lt', '<'], ['amp', '&']].map(function (x /*:[string, string]*/) {
    return [new RegExp('&' + x[0] + ';', "ig"), x[1]];
  });
  return function htmldecode(str /*:string*/) /*:string*/{
    var o = str
    // Remove new lines and spaces from start of content
    .replace(/^[\t\n\r ]+/, "")
    // Remove new lines and spaces from end of content
    .replace(/[\t\n\r ]+$/, "")
    // Added line which removes any white space characters after and before html tags
    .replace(/>\s+/g, ">").replace(/\s+</g, "<")
    // Replace remaining new lines and spaces with space
    .replace(/[\t\n\r ]+/g, " ")
    // Replace <br> tags with new lines
    .replace(/<\s*[bB][rR]\s*\/?>/g, "\n")
    // Strip HTML elements
    .replace(/<[^>]*>/g, "");
    for (var i = 0; i < entities.length; ++i) o = o.replace(entities[i][0], entities[i][1]);
    return o;
  };
}();
var vtregex = /*#__PURE__*/function () {
  var vt_cache = {};
  return function vt_regex(bt) {
    if (vt_cache[bt] !== undefined) return vt_cache[bt];
    return vt_cache[bt] = new RegExp("<(?:vt:)?" + bt + ">([\\s\\S]*?)</(?:vt:)?" + bt + ">", 'g');
  };
}();
var vtvregex = /<\/?(?:vt:)?variant>/g,
  vtmregex = /<(?:vt:)([^>]*)>([\s\S]*)</;
function parseVector(data /*:string*/, opts) /*:Array<{v:string,t:string}>*/{
  var h = parsexmltag(data);
  var matches /*:Array<string>*/ = data.match(vtregex(h.baseType)) || [];
  var res /*:Array<any>*/ = [];
  if (matches.length != h.size) {
    if (opts.WTF) throw new Error("unexpected vector length " + matches.length + " != " + h.size);
    return res;
  }
  matches.forEach(function (x /*:string*/) {
    var v = x.replace(vtvregex, "").match(vtmregex);
    if (v) res.push({
      v: utf8read(v[2]),
      t: v[1]
    });
  });
  return res;
}
var wtregex = /(^\s|\s$|\n)/;
function writetag(f /*:string*/, g /*:string*/) /*:string*/{
  return '<' + f + (g.match(wtregex) ? ' xml:space="preserve"' : "") + '>' + g + '</' + f + '>';
}
function wxt_helper(h) /*:string*/{
  return keys(h).map(function (k) {
    return " " + k + '="' + h[k] + '"';
  }).join("");
}
function writextag(f /*:string*/, g /*:?string*/, h) {
  return '<' + f + (h != null ? wxt_helper(h) : "") + (g != null ? (g.match(wtregex) ? ' xml:space="preserve"' : "") + '>' + g + '</' + f : "/") + '>';
}
function write_w3cdtf(d /*:Date*/, t /*:?boolean*/) /*:string*/{
  try {
    return d.toISOString().replace(/\.\d*/, "");
  } catch (e) {
    if (t) throw e;
  }
  return "";
}
function write_vt(s, xlsx /*:?boolean*/) /*:string*/{
  switch (typeof s) {
    case 'string':
      var o = writextag('vt:lpwstr', escapexml(s));
      if (xlsx) o = o.replace(/&quot;/g, "_x0022_");
      return o;
    case 'number':
      return writextag((s | 0) == s ? 'vt:i4' : 'vt:r8', escapexml(String(s)));
    case 'boolean':
      return writextag('vt:bool', s ? 'true' : 'false');
  }
  if (s instanceof Date) return writextag('vt:filetime', write_w3cdtf(s));
  throw new Error("Unable to serialize " + s);
}
function xlml_normalize(d) /*:string*/{
  if (has_buf && /*::typeof Buffer !== "undefined" && d != null && d instanceof Buffer &&*/Buffer.isBuffer(d)) return d.toString('utf8');
  if (typeof d === 'string') return d;
  /* duktape */
  if (typeof Uint8Array !== 'undefined' && d instanceof Uint8Array) return utf8read(a2s(ab2a(d)));
  throw new Error("Bad input format: expected Buffer or string");
}
/* UOS uses CJK in tags */
var xlmlregex = /<(\/?)([^\s?><!\/:]*:|)([^\s?<>:\/]+)(?:[\s?:\/][^>]*)?>/mg;
//var xlmlregex = /<(\/?)([a-z0-9]*:|)(\w+)[^>]*>/mg;

var XMLNS = {
  CORE_PROPS: 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties',
  CUST_PROPS: "http://schemas.openxmlformats.org/officeDocument/2006/custom-properties",
  EXT_PROPS: "http://schemas.openxmlformats.org/officeDocument/2006/extended-properties",
  CT: 'http://schemas.openxmlformats.org/package/2006/content-types',
  RELS: 'http://schemas.openxmlformats.org/package/2006/relationships',
  TCMNT: 'http://schemas.microsoft.com/office/spreadsheetml/2018/threadedcomments',
  'dc': 'http://purl.org/dc/elements/1.1/',
  'dcterms': 'http://purl.org/dc/terms/',
  'dcmitype': 'http://purl.org/dc/dcmitype/',
  'mx': 'http://schemas.microsoft.com/office/mac/excel/2008/main',
  'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
  'sjs': 'http://schemas.openxmlformats.org/package/2006/sheetjs/core-properties',
  'vt': 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes',
  'xsi': 'http://www.w3.org/2001/XMLSchema-instance',
  'xsd': 'http://www.w3.org/2001/XMLSchema'
} /*:any*/;
var XMLNS_main = ['http://schemas.openxmlformats.org/spreadsheetml/2006/main', 'http://purl.oclc.org/ooxml/spreadsheetml/main', 'http://schemas.microsoft.com/office/excel/2006/main', 'http://schemas.microsoft.com/office/excel/2006/2'];
var XLMLNS = {
  'o': 'urn:schemas-microsoft-com:office:office',
  'x': 'urn:schemas-microsoft-com:office:excel',
  'ss': 'urn:schemas-microsoft-com:office:spreadsheet',
  'dt': 'uuid:C2F41010-65B3-11d1-A29F-00AA00C14882',
  'mv': 'http://macVmlSchemaUri',
  'v': 'urn:schemas-microsoft-com:vml',
  'html': 'http://www.w3.org/TR/REC-html40'
} /*:any*/;
function read_double_le(b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  var s = 1 - 2 * (b[idx + 7] >>> 7);
  var e = ((b[idx + 7] & 0x7f) << 4) + (b[idx + 6] >>> 4 & 0x0f);
  var m = b[idx + 6] & 0x0f;
  for (var i = 5; i >= 0; --i) m = m * 256 + b[idx + i];
  if (e == 0x7ff) return m == 0 ? s * Infinity : NaN;
  if (e == 0) e = -1022;else {
    e -= 1023;
    m += Math.pow(2, 52);
  }
  return s * Math.pow(2, e - 52) * m;
}
function write_double_le(b /*:RawBytes|CFBlob*/, v /*:number*/, idx /*:number*/) {
  var bs = (v < 0 || 1 / v == -Infinity ? 1 : 0) << 7,
    e = 0,
    m = 0;
  var av = bs ? -v : v;
  if (!isFinite(av)) {
    e = 0x7ff;
    m = isNaN(v) ? 0x6969 : 0;
  } else if (av == 0) e = m = 0;else {
    e = Math.floor(Math.log(av) / Math.LN2);
    m = av * Math.pow(2, 52 - e);
    if (e <= -1023 && (!isFinite(m) || m < Math.pow(2, 52))) {
      e = -1022;
    } else {
      m -= Math.pow(2, 52);
      e += 1023;
    }
  }
  for (var i = 0; i <= 5; ++i, m /= 256) b[idx + i] = m & 0xff;
  b[idx + 6] = (e & 0x0f) << 4 | m & 0xf;
  b[idx + 7] = e >> 4 | bs;
}
var ___toBuffer = function (bufs /*:Array<Array<RawBytes> >*/) /*:RawBytes*/{
  var x = [],
    w = 10240;
  for (var i = 0; i < bufs[0].length; ++i) if (bufs[0][i]) for (var j = 0, L = bufs[0][i].length; j < L; j += w) x.push.apply(x, bufs[0][i].slice(j, j + w));
  return x;
};
var __toBuffer = has_buf ? function (bufs) {
  return bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0]) ? Buffer.concat(bufs[0].map(function (x) {
    return Buffer.isBuffer(x) ? x : Buffer_from(x);
  })) : ___toBuffer(bufs);
} : ___toBuffer;
var ___utf16le = function (b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) /*:string*/{
  var ss /*:Array<string>*/ = [];
  for (var i = s; i < e; i += 2) ss.push(String.fromCharCode(__readUInt16LE(b, i)));
  return ss.join("").replace(chr0, '');
};
var __utf16le = has_buf ? function (b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) /*:string*/{
  if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___utf16le(b, s, e);
  return b.toString('utf16le', s, e).replace(chr0, '') /*.replace(chr1,'!')*/;
} : ___utf16le;
var ___hexlify = function (b /*:RawBytes|CFBlob*/, s /*:number*/, l /*:number*/) /*:string*/{
  var ss /*:Array<string>*/ = [];
  for (var i = s; i < s + l; ++i) ss.push(("0" + b[i].toString(16)).slice(-2));
  return ss.join("");
};
var __hexlify = has_buf ? function (b /*:RawBytes|CFBlob*/, s /*:number*/, l /*:number*/) /*:string*/{
  return Buffer.isBuffer(b) /*:: && b instanceof Buffer*/ ? b.toString('hex', s, s + l) : ___hexlify(b, s, l);
} : ___hexlify;
var ___utf8 = function (b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) {
  var ss = [];
  for (var i = s; i < e; i++) ss.push(String.fromCharCode(__readUInt8(b, i)));
  return ss.join("");
};
var __utf8 = has_buf ? function utf8_b(b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) {
  return Buffer.isBuffer(b) /*:: && (b instanceof Buffer)*/ ? b.toString('utf8', s, e) : ___utf8(b, s, e);
} : ___utf8;
var ___lpstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
  var len = __readUInt32LE(b, i);
  return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : "";
};
var __lpstr = ___lpstr;
var ___cpstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
  var len = __readUInt32LE(b, i);
  return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : "";
};
var __cpstr = ___cpstr;
var ___lpwstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
  var len = 2 * __readUInt32LE(b, i);
  return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : "";
};
var __lpwstr = ___lpwstr;
var ___lpp4 = function lpp4_(b /*:RawBytes|CFBlob*/, i /*:number*/) {
  var len = __readUInt32LE(b, i);
  return len > 0 ? __utf16le(b, i + 4, i + 4 + len) : "";
};
var __lpp4 = ___lpp4;
var ___8lpp4 = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
  var len = __readUInt32LE(b, i);
  return len > 0 ? __utf8(b, i + 4, i + 4 + len) : "";
};
var __8lpp4 = ___8lpp4;
var ___double = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) {
  return read_double_le(b, idx);
};
var __double = ___double;
var is_buf = function is_buf_a(a) {
  return Array.isArray(a) || typeof Uint8Array !== "undefined" && a instanceof Uint8Array;
};
if (has_buf /*:: && typeof Buffer !== 'undefined'*/) {
  __lpstr = function lpstr_b(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___lpstr(b, i);
    var len = b.readUInt32LE(i);
    return len > 0 ? b.toString('utf8', i + 4, i + 4 + len - 1) : "";
  };
  __cpstr = function cpstr_b(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___cpstr(b, i);
    var len = b.readUInt32LE(i);
    return len > 0 ? b.toString('utf8', i + 4, i + 4 + len - 1) : "";
  };
  __lpwstr = function lpwstr_b(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___lpwstr(b, i);
    var len = 2 * b.readUInt32LE(i);
    return b.toString('utf16le', i + 4, i + 4 + len - 1);
  };
  __lpp4 = function lpp4_b(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___lpp4(b, i);
    var len = b.readUInt32LE(i);
    return b.toString('utf16le', i + 4, i + 4 + len);
  };
  __8lpp4 = function lpp4_8b(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (!Buffer.isBuffer(b) /*:: || !(b instanceof Buffer)*/) return ___8lpp4(b, i);
    var len = b.readUInt32LE(i);
    return b.toString('utf8', i + 4, i + 4 + len);
  };
  __double = function double_(b /*:RawBytes|CFBlob*/, i /*:number*/) {
    if (Buffer.isBuffer(b) /*::&& b instanceof Buffer*/) return b.readDoubleLE(i);
    return ___double(b, i);
  };
  is_buf = function is_buf_b(a) {
    return Buffer.isBuffer(a) || Array.isArray(a) || typeof Uint8Array !== "undefined" && a instanceof Uint8Array;
  };
}

/* from js-xls */
function cpdoit() {
  __utf16le = function (b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) {
    return $cptable.utils.decode(1200, b.slice(s, e)).replace(chr0, '');
  };
  __utf8 = function (b /*:RawBytes|CFBlob*/, s /*:number*/, e /*:number*/) {
    return $cptable.utils.decode(65001, b.slice(s, e));
  };
  __lpstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
    var len = __readUInt32LE(b, i);
    return len > 0 ? $cptable.utils.decode(current_ansi, b.slice(i + 4, i + 4 + len - 1)) : "";
  };
  __cpstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
    var len = __readUInt32LE(b, i);
    return len > 0 ? $cptable.utils.decode(current_codepage, b.slice(i + 4, i + 4 + len - 1)) : "";
  };
  __lpwstr = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
    var len = 2 * __readUInt32LE(b, i);
    return len > 0 ? $cptable.utils.decode(1200, b.slice(i + 4, i + 4 + len - 1)) : "";
  };
  __lpp4 = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
    var len = __readUInt32LE(b, i);
    return len > 0 ? $cptable.utils.decode(1200, b.slice(i + 4, i + 4 + len)) : "";
  };
  __8lpp4 = function (b /*:RawBytes|CFBlob*/, i /*:number*/) {
    var len = __readUInt32LE(b, i);
    return len > 0 ? $cptable.utils.decode(65001, b.slice(i + 4, i + 4 + len)) : "";
  };
}
if (typeof $cptable !== 'undefined') cpdoit();
var __readUInt8 = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  return b[idx];
};
var __readUInt16LE = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  return b[idx + 1] * (1 << 8) + b[idx];
};
var __readInt16LE = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  var u = b[idx + 1] * (1 << 8) + b[idx];
  return u < 0x8000 ? u : (0xffff - u + 1) * -1;
};
var __readUInt32LE = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  return b[idx + 3] * (1 << 24) + (b[idx + 2] << 16) + (b[idx + 1] << 8) + b[idx];
};
var __readInt32LE = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  return b[idx + 3] << 24 | b[idx + 2] << 16 | b[idx + 1] << 8 | b[idx];
};
var __readInt32BE = function (b /*:RawBytes|CFBlob*/, idx /*:number*/) /*:number*/{
  return b[idx] << 24 | b[idx + 1] << 16 | b[idx + 2] << 8 | b[idx + 3];
};
function ReadShift(size /*:number*/, t /*:?string*/) /*:number|string*/{
  var o = "",
    oI /*:: :number = 0*/,
    oR,
    oo = [],
    w,
    vv,
    i,
    loc;
  switch (t) {
    case 'dbcs':
      loc = this.l;
      if (has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l + 2 * size).toString("utf16le");else for (i = 0; i < size; ++i) {
        o += String.fromCharCode(__readUInt16LE(this, loc));
        loc += 2;
      }
      size *= 2;
      break;
    case 'utf8':
      o = __utf8(this, this.l, this.l + size);
      break;
    case 'utf16le':
      size *= 2;
      o = __utf16le(this, this.l, this.l + size);
      break;
    case 'wstr':
      if (typeof $cptable !== 'undefined') o = $cptable.utils.decode(current_codepage, this.slice(this.l, this.l + 2 * size));else return ReadShift.call(this, size, 'dbcs');
      size = 2 * size;
      break;

    /* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */
    case 'lpstr-ansi':
      o = __lpstr(this, this.l);
      size = 4 + __readUInt32LE(this, this.l);
      break;
    case 'lpstr-cp':
      o = __cpstr(this, this.l);
      size = 4 + __readUInt32LE(this, this.l);
      break;
    /* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */
    case 'lpwstr':
      o = __lpwstr(this, this.l);
      size = 4 + 2 * __readUInt32LE(this, this.l);
      break;
    /* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */
    case 'lpp4':
      size = 4 + __readUInt32LE(this, this.l);
      o = __lpp4(this, this.l);
      if (size & 0x02) size += 2;
      break;
    /* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */
    case '8lpp4':
      size = 4 + __readUInt32LE(this, this.l);
      o = __8lpp4(this, this.l);
      if (size & 0x03) size += 4 - (size & 0x03);
      break;
    case 'cstr':
      size = 0;
      o = "";
      while ((w = __readUInt8(this, this.l + size++)) !== 0) oo.push(_getchar(w));
      o = oo.join("");
      break;
    case '_wstr':
      size = 0;
      o = "";
      while ((w = __readUInt16LE(this, this.l + size)) !== 0) {
        oo.push(_getchar(w));
        size += 2;
      }
      size += 2;
      o = oo.join("");
      break;

    /* sbcs and dbcs support continue records in the SST way TODO codepages */
    case 'dbcs-cont':
      o = "";
      loc = this.l;
      for (i = 0; i < size; ++i) {
        if (this.lens && this.lens.indexOf(loc) !== -1) {
          w = __readUInt8(this, loc);
          this.l = loc + 1;
          vv = ReadShift.call(this, size - i, w ? 'dbcs-cont' : 'sbcs-cont');
          return oo.join("") + vv;
        }
        oo.push(_getchar(__readUInt16LE(this, loc)));
        loc += 2;
      }
      o = oo.join("");
      size *= 2;
      break;
    case 'cpstr':
      if (typeof $cptable !== 'undefined') {
        o = $cptable.utils.decode(current_codepage, this.slice(this.l, this.l + size));
        break;
      }
    /* falls through */
    case 'sbcs-cont':
      o = "";
      loc = this.l;
      for (i = 0; i != size; ++i) {
        if (this.lens && this.lens.indexOf(loc) !== -1) {
          w = __readUInt8(this, loc);
          this.l = loc + 1;
          vv = ReadShift.call(this, size - i, w ? 'dbcs-cont' : 'sbcs-cont');
          return oo.join("") + vv;
        }
        oo.push(_getchar(__readUInt8(this, loc)));
        loc += 1;
      }
      o = oo.join("");
      break;
    default:
      switch (size) {
        case 1:
          oI = __readUInt8(this, this.l);
          this.l++;
          return oI;
        case 2:
          oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l);
          this.l += 2;
          return oI;
        case 4:
        case -4:
          if (t === 'i' || (this[this.l + 3] & 0x80) === 0) {
            oI = (size > 0 ? __readInt32LE : __readInt32BE)(this, this.l);
            this.l += 4;
            return oI;
          } else {
            oR = __readUInt32LE(this, this.l);
            this.l += 4;
          }
          return oR;
        case 8:
        case -8:
          if (t === 'f') {
            if (size == 8) oR = __double(this, this.l);else oR = __double([this[this.l + 7], this[this.l + 6], this[this.l + 5], this[this.l + 4], this[this.l + 3], this[this.l + 2], this[this.l + 1], this[this.l + 0]], 0);
            this.l += 8;
            return oR;
          } else size = 8;
        /* falls through */
        case 16:
          o = __hexlify(this, this.l, size);
          break;
      }
  }
  this.l += size;
  return o;
}
var __writeUInt32LE = function (b /*:RawBytes|CFBlob*/, val /*:number*/, idx /*:number*/) /*:void*/{
  b[idx] = val & 0xFF;
  b[idx + 1] = val >>> 8 & 0xFF;
  b[idx + 2] = val >>> 16 & 0xFF;
  b[idx + 3] = val >>> 24 & 0xFF;
};
var __writeInt32LE = function (b /*:RawBytes|CFBlob*/, val /*:number*/, idx /*:number*/) /*:void*/{
  b[idx] = val & 0xFF;
  b[idx + 1] = val >> 8 & 0xFF;
  b[idx + 2] = val >> 16 & 0xFF;
  b[idx + 3] = val >> 24 & 0xFF;
};
var __writeUInt16LE = function (b /*:RawBytes|CFBlob*/, val /*:number*/, idx /*:number*/) /*:void*/{
  b[idx] = val & 0xFF;
  b[idx + 1] = val >>> 8 & 0xFF;
};
function WriteShift(t /*:number*/, val /*:string|number*/, f /*:?string*/) /*:any*/{
  var size = 0,
    i = 0;
  if (f === 'dbcs') {
    /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
    for (i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);
    size = 2 * val.length;
  } else if (f === 'sbcs') {
    if (typeof $cptable !== 'undefined' && current_ansi == 874) {
      /* TODO: use tables directly, don't encode */
      /*:: if(typeof val !== "string") throw new Error("unreachable"); */
      for (i = 0; i != val.length; ++i) {
        var cppayload = $cptable.utils.encode(current_ansi, val.charAt(i));
        this[this.l + i] = cppayload[0];
      }
    } else {
      /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
      val = val.replace(/[^\x00-\x7F]/g, "_");
      /*:: if(typeof val !== 'string') throw new Error("unreachable"); */
      for (i = 0; i != val.length; ++i) this[this.l + i] = val.charCodeAt(i) & 0xFF;
    }
    size = val.length;
  } else if (f === 'hex') {
    for (; i < t; ++i) {
      /*:: if(typeof val !== "string") throw new Error("unreachable"); */
      this[this.l++] = parseInt(val.slice(2 * i, 2 * i + 2), 16) || 0;
    }
    return this;
  } else if (f === 'utf16le') {
    /*:: if(typeof val !== "string") throw new Error("unreachable"); */
    var end /*:number*/ = Math.min(this.l + t, this.length);
    for (i = 0; i < Math.min(val.length, t); ++i) {
      var cc = val.charCodeAt(i);
      this[this.l++] = cc & 0xff;
      this[this.l++] = cc >> 8;
    }
    while (this.l < end) this[this.l++] = 0;
    return this;
  } else /*:: if(typeof val === 'number') */switch (t) {
      case 1:
        size = 1;
        this[this.l] = val & 0xFF;
        break;
      case 2:
        size = 2;
        this[this.l] = val & 0xFF;
        val >>>= 8;
        this[this.l + 1] = val & 0xFF;
        break;
      case 3:
        size = 3;
        this[this.l] = val & 0xFF;
        val >>>= 8;
        this[this.l + 1] = val & 0xFF;
        val >>>= 8;
        this[this.l + 2] = val & 0xFF;
        break;
      case 4:
        size = 4;
        __writeUInt32LE(this, val, this.l);
        break;
      case 8:
        size = 8;
        if (f === 'f') {
          write_double_le(this, val, this.l);
          break;
        }
      /* falls through */
      case 16:
        break;
      case -4:
        size = 4;
        __writeInt32LE(this, val, this.l);
        break;
    }
  this.l += size;
  return this;
}
function CheckField(hexstr /*:string*/, fld /*:string*/) /*:void*/{
  var m = __hexlify(this, this.l, hexstr.length >> 1);
  if (m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);
  this.l += hexstr.length >> 1;
}
function prep_blob(blob, pos /*:number*/) /*:void*/{
  blob.l = pos;
  blob.read_shift = /*::(*/ReadShift /*:: :any)*/;
  blob.chk = CheckField;
  blob.write_shift = WriteShift;
}
function parsenoop(blob, length /*:: :number, opts?:any */) {
  blob.l += length;
}
function new_buf(sz /*:number*/) /*:Block*/{
  var o = new_raw_buf(sz);
  prep_blob(o, 0);
  return o;
}

/* [MS-XLSB] 2.1.4 Record */
function recordhopper(data, cb /*:RecordHopperCB*/, opts /*:?any*/) {
  if (!data) return;
  var tmpbyte, cntbyte, length;
  prep_blob(data, data.l || 0);
  var L = data.length,
    RT = 0,
    tgt = 0;
  while (data.l < L) {
    RT = data.read_shift(1);
    if (RT & 0x80) RT = (RT & 0x7F) + ((data.read_shift(1) & 0x7F) << 7);
    var R = XLSBRecordEnum[RT] || XLSBRecordEnum[0xFFFF];
    tmpbyte = data.read_shift(1);
    length = tmpbyte & 0x7F;
    for (cntbyte = 1; cntbyte < 4 && tmpbyte & 0x80; ++cntbyte) length += ((tmpbyte = data.read_shift(1)) & 0x7F) << 7 * cntbyte;
    tgt = data.l + length;
    var d = R.f && R.f(data, length, opts);
    data.l = tgt;
    if (cb(d, R, RT)) return;
  }
}

/* control buffer usage for fixed-length buffers */
function buf_array() /*:BufArray*/{
  var bufs /*:Array<Block>*/ = [],
    blksz = has_buf ? 256 : 2048;
  var newblk = function ba_newblk(sz /*:number*/) /*:Block*/{
    var o /*:Block*/ = new_buf(sz) /*:any*/;
    prep_blob(o, 0);
    return o;
  };
  var curbuf /*:Block*/ = newblk(blksz);
  var endbuf = function ba_endbuf() {
    if (!curbuf) return;
    if (curbuf.length > curbuf.l) {
      curbuf = curbuf.slice(0, curbuf.l);
      curbuf.l = curbuf.length;
    }
    if (curbuf.length > 0) bufs.push(curbuf);
    curbuf = null;
  };
  var next = function ba_next(sz /*:number*/) /*:Block*/{
    if (curbuf && sz < curbuf.length - curbuf.l) return curbuf;
    endbuf();
    return curbuf = newblk(Math.max(sz + 1, blksz));
  };
  var end = function ba_end() {
    endbuf();
    return bconcat(bufs);
  };
  var push = function ba_push(buf) {
    endbuf();
    curbuf = buf;
    if (curbuf.l == null) curbuf.l = curbuf.length;
    next(blksz);
  };
  return {
    next: next,
    push: push,
    end: end,
    _bufs: bufs
  } /*:any*/;
}
function write_record(ba /*:BufArray*/, type /*:number*/, payload, length /*:?number*/) {
  var t /*:number*/ = +type,
    l;
  if (isNaN(t)) return; // TODO: throw something here?
  if (!length) length = XLSBRecordEnum[t].p || (payload || []).length || 0;
  l = 1 + (t >= 0x80 ? 1 : 0) + 1 /* + length*/;
  if (length >= 0x80) ++l;
  if (length >= 0x4000) ++l;
  if (length >= 0x200000) ++l;
  var o = ba.next(l);
  if (t <= 0x7F) o.write_shift(1, t);else {
    o.write_shift(1, (t & 0x7F) + 0x80);
    o.write_shift(1, t >> 7);
  }
  for (var i = 0; i != 4; ++i) {
    if (length >= 0x80) {
      o.write_shift(1, (length & 0x7F) + 0x80);
      length >>= 7;
    } else {
      o.write_shift(1, length);
      break;
    }
  }
  if (/*:: length != null &&*/length > 0 && is_buf(payload)) ba.push(payload);
}
/* XLS ranges enforced */
function shift_cell_xls(cell /*:CellAddress*/, tgt /*:any*/, opts /*:?any*/) /*:CellAddress*/{
  var out = dup(cell);
  if (tgt.s) {
    if (out.cRel) out.c += tgt.s.c;
    if (out.rRel) out.r += tgt.s.r;
  } else {
    if (out.cRel) out.c += tgt.c;
    if (out.rRel) out.r += tgt.r;
  }
  if (!opts || opts.biff < 12) {
    while (out.c >= 0x100) out.c -= 0x100;
    while (out.r >= 0x10000) out.r -= 0x10000;
  }
  return out;
}
function shift_range_xls(cell, range, opts) {
  var out = dup(cell);
  out.s = shift_cell_xls(out.s, range.s, opts);
  out.e = shift_cell_xls(out.e, range.s, opts);
  return out;
}
function encode_cell_xls(c /*:CellAddress*/, biff /*:number*/) /*:string*/{
  if (c.cRel && c.c < 0) {
    c = dup(c);
    while (c.c < 0) c.c += biff > 8 ? 0x4000 : 0x100;
  }
  if (c.rRel && c.r < 0) {
    c = dup(c);
    while (c.r < 0) c.r += biff > 8 ? 0x100000 : biff > 5 ? 0x10000 : 0x4000;
  }
  var s = encode_cell(c);
  if (!c.cRel && c.cRel != null) s = fix_col(s);
  if (!c.rRel && c.rRel != null) s = fix_row(s);
  return s;
}
function encode_range_xls(r, opts) /*:string*/{
  if (r.s.r == 0 && !r.s.rRel) {
    if (r.e.r == (opts.biff >= 12 ? 0xFFFFF : opts.biff >= 8 ? 0x10000 : 0x4000) && !r.e.rRel) {
      return (r.s.cRel ? "" : "$") + encode_col(r.s.c) + ":" + (r.e.cRel ? "" : "$") + encode_col(r.e.c);
    }
  }
  if (r.s.c == 0 && !r.s.cRel) {
    if (r.e.c == (opts.biff >= 12 ? 0x3FFF : 0xFF) && !r.e.cRel) {
      return (r.s.rRel ? "" : "$") + encode_row(r.s.r) + ":" + (r.e.rRel ? "" : "$") + encode_row(r.e.r);
    }
  }
  return encode_cell_xls(r.s, opts.biff) + ":" + encode_cell_xls(r.e, opts.biff);
}
function decode_row(rowstr /*:string*/) /*:number*/{
  return parseInt(unfix_row(rowstr), 10) - 1;
}
function encode_row(row /*:number*/) /*:string*/{
  return "" + (row + 1);
}
function fix_row(cstr /*:string*/) /*:string*/{
  return cstr.replace(/([A-Z]|^)(\d+)$/, "$1$$$2");
}
function unfix_row(cstr /*:string*/) /*:string*/{
  return cstr.replace(/\$(\d+)$/, "$1");
}
function decode_col(colstr /*:string*/) /*:number*/{
  var c = unfix_col(colstr),
    d = 0,
    i = 0;
  for (; i !== c.length; ++i) d = 26 * d + c.charCodeAt(i) - 64;
  return d - 1;
}
function encode_col(col /*:number*/) /*:string*/{
  if (col < 0) throw new Error("invalid column " + col);
  var s = "";
  for (++col; col; col = Math.floor((col - 1) / 26)) s = String.fromCharCode((col - 1) % 26 + 65) + s;
  return s;
}
function fix_col(cstr /*:string*/) /*:string*/{
  return cstr.replace(/^([A-Z])/, "$$$1");
}
function unfix_col(cstr /*:string*/) /*:string*/{
  return cstr.replace(/^\$([A-Z])/, "$1");
}
function split_cell(cstr /*:string*/) /*:Array<string>*/{
  return cstr.replace(/(\$?[A-Z]*)(\$?\d*)/, "$1,$2").split(",");
}
//function decode_cell(cstr/*:string*/)/*:CellAddress*/ { var splt = split_cell(cstr); return { c:decode_col(splt[0]), r:decode_row(splt[1]) }; }
function decode_cell(cstr /*:string*/) /*:CellAddress*/{
  var R = 0,
    C = 0;
  for (var i = 0; i < cstr.length; ++i) {
    var cc = cstr.charCodeAt(i);
    if (cc >= 48 && cc <= 57) R = 10 * R + (cc - 48);else if (cc >= 65 && cc <= 90) C = 26 * C + (cc - 64);
  }
  return {
    c: C - 1,
    r: R - 1
  };
}
//function encode_cell(cell/*:CellAddress*/)/*:string*/ { return encode_col(cell.c) + encode_row(cell.r); }
function encode_cell(cell /*:CellAddress*/) /*:string*/{
  var col = cell.c + 1;
  var s = "";
  for (; col; col = (col - 1) / 26 | 0) s = String.fromCharCode((col - 1) % 26 + 65) + s;
  return s + (cell.r + 1);
}
function decode_range(range /*:string*/) /*:Range*/{
  var idx = range.indexOf(":");
  if (idx == -1) return {
    s: decode_cell(range),
    e: decode_cell(range)
  };
  return {
    s: decode_cell(range.slice(0, idx)),
    e: decode_cell(range.slice(idx + 1))
  };
}
/*# if only one arg, it is assumed to be a Range.  If 2 args, both are cell addresses */
function encode_range(cs /*:CellAddrSpec|Range*/, ce /*:?CellAddrSpec*/) /*:string*/{
  if (typeof ce === 'undefined' || typeof ce === 'number') {
    /*:: if(!(cs instanceof Range)) throw "unreachable"; */
    return encode_range(cs.s, cs.e);
  }
  /*:: if((cs instanceof Range)) throw "unreachable"; */
  if (typeof cs !== 'string') cs = encode_cell(cs /*:any*/);
  if (typeof ce !== 'string') ce = encode_cell(ce /*:any*/);
  /*:: if(typeof cs !== 'string') throw "unreachable"; */
  /*:: if(typeof ce !== 'string') throw "unreachable"; */
  return cs == ce ? cs : cs + ":" + ce;
}
function safe_decode_range(range /*:string*/) /*:Range*/{
  var o = {
    s: {
      c: 0,
      r: 0
    },
    e: {
      c: 0,
      r: 0
    }
  };
  var idx = 0,
    i = 0,
    cc = 0;
  var len = range.length;
  for (idx = 0; i < len; ++i) {
    if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
    idx = 26 * idx + cc;
  }
  o.s.c = --idx;
  for (idx = 0; i < len; ++i) {
    if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
    idx = 10 * idx + cc;
  }
  o.s.r = --idx;
  if (i === len || cc != 10) {
    o.e.c = o.s.c;
    o.e.r = o.s.r;
    return o;
  }
  ++i;
  for (idx = 0; i != len; ++i) {
    if ((cc = range.charCodeAt(i) - 64) < 1 || cc > 26) break;
    idx = 26 * idx + cc;
  }
  o.e.c = --idx;
  for (idx = 0; i != len; ++i) {
    if ((cc = range.charCodeAt(i) - 48) < 0 || cc > 9) break;
    idx = 10 * idx + cc;
  }
  o.e.r = --idx;
  return o;
}
function safe_format_cell(cell /*:Cell*/, v /*:any*/) {
  var q = cell.t == 'd' && v instanceof Date;
  if (cell.z != null) try {
    return cell.w = SSF_format(cell.z, q ? datenum(v) : v);
  } catch (e) {}
  try {
    return cell.w = SSF_format((cell.XF || {}).numFmtId || (q ? 14 : 0), q ? datenum(v) : v);
  } catch (e) {
    return '' + v;
  }
}
function format_cell(cell /*:Cell*/, v /*:any*/, o /*:any*/) {
  if (cell == null || cell.t == null || cell.t == 'z') return "";
  if (cell.w !== undefined) return cell.w;
  if (cell.t == 'd' && !cell.z && o && o.dateNF) cell.z = o.dateNF;
  if (cell.t == "e") return BErr[cell.v] || cell.v;
  if (v == undefined) return safe_format_cell(cell, cell.v);
  return safe_format_cell(cell, v);
}
function sheet_to_workbook(sheet /*:Worksheet*/, opts) /*:Workbook*/{
  var n = opts && opts.sheet ? opts.sheet : "Sheet1";
  var sheets = {};
  sheets[n] = sheet;
  return {
    SheetNames: [n],
    Sheets: sheets
  };
}
function sheet_add_aoa(_ws /*:?Worksheet*/, data /*:AOA*/, opts /*:?any*/) /*:Worksheet*/{
  var o = opts || {};
  var dense = _ws ? Array.isArray(_ws) : o.dense;
  if (DENSE != null && dense == null) dense = DENSE;
  var ws /*:Worksheet*/ = _ws || (dense ? [] /*:any*/ : {} /*:any*/);
  var _R = 0,
    _C = 0;
  if (ws && o.origin != null) {
    if (typeof o.origin == 'number') _R = o.origin;else {
      var _origin /*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
      _R = _origin.r;
      _C = _origin.c;
    }
    if (!ws["!ref"]) ws["!ref"] = "A1:A1";
  }
  var range /*:Range*/ = {
    s: {
      c: 10000000,
      r: 10000000
    },
    e: {
      c: 0,
      r: 0
    }
  } /*:any*/;
  if (ws['!ref']) {
    var _range = safe_decode_range(ws['!ref']);
    range.s.c = _range.s.c;
    range.s.r = _range.s.r;
    range.e.c = Math.max(range.e.c, _range.e.c);
    range.e.r = Math.max(range.e.r, _range.e.r);
    if (_R == -1) range.e.r = _R = _range.e.r + 1;
  }
  for (var R = 0; R != data.length; ++R) {
    if (!data[R]) continue;
    if (!Array.isArray(data[R])) throw new Error("aoa_to_sheet expects an array of arrays");
    for (var C = 0; C != data[R].length; ++C) {
      if (typeof data[R][C] === 'undefined') continue;
      var cell /*:Cell*/ = {
        v: data[R][C]
      } /*:any*/;
      var __R = _R + R,
        __C = _C + C;
      if (range.s.r > __R) range.s.r = __R;
      if (range.s.c > __C) range.s.c = __C;
      if (range.e.r < __R) range.e.r = __R;
      if (range.e.c < __C) range.e.c = __C;
      if (data[R][C] && typeof data[R][C] === 'object' && !Array.isArray(data[R][C]) && !(data[R][C] instanceof Date)) cell = data[R][C];else {
        if (Array.isArray(cell.v)) {
          cell.f = data[R][C][1];
          cell.v = cell.v[0];
        }
        if (cell.v === null) {
          if (cell.f) cell.t = 'n';else if (o.nullError) {
            cell.t = 'e';
            cell.v = 0;
          } else if (!o.sheetStubs) continue;else cell.t = 'z';
        } else if (typeof cell.v === 'number') cell.t = 'n';else if (typeof cell.v === 'boolean') cell.t = 'b';else if (cell.v instanceof Date) {
          cell.z = o.dateNF || table_fmt[14];
          if (o.cellDates) {
            cell.t = 'd';
            cell.w = SSF_format(cell.z, datenum(cell.v));
          } else {
            cell.t = 'n';
            cell.v = datenum(cell.v);
            cell.w = SSF_format(cell.z, cell.v);
          }
        } else cell.t = 's';
      }
      if (dense) {
        if (!ws[__R]) ws[__R] = [];
        if (ws[__R][__C] && ws[__R][__C].z) cell.z = ws[__R][__C].z;
        ws[__R][__C] = cell;
      } else {
        var cell_ref = encode_cell({
          c: __C,
          r: __R
        } /*:any*/);
        if (ws[cell_ref] && ws[cell_ref].z) cell.z = ws[cell_ref].z;
        ws[cell_ref] = cell;
      }
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = encode_range(range);
  return ws;
}
function aoa_to_sheet(data /*:AOA*/, opts /*:?any*/) /*:Worksheet*/{
  return sheet_add_aoa(null, data, opts);
}
function parse_Int32LE(data) {
  return data.read_shift(4, 'i');
}
function write_UInt32LE(x /*:number*/, o) {
  if (!o) o = new_buf(4);
  o.write_shift(4, x);
  return o;
}

/* [MS-XLSB] 2.5.168 */
function parse_XLWideString(data /*::, length*/) /*:string*/{
  var cchCharacters = data.read_shift(4);
  return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLWideString(data /*:string*/, o) {
  var _null = false;
  if (o == null) {
    _null = true;
    o = new_buf(4 + 2 * data.length);
  }
  o.write_shift(4, data.length);
  if (data.length > 0) o.write_shift(0, data, 'dbcs');
  return _null ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.5.91 */
//function parse_LPWideString(data/*::, length*/)/*:string*/ {
//	var cchCharacters = data.read_shift(2);
//	return cchCharacters === 0 ? "" : data.read_shift(cchCharacters, "utf16le");
//}

/* [MS-XLSB] 2.5.143 */
function parse_StrRun(data) {
  return {
    ich: data.read_shift(2),
    ifnt: data.read_shift(2)
  };
}
function write_StrRun(run, o) {
  if (!o) o = new_buf(4);
  o.write_shift(2, run.ich || 0);
  o.write_shift(2, run.ifnt || 0);
  return o;
}

/* [MS-XLSB] 2.5.121 */
function parse_RichStr(data, length /*:number*/) /*:XLString*/{
  var start = data.l;
  var flags = data.read_shift(1);
  var str = parse_XLWideString(data);
  var rgsStrRun = [];
  var z = {
    t: str,
    h: str
  } /*:any*/;
  if ((flags & 1) !== 0) {
    /* fRichStr */
    /* TODO: formatted string */
    var dwSizeStrRun = data.read_shift(4);
    for (var i = 0; i != dwSizeStrRun; ++i) rgsStrRun.push(parse_StrRun(data));
    z.r = rgsStrRun;
  } else z.r = [{
    ich: 0,
    ifnt: 0
  }];
  //if((flags & 2) !== 0) { /* fExtStr */
  //	/* TODO: phonetic string */
  //}
  data.l = start + length;
  return z;
}
function write_RichStr(str /*:XLString*/, o /*:?Block*/) /*:Block*/{
  /* TODO: formatted string */
  var _null = false;
  if (o == null) {
    _null = true;
    o = new_buf(15 + 4 * str.t.length);
  }
  o.write_shift(1, 0);
  write_XLWideString(str.t, o);
  return _null ? o.slice(0, o.l) : o;
}
/* [MS-XLSB] 2.4.328 BrtCommentText (RichStr w/1 run) */
var parse_BrtCommentText = parse_RichStr;
function write_BrtCommentText(str /*:XLString*/, o /*:?Block*/) /*:Block*/{
  /* TODO: formatted string */
  var _null = false;
  if (o == null) {
    _null = true;
    o = new_buf(23 + 4 * str.t.length);
  }
  o.write_shift(1, 1);
  write_XLWideString(str.t, o);
  o.write_shift(4, 1);
  write_StrRun({
    ich: 0,
    ifnt: 0
  }, o);
  return _null ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.5.9 */
function parse_XLSBCell(data) /*:any*/{
  var col = data.read_shift(4);
  var iStyleRef = data.read_shift(2);
  iStyleRef += data.read_shift(1) << 16;
  data.l++; //var fPhShow = data.read_shift(1);
  return {
    c: col,
    iStyleRef: iStyleRef
  };
}
function write_XLSBCell(cell /*:any*/, o /*:?Block*/) {
  if (o == null) o = new_buf(8);
  o.write_shift(-4, cell.c);
  o.write_shift(3, cell.iStyleRef || cell.s);
  o.write_shift(1, 0); /* fPhShow */
  return o;
}

/* Short XLSB Cell does not include column */
function parse_XLSBShortCell(data) /*:any*/{
  var iStyleRef = data.read_shift(2);
  iStyleRef += data.read_shift(1) << 16;
  data.l++; //var fPhShow = data.read_shift(1);
  return {
    c: -1,
    iStyleRef: iStyleRef
  };
}
function write_XLSBShortCell(cell /*:any*/, o /*:?Block*/) {
  if (o == null) o = new_buf(4);
  o.write_shift(3, cell.iStyleRef || cell.s);
  o.write_shift(1, 0); /* fPhShow */
  return o;
}

/* [MS-XLSB] 2.5.21 */
var parse_XLSBCodeName = parse_XLWideString;
var write_XLSBCodeName = write_XLWideString;

/* [MS-XLSB] 2.5.166 */
function parse_XLNullableWideString(data /*::, length*/) /*:string*/{
  var cchCharacters = data.read_shift(4);
  return cchCharacters === 0 || cchCharacters === 0xFFFFFFFF ? "" : data.read_shift(cchCharacters, 'dbcs');
}
function write_XLNullableWideString(data /*:string*/, o) {
  var _null = false;
  if (o == null) {
    _null = true;
    o = new_buf(127);
  }
  o.write_shift(4, data.length > 0 ? data.length : 0xFFFFFFFF);
  if (data.length > 0) o.write_shift(0, data, 'dbcs');
  return _null ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.5.165 */
var parse_XLNameWideString = parse_XLWideString;
//var write_XLNameWideString = write_XLWideString;

/* [MS-XLSB] 2.5.114 */
var parse_RelID = parse_XLNullableWideString;
var write_RelID = write_XLNullableWideString;

/* [MS-XLS] 2.5.217 ; [MS-XLSB] 2.5.122 */
function parse_RkNumber(data) /*:number*/{
  var b = data.slice(data.l, data.l + 4);
  var fX100 = b[0] & 1,
    fInt = b[0] & 2;
  data.l += 4;
  var RK = fInt === 0 ? __double([0, 0, 0, 0, b[0] & 0xFC, b[1], b[2], b[3]], 0) : __readInt32LE(b, 0) >> 2;
  return fX100 ? RK / 100 : RK;
}
function write_RkNumber(data /*:number*/, o) {
  if (o == null) o = new_buf(4);
  var fX100 = 0,
    fInt = 0,
    d100 = data * 100;
  if (data == (data | 0) && data >= -(1 << 29) && data < 1 << 29) {
    fInt = 1;
  } else if (d100 == (d100 | 0) && d100 >= -(1 << 29) && d100 < 1 << 29) {
    fInt = 1;
    fX100 = 1;
  }
  if (fInt) o.write_shift(-4, ((fX100 ? d100 : data) << 2) + (fX100 + 2));else throw new Error("unsupported RkNumber " + data); // TODO
}

/* [MS-XLSB] 2.5.117 RfX */
function parse_RfX(data /*::, length*/) /*:Range*/{
  var cell /*:Range*/ = {
    s: {},
    e: {}
  } /*:any*/;
  cell.s.r = data.read_shift(4);
  cell.e.r = data.read_shift(4);
  cell.s.c = data.read_shift(4);
  cell.e.c = data.read_shift(4);
  return cell;
}
function write_RfX(r /*:Range*/, o) {
  if (!o) o = new_buf(16);
  o.write_shift(4, r.s.r);
  o.write_shift(4, r.e.r);
  o.write_shift(4, r.s.c);
  o.write_shift(4, r.e.c);
  return o;
}

/* [MS-XLSB] 2.5.153 UncheckedRfX */
var parse_UncheckedRfX = parse_RfX;
var write_UncheckedRfX = write_RfX;

/* [MS-XLSB] 2.5.155 UncheckedSqRfX */
//function parse_UncheckedSqRfX(data) {
//	var cnt = data.read_shift(4);
//	var out = [];
//	for(var i = 0; i < cnt; ++i) {
//		var rng = parse_UncheckedRfX(data);
//		out.push(encode_range(rng));
//	}
//	return out.join(",");
//}
//function write_UncheckedSqRfX(sqrfx/*:string*/) {
//	var parts = sqrfx.split(/\s*,\s*/);
//	var o = new_buf(4); o.write_shift(4, parts.length);
//	var out = [o];
//	parts.forEach(function(rng) {
//		out.push(write_UncheckedRfX(safe_decode_range(rng)));
//	});
//	return bconcat(out);
//}

/* [MS-XLS] 2.5.342 ; [MS-XLSB] 2.5.171 */
/* TODO: error checking, NaN and Infinity values are not valid Xnum */
function parse_Xnum(data /*::, length*/) {
  if (data.length - data.l < 8) throw "XLS Xnum Buffer underflow";
  return data.read_shift(8, 'f');
}
function write_Xnum(data, o) {
  return (o || new_buf(8)).write_shift(8, data, 'f');
}

/* [MS-XLSB] 2.4.324 BrtColor */
function parse_BrtColor(data /*::, length*/) {
  var out = {};
  var d = data.read_shift(1);

  //var fValidRGB = d & 1;
  var xColorType = d >>> 1;
  var index = data.read_shift(1);
  var nTS = data.read_shift(2, 'i');
  var bR = data.read_shift(1);
  var bG = data.read_shift(1);
  var bB = data.read_shift(1);
  data.l++; //var bAlpha = data.read_shift(1);

  switch (xColorType) {
    case 0:
      out.auto = 1;
      break;
    case 1:
      out.index = index;
      var icv = XLSIcv[index];
      /* automatic pseudo index 81 */
      if (icv) out.rgb = rgb2Hex(icv);
      break;
    case 2:
      /* if(!fValidRGB) throw new Error("invalid"); */
      out.rgb = rgb2Hex([bR, bG, bB]);
      break;
    case 3:
      out.theme = index;
      break;
  }
  if (nTS != 0) out.tint = nTS > 0 ? nTS / 32767 : nTS / 32768;
  return out;
}
function write_BrtColor(color, o) {
  if (!o) o = new_buf(8);
  if (!color || color.auto) {
    o.write_shift(4, 0);
    o.write_shift(4, 0);
    return o;
  }
  if (color.index != null) {
    o.write_shift(1, 0x02);
    o.write_shift(1, color.index);
  } else if (color.theme != null) {
    o.write_shift(1, 0x06);
    o.write_shift(1, color.theme);
  } else {
    o.write_shift(1, 0x05);
    o.write_shift(1, 0);
  }
  var nTS = color.tint || 0;
  if (nTS > 0) nTS *= 32767;else if (nTS < 0) nTS *= 32768;
  o.write_shift(2, nTS);
  if (!color.rgb || color.theme != null) {
    o.write_shift(2, 0);
    o.write_shift(1, 0);
    o.write_shift(1, 0);
  } else {
    var rgb = color.rgb || 'FFFFFF';
    if (typeof rgb == 'number') rgb = ("000000" + rgb.toString(16)).slice(-6);
    o.write_shift(1, parseInt(rgb.slice(0, 2), 16));
    o.write_shift(1, parseInt(rgb.slice(2, 4), 16));
    o.write_shift(1, parseInt(rgb.slice(4, 6), 16));
    o.write_shift(1, 0xFF);
  }
  return o;
}

/* [MS-XLSB] 2.5.52 */
function parse_FontFlags(data /*::, length, opts*/) {
  var d = data.read_shift(1);
  data.l++;
  var out = {
    fBold: d & 0x01,
    fItalic: d & 0x02,
    fUnderline: d & 0x04,
    fStrikeout: d & 0x08,
    fOutline: d & 0x10,
    fShadow: d & 0x20,
    fCondense: d & 0x40,
    fExtend: d & 0x80
  };
  return out;
}
function write_FontFlags(font, o) {
  if (!o) o = new_buf(2);
  var grbit = (font.italic ? 0x02 : 0) | (font.strike ? 0x08 : 0) | (font.outline ? 0x10 : 0) | (font.shadow ? 0x20 : 0) | (font.condense ? 0x40 : 0) | (font.extend ? 0x80 : 0);
  o.write_shift(1, grbit);
  o.write_shift(1, 0);
  return o;
}

/* [MS-OLEDS] 2.3.1 and 2.3.2 */
function parse_ClipboardFormatOrString(o, w /*:number*/) /*:string*/{
  // $FlowIgnore
  var ClipFmt = {
    2: "BITMAP",
    3: "METAFILEPICT",
    8: "DIB",
    14: "ENHMETAFILE"
  };
  var m /*:number*/ = o.read_shift(4);
  switch (m) {
    case 0x00000000:
      return "";
    case 0xffffffff:
    case 0xfffffffe:
      return ClipFmt[o.read_shift(4)] || "";
  }
  if (m > 0x190) throw new Error("Unsupported Clipboard: " + m.toString(16));
  o.l -= 4;
  return o.read_shift(0, w == 1 ? "lpstr" : "lpwstr");
}
function parse_ClipboardFormatOrAnsiString(o) {
  return parse_ClipboardFormatOrString(o, 1);
}
function parse_ClipboardFormatOrUnicodeString(o) {
  return parse_ClipboardFormatOrString(o, 2);
}

/* [MS-OLEPS] 2.2 PropertyType */
// Note: some tree shakers cannot handle VT_VECTOR | $CONST, hence extra vars
//var VT_EMPTY    = 0x0000;
//var VT_NULL     = 0x0001;
var VT_I2 = 0x0002;
var VT_I4 = 0x0003;
//var VT_R4       = 0x0004;
//var VT_R8       = 0x0005;
//var VT_CY       = 0x0006;
//var VT_DATE     = 0x0007;
//var VT_BSTR     = 0x0008;
//var VT_ERROR    = 0x000A;
var VT_BOOL = 0x000B;
var VT_VARIANT = 0x000C;
//var VT_DECIMAL  = 0x000E;
//var VT_I1       = 0x0010;
//var VT_UI1      = 0x0011;
//var VT_UI2      = 0x0012;
var VT_UI4 = 0x0013;
//var VT_I8       = 0x0014;
//var VT_UI8      = 0x0015;
//var VT_INT      = 0x0016;
//var VT_UINT     = 0x0017;
var VT_LPSTR = 0x001E;
//var VT_LPWSTR   = 0x001F;
var VT_FILETIME = 0x0040;
var VT_BLOB = 0x0041;
//var VT_STREAM   = 0x0042;
//var VT_STORAGE  = 0x0043;
//var VT_STREAMED_Object  = 0x0044;
//var VT_STORED_Object    = 0x0045;
//var VT_BLOB_Object      = 0x0046;
var VT_CF = 0x0047;
//var VT_CLSID    = 0x0048;
//var VT_VERSIONED_STREAM = 0x0049;
var VT_VECTOR = 0x1000;
var VT_VECTOR_VARIANT = 0x100C;
var VT_VECTOR_LPSTR = 0x101E;
//var VT_ARRAY    = 0x2000;

var VT_STRING = 0x0050; // 2.3.3.1.11 VtString
var VT_USTR = 0x0051; // 2.3.3.1.12 VtUnalignedString
var VT_CUSTOM = [VT_STRING, VT_USTR];

/* [MS-OSHARED] 2.3.3.2.2.1 Document Summary Information PIDDSI */
var DocSummaryPIDDSI = {
  /*::[*/0x01 /*::]*/: {
    n: 'CodePage',
    t: VT_I2
  },
  /*::[*/0x02 /*::]*/: {
    n: 'Category',
    t: VT_STRING
  },
  /*::[*/0x03 /*::]*/: {
    n: 'PresentationFormat',
    t: VT_STRING
  },
  /*::[*/0x04 /*::]*/: {
    n: 'ByteCount',
    t: VT_I4
  },
  /*::[*/0x05 /*::]*/: {
    n: 'LineCount',
    t: VT_I4
  },
  /*::[*/0x06 /*::]*/: {
    n: 'ParagraphCount',
    t: VT_I4
  },
  /*::[*/0x07 /*::]*/: {
    n: 'SlideCount',
    t: VT_I4
  },
  /*::[*/0x08 /*::]*/: {
    n: 'NoteCount',
    t: VT_I4
  },
  /*::[*/0x09 /*::]*/: {
    n: 'HiddenCount',
    t: VT_I4
  },
  /*::[*/0x0a /*::]*/: {
    n: 'MultimediaClipCount',
    t: VT_I4
  },
  /*::[*/0x0b /*::]*/: {
    n: 'ScaleCrop',
    t: VT_BOOL
  },
  /*::[*/0x0c /*::]*/: {
    n: 'HeadingPairs',
    t: VT_VECTOR_VARIANT /* VT_VECTOR | VT_VARIANT */
  },
  /*::[*/0x0d /*::]*/: {
    n: 'TitlesOfParts',
    t: VT_VECTOR_LPSTR /* VT_VECTOR | VT_LPSTR */
  },
  /*::[*/0x0e /*::]*/: {
    n: 'Manager',
    t: VT_STRING
  },
  /*::[*/0x0f /*::]*/: {
    n: 'Company',
    t: VT_STRING
  },
  /*::[*/0x10 /*::]*/: {
    n: 'LinksUpToDate',
    t: VT_BOOL
  },
  /*::[*/0x11 /*::]*/: {
    n: 'CharacterCount',
    t: VT_I4
  },
  /*::[*/0x13 /*::]*/: {
    n: 'SharedDoc',
    t: VT_BOOL
  },
  /*::[*/0x16 /*::]*/: {
    n: 'HyperlinksChanged',
    t: VT_BOOL
  },
  /*::[*/0x17 /*::]*/: {
    n: 'AppVersion',
    t: VT_I4,
    p: 'version'
  },
  /*::[*/0x18 /*::]*/: {
    n: 'DigSig',
    t: VT_BLOB
  },
  /*::[*/0x1A /*::]*/: {
    n: 'ContentType',
    t: VT_STRING
  },
  /*::[*/0x1B /*::]*/: {
    n: 'ContentStatus',
    t: VT_STRING
  },
  /*::[*/0x1C /*::]*/: {
    n: 'Language',
    t: VT_STRING
  },
  /*::[*/0x1D /*::]*/: {
    n: 'Version',
    t: VT_STRING
  },
  /*::[*/0xFF /*::]*/: {},
  /* [MS-OLEPS] 2.18 */
  /*::[*/0x80000000 /*::]*/: {
    n: 'Locale',
    t: VT_UI4
  },
  /*::[*/0x80000003 /*::]*/: {
    n: 'Behavior',
    t: VT_UI4
  },
  /*::[*/0x72627262 /*::]*/: {}
};

/* [MS-OSHARED] 2.3.3.2.1.1 Summary Information Property Set PIDSI */
var SummaryPIDSI = {
  /*::[*/0x01 /*::]*/: {
    n: 'CodePage',
    t: VT_I2
  },
  /*::[*/0x02 /*::]*/: {
    n: 'Title',
    t: VT_STRING
  },
  /*::[*/0x03 /*::]*/: {
    n: 'Subject',
    t: VT_STRING
  },
  /*::[*/0x04 /*::]*/: {
    n: 'Author',
    t: VT_STRING
  },
  /*::[*/0x05 /*::]*/: {
    n: 'Keywords',
    t: VT_STRING
  },
  /*::[*/0x06 /*::]*/: {
    n: 'Comments',
    t: VT_STRING
  },
  /*::[*/0x07 /*::]*/: {
    n: 'Template',
    t: VT_STRING
  },
  /*::[*/0x08 /*::]*/: {
    n: 'LastAuthor',
    t: VT_STRING
  },
  /*::[*/0x09 /*::]*/: {
    n: 'RevNumber',
    t: VT_STRING
  },
  /*::[*/0x0A /*::]*/: {
    n: 'EditTime',
    t: VT_FILETIME
  },
  /*::[*/0x0B /*::]*/: {
    n: 'LastPrinted',
    t: VT_FILETIME
  },
  /*::[*/0x0C /*::]*/: {
    n: 'CreatedDate',
    t: VT_FILETIME
  },
  /*::[*/0x0D /*::]*/: {
    n: 'ModifiedDate',
    t: VT_FILETIME
  },
  /*::[*/0x0E /*::]*/: {
    n: 'PageCount',
    t: VT_I4
  },
  /*::[*/0x0F /*::]*/: {
    n: 'WordCount',
    t: VT_I4
  },
  /*::[*/0x10 /*::]*/: {
    n: 'CharCount',
    t: VT_I4
  },
  /*::[*/0x11 /*::]*/: {
    n: 'Thumbnail',
    t: VT_CF
  },
  /*::[*/0x12 /*::]*/: {
    n: 'Application',
    t: VT_STRING
  },
  /*::[*/0x13 /*::]*/: {
    n: 'DocSecurity',
    t: VT_I4
  },
  /*::[*/0xFF /*::]*/: {},
  /* [MS-OLEPS] 2.18 */
  /*::[*/0x80000000 /*::]*/: {
    n: 'Locale',
    t: VT_UI4
  },
  /*::[*/0x80000003 /*::]*/: {
    n: 'Behavior',
    t: VT_UI4
  },
  /*::[*/0x72627262 /*::]*/: {}
};

/* [MS-XLS] 2.4.63 Country/Region codes */
var CountryEnum = {
  /*::[*/0x0001 /*::]*/: "US",
  // United States
  /*::[*/
  0x0002 /*::]*/: "CA",
  // Canada
  /*::[*/
  0x0003 /*::]*/: "",
  // Latin America (except Brazil)
  /*::[*/
  0x0007 /*::]*/: "RU",
  // Russia
  /*::[*/
  0x0014 /*::]*/: "EG",
  // Egypt
  /*::[*/
  0x001E /*::]*/: "GR",
  // Greece
  /*::[*/
  0x001F /*::]*/: "NL",
  // Netherlands
  /*::[*/
  0x0020 /*::]*/: "BE",
  // Belgium
  /*::[*/
  0x0021 /*::]*/: "FR",
  // France
  /*::[*/
  0x0022 /*::]*/: "ES",
  // Spain
  /*::[*/
  0x0024 /*::]*/: "HU",
  // Hungary
  /*::[*/
  0x0027 /*::]*/: "IT",
  // Italy
  /*::[*/
  0x0029 /*::]*/: "CH",
  // Switzerland
  /*::[*/
  0x002B /*::]*/: "AT",
  // Austria
  /*::[*/
  0x002C /*::]*/: "GB",
  // United Kingdom
  /*::[*/
  0x002D /*::]*/: "DK",
  // Denmark
  /*::[*/
  0x002E /*::]*/: "SE",
  // Sweden
  /*::[*/
  0x002F /*::]*/: "NO",
  // Norway
  /*::[*/
  0x0030 /*::]*/: "PL",
  // Poland
  /*::[*/
  0x0031 /*::]*/: "DE",
  // Germany
  /*::[*/
  0x0034 /*::]*/: "MX",
  // Mexico
  /*::[*/
  0x0037 /*::]*/: "BR",
  // Brazil
  /*::[*/
  0x003d /*::]*/: "AU",
  // Australia
  /*::[*/
  0x0040 /*::]*/: "NZ",
  // New Zealand
  /*::[*/
  0x0042 /*::]*/: "TH",
  // Thailand
  /*::[*/
  0x0051 /*::]*/: "JP",
  // Japan
  /*::[*/
  0x0052 /*::]*/: "KR",
  // Korea
  /*::[*/
  0x0054 /*::]*/: "VN",
  // Viet Nam
  /*::[*/
  0x0056 /*::]*/: "CN",
  // China
  /*::[*/
  0x005A /*::]*/: "TR",
  // Turkey
  /*::[*/
  0x0069 /*::]*/: "JS",
  // Ramastan
  /*::[*/
  0x00D5 /*::]*/: "DZ",
  // Algeria
  /*::[*/
  0x00D8 /*::]*/: "MA",
  // Morocco
  /*::[*/
  0x00DA /*::]*/: "LY",
  // Libya
  /*::[*/
  0x015F /*::]*/: "PT",
  // Portugal
  /*::[*/
  0x0162 /*::]*/: "IS",
  // Iceland
  /*::[*/
  0x0166 /*::]*/: "FI",
  // Finland
  /*::[*/
  0x01A4 /*::]*/: "CZ",
  // Czech Republic
  /*::[*/
  0x0376 /*::]*/: "TW",
  // Taiwan
  /*::[*/
  0x03C1 /*::]*/: "LB",
  // Lebanon
  /*::[*/
  0x03C2 /*::]*/: "JO",
  // Jordan
  /*::[*/
  0x03C3 /*::]*/: "SY",
  // Syria
  /*::[*/
  0x03C4 /*::]*/: "IQ",
  // Iraq
  /*::[*/
  0x03C5 /*::]*/: "KW",
  // Kuwait
  /*::[*/
  0x03C6 /*::]*/: "SA",
  // Saudi Arabia
  /*::[*/
  0x03CB /*::]*/: "AE",
  // United Arab Emirates
  /*::[*/
  0x03CC /*::]*/: "IL",
  // Israel
  /*::[*/
  0x03CE /*::]*/: "QA",
  // Qatar
  /*::[*/
  0x03D5 /*::]*/: "IR",
  // Iran
  /*::[*/
  0xFFFF /*::]*/: "US" // United States
};

/* [MS-XLS] 2.5.127 */
var XLSFillPattern = [null, 'solid', 'mediumGray', 'darkGray', 'lightGray', 'darkHorizontal', 'darkVertical', 'darkDown', 'darkUp', 'darkGrid', 'darkTrellis', 'lightHorizontal', 'lightVertical', 'lightDown', 'lightUp', 'lightGrid', 'lightTrellis', 'gray125', 'gray0625'];
function rgbify(arr /*:Array<number>*/) /*:Array<[number, number, number]>*/{
  return arr.map(function (x) {
    return [x >> 16 & 255, x >> 8 & 255, x & 255];
  });
}

/* [MS-XLS] 2.5.161 */
/* [MS-XLSB] 2.5.75 Icv */
var _XLSIcv = /*#__PURE__*/rgbify([/* Color Constants */
0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, /* Overridable Defaults */
0x000000, 0xFFFFFF, 0xFF0000, 0x00FF00, 0x0000FF, 0xFFFF00, 0xFF00FF, 0x00FFFF, 0x800000, 0x008000, 0x000080, 0x808000, 0x800080, 0x008080, 0xC0C0C0, 0x808080, 0x9999FF, 0x993366, 0xFFFFCC, 0xCCFFFF, 0x660066, 0xFF8080, 0x0066CC, 0xCCCCFF, 0x000080, 0xFF00FF, 0xFFFF00, 0x00FFFF, 0x800080, 0x800000, 0x008080, 0x0000FF, 0x00CCFF, 0xCCFFFF, 0xCCFFCC, 0xFFFF99, 0x99CCFF, 0xFF99CC, 0xCC99FF, 0xFFCC99, 0x3366FF, 0x33CCCC, 0x99CC00, 0xFFCC00, 0xFF9900, 0xFF6600, 0x666699, 0x969696, 0x003366, 0x339966, 0x003300, 0x333300, 0x993300, 0x993366, 0x333399, 0x333333, /* Other entries to appease BIFF8/12 */
0xFFFFFF, /* 0x40 icvForeground ?? */
0x000000, /* 0x41 icvBackground ?? */
0x000000, /* 0x42 icvFrame ?? */
0x000000, /* 0x43 icv3D ?? */
0x000000, /* 0x44 icv3DText ?? */
0x000000, /* 0x45 icv3DHilite ?? */
0x000000, /* 0x46 icv3DShadow ?? */
0x000000, /* 0x47 icvHilite ?? */
0x000000, /* 0x48 icvCtlText ?? */
0x000000, /* 0x49 icvCtlScrl ?? */
0x000000, /* 0x4A icvCtlInv ?? */
0x000000, /* 0x4B icvCtlBody ?? */
0x000000, /* 0x4C icvCtlFrame ?? */
0x000000, /* 0x4D icvCtlFore ?? */
0x000000, /* 0x4E icvCtlBack ?? */
0x000000, /* 0x4F icvCtlNeutral */
0x000000, /* 0x50 icvInfoBk ?? */
0x000000 /* 0x51 icvInfoText ?? */]);
var XLSIcv = /*#__PURE__*/dup(_XLSIcv);

/* [MS-XLSB] 2.5.97.2 */
var BErr = {
  /*::[*/0x00 /*::]*/: "#NULL!",
  /*::[*/0x07 /*::]*/: "#DIV/0!",
  /*::[*/0x0F /*::]*/: "#VALUE!",
  /*::[*/0x17 /*::]*/: "#REF!",
  /*::[*/0x1D /*::]*/: "#NAME?",
  /*::[*/0x24 /*::]*/: "#NUM!",
  /*::[*/0x2A /*::]*/: "#N/A",
  /*::[*/0x2B /*::]*/: "#GETTING_DATA",
  /*::[*/0xFF /*::]*/: "#WTF?"
};
//var RBErr = evert_num(BErr);
var RBErr = {
  "#NULL!": 0x00,
  "#DIV/0!": 0x07,
  "#VALUE!": 0x0F,
  "#REF!": 0x17,
  "#NAME?": 0x1D,
  "#NUM!": 0x24,
  "#N/A": 0x2A,
  "#GETTING_DATA": 0x2B,
  "#WTF?": 0xFF
};

/* Parts enumerated in OPC spec, MS-XLSB and MS-XLSX */
/* 12.3 Part Summary <SpreadsheetML> */
/* 14.2 Part Summary <DrawingML> */
/* [MS-XLSX] 2.1 Part Enumerations ; [MS-XLSB] 2.1.7 Part Enumeration */
var ct2type /*{[string]:string}*/ = {
  /* Workbook */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml": "workbooks",
  "application/vnd.ms-excel.sheet.macroEnabled.main+xml": "workbooks",
  "application/vnd.ms-excel.sheet.binary.macroEnabled.main": "workbooks",
  "application/vnd.ms-excel.addin.macroEnabled.main+xml": "workbooks",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml": "workbooks",
  /* Worksheet */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml": "sheets",
  "application/vnd.ms-excel.worksheet": "sheets",
  "application/vnd.ms-excel.binIndexWs": "TODO",
  /* Binary Index */

  /* Chartsheet */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml": "charts",
  "application/vnd.ms-excel.chartsheet": "charts",
  /* Macrosheet */
  "application/vnd.ms-excel.macrosheet+xml": "macros",
  "application/vnd.ms-excel.macrosheet": "macros",
  "application/vnd.ms-excel.intlmacrosheet": "TODO",
  "application/vnd.ms-excel.binIndexMs": "TODO",
  /* Binary Index */

  /* Dialogsheet */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml": "dialogs",
  "application/vnd.ms-excel.dialogsheet": "dialogs",
  /* Shared Strings */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml": "strs",
  "application/vnd.ms-excel.sharedStrings": "strs",
  /* Styles */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml": "styles",
  "application/vnd.ms-excel.styles": "styles",
  /* File Properties */
  "application/vnd.openxmlformats-package.core-properties+xml": "coreprops",
  "application/vnd.openxmlformats-officedocument.custom-properties+xml": "custprops",
  "application/vnd.openxmlformats-officedocument.extended-properties+xml": "extprops",
  /* Custom Data Properties */
  "application/vnd.openxmlformats-officedocument.customXmlProperties+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.customProperty": "TODO",
  /* Comments */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml": "comments",
  "application/vnd.ms-excel.comments": "comments",
  "application/vnd.ms-excel.threadedcomments+xml": "threadedcomments",
  "application/vnd.ms-excel.person+xml": "people",
  /* Metadata (Stock/Geography and Dynamic Array) */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml": "metadata",
  "application/vnd.ms-excel.sheetMetadata": "metadata",
  /* PivotTable */
  "application/vnd.ms-excel.pivotTable": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml": "TODO",
  /* Chart Objects */
  "application/vnd.openxmlformats-officedocument.drawingml.chart+xml": "TODO",
  /* Chart Colors */
  "application/vnd.ms-office.chartcolorstyle+xml": "TODO",
  /* Chart Style */
  "application/vnd.ms-office.chartstyle+xml": "TODO",
  /* Chart Advanced */
  "application/vnd.ms-office.chartex+xml": "TODO",
  /* Calculation Chain */
  "application/vnd.ms-excel.calcChain": "calcchains",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml": "calcchains",
  /* Printer Settings */
  "application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings": "TODO",
  /* ActiveX */
  "application/vnd.ms-office.activeX": "TODO",
  "application/vnd.ms-office.activeX+xml": "TODO",
  /* Custom Toolbars */
  "application/vnd.ms-excel.attachedToolbars": "TODO",
  /* External Data Connections */
  "application/vnd.ms-excel.connections": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml": "TODO",
  /* External Links */
  "application/vnd.ms-excel.externalLink": "links",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml": "links",
  /* PivotCache */
  "application/vnd.ms-excel.pivotCacheDefinition": "TODO",
  "application/vnd.ms-excel.pivotCacheRecords": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml": "TODO",
  /* Query Table */
  "application/vnd.ms-excel.queryTable": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml": "TODO",
  /* Shared Workbook */
  "application/vnd.ms-excel.userNames": "TODO",
  "application/vnd.ms-excel.revisionHeaders": "TODO",
  "application/vnd.ms-excel.revisionLog": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml": "TODO",
  /* Single Cell Table */
  "application/vnd.ms-excel.tableSingleCells": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml": "TODO",
  /* Slicer */
  "application/vnd.ms-excel.slicer": "TODO",
  "application/vnd.ms-excel.slicerCache": "TODO",
  "application/vnd.ms-excel.slicer+xml": "TODO",
  "application/vnd.ms-excel.slicerCache+xml": "TODO",
  /* Sort Map */
  "application/vnd.ms-excel.wsSortMap": "TODO",
  /* Table */
  "application/vnd.ms-excel.table": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml": "TODO",
  /* Themes */
  "application/vnd.openxmlformats-officedocument.theme+xml": "themes",
  /* Theme Override */
  "application/vnd.openxmlformats-officedocument.themeOverride+xml": "TODO",
  /* Timeline */
  "application/vnd.ms-excel.Timeline+xml": "TODO",
  /* verify */
  "application/vnd.ms-excel.TimelineCache+xml": "TODO",
  /* verify */

  /* VBA */
  "application/vnd.ms-office.vbaProject": "vba",
  "application/vnd.ms-office.vbaProjectSignature": "TODO",
  /* Volatile Dependencies */
  "application/vnd.ms-office.volatileDependencies": "TODO",
  "application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml": "TODO",
  /* Control Properties */
  "application/vnd.ms-excel.controlproperties+xml": "TODO",
  /* Data Model */
  "application/vnd.openxmlformats-officedocument.model+data": "TODO",
  /* Survey */
  "application/vnd.ms-excel.Survey+xml": "TODO",
  /* Drawing */
  "application/vnd.openxmlformats-officedocument.drawing+xml": "drawings",
  "application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml": "TODO",
  "application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml": "TODO",
  /* VML */
  "application/vnd.openxmlformats-officedocument.vmlDrawing": "TODO",
  "application/vnd.openxmlformats-package.relationships+xml": "rels",
  "application/vnd.openxmlformats-officedocument.oleObject": "TODO",
  /* Image */
  "image/png": "TODO",
  "sheet": "js"
} /*:any*/;
var CT_LIST = {
  workbooks: {
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
    xlsm: "application/vnd.ms-excel.sheet.macroEnabled.main+xml",
    xlsb: "application/vnd.ms-excel.sheet.binary.macroEnabled.main",
    xlam: "application/vnd.ms-excel.addin.macroEnabled.main+xml",
    xltx: "application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml"
  },
  strs: {
    /* Shared Strings */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
    xlsb: "application/vnd.ms-excel.sharedStrings"
  },
  comments: {
    /* Comments */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
    xlsb: "application/vnd.ms-excel.comments"
  },
  sheets: {
    /* Worksheet */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
    xlsb: "application/vnd.ms-excel.worksheet"
  },
  charts: {
    /* Chartsheet */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
    xlsb: "application/vnd.ms-excel.chartsheet"
  },
  dialogs: {
    /* Dialogsheet */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",
    xlsb: "application/vnd.ms-excel.dialogsheet"
  },
  macros: {
    /* Macrosheet (Excel 4.0 Macros) */
    xlsx: "application/vnd.ms-excel.macrosheet+xml",
    xlsb: "application/vnd.ms-excel.macrosheet"
  },
  metadata: {
    /* Metadata (Stock/Geography and Dynamic Array) */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
    xlsb: "application/vnd.ms-excel.sheetMetadata"
  },
  styles: {
    /* Styles */
    xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
    xlsb: "application/vnd.ms-excel.styles"
  }
};
function new_ct() /*:any*/{
  return {
    workbooks: [],
    sheets: [],
    charts: [],
    dialogs: [],
    macros: [],
    rels: [],
    strs: [],
    comments: [],
    threadedcomments: [],
    links: [],
    coreprops: [],
    extprops: [],
    custprops: [],
    themes: [],
    styles: [],
    calcchains: [],
    vba: [],
    drawings: [],
    metadata: [],
    people: [],
    TODO: [],
    xmlns: ""
  } /*:any*/;
}
function parse_ct(data /*:?string*/) {
  var ct = new_ct();
  if (!data || !data.match) return ct;
  var ctext = {};
  (data.match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (y[0].replace(nsregex, "<")) {
      case '<?xml':
        break;
      case '<Types':
        ct.xmlns = y['xmlns' + (y[0].match(/<(\w+):/) || ["", ""])[1]];
        break;
      case '<Default':
        ctext[y.Extension] = y.ContentType;
        break;
      case '<Override':
        if (ct[ct2type[y.ContentType]] !== undefined) ct[ct2type[y.ContentType]].push(y.PartName);
        break;
    }
  });
  if (ct.xmlns !== XMLNS.CT) throw new Error("Unknown Namespace: " + ct.xmlns);
  ct.calcchain = ct.calcchains.length > 0 ? ct.calcchains[0] : "";
  ct.sst = ct.strs.length > 0 ? ct.strs[0] : "";
  ct.style = ct.styles.length > 0 ? ct.styles[0] : "";
  ct.defaults = ctext;
  delete ct.calcchains;
  return ct;
}
function write_ct(ct, opts) /*:string*/{
  var type2ct /*{[string]:Array<string>}*/ = evert_arr(ct2type);
  var o /*:Array<string>*/ = [],
    v;
  o[o.length] = XML_HEADER;
  o[o.length] = writextag('Types', null, {
    'xmlns': XMLNS.CT,
    'xmlns:xsd': XMLNS.xsd,
    'xmlns:xsi': XMLNS.xsi
  });
  o = o.concat([['xml', 'application/xml'], ['bin', 'application/vnd.ms-excel.sheet.binary.macroEnabled.main'], ['vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'], ['data', 'application/vnd.openxmlformats-officedocument.model+data'], /* from test files */
  ['bmp', 'image/bmp'], ['png', 'image/png'], ['gif', 'image/gif'], ['emf', 'image/x-emf'], ['wmf', 'image/x-wmf'], ['jpg', 'image/jpeg'], ['jpeg', 'image/jpeg'], ['tif', 'image/tiff'], ['tiff', 'image/tiff'], ['pdf', 'application/pdf'], ['rels', 'application/vnd.openxmlformats-package.relationships+xml']].map(function (x) {
    return writextag('Default', null, {
      'Extension': x[0],
      'ContentType': x[1]
    });
  }));

  /* only write first instance */
  var f1 = function (w) {
    if (ct[w] && ct[w].length > 0) {
      v = ct[w][0];
      o[o.length] = writextag('Override', null, {
        'PartName': (v[0] == '/' ? "" : "/") + v,
        'ContentType': CT_LIST[w][opts.bookType] || CT_LIST[w]['xlsx']
      });
    }
  };

  /* book type-specific */
  var f2 = function (w) {
    (ct[w] || []).forEach(function (v) {
      o[o.length] = writextag('Override', null, {
        'PartName': (v[0] == '/' ? "" : "/") + v,
        'ContentType': CT_LIST[w][opts.bookType] || CT_LIST[w]['xlsx']
      });
    });
  };

  /* standard type */
  var f3 = function (t) {
    (ct[t] || []).forEach(function (v) {
      o[o.length] = writextag('Override', null, {
        'PartName': (v[0] == '/' ? "" : "/") + v,
        'ContentType': type2ct[t][0]
      });
    });
  };
  f1('workbooks');
  f2('sheets');
  f2('charts');
  f3('themes');
  ['strs', 'styles'].forEach(f1);
  ['coreprops', 'extprops', 'custprops'].forEach(f3);
  f3('vba');
  f3('comments');
  f3('threadedcomments');
  f3('drawings');
  f2('metadata');
  f3('people');
  if (o.length > 2) {
    o[o.length] = '</Types>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* 9.3 Relationships */
var RELS = {
  WB: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  SHEET: "http://sheetjs.openxmlformats.org/officeDocument/2006/relationships/officeDocument",
  HLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink",
  VML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing",
  XPATH: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLinkPath",
  XMISS: "http://schemas.microsoft.com/office/2006/relationships/xlExternalLinkPath/xlPathMissing",
  XLINK: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/externalLink",
  CXML: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml",
  CXMLP: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps",
  CMNT: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
  CORE_PROPS: "http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties",
  EXT_PROPS: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',
  CUST_PROPS: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',
  SST: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings",
  STY: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
  THEME: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme",
  CHART: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart",
  CHARTEX: "http://schemas.microsoft.com/office/2014/relationships/chartEx",
  CS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/chartsheet",
  WS: ["http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet", "http://purl.oclc.org/ooxml/officeDocument/relationships/worksheet"],
  DS: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/dialogsheet",
  MS: "http://schemas.microsoft.com/office/2006/relationships/xlMacrosheet",
  IMG: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
  DRAW: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing",
  XLMETA: "http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata",
  TCMNT: "http://schemas.microsoft.com/office/2017/10/relationships/threadedComment",
  PEOPLE: "http://schemas.microsoft.com/office/2017/10/relationships/person",
  VBA: "http://schemas.microsoft.com/office/2006/relationships/vbaProject"
} /*:any*/;

/* 9.3.3 Representing Relationships */
function get_rels_path(file /*:string*/) /*:string*/{
  var n = file.lastIndexOf("/");
  return file.slice(0, n + 1) + '_rels/' + file.slice(n + 1) + ".rels";
}
function parse_rels(data /*:?string*/, currentFilePath /*:string*/) {
  var rels = {
    "!id": {}
  };
  if (!data) return rels;
  if (currentFilePath.charAt(0) !== '/') {
    currentFilePath = '/' + currentFilePath;
  }
  var hash = {};
  (data.match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    /* 9.3.2.2 OPC_Relationships */
    if (y[0] === '<Relationship') {
      var rel = {};
      rel.Type = y.Type;
      rel.Target = y.Target;
      rel.Id = y.Id;
      if (y.TargetMode) rel.TargetMode = y.TargetMode;
      var canonictarget = y.TargetMode === 'External' ? y.Target : resolve_path(y.Target, currentFilePath);
      rels[canonictarget] = rel;
      hash[y.Id] = rel;
    }
  });
  rels["!id"] = hash;
  return rels;
}

/* TODO */
function write_rels(rels) /*:string*/{
  var o = [XML_HEADER, writextag('Relationships', null, {
    //'xmlns:ns0': XMLNS.RELS,
    'xmlns': XMLNS.RELS
  })];
  keys(rels['!id']).forEach(function (rid) {
    o[o.length] = writextag('Relationship', null, rels['!id'][rid]);
  });
  if (o.length > 2) {
    o[o.length] = '</Relationships>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
function add_rels(rels, rId /*:number*/, f, type, relobj, targetmode /*:?string*/) /*:number*/{
  if (!relobj) relobj = {};
  if (!rels['!id']) rels['!id'] = {};
  if (!rels['!idx']) rels['!idx'] = 1;
  if (rId < 0) for (rId = rels['!idx']; rels['!id']['rId' + rId]; ++rId) {/* empty */}
  rels['!idx'] = rId + 1;
  relobj.Id = 'rId' + rId;
  relobj.Type = type;
  relobj.Target = f;
  if (targetmode) relobj.TargetMode = targetmode;else if ([RELS.HLINK, RELS.XPATH, RELS.XMISS].indexOf(relobj.Type) > -1) relobj.TargetMode = "External";
  if (rels['!id'][relobj.Id]) throw new Error("Cannot rewrite rId " + rId);
  rels['!id'][relobj.Id] = relobj;
  rels[('/' + relobj.Target).replace("//", "/")] = relobj;
  return rId;
}
/* Open Document Format for Office Applications (OpenDocument) Version 1.2 */
/* Part 3 Section 4 Manifest File */
var CT_ODS = "application/vnd.oasis.opendocument.spreadsheet";
function parse_manifest(d, opts) {
  var str = xlml_normalize(d);
  var Rn;
  var FEtag;
  while (Rn = xlmlregex.exec(str)) switch (Rn[3]) {
    case 'manifest':
      break;
    // 4.2 <manifest:manifest>
    case 'file-entry':
      // 4.3 <manifest:file-entry>
      FEtag = parsexmltag(Rn[0], false);
      if (FEtag.path == '/' && FEtag.type !== CT_ODS) throw new Error("This OpenDocument is not a spreadsheet");
      break;
    case 'encryption-data': // 4.4 <manifest:encryption-data>
    case 'algorithm': // 4.5 <manifest:algorithm>
    case 'start-key-generation': // 4.6 <manifest:start-key-generation>
    case 'key-derivation':
      // 4.7 <manifest:key-derivation>
      throw new Error("Unsupported ODS Encryption");
    default:
      if (opts && opts.WTF) throw Rn;
  }
}
function write_manifest(manifest /*:Array<Array<string> >*/) /*:string*/{
  var o = [XML_HEADER];
  o.push('<manifest:manifest xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0" manifest:version="1.2">\n');
  o.push('  <manifest:file-entry manifest:full-path="/" manifest:version="1.2" manifest:media-type="application/vnd.oasis.opendocument.spreadsheet"/>\n');
  for (var i = 0; i < manifest.length; ++i) o.push('  <manifest:file-entry manifest:full-path="' + manifest[i][0] + '" manifest:media-type="' + manifest[i][1] + '"/>\n');
  o.push('</manifest:manifest>');
  return o.join("");
}

/* Part 3 Section 6 Metadata Manifest File */
function write_rdf_type(file /*:string*/, res /*:string*/, tag /*:?string*/) {
  return ['  <rdf:Description rdf:about="' + file + '">\n', '    <rdf:type rdf:resource="http://docs.oasis-open.org/ns/office/1.2/meta/' + (tag || "odf") + '#' + res + '"/>\n', '  </rdf:Description>\n'].join("");
}
function write_rdf_has(base /*:string*/, file /*:string*/) {
  return ['  <rdf:Description rdf:about="' + base + '">\n', '    <ns0:hasPart xmlns:ns0="http://docs.oasis-open.org/ns/office/1.2/meta/pkg#" rdf:resource="' + file + '"/>\n', '  </rdf:Description>\n'].join("");
}
function write_rdf(rdf) {
  var o = [XML_HEADER];
  o.push('<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\n');
  for (var i = 0; i != rdf.length; ++i) {
    o.push(write_rdf_type(rdf[i][0], rdf[i][1]));
    o.push(write_rdf_has("", rdf[i][0]));
  }
  o.push(write_rdf_type("", "Document", "pkg"));
  o.push('</rdf:RDF>');
  return o.join("");
}
/* TODO: pull properties */
function write_meta_ods(/*:: wb: Workbook, opts: any*/
) /*:string*/{
  return '<office:document-meta xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:xlink="http://www.w3.org/1999/xlink" office:version="1.2"><office:meta><meta:generator>Sheet' + 'JS ' + XLSX.version + '</meta:generator></office:meta></office:document-meta>';
}

/* ECMA-376 Part II 11.1 Core Properties Part */
/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
var CORE_PROPS /*:Array<Array<string> >*/ = [["cp:category", "Category"], ["cp:contentStatus", "ContentStatus"], ["cp:keywords", "Keywords"], ["cp:lastModifiedBy", "LastAuthor"], ["cp:lastPrinted", "LastPrinted"], ["cp:revision", "RevNumber"], ["cp:version", "Version"], ["dc:creator", "Author"], ["dc:description", "Comments"], ["dc:identifier", "Identifier"], ["dc:language", "Language"], ["dc:subject", "Subject"], ["dc:title", "Title"], ["dcterms:created", "CreatedDate", 'date'], ["dcterms:modified", "ModifiedDate", 'date']];
var CORE_PROPS_REGEX /*:Array<RegExp>*/ = /*#__PURE__*/function () {
  var r = new Array(CORE_PROPS.length);
  for (var i = 0; i < CORE_PROPS.length; ++i) {
    var f = CORE_PROPS[i];
    var g = "(?:" + f[0].slice(0, f[0].indexOf(":")) + ":)" + f[0].slice(f[0].indexOf(":") + 1);
    r[i] = new RegExp("<" + g + "[^>]*>([\\s\\S]*?)<\/" + g + ">");
  }
  return r;
}();
function parse_core_props(data) {
  var p = {};
  data = utf8read(data);
  for (var i = 0; i < CORE_PROPS.length; ++i) {
    var f = CORE_PROPS[i],
      cur = data.match(CORE_PROPS_REGEX[i]);
    if (cur != null && cur.length > 0) p[f[1]] = unescapexml(cur[1]);
    if (f[2] === 'date' && p[f[1]]) p[f[1]] = parseDate(p[f[1]]);
  }
  return p;
}
function cp_doit(f, g, h, o, p) {
  if (p[f] != null || g == null || g === "") return;
  p[f] = g;
  g = escapexml(g);
  o[o.length] = h ? writextag(f, g, h) : writetag(f, g);
}
function write_core_props(cp, _opts) {
  var opts = _opts || {};
  var o = [XML_HEADER, writextag('cp:coreProperties', null, {
      //'xmlns': XMLNS.CORE_PROPS,
      'xmlns:cp': XMLNS.CORE_PROPS,
      'xmlns:dc': XMLNS.dc,
      'xmlns:dcterms': XMLNS.dcterms,
      'xmlns:dcmitype': XMLNS.dcmitype,
      'xmlns:xsi': XMLNS.xsi
    })],
    p = {};
  if (!cp && !opts.Props) return o.join("");
  if (cp) {
    if (cp.CreatedDate != null) cp_doit("dcterms:created", typeof cp.CreatedDate === "string" ? cp.CreatedDate : write_w3cdtf(cp.CreatedDate, opts.WTF), {
      "xsi:type": "dcterms:W3CDTF"
    }, o, p);
    if (cp.ModifiedDate != null) cp_doit("dcterms:modified", typeof cp.ModifiedDate === "string" ? cp.ModifiedDate : write_w3cdtf(cp.ModifiedDate, opts.WTF), {
      "xsi:type": "dcterms:W3CDTF"
    }, o, p);
  }
  for (var i = 0; i != CORE_PROPS.length; ++i) {
    var f = CORE_PROPS[i];
    var v = opts.Props && opts.Props[f[1]] != null ? opts.Props[f[1]] : cp ? cp[f[1]] : null;
    if (v === true) v = "1";else if (v === false) v = "0";else if (typeof v == "number") v = String(v);
    if (v != null) cp_doit(f[0], v, null, o, p);
  }
  if (o.length > 2) {
    o[o.length] = '</cp:coreProperties>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* 15.2.12.3 Extended File Properties Part */
/* [MS-OSHARED] 2.3.3.2.[1-2].1 (PIDSI/PIDDSI) */
var EXT_PROPS /*:Array<Array<string> >*/ = [["Application", "Application", "string"], ["AppVersion", "AppVersion", "string"], ["Company", "Company", "string"], ["DocSecurity", "DocSecurity", "string"], ["Manager", "Manager", "string"], ["HyperlinksChanged", "HyperlinksChanged", "bool"], ["SharedDoc", "SharedDoc", "bool"], ["LinksUpToDate", "LinksUpToDate", "bool"], ["ScaleCrop", "ScaleCrop", "bool"], ["HeadingPairs", "HeadingPairs", "raw"], ["TitlesOfParts", "TitlesOfParts", "raw"]];
var PseudoPropsPairs = ["Worksheets", "SheetNames", "NamedRanges", "DefinedNames", "Chartsheets", "ChartNames"];
function load_props_pairs(HP /*:string|Array<Array<any>>*/, TOP, props, opts) {
  var v = [];
  if (typeof HP == "string") v = parseVector(HP, opts);else for (var j = 0; j < HP.length; ++j) v = v.concat(HP[j].map(function (hp) {
    return {
      v: hp
    };
  }));
  var parts = typeof TOP == "string" ? parseVector(TOP, opts).map(function (x) {
    return x.v;
  }) : TOP;
  var idx = 0,
    len = 0;
  if (parts.length > 0) for (var i = 0; i !== v.length; i += 2) {
    len = +v[i + 1].v;
    switch (v[i].v) {
      case "Worksheets":
      case "工作表":
      case "Листы":
      case "أوراق العمل":
      case "ワークシート":
      case "גליונות עבודה":
      case "Arbeitsblätter":
      case "Çalışma Sayfaları":
      case "Feuilles de calcul":
      case "Fogli di lavoro":
      case "Folhas de cálculo":
      case "Planilhas":
      case "Regneark":
      case "Hojas de cálculo":
      case "Werkbladen":
        props.Worksheets = len;
        props.SheetNames = parts.slice(idx, idx + len);
        break;
      case "Named Ranges":
      case "Rangos con nombre":
      case "名前付き一覧":
      case "Benannte Bereiche":
      case "Navngivne områder":
        props.NamedRanges = len;
        props.DefinedNames = parts.slice(idx, idx + len);
        break;
      case "Charts":
      case "Diagramme":
        props.Chartsheets = len;
        props.ChartNames = parts.slice(idx, idx + len);
        break;
    }
    idx += len;
  }
}
function parse_ext_props(data, p, opts) {
  var q = {};
  if (!p) p = {};
  data = utf8read(data);
  EXT_PROPS.forEach(function (f) {
    var xml = (data.match(matchtag(f[0])) || [])[1];
    switch (f[2]) {
      case "string":
        if (xml) p[f[1]] = unescapexml(xml);
        break;
      case "bool":
        p[f[1]] = xml === "true";
        break;
      case "raw":
        var cur = data.match(new RegExp("<" + f[0] + "[^>]*>([\\s\\S]*?)<\/" + f[0] + ">"));
        if (cur && cur.length > 0) q[f[1]] = cur[1];
        break;
    }
  });
  if (q.HeadingPairs && q.TitlesOfParts) load_props_pairs(q.HeadingPairs, q.TitlesOfParts, p, opts);
  return p;
}
function write_ext_props(cp /*::, opts*/) /*:string*/{
  var o /*:Array<string>*/ = [],
    W = writextag;
  if (!cp) cp = {};
  cp.Application = "SheetJS";
  o[o.length] = XML_HEADER;
  o[o.length] = writextag('Properties', null, {
    'xmlns': XMLNS.EXT_PROPS,
    'xmlns:vt': XMLNS.vt
  });
  EXT_PROPS.forEach(function (f) {
    if (cp[f[1]] === undefined) return;
    var v;
    switch (f[2]) {
      case 'string':
        v = escapexml(String(cp[f[1]]));
        break;
      case 'bool':
        v = cp[f[1]] ? 'true' : 'false';
        break;
    }
    if (v !== undefined) o[o.length] = W(f[0], v);
  });

  /* TODO: HeadingPairs, TitlesOfParts */
  o[o.length] = W('HeadingPairs', W('vt:vector', W('vt:variant', '<vt:lpstr>Worksheets</vt:lpstr>') + W('vt:variant', W('vt:i4', String(cp.Worksheets))), {
    size: 2,
    baseType: "variant"
  }));
  o[o.length] = W('TitlesOfParts', W('vt:vector', cp.SheetNames.map(function (s) {
    return "<vt:lpstr>" + escapexml(s) + "</vt:lpstr>";
  }).join(""), {
    size: cp.Worksheets,
    baseType: "lpstr"
  }));
  if (o.length > 2) {
    o[o.length] = '</Properties>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* 15.2.12.2 Custom File Properties Part */
var custregex = /<[^>]+>[^<]*/g;
function parse_cust_props(data /*:string*/, opts) {
  var p = {},
    name = "";
  var m = data.match(custregex);
  if (m) for (var i = 0; i != m.length; ++i) {
    var x = m[i],
      y = parsexmltag(x);
    switch (y[0]) {
      case '<?xml':
        break;
      case '<Properties':
        break;
      case '<property':
        name = unescapexml(y.name);
        break;
      case '</property>':
        name = null;
        break;
      default:
        if (x.indexOf('<vt:') === 0) {
          var toks = x.split('>');
          var type = toks[0].slice(4),
            text = toks[1];
          /* 22.4.2.32 (CT_Variant). Omit the binary types from 22.4 (Variant Types) */
          switch (type) {
            case 'lpstr':
            case 'bstr':
            case 'lpwstr':
              p[name] = unescapexml(text);
              break;
            case 'bool':
              p[name] = parsexmlbool(text);
              break;
            case 'i1':
            case 'i2':
            case 'i4':
            case 'i8':
            case 'int':
            case 'uint':
              p[name] = parseInt(text, 10);
              break;
            case 'r4':
            case 'r8':
            case 'decimal':
              p[name] = parseFloat(text);
              break;
            case 'filetime':
            case 'date':
              p[name] = parseDate(text);
              break;
            case 'cy':
            case 'error':
              p[name] = unescapexml(text);
              break;
            default:
              if (type.slice(-1) == '/') break;
              if (opts.WTF && typeof console !== 'undefined') console.warn('Unexpected', x, type, toks);
          }
        } else if (x.slice(0, 2) === "</") {/* empty */
        } else if (opts.WTF) throw new Error(x);
    }
  }
  return p;
}
function write_cust_props(cp /*::, opts*/) /*:string*/{
  var o = [XML_HEADER, writextag('Properties', null, {
    'xmlns': XMLNS.CUST_PROPS,
    'xmlns:vt': XMLNS.vt
  })];
  if (!cp) return o.join("");
  var pid = 1;
  keys(cp).forEach(function custprop(k) {
    ++pid;
    o[o.length] = writextag('property', write_vt(cp[k], true), {
      'fmtid': '{D5CDD505-2E9C-101B-9397-08002B2CF9AE}',
      'pid': pid,
      'name': escapexml(k)
    });
  });
  if (o.length > 2) {
    o[o.length] = '</Properties>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* Common Name -> XLML Name */
var XLMLDocPropsMap = {
  Title: 'Title',
  Subject: 'Subject',
  Author: 'Author',
  Keywords: 'Keywords',
  Comments: 'Description',
  LastAuthor: 'LastAuthor',
  RevNumber: 'Revision',
  Application: 'AppName',
  /* TotalTime: 'TotalTime', */
  LastPrinted: 'LastPrinted',
  CreatedDate: 'Created',
  ModifiedDate: 'LastSaved',
  /* Pages */
  /* Words */
  /* Characters */
  Category: 'Category',
  /* PresentationFormat */
  Manager: 'Manager',
  Company: 'Company',
  /* Guid */
  /* HyperlinkBase */
  /* Bytes */
  /* Lines */
  /* Paragraphs */
  /* CharactersWithSpaces */
  AppVersion: 'Version',
  ContentStatus: 'ContentStatus',
  /* NOTE: missing from schema */
  Identifier: 'Identifier',
  /* NOTE: missing from schema */
  Language: 'Language' /* NOTE: missing from schema */
};
var evert_XLMLDPM;
function xlml_set_prop(Props, tag /*:string*/, val) {
  if (!evert_XLMLDPM) evert_XLMLDPM = evert(XLMLDocPropsMap);
  tag = evert_XLMLDPM[tag] || tag;
  Props[tag] = val;
}
function xlml_write_docprops(Props, opts) {
  var o /*:Array<string>*/ = [];
  keys(XLMLDocPropsMap).map(function (m) {
    for (var i = 0; i < CORE_PROPS.length; ++i) if (CORE_PROPS[i][1] == m) return CORE_PROPS[i];
    for (i = 0; i < EXT_PROPS.length; ++i) if (EXT_PROPS[i][1] == m) return EXT_PROPS[i];
    throw m;
  }).forEach(function (p) {
    if (Props[p[1]] == null) return;
    var m = opts && opts.Props && opts.Props[p[1]] != null ? opts.Props[p[1]] : Props[p[1]];
    switch (p[2]) {
      case 'date':
        m = new Date(m).toISOString().replace(/\.\d*Z/, "Z");
        break;
    }
    if (typeof m == 'number') m = String(m);else if (m === true || m === false) {
      m = m ? "1" : "0";
    } else if (m instanceof Date) m = new Date(m).toISOString().replace(/\.\d*Z/, "");
    o.push(writetag(XLMLDocPropsMap[p[1]] || p[1], m));
  });
  return writextag('DocumentProperties', o.join(""), {
    xmlns: XLMLNS.o
  });
}
function xlml_write_custprops(Props, Custprops /*::, opts*/) {
  var BLACKLIST = ["Worksheets", "SheetNames"];
  var T = 'CustomDocumentProperties';
  var o /*:Array<string>*/ = [];
  if (Props) keys(Props).forEach(function (k) {
    /*:: if(!Props) return; */
    if (!Object.prototype.hasOwnProperty.call(Props, k)) return;
    for (var i = 0; i < CORE_PROPS.length; ++i) if (k == CORE_PROPS[i][1]) return;
    for (i = 0; i < EXT_PROPS.length; ++i) if (k == EXT_PROPS[i][1]) return;
    for (i = 0; i < BLACKLIST.length; ++i) if (k == BLACKLIST[i]) return;
    var m = Props[k];
    var t = "string";
    if (typeof m == 'number') {
      t = "float";
      m = String(m);
    } else if (m === true || m === false) {
      t = "boolean";
      m = m ? "1" : "0";
    } else m = String(m);
    o.push(writextag(escapexmltag(k), m, {
      "dt:dt": t
    }));
  });
  if (Custprops) keys(Custprops).forEach(function (k) {
    /*:: if(!Custprops) return; */
    if (!Object.prototype.hasOwnProperty.call(Custprops, k)) return;
    if (Props && Object.prototype.hasOwnProperty.call(Props, k)) return;
    var m = Custprops[k];
    var t = "string";
    if (typeof m == 'number') {
      t = "float";
      m = String(m);
    } else if (m === true || m === false) {
      t = "boolean";
      m = m ? "1" : "0";
    } else if (m instanceof Date) {
      t = "dateTime.tz";
      m = m.toISOString();
    } else m = String(m);
    o.push(writextag(escapexmltag(k), m, {
      "dt:dt": t
    }));
  });
  return '<' + T + ' xmlns="' + XLMLNS.o + '">' + o.join("") + '</' + T + '>';
}
/* [MS-DTYP] 2.3.3 FILETIME */
/* [MS-OLEDS] 2.1.3 FILETIME (Packet Version) */
/* [MS-OLEPS] 2.8 FILETIME (Packet Version) */
function parse_FILETIME(blob) {
  var dwLowDateTime = blob.read_shift(4),
    dwHighDateTime = blob.read_shift(4);
  return new Date((dwHighDateTime / 1e7 * Math.pow(2, 32) + dwLowDateTime / 1e7 - 11644473600) * 1000).toISOString().replace(/\.000/, "");
}
function write_FILETIME(time /*:string|Date*/) {
  var date = typeof time == "string" ? new Date(Date.parse(time)) : time;
  var t = date.getTime() / 1000 + 11644473600;
  var l = t % Math.pow(2, 32),
    h = (t - l) / Math.pow(2, 32);
  l *= 1e7;
  h *= 1e7;
  var w = l / Math.pow(2, 32) | 0;
  if (w > 0) {
    l = l % Math.pow(2, 32);
    h += w;
  }
  var o = new_buf(8);
  o.write_shift(4, l);
  o.write_shift(4, h);
  return o;
}

/* [MS-OSHARED] 2.3.3.1.4 Lpstr */
function parse_lpstr(blob, type, pad /*:?number*/) {
  var start = blob.l;
  var str = blob.read_shift(0, 'lpstr-cp');
  if (pad) while (blob.l - start & 3) ++blob.l;
  return str;
}

/* [MS-OSHARED] 2.3.3.1.6 Lpwstr */
function parse_lpwstr(blob, type, pad) {
  var str = blob.read_shift(0, 'lpwstr');
  if (pad) blob.l += 4 - (str.length + 1 & 3) & 3;
  return str;
}

/* [MS-OSHARED] 2.3.3.1.11 VtString */
/* [MS-OSHARED] 2.3.3.1.12 VtUnalignedString */
function parse_VtStringBase(blob, stringType, pad) {
  if (stringType === 0x1F /*VT_LPWSTR*/) return parse_lpwstr(blob);
  return parse_lpstr(blob, stringType, pad);
}
function parse_VtString(blob, t /*:number*/, pad /*:?boolean*/) {
  return parse_VtStringBase(blob, t, pad === false ? 0 : 4);
}
function parse_VtUnalignedString(blob, t /*:number*/) {
  if (!t) throw new Error("VtUnalignedString must have positive length");
  return parse_VtStringBase(blob, t, 0);
}

/* [MS-OSHARED] 2.3.3.1.7 VtVecLpwstrValue */
function parse_VtVecLpwstrValue(blob) /*:Array<string>*/{
  var length = blob.read_shift(4);
  var ret /*:Array<string>*/ = [];
  for (var i = 0; i != length; ++i) {
    var start = blob.l;
    ret[i] = blob.read_shift(0, 'lpwstr').replace(chr0, '');
    if (blob.l - start & 0x02) blob.l += 2;
  }
  return ret;
}

/* [MS-OSHARED] 2.3.3.1.9 VtVecUnalignedLpstrValue */
function parse_VtVecUnalignedLpstrValue(blob) /*:Array<string>*/{
  var length = blob.read_shift(4);
  var ret /*:Array<string>*/ = [];
  for (var i = 0; i != length; ++i) ret[i] = blob.read_shift(0, 'lpstr-cp').replace(chr0, '');
  return ret;
}

/* [MS-OSHARED] 2.3.3.1.13 VtHeadingPair */
function parse_VtHeadingPair(blob) {
  var start = blob.l;
  var headingString = parse_TypedPropertyValue(blob, VT_USTR);
  if (blob[blob.l] == 0x00 && blob[blob.l + 1] == 0x00 && blob.l - start & 0x02) blob.l += 2;
  var headerParts = parse_TypedPropertyValue(blob, VT_I4);
  return [headingString, headerParts];
}

/* [MS-OSHARED] 2.3.3.1.14 VtVecHeadingPairValue */
function parse_VtVecHeadingPairValue(blob) {
  var cElements = blob.read_shift(4);
  var out = [];
  for (var i = 0; i < cElements / 2; ++i) out.push(parse_VtHeadingPair(blob));
  return out;
}

/* [MS-OLEPS] 2.18.1 Dictionary (uses 2.17, 2.16) */
function parse_dictionary(blob, CodePage) {
  var cnt = blob.read_shift(4);
  var dict /*:{[number]:string}*/ = {} /*:any*/;
  for (var j = 0; j != cnt; ++j) {
    var pid = blob.read_shift(4);
    var len = blob.read_shift(4);
    dict[pid] = blob.read_shift(len, CodePage === 0x4B0 ? 'utf16le' : 'utf8').replace(chr0, '').replace(chr1, '!');
    if (CodePage === 0x4B0 && len % 2) blob.l += 2;
  }
  if (blob.l & 3) blob.l = blob.l >> 2 + 1 << 2;
  return dict;
}

/* [MS-OLEPS] 2.9 BLOB */
function parse_BLOB(blob) {
  var size = blob.read_shift(4);
  var bytes = blob.slice(blob.l, blob.l + size);
  blob.l += size;
  if ((size & 3) > 0) blob.l += 4 - (size & 3) & 3;
  return bytes;
}

/* [MS-OLEPS] 2.11 ClipboardData */
function parse_ClipboardData(blob) {
  // TODO
  var o = {};
  o.Size = blob.read_shift(4);
  //o.Format = blob.read_shift(4);
  blob.l += o.Size + 3 - (o.Size - 1) % 4;
  return o;
}

/* [MS-OLEPS] 2.15 TypedPropertyValue */
function parse_TypedPropertyValue(blob, type /*:number*/, _opts) /*:any*/{
  var t = blob.read_shift(2),
    ret,
    opts = _opts || {};
  blob.l += 2;
  if (type !== VT_VARIANT) if (t !== type && VT_CUSTOM.indexOf(type) === -1 && !((type & 0xFFFE) == 0x101E && (t & 0xFFFE) == 0x101E)) throw new Error('Expected type ' + type + ' saw ' + t);
  switch (type === VT_VARIANT ? t : type) {
    case 0x02 /*VT_I2*/:
      ret = blob.read_shift(2, 'i');
      if (!opts.raw) blob.l += 2;
      return ret;
    case 0x03 /*VT_I4*/:
      ret = blob.read_shift(4, 'i');
      return ret;
    case 0x0B /*VT_BOOL*/:
      return blob.read_shift(4) !== 0x0;
    case 0x13 /*VT_UI4*/:
      ret = blob.read_shift(4);
      return ret;
    case 0x1E /*VT_LPSTR*/:
      return parse_lpstr(blob, t, 4).replace(chr0, '');
    case 0x1F /*VT_LPWSTR*/:
      return parse_lpwstr(blob);
    case 0x40 /*VT_FILETIME*/:
      return parse_FILETIME(blob);
    case 0x41 /*VT_BLOB*/:
      return parse_BLOB(blob);
    case 0x47 /*VT_CF*/:
      return parse_ClipboardData(blob);
    case 0x50 /*VT_STRING*/:
      return parse_VtString(blob, t, !opts.raw).replace(chr0, '');
    case 0x51 /*VT_USTR*/:
      return parse_VtUnalignedString(blob, t /*, 4*/).replace(chr0, '');
    case 0x100C /*VT_VECTOR|VT_VARIANT*/:
      return parse_VtVecHeadingPairValue(blob);
    case 0x101E /*VT_VECTOR|VT_LPSTR*/:
    case 0x101F /*VT_VECTOR|VT_LPWSTR*/:
      return t == 0x101F ? parse_VtVecLpwstrValue(blob) : parse_VtVecUnalignedLpstrValue(blob);
    default:
      throw new Error("TypedPropertyValue unrecognized type " + type + " " + t);
  }
}
function write_TypedPropertyValue(type /*:number*/, value) {
  var o = new_buf(4),
    p = new_buf(4);
  o.write_shift(4, type == 0x50 ? 0x1F : type);
  switch (type) {
    case 0x03 /*VT_I4*/:
      p.write_shift(-4, value);
      break;
    case 0x05 /*VT_I4*/:
      p = new_buf(8);
      p.write_shift(8, value, 'f');
      break;
    case 0x0B /*VT_BOOL*/:
      p.write_shift(4, value ? 0x01 : 0x00);
      break;
    case 0x40 /*VT_FILETIME*/:
      /*:: if(typeof value !== "string" && !(value instanceof Date)) throw "unreachable"; */p = write_FILETIME(value);
      break;
    case 0x1F /*VT_LPWSTR*/:
    case 0x50 /*VT_STRING*/:
      /*:: if(typeof value !== "string") throw "unreachable"; */
      p = new_buf(4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
      p.write_shift(4, value.length + 1);
      p.write_shift(0, value, "dbcs");
      while (p.l != p.length) p.write_shift(1, 0);
      break;
    default:
      throw new Error("TypedPropertyValue unrecognized type " + type + " " + value);
  }
  return bconcat([o, p]);
}

/* [MS-OLEPS] 2.20 PropertySet */
function parse_PropertySet(blob, PIDSI) {
  var start_addr = blob.l;
  var size = blob.read_shift(4);
  var NumProps = blob.read_shift(4);
  var Props = [],
    i = 0;
  var CodePage = 0;
  var Dictionary = -1,
    DictObj /*:{[number]:string}*/ = {} /*:any*/;
  for (i = 0; i != NumProps; ++i) {
    var PropID = blob.read_shift(4);
    var Offset = blob.read_shift(4);
    Props[i] = [PropID, Offset + start_addr];
  }
  Props.sort(function (x, y) {
    return x[1] - y[1];
  });
  var PropH = {};
  for (i = 0; i != NumProps; ++i) {
    if (blob.l !== Props[i][1]) {
      var fail = true;
      if (i > 0 && PIDSI) switch (PIDSI[Props[i - 1][0]].t) {
        case 0x02 /*VT_I2*/:
          if (blob.l + 2 === Props[i][1]) {
            blob.l += 2;
            fail = false;
          }
          break;
        case 0x50 /*VT_STRING*/:
          if (blob.l <= Props[i][1]) {
            blob.l = Props[i][1];
            fail = false;
          }
          break;
        case 0x100C /*VT_VECTOR|VT_VARIANT*/:
          if (blob.l <= Props[i][1]) {
            blob.l = Props[i][1];
            fail = false;
          }
          break;
      }
      if ((!PIDSI || i == 0) && blob.l <= Props[i][1]) {
        fail = false;
        blob.l = Props[i][1];
      }
      if (fail) throw new Error("Read Error: Expected address " + Props[i][1] + ' at ' + blob.l + ' :' + i);
    }
    if (PIDSI) {
      var piddsi = PIDSI[Props[i][0]];
      PropH[piddsi.n] = parse_TypedPropertyValue(blob, piddsi.t, {
        raw: true
      });
      if (piddsi.p === 'version') PropH[piddsi.n] = String(PropH[piddsi.n] >> 16) + "." + ("0000" + String(PropH[piddsi.n] & 0xFFFF)).slice(-4);
      if (piddsi.n == "CodePage") switch (PropH[piddsi.n]) {
        case 0:
          PropH[piddsi.n] = 1252;
        /* falls through */
        case 874:
        case 932:
        case 936:
        case 949:
        case 950:
        case 1250:
        case 1251:
        case 1253:
        case 1254:
        case 1255:
        case 1256:
        case 1257:
        case 1258:
        case 10000:
        case 1200:
        case 1201:
        case 1252:
        case 65000:
        case -536:
        case 65001:
        case -535:
          set_cp(CodePage = PropH[piddsi.n] >>> 0 & 0xFFFF);
          break;
        default:
          throw new Error("Unsupported CodePage: " + PropH[piddsi.n]);
      }
    } else {
      if (Props[i][0] === 0x1) {
        CodePage = PropH.CodePage = parse_TypedPropertyValue(blob, VT_I2) /*:number*/;
        set_cp(CodePage);
        if (Dictionary !== -1) {
          var oldpos = blob.l;
          blob.l = Props[Dictionary][1];
          DictObj = parse_dictionary(blob, CodePage);
          blob.l = oldpos;
        }
      } else if (Props[i][0] === 0) {
        if (CodePage === 0) {
          Dictionary = i;
          blob.l = Props[i + 1][1];
          continue;
        }
        DictObj = parse_dictionary(blob, CodePage);
      } else {
        var name = DictObj[Props[i][0]];
        var val;
        /* [MS-OSHARED] 2.3.3.2.3.1.2 + PROPVARIANT */
        switch (blob[blob.l]) {
          case 0x41 /*VT_BLOB*/:
            blob.l += 4;
            val = parse_BLOB(blob);
            break;
          case 0x1E /*VT_LPSTR*/:
            blob.l += 4;
            val = parse_VtString(blob, blob[blob.l - 4]).replace(/\u0000+$/, "");
            break;
          case 0x1F /*VT_LPWSTR*/:
            blob.l += 4;
            val = parse_VtString(blob, blob[blob.l - 4]).replace(/\u0000+$/, "");
            break;
          case 0x03 /*VT_I4*/:
            blob.l += 4;
            val = blob.read_shift(4, 'i');
            break;
          case 0x13 /*VT_UI4*/:
            blob.l += 4;
            val = blob.read_shift(4);
            break;
          case 0x05 /*VT_R8*/:
            blob.l += 4;
            val = blob.read_shift(8, 'f');
            break;
          case 0x0B /*VT_BOOL*/:
            blob.l += 4;
            val = parsebool(blob, 4);
            break;
          case 0x40 /*VT_FILETIME*/:
            blob.l += 4;
            val = parseDate(parse_FILETIME(blob));
            break;
          default:
            throw new Error("unparsed value: " + blob[blob.l]);
        }
        PropH[name] = val;
      }
    }
  }
  blob.l = start_addr + size; /* step ahead to skip padding */
  return PropH;
}
var XLSPSSkip = ["CodePage", "Thumbnail", "_PID_LINKBASE", "_PID_HLINKS", "SystemIdentifier", "FMTID"]; //.concat(PseudoPropsPairs);
function guess_property_type(val /*:any*/) /*:number*/{
  switch (typeof val) {
    case "boolean":
      return 0x0B;
    case "number":
      return (val | 0) == val ? 0x03 : 0x05;
    case "string":
      return 0x1F;
    case "object":
      if (val instanceof Date) return 0x40;
      break;
  }
  return -1;
}
function write_PropertySet(entries, RE, PIDSI) {
  var hdr = new_buf(8),
    piao = [],
    prop = [];
  var sz = 8,
    i = 0;
  var pr = new_buf(8),
    pio = new_buf(8);
  pr.write_shift(4, 0x0002);
  pr.write_shift(4, 0x04B0);
  pio.write_shift(4, 0x0001);
  prop.push(pr);
  piao.push(pio);
  sz += 8 + pr.length;
  if (!RE) {
    pio = new_buf(8);
    pio.write_shift(4, 0);
    piao.unshift(pio);
    var bufs = [new_buf(4)];
    bufs[0].write_shift(4, entries.length);
    for (i = 0; i < entries.length; ++i) {
      var value = entries[i][0];
      pr = new_buf(4 + 4 + 2 * (value.length + 1) + (value.length % 2 ? 0 : 2));
      pr.write_shift(4, i + 2);
      pr.write_shift(4, value.length + 1);
      pr.write_shift(0, value, "dbcs");
      while (pr.l != pr.length) pr.write_shift(1, 0);
      bufs.push(pr);
    }
    pr = bconcat(bufs);
    prop.unshift(pr);
    sz += 8 + pr.length;
  }
  for (i = 0; i < entries.length; ++i) {
    if (RE && !RE[entries[i][0]]) continue;
    if (XLSPSSkip.indexOf(entries[i][0]) > -1 || PseudoPropsPairs.indexOf(entries[i][0]) > -1) continue;
    if (entries[i][1] == null) continue;
    var val = entries[i][1],
      idx = 0;
    if (RE) {
      idx = +RE[entries[i][0]];
      var pinfo = PIDSI /*:: || {}*/[idx] /*:: || {} */;
      if (pinfo.p == "version" && typeof val == "string") {
        /*:: if(typeof val !== "string") throw "unreachable"; */
        var arr = val.split(".");
        val = (+arr[0] << 16) + (+arr[1] || 0);
      }
      pr = write_TypedPropertyValue(pinfo.t, val);
    } else {
      var T = guess_property_type(val);
      if (T == -1) {
        T = 0x1F;
        val = String(val);
      }
      pr = write_TypedPropertyValue(T, val);
    }
    prop.push(pr);
    pio = new_buf(8);
    pio.write_shift(4, !RE ? 2 + i : idx);
    piao.push(pio);
    sz += 8 + pr.length;
  }
  var w = 8 * (prop.length + 1);
  for (i = 0; i < prop.length; ++i) {
    piao[i].write_shift(4, w);
    w += prop[i].length;
  }
  hdr.write_shift(4, sz);
  hdr.write_shift(4, prop.length);
  return bconcat([hdr].concat(piao).concat(prop));
}

/* [MS-OLEPS] 2.21 PropertySetStream */
function parse_PropertySetStream(file, PIDSI, clsid) {
  var blob = file.content;
  if (!blob) return {} /*:any*/;
  prep_blob(blob, 0);
  var NumSets,
    FMTID0,
    FMTID1,
    Offset0,
    Offset1 = 0;
  blob.chk('feff', 'Byte Order: ');

  /*var vers = */
  blob.read_shift(2); // TODO: check version
  var SystemIdentifier = blob.read_shift(4);
  var CLSID = blob.read_shift(16);
  if (CLSID !== CFB.utils.consts.HEADER_CLSID && CLSID !== clsid) throw new Error("Bad PropertySet CLSID " + CLSID);
  NumSets = blob.read_shift(4);
  if (NumSets !== 1 && NumSets !== 2) throw new Error("Unrecognized #Sets: " + NumSets);
  FMTID0 = blob.read_shift(16);
  Offset0 = blob.read_shift(4);
  if (NumSets === 1 && Offset0 !== blob.l) throw new Error("Length mismatch: " + Offset0 + " !== " + blob.l);else if (NumSets === 2) {
    FMTID1 = blob.read_shift(16);
    Offset1 = blob.read_shift(4);
  }
  var PSet0 = parse_PropertySet(blob, PIDSI);
  var rval = {
    SystemIdentifier: SystemIdentifier
  } /*:any*/;
  for (var y in PSet0) rval[y] = PSet0[y];
  //rval.blob = blob;
  rval.FMTID = FMTID0;
  //rval.PSet0 = PSet0;
  if (NumSets === 1) return rval;
  if (Offset1 - blob.l == 2) blob.l += 2;
  if (blob.l !== Offset1) throw new Error("Length mismatch 2: " + blob.l + " !== " + Offset1);
  var PSet1;
  try {
    PSet1 = parse_PropertySet(blob, null);
  } catch (e) {/* empty */}
  for (y in PSet1) rval[y] = PSet1[y];
  rval.FMTID = [FMTID0, FMTID1]; // TODO: verify FMTID0/1
  return rval;
}
function write_PropertySetStream(entries, clsid, RE, PIDSI /*:{[key:string|number]:any}*/, entries2 /*:?any*/, clsid2 /*:?any*/) {
  var hdr = new_buf(entries2 ? 68 : 48);
  var bufs = [hdr];
  hdr.write_shift(2, 0xFFFE);
  hdr.write_shift(2, 0x0000); /* TODO: type 1 props */
  hdr.write_shift(4, 0x32363237);
  hdr.write_shift(16, CFB.utils.consts.HEADER_CLSID, "hex");
  hdr.write_shift(4, entries2 ? 2 : 1);
  hdr.write_shift(16, clsid, "hex");
  hdr.write_shift(4, entries2 ? 68 : 48);
  var ps0 = write_PropertySet(entries, RE, PIDSI);
  bufs.push(ps0);
  if (entries2) {
    var ps1 = write_PropertySet(entries2, null, null);
    hdr.write_shift(16, clsid2, "hex");
    hdr.write_shift(4, 68 + ps0.length);
    bufs.push(ps1);
  }
  return bconcat(bufs);
}
function parsenoop2(blob, length) {
  blob.read_shift(length);
  return null;
}
function writezeroes(n, o) {
  if (!o) o = new_buf(n);
  for (var j = 0; j < n; ++j) o.write_shift(1, 0);
  return o;
}
function parslurp(blob, length, cb) {
  var arr = [],
    target = blob.l + length;
  while (blob.l < target) arr.push(cb(blob, target - blob.l));
  if (target !== blob.l) throw new Error("Slurp error");
  return arr;
}
function parsebool(blob, length /*:number*/) {
  return blob.read_shift(length) === 0x1;
}
function writebool(v /*:any*/, o) {
  if (!o) o = new_buf(2);
  o.write_shift(2, +!!v);
  return o;
}
function parseuint16(blob /*::, length:?number, opts:?any*/) {
  return blob.read_shift(2, 'u');
}
function writeuint16(v /*:number*/, o) {
  if (!o) o = new_buf(2);
  o.write_shift(2, v);
  return o;
}
function parseuint16a(blob, length /*:: :?number, opts:?any*/) {
  return parslurp(blob, length, parseuint16);
}

/* --- 2.5 Structures --- */

/* [MS-XLS] 2.5.10 Bes (boolean or error) */
function parse_Bes(blob /*::, length*/) {
  var v = blob.read_shift(1),
    t = blob.read_shift(1);
  return t === 0x01 ? v : v === 0x01;
}
function write_Bes(v, t /*:string*/, o) {
  if (!o) o = new_buf(2);
  o.write_shift(1, t == 'e' ? +v : +!!v);
  o.write_shift(1, t == 'e' ? 1 : 0);
  return o;
}

/* [MS-XLS] 2.5.240 ShortXLUnicodeString */
function parse_ShortXLUnicodeString(blob, length, opts) {
  var cch = blob.read_shift(opts && opts.biff >= 12 ? 2 : 1);
  var encoding = 'sbcs-cont';
  var cp = current_codepage;
  if (opts && opts.biff >= 8) current_codepage = 1200;
  if (!opts || opts.biff == 8) {
    var fHighByte = blob.read_shift(1);
    if (fHighByte) {
      encoding = 'dbcs-cont';
    }
  } else if (opts.biff == 12) {
    encoding = 'wstr';
  }
  if (opts.biff >= 2 && opts.biff <= 5) encoding = 'cpstr';
  var o = cch ? blob.read_shift(cch, encoding) : "";
  current_codepage = cp;
  return o;
}

/* 2.5.293 XLUnicodeRichExtendedString */
function parse_XLUnicodeRichExtendedString(blob) {
  var cp = current_codepage;
  current_codepage = 1200;
  var cch = blob.read_shift(2),
    flags = blob.read_shift(1);
  var /*fHighByte = flags & 0x1,*/fExtSt = flags & 0x4,
    fRichSt = flags & 0x8;
  var width = 1 + (flags & 0x1); // 0x0 -> utf8, 0x1 -> dbcs
  var cRun = 0,
    cbExtRst;
  var z = {};
  if (fRichSt) cRun = blob.read_shift(2);
  if (fExtSt) cbExtRst = blob.read_shift(4);
  var encoding = width == 2 ? 'dbcs-cont' : 'sbcs-cont';
  var msg = cch === 0 ? "" : blob.read_shift(cch, encoding);
  if (fRichSt) blob.l += 4 * cRun; //TODO: parse this
  if (fExtSt) blob.l += cbExtRst; //TODO: parse this
  z.t = msg;
  if (!fRichSt) {
    z.raw = "<t>" + z.t + "</t>";
    z.r = z.t;
  }
  current_codepage = cp;
  return z;
}
function write_XLUnicodeRichExtendedString(xlstr /*:: :XLString, opts*/) {
  var str = xlstr.t || "",
    nfmts = 1;
  var hdr = new_buf(3 + (nfmts > 1 ? 2 : 0));
  hdr.write_shift(2, str.length);
  hdr.write_shift(1, (nfmts > 1 ? 0x08 : 0x00) | 0x01);
  if (nfmts > 1) hdr.write_shift(2, nfmts);
  var otext = new_buf(2 * str.length);
  otext.write_shift(2 * str.length, str, 'utf16le');
  var out = [hdr, otext];
  return bconcat(out);
}

/* 2.5.296 XLUnicodeStringNoCch */
function parse_XLUnicodeStringNoCch(blob, cch, opts) {
  var retval;
  if (opts) {
    if (opts.biff >= 2 && opts.biff <= 5) return blob.read_shift(cch, 'cpstr');
    if (opts.biff >= 12) return blob.read_shift(cch, 'dbcs-cont');
  }
  var fHighByte = blob.read_shift(1);
  if (fHighByte === 0) {
    retval = blob.read_shift(cch, 'sbcs-cont');
  } else {
    retval = blob.read_shift(cch, 'dbcs-cont');
  }
  return retval;
}

/* 2.5.294 XLUnicodeString */
function parse_XLUnicodeString(blob, length, opts) {
  var cch = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  if (cch === 0) {
    blob.l++;
    return "";
  }
  return parse_XLUnicodeStringNoCch(blob, cch, opts);
}
/* BIFF5 override */
function parse_XLUnicodeString2(blob, length, opts) {
  if (opts.biff > 5) return parse_XLUnicodeString(blob, length, opts);
  var cch = blob.read_shift(1);
  if (cch === 0) {
    blob.l++;
    return "";
  }
  return blob.read_shift(cch, opts.biff <= 4 || !blob.lens ? 'cpstr' : 'sbcs-cont');
}
/* TODO: BIFF5 and lower, codepage awareness */
function write_XLUnicodeString(str, opts, o) {
  if (!o) o = new_buf(3 + 2 * str.length);
  o.write_shift(2, str.length);
  o.write_shift(1, 1);
  o.write_shift(31, str, 'utf16le');
  return o;
}

/* [MS-XLS] 2.5.61 ControlInfo */
function parse_ControlInfo(blob /*::, length, opts*/) {
  var flags = blob.read_shift(1);
  blob.l++;
  var accel = blob.read_shift(2);
  blob.l += 2;
  return [flags, accel];
}

/* [MS-OSHARED] 2.3.7.6 URLMoniker TODO: flags */
function parse_URLMoniker(blob /*::, length, opts*/) {
  var len = blob.read_shift(4),
    start = blob.l;
  var extra = false;
  if (len > 24) {
    /* look ahead */
    blob.l += len - 24;
    if (blob.read_shift(16) === "795881f43b1d7f48af2c825dc4852763") extra = true;
    blob.l = start;
  }
  var url = blob.read_shift((extra ? len - 24 : len) >> 1, 'utf16le').replace(chr0, "");
  if (extra) blob.l += 24;
  return url;
}

/* [MS-OSHARED] 2.3.7.8 FileMoniker TODO: all fields */
function parse_FileMoniker(blob /*::, length*/) {
  var cAnti = blob.read_shift(2);
  var preamble = "";
  while (cAnti-- > 0) preamble += "../";
  var ansiPath = blob.read_shift(0, 'lpstr-ansi');
  blob.l += 2; //var endServer = blob.read_shift(2);
  if (blob.read_shift(2) != 0xDEAD) throw new Error("Bad FileMoniker");
  var sz = blob.read_shift(4);
  if (sz === 0) return preamble + ansiPath.replace(/\\/g, "/");
  var bytes = blob.read_shift(4);
  if (blob.read_shift(2) != 3) throw new Error("Bad FileMoniker");
  var unicodePath = blob.read_shift(bytes >> 1, 'utf16le').replace(chr0, "");
  return preamble + unicodePath;
}

/* [MS-OSHARED] 2.3.7.2 HyperlinkMoniker TODO: all the monikers */
function parse_HyperlinkMoniker(blob, length) {
  var clsid = blob.read_shift(16);
  length -= 16;
  switch (clsid) {
    case "e0c9ea79f9bace118c8200aa004ba90b":
      return parse_URLMoniker(blob, length);
    case "0303000000000000c000000000000046":
      return parse_FileMoniker(blob, length);
    default:
      throw new Error("Unsupported Moniker " + clsid);
  }
}

/* [MS-OSHARED] 2.3.7.9 HyperlinkString */
function parse_HyperlinkString(blob /*::, length*/) {
  var len = blob.read_shift(4);
  var o = len > 0 ? blob.read_shift(len, 'utf16le').replace(chr0, "") : "";
  return o;
}
function write_HyperlinkString(str /*:string*/, o) {
  if (!o) o = new_buf(6 + str.length * 2);
  o.write_shift(4, 1 + str.length);
  for (var i = 0; i < str.length; ++i) o.write_shift(2, str.charCodeAt(i));
  o.write_shift(2, 0);
  return o;
}

/* [MS-OSHARED] 2.3.7.1 Hyperlink Object */
function parse_Hyperlink(blob, length) /*:Hyperlink*/{
  var end = blob.l + length;
  var sVer = blob.read_shift(4);
  if (sVer !== 2) throw new Error("Unrecognized streamVersion: " + sVer);
  var flags = blob.read_shift(2);
  blob.l += 2;
  var displayName,
    targetFrameName,
    moniker,
    oleMoniker,
    Loc = "",
    guid,
    fileTime;
  if (flags & 0x0010) displayName = parse_HyperlinkString(blob, end - blob.l);
  if (flags & 0x0080) targetFrameName = parse_HyperlinkString(blob, end - blob.l);
  if ((flags & 0x0101) === 0x0101) moniker = parse_HyperlinkString(blob, end - blob.l);
  if ((flags & 0x0101) === 0x0001) oleMoniker = parse_HyperlinkMoniker(blob, end - blob.l);
  if (flags & 0x0008) Loc = parse_HyperlinkString(blob, end - blob.l);
  if (flags & 0x0020) guid = blob.read_shift(16);
  if (flags & 0x0040) fileTime = parse_FILETIME(blob /*, 8*/);
  blob.l = end;
  var target = targetFrameName || moniker || oleMoniker || "";
  if (target && Loc) target += "#" + Loc;
  if (!target) target = "#" + Loc;
  if (flags & 0x0002 && target.charAt(0) == "/" && target.charAt(1) != "/") target = "file://" + target;
  var out = {
    Target: target
  } /*:any*/;
  if (guid) out.guid = guid;
  if (fileTime) out.time = fileTime;
  if (displayName) out.Tooltip = displayName;
  return out;
}
function write_Hyperlink(hl) {
  var out = new_buf(512),
    i = 0;
  var Target = hl.Target;
  if (Target.slice(0, 7) == "file://") Target = Target.slice(7);
  var hashidx = Target.indexOf("#");
  var F = hashidx > -1 ? 0x1f : 0x17;
  switch (Target.charAt(0)) {
    case "#":
      F = 0x1c;
      break;
    case ".":
      F &= ~2;
      break;
  }
  out.write_shift(4, 2);
  out.write_shift(4, F);
  var data = [8, 6815827, 6619237, 4849780, 83];
  for (i = 0; i < data.length; ++i) out.write_shift(4, data[i]);
  if (F == 0x1C) {
    Target = Target.slice(1);
    write_HyperlinkString(Target, out);
  } else if (F & 0x02) {
    data = "e0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
    for (i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
    var Pretarget = hashidx > -1 ? Target.slice(0, hashidx) : Target;
    out.write_shift(4, 2 * (Pretarget.length + 1));
    for (i = 0; i < Pretarget.length; ++i) out.write_shift(2, Pretarget.charCodeAt(i));
    out.write_shift(2, 0);
    if (F & 0x08) write_HyperlinkString(hashidx > -1 ? Target.slice(hashidx + 1) : "", out);
  } else {
    data = "03 03 00 00 00 00 00 00 c0 00 00 00 00 00 00 46".split(" ");
    for (i = 0; i < data.length; ++i) out.write_shift(1, parseInt(data[i], 16));
    var P = 0;
    while (Target.slice(P * 3, P * 3 + 3) == "../" || Target.slice(P * 3, P * 3 + 3) == "..\\") ++P;
    out.write_shift(2, P);
    out.write_shift(4, Target.length - 3 * P + 1);
    for (i = 0; i < Target.length - 3 * P; ++i) out.write_shift(1, Target.charCodeAt(i + 3 * P) & 0xFF);
    out.write_shift(1, 0);
    out.write_shift(2, 0xFFFF);
    out.write_shift(2, 0xDEAD);
    for (i = 0; i < 6; ++i) out.write_shift(4, 0);
  }
  return out.slice(0, out.l);
}

/* 2.5.178 LongRGBA */
function parse_LongRGBA(blob /*::, length*/) {
  var r = blob.read_shift(1),
    g = blob.read_shift(1),
    b = blob.read_shift(1),
    a = blob.read_shift(1);
  return [r, g, b, a];
}

/* 2.5.177 LongRGB */
function parse_LongRGB(blob, length) {
  var x = parse_LongRGBA(blob, length);
  x[3] = 0;
  return x;
}

/* [MS-XLS] 2.5.19 */
function parse_XLSCell(blob /*::, length*/) /*:Cell*/{
  var rw = blob.read_shift(2); // 0-indexed
  var col = blob.read_shift(2);
  var ixfe = blob.read_shift(2);
  return {
    r: rw,
    c: col,
    ixfe: ixfe
  } /*:any*/;
}
function write_XLSCell(R /*:number*/, C /*:number*/, ixfe /*:?number*/, o) {
  if (!o) o = new_buf(6);
  o.write_shift(2, R);
  o.write_shift(2, C);
  o.write_shift(2, ixfe || 0);
  return o;
}

/* [MS-XLS] 2.5.134 */
function parse_frtHeader(blob) {
  var rt = blob.read_shift(2);
  var flags = blob.read_shift(2); // TODO: parse these flags
  blob.l += 8;
  return {
    type: rt,
    flags: flags
  };
}
function parse_OptXLUnicodeString(blob, length, opts) {
  return length === 0 ? "" : parse_XLUnicodeString2(blob, length, opts);
}

/* [MS-XLS] 2.5.344 */
function parse_XTI(blob, length, opts) {
  var w = opts.biff > 8 ? 4 : 2;
  var iSupBook = blob.read_shift(w),
    itabFirst = blob.read_shift(w, 'i'),
    itabLast = blob.read_shift(w, 'i');
  return [iSupBook, itabFirst, itabLast];
}

/* [MS-XLS] 2.5.218 */
function parse_RkRec(blob) {
  var ixfe = blob.read_shift(2);
  var RK = parse_RkNumber(blob);
  return [ixfe, RK];
}

/* [MS-XLS] 2.5.1 */
function parse_AddinUdf(blob, length, opts) {
  blob.l += 4;
  length -= 4;
  var l = blob.l + length;
  var udfName = parse_ShortXLUnicodeString(blob, length, opts);
  var cb = blob.read_shift(2);
  l -= blob.l;
  if (cb !== l) throw new Error("Malformed AddinUdf: padding = " + l + " != " + cb);
  blob.l += cb;
  return udfName;
}

/* [MS-XLS] 2.5.209 TODO: Check sizes */
function parse_Ref8U(blob /*::, length*/) {
  var rwFirst = blob.read_shift(2);
  var rwLast = blob.read_shift(2);
  var colFirst = blob.read_shift(2);
  var colLast = blob.read_shift(2);
  return {
    s: {
      c: colFirst,
      r: rwFirst
    },
    e: {
      c: colLast,
      r: rwLast
    }
  };
}
function write_Ref8U(r /*:Range*/, o) {
  if (!o) o = new_buf(8);
  o.write_shift(2, r.s.r);
  o.write_shift(2, r.e.r);
  o.write_shift(2, r.s.c);
  o.write_shift(2, r.e.c);
  return o;
}

/* [MS-XLS] 2.5.211 */
function parse_RefU(blob /*::, length*/) {
  var rwFirst = blob.read_shift(2);
  var rwLast = blob.read_shift(2);
  var colFirst = blob.read_shift(1);
  var colLast = blob.read_shift(1);
  return {
    s: {
      c: colFirst,
      r: rwFirst
    },
    e: {
      c: colLast,
      r: rwLast
    }
  };
}

/* [MS-XLS] 2.5.207 */
var parse_Ref = parse_RefU;

/* [MS-XLS] 2.5.143 */
function parse_FtCmo(blob /*::, length*/) {
  blob.l += 4;
  var ot = blob.read_shift(2);
  var id = blob.read_shift(2);
  var flags = blob.read_shift(2);
  blob.l += 12;
  return [id, ot, flags];
}

/* [MS-XLS] 2.5.149 */
function parse_FtNts(blob) {
  var out = {};
  blob.l += 4;
  blob.l += 16; // GUID TODO
  out.fSharedNote = blob.read_shift(2);
  blob.l += 4;
  return out;
}

/* [MS-XLS] 2.5.142 */
function parse_FtCf(blob) {
  var out = {};
  blob.l += 4;
  blob.cf = blob.read_shift(2);
  return out;
}

/* [MS-XLS] 2.5.140 - 2.5.154 and friends */
function parse_FtSkip(blob) {
  blob.l += 2;
  blob.l += blob.read_shift(2);
}
var FtTab = {
  /*::[*/0x00 /*::]*/: parse_FtSkip,
  /* FtEnd */
  /*::[*/0x04 /*::]*/: parse_FtSkip,
  /* FtMacro */
  /*::[*/0x05 /*::]*/: parse_FtSkip,
  /* FtButton */
  /*::[*/0x06 /*::]*/: parse_FtSkip,
  /* FtGmo */
  /*::[*/0x07 /*::]*/: parse_FtCf,
  /* FtCf */
  /*::[*/0x08 /*::]*/: parse_FtSkip,
  /* FtPioGrbit */
  /*::[*/0x09 /*::]*/: parse_FtSkip,
  /* FtPictFmla */
  /*::[*/0x0A /*::]*/: parse_FtSkip,
  /* FtCbls */
  /*::[*/0x0B /*::]*/: parse_FtSkip,
  /* FtRbo */
  /*::[*/0x0C /*::]*/: parse_FtSkip,
  /* FtSbs */
  /*::[*/0x0D /*::]*/: parse_FtNts,
  /* FtNts */
  /*::[*/0x0E /*::]*/: parse_FtSkip,
  /* FtSbsFmla */
  /*::[*/0x0F /*::]*/: parse_FtSkip,
  /* FtGboData */
  /*::[*/0x10 /*::]*/: parse_FtSkip,
  /* FtEdoData */
  /*::[*/0x11 /*::]*/: parse_FtSkip,
  /* FtRboData */
  /*::[*/0x12 /*::]*/: parse_FtSkip,
  /* FtCblsData */
  /*::[*/0x13 /*::]*/: parse_FtSkip,
  /* FtLbsData */
  /*::[*/0x14 /*::]*/: parse_FtSkip,
  /* FtCblsFmla */
  /*::[*/0x15 /*::]*/: parse_FtCmo
};
function parse_FtArray(blob, length /*::, ot*/) {
  var tgt = blob.l + length;
  var fts = [];
  while (blob.l < tgt) {
    var ft = blob.read_shift(2);
    blob.l -= 2;
    try {
      fts.push(FtTab[ft](blob, tgt - blob.l));
    } catch (e) {
      blob.l = tgt;
      return fts;
    }
  }
  if (blob.l != tgt) blob.l = tgt; //throw new Error("bad Object Ft-sequence");
  return fts;
}

/* --- 2.4 Records --- */

/* [MS-XLS] 2.4.21 */
function parse_BOF(blob, length) {
  var o = {
    BIFFVer: 0,
    dt: 0
  };
  o.BIFFVer = blob.read_shift(2);
  length -= 2;
  if (length >= 2) {
    o.dt = blob.read_shift(2);
    blob.l -= 2;
  }
  switch (o.BIFFVer) {
    case 0x0600: /* BIFF8 */
    case 0x0500: /* BIFF5 */
    case 0x0400: /* BIFF4 */
    case 0x0300: /* BIFF3 */
    case 0x0200: /* BIFF2 */
    case 0x0002:
    case 0x0007:
      /* BIFF2 */
      break;
    default:
      if (length > 6) throw new Error("Unexpected BIFF Ver " + o.BIFFVer);
  }
  blob.read_shift(length);
  return o;
}
function write_BOF(wb /*:Workbook*/, t /*:number*/, o) {
  var h = 0x0600,
    w = 16;
  switch (o.bookType) {
    case 'biff8':
      break;
    case 'biff5':
      h = 0x0500;
      w = 8;
      break;
    case 'biff4':
      h = 0x0004;
      w = 6;
      break;
    case 'biff3':
      h = 0x0003;
      w = 6;
      break;
    case 'biff2':
      h = 0x0002;
      w = 4;
      break;
    case 'xla':
      break;
    default:
      throw new Error("unsupported BIFF version");
  }
  var out = new_buf(w);
  out.write_shift(2, h);
  out.write_shift(2, t);
  if (w > 4) out.write_shift(2, 0x7262);
  if (w > 6) out.write_shift(2, 0x07CD);
  if (w > 8) {
    out.write_shift(2, 0xC009);
    out.write_shift(2, 0x0001);
    out.write_shift(2, 0x0706);
    out.write_shift(2, 0x0000);
  }
  return out;
}

/* [MS-XLS] 2.4.146 */
function parse_InterfaceHdr(blob, length) {
  if (length === 0) return 0x04b0;
  if (blob.read_shift(2) !== 0x04b0) {/* empty */}
  return 0x04b0;
}

/* [MS-XLS] 2.4.349 */
function parse_WriteAccess(blob, length, opts) {
  if (opts.enc) {
    blob.l += length;
    return "";
  }
  var l = blob.l;
  // TODO: make sure XLUnicodeString doesnt overrun
  var UserName = parse_XLUnicodeString2(blob, 0, opts);
  blob.read_shift(length + l - blob.l);
  return UserName;
}
function write_WriteAccess(s /*:string*/, opts) {
  var b8 = !opts || opts.biff == 8;
  var o = new_buf(b8 ? 112 : 54);
  o.write_shift(opts.biff == 8 ? 2 : 1, 7);
  if (b8) o.write_shift(1, 0);
  o.write_shift(4, 0x33336853);
  o.write_shift(4, 0x00534A74 | (b8 ? 0 : 0x20000000));
  while (o.l < o.length) o.write_shift(1, b8 ? 0 : 32);
  return o;
}

/* [MS-XLS] 2.4.351 */
function parse_WsBool(blob, length, opts) {
  var flags = opts && opts.biff == 8 || length == 2 ? blob.read_shift(2) : (blob.l += length, 0);
  return {
    fDialog: flags & 0x10,
    fBelow: flags & 0x40,
    fRight: flags & 0x80
  };
}

/* [MS-XLS] 2.4.28 */
function parse_BoundSheet8(blob, length, opts) {
  var pos = blob.read_shift(4);
  var hidden = blob.read_shift(1) & 0x03;
  var dt = blob.read_shift(1);
  switch (dt) {
    case 0:
      dt = 'Worksheet';
      break;
    case 1:
      dt = 'Macrosheet';
      break;
    case 2:
      dt = 'Chartsheet';
      break;
    case 6:
      dt = 'VBAModule';
      break;
  }
  var name = parse_ShortXLUnicodeString(blob, 0, opts);
  if (name.length === 0) name = "Sheet1";
  return {
    pos: pos,
    hs: hidden,
    dt: dt,
    name: name
  };
}
function write_BoundSheet8(data, opts) {
  var w = !opts || opts.biff >= 8 ? 2 : 1;
  var o = new_buf(8 + w * data.name.length);
  o.write_shift(4, data.pos);
  o.write_shift(1, data.hs || 0);
  o.write_shift(1, data.dt);
  o.write_shift(1, data.name.length);
  if (opts.biff >= 8) o.write_shift(1, 1);
  o.write_shift(w * data.name.length, data.name, opts.biff < 8 ? 'sbcs' : 'utf16le');
  var out = o.slice(0, o.l);
  out.l = o.l;
  return out;
}

/* [MS-XLS] 2.4.265 TODO */
function parse_SST(blob, length) /*:SST*/{
  var end = blob.l + length;
  var cnt = blob.read_shift(4);
  var ucnt = blob.read_shift(4);
  var strs /*:SST*/ = [] /*:any*/;
  for (var i = 0; i != ucnt && blob.l < end; ++i) {
    strs.push(parse_XLUnicodeRichExtendedString(blob));
  }
  strs.Count = cnt;
  strs.Unique = ucnt;
  return strs;
}
function write_SST(sst, opts) {
  var header = new_buf(8);
  header.write_shift(4, sst.Count);
  header.write_shift(4, sst.Unique);
  var strs = [];
  for (var j = 0; j < sst.length; ++j) strs[j] = write_XLUnicodeRichExtendedString(sst[j], opts);
  var o = bconcat([header].concat(strs));
  /*::(*/
  o /*:: :any)*/.parts = [header.length].concat(strs.map(function (str) {
    return str.length;
  }));
  return o;
}

/* [MS-XLS] 2.4.107 */
function parse_ExtSST(blob, length) {
  var extsst = {};
  extsst.dsst = blob.read_shift(2);
  blob.l += length - 2;
  return extsst;
}

/* [MS-XLS] 2.4.221 TODO: check BIFF2-4 */
function parse_Row(blob) {
  var z = {} /*:any*/;
  z.r = blob.read_shift(2);
  z.c = blob.read_shift(2);
  z.cnt = blob.read_shift(2) - z.c;
  var miyRw = blob.read_shift(2);
  blob.l += 4; // reserved(2), unused(2)
  var flags = blob.read_shift(1); // various flags
  blob.l += 3; // reserved(8), ixfe(12), flags(4)
  if (flags & 0x07) z.level = flags & 0x07;
  // collapsed: flags & 0x10
  if (flags & 0x20) z.hidden = true;
  if (flags & 0x40) z.hpt = miyRw / 20;
  return z;
}

/* [MS-XLS] 2.4.125 */
function parse_ForceFullCalculation(blob) {
  var header = parse_frtHeader(blob);
  if (header.type != 0x08A3) throw new Error("Invalid Future Record " + header.type);
  var fullcalc = blob.read_shift(4);
  return fullcalc !== 0x0;
}

/* [MS-XLS] 2.4.215 rt */
function parse_RecalcId(blob) {
  blob.read_shift(2);
  return blob.read_shift(4);
}

/* [MS-XLS] 2.4.87 */
function parse_DefaultRowHeight(blob, length, opts) {
  var f = 0;
  if (!(opts && opts.biff == 2)) {
    f = blob.read_shift(2);
  }
  var miyRw = blob.read_shift(2);
  if (opts && opts.biff == 2) {
    f = 1 - (miyRw >> 15);
    miyRw &= 0x7fff;
  }
  var fl = {
    Unsynced: f & 1,
    DyZero: (f & 2) >> 1,
    ExAsc: (f & 4) >> 2,
    ExDsc: (f & 8) >> 3
  };
  return [fl, miyRw];
}

/* [MS-XLS] 2.4.345 TODO */
function parse_Window1(blob) {
  var xWn = blob.read_shift(2),
    yWn = blob.read_shift(2),
    dxWn = blob.read_shift(2),
    dyWn = blob.read_shift(2);
  var flags = blob.read_shift(2),
    iTabCur = blob.read_shift(2),
    iTabFirst = blob.read_shift(2);
  var ctabSel = blob.read_shift(2),
    wTabRatio = blob.read_shift(2);
  return {
    Pos: [xWn, yWn],
    Dim: [dxWn, dyWn],
    Flags: flags,
    CurTab: iTabCur,
    FirstTab: iTabFirst,
    Selected: ctabSel,
    TabRatio: wTabRatio
  };
}
function write_Window1(/*::opts*/
) {
  var o = new_buf(18);
  o.write_shift(2, 0);
  o.write_shift(2, 0);
  o.write_shift(2, 0x7260);
  o.write_shift(2, 0x44c0);
  o.write_shift(2, 0x38);
  o.write_shift(2, 0);
  o.write_shift(2, 0);
  o.write_shift(2, 1);
  o.write_shift(2, 0x01f4);
  return o;
}
/* [MS-XLS] 2.4.346 TODO */
function parse_Window2(blob, length, opts) {
  if (opts && opts.biff >= 2 && opts.biff < 5) return {};
  var f = blob.read_shift(2);
  return {
    RTL: f & 0x40
  };
}
function write_Window2(view) {
  var o = new_buf(18),
    f = 0x6b6;
  if (view && view.RTL) f |= 0x40;
  o.write_shift(2, f);
  o.write_shift(4, 0);
  o.write_shift(4, 64);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  return o;
}

/* [MS-XLS] 2.4.189 TODO */
function parse_Pane(/*blob, length, opts*/
) {}

/* [MS-XLS] 2.4.122 TODO */
function parse_Font(blob, length, opts) {
  var o /*:any*/ = {
    dyHeight: blob.read_shift(2),
    fl: blob.read_shift(2)
  };
  switch (opts && opts.biff || 8) {
    case 2:
      break;
    case 3:
    case 4:
      blob.l += 2;
      break;
    default:
      blob.l += 10;
      break;
  }
  o.name = parse_ShortXLUnicodeString(blob, 0, opts);
  return o;
}
function write_Font(data, opts) {
  var name = data.name || "Arial";
  var b5 = opts && opts.biff == 5,
    w = b5 ? 15 + name.length : 16 + 2 * name.length;
  var o = new_buf(w);
  o.write_shift(2, (data.sz || 12) * 20);
  o.write_shift(4, 0);
  o.write_shift(2, 400);
  o.write_shift(4, 0);
  o.write_shift(2, 0);
  o.write_shift(1, name.length);
  if (!b5) o.write_shift(1, 1);
  o.write_shift((b5 ? 1 : 2) * name.length, name, b5 ? "sbcs" : "utf16le");
  return o;
}

/* [MS-XLS] 2.4.149 */
function parse_LabelSst(blob) {
  var cell = parse_XLSCell(blob);
  cell.isst = blob.read_shift(4);
  return cell;
}
function write_LabelSst(R /*:number*/, C /*:number*/, v /*:number*/, os /*:number*/ /*::, opts*/) {
  var o = new_buf(10);
  write_XLSCell(R, C, os, o);
  o.write_shift(4, v);
  return o;
}

/* [MS-XLS] 2.4.148 */
function parse_Label(blob, length, opts) {
  if (opts.biffguess && opts.biff == 2) opts.biff = 5;
  var target = blob.l + length;
  var cell = parse_XLSCell(blob, 6);
  if (opts.biff == 2) blob.l++;
  var str = parse_XLUnicodeString(blob, target - blob.l, opts);
  cell.val = str;
  return cell;
}
function write_Label(R /*:number*/, C /*:number*/, v /*:string*/, os /*:number*/, opts) {
  var b8 = !opts || opts.biff == 8;
  var o = new_buf(6 + 2 + +b8 + (1 + b8) * v.length);
  write_XLSCell(R, C, os, o);
  o.write_shift(2, v.length);
  if (b8) o.write_shift(1, 1);
  o.write_shift((1 + b8) * v.length, v, b8 ? 'utf16le' : 'sbcs');
  return o;
}

/* [MS-XLS] 2.4.126 Number Formats */
function parse_Format(blob, length, opts) {
  var numFmtId = blob.read_shift(2);
  var fmtstr = parse_XLUnicodeString2(blob, 0, opts);
  return [numFmtId, fmtstr];
}
function write_Format(i /*:number*/, f /*:string*/, opts, o) {
  var b5 = opts && opts.biff == 5;
  if (!o) o = new_buf(b5 ? 3 + f.length : 5 + 2 * f.length);
  o.write_shift(2, i);
  o.write_shift(b5 ? 1 : 2, f.length);
  if (!b5) o.write_shift(1, 1);
  o.write_shift((b5 ? 1 : 2) * f.length, f, b5 ? 'sbcs' : 'utf16le');
  var out = o.length > o.l ? o.slice(0, o.l) : o;
  if (out.l == null) out.l = out.length;
  return out;
}
var parse_BIFF2Format = parse_XLUnicodeString2;

/* [MS-XLS] 2.4.90 */
function parse_Dimensions(blob, length, opts) {
  var end = blob.l + length;
  var w = opts.biff == 8 || !opts.biff ? 4 : 2;
  var r = blob.read_shift(w),
    R = blob.read_shift(w);
  var c = blob.read_shift(2),
    C = blob.read_shift(2);
  blob.l = end;
  return {
    s: {
      r: r,
      c: c
    },
    e: {
      r: R,
      c: C
    }
  };
}
function write_Dimensions(range, opts) {
  var w = opts.biff == 8 || !opts.biff ? 4 : 2;
  var o = new_buf(2 * w + 6);
  o.write_shift(w, range.s.r);
  o.write_shift(w, range.e.r + 1);
  o.write_shift(2, range.s.c);
  o.write_shift(2, range.e.c + 1);
  o.write_shift(2, 0);
  return o;
}

/* [MS-XLS] 2.4.220 */
function parse_RK(blob) {
  var rw = blob.read_shift(2),
    col = blob.read_shift(2);
  var rkrec = parse_RkRec(blob);
  return {
    r: rw,
    c: col,
    ixfe: rkrec[0],
    rknum: rkrec[1]
  };
}

/* [MS-XLS] 2.4.175 */
function parse_MulRk(blob, length) {
  var target = blob.l + length - 2;
  var rw = blob.read_shift(2),
    col = blob.read_shift(2);
  var rkrecs = [];
  while (blob.l < target) rkrecs.push(parse_RkRec(blob));
  if (blob.l !== target) throw new Error("MulRK read error");
  var lastcol = blob.read_shift(2);
  if (rkrecs.length != lastcol - col + 1) throw new Error("MulRK length mismatch");
  return {
    r: rw,
    c: col,
    C: lastcol,
    rkrec: rkrecs
  };
}
/* [MS-XLS] 2.4.174 */
function parse_MulBlank(blob, length) {
  var target = blob.l + length - 2;
  var rw = blob.read_shift(2),
    col = blob.read_shift(2);
  var ixfes = [];
  while (blob.l < target) ixfes.push(blob.read_shift(2));
  if (blob.l !== target) throw new Error("MulBlank read error");
  var lastcol = blob.read_shift(2);
  if (ixfes.length != lastcol - col + 1) throw new Error("MulBlank length mismatch");
  return {
    r: rw,
    c: col,
    C: lastcol,
    ixfe: ixfes
  };
}

/* [MS-XLS] 2.5.20 2.5.249 TODO: interpret values here */
function parse_CellStyleXF(blob, length, style, opts) {
  var o = {};
  var a = blob.read_shift(4),
    b = blob.read_shift(4);
  var c = blob.read_shift(4),
    d = blob.read_shift(2);
  o.patternType = XLSFillPattern[c >> 26];
  if (!opts.cellStyles) return o;
  o.alc = a & 0x07;
  o.fWrap = a >> 3 & 0x01;
  o.alcV = a >> 4 & 0x07;
  o.fJustLast = a >> 7 & 0x01;
  o.trot = a >> 8 & 0xFF;
  o.cIndent = a >> 16 & 0x0F;
  o.fShrinkToFit = a >> 20 & 0x01;
  o.iReadOrder = a >> 22 & 0x02;
  o.fAtrNum = a >> 26 & 0x01;
  o.fAtrFnt = a >> 27 & 0x01;
  o.fAtrAlc = a >> 28 & 0x01;
  o.fAtrBdr = a >> 29 & 0x01;
  o.fAtrPat = a >> 30 & 0x01;
  o.fAtrProt = a >> 31 & 0x01;
  o.dgLeft = b & 0x0F;
  o.dgRight = b >> 4 & 0x0F;
  o.dgTop = b >> 8 & 0x0F;
  o.dgBottom = b >> 12 & 0x0F;
  o.icvLeft = b >> 16 & 0x7F;
  o.icvRight = b >> 23 & 0x7F;
  o.grbitDiag = b >> 30 & 0x03;
  o.icvTop = c & 0x7F;
  o.icvBottom = c >> 7 & 0x7F;
  o.icvDiag = c >> 14 & 0x7F;
  o.dgDiag = c >> 21 & 0x0F;
  o.icvFore = d & 0x7F;
  o.icvBack = d >> 7 & 0x7F;
  o.fsxButton = d >> 14 & 0x01;
  return o;
}
//function parse_CellXF(blob, length, opts) {return parse_CellStyleXF(blob,length,0, opts);}
//function parse_StyleXF(blob, length, opts) {return parse_CellStyleXF(blob,length,1, opts);}

/* [MS-XLS] 2.4.353 TODO: actually do this right */
function parse_XF(blob, length, opts) {
  var o = {};
  o.ifnt = blob.read_shift(2);
  o.numFmtId = blob.read_shift(2);
  o.flags = blob.read_shift(2);
  o.fStyle = o.flags >> 2 & 0x01;
  length -= 6;
  o.data = parse_CellStyleXF(blob, length, o.fStyle, opts);
  return o;
}
function write_XF(data, ixfeP, opts, o) {
  var b5 = opts && opts.biff == 5;
  if (!o) o = new_buf(b5 ? 16 : 20);
  o.write_shift(2, 0);
  if (data.style) {
    o.write_shift(2, data.numFmtId || 0);
    o.write_shift(2, 0xFFF4);
  } else {
    o.write_shift(2, data.numFmtId || 0);
    o.write_shift(2, ixfeP << 4);
  }
  var f = 0;
  if (data.numFmtId > 0 && b5) f |= 0x0400;
  o.write_shift(4, f);
  o.write_shift(4, 0);
  if (!b5) o.write_shift(4, 0);
  o.write_shift(2, 0);
  return o;
}

/* [MS-XLS] 2.4.134 */
function parse_Guts(blob) {
  blob.l += 4;
  var out = [blob.read_shift(2), blob.read_shift(2)];
  if (out[0] !== 0) out[0]--;
  if (out[1] !== 0) out[1]--;
  if (out[0] > 7 || out[1] > 7) throw new Error("Bad Gutters: " + out.join("|"));
  return out;
}
function write_Guts(guts /*:Array<number>*/) {
  var o = new_buf(8);
  o.write_shift(4, 0);
  o.write_shift(2, guts[0] ? guts[0] + 1 : 0);
  o.write_shift(2, guts[1] ? guts[1] + 1 : 0);
  return o;
}

/* [MS-XLS] 2.4.24 */
function parse_BoolErr(blob, length, opts) {
  var cell = parse_XLSCell(blob, 6);
  if (opts.biff == 2 || length == 9) ++blob.l;
  var val = parse_Bes(blob, 2);
  cell.val = val;
  cell.t = val === true || val === false ? 'b' : 'e';
  return cell;
}
function write_BoolErr(R /*:number*/, C /*:number*/, v, os /*:number*/, opts, t /*:string*/) {
  var o = new_buf(8);
  write_XLSCell(R, C, os, o);
  write_Bes(v, t, o);
  return o;
}

/* [MS-XLS] 2.4.180 Number */
function parse_Number(blob, length, opts) {
  if (opts.biffguess && opts.biff == 2) opts.biff = 5;
  var cell = parse_XLSCell(blob, 6);
  var xnum = parse_Xnum(blob, 8);
  cell.val = xnum;
  return cell;
}
function write_Number(R /*:number*/, C /*:number*/, v, os /*:: :number, opts*/) {
  var o = new_buf(14);
  write_XLSCell(R, C, os, o);
  write_Xnum(v, o);
  return o;
}
var parse_XLHeaderFooter = parse_OptXLUnicodeString; // TODO: parse 2.4.136

/* [MS-XLS] 2.4.271 */
function parse_SupBook(blob, length, opts) {
  var end = blob.l + length;
  var ctab = blob.read_shift(2);
  var cch = blob.read_shift(2);
  opts.sbcch = cch;
  if (cch == 0x0401 || cch == 0x3A01) return [cch, ctab];
  if (cch < 0x01 || cch > 0xff) throw new Error("Unexpected SupBook type: " + cch);
  var virtPath = parse_XLUnicodeStringNoCch(blob, cch);
  /* TODO: 2.5.277 Virtual Path */
  var rgst = [];
  while (end > blob.l) rgst.push(parse_XLUnicodeString(blob));
  return [cch, ctab, virtPath, rgst];
}

/* [MS-XLS] 2.4.105 TODO */
function parse_ExternName(blob, length, opts) {
  var flags = blob.read_shift(2);
  var body;
  var o = {
    fBuiltIn: flags & 0x01,
    fWantAdvise: flags >>> 1 & 0x01,
    fWantPict: flags >>> 2 & 0x01,
    fOle: flags >>> 3 & 0x01,
    fOleLink: flags >>> 4 & 0x01,
    cf: flags >>> 5 & 0x3FF,
    fIcon: flags >>> 15 & 0x01
  } /*:any*/;
  if (opts.sbcch === 0x3A01) body = parse_AddinUdf(blob, length - 2, opts);
  //else throw new Error("unsupported SupBook cch: " + opts.sbcch);
  o.body = body || blob.read_shift(length - 2);
  if (typeof body === "string") o.Name = body;
  return o;
}

/* [MS-XLS] 2.4.150 TODO */
var XLSLblBuiltIn = ["_xlnm.Consolidate_Area", "_xlnm.Auto_Open", "_xlnm.Auto_Close", "_xlnm.Extract", "_xlnm.Database", "_xlnm.Criteria", "_xlnm.Print_Area", "_xlnm.Print_Titles", "_xlnm.Recorder", "_xlnm.Data_Form", "_xlnm.Auto_Activate", "_xlnm.Auto_Deactivate", "_xlnm.Sheet_Title", "_xlnm._FilterDatabase"];
function parse_Lbl(blob, length, opts) {
  var target = blob.l + length;
  var flags = blob.read_shift(2);
  var chKey = blob.read_shift(1);
  var cch = blob.read_shift(1);
  var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  var itab = 0;
  if (!opts || opts.biff >= 5) {
    if (opts.biff != 5) blob.l += 2;
    itab = blob.read_shift(2);
    if (opts.biff == 5) blob.l += 2;
    blob.l += 4;
  }
  var name = parse_XLUnicodeStringNoCch(blob, cch, opts);
  if (flags & 0x20) name = XLSLblBuiltIn[name.charCodeAt(0)];
  var npflen = target - blob.l;
  if (opts && opts.biff == 2) --npflen;
  /*jshint -W018 */
  var rgce = target == blob.l || cce === 0 || !(npflen > 0) ? [] : parse_NameParsedFormula(blob, npflen, opts, cce);
  /*jshint +W018 */
  return {
    chKey: chKey,
    Name: name,
    itab: itab,
    rgce: rgce
  };
}

/* [MS-XLS] 2.4.106 TODO: verify filename encoding */
function parse_ExternSheet(blob, length, opts) {
  if (opts.biff < 8) return parse_BIFF5ExternSheet(blob, length, opts);
  var o = [],
    target = blob.l + length,
    len = blob.read_shift(opts.biff > 8 ? 4 : 2);
  while (len-- !== 0) o.push(parse_XTI(blob, opts.biff > 8 ? 12 : 6, opts));
  // [iSupBook, itabFirst, itabLast];
  if (blob.l != target) throw new Error("Bad ExternSheet: " + blob.l + " != " + target);
  return o;
}
function parse_BIFF5ExternSheet(blob, length, opts) {
  if (blob[blob.l + 1] == 0x03) blob[blob.l]++;
  var o = parse_ShortXLUnicodeString(blob, length, opts);
  return o.charCodeAt(0) == 0x03 ? o.slice(1) : o;
}

/* [MS-XLS] 2.4.176 TODO: check older biff */
function parse_NameCmt(blob, length, opts) {
  if (opts.biff < 8) {
    blob.l += length;
    return;
  }
  var cchName = blob.read_shift(2);
  var cchComment = blob.read_shift(2);
  var name = parse_XLUnicodeStringNoCch(blob, cchName, opts);
  var comment = parse_XLUnicodeStringNoCch(blob, cchComment, opts);
  return [name, comment];
}

/* [MS-XLS] 2.4.260 */
function parse_ShrFmla(blob, length, opts) {
  var ref = parse_RefU(blob, 6);
  blob.l++;
  var cUse = blob.read_shift(1);
  length -= 8;
  return [parse_SharedParsedFormula(blob, length, opts), cUse, ref];
}

/* [MS-XLS] 2.4.4 TODO */
function parse_Array(blob, length, opts) {
  var ref = parse_Ref(blob, 6);
  /* TODO: fAlwaysCalc */
  switch (opts.biff) {
    case 2:
      blob.l++;
      length -= 7;
      break;
    case 3:
    case 4:
      blob.l += 2;
      length -= 8;
      break;
    default:
      blob.l += 6;
      length -= 12;
  }
  return [ref, parse_ArrayParsedFormula(blob, length, opts, ref)];
}

/* [MS-XLS] 2.4.173 */
function parse_MTRSettings(blob) {
  var fMTREnabled = blob.read_shift(4) !== 0x00;
  var fUserSetThreadCount = blob.read_shift(4) !== 0x00;
  var cUserThreadCount = blob.read_shift(4);
  return [fMTREnabled, fUserSetThreadCount, cUserThreadCount];
}

/* [MS-XLS] 2.5.186 TODO: BIFF5 */
function parse_NoteSh(blob, length, opts) {
  if (opts.biff < 8) return;
  var row = blob.read_shift(2),
    col = blob.read_shift(2);
  var flags = blob.read_shift(2),
    idObj = blob.read_shift(2);
  var stAuthor = parse_XLUnicodeString2(blob, 0, opts);
  if (opts.biff < 8) blob.read_shift(1);
  return [{
    r: row,
    c: col
  }, stAuthor, idObj, flags];
}

/* [MS-XLS] 2.4.179 */
function parse_Note(blob, length, opts) {
  /* TODO: Support revisions */
  return parse_NoteSh(blob, length, opts);
}

/* [MS-XLS] 2.4.168 */
function parse_MergeCells(blob, length) /*:Array<Range>*/{
  var merges /*:Array<Range>*/ = [];
  var cmcs = blob.read_shift(2);
  while (cmcs--) merges.push(parse_Ref8U(blob, length));
  return merges;
}
function write_MergeCells(merges /*:Array<Range>*/) {
  var o = new_buf(2 + merges.length * 8);
  o.write_shift(2, merges.length);
  for (var i = 0; i < merges.length; ++i) write_Ref8U(merges[i], o);
  return o;
}

/* [MS-XLS] 2.4.181 TODO: parse all the things! */
function parse_Obj(blob, length, opts) {
  if (opts && opts.biff < 8) return parse_BIFF5Obj(blob, length, opts);
  var cmo = parse_FtCmo(blob, 22); // id, ot, flags
  var fts = parse_FtArray(blob, length - 22, cmo[1]);
  return {
    cmo: cmo,
    ft: fts
  };
}
/* from older spec */
var parse_BIFF5OT = {
  0x08: function (blob, length) {
    var tgt = blob.l + length;
    blob.l += 10; // todo
    var cf = blob.read_shift(2);
    blob.l += 4;
    blob.l += 2; //var cbPictFmla = blob.read_shift(2);
    blob.l += 2;
    blob.l += 2; //var grbit = blob.read_shift(2);
    blob.l += 4;
    var cchName = blob.read_shift(1);
    blob.l += cchName; // TODO: stName
    blob.l = tgt; // TODO: fmla
    return {
      fmt: cf
    };
  }
};
function parse_BIFF5Obj(blob, length, opts) {
  blob.l += 4; //var cnt = blob.read_shift(4);
  var ot = blob.read_shift(2);
  var id = blob.read_shift(2);
  var grbit = blob.read_shift(2);
  blob.l += 2; //var colL = blob.read_shift(2);
  blob.l += 2; //var dxL = blob.read_shift(2);
  blob.l += 2; //var rwT = blob.read_shift(2);
  blob.l += 2; //var dyT = blob.read_shift(2);
  blob.l += 2; //var colR = blob.read_shift(2);
  blob.l += 2; //var dxR = blob.read_shift(2);
  blob.l += 2; //var rwB = blob.read_shift(2);
  blob.l += 2; //var dyB = blob.read_shift(2);
  blob.l += 2; //var cbMacro = blob.read_shift(2);
  blob.l += 6;
  length -= 36;
  var fts = [];
  fts.push((parse_BIFF5OT[ot] || parsenoop)(blob, length, opts));
  return {
    cmo: [id, ot, grbit],
    ft: fts
  };
}

/* [MS-XLS] 2.4.329 TODO: parse properly */
function parse_TxO(blob, length, opts) {
  var s = blob.l;
  var texts = "";
  try {
    blob.l += 4;
    var ot = (opts.lastobj || {
      cmo: [0, 0]
    }).cmo[1];
    var controlInfo; // eslint-disable-line no-unused-vars
    if ([0, 5, 7, 11, 12, 14].indexOf(ot) == -1) blob.l += 6;else controlInfo = parse_ControlInfo(blob, 6, opts); // eslint-disable-line no-unused-vars
    var cchText = blob.read_shift(2);
    /*var cbRuns = */
    blob.read_shift(2);
    /*var ifntEmpty = */
    parseuint16(blob, 2);
    var len = blob.read_shift(2);
    blob.l += len;
    //var fmla = parse_ObjFmla(blob, s + length - blob.l);

    for (var i = 1; i < blob.lens.length - 1; ++i) {
      if (blob.l - s != blob.lens[i]) throw new Error("TxO: bad continue record");
      var hdr = blob[blob.l];
      var t = parse_XLUnicodeStringNoCch(blob, blob.lens[i + 1] - blob.lens[i] - 1);
      texts += t;
      if (texts.length >= (hdr ? cchText : 2 * cchText)) break;
    }
    if (texts.length !== cchText && texts.length !== cchText * 2) {
      throw new Error("cchText: " + cchText + " != " + texts.length);
    }
    blob.l = s + length;
    /* [MS-XLS] 2.5.272 TxORuns */
    //	var rgTxoRuns = [];
    //	for(var j = 0; j != cbRuns/8-1; ++j) blob.l += 8;
    //	var cchText2 = blob.read_shift(2);
    //	if(cchText2 !== cchText) throw new Error("TxOLastRun mismatch: " + cchText2 + " " + cchText);
    //	blob.l += 6;
    //	if(s + length != blob.l) throw new Error("TxO " + (s + length) + ", at " + blob.l);
    return {
      t: texts
    };
  } catch (e) {
    blob.l = s + length;
    return {
      t: texts
    };
  }
}

/* [MS-XLS] 2.4.140 */
function parse_HLink(blob, length) {
  var ref = parse_Ref8U(blob, 8);
  blob.l += 16; /* CLSID */
  var hlink = parse_Hyperlink(blob, length - 24);
  return [ref, hlink];
}
function write_HLink(hl) {
  var O = new_buf(24);
  var ref = decode_cell(hl[0]);
  O.write_shift(2, ref.r);
  O.write_shift(2, ref.r);
  O.write_shift(2, ref.c);
  O.write_shift(2, ref.c);
  var clsid = "d0 c9 ea 79 f9 ba ce 11 8c 82 00 aa 00 4b a9 0b".split(" ");
  for (var i = 0; i < 16; ++i) O.write_shift(1, parseInt(clsid[i], 16));
  return bconcat([O, write_Hyperlink(hl[1])]);
}

/* [MS-XLS] 2.4.141 */
function parse_HLinkTooltip(blob, length) {
  blob.read_shift(2);
  var ref = parse_Ref8U(blob, 8);
  var wzTooltip = blob.read_shift((length - 10) / 2, 'dbcs-cont');
  wzTooltip = wzTooltip.replace(chr0, "");
  return [ref, wzTooltip];
}
function write_HLinkTooltip(hl) {
  var TT = hl[1].Tooltip;
  var O = new_buf(10 + 2 * (TT.length + 1));
  O.write_shift(2, 0x0800);
  var ref = decode_cell(hl[0]);
  O.write_shift(2, ref.r);
  O.write_shift(2, ref.r);
  O.write_shift(2, ref.c);
  O.write_shift(2, ref.c);
  for (var i = 0; i < TT.length; ++i) O.write_shift(2, TT.charCodeAt(i));
  O.write_shift(2, 0);
  return O;
}

/* [MS-XLS] 2.4.63 */
function parse_Country(blob) /*:[string|number, string|number]*/{
  var o = [0, 0],
    d;
  d = blob.read_shift(2);
  o[0] = CountryEnum[d] || d;
  d = blob.read_shift(2);
  o[1] = CountryEnum[d] || d;
  return o;
}
function write_Country(o) {
  if (!o) o = new_buf(4);
  o.write_shift(2, 0x01);
  o.write_shift(2, 0x01);
  return o;
}

/* [MS-XLS] 2.4.50 ClrtClient */
function parse_ClrtClient(blob) {
  var ccv = blob.read_shift(2);
  var o = [];
  while (ccv-- > 0) o.push(parse_LongRGB(blob, 8));
  return o;
}

/* [MS-XLS] 2.4.188 */
function parse_Palette(blob) {
  var ccv = blob.read_shift(2);
  var o = [];
  while (ccv-- > 0) o.push(parse_LongRGB(blob, 8));
  return o;
}

/* [MS-XLS] 2.4.354 */
function parse_XFCRC(blob) {
  blob.l += 2;
  var o = {
    cxfs: 0,
    crc: 0
  };
  o.cxfs = blob.read_shift(2);
  o.crc = blob.read_shift(4);
  return o;
}

/* [MS-XLS] 2.4.53 TODO: parse flags */
/* [MS-XLSB] 2.4.323 TODO: parse flags */
function parse_ColInfo(blob, length, opts) {
  if (!opts.cellStyles) return parsenoop(blob, length);
  var w = opts && opts.biff >= 12 ? 4 : 2;
  var colFirst = blob.read_shift(w);
  var colLast = blob.read_shift(w);
  var coldx = blob.read_shift(w);
  var ixfe = blob.read_shift(w);
  var flags = blob.read_shift(2);
  if (w == 2) blob.l += 2;
  var o = {
    s: colFirst,
    e: colLast,
    w: coldx,
    ixfe: ixfe,
    flags: flags
  } /*:any*/;
  if (opts.biff >= 5 || !opts.biff) o.level = flags >> 8 & 0x7;
  return o;
}
function write_ColInfo(col, idx) {
  var o = new_buf(12);
  o.write_shift(2, idx);
  o.write_shift(2, idx);
  o.write_shift(2, col.width * 256);
  o.write_shift(2, 0);
  var f = 0;
  if (col.hidden) f |= 1;
  o.write_shift(1, f);
  f = col.level || 0;
  o.write_shift(1, f);
  o.write_shift(2, 0);
  return o;
}

/* [MS-XLS] 2.4.257 */
function parse_Setup(blob, length) {
  var o = {};
  if (length < 32) return o;
  blob.l += 16;
  o.header = parse_Xnum(blob, 8);
  o.footer = parse_Xnum(blob, 8);
  blob.l += 2;
  return o;
}

/* [MS-XLS] 2.4.261 */
function parse_ShtProps(blob, length, opts) {
  var def = {
    area: false
  };
  if (opts.biff != 5) {
    blob.l += length;
    return def;
  }
  var d = blob.read_shift(1);
  blob.l += 3;
  if (d & 0x10) def.area = true;
  return def;
}

/* [MS-XLS] 2.4.241 */
function write_RRTabId(n /*:number*/) {
  var out = new_buf(2 * n);
  for (var i = 0; i < n; ++i) out.write_shift(2, i + 1);
  return out;
}
var parse_Blank = parse_XLSCell; /* [MS-XLS] 2.4.20 Just the cell */
var parse_Scl = parseuint16a; /* [MS-XLS] 2.4.247 num, den */
var parse_String = parse_XLUnicodeString; /* [MS-XLS] 2.4.268 */

/* --- Specific to versions before BIFF8 --- */
function parse_ImData(blob) {
  var cf = blob.read_shift(2);
  var env = blob.read_shift(2);
  var lcb = blob.read_shift(4);
  var o = {
    fmt: cf,
    env: env,
    len: lcb,
    data: blob.slice(blob.l, blob.l + lcb)
  };
  blob.l += lcb;
  return o;
}

/* BIFF2_??? where ??? is the name from [XLS] */
function parse_BIFF2STR(blob, length, opts) {
  if (opts.biffguess && opts.biff == 5) opts.biff = 2;
  var cell = parse_XLSCell(blob, 6);
  ++blob.l;
  var str = parse_XLUnicodeString2(blob, length - 7, opts);
  cell.t = 'str';
  cell.val = str;
  return cell;
}
function parse_BIFF2NUM(blob /*::, length*/) {
  var cell = parse_XLSCell(blob, 6);
  ++blob.l;
  var num = parse_Xnum(blob, 8);
  cell.t = 'n';
  cell.val = num;
  return cell;
}
function write_BIFF2NUM(r /*:number*/, c /*:number*/, val /*:number*/) {
  var out = new_buf(15);
  write_BIFF2Cell(out, r, c);
  out.write_shift(8, val, 'f');
  return out;
}
function parse_BIFF2INT(blob) {
  var cell = parse_XLSCell(blob, 6);
  ++blob.l;
  var num = blob.read_shift(2);
  cell.t = 'n';
  cell.val = num;
  return cell;
}
function write_BIFF2INT(r /*:number*/, c /*:number*/, val /*:number*/) {
  var out = new_buf(9);
  write_BIFF2Cell(out, r, c);
  out.write_shift(2, val);
  return out;
}
function parse_BIFF2STRING(blob) {
  var cch = blob.read_shift(1);
  if (cch === 0) {
    blob.l++;
    return "";
  }
  return blob.read_shift(cch, 'sbcs-cont');
}

/* TODO: convert to BIFF8 font struct */
function parse_BIFF2FONTXTRA(blob, length) {
  blob.l += 6; // unknown
  blob.l += 2; // font weight "bls"
  blob.l += 1; // charset
  blob.l += 3; // unknown
  blob.l += 1; // font family
  blob.l += length - 13;
}

/* TODO: parse rich text runs */
function parse_RString(blob, length, opts) {
  var end = blob.l + length;
  var cell = parse_XLSCell(blob, 6);
  var cch = blob.read_shift(2);
  var str = parse_XLUnicodeStringNoCch(blob, cch, opts);
  blob.l = end;
  cell.t = 'str';
  cell.val = str;
  return cell;
}
/* from js-harb (C) 2014-present  SheetJS */
var DBF_SUPPORTED_VERSIONS = [0x02, 0x03, 0x30, 0x31, 0x83, 0x8B, 0x8C, 0xF5];
var DBF = /*#__PURE__*/function () {
  var dbf_codepage_map = {
    /* Code Pages Supported by Visual FoxPro */
    /*::[*/0x01 /*::]*/: 437,
    /*::[*/0x02 /*::]*/: 850,
    /*::[*/0x03 /*::]*/: 1252,
    /*::[*/0x04 /*::]*/: 10000,
    /*::[*/0x64 /*::]*/: 852,
    /*::[*/0x65 /*::]*/: 866,
    /*::[*/0x66 /*::]*/: 865,
    /*::[*/0x67 /*::]*/: 861,
    /*::[*/0x68 /*::]*/: 895,
    /*::[*/0x69 /*::]*/: 620,
    /*::[*/0x6A /*::]*/: 737,
    /*::[*/0x6B /*::]*/: 857,
    /*::[*/0x78 /*::]*/: 950,
    /*::[*/0x79 /*::]*/: 949,
    /*::[*/0x7A /*::]*/: 936,
    /*::[*/0x7B /*::]*/: 932,
    /*::[*/0x7C /*::]*/: 874,
    /*::[*/0x7D /*::]*/: 1255,
    /*::[*/0x7E /*::]*/: 1256,
    /*::[*/0x96 /*::]*/: 10007,
    /*::[*/0x97 /*::]*/: 10029,
    /*::[*/0x98 /*::]*/: 10006,
    /*::[*/0xC8 /*::]*/: 1250,
    /*::[*/0xC9 /*::]*/: 1251,
    /*::[*/0xCA /*::]*/: 1254,
    /*::[*/0xCB /*::]*/: 1253,
    /* shapefile DBF extension */
    /*::[*/0x00 /*::]*/: 20127,
    /*::[*/0x08 /*::]*/: 865,
    /*::[*/0x09 /*::]*/: 437,
    /*::[*/0x0A /*::]*/: 850,
    /*::[*/0x0B /*::]*/: 437,
    /*::[*/0x0D /*::]*/: 437,
    /*::[*/0x0E /*::]*/: 850,
    /*::[*/0x0F /*::]*/: 437,
    /*::[*/0x10 /*::]*/: 850,
    /*::[*/0x11 /*::]*/: 437,
    /*::[*/0x12 /*::]*/: 850,
    /*::[*/0x13 /*::]*/: 932,
    /*::[*/0x14 /*::]*/: 850,
    /*::[*/0x15 /*::]*/: 437,
    /*::[*/0x16 /*::]*/: 850,
    /*::[*/0x17 /*::]*/: 865,
    /*::[*/0x18 /*::]*/: 437,
    /*::[*/0x19 /*::]*/: 437,
    /*::[*/0x1A /*::]*/: 850,
    /*::[*/0x1B /*::]*/: 437,
    /*::[*/0x1C /*::]*/: 863,
    /*::[*/0x1D /*::]*/: 850,
    /*::[*/0x1F /*::]*/: 852,
    /*::[*/0x22 /*::]*/: 852,
    /*::[*/0x23 /*::]*/: 852,
    /*::[*/0x24 /*::]*/: 860,
    /*::[*/0x25 /*::]*/: 850,
    /*::[*/0x26 /*::]*/: 866,
    /*::[*/0x37 /*::]*/: 850,
    /*::[*/0x40 /*::]*/: 852,
    /*::[*/0x4D /*::]*/: 936,
    /*::[*/0x4E /*::]*/: 949,
    /*::[*/0x4F /*::]*/: 950,
    /*::[*/0x50 /*::]*/: 874,
    /*::[*/0x57 /*::]*/: 1252,
    /*::[*/0x58 /*::]*/: 1252,
    /*::[*/0x59 /*::]*/: 1252,
    /*::[*/0x6C /*::]*/: 863,
    /*::[*/0x86 /*::]*/: 737,
    /*::[*/0x87 /*::]*/: 852,
    /*::[*/0x88 /*::]*/: 857,
    /*::[*/0xCC /*::]*/: 1257,
    /*::[*/0xFF /*::]*/: 16969
  };
  var dbf_reverse_map = evert({
    /*::[*/0x01 /*::]*/: 437,
    /*::[*/0x02 /*::]*/: 850,
    /*::[*/0x03 /*::]*/: 1252,
    /*::[*/0x04 /*::]*/: 10000,
    /*::[*/0x64 /*::]*/: 852,
    /*::[*/0x65 /*::]*/: 866,
    /*::[*/0x66 /*::]*/: 865,
    /*::[*/0x67 /*::]*/: 861,
    /*::[*/0x68 /*::]*/: 895,
    /*::[*/0x69 /*::]*/: 620,
    /*::[*/0x6A /*::]*/: 737,
    /*::[*/0x6B /*::]*/: 857,
    /*::[*/0x78 /*::]*/: 950,
    /*::[*/0x79 /*::]*/: 949,
    /*::[*/0x7A /*::]*/: 936,
    /*::[*/0x7B /*::]*/: 932,
    /*::[*/0x7C /*::]*/: 874,
    /*::[*/0x7D /*::]*/: 1255,
    /*::[*/0x7E /*::]*/: 1256,
    /*::[*/0x96 /*::]*/: 10007,
    /*::[*/0x97 /*::]*/: 10029,
    /*::[*/0x98 /*::]*/: 10006,
    /*::[*/0xC8 /*::]*/: 1250,
    /*::[*/0xC9 /*::]*/: 1251,
    /*::[*/0xCA /*::]*/: 1254,
    /*::[*/0xCB /*::]*/: 1253,
    /*::[*/0x00 /*::]*/: 20127
  });
  /* TODO: find an actual specification */
  function dbf_to_aoa(buf, opts) /*:AOA*/{
    var out /*:AOA*/ = [];
    var d /*:Block*/ = new_raw_buf(1) /*:any*/;
    switch (opts.type) {
      case 'base64':
        d = s2a(Base64_decode(buf));
        break;
      case 'binary':
        d = s2a(buf);
        break;
      case 'buffer':
      case 'array':
        d = buf;
        break;
    }
    prep_blob(d, 0);

    /* header */
    var ft = d.read_shift(1);
    var memo = !!(ft & 0x88);
    var vfp = false,
      l7 = false;
    switch (ft) {
      case 0x02:
        break;
      // dBASE II
      case 0x03:
        break;
      // dBASE III
      case 0x30:
        vfp = true;
        memo = true;
        break;
      // VFP
      case 0x31:
        vfp = true;
        memo = true;
        break;
      // VFP with autoincrement
      // 0x43 dBASE IV SQL table files
      // 0x63 dBASE IV SQL system files
      case 0x83:
        break;
      // dBASE III with memo
      case 0x8B:
        break;
      // dBASE IV with memo
      case 0x8C:
        l7 = true;
        break;
      // dBASE Level 7 with memo
      // case 0xCB dBASE IV SQL table files with memo
      case 0xF5:
        break;
      // FoxPro 2.x with memo
      // case 0xFB FoxBASE
      default:
        throw new Error("DBF Unsupported Version: " + ft.toString(16));
    }
    var nrow = 0,
      fpos = 0x0209;
    if (ft == 0x02) nrow = d.read_shift(2);
    d.l += 3; // dBASE II stores DDMMYY date, others use YYMMDD
    if (ft != 0x02) nrow = d.read_shift(4);
    if (nrow > 1048576) nrow = 1e6;
    if (ft != 0x02) fpos = d.read_shift(2); // header length
    var rlen = d.read_shift(2); // record length

    var /*flags = 0,*/current_cp = opts.codepage || 1252;
    if (ft != 0x02) {
      // 20 reserved bytes
      d.l += 16;
      /*flags = */
      d.read_shift(1);
      //if(memo && ((flags & 0x02) === 0)) throw new Error("DBF Flags " + flags.toString(16) + " ft " + ft.toString(16));

      /* codepage present in FoxPro and dBASE Level 7 */
      if (d[d.l] !== 0) current_cp = dbf_codepage_map[d[d.l]];
      d.l += 1;
      d.l += 2;
    }
    if (l7) d.l += 36; // Level 7: 32 byte "Language driver name", 4 byte reserved

    /*:: type DBFField = { name:string; len:number; type:string; } */
    var fields /*:Array<DBFField>*/ = [],
      field /*:DBFField*/ = {} /*:any*/;
    var hend = Math.min(d.length, ft == 0x02 ? 0x209 : fpos - 10 - (vfp ? 264 : 0));
    var ww = l7 ? 32 : 11;
    while (d.l < hend && d[d.l] != 0x0d) {
      field = {} /*:any*/;
      field.name = $cptable.utils.decode(current_cp, d.slice(d.l, d.l + ww)).replace(/[\u0000\r\n].*$/g, "");
      d.l += ww;
      field.type = String.fromCharCode(d.read_shift(1));
      if (ft != 0x02 && !l7) field.offset = d.read_shift(4);
      field.len = d.read_shift(1);
      if (ft == 0x02) field.offset = d.read_shift(2);
      field.dec = d.read_shift(1);
      if (field.name.length) fields.push(field);
      if (ft != 0x02) d.l += l7 ? 13 : 14;
      switch (field.type) {
        case 'B':
          // Double (VFP) / Binary (dBASE L7)
          if ((!vfp || field.len != 8) && opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
          break;
        case 'G': // General (FoxPro and dBASE L7)
        case 'P':
          // Picture (FoxPro and dBASE L7)
          if (opts.WTF) console.log('Skipping ' + field.name + ':' + field.type);
          break;
        case '+': // Autoincrement (dBASE L7 only)
        case '0': // _NullFlags (VFP only)
        case '@': // Timestamp (dBASE L7 only)
        case 'C': // Character (dBASE II)
        case 'D': // Date (dBASE III)
        case 'F': // Float (dBASE IV)
        case 'I': // Long (VFP and dBASE L7)
        case 'L': // Logical (dBASE II)
        case 'M': // Memo (dBASE III)
        case 'N': // Number (dBASE II)
        case 'O': // Double (dBASE L7 only)
        case 'T': // Datetime (VFP only)
        case 'Y':
          // Currency (VFP only)
          break;
        default:
          throw new Error('Unknown Field Type: ' + field.type);
      }
    }
    if (d[d.l] !== 0x0D) d.l = fpos - 1;
    if (d.read_shift(1) !== 0x0D) throw new Error("DBF Terminator not found " + d.l + " " + d[d.l]);
    d.l = fpos;

    /* data */
    var R = 0,
      C = 0;
    out[0] = [];
    for (C = 0; C != fields.length; ++C) out[0][C] = fields[C].name;
    while (nrow-- > 0) {
      if (d[d.l] === 0x2A) {
        // TODO: record marked as deleted -- create a hidden row?
        d.l += rlen;
        continue;
      }
      ++d.l;
      out[++R] = [];
      C = 0;
      for (C = 0; C != fields.length; ++C) {
        var dd = d.slice(d.l, d.l + fields[C].len);
        d.l += fields[C].len;
        prep_blob(dd, 0);
        var s = $cptable.utils.decode(current_cp, dd);
        switch (fields[C].type) {
          case 'C':
            // NOTE: it is conventional to write '  /  /  ' for empty dates
            if (s.trim().length) out[R][C] = s.replace(/\s+$/, "");
            break;
          case 'D':
            if (s.length === 8) out[R][C] = new Date(+s.slice(0, 4), +s.slice(4, 6) - 1, +s.slice(6, 8));else out[R][C] = s;
            break;
          case 'F':
            out[R][C] = parseFloat(s.trim());
            break;
          case '+':
          case 'I':
            out[R][C] = l7 ? dd.read_shift(-4, 'i') ^ 0x80000000 : dd.read_shift(4, 'i');
            break;
          case 'L':
            switch (s.trim().toUpperCase()) {
              case 'Y':
              case 'T':
                out[R][C] = true;
                break;
              case 'N':
              case 'F':
                out[R][C] = false;
                break;
              case '':
              case '?':
                break;
              default:
                throw new Error("DBF Unrecognized L:|" + s + "|");
            }
            break;
          case 'M':
            /* TODO: handle memo files */
            if (!memo) throw new Error("DBF Unexpected MEMO for type " + ft.toString(16));
            out[R][C] = "##MEMO##" + (l7 ? parseInt(s.trim(), 10) : dd.read_shift(4));
            break;
          case 'N':
            s = s.replace(/\u0000/g, "").trim();
            // NOTE: dBASE II interprets "  .  " as 0
            if (s && s != ".") out[R][C] = +s || 0;
            break;
          case '@':
            // NOTE: dBASE specs appear to be incorrect
            out[R][C] = new Date(dd.read_shift(-8, 'f') - 0x388317533400);
            break;
          case 'T':
            out[R][C] = new Date((dd.read_shift(4) - 0x253D8C) * 0x5265C00 + dd.read_shift(4));
            break;
          case 'Y':
            out[R][C] = dd.read_shift(4, 'i') / 1e4 + dd.read_shift(4, 'i') / 1e4 * Math.pow(2, 32);
            break;
          case 'O':
            out[R][C] = -dd.read_shift(-8, 'f');
            break;
          case 'B':
            if (vfp && fields[C].len == 8) {
              out[R][C] = dd.read_shift(8, 'f');
              break;
            }
          /* falls through */
          case 'G':
          case 'P':
            dd.l += fields[C].len;
            break;
          case '0':
            if (fields[C].name === '_NullFlags') break;
          /* falls through */
          default:
            throw new Error("DBF Unsupported data type " + fields[C].type);
        }
      }
    }
    if (ft != 0x02) if (d.l < d.length && d[d.l++] != 0x1A) throw new Error("DBF EOF Marker missing " + (d.l - 1) + " of " + d.length + " " + d[d.l - 1].toString(16));
    if (opts && opts.sheetRows) out = out.slice(0, opts.sheetRows);
    opts.DBF = fields;
    return out;
  }
  function dbf_to_sheet(buf, opts) /*:Worksheet*/{
    var o = opts || {};
    if (!o.dateNF) o.dateNF = "yyyymmdd";
    var ws = aoa_to_sheet(dbf_to_aoa(buf, o), o);
    ws["!cols"] = o.DBF.map(function (field) {
      return {
        wch: field.len,
        DBF: field
      };
    });
    delete o.DBF;
    return ws;
  }
  function dbf_to_workbook(buf, opts) /*:Workbook*/{
    try {
      return sheet_to_workbook(dbf_to_sheet(buf, opts), opts);
    } catch (e) {
      if (opts && opts.WTF) throw e;
    }
    return {
      SheetNames: [],
      Sheets: {}
    };
  }
  var _RLEN = {
    'B': 8,
    'C': 250,
    'L': 1,
    'D': 8,
    '?': 0,
    '': 0
  };
  function sheet_to_dbf(ws /*:Worksheet*/, opts /*:WriteOpts*/) {
    var o = opts || {};
    if (+o.codepage >= 0) set_cp(+o.codepage);
    if (o.type == "string") throw new Error("Cannot write DBF to JS string");
    var ba = buf_array();
    var aoa /*:AOA*/ = sheet_to_json(ws, {
      header: 1,
      raw: true,
      cellDates: true
    });
    var headers = aoa[0],
      data = aoa.slice(1),
      cols = ws["!cols"] || [];
    var i = 0,
      j = 0,
      hcnt = 0,
      rlen = 1;
    for (i = 0; i < headers.length; ++i) {
      if (((cols[i] || {}).DBF || {}).name) {
        headers[i] = cols[i].DBF.name;
        ++hcnt;
        continue;
      }
      if (headers[i] == null) continue;
      ++hcnt;
      if (typeof headers[i] === 'number') headers[i] = headers[i].toString(10);
      if (typeof headers[i] !== 'string') throw new Error("DBF Invalid column name " + headers[i] + " |" + typeof headers[i] + "|");
      if (headers.indexOf(headers[i]) !== i) for (j = 0; j < 1024; ++j) if (headers.indexOf(headers[i] + "_" + j) == -1) {
        headers[i] += "_" + j;
        break;
      }
    }
    var range = safe_decode_range(ws['!ref']);
    var coltypes /*:Array<string>*/ = [];
    var colwidths /*:Array<number>*/ = [];
    var coldecimals /*:Array<number>*/ = [];
    for (i = 0; i <= range.e.c - range.s.c; ++i) {
      var guess = '',
        _guess = '',
        maxlen = 0;
      var col /*:Array<any>*/ = [];
      for (j = 0; j < data.length; ++j) {
        if (data[j][i] != null) col.push(data[j][i]);
      }
      if (col.length == 0 || headers[i] == null) {
        coltypes[i] = '?';
        continue;
      }
      for (j = 0; j < col.length; ++j) {
        switch (typeof col[j]) {
          /* TODO: check if L2 compat is desired */
          case 'number':
            _guess = 'B';
            break;
          case 'string':
            _guess = 'C';
            break;
          case 'boolean':
            _guess = 'L';
            break;
          case 'object':
            _guess = col[j] instanceof Date ? 'D' : 'C';
            break;
          default:
            _guess = 'C';
        }
        maxlen = Math.max(maxlen, String(col[j]).length);
        guess = guess && guess != _guess ? 'C' : _guess;
        //if(guess == 'C') break;
      }
      if (maxlen > 250) maxlen = 250;
      _guess = ((cols[i] || {}).DBF || {}).type;
      /* TODO: more fine grained control over DBF type resolution */
      if (_guess == 'C') {
        if (cols[i].DBF.len > maxlen) maxlen = cols[i].DBF.len;
      }
      if (guess == 'B' && _guess == 'N') {
        guess = 'N';
        coldecimals[i] = cols[i].DBF.dec;
        maxlen = cols[i].DBF.len;
      }
      colwidths[i] = guess == 'C' || _guess == 'N' ? maxlen : _RLEN[guess] || 0;
      rlen += colwidths[i];
      coltypes[i] = guess;
    }
    var h = ba.next(32);
    h.write_shift(4, 0x13021130);
    h.write_shift(4, data.length);
    h.write_shift(2, 296 + 32 * hcnt);
    h.write_shift(2, rlen);
    for (i = 0; i < 4; ++i) h.write_shift(4, 0);
    h.write_shift(4, 0x00000000 | (+dbf_reverse_map[/*::String(*/current_ansi /*::)*/] || 0x03) << 8);
    for (i = 0, j = 0; i < headers.length; ++i) {
      if (headers[i] == null) continue;
      var hf = ba.next(32);
      var _f = (headers[i].slice(-10) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00").slice(0, 11);
      hf.write_shift(1, _f, "sbcs");
      hf.write_shift(1, coltypes[i] == '?' ? 'C' : coltypes[i], "sbcs");
      hf.write_shift(4, j);
      hf.write_shift(1, colwidths[i] || _RLEN[coltypes[i]] || 0);
      hf.write_shift(1, coldecimals[i] || 0);
      hf.write_shift(1, 0x02);
      hf.write_shift(4, 0);
      hf.write_shift(1, 0);
      hf.write_shift(4, 0);
      hf.write_shift(4, 0);
      j += colwidths[i] || _RLEN[coltypes[i]] || 0;
    }
    var hb = ba.next(264);
    hb.write_shift(4, 0x0000000D);
    for (i = 0; i < 65; ++i) hb.write_shift(4, 0x00000000);
    for (i = 0; i < data.length; ++i) {
      var rout = ba.next(rlen);
      rout.write_shift(1, 0);
      for (j = 0; j < headers.length; ++j) {
        if (headers[j] == null) continue;
        switch (coltypes[j]) {
          case 'L':
            rout.write_shift(1, data[i][j] == null ? 0x3F : data[i][j] ? 0x54 : 0x46);
            break;
          case 'B':
            rout.write_shift(8, data[i][j] || 0, 'f');
            break;
          case 'N':
            var _n = "0";
            if (typeof data[i][j] == "number") _n = data[i][j].toFixed(coldecimals[j] || 0);
            for (hcnt = 0; hcnt < colwidths[j] - _n.length; ++hcnt) rout.write_shift(1, 0x20);
            rout.write_shift(1, _n, "sbcs");
            break;
          case 'D':
            if (!data[i][j]) rout.write_shift(8, "00000000", "sbcs");else {
              rout.write_shift(4, ("0000" + data[i][j].getFullYear()).slice(-4), "sbcs");
              rout.write_shift(2, ("00" + (data[i][j].getMonth() + 1)).slice(-2), "sbcs");
              rout.write_shift(2, ("00" + data[i][j].getDate()).slice(-2), "sbcs");
            }
            break;
          case 'C':
            var _s = String(data[i][j] != null ? data[i][j] : "").slice(0, colwidths[j]);
            rout.write_shift(1, _s, "sbcs");
            for (hcnt = 0; hcnt < colwidths[j] - _s.length; ++hcnt) rout.write_shift(1, 0x20);
            break;
        }
      }
      // data
    }
    ba.next(1).write_shift(1, 0x1A);
    return ba.end();
  }
  return {
    to_workbook: dbf_to_workbook,
    to_sheet: dbf_to_sheet,
    from_sheet: sheet_to_dbf
  };
}();
var SYLK = /*#__PURE__*/function () {
  /* TODO: stress test sequences */
  var sylk_escapes = {
    AA: 'À',
    BA: 'Á',
    CA: 'Â',
    DA: 195,
    HA: 'Ä',
    JA: 197,
    AE: 'È',
    BE: 'É',
    CE: 'Ê',
    HE: 'Ë',
    AI: 'Ì',
    BI: 'Í',
    CI: 'Î',
    HI: 'Ï',
    AO: 'Ò',
    BO: 'Ó',
    CO: 'Ô',
    DO: 213,
    HO: 'Ö',
    AU: 'Ù',
    BU: 'Ú',
    CU: 'Û',
    HU: 'Ü',
    Aa: 'à',
    Ba: 'á',
    Ca: 'â',
    Da: 227,
    Ha: 'ä',
    Ja: 229,
    Ae: 'è',
    Be: 'é',
    Ce: 'ê',
    He: 'ë',
    Ai: 'ì',
    Bi: 'í',
    Ci: 'î',
    Hi: 'ï',
    Ao: 'ò',
    Bo: 'ó',
    Co: 'ô',
    Do: 245,
    Ho: 'ö',
    Au: 'ù',
    Bu: 'ú',
    Cu: 'û',
    Hu: 'ü',
    KC: 'Ç',
    Kc: 'ç',
    q: 'æ',
    z: 'œ',
    a: 'Æ',
    j: 'Œ',
    DN: 209,
    Dn: 241,
    Hy: 255,
    S: 169,
    c: 170,
    R: 174,
    "B ": 180,
    /*::[*/0 /*::]*/: 176,
    /*::[*/1 /*::]*/: 177,
    /*::[*/2 /*::]*/: 178,
    /*::[*/3 /*::]*/: 179,
    /*::[*/5 /*::]*/: 181,
    /*::[*/6 /*::]*/: 182,
    /*::[*/7 /*::]*/: 183,
    Q: 185,
    k: 186,
    b: 208,
    i: 216,
    l: 222,
    s: 240,
    y: 248,
    "!": 161,
    '"': 162,
    "#": 163,
    "(": 164,
    "%": 165,
    "'": 167,
    "H ": 168,
    "+": 171,
    ";": 187,
    "<": 188,
    "=": 189,
    ">": 190,
    "?": 191,
    "{": 223
  } /*:any*/;
  var sylk_char_regex = new RegExp("\u001BN(" + keys(sylk_escapes).join("|").replace(/\|\|\|/, "|\\||").replace(/([?()+])/g, "\\$1") + "|\\|)", "gm");
  var sylk_char_fn = function (_, $1) {
    var o = sylk_escapes[$1];
    return typeof o == "number" ? _getansi(o) : o;
  };
  var decode_sylk_char = function ($$, $1, $2) {
    var newcc = $1.charCodeAt(0) - 0x20 << 4 | $2.charCodeAt(0) - 0x30;
    return newcc == 59 ? $$ : _getansi(newcc);
  };
  sylk_escapes["|"] = 254;
  /* TODO: find an actual specification */
  function sylk_to_aoa(d /*:RawData*/, opts) /*:[AOA, Worksheet]*/{
    switch (opts.type) {
      case 'base64':
        return sylk_to_aoa_str(Base64_decode(d), opts);
      case 'binary':
        return sylk_to_aoa_str(d, opts);
      case 'buffer':
        return sylk_to_aoa_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
      case 'array':
        return sylk_to_aoa_str(cc2str(d), opts);
    }
    throw new Error("Unrecognized type " + opts.type);
  }
  function sylk_to_aoa_str(str /*:string*/, opts) /*:[AOA, Worksheet]*/{
    var records = str.split(/[\n\r]+/),
      R = -1,
      C = -1,
      ri = 0,
      rj = 0,
      arr /*:AOA*/ = [];
    var formats /*:Array<string>*/ = [];
    var next_cell_format /*:string|null*/ = null;
    var sht = {},
      rowinfo /*:Array<RowInfo>*/ = [],
      colinfo /*:Array<ColInfo>*/ = [],
      cw /*:Array<string>*/ = [];
    var Mval = 0,
      j;
    if (+opts.codepage >= 0) set_cp(+opts.codepage);
    for (; ri !== records.length; ++ri) {
      Mval = 0;
      var rstr = records[ri].trim().replace(/\x1B([\x20-\x2F])([\x30-\x3F])/g, decode_sylk_char).replace(sylk_char_regex, sylk_char_fn);
      var record = rstr.replace(/;;/g, "\u0000").split(";").map(function (x) {
        return x.replace(/\u0000/g, ";");
      });
      var RT = record[0],
        val;
      if (rstr.length > 0) switch (RT) {
        case 'ID':
          break;
        /* header */
        case 'E':
          break;
        /* EOF */
        case 'B':
          break;
        /* dimensions */
        case 'O':
          break;
        /* options? */
        case 'W':
          break;
        /* window? */
        case 'P':
          if (record[1].charAt(0) == 'P') formats.push(rstr.slice(3).replace(/;;/g, ";"));
          break;
        case 'C':
          var C_seen_K = false,
            C_seen_X = false,
            C_seen_S = false,
            C_seen_E = false,
            _R = -1,
            _C = -1;
          for (rj = 1; rj < record.length; ++rj) switch (record[rj].charAt(0)) {
            case 'A':
              break;
            // TODO: comment
            case 'X':
              C = parseInt(record[rj].slice(1)) - 1;
              C_seen_X = true;
              break;
            case 'Y':
              R = parseInt(record[rj].slice(1)) - 1;
              if (!C_seen_X) C = 0;
              for (j = arr.length; j <= R; ++j) arr[j] = [];
              break;
            case 'K':
              val = record[rj].slice(1);
              if (val.charAt(0) === '"') val = val.slice(1, val.length - 1);else if (val === 'TRUE') val = true;else if (val === 'FALSE') val = false;else if (!isNaN(fuzzynum(val))) {
                val = fuzzynum(val);
                if (next_cell_format !== null && fmt_is_date(next_cell_format)) val = numdate(val);
              } else if (!isNaN(fuzzydate(val).getDate())) {
                val = parseDate(val);
              }
              if (typeof $cptable !== 'undefined' && typeof val == "string" && (opts || {}).type != "string" && (opts || {}).codepage) val = $cptable.utils.decode(opts.codepage, val);
              C_seen_K = true;
              break;
            case 'E':
              C_seen_E = true;
              var formula = rc_to_a1(record[rj].slice(1), {
                r: R,
                c: C
              });
              arr[R][C] = [arr[R][C], formula];
              break;
            case 'S':
              C_seen_S = true;
              arr[R][C] = [arr[R][C], "S5S"];
              break;
            case 'G':
              break;
            // unknown
            case 'R':
              _R = parseInt(record[rj].slice(1)) - 1;
              break;
            case 'C':
              _C = parseInt(record[rj].slice(1)) - 1;
              break;
            default:
              if (opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
          }
          if (C_seen_K) {
            if (arr[R][C] && arr[R][C].length == 2) arr[R][C][0] = val;else arr[R][C] = val;
            next_cell_format = null;
          }
          if (C_seen_S) {
            if (C_seen_E) throw new Error("SYLK shared formula cannot have own formula");
            var shrbase = _R > -1 && arr[_R][_C];
            if (!shrbase || !shrbase[1]) throw new Error("SYLK shared formula cannot find base");
            arr[R][C][1] = shift_formula_str(shrbase[1], {
              r: R - _R,
              c: C - _C
            });
          }
          break;
        case 'F':
          var F_seen = 0;
          for (rj = 1; rj < record.length; ++rj) switch (record[rj].charAt(0)) {
            case 'X':
              C = parseInt(record[rj].slice(1)) - 1;
              ++F_seen;
              break;
            case 'Y':
              R = parseInt(record[rj].slice(1)) - 1; /*C = 0;*/
              for (j = arr.length; j <= R; ++j) arr[j] = [];
              break;
            case 'M':
              Mval = parseInt(record[rj].slice(1)) / 20;
              break;
            case 'F':
              break;
            /* ??? */
            case 'G':
              break;
            /* hide grid */
            case 'P':
              next_cell_format = formats[parseInt(record[rj].slice(1))];
              break;
            case 'S':
              break;
            /* cell style */
            case 'D':
              break;
            /* column */
            case 'N':
              break;
            /* font */
            case 'W':
              cw = record[rj].slice(1).split(" ");
              for (j = parseInt(cw[0], 10); j <= parseInt(cw[1], 10); ++j) {
                Mval = parseInt(cw[2], 10);
                colinfo[j - 1] = Mval === 0 ? {
                  hidden: true
                } : {
                  wch: Mval
                };
                process_col(colinfo[j - 1]);
              }
              break;
            case 'C':
              /* default column format */
              C = parseInt(record[rj].slice(1)) - 1;
              if (!colinfo[C]) colinfo[C] = {};
              break;
            case 'R':
              /* row properties */
              R = parseInt(record[rj].slice(1)) - 1;
              if (!rowinfo[R]) rowinfo[R] = {};
              if (Mval > 0) {
                rowinfo[R].hpt = Mval;
                rowinfo[R].hpx = pt2px(Mval);
              } else if (Mval === 0) rowinfo[R].hidden = true;
              break;
            default:
              if (opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
          }
          if (F_seen < 1) next_cell_format = null;
          break;
        default:
          if (opts && opts.WTF) throw new Error("SYLK bad record " + rstr);
      }
    }
    if (rowinfo.length > 0) sht['!rows'] = rowinfo;
    if (colinfo.length > 0) sht['!cols'] = colinfo;
    if (opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
    return [arr, sht];
  }
  function sylk_to_sheet(d /*:RawData*/, opts) /*:Worksheet*/{
    var aoasht = sylk_to_aoa(d, opts);
    var aoa = aoasht[0],
      ws = aoasht[1];
    var o = aoa_to_sheet(aoa, opts);
    keys(ws).forEach(function (k) {
      o[k] = ws[k];
    });
    return o;
  }
  function sylk_to_workbook(d /*:RawData*/, opts) /*:Workbook*/{
    return sheet_to_workbook(sylk_to_sheet(d, opts), opts);
  }
  function write_ws_cell_sylk(cell /*:Cell*/, ws /*:Worksheet*/, R /*:number*/, C /*:number*/ /*::, opts*/) /*:string*/{
    var o = "C;Y" + (R + 1) + ";X" + (C + 1) + ";K";
    switch (cell.t) {
      case 'n':
        o += cell.v || 0;
        if (cell.f && !cell.F) o += ";E" + a1_to_rc(cell.f, {
          r: R,
          c: C
        });
        break;
      case 'b':
        o += cell.v ? "TRUE" : "FALSE";
        break;
      case 'e':
        o += cell.w || cell.v;
        break;
      case 'd':
        o += '"' + (cell.w || cell.v) + '"';
        break;
      case 's':
        o += '"' + cell.v.replace(/"/g, "").replace(/;/g, ";;") + '"';
        break;
    }
    return o;
  }
  function write_ws_cols_sylk(out, cols) {
    cols.forEach(function (col, i) {
      var rec = "F;W" + (i + 1) + " " + (i + 1) + " ";
      if (col.hidden) rec += "0";else {
        if (typeof col.width == 'number' && !col.wpx) col.wpx = width2px(col.width);
        if (typeof col.wpx == 'number' && !col.wch) col.wch = px2char(col.wpx);
        if (typeof col.wch == 'number') rec += Math.round(col.wch);
      }
      if (rec.charAt(rec.length - 1) != " ") out.push(rec);
    });
  }
  function write_ws_rows_sylk(out /*:Array<string>*/, rows /*:Array<RowInfo>*/) {
    rows.forEach(function (row, i) {
      var rec = "F;";
      if (row.hidden) rec += "M0;";else if (row.hpt) rec += "M" + 20 * row.hpt + ";";else if (row.hpx) rec += "M" + 20 * px2pt(row.hpx) + ";";
      if (rec.length > 2) out.push(rec + "R" + (i + 1));
    });
  }
  function sheet_to_sylk(ws /*:Worksheet*/, opts /*:?any*/) /*:string*/{
    var preamble /*:Array<string>*/ = ["ID;PWXL;N;E"],
      o /*:Array<string>*/ = [];
    var r = safe_decode_range(ws['!ref']),
      cell /*:Cell*/;
    var dense = Array.isArray(ws);
    var RS = "\r\n";
    preamble.push("P;PGeneral");
    preamble.push("F;P0;DG0G8;M255");
    if (ws['!cols']) write_ws_cols_sylk(preamble, ws['!cols']);
    if (ws['!rows']) write_ws_rows_sylk(preamble, ws['!rows']);
    preamble.push("B;Y" + (r.e.r - r.s.r + 1) + ";X" + (r.e.c - r.s.c + 1) + ";D" + [r.s.c, r.s.r, r.e.c, r.e.r].join(" "));
    for (var R = r.s.r; R <= r.e.r; ++R) {
      for (var C = r.s.c; C <= r.e.c; ++C) {
        var coord = encode_cell({
          r: R,
          c: C
        });
        cell = dense ? (ws[R] || [])[C] : ws[coord];
        if (!cell || cell.v == null && (!cell.f || cell.F)) continue;
        o.push(write_ws_cell_sylk(cell, ws, R, C, opts));
      }
    }
    return preamble.join(RS) + RS + o.join(RS) + RS + "E" + RS;
  }
  return {
    to_workbook: sylk_to_workbook,
    to_sheet: sylk_to_sheet,
    from_sheet: sheet_to_sylk
  };
}();
var DIF = /*#__PURE__*/function () {
  function dif_to_aoa(d /*:RawData*/, opts) /*:AOA*/{
    switch (opts.type) {
      case 'base64':
        return dif_to_aoa_str(Base64_decode(d), opts);
      case 'binary':
        return dif_to_aoa_str(d, opts);
      case 'buffer':
        return dif_to_aoa_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
      case 'array':
        return dif_to_aoa_str(cc2str(d), opts);
    }
    throw new Error("Unrecognized type " + opts.type);
  }
  function dif_to_aoa_str(str /*:string*/, opts) /*:AOA*/{
    var records = str.split('\n'),
      R = -1,
      C = -1,
      ri = 0,
      arr /*:AOA*/ = [];
    for (; ri !== records.length; ++ri) {
      if (records[ri].trim() === 'BOT') {
        arr[++R] = [];
        C = 0;
        continue;
      }
      if (R < 0) continue;
      var metadata = records[ri].trim().split(",");
      var type = metadata[0],
        value = metadata[1];
      ++ri;
      var data = records[ri] || "";
      while ((data.match(/["]/g) || []).length & 1 && ri < records.length - 1) data += "\n" + records[++ri];
      data = data.trim();
      switch (+type) {
        case -1:
          if (data === 'BOT') {
            arr[++R] = [];
            C = 0;
            continue;
          } else if (data !== 'EOD') throw new Error("Unrecognized DIF special command " + data);
          break;
        case 0:
          if (data === 'TRUE') arr[R][C] = true;else if (data === 'FALSE') arr[R][C] = false;else if (!isNaN(fuzzynum(value))) arr[R][C] = fuzzynum(value);else if (!isNaN(fuzzydate(value).getDate())) arr[R][C] = parseDate(value);else arr[R][C] = value;
          ++C;
          break;
        case 1:
          data = data.slice(1, data.length - 1);
          data = data.replace(/""/g, '"');
          if (DIF_XL && data && data.match(/^=".*"$/)) data = data.slice(2, -1);
          arr[R][C++] = data !== '' ? data : null;
          break;
      }
      if (data === 'EOD') break;
    }
    if (opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
    return arr;
  }
  function dif_to_sheet(str /*:string*/, opts) /*:Worksheet*/{
    return aoa_to_sheet(dif_to_aoa(str, opts), opts);
  }
  function dif_to_workbook(str /*:string*/, opts) /*:Workbook*/{
    return sheet_to_workbook(dif_to_sheet(str, opts), opts);
  }
  var sheet_to_dif = /*#__PURE__*/function () {
    var push_field = function pf(o /*:Array<string>*/, topic /*:string*/, v /*:number*/, n /*:number*/, s /*:string*/) {
      o.push(topic);
      o.push(v + "," + n);
      o.push('"' + s.replace(/"/g, '""') + '"');
    };
    var push_value = function po(o /*:Array<string>*/, type /*:number*/, v /*:any*/, s /*:string*/) {
      o.push(type + "," + v);
      o.push(type == 1 ? '"' + s.replace(/"/g, '""') + '"' : s);
    };
    return function sheet_to_dif(ws /*:Worksheet*/ /*::, opts:?any*/) /*:string*/{
      var o /*:Array<string>*/ = [];
      var r = safe_decode_range(ws['!ref']),
        cell /*:Cell*/;
      var dense = Array.isArray(ws);
      push_field(o, "TABLE", 0, 1, "sheetjs");
      push_field(o, "VECTORS", 0, r.e.r - r.s.r + 1, "");
      push_field(o, "TUPLES", 0, r.e.c - r.s.c + 1, "");
      push_field(o, "DATA", 0, 0, "");
      for (var R = r.s.r; R <= r.e.r; ++R) {
        push_value(o, -1, 0, "BOT");
        for (var C = r.s.c; C <= r.e.c; ++C) {
          var coord = encode_cell({
            r: R,
            c: C
          });
          cell = dense ? (ws[R] || [])[C] : ws[coord];
          if (!cell) {
            push_value(o, 1, 0, "");
            continue;
          }
          switch (cell.t) {
            case 'n':
              var val = DIF_XL ? cell.w : cell.v;
              if (!val && cell.v != null) val = cell.v;
              if (val == null) {
                if (DIF_XL && cell.f && !cell.F) push_value(o, 1, 0, "=" + cell.f);else push_value(o, 1, 0, "");
              } else push_value(o, 0, val, "V");
              break;
            case 'b':
              push_value(o, 0, cell.v ? 1 : 0, cell.v ? "TRUE" : "FALSE");
              break;
            case 's':
              push_value(o, 1, 0, !DIF_XL || isNaN(cell.v) ? cell.v : '="' + cell.v + '"');
              break;
            case 'd':
              if (!cell.w) cell.w = SSF_format(cell.z || table_fmt[14], datenum(parseDate(cell.v)));
              if (DIF_XL) push_value(o, 0, cell.w, "V");else push_value(o, 1, 0, cell.w);
              break;
            default:
              push_value(o, 1, 0, "");
          }
        }
      }
      push_value(o, -1, 0, "EOD");
      var RS = "\r\n";
      var oo = o.join(RS);
      //while((oo.length & 0x7F) != 0) oo += "\0";
      return oo;
    };
  }();
  return {
    to_workbook: dif_to_workbook,
    to_sheet: dif_to_sheet,
    from_sheet: sheet_to_dif
  };
}();
var ETH = /*#__PURE__*/function () {
  function decode(s /*:string*/) /*:string*/{
    return s.replace(/\\b/g, "\\").replace(/\\c/g, ":").replace(/\\n/g, "\n");
  }
  function encode(s /*:string*/) /*:string*/{
    return s.replace(/\\/g, "\\b").replace(/:/g, "\\c").replace(/\n/g, "\\n");
  }
  function eth_to_aoa(str /*:string*/, opts) /*:AOA*/{
    var records = str.split('\n'),
      R = -1,
      C = -1,
      ri = 0,
      arr /*:AOA*/ = [];
    for (; ri !== records.length; ++ri) {
      var record = records[ri].trim().split(":");
      if (record[0] !== 'cell') continue;
      var addr = decode_cell(record[1]);
      if (arr.length <= addr.r) for (R = arr.length; R <= addr.r; ++R) if (!arr[R]) arr[R] = [];
      R = addr.r;
      C = addr.c;
      switch (record[2]) {
        case 't':
          arr[R][C] = decode(record[3]);
          break;
        case 'v':
          arr[R][C] = +record[3];
          break;
        case 'vtf':
          var _f = record[record.length - 1];
        /* falls through */
        case 'vtc':
          switch (record[3]) {
            case 'nl':
              arr[R][C] = +record[4] ? true : false;
              break;
            default:
              arr[R][C] = +record[4];
              break;
          }
          if (record[2] == 'vtf') arr[R][C] = [arr[R][C], _f];
      }
    }
    if (opts && opts.sheetRows) arr = arr.slice(0, opts.sheetRows);
    return arr;
  }
  function eth_to_sheet(d /*:string*/, opts) /*:Worksheet*/{
    return aoa_to_sheet(eth_to_aoa(d, opts), opts);
  }
  function eth_to_workbook(d /*:string*/, opts) /*:Workbook*/{
    return sheet_to_workbook(eth_to_sheet(d, opts), opts);
  }
  var header = ["socialcalc:version:1.5", "MIME-Version: 1.0", "Content-Type: multipart/mixed; boundary=SocialCalcSpreadsheetControlSave"].join("\n");
  var sep = ["--SocialCalcSpreadsheetControlSave", "Content-type: text/plain; charset=UTF-8"].join("\n") + "\n";

  /* TODO: the other parts */
  var meta = ["# SocialCalc Spreadsheet Control Save", "part:sheet"].join("\n");
  var end = "--SocialCalcSpreadsheetControlSave--";
  function sheet_to_eth_data(ws /*:Worksheet*/) /*:string*/{
    if (!ws || !ws['!ref']) return "";
    var o /*:Array<string>*/ = [],
      oo /*:Array<string>*/ = [],
      cell,
      coord = "";
    var r = decode_range(ws['!ref']);
    var dense = Array.isArray(ws);
    for (var R = r.s.r; R <= r.e.r; ++R) {
      for (var C = r.s.c; C <= r.e.c; ++C) {
        coord = encode_cell({
          r: R,
          c: C
        });
        cell = dense ? (ws[R] || [])[C] : ws[coord];
        if (!cell || cell.v == null || cell.t === 'z') continue;
        oo = ["cell", coord, 't'];
        switch (cell.t) {
          case 's':
          case 'str':
            oo.push(encode(cell.v));
            break;
          case 'n':
            if (!cell.f) {
              oo[2] = 'v';
              oo[3] = cell.v;
            } else {
              oo[2] = 'vtf';
              oo[3] = 'n';
              oo[4] = cell.v;
              oo[5] = encode(cell.f);
            }
            break;
          case 'b':
            oo[2] = 'vt' + (cell.f ? 'f' : 'c');
            oo[3] = 'nl';
            oo[4] = cell.v ? "1" : "0";
            oo[5] = encode(cell.f || (cell.v ? 'TRUE' : 'FALSE'));
            break;
          case 'd':
            var t = datenum(parseDate(cell.v));
            oo[2] = 'vtc';
            oo[3] = 'nd';
            oo[4] = "" + t;
            oo[5] = cell.w || SSF_format(cell.z || table_fmt[14], t);
            break;
          case 'e':
            continue;
        }
        o.push(oo.join(":"));
      }
    }
    o.push("sheet:c:" + (r.e.c - r.s.c + 1) + ":r:" + (r.e.r - r.s.r + 1) + ":tvf:1");
    o.push("valueformat:1:text-wiki");
    //o.push("copiedfrom:" + ws['!ref']); // clipboard only
    return o.join("\n");
  }
  function sheet_to_eth(ws /*:Worksheet*/ /*::, opts:?any*/) /*:string*/{
    return [header, sep, meta, sep, sheet_to_eth_data(ws), end].join("\n");
    // return ["version:1.5", sheet_to_eth_data(ws)].join("\n"); // clipboard form
  }
  return {
    to_workbook: eth_to_workbook,
    to_sheet: eth_to_sheet,
    from_sheet: sheet_to_eth
  };
}();
var PRN = /*#__PURE__*/function () {
  function set_text_arr(data /*:string*/, arr /*:AOA*/, R /*:number*/, C /*:number*/, o /*:any*/) {
    if (o.raw) arr[R][C] = data;else if (data === "") {/* empty */} else if (data === 'TRUE') arr[R][C] = true;else if (data === 'FALSE') arr[R][C] = false;else if (!isNaN(fuzzynum(data))) arr[R][C] = fuzzynum(data);else if (!isNaN(fuzzydate(data).getDate())) arr[R][C] = parseDate(data);else arr[R][C] = data;
  }
  function prn_to_aoa_str(f /*:string*/, opts) /*:AOA*/{
    var o = opts || {};
    var arr /*:AOA*/ = [] /*:any*/;
    if (!f || f.length === 0) return arr;
    var lines = f.split(/[\r\n]/);
    var L = lines.length - 1;
    while (L >= 0 && lines[L].length === 0) --L;
    var start = 10,
      idx = 0;
    var R = 0;
    for (; R <= L; ++R) {
      idx = lines[R].indexOf(" ");
      if (idx == -1) idx = lines[R].length;else idx++;
      start = Math.max(start, idx);
    }
    for (R = 0; R <= L; ++R) {
      arr[R] = [];
      /* TODO: confirm that widths are always 10 */
      var C = 0;
      set_text_arr(lines[R].slice(0, start).trim(), arr, R, C, o);
      for (C = 1; C <= (lines[R].length - start) / 10 + 1; ++C) set_text_arr(lines[R].slice(start + (C - 1) * 10, start + C * 10).trim(), arr, R, C, o);
    }
    if (o.sheetRows) arr = arr.slice(0, o.sheetRows);
    return arr;
  }

  // List of accepted CSV separators
  var guess_seps = {
    /*::[*/0x2C /*::]*/: ',',
    /*::[*/0x09 /*::]*/: "\t",
    /*::[*/0x3B /*::]*/: ';',
    /*::[*/0x7C /*::]*/: '|'
  };

  // CSV separator weights to be used in case of equal numbers
  var guess_sep_weights = {
    /*::[*/0x2C /*::]*/: 3,
    /*::[*/0x09 /*::]*/: 2,
    /*::[*/0x3B /*::]*/: 1,
    /*::[*/0x7C /*::]*/: 0
  };
  function guess_sep(str) {
    var cnt = {},
      instr = false,
      end = 0,
      cc = 0;
    for (; end < str.length; ++end) {
      if ((cc = str.charCodeAt(end)) == 0x22) instr = !instr;else if (!instr && cc in guess_seps) cnt[cc] = (cnt[cc] || 0) + 1;
    }
    cc = [];
    for (end in cnt) if (Object.prototype.hasOwnProperty.call(cnt, end)) {
      cc.push([cnt[end], end]);
    }
    if (!cc.length) {
      cnt = guess_sep_weights;
      for (end in cnt) if (Object.prototype.hasOwnProperty.call(cnt, end)) {
        cc.push([cnt[end], end]);
      }
    }
    cc.sort(function (a, b) {
      return a[0] - b[0] || guess_sep_weights[a[1]] - guess_sep_weights[b[1]];
    });
    return guess_seps[cc.pop()[1]] || 0x2C;
  }
  function dsv_to_sheet_str(str /*:string*/, opts) /*:Worksheet*/{
    var o = opts || {};
    var sep = "";
    if (DENSE != null && o.dense == null) o.dense = DENSE;
    var ws /*:Worksheet*/ = o.dense ? [] /*:any*/ : {} /*:any*/;
    var range /*:Range*/ = {
      s: {
        c: 0,
        r: 0
      },
      e: {
        c: 0,
        r: 0
      }
    } /*:any*/;
    if (str.slice(0, 4) == "sep=") {
      // If the line ends in \r\n
      if (str.charCodeAt(5) == 13 && str.charCodeAt(6) == 10) {
        sep = str.charAt(4);
        str = str.slice(7);
      }
      // If line ends in \r OR \n
      else if (str.charCodeAt(5) == 13 || str.charCodeAt(5) == 10) {
        sep = str.charAt(4);
        str = str.slice(6);
      } else sep = guess_sep(str.slice(0, 1024));
    } else if (o && o.FS) sep = o.FS;else sep = guess_sep(str.slice(0, 1024));
    var R = 0,
      C = 0,
      v = 0;
    var start = 0,
      end = 0,
      sepcc = sep.charCodeAt(0),
      instr = false,
      cc = 0,
      startcc = str.charCodeAt(0);
    str = str.replace(/\r\n/mg, "\n");
    var _re /*:?RegExp*/ = o.dateNF != null ? dateNF_regex(o.dateNF) : null;
    function finish_cell() {
      var s = str.slice(start, end);
      var cell = {} /*:any*/;
      if (s.charAt(0) == '"' && s.charAt(s.length - 1) == '"') s = s.slice(1, -1).replace(/""/g, '"');
      if (s.length === 0) cell.t = 'z';else if (o.raw) {
        cell.t = 's';
        cell.v = s;
      } else if (s.trim().length === 0) {
        cell.t = 's';
        cell.v = s;
      } else if (s.charCodeAt(0) == 0x3D) {
        if (s.charCodeAt(1) == 0x22 && s.charCodeAt(s.length - 1) == 0x22) {
          cell.t = 's';
          cell.v = s.slice(2, -1).replace(/""/g, '"');
        } else if (fuzzyfmla(s)) {
          cell.t = 'n';
          cell.f = s.slice(1);
        } else {
          cell.t = 's';
          cell.v = s;
        }
      } else if (s == "TRUE") {
        cell.t = 'b';
        cell.v = true;
      } else if (s == "FALSE") {
        cell.t = 'b';
        cell.v = false;
      } else if (!isNaN(v = fuzzynum(s))) {
        cell.t = 'n';
        if (o.cellText !== false) cell.w = s;
        cell.v = v;
      } else if (!isNaN(fuzzydate(s).getDate()) || _re && s.match(_re)) {
        cell.z = o.dateNF || table_fmt[14];
        var k = 0;
        if (_re && s.match(_re)) {
          s = dateNF_fix(s, o.dateNF, s.match(_re) || []);
          k = 1;
        }
        if (o.cellDates) {
          cell.t = 'd';
          cell.v = parseDate(s, k);
        } else {
          cell.t = 'n';
          cell.v = datenum(parseDate(s, k));
        }
        if (o.cellText !== false) cell.w = SSF_format(cell.z, cell.v instanceof Date ? datenum(cell.v) : cell.v);
        if (!o.cellNF) delete cell.z;
      } else {
        cell.t = 's';
        cell.v = s;
      }
      if (cell.t == 'z') {} else if (o.dense) {
        if (!ws[R]) ws[R] = [];
        ws[R][C] = cell;
      } else ws[encode_cell({
        c: C,
        r: R
      })] = cell;
      start = end + 1;
      startcc = str.charCodeAt(start);
      if (range.e.c < C) range.e.c = C;
      if (range.e.r < R) range.e.r = R;
      if (cc == sepcc) ++C;else {
        C = 0;
        ++R;
        if (o.sheetRows && o.sheetRows <= R) return true;
      }
    }
    outer: for (; end < str.length; ++end) switch (cc = str.charCodeAt(end)) {
      case 0x22:
        if (startcc === 0x22) instr = !instr;
        break;
      case sepcc:
      case 0x0a:
      case 0x0d:
        if (!instr && finish_cell()) break outer;
        break;
      default:
        break;
    }
    if (end - start > 0) finish_cell();
    ws['!ref'] = encode_range(range);
    return ws;
  }
  function prn_to_sheet_str(str /*:string*/, opts) /*:Worksheet*/{
    if (!(opts && opts.PRN)) return dsv_to_sheet_str(str, opts);
    if (opts.FS) return dsv_to_sheet_str(str, opts);
    if (str.slice(0, 4) == "sep=") return dsv_to_sheet_str(str, opts);
    if (str.indexOf("\t") >= 0 || str.indexOf(",") >= 0 || str.indexOf(";") >= 0) return dsv_to_sheet_str(str, opts);
    return aoa_to_sheet(prn_to_aoa_str(str, opts), opts);
  }
  function prn_to_sheet(d /*:RawData*/, opts) /*:Worksheet*/{
    var str = "",
      bytes = opts.type == 'string' ? [0, 0, 0, 0] : firstbyte(d, opts);
    switch (opts.type) {
      case 'base64':
        str = Base64_decode(d);
        break;
      case 'binary':
        str = d;
        break;
      case 'buffer':
        if (opts.codepage == 65001) str = d.toString('utf8'); // TODO: test if buf
        else if (opts.codepage && typeof $cptable !== 'undefined') str = $cptable.utils.decode(opts.codepage, d);else str = has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d);
        break;
      case 'array':
        str = cc2str(d);
        break;
      case 'string':
        str = d;
        break;
      default:
        throw new Error("Unrecognized type " + opts.type);
    }
    if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str.slice(3));else if (opts.type != 'string' && opts.type != 'buffer' && opts.codepage == 65001) str = utf8read(str);else if (opts.type == 'binary' && typeof $cptable !== 'undefined' && opts.codepage) str = $cptable.utils.decode(opts.codepage, $cptable.utils.encode(28591, str));
    if (str.slice(0, 19) == "socialcalc:version:") return ETH.to_sheet(opts.type == 'string' ? str : utf8read(str), opts);
    return prn_to_sheet_str(str, opts);
  }
  function prn_to_workbook(d /*:RawData*/, opts) /*:Workbook*/{
    return sheet_to_workbook(prn_to_sheet(d, opts), opts);
  }
  function sheet_to_prn(ws /*:Worksheet*/ /*::, opts:?any*/) /*:string*/{
    var o /*:Array<string>*/ = [];
    var r = safe_decode_range(ws['!ref']),
      cell /*:Cell*/;
    var dense = Array.isArray(ws);
    for (var R = r.s.r; R <= r.e.r; ++R) {
      var oo /*:Array<string>*/ = [];
      for (var C = r.s.c; C <= r.e.c; ++C) {
        var coord = encode_cell({
          r: R,
          c: C
        });
        cell = dense ? (ws[R] || [])[C] : ws[coord];
        if (!cell || cell.v == null) {
          oo.push("          ");
          continue;
        }
        var w = (cell.w || (format_cell(cell), cell.w) || "").slice(0, 10);
        while (w.length < 10) w += " ";
        oo.push(w + (C === 0 ? " " : ""));
      }
      o.push(oo.join(""));
    }
    return o.join("\n");
  }
  return {
    to_workbook: prn_to_workbook,
    to_sheet: prn_to_sheet,
    from_sheet: sheet_to_prn
  };
}();

/* Excel defaults to SYLK but warns if data is not valid */
function read_wb_ID(d, opts) {
  var o = opts || {},
    OLD_WTF = !!o.WTF;
  o.WTF = true;
  try {
    var out = SYLK.to_workbook(d, o);
    o.WTF = OLD_WTF;
    return out;
  } catch (e) {
    o.WTF = OLD_WTF;
    if (!e.message.match(/SYLK bad record ID/) && OLD_WTF) throw e;
    return PRN.to_workbook(d, opts);
  }
}
var WK_ = /*#__PURE__*/function () {
  function lotushopper(data, cb /*:RecordHopperCB*/, opts /*:any*/) {
    if (!data) return;
    prep_blob(data, data.l || 0);
    var Enum = opts.Enum || WK1Enum;
    while (data.l < data.length) {
      var RT = data.read_shift(2);
      var R = Enum[RT] || Enum[0xFFFF];
      var length = data.read_shift(2);
      var tgt = data.l + length;
      var d = R.f && R.f(data, length, opts);
      data.l = tgt;
      if (cb(d, R, RT)) return;
    }
  }
  function lotus_to_workbook(d /*:RawData*/, opts) {
    switch (opts.type) {
      case 'base64':
        return lotus_to_workbook_buf(s2a(Base64_decode(d)), opts);
      case 'binary':
        return lotus_to_workbook_buf(s2a(d), opts);
      case 'buffer':
      case 'array':
        return lotus_to_workbook_buf(d, opts);
    }
    throw "Unsupported type " + opts.type;
  }
  function lotus_to_workbook_buf(d, opts) /*:Workbook*/{
    if (!d) return d;
    var o = opts || {};
    if (DENSE != null && o.dense == null) o.dense = DENSE;
    var s /*:Worksheet*/ = o.dense ? [] : {} /*:any*/,
      n = "Sheet1",
      next_n = "",
      sidx = 0;
    var sheets = {},
      snames = [],
      realnames = [];
    var refguess = {
      s: {
        r: 0,
        c: 0
      },
      e: {
        r: 0,
        c: 0
      }
    };
    var sheetRows = o.sheetRows || 0;
    if (d[2] == 0x00) {
      if (d[3] == 0x08 || d[3] == 0x09) {
        if (d.length >= 16 && d[14] == 0x05 && d[15] === 0x6c) throw new Error("Unsupported Works 3 for Mac file");
      }
    }
    if (d[2] == 0x02) {
      o.Enum = WK1Enum;
      lotushopper(d, function (val, R, RT) {
        switch (RT) {
          case 0x00:
            /* BOF */
            o.vers = val;
            if (val >= 0x1000) o.qpro = true;
            break;
          case 0x06:
            refguess = val;
            break;
          /* RANGE */
          case 0xCC:
            if (val) next_n = val;
            break;
          /* SHEETNAMECS */
          case 0xDE:
            next_n = val;
            break;
          /* SHEETNAMELP */
          case 0x0F: /* LABEL */
          case 0x33:
            /* STRING */
            if (!o.qpro) val[1].v = val[1].v.slice(1);
          /* falls through */
          case 0x0D: /* INTEGER */
          case 0x0E: /* NUMBER */
          case 0x10:
            /* FORMULA */
            /* TODO: actual translation of the format code */
            if (RT == 0x0E && (val[2] & 0x70) == 0x70 && (val[2] & 0x0F) > 1 && (val[2] & 0x0F) < 15) {
              val[1].z = o.dateNF || table_fmt[14];
              if (o.cellDates) {
                val[1].t = 'd';
                val[1].v = numdate(val[1].v);
              }
            }
            if (o.qpro) {
              if (val[3] > sidx) {
                s["!ref"] = encode_range(refguess);
                sheets[n] = s;
                snames.push(n);
                s = o.dense ? [] : {};
                refguess = {
                  s: {
                    r: 0,
                    c: 0
                  },
                  e: {
                    r: 0,
                    c: 0
                  }
                };
                sidx = val[3];
                n = next_n || "Sheet" + (sidx + 1);
                next_n = "";
              }
            }
            var tmpcell = o.dense ? (s[val[0].r] || [])[val[0].c] : s[encode_cell(val[0])];
            if (tmpcell) {
              tmpcell.t = val[1].t;
              tmpcell.v = val[1].v;
              if (val[1].z != null) tmpcell.z = val[1].z;
              if (val[1].f != null) tmpcell.f = val[1].f;
              break;
            }
            if (o.dense) {
              if (!s[val[0].r]) s[val[0].r] = [];
              s[val[0].r][val[0].c] = val[1];
            } else s[encode_cell(val[0])] = val[1];
            break;
          default:
        }
      }, o);
    } else if (d[2] == 0x1A || d[2] == 0x0E) {
      o.Enum = WK3Enum;
      if (d[2] == 0x0E) {
        o.qpro = true;
        d.l = 0;
      }
      lotushopper(d, function (val, R, RT) {
        switch (RT) {
          case 0xCC:
            n = val;
            break;
          /* SHEETNAMECS */
          case 0x16:
            /* LABEL16 */
            val[1].v = val[1].v.slice(1);
          /* falls through */
          case 0x17: /* NUMBER17 */
          case 0x18: /* NUMBER18 */
          case 0x19: /* FORMULA19 */
          case 0x25: /* NUMBER25 */
          case 0x27: /* NUMBER27 */
          case 0x28:
            /* FORMULA28 */
            if (val[3] > sidx) {
              s["!ref"] = encode_range(refguess);
              sheets[n] = s;
              snames.push(n);
              s = o.dense ? [] : {};
              refguess = {
                s: {
                  r: 0,
                  c: 0
                },
                e: {
                  r: 0,
                  c: 0
                }
              };
              sidx = val[3];
              n = "Sheet" + (sidx + 1);
            }
            if (sheetRows > 0 && val[0].r >= sheetRows) break;
            if (o.dense) {
              if (!s[val[0].r]) s[val[0].r] = [];
              s[val[0].r][val[0].c] = val[1];
            } else s[encode_cell(val[0])] = val[1];
            if (refguess.e.c < val[0].c) refguess.e.c = val[0].c;
            if (refguess.e.r < val[0].r) refguess.e.r = val[0].r;
            break;
          case 0x1B:
            /* XFORMAT */
            if (val[0x36b0]) realnames[val[0x36b0][0]] = val[0x36b0][1];
            break;
          case 0x0601:
            /* SHEETINFOQP */
            realnames[val[0]] = val[1];
            if (val[0] == sidx) n = val[1];
            break;
          default:
            break;
        }
      }, o);
    } else throw new Error("Unrecognized LOTUS BOF " + d[2]);
    s["!ref"] = encode_range(refguess);
    sheets[next_n || n] = s;
    snames.push(next_n || n);
    if (!realnames.length) return {
      SheetNames: snames,
      Sheets: sheets
    };
    var osheets = {},
      rnames = [];
    /* TODO: verify no collisions */
    for (var i = 0; i < realnames.length; ++i) if (sheets[snames[i]]) {
      rnames.push(realnames[i] || snames[i]);
      osheets[realnames[i]] = sheets[realnames[i]] || sheets[snames[i]];
    } else {
      rnames.push(realnames[i]);
      osheets[realnames[i]] = {
        "!ref": "A1"
      };
    }
    return {
      SheetNames: rnames,
      Sheets: osheets
    };
  }
  function sheet_to_wk1(ws /*:Worksheet*/, opts /*:WriteOpts*/) {
    var o = opts || {};
    if (+o.codepage >= 0) set_cp(+o.codepage);
    if (o.type == "string") throw new Error("Cannot write WK1 to JS string");
    var ba = buf_array();
    var range = safe_decode_range(ws["!ref"]);
    var dense = Array.isArray(ws);
    var cols = [];
    write_biff_rec(ba, 0x00, write_BOF_WK1(0x0406));
    write_biff_rec(ba, 0x06, write_RANGE(range));
    var max_R = Math.min(range.e.r, 8191);
    for (var R = range.s.r; R <= max_R; ++R) {
      var rr = encode_row(R);
      for (var C = range.s.c; C <= range.e.c; ++C) {
        if (R === range.s.r) cols[C] = encode_col(C);
        var ref = cols[C] + rr;
        var cell = dense ? (ws[R] || [])[C] : ws[ref];
        if (!cell || cell.t == "z") continue;
        /* TODO: formula records */
        if (cell.t == "n") {
          if ((cell.v | 0) == cell.v && cell.v >= -32768 && cell.v <= 32767) write_biff_rec(ba, 0x0d, write_INTEGER(R, C, cell.v));else write_biff_rec(ba, 0x0e, write_NUMBER(R, C, cell.v));
        } else {
          var str = format_cell(cell);
          write_biff_rec(ba, 0x0F, write_LABEL(R, C, str.slice(0, 239)));
        }
      }
    }
    write_biff_rec(ba, 0x01);
    return ba.end();
  }
  function book_to_wk3(wb /*:Workbook*/, opts /*:WriteOpts*/) {
    var o = opts || {};
    if (+o.codepage >= 0) set_cp(+o.codepage);
    if (o.type == "string") throw new Error("Cannot write WK3 to JS string");
    var ba = buf_array();
    write_biff_rec(ba, 0x00, write_BOF_WK3(wb));
    for (var i = 0, cnt = 0; i < wb.SheetNames.length; ++i) if ((wb.Sheets[wb.SheetNames[i]] || {})["!ref"]) write_biff_rec(ba, 0x1b, write_XFORMAT_SHEETNAME(wb.SheetNames[i], cnt++));
    var wsidx = 0;
    for (i = 0; i < wb.SheetNames.length; ++i) {
      var ws = wb.Sheets[wb.SheetNames[i]];
      if (!ws || !ws["!ref"]) continue;
      var range = safe_decode_range(ws["!ref"]);
      var dense = Array.isArray(ws);
      var cols = [];
      var max_R = Math.min(range.e.r, 8191);
      for (var R = range.s.r; R <= max_R; ++R) {
        var rr = encode_row(R);
        for (var C = range.s.c; C <= range.e.c; ++C) {
          if (R === range.s.r) cols[C] = encode_col(C);
          var ref = cols[C] + rr;
          var cell = dense ? (ws[R] || [])[C] : ws[ref];
          if (!cell || cell.t == "z") continue;
          /* TODO: FORMULA19 NUMBER18 records */
          if (cell.t == "n") {
            write_biff_rec(ba, 0x17, write_NUMBER_17(R, C, wsidx, cell.v));
          } else {
            var str = format_cell(cell);
            /* TODO: max len? */
            write_biff_rec(ba, 0x16, write_LABEL_16(R, C, wsidx, str.slice(0, 239)));
          }
        }
      }
      ++wsidx;
    }
    write_biff_rec(ba, 0x01);
    return ba.end();
  }
  function write_BOF_WK1(v /*:number*/) {
    var out = new_buf(2);
    out.write_shift(2, v);
    return out;
  }
  function write_BOF_WK3(wb /*:Workbook*/) {
    var out = new_buf(26);
    out.write_shift(2, 0x1000);
    out.write_shift(2, 0x0004);
    out.write_shift(4, 0x0000);
    var rows = 0,
      cols = 0,
      wscnt = 0;
    for (var i = 0; i < wb.SheetNames.length; ++i) {
      var name = wb.SheetNames[i];
      var ws = wb.Sheets[name];
      if (!ws || !ws["!ref"]) continue;
      ++wscnt;
      var range = decode_range(ws["!ref"]);
      if (rows < range.e.r) rows = range.e.r;
      if (cols < range.e.c) cols = range.e.c;
    }
    if (rows > 8191) rows = 8191;
    out.write_shift(2, rows);
    out.write_shift(1, wscnt);
    out.write_shift(1, cols);
    out.write_shift(2, 0x00);
    out.write_shift(2, 0x00);
    out.write_shift(1, 0x01);
    out.write_shift(1, 0x02);
    out.write_shift(4, 0);
    out.write_shift(4, 0);
    return out;
  }
  function parse_RANGE(blob, length, opts) {
    var o = {
      s: {
        c: 0,
        r: 0
      },
      e: {
        c: 0,
        r: 0
      }
    };
    if (length == 8 && opts.qpro) {
      o.s.c = blob.read_shift(1);
      blob.l++;
      o.s.r = blob.read_shift(2);
      o.e.c = blob.read_shift(1);
      blob.l++;
      o.e.r = blob.read_shift(2);
      return o;
    }
    o.s.c = blob.read_shift(2);
    o.s.r = blob.read_shift(2);
    if (length == 12 && opts.qpro) blob.l += 2;
    o.e.c = blob.read_shift(2);
    o.e.r = blob.read_shift(2);
    if (length == 12 && opts.qpro) blob.l += 2;
    if (o.s.c == 0xFFFF) o.s.c = o.e.c = o.s.r = o.e.r = 0;
    return o;
  }
  function write_RANGE(range) {
    var out = new_buf(8);
    out.write_shift(2, range.s.c);
    out.write_shift(2, range.s.r);
    out.write_shift(2, range.e.c);
    out.write_shift(2, range.e.r);
    return out;
  }
  function parse_cell(blob, length, opts) {
    var o = [{
      c: 0,
      r: 0
    }, {
      t: 'n',
      v: 0
    }, 0, 0];
    if (opts.qpro && opts.vers != 0x5120) {
      o[0].c = blob.read_shift(1);
      o[3] = blob.read_shift(1);
      o[0].r = blob.read_shift(2);
      blob.l += 2;
    } else {
      o[2] = blob.read_shift(1);
      o[0].c = blob.read_shift(2);
      o[0].r = blob.read_shift(2);
    }
    return o;
  }
  function parse_LABEL(blob, length, opts) {
    var tgt = blob.l + length;
    var o = parse_cell(blob, length, opts);
    o[1].t = 's';
    if (opts.vers == 0x5120) {
      blob.l++;
      var len = blob.read_shift(1);
      o[1].v = blob.read_shift(len, 'utf8');
      return o;
    }
    if (opts.qpro) blob.l++;
    o[1].v = blob.read_shift(tgt - blob.l, 'cstr');
    return o;
  }
  function write_LABEL(R, C, s) {
    /* TODO: encoding */
    var o = new_buf(7 + s.length);
    o.write_shift(1, 0xFF);
    o.write_shift(2, C);
    o.write_shift(2, R);
    o.write_shift(1, 0x27); // ??
    for (var i = 0; i < o.length; ++i) {
      var cc = s.charCodeAt(i);
      o.write_shift(1, cc >= 0x80 ? 0x5F : cc);
    }
    o.write_shift(1, 0);
    return o;
  }
  function parse_INTEGER(blob, length, opts) {
    var o = parse_cell(blob, length, opts);
    o[1].v = blob.read_shift(2, 'i');
    return o;
  }
  function write_INTEGER(R, C, v) {
    var o = new_buf(7);
    o.write_shift(1, 0xFF);
    o.write_shift(2, C);
    o.write_shift(2, R);
    o.write_shift(2, v, 'i');
    return o;
  }
  function parse_NUMBER(blob, length, opts) {
    var o = parse_cell(blob, length, opts);
    o[1].v = blob.read_shift(8, 'f');
    return o;
  }
  function write_NUMBER(R, C, v) {
    var o = new_buf(13);
    o.write_shift(1, 0xFF);
    o.write_shift(2, C);
    o.write_shift(2, R);
    o.write_shift(8, v, 'f');
    return o;
  }
  function parse_FORMULA(blob, length, opts) {
    var tgt = blob.l + length;
    var o = parse_cell(blob, length, opts);
    /* TODO: formula */
    o[1].v = blob.read_shift(8, 'f');
    if (opts.qpro) blob.l = tgt;else {
      var flen = blob.read_shift(2);
      wk1_fmla_to_csf(blob.slice(blob.l, blob.l + flen), o);
      blob.l += flen;
    }
    return o;
  }
  function wk1_parse_rc(B, V, col) {
    var rel = V & 0x8000;
    V &= ~0x8000;
    V = (rel ? B : 0) + (V >= 0x2000 ? V - 0x4000 : V);
    return (rel ? "" : "$") + (col ? encode_col(V) : encode_row(V));
  }
  /* var oprec = [
  	8, 8, 8, 8, 8, 8, 8, 8, 6, 4, 4, 5, 5, 7, 3, 3,
  	3, 3, 3, 3, 1, 1, 2, 6, 8, 8, 8, 8, 8, 8, 8, 8
  ]; */
  /* TODO: flesh out */
  var FuncTab = {
    0x33: ["FALSE", 0],
    0x34: ["TRUE", 0],
    0x46: ["LEN", 1],
    0x50: ["SUM", 69],
    0x51: ["AVERAGEA", 69],
    0x52: ["COUNTA", 69],
    0x53: ["MINA", 69],
    0x54: ["MAXA", 69],
    0x6F: ["T", 1]
  };
  var BinOpTab = ["", "", "", "", "", "", "", "",
  // eslint-disable-line no-mixed-spaces-and-tabs
  "", "+", "-", "*", "/", "^", "=", "<>",
  // eslint-disable-line no-mixed-spaces-and-tabs
  "<=", ">=", "<", ">", "", "", "", "",
  // eslint-disable-line no-mixed-spaces-and-tabs
  "&", "", "", "", "", "", "", "" // eslint-disable-line no-mixed-spaces-and-tabs
  ];
  function wk1_fmla_to_csf(blob, o) {
    prep_blob(blob, 0);
    var out = [],
      argc = 0,
      R = "",
      C = "",
      argL = "",
      argR = "";
    while (blob.l < blob.length) {
      var cc = blob[blob.l++];
      switch (cc) {
        case 0x00:
          out.push(blob.read_shift(8, 'f'));
          break;
        case 0x01:
          {
            C = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
            R = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
            out.push(C + R);
          }
          break;
        case 0x02:
          {
            var c = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
            var r = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
            C = wk1_parse_rc(o[0].c, blob.read_shift(2), true);
            R = wk1_parse_rc(o[0].r, blob.read_shift(2), false);
            out.push(c + r + ":" + C + R);
          }
          break;
        case 0x03:
          if (blob.l < blob.length) {
            console.error("WK1 premature formula end");
            return;
          }
          break;
        case 0x04:
          out.push("(" + out.pop() + ")");
          break;
        case 0x05:
          out.push(blob.read_shift(2));
          break;
        case 0x06:
          {
            /* TODO: text encoding */
            var Z = "";
            while (cc = blob[blob.l++]) Z += String.fromCharCode(cc);
            out.push('"' + Z.replace(/"/g, '""') + '"');
          }
          break;
        case 0x08:
          out.push("-" + out.pop());
          break;
        case 0x17:
          out.push("+" + out.pop());
          break;
        case 0x16:
          out.push("NOT(" + out.pop() + ")");
          break;
        case 0x14:
        case 0x15:
          {
            argR = out.pop();
            argL = out.pop();
            out.push(["AND", "OR"][cc - 0x14] + "(" + argL + "," + argR + ")");
          }
          break;
        default:
          if (cc < 0x20 && BinOpTab[cc]) {
            argR = out.pop();
            argL = out.pop();
            out.push(argL + BinOpTab[cc] + argR);
          } else if (FuncTab[cc]) {
            argc = FuncTab[cc][1];
            if (argc == 69) argc = blob[blob.l++];
            if (argc > out.length) {
              console.error("WK1 bad formula parse 0x" + cc.toString(16) + ":|" + out.join("|") + "|");
              return;
            }
            var args = out.slice(-argc);
            out.length -= argc;
            out.push(FuncTab[cc][0] + "(" + args.join(",") + ")");
          } else if (cc <= 0x07) return console.error("WK1 invalid opcode " + cc.toString(16));else if (cc <= 0x18) return console.error("WK1 unsupported op " + cc.toString(16));else if (cc <= 0x1E) return console.error("WK1 invalid opcode " + cc.toString(16));else if (cc <= 0x73) return console.error("WK1 unsupported function opcode " + cc.toString(16));
          // possible future functions ??
          else return console.error("WK1 unrecognized opcode " + cc.toString(16));
      }
    }
    if (out.length == 1) o[1].f = "" + out[0];else console.error("WK1 bad formula parse |" + out.join("|") + "|");
  }
  function parse_cell_3(blob /*::, length*/) {
    var o = [{
      c: 0,
      r: 0
    }, {
      t: 'n',
      v: 0
    }, 0];
    o[0].r = blob.read_shift(2);
    o[3] = blob[blob.l++];
    o[0].c = blob[blob.l++];
    return o;
  }
  function parse_LABEL_16(blob, length) {
    var o = parse_cell_3(blob, length);
    o[1].t = 's';
    o[1].v = blob.read_shift(length - 4, 'cstr');
    return o;
  }
  function write_LABEL_16(R, C, wsidx, s) {
    /* TODO: encoding */
    var o = new_buf(6 + s.length);
    o.write_shift(2, R);
    o.write_shift(1, wsidx);
    o.write_shift(1, C);
    o.write_shift(1, 0x27);
    for (var i = 0; i < s.length; ++i) {
      var cc = s.charCodeAt(i);
      o.write_shift(1, cc >= 0x80 ? 0x5F : cc);
    }
    o.write_shift(1, 0);
    return o;
  }
  function parse_NUMBER_18(blob, length) {
    var o = parse_cell_3(blob, length);
    o[1].v = blob.read_shift(2);
    var v = o[1].v >> 1;
    if (o[1].v & 0x1) {
      switch (v & 0x07) {
        case 0:
          v = (v >> 3) * 5000;
          break;
        case 1:
          v = (v >> 3) * 500;
          break;
        case 2:
          v = (v >> 3) / 20;
          break;
        case 3:
          v = (v >> 3) / 200;
          break;
        case 4:
          v = (v >> 3) / 2000;
          break;
        case 5:
          v = (v >> 3) / 20000;
          break;
        case 6:
          v = (v >> 3) / 16;
          break;
        case 7:
          v = (v >> 3) / 64;
          break;
      }
    }
    o[1].v = v;
    return o;
  }
  function parse_NUMBER_17(blob, length) {
    var o = parse_cell_3(blob, length);
    var v1 = blob.read_shift(4);
    var v2 = blob.read_shift(4);
    var e = blob.read_shift(2);
    if (e == 0xFFFF) {
      if (v1 === 0 && v2 === 0xC0000000) {
        o[1].t = "e";
        o[1].v = 0x0F;
      } // ERR -> #VALUE!
      else if (v1 === 0 && v2 === 0xD0000000) {
        o[1].t = "e";
        o[1].v = 0x2A;
      } // NA -> #N/A
      else o[1].v = 0;
      return o;
    }
    var s = e & 0x8000;
    e = (e & 0x7FFF) - 16446;
    o[1].v = (1 - s * 2) * (v2 * Math.pow(2, e + 32) + v1 * Math.pow(2, e));
    return o;
  }
  function write_NUMBER_17(R, C, wsidx, v) {
    var o = new_buf(14);
    o.write_shift(2, R);
    o.write_shift(1, wsidx);
    o.write_shift(1, C);
    if (v == 0) {
      o.write_shift(4, 0);
      o.write_shift(4, 0);
      o.write_shift(2, 0xFFFF);
      return o;
    }
    var s = 0,
      e = 0,
      v1 = 0,
      v2 = 0;
    if (v < 0) {
      s = 1;
      v = -v;
    }
    e = Math.log2(v) | 0;
    v /= Math.pow(2, e - 31);
    v2 = v >>> 0;
    if ((v2 & 0x80000000) == 0) {
      v /= 2;
      ++e;
      v2 = v >>> 0;
    }
    v -= v2;
    v2 |= 0x80000000;
    v2 >>>= 0;
    v *= Math.pow(2, 32);
    v1 = v >>> 0;
    o.write_shift(4, v1);
    o.write_shift(4, v2);
    e += 0x3FFF + (s ? 0x8000 : 0);
    o.write_shift(2, e);
    return o;
  }
  function parse_FORMULA_19(blob, length) {
    var o = parse_NUMBER_17(blob, 14);
    blob.l += length - 14; /* TODO: WK3 formula */
    return o;
  }
  function parse_NUMBER_25(blob, length) {
    var o = parse_cell_3(blob, length);
    var v1 = blob.read_shift(4);
    o[1].v = v1 >> 6;
    return o;
  }
  function parse_NUMBER_27(blob, length) {
    var o = parse_cell_3(blob, length);
    var v1 = blob.read_shift(8, 'f');
    o[1].v = v1;
    return o;
  }
  function parse_FORMULA_28(blob, length) {
    var o = parse_NUMBER_27(blob, 14);
    blob.l += length - 10; /* TODO: formula */
    return o;
  }
  function parse_SHEETNAMECS(blob, length) {
    return blob[blob.l + length - 1] == 0 ? blob.read_shift(length, 'cstr') : "";
  }
  function parse_SHEETNAMELP(blob, length) {
    var len = blob[blob.l++];
    if (len > length - 1) len = length - 1;
    var o = "";
    while (o.length < len) o += String.fromCharCode(blob[blob.l++]);
    return o;
  }
  function parse_SHEETINFOQP(blob, length, opts) {
    if (!opts.qpro || length < 21) return;
    var id = blob.read_shift(1);
    blob.l += 17;
    blob.l += 1; //var len = blob.read_shift(1);
    blob.l += 2;
    var nm = blob.read_shift(length - 21, 'cstr');
    return [id, nm];
  }
  function parse_XFORMAT(blob, length) {
    var o = {},
      tgt = blob.l + length;
    while (blob.l < tgt) {
      var dt = blob.read_shift(2);
      if (dt == 0x36b0) {
        o[dt] = [0, ""];
        o[dt][0] = blob.read_shift(2);
        while (blob[blob.l]) {
          o[dt][1] += String.fromCharCode(blob[blob.l]);
          blob.l++;
        }
        blob.l++;
      }
      // TODO: 0x3a99 ??
    }
    return o;
  }
  function write_XFORMAT_SHEETNAME(name, wsidx) {
    var out = new_buf(5 + name.length);
    out.write_shift(2, 0x36b0);
    out.write_shift(2, wsidx);
    for (var i = 0; i < name.length; ++i) {
      var cc = name.charCodeAt(i);
      out[out.l++] = cc > 0x7F ? 0x5F : cc;
    }
    out[out.l++] = 0;
    return out;
  }
  var WK1Enum = {
    /*::[*/0x0000 /*::]*/: {
      n: "BOF",
      f: parseuint16
    },
    /*::[*/0x0001 /*::]*/: {
      n: "EOF"
    },
    /*::[*/0x0002 /*::]*/: {
      n: "CALCMODE"
    },
    /*::[*/0x0003 /*::]*/: {
      n: "CALCORDER"
    },
    /*::[*/0x0004 /*::]*/: {
      n: "SPLIT"
    },
    /*::[*/0x0005 /*::]*/: {
      n: "SYNC"
    },
    /*::[*/0x0006 /*::]*/: {
      n: "RANGE",
      f: parse_RANGE
    },
    /*::[*/0x0007 /*::]*/: {
      n: "WINDOW1"
    },
    /*::[*/0x0008 /*::]*/: {
      n: "COLW1"
    },
    /*::[*/0x0009 /*::]*/: {
      n: "WINTWO"
    },
    /*::[*/0x000A /*::]*/: {
      n: "COLW2"
    },
    /*::[*/0x000B /*::]*/: {
      n: "NAME"
    },
    /*::[*/0x000C /*::]*/: {
      n: "BLANK"
    },
    /*::[*/0x000D /*::]*/: {
      n: "INTEGER",
      f: parse_INTEGER
    },
    /*::[*/0x000E /*::]*/: {
      n: "NUMBER",
      f: parse_NUMBER
    },
    /*::[*/0x000F /*::]*/: {
      n: "LABEL",
      f: parse_LABEL
    },
    /*::[*/0x0010 /*::]*/: {
      n: "FORMULA",
      f: parse_FORMULA
    },
    /*::[*/0x0018 /*::]*/: {
      n: "TABLE"
    },
    /*::[*/0x0019 /*::]*/: {
      n: "ORANGE"
    },
    /*::[*/0x001A /*::]*/: {
      n: "PRANGE"
    },
    /*::[*/0x001B /*::]*/: {
      n: "SRANGE"
    },
    /*::[*/0x001C /*::]*/: {
      n: "FRANGE"
    },
    /*::[*/0x001D /*::]*/: {
      n: "KRANGE1"
    },
    /*::[*/0x0020 /*::]*/: {
      n: "HRANGE"
    },
    /*::[*/0x0023 /*::]*/: {
      n: "KRANGE2"
    },
    /*::[*/0x0024 /*::]*/: {
      n: "PROTEC"
    },
    /*::[*/0x0025 /*::]*/: {
      n: "FOOTER"
    },
    /*::[*/0x0026 /*::]*/: {
      n: "HEADER"
    },
    /*::[*/0x0027 /*::]*/: {
      n: "SETUP"
    },
    /*::[*/0x0028 /*::]*/: {
      n: "MARGINS"
    },
    /*::[*/0x0029 /*::]*/: {
      n: "LABELFMT"
    },
    /*::[*/0x002A /*::]*/: {
      n: "TITLES"
    },
    /*::[*/0x002B /*::]*/: {
      n: "SHEETJS"
    },
    /*::[*/0x002D /*::]*/: {
      n: "GRAPH"
    },
    /*::[*/0x002E /*::]*/: {
      n: "NGRAPH"
    },
    /*::[*/0x002F /*::]*/: {
      n: "CALCCOUNT"
    },
    /*::[*/0x0030 /*::]*/: {
      n: "UNFORMATTED"
    },
    /*::[*/0x0031 /*::]*/: {
      n: "CURSORW12"
    },
    /*::[*/0x0032 /*::]*/: {
      n: "WINDOW"
    },
    /*::[*/0x0033 /*::]*/: {
      n: "STRING",
      f: parse_LABEL
    },
    /*::[*/0x0037 /*::]*/: {
      n: "PASSWORD"
    },
    /*::[*/0x0038 /*::]*/: {
      n: "LOCKED"
    },
    /*::[*/0x003C /*::]*/: {
      n: "QUERY"
    },
    /*::[*/0x003D /*::]*/: {
      n: "QUERYNAME"
    },
    /*::[*/0x003E /*::]*/: {
      n: "PRINT"
    },
    /*::[*/0x003F /*::]*/: {
      n: "PRINTNAME"
    },
    /*::[*/0x0040 /*::]*/: {
      n: "GRAPH2"
    },
    /*::[*/0x0041 /*::]*/: {
      n: "GRAPHNAME"
    },
    /*::[*/0x0042 /*::]*/: {
      n: "ZOOM"
    },
    /*::[*/0x0043 /*::]*/: {
      n: "SYMSPLIT"
    },
    /*::[*/0x0044 /*::]*/: {
      n: "NSROWS"
    },
    /*::[*/0x0045 /*::]*/: {
      n: "NSCOLS"
    },
    /*::[*/0x0046 /*::]*/: {
      n: "RULER"
    },
    /*::[*/0x0047 /*::]*/: {
      n: "NNAME"
    },
    /*::[*/0x0048 /*::]*/: {
      n: "ACOMM"
    },
    /*::[*/0x0049 /*::]*/: {
      n: "AMACRO"
    },
    /*::[*/0x004A /*::]*/: {
      n: "PARSE"
    },
    /*::[*/0x0066 /*::]*/: {
      n: "PRANGES??"
    },
    /*::[*/0x0067 /*::]*/: {
      n: "RRANGES??"
    },
    /*::[*/0x0068 /*::]*/: {
      n: "FNAME??"
    },
    /*::[*/0x0069 /*::]*/: {
      n: "MRANGES??"
    },
    /*::[*/0x00CC /*::]*/: {
      n: "SHEETNAMECS",
      f: parse_SHEETNAMECS
    },
    /*::[*/0x00DE /*::]*/: {
      n: "SHEETNAMELP",
      f: parse_SHEETNAMELP
    },
    /*::[*/0xFFFF /*::]*/: {
      n: ""
    }
  };
  var WK3Enum = {
    /*::[*/0x0000 /*::]*/: {
      n: "BOF"
    },
    /*::[*/0x0001 /*::]*/: {
      n: "EOF"
    },
    /*::[*/0x0002 /*::]*/: {
      n: "PASSWORD"
    },
    /*::[*/0x0003 /*::]*/: {
      n: "CALCSET"
    },
    /*::[*/0x0004 /*::]*/: {
      n: "WINDOWSET"
    },
    /*::[*/0x0005 /*::]*/: {
      n: "SHEETCELLPTR"
    },
    /*::[*/0x0006 /*::]*/: {
      n: "SHEETLAYOUT"
    },
    /*::[*/0x0007 /*::]*/: {
      n: "COLUMNWIDTH"
    },
    /*::[*/0x0008 /*::]*/: {
      n: "HIDDENCOLUMN"
    },
    /*::[*/0x0009 /*::]*/: {
      n: "USERRANGE"
    },
    /*::[*/0x000A /*::]*/: {
      n: "SYSTEMRANGE"
    },
    /*::[*/0x000B /*::]*/: {
      n: "ZEROFORCE"
    },
    /*::[*/0x000C /*::]*/: {
      n: "SORTKEYDIR"
    },
    /*::[*/0x000D /*::]*/: {
      n: "FILESEAL"
    },
    /*::[*/0x000E /*::]*/: {
      n: "DATAFILLNUMS"
    },
    /*::[*/0x000F /*::]*/: {
      n: "PRINTMAIN"
    },
    /*::[*/0x0010 /*::]*/: {
      n: "PRINTSTRING"
    },
    /*::[*/0x0011 /*::]*/: {
      n: "GRAPHMAIN"
    },
    /*::[*/0x0012 /*::]*/: {
      n: "GRAPHSTRING"
    },
    /*::[*/0x0013 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0014 /*::]*/: {
      n: "ERRCELL"
    },
    /*::[*/0x0015 /*::]*/: {
      n: "NACELL"
    },
    /*::[*/0x0016 /*::]*/: {
      n: "LABEL16",
      f: parse_LABEL_16
    },
    /*::[*/0x0017 /*::]*/: {
      n: "NUMBER17",
      f: parse_NUMBER_17
    },
    /*::[*/0x0018 /*::]*/: {
      n: "NUMBER18",
      f: parse_NUMBER_18
    },
    /*::[*/0x0019 /*::]*/: {
      n: "FORMULA19",
      f: parse_FORMULA_19
    },
    /*::[*/0x001A /*::]*/: {
      n: "FORMULA1A"
    },
    /*::[*/0x001B /*::]*/: {
      n: "XFORMAT",
      f: parse_XFORMAT
    },
    /*::[*/0x001C /*::]*/: {
      n: "DTLABELMISC"
    },
    /*::[*/0x001D /*::]*/: {
      n: "DTLABELCELL"
    },
    /*::[*/0x001E /*::]*/: {
      n: "GRAPHWINDOW"
    },
    /*::[*/0x001F /*::]*/: {
      n: "CPA"
    },
    /*::[*/0x0020 /*::]*/: {
      n: "LPLAUTO"
    },
    /*::[*/0x0021 /*::]*/: {
      n: "QUERY"
    },
    /*::[*/0x0022 /*::]*/: {
      n: "HIDDENSHEET"
    },
    /*::[*/0x0023 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0025 /*::]*/: {
      n: "NUMBER25",
      f: parse_NUMBER_25
    },
    /*::[*/0x0026 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0027 /*::]*/: {
      n: "NUMBER27",
      f: parse_NUMBER_27
    },
    /*::[*/0x0028 /*::]*/: {
      n: "FORMULA28",
      f: parse_FORMULA_28
    },
    /*::[*/0x008E /*::]*/: {
      n: "??"
    },
    /*::[*/0x0093 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0096 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0097 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0098 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0099 /*::]*/: {
      n: "??"
    },
    /*::[*/0x009A /*::]*/: {
      n: "??"
    },
    /*::[*/0x009B /*::]*/: {
      n: "??"
    },
    /*::[*/0x009C /*::]*/: {
      n: "??"
    },
    /*::[*/0x00A3 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00AE /*::]*/: {
      n: "??"
    },
    /*::[*/0x00AF /*::]*/: {
      n: "??"
    },
    /*::[*/0x00B0 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00B1 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00B8 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00B9 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00BA /*::]*/: {
      n: "??"
    },
    /*::[*/0x00BB /*::]*/: {
      n: "??"
    },
    /*::[*/0x00BC /*::]*/: {
      n: "??"
    },
    /*::[*/0x00C3 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00C9 /*::]*/: {
      n: "??"
    },
    /*::[*/0x00CC /*::]*/: {
      n: "SHEETNAMECS",
      f: parse_SHEETNAMECS
    },
    /*::[*/0x00CD /*::]*/: {
      n: "??"
    },
    /*::[*/0x00CE /*::]*/: {
      n: "??"
    },
    /*::[*/0x00CF /*::]*/: {
      n: "??"
    },
    /*::[*/0x00D0 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0100 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0103 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0104 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0105 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0106 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0107 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0109 /*::]*/: {
      n: "??"
    },
    /*::[*/0x010A /*::]*/: {
      n: "??"
    },
    /*::[*/0x010B /*::]*/: {
      n: "??"
    },
    /*::[*/0x010C /*::]*/: {
      n: "??"
    },
    /*::[*/0x010E /*::]*/: {
      n: "??"
    },
    /*::[*/0x010F /*::]*/: {
      n: "??"
    },
    /*::[*/0x0180 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0185 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0186 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0189 /*::]*/: {
      n: "??"
    },
    /*::[*/0x018C /*::]*/: {
      n: "??"
    },
    /*::[*/0x0200 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0202 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0201 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0204 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0205 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0280 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0281 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0282 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0283 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0284 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0285 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0286 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0287 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0288 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0292 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0293 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0294 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0295 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0296 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0299 /*::]*/: {
      n: "??"
    },
    /*::[*/0x029A /*::]*/: {
      n: "??"
    },
    /*::[*/0x0300 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0304 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0601 /*::]*/: {
      n: "SHEETINFOQP",
      f: parse_SHEETINFOQP
    },
    /*::[*/0x0640 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0642 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0701 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0702 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0703 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0704 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0780 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0800 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0801 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0804 /*::]*/: {
      n: "??"
    },
    /*::[*/0x0A80 /*::]*/: {
      n: "??"
    },
    /*::[*/0x2AF6 /*::]*/: {
      n: "??"
    },
    /*::[*/0x3231 /*::]*/: {
      n: "??"
    },
    /*::[*/0x6E49 /*::]*/: {
      n: "??"
    },
    /*::[*/0x6F44 /*::]*/: {
      n: "??"
    },
    /*::[*/0xFFFF /*::]*/: {
      n: ""
    }
  };
  return {
    sheet_to_wk1: sheet_to_wk1,
    book_to_wk3: book_to_wk3,
    to_workbook: lotus_to_workbook
  };
}();
/* 18.4.7 rPr CT_RPrElt */
function parse_rpr(rpr) {
  var font = {},
    m = rpr.match(tagregex),
    i = 0;
  var pass = false;
  if (m) for (; i != m.length; ++i) {
    var y = parsexmltag(m[i]);
    switch (y[0].replace(/\w*:/g, "")) {
      /* 18.8.12 condense CT_BooleanProperty */
      /* ** not required . */
      case '<condense':
        break;
      /* 18.8.17 extend CT_BooleanProperty */
      /* ** not required . */
      case '<extend':
        break;
      /* 18.8.36 shadow CT_BooleanProperty */
      /* ** not required . */
      case '<shadow':
        if (!y.val) break;
      /* falls through */
      case '<shadow>':
      case '<shadow/>':
        font.shadow = 1;
        break;
      case '</shadow>':
        break;

      /* 18.4.1 charset CT_IntProperty TODO */
      case '<charset':
        if (y.val == '1') break;
        font.cp = CS2CP[parseInt(y.val, 10)];
        break;

      /* 18.4.2 outline CT_BooleanProperty TODO */
      case '<outline':
        if (!y.val) break;
      /* falls through */
      case '<outline>':
      case '<outline/>':
        font.outline = 1;
        break;
      case '</outline>':
        break;

      /* 18.4.5 rFont CT_FontName */
      case '<rFont':
        font.name = y.val;
        break;

      /* 18.4.11 sz CT_FontSize */
      case '<sz':
        font.sz = y.val;
        break;

      /* 18.4.10 strike CT_BooleanProperty */
      case '<strike':
        if (!y.val) break;
      /* falls through */
      case '<strike>':
      case '<strike/>':
        font.strike = 1;
        break;
      case '</strike>':
        break;

      /* 18.4.13 u CT_UnderlineProperty */
      case '<u':
        if (!y.val) break;
        switch (y.val) {
          case 'double':
            font.uval = "double";
            break;
          case 'singleAccounting':
            font.uval = "single-accounting";
            break;
          case 'doubleAccounting':
            font.uval = "double-accounting";
            break;
        }
      /* falls through */
      case '<u>':
      case '<u/>':
        font.u = 1;
        break;
      case '</u>':
        break;

      /* 18.8.2 b */
      case '<b':
        if (y.val == '0') break;
      /* falls through */
      case '<b>':
      case '<b/>':
        font.b = 1;
        break;
      case '</b>':
        break;

      /* 18.8.26 i */
      case '<i':
        if (y.val == '0') break;
      /* falls through */
      case '<i>':
      case '<i/>':
        font.i = 1;
        break;
      case '</i>':
        break;

      /* 18.3.1.15 color CT_Color TODO: tint, theme, auto, indexed */
      case '<color':
        if (y.rgb) font.color = y.rgb.slice(2, 8);
        break;
      case '<color>':
      case '<color/>':
      case '</color>':
        break;

      /* 18.8.18 family ST_FontFamily */
      case '<family':
        font.family = y.val;
        break;
      case '<family>':
      case '<family/>':
      case '</family>':
        break;

      /* 18.4.14 vertAlign CT_VerticalAlignFontProperty TODO */
      case '<vertAlign':
        font.valign = y.val;
        break;
      case '<vertAlign>':
      case '<vertAlign/>':
      case '</vertAlign>':
        break;

      /* 18.8.35 scheme CT_FontScheme TODO */
      case '<scheme':
        break;
      case '<scheme>':
      case '<scheme/>':
      case '</scheme>':
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
        break;
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (y[0].charCodeAt(1) !== 47 && !pass) throw new Error('Unrecognized rich format ' + y[0]);
    }
  }
  return font;
}
var parse_rs = /*#__PURE__*/function () {
  var tregex = matchtag("t"),
    rpregex = matchtag("rPr");
  /* 18.4.4 r CT_RElt */
  function parse_r(r) {
    /* 18.4.12 t ST_Xstring */
    var t = r.match(tregex) /*, cp = 65001*/;
    if (!t) return {
      t: "s",
      v: ""
    };
    var o /*:Cell*/ = {
      t: 's',
      v: unescapexml(t[1])
    } /*:any*/;
    var rpr = r.match(rpregex);
    if (rpr) o.s = parse_rpr(rpr[1]);
    return o;
  }
  var rregex = /<(?:\w+:)?r>/g,
    rend = /<\/(?:\w+:)?r>/;
  return function parse_rs(rs) {
    return rs.replace(rregex, "").split(rend).map(parse_r).filter(function (r) {
      return r.v;
    });
  };
}();

/* Parse a list of <r> tags */
var rs_to_html = /*#__PURE__*/function parse_rs_factory() {
  var nlregex = /(\r\n|\n)/g;
  function parse_rpr2(font, intro, outro) {
    var style /*:Array<string>*/ = [];
    if (font.u) style.push("text-decoration: underline;");
    if (font.uval) style.push("text-underline-style:" + font.uval + ";");
    if (font.sz) style.push("font-size:" + font.sz + "pt;");
    if (font.outline) style.push("text-effect: outline;");
    if (font.shadow) style.push("text-shadow: auto;");
    intro.push('<span style="' + style.join("") + '">');
    if (font.b) {
      intro.push("<b>");
      outro.push("</b>");
    }
    if (font.i) {
      intro.push("<i>");
      outro.push("</i>");
    }
    if (font.strike) {
      intro.push("<s>");
      outro.push("</s>");
    }
    var align = font.valign || "";
    if (align == "superscript" || align == "super") align = "sup";else if (align == "subscript") align = "sub";
    if (align != "") {
      intro.push("<" + align + ">");
      outro.push("</" + align + ">");
    }
    outro.push("</span>");
    return font;
  }

  /* 18.4.4 r CT_RElt */
  function r_to_html(r) {
    var terms /*:[Array<string>, string, Array<string>]*/ = [[], r.v, []];
    if (!r.v) return "";
    if (r.s) parse_rpr2(r.s, terms[0], terms[2]);
    return terms[0].join("") + terms[1].replace(nlregex, '<br/>') + terms[2].join("");
  }
  return function parse_rs(rs) {
    return rs.map(r_to_html).join("");
  };
}();

/* 18.4.8 si CT_Rst */
var sitregex = /<(?:\w+:)?t[^>]*>([^<]*)<\/(?:\w+:)?t>/g,
  sirregex = /<(?:\w+:)?r>/;
var sirphregex = /<(?:\w+:)?rPh.*?>([\s\S]*?)<\/(?:\w+:)?rPh>/g;
function parse_si(x, opts) {
  var html = opts ? opts.cellHTML : true;
  var z = {};
  if (!x) return {
    t: ""
  };
  //var y;
  /* 18.4.12 t ST_Xstring (Plaintext String) */
  // TODO: is whitespace actually valid here?
  if (x.match(/^\s*<(?:\w+:)?t[^>]*>/)) {
    z.t = unescapexml(utf8read(x.slice(x.indexOf(">") + 1).split(/<\/(?:\w+:)?t>/)[0] || ""));
    z.r = utf8read(x);
    if (html) z.h = escapehtml(z.t);
  }
  /* 18.4.4 r CT_RElt (Rich Text Run) */else if ((/*y = */x.match(sirregex))) {
    z.r = utf8read(x);
    z.t = unescapexml(utf8read((x.replace(sirphregex, '').match(sitregex) || []).join("").replace(tagregex, "")));
    if (html) z.h = rs_to_html(parse_rs(z.r));
  }
  /* 18.4.3 phoneticPr CT_PhoneticPr (TODO: needed for Asian support) */
  /* 18.4.6 rPh CT_PhoneticRun (TODO: needed for Asian support) */
  return z;
}

/* 18.4 Shared String Table */
var sstr0 = /<(?:\w+:)?sst([^>]*)>([\s\S]*)<\/(?:\w+:)?sst>/;
var sstr1 = /<(?:\w+:)?(?:si|sstItem)>/g;
var sstr2 = /<\/(?:\w+:)?(?:si|sstItem)>/;
function parse_sst_xml(data /*:string*/, opts) /*:SST*/{
  var s /*:SST*/ = [] /*:any*/,
    ss = "";
  if (!data) return s;
  /* 18.4.9 sst CT_Sst */
  var sst = data.match(sstr0);
  if (sst) {
    ss = sst[2].replace(sstr1, "").split(sstr2);
    for (var i = 0; i != ss.length; ++i) {
      var o = parse_si(ss[i].trim(), opts);
      if (o != null) s[s.length] = o;
    }
    sst = parsexmltag(sst[1]);
    s.Count = sst.count;
    s.Unique = sst.uniqueCount;
  }
  return s;
}
var straywsregex = /^\s|\s$|[\t\n\r]/;
function write_sst_xml(sst /*:SST*/, opts) /*:string*/{
  if (!opts.bookSST) return "";
  var o = [XML_HEADER];
  o[o.length] = writextag('sst', null, {
    xmlns: XMLNS_main[0],
    count: sst.Count,
    uniqueCount: sst.Unique
  });
  for (var i = 0; i != sst.length; ++i) {
    if (sst[i] == null) continue;
    var s /*:XLString*/ = sst[i];
    var sitag = "<si>";
    if (s.r) sitag += s.r;else {
      sitag += "<t";
      if (!s.t) s.t = "";
      if (s.t.match(straywsregex)) sitag += ' xml:space="preserve"';
      sitag += ">" + escapexml(s.t) + "</t>";
    }
    sitag += "</si>";
    o[o.length] = sitag;
  }
  if (o.length > 2) {
    o[o.length] = '</sst>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* [MS-XLSB] 2.4.221 BrtBeginSst */
function parse_BrtBeginSst(data) {
  return [data.read_shift(4), data.read_shift(4)];
}

/* [MS-XLSB] 2.1.7.45 Shared Strings */
function parse_sst_bin(data, opts) /*:SST*/{
  var s /*:SST*/ = [] /*:any*/;
  var pass = false;
  recordhopper(data, function hopper_sst(val, R, RT) {
    switch (RT) {
      case 0x009F:
        /* BrtBeginSst */
        s.Count = val[0];
        s.Unique = val[1];
        break;
      case 0x0013:
        /* BrtSSTItem */
        s.push(val);
        break;
      case 0x00A0:
        /* BrtEndSst */
        return true;
      case 0x0023:
        /* BrtFRTBegin */
        pass = true;
        break;
      case 0x0024:
        /* BrtFRTEnd */
        pass = false;
        break;
      default:
        if (R.T) {}
        if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  });
  return s;
}
function write_BrtBeginSst(sst, o) {
  if (!o) o = new_buf(8);
  o.write_shift(4, sst.Count);
  o.write_shift(4, sst.Unique);
  return o;
}
var write_BrtSSTItem = write_RichStr;
function write_sst_bin(sst /*::, opts*/) {
  var ba = buf_array();
  write_record(ba, 0x009F /* BrtBeginSst */, write_BrtBeginSst(sst));
  for (var i = 0; i < sst.length; ++i) write_record(ba, 0x0013 /* BrtSSTItem */, write_BrtSSTItem(sst[i]));
  /* FRTSST */
  write_record(ba, 0x00A0 /* BrtEndSst */);
  return ba.end();
}
function _JS2ANSI(str /*:string*/) /*:Array<number>*/{
  if (typeof $cptable !== 'undefined') return $cptable.utils.encode(current_ansi, str);
  var o /*:Array<number>*/ = [],
    oo = str.split("");
  for (var i = 0; i < oo.length; ++i) o[i] = oo[i].charCodeAt(0);
  return o;
}

/* [MS-OFFCRYPTO] 2.1.4 Version */
function parse_CRYPTOVersion(blob, length /*:?number*/) {
  var o /*:any*/ = {};
  o.Major = blob.read_shift(2);
  o.Minor = blob.read_shift(2);
  /*:: if(length == null) return o; */
  if (length >= 4) blob.l += length - 4;
  return o;
}

/* [MS-OFFCRYPTO] 2.1.5 DataSpaceVersionInfo */
function parse_DataSpaceVersionInfo(blob) {
  var o = {};
  o.id = blob.read_shift(0, 'lpp4');
  o.R = parse_CRYPTOVersion(blob, 4);
  o.U = parse_CRYPTOVersion(blob, 4);
  o.W = parse_CRYPTOVersion(blob, 4);
  return o;
}

/* [MS-OFFCRYPTO] 2.1.6.1 DataSpaceMapEntry Structure */
function parse_DataSpaceMapEntry(blob) {
  var len = blob.read_shift(4);
  var end = blob.l + len - 4;
  var o = {};
  var cnt = blob.read_shift(4);
  var comps /*:Array<{t:number, v:string}>*/ = [];
  /* [MS-OFFCRYPTO] 2.1.6.2 DataSpaceReferenceComponent Structure */
  while (cnt-- > 0) comps.push({
    t: blob.read_shift(4),
    v: blob.read_shift(0, 'lpp4')
  });
  o.name = blob.read_shift(0, 'lpp4');
  o.comps = comps;
  if (blob.l != end) throw new Error("Bad DataSpaceMapEntry: " + blob.l + " != " + end);
  return o;
}

/* [MS-OFFCRYPTO] 2.1.6 DataSpaceMap */
function parse_DataSpaceMap(blob) {
  var o = [];
  blob.l += 4; // must be 0x8
  var cnt = blob.read_shift(4);
  while (cnt-- > 0) o.push(parse_DataSpaceMapEntry(blob));
  return o;
}

/* [MS-OFFCRYPTO] 2.1.7 DataSpaceDefinition */
function parse_DataSpaceDefinition(blob) /*:Array<string>*/{
  var o /*:Array<string>*/ = [];
  blob.l += 4; // must be 0x8
  var cnt = blob.read_shift(4);
  while (cnt-- > 0) o.push(blob.read_shift(0, 'lpp4'));
  return o;
}

/* [MS-OFFCRYPTO] 2.1.8 DataSpaceDefinition */
function parse_TransformInfoHeader(blob) {
  var o = {};
  /*var len = */
  blob.read_shift(4);
  blob.l += 4; // must be 0x1
  o.id = blob.read_shift(0, 'lpp4');
  o.name = blob.read_shift(0, 'lpp4');
  o.R = parse_CRYPTOVersion(blob, 4);
  o.U = parse_CRYPTOVersion(blob, 4);
  o.W = parse_CRYPTOVersion(blob, 4);
  return o;
}
function parse_Primary(blob) {
  /* [MS-OFFCRYPTO] 2.2.6 IRMDSTransformInfo */
  var hdr = parse_TransformInfoHeader(blob);
  /* [MS-OFFCRYPTO] 2.1.9 EncryptionTransformInfo */
  hdr.ename = blob.read_shift(0, '8lpp4');
  hdr.blksz = blob.read_shift(4);
  hdr.cmode = blob.read_shift(4);
  if (blob.read_shift(4) != 0x04) throw new Error("Bad !Primary record");
  return hdr;
}

/* [MS-OFFCRYPTO] 2.3.2 Encryption Header */
function parse_EncryptionHeader(blob, length /*:number*/) {
  var tgt = blob.l + length;
  var o = {};
  o.Flags = blob.read_shift(4) & 0x3F;
  blob.l += 4;
  o.AlgID = blob.read_shift(4);
  var valid = false;
  switch (o.AlgID) {
    case 0x660E:
    case 0x660F:
    case 0x6610:
      valid = o.Flags == 0x24;
      break;
    case 0x6801:
      valid = o.Flags == 0x04;
      break;
    case 0:
      valid = o.Flags == 0x10 || o.Flags == 0x04 || o.Flags == 0x24;
      break;
    default:
      throw 'Unrecognized encryption algorithm: ' + o.AlgID;
  }
  if (!valid) throw new Error("Encryption Flags/AlgID mismatch");
  o.AlgIDHash = blob.read_shift(4);
  o.KeySize = blob.read_shift(4);
  o.ProviderType = blob.read_shift(4);
  blob.l += 8;
  o.CSPName = blob.read_shift(tgt - blob.l >> 1, 'utf16le');
  blob.l = tgt;
  return o;
}

/* [MS-OFFCRYPTO] 2.3.3 Encryption Verifier */
function parse_EncryptionVerifier(blob, length /*:number*/) {
  var o = {},
    tgt = blob.l + length;
  blob.l += 4; // SaltSize must be 0x10
  o.Salt = blob.slice(blob.l, blob.l + 16);
  blob.l += 16;
  o.Verifier = blob.slice(blob.l, blob.l + 16);
  blob.l += 16;
  /*var sz = */
  blob.read_shift(4);
  o.VerifierHash = blob.slice(blob.l, tgt);
  blob.l = tgt;
  return o;
}

/* [MS-OFFCRYPTO] 2.3.4.* EncryptionInfo Stream */
function parse_EncryptionInfo(blob) {
  var vers = parse_CRYPTOVersion(blob);
  switch (vers.Minor) {
    case 0x02:
      return [vers.Minor, parse_EncInfoStd(blob, vers)];
    case 0x03:
      return [vers.Minor, parse_EncInfoExt(blob, vers)];
    case 0x04:
      return [vers.Minor, parse_EncInfoAgl(blob, vers)];
  }
  throw new Error("ECMA-376 Encrypted file unrecognized Version: " + vers.Minor);
}

/* [MS-OFFCRYPTO] 2.3.4.5  EncryptionInfo Stream (Standard Encryption) */
function parse_EncInfoStd(blob /*::, vers*/) {
  var flags = blob.read_shift(4);
  if ((flags & 0x3F) != 0x24) throw new Error("EncryptionInfo mismatch");
  var sz = blob.read_shift(4);
  //var tgt = blob.l + sz;
  var hdr = parse_EncryptionHeader(blob, sz);
  var verifier = parse_EncryptionVerifier(blob, blob.length - blob.l);
  return {
    t: "Std",
    h: hdr,
    v: verifier
  };
}
/* [MS-OFFCRYPTO] 2.3.4.6  EncryptionInfo Stream (Extensible Encryption) */
function parse_EncInfoExt(/*::blob, vers*/) {
  throw new Error("File is password-protected: ECMA-376 Extensible");
}
/* [MS-OFFCRYPTO] 2.3.4.10 EncryptionInfo Stream (Agile Encryption) */
function parse_EncInfoAgl(blob /*::, vers*/) {
  var KeyData = ["saltSize", "blockSize", "keyBits", "hashSize", "cipherAlgorithm", "cipherChaining", "hashAlgorithm", "saltValue"];
  blob.l += 4;
  var xml = blob.read_shift(blob.length - blob.l, 'utf8');
  var o = {};
  xml.replace(tagregex, function xml_agile(x) {
    var y /*:any*/ = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<?xml':
        break;
      case '<encryption':
      case '</encryption>':
        break;
      case '<keyData':
        KeyData.forEach(function (k) {
          o[k] = y[k];
        });
        break;
      case '<dataIntegrity':
        o.encryptedHmacKey = y.encryptedHmacKey;
        o.encryptedHmacValue = y.encryptedHmacValue;
        break;
      case '<keyEncryptors>':
      case '<keyEncryptors':
        o.encs = [];
        break;
      case '</keyEncryptors>':
        break;
      case '<keyEncryptor':
        o.uri = y.uri;
        break;
      case '</keyEncryptor>':
        break;
      case '<encryptedKey':
        o.encs.push(y);
        break;
      default:
        throw y[0];
    }
  });
  return o;
}

/* [MS-OFFCRYPTO] 2.3.5.1 RC4 CryptoAPI Encryption Header */
function parse_RC4CryptoHeader(blob, length /*:number*/) {
  var o = {};
  var vers = o.EncryptionVersionInfo = parse_CRYPTOVersion(blob, 4);
  length -= 4;
  if (vers.Minor != 2) throw new Error('unrecognized minor version code: ' + vers.Minor);
  if (vers.Major > 4 || vers.Major < 2) throw new Error('unrecognized major version code: ' + vers.Major);
  o.Flags = blob.read_shift(4);
  length -= 4;
  var sz = blob.read_shift(4);
  length -= 4;
  o.EncryptionHeader = parse_EncryptionHeader(blob, sz);
  length -= sz;
  o.EncryptionVerifier = parse_EncryptionVerifier(blob, length);
  return o;
}
/* [MS-OFFCRYPTO] 2.3.6.1 RC4 Encryption Header */
function parse_RC4Header(blob /*::, length*/) {
  var o = {};
  var vers = o.EncryptionVersionInfo = parse_CRYPTOVersion(blob, 4);
  if (vers.Major != 1 || vers.Minor != 1) throw 'unrecognized version code ' + vers.Major + ' : ' + vers.Minor;
  o.Salt = blob.read_shift(16);
  o.EncryptedVerifier = blob.read_shift(16);
  o.EncryptedVerifierHash = blob.read_shift(16);
  return o;
}

/* [MS-OFFCRYPTO] 2.3.7.1 Binary Document Password Verifier Derivation */
function crypto_CreatePasswordVerifier_Method1(Password /*:string*/) {
  var Verifier = 0x0000,
    PasswordArray;
  var PasswordDecoded = _JS2ANSI(Password);
  var len = PasswordDecoded.length + 1,
    i,
    PasswordByte;
  var Intermediate1, Intermediate2, Intermediate3;
  PasswordArray = new_raw_buf(len);
  PasswordArray[0] = PasswordDecoded.length;
  for (i = 1; i != len; ++i) PasswordArray[i] = PasswordDecoded[i - 1];
  for (i = len - 1; i >= 0; --i) {
    PasswordByte = PasswordArray[i];
    Intermediate1 = (Verifier & 0x4000) === 0x0000 ? 0 : 1;
    Intermediate2 = Verifier << 1 & 0x7FFF;
    Intermediate3 = Intermediate1 | Intermediate2;
    Verifier = Intermediate3 ^ PasswordByte;
  }
  return Verifier ^ 0xCE4B;
}

/* [MS-OFFCRYPTO] 2.3.7.2 Binary Document XOR Array Initialization */
var crypto_CreateXorArray_Method1 = /*#__PURE__*/function () {
  var PadArray = [0xBB, 0xFF, 0xFF, 0xBA, 0xFF, 0xFF, 0xB9, 0x80, 0x00, 0xBE, 0x0F, 0x00, 0xBF, 0x0F, 0x00];
  var InitialCode = [0xE1F0, 0x1D0F, 0xCC9C, 0x84C0, 0x110C, 0x0E10, 0xF1CE, 0x313E, 0x1872, 0xE139, 0xD40F, 0x84F9, 0x280C, 0xA96A, 0x4EC3];
  var XorMatrix = [0xAEFC, 0x4DD9, 0x9BB2, 0x2745, 0x4E8A, 0x9D14, 0x2A09, 0x7B61, 0xF6C2, 0xFDA5, 0xEB6B, 0xC6F7, 0x9DCF, 0x2BBF, 0x4563, 0x8AC6, 0x05AD, 0x0B5A, 0x16B4, 0x2D68, 0x5AD0, 0x0375, 0x06EA, 0x0DD4, 0x1BA8, 0x3750, 0x6EA0, 0xDD40, 0xD849, 0xA0B3, 0x5147, 0xA28E, 0x553D, 0xAA7A, 0x44D5, 0x6F45, 0xDE8A, 0xAD35, 0x4A4B, 0x9496, 0x390D, 0x721A, 0xEB23, 0xC667, 0x9CEF, 0x29FF, 0x53FE, 0xA7FC, 0x5FD9, 0x47D3, 0x8FA6, 0x0F6D, 0x1EDA, 0x3DB4, 0x7B68, 0xF6D0, 0xB861, 0x60E3, 0xC1C6, 0x93AD, 0x377B, 0x6EF6, 0xDDEC, 0x45A0, 0x8B40, 0x06A1, 0x0D42, 0x1A84, 0x3508, 0x6A10, 0xAA51, 0x4483, 0x8906, 0x022D, 0x045A, 0x08B4, 0x1168, 0x76B4, 0xED68, 0xCAF1, 0x85C3, 0x1BA7, 0x374E, 0x6E9C, 0x3730, 0x6E60, 0xDCC0, 0xA9A1, 0x4363, 0x86C6, 0x1DAD, 0x3331, 0x6662, 0xCCC4, 0x89A9, 0x0373, 0x06E6, 0x0DCC, 0x1021, 0x2042, 0x4084, 0x8108, 0x1231, 0x2462, 0x48C4];
  var Ror = function (Byte) {
    return (Byte / 2 | Byte * 128) & 0xFF;
  };
  var XorRor = function (byte1, byte2) {
    return Ror(byte1 ^ byte2);
  };
  var CreateXorKey_Method1 = function (Password) {
    var XorKey = InitialCode[Password.length - 1];
    var CurrentElement = 0x68;
    for (var i = Password.length - 1; i >= 0; --i) {
      var Char = Password[i];
      for (var j = 0; j != 7; ++j) {
        if (Char & 0x40) XorKey ^= XorMatrix[CurrentElement];
        Char *= 2;
        --CurrentElement;
      }
    }
    return XorKey;
  };
  return function (password /*:string*/) {
    var Password = _JS2ANSI(password);
    var XorKey = CreateXorKey_Method1(Password);
    var Index = Password.length;
    var ObfuscationArray = new_raw_buf(16);
    for (var i = 0; i != 16; ++i) ObfuscationArray[i] = 0x00;
    var Temp, PasswordLastChar, PadIndex;
    if ((Index & 1) === 1) {
      Temp = XorKey >> 8;
      ObfuscationArray[Index] = XorRor(PadArray[0], Temp);
      --Index;
      Temp = XorKey & 0xFF;
      PasswordLastChar = Password[Password.length - 1];
      ObfuscationArray[Index] = XorRor(PasswordLastChar, Temp);
    }
    while (Index > 0) {
      --Index;
      Temp = XorKey >> 8;
      ObfuscationArray[Index] = XorRor(Password[Index], Temp);
      --Index;
      Temp = XorKey & 0xFF;
      ObfuscationArray[Index] = XorRor(Password[Index], Temp);
    }
    Index = 15;
    PadIndex = 15 - Password.length;
    while (PadIndex > 0) {
      Temp = XorKey >> 8;
      ObfuscationArray[Index] = XorRor(PadArray[PadIndex], Temp);
      --Index;
      --PadIndex;
      Temp = XorKey & 0xFF;
      ObfuscationArray[Index] = XorRor(Password[Index], Temp);
      --Index;
      --PadIndex;
    }
    return ObfuscationArray;
  };
}();

/* [MS-OFFCRYPTO] 2.3.7.3 Binary Document XOR Data Transformation Method 1 */
var crypto_DecryptData_Method1 = function (password /*:string*/, Data, XorArrayIndex, XorArray, O) {
  /* If XorArray is set, use it; if O is not set, make changes in-place */
  if (!O) O = Data;
  if (!XorArray) XorArray = crypto_CreateXorArray_Method1(password);
  var Index, Value;
  for (Index = 0; Index != Data.length; ++Index) {
    Value = Data[Index];
    Value ^= XorArray[XorArrayIndex];
    Value = (Value >> 5 | Value << 3) & 0xFF;
    O[Index] = Value;
    ++XorArrayIndex;
  }
  return [O, XorArrayIndex, XorArray];
};
var crypto_MakeXorDecryptor = function (password /*:string*/) {
  var XorArrayIndex = 0,
    XorArray = crypto_CreateXorArray_Method1(password);
  return function (Data) {
    var O = crypto_DecryptData_Method1("", Data, XorArrayIndex, XorArray);
    XorArrayIndex = O[1];
    return O[0];
  };
};

/* 2.5.343 */
function parse_XORObfuscation(blob, length, opts, out) {
  var o = {
    key: parseuint16(blob),
    verificationBytes: parseuint16(blob)
  } /*:any*/;
  if (opts.password) o.verifier = crypto_CreatePasswordVerifier_Method1(opts.password);
  out.valid = o.verificationBytes === o.verifier;
  if (out.valid) out.insitu = crypto_MakeXorDecryptor(opts.password);
  return o;
}

/* 2.4.117 */
function parse_FilePassHeader(blob, length /*:number*/, oo) {
  var o = oo || {};
  o.Info = blob.read_shift(2);
  blob.l -= 2;
  if (o.Info === 1) o.Data = parse_RC4Header(blob, length);else o.Data = parse_RC4CryptoHeader(blob, length);
  return o;
}
function parse_FilePass(blob, length /*:number*/, opts) {
  var o = {
    Type: opts.biff >= 8 ? blob.read_shift(2) : 0
  } /*:any*/; /* wEncryptionType */
  if (o.Type) parse_FilePassHeader(blob, length - 2, o);else parse_XORObfuscation(blob, opts.biff >= 8 ? length : length - 2, opts, o);
  return o;
}
var RTF = /*#__PURE__*/function () {
  function rtf_to_sheet(d /*:RawData*/, opts) /*:Worksheet*/{
    switch (opts.type) {
      case 'base64':
        return rtf_to_sheet_str(Base64_decode(d), opts);
      case 'binary':
        return rtf_to_sheet_str(d, opts);
      case 'buffer':
        return rtf_to_sheet_str(has_buf && Buffer.isBuffer(d) ? d.toString('binary') : a2s(d), opts);
      case 'array':
        return rtf_to_sheet_str(cc2str(d), opts);
    }
    throw new Error("Unrecognized type " + opts.type);
  }

  /* TODO: this is a stub */
  function rtf_to_sheet_str(str /*:string*/, opts) /*:Worksheet*/{
    var o = opts || {};
    var ws /*:Worksheet*/ = o.dense ? [] /*:any*/ : {} /*:any*/;
    var rows = str.match(/\\trowd.*?\\row\b/g);
    if (!rows.length) throw new Error("RTF missing table");
    var range /*:Range*/ = {
      s: {
        c: 0,
        r: 0
      },
      e: {
        c: 0,
        r: rows.length - 1
      }
    } /*:any*/;
    rows.forEach(function (rowtf, R) {
      if (Array.isArray(ws)) ws[R] = [];
      var rtfre = /\\\w+\b/g;
      var last_index = 0;
      var res;
      var C = -1;
      while (res = rtfre.exec(rowtf)) {
        switch (res[0]) {
          case "\\cell":
            var data = rowtf.slice(last_index, rtfre.lastIndex - res[0].length);
            if (data[0] == " ") data = data.slice(1);
            ++C;
            if (data.length) {
              // TODO: value parsing, including codepage adjustments
              var cell = {
                v: data,
                t: "s"
              };
              if (Array.isArray(ws)) ws[R][C] = cell;else ws[encode_cell({
                r: R,
                c: C
              })] = cell;
            }
            break;
        }
        last_index = rtfre.lastIndex;
      }
      if (C > range.e.c) range.e.c = C;
    });
    ws['!ref'] = encode_range(range);
    return ws;
  }
  function rtf_to_workbook(d /*:RawData*/, opts) /*:Workbook*/{
    return sheet_to_workbook(rtf_to_sheet(d, opts), opts);
  }

  /* TODO: this is a stub */
  function sheet_to_rtf(ws /*:Worksheet*/ /*::, opts*/) /*:string*/{
    var o = ["{\\rtf1\\ansi"];
    var r = safe_decode_range(ws['!ref']),
      cell /*:Cell*/;
    var dense = Array.isArray(ws);
    for (var R = r.s.r; R <= r.e.r; ++R) {
      o.push("\\trowd\\trautofit1");
      for (var C = r.s.c; C <= r.e.c; ++C) o.push("\\cellx" + (C + 1));
      o.push("\\pard\\intbl");
      for (C = r.s.c; C <= r.e.c; ++C) {
        var coord = encode_cell({
          r: R,
          c: C
        });
        cell = dense ? (ws[R] || [])[C] : ws[coord];
        if (!cell || cell.v == null && (!cell.f || cell.F)) continue;
        o.push(" " + (cell.w || (format_cell(cell), cell.w)));
        o.push("\\cell");
      }
      o.push("\\pard\\intbl\\row");
    }
    return o.join("") + "}";
  }
  return {
    to_workbook: rtf_to_workbook,
    to_sheet: rtf_to_sheet,
    from_sheet: sheet_to_rtf
  };
}();
function hex2RGB(h) {
  var o = h.slice(h[0] === "#" ? 1 : 0).slice(0, 6);
  return [parseInt(o.slice(0, 2), 16), parseInt(o.slice(2, 4), 16), parseInt(o.slice(4, 6), 16)];
}
function rgb2Hex(rgb) {
  for (var i = 0, o = 1; i != 3; ++i) o = o * 256 + (rgb[i] > 255 ? 255 : rgb[i] < 0 ? 0 : rgb[i]);
  return o.toString(16).toUpperCase().slice(1);
}
function rgb2HSL(rgb) {
  var R = rgb[0] / 255,
    G = rgb[1] / 255,
    B = rgb[2] / 255;
  var M = Math.max(R, G, B),
    m = Math.min(R, G, B),
    C = M - m;
  if (C === 0) return [0, 0, R];
  var H6 = 0,
    S = 0,
    L2 = M + m;
  S = C / (L2 > 1 ? 2 - L2 : L2);
  switch (M) {
    case R:
      H6 = ((G - B) / C + 6) % 6;
      break;
    case G:
      H6 = (B - R) / C + 2;
      break;
    case B:
      H6 = (R - G) / C + 4;
      break;
  }
  return [H6 / 6, S, L2 / 2];
}
function hsl2RGB(hsl) {
  var H = hsl[0],
    S = hsl[1],
    L = hsl[2];
  var C = S * 2 * (L < 0.5 ? L : 1 - L),
    m = L - C / 2;
  var rgb = [m, m, m],
    h6 = 6 * H;
  var X;
  if (S !== 0) switch (h6 | 0) {
    case 0:
    case 6:
      X = C * h6;
      rgb[0] += C;
      rgb[1] += X;
      break;
    case 1:
      X = C * (2 - h6);
      rgb[0] += X;
      rgb[1] += C;
      break;
    case 2:
      X = C * (h6 - 2);
      rgb[1] += C;
      rgb[2] += X;
      break;
    case 3:
      X = C * (4 - h6);
      rgb[1] += X;
      rgb[2] += C;
      break;
    case 4:
      X = C * (h6 - 4);
      rgb[2] += C;
      rgb[0] += X;
      break;
    case 5:
      X = C * (6 - h6);
      rgb[2] += X;
      rgb[0] += C;
      break;
  }
  for (var i = 0; i != 3; ++i) rgb[i] = Math.round(rgb[i] * 255);
  return rgb;
}

/* 18.8.3 bgColor tint algorithm */
function rgb_tint(hex, tint) {
  if (tint === 0) return hex;
  var hsl = rgb2HSL(hex2RGB(hex));
  if (tint < 0) hsl[2] = hsl[2] * (1 + tint);else hsl[2] = 1 - (1 - hsl[2]) * (1 - tint);
  return rgb2Hex(hsl2RGB(hsl));
}

/* 18.3.1.13 width calculations */
/* [MS-OI29500] 2.1.595 Column Width & Formatting */
var DEF_MDW = 6,
  MAX_MDW = 15,
  MIN_MDW = 1,
  MDW = DEF_MDW;
function width2px(width) {
  return Math.floor((width + Math.round(128 / MDW) / 256) * MDW);
}
function px2char(px) {
  return Math.floor((px - 5) / MDW * 100 + 0.5) / 100;
}
function char2width(chr) {
  return Math.round((chr * MDW + 5) / MDW * 256) / 256;
}
//function px2char_(px) { return (((px - 5)/MDW * 100 + 0.5))/100; }
//function char2width_(chr) { return (((chr * MDW + 5)/MDW*256))/256; }
function cycle_width(collw) {
  return char2width(px2char(width2px(collw)));
}
/* XLSX/XLSB/XLS specify width in units of MDW */
function find_mdw_colw(collw) {
  var delta = Math.abs(collw - cycle_width(collw)),
    _MDW = MDW;
  if (delta > 0.005) for (MDW = MIN_MDW; MDW < MAX_MDW; ++MDW) if (Math.abs(collw - cycle_width(collw)) <= delta) {
    delta = Math.abs(collw - cycle_width(collw));
    _MDW = MDW;
  }
  MDW = _MDW;
}
/* XLML specifies width in terms of pixels */
/*function find_mdw_wpx(wpx) {
	var delta = Infinity, guess = 0, _MDW = MIN_MDW;
	for(MDW=MIN_MDW; MDW<MAX_MDW; ++MDW) {
		guess = char2width_(px2char_(wpx))*256;
		guess = (guess) % 1;
		if(guess > 0.5) guess--;
		if(Math.abs(guess) < delta) { delta = Math.abs(guess); _MDW = MDW; }
	}
	MDW = _MDW;
}*/

function process_col(coll /*:ColInfo*/) {
  if (coll.width) {
    coll.wpx = width2px(coll.width);
    coll.wch = px2char(coll.wpx);
    coll.MDW = MDW;
  } else if (coll.wpx) {
    coll.wch = px2char(coll.wpx);
    coll.width = char2width(coll.wch);
    coll.MDW = MDW;
  } else if (typeof coll.wch == 'number') {
    coll.width = char2width(coll.wch);
    coll.wpx = width2px(coll.width);
    coll.MDW = MDW;
  }
  if (coll.customWidth) delete coll.customWidth;
}
var DEF_PPI = 96,
  PPI = DEF_PPI;
function px2pt(px) {
  return px * 96 / PPI;
}
function pt2px(pt) {
  return pt * PPI / 96;
}

/* [MS-EXSPXML3] 2.4.54 ST_enmPattern */
var XLMLPatternTypeMap = {
  "None": "none",
  "Solid": "solid",
  "Gray50": "mediumGray",
  "Gray75": "darkGray",
  "Gray25": "lightGray",
  "HorzStripe": "darkHorizontal",
  "VertStripe": "darkVertical",
  "ReverseDiagStripe": "darkDown",
  "DiagStripe": "darkUp",
  "DiagCross": "darkGrid",
  "ThickDiagCross": "darkTrellis",
  "ThinHorzStripe": "lightHorizontal",
  "ThinVertStripe": "lightVertical",
  "ThinReverseDiagStripe": "lightDown",
  "ThinHorzCross": "lightGrid"
};

/* 18.8.5 borders CT_Borders */
function parse_borders(t, styles, themes, opts) {
  styles.Borders = [];
  var border = {};
  var pass = false;
  (t[0].match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<borders':
      case '<borders>':
      case '</borders>':
        break;

      /* 18.8.4 border CT_Border */
      case '<border':
      case '<border>':
      case '<border/>':
        border = /*::(*/{} /*:: :any)*/;
        if (y.diagonalUp) border.diagonalUp = parsexmlbool(y.diagonalUp);
        if (y.diagonalDown) border.diagonalDown = parsexmlbool(y.diagonalDown);
        styles.Borders.push(border);
        break;
      case '</border>':
        break;

      /* note: not in spec, appears to be CT_BorderPr */
      case '<left/>':
        break;
      case '<left':
      case '<left>':
        break;
      case '</left>':
        break;

      /* note: not in spec, appears to be CT_BorderPr */
      case '<right/>':
        break;
      case '<right':
      case '<right>':
        break;
      case '</right>':
        break;

      /* 18.8.43 top CT_BorderPr */
      case '<top/>':
        break;
      case '<top':
      case '<top>':
        break;
      case '</top>':
        break;

      /* 18.8.6 bottom CT_BorderPr */
      case '<bottom/>':
        break;
      case '<bottom':
      case '<bottom>':
        break;
      case '</bottom>':
        break;

      /* 18.8.13 diagonal CT_BorderPr */
      case '<diagonal':
      case '<diagonal>':
      case '<diagonal/>':
        break;
      case '</diagonal>':
        break;

      /* 18.8.25 horizontal CT_BorderPr */
      case '<horizontal':
      case '<horizontal>':
      case '<horizontal/>':
        break;
      case '</horizontal>':
        break;

      /* 18.8.44 vertical CT_BorderPr */
      case '<vertical':
      case '<vertical>':
      case '<vertical/>':
        break;
      case '</vertical>':
        break;

      /* 18.8.37 start CT_BorderPr */
      case '<start':
      case '<start>':
      case '<start/>':
        break;
      case '</start>':
        break;

      /* 18.8.16 end CT_BorderPr */
      case '<end':
      case '<end>':
      case '<end/>':
        break;
      case '</end>':
        break;

      /* 18.8.? color CT_Color */
      case '<color':
      case '<color>':
        break;
      case '<color/>':
      case '</color>':
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
        break;
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (opts && opts.WTF) {
          if (!pass) throw new Error('unrecognized ' + y[0] + ' in borders');
        }
    }
  });
}

/* 18.8.21 fills CT_Fills */
function parse_fills(t, styles, themes, opts) {
  styles.Fills = [];
  var fill = {};
  var pass = false;
  (t[0].match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<fills':
      case '<fills>':
      case '</fills>':
        break;

      /* 18.8.20 fill CT_Fill */
      case '<fill>':
      case '<fill':
      case '<fill/>':
        fill = {};
        styles.Fills.push(fill);
        break;
      case '</fill>':
        break;

      /* 18.8.24 gradientFill CT_GradientFill */
      case '<gradientFill>':
        break;
      case '<gradientFill':
      case '</gradientFill>':
        styles.Fills.push(fill);
        fill = {};
        break;

      /* 18.8.32 patternFill CT_PatternFill */
      case '<patternFill':
      case '<patternFill>':
        if (y.patternType) fill.patternType = y.patternType;
        break;
      case '<patternFill/>':
      case '</patternFill>':
        break;

      /* 18.8.3 bgColor CT_Color */
      case '<bgColor':
        if (!fill.bgColor) fill.bgColor = {};
        if (y.indexed) fill.bgColor.indexed = parseInt(y.indexed, 10);
        if (y.theme) fill.bgColor.theme = parseInt(y.theme, 10);
        if (y.tint) fill.bgColor.tint = parseFloat(y.tint);
        /* Excel uses ARGB strings */
        if (y.rgb) fill.bgColor.rgb = y.rgb.slice(-6);
        break;
      case '<bgColor/>':
      case '</bgColor>':
        break;

      /* 18.8.19 fgColor CT_Color */
      case '<fgColor':
        if (!fill.fgColor) fill.fgColor = {};
        if (y.theme) fill.fgColor.theme = parseInt(y.theme, 10);
        if (y.tint) fill.fgColor.tint = parseFloat(y.tint);
        /* Excel uses ARGB strings */
        if (y.rgb != null) fill.fgColor.rgb = y.rgb.slice(-6);
        break;
      case '<fgColor/>':
      case '</fgColor>':
        break;

      /* 18.8.38 stop CT_GradientStop */
      case '<stop':
      case '<stop/>':
        break;
      case '</stop>':
        break;

      /* 18.8.? color CT_Color */
      case '<color':
      case '<color/>':
        break;
      case '</color>':
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
        break;
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (opts && opts.WTF) {
          if (!pass) throw new Error('unrecognized ' + y[0] + ' in fills');
        }
    }
  });
}

/* 18.8.23 fonts CT_Fonts */
function parse_fonts(t, styles, themes, opts) {
  styles.Fonts = [];
  var font = {};
  var pass = false;
  (t[0].match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<fonts':
      case '<fonts>':
      case '</fonts>':
        break;

      /* 18.8.22 font CT_Font */
      case '<font':
      case '<font>':
        break;
      case '</font>':
      case '<font/>':
        styles.Fonts.push(font);
        font = {};
        break;

      /* 18.8.29 name CT_FontName */
      case '<name':
        if (y.val) font.name = utf8read(y.val);
        break;
      case '<name/>':
      case '</name>':
        break;

      /* 18.8.2  b CT_BooleanProperty */
      case '<b':
        font.bold = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<b/>':
        font.bold = 1;
        break;

      /* 18.8.26 i CT_BooleanProperty */
      case '<i':
        font.italic = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<i/>':
        font.italic = 1;
        break;

      /* 18.4.13 u CT_UnderlineProperty */
      case '<u':
        switch (y.val) {
          case "none":
            font.underline = 0x00;
            break;
          case "single":
            font.underline = 0x01;
            break;
          case "double":
            font.underline = 0x02;
            break;
          case "singleAccounting":
            font.underline = 0x21;
            break;
          case "doubleAccounting":
            font.underline = 0x22;
            break;
        }
        break;
      case '<u/>':
        font.underline = 1;
        break;

      /* 18.4.10 strike CT_BooleanProperty */
      case '<strike':
        font.strike = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<strike/>':
        font.strike = 1;
        break;

      /* 18.4.2  outline CT_BooleanProperty */
      case '<outline':
        font.outline = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<outline/>':
        font.outline = 1;
        break;

      /* 18.8.36 shadow CT_BooleanProperty */
      case '<shadow':
        font.shadow = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<shadow/>':
        font.shadow = 1;
        break;

      /* 18.8.12 condense CT_BooleanProperty */
      case '<condense':
        font.condense = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<condense/>':
        font.condense = 1;
        break;

      /* 18.8.17 extend CT_BooleanProperty */
      case '<extend':
        font.extend = y.val ? parsexmlbool(y.val) : 1;
        break;
      case '<extend/>':
        font.extend = 1;
        break;

      /* 18.4.11 sz CT_FontSize */
      case '<sz':
        if (y.val) font.sz = +y.val;
        break;
      case '<sz/>':
      case '</sz>':
        break;

      /* 18.4.14 vertAlign CT_VerticalAlignFontProperty */
      case '<vertAlign':
        if (y.val) font.vertAlign = y.val;
        break;
      case '<vertAlign/>':
      case '</vertAlign>':
        break;

      /* 18.8.18 family CT_FontFamily */
      case '<family':
        if (y.val) font.family = parseInt(y.val, 10);
        break;
      case '<family/>':
      case '</family>':
        break;

      /* 18.8.35 scheme CT_FontScheme */
      case '<scheme':
        if (y.val) font.scheme = y.val;
        break;
      case '<scheme/>':
      case '</scheme>':
        break;

      /* 18.4.1 charset CT_IntProperty */
      case '<charset':
        if (y.val == '1') break;
        y.codepage = CS2CP[parseInt(y.val, 10)];
        break;

      /* 18.?.? color CT_Color */
      case '<color':
        if (!font.color) font.color = {};
        if (y.auto) font.color.auto = parsexmlbool(y.auto);
        if (y.rgb) font.color.rgb = y.rgb.slice(-6);else if (y.indexed) {
          font.color.index = parseInt(y.indexed, 10);
          var icv = XLSIcv[font.color.index];
          if (font.color.index == 81) icv = XLSIcv[1];
          if (!icv) icv = XLSIcv[1]; //throw new Error(x); // note: 206 is valid
          font.color.rgb = icv[0].toString(16) + icv[1].toString(16) + icv[2].toString(16);
        } else if (y.theme) {
          font.color.theme = parseInt(y.theme, 10);
          if (y.tint) font.color.tint = parseFloat(y.tint);
          if (y.theme && themes.themeElements && themes.themeElements.clrScheme) {
            font.color.rgb = rgb_tint(themes.themeElements.clrScheme[font.color.theme].rgb, font.color.tint || 0);
          }
        }
        break;
      case '<color/>':
      case '</color>':
        break;

      /* note: sometimes mc:AlternateContent appears bare */
      case '<AlternateContent':
        pass = true;
        break;
      case '</AlternateContent>':
        pass = false;
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
        break;
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (opts && opts.WTF) {
          if (!pass) throw new Error('unrecognized ' + y[0] + ' in fonts');
        }
    }
  });
}

/* 18.8.31 numFmts CT_NumFmts */
function parse_numFmts(t, styles, opts) {
  styles.NumberFmt = [];
  var k /*Array<number>*/ = keys(table_fmt) /*:any*/;
  for (var i = 0; i < k.length; ++i) styles.NumberFmt[k[i]] = table_fmt[k[i]];
  var m = t[0].match(tagregex);
  if (!m) return;
  for (i = 0; i < m.length; ++i) {
    var y = parsexmltag(m[i]);
    switch (strip_ns(y[0])) {
      case '<numFmts':
      case '</numFmts>':
      case '<numFmts/>':
      case '<numFmts>':
        break;
      case '<numFmt':
        {
          var f = unescapexml(utf8read(y.formatCode)),
            j = parseInt(y.numFmtId, 10);
          styles.NumberFmt[j] = f;
          if (j > 0) {
            if (j > 0x188) {
              for (j = 0x188; j > 0x3c; --j) if (styles.NumberFmt[j] == null) break;
              styles.NumberFmt[j] = f;
            }
            SSF_load(f, j);
          }
        }
        break;
      case '</numFmt>':
        break;
      default:
        if (opts.WTF) throw new Error('unrecognized ' + y[0] + ' in numFmts');
    }
  }
}
function write_numFmts(NF /*:{[n:number|string]:string}*/ /*::, opts*/) {
  var o = ["<numFmts>"];
  [[5, 8], [23, 26], [41, 44], [/*63*/50, /*66],[164,*/392]].forEach(function (r) {
    for (var i = r[0]; i <= r[1]; ++i) if (NF[i] != null) o[o.length] = writextag('numFmt', null, {
      numFmtId: i,
      formatCode: escapexml(NF[i])
    });
  });
  if (o.length === 1) return "";
  o[o.length] = "</numFmts>";
  o[0] = writextag('numFmts', null, {
    count: o.length - 2
  }).replace("/>", ">");
  return o.join("");
}

/* 18.8.10 cellXfs CT_CellXfs */
var cellXF_uint = ["numFmtId", "fillId", "fontId", "borderId", "xfId"];
var cellXF_bool = ["applyAlignment", "applyBorder", "applyFill", "applyFont", "applyNumberFormat", "applyProtection", "pivotButton", "quotePrefix"];
function parse_cellXfs(t, styles, opts) {
  styles.CellXf = [];
  var xf;
  var pass = false;
  (t[0].match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x),
      i = 0;
    switch (strip_ns(y[0])) {
      case '<cellXfs':
      case '<cellXfs>':
      case '<cellXfs/>':
      case '</cellXfs>':
        break;

      /* 18.8.45 xf CT_Xf */
      case '<xf':
      case '<xf/>':
        xf = y;
        delete xf[0];
        for (i = 0; i < cellXF_uint.length; ++i) if (xf[cellXF_uint[i]]) xf[cellXF_uint[i]] = parseInt(xf[cellXF_uint[i]], 10);
        for (i = 0; i < cellXF_bool.length; ++i) if (xf[cellXF_bool[i]]) xf[cellXF_bool[i]] = parsexmlbool(xf[cellXF_bool[i]]);
        if (styles.NumberFmt && xf.numFmtId > 0x188) {
          for (i = 0x188; i > 0x3c; --i) if (styles.NumberFmt[xf.numFmtId] == styles.NumberFmt[i]) {
            xf.numFmtId = i;
            break;
          }
        }
        styles.CellXf.push(xf);
        break;
      case '</xf>':
        break;

      /* 18.8.1 alignment CT_CellAlignment */
      case '<alignment':
      case '<alignment/>':
        var alignment = {};
        if (y.vertical) alignment.vertical = y.vertical;
        if (y.horizontal) alignment.horizontal = y.horizontal;
        if (y.textRotation != null) alignment.textRotation = y.textRotation;
        if (y.indent) alignment.indent = y.indent;
        if (y.wrapText) alignment.wrapText = parsexmlbool(y.wrapText);
        xf.alignment = alignment;
        break;
      case '</alignment>':
        break;

      /* 18.8.33 protection CT_CellProtection */
      case '<protection':
        break;
      case '</protection>':
      case '<protection/>':
        break;

      /* note: sometimes mc:AlternateContent appears bare */
      case '<AlternateContent':
        pass = true;
        break;
      case '</AlternateContent>':
        pass = false;
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
        break;
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (opts && opts.WTF) {
          if (!pass) throw new Error('unrecognized ' + y[0] + ' in cellXfs');
        }
    }
  });
}
function write_cellXfs(cellXfs) /*:string*/{
  var o /*:Array<string>*/ = [];
  o[o.length] = writextag('cellXfs', null);
  cellXfs.forEach(function (c) {
    o[o.length] = writextag('xf', null, c);
  });
  o[o.length] = "</cellXfs>";
  if (o.length === 2) return "";
  o[0] = writextag('cellXfs', null, {
    count: o.length - 2
  }).replace("/>", ">");
  return o.join("");
}

/* 18.8 Styles CT_Stylesheet*/
var parse_sty_xml = /*#__PURE__*/function make_pstyx() {
  var numFmtRegex = /<(?:\w+:)?numFmts([^>]*)>[\S\s]*?<\/(?:\w+:)?numFmts>/;
  var cellXfRegex = /<(?:\w+:)?cellXfs([^>]*)>[\S\s]*?<\/(?:\w+:)?cellXfs>/;
  var fillsRegex = /<(?:\w+:)?fills([^>]*)>[\S\s]*?<\/(?:\w+:)?fills>/;
  var fontsRegex = /<(?:\w+:)?fonts([^>]*)>[\S\s]*?<\/(?:\w+:)?fonts>/;
  var bordersRegex = /<(?:\w+:)?borders([^>]*)>[\S\s]*?<\/(?:\w+:)?borders>/;
  return function parse_sty_xml(data, themes, opts) {
    var styles = {};
    if (!data) return styles;
    data = data.replace(/<!--([\s\S]*?)-->/mg, "").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm, "");
    /* 18.8.39 styleSheet CT_Stylesheet */
    var t;

    /* 18.8.31 numFmts CT_NumFmts ? */
    if (t = data.match(numFmtRegex)) parse_numFmts(t, styles, opts);

    /* 18.8.23 fonts CT_Fonts ? */
    if (t = data.match(fontsRegex)) parse_fonts(t, styles, themes, opts);

    /* 18.8.21 fills CT_Fills ? */
    if (t = data.match(fillsRegex)) parse_fills(t, styles, themes, opts);

    /* 18.8.5  borders CT_Borders ? */
    if (t = data.match(bordersRegex)) parse_borders(t, styles, themes, opts);

    /* 18.8.9  cellStyleXfs CT_CellStyleXfs ? */
    /* 18.8.8  cellStyles CT_CellStyles ? */

    /* 18.8.10 cellXfs CT_CellXfs ? */
    if (t = data.match(cellXfRegex)) parse_cellXfs(t, styles, opts);

    /* 18.8.15 dxfs CT_Dxfs ? */
    /* 18.8.42 tableStyles CT_TableStyles ? */
    /* 18.8.11 colors CT_Colors ? */
    /* 18.2.10 extLst CT_ExtensionList ? */

    return styles;
  };
}();
function write_sty_xml(wb /*:Workbook*/, opts) /*:string*/{
  var o = [XML_HEADER, writextag('styleSheet', null, {
      'xmlns': XMLNS_main[0],
      'xmlns:vt': XMLNS.vt
    })],
    w;
  if (wb.SSF && (w = write_numFmts(wb.SSF)) != null) o[o.length] = w;
  o[o.length] = '<fonts count="1"><font><sz val="12"/><color theme="1"/><name val="Calibri"/><family val="2"/><scheme val="minor"/></font></fonts>';
  o[o.length] = '<fills count="2"><fill><patternFill patternType="none"/></fill><fill><patternFill patternType="gray125"/></fill></fills>';
  o[o.length] = '<borders count="1"><border><left/><right/><top/><bottom/><diagonal/></border></borders>';
  o[o.length] = '<cellStyleXfs count="1"><xf numFmtId="0" fontId="0" fillId="0" borderId="0"/></cellStyleXfs>';
  if (w = write_cellXfs(opts.cellXfs)) o[o.length] = w;
  o[o.length] = '<cellStyles count="1"><cellStyle name="Normal" xfId="0" builtinId="0"/></cellStyles>';
  o[o.length] = '<dxfs count="0"/>';
  o[o.length] = '<tableStyles count="0" defaultTableStyle="TableStyleMedium9" defaultPivotStyle="PivotStyleMedium4"/>';
  if (o.length > 2) {
    o[o.length] = '</styleSheet>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* [MS-XLSB] 2.4.657 BrtFmt */
function parse_BrtFmt(data, length /*:number*/) {
  var numFmtId = data.read_shift(2);
  var stFmtCode = parse_XLWideString(data, length - 2);
  return [numFmtId, stFmtCode];
}
function write_BrtFmt(i /*:number*/, f /*:string*/, o) {
  if (!o) o = new_buf(6 + 4 * f.length);
  o.write_shift(2, i);
  write_XLWideString(f, o);
  var out = o.length > o.l ? o.slice(0, o.l) : o;
  if (o.l == null) o.l = o.length;
  return out;
}

/* [MS-XLSB] 2.4.659 BrtFont TODO */
function parse_BrtFont(data, length /*:number*/, opts) {
  var out = {} /*:any*/;
  out.sz = data.read_shift(2) / 20;
  var grbit = parse_FontFlags(data, 2, opts);
  if (grbit.fItalic) out.italic = 1;
  if (grbit.fCondense) out.condense = 1;
  if (grbit.fExtend) out.extend = 1;
  if (grbit.fShadow) out.shadow = 1;
  if (grbit.fOutline) out.outline = 1;
  if (grbit.fStrikeout) out.strike = 1;
  var bls = data.read_shift(2);
  if (bls === 0x02BC) out.bold = 1;
  switch (data.read_shift(2)) {
    /* case 0: out.vertAlign = "baseline"; break; */
    case 1:
      out.vertAlign = "superscript";
      break;
    case 2:
      out.vertAlign = "subscript";
      break;
  }
  var underline = data.read_shift(1);
  if (underline != 0) out.underline = underline;
  var family = data.read_shift(1);
  if (family > 0) out.family = family;
  var bCharSet = data.read_shift(1);
  if (bCharSet > 0) out.charset = bCharSet;
  data.l++;
  out.color = parse_BrtColor(data, 8);
  switch (data.read_shift(1)) {
    /* case 0: out.scheme = "none": break; */
    case 1:
      out.scheme = "major";
      break;
    case 2:
      out.scheme = "minor";
      break;
  }
  out.name = parse_XLWideString(data, length - 21);
  return out;
}
function write_BrtFont(font /*:any*/, o) {
  if (!o) o = new_buf(25 + 4 * 32);
  o.write_shift(2, font.sz * 20);
  write_FontFlags(font, o);
  o.write_shift(2, font.bold ? 0x02BC : 0x0190);
  var sss = 0;
  if (font.vertAlign == "superscript") sss = 1;else if (font.vertAlign == "subscript") sss = 2;
  o.write_shift(2, sss);
  o.write_shift(1, font.underline || 0);
  o.write_shift(1, font.family || 0);
  o.write_shift(1, font.charset || 0);
  o.write_shift(1, 0);
  write_BrtColor(font.color, o);
  var scheme = 0;
  if (font.scheme == "major") scheme = 1;
  if (font.scheme == "minor") scheme = 2;
  o.write_shift(1, scheme);
  write_XLWideString(font.name, o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.650 BrtFill */
var XLSBFillPTNames = ["none", "solid", "mediumGray", "darkGray", "lightGray", "darkHorizontal", "darkVertical", "darkDown", "darkUp", "darkGrid", "darkTrellis", "lightHorizontal", "lightVertical", "lightDown", "lightUp", "lightGrid", "lightTrellis", "gray125", "gray0625"];
var rev_XLSBFillPTNames /*:EvertNumType*/;
/* TODO: gradient fill representation */
var parse_BrtFill = parsenoop;
function write_BrtFill(fill, o) {
  if (!o) o = new_buf(4 * 3 + 8 * 7 + 16 * 1);
  if (!rev_XLSBFillPTNames) rev_XLSBFillPTNames = evert(XLSBFillPTNames) /*:any*/;
  var fls /*:number*/ = rev_XLSBFillPTNames[fill.patternType];
  if (fls == null) fls = 0x28;
  o.write_shift(4, fls);
  var j = 0;
  if (fls != 0x28) {
    /* TODO: custom FG Color */
    write_BrtColor({
      auto: 1
    }, o);
    /* TODO: custom BG Color */
    write_BrtColor({
      auto: 1
    }, o);
    for (; j < 12; ++j) o.write_shift(4, 0);
  } else {
    for (; j < 4; ++j) o.write_shift(4, 0);
    for (; j < 12; ++j) o.write_shift(4, 0); /* TODO */
    /* iGradientType */
    /* xnumDegree */
    /* xnumFillToLeft */
    /* xnumFillToRight */
    /* xnumFillToTop */
    /* xnumFillToBottom */
    /* cNumStop */
    /* xfillGradientStop */
  }
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.824 BrtXF */
function parse_BrtXF(data, length /*:number*/) {
  var tgt = data.l + length;
  var ixfeParent = data.read_shift(2);
  var ifmt = data.read_shift(2);
  data.l = tgt;
  return {
    ixfe: ixfeParent,
    numFmtId: ifmt
  };
}
function write_BrtXF(data, ixfeP, o) {
  if (!o) o = new_buf(16);
  o.write_shift(2, ixfeP || 0);
  o.write_shift(2, data.numFmtId || 0);
  o.write_shift(2, 0); /* iFont */
  o.write_shift(2, 0); /* iFill */
  o.write_shift(2, 0); /* ixBorder */
  o.write_shift(1, 0); /* trot */
  o.write_shift(1, 0); /* indent */
  var flow = 0;
  o.write_shift(1, flow); /* flags */
  o.write_shift(1, 0); /* flags */
  o.write_shift(1, 0); /* xfGrbitAtr */
  o.write_shift(1, 0);
  return o;
}

/* [MS-XLSB] 2.5.4 Blxf TODO */
function write_Blxf(data, o) {
  if (!o) o = new_buf(10);
  o.write_shift(1, 0); /* dg */
  o.write_shift(1, 0);
  o.write_shift(4, 0); /* color */
  o.write_shift(4, 0); /* color */
  return o;
}
/* [MS-XLSB] 2.4.302 BrtBorder TODO */
var parse_BrtBorder = parsenoop;
function write_BrtBorder(border, o) {
  if (!o) o = new_buf(51);
  o.write_shift(1, 0); /* diagonal */
  write_Blxf(null, o); /* top */
  write_Blxf(null, o); /* bottom */
  write_Blxf(null, o); /* left */
  write_Blxf(null, o); /* right */
  write_Blxf(null, o); /* diag */
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.763 BrtStyle TODO */
function write_BrtStyle(style, o) {
  if (!o) o = new_buf(12 + 4 * 10);
  o.write_shift(4, style.xfId);
  o.write_shift(2, 1);
  o.write_shift(1, +style.builtinId);
  o.write_shift(1, 0); /* iLevel */
  write_XLNullableWideString(style.name || "", o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.272 BrtBeginTableStyles */
function write_BrtBeginTableStyles(cnt, defTableStyle, defPivotStyle) {
  var o = new_buf(4 + 256 * 2 * 4);
  o.write_shift(4, cnt);
  write_XLNullableWideString(defTableStyle, o);
  write_XLNullableWideString(defPivotStyle, o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.1.7.50 Styles */
function parse_sty_bin(data, themes, opts) {
  var styles = {};
  styles.NumberFmt = [] /*:any*/;
  for (var y in table_fmt) styles.NumberFmt[y] = table_fmt[y];
  styles.CellXf = [];
  styles.Fonts = [];
  var state /*:Array<string>*/ = [];
  var pass = false;
  recordhopper(data, function hopper_sty(val, R, RT) {
    switch (RT) {
      case 0x002C:
        /* BrtFmt */
        styles.NumberFmt[val[0]] = val[1];
        SSF_load(val[1], val[0]);
        break;
      case 0x002B:
        /* BrtFont */
        styles.Fonts.push(val);
        if (val.color.theme != null && themes && themes.themeElements && themes.themeElements.clrScheme) {
          val.color.rgb = rgb_tint(themes.themeElements.clrScheme[val.color.theme].rgb, val.color.tint || 0);
        }
        break;
      case 0x0401:
        /* BrtKnownFonts */break;
      case 0x002D:
        /* BrtFill */
        break;
      case 0x002E:
        /* BrtBorder */
        break;
      case 0x002F:
        /* BrtXF */
        if (state[state.length - 1] == 0x0269 /* BrtBeginCellXFs */) {
          styles.CellXf.push(val);
        }
        break;
      case 0x0030: /* BrtStyle */
      case 0x01FB: /* BrtDXF */
      case 0x023C: /* BrtMRUColor */
      case 0x01DB:
        /* BrtIndexedColor */
        break;
      case 0x0493: /* BrtDXF14 */
      case 0x0836: /* BrtDXF15 */
      case 0x046A: /* BrtSlicerStyleElement */
      case 0x0200: /* BrtTableStyleElement */
      case 0x082F: /* BrtTimelineStyleElement */
      case 0x0C00:
        /* BrtUid */
        break;
      case 0x0023:
        /* BrtFRTBegin */
        pass = true;
        break;
      case 0x0024:
        /* BrtFRTEnd */
        pass = false;
        break;
      case 0x0025:
        /* BrtACBegin */
        state.push(RT);
        pass = true;
        break;
      case 0x0026:
        /* BrtACEnd */
        state.pop();
        pass = false;
        break;
      default:
        if (R.T > 0) state.push(RT);else if (R.T < 0) state.pop();else if (!pass || opts.WTF && state[state.length - 1] != 0x0025 /* BrtACBegin */) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  });
  return styles;
}
function write_FMTS_bin(ba, NF /*:?SSFTable*/) {
  if (!NF) return;
  var cnt = 0;
  [[5, 8], [23, 26], [41, 44], [/*63*/50, /*66],[164,*/392]].forEach(function (r) {
    /*:: if(!NF) return; */
    for (var i = r[0]; i <= r[1]; ++i) if (NF[i] != null) ++cnt;
  });
  if (cnt == 0) return;
  write_record(ba, 0x0267 /* BrtBeginFmts */, write_UInt32LE(cnt));
  [[5, 8], [23, 26], [41, 44], [/*63*/50, /*66],[164,*/392]].forEach(function (r) {
    /*:: if(!NF) return; */
    for (var i = r[0]; i <= r[1]; ++i) if (NF[i] != null) write_record(ba, 0x002C /* BrtFmt */, write_BrtFmt(i, NF[i]));
  });
  write_record(ba, 0x0268 /* BrtEndFmts */);
}
function write_FONTS_bin(ba /*::, data*/) {
  var cnt = 1;
  if (cnt == 0) return;
  write_record(ba, 0x0263 /* BrtBeginFonts */, write_UInt32LE(cnt));
  write_record(ba, 0x002B /* BrtFont */, write_BrtFont({
    sz: 12,
    color: {
      theme: 1
    },
    name: "Calibri",
    family: 2,
    scheme: "minor"
  }));
  /* 1*65491BrtFont [ACFONTS] */
  write_record(ba, 0x0264 /* BrtEndFonts */);
}
function write_FILLS_bin(ba /*::, data*/) {
  var cnt = 2;
  if (cnt == 0) return;
  write_record(ba, 0x025B /* BrtBeginFills */, write_UInt32LE(cnt));
  write_record(ba, 0x002D /* BrtFill */, write_BrtFill({
    patternType: "none"
  }));
  write_record(ba, 0x002D /* BrtFill */, write_BrtFill({
    patternType: "gray125"
  }));
  /* 1*65431BrtFill */
  write_record(ba, 0x025C /* BrtEndFills */);
}
function write_BORDERS_bin(ba /*::, data*/) {
  var cnt = 1;
  if (cnt == 0) return;
  write_record(ba, 0x0265 /* BrtBeginBorders */, write_UInt32LE(cnt));
  write_record(ba, 0x002E /* BrtBorder */, write_BrtBorder({}));
  /* 1*65430BrtBorder */
  write_record(ba, 0x0266 /* BrtEndBorders */);
}
function write_CELLSTYLEXFS_bin(ba /*::, data*/) {
  var cnt = 1;
  write_record(ba, 0x0272 /* BrtBeginCellStyleXFs */, write_UInt32LE(cnt));
  write_record(ba, 0x002F /* BrtXF */, write_BrtXF({
    numFmtId: 0,
    fontId: 0,
    fillId: 0,
    borderId: 0
  }, 0xFFFF));
  /* 1*65430(BrtXF *FRT) */
  write_record(ba, 0x0273 /* BrtEndCellStyleXFs */);
}
function write_CELLXFS_bin(ba, data) {
  write_record(ba, 0x0269 /* BrtBeginCellXFs */, write_UInt32LE(data.length));
  data.forEach(function (c) {
    write_record(ba, 0x002F /* BrtXF */, write_BrtXF(c, 0));
  });
  /* 1*65430(BrtXF *FRT) */
  write_record(ba, 0x026A /* BrtEndCellXFs */);
}
function write_STYLES_bin(ba /*::, data*/) {
  var cnt = 1;
  write_record(ba, 0x026B /* BrtBeginStyles */, write_UInt32LE(cnt));
  write_record(ba, 0x0030 /* BrtStyle */, write_BrtStyle({
    xfId: 0,
    builtinId: 0,
    name: "Normal"
  }));
  /* 1*65430(BrtStyle *FRT) */
  write_record(ba, 0x026C /* BrtEndStyles */);
}
function write_DXFS_bin(ba /*::, data*/) {
  var cnt = 0;
  write_record(ba, 0x01F9 /* BrtBeginDXFs */, write_UInt32LE(cnt));
  /* *2147483647(BrtDXF *FRT) */
  write_record(ba, 0x01FA /* BrtEndDXFs */);
}
function write_TABLESTYLES_bin(ba /*::, data*/) {
  var cnt = 0;
  write_record(ba, 0x01FC /* BrtBeginTableStyles */, write_BrtBeginTableStyles(cnt, "TableStyleMedium9", "PivotStyleMedium4"));
  /* *TABLESTYLE */
  write_record(ba, 0x01FD /* BrtEndTableStyles */);
}
function write_COLORPALETTE_bin(/*::ba, data*/
) {
  return;
  /* BrtBeginColorPalette [INDEXEDCOLORS] [MRUCOLORS] BrtEndColorPalette */
}

/* [MS-XLSB] 2.1.7.50 Styles */
function write_sty_bin(wb, opts) {
  var ba = buf_array();
  write_record(ba, 0x0116 /* BrtBeginStyleSheet */);
  write_FMTS_bin(ba, wb.SSF);
  write_FONTS_bin(ba, wb);
  write_FILLS_bin(ba, wb);
  write_BORDERS_bin(ba, wb);
  write_CELLSTYLEXFS_bin(ba, wb);
  write_CELLXFS_bin(ba, opts.cellXfs);
  write_STYLES_bin(ba, wb);
  write_DXFS_bin(ba, wb);
  write_TABLESTYLES_bin(ba, wb);
  write_COLORPALETTE_bin(ba, wb);
  /* FRTSTYLESHEET*/
  write_record(ba, 0x0117 /* BrtEndStyleSheet */);
  return ba.end();
}
/* Even though theme layout is dk1 lt1 dk2 lt2, true order is lt1 dk1 lt2 dk2 */
var XLSXThemeClrScheme = ['</a:lt1>', '</a:dk1>', '</a:lt2>', '</a:dk2>', '</a:accent1>', '</a:accent2>', '</a:accent3>', '</a:accent4>', '</a:accent5>', '</a:accent6>', '</a:hlink>', '</a:folHlink>'];
/* 20.1.6.2 clrScheme CT_ColorScheme */
function parse_clrScheme(t, themes, opts) {
  themes.themeElements.clrScheme = [];
  var color = {};
  (t[0].match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (y[0]) {
      /* 20.1.6.2 clrScheme (Color Scheme) CT_ColorScheme */
      case '<a:clrScheme':
      case '</a:clrScheme>':
        break;

      /* 20.1.2.3.32 srgbClr CT_SRgbColor */
      case '<a:srgbClr':
        color.rgb = y.val;
        break;

      /* 20.1.2.3.33 sysClr CT_SystemColor */
      case '<a:sysClr':
        color.rgb = y.lastClr;
        break;

      /* 20.1.4.1.1 accent1 (Accent 1) */
      /* 20.1.4.1.2 accent2 (Accent 2) */
      /* 20.1.4.1.3 accent3 (Accent 3) */
      /* 20.1.4.1.4 accent4 (Accent 4) */
      /* 20.1.4.1.5 accent5 (Accent 5) */
      /* 20.1.4.1.6 accent6 (Accent 6) */
      /* 20.1.4.1.9 dk1 (Dark 1) */
      /* 20.1.4.1.10 dk2 (Dark 2) */
      /* 20.1.4.1.15 folHlink (Followed Hyperlink) */
      /* 20.1.4.1.19 hlink (Hyperlink) */
      /* 20.1.4.1.22 lt1 (Light 1) */
      /* 20.1.4.1.23 lt2 (Light 2) */
      case '<a:dk1>':
      case '</a:dk1>':
      case '<a:lt1>':
      case '</a:lt1>':
      case '<a:dk2>':
      case '</a:dk2>':
      case '<a:lt2>':
      case '</a:lt2>':
      case '<a:accent1>':
      case '</a:accent1>':
      case '<a:accent2>':
      case '</a:accent2>':
      case '<a:accent3>':
      case '</a:accent3>':
      case '<a:accent4>':
      case '</a:accent4>':
      case '<a:accent5>':
      case '</a:accent5>':
      case '<a:accent6>':
      case '</a:accent6>':
      case '<a:hlink>':
      case '</a:hlink>':
      case '<a:folHlink>':
      case '</a:folHlink>':
        if (y[0].charAt(1) === '/') {
          themes.themeElements.clrScheme[XLSXThemeClrScheme.indexOf(y[0])] = color;
          color = {};
        } else {
          color.name = y[0].slice(3, y[0].length - 1);
        }
        break;
      default:
        if (opts && opts.WTF) throw new Error('Unrecognized ' + y[0] + ' in clrScheme');
    }
  });
}

/* 20.1.4.1.18 fontScheme CT_FontScheme */
function parse_fontScheme(/*::t, themes, opts*/) {}

/* 20.1.4.1.15 fmtScheme CT_StyleMatrix */
function parse_fmtScheme(/*::t, themes, opts*/) {}
var clrsregex = /<a:clrScheme([^>]*)>[\s\S]*<\/a:clrScheme>/;
var fntsregex = /<a:fontScheme([^>]*)>[\s\S]*<\/a:fontScheme>/;
var fmtsregex = /<a:fmtScheme([^>]*)>[\s\S]*<\/a:fmtScheme>/;

/* 20.1.6.10 themeElements CT_BaseStyles */
function parse_themeElements(data, themes, opts) {
  themes.themeElements = {};
  var t;
  [/* clrScheme CT_ColorScheme */
  ['clrScheme', clrsregex, parse_clrScheme], /* fontScheme CT_FontScheme */
  ['fontScheme', fntsregex, parse_fontScheme], /* fmtScheme CT_StyleMatrix */
  ['fmtScheme', fmtsregex, parse_fmtScheme]].forEach(function (m) {
    if (!(t = data.match(m[1]))) throw new Error(m[0] + ' not found in themeElements');
    m[2](t, themes, opts);
  });
}
var themeltregex = /<a:themeElements([^>]*)>[\s\S]*<\/a:themeElements>/;

/* 14.2.7 Theme Part */
function parse_theme_xml(data /*:string*/, opts) {
  /* 20.1.6.9 theme CT_OfficeStyleSheet */
  if (!data || data.length === 0) data = write_theme();
  var t;
  var themes = {};

  /* themeElements CT_BaseStyles */
  if (!(t = data.match(themeltregex))) throw new Error('themeElements not found in theme');
  parse_themeElements(t[0], themes, opts);
  themes.raw = data;
  return themes;
}
function write_theme(Themes, opts) /*:string*/{
  if (opts && opts.themeXLSX) return opts.themeXLSX;
  if (Themes && typeof Themes.raw == "string") return Themes.raw;
  var o = [XML_HEADER];
  o[o.length] = '<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">';
  o[o.length] = '<a:themeElements>';
  o[o.length] = '<a:clrScheme name="Office">';
  o[o.length] = '<a:dk1><a:sysClr val="windowText" lastClr="000000"/></a:dk1>';
  o[o.length] = '<a:lt1><a:sysClr val="window" lastClr="FFFFFF"/></a:lt1>';
  o[o.length] = '<a:dk2><a:srgbClr val="1F497D"/></a:dk2>';
  o[o.length] = '<a:lt2><a:srgbClr val="EEECE1"/></a:lt2>';
  o[o.length] = '<a:accent1><a:srgbClr val="4F81BD"/></a:accent1>';
  o[o.length] = '<a:accent2><a:srgbClr val="C0504D"/></a:accent2>';
  o[o.length] = '<a:accent3><a:srgbClr val="9BBB59"/></a:accent3>';
  o[o.length] = '<a:accent4><a:srgbClr val="8064A2"/></a:accent4>';
  o[o.length] = '<a:accent5><a:srgbClr val="4BACC6"/></a:accent5>';
  o[o.length] = '<a:accent6><a:srgbClr val="F79646"/></a:accent6>';
  o[o.length] = '<a:hlink><a:srgbClr val="0000FF"/></a:hlink>';
  o[o.length] = '<a:folHlink><a:srgbClr val="800080"/></a:folHlink>';
  o[o.length] = '</a:clrScheme>';
  o[o.length] = '<a:fontScheme name="Office">';
  o[o.length] = '<a:majorFont>';
  o[o.length] = '<a:latin typeface="Cambria"/>';
  o[o.length] = '<a:ea typeface=""/>';
  o[o.length] = '<a:cs typeface=""/>';
  o[o.length] = '<a:font script="Jpan" typeface="MS Pゴシック"/>';
  o[o.length] = '<a:font script="Hang" typeface="맑은 고딕"/>';
  o[o.length] = '<a:font script="Hans" typeface="宋体"/>';
  o[o.length] = '<a:font script="Hant" typeface="新細明體"/>';
  o[o.length] = '<a:font script="Arab" typeface="Times New Roman"/>';
  o[o.length] = '<a:font script="Hebr" typeface="Times New Roman"/>';
  o[o.length] = '<a:font script="Thai" typeface="Tahoma"/>';
  o[o.length] = '<a:font script="Ethi" typeface="Nyala"/>';
  o[o.length] = '<a:font script="Beng" typeface="Vrinda"/>';
  o[o.length] = '<a:font script="Gujr" typeface="Shruti"/>';
  o[o.length] = '<a:font script="Khmr" typeface="MoolBoran"/>';
  o[o.length] = '<a:font script="Knda" typeface="Tunga"/>';
  o[o.length] = '<a:font script="Guru" typeface="Raavi"/>';
  o[o.length] = '<a:font script="Cans" typeface="Euphemia"/>';
  o[o.length] = '<a:font script="Cher" typeface="Plantagenet Cherokee"/>';
  o[o.length] = '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>';
  o[o.length] = '<a:font script="Tibt" typeface="Microsoft Himalaya"/>';
  o[o.length] = '<a:font script="Thaa" typeface="MV Boli"/>';
  o[o.length] = '<a:font script="Deva" typeface="Mangal"/>';
  o[o.length] = '<a:font script="Telu" typeface="Gautami"/>';
  o[o.length] = '<a:font script="Taml" typeface="Latha"/>';
  o[o.length] = '<a:font script="Syrc" typeface="Estrangelo Edessa"/>';
  o[o.length] = '<a:font script="Orya" typeface="Kalinga"/>';
  o[o.length] = '<a:font script="Mlym" typeface="Kartika"/>';
  o[o.length] = '<a:font script="Laoo" typeface="DokChampa"/>';
  o[o.length] = '<a:font script="Sinh" typeface="Iskoola Pota"/>';
  o[o.length] = '<a:font script="Mong" typeface="Mongolian Baiti"/>';
  o[o.length] = '<a:font script="Viet" typeface="Times New Roman"/>';
  o[o.length] = '<a:font script="Uigh" typeface="Microsoft Uighur"/>';
  o[o.length] = '<a:font script="Geor" typeface="Sylfaen"/>';
  o[o.length] = '</a:majorFont>';
  o[o.length] = '<a:minorFont>';
  o[o.length] = '<a:latin typeface="Calibri"/>';
  o[o.length] = '<a:ea typeface=""/>';
  o[o.length] = '<a:cs typeface=""/>';
  o[o.length] = '<a:font script="Jpan" typeface="MS Pゴシック"/>';
  o[o.length] = '<a:font script="Hang" typeface="맑은 고딕"/>';
  o[o.length] = '<a:font script="Hans" typeface="宋体"/>';
  o[o.length] = '<a:font script="Hant" typeface="新細明體"/>';
  o[o.length] = '<a:font script="Arab" typeface="Arial"/>';
  o[o.length] = '<a:font script="Hebr" typeface="Arial"/>';
  o[o.length] = '<a:font script="Thai" typeface="Tahoma"/>';
  o[o.length] = '<a:font script="Ethi" typeface="Nyala"/>';
  o[o.length] = '<a:font script="Beng" typeface="Vrinda"/>';
  o[o.length] = '<a:font script="Gujr" typeface="Shruti"/>';
  o[o.length] = '<a:font script="Khmr" typeface="DaunPenh"/>';
  o[o.length] = '<a:font script="Knda" typeface="Tunga"/>';
  o[o.length] = '<a:font script="Guru" typeface="Raavi"/>';
  o[o.length] = '<a:font script="Cans" typeface="Euphemia"/>';
  o[o.length] = '<a:font script="Cher" typeface="Plantagenet Cherokee"/>';
  o[o.length] = '<a:font script="Yiii" typeface="Microsoft Yi Baiti"/>';
  o[o.length] = '<a:font script="Tibt" typeface="Microsoft Himalaya"/>';
  o[o.length] = '<a:font script="Thaa" typeface="MV Boli"/>';
  o[o.length] = '<a:font script="Deva" typeface="Mangal"/>';
  o[o.length] = '<a:font script="Telu" typeface="Gautami"/>';
  o[o.length] = '<a:font script="Taml" typeface="Latha"/>';
  o[o.length] = '<a:font script="Syrc" typeface="Estrangelo Edessa"/>';
  o[o.length] = '<a:font script="Orya" typeface="Kalinga"/>';
  o[o.length] = '<a:font script="Mlym" typeface="Kartika"/>';
  o[o.length] = '<a:font script="Laoo" typeface="DokChampa"/>';
  o[o.length] = '<a:font script="Sinh" typeface="Iskoola Pota"/>';
  o[o.length] = '<a:font script="Mong" typeface="Mongolian Baiti"/>';
  o[o.length] = '<a:font script="Viet" typeface="Arial"/>';
  o[o.length] = '<a:font script="Uigh" typeface="Microsoft Uighur"/>';
  o[o.length] = '<a:font script="Geor" typeface="Sylfaen"/>';
  o[o.length] = '</a:minorFont>';
  o[o.length] = '</a:fontScheme>';
  o[o.length] = '<a:fmtScheme name="Office">';
  o[o.length] = '<a:fillStyleLst>';
  o[o.length] = '<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>';
  o[o.length] = '<a:gradFill rotWithShape="1">';
  o[o.length] = '<a:gsLst>';
  o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="50000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="35000"><a:schemeClr val="phClr"><a:tint val="37000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="15000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
  o[o.length] = '</a:gsLst>';
  o[o.length] = '<a:lin ang="16200000" scaled="1"/>';
  o[o.length] = '</a:gradFill>';
  o[o.length] = '<a:gradFill rotWithShape="1">';
  o[o.length] = '<a:gsLst>';
  o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="100000"/><a:shade val="100000"/><a:satMod val="130000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:tint val="50000"/><a:shade val="100000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
  o[o.length] = '</a:gsLst>';
  o[o.length] = '<a:lin ang="16200000" scaled="0"/>';
  o[o.length] = '</a:gradFill>';
  o[o.length] = '</a:fillStyleLst>';
  o[o.length] = '<a:lnStyleLst>';
  o[o.length] = '<a:ln w="9525" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"><a:shade val="95000"/><a:satMod val="105000"/></a:schemeClr></a:solidFill><a:prstDash val="solid"/></a:ln>';
  o[o.length] = '<a:ln w="25400" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>';
  o[o.length] = '<a:ln w="38100" cap="flat" cmpd="sng" algn="ctr"><a:solidFill><a:schemeClr val="phClr"/></a:solidFill><a:prstDash val="solid"/></a:ln>';
  o[o.length] = '</a:lnStyleLst>';
  o[o.length] = '<a:effectStyleLst>';
  o[o.length] = '<a:effectStyle>';
  o[o.length] = '<a:effectLst>';
  o[o.length] = '<a:outerShdw blurRad="40000" dist="20000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="38000"/></a:srgbClr></a:outerShdw>';
  o[o.length] = '</a:effectLst>';
  o[o.length] = '</a:effectStyle>';
  o[o.length] = '<a:effectStyle>';
  o[o.length] = '<a:effectLst>';
  o[o.length] = '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw>';
  o[o.length] = '</a:effectLst>';
  o[o.length] = '</a:effectStyle>';
  o[o.length] = '<a:effectStyle>';
  o[o.length] = '<a:effectLst>';
  o[o.length] = '<a:outerShdw blurRad="40000" dist="23000" dir="5400000" rotWithShape="0"><a:srgbClr val="000000"><a:alpha val="35000"/></a:srgbClr></a:outerShdw>';
  o[o.length] = '</a:effectLst>';
  o[o.length] = '<a:scene3d><a:camera prst="orthographicFront"><a:rot lat="0" lon="0" rev="0"/></a:camera><a:lightRig rig="threePt" dir="t"><a:rot lat="0" lon="0" rev="1200000"/></a:lightRig></a:scene3d>';
  o[o.length] = '<a:sp3d><a:bevelT w="63500" h="25400"/></a:sp3d>';
  o[o.length] = '</a:effectStyle>';
  o[o.length] = '</a:effectStyleLst>';
  o[o.length] = '<a:bgFillStyleLst>';
  o[o.length] = '<a:solidFill><a:schemeClr val="phClr"/></a:solidFill>';
  o[o.length] = '<a:gradFill rotWithShape="1">';
  o[o.length] = '<a:gsLst>';
  o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="40000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="40000"><a:schemeClr val="phClr"><a:tint val="45000"/><a:shade val="99000"/><a:satMod val="350000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="20000"/><a:satMod val="255000"/></a:schemeClr></a:gs>';
  o[o.length] = '</a:gsLst>';
  o[o.length] = '<a:path path="circle"><a:fillToRect l="50000" t="-80000" r="50000" b="180000"/></a:path>';
  o[o.length] = '</a:gradFill>';
  o[o.length] = '<a:gradFill rotWithShape="1">';
  o[o.length] = '<a:gsLst>';
  o[o.length] = '<a:gs pos="0"><a:schemeClr val="phClr"><a:tint val="80000"/><a:satMod val="300000"/></a:schemeClr></a:gs>';
  o[o.length] = '<a:gs pos="100000"><a:schemeClr val="phClr"><a:shade val="30000"/><a:satMod val="200000"/></a:schemeClr></a:gs>';
  o[o.length] = '</a:gsLst>';
  o[o.length] = '<a:path path="circle"><a:fillToRect l="50000" t="50000" r="50000" b="50000"/></a:path>';
  o[o.length] = '</a:gradFill>';
  o[o.length] = '</a:bgFillStyleLst>';
  o[o.length] = '</a:fmtScheme>';
  o[o.length] = '</a:themeElements>';
  o[o.length] = '<a:objectDefaults>';
  o[o.length] = '<a:spDef>';
  o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="1"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="3"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="2"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="lt1"/></a:fontRef></a:style>';
  o[o.length] = '</a:spDef>';
  o[o.length] = '<a:lnDef>';
  o[o.length] = '<a:spPr/><a:bodyPr/><a:lstStyle/><a:style><a:lnRef idx="2"><a:schemeClr val="accent1"/></a:lnRef><a:fillRef idx="0"><a:schemeClr val="accent1"/></a:fillRef><a:effectRef idx="1"><a:schemeClr val="accent1"/></a:effectRef><a:fontRef idx="minor"><a:schemeClr val="tx1"/></a:fontRef></a:style>';
  o[o.length] = '</a:lnDef>';
  o[o.length] = '</a:objectDefaults>';
  o[o.length] = '<a:extraClrSchemeLst/>';
  o[o.length] = '</a:theme>';
  return o.join("");
}
/* [MS-XLS] 2.4.326 TODO: payload is a zip file */
function parse_Theme(blob, length, opts) {
  var end = blob.l + length;
  var dwThemeVersion = blob.read_shift(4);
  if (dwThemeVersion === 124226) return;
  if (!opts.cellStyles) {
    blob.l = end;
    return;
  }
  var data = blob.slice(blob.l);
  blob.l = end;
  var zip;
  try {
    zip = zip_read(data, {
      type: "array"
    });
  } catch (e) {
    return;
  }
  var themeXML = getzipstr(zip, "theme/theme/theme1.xml", true);
  if (!themeXML) return;
  return parse_theme_xml(themeXML, opts);
}

/* 2.5.49 */
function parse_ColorTheme(blob /*::, length*/) {
  return blob.read_shift(4);
}

/* 2.5.155 */
function parse_FullColorExt(blob /*::, length*/) {
  var o = {};
  o.xclrType = blob.read_shift(2);
  o.nTintShade = blob.read_shift(2);
  switch (o.xclrType) {
    case 0:
      blob.l += 4;
      break;
    case 1:
      o.xclrValue = parse_IcvXF(blob, 4);
      break;
    case 2:
      o.xclrValue = parse_LongRGBA(blob, 4);
      break;
    case 3:
      o.xclrValue = parse_ColorTheme(blob, 4);
      break;
    case 4:
      blob.l += 4;
      break;
  }
  blob.l += 8;
  return o;
}

/* 2.5.164 TODO: read 7 bits*/
function parse_IcvXF(blob, length) {
  return parsenoop(blob, length);
}

/* 2.5.280 */
function parse_XFExtGradient(blob, length) {
  return parsenoop(blob, length);
}

/* [MS-XLS] 2.5.108 */
function parse_ExtProp(blob /*::, length*/) /*:Array<any>*/{
  var extType = blob.read_shift(2);
  var cb = blob.read_shift(2) - 4;
  var o = [extType];
  switch (extType) {
    case 0x04:
    case 0x05:
    case 0x07:
    case 0x08:
    case 0x09:
    case 0x0A:
    case 0x0B:
    case 0x0D:
      o[1] = parse_FullColorExt(blob, cb);
      break;
    case 0x06:
      o[1] = parse_XFExtGradient(blob, cb);
      break;
    case 0x0E:
    case 0x0F:
      o[1] = blob.read_shift(cb === 1 ? 1 : 2);
      break;
    default:
      throw new Error("Unrecognized ExtProp type: " + extType + " " + cb);
  }
  return o;
}

/* 2.4.355 */
function parse_XFExt(blob, length) {
  var end = blob.l + length;
  blob.l += 2;
  var ixfe = blob.read_shift(2);
  blob.l += 2;
  var cexts = blob.read_shift(2);
  var ext /*:AOA*/ = [];
  while (cexts-- > 0) ext.push(parse_ExtProp(blob, end - blob.l));
  return {
    ixfe: ixfe,
    ext: ext
  };
}

/* xf is an XF, see parse_XFExt for xfext */
function update_xfext(xf, xfext) {
  xfext.forEach(function (xfe) {
    switch (xfe[0]) {
      /* 2.5.108 extPropData */
      case 0x04:
        break;
      /* foreground color */
      case 0x05:
        break;
      /* background color */
      case 0x06:
        break;
      /* gradient fill */
      case 0x07:
        break;
      /* top cell border color */
      case 0x08:
        break;
      /* bottom cell border color */
      case 0x09:
        break;
      /* left cell border color */
      case 0x0a:
        break;
      /* right cell border color */
      case 0x0b:
        break;
      /* diagonal cell border color */
      case 0x0d:
        /* text color */
        break;
      case 0x0e:
        break;
      /* font scheme */
      case 0x0f:
        break;
      /* indentation level */
    }
  });
}
function parse_BrtMdtinfo(data, length) {
  return {
    flags: data.read_shift(4),
    version: data.read_shift(4),
    name: parse_XLWideString(data, length - 8)
  };
}
function write_BrtMdtinfo(data) {
  var o = new_buf(12 + 2 * data.name.length);
  o.write_shift(4, data.flags);
  o.write_shift(4, data.version);
  write_XLWideString(data.name, o);
  return o.slice(0, o.l);
}
function parse_BrtMdb(data) {
  var out = [];
  var cnt = data.read_shift(4);
  while (cnt-- > 0) out.push([data.read_shift(4), data.read_shift(4)]);
  return out;
}
function write_BrtMdb(mdb) {
  var o = new_buf(4 + 8 * mdb.length);
  o.write_shift(4, mdb.length);
  for (var i = 0; i < mdb.length; ++i) {
    o.write_shift(4, mdb[i][0]);
    o.write_shift(4, mdb[i][1]);
  }
  return o;
}
function write_BrtBeginEsfmd(cnt, name) {
  var o = new_buf(8 + 2 * name.length);
  o.write_shift(4, cnt);
  write_XLWideString(name, o);
  return o.slice(0, o.l);
}
function parse_BrtBeginEsmdb(data) {
  data.l += 4;
  return data.read_shift(4) != 0;
}
function write_BrtBeginEsmdb(cnt, cm) {
  var o = new_buf(8);
  o.write_shift(4, cnt);
  o.write_shift(4, cm ? 1 : 0);
  return o;
}
function parse_xlmeta_bin(data, name, _opts) {
  var out = {
    Types: [],
    Cell: [],
    Value: []
  };
  var opts = _opts || {};
  var state = [];
  var pass = false;
  var metatype = 2;
  recordhopper(data, function (val, R, RT) {
    switch (RT) {
      case 335:
        out.Types.push({
          name: val.name
        });
        break;
      case 51:
        val.forEach(function (r) {
          if (metatype == 1) out.Cell.push({
            type: out.Types[r[0] - 1].name,
            index: r[1]
          });else if (metatype == 0) out.Value.push({
            type: out.Types[r[0] - 1].name,
            index: r[1]
          });
        });
        break;
      case 337:
        metatype = val ? 1 : 0;
        break;
      case 338:
        metatype = 2;
        break;
      case 35:
        state.push(RT);
        pass = true;
        break;
      case 36:
        state.pop();
        pass = false;
        break;
      default:
        if (R.T) {} else if (!pass || opts.WTF && state[state.length - 1] != 35) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  });
  return out;
}
function write_xlmeta_bin() {
  var ba = buf_array();
  write_record(ba, 332);
  write_record(ba, 334, write_UInt32LE(1));
  write_record(ba, 335, write_BrtMdtinfo({
    name: "XLDAPR",
    version: 12e4,
    flags: 3496657072
  }));
  write_record(ba, 336);
  write_record(ba, 339, write_BrtBeginEsfmd(1, "XLDAPR"));
  write_record(ba, 52);
  write_record(ba, 35, write_UInt32LE(514));
  write_record(ba, 4096, write_UInt32LE(0));
  write_record(ba, 4097, writeuint16(1));
  write_record(ba, 36);
  write_record(ba, 53);
  write_record(ba, 340);
  write_record(ba, 337, write_BrtBeginEsmdb(1, true));
  write_record(ba, 51, write_BrtMdb([[1, 0]]));
  write_record(ba, 338);
  write_record(ba, 333);
  return ba.end();
}
function parse_xlmeta_xml(data, name, opts) {
  var out = {
    Types: [],
    Cell: [],
    Value: []
  };
  if (!data) return out;
  var pass = false;
  var metatype = 2;
  var lastmeta;
  data.replace(tagregex, function (x) {
    var y = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case "<?xml":
        break;
      case "<metadata":
      case "</metadata>":
        break;
      case "<metadataTypes":
      case "</metadataTypes>":
        break;
      case "<metadataType":
        out.Types.push({
          name: y.name
        });
        break;
      case "</metadataType>":
        break;
      case "<futureMetadata":
        for (var j = 0; j < out.Types.length; ++j) if (out.Types[j].name == y.name) lastmeta = out.Types[j];
        break;
      case "</futureMetadata>":
        break;
      case "<bk>":
        break;
      case "</bk>":
        break;
      case "<rc":
        if (metatype == 1) out.Cell.push({
          type: out.Types[y.t - 1].name,
          index: +y.v
        });else if (metatype == 0) out.Value.push({
          type: out.Types[y.t - 1].name,
          index: +y.v
        });
        break;
      case "</rc>":
        break;
      case "<cellMetadata":
        metatype = 1;
        break;
      case "</cellMetadata>":
        metatype = 2;
        break;
      case "<valueMetadata":
        metatype = 0;
        break;
      case "</valueMetadata>":
        metatype = 2;
        break;
      case "<extLst":
      case "<extLst>":
      case "</extLst>":
      case "<extLst/>":
        break;
      case "<ext":
        pass = true;
        break;
      case "</ext>":
        pass = false;
        break;
      case "<rvb":
        if (!lastmeta) break;
        if (!lastmeta.offsets) lastmeta.offsets = [];
        lastmeta.offsets.push(+y.i);
        break;
      default:
        if (!pass && opts.WTF) throw new Error("unrecognized " + y[0] + " in metadata");
    }
    return x;
  });
  return out;
}
function write_xlmeta_xml() {
  var o = [XML_HEADER];
  o.push('<metadata xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:xlrd="http://schemas.microsoft.com/office/spreadsheetml/2017/richdata" xmlns:xda="http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray">\n  <metadataTypes count="1">\n    <metadataType name="XLDAPR" minSupportedVersion="120000" copy="1" pasteAll="1" pasteValues="1" merge="1" splitFirst="1" rowColShift="1" clearFormats="1" clearComments="1" assign="1" coerce="1" cellMeta="1"/>\n  </metadataTypes>\n  <futureMetadata name="XLDAPR" count="1">\n    <bk>\n      <extLst>\n        <ext uri="{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}">\n          <xda:dynamicArrayProperties fDynamic="1" fCollapsed="0"/>\n        </ext>\n      </extLst>\n    </bk>\n  </futureMetadata>\n  <cellMetadata count="1">\n    <bk>\n      <rc t="1" v="0"/>\n    </bk>\n  </cellMetadata>\n</metadata>');
  return o.join("");
}
/* 18.6 Calculation Chain */
function parse_cc_xml(data /*::, name, opts*/) /*:Array<any>*/{
  var d = [];
  if (!data) return d;
  var i = 1;
  (data.match(tagregex) || []).forEach(function (x) {
    var y = parsexmltag(x);
    switch (y[0]) {
      case '<?xml':
        break;
      /* 18.6.2  calcChain CT_CalcChain 1 */
      case '<calcChain':
      case '<calcChain>':
      case '</calcChain>':
        break;
      /* 18.6.1  c CT_CalcCell 1 */
      case '<c':
        delete y[0];
        if (y.i) i = y.i;else y.i = i;
        d.push(y);
        break;
    }
  });
  return d;
}

//function write_cc_xml(data, opts) { }

/* [MS-XLSB] 2.6.4.1 */
function parse_BrtCalcChainItem$(data) {
  var out = {};
  out.i = data.read_shift(4);
  var cell = {};
  cell.r = data.read_shift(4);
  cell.c = data.read_shift(4);
  out.r = encode_cell(cell);
  var flags = data.read_shift(1);
  if (flags & 0x2) out.l = '1';
  if (flags & 0x8) out.a = '1';
  return out;
}

/* 18.6 Calculation Chain */
function parse_cc_bin(data, name, opts) {
  var out = [];
  var pass = false;
  recordhopper(data, function hopper_cc(val, R, RT) {
    switch (RT) {
      case 0x003F:
        /* 'BrtCalcChainItem$' */
        out.push(val);
        break;
      default:
        if (R.T) {/* empty */} else if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  });
  return out;
}

//function write_cc_bin(data, opts) { }
/* 18.14 Supplementary Workbook Data */
function parse_xlink_xml(/*::data, rel, name:string, _opts*/
) {
  //var opts = _opts || {};
  //if(opts.WTF) throw "XLSX External Link";
}

/* [MS-XLSB] 2.1.7.25 External Link */
function parse_xlink_bin(data, rel, name /*:string*/, _opts) {
  if (!data) return data;
  var opts = _opts || {};
  var pass = false,
    end = false;
  recordhopper(data, function xlink_parse(val, R, RT) {
    if (end) return;
    switch (RT) {
      case 0x0167: /* 'BrtSupTabs' */
      case 0x016B: /* 'BrtExternTableStart' */
      case 0x016C: /* 'BrtExternTableEnd' */
      case 0x016E: /* 'BrtExternRowHdr' */
      case 0x016F: /* 'BrtExternCellBlank' */
      case 0x0170: /* 'BrtExternCellReal' */
      case 0x0171: /* 'BrtExternCellBool' */
      case 0x0172: /* 'BrtExternCellError' */
      case 0x0173: /* 'BrtExternCellString' */
      case 0x01D8: /* 'BrtExternValueMeta' */
      case 0x0241: /* 'BrtSupNameStart' */
      case 0x0242: /* 'BrtSupNameValueStart' */
      case 0x0243: /* 'BrtSupNameValueEnd' */
      case 0x0244: /* 'BrtSupNameNum' */
      case 0x0245: /* 'BrtSupNameErr' */
      case 0x0246: /* 'BrtSupNameSt' */
      case 0x0247: /* 'BrtSupNameNil' */
      case 0x0248: /* 'BrtSupNameBool' */
      case 0x0249: /* 'BrtSupNameFmla' */
      case 0x024A: /* 'BrtSupNameBits' */
      case 0x024B:
        /* 'BrtSupNameEnd' */
        break;
      case 0x0023:
        /* 'BrtFRTBegin' */
        pass = true;
        break;
      case 0x0024:
        /* 'BrtFRTEnd' */
        pass = false;
        break;
      default:
        if (R.T) {/* empty */} else if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  }, opts);
}
/* 20.5 DrawingML - SpreadsheetML Drawing */
/* 20.5.2.35 wsDr CT_Drawing */
function parse_drawing(data, rels /*:any*/) {
  if (!data) return "??";
  /*
    Chartsheet Drawing:
     - 20.5.2.35 wsDr CT_Drawing
      - 20.5.2.1  absoluteAnchor CT_AbsoluteAnchor
       - 20.5.2.16 graphicFrame CT_GraphicalObjectFrame
        - 20.1.2.2.16 graphic CT_GraphicalObject
         - 20.1.2.2.17 graphicData CT_GraphicalObjectData
           - chart reference
     the actual type is based on the URI of the graphicData
  	TODO: handle embedded charts and other types of graphics
  */
  var id = (data.match(/<c:chart [^>]*r:id="([^"]*)"/) || ["", ""])[1];
  return rels['!id'][id].Target;
}

/* L.5.5.2 SpreadsheetML Comments + VML Schema */
var _shapeid = 1024;
function write_comments_vml(rId /*:number*/, comments) {
  var csize = [21600, 21600];
  /* L.5.2.1.2 Path Attribute */
  var bbox = ["m0,0l0", csize[1], csize[0], csize[1], csize[0], "0xe"].join(",");
  var o = [writextag("xml", null, {
    'xmlns:v': XLMLNS.v,
    'xmlns:o': XLMLNS.o,
    'xmlns:x': XLMLNS.x,
    'xmlns:mv': XLMLNS.mv
  }).replace(/\/>/, ">"), writextag("o:shapelayout", writextag("o:idmap", null, {
    'v:ext': "edit",
    'data': rId
  }), {
    'v:ext': "edit"
  }), writextag("v:shapetype", [writextag("v:stroke", null, {
    joinstyle: "miter"
  }), writextag("v:path", null, {
    gradientshapeok: "t",
    'o:connecttype': "rect"
  })].join(""), {
    id: "_x0000_t202",
    'o:spt': 202,
    coordsize: csize.join(","),
    path: bbox
  })];
  while (_shapeid < rId * 1000) _shapeid += 1000;
  comments.forEach(function (x) {
    var c = decode_cell(x[0]);
    var fillopts = /*::(*/{
      'color2': "#BEFF82",
      'type': "gradient"
    } /*:: :any)*/;
    if (fillopts.type == "gradient") fillopts.angle = "-180";
    var fillparm = fillopts.type == "gradient" ? writextag("o:fill", null, {
      type: "gradientUnscaled",
      'v:ext': "view"
    }) : null;
    var fillxml = writextag('v:fill', fillparm, fillopts);
    var shadata = {
      on: "t",
      'obscured': "t"
    } /*:any*/;
    ++_shapeid;
    o = o.concat(['<v:shape' + wxt_helper({
      id: '_x0000_s' + _shapeid,
      type: "#_x0000_t202",
      style: "position:absolute; margin-left:80pt;margin-top:5pt;width:104pt;height:64pt;z-index:10" + (x[1].hidden ? ";visibility:hidden" : ""),
      fillcolor: "#ECFAD4",
      strokecolor: "#edeaa1"
    }) + '>', fillxml, writextag("v:shadow", null, shadata), writextag("v:path", null, {
      'o:connecttype': "none"
    }), '<v:textbox><div style="text-align:left"></div></v:textbox>', '<x:ClientData ObjectType="Note">', '<x:MoveWithCells/>', '<x:SizeWithCells/>', /* Part 4 19.4.2.3 Anchor (Anchor) */
    writetag('x:Anchor', [c.c + 1, 0, c.r + 1, 0, c.c + 3, 20, c.r + 5, 20].join(",")), writetag('x:AutoFill', "False"), writetag('x:Row', String(c.r)), writetag('x:Column', String(c.c)), x[1].hidden ? '' : '<x:Visible/>', '</x:ClientData>', '</v:shape>']);
  });
  o.push('</xml>');
  return o.join("");
}
function sheet_insert_comments(sheet, comments /*:Array<RawComment>*/, threaded /*:boolean*/, people /*:?Array<any>*/) {
  var dense = Array.isArray(sheet);
  var cell /*:Cell*/;
  comments.forEach(function (comment) {
    var r = decode_cell(comment.ref);
    if (dense) {
      if (!sheet[r.r]) sheet[r.r] = [];
      cell = sheet[r.r][r.c];
    } else cell = sheet[comment.ref];
    if (!cell) {
      cell = {
        t: "z"
      } /*:any*/;
      if (dense) sheet[r.r][r.c] = cell;else sheet[comment.ref] = cell;
      var range = safe_decode_range(sheet["!ref"] || "BDWGO1000001:A1");
      if (range.s.r > r.r) range.s.r = r.r;
      if (range.e.r < r.r) range.e.r = r.r;
      if (range.s.c > r.c) range.s.c = r.c;
      if (range.e.c < r.c) range.e.c = r.c;
      var encoded = encode_range(range);
      if (encoded !== sheet["!ref"]) sheet["!ref"] = encoded;
    }
    if (!cell.c) cell.c = [];
    var o /*:Comment*/ = {
      a: comment.author,
      t: comment.t,
      r: comment.r,
      T: threaded
    };
    if (comment.h) o.h = comment.h;

    /* threaded comments always override */
    for (var i = cell.c.length - 1; i >= 0; --i) {
      if (!threaded && cell.c[i].T) return;
      if (threaded && !cell.c[i].T) cell.c.splice(i, 1);
    }
    if (threaded && people) for (i = 0; i < people.length; ++i) {
      if (o.a == people[i].id) {
        o.a = people[i].name || o.a;
        break;
      }
    }
    cell.c.push(o);
  });
}

/* 18.7 Comments */
function parse_comments_xml(data /*:string*/, opts) /*:Array<RawComment>*/{
  /* 18.7.6 CT_Comments */
  if (data.match(/<(?:\w+:)?comments *\/>/)) return [];
  var authors /*:Array<string>*/ = [];
  var commentList /*:Array<RawComment>*/ = [];
  var authtag = data.match(/<(?:\w+:)?authors>([\s\S]*)<\/(?:\w+:)?authors>/);
  if (authtag && authtag[1]) authtag[1].split(/<\/\w*:?author>/).forEach(function (x) {
    if (x === "" || x.trim() === "") return;
    var a = x.match(/<(?:\w+:)?author[^>]*>(.*)/);
    if (a) authors.push(a[1]);
  });
  var cmnttag = data.match(/<(?:\w+:)?commentList>([\s\S]*)<\/(?:\w+:)?commentList>/);
  if (cmnttag && cmnttag[1]) cmnttag[1].split(/<\/\w*:?comment>/).forEach(function (x) {
    if (x === "" || x.trim() === "") return;
    var cm = x.match(/<(?:\w+:)?comment[^>]*>/);
    if (!cm) return;
    var y = parsexmltag(cm[0]);
    var comment /*:RawComment*/ = {
      author: y.authorId && authors[y.authorId] || "sheetjsghost",
      ref: y.ref,
      guid: y.guid
    } /*:any*/;
    var cell = decode_cell(y.ref);
    if (opts.sheetRows && opts.sheetRows <= cell.r) return;
    var textMatch = x.match(/<(?:\w+:)?text>([\s\S]*)<\/(?:\w+:)?text>/);
    var rt = !!textMatch && !!textMatch[1] && parse_si(textMatch[1]) || {
      r: "",
      t: "",
      h: ""
    };
    comment.r = rt.r;
    if (rt.r == "<t></t>") rt.t = rt.h = "";
    comment.t = (rt.t || "").replace(/\r\n/g, "\n").replace(/\r/g, "\n");
    if (opts.cellHTML) comment.h = rt.h;
    commentList.push(comment);
  });
  return commentList;
}
function write_comments_xml(data /*::, opts*/) {
  var o = [XML_HEADER, writextag('comments', null, {
    'xmlns': XMLNS_main[0]
  })];
  var iauthor /*:Array<string>*/ = [];
  o.push("<authors>");
  data.forEach(function (x) {
    x[1].forEach(function (w) {
      var a = escapexml(w.a);
      if (iauthor.indexOf(a) == -1) {
        iauthor.push(a);
        o.push("<author>" + a + "</author>");
      }
      if (w.T && w.ID && iauthor.indexOf("tc=" + w.ID) == -1) {
        iauthor.push("tc=" + w.ID);
        o.push("<author>" + "tc=" + w.ID + "</author>");
      }
    });
  });
  if (iauthor.length == 0) {
    iauthor.push("SheetJ5");
    o.push("<author>SheetJ5</author>");
  }
  o.push("</authors>");
  o.push("<commentList>");
  data.forEach(function (d) {
    /* 18.7.3 CT_Comment */
    var lastauthor = 0,
      ts = [];
    if (d[1][0] && d[1][0].T && d[1][0].ID) lastauthor = iauthor.indexOf("tc=" + d[1][0].ID);else d[1].forEach(function (c) {
      if (c.a) lastauthor = iauthor.indexOf(escapexml(c.a));
      ts.push(c.t || "");
    });
    o.push('<comment ref="' + d[0] + '" authorId="' + lastauthor + '"><text>');
    if (ts.length <= 1) o.push(writetag("t", escapexml(ts[0] || "")));else {
      /* based on Threaded Comments -> Comments projection */
      var t = "Comment:\n    " + ts[0] + "\n";
      for (var i = 1; i < ts.length; ++i) t += "Reply:\n    " + ts[i] + "\n";
      o.push(writetag("t", escapexml(t)));
    }
    o.push('</text></comment>');
  });
  o.push("</commentList>");
  if (o.length > 2) {
    o[o.length] = '</comments>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}

/* [MS-XLSX] 2.1.17 */
function parse_tcmnt_xml(data /*:string*/, opts) /*:Array<RawComment>*/{
  var out = [];
  var pass = false,
    comment = {},
    tidx = 0;
  data.replace(tagregex, function xml_tcmnt(x, idx) {
    var y /*:any*/ = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<?xml':
        break;

      /* 2.6.207 ThreadedComments CT_ThreadedComments */
      case '<ThreadedComments':
        break;
      case '</ThreadedComments>':
        break;

      /* 2.6.205 threadedComment CT_ThreadedComment */
      case '<threadedComment':
        comment = {
          author: y.personId,
          guid: y.id,
          ref: y.ref,
          T: 1
        };
        break;
      case '</threadedComment>':
        if (comment.t != null) out.push(comment);
        break;
      case '<text>':
      case '<text':
        tidx = idx + x.length;
        break;
      case '</text>':
        comment.t = data.slice(tidx, idx).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
        break;

      /* 2.6.206 mentions CT_ThreadedCommentMentions TODO */
      case '<mentions':
      case '<mentions>':
        pass = true;
        break;
      case '</mentions>':
        pass = false;
        break;

      /* 2.6.202 mention CT_Mention TODO */

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
      case '<extLst/>':
        break;
      /* 18.2.7  ext CT_Extension + */
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in threaded comments');
    }
    return x;
  });
  return out;
}
function write_tcmnt_xml(comments, people, opts) {
  var o = [XML_HEADER, writextag('ThreadedComments', null, {
    'xmlns': XMLNS.TCMNT
  }).replace(/[\/]>/, ">")];
  comments.forEach(function (carr) {
    var rootid = "";
    (carr[1] || []).forEach(function (c, idx) {
      if (!c.T) {
        delete c.ID;
        return;
      }
      if (c.a && people.indexOf(c.a) == -1) people.push(c.a);
      var tcopts = {
        ref: carr[0],
        id: "{54EE7951-7262-4200-6969-" + ("000000000000" + opts.tcid++).slice(-12) + "}"
      };
      if (idx == 0) rootid = tcopts.id;else tcopts.parentId = rootid;
      c.ID = tcopts.id;
      if (c.a) tcopts.personId = "{54EE7950-7262-4200-6969-" + ("000000000000" + people.indexOf(c.a)).slice(-12) + "}";
      o.push(writextag('threadedComment', writetag('text', c.t || ""), tcopts));
    });
  });
  o.push('</ThreadedComments>');
  return o.join("");
}

/* [MS-XLSX] 2.1.18 */
function parse_people_xml(data /*:string*/, opts) {
  var out = [];
  var pass = false;
  data.replace(tagregex, function xml_tcmnt(x) {
    var y /*:any*/ = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<?xml':
        break;

      /* 2.4.85 personList CT_PersonList */
      case '<personList':
        break;
      case '</personList>':
        break;

      /* 2.6.203 person CT_Person TODO: providers */
      case '<person':
        out.push({
          name: y.displayname,
          id: y.id
        });
        break;
      case '</person>':
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
      case '<extLst/>':
        break;
      /* 18.2.7  ext CT_Extension + */
      case '<ext':
        pass = true;
        break;
      case '</ext>':
        pass = false;
        break;
      default:
        if (!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in threaded comments');
    }
    return x;
  });
  return out;
}
function write_people_xml(people /*, opts*/) {
  var o = [XML_HEADER, writextag('personList', null, {
    'xmlns': XMLNS.TCMNT,
    'xmlns:x': XMLNS_main[0]
  }).replace(/[\/]>/, ">")];
  people.forEach(function (person, idx) {
    o.push(writextag('person', null, {
      displayName: person,
      id: "{54EE7950-7262-4200-6969-" + ("000000000000" + idx).slice(-12) + "}",
      userId: person,
      providerId: "None"
    }));
  });
  o.push("</personList>");
  return o.join("");
}
/* [MS-XLSB] 2.4.28 BrtBeginComment */
function parse_BrtBeginComment(data) {
  var out = {};
  out.iauthor = data.read_shift(4);
  var rfx = parse_UncheckedRfX(data, 16);
  out.rfx = rfx.s;
  out.ref = encode_cell(rfx.s);
  data.l += 16; /*var guid = parse_GUID(data); */
  return out;
}
function write_BrtBeginComment(data, o) {
  if (o == null) o = new_buf(36);
  o.write_shift(4, data[1].iauthor);
  write_UncheckedRfX(data[0] /*:any*/, o);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  return o;
}

/* [MS-XLSB] 2.4.327 BrtCommentAuthor */
var parse_BrtCommentAuthor = parse_XLWideString;
function write_BrtCommentAuthor(data) {
  return write_XLWideString(data.slice(0, 54));
}

/* [MS-XLSB] 2.1.7.8 Comments */
function parse_comments_bin(data, opts) /*:Array<RawComment>*/{
  var out /*:Array<RawComment>*/ = [];
  var authors /*:Array<string>*/ = [];
  var c = {};
  var pass = false;
  recordhopper(data, function hopper_cmnt(val, R, RT) {
    switch (RT) {
      case 0x0278:
        /* 'BrtCommentAuthor' */
        authors.push(val);
        break;
      case 0x027B:
        /* 'BrtBeginComment' */
        c = val;
        break;
      case 0x027D:
        /* 'BrtCommentText' */
        c.t = val.t;
        c.h = val.h;
        c.r = val.r;
        break;
      case 0x027C:
        /* 'BrtEndComment' */
        c.author = authors[c.iauthor];
        delete c /*:any*/.iauthor;
        if (opts.sheetRows && c.rfx && opts.sheetRows <= c.rfx.r) break;
        if (!c.t) c.t = "";
        delete c.rfx;
        out.push(c);
        break;
      case 0x0C00:
        /* 'BrtUid' */
        break;
      case 0x0023:
        /* 'BrtFRTBegin' */
        pass = true;
        break;
      case 0x0024:
        /* 'BrtFRTEnd' */
        pass = false;
        break;
      case 0x0025:
        /* 'BrtACBegin' */break;
      case 0x0026:
        /* 'BrtACEnd' */break;
      default:
        if (R.T) {/* empty */} else if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  });
  return out;
}
function write_comments_bin(data /*::, opts*/) {
  var ba = buf_array();
  var iauthor /*:Array<string>*/ = [];
  write_record(ba, 0x0274 /* BrtBeginComments */);
  write_record(ba, 0x0276 /* BrtBeginCommentAuthors */);
  data.forEach(function (comment) {
    comment[1].forEach(function (c) {
      if (iauthor.indexOf(c.a) > -1) return;
      iauthor.push(c.a.slice(0, 54));
      write_record(ba, 0x0278 /* BrtCommentAuthor */, write_BrtCommentAuthor(c.a));
    });
  });
  write_record(ba, 0x0277 /* BrtEndCommentAuthors */);
  write_record(ba, 0x0279 /* BrtBeginCommentList */);
  data.forEach(function (comment) {
    comment[1].forEach(function (c) {
      c.iauthor = iauthor.indexOf(c.a);
      var range = {
        s: decode_cell(comment[0]),
        e: decode_cell(comment[0])
      };
      write_record(ba, 0x027B /* BrtBeginComment */, write_BrtBeginComment([range, c]));
      if (c.t && c.t.length > 0) write_record(ba, 0x027D /* BrtCommentText */, write_BrtCommentText(c));
      write_record(ba, 0x027C /* BrtEndComment */);
      delete c.iauthor;
    });
  });
  write_record(ba, 0x027A /* BrtEndCommentList */);
  write_record(ba, 0x0275 /* BrtEndComments */);
  return ba.end();
}
var CT_VBA = "application/vnd.ms-office.vbaProject";
function make_vba_xls(cfb) {
  var newcfb = CFB.utils.cfb_new({
    root: "R"
  });
  cfb.FullPaths.forEach(function (p, i) {
    if (p.slice(-1) === "/" || !p.match(/_VBA_PROJECT_CUR/)) return;
    var newpath = p.replace(/^[^\/]*/, "R").replace(/\/_VBA_PROJECT_CUR\u0000*/, "");
    CFB.utils.cfb_add(newcfb, newpath, cfb.FileIndex[i].content);
  });
  return CFB.write(newcfb);
}
function fill_vba_xls(cfb, vba) {
  vba.FullPaths.forEach(function (p, i) {
    if (i == 0) return;
    var newpath = p.replace(/[^\/]*[\/]/, "/_VBA_PROJECT_CUR/");
    if (newpath.slice(-1) !== "/") CFB.utils.cfb_add(cfb, newpath, vba.FileIndex[i].content);
  });
}
var VBAFMTS = ["xlsb", "xlsm", "xlam", "biff8", "xla"];
/* macro and dialog sheet stubs */
function parse_ds_bin(/*::data:any, opts, idx:number, rels, wb, themes, styles*/) /*:Worksheet*/{
  return {
    '!type': 'dialog'
  };
}
function parse_ds_xml(/*::data:any, opts, idx:number, rels, wb, themes, styles*/) /*:Worksheet*/{
  return {
    '!type': 'dialog'
  };
}
function parse_ms_bin(/*::data:any, opts, idx:number, rels, wb, themes, styles*/) /*:Worksheet*/{
  return {
    '!type': 'macro'
  };
}
function parse_ms_xml(/*::data:any, opts, idx:number, rels, wb, themes, styles*/) /*:Worksheet*/{
  return {
    '!type': 'macro'
  };
}
/* TODO: it will be useful to parse the function str */
var rc_to_a1 = /*#__PURE__*/function () {
  var rcregex = /(^|[^A-Za-z_])R(\[?-?\d+\]|[1-9]\d*|)C(\[?-?\d+\]|[1-9]\d*|)(?![A-Za-z0-9_])/g;
  var rcbase /*:Cell*/ = {
    r: 0,
    c: 0
  } /*:any*/;
  function rcfunc($$, $1, $2, $3) {
    var cRel = false,
      rRel = false;
    if ($2.length == 0) rRel = true;else if ($2.charAt(0) == "[") {
      rRel = true;
      $2 = $2.slice(1, -1);
    }
    if ($3.length == 0) cRel = true;else if ($3.charAt(0) == "[") {
      cRel = true;
      $3 = $3.slice(1, -1);
    }
    var R = $2.length > 0 ? parseInt($2, 10) | 0 : 0,
      C = $3.length > 0 ? parseInt($3, 10) | 0 : 0;
    if (cRel) C += rcbase.c;else --C;
    if (rRel) R += rcbase.r;else --R;
    return $1 + (cRel ? "" : "$") + encode_col(C) + (rRel ? "" : "$") + encode_row(R);
  }
  return function rc_to_a1(fstr /*:string*/, base /*:Cell*/) /*:string*/{
    rcbase = base;
    return fstr.replace(rcregex, rcfunc);
  };
}();
var crefregex = /(^|[^._A-Z0-9])([$]?)([A-Z]{1,2}|[A-W][A-Z]{2}|X[A-E][A-Z]|XF[A-D])([$]?)(10[0-3]\d{4}|104[0-7]\d{3}|1048[0-4]\d{2}|10485[0-6]\d|104857[0-6]|[1-9]\d{0,5})(?![_.\(A-Za-z0-9])/g;
var a1_to_rc = /*#__PURE__*/function () {
  return function a1_to_rc(fstr /*:string*/, base /*:CellAddress*/) {
    return fstr.replace(crefregex, function ($0, $1, $2, $3, $4, $5) {
      var c = decode_col($3) - ($2 ? 0 : base.c);
      var r = decode_row($5) - ($4 ? 0 : base.r);
      var R = r == 0 ? "" : !$4 ? "[" + r + "]" : r + 1;
      var C = c == 0 ? "" : !$2 ? "[" + c + "]" : c + 1;
      return $1 + "R" + R + "C" + C;
    });
  };
}();

/* no defined name can collide with a valid cell address A1:XFD1048576 ... except LOG10! */
function shift_formula_str(f /*:string*/, delta /*:Cell*/) /*:string*/{
  return f.replace(crefregex, function ($0, $1, $2, $3, $4, $5) {
    return $1 + ($2 == "$" ? $2 + $3 : encode_col(decode_col($3) + delta.c)) + ($4 == "$" ? $4 + $5 : encode_row(decode_row($5) + delta.r));
  });
}
function shift_formula_xlsx(f /*:string*/, range /*:string*/, cell /*:string*/) /*:string*/{
  var r = decode_range(range),
    s = r.s,
    c = decode_cell(cell);
  var delta = {
    r: c.r - s.r,
    c: c.c - s.c
  };
  return shift_formula_str(f, delta);
}

/* TODO: parse formula */
function fuzzyfmla(f /*:string*/) /*:boolean*/{
  if (f.length == 1) return false;
  return true;
}
function _xlfn(f /*:string*/) /*:string*/{
  return f.replace(/_xlfn\./g, "");
}
function parseread1(blob) {
  blob.l += 1;
  return;
}

/* [MS-XLS] 2.5.51 */
function parse_ColRelU(blob, length) {
  var c = blob.read_shift(length == 1 ? 1 : 2);
  return [c & 0x3FFF, c >> 14 & 1, c >> 15 & 1];
}

/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.89 */
function parse_RgceArea(blob, length, opts) {
  var w = 2;
  if (opts) {
    if (opts.biff >= 2 && opts.biff <= 5) return parse_RgceArea_BIFF2(blob, length, opts);else if (opts.biff == 12) w = 4;
  }
  var r = blob.read_shift(w),
    R = blob.read_shift(w);
  var c = parse_ColRelU(blob, 2);
  var C = parse_ColRelU(blob, 2);
  return {
    s: {
      r: r,
      c: c[0],
      cRel: c[1],
      rRel: c[2]
    },
    e: {
      r: R,
      c: C[0],
      cRel: C[1],
      rRel: C[2]
    }
  };
}
/* BIFF 2-5 encodes flags in the row field */
function parse_RgceArea_BIFF2(blob /*::, length, opts*/) {
  var r = parse_ColRelU(blob, 2),
    R = parse_ColRelU(blob, 2);
  var c = blob.read_shift(1);
  var C = blob.read_shift(1);
  return {
    s: {
      r: r[0],
      c: c,
      cRel: r[1],
      rRel: r[2]
    },
    e: {
      r: R[0],
      c: C,
      cRel: R[1],
      rRel: R[2]
    }
  };
}

/* [MS-XLS] 2.5.198.105 ; [MS-XLSB] 2.5.97.90 */
function parse_RgceAreaRel(blob, length, opts) {
  if (opts.biff < 8) return parse_RgceArea_BIFF2(blob, length, opts);
  var r = blob.read_shift(opts.biff == 12 ? 4 : 2),
    R = blob.read_shift(opts.biff == 12 ? 4 : 2);
  var c = parse_ColRelU(blob, 2);
  var C = parse_ColRelU(blob, 2);
  return {
    s: {
      r: r,
      c: c[0],
      cRel: c[1],
      rRel: c[2]
    },
    e: {
      r: R,
      c: C[0],
      cRel: C[1],
      rRel: C[2]
    }
  };
}

/* [MS-XLS] 2.5.198.109 ; [MS-XLSB] 2.5.97.91 */
function parse_RgceLoc(blob, length, opts) {
  if (opts && opts.biff >= 2 && opts.biff <= 5) return parse_RgceLoc_BIFF2(blob, length, opts);
  var r = blob.read_shift(opts && opts.biff == 12 ? 4 : 2);
  var c = parse_ColRelU(blob, 2);
  return {
    r: r,
    c: c[0],
    cRel: c[1],
    rRel: c[2]
  };
}
function parse_RgceLoc_BIFF2(blob /*::, length, opts*/) {
  var r = parse_ColRelU(blob, 2);
  var c = blob.read_shift(1);
  return {
    r: r[0],
    c: c,
    cRel: r[1],
    rRel: r[2]
  };
}

/* [MS-XLS] 2.5.198.107, 2.5.47 */
function parse_RgceElfLoc(blob /*::, length, opts*/) {
  var r = blob.read_shift(2);
  var c = blob.read_shift(2);
  return {
    r: r,
    c: c & 0xFF,
    fQuoted: !!(c & 0x4000),
    cRel: c >> 15,
    rRel: c >> 15
  };
}

/* [MS-XLS] 2.5.198.111 ; [MS-XLSB] 2.5.97.92 TODO */
function parse_RgceLocRel(blob, length, opts) {
  var biff = opts && opts.biff ? opts.biff : 8;
  if (biff >= 2 && biff <= 5) return parse_RgceLocRel_BIFF2(blob, length, opts);
  var r = blob.read_shift(biff >= 12 ? 4 : 2);
  var cl = blob.read_shift(2);
  var cRel = (cl & 0x4000) >> 14,
    rRel = (cl & 0x8000) >> 15;
  cl &= 0x3FFF;
  if (rRel == 1) while (r > 0x7FFFF) r -= 0x100000;
  if (cRel == 1) while (cl > 0x1FFF) cl = cl - 0x4000;
  return {
    r: r,
    c: cl,
    cRel: cRel,
    rRel: rRel
  };
}
function parse_RgceLocRel_BIFF2(blob /*::, length:number, opts*/) {
  var rl = blob.read_shift(2);
  var c = blob.read_shift(1);
  var rRel = (rl & 0x8000) >> 15,
    cRel = (rl & 0x4000) >> 14;
  rl &= 0x3FFF;
  if (rRel == 1 && rl >= 0x2000) rl = rl - 0x4000;
  if (cRel == 1 && c >= 0x80) c = c - 0x100;
  return {
    r: rl,
    c: c,
    cRel: cRel,
    rRel: rRel
  };
}

/* [MS-XLS] 2.5.198.27 ; [MS-XLSB] 2.5.97.18 */
function parse_PtgArea(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  var area = parse_RgceArea(blob, opts.biff >= 2 && opts.biff <= 5 ? 6 : 8, opts);
  return [type, area];
}

/* [MS-XLS] 2.5.198.28 ; [MS-XLSB] 2.5.97.19 */
function parse_PtgArea3d(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  var ixti = blob.read_shift(2, 'i');
  var w = 8;
  if (opts) switch (opts.biff) {
    case 5:
      blob.l += 12;
      w = 6;
      break;
    case 12:
      w = 12;
      break;
  }
  var area = parse_RgceArea(blob, w, opts);
  return [type, ixti, area];
}

/* [MS-XLS] 2.5.198.29 ; [MS-XLSB] 2.5.97.20 */
function parse_PtgAreaErr(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  blob.l += opts && opts.biff > 8 ? 12 : opts.biff < 8 ? 6 : 8;
  return [type];
}
/* [MS-XLS] 2.5.198.30 ; [MS-XLSB] 2.5.97.21 */
function parse_PtgAreaErr3d(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  var ixti = blob.read_shift(2);
  var w = 8;
  if (opts) switch (opts.biff) {
    case 5:
      blob.l += 12;
      w = 6;
      break;
    case 12:
      w = 12;
      break;
  }
  blob.l += w;
  return [type, ixti];
}

/* [MS-XLS] 2.5.198.31 ; [MS-XLSB] 2.5.97.22 */
function parse_PtgAreaN(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  var area = parse_RgceAreaRel(blob, length - 1, opts);
  return [type, area];
}

/* [MS-XLS] 2.5.198.32 ; [MS-XLSB] 2.5.97.23 */
function parse_PtgArray(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  blob.l += opts.biff == 2 ? 6 : opts.biff == 12 ? 14 : 7;
  return [type];
}

/* [MS-XLS] 2.5.198.33 ; [MS-XLSB] 2.5.97.24 */
function parse_PtgAttrBaxcel(blob) {
  var bitSemi = blob[blob.l + 1] & 0x01; /* 1 = volatile */
  var bitBaxcel = 1;
  blob.l += 4;
  return [bitSemi, bitBaxcel];
}

/* [MS-XLS] 2.5.198.34 ; [MS-XLSB] 2.5.97.25 */
function parse_PtgAttrChoose(blob, length, opts) /*:Array<number>*/{
  blob.l += 2;
  var offset = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  var o /*:Array<number>*/ = [];
  /* offset is 1 less than the number of elements */
  for (var i = 0; i <= offset; ++i) o.push(blob.read_shift(opts && opts.biff == 2 ? 1 : 2));
  return o;
}

/* [MS-XLS] 2.5.198.35 ; [MS-XLSB] 2.5.97.26 */
function parse_PtgAttrGoto(blob, length, opts) {
  var bitGoto = blob[blob.l + 1] & 0xFF ? 1 : 0;
  blob.l += 2;
  return [bitGoto, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)];
}

/* [MS-XLS] 2.5.198.36 ; [MS-XLSB] 2.5.97.27 */
function parse_PtgAttrIf(blob, length, opts) {
  var bitIf = blob[blob.l + 1] & 0xFF ? 1 : 0;
  blob.l += 2;
  return [bitIf, blob.read_shift(opts && opts.biff == 2 ? 1 : 2)];
}

/* [MS-XLSB] 2.5.97.28 */
function parse_PtgAttrIfError(blob) {
  var bitIf = blob[blob.l + 1] & 0xFF ? 1 : 0;
  blob.l += 2;
  return [bitIf, blob.read_shift(2)];
}

/* [MS-XLS] 2.5.198.37 ; [MS-XLSB] 2.5.97.29 */
function parse_PtgAttrSemi(blob, length, opts) {
  var bitSemi = blob[blob.l + 1] & 0xFF ? 1 : 0;
  blob.l += opts && opts.biff == 2 ? 3 : 4;
  return [bitSemi];
}

/* [MS-XLS] 2.5.198.40 ; [MS-XLSB] 2.5.97.32 */
function parse_PtgAttrSpaceType(blob /*::, length*/) {
  var type = blob.read_shift(1),
    cch = blob.read_shift(1);
  return [type, cch];
}

/* [MS-XLS] 2.5.198.38 ; [MS-XLSB] 2.5.97.30 */
function parse_PtgAttrSpace(blob) {
  blob.read_shift(2);
  return parse_PtgAttrSpaceType(blob, 2);
}

/* [MS-XLS] 2.5.198.39 ; [MS-XLSB] 2.5.97.31 */
function parse_PtgAttrSpaceSemi(blob) {
  blob.read_shift(2);
  return parse_PtgAttrSpaceType(blob, 2);
}

/* [MS-XLS] 2.5.198.84 ; [MS-XLSB] 2.5.97.68 TODO */
function parse_PtgRef(blob, length, opts) {
  //var ptg = blob[blob.l] & 0x1F;
  var type = (blob[blob.l] & 0x60) >> 5;
  blob.l += 1;
  var loc = parse_RgceLoc(blob, 0, opts);
  return [type, loc];
}

/* [MS-XLS] 2.5.198.88 ; [MS-XLSB] 2.5.97.72 TODO */
function parse_PtgRefN(blob, length, opts) {
  var type = (blob[blob.l] & 0x60) >> 5;
  blob.l += 1;
  var loc = parse_RgceLocRel(blob, 0, opts);
  return [type, loc];
}

/* [MS-XLS] 2.5.198.85 ; [MS-XLSB] 2.5.97.69 TODO */
function parse_PtgRef3d(blob, length, opts) {
  var type = (blob[blob.l] & 0x60) >> 5;
  blob.l += 1;
  var ixti = blob.read_shift(2); // XtiIndex
  if (opts && opts.biff == 5) blob.l += 12;
  var loc = parse_RgceLoc(blob, 0, opts); // TODO: or RgceLocRel
  return [type, ixti, loc];
}

/* [MS-XLS] 2.5.198.62 ; [MS-XLSB] 2.5.97.45 TODO */
function parse_PtgFunc(blob, length, opts) {
  //var ptg = blob[blob.l] & 0x1F;
  var type = (blob[blob.l] & 0x60) >> 5;
  blob.l += 1;
  var iftab = blob.read_shift(opts && opts.biff <= 3 ? 1 : 2);
  return [FtabArgc[iftab], Ftab[iftab], type];
}
/* [MS-XLS] 2.5.198.63 ; [MS-XLSB] 2.5.97.46 TODO */
function parse_PtgFuncVar(blob, length, opts) {
  var type = blob[blob.l++];
  var cparams = blob.read_shift(1),
    tab = opts && opts.biff <= 3 ? [type == 0x58 ? -1 : 0, blob.read_shift(1)] : parsetab(blob);
  return [cparams, (tab[0] === 0 ? Ftab : Cetab)[tab[1]]];
}
function parsetab(blob) {
  return [blob[blob.l + 1] >> 7, blob.read_shift(2) & 0x7FFF];
}

/* [MS-XLS] 2.5.198.41 ; [MS-XLSB] 2.5.97.33 */
function parse_PtgAttrSum(blob, length, opts) {
  blob.l += opts && opts.biff == 2 ? 3 : 4;
  return;
}

/* [MS-XLS] 2.5.198.58 ; [MS-XLSB] 2.5.97.40 */
function parse_PtgExp(blob, length, opts) {
  blob.l++;
  if (opts && opts.biff == 12) return [blob.read_shift(4, 'i'), 0];
  var row = blob.read_shift(2);
  var col = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  return [row, col];
}

/* [MS-XLS] 2.5.198.57 ; [MS-XLSB] 2.5.97.39 */
function parse_PtgErr(blob) {
  blob.l++;
  return BErr[blob.read_shift(1)];
}

/* [MS-XLS] 2.5.198.66 ; [MS-XLSB] 2.5.97.49 */
function parse_PtgInt(blob) {
  blob.l++;
  return blob.read_shift(2);
}

/* [MS-XLS] 2.5.198.42 ; [MS-XLSB] 2.5.97.34 */
function parse_PtgBool(blob) {
  blob.l++;
  return blob.read_shift(1) !== 0;
}

/* [MS-XLS] 2.5.198.79 ; [MS-XLSB] 2.5.97.63 */
function parse_PtgNum(blob) {
  blob.l++;
  return parse_Xnum(blob, 8);
}

/* [MS-XLS] 2.5.198.89 ; [MS-XLSB] 2.5.97.74 */
function parse_PtgStr(blob, length, opts) {
  blob.l++;
  return parse_ShortXLUnicodeString(blob, length - 1, opts);
}

/* [MS-XLS] 2.5.192.112 + 2.5.192.11{3,4,5,6,7} */
/* [MS-XLSB] 2.5.97.93 + 2.5.97.9{4,5,6,7} */
function parse_SerAr(blob, biff /*:number*/) {
  var val = [blob.read_shift(1)];
  if (biff == 12) switch (val[0]) {
    case 0x02:
      val[0] = 0x04;
      break;
    /* SerBool */
    case 0x04:
      val[0] = 0x10;
      break;
    /* SerErr */
    case 0x00:
      val[0] = 0x01;
      break;
    /* SerNum */
    case 0x01:
      val[0] = 0x02;
      break;
    /* SerStr */
  }
  switch (val[0]) {
    case 0x04:
      /* SerBool -- boolean */
      val[1] = parsebool(blob, 1) ? 'TRUE' : 'FALSE';
      if (biff != 12) blob.l += 7;
      break;
    case 0x25: /* appears to be an alias */
    case 0x10:
      /* SerErr -- error */
      val[1] = BErr[blob[blob.l]];
      blob.l += biff == 12 ? 4 : 8;
      break;
    case 0x00:
      /* SerNil -- honestly, I'm not sure how to reproduce this */
      blob.l += 8;
      break;
    case 0x01:
      /* SerNum -- Xnum */
      val[1] = parse_Xnum(blob, 8);
      break;
    case 0x02:
      /* SerStr -- XLUnicodeString (<256 chars) */
      val[1] = parse_XLUnicodeString2(blob, 0, {
        biff: biff > 0 && biff < 8 ? 2 : biff
      });
      break;
    default:
      throw new Error("Bad SerAr: " + val[0]);
    /* Unreachable */
  }
  return val;
}

/* [MS-XLS] 2.5.198.61 ; [MS-XLSB] 2.5.97.44 */
function parse_PtgExtraMem(blob, cce, opts) {
  var count = blob.read_shift(opts.biff == 12 ? 4 : 2);
  var out /*:Array<Range>*/ = [];
  for (var i = 0; i != count; ++i) out.push((opts.biff == 12 ? parse_UncheckedRfX : parse_Ref8U)(blob, 8));
  return out;
}

/* [MS-XLS] 2.5.198.59 ; [MS-XLSB] 2.5.97.41 */
function parse_PtgExtraArray(blob, length, opts) {
  var rows = 0,
    cols = 0;
  if (opts.biff == 12) {
    rows = blob.read_shift(4); // DRw
    cols = blob.read_shift(4); // DCol
  } else {
    cols = 1 + blob.read_shift(1); //DColByteU
    rows = 1 + blob.read_shift(2); //DRw
  }
  if (opts.biff >= 2 && opts.biff < 8) {
    --rows;
    if (--cols == 0) cols = 0x100;
  }
  // $FlowIgnore
  for (var i = 0, o /*:Array<Array<any>>*/ = []; i != rows && (o[i] = []); ++i) for (var j = 0; j != cols; ++j) o[i][j] = parse_SerAr(blob, opts.biff);
  return o;
}

/* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 */
function parse_PtgName(blob, length, opts) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var w = !opts || opts.biff >= 8 ? 4 : 2;
  var nameindex = blob.read_shift(w);
  switch (opts.biff) {
    case 2:
      blob.l += 5;
      break;
    case 3:
    case 4:
      blob.l += 8;
      break;
    case 5:
      blob.l += 12;
      break;
  }
  return [type, 0, nameindex];
}

/* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 */
function parse_PtgNameX(blob, length, opts) {
  if (opts.biff == 5) return parse_PtgNameX_BIFF5(blob, length, opts);
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var ixti = blob.read_shift(2); // XtiIndex
  var nameindex = blob.read_shift(4);
  return [type, ixti, nameindex];
}
function parse_PtgNameX_BIFF5(blob /*::, length, opts*/) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var ixti = blob.read_shift(2, 'i'); // XtiIndex
  blob.l += 8;
  var nameindex = blob.read_shift(2);
  blob.l += 12;
  return [type, ixti, nameindex];
}

/* [MS-XLS] 2.5.198.70 ; [MS-XLSB] 2.5.97.54 */
function parse_PtgMemArea(blob, length, opts) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  blob.l += opts && opts.biff == 2 ? 3 : 4;
  var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  return [type, cce];
}

/* [MS-XLS] 2.5.198.72 ; [MS-XLSB] 2.5.97.56 */
function parse_PtgMemFunc(blob, length, opts) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var cce = blob.read_shift(opts && opts.biff == 2 ? 1 : 2);
  return [type, cce];
}

/* [MS-XLS] 2.5.198.86 ; [MS-XLSB] 2.5.97.69 */
function parse_PtgRefErr(blob, length, opts) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  blob.l += 4;
  if (opts.biff < 8) blob.l--;
  if (opts.biff == 12) blob.l += 2;
  return [type];
}

/* [MS-XLS] 2.5.198.87 ; [MS-XLSB] 2.5.97.71 */
function parse_PtgRefErr3d(blob, length, opts) {
  var type = (blob[blob.l++] & 0x60) >> 5;
  var ixti = blob.read_shift(2);
  var w = 4;
  if (opts) switch (opts.biff) {
    case 5:
      w = 15;
      break;
    case 12:
      w = 6;
      break;
  }
  blob.l += w;
  return [type, ixti];
}

/* [MS-XLS] 2.5.198.71 ; [MS-XLSB] 2.5.97.55 */
var parse_PtgMemErr = parsenoop;
/* [MS-XLS] 2.5.198.73  ; [MS-XLSB] 2.5.97.57 */
var parse_PtgMemNoMem = parsenoop;
/* [MS-XLS] 2.5.198.92 */
var parse_PtgTbl = parsenoop;
function parse_PtgElfLoc(blob, length, opts) {
  blob.l += 2;
  return [parse_RgceElfLoc(blob, 4, opts)];
}
function parse_PtgElfNoop(blob /*::, length, opts*/) {
  blob.l += 6;
  return [];
}
/* [MS-XLS] 2.5.198.46 */
var parse_PtgElfCol = parse_PtgElfLoc;
/* [MS-XLS] 2.5.198.47 */
var parse_PtgElfColS = parse_PtgElfNoop;
/* [MS-XLS] 2.5.198.48 */
var parse_PtgElfColSV = parse_PtgElfNoop;
/* [MS-XLS] 2.5.198.49 */
var parse_PtgElfColV = parse_PtgElfLoc;
/* [MS-XLS] 2.5.198.50 */
function parse_PtgElfLel(blob /*::, length, opts*/) {
  blob.l += 2;
  return [parseuint16(blob), blob.read_shift(2) & 0x01];
}
/* [MS-XLS] 2.5.198.51 */
var parse_PtgElfRadical = parse_PtgElfLoc;
/* [MS-XLS] 2.5.198.52 */
var parse_PtgElfRadicalLel = parse_PtgElfLel;
/* [MS-XLS] 2.5.198.53 */
var parse_PtgElfRadicalS = parse_PtgElfNoop;
/* [MS-XLS] 2.5.198.54 */
var parse_PtgElfRw = parse_PtgElfLoc;
/* [MS-XLS] 2.5.198.55 */
var parse_PtgElfRwV = parse_PtgElfLoc;

/* [MS-XLSB] 2.5.97.52 TODO */
var PtgListRT = ["Data", "All", "Headers", "??", "?Data2", "??", "?DataHeaders", "??", "Totals", "??", "??", "??", "?DataTotals", "??", "??", "??", "?Current"];
function parse_PtgList(blob /*::, length, opts*/) {
  blob.l += 2;
  var ixti = blob.read_shift(2);
  var flags = blob.read_shift(2);
  var idx = blob.read_shift(4);
  var c = blob.read_shift(2);
  var C = blob.read_shift(2);
  var rt = PtgListRT[flags >> 2 & 0x1F];
  return {
    ixti: ixti,
    coltype: flags & 0x3,
    rt: rt,
    idx: idx,
    c: c,
    C: C
  };
}
/* [MS-XLS] 2.5.198.91 ; [MS-XLSB] 2.5.97.76 */
function parse_PtgSxName(blob /*::, length, opts*/) {
  blob.l += 2;
  return [blob.read_shift(4)];
}

/* [XLS] old spec */
function parse_PtgSheet(blob, length, opts) {
  blob.l += 5;
  blob.l += 2;
  blob.l += opts.biff == 2 ? 1 : 4;
  return ["PTGSHEET"];
}
function parse_PtgEndSheet(blob, length, opts) {
  blob.l += opts.biff == 2 ? 4 : 5;
  return ["PTGENDSHEET"];
}
function parse_PtgMemAreaN(blob /*::, length, opts*/) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var cce = blob.read_shift(2);
  return [type, cce];
}
function parse_PtgMemNoMemN(blob /*::, length, opts*/) {
  var type = blob.read_shift(1) >>> 5 & 0x03;
  var cce = blob.read_shift(2);
  return [type, cce];
}
function parse_PtgAttrNoop(blob /*::, length, opts*/) {
  blob.l += 4;
  return [0, 0];
}

/* [MS-XLS] 2.5.198.25 ; [MS-XLSB] 2.5.97.16 */
var PtgTypes = {
  /*::[*/0x01 /*::]*/: {
    n: 'PtgExp',
    f: parse_PtgExp
  },
  /*::[*/0x02 /*::]*/: {
    n: 'PtgTbl',
    f: parse_PtgTbl
  },
  /*::[*/0x03 /*::]*/: {
    n: 'PtgAdd',
    f: parseread1
  },
  /*::[*/0x04 /*::]*/: {
    n: 'PtgSub',
    f: parseread1
  },
  /*::[*/0x05 /*::]*/: {
    n: 'PtgMul',
    f: parseread1
  },
  /*::[*/0x06 /*::]*/: {
    n: 'PtgDiv',
    f: parseread1
  },
  /*::[*/0x07 /*::]*/: {
    n: 'PtgPower',
    f: parseread1
  },
  /*::[*/0x08 /*::]*/: {
    n: 'PtgConcat',
    f: parseread1
  },
  /*::[*/0x09 /*::]*/: {
    n: 'PtgLt',
    f: parseread1
  },
  /*::[*/0x0A /*::]*/: {
    n: 'PtgLe',
    f: parseread1
  },
  /*::[*/0x0B /*::]*/: {
    n: 'PtgEq',
    f: parseread1
  },
  /*::[*/0x0C /*::]*/: {
    n: 'PtgGe',
    f: parseread1
  },
  /*::[*/0x0D /*::]*/: {
    n: 'PtgGt',
    f: parseread1
  },
  /*::[*/0x0E /*::]*/: {
    n: 'PtgNe',
    f: parseread1
  },
  /*::[*/0x0F /*::]*/: {
    n: 'PtgIsect',
    f: parseread1
  },
  /*::[*/0x10 /*::]*/: {
    n: 'PtgUnion',
    f: parseread1
  },
  /*::[*/0x11 /*::]*/: {
    n: 'PtgRange',
    f: parseread1
  },
  /*::[*/0x12 /*::]*/: {
    n: 'PtgUplus',
    f: parseread1
  },
  /*::[*/0x13 /*::]*/: {
    n: 'PtgUminus',
    f: parseread1
  },
  /*::[*/0x14 /*::]*/: {
    n: 'PtgPercent',
    f: parseread1
  },
  /*::[*/0x15 /*::]*/: {
    n: 'PtgParen',
    f: parseread1
  },
  /*::[*/0x16 /*::]*/: {
    n: 'PtgMissArg',
    f: parseread1
  },
  /*::[*/0x17 /*::]*/: {
    n: 'PtgStr',
    f: parse_PtgStr
  },
  /*::[*/0x1A /*::]*/: {
    n: 'PtgSheet',
    f: parse_PtgSheet
  },
  /*::[*/0x1B /*::]*/: {
    n: 'PtgEndSheet',
    f: parse_PtgEndSheet
  },
  /*::[*/0x1C /*::]*/: {
    n: 'PtgErr',
    f: parse_PtgErr
  },
  /*::[*/0x1D /*::]*/: {
    n: 'PtgBool',
    f: parse_PtgBool
  },
  /*::[*/0x1E /*::]*/: {
    n: 'PtgInt',
    f: parse_PtgInt
  },
  /*::[*/0x1F /*::]*/: {
    n: 'PtgNum',
    f: parse_PtgNum
  },
  /*::[*/0x20 /*::]*/: {
    n: 'PtgArray',
    f: parse_PtgArray
  },
  /*::[*/0x21 /*::]*/: {
    n: 'PtgFunc',
    f: parse_PtgFunc
  },
  /*::[*/0x22 /*::]*/: {
    n: 'PtgFuncVar',
    f: parse_PtgFuncVar
  },
  /*::[*/0x23 /*::]*/: {
    n: 'PtgName',
    f: parse_PtgName
  },
  /*::[*/0x24 /*::]*/: {
    n: 'PtgRef',
    f: parse_PtgRef
  },
  /*::[*/0x25 /*::]*/: {
    n: 'PtgArea',
    f: parse_PtgArea
  },
  /*::[*/0x26 /*::]*/: {
    n: 'PtgMemArea',
    f: parse_PtgMemArea
  },
  /*::[*/0x27 /*::]*/: {
    n: 'PtgMemErr',
    f: parse_PtgMemErr
  },
  /*::[*/0x28 /*::]*/: {
    n: 'PtgMemNoMem',
    f: parse_PtgMemNoMem
  },
  /*::[*/0x29 /*::]*/: {
    n: 'PtgMemFunc',
    f: parse_PtgMemFunc
  },
  /*::[*/0x2A /*::]*/: {
    n: 'PtgRefErr',
    f: parse_PtgRefErr
  },
  /*::[*/0x2B /*::]*/: {
    n: 'PtgAreaErr',
    f: parse_PtgAreaErr
  },
  /*::[*/0x2C /*::]*/: {
    n: 'PtgRefN',
    f: parse_PtgRefN
  },
  /*::[*/0x2D /*::]*/: {
    n: 'PtgAreaN',
    f: parse_PtgAreaN
  },
  /*::[*/0x2E /*::]*/: {
    n: 'PtgMemAreaN',
    f: parse_PtgMemAreaN
  },
  /*::[*/0x2F /*::]*/: {
    n: 'PtgMemNoMemN',
    f: parse_PtgMemNoMemN
  },
  /*::[*/0x39 /*::]*/: {
    n: 'PtgNameX',
    f: parse_PtgNameX
  },
  /*::[*/0x3A /*::]*/: {
    n: 'PtgRef3d',
    f: parse_PtgRef3d
  },
  /*::[*/0x3B /*::]*/: {
    n: 'PtgArea3d',
    f: parse_PtgArea3d
  },
  /*::[*/0x3C /*::]*/: {
    n: 'PtgRefErr3d',
    f: parse_PtgRefErr3d
  },
  /*::[*/0x3D /*::]*/: {
    n: 'PtgAreaErr3d',
    f: parse_PtgAreaErr3d
  },
  /*::[*/0xFF /*::]*/: {}
};
/* These are duplicated in the PtgTypes table */
var PtgDupes = {
  /*::[*/0x40 /*::]*/: 0x20,
  /*::[*/0x60 /*::]*/: 0x20,
  /*::[*/0x41 /*::]*/: 0x21,
  /*::[*/0x61 /*::]*/: 0x21,
  /*::[*/0x42 /*::]*/: 0x22,
  /*::[*/0x62 /*::]*/: 0x22,
  /*::[*/0x43 /*::]*/: 0x23,
  /*::[*/0x63 /*::]*/: 0x23,
  /*::[*/0x44 /*::]*/: 0x24,
  /*::[*/0x64 /*::]*/: 0x24,
  /*::[*/0x45 /*::]*/: 0x25,
  /*::[*/0x65 /*::]*/: 0x25,
  /*::[*/0x46 /*::]*/: 0x26,
  /*::[*/0x66 /*::]*/: 0x26,
  /*::[*/0x47 /*::]*/: 0x27,
  /*::[*/0x67 /*::]*/: 0x27,
  /*::[*/0x48 /*::]*/: 0x28,
  /*::[*/0x68 /*::]*/: 0x28,
  /*::[*/0x49 /*::]*/: 0x29,
  /*::[*/0x69 /*::]*/: 0x29,
  /*::[*/0x4A /*::]*/: 0x2A,
  /*::[*/0x6A /*::]*/: 0x2A,
  /*::[*/0x4B /*::]*/: 0x2B,
  /*::[*/0x6B /*::]*/: 0x2B,
  /*::[*/0x4C /*::]*/: 0x2C,
  /*::[*/0x6C /*::]*/: 0x2C,
  /*::[*/0x4D /*::]*/: 0x2D,
  /*::[*/0x6D /*::]*/: 0x2D,
  /*::[*/0x4E /*::]*/: 0x2E,
  /*::[*/0x6E /*::]*/: 0x2E,
  /*::[*/0x4F /*::]*/: 0x2F,
  /*::[*/0x6F /*::]*/: 0x2F,
  /*::[*/0x58 /*::]*/: 0x22,
  /*::[*/0x78 /*::]*/: 0x22,
  /*::[*/0x59 /*::]*/: 0x39,
  /*::[*/0x79 /*::]*/: 0x39,
  /*::[*/0x5A /*::]*/: 0x3A,
  /*::[*/0x7A /*::]*/: 0x3A,
  /*::[*/0x5B /*::]*/: 0x3B,
  /*::[*/0x7B /*::]*/: 0x3B,
  /*::[*/0x5C /*::]*/: 0x3C,
  /*::[*/0x7C /*::]*/: 0x3C,
  /*::[*/0x5D /*::]*/: 0x3D,
  /*::[*/0x7D /*::]*/: 0x3D
};
var Ptg18 = {
  /*::[*/0x01 /*::]*/: {
    n: 'PtgElfLel',
    f: parse_PtgElfLel
  },
  /*::[*/0x02 /*::]*/: {
    n: 'PtgElfRw',
    f: parse_PtgElfRw
  },
  /*::[*/0x03 /*::]*/: {
    n: 'PtgElfCol',
    f: parse_PtgElfCol
  },
  /*::[*/0x06 /*::]*/: {
    n: 'PtgElfRwV',
    f: parse_PtgElfRwV
  },
  /*::[*/0x07 /*::]*/: {
    n: 'PtgElfColV',
    f: parse_PtgElfColV
  },
  /*::[*/0x0A /*::]*/: {
    n: 'PtgElfRadical',
    f: parse_PtgElfRadical
  },
  /*::[*/0x0B /*::]*/: {
    n: 'PtgElfRadicalS',
    f: parse_PtgElfRadicalS
  },
  /*::[*/0x0D /*::]*/: {
    n: 'PtgElfColS',
    f: parse_PtgElfColS
  },
  /*::[*/0x0F /*::]*/: {
    n: 'PtgElfColSV',
    f: parse_PtgElfColSV
  },
  /*::[*/0x10 /*::]*/: {
    n: 'PtgElfRadicalLel',
    f: parse_PtgElfRadicalLel
  },
  /*::[*/0x19 /*::]*/: {
    n: 'PtgList',
    f: parse_PtgList
  },
  /*::[*/0x1D /*::]*/: {
    n: 'PtgSxName',
    f: parse_PtgSxName
  },
  /*::[*/0xFF /*::]*/: {}
};
var Ptg19 = {
  /*::[*/0x00 /*::]*/: {
    n: 'PtgAttrNoop',
    f: parse_PtgAttrNoop
  },
  /*::[*/0x01 /*::]*/: {
    n: 'PtgAttrSemi',
    f: parse_PtgAttrSemi
  },
  /*::[*/0x02 /*::]*/: {
    n: 'PtgAttrIf',
    f: parse_PtgAttrIf
  },
  /*::[*/0x04 /*::]*/: {
    n: 'PtgAttrChoose',
    f: parse_PtgAttrChoose
  },
  /*::[*/0x08 /*::]*/: {
    n: 'PtgAttrGoto',
    f: parse_PtgAttrGoto
  },
  /*::[*/0x10 /*::]*/: {
    n: 'PtgAttrSum',
    f: parse_PtgAttrSum
  },
  /*::[*/0x20 /*::]*/: {
    n: 'PtgAttrBaxcel',
    f: parse_PtgAttrBaxcel
  },
  /*::[*/0x21 /*::]*/: {
    n: 'PtgAttrBaxcel',
    f: parse_PtgAttrBaxcel
  },
  /*::[*/0x40 /*::]*/: {
    n: 'PtgAttrSpace',
    f: parse_PtgAttrSpace
  },
  /*::[*/0x41 /*::]*/: {
    n: 'PtgAttrSpaceSemi',
    f: parse_PtgAttrSpaceSemi
  },
  /*::[*/0x80 /*::]*/: {
    n: 'PtgAttrIfError',
    f: parse_PtgAttrIfError
  },
  /*::[*/0xFF /*::]*/: {}
};

/* [MS-XLS] 2.5.198.103 ; [MS-XLSB] 2.5.97.87 */
function parse_RgbExtra(blob, length, rgce, opts) {
  if (opts.biff < 8) return parsenoop(blob, length);
  var target = blob.l + length;
  var o = [];
  for (var i = 0; i !== rgce.length; ++i) {
    switch (rgce[i][0]) {
      case 'PtgArray':
        /* PtgArray -> PtgExtraArray */
        rgce[i][1] = parse_PtgExtraArray(blob, 0, opts);
        o.push(rgce[i][1]);
        break;
      case 'PtgMemArea':
        /* PtgMemArea -> PtgExtraMem */
        rgce[i][2] = parse_PtgExtraMem(blob, rgce[i][1], opts);
        o.push(rgce[i][2]);
        break;
      case 'PtgExp':
        /* PtgExp -> PtgExtraCol */
        if (opts && opts.biff == 12) {
          rgce[i][1][1] = blob.read_shift(4);
          o.push(rgce[i][1]);
        }
        break;
      case 'PtgList': /* TODO: PtgList -> PtgExtraList */
      case 'PtgElfRadicalS': /* TODO: PtgElfRadicalS -> PtgExtraElf */
      case 'PtgElfColS': /* TODO: PtgElfColS -> PtgExtraElf */
      case 'PtgElfColSV':
        /* TODO: PtgElfColSV -> PtgExtraElf */
        throw "Unsupported " + rgce[i][0];
      default:
        break;
    }
  }
  length = target - blob.l;
  /* note: this is technically an error but Excel disregards */
  //if(target !== blob.l && blob.l !== target - length) throw new Error(target + " != " + blob.l);
  if (length !== 0) o.push(parsenoop(blob, length));
  return o;
}

/* [MS-XLS] 2.5.198.104 ; [MS-XLSB] 2.5.97.88 */
function parse_Rgce(blob, length, opts) {
  var target = blob.l + length;
  var R,
    id,
    ptgs = [];
  while (target != blob.l) {
    length = target - blob.l;
    id = blob[blob.l];
    R = PtgTypes[id] || PtgTypes[PtgDupes[id]];
    if (id === 0x18 || id === 0x19) R = (id === 0x18 ? Ptg18 : Ptg19)[blob[blob.l + 1]];
    if (!R || !R.f) {
      /*ptgs.push*/parsenoop(blob, length);
    } else {
      ptgs.push([R.n, R.f(blob, length, opts)]);
    }
  }
  return ptgs;
}
function stringify_array(f /*:Array<Array<string>>*/) /*:string*/{
  var o /*:Array<string>*/ = [];
  for (var i = 0; i < f.length; ++i) {
    var x = f[i],
      r /*:Array<string>*/ = [];
    for (var j = 0; j < x.length; ++j) {
      var y = x[j];
      if (y) switch (y[0]) {
        // TODO: handle embedded quotes
        case 0x02:
          /*:: if(typeof y[1] != 'string') throw "unreachable"; */
          r.push('"' + y[1].replace(/"/g, '""') + '"');
          break;
        default:
          r.push(y[1]);
      } else r.push("");
    }
    o.push(r.join(","));
  }
  return o.join(";");
}

/* [MS-XLS] 2.2.2 ; [MS-XLSB] 2.2.2 TODO */
var PtgBinOp = {
  PtgAdd: "+",
  PtgConcat: "&",
  PtgDiv: "/",
  PtgEq: "=",
  PtgGe: ">=",
  PtgGt: ">",
  PtgLe: "<=",
  PtgLt: "<",
  PtgMul: "*",
  PtgNe: "<>",
  PtgPower: "^",
  PtgSub: "-"
};

// List of invalid characters needs to be tested further
function formula_quote_sheet_name(sname /*:string*/, opts) /*:string*/{
  if (!sname && !(opts && opts.biff <= 5 && opts.biff >= 2)) throw new Error("empty sheet name");
  if (/[^\w\u4E00-\u9FFF\u3040-\u30FF]/.test(sname)) return "'" + sname + "'";
  return sname;
}
function get_ixti_raw(supbooks, ixti /*:number*/, opts) /*:string*/{
  if (!supbooks) return "SH33TJSERR0";
  if (opts.biff > 8 && (!supbooks.XTI || !supbooks.XTI[ixti])) return supbooks.SheetNames[ixti];
  if (!supbooks.XTI) return "SH33TJSERR6";
  var XTI = supbooks.XTI[ixti];
  if (opts.biff < 8) {
    if (ixti > 10000) ixti -= 65536;
    if (ixti < 0) ixti = -ixti;
    return ixti == 0 ? "" : supbooks.XTI[ixti - 1];
  }
  if (!XTI) return "SH33TJSERR1";
  var o = "";
  if (opts.biff > 8) switch (supbooks[XTI[0]][0]) {
    case 0x0165:
      /* 'BrtSupSelf' */
      o = XTI[1] == -1 ? "#REF" : supbooks.SheetNames[XTI[1]];
      return XTI[1] == XTI[2] ? o : o + ":" + supbooks.SheetNames[XTI[2]];
    case 0x0166:
      /* 'BrtSupSame' */
      if (opts.SID != null) return supbooks.SheetNames[opts.SID];
      return "SH33TJSSAME" + supbooks[XTI[0]][0];
    case 0x0163: /* 'BrtSupBookSrc' */
    /* falls through */
    default:
      return "SH33TJSSRC" + supbooks[XTI[0]][0];
  }
  switch (supbooks[XTI[0]][0][0]) {
    case 0x0401:
      o = XTI[1] == -1 ? "#REF" : supbooks.SheetNames[XTI[1]] || "SH33TJSERR3";
      return XTI[1] == XTI[2] ? o : o + ":" + supbooks.SheetNames[XTI[2]];
    case 0x3A01:
      return supbooks[XTI[0]].slice(1).map(function (name) {
        return name.Name;
      }).join(";;");
    //return "SH33TJSERR8";
    default:
      if (!supbooks[XTI[0]][0][3]) return "SH33TJSERR2";
      o = XTI[1] == -1 ? "#REF" : supbooks[XTI[0]][0][3][XTI[1]] || "SH33TJSERR4";
      return XTI[1] == XTI[2] ? o : o + ":" + supbooks[XTI[0]][0][3][XTI[2]];
  }
}
function get_ixti(supbooks, ixti /*:number*/, opts) /*:string*/{
  var ixtiraw = get_ixti_raw(supbooks, ixti, opts);
  return ixtiraw == "#REF" ? ixtiraw : formula_quote_sheet_name(ixtiraw, opts);
}
function stringify_formula(formula /*Array<any>*/, range, cell /*:any*/, supbooks, opts) /*:string*/{
  var biff = opts && opts.biff || 8;
  var _range = /*range != null ? range :*/{
    s: {
      c: 0,
      r: 0
    },
    e: {
      c: 0,
      r: 0
    }
  };
  var stack /*:Array<string>*/ = [],
    e1,
    e2,
    /*::type,*/c /*:CellAddress*/,
    ixti = 0,
    nameidx = 0,
    r,
    sname = "";
  if (!formula[0] || !formula[0][0]) return "";
  var last_sp = -1,
    sp = "";
  for (var ff = 0, fflen = formula[0].length; ff < fflen; ++ff) {
    var f = formula[0][ff];
    switch (f[0]) {
      case 'PtgUminus':
        /* [MS-XLS] 2.5.198.93 */
        stack.push("-" + stack.pop());
        break;
      case 'PtgUplus':
        /* [MS-XLS] 2.5.198.95 */
        stack.push("+" + stack.pop());
        break;
      case 'PtgPercent':
        /* [MS-XLS] 2.5.198.81 */
        stack.push(stack.pop() + "%");
        break;
      case 'PtgAdd': /* [MS-XLS] 2.5.198.26 */
      case 'PtgConcat': /* [MS-XLS] 2.5.198.43 */
      case 'PtgDiv': /* [MS-XLS] 2.5.198.45 */
      case 'PtgEq': /* [MS-XLS] 2.5.198.56 */
      case 'PtgGe': /* [MS-XLS] 2.5.198.64 */
      case 'PtgGt': /* [MS-XLS] 2.5.198.65 */
      case 'PtgLe': /* [MS-XLS] 2.5.198.68 */
      case 'PtgLt': /* [MS-XLS] 2.5.198.69 */
      case 'PtgMul': /* [MS-XLS] 2.5.198.75 */
      case 'PtgNe': /* [MS-XLS] 2.5.198.78 */
      case 'PtgPower': /* [MS-XLS] 2.5.198.82 */
      case 'PtgSub':
        /* [MS-XLS] 2.5.198.90 */
        e1 = stack.pop();
        e2 = stack.pop();
        if (last_sp >= 0) {
          switch (formula[0][last_sp][1][0]) {
            case 0:
              // $FlowIgnore
              sp = fill(" ", formula[0][last_sp][1][1]);
              break;
            case 1:
              // $FlowIgnore
              sp = fill("\r", formula[0][last_sp][1][1]);
              break;
            default:
              sp = "";
              // $FlowIgnore
              if (opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
          }
          e2 = e2 + sp;
          last_sp = -1;
        }
        stack.push(e2 + PtgBinOp[f[0]] + e1);
        break;
      case 'PtgIsect':
        /* [MS-XLS] 2.5.198.67 */
        e1 = stack.pop();
        e2 = stack.pop();
        stack.push(e2 + " " + e1);
        break;
      case 'PtgUnion':
        /* [MS-XLS] 2.5.198.94 */
        e1 = stack.pop();
        e2 = stack.pop();
        stack.push(e2 + "," + e1);
        break;
      case 'PtgRange':
        /* [MS-XLS] 2.5.198.83 */
        e1 = stack.pop();
        e2 = stack.pop();
        stack.push(e2 + ":" + e1);
        break;
      case 'PtgAttrChoose':
        /* [MS-XLS] 2.5.198.34 */
        break;
      case 'PtgAttrGoto':
        /* [MS-XLS] 2.5.198.35 */
        break;
      case 'PtgAttrIf':
        /* [MS-XLS] 2.5.198.36 */
        break;
      case 'PtgAttrIfError':
        /* [MS-XLSB] 2.5.97.28 */
        break;
      case 'PtgRef':
        /* [MS-XLS] 2.5.198.84 */
        /*::type = f[1][0]; */c = shift_cell_xls(f[1][1] /*:any*/, _range, opts);
        stack.push(encode_cell_xls(c, biff));
        break;
      case 'PtgRefN':
        /* [MS-XLS] 2.5.198.88 */
        /*::type = f[1][0]; */c = cell ? shift_cell_xls(f[1][1] /*:any*/, cell, opts) : f[1][1] /*:any*/;
        stack.push(encode_cell_xls(c, biff));
        break;
      case 'PtgRef3d':
        /* [MS-XLS] 2.5.198.85 */
        /*::type = f[1][0]; */ixti = /*::Number(*/f[1][1] /*::)*/;
        c = shift_cell_xls(f[1][2] /*:any*/, _range, opts);
        sname = get_ixti(supbooks, ixti, opts);
        var w = sname; /* IE9 fails on defined names */ // eslint-disable-line no-unused-vars
        stack.push(sname + "!" + encode_cell_xls(c, biff));
        break;
      case 'PtgFunc': /* [MS-XLS] 2.5.198.62 */
      case 'PtgFuncVar':
        /* [MS-XLS] 2.5.198.63 */
        /* f[1] = [argc, func, type] */
        var argc /*:number*/ = f[1][0] /*:any*/,
          func /*:string*/ = f[1][1] /*:any*/;
        if (!argc) argc = 0;
        argc &= 0x7F;
        var args = argc == 0 ? [] : stack.slice(-argc);
        stack.length -= argc;
        if (func === 'User') func = args.shift();
        stack.push(func + "(" + args.join(",") + ")");
        break;
      case 'PtgBool':
        /* [MS-XLS] 2.5.198.42 */
        stack.push(f[1] ? "TRUE" : "FALSE");
        break;
      case 'PtgInt':
        /* [MS-XLS] 2.5.198.66 */
        stack.push(/*::String(*/f[1] /*::)*/);
        break;
      case 'PtgNum':
        /* [MS-XLS] 2.5.198.79 TODO: precision? */
        stack.push(String(f[1]));
        break;
      case 'PtgStr':
        /* [MS-XLS] 2.5.198.89 */
        // $FlowIgnore
        stack.push('"' + f[1].replace(/"/g, '""') + '"');
        break;
      case 'PtgErr':
        /* [MS-XLS] 2.5.198.57 */
        stack.push(/*::String(*/f[1] /*::)*/);
        break;
      case 'PtgAreaN':
        /* [MS-XLS] 2.5.198.31 TODO */
        /*::type = f[1][0]; */r = shift_range_xls(f[1][1], cell ? {
          s: cell
        } : _range, opts);
        stack.push(encode_range_xls(r /*:any*/, opts));
        break;
      case 'PtgArea':
        /* [MS-XLS] 2.5.198.27 TODO: fixed points */
        /*::type = f[1][0]; */r = shift_range_xls(f[1][1], _range, opts);
        stack.push(encode_range_xls(r /*:any*/, opts));
        break;
      case 'PtgArea3d':
        /* [MS-XLS] 2.5.198.28 TODO */
        /*::type = f[1][0]; */ixti = /*::Number(*/f[1][1] /*::)*/;
        r = f[1][2];
        sname = get_ixti(supbooks, ixti, opts);
        stack.push(sname + "!" + encode_range_xls(r /*:any*/, opts));
        break;
      case 'PtgAttrSum':
        /* [MS-XLS] 2.5.198.41 */
        stack.push("SUM(" + stack.pop() + ")");
        break;
      case 'PtgAttrBaxcel': /* [MS-XLS] 2.5.198.33 */
      case 'PtgAttrSemi':
        /* [MS-XLS] 2.5.198.37 */
        break;
      case 'PtgName':
        /* [MS-XLS] 2.5.198.76 ; [MS-XLSB] 2.5.97.60 TODO: revisions */
        /* f[1] = type, 0, nameindex */
        nameidx = f[1][2] /*:any*/;
        var lbl = (supbooks.names || [])[nameidx - 1] || (supbooks[0] || [])[nameidx];
        var name = lbl ? lbl.Name : "SH33TJSNAME" + String(nameidx);
        /* [MS-XLSB] 2.5.97.10 Ftab -- last verified 20220204 */
        if (name && name.slice(0, 6) == "_xlfn." && !opts.xlfn) name = name.slice(6);
        stack.push(name);
        break;
      case 'PtgNameX':
        /* [MS-XLS] 2.5.198.77 ; [MS-XLSB] 2.5.97.61 TODO: revisions */
        /* f[1] = type, ixti, nameindex */
        var bookidx /*:number*/ = f[1][1] /*:any*/;
        nameidx = f[1][2] /*:any*/;
        var externbook;
        /* TODO: Properly handle missing values -- this should be using get_ixti_raw primarily */
        if (opts.biff <= 5) {
          if (bookidx < 0) bookidx = -bookidx;
          if (supbooks[bookidx]) externbook = supbooks[bookidx][nameidx];
        } else {
          var o = "";
          if (((supbooks[bookidx] || [])[0] || [])[0] == 0x3A01) {/* empty */} else if (((supbooks[bookidx] || [])[0] || [])[0] == 0x0401) {
            if (supbooks[bookidx][nameidx] && supbooks[bookidx][nameidx].itab > 0) {
              o = supbooks.SheetNames[supbooks[bookidx][nameidx].itab - 1] + "!";
            }
          } else o = supbooks.SheetNames[nameidx - 1] + "!";
          if (supbooks[bookidx] && supbooks[bookidx][nameidx]) o += supbooks[bookidx][nameidx].Name;else if (supbooks[0] && supbooks[0][nameidx]) o += supbooks[0][nameidx].Name;else {
            var ixtidata = (get_ixti_raw(supbooks, bookidx, opts) || "").split(";;");
            if (ixtidata[nameidx - 1]) o = ixtidata[nameidx - 1]; // TODO: confirm this is correct
            else o += "SH33TJSERRX";
          }
          stack.push(o);
          break;
        }
        if (!externbook) externbook = {
          Name: "SH33TJSERRY"
        };
        stack.push(externbook.Name);
        break;
      case 'PtgParen':
        /* [MS-XLS] 2.5.198.80 */
        var lp = '(',
          rp = ')';
        if (last_sp >= 0) {
          sp = "";
          switch (formula[0][last_sp][1][0]) {
            // $FlowIgnore
            case 2:
              lp = fill(" ", formula[0][last_sp][1][1]) + lp;
              break;
            // $FlowIgnore
            case 3:
              lp = fill("\r", formula[0][last_sp][1][1]) + lp;
              break;
            // $FlowIgnore
            case 4:
              rp = fill(" ", formula[0][last_sp][1][1]) + rp;
              break;
            // $FlowIgnore
            case 5:
              rp = fill("\r", formula[0][last_sp][1][1]) + rp;
              break;
            default:
              // $FlowIgnore
              if (opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + formula[0][last_sp][1][0]);
          }
          last_sp = -1;
        }
        stack.push(lp + stack.pop() + rp);
        break;
      case 'PtgRefErr':
        /* [MS-XLS] 2.5.198.86 */
        stack.push('#REF!');
        break;
      case 'PtgRefErr3d':
        /* [MS-XLS] 2.5.198.87 */
        stack.push('#REF!');
        break;
      case 'PtgExp':
        /* [MS-XLS] 2.5.198.58 TODO */
        c = {
          c: f[1][1] /*:any*/,
          r: f[1][0] /*:any*/
        };
        var q = {
          c: cell.c,
          r: cell.r
        } /*:any*/;
        if (supbooks.sharedf[encode_cell(c)]) {
          var parsedf = supbooks.sharedf[encode_cell(c)];
          stack.push(stringify_formula(parsedf, _range, q, supbooks, opts));
        } else {
          var fnd = false;
          for (e1 = 0; e1 != supbooks.arrayf.length; ++e1) {
            /* TODO: should be something like range_has */
            e2 = supbooks.arrayf[e1];
            if (c.c < e2[0].s.c || c.c > e2[0].e.c) continue;
            if (c.r < e2[0].s.r || c.r > e2[0].e.r) continue;
            stack.push(stringify_formula(e2[1], _range, q, supbooks, opts));
            fnd = true;
            break;
          }
          if (!fnd) stack.push(/*::String(*/f[1] /*::)*/);
        }
        break;
      case 'PtgArray':
        /* [MS-XLS] 2.5.198.32 TODO */
        stack.push("{" + stringify_array(/*::(*/f[1] /*:: :any)*/) + "}");
        break;
      case 'PtgMemArea':
        /* [MS-XLS] 2.5.198.70 TODO: confirm this is a non-display */
        //stack.push("(" + f[2].map(encode_range).join(",") + ")");
        break;
      case 'PtgAttrSpace': /* [MS-XLS] 2.5.198.38 */
      case 'PtgAttrSpaceSemi':
        /* [MS-XLS] 2.5.198.39 */
        last_sp = ff;
        break;
      case 'PtgTbl':
        /* [MS-XLS] 2.5.198.92 TODO */
        break;
      case 'PtgMemErr':
        /* [MS-XLS] 2.5.198.71 */
        break;
      case 'PtgMissArg':
        /* [MS-XLS] 2.5.198.74 */
        stack.push("");
        break;
      case 'PtgAreaErr':
        /* [MS-XLS] 2.5.198.29 */
        stack.push("#REF!");
        break;
      case 'PtgAreaErr3d':
        /* [MS-XLS] 2.5.198.30 */
        stack.push("#REF!");
        break;
      case 'PtgList':
        /* [MS-XLSB] 2.5.97.52 */
        // $FlowIgnore
        stack.push("Table" + f[1].idx + "[#" + f[1].rt + "]");
        break;
      case 'PtgMemAreaN':
      case 'PtgMemNoMemN':
      case 'PtgAttrNoop':
      case 'PtgSheet':
      case 'PtgEndSheet':
        break;
      case 'PtgMemFunc':
        /* [MS-XLS] 2.5.198.72 TODO */
        break;
      case 'PtgMemNoMem':
        /* [MS-XLS] 2.5.198.73 TODO */
        break;
      case 'PtgElfCol': /* [MS-XLS] 2.5.198.46 */
      case 'PtgElfColS': /* [MS-XLS] 2.5.198.47 */
      case 'PtgElfColSV': /* [MS-XLS] 2.5.198.48 */
      case 'PtgElfColV': /* [MS-XLS] 2.5.198.49 */
      case 'PtgElfLel': /* [MS-XLS] 2.5.198.50 */
      case 'PtgElfRadical': /* [MS-XLS] 2.5.198.51 */
      case 'PtgElfRadicalLel': /* [MS-XLS] 2.5.198.52 */
      case 'PtgElfRadicalS': /* [MS-XLS] 2.5.198.53 */
      case 'PtgElfRw': /* [MS-XLS] 2.5.198.54 */
      case 'PtgElfRwV':
        /* [MS-XLS] 2.5.198.55 */
        throw new Error("Unsupported ELFs");
      case 'PtgSxName':
        /* [MS-XLS] 2.5.198.91 TODO -- find a test case */
        throw new Error('Unrecognized Formula Token: ' + String(f));
      default:
        throw new Error('Unrecognized Formula Token: ' + String(f));
    }
    var PtgNonDisp = ['PtgAttrSpace', 'PtgAttrSpaceSemi', 'PtgAttrGoto'];
    if (opts.biff != 3) if (last_sp >= 0 && PtgNonDisp.indexOf(formula[0][ff][0]) == -1) {
      f = formula[0][last_sp];
      var _left = true;
      switch (f[1][0]) {
        /* note: some bad XLSB files omit the PtgParen */
        case 4:
          _left = false;
        /* falls through */
        case 0:
          // $FlowIgnore
          sp = fill(" ", f[1][1]);
          break;
        case 5:
          _left = false;
        /* falls through */
        case 1:
          // $FlowIgnore
          sp = fill("\r", f[1][1]);
          break;
        default:
          sp = "";
          // $FlowIgnore
          if (opts.WTF) throw new Error("Unexpected PtgAttrSpaceType " + f[1][0]);
      }
      stack.push((_left ? sp : "") + stack.pop() + (_left ? "" : sp));
      last_sp = -1;
    }
  }
  if (stack.length > 1 && opts.WTF) throw new Error("bad formula stack");
  return stack[0];
}

/* [MS-XLS] 2.5.198.1 TODO */
function parse_ArrayParsedFormula(blob, length, opts /*::, ref*/) {
  var target = blob.l + length,
    len = opts.biff == 2 ? 1 : 2;
  var rgcb,
    cce = blob.read_shift(len); // length of rgce
  if (cce == 0xFFFF) return [[], parsenoop(blob, length - 2)];
  var rgce = parse_Rgce(blob, cce, opts);
  if (length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
  blob.l = target;
  return [rgce, rgcb];
}

/* [MS-XLS] 2.5.198.3 TODO */
function parse_XLSCellParsedFormula(blob, length, opts) {
  var target = blob.l + length,
    len = opts.biff == 2 ? 1 : 2;
  var rgcb,
    cce = blob.read_shift(len); // length of rgce
  if (cce == 0xFFFF) return [[], parsenoop(blob, length - 2)];
  var rgce = parse_Rgce(blob, cce, opts);
  if (length !== cce + len) rgcb = parse_RgbExtra(blob, length - cce - len, rgce, opts);
  blob.l = target;
  return [rgce, rgcb];
}

/* [MS-XLS] 2.5.198.21 */
function parse_NameParsedFormula(blob, length, opts, cce) {
  var target = blob.l + length;
  var rgce = parse_Rgce(blob, cce, opts);
  var rgcb;
  if (target !== blob.l) rgcb = parse_RgbExtra(blob, target - blob.l, rgce, opts);
  return [rgce, rgcb];
}

/* [MS-XLS] 2.5.198.118 TODO */
function parse_SharedParsedFormula(blob, length, opts) {
  var target = blob.l + length;
  var rgcb,
    cce = blob.read_shift(2); // length of rgce
  var rgce = parse_Rgce(blob, cce, opts);
  if (cce == 0xFFFF) return [[], parsenoop(blob, length - 2)];
  if (length !== cce + 2) rgcb = parse_RgbExtra(blob, target - cce - 2, rgce, opts);
  return [rgce, rgcb];
}

/* [MS-XLS] 2.5.133 TODO: how to emit empty strings? */
function parse_FormulaValue(blob /*::, length*/) {
  var b;
  if (__readUInt16LE(blob, blob.l + 6) !== 0xFFFF) return [parse_Xnum(blob), 'n'];
  switch (blob[blob.l]) {
    case 0x00:
      blob.l += 8;
      return ["String", 's'];
    case 0x01:
      b = blob[blob.l + 2] === 0x1;
      blob.l += 8;
      return [b, 'b'];
    case 0x02:
      b = blob[blob.l + 2];
      blob.l += 8;
      return [b, 'e'];
    case 0x03:
      blob.l += 8;
      return ["", 's'];
  }
  return [];
}
function write_FormulaValue(value) {
  if (value == null) {
    // Blank String Value
    var o = new_buf(8);
    o.write_shift(1, 0x03);
    o.write_shift(1, 0);
    o.write_shift(2, 0);
    o.write_shift(2, 0);
    o.write_shift(2, 0xFFFF);
    return o;
  } else if (typeof value == "number") return write_Xnum(value);
  return write_Xnum(0);
}

/* [MS-XLS] 2.4.127 TODO */
function parse_Formula(blob, length, opts) {
  var end = blob.l + length;
  var cell = parse_XLSCell(blob, 6);
  if (opts.biff == 2) ++blob.l;
  var val = parse_FormulaValue(blob, 8);
  var flags = blob.read_shift(1);
  if (opts.biff != 2) {
    blob.read_shift(1);
    if (opts.biff >= 5) {
      /*var chn = */blob.read_shift(4);
    }
  }
  var cbf = parse_XLSCellParsedFormula(blob, end - blob.l, opts);
  return {
    cell: cell,
    val: val[0],
    formula: cbf,
    shared: flags >> 3 & 1,
    tt: val[1]
  };
}
function write_Formula(cell /*:Cell*/, R /*:number*/, C /*:number*/, opts, os /*:number*/) {
  // Cell
  var o1 = write_XLSCell(R, C, os);

  // FormulaValue
  var o2 = write_FormulaValue(cell.v);

  // flags + cache
  var o3 = new_buf(6);
  var flags = 0x01 | 0x20;
  o3.write_shift(2, flags);
  o3.write_shift(4, 0);

  // CellParsedFormula
  var bf = new_buf(cell.bf.length);
  for (var i = 0; i < cell.bf.length; ++i) bf[i] = cell.bf[i];
  var out = bconcat([o1, o2, o3, bf]);
  return out;
}

/* XLSB Parsed Formula records have the same shape */
function parse_XLSBParsedFormula(data, length, opts) {
  var cce = data.read_shift(4);
  var rgce = parse_Rgce(data, cce, opts);
  var cb = data.read_shift(4);
  var rgcb = cb > 0 ? parse_RgbExtra(data, cb, rgce, opts) : null;
  return [rgce, rgcb];
}

/* [MS-XLSB] 2.5.97.1 ArrayParsedFormula */
var parse_XLSBArrayParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.4 CellParsedFormula */
var parse_XLSBCellParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.8 DVParsedFormula */
//var parse_XLSBDVParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.9 FRTParsedFormula */
//var parse_XLSBFRTParsedFormula = parse_XLSBParsedFormula2;
/* [MS-XLSB] 2.5.97.12 NameParsedFormula */
var parse_XLSBNameParsedFormula = parse_XLSBParsedFormula;
/* [MS-XLSB] 2.5.97.98 SharedParsedFormula */
var parse_XLSBSharedParsedFormula = parse_XLSBParsedFormula;
var Cetab = {
  0: "BEEP",
  1: "OPEN",
  2: "OPEN.LINKS",
  3: "CLOSE.ALL",
  4: "SAVE",
  5: "SAVE.AS",
  6: "FILE.DELETE",
  7: "PAGE.SETUP",
  8: "PRINT",
  9: "PRINTER.SETUP",
  10: "QUIT",
  11: "NEW.WINDOW",
  12: "ARRANGE.ALL",
  13: "WINDOW.SIZE",
  14: "WINDOW.MOVE",
  15: "FULL",
  16: "CLOSE",
  17: "RUN",
  22: "SET.PRINT.AREA",
  23: "SET.PRINT.TITLES",
  24: "SET.PAGE.BREAK",
  25: "REMOVE.PAGE.BREAK",
  26: "FONT",
  27: "DISPLAY",
  28: "PROTECT.DOCUMENT",
  29: "PRECISION",
  30: "A1.R1C1",
  31: "CALCULATE.NOW",
  32: "CALCULATION",
  34: "DATA.FIND",
  35: "EXTRACT",
  36: "DATA.DELETE",
  37: "SET.DATABASE",
  38: "SET.CRITERIA",
  39: "SORT",
  40: "DATA.SERIES",
  41: "TABLE",
  42: "FORMAT.NUMBER",
  43: "ALIGNMENT",
  44: "STYLE",
  45: "BORDER",
  46: "CELL.PROTECTION",
  47: "COLUMN.WIDTH",
  48: "UNDO",
  49: "CUT",
  50: "COPY",
  51: "PASTE",
  52: "CLEAR",
  53: "PASTE.SPECIAL",
  54: "EDIT.DELETE",
  55: "INSERT",
  56: "FILL.RIGHT",
  57: "FILL.DOWN",
  61: "DEFINE.NAME",
  62: "CREATE.NAMES",
  63: "FORMULA.GOTO",
  64: "FORMULA.FIND",
  65: "SELECT.LAST.CELL",
  66: "SHOW.ACTIVE.CELL",
  67: "GALLERY.AREA",
  68: "GALLERY.BAR",
  69: "GALLERY.COLUMN",
  70: "GALLERY.LINE",
  71: "GALLERY.PIE",
  72: "GALLERY.SCATTER",
  73: "COMBINATION",
  74: "PREFERRED",
  75: "ADD.OVERLAY",
  76: "GRIDLINES",
  77: "SET.PREFERRED",
  78: "AXES",
  79: "LEGEND",
  80: "ATTACH.TEXT",
  81: "ADD.ARROW",
  82: "SELECT.CHART",
  83: "SELECT.PLOT.AREA",
  84: "PATTERNS",
  85: "MAIN.CHART",
  86: "OVERLAY",
  87: "SCALE",
  88: "FORMAT.LEGEND",
  89: "FORMAT.TEXT",
  90: "EDIT.REPEAT",
  91: "PARSE",
  92: "JUSTIFY",
  93: "HIDE",
  94: "UNHIDE",
  95: "WORKSPACE",
  96: "FORMULA",
  97: "FORMULA.FILL",
  98: "FORMULA.ARRAY",
  99: "DATA.FIND.NEXT",
  100: "DATA.FIND.PREV",
  101: "FORMULA.FIND.NEXT",
  102: "FORMULA.FIND.PREV",
  103: "ACTIVATE",
  104: "ACTIVATE.NEXT",
  105: "ACTIVATE.PREV",
  106: "UNLOCKED.NEXT",
  107: "UNLOCKED.PREV",
  108: "COPY.PICTURE",
  109: "SELECT",
  110: "DELETE.NAME",
  111: "DELETE.FORMAT",
  112: "VLINE",
  113: "HLINE",
  114: "VPAGE",
  115: "HPAGE",
  116: "VSCROLL",
  117: "HSCROLL",
  118: "ALERT",
  119: "NEW",
  120: "CANCEL.COPY",
  121: "SHOW.CLIPBOARD",
  122: "MESSAGE",
  124: "PASTE.LINK",
  125: "APP.ACTIVATE",
  126: "DELETE.ARROW",
  127: "ROW.HEIGHT",
  128: "FORMAT.MOVE",
  129: "FORMAT.SIZE",
  130: "FORMULA.REPLACE",
  131: "SEND.KEYS",
  132: "SELECT.SPECIAL",
  133: "APPLY.NAMES",
  134: "REPLACE.FONT",
  135: "FREEZE.PANES",
  136: "SHOW.INFO",
  137: "SPLIT",
  138: "ON.WINDOW",
  139: "ON.DATA",
  140: "DISABLE.INPUT",
  142: "OUTLINE",
  143: "LIST.NAMES",
  144: "FILE.CLOSE",
  145: "SAVE.WORKBOOK",
  146: "DATA.FORM",
  147: "COPY.CHART",
  148: "ON.TIME",
  149: "WAIT",
  150: "FORMAT.FONT",
  151: "FILL.UP",
  152: "FILL.LEFT",
  153: "DELETE.OVERLAY",
  155: "SHORT.MENUS",
  159: "SET.UPDATE.STATUS",
  161: "COLOR.PALETTE",
  162: "DELETE.STYLE",
  163: "WINDOW.RESTORE",
  164: "WINDOW.MAXIMIZE",
  166: "CHANGE.LINK",
  167: "CALCULATE.DOCUMENT",
  168: "ON.KEY",
  169: "APP.RESTORE",
  170: "APP.MOVE",
  171: "APP.SIZE",
  172: "APP.MINIMIZE",
  173: "APP.MAXIMIZE",
  174: "BRING.TO.FRONT",
  175: "SEND.TO.BACK",
  185: "MAIN.CHART.TYPE",
  186: "OVERLAY.CHART.TYPE",
  187: "SELECT.END",
  188: "OPEN.MAIL",
  189: "SEND.MAIL",
  190: "STANDARD.FONT",
  191: "CONSOLIDATE",
  192: "SORT.SPECIAL",
  193: "GALLERY.3D.AREA",
  194: "GALLERY.3D.COLUMN",
  195: "GALLERY.3D.LINE",
  196: "GALLERY.3D.PIE",
  197: "VIEW.3D",
  198: "GOAL.SEEK",
  199: "WORKGROUP",
  200: "FILL.GROUP",
  201: "UPDATE.LINK",
  202: "PROMOTE",
  203: "DEMOTE",
  204: "SHOW.DETAIL",
  206: "UNGROUP",
  207: "OBJECT.PROPERTIES",
  208: "SAVE.NEW.OBJECT",
  209: "SHARE",
  210: "SHARE.NAME",
  211: "DUPLICATE",
  212: "APPLY.STYLE",
  213: "ASSIGN.TO.OBJECT",
  214: "OBJECT.PROTECTION",
  215: "HIDE.OBJECT",
  216: "SET.EXTRACT",
  217: "CREATE.PUBLISHER",
  218: "SUBSCRIBE.TO",
  219: "ATTRIBUTES",
  220: "SHOW.TOOLBAR",
  222: "PRINT.PREVIEW",
  223: "EDIT.COLOR",
  224: "SHOW.LEVELS",
  225: "FORMAT.MAIN",
  226: "FORMAT.OVERLAY",
  227: "ON.RECALC",
  228: "EDIT.SERIES",
  229: "DEFINE.STYLE",
  240: "LINE.PRINT",
  243: "ENTER.DATA",
  249: "GALLERY.RADAR",
  250: "MERGE.STYLES",
  251: "EDITION.OPTIONS",
  252: "PASTE.PICTURE",
  253: "PASTE.PICTURE.LINK",
  254: "SPELLING",
  256: "ZOOM",
  259: "INSERT.OBJECT",
  260: "WINDOW.MINIMIZE",
  265: "SOUND.NOTE",
  266: "SOUND.PLAY",
  267: "FORMAT.SHAPE",
  268: "EXTEND.POLYGON",
  269: "FORMAT.AUTO",
  272: "GALLERY.3D.BAR",
  273: "GALLERY.3D.SURFACE",
  274: "FILL.AUTO",
  276: "CUSTOMIZE.TOOLBAR",
  277: "ADD.TOOL",
  278: "EDIT.OBJECT",
  279: "ON.DOUBLECLICK",
  280: "ON.ENTRY",
  281: "WORKBOOK.ADD",
  282: "WORKBOOK.MOVE",
  283: "WORKBOOK.COPY",
  284: "WORKBOOK.OPTIONS",
  285: "SAVE.WORKSPACE",
  288: "CHART.WIZARD",
  289: "DELETE.TOOL",
  290: "MOVE.TOOL",
  291: "WORKBOOK.SELECT",
  292: "WORKBOOK.ACTIVATE",
  293: "ASSIGN.TO.TOOL",
  295: "COPY.TOOL",
  296: "RESET.TOOL",
  297: "CONSTRAIN.NUMERIC",
  298: "PASTE.TOOL",
  302: "WORKBOOK.NEW",
  305: "SCENARIO.CELLS",
  306: "SCENARIO.DELETE",
  307: "SCENARIO.ADD",
  308: "SCENARIO.EDIT",
  309: "SCENARIO.SHOW",
  310: "SCENARIO.SHOW.NEXT",
  311: "SCENARIO.SUMMARY",
  312: "PIVOT.TABLE.WIZARD",
  313: "PIVOT.FIELD.PROPERTIES",
  314: "PIVOT.FIELD",
  315: "PIVOT.ITEM",
  316: "PIVOT.ADD.FIELDS",
  318: "OPTIONS.CALCULATION",
  319: "OPTIONS.EDIT",
  320: "OPTIONS.VIEW",
  321: "ADDIN.MANAGER",
  322: "MENU.EDITOR",
  323: "ATTACH.TOOLBARS",
  324: "VBAActivate",
  325: "OPTIONS.CHART",
  328: "VBA.INSERT.FILE",
  330: "VBA.PROCEDURE.DEFINITION",
  336: "ROUTING.SLIP",
  338: "ROUTE.DOCUMENT",
  339: "MAIL.LOGON",
  342: "INSERT.PICTURE",
  343: "EDIT.TOOL",
  344: "GALLERY.DOUGHNUT",
  350: "CHART.TREND",
  352: "PIVOT.ITEM.PROPERTIES",
  354: "WORKBOOK.INSERT",
  355: "OPTIONS.TRANSITION",
  356: "OPTIONS.GENERAL",
  370: "FILTER.ADVANCED",
  373: "MAIL.ADD.MAILER",
  374: "MAIL.DELETE.MAILER",
  375: "MAIL.REPLY",
  376: "MAIL.REPLY.ALL",
  377: "MAIL.FORWARD",
  378: "MAIL.NEXT.LETTER",
  379: "DATA.LABEL",
  380: "INSERT.TITLE",
  381: "FONT.PROPERTIES",
  382: "MACRO.OPTIONS",
  383: "WORKBOOK.HIDE",
  384: "WORKBOOK.UNHIDE",
  385: "WORKBOOK.DELETE",
  386: "WORKBOOK.NAME",
  388: "GALLERY.CUSTOM",
  390: "ADD.CHART.AUTOFORMAT",
  391: "DELETE.CHART.AUTOFORMAT",
  392: "CHART.ADD.DATA",
  393: "AUTO.OUTLINE",
  394: "TAB.ORDER",
  395: "SHOW.DIALOG",
  396: "SELECT.ALL",
  397: "UNGROUP.SHEETS",
  398: "SUBTOTAL.CREATE",
  399: "SUBTOTAL.REMOVE",
  400: "RENAME.OBJECT",
  412: "WORKBOOK.SCROLL",
  413: "WORKBOOK.NEXT",
  414: "WORKBOOK.PREV",
  415: "WORKBOOK.TAB.SPLIT",
  416: "FULL.SCREEN",
  417: "WORKBOOK.PROTECT",
  420: "SCROLLBAR.PROPERTIES",
  421: "PIVOT.SHOW.PAGES",
  422: "TEXT.TO.COLUMNS",
  423: "FORMAT.CHARTTYPE",
  424: "LINK.FORMAT",
  425: "TRACER.DISPLAY",
  430: "TRACER.NAVIGATE",
  431: "TRACER.CLEAR",
  432: "TRACER.ERROR",
  433: "PIVOT.FIELD.GROUP",
  434: "PIVOT.FIELD.UNGROUP",
  435: "CHECKBOX.PROPERTIES",
  436: "LABEL.PROPERTIES",
  437: "LISTBOX.PROPERTIES",
  438: "EDITBOX.PROPERTIES",
  439: "PIVOT.REFRESH",
  440: "LINK.COMBO",
  441: "OPEN.TEXT",
  442: "HIDE.DIALOG",
  443: "SET.DIALOG.FOCUS",
  444: "ENABLE.OBJECT",
  445: "PUSHBUTTON.PROPERTIES",
  446: "SET.DIALOG.DEFAULT",
  447: "FILTER",
  448: "FILTER.SHOW.ALL",
  449: "CLEAR.OUTLINE",
  450: "FUNCTION.WIZARD",
  451: "ADD.LIST.ITEM",
  452: "SET.LIST.ITEM",
  453: "REMOVE.LIST.ITEM",
  454: "SELECT.LIST.ITEM",
  455: "SET.CONTROL.VALUE",
  456: "SAVE.COPY.AS",
  458: "OPTIONS.LISTS.ADD",
  459: "OPTIONS.LISTS.DELETE",
  460: "SERIES.AXES",
  461: "SERIES.X",
  462: "SERIES.Y",
  463: "ERRORBAR.X",
  464: "ERRORBAR.Y",
  465: "FORMAT.CHART",
  466: "SERIES.ORDER",
  467: "MAIL.LOGOFF",
  468: "CLEAR.ROUTING.SLIP",
  469: "APP.ACTIVATE.MICROSOFT",
  470: "MAIL.EDIT.MAILER",
  471: "ON.SHEET",
  472: "STANDARD.WIDTH",
  473: "SCENARIO.MERGE",
  474: "SUMMARY.INFO",
  475: "FIND.FILE",
  476: "ACTIVE.CELL.FONT",
  477: "ENABLE.TIPWIZARD",
  478: "VBA.MAKE.ADDIN",
  480: "INSERTDATATABLE",
  481: "WORKGROUP.OPTIONS",
  482: "MAIL.SEND.MAILER",
  485: "AUTOCORRECT",
  489: "POST.DOCUMENT",
  491: "PICKLIST",
  493: "VIEW.SHOW",
  494: "VIEW.DEFINE",
  495: "VIEW.DELETE",
  509: "SHEET.BACKGROUND",
  510: "INSERT.MAP.OBJECT",
  511: "OPTIONS.MENONO",
  517: "MSOCHECKS",
  518: "NORMAL",
  519: "LAYOUT",
  520: "RM.PRINT.AREA",
  521: "CLEAR.PRINT.AREA",
  522: "ADD.PRINT.AREA",
  523: "MOVE.BRK",
  545: "HIDECURR.NOTE",
  546: "HIDEALL.NOTES",
  547: "DELETE.NOTE",
  548: "TRAVERSE.NOTES",
  549: "ACTIVATE.NOTES",
  620: "PROTECT.REVISIONS",
  621: "UNPROTECT.REVISIONS",
  647: "OPTIONS.ME",
  653: "WEB.PUBLISH",
  667: "NEWWEBQUERY",
  673: "PIVOT.TABLE.CHART",
  753: "OPTIONS.SAVE",
  755: "OPTIONS.SPELL",
  808: "HIDEALL.INKANNOTS"
};
var Ftab = {
  0: "COUNT",
  1: "IF",
  2: "ISNA",
  3: "ISERROR",
  4: "SUM",
  5: "AVERAGE",
  6: "MIN",
  7: "MAX",
  8: "ROW",
  9: "COLUMN",
  10: "NA",
  11: "NPV",
  12: "STDEV",
  13: "DOLLAR",
  14: "FIXED",
  15: "SIN",
  16: "COS",
  17: "TAN",
  18: "ATAN",
  19: "PI",
  20: "SQRT",
  21: "EXP",
  22: "LN",
  23: "LOG10",
  24: "ABS",
  25: "INT",
  26: "SIGN",
  27: "ROUND",
  28: "LOOKUP",
  29: "INDEX",
  30: "REPT",
  31: "MID",
  32: "LEN",
  33: "VALUE",
  34: "TRUE",
  35: "FALSE",
  36: "AND",
  37: "OR",
  38: "NOT",
  39: "MOD",
  40: "DCOUNT",
  41: "DSUM",
  42: "DAVERAGE",
  43: "DMIN",
  44: "DMAX",
  45: "DSTDEV",
  46: "VAR",
  47: "DVAR",
  48: "TEXT",
  49: "LINEST",
  50: "TREND",
  51: "LOGEST",
  52: "GROWTH",
  53: "GOTO",
  54: "HALT",
  55: "RETURN",
  56: "PV",
  57: "FV",
  58: "NPER",
  59: "PMT",
  60: "RATE",
  61: "MIRR",
  62: "IRR",
  63: "RAND",
  64: "MATCH",
  65: "DATE",
  66: "TIME",
  67: "DAY",
  68: "MONTH",
  69: "YEAR",
  70: "WEEKDAY",
  71: "HOUR",
  72: "MINUTE",
  73: "SECOND",
  74: "NOW",
  75: "AREAS",
  76: "ROWS",
  77: "COLUMNS",
  78: "OFFSET",
  79: "ABSREF",
  80: "RELREF",
  81: "ARGUMENT",
  82: "SEARCH",
  83: "TRANSPOSE",
  84: "ERROR",
  85: "STEP",
  86: "TYPE",
  87: "ECHO",
  88: "SET.NAME",
  89: "CALLER",
  90: "DEREF",
  91: "WINDOWS",
  92: "SERIES",
  93: "DOCUMENTS",
  94: "ACTIVE.CELL",
  95: "SELECTION",
  96: "RESULT",
  97: "ATAN2",
  98: "ASIN",
  99: "ACOS",
  100: "CHOOSE",
  101: "HLOOKUP",
  102: "VLOOKUP",
  103: "LINKS",
  104: "INPUT",
  105: "ISREF",
  106: "GET.FORMULA",
  107: "GET.NAME",
  108: "SET.VALUE",
  109: "LOG",
  110: "EXEC",
  111: "CHAR",
  112: "LOWER",
  113: "UPPER",
  114: "PROPER",
  115: "LEFT",
  116: "RIGHT",
  117: "EXACT",
  118: "TRIM",
  119: "REPLACE",
  120: "SUBSTITUTE",
  121: "CODE",
  122: "NAMES",
  123: "DIRECTORY",
  124: "FIND",
  125: "CELL",
  126: "ISERR",
  127: "ISTEXT",
  128: "ISNUMBER",
  129: "ISBLANK",
  130: "T",
  131: "N",
  132: "FOPEN",
  133: "FCLOSE",
  134: "FSIZE",
  135: "FREADLN",
  136: "FREAD",
  137: "FWRITELN",
  138: "FWRITE",
  139: "FPOS",
  140: "DATEVALUE",
  141: "TIMEVALUE",
  142: "SLN",
  143: "SYD",
  144: "DDB",
  145: "GET.DEF",
  146: "REFTEXT",
  147: "TEXTREF",
  148: "INDIRECT",
  149: "REGISTER",
  150: "CALL",
  151: "ADD.BAR",
  152: "ADD.MENU",
  153: "ADD.COMMAND",
  154: "ENABLE.COMMAND",
  155: "CHECK.COMMAND",
  156: "RENAME.COMMAND",
  157: "SHOW.BAR",
  158: "DELETE.MENU",
  159: "DELETE.COMMAND",
  160: "GET.CHART.ITEM",
  161: "DIALOG.BOX",
  162: "CLEAN",
  163: "MDETERM",
  164: "MINVERSE",
  165: "MMULT",
  166: "FILES",
  167: "IPMT",
  168: "PPMT",
  169: "COUNTA",
  170: "CANCEL.KEY",
  171: "FOR",
  172: "WHILE",
  173: "BREAK",
  174: "NEXT",
  175: "INITIATE",
  176: "REQUEST",
  177: "POKE",
  178: "EXECUTE",
  179: "TERMINATE",
  180: "RESTART",
  181: "HELP",
  182: "GET.BAR",
  183: "PRODUCT",
  184: "FACT",
  185: "GET.CELL",
  186: "GET.WORKSPACE",
  187: "GET.WINDOW",
  188: "GET.DOCUMENT",
  189: "DPRODUCT",
  190: "ISNONTEXT",
  191: "GET.NOTE",
  192: "NOTE",
  193: "STDEVP",
  194: "VARP",
  195: "DSTDEVP",
  196: "DVARP",
  197: "TRUNC",
  198: "ISLOGICAL",
  199: "DCOUNTA",
  200: "DELETE.BAR",
  201: "UNREGISTER",
  204: "USDOLLAR",
  205: "FINDB",
  206: "SEARCHB",
  207: "REPLACEB",
  208: "LEFTB",
  209: "RIGHTB",
  210: "MIDB",
  211: "LENB",
  212: "ROUNDUP",
  213: "ROUNDDOWN",
  214: "ASC",
  215: "DBCS",
  216: "RANK",
  219: "ADDRESS",
  220: "DAYS360",
  221: "TODAY",
  222: "VDB",
  223: "ELSE",
  224: "ELSE.IF",
  225: "END.IF",
  226: "FOR.CELL",
  227: "MEDIAN",
  228: "SUMPRODUCT",
  229: "SINH",
  230: "COSH",
  231: "TANH",
  232: "ASINH",
  233: "ACOSH",
  234: "ATANH",
  235: "DGET",
  236: "CREATE.OBJECT",
  237: "VOLATILE",
  238: "LAST.ERROR",
  239: "CUSTOM.UNDO",
  240: "CUSTOM.REPEAT",
  241: "FORMULA.CONVERT",
  242: "GET.LINK.INFO",
  243: "TEXT.BOX",
  244: "INFO",
  245: "GROUP",
  246: "GET.OBJECT",
  247: "DB",
  248: "PAUSE",
  251: "RESUME",
  252: "FREQUENCY",
  253: "ADD.TOOLBAR",
  254: "DELETE.TOOLBAR",
  255: "User",
  256: "RESET.TOOLBAR",
  257: "EVALUATE",
  258: "GET.TOOLBAR",
  259: "GET.TOOL",
  260: "SPELLING.CHECK",
  261: "ERROR.TYPE",
  262: "APP.TITLE",
  263: "WINDOW.TITLE",
  264: "SAVE.TOOLBAR",
  265: "ENABLE.TOOL",
  266: "PRESS.TOOL",
  267: "REGISTER.ID",
  268: "GET.WORKBOOK",
  269: "AVEDEV",
  270: "BETADIST",
  271: "GAMMALN",
  272: "BETAINV",
  273: "BINOMDIST",
  274: "CHIDIST",
  275: "CHIINV",
  276: "COMBIN",
  277: "CONFIDENCE",
  278: "CRITBINOM",
  279: "EVEN",
  280: "EXPONDIST",
  281: "FDIST",
  282: "FINV",
  283: "FISHER",
  284: "FISHERINV",
  285: "FLOOR",
  286: "GAMMADIST",
  287: "GAMMAINV",
  288: "CEILING",
  289: "HYPGEOMDIST",
  290: "LOGNORMDIST",
  291: "LOGINV",
  292: "NEGBINOMDIST",
  293: "NORMDIST",
  294: "NORMSDIST",
  295: "NORMINV",
  296: "NORMSINV",
  297: "STANDARDIZE",
  298: "ODD",
  299: "PERMUT",
  300: "POISSON",
  301: "TDIST",
  302: "WEIBULL",
  303: "SUMXMY2",
  304: "SUMX2MY2",
  305: "SUMX2PY2",
  306: "CHITEST",
  307: "CORREL",
  308: "COVAR",
  309: "FORECAST",
  310: "FTEST",
  311: "INTERCEPT",
  312: "PEARSON",
  313: "RSQ",
  314: "STEYX",
  315: "SLOPE",
  316: "TTEST",
  317: "PROB",
  318: "DEVSQ",
  319: "GEOMEAN",
  320: "HARMEAN",
  321: "SUMSQ",
  322: "KURT",
  323: "SKEW",
  324: "ZTEST",
  325: "LARGE",
  326: "SMALL",
  327: "QUARTILE",
  328: "PERCENTILE",
  329: "PERCENTRANK",
  330: "MODE",
  331: "TRIMMEAN",
  332: "TINV",
  334: "MOVIE.COMMAND",
  335: "GET.MOVIE",
  336: "CONCATENATE",
  337: "POWER",
  338: "PIVOT.ADD.DATA",
  339: "GET.PIVOT.TABLE",
  340: "GET.PIVOT.FIELD",
  341: "GET.PIVOT.ITEM",
  342: "RADIANS",
  343: "DEGREES",
  344: "SUBTOTAL",
  345: "SUMIF",
  346: "COUNTIF",
  347: "COUNTBLANK",
  348: "SCENARIO.GET",
  349: "OPTIONS.LISTS.GET",
  350: "ISPMT",
  351: "DATEDIF",
  352: "DATESTRING",
  353: "NUMBERSTRING",
  354: "ROMAN",
  355: "OPEN.DIALOG",
  356: "SAVE.DIALOG",
  357: "VIEW.GET",
  358: "GETPIVOTDATA",
  359: "HYPERLINK",
  360: "PHONETIC",
  361: "AVERAGEA",
  362: "MAXA",
  363: "MINA",
  364: "STDEVPA",
  365: "VARPA",
  366: "STDEVA",
  367: "VARA",
  368: "BAHTTEXT",
  369: "THAIDAYOFWEEK",
  370: "THAIDIGIT",
  371: "THAIMONTHOFYEAR",
  372: "THAINUMSOUND",
  373: "THAINUMSTRING",
  374: "THAISTRINGLENGTH",
  375: "ISTHAIDIGIT",
  376: "ROUNDBAHTDOWN",
  377: "ROUNDBAHTUP",
  378: "THAIYEAR",
  379: "RTD",
  380: "CUBEVALUE",
  381: "CUBEMEMBER",
  382: "CUBEMEMBERPROPERTY",
  383: "CUBERANKEDMEMBER",
  384: "HEX2BIN",
  385: "HEX2DEC",
  386: "HEX2OCT",
  387: "DEC2BIN",
  388: "DEC2HEX",
  389: "DEC2OCT",
  390: "OCT2BIN",
  391: "OCT2HEX",
  392: "OCT2DEC",
  393: "BIN2DEC",
  394: "BIN2OCT",
  395: "BIN2HEX",
  396: "IMSUB",
  397: "IMDIV",
  398: "IMPOWER",
  399: "IMABS",
  400: "IMSQRT",
  401: "IMLN",
  402: "IMLOG2",
  403: "IMLOG10",
  404: "IMSIN",
  405: "IMCOS",
  406: "IMEXP",
  407: "IMARGUMENT",
  408: "IMCONJUGATE",
  409: "IMAGINARY",
  410: "IMREAL",
  411: "COMPLEX",
  412: "IMSUM",
  413: "IMPRODUCT",
  414: "SERIESSUM",
  415: "FACTDOUBLE",
  416: "SQRTPI",
  417: "QUOTIENT",
  418: "DELTA",
  419: "GESTEP",
  420: "ISEVEN",
  421: "ISODD",
  422: "MROUND",
  423: "ERF",
  424: "ERFC",
  425: "BESSELJ",
  426: "BESSELK",
  427: "BESSELY",
  428: "BESSELI",
  429: "XIRR",
  430: "XNPV",
  431: "PRICEMAT",
  432: "YIELDMAT",
  433: "INTRATE",
  434: "RECEIVED",
  435: "DISC",
  436: "PRICEDISC",
  437: "YIELDDISC",
  438: "TBILLEQ",
  439: "TBILLPRICE",
  440: "TBILLYIELD",
  441: "PRICE",
  442: "YIELD",
  443: "DOLLARDE",
  444: "DOLLARFR",
  445: "NOMINAL",
  446: "EFFECT",
  447: "CUMPRINC",
  448: "CUMIPMT",
  449: "EDATE",
  450: "EOMONTH",
  451: "YEARFRAC",
  452: "COUPDAYBS",
  453: "COUPDAYS",
  454: "COUPDAYSNC",
  455: "COUPNCD",
  456: "COUPNUM",
  457: "COUPPCD",
  458: "DURATION",
  459: "MDURATION",
  460: "ODDLPRICE",
  461: "ODDLYIELD",
  462: "ODDFPRICE",
  463: "ODDFYIELD",
  464: "RANDBETWEEN",
  465: "WEEKNUM",
  466: "AMORDEGRC",
  467: "AMORLINC",
  468: "CONVERT",
  724: "SHEETJS",
  469: "ACCRINT",
  470: "ACCRINTM",
  471: "WORKDAY",
  472: "NETWORKDAYS",
  473: "GCD",
  474: "MULTINOMIAL",
  475: "LCM",
  476: "FVSCHEDULE",
  477: "CUBEKPIMEMBER",
  478: "CUBESET",
  479: "CUBESETCOUNT",
  480: "IFERROR",
  481: "COUNTIFS",
  482: "SUMIFS",
  483: "AVERAGEIF",
  484: "AVERAGEIFS"
};
var FtabArgc = {
  2: 1,
  3: 1,
  10: 0,
  15: 1,
  16: 1,
  17: 1,
  18: 1,
  19: 0,
  20: 1,
  21: 1,
  22: 1,
  23: 1,
  24: 1,
  25: 1,
  26: 1,
  27: 2,
  30: 2,
  31: 3,
  32: 1,
  33: 1,
  34: 0,
  35: 0,
  38: 1,
  39: 2,
  40: 3,
  41: 3,
  42: 3,
  43: 3,
  44: 3,
  45: 3,
  47: 3,
  48: 2,
  53: 1,
  61: 3,
  63: 0,
  65: 3,
  66: 3,
  67: 1,
  68: 1,
  69: 1,
  70: 1,
  71: 1,
  72: 1,
  73: 1,
  74: 0,
  75: 1,
  76: 1,
  77: 1,
  79: 2,
  80: 2,
  83: 1,
  85: 0,
  86: 1,
  89: 0,
  90: 1,
  94: 0,
  95: 0,
  97: 2,
  98: 1,
  99: 1,
  101: 3,
  102: 3,
  105: 1,
  106: 1,
  108: 2,
  111: 1,
  112: 1,
  113: 1,
  114: 1,
  117: 2,
  118: 1,
  119: 4,
  121: 1,
  126: 1,
  127: 1,
  128: 1,
  129: 1,
  130: 1,
  131: 1,
  133: 1,
  134: 1,
  135: 1,
  136: 2,
  137: 2,
  138: 2,
  140: 1,
  141: 1,
  142: 3,
  143: 4,
  144: 4,
  161: 1,
  162: 1,
  163: 1,
  164: 1,
  165: 2,
  172: 1,
  175: 2,
  176: 2,
  177: 3,
  178: 2,
  179: 1,
  184: 1,
  186: 1,
  189: 3,
  190: 1,
  195: 3,
  196: 3,
  197: 1,
  198: 1,
  199: 3,
  201: 1,
  207: 4,
  210: 3,
  211: 1,
  212: 2,
  213: 2,
  214: 1,
  215: 1,
  225: 0,
  229: 1,
  230: 1,
  231: 1,
  232: 1,
  233: 1,
  234: 1,
  235: 3,
  244: 1,
  247: 4,
  252: 2,
  257: 1,
  261: 1,
  271: 1,
  273: 4,
  274: 2,
  275: 2,
  276: 2,
  277: 3,
  278: 3,
  279: 1,
  280: 3,
  281: 3,
  282: 3,
  283: 1,
  284: 1,
  285: 2,
  286: 4,
  287: 3,
  288: 2,
  289: 4,
  290: 3,
  291: 3,
  292: 3,
  293: 4,
  294: 1,
  295: 3,
  296: 1,
  297: 3,
  298: 1,
  299: 2,
  300: 3,
  301: 3,
  302: 4,
  303: 2,
  304: 2,
  305: 2,
  306: 2,
  307: 2,
  308: 2,
  309: 3,
  310: 2,
  311: 2,
  312: 2,
  313: 2,
  314: 2,
  315: 2,
  316: 4,
  325: 2,
  326: 2,
  327: 2,
  328: 2,
  331: 2,
  332: 2,
  337: 2,
  342: 1,
  343: 1,
  346: 2,
  347: 1,
  350: 4,
  351: 3,
  352: 1,
  353: 2,
  360: 1,
  368: 1,
  369: 1,
  370: 1,
  371: 1,
  372: 1,
  373: 1,
  374: 1,
  375: 1,
  376: 1,
  377: 1,
  378: 1,
  382: 3,
  385: 1,
  392: 1,
  393: 1,
  396: 2,
  397: 2,
  398: 2,
  399: 1,
  400: 1,
  401: 1,
  402: 1,
  403: 1,
  404: 1,
  405: 1,
  406: 1,
  407: 1,
  408: 1,
  409: 1,
  410: 1,
  414: 4,
  415: 1,
  416: 1,
  417: 2,
  420: 1,
  421: 1,
  422: 2,
  424: 1,
  425: 2,
  426: 2,
  427: 2,
  428: 2,
  430: 3,
  438: 3,
  439: 3,
  440: 3,
  443: 2,
  444: 2,
  445: 2,
  446: 2,
  447: 6,
  448: 6,
  449: 2,
  450: 2,
  464: 2,
  468: 3,
  476: 2,
  479: 1,
  480: 2,
  65535: 0
};
/* Part 3 TODO: actually parse formulae */
function ods_to_csf_formula(f /*:string*/) /*:string*/{
  if (f.slice(0, 3) == "of:") f = f.slice(3);
  /* 5.2 Basic Expressions */
  if (f.charCodeAt(0) == 61) {
    f = f.slice(1);
    if (f.charCodeAt(0) == 61) f = f.slice(1);
  }
  f = f.replace(/COM\.MICROSOFT\./g, "");
  /* Part 3 Section 5.8 References */
  f = f.replace(/\[((?:\.[A-Z]+[0-9]+)(?::\.[A-Z]+[0-9]+)?)\]/g, function ($$, $1) {
    return $1.replace(/\./g, "");
  });
  /* TODO: something other than this */
  f = f.replace(/\[.(#[A-Z]*[?!])\]/g, "$1");
  return f.replace(/[;~]/g, ",").replace(/\|/g, ";");
}
function csf_to_ods_formula(f /*:string*/) /*:string*/{
  var o = "of:=" + f.replace(crefregex, "$1[.$2$3$4$5]").replace(/\]:\[/g, ":");
  /* TODO: something other than this */
  return o.replace(/;/g, "|").replace(/,/g, ";");
}
function ods_to_csf_3D(r /*:string*/) /*:[string, string]*/{
  var a = r.split(":");
  var s = a[0].split(".")[0];
  return [s, a[0].split(".")[1] + (a.length > 1 ? ":" + (a[1].split(".")[1] || a[1].split(".")[0]) : "")];
}
function csf_to_ods_3D(r /*:string*/) /*:string*/{
  return r.replace(/\./, "!");
}
var strs = {}; // shared strings
var _ssfopts = {}; // spreadsheet formatting options

/*global Map */
var browser_has_Map = typeof Map !== 'undefined';
function get_sst_id(sst /*:SST*/, str /*:string*/, rev) /*:number*/{
  var i = 0,
    len = sst.length;
  if (rev) {
    if (browser_has_Map ? rev.has(str) : Object.prototype.hasOwnProperty.call(rev, str)) {
      var revarr = browser_has_Map ? rev.get(str) : rev[str];
      for (; i < revarr.length; ++i) {
        if (sst[revarr[i]].t === str) {
          sst.Count++;
          return revarr[i];
        }
      }
    }
  } else for (; i < len; ++i) {
    if (sst[i].t === str) {
      sst.Count++;
      return i;
    }
  }
  sst[len] = {
    t: str
  } /*:any*/;
  sst.Count++;
  sst.Unique++;
  if (rev) {
    if (browser_has_Map) {
      if (!rev.has(str)) rev.set(str, []);
      rev.get(str).push(len);
    } else {
      if (!Object.prototype.hasOwnProperty.call(rev, str)) rev[str] = [];
      rev[str].push(len);
    }
  }
  return len;
}
function col_obj_w(C /*:number*/, col) {
  var p = {
    min: C + 1,
    max: C + 1
  } /*:any*/;
  /* wch (chars), wpx (pixels) */
  var wch = -1;
  if (col.MDW) MDW = col.MDW;
  if (col.width != null) p.customWidth = 1;else if (col.wpx != null) wch = px2char(col.wpx);else if (col.wch != null) wch = col.wch;
  if (wch > -1) {
    p.width = char2width(wch);
    p.customWidth = 1;
  } else if (col.width != null) p.width = col.width;
  if (col.hidden) p.hidden = true;
  if (col.level != null) {
    p.outlineLevel = p.level = col.level;
  }
  return p;
}
function default_margins(margins /*:Margins*/, mode /*:?string*/) {
  if (!margins) return;
  var defs = [0.7, 0.7, 0.75, 0.75, 0.3, 0.3];
  if (mode == 'xlml') defs = [1, 1, 1, 1, 0.5, 0.5];
  if (margins.left == null) margins.left = defs[0];
  if (margins.right == null) margins.right = defs[1];
  if (margins.top == null) margins.top = defs[2];
  if (margins.bottom == null) margins.bottom = defs[3];
  if (margins.header == null) margins.header = defs[4];
  if (margins.footer == null) margins.footer = defs[5];
}
function get_cell_style(styles /*:Array<any>*/, cell /*:Cell*/, opts) {
  var z = opts.revssf[cell.z != null ? cell.z : "General"];
  var i = 0x3c,
    len = styles.length;
  if (z == null && opts.ssf) {
    for (; i < 0x188; ++i) if (opts.ssf[i] == null) {
      SSF_load(cell.z, i);
      // $FlowIgnore
      opts.ssf[i] = cell.z;
      opts.revssf[cell.z] = z = i;
      break;
    }
  }
  for (i = 0; i != len; ++i) if (styles[i].numFmtId === z) return i;
  styles[len] = {
    numFmtId: z,
    fontId: 0,
    fillId: 0,
    borderId: 0,
    xfId: 0,
    applyNumberFormat: 1
  };
  return len;
}
function safe_format(p /*:Cell*/, fmtid /*:number*/, fillid /*:?number*/, opts, themes, styles) {
  try {
    if (opts.cellNF) p.z = table_fmt[fmtid];
  } catch (e) {
    if (opts.WTF) throw e;
  }
  if (p.t === 'z' && !opts.cellStyles) return;
  if (p.t === 'd' && typeof p.v === 'string') p.v = parseDate(p.v);
  if ((!opts || opts.cellText !== false) && p.t !== 'z') try {
    if (table_fmt[fmtid] == null) SSF_load(SSFImplicit[fmtid] || "General", fmtid);
    if (p.t === 'e') p.w = p.w || BErr[p.v];else if (fmtid === 0) {
      if (p.t === 'n') {
        if ((p.v | 0) === p.v) p.w = p.v.toString(10);else p.w = SSF_general_num(p.v);
      } else if (p.t === 'd') {
        var dd = datenum(p.v);
        if ((dd | 0) === dd) p.w = dd.toString(10);else p.w = SSF_general_num(dd);
      } else if (p.v === undefined) return "";else p.w = SSF_general(p.v, _ssfopts);
    } else if (p.t === 'd') p.w = SSF_format(fmtid, datenum(p.v), _ssfopts);else p.w = SSF_format(fmtid, p.v, _ssfopts);
  } catch (e) {
    if (opts.WTF) throw e;
  }
  if (!opts.cellStyles) return;
  if (fillid != null) try {
    p.s = styles.Fills[fillid];
    if (p.s.fgColor && p.s.fgColor.theme && !p.s.fgColor.rgb) {
      p.s.fgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.fgColor.theme].rgb, p.s.fgColor.tint || 0);
      if (opts.WTF) p.s.fgColor.raw_rgb = themes.themeElements.clrScheme[p.s.fgColor.theme].rgb;
    }
    if (p.s.bgColor && p.s.bgColor.theme) {
      p.s.bgColor.rgb = rgb_tint(themes.themeElements.clrScheme[p.s.bgColor.theme].rgb, p.s.bgColor.tint || 0);
      if (opts.WTF) p.s.bgColor.raw_rgb = themes.themeElements.clrScheme[p.s.bgColor.theme].rgb;
    }
  } catch (e) {
    if (opts.WTF && styles.Fills) throw e;
  }
}
function check_ws(ws /*:Worksheet*/, sname /*:string*/, i /*:number*/) {
  if (ws && ws['!ref']) {
    var range = safe_decode_range(ws['!ref']);
    if (range.e.c < range.s.c || range.e.r < range.s.r) throw new Error("Bad range (" + i + "): " + ws['!ref']);
  }
}
function parse_ws_xml_dim(ws /*:Worksheet*/, s /*:string*/) {
  var d = safe_decode_range(s);
  if (d.s.r <= d.e.r && d.s.c <= d.e.c && d.s.r >= 0 && d.s.c >= 0) ws["!ref"] = encode_range(d);
}
var mergecregex = /<(?:\w:)?mergeCell ref="[A-Z0-9:]+"\s*[\/]?>/g;
var sheetdataregex = /<(?:\w+:)?sheetData[^>]*>([\s\S]*)<\/(?:\w+:)?sheetData>/;
var hlinkregex = /<(?:\w:)?hyperlink [^>]*>/mg;
var dimregex = /"(\w*:\w*)"/;
var colregex = /<(?:\w:)?col\b[^>]*[\/]?>/g;
var afregex = /<(?:\w:)?autoFilter[^>]*([\/]|>([\s\S]*)<\/(?:\w:)?autoFilter)>/g;
var marginregex = /<(?:\w:)?pageMargins[^>]*\/>/g;
var sheetprregex = /<(?:\w:)?sheetPr\b(?:[^>a-z][^>]*)?\/>/;
var sheetprregex2 = /<(?:\w:)?sheetPr[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetPr)>/;
var svsregex = /<(?:\w:)?sheetViews[^>]*(?:[\/]|>([\s\S]*)<\/(?:\w:)?sheetViews)>/;

/* 18.3 Worksheets */
function parse_ws_xml(data /*:?string*/, opts, idx /*:number*/, rels, wb /*:WBWBProps*/, themes, styles) /*:Worksheet*/{
  if (!data) return data;
  if (!rels) rels = {
    '!id': {}
  };
  if (DENSE != null && opts.dense == null) opts.dense = DENSE;

  /* 18.3.1.99 worksheet CT_Worksheet */
  var s = opts.dense ? [] /*:any*/ : {} /*:any*/;
  var refguess /*:Range*/ = {
    s: {
      r: 2000000,
      c: 2000000
    },
    e: {
      r: 0,
      c: 0
    }
  } /*:any*/;
  var data1 = "",
    data2 = "";
  var mtch /*:?any*/ = data.match(sheetdataregex);
  if (mtch) {
    data1 = data.slice(0, mtch.index);
    data2 = data.slice(mtch.index + mtch[0].length);
  } else data1 = data2 = data;

  /* 18.3.1.82 sheetPr CT_SheetPr */
  var sheetPr = data1.match(sheetprregex);
  if (sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);else if (sheetPr = data1.match(sheetprregex2)) parse_ws_xml_sheetpr2(sheetPr[0], sheetPr[1] || "", s, wb, idx, styles, themes);

  /* 18.3.1.35 dimension CT_SheetDimension */
  var ridx = (data1.match(/<(?:\w*:)?dimension/) || {
    index: -1
  }).index;
  if (ridx > 0) {
    var ref = data1.slice(ridx, ridx + 50).match(dimregex);
    if (ref) parse_ws_xml_dim(s, ref[1]);
  }

  /* 18.3.1.88 sheetViews CT_SheetViews */
  var svs = data1.match(svsregex);
  if (svs && svs[1]) parse_ws_xml_sheetviews(svs[1], wb);

  /* 18.3.1.17 cols CT_Cols */
  var columns /*:Array<ColInfo>*/ = [];
  if (opts.cellStyles) {
    /* 18.3.1.13 col CT_Col */
    var cols = data1.match(colregex);
    if (cols) parse_ws_xml_cols(columns, cols);
  }

  /* 18.3.1.80 sheetData CT_SheetData ? */
  if (mtch) parse_ws_xml_data(mtch[1], s, opts, refguess, themes, styles);

  /* 18.3.1.2  autoFilter CT_AutoFilter */
  var afilter = data2.match(afregex);
  if (afilter) s['!autofilter'] = parse_ws_xml_autofilter(afilter[0]);

  /* 18.3.1.55 mergeCells CT_MergeCells */
  var merges /*:Array<Range>*/ = [];
  var _merge = data2.match(mergecregex);
  if (_merge) for (ridx = 0; ridx != _merge.length; ++ridx) merges[ridx] = safe_decode_range(_merge[ridx].slice(_merge[ridx].indexOf("\"") + 1));

  /* 18.3.1.48 hyperlinks CT_Hyperlinks */
  var hlink = data2.match(hlinkregex);
  if (hlink) parse_ws_xml_hlinks(s, hlink, rels);

  /* 18.3.1.62 pageMargins CT_PageMargins */
  var margins = data2.match(marginregex);
  if (margins) s['!margins'] = parse_ws_xml_margins(parsexmltag(margins[0]));
  if (!s["!ref"] && refguess.e.c >= refguess.s.c && refguess.e.r >= refguess.s.r) s["!ref"] = encode_range(refguess);
  if (opts.sheetRows > 0 && s["!ref"]) {
    var tmpref = safe_decode_range(s["!ref"]);
    if (opts.sheetRows <= +tmpref.e.r) {
      tmpref.e.r = opts.sheetRows - 1;
      if (tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
      if (tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
      if (tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
      if (tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
      s["!fullref"] = s["!ref"];
      s["!ref"] = encode_range(tmpref);
    }
  }
  if (columns.length > 0) s["!cols"] = columns;
  if (merges.length > 0) s["!merges"] = merges;
  return s;
}
function write_ws_xml_merges(merges /*:Array<Range>*/) /*:string*/{
  if (merges.length === 0) return "";
  var o = '<mergeCells count="' + merges.length + '">';
  for (var i = 0; i != merges.length; ++i) o += '<mergeCell ref="' + encode_range(merges[i]) + '"/>';
  return o + '</mergeCells>';
}

/* 18.3.1.82-3 sheetPr CT_ChartsheetPr / CT_SheetPr */
function parse_ws_xml_sheetpr(sheetPr /*:string*/, s, wb /*:WBWBProps*/, idx /*:number*/) {
  var data = parsexmltag(sheetPr);
  if (!wb.Sheets[idx]) wb.Sheets[idx] = {};
  if (data.codeName) wb.Sheets[idx].CodeName = unescapexml(utf8read(data.codeName));
}
function parse_ws_xml_sheetpr2(sheetPr /*:string*/, body /*:string*/, s, wb /*:WBWBProps*/, idx /*:number*/) {
  parse_ws_xml_sheetpr(sheetPr.slice(0, sheetPr.indexOf(">")), s, wb, idx);
}
function write_ws_xml_sheetpr(ws, wb, idx, opts, o) {
  var needed = false;
  var props = {},
    payload = null;
  if (opts.bookType !== 'xlsx' && wb.vbaraw) {
    var cname = wb.SheetNames[idx];
    try {
      if (wb.Workbook) cname = wb.Workbook.Sheets[idx].CodeName || cname;
    } catch (e) {}
    needed = true;
    props.codeName = utf8write(escapexml(cname));
  }
  if (ws && ws["!outline"]) {
    var outlineprops = {
      summaryBelow: 1,
      summaryRight: 1
    };
    if (ws["!outline"].above) outlineprops.summaryBelow = 0;
    if (ws["!outline"].left) outlineprops.summaryRight = 0;
    payload = (payload || "") + writextag('outlinePr', null, outlineprops);
  }
  if (!needed && !payload) return;
  o[o.length] = writextag('sheetPr', payload, props);
}

/* 18.3.1.85 sheetProtection CT_SheetProtection */
var sheetprot_deffalse = ["objects", "scenarios", "selectLockedCells", "selectUnlockedCells"];
var sheetprot_deftrue = ["formatColumns", "formatRows", "formatCells", "insertColumns", "insertRows", "insertHyperlinks", "deleteColumns", "deleteRows", "sort", "autoFilter", "pivotTables"];
function write_ws_xml_protection(sp) /*:string*/{
  // algorithmName, hashValue, saltValue, spinCount
  var o = {
    sheet: 1
  } /*:any*/;
  sheetprot_deffalse.forEach(function (n) {
    if (sp[n] != null && sp[n]) o[n] = "1";
  });
  sheetprot_deftrue.forEach(function (n) {
    if (sp[n] != null && !sp[n]) o[n] = "0";
  });
  /* TODO: algorithm */
  if (sp.password) o.password = crypto_CreatePasswordVerifier_Method1(sp.password).toString(16).toUpperCase();
  return writextag('sheetProtection', null, o);
}
function parse_ws_xml_hlinks(s, data /*:Array<string>*/, rels) {
  var dense = Array.isArray(s);
  for (var i = 0; i != data.length; ++i) {
    var val = parsexmltag(utf8read(data[i]), true);
    if (!val.ref) return;
    var rel = ((rels || {})['!id'] || [])[val.id];
    if (rel) {
      val.Target = rel.Target;
      if (val.location) val.Target += "#" + unescapexml(val.location);
    } else {
      val.Target = "#" + unescapexml(val.location);
      rel = {
        Target: val.Target,
        TargetMode: 'Internal'
      };
    }
    val.Rel = rel;
    if (val.tooltip) {
      val.Tooltip = val.tooltip;
      delete val.tooltip;
    }
    var rng = safe_decode_range(val.ref);
    for (var R = rng.s.r; R <= rng.e.r; ++R) for (var C = rng.s.c; C <= rng.e.c; ++C) {
      var addr = encode_cell({
        c: C,
        r: R
      });
      if (dense) {
        if (!s[R]) s[R] = [];
        if (!s[R][C]) s[R][C] = {
          t: "z",
          v: undefined
        };
        s[R][C].l = val;
      } else {
        if (!s[addr]) s[addr] = {
          t: "z",
          v: undefined
        };
        s[addr].l = val;
      }
    }
  }
}
function parse_ws_xml_margins(margin) {
  var o = {};
  ["left", "right", "top", "bottom", "header", "footer"].forEach(function (k) {
    if (margin[k]) o[k] = parseFloat(margin[k]);
  });
  return o;
}
function write_ws_xml_margins(margin) /*:string*/{
  default_margins(margin);
  return writextag('pageMargins', null, margin);
}
function parse_ws_xml_cols(columns, cols) {
  var seencol = false;
  for (var coli = 0; coli != cols.length; ++coli) {
    var coll = parsexmltag(cols[coli], true);
    if (coll.hidden) coll.hidden = parsexmlbool(coll.hidden);
    var colm = parseInt(coll.min, 10) - 1,
      colM = parseInt(coll.max, 10) - 1;
    if (coll.outlineLevel) coll.level = +coll.outlineLevel || 0;
    delete coll.min;
    delete coll.max;
    coll.width = +coll.width;
    if (!seencol && coll.width) {
      seencol = true;
      find_mdw_colw(coll.width);
    }
    process_col(coll);
    while (colm <= colM) columns[colm++] = dup(coll);
  }
}
function write_ws_xml_cols(ws, cols) /*:string*/{
  var o = ["<cols>"],
    col;
  for (var i = 0; i != cols.length; ++i) {
    if (!(col = cols[i])) continue;
    o[o.length] = writextag('col', null, col_obj_w(i, col));
  }
  o[o.length] = "</cols>";
  return o.join("");
}
function parse_ws_xml_autofilter(data /*:string*/) {
  var o = {
    ref: (data.match(/ref="([^"]*)"/) || [])[1]
  };
  return o;
}
function write_ws_xml_autofilter(data, ws, wb, idx) /*:string*/{
  var ref = typeof data.ref == "string" ? data.ref : encode_range(data.ref);
  if (!wb.Workbook) wb.Workbook = {
    Sheets: []
  } /*:any*/;
  if (!wb.Workbook.Names) wb.Workbook.Names = [];
  var names /*: Array<any> */ = wb.Workbook.Names;
  var range = decode_range(ref);
  if (range.s.r == range.e.r) {
    range.e.r = decode_range(ws["!ref"]).e.r;
    ref = encode_range(range);
  }
  for (var i = 0; i < names.length; ++i) {
    var name = names[i];
    if (name.Name != '_xlnm._FilterDatabase') continue;
    if (name.Sheet != idx) continue;
    name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref;
    break;
  }
  if (i == names.length) names.push({
    Name: '_xlnm._FilterDatabase',
    Sheet: idx,
    Ref: "'" + wb.SheetNames[idx] + "'!" + ref
  });
  return writextag("autoFilter", null, {
    ref: ref
  });
}

/* 18.3.1.88 sheetViews CT_SheetViews */
/* 18.3.1.87 sheetView CT_SheetView */
var sviewregex = /<(?:\w:)?sheetView(?:[^>a-z][^>]*)?\/?>/;
function parse_ws_xml_sheetviews(data, wb /*:WBWBProps*/) {
  if (!wb.Views) wb.Views = [{}];
  (data.match(sviewregex) || []).forEach(function (r /*:string*/, i /*:number*/) {
    var tag = parsexmltag(r);
    // $FlowIgnore
    if (!wb.Views[i]) wb.Views[i] = {};
    // $FlowIgnore
    if (+tag.zoomScale) wb.Views[i].zoom = +tag.zoomScale;
    // $FlowIgnore
    if (parsexmlbool(tag.rightToLeft)) wb.Views[i].RTL = true;
  });
}
function write_ws_xml_sheetviews(ws, opts, idx, wb) /*:string*/{
  var sview = {
    workbookViewId: "0"
  } /*:any*/;
  // $FlowIgnore
  if ((((wb || {}).Workbook || {}).Views || [])[0]) sview.rightToLeft = wb.Workbook.Views[0].RTL ? "1" : "0";
  return writextag("sheetViews", writextag("sheetView", null, sview), {});
}
function write_ws_xml_cell(cell /*:Cell*/, ref, ws, opts /*::, idx, wb*/) /*:string*/{
  if (cell.c) ws['!comments'].push([ref, cell.c]);
  if (cell.v === undefined && typeof cell.f !== "string" || cell.t === 'z' && !cell.f) return "";
  var vv = "";
  var oldt = cell.t,
    oldv = cell.v;
  if (cell.t !== "z") switch (cell.t) {
    case 'b':
      vv = cell.v ? "1" : "0";
      break;
    case 'n':
      vv = '' + cell.v;
      break;
    case 'e':
      vv = BErr[cell.v];
      break;
    case 'd':
      if (opts && opts.cellDates) vv = parseDate(cell.v, -1).toISOString();else {
        cell = dup(cell);
        cell.t = 'n';
        vv = '' + (cell.v = datenum(parseDate(cell.v)));
      }
      if (typeof cell.z === 'undefined') cell.z = table_fmt[14];
      break;
    default:
      vv = cell.v;
      break;
  }
  var v = writetag('v', escapexml(vv)),
    o = {
      r: ref
    } /*:any*/;
  /* TODO: cell style */
  var os = get_cell_style(opts.cellXfs, cell, opts);
  if (os !== 0) o.s = os;
  switch (cell.t) {
    case 'n':
      break;
    case 'd':
      o.t = "d";
      break;
    case 'b':
      o.t = "b";
      break;
    case 'e':
      o.t = "e";
      break;
    case 'z':
      break;
    default:
      if (cell.v == null) {
        delete cell.t;
        break;
      }
      if (cell.v.length > 32767) throw new Error("Text length must not exceed 32767 characters");
      if (opts && opts.bookSST) {
        v = writetag('v', '' + get_sst_id(opts.Strings, cell.v, opts.revStrings));
        o.t = "s";
        break;
      }
      o.t = "str";
      break;
  }
  if (cell.t != oldt) {
    cell.t = oldt;
    cell.v = oldv;
  }
  if (typeof cell.f == "string" && cell.f) {
    var ff = cell.F && cell.F.slice(0, ref.length) == ref ? {
      t: "array",
      ref: cell.F
    } : null;
    v = writextag('f', escapexml(cell.f), ff) + (cell.v != null ? v : "");
  }
  if (cell.l) ws['!links'].push([ref, cell.l]);
  if (cell.D) o.cm = 1;
  return writextag('c', v, o);
}
var parse_ws_xml_data = /*#__PURE__*/function () {
  var cellregex = /<(?:\w+:)?c[ \/>]/,
    rowregex = /<\/(?:\w+:)?row>/;
  var rregex = /r=["']([^"']*)["']/,
    isregex = /<(?:\w+:)?is>([\S\s]*?)<\/(?:\w+:)?is>/;
  var refregex = /ref=["']([^"']*)["']/;
  var match_v = matchtag("v"),
    match_f = matchtag("f");
  return function parse_ws_xml_data(sdata /*:string*/, s, opts, guess /*:Range*/, themes, styles) {
    var ri = 0,
      x = "",
      cells /*:Array<string>*/ = [],
      cref /*:?Array<string>*/ = [],
      idx = 0,
      i = 0,
      cc = 0,
      d = "",
      p /*:any*/;
    var tag,
      tagr = 0,
      tagc = 0;
    var sstr, ftag;
    var fmtid = 0,
      fillid = 0;
    var do_format = Array.isArray(styles.CellXf),
      cf;
    var arrayf /*:Array<[Range, string]>*/ = [];
    var sharedf = [];
    var dense = Array.isArray(s);
    var rows /*:Array<RowInfo>*/ = [],
      rowobj = {},
      rowrite = false;
    var sheetStubs = !!opts.sheetStubs;
    for (var marr = sdata.split(rowregex), mt = 0, marrlen = marr.length; mt != marrlen; ++mt) {
      x = marr[mt].trim();
      var xlen = x.length;
      if (xlen === 0) continue;

      /* 18.3.1.73 row CT_Row */
      var rstarti = 0;
      outa: for (ri = 0; ri < xlen; ++ri) switch (/*x.charCodeAt(ri)*/x[ri]) {
        case ">" /*62*/:
          if (/*x.charCodeAt(ri-1) != 47*/x[ri - 1] != "/") {
            ++ri;
            break outa;
          }
          if (opts && opts.cellStyles) {
            // TODO: avoid duplication
            tag = parsexmltag(x.slice(rstarti, ri), true);
            tagr = tag.r != null ? parseInt(tag.r, 10) : tagr + 1;
            tagc = -1;
            if (opts.sheetRows && opts.sheetRows < tagr) continue;
            rowobj = {};
            rowrite = false;
            if (tag.ht) {
              rowrite = true;
              rowobj.hpt = parseFloat(tag.ht);
              rowobj.hpx = pt2px(rowobj.hpt);
            }
            if (tag.hidden == "1") {
              rowrite = true;
              rowobj.hidden = true;
            }
            if (tag.outlineLevel != null) {
              rowrite = true;
              rowobj.level = +tag.outlineLevel;
            }
            if (rowrite) rows[tagr - 1] = rowobj;
          }
          break;
        case "<" /*60*/:
          rstarti = ri;
          break;
      }
      if (rstarti >= ri) break;
      tag = parsexmltag(x.slice(rstarti, ri), true);
      tagr = tag.r != null ? parseInt(tag.r, 10) : tagr + 1;
      tagc = -1;
      if (opts.sheetRows && opts.sheetRows < tagr) continue;
      if (guess.s.r > tagr - 1) guess.s.r = tagr - 1;
      if (guess.e.r < tagr - 1) guess.e.r = tagr - 1;
      if (opts && opts.cellStyles) {
        rowobj = {};
        rowrite = false;
        if (tag.ht) {
          rowrite = true;
          rowobj.hpt = parseFloat(tag.ht);
          rowobj.hpx = pt2px(rowobj.hpt);
        }
        if (tag.hidden == "1") {
          rowrite = true;
          rowobj.hidden = true;
        }
        if (tag.outlineLevel != null) {
          rowrite = true;
          rowobj.level = +tag.outlineLevel;
        }
        if (rowrite) rows[tagr - 1] = rowobj;
      }

      /* 18.3.1.4 c CT_Cell */
      cells = x.slice(ri).split(cellregex);
      for (var rslice = 0; rslice != cells.length; ++rslice) if (cells[rslice].trim().charAt(0) != "<") break;
      cells = cells.slice(rslice);
      for (ri = 0; ri != cells.length; ++ri) {
        x = cells[ri].trim();
        if (x.length === 0) continue;
        cref = x.match(rregex);
        idx = ri;
        i = 0;
        cc = 0;
        x = "<c " + (x.slice(0, 1) == "<" ? ">" : "") + x;
        if (cref != null && cref.length === 2) {
          idx = 0;
          d = cref[1];
          for (i = 0; i != d.length; ++i) {
            if ((cc = d.charCodeAt(i) - 64) < 1 || cc > 26) break;
            idx = 26 * idx + cc;
          }
          --idx;
          tagc = idx;
        } else ++tagc;
        for (i = 0; i != x.length; ++i) if (x.charCodeAt(i) === 62) break;
        ++i;
        tag = parsexmltag(x.slice(0, i), true);
        if (!tag.r) tag.r = encode_cell({
          r: tagr - 1,
          c: tagc
        });
        d = x.slice(i);
        p = {
          t: ""
        } /*:any*/;
        if ((cref = d.match(match_v)) != null && /*::cref != null && */cref[1] !== '') p.v = unescapexml(cref[1]);
        if (opts.cellFormula) {
          if ((cref = d.match(match_f)) != null && /*::cref != null && */cref[1] !== '') {
            /* TODO: match against XLSXFutureFunctions */
            p.f = unescapexml(utf8read(cref[1])).replace(/\r\n/g, "\n");
            if (!opts.xlfn) p.f = _xlfn(p.f);
            if (/*::cref != null && cref[0] != null && */cref[0].indexOf('t="array"') > -1) {
              p.F = (d.match(refregex) || [])[1];
              if (p.F.indexOf(":") > -1) arrayf.push([safe_decode_range(p.F), p.F]);
            } else if (/*::cref != null && cref[0] != null && */cref[0].indexOf('t="shared"') > -1) {
              // TODO: parse formula
              ftag = parsexmltag(cref[0]);
              var ___f = unescapexml(utf8read(cref[1]));
              if (!opts.xlfn) ___f = _xlfn(___f);
              sharedf[parseInt(ftag.si, 10)] = [ftag, ___f, tag.r];
            }
          } else if (cref = d.match(/<f[^>]*\/>/)) {
            ftag = parsexmltag(cref[0]);
            if (sharedf[ftag.si]) p.f = shift_formula_xlsx(sharedf[ftag.si][1], sharedf[ftag.si][2] /*[0].ref*/, tag.r);
          }
          /* TODO: factor out contains logic */
          var _tag = decode_cell(tag.r);
          for (i = 0; i < arrayf.length; ++i) if (_tag.r >= arrayf[i][0].s.r && _tag.r <= arrayf[i][0].e.r) if (_tag.c >= arrayf[i][0].s.c && _tag.c <= arrayf[i][0].e.c) p.F = arrayf[i][1];
        }
        if (tag.t == null && p.v === undefined) {
          if (p.f || p.F) {
            p.v = 0;
            p.t = "n";
          } else if (!sheetStubs) continue;else p.t = "z";
        } else p.t = tag.t || "n";
        if (guess.s.c > tagc) guess.s.c = tagc;
        if (guess.e.c < tagc) guess.e.c = tagc;
        /* 18.18.11 t ST_CellType */
        switch (p.t) {
          case 'n':
            if (p.v == "" || p.v == null) {
              if (!sheetStubs) continue;
              p.t = 'z';
            } else p.v = parseFloat(p.v);
            break;
          case 's':
            if (typeof p.v == 'undefined') {
              if (!sheetStubs) continue;
              p.t = 'z';
            } else {
              sstr = strs[parseInt(p.v, 10)];
              p.v = sstr.t;
              p.r = sstr.r;
              if (opts.cellHTML) p.h = sstr.h;
            }
            break;
          case 'str':
            p.t = "s";
            p.v = p.v != null ? utf8read(p.v) : '';
            if (opts.cellHTML) p.h = escapehtml(p.v);
            break;
          case 'inlineStr':
            cref = d.match(isregex);
            p.t = 's';
            if (cref != null && (sstr = parse_si(cref[1]))) {
              p.v = sstr.t;
              if (opts.cellHTML) p.h = sstr.h;
            } else p.v = "";
            break;
          case 'b':
            p.v = parsexmlbool(p.v);
            break;
          case 'd':
            if (opts.cellDates) p.v = parseDate(p.v, 1);else {
              p.v = datenum(parseDate(p.v, 1));
              p.t = 'n';
            }
            break;
          /* error string in .w, number in .v */
          case 'e':
            if (!opts || opts.cellText !== false) p.w = p.v;
            p.v = RBErr[p.v];
            break;
        }
        /* formatting */
        fmtid = fillid = 0;
        cf = null;
        if (do_format && tag.s !== undefined) {
          cf = styles.CellXf[tag.s];
          if (cf != null) {
            if (cf.numFmtId != null) fmtid = cf.numFmtId;
            if (opts.cellStyles) {
              if (cf.fillId != null) fillid = cf.fillId;
            }
          }
        }
        safe_format(p, fmtid, fillid, opts, themes, styles);
        if (opts.cellDates && do_format && p.t == 'n' && fmt_is_date(table_fmt[fmtid])) {
          p.t = 'd';
          p.v = numdate(p.v);
        }
        if (tag.cm && opts.xlmeta) {
          var cm = (opts.xlmeta.Cell || [])[+tag.cm - 1];
          if (cm && cm.type == 'XLDAPR') p.D = true;
        }
        if (dense) {
          var _r = decode_cell(tag.r);
          if (!s[_r.r]) s[_r.r] = [];
          s[_r.r][_r.c] = p;
        } else s[tag.r] = p;
      }
    }
    if (rows.length > 0) s['!rows'] = rows;
  };
}();
function write_ws_xml_data(ws /*:Worksheet*/, opts, idx /*:number*/, wb /*:Workbook*/ /*::, rels*/) /*:string*/{
  var o /*:Array<string>*/ = [],
    r /*:Array<string>*/ = [],
    range = safe_decode_range(ws['!ref']),
    cell = "",
    ref,
    rr = "",
    cols /*:Array<string>*/ = [],
    R = 0,
    C = 0,
    rows = ws['!rows'];
  var dense = Array.isArray(ws);
  var params = {
      r: rr
    } /*:any*/,
    row /*:RowInfo*/,
    height = -1;
  for (C = range.s.c; C <= range.e.c; ++C) cols[C] = encode_col(C);
  for (R = range.s.r; R <= range.e.r; ++R) {
    r = [];
    rr = encode_row(R);
    for (C = range.s.c; C <= range.e.c; ++C) {
      ref = cols[C] + rr;
      var _cell = dense ? (ws[R] || [])[C] : ws[ref];
      if (_cell === undefined) continue;
      if ((cell = write_ws_xml_cell(_cell, ref, ws, opts, idx, wb)) != null) r.push(cell);
    }
    if (r.length > 0 || rows && rows[R]) {
      params = {
        r: rr
      } /*:any*/;
      if (rows && rows[R]) {
        row = rows[R];
        if (row.hidden) params.hidden = 1;
        height = -1;
        if (row.hpx) height = px2pt(row.hpx);else if (row.hpt) height = row.hpt;
        if (height > -1) {
          params.ht = height;
          params.customHeight = 1;
        }
        if (row.level) {
          params.outlineLevel = row.level;
        }
      }
      o[o.length] = writextag('row', r.join(""), params);
    }
  }
  if (rows) for (; R < rows.length; ++R) {
    if (rows && rows[R]) {
      params = {
        r: R + 1
      } /*:any*/;
      row = rows[R];
      if (row.hidden) params.hidden = 1;
      height = -1;
      if (row.hpx) height = px2pt(row.hpx);else if (row.hpt) height = row.hpt;
      if (height > -1) {
        params.ht = height;
        params.customHeight = 1;
      }
      if (row.level) {
        params.outlineLevel = row.level;
      }
      o[o.length] = writextag('row', "", params);
    }
  }
  return o.join("");
}
function write_ws_xml(idx /*:number*/, opts, wb /*:Workbook*/, rels) /*:string*/{
  var o = [XML_HEADER, writextag('worksheet', null, {
    'xmlns': XMLNS_main[0],
    'xmlns:r': XMLNS.r
  })];
  var s = wb.SheetNames[idx],
    sidx = 0,
    rdata = "";
  var ws = wb.Sheets[s];
  if (ws == null) ws = {};
  var ref = ws['!ref'] || 'A1';
  var range = safe_decode_range(ref);
  if (range.e.c > 0x3FFF || range.e.r > 0xFFFFF) {
    if (opts.WTF) throw new Error("Range " + ref + " exceeds format limit A1:XFD1048576");
    range.e.c = Math.min(range.e.c, 0x3FFF);
    range.e.r = Math.min(range.e.c, 0xFFFFF);
    ref = encode_range(range);
  }
  if (!rels) rels = {};
  ws['!comments'] = [];
  var _drawing = [];
  write_ws_xml_sheetpr(ws, wb, idx, opts, o);
  o[o.length] = writextag('dimension', null, {
    'ref': ref
  });
  o[o.length] = write_ws_xml_sheetviews(ws, opts, idx, wb);

  /* TODO: store in WB, process styles */
  if (opts.sheetFormat) o[o.length] = writextag('sheetFormatPr', null, {
    defaultRowHeight: opts.sheetFormat.defaultRowHeight || '16',
    baseColWidth: opts.sheetFormat.baseColWidth || '10',
    outlineLevelRow: opts.sheetFormat.outlineLevelRow || '7'
  });
  if (ws['!cols'] != null && ws['!cols'].length > 0) o[o.length] = write_ws_xml_cols(ws, ws['!cols']);
  o[sidx = o.length] = '<sheetData/>';
  ws['!links'] = [];
  if (ws['!ref'] != null) {
    rdata = write_ws_xml_data(ws, opts, idx, wb, rels);
    if (rdata.length > 0) o[o.length] = rdata;
  }
  if (o.length > sidx + 1) {
    o[o.length] = '</sheetData>';
    o[sidx] = o[sidx].replace("/>", ">");
  }

  /* sheetCalcPr */

  if (ws['!protect']) o[o.length] = write_ws_xml_protection(ws['!protect']);

  /* protectedRanges */
  /* scenarios */

  if (ws['!autofilter'] != null) o[o.length] = write_ws_xml_autofilter(ws['!autofilter'], ws, wb, idx);

  /* sortState */
  /* dataConsolidate */
  /* customSheetViews */

  if (ws['!merges'] != null && ws['!merges'].length > 0) o[o.length] = write_ws_xml_merges(ws['!merges']);

  /* phoneticPr */
  /* conditionalFormatting */
  /* dataValidations */

  var relc = -1,
    rel,
    rId = -1;
  if (/*::(*/ws['!links'] /*::||[])*/.length > 0) {
    o[o.length] = "<hyperlinks>";
    /*::(*/
    ws['!links'] /*::||[])*/.forEach(function (l) {
      if (!l[1].Target) return;
      rel = {
        "ref": l[0]
      } /*:any*/;
      if (l[1].Target.charAt(0) != "#") {
        rId = add_rels(rels, -1, escapexml(l[1].Target).replace(/#.*$/, ""), RELS.HLINK);
        rel["r:id"] = "rId" + rId;
      }
      if ((relc = l[1].Target.indexOf("#")) > -1) rel.location = escapexml(l[1].Target.slice(relc + 1));
      if (l[1].Tooltip) rel.tooltip = escapexml(l[1].Tooltip);
      o[o.length] = writextag("hyperlink", null, rel);
    });
    o[o.length] = "</hyperlinks>";
  }
  delete ws['!links'];

  /* printOptions */

  if (ws['!margins'] != null) o[o.length] = write_ws_xml_margins(ws['!margins']);

  /* pageSetup */
  /* headerFooter */
  /* rowBreaks */
  /* colBreaks */
  /* customProperties */
  /* cellWatches */

  if (!opts || opts.ignoreEC || opts.ignoreEC == void 0) o[o.length] = writetag("ignoredErrors", writextag("ignoredError", null, {
    numberStoredAsText: 1,
    sqref: ref
  }));

  /* smartTags */

  if (_drawing.length > 0) {
    rId = add_rels(rels, -1, "../drawings/drawing" + (idx + 1) + ".xml", RELS.DRAW);
    o[o.length] = writextag("drawing", null, {
      "r:id": "rId" + rId
    });
    ws['!drawing'] = _drawing;
  }
  if (ws['!comments'].length > 0) {
    rId = add_rels(rels, -1, "../drawings/vmlDrawing" + (idx + 1) + ".vml", RELS.VML);
    o[o.length] = writextag("legacyDrawing", null, {
      "r:id": "rId" + rId
    });
    ws['!legacy'] = rId;
  }

  /* legacyDrawingHF */
  /* picture */
  /* oleObjects */
  /* controls */
  /* webPublishItems */
  /* tableParts */
  /* extLst */

  if (o.length > 1) {
    o[o.length] = '</worksheet>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}

/* [MS-XLSB] 2.4.726 BrtRowHdr */
function parse_BrtRowHdr(data, length) {
  var z = {} /*:any*/;
  var tgt = data.l + length;
  z.r = data.read_shift(4);
  data.l += 4; // TODO: ixfe
  var miyRw = data.read_shift(2);
  data.l += 1; // TODO: top/bot padding
  var flags = data.read_shift(1);
  data.l = tgt;
  if (flags & 0x07) z.level = flags & 0x07;
  if (flags & 0x10) z.hidden = true;
  if (flags & 0x20) z.hpt = miyRw / 20;
  return z;
}
function write_BrtRowHdr(R /*:number*/, range, ws) {
  var o = new_buf(17 + 8 * 16);
  var row = (ws['!rows'] || [])[R] || {};
  o.write_shift(4, R);
  o.write_shift(4, 0); /* TODO: ixfe */

  var miyRw = 0x0140;
  if (row.hpx) miyRw = px2pt(row.hpx) * 20;else if (row.hpt) miyRw = row.hpt * 20;
  o.write_shift(2, miyRw);
  o.write_shift(1, 0); /* top/bot padding */

  var flags = 0x0;
  if (row.level) flags |= row.level;
  if (row.hidden) flags |= 0x10;
  if (row.hpx || row.hpt) flags |= 0x20;
  o.write_shift(1, flags);
  o.write_shift(1, 0); /* phonetic guide */

  /* [MS-XLSB] 2.5.8 BrtColSpan explains the mechanism */
  var ncolspan = 0,
    lcs = o.l;
  o.l += 4;
  var caddr = {
    r: R,
    c: 0
  };
  for (var i = 0; i < 16; ++i) {
    if (range.s.c > i + 1 << 10 || range.e.c < i << 10) continue;
    var first = -1,
      last = -1;
    for (var j = i << 10; j < i + 1 << 10; ++j) {
      caddr.c = j;
      var cell = Array.isArray(ws) ? (ws[caddr.r] || [])[caddr.c] : ws[encode_cell(caddr)];
      if (cell) {
        if (first < 0) first = j;
        last = j;
      }
    }
    if (first < 0) continue;
    ++ncolspan;
    o.write_shift(4, first);
    o.write_shift(4, last);
  }
  var l = o.l;
  o.l = lcs;
  o.write_shift(4, ncolspan);
  o.l = l;
  return o.length > o.l ? o.slice(0, o.l) : o;
}
function write_row_header(ba, ws, range, R) {
  var o = write_BrtRowHdr(R, range, ws);
  if (o.length > 17 || (ws['!rows'] || [])[R]) write_record(ba, 0x0000 /* BrtRowHdr */, o);
}

/* [MS-XLSB] 2.4.820 BrtWsDim */
var parse_BrtWsDim = parse_UncheckedRfX;
var write_BrtWsDim = write_UncheckedRfX;

/* [MS-XLSB] 2.4.821 BrtWsFmtInfo */
function parse_BrtWsFmtInfo(/*::data, length*/
) {}
//function write_BrtWsFmtInfo(ws, o) { }

/* [MS-XLSB] 2.4.823 BrtWsProp */
function parse_BrtWsProp(data, length) {
  var z = {};
  var f = data[data.l];
  ++data.l;
  z.above = !(f & 0x40);
  z.left = !(f & 0x80);
  /* TODO: pull flags */
  data.l += 18;
  z.name = parse_XLSBCodeName(data, length - 19);
  return z;
}
function write_BrtWsProp(str, outl, o) {
  if (o == null) o = new_buf(84 + 4 * str.length);
  var f = 0xC0;
  if (outl) {
    if (outl.above) f &= ~0x40;
    if (outl.left) f &= ~0x80;
  }
  o.write_shift(1, f);
  for (var i = 1; i < 3; ++i) o.write_shift(1, 0);
  write_BrtColor({
    auto: 1
  }, o);
  o.write_shift(-4, -1);
  o.write_shift(-4, -1);
  write_XLSBCodeName(str, o);
  return o.slice(0, o.l);
}

/* [MS-XLSB] 2.4.306 BrtCellBlank */
function parse_BrtCellBlank(data) {
  var cell = parse_XLSBCell(data);
  return [cell];
}
function write_BrtCellBlank(cell, ncell, o) {
  if (o == null) o = new_buf(8);
  return write_XLSBCell(ncell, o);
}
function parse_BrtShortBlank(data) {
  var cell = parse_XLSBShortCell(data);
  return [cell];
}
function write_BrtShortBlank(cell, ncell, o) {
  if (o == null) o = new_buf(4);
  return write_XLSBShortCell(ncell, o);
}

/* [MS-XLSB] 2.4.307 BrtCellBool */
function parse_BrtCellBool(data) {
  var cell = parse_XLSBCell(data);
  var fBool = data.read_shift(1);
  return [cell, fBool, 'b'];
}
function write_BrtCellBool(cell, ncell, o) {
  if (o == null) o = new_buf(9);
  write_XLSBCell(ncell, o);
  o.write_shift(1, cell.v ? 1 : 0);
  return o;
}
function parse_BrtShortBool(data) {
  var cell = parse_XLSBShortCell(data);
  var fBool = data.read_shift(1);
  return [cell, fBool, 'b'];
}
function write_BrtShortBool(cell, ncell, o) {
  if (o == null) o = new_buf(5);
  write_XLSBShortCell(ncell, o);
  o.write_shift(1, cell.v ? 1 : 0);
  return o;
}

/* [MS-XLSB] 2.4.308 BrtCellError */
function parse_BrtCellError(data) {
  var cell = parse_XLSBCell(data);
  var bError = data.read_shift(1);
  return [cell, bError, 'e'];
}
function write_BrtCellError(cell, ncell, o) {
  if (o == null) o = new_buf(9);
  write_XLSBCell(ncell, o);
  o.write_shift(1, cell.v);
  return o;
}
function parse_BrtShortError(data) {
  var cell = parse_XLSBShortCell(data);
  var bError = data.read_shift(1);
  return [cell, bError, 'e'];
}
function write_BrtShortError(cell, ncell, o) {
  if (o == null) o = new_buf(8);
  write_XLSBShortCell(ncell, o);
  o.write_shift(1, cell.v);
  o.write_shift(2, 0);
  o.write_shift(1, 0);
  return o;
}

/* [MS-XLSB] 2.4.311 BrtCellIsst */
function parse_BrtCellIsst(data) {
  var cell = parse_XLSBCell(data);
  var isst = data.read_shift(4);
  return [cell, isst, 's'];
}
function write_BrtCellIsst(cell, ncell, o) {
  if (o == null) o = new_buf(12);
  write_XLSBCell(ncell, o);
  o.write_shift(4, ncell.v);
  return o;
}
function parse_BrtShortIsst(data) {
  var cell = parse_XLSBShortCell(data);
  var isst = data.read_shift(4);
  return [cell, isst, 's'];
}
function write_BrtShortIsst(cell, ncell, o) {
  if (o == null) o = new_buf(8);
  write_XLSBShortCell(ncell, o);
  o.write_shift(4, ncell.v);
  return o;
}

/* [MS-XLSB] 2.4.313 BrtCellReal */
function parse_BrtCellReal(data) {
  var cell = parse_XLSBCell(data);
  var value = parse_Xnum(data);
  return [cell, value, 'n'];
}
function write_BrtCellReal(cell, ncell, o) {
  if (o == null) o = new_buf(16);
  write_XLSBCell(ncell, o);
  write_Xnum(cell.v, o);
  return o;
}
function parse_BrtShortReal(data) {
  var cell = parse_XLSBShortCell(data);
  var value = parse_Xnum(data);
  return [cell, value, 'n'];
}
function write_BrtShortReal(cell, ncell, o) {
  if (o == null) o = new_buf(12);
  write_XLSBShortCell(ncell, o);
  write_Xnum(cell.v, o);
  return o;
}

/* [MS-XLSB] 2.4.314 BrtCellRk */
function parse_BrtCellRk(data) {
  var cell = parse_XLSBCell(data);
  var value = parse_RkNumber(data);
  return [cell, value, 'n'];
}
function write_BrtCellRk(cell, ncell, o) {
  if (o == null) o = new_buf(12);
  write_XLSBCell(ncell, o);
  write_RkNumber(cell.v, o);
  return o;
}
function parse_BrtShortRk(data) {
  var cell = parse_XLSBShortCell(data);
  var value = parse_RkNumber(data);
  return [cell, value, 'n'];
}
function write_BrtShortRk(cell, ncell, o) {
  if (o == null) o = new_buf(8);
  write_XLSBShortCell(ncell, o);
  write_RkNumber(cell.v, o);
  return o;
}

/* [MS-XLSB] 2.4.323 BrtCellRString */
function parse_BrtCellRString(data) {
  var cell = parse_XLSBCell(data);
  var value = parse_RichStr(data);
  return [cell, value, 'is'];
}

/* [MS-XLSB] 2.4.317 BrtCellSt */
function parse_BrtCellSt(data) {
  var cell = parse_XLSBCell(data);
  var value = parse_XLWideString(data);
  return [cell, value, 'str'];
}
function write_BrtCellSt(cell, ncell, o) {
  if (o == null) o = new_buf(12 + 4 * cell.v.length);
  write_XLSBCell(ncell, o);
  write_XLWideString(cell.v, o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}
function parse_BrtShortSt(data) {
  var cell = parse_XLSBShortCell(data);
  var value = parse_XLWideString(data);
  return [cell, value, 'str'];
}
function write_BrtShortSt(cell, ncell, o) {
  if (o == null) o = new_buf(8 + 4 * cell.v.length);
  write_XLSBShortCell(ncell, o);
  write_XLWideString(cell.v, o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.653 BrtFmlaBool */
function parse_BrtFmlaBool(data, length, opts) {
  var end = data.l + length;
  var cell = parse_XLSBCell(data);
  cell.r = opts['!row'];
  var value = data.read_shift(1);
  var o = [cell, value, 'b'];
  if (opts.cellFormula) {
    data.l += 2;
    var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
    o[3] = stringify_formula(formula, null /*range*/, cell, opts.supbooks, opts); /* TODO */
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.654 BrtFmlaError */
function parse_BrtFmlaError(data, length, opts) {
  var end = data.l + length;
  var cell = parse_XLSBCell(data);
  cell.r = opts['!row'];
  var value = data.read_shift(1);
  var o = [cell, value, 'e'];
  if (opts.cellFormula) {
    data.l += 2;
    var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
    o[3] = stringify_formula(formula, null /*range*/, cell, opts.supbooks, opts); /* TODO */
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.655 BrtFmlaNum */
function parse_BrtFmlaNum(data, length, opts) {
  var end = data.l + length;
  var cell = parse_XLSBCell(data);
  cell.r = opts['!row'];
  var value = parse_Xnum(data);
  var o = [cell, value, 'n'];
  if (opts.cellFormula) {
    data.l += 2;
    var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
    o[3] = stringify_formula(formula, null /*range*/, cell, opts.supbooks, opts); /* TODO */
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.656 BrtFmlaString */
function parse_BrtFmlaString(data, length, opts) {
  var end = data.l + length;
  var cell = parse_XLSBCell(data);
  cell.r = opts['!row'];
  var value = parse_XLWideString(data);
  var o = [cell, value, 'str'];
  if (opts.cellFormula) {
    data.l += 2;
    var formula = parse_XLSBCellParsedFormula(data, end - data.l, opts);
    o[3] = stringify_formula(formula, null /*range*/, cell, opts.supbooks, opts); /* TODO */
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.682 BrtMergeCell */
var parse_BrtMergeCell = parse_UncheckedRfX;
var write_BrtMergeCell = write_UncheckedRfX;
/* [MS-XLSB] 2.4.107 BrtBeginMergeCells */
function write_BrtBeginMergeCells(cnt, o) {
  if (o == null) o = new_buf(4);
  o.write_shift(4, cnt);
  return o;
}

/* [MS-XLSB] 2.4.662 BrtHLink */
function parse_BrtHLink(data, length /*::, opts*/) {
  var end = data.l + length;
  var rfx = parse_UncheckedRfX(data, 16);
  var relId = parse_XLNullableWideString(data);
  var loc = parse_XLWideString(data);
  var tooltip = parse_XLWideString(data);
  var display = parse_XLWideString(data);
  data.l = end;
  var o = {
    rfx: rfx,
    relId: relId,
    loc: loc,
    display: display
  } /*:any*/;
  if (tooltip) o.Tooltip = tooltip;
  return o;
}
function write_BrtHLink(l, rId) {
  var o = new_buf(50 + 4 * (l[1].Target.length + (l[1].Tooltip || "").length));
  write_UncheckedRfX({
    s: decode_cell(l[0]),
    e: decode_cell(l[0])
  }, o);
  write_RelID("rId" + rId, o);
  var locidx = l[1].Target.indexOf("#");
  var loc = locidx == -1 ? "" : l[1].Target.slice(locidx + 1);
  write_XLWideString(loc || "", o);
  write_XLWideString(l[1].Tooltip || "", o);
  write_XLWideString("", o);
  return o.slice(0, o.l);
}

/* [MS-XLSB] 2.4.692 BrtPane */
function parse_BrtPane(/*data, length, opts*/
) {}

/* [MS-XLSB] 2.4.6 BrtArrFmla */
function parse_BrtArrFmla(data, length, opts) {
  var end = data.l + length;
  var rfx = parse_RfX(data, 16);
  var fAlwaysCalc = data.read_shift(1);
  var o = [rfx];
  o[2] = fAlwaysCalc;
  if (opts.cellFormula) {
    var formula = parse_XLSBArrayParsedFormula(data, end - data.l, opts);
    o[1] = formula;
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.750 BrtShrFmla */
function parse_BrtShrFmla(data, length, opts) {
  var end = data.l + length;
  var rfx = parse_UncheckedRfX(data, 16);
  var o = [rfx];
  if (opts.cellFormula) {
    var formula = parse_XLSBSharedParsedFormula(data, end - data.l, opts);
    o[1] = formula;
    data.l = end;
  } else data.l = end;
  return o;
}

/* [MS-XLSB] 2.4.323 BrtColInfo */
/* TODO: once XLS ColInfo is set, combine the functions */
function write_BrtColInfo(C /*:number*/, col, o) {
  if (o == null) o = new_buf(18);
  var p = col_obj_w(C, col);
  o.write_shift(-4, C);
  o.write_shift(-4, C);
  o.write_shift(4, (p.width || 10) * 256);
  o.write_shift(4, 0 /*ixfe*/); // style
  var flags = 0;
  if (col.hidden) flags |= 0x01;
  if (typeof p.width == 'number') flags |= 0x02;
  if (col.level) flags |= col.level << 8;
  o.write_shift(2, flags); // bit flag
  return o;
}

/* [MS-XLSB] 2.4.678 BrtMargins */
var BrtMarginKeys = ["left", "right", "top", "bottom", "header", "footer"];
function parse_BrtMargins(data /*::, length, opts*/) /*:Margins*/{
  var margins = {} /*:any*/;
  BrtMarginKeys.forEach(function (k) {
    margins[k] = parse_Xnum(data, 8);
  });
  return margins;
}
function write_BrtMargins(margins /*:Margins*/, o) {
  if (o == null) o = new_buf(6 * 8);
  default_margins(margins);
  BrtMarginKeys.forEach(function (k) {
    write_Xnum(margins /*:any*/[k], o);
  });
  return o;
}

/* [MS-XLSB] 2.4.299 BrtBeginWsView */
function parse_BrtBeginWsView(data /*::, length, opts*/) {
  var f = data.read_shift(2);
  data.l += 28;
  return {
    RTL: f & 0x20
  };
}
function write_BrtBeginWsView(ws, Workbook, o) {
  if (o == null) o = new_buf(30);
  var f = 0x39c;
  if ((((Workbook || {}).Views || [])[0] || {}).RTL) f |= 0x20;
  o.write_shift(2, f); // bit flag
  o.write_shift(4, 0);
  o.write_shift(4, 0); // view first row
  o.write_shift(4, 0); // view first col
  o.write_shift(1, 0); // gridline color ICV
  o.write_shift(1, 0);
  o.write_shift(2, 0);
  o.write_shift(2, 100); // zoom scale
  o.write_shift(2, 0);
  o.write_shift(2, 0);
  o.write_shift(2, 0);
  o.write_shift(4, 0); // workbook view id
  return o;
}

/* [MS-XLSB] 2.4.309 BrtCellIgnoreEC */
function write_BrtCellIgnoreEC(ref) {
  var o = new_buf(24);
  o.write_shift(4, 4);
  o.write_shift(4, 1);
  write_UncheckedRfX(ref, o);
  return o;
}

/* [MS-XLSB] 2.4.748 BrtSheetProtection */
function write_BrtSheetProtection(sp, o) {
  if (o == null) o = new_buf(16 * 4 + 2);
  o.write_shift(2, sp.password ? crypto_CreatePasswordVerifier_Method1(sp.password) : 0);
  o.write_shift(4, 1); // this record should not be written if no protection
  [["objects", false],
  // fObjects
  ["scenarios", false],
  // fScenarios
  ["formatCells", true],
  // fFormatCells
  ["formatColumns", true],
  // fFormatColumns
  ["formatRows", true],
  // fFormatRows
  ["insertColumns", true],
  // fInsertColumns
  ["insertRows", true],
  // fInsertRows
  ["insertHyperlinks", true],
  // fInsertHyperlinks
  ["deleteColumns", true],
  // fDeleteColumns
  ["deleteRows", true],
  // fDeleteRows
  ["selectLockedCells", false],
  // fSelLockedCells
  ["sort", true],
  // fSort
  ["autoFilter", true],
  // fAutoFilter
  ["pivotTables", true],
  // fPivotTables
  ["selectUnlockedCells", false] // fSelUnlockedCells
  ].forEach(function (n) {
    /*:: if(o == null) throw "unreachable"; */
    if (n[1]) o.write_shift(4, sp[n[0]] != null && !sp[n[0]] ? 1 : 0);else o.write_shift(4, sp[n[0]] != null && sp[n[0]] ? 0 : 1);
  });
  return o;
}
function parse_BrtDVal(/*data, length, opts*/
) {}
function parse_BrtDVal14(/*data, length, opts*/
) {}
/* [MS-XLSB] 2.1.7.61 Worksheet */
function parse_ws_bin(data, _opts, idx, rels, wb /*:WBWBProps*/, themes, styles) /*:Worksheet*/{
  if (!data) return data;
  var opts = _opts || {};
  if (!rels) rels = {
    '!id': {}
  };
  if (DENSE != null && opts.dense == null) opts.dense = DENSE;
  var s /*:Worksheet*/ = opts.dense ? [] : {};
  var ref;
  var refguess = {
    s: {
      r: 2000000,
      c: 2000000
    },
    e: {
      r: 0,
      c: 0
    }
  };
  var state /*:Array<string>*/ = [];
  var pass = false,
    end = false;
  var row, p, cf, R, C, addr, sstr, rr, cell /*:Cell*/;
  var merges /*:Array<Range>*/ = [];
  opts.biff = 12;
  opts['!row'] = 0;
  var ai = 0,
    af = false;
  var arrayf /*:Array<[Range, string]>*/ = [];
  var sharedf = {};
  var supbooks = opts.supbooks || /*::(*/wb /*:: :any)*/.supbooks || [[]] /*:any*/;
  supbooks.sharedf = sharedf;
  supbooks.arrayf = arrayf;
  supbooks.SheetNames = wb.SheetNames || wb.Sheets.map(function (x) {
    return x.name;
  });
  if (!opts.supbooks) {
    opts.supbooks = supbooks;
    if (wb.Names) for (var i = 0; i < wb.Names.length; ++i) supbooks[0][i + 1] = wb.Names[i];
  }
  var colinfo /*:Array<ColInfo>*/ = [],
    rowinfo /*:Array<RowInfo>*/ = [];
  var seencol = false;
  XLSBRecordEnum[0x0010] = {
    n: "BrtShortReal",
    f: parse_BrtShortReal
  };
  var cm, vm;
  recordhopper(data, function ws_parse(val, RR, RT) {
    if (end) return;
    switch (RT) {
      case 0x0094:
        /* 'BrtWsDim' */
        ref = val;
        break;
      case 0x0000:
        /* 'BrtRowHdr' */
        row = val;
        if (opts.sheetRows && opts.sheetRows <= row.r) end = true;
        rr = encode_row(R = row.r);
        opts['!row'] = row.r;
        if (val.hidden || val.hpt || val.level != null) {
          if (val.hpt) val.hpx = pt2px(val.hpt);
          rowinfo[val.r] = val;
        }
        break;
      case 0x0002: /* 'BrtCellRk' */
      case 0x0003: /* 'BrtCellError' */
      case 0x0004: /* 'BrtCellBool' */
      case 0x0005: /* 'BrtCellReal' */
      case 0x0006: /* 'BrtCellSt' */
      case 0x0007: /* 'BrtCellIsst' */
      case 0x0008: /* 'BrtFmlaString' */
      case 0x0009: /* 'BrtFmlaNum' */
      case 0x000A: /* 'BrtFmlaBool' */
      case 0x000B: /* 'BrtFmlaError' */
      case 0x000D: /* 'BrtShortRk' */
      case 0x000E: /* 'BrtShortError' */
      case 0x000F: /* 'BrtShortBool' */
      case 0x0010: /* 'BrtShortReal' */
      case 0x0011: /* 'BrtShortSt' */
      case 0x0012: /* 'BrtShortIsst' */
      case 0x003E:
        /* 'BrtCellRString' */
        p = {
          t: val[2]
        } /*:any*/;
        switch (val[2]) {
          case 'n':
            p.v = val[1];
            break;
          case 's':
            sstr = strs[val[1]];
            p.v = sstr.t;
            p.r = sstr.r;
            break;
          case 'b':
            p.v = val[1] ? true : false;
            break;
          case 'e':
            p.v = val[1];
            if (opts.cellText !== false) p.w = BErr[p.v];
            break;
          case 'str':
            p.t = 's';
            p.v = val[1];
            break;
          case 'is':
            p.t = 's';
            p.v = val[1].t;
            break;
        }
        if (cf = styles.CellXf[val[0].iStyleRef]) safe_format(p, cf.numFmtId, null, opts, themes, styles);
        C = val[0].c == -1 ? C + 1 : val[0].c;
        if (opts.dense) {
          if (!s[R]) s[R] = [];
          s[R][C] = p;
        } else s[encode_col(C) + rr] = p;
        if (opts.cellFormula) {
          af = false;
          for (ai = 0; ai < arrayf.length; ++ai) {
            var aii = arrayf[ai];
            if (row.r >= aii[0].s.r && row.r <= aii[0].e.r) if (C >= aii[0].s.c && C <= aii[0].e.c) {
              p.F = encode_range(aii[0]);
              af = true;
            }
          }
          if (!af && val.length > 3) p.f = val[3];
        }
        if (refguess.s.r > row.r) refguess.s.r = row.r;
        if (refguess.s.c > C) refguess.s.c = C;
        if (refguess.e.r < row.r) refguess.e.r = row.r;
        if (refguess.e.c < C) refguess.e.c = C;
        if (opts.cellDates && cf && p.t == 'n' && fmt_is_date(table_fmt[cf.numFmtId])) {
          var _d = SSF_parse_date_code(p.v);
          if (_d) {
            p.t = 'd';
            p.v = new Date(_d.y, _d.m - 1, _d.d, _d.H, _d.M, _d.S, _d.u);
          }
        }
        if (cm) {
          if (cm.type == 'XLDAPR') p.D = true;
          cm = void 0;
        }
        if (vm) vm = void 0;
        break;
      case 0x0001: /* 'BrtCellBlank' */
      case 0x000C:
        /* 'BrtShortBlank' */
        if (!opts.sheetStubs || pass) break;
        p = {
          t: 'z',
          v: void 0
        } /*:any*/;
        C = val[0].c == -1 ? C + 1 : val[0].c;
        if (opts.dense) {
          if (!s[R]) s[R] = [];
          s[R][C] = p;
        } else s[encode_col(C) + rr] = p;
        if (refguess.s.r > row.r) refguess.s.r = row.r;
        if (refguess.s.c > C) refguess.s.c = C;
        if (refguess.e.r < row.r) refguess.e.r = row.r;
        if (refguess.e.c < C) refguess.e.c = C;
        if (cm) {
          if (cm.type == 'XLDAPR') p.D = true;
          cm = void 0;
        }
        if (vm) vm = void 0;
        break;
      case 0x00B0:
        /* 'BrtMergeCell' */
        merges.push(val);
        break;
      case 0x0031:
        {
          /* 'BrtCellMeta' */
          cm = ((opts.xlmeta || {}).Cell || [])[val - 1];
        }
        break;
      case 0x01EE:
        /* 'BrtHLink' */
        var rel = rels['!id'][val.relId];
        if (rel) {
          val.Target = rel.Target;
          if (val.loc) val.Target += "#" + val.loc;
          val.Rel = rel;
        } else if (val.relId == '') {
          val.Target = "#" + val.loc;
        }
        for (R = val.rfx.s.r; R <= val.rfx.e.r; ++R) for (C = val.rfx.s.c; C <= val.rfx.e.c; ++C) {
          if (opts.dense) {
            if (!s[R]) s[R] = [];
            if (!s[R][C]) s[R][C] = {
              t: 'z',
              v: undefined
            };
            s[R][C].l = val;
          } else {
            addr = encode_cell({
              c: C,
              r: R
            });
            if (!s[addr]) s[addr] = {
              t: 'z',
              v: undefined
            };
            s[addr].l = val;
          }
        }
        break;
      case 0x01AA:
        /* 'BrtArrFmla' */
        if (!opts.cellFormula) break;
        arrayf.push(val);
        cell = opts.dense ? s[R][C] : s[encode_col(C) + rr] /*:any*/;
        cell.f = stringify_formula(val[1], refguess, {
          r: row.r,
          c: C
        }, supbooks, opts);
        cell.F = encode_range(val[0]);
        break;
      case 0x01AB:
        /* 'BrtShrFmla' */
        if (!opts.cellFormula) break;
        sharedf[encode_cell(val[0].s)] = val[1];
        cell = opts.dense ? s[R][C] : s[encode_col(C) + rr];
        cell.f = stringify_formula(val[1], refguess, {
          r: row.r,
          c: C
        }, supbooks, opts);
        break;

      /* identical to 'ColInfo' in XLS */
      case 0x003C:
        /* 'BrtColInfo' */
        if (!opts.cellStyles) break;
        while (val.e >= val.s) {
          colinfo[val.e--] = {
            width: val.w / 256,
            hidden: !!(val.flags & 0x01),
            level: val.level
          };
          if (!seencol) {
            seencol = true;
            find_mdw_colw(val.w / 256);
          }
          process_col(colinfo[val.e + 1]);
        }
        break;
      case 0x00A1:
        /* 'BrtBeginAFilter' */
        s['!autofilter'] = {
          ref: encode_range(val)
        };
        break;
      case 0x01DC:
        /* 'BrtMargins' */
        s['!margins'] = val;
        break;
      case 0x0093:
        /* 'BrtWsProp' */
        if (!wb.Sheets[idx]) wb.Sheets[idx] = {};
        if (val.name) wb.Sheets[idx].CodeName = val.name;
        if (val.above || val.left) s['!outline'] = {
          above: val.above,
          left: val.left
        };
        break;
      case 0x0089:
        /* 'BrtBeginWsView' */
        if (!wb.Views) wb.Views = [{}];
        if (!wb.Views[0]) wb.Views[0] = {};
        if (val.RTL) wb.Views[0].RTL = true;
        break;
      case 0x01E5:
        /* 'BrtWsFmtInfo' */
        break;
      case 0x0040: /* 'BrtDVal' */
      case 0x041D:
        /* 'BrtDVal14' */
        break;
      case 0x0097:
        /* 'BrtPane' */
        break;
      case 0x0098: /* 'BrtSel' */
      case 0x00AF: /* 'BrtAFilterDateGroupItem' */
      case 0x0284: /* 'BrtActiveX' */
      case 0x0271: /* 'BrtBigName' */
      case 0x0232: /* 'BrtBkHim' */
      case 0x018C: /* 'BrtBrk' */
      case 0x0458: /* 'BrtCFIcon' */
      case 0x047A: /* 'BrtCFRuleExt' */
      case 0x01D7: /* 'BrtCFVO' */
      case 0x041A: /* 'BrtCFVO14' */
      case 0x0289: /* 'BrtCellIgnoreEC' */
      case 0x0451: /* 'BrtCellIgnoreEC14' */
      case 0x024D: /* 'BrtCellSmartTagProperty' */
      case 0x025F: /* 'BrtCellWatch' */
      case 0x0234: /* 'BrtColor' */
      case 0x041F: /* 'BrtColor14' */
      case 0x00A8: /* 'BrtColorFilter' */
      case 0x00AE: /* 'BrtCustomFilter' */
      case 0x049C: /* 'BrtCustomFilter14' */
      case 0x01F3: /* 'BrtDRef' */
      case 0x01FB: /* 'BrtDXF' */
      case 0x0226: /* 'BrtDrawing' */
      case 0x00AB: /* 'BrtDynamicFilter' */
      case 0x00A7: /* 'BrtFilter' */
      case 0x0499: /* 'BrtFilter14' */
      case 0x00A9: /* 'BrtIconFilter' */
      case 0x049D: /* 'BrtIconFilter14' */
      case 0x0227: /* 'BrtLegacyDrawing' */
      case 0x0228: /* 'BrtLegacyDrawingHF' */
      case 0x0295: /* 'BrtListPart' */
      case 0x027F: /* 'BrtOleObject' */
      case 0x01DE: /* 'BrtPageSetup' */
      case 0x0219: /* 'BrtPhoneticInfo' */
      case 0x01DD: /* 'BrtPrintOptions' */
      case 0x0218: /* 'BrtRangeProtection' */
      case 0x044F: /* 'BrtRangeProtection14' */
      case 0x02A8: /* 'BrtRangeProtectionIso' */
      case 0x0450: /* 'BrtRangeProtectionIso14' */
      case 0x0400: /* 'BrtRwDescent' */
      case 0x0297: /* 'BrtSheetCalcProp' */
      case 0x0217: /* 'BrtSheetProtection' */
      case 0x02A6: /* 'BrtSheetProtectionIso' */
      case 0x01F8: /* 'BrtSlc' */
      case 0x0413: /* 'BrtSparkline' */
      case 0x01AC: /* 'BrtTable' */
      case 0x00AA: /* 'BrtTop10Filter' */
      case 0x0C00: /* 'BrtUid' */
      case 0x0032: /* 'BrtValueMeta' */
      case 0x0816: /* 'BrtWebExtension' */
      case 0x0415:
        /* 'BrtWsFmtInfoEx14' */
        break;
      case 0x0023:
        /* 'BrtFRTBegin' */
        pass = true;
        break;
      case 0x0024:
        /* 'BrtFRTEnd' */
        pass = false;
        break;
      case 0x0025:
        /* 'BrtACBegin' */
        state.push(RT);
        pass = true;
        break;
      case 0x0026:
        /* 'BrtACEnd' */
        state.pop();
        pass = false;
        break;
      default:
        if (RR.T) {/* empty */} else if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  }, opts);
  delete opts.supbooks;
  delete opts['!row'];
  if (!s["!ref"] && (refguess.s.r < 2000000 || ref && (ref.e.r > 0 || ref.e.c > 0 || ref.s.r > 0 || ref.s.c > 0))) s["!ref"] = encode_range(ref || refguess);
  if (opts.sheetRows && s["!ref"]) {
    var tmpref = safe_decode_range(s["!ref"]);
    if (opts.sheetRows <= +tmpref.e.r) {
      tmpref.e.r = opts.sheetRows - 1;
      if (tmpref.e.r > refguess.e.r) tmpref.e.r = refguess.e.r;
      if (tmpref.e.r < tmpref.s.r) tmpref.s.r = tmpref.e.r;
      if (tmpref.e.c > refguess.e.c) tmpref.e.c = refguess.e.c;
      if (tmpref.e.c < tmpref.s.c) tmpref.s.c = tmpref.e.c;
      s["!fullref"] = s["!ref"];
      s["!ref"] = encode_range(tmpref);
    }
  }
  if (merges.length > 0) s["!merges"] = merges;
  if (colinfo.length > 0) s["!cols"] = colinfo;
  if (rowinfo.length > 0) s["!rows"] = rowinfo;
  return s;
}

/* TODO: something useful -- this is a stub */
function write_ws_bin_cell(ba /*:BufArray*/, cell /*:Cell*/, R /*:number*/, C /*:number*/, opts, ws /*:Worksheet*/, last_seen /*:boolean*/) /*:boolean*/{
  if (cell.v === undefined) return false;
  var vv = "";
  switch (cell.t) {
    case 'b':
      vv = cell.v ? "1" : "0";
      break;
    case 'd':
      // no BrtCellDate :(
      cell = dup(cell);
      cell.z = cell.z || table_fmt[14];
      cell.v = datenum(parseDate(cell.v));
      cell.t = 'n';
      break;
    /* falls through */
    case 'n':
    case 'e':
      vv = '' + cell.v;
      break;
    default:
      vv = cell.v;
      break;
  }
  var o /*:any*/ = {
    r: R,
    c: C
  } /*:any*/;
  /* TODO: cell style */
  o.s = get_cell_style(opts.cellXfs, cell, opts);
  if (cell.l) ws['!links'].push([encode_cell(o), cell.l]);
  if (cell.c) ws['!comments'].push([encode_cell(o), cell.c]);
  switch (cell.t) {
    case 's':
    case 'str':
      if (opts.bookSST) {
        vv = get_sst_id(opts.Strings, cell.v /*:any*/, opts.revStrings);
        o.t = "s";
        o.v = vv;
        if (last_seen) write_record(ba, 0x0012 /* BrtShortIsst */, write_BrtShortIsst(cell, o));else write_record(ba, 0x0007 /* BrtCellIsst */, write_BrtCellIsst(cell, o));
      } else {
        o.t = "str";
        if (last_seen) write_record(ba, 0x0011 /* BrtShortSt */, write_BrtShortSt(cell, o));else write_record(ba, 0x0006 /* BrtCellSt */, write_BrtCellSt(cell, o));
      }
      return true;
    case 'n':
      /* TODO: determine threshold for Real vs RK */
      if (cell.v == (cell.v | 0) && cell.v > -1000 && cell.v < 1000) {
        if (last_seen) write_record(ba, 0x000D /* BrtShortRk */, write_BrtShortRk(cell, o));else write_record(ba, 0x0002 /* BrtCellRk */, write_BrtCellRk(cell, o));
      } else {
        if (last_seen) write_record(ba, 0x0010 /* BrtShortReal */, write_BrtShortReal(cell, o));else write_record(ba, 0x0005 /* BrtCellReal */, write_BrtCellReal(cell, o));
      }
      return true;
    case 'b':
      o.t = "b";
      if (last_seen) write_record(ba, 0x000F /* BrtShortBool */, write_BrtShortBool(cell, o));else write_record(ba, 0x0004 /* BrtCellBool */, write_BrtCellBool(cell, o));
      return true;
    case 'e':
      o.t = "e";
      if (last_seen) write_record(ba, 0x000E /* BrtShortError */, write_BrtShortError(cell, o));else write_record(ba, 0x0003 /* BrtCellError */, write_BrtCellError(cell, o));
      return true;
  }
  if (last_seen) write_record(ba, 0x000C /* BrtShortBlank */, write_BrtShortBlank(cell, o));else write_record(ba, 0x0001 /* BrtCellBlank */, write_BrtCellBlank(cell, o));
  return true;
}
function write_CELLTABLE(ba, ws /*:Worksheet*/, idx /*:number*/, opts /*::, wb:Workbook*/) {
  var range = safe_decode_range(ws['!ref'] || "A1"),
    ref,
    rr = "",
    cols /*:Array<string>*/ = [];
  write_record(ba, 0x0091 /* BrtBeginSheetData */);
  var dense = Array.isArray(ws);
  var cap = range.e.r;
  if (ws['!rows']) cap = Math.max(range.e.r, ws['!rows'].length - 1);
  for (var R = range.s.r; R <= cap; ++R) {
    rr = encode_row(R);
    /* [ACCELLTABLE] */
    /* BrtRowHdr */
    write_row_header(ba, ws, range, R);
    var last_seen = false;
    if (R <= range.e.r) for (var C = range.s.c; C <= range.e.c; ++C) {
      /* *16384CELL */
      if (R === range.s.r) cols[C] = encode_col(C);
      ref = cols[C] + rr;
      var cell = dense ? (ws[R] || [])[C] : ws[ref];
      if (!cell) {
        last_seen = false;
        continue;
      }
      /* write cell */
      last_seen = write_ws_bin_cell(ba, cell, R, C, opts, ws, last_seen);
    }
  }
  write_record(ba, 0x0092 /* BrtEndSheetData */);
}
function write_MERGECELLS(ba, ws /*:Worksheet*/) {
  if (!ws || !ws['!merges']) return;
  write_record(ba, 0x00B1 /* BrtBeginMergeCells */, write_BrtBeginMergeCells(ws['!merges'].length));
  ws['!merges'].forEach(function (m) {
    write_record(ba, 0x00B0 /* BrtMergeCell */, write_BrtMergeCell(m));
  });
  write_record(ba, 0x00B2 /* BrtEndMergeCells */);
}
function write_COLINFOS(ba, ws /*:Worksheet*/ /*::, idx:number, opts, wb:Workbook*/) {
  if (!ws || !ws['!cols']) return;
  write_record(ba, 0x0186 /* BrtBeginColInfos */);
  ws['!cols'].forEach(function (m, i) {
    if (m) write_record(ba, 0x003C /* 'BrtColInfo' */, write_BrtColInfo(i, m));
  });
  write_record(ba, 0x0187 /* BrtEndColInfos */);
}
function write_IGNOREECS(ba, ws /*:Worksheet*/) {
  if (!ws || !ws['!ref']) return;
  write_record(ba, 0x0288 /* BrtBeginCellIgnoreECs */);
  write_record(ba, 0x0289 /* BrtCellIgnoreEC */, write_BrtCellIgnoreEC(safe_decode_range(ws['!ref'])));
  write_record(ba, 0x028A /* BrtEndCellIgnoreECs */);
}
function write_HLINKS(ba, ws /*:Worksheet*/, rels) {
  /* *BrtHLink */
  ws['!links'].forEach(function (l) {
    if (!l[1].Target) return;
    var rId = add_rels(rels, -1, l[1].Target.replace(/#.*$/, ""), RELS.HLINK);
    write_record(ba, 0x01EE /* BrtHLink */, write_BrtHLink(l, rId));
  });
  delete ws['!links'];
}
function write_LEGACYDRAWING(ba, ws /*:Worksheet*/, idx /*:number*/, rels) {
  /* [BrtLegacyDrawing] */
  if (ws['!comments'].length > 0) {
    var rId = add_rels(rels, -1, "../drawings/vmlDrawing" + (idx + 1) + ".vml", RELS.VML);
    write_record(ba, 0x0227 /* BrtLegacyDrawing */, write_RelID("rId" + rId));
    ws['!legacy'] = rId;
  }
}
function write_AUTOFILTER(ba, ws, wb, idx) {
  if (!ws['!autofilter']) return;
  var data = ws['!autofilter'];
  var ref = typeof data.ref === "string" ? data.ref : encode_range(data.ref);

  /* Update FilterDatabase defined name for the worksheet */
  if (!wb.Workbook) wb.Workbook = {
    Sheets: []
  } /*:any*/;
  if (!wb.Workbook.Names) wb.Workbook.Names = [];
  var names /*: Array<any> */ = wb.Workbook.Names;
  var range = decode_range(ref);
  if (range.s.r == range.e.r) {
    range.e.r = decode_range(ws["!ref"]).e.r;
    ref = encode_range(range);
  }
  for (var i = 0; i < names.length; ++i) {
    var name = names[i];
    if (name.Name != '_xlnm._FilterDatabase') continue;
    if (name.Sheet != idx) continue;
    name.Ref = "'" + wb.SheetNames[idx] + "'!" + ref;
    break;
  }
  if (i == names.length) names.push({
    Name: '_xlnm._FilterDatabase',
    Sheet: idx,
    Ref: "'" + wb.SheetNames[idx] + "'!" + ref
  });
  write_record(ba, 0x00A1 /* BrtBeginAFilter */, write_UncheckedRfX(safe_decode_range(ref)));
  /* *FILTERCOLUMN */
  /* [SORTSTATE] */
  /* BrtEndAFilter */
  write_record(ba, 0x00A2 /* BrtEndAFilter */);
}
function write_WSVIEWS2(ba, ws, Workbook) {
  write_record(ba, 0x0085 /* BrtBeginWsViews */);
  {
    /* 1*WSVIEW2 */
    /* [ACUID] */
    write_record(ba, 0x0089 /* BrtBeginWsView */, write_BrtBeginWsView(ws, Workbook));
    /* [BrtPane] */
    /* *4BrtSel */
    /* *4SXSELECT */
    /* *FRT */
    write_record(ba, 0x008A /* BrtEndWsView */);
  }
  /* *FRT */
  write_record(ba, 0x0086 /* BrtEndWsViews */);
}
function write_WSFMTINFO(/*::ba, ws*/
) {
  /* [ACWSFMTINFO] */
  // write_record(ba, 0x01E5 /* BrtWsFmtInfo */, write_BrtWsFmtInfo(ws));
}
function write_SHEETPROTECT(ba, ws) {
  if (!ws['!protect']) return;
  /* [BrtSheetProtectionIso] */
  write_record(ba, 0x0217 /* BrtSheetProtection */, write_BrtSheetProtection(ws['!protect']));
}
function write_ws_bin(idx /*:number*/, opts, wb /*:Workbook*/, rels) {
  var ba = buf_array();
  var s = wb.SheetNames[idx],
    ws = wb.Sheets[s] || {};
  var c /*:string*/ = s;
  try {
    if (wb && wb.Workbook) c = wb.Workbook.Sheets[idx].CodeName || c;
  } catch (e) {}
  var r = safe_decode_range(ws['!ref'] || "A1");
  if (r.e.c > 0x3FFF || r.e.r > 0xFFFFF) {
    if (opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:XFD1048576");
    r.e.c = Math.min(r.e.c, 0x3FFF);
    r.e.r = Math.min(r.e.c, 0xFFFFF);
  }
  ws['!links'] = [];
  /* passed back to write_zip and removed there */
  ws['!comments'] = [];
  write_record(ba, 0x0081 /* BrtBeginSheet */);
  if (wb.vbaraw || ws['!outline']) write_record(ba, 0x0093 /* BrtWsProp */, write_BrtWsProp(c, ws['!outline']));
  write_record(ba, 0x0094 /* BrtWsDim */, write_BrtWsDim(r));
  write_WSVIEWS2(ba, ws, wb.Workbook);
  write_WSFMTINFO(ba, ws);
  write_COLINFOS(ba, ws, idx, opts, wb);
  write_CELLTABLE(ba, ws, idx, opts, wb);
  /* [BrtSheetCalcProp] */
  write_SHEETPROTECT(ba, ws);
  /* *([BrtRangeProtectionIso] BrtRangeProtection) */
  /* [SCENMAN] */
  write_AUTOFILTER(ba, ws, wb, idx);
  /* [SORTSTATE] */
  /* [DCON] */
  /* [USERSHVIEWS] */
  write_MERGECELLS(ba, ws);
  /* [BrtPhoneticInfo] */
  /* *CONDITIONALFORMATTING */
  /* [DVALS] */
  write_HLINKS(ba, ws, rels);
  /* [BrtPrintOptions] */
  if (ws['!margins']) write_record(ba, 0x01DC /* BrtMargins */, write_BrtMargins(ws['!margins']));
  /* [BrtPageSetup] */
  /* [HEADERFOOTER] */
  /* [RWBRK] */
  /* [COLBRK] */
  /* *BrtBigName */
  /* [CELLWATCHES] */
  if (!opts || opts.ignoreEC || opts.ignoreEC == void 0) write_IGNOREECS(ba, ws);
  /* [SMARTTAGS] */
  /* [BrtDrawing] */
  write_LEGACYDRAWING(ba, ws, idx, rels);
  /* [BrtLegacyDrawingHF] */
  /* [BrtBkHim] */
  /* [OLEOBJECTS] */
  /* [ACTIVEXCONTROLS] */
  /* [WEBPUBITEMS] */
  /* [LISTPARTS] */
  /* FRTWORKSHEET */
  write_record(ba, 0x0082 /* BrtEndSheet */);
  return ba.end();
}
function parse_Cache(data /*:string*/) /*:[Array<number|string>, string, ?string]*/{
  var col /*:Array<number|string>*/ = [];
  var num = data.match(/^<c:numCache>/);
  var f;

  /* 21.2.2.150 pt CT_NumVal */
  (data.match(/<c:pt idx="(\d*)">(.*?)<\/c:pt>/mg) || []).forEach(function (pt) {
    var q = pt.match(/<c:pt idx="(\d*?)"><c:v>(.*)<\/c:v><\/c:pt>/);
    if (!q) return;
    col[+q[1]] = num ? +q[2] : q[2];
  });

  /* 21.2.2.71 formatCode CT_Xstring */
  var nf = unescapexml((data.match(/<c:formatCode>([\s\S]*?)<\/c:formatCode>/) || ["", "General"])[1]);
  (data.match(/<c:f>(.*?)<\/c:f>/mg) || []).forEach(function (F) {
    f = F.replace(/<.*?>/g, "");
  });
  return [col, nf, f];
}

/* 21.2 DrawingML - Charts */
function parse_chart(data /*:?string*/, name /*:string*/, opts, rels, wb, csheet) {
  var cs /*:Worksheet*/ = csheet || {
    "!type": "chart"
  } /*:any*/;
  if (!data) return csheet;
  /* 21.2.2.27 chart CT_Chart */

  var C = 0,
    R = 0,
    col = "A";
  var refguess = {
    s: {
      r: 2000000,
      c: 2000000
    },
    e: {
      r: 0,
      c: 0
    }
  };

  /* 21.2.2.120 numCache CT_NumData */
  (data.match(/<c:numCache>[\s\S]*?<\/c:numCache>/gm) || []).forEach(function (nc) {
    var cache = parse_Cache(nc);
    refguess.s.r = refguess.s.c = 0;
    refguess.e.c = C;
    col = encode_col(C);
    cache[0].forEach(function (n, i) {
      cs[col + encode_row(i)] = {
        t: 'n',
        v: n,
        z: cache[1]
      };
      R = i;
    });
    if (refguess.e.r < R) refguess.e.r = R;
    ++C;
  });
  if (C > 0) cs["!ref"] = encode_range(refguess);
  return cs;
}
/* 18.3 Worksheets also covers Chartsheets */
function parse_cs_xml(data /*:?string*/, opts, idx /*:number*/, rels, wb /*::, themes, styles*/) /*:Worksheet*/{
  if (!data) return data;
  /* 18.3.1.12 chartsheet CT_ChartSheet */
  if (!rels) rels = {
    '!id': {}
  };
  var s = {
    '!type': "chart",
    '!drawel': null,
    '!rel': ""
  } /*:any*/;
  var m;

  /* 18.3.1.83 sheetPr CT_ChartsheetPr */
  var sheetPr = data.match(sheetprregex);
  if (sheetPr) parse_ws_xml_sheetpr(sheetPr[0], s, wb, idx);

  /* 18.3.1.36 drawing CT_Drawing */
  if (m = data.match(/drawing r:id="(.*?)"/)) s['!rel'] = m[1];
  if (rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
  return s;
}
function write_cs_xml(idx /*:number*/, opts, wb /*:Workbook*/, rels) /*:string*/{
  var o = [XML_HEADER, writextag('chartsheet', null, {
    'xmlns': XMLNS_main[0],
    'xmlns:r': XMLNS.r
  })];
  o[o.length] = writextag("drawing", null, {
    "r:id": "rId1"
  });
  add_rels(rels, -1, "../drawings/drawing" + (idx + 1) + ".xml", RELS.DRAW);
  if (o.length > 2) {
    o[o.length] = '</chartsheet>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}

/* [MS-XLSB] 2.4.331 BrtCsProp */
function parse_BrtCsProp(data, length /*:number*/) {
  data.l += 10;
  var name = parse_XLWideString(data, length - 10);
  return {
    name: name
  };
}

/* [MS-XLSB] 2.1.7.7 Chart Sheet */
function parse_cs_bin(data, opts, idx /*:number*/, rels, wb /*::, themes, styles*/) /*:Worksheet*/{
  if (!data) return data;
  if (!rels) rels = {
    '!id': {}
  };
  var s = {
    '!type': "chart",
    '!drawel': null,
    '!rel': ""
  };
  var state /*:Array<string>*/ = [];
  var pass = false;
  recordhopper(data, function cs_parse(val, R, RT) {
    switch (RT) {
      case 0x0226:
        /* 'BrtDrawing' */
        s['!rel'] = val;
        break;
      case 0x028B:
        /* 'BrtCsProp' */
        if (!wb.Sheets[idx]) wb.Sheets[idx] = {};
        if (val.name) wb.Sheets[idx].CodeName = val.name;
        break;
      case 0x0232: /* 'BrtBkHim' */
      case 0x028C: /* 'BrtCsPageSetup' */
      case 0x029D: /* 'BrtCsProtection' */
      case 0x02A7: /* 'BrtCsProtectionIso' */
      case 0x0227: /* 'BrtLegacyDrawing' */
      case 0x0228: /* 'BrtLegacyDrawingHF' */
      case 0x01DC: /* 'BrtMargins' */
      case 0x0C00:
        /* 'BrtUid' */
        break;
      case 0x0023:
        /* 'BrtFRTBegin' */
        pass = true;
        break;
      case 0x0024:
        /* 'BrtFRTEnd' */
        pass = false;
        break;
      case 0x0025:
        /* 'BrtACBegin' */
        state.push(RT);
        break;
      case 0x0026:
        /* 'BrtACEnd' */
        state.pop();
        break;
      default:
        if (R.T > 0) state.push(RT);else if (R.T < 0) state.pop();else if (!pass || opts.WTF) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  }, opts);
  if (rels['!id'][s['!rel']]) s['!drawel'] = rels['!id'][s['!rel']];
  return s;
}
function write_cs_bin(/*::idx:number, opts, wb:Workbook, rels*/
) {
  var ba = buf_array();
  write_record(ba, 0x0081 /* BrtBeginSheet */);
  /* [BrtCsProp] */
  /* CSVIEWS */
  /* [[BrtCsProtectionIso] BrtCsProtection] */
  /* [USERCSVIEWS] */
  /* [BrtMargins] */
  /* [BrtCsPageSetup] */
  /* [HEADERFOOTER] */
  /* BrtDrawing */
  /* [BrtLegacyDrawing] */
  /* [BrtLegacyDrawingHF] */
  /* [BrtBkHim] */
  /* [WEBPUBITEMS] */
  /* FRTCHARTSHEET */
  write_record(ba, 0x0082 /* BrtEndSheet */);
  return ba.end();
}
/* 18.2.28 (CT_WorkbookProtection) Defaults */
var WBPropsDef = [['allowRefreshQuery', false, "bool"], ['autoCompressPictures', true, "bool"], ['backupFile', false, "bool"], ['checkCompatibility', false, "bool"], ['CodeName', ''], ['date1904', false, "bool"], ['defaultThemeVersion', 0, "int"], ['filterPrivacy', false, "bool"], ['hidePivotFieldList', false, "bool"], ['promptedSolutions', false, "bool"], ['publishItems', false, "bool"], ['refreshAllConnections', false, "bool"], ['saveExternalLinkValues', true, "bool"], ['showBorderUnselectedTables', true, "bool"], ['showInkAnnotation', true, "bool"], ['showObjects', 'all'], ['showPivotChartFilter', false, "bool"], ['updateLinks', 'userSet']];

/* 18.2.30 (CT_BookView) Defaults */
var WBViewDef = [['activeTab', 0, "int"], ['autoFilterDateGrouping', true, "bool"], ['firstSheet', 0, "int"], ['minimized', false, "bool"], ['showHorizontalScroll', true, "bool"], ['showSheetTabs', true, "bool"], ['showVerticalScroll', true, "bool"], ['tabRatio', 600, "int"], ['visibility', 'visible']
//window{Height,Width}, {x,y}Window
];

/* 18.2.19 (CT_Sheet) Defaults */
var SheetDef = [
  //['state', 'visible']
];

/* 18.2.2  (CT_CalcPr) Defaults */
var CalcPrDef = [['calcCompleted', 'true'], ['calcMode', 'auto'], ['calcOnSave', 'true'], ['concurrentCalc', 'true'], ['fullCalcOnLoad', 'false'], ['fullPrecision', 'true'], ['iterate', 'false'], ['iterateCount', '100'], ['iterateDelta', '0.001'], ['refMode', 'A1']];

/* 18.2.3 (CT_CustomWorkbookView) Defaults */
/*var CustomWBViewDef = [
	['autoUpdate', 'false'],
	['changesSavedWin', 'false'],
	['includeHiddenRowCol', 'true'],
	['includePrintSettings', 'true'],
	['maximized', 'false'],
	['minimized', 'false'],
	['onlySync', 'false'],
	['personalView', 'false'],
	['showComments', 'commIndicator'],
	['showFormulaBar', 'true'],
	['showHorizontalScroll', 'true'],
	['showObjects', 'all'],
	['showSheetTabs', 'true'],
	['showStatusbar', 'true'],
	['showVerticalScroll', 'true'],
	['tabRatio', '600'],
	['xWindow', '0'],
	['yWindow', '0']
];*/

function push_defaults_array(target, defaults) {
  for (var j = 0; j != target.length; ++j) {
    var w = target[j];
    for (var i = 0; i != defaults.length; ++i) {
      var z = defaults[i];
      if (w[z[0]] == null) w[z[0]] = z[1];else switch (z[2]) {
        case "bool":
          if (typeof w[z[0]] == "string") w[z[0]] = parsexmlbool(w[z[0]]);
          break;
        case "int":
          if (typeof w[z[0]] == "string") w[z[0]] = parseInt(w[z[0]], 10);
          break;
      }
    }
  }
}
function push_defaults(target, defaults) {
  for (var i = 0; i != defaults.length; ++i) {
    var z = defaults[i];
    if (target[z[0]] == null) target[z[0]] = z[1];else switch (z[2]) {
      case "bool":
        if (typeof target[z[0]] == "string") target[z[0]] = parsexmlbool(target[z[0]]);
        break;
      case "int":
        if (typeof target[z[0]] == "string") target[z[0]] = parseInt(target[z[0]], 10);
        break;
    }
  }
}
function parse_wb_defaults(wb) {
  push_defaults(wb.WBProps, WBPropsDef);
  push_defaults(wb.CalcPr, CalcPrDef);
  push_defaults_array(wb.WBView, WBViewDef);
  push_defaults_array(wb.Sheets, SheetDef);
  _ssfopts.date1904 = parsexmlbool(wb.WBProps.date1904);
}
function safe1904(wb /*:Workbook*/) /*:string*/{
  /* TODO: store date1904 somewhere else */
  if (!wb.Workbook) return "false";
  if (!wb.Workbook.WBProps) return "false";
  return parsexmlbool(wb.Workbook.WBProps.date1904) ? "true" : "false";
}
var badchars = /*#__PURE__*/"][*?\/\\".split("");
function check_ws_name(n /*:string*/, safe /*:?boolean*/) /*:boolean*/{
  if (n.length > 31) {
    if (safe) return false;
    throw new Error("Sheet names cannot exceed 31 chars");
  }
  var _good = true;
  badchars.forEach(function (c) {
    if (n.indexOf(c) == -1) return;
    if (!safe) throw new Error("Sheet name cannot contain : \\ / ? * [ ]");
    _good = false;
  });
  return _good;
}
function check_wb_names(N, S, codes) {
  N.forEach(function (n, i) {
    check_ws_name(n);
    for (var j = 0; j < i; ++j) if (n == N[j]) throw new Error("Duplicate Sheet Name: " + n);
    if (codes) {
      var cn = S && S[i] && S[i].CodeName || n;
      if (cn.charCodeAt(0) == 95 && cn.length > 22) throw new Error("Bad Code Name: Worksheet" + cn);
    }
  });
}
function check_wb(wb) {
  if (!wb || !wb.SheetNames || !wb.Sheets) throw new Error("Invalid Workbook");
  if (!wb.SheetNames.length) throw new Error("Workbook is empty");
  var Sheets = wb.Workbook && wb.Workbook.Sheets || [];
  check_wb_names(wb.SheetNames, Sheets, !!wb.vbaraw);
  for (var i = 0; i < wb.SheetNames.length; ++i) check_ws(wb.Sheets[wb.SheetNames[i]], wb.SheetNames[i], i);
  /* TODO: validate workbook */
}
/* 18.2 Workbook */
var wbnsregex = /<\w+:workbook/;
function parse_wb_xml(data, opts) /*:WorkbookFile*/{
  if (!data) throw new Error("Could not find file");
  var wb = /*::(*/{
    AppVersion: {},
    WBProps: {},
    WBView: [],
    Sheets: [],
    CalcPr: {},
    Names: [],
    xmlns: ""
  } /*::)*/;
  var pass = false,
    xmlns = "xmlns";
  var dname = {},
    dnstart = 0;
  data.replace(tagregex, function xml_wb(x, idx) {
    var y /*:any*/ = parsexmltag(x);
    switch (strip_ns(y[0])) {
      case '<?xml':
        break;

      /* 18.2.27 workbook CT_Workbook 1 */
      case '<workbook':
        if (x.match(wbnsregex)) xmlns = "xmlns" + x.match(/<(\w+):/)[1];
        wb.xmlns = y[xmlns];
        break;
      case '</workbook>':
        break;

      /* 18.2.13 fileVersion CT_FileVersion ? */
      case '<fileVersion':
        delete y[0];
        wb.AppVersion = y;
        break;
      case '<fileVersion/>':
      case '</fileVersion>':
        break;

      /* 18.2.12 fileSharing CT_FileSharing ? */
      case '<fileSharing':
        break;
      case '<fileSharing/>':
        break;

      /* 18.2.28 workbookPr CT_WorkbookPr ? */
      case '<workbookPr':
      case '<workbookPr/>':
        WBPropsDef.forEach(function (w) {
          if (y[w[0]] == null) return;
          switch (w[2]) {
            case "bool":
              wb.WBProps[w[0]] = parsexmlbool(y[w[0]]);
              break;
            case "int":
              wb.WBProps[w[0]] = parseInt(y[w[0]], 10);
              break;
            default:
              wb.WBProps[w[0]] = y[w[0]];
          }
        });
        if (y.codeName) wb.WBProps.CodeName = utf8read(y.codeName);
        break;
      case '</workbookPr>':
        break;

      /* 18.2.29 workbookProtection CT_WorkbookProtection ? */
      case '<workbookProtection':
        break;
      case '<workbookProtection/>':
        break;

      /* 18.2.1  bookViews CT_BookViews ? */
      case '<bookViews':
      case '<bookViews>':
      case '</bookViews>':
        break;
      /* 18.2.30   workbookView CT_BookView + */
      case '<workbookView':
      case '<workbookView/>':
        delete y[0];
        wb.WBView.push(y);
        break;
      case '</workbookView>':
        break;

      /* 18.2.20 sheets CT_Sheets 1 */
      case '<sheets':
      case '<sheets>':
      case '</sheets>':
        break;
      // aggregate sheet
      /* 18.2.19   sheet CT_Sheet + */
      case '<sheet':
        switch (y.state) {
          case "hidden":
            y.Hidden = 1;
            break;
          case "veryHidden":
            y.Hidden = 2;
            break;
          default:
            y.Hidden = 0;
        }
        delete y.state;
        y.name = unescapexml(utf8read(y.name));
        delete y[0];
        wb.Sheets.push(y);
        break;
      case '</sheet>':
        break;

      /* 18.2.15 functionGroups CT_FunctionGroups ? */
      case '<functionGroups':
      case '<functionGroups/>':
        break;
      /* 18.2.14   functionGroup CT_FunctionGroup + */
      case '<functionGroup':
        break;

      /* 18.2.9  externalReferences CT_ExternalReferences ? */
      case '<externalReferences':
      case '</externalReferences>':
      case '<externalReferences>':
        break;
      /* 18.2.8    externalReference CT_ExternalReference + */
      case '<externalReference':
        break;

      /* 18.2.6  definedNames CT_DefinedNames ? */
      case '<definedNames/>':
        break;
      case '<definedNames>':
      case '<definedNames':
        pass = true;
        break;
      case '</definedNames>':
        pass = false;
        break;
      /* 18.2.5    definedName CT_DefinedName + */
      case '<definedName':
        {
          dname = {};
          dname.Name = utf8read(y.name);
          if (y.comment) dname.Comment = y.comment;
          if (y.localSheetId) dname.Sheet = +y.localSheetId;
          if (parsexmlbool(y.hidden || "0")) dname.Hidden = true;
          dnstart = idx + x.length;
        }
        break;
      case '</definedName>':
        {
          dname.Ref = unescapexml(utf8read(data.slice(dnstart, idx)));
          wb.Names.push(dname);
        }
        break;
      case '<definedName/>':
        break;

      /* 18.2.2  calcPr CT_CalcPr ? */
      case '<calcPr':
        delete y[0];
        wb.CalcPr = y;
        break;
      case '<calcPr/>':
        delete y[0];
        wb.CalcPr = y;
        break;
      case '</calcPr>':
        break;

      /* 18.2.16 oleSize CT_OleSize ? (ref required) */
      case '<oleSize':
        break;

      /* 18.2.4  customWorkbookViews CT_CustomWorkbookViews ? */
      case '<customWorkbookViews>':
      case '</customWorkbookViews>':
      case '<customWorkbookViews':
        break;
      /* 18.2.3  customWorkbookView CT_CustomWorkbookView + */
      case '<customWorkbookView':
      case '</customWorkbookView>':
        break;

      /* 18.2.18 pivotCaches CT_PivotCaches ? */
      case '<pivotCaches>':
      case '</pivotCaches>':
      case '<pivotCaches':
        break;
      /* 18.2.17 pivotCache CT_PivotCache ? */
      case '<pivotCache':
        break;

      /* 18.2.21 smartTagPr CT_SmartTagPr ? */
      case '<smartTagPr':
      case '<smartTagPr/>':
        break;

      /* 18.2.23 smartTagTypes CT_SmartTagTypes ? */
      case '<smartTagTypes':
      case '<smartTagTypes>':
      case '</smartTagTypes>':
        break;
      /* 18.2.22 smartTagType CT_SmartTagType ? */
      case '<smartTagType':
        break;

      /* 18.2.24 webPublishing CT_WebPublishing ? */
      case '<webPublishing':
      case '<webPublishing/>':
        break;

      /* 18.2.11 fileRecoveryPr CT_FileRecoveryPr ? */
      case '<fileRecoveryPr':
      case '<fileRecoveryPr/>':
        break;

      /* 18.2.26 webPublishObjects CT_WebPublishObjects ? */
      case '<webPublishObjects>':
      case '<webPublishObjects':
      case '</webPublishObjects>':
        break;
      /* 18.2.25 webPublishObject CT_WebPublishObject ? */
      case '<webPublishObject':
        break;

      /* 18.2.10 extLst CT_ExtensionList ? */
      case '<extLst':
      case '<extLst>':
      case '</extLst>':
      case '<extLst/>':
        break;
      /* 18.2.7  ext CT_Extension + */
      case '<ext':
        pass = true;
        break;
      //TODO: check with versions of excel
      case '</ext>':
        pass = false;
        break;

      /* Others */
      case '<ArchID':
        break;
      case '<AlternateContent':
      case '<AlternateContent>':
        pass = true;
        break;
      case '</AlternateContent>':
        pass = false;
        break;

      /* TODO */
      case '<revisionPtr':
        break;
      default:
        if (!pass && opts.WTF) throw new Error('unrecognized ' + y[0] + ' in workbook');
    }
    return x;
  });
  if (XMLNS_main.indexOf(wb.xmlns) === -1) throw new Error("Unknown Namespace: " + wb.xmlns);
  parse_wb_defaults(wb);
  return wb;
}
function write_wb_xml(wb /*:Workbook*/ /*::, opts:?WriteOpts*/) /*:string*/{
  var o = [XML_HEADER];
  o[o.length] = writextag('workbook', null, {
    'xmlns': XMLNS_main[0],
    //'xmlns:mx': XMLNS.mx,
    //'xmlns:s': XMLNS_main[0],
    'xmlns:r': XMLNS.r
  });
  var write_names = wb.Workbook && (wb.Workbook.Names || []).length > 0;

  /* fileVersion */
  /* fileSharing */

  var workbookPr /*:any*/ = {
    codeName: "ThisWorkbook"
  } /*:any*/;
  if (wb.Workbook && wb.Workbook.WBProps) {
    WBPropsDef.forEach(function (x) {
      /*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */
      if (wb.Workbook.WBProps[x[0]] /*:any*/ == null) return;
      if (wb.Workbook.WBProps[x[0]] /*:any*/ == x[1]) return;
      workbookPr[x[0]] = wb.Workbook.WBProps[x[0]] /*:any*/;
    });
    /*:: if(!wb.Workbook || !wb.Workbook.WBProps) throw "unreachable"; */
    if (wb.Workbook.WBProps.CodeName) {
      workbookPr.codeName = wb.Workbook.WBProps.CodeName;
      delete workbookPr.CodeName;
    }
  }
  o[o.length] = writextag('workbookPr', null, workbookPr);

  /* workbookProtection */

  var sheets = wb.Workbook && wb.Workbook.Sheets || [];
  var i = 0;

  /* bookViews only written if first worksheet is hidden */
  if (sheets && sheets[0] && !!sheets[0].Hidden) {
    o[o.length] = "<bookViews>";
    for (i = 0; i != wb.SheetNames.length; ++i) {
      if (!sheets[i]) break;
      if (!sheets[i].Hidden) break;
    }
    if (i == wb.SheetNames.length) i = 0;
    o[o.length] = '<workbookView firstSheet="' + i + '" activeTab="' + i + '"/>';
    o[o.length] = "</bookViews>";
  }
  o[o.length] = "<sheets>";
  for (i = 0; i != wb.SheetNames.length; ++i) {
    var sht = {
      name: escapexml(wb.SheetNames[i].slice(0, 31))
    } /*:any*/;
    sht.sheetId = "" + (i + 1);
    sht["r:id"] = "rId" + (i + 1);
    if (sheets[i]) switch (sheets[i].Hidden) {
      case 1:
        sht.state = "hidden";
        break;
      case 2:
        sht.state = "veryHidden";
        break;
    }
    o[o.length] = writextag('sheet', null, sht);
  }
  o[o.length] = "</sheets>";

  /* functionGroups */
  /* externalReferences */

  if (write_names) {
    o[o.length] = "<definedNames>";
    if (wb.Workbook && wb.Workbook.Names) wb.Workbook.Names.forEach(function (n) {
      var d /*:any*/ = {
        name: n.Name
      };
      if (n.Comment) d.comment = n.Comment;
      if (n.Sheet != null) d.localSheetId = "" + n.Sheet;
      if (n.Hidden) d.hidden = "1";
      if (!n.Ref) return;
      o[o.length] = writextag('definedName', escapexml(n.Ref), d);
    });
    o[o.length] = "</definedNames>";
  }

  /* calcPr */
  /* oleSize */
  /* customWorkbookViews */
  /* pivotCaches */
  /* smartTagPr */
  /* smartTagTypes */
  /* webPublishing */
  /* fileRecoveryPr */
  /* webPublishObjects */
  /* extLst */

  if (o.length > 2) {
    o[o.length] = '</workbook>';
    o[1] = o[1].replace("/>", ">");
  }
  return o.join("");
}
/* [MS-XLSB] 2.4.304 BrtBundleSh */
function parse_BrtBundleSh(data, length /*:number*/) {
  var z = {};
  z.Hidden = data.read_shift(4); //hsState ST_SheetState
  z.iTabID = data.read_shift(4);
  z.strRelID = parse_RelID(data, length - 8);
  z.name = parse_XLWideString(data);
  return z;
}
function write_BrtBundleSh(data, o) {
  if (!o) o = new_buf(127);
  o.write_shift(4, data.Hidden);
  o.write_shift(4, data.iTabID);
  write_RelID(data.strRelID, o);
  write_XLWideString(data.name.slice(0, 31), o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.815 BrtWbProp */
function parse_BrtWbProp(data, length) /*:WBProps*/{
  var o /*:WBProps*/ = {} /*:any*/;
  var flags = data.read_shift(4);
  o.defaultThemeVersion = data.read_shift(4);
  var strName = length > 8 ? parse_XLWideString(data) : "";
  if (strName.length > 0) o.CodeName = strName;
  o.autoCompressPictures = !!(flags & 0x10000);
  o.backupFile = !!(flags & 0x40);
  o.checkCompatibility = !!(flags & 0x1000);
  o.date1904 = !!(flags & 0x01);
  o.filterPrivacy = !!(flags & 0x08);
  o.hidePivotFieldList = !!(flags & 0x400);
  o.promptedSolutions = !!(flags & 0x10);
  o.publishItems = !!(flags & 0x800);
  o.refreshAllConnections = !!(flags & 0x40000);
  o.saveExternalLinkValues = !!(flags & 0x80);
  o.showBorderUnselectedTables = !!(flags & 0x04);
  o.showInkAnnotation = !!(flags & 0x20);
  o.showObjects = ["all", "placeholders", "none"][flags >> 13 & 0x03];
  o.showPivotChartFilter = !!(flags & 0x8000);
  o.updateLinks = ["userSet", "never", "always"][flags >> 8 & 0x03];
  return o;
}
function write_BrtWbProp(data /*:?WBProps*/, o) {
  if (!o) o = new_buf(72);
  var flags = 0;
  if (data) {
    /* TODO: mirror parse_BrtWbProp fields */
    if (data.filterPrivacy) flags |= 0x08;
  }
  o.write_shift(4, flags);
  o.write_shift(4, 0);
  write_XLSBCodeName(data && data.CodeName || "ThisWorkbook", o);
  return o.slice(0, o.l);
}
function parse_BrtFRTArchID$(data, length) {
  var o = {};
  data.read_shift(4);
  o.ArchID = data.read_shift(4);
  data.l += length - 8;
  return o;
}

/* [MS-XLSB] 2.4.687 BrtName */
function parse_BrtName(data, length, opts) {
  var end = data.l + length;
  data.l += 4; //var flags = data.read_shift(4);
  data.l += 1; //var chKey = data.read_shift(1);
  var itab = data.read_shift(4);
  var name = parse_XLNameWideString(data);
  var formula = parse_XLSBNameParsedFormula(data, 0, opts);
  var comment = parse_XLNullableWideString(data);
  //if(0 /* fProc */) {
  // unusedstring1: XLNullableWideString
  // description: XLNullableWideString
  // helpTopic: XLNullableWideString
  // unusedstring2: XLNullableWideString
  //}
  data.l = end;
  var out = {
    Name: name,
    Ptg: formula
  } /*:any*/;
  if (itab < 0xFFFFFFF) out.Sheet = itab;
  if (comment) out.Comment = comment;
  return out;
}

/* [MS-XLSB] 2.1.7.61 Workbook */
function parse_wb_bin(data, opts) /*:WorkbookFile*/{
  var wb = {
    AppVersion: {},
    WBProps: {},
    WBView: [],
    Sheets: [],
    CalcPr: {},
    xmlns: ""
  };
  var state /*:Array<string>*/ = [];
  var pass = false;
  if (!opts) opts = {};
  opts.biff = 12;
  var Names = [];
  var supbooks = [[]] /*:any*/;
  supbooks.SheetNames = [];
  supbooks.XTI = [];
  XLSBRecordEnum[0x0010] = {
    n: "BrtFRTArchID$",
    f: parse_BrtFRTArchID$
  };
  recordhopper(data, function hopper_wb(val, R, RT) {
    switch (RT) {
      case 0x009C:
        /* 'BrtBundleSh' */
        supbooks.SheetNames.push(val.name);
        wb.Sheets.push(val);
        break;
      case 0x0099:
        /* 'BrtWbProp' */
        wb.WBProps = val;
        break;
      case 0x0027:
        /* 'BrtName' */
        if (val.Sheet != null) opts.SID = val.Sheet;
        val.Ref = stringify_formula(val.Ptg, null, null, supbooks, opts);
        delete opts.SID;
        delete val.Ptg;
        Names.push(val);
        break;
      case 0x040C:
        /* 'BrtNameExt' */break;
      case 0x0165: /* 'BrtSupSelf' */
      case 0x0166: /* 'BrtSupSame' */
      case 0x0163: /* 'BrtSupBookSrc' */
      case 0x029B:
        /* 'BrtSupAddin' */
        if (!supbooks[0].length) supbooks[0] = [RT, val];else supbooks.push([RT, val]);
        supbooks[supbooks.length - 1].XTI = [];
        break;
      case 0x016A:
        /* 'BrtExternSheet' */
        if (supbooks.length === 0) {
          supbooks[0] = [];
          supbooks[0].XTI = [];
        }
        supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val);
        supbooks.XTI = supbooks.XTI.concat(val);
        break;
      case 0x0169:
        /* 'BrtPlaceholderName' */
        break;
      case 0x0817: /* 'BrtAbsPath15' */
      case 0x009E: /* 'BrtBookView' */
      case 0x008F: /* 'BrtBeginBundleShs' */
      case 0x0298: /* 'BrtBeginFnGroup' */
      case 0x0161:
        /* 'BrtBeginExternals' */
        break;

      /* case 'BrtModelTimeGroupingCalcCol' */
      case 0x0C00: /* 'BrtUid' */
      case 0x0C01: /* 'BrtRevisionPtr' */
      case 0x0216: /* 'BrtBookProtection' */
      case 0x02A5: /* 'BrtBookProtectionIso' */
      case 0x009D: /* 'BrtCalcProp' */
      case 0x0262: /* 'BrtCrashRecErr' */
      case 0x0802: /* 'BrtDecoupledPivotCacheID' */
      case 0x009B: /* 'BrtFileRecover' */
      case 0x0224: /* 'BrtFileSharing' */
      case 0x02A4: /* 'BrtFileSharingIso' */
      case 0x0080: /* 'BrtFileVersion' */
      case 0x0299: /* 'BrtFnGroup' */
      case 0x0850: /* 'BrtModelRelationship' */
      case 0x084D: /* 'BrtModelTable' */
      case 0x0225: /* 'BrtOleSize' */
      case 0x0805: /* 'BrtPivotTableRef' */
      case 0x0254: /* 'BrtSmartTagType' */
      case 0x081C: /* 'BrtTableSlicerCacheID' */
      case 0x081B: /* 'BrtTableSlicerCacheIDs' */
      case 0x0822: /* 'BrtTimelineCachePivotCacheID' */
      case 0x018D: /* 'BrtUserBookView' */
      case 0x009A: /* 'BrtWbFactoid' */
      case 0x045D: /* 'BrtWbProp14' */
      case 0x0229: /* 'BrtWebOpt' */
      case 0x082B:
        /* 'BrtWorkBookPr15' */
        break;
      case 0x0023:
        /* 'BrtFRTBegin' */
        state.push(RT);
        pass = true;
        break;
      case 0x0024:
        /* 'BrtFRTEnd' */
        state.pop();
        pass = false;
        break;
      case 0x0025:
        /* 'BrtACBegin' */
        state.push(RT);
        pass = true;
        break;
      case 0x0026:
        /* 'BrtACEnd' */
        state.pop();
        pass = false;
        break;
      case 0x0010:
        /* 'BrtFRTArchID$' */break;
      default:
        if (R.T) {/* empty */} else if (!pass || opts.WTF && state[state.length - 1] != 0x0025 /* BrtACBegin */ && state[state.length - 1] != 0x0023 /* BrtFRTBegin */) throw new Error("Unexpected record 0x" + RT.toString(16));
    }
  }, opts);
  parse_wb_defaults(wb);

  // $FlowIgnore
  wb.Names = Names;
  wb /*:any*/.supbooks = supbooks;
  return wb;
}
function write_BUNDLESHS(ba, wb /*::, opts*/) {
  write_record(ba, 0x008F /* BrtBeginBundleShs */);
  for (var idx = 0; idx != wb.SheetNames.length; ++idx) {
    var viz = wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx] && wb.Workbook.Sheets[idx].Hidden || 0;
    var d = {
      Hidden: viz,
      iTabID: idx + 1,
      strRelID: 'rId' + (idx + 1),
      name: wb.SheetNames[idx]
    };
    write_record(ba, 0x009C /* BrtBundleSh */, write_BrtBundleSh(d));
  }
  write_record(ba, 0x0090 /* BrtEndBundleShs */);
}

/* [MS-XLSB] 2.4.649 BrtFileVersion */
function write_BrtFileVersion(data, o) {
  if (!o) o = new_buf(127);
  for (var i = 0; i != 4; ++i) o.write_shift(4, 0);
  write_XLWideString("SheetJS", o);
  write_XLWideString(XLSX.version, o);
  write_XLWideString(XLSX.version, o);
  write_XLWideString("7262", o);
  return o.length > o.l ? o.slice(0, o.l) : o;
}

/* [MS-XLSB] 2.4.301 BrtBookView */
function write_BrtBookView(idx, o) {
  if (!o) o = new_buf(29);
  o.write_shift(-4, 0);
  o.write_shift(-4, 460);
  o.write_shift(4, 28800);
  o.write_shift(4, 17600);
  o.write_shift(4, 500);
  o.write_shift(4, idx);
  o.write_shift(4, idx);
  var flags = 0x78;
  o.write_shift(1, flags);
  return o.length > o.l ? o.slice(0, o.l) : o;
}
function write_BOOKVIEWS(ba, wb /*::, opts*/) {
  /* required if hidden tab appears before visible tab */
  if (!wb.Workbook || !wb.Workbook.Sheets) return;
  var sheets = wb.Workbook.Sheets;
  var i = 0,
    vistab = -1,
    hidden = -1;
  for (; i < sheets.length; ++i) {
    if (!sheets[i] || !sheets[i].Hidden && vistab == -1) vistab = i;else if (sheets[i].Hidden == 1 && hidden == -1) hidden = i;
  }
  if (hidden > vistab) return;
  write_record(ba, 0x0087 /* BrtBeginBookViews */);
  write_record(ba, 0x009E /* BrtBookView */, write_BrtBookView(vistab));
  /* 1*(BrtBookView *FRT) */
  write_record(ba, 0x0088 /* BrtEndBookViews */);
}

/* [MS-XLSB] 2.4.305 BrtCalcProp */
/*function write_BrtCalcProp(data, o) {
	if(!o) o = new_buf(26);
	o.write_shift(4,0); // force recalc
	o.write_shift(4,1);
	o.write_shift(4,0);
	write_Xnum(0, o);
	o.write_shift(-4, 1023);
	o.write_shift(1, 0x33);
	o.write_shift(1, 0x00);
	return o;
}*/

/* [MS-XLSB] 2.4.646 BrtFileRecover */
/*function write_BrtFileRecover(data, o) {
	if(!o) o = new_buf(1);
	o.write_shift(1,0);
	return o;
}*/

/* [MS-XLSB] 2.1.7.61 Workbook */
function write_wb_bin(wb, opts) {
  var ba = buf_array();
  write_record(ba, 0x0083 /* BrtBeginBook */);
  write_record(ba, 0x0080 /* BrtFileVersion */, write_BrtFileVersion());
  /* [[BrtFileSharingIso] BrtFileSharing] */
  write_record(ba, 0x0099 /* BrtWbProp */, write_BrtWbProp(wb.Workbook && wb.Workbook.WBProps || null));
  /* [ACABSPATH] */
  /* [[BrtBookProtectionIso] BrtBookProtection] */
  write_BOOKVIEWS(ba, wb, opts);
  write_BUNDLESHS(ba, wb, opts);
  /* [FNGROUP] */
  /* [EXTERNALS] */
  /* *BrtName */
  /* write_record(ba, 0x009D BrtCalcProp, write_BrtCalcProp()); */
  /* [BrtOleSize] */
  /* *(BrtUserBookView *FRT) */
  /* [PIVOTCACHEIDS] */
  /* [BrtWbFactoid] */
  /* [SMARTTAGTYPES] */
  /* [BrtWebOpt] */
  /* write_record(ba, 0x009B BrtFileRecover, write_BrtFileRecover()); */
  /* [WEBPUBITEMS] */
  /* [CRERRS] */
  /* FRTWORKBOOK */
  write_record(ba, 0x0084 /* BrtEndBook */);
  return ba.end();
}
function parse_wb(data, name /*:string*/, opts) /*:WorkbookFile*/{
  if (name.slice(-4) === ".bin") return parse_wb_bin(data /*:any*/, opts);
  return parse_wb_xml(data /*:any*/, opts);
}
function parse_ws(data, name /*:string*/, idx /*:number*/, opts, rels, wb, themes, styles) /*:Worksheet*/{
  if (name.slice(-4) === ".bin") return parse_ws_bin(data /*:any*/, opts, idx, rels, wb, themes, styles);
  return parse_ws_xml(data /*:any*/, opts, idx, rels, wb, themes, styles);
}
function parse_cs(data, name /*:string*/, idx /*:number*/, opts, rels, wb, themes, styles) /*:Worksheet*/{
  if (name.slice(-4) === ".bin") return parse_cs_bin(data /*:any*/, opts, idx, rels, wb, themes, styles);
  return parse_cs_xml(data /*:any*/, opts, idx, rels, wb, themes, styles);
}
function parse_ms(data, name /*:string*/, idx /*:number*/, opts, rels, wb, themes, styles) /*:Worksheet*/{
  if (name.slice(-4) === ".bin") return parse_ms_bin(data /*:any*/, opts, idx, rels, wb, themes, styles);
  return parse_ms_xml(data /*:any*/, opts, idx, rels, wb, themes, styles);
}
function parse_ds(data, name /*:string*/, idx /*:number*/, opts, rels, wb, themes, styles) /*:Worksheet*/{
  if (name.slice(-4) === ".bin") return parse_ds_bin(data /*:any*/, opts, idx, rels, wb, themes, styles);
  return parse_ds_xml(data /*:any*/, opts, idx, rels, wb, themes, styles);
}
function parse_sty(data, name /*:string*/, themes, opts) {
  if (name.slice(-4) === ".bin") return parse_sty_bin(data /*:any*/, themes, opts);
  return parse_sty_xml(data /*:any*/, themes, opts);
}
function parse_theme(data /*:string*/, name /*:string*/, opts) {
  return parse_theme_xml(data, opts);
}
function parse_sst(data, name /*:string*/, opts) /*:SST*/{
  if (name.slice(-4) === ".bin") return parse_sst_bin(data /*:any*/, opts);
  return parse_sst_xml(data /*:any*/, opts);
}
function parse_cmnt(data, name /*:string*/, opts) /*:Array<RawComment>*/{
  if (name.slice(-4) === ".bin") return parse_comments_bin(data /*:any*/, opts);
  return parse_comments_xml(data /*:any*/, opts);
}
function parse_cc(data, name /*:string*/, opts) {
  if (name.slice(-4) === ".bin") return parse_cc_bin(data /*:any*/, name, opts);
  return parse_cc_xml(data /*:any*/, name, opts);
}
function parse_xlink(data, rel, name /*:string*/, opts) {
  if (name.slice(-4) === ".bin") return parse_xlink_bin(data /*:any*/, rel, name, opts);
  return parse_xlink_xml(data /*:any*/, rel, name, opts);
}
function parse_xlmeta(data, name /*:string*/, opts) {
  if (name.slice(-4) === ".bin") return parse_xlmeta_bin(data /*:any*/, name, opts);
  return parse_xlmeta_xml(data /*:any*/, name, opts);
}
function write_wb(wb, name /*:string*/, opts) {
  return (name.slice(-4) === ".bin" ? write_wb_bin : write_wb_xml)(wb, opts);
}
function write_ws(data /*:number*/, name /*:string*/, opts, wb /*:Workbook*/, rels) {
  return (name.slice(-4) === ".bin" ? write_ws_bin : write_ws_xml)(data, opts, wb, rels);
}

// eslint-disable-next-line no-unused-vars
function write_cs(data /*:number*/, name /*:string*/, opts, wb /*:Workbook*/, rels) {
  return (name.slice(-4) === ".bin" ? write_cs_bin : write_cs_xml)(data, opts, wb, rels);
}
function write_sty(data, name /*:string*/, opts) {
  return (name.slice(-4) === ".bin" ? write_sty_bin : write_sty_xml)(data, opts);
}
function write_sst(data /*:SST*/, name /*:string*/, opts) {
  return (name.slice(-4) === ".bin" ? write_sst_bin : write_sst_xml)(data, opts);
}
function write_cmnt(data /*:Array<any>*/, name /*:string*/, opts) {
  return (name.slice(-4) === ".bin" ? write_comments_bin : write_comments_xml)(data, opts);
}
/*
function write_cc(data, name:string, opts) {
	return (name.slice(-4)===".bin" ? write_cc_bin : write_cc_xml)(data, opts);
}
*/

function write_xlmeta(name /*:string*/) {
  return (name.slice(-4) === ".bin" ? write_xlmeta_bin : write_xlmeta_xml)();
}
var attregexg2 = /([\w:]+)=((?:")([^"]*)(?:")|(?:')([^']*)(?:'))/g;
var attregex2 = /([\w:]+)=((?:")(?:[^"]*)(?:")|(?:')(?:[^']*)(?:'))/;
function xlml_parsexmltag(tag /*:string*/, skip_root /*:?boolean*/) {
  var words = tag.split(/\s+/);
  var z /*:any*/ = [] /*:any*/;
  if (!skip_root) z[0] = words[0];
  if (words.length === 1) return z;
  var m = tag.match(attregexg2),
    y,
    j,
    w,
    i;
  if (m) for (i = 0; i != m.length; ++i) {
    y = m[i].match(attregex2);
    /*:: if(!y || !y[2]) continue; */
    if ((j = y[1].indexOf(":")) === -1) z[y[1]] = y[2].slice(1, y[2].length - 1);else {
      if (y[1].slice(0, 6) === "xmlns:") w = "xmlns" + y[1].slice(6);else w = y[1].slice(j + 1);
      z[w] = y[2].slice(1, y[2].length - 1);
    }
  }
  return z;
}
function xlml_parsexmltagobj(tag /*:string*/) {
  var words = tag.split(/\s+/);
  var z = {};
  if (words.length === 1) return z;
  var m = tag.match(attregexg2),
    y,
    j,
    w,
    i;
  if (m) for (i = 0; i != m.length; ++i) {
    y = m[i].match(attregex2);
    /*:: if(!y || !y[2]) continue; */
    if ((j = y[1].indexOf(":")) === -1) z[y[1]] = y[2].slice(1, y[2].length - 1);else {
      if (y[1].slice(0, 6) === "xmlns:") w = "xmlns" + y[1].slice(6);else w = y[1].slice(j + 1);
      z[w] = y[2].slice(1, y[2].length - 1);
    }
  }
  return z;
}

// ----

/* map from xlml named formats to SSF TODO: localize */
var XLMLFormatMap /*: {[string]:string}*/;
function xlml_format(format, value) /*:string*/{
  var fmt = XLMLFormatMap[format] || unescapexml(format);
  if (fmt === "General") return SSF_general(value);
  return SSF_format(fmt, value);
}
function xlml_set_custprop(Custprops, key, cp, val /*:string*/) {
  var oval /*:any*/ = val;
  switch ((cp[0].match(/dt:dt="([\w.]+)"/) || ["", ""])[1]) {
    case "boolean":
      oval = parsexmlbool(val);
      break;
    case "i2":
    case "int":
      oval = parseInt(val, 10);
      break;
    case "r4":
    case "float":
      oval = parseFloat(val);
      break;
    case "date":
    case "dateTime.tz":
      oval = parseDate(val);
      break;
    case "i8":
    case "string":
    case "fixed":
    case "uuid":
    case "bin.base64":
      break;
    default:
      throw new Error("bad custprop:" + cp[0]);
  }
  Custprops[unescapexml(key)] = oval;
}
function safe_format_xlml(cell /*:Cell*/, nf, o) {
  if (cell.t === 'z') return;
  if (!o || o.cellText !== false) try {
    if (cell.t === 'e') {
      cell.w = cell.w || BErr[cell.v];
    } else if (nf === "General") {
      if (cell.t === 'n') {
        if ((cell.v | 0) === cell.v) cell.w = cell.v.toString(10);else cell.w = SSF_general_num(cell.v);
      } else cell.w = SSF_general(cell.v);
    } else cell.w = xlml_format(nf || "General", cell.v);
  } catch (e) {
    if (o.WTF) throw e;
  }
  try {
    var z = XLMLFormatMap[nf] || nf || "General";
    if (o.cellNF) cell.z = z;
    if (o.cellDates && cell.t == 'n' && fmt_is_date(z)) {
      var _d = SSF_parse_date_code(cell.v);
      if (_d) {
        cell.t = 'd';
        cell.v = new Date(_d.y, _d.m - 1, _d.d, _d.H, _d.M, _d.S, _d.u);
      }
    }
  } catch (e) {
    if (o.WTF) throw e;
  }
}
function process_style_xlml(styles, stag, opts) {
  if (opts.cellStyles) {
    if (stag.Interior) {
      var I = stag.Interior;
      if (I.Pattern) I.patternType = XLMLPatternTypeMap[I.Pattern] || I.Pattern;
    }
  }
  styles[stag.ID] = stag;
}

/* TODO: there must exist some form of OSP-blessed spec */
function parse_xlml_data(xml, ss, data, cell /*:any*/, base, styles, csty, row, arrayf, o) {
  var nf = "General",
    sid = cell.StyleID,
    S = {};
  o = o || {};
  var interiors = [];
  var i = 0;
  if (sid === undefined && row) sid = row.StyleID;
  if (sid === undefined && csty) sid = csty.StyleID;
  while (styles[sid] !== undefined) {
    if (styles[sid].nf) nf = styles[sid].nf;
    if (styles[sid].Interior) interiors.push(styles[sid].Interior);
    if (!styles[sid].Parent) break;
    sid = styles[sid].Parent;
  }
  switch (data.Type) {
    case 'Boolean':
      cell.t = 'b';
      cell.v = parsexmlbool(xml);
      break;
    case 'String':
      cell.t = 's';
      cell.r = xlml_fixstr(unescapexml(xml));
      cell.v = xml.indexOf("<") > -1 ? unescapexml(ss || xml).replace(/<.*?>/g, "") : cell.r; // todo: BR etc
      break;
    case 'DateTime':
      if (xml.slice(-1) != "Z") xml += "Z";
      cell.v = (parseDate(xml) - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
      if (cell.v !== cell.v) cell.v = unescapexml(xml);else if (cell.v < 60) cell.v = cell.v - 1;
      if (!nf || nf == "General") nf = "yyyy-mm-dd";
    /* falls through */
    case 'Number':
      if (cell.v === undefined) cell.v = +xml;
      if (!cell.t) cell.t = 'n';
      break;
    case 'Error':
      cell.t = 'e';
      cell.v = RBErr[xml];
      if (o.cellText !== false) cell.w = xml;
      break;
    default:
      if (xml == "" && ss == "") {
        cell.t = 'z';
      } else {
        cell.t = 's';
        cell.v = xlml_fixstr(ss || xml);
      }
      break;
  }
  safe_format_xlml(cell, nf, o);
  if (o.cellFormula !== false) {
    if (cell.Formula) {
      var fstr = unescapexml(cell.Formula);
      /* strictly speaking, the leading = is required but some writers omit */
      if (fstr.charCodeAt(0) == 61 /* = */) fstr = fstr.slice(1);
      cell.f = rc_to_a1(fstr, base);
      delete cell.Formula;
      if (cell.ArrayRange == "RC") cell.F = rc_to_a1("RC:RC", base);else if (cell.ArrayRange) {
        cell.F = rc_to_a1(cell.ArrayRange, base);
        arrayf.push([safe_decode_range(cell.F), cell.F]);
      }
    } else {
      for (i = 0; i < arrayf.length; ++i) if (base.r >= arrayf[i][0].s.r && base.r <= arrayf[i][0].e.r) if (base.c >= arrayf[i][0].s.c && base.c <= arrayf[i][0].e.c) cell.F = arrayf[i][1];
    }
  }
  if (o.cellStyles) {
    interiors.forEach(function (x) {
      if (!S.patternType && x.patternType) S.patternType = x.patternType;
    });
    cell.s = S;
  }
  if (cell.StyleID !== undefined) cell.ixfe = cell.StyleID;
}
function xlml_clean_comment(comment /*:any*/) {
  comment.t = comment.v || "";
  comment.t = comment.t.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
  comment.v = comment.w = comment.ixfe = undefined;
}

/* TODO: Everything */
function parse_xlml_xml(d, _opts) /*:Workbook*/{
  var opts = _opts || {};
  make_ssf();
  var str = debom(xlml_normalize(d));
  if (opts.type == 'binary' || opts.type == 'array' || opts.type == 'base64') {
    if (typeof $cptable !== 'undefined') str = $cptable.utils.decode(65001, char_codes(str));else str = utf8read(str);
  }
  var opening = str.slice(0, 1024).toLowerCase(),
    ishtml = false;
  opening = opening.replace(/".*?"/g, "");
  if ((opening.indexOf(">") & 1023) > Math.min(opening.indexOf(",") & 1023, opening.indexOf(";") & 1023)) {
    var _o = dup(opts);
    _o.type = "string";
    return PRN.to_workbook(str, _o);
  }
  if (opening.indexOf("<?xml") == -1) ["html", "table", "head", "meta", "script", "style", "div"].forEach(function (tag) {
    if (opening.indexOf("<" + tag) >= 0) ishtml = true;
  });
  if (ishtml) return html_to_workbook(str, opts);
  XLMLFormatMap = {
    "General Number": "General",
    "General Date": table_fmt[22],
    "Long Date": "dddd, mmmm dd, yyyy",
    "Medium Date": table_fmt[15],
    "Short Date": table_fmt[14],
    "Long Time": table_fmt[19],
    "Medium Time": table_fmt[18],
    "Short Time": table_fmt[20],
    "Currency": '"$"#,##0.00_);[Red]\\("$"#,##0.00\\)',
    "Fixed": table_fmt[2],
    "Standard": table_fmt[4],
    "Percent": table_fmt[10],
    "Scientific": table_fmt[11],
    "Yes/No": '"Yes";"Yes";"No";@',
    "True/False": '"True";"True";"False";@',
    "On/Off": '"Yes";"Yes";"No";@'
  } /*:any*/;
  var Rn;
  var state = [],
    tmp;
  if (DENSE != null && opts.dense == null) opts.dense = DENSE;
  var sheets = {},
    sheetnames /*:Array<string>*/ = [],
    cursheet /*:Worksheet*/ = opts.dense ? [] : {},
    sheetname = "";
  var cell = {} /*:any*/,
    row = {}; // eslint-disable-line no-unused-vars
  var dtag = xlml_parsexmltag('<Data ss:Type="String">'),
    didx = 0;
  var c = 0,
    r = 0;
  var refguess /*:Range*/ = {
    s: {
      r: 2000000,
      c: 2000000
    },
    e: {
      r: 0,
      c: 0
    }
  };
  var styles = {},
    stag = {};
  var ss = "",
    fidx = 0;
  var merges /*:Array<Range>*/ = [];
  var Props = {},
    Custprops = {},
    pidx = 0,
    cp = [];
  var comments /*:Array<Comment>*/ = [],
    comment /*:Comment*/ = {} /*:any*/;
  var cstys = [],
    csty,
    seencol = false;
  var arrayf /*:Array<[Range, string]>*/ = [];
  var rowinfo /*:Array<RowInfo>*/ = [],
    rowobj = {},
    cc = 0,
    rr = 0;
  var Workbook /*:WBWBProps*/ = {
      Sheets: [],
      WBProps: {
        date1904: false
      }
    } /*:any*/,
    wsprops = {};
  xlmlregex.lastIndex = 0;
  str = str.replace(/<!--([\s\S]*?)-->/mg, "");
  var raw_Rn3 = "";
  while (Rn = xlmlregex.exec(str)) switch (Rn[3] = (raw_Rn3 = Rn[3]).toLowerCase()) {
    case 'data' /*case 'Data'*/:
      if (raw_Rn3 == "data") {
        if (Rn[1] === '/') {
          if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
        } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') state.push([Rn[3], true]);
        break;
      }
      if (state[state.length - 1][1]) break;
      if (Rn[1] === '/') parse_xlml_data(str.slice(didx, Rn.index), ss, dtag, state[state.length - 1][0] == /*"Comment"*/"comment" ? comment : cell, {
        c: c,
        r: r
      }, styles, cstys[c], row, arrayf, opts);else {
        ss = "";
        dtag = xlml_parsexmltag(Rn[0]);
        didx = Rn.index + Rn[0].length;
      }
      break;
    case 'cell' /*case 'Cell'*/:
      if (Rn[1] === '/') {
        if (comments.length > 0) cell.c = comments;
        if ((!opts.sheetRows || opts.sheetRows > r) && cell.v !== undefined) {
          if (opts.dense) {
            if (!cursheet[r]) cursheet[r] = [];
            cursheet[r][c] = cell;
          } else cursheet[encode_col(c) + encode_row(r)] = cell;
        }
        if (cell.HRef) {
          cell.l = {
            Target: unescapexml(cell.HRef)
          } /*:any*/;
          if (cell.HRefScreenTip) cell.l.Tooltip = cell.HRefScreenTip;
          delete cell.HRef;
          delete cell.HRefScreenTip;
        }
        if (cell.MergeAcross || cell.MergeDown) {
          cc = c + (parseInt(cell.MergeAcross, 10) | 0);
          rr = r + (parseInt(cell.MergeDown, 10) | 0);
          merges.push({
            s: {
              c: c,
              r: r
            },
            e: {
              c: cc,
              r: rr
            }
          });
        }
        if (!opts.sheetStubs) {
          if (cell.MergeAcross) c = cc + 1;else ++c;
        } else if (cell.MergeAcross || cell.MergeDown) {
          /*:: if(!cc) cc = 0; if(!rr) rr = 0; */
          for (var cma = c; cma <= cc; ++cma) {
            for (var cmd = r; cmd <= rr; ++cmd) {
              if (cma > c || cmd > r) {
                if (opts.dense) {
                  if (!cursheet[cmd]) cursheet[cmd] = [];
                  cursheet[cmd][cma] = {
                    t: 'z'
                  };
                } else cursheet[encode_col(cma) + encode_row(cmd)] = {
                  t: 'z'
                };
              }
            }
          }
          c = cc + 1;
        } else ++c;
      } else {
        cell = xlml_parsexmltagobj(Rn[0]);
        if (cell.Index) c = +cell.Index - 1;
        if (c < refguess.s.c) refguess.s.c = c;
        if (c > refguess.e.c) refguess.e.c = c;
        if (Rn[0].slice(-2) === "/>") ++c;
        comments = [];
      }
      break;
    case 'row' /*case 'Row'*/:
      if (Rn[1] === '/' || Rn[0].slice(-2) === "/>") {
        if (r < refguess.s.r) refguess.s.r = r;
        if (r > refguess.e.r) refguess.e.r = r;
        if (Rn[0].slice(-2) === "/>") {
          row = xlml_parsexmltag(Rn[0]);
          if (row.Index) r = +row.Index - 1;
        }
        c = 0;
        ++r;
      } else {
        row = xlml_parsexmltag(Rn[0]);
        if (row.Index) r = +row.Index - 1;
        rowobj = {};
        if (row.AutoFitHeight == "0" || row.Height) {
          rowobj.hpx = parseInt(row.Height, 10);
          rowobj.hpt = px2pt(rowobj.hpx);
          rowinfo[r] = rowobj;
        }
        if (row.Hidden == "1") {
          rowobj.hidden = true;
          rowinfo[r] = rowobj;
        }
      }
      break;
    case 'worksheet' /*case 'Worksheet'*/:
      /* TODO: read range from FullRows/FullColumns */
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
        sheetnames.push(sheetname);
        if (refguess.s.r <= refguess.e.r && refguess.s.c <= refguess.e.c) {
          cursheet["!ref"] = encode_range(refguess);
          if (opts.sheetRows && opts.sheetRows <= refguess.e.r) {
            cursheet["!fullref"] = cursheet["!ref"];
            refguess.e.r = opts.sheetRows - 1;
            cursheet["!ref"] = encode_range(refguess);
          }
        }
        if (merges.length) cursheet["!merges"] = merges;
        if (cstys.length > 0) cursheet["!cols"] = cstys;
        if (rowinfo.length > 0) cursheet["!rows"] = rowinfo;
        sheets[sheetname] = cursheet;
      } else {
        refguess = {
          s: {
            r: 2000000,
            c: 2000000
          },
          e: {
            r: 0,
            c: 0
          }
        };
        r = c = 0;
        state.push([Rn[3], false]);
        tmp = xlml_parsexmltag(Rn[0]);
        sheetname = unescapexml(tmp.Name);
        cursheet = opts.dense ? [] : {};
        merges = [];
        arrayf = [];
        rowinfo = [];
        wsprops = {
          name: sheetname,
          Hidden: 0
        };
        Workbook.Sheets.push(wsprops);
      }
      break;
    case 'table' /*case 'Table'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
      } else if (Rn[0].slice(-2) == "/>") break;else {
        state.push([Rn[3], false]);
        cstys = [];
        seencol = false;
      }
      break;
    case 'style' /*case 'Style'*/:
      if (Rn[1] === '/') process_style_xlml(styles, stag, opts);else stag = xlml_parsexmltag(Rn[0]);
      break;
    case 'numberformat' /*case 'NumberFormat'*/:
      stag.nf = unescapexml(xlml_parsexmltag(Rn[0]).Format || "General");
      if (XLMLFormatMap[stag.nf]) stag.nf = XLMLFormatMap[stag.nf];
      for (var ssfidx = 0; ssfidx != 0x188; ++ssfidx) if (table_fmt[ssfidx] == stag.nf) break;
      if (ssfidx == 0x188) for (ssfidx = 0x39; ssfidx != 0x188; ++ssfidx) if (table_fmt[ssfidx] == null) {
        SSF_load(stag.nf, ssfidx);
        break;
      }
      break;
    case 'column' /*case 'Column'*/:
      if (state[state.length - 1][0] !== /*'Table'*/'table') break;
      csty = xlml_parsexmltag(Rn[0]);
      if (csty.Hidden) {
        csty.hidden = true;
        delete csty.Hidden;
      }
      if (csty.Width) csty.wpx = parseInt(csty.Width, 10);
      if (!seencol && csty.wpx > 10) {
        seencol = true;
        MDW = DEF_MDW; //find_mdw_wpx(csty.wpx);
        for (var _col = 0; _col < cstys.length; ++_col) if (cstys[_col]) process_col(cstys[_col]);
      }
      if (seencol) process_col(csty);
      cstys[csty.Index - 1 || cstys.length] = csty;
      for (var i = 0; i < +csty.Span; ++i) cstys[cstys.length] = dup(csty);
      break;
    case 'namedrange' /*case 'NamedRange'*/:
      if (Rn[1] === '/') break;
      if (!Workbook.Names) Workbook.Names = [];
      var _NamedRange = parsexmltag(Rn[0]);
      var _DefinedName /*:DefinedName*/ = {
        Name: _NamedRange.Name,
        Ref: rc_to_a1(_NamedRange.RefersTo.slice(1), {
          r: 0,
          c: 0
        })
      } /*:any*/;
      if (Workbook.Sheets.length > 0) _DefinedName.Sheet = Workbook.Sheets.length - 1;
      /*:: if(Workbook.Names) */
      Workbook.Names.push(_DefinedName);
      break;
    case 'namedcell' /*case 'NamedCell'*/:
      break;
    case 'b' /*case 'B'*/:
      break;
    case 'i' /*case 'I'*/:
      break;
    case 'u' /*case 'U'*/:
      break;
    case 's' /*case 'S'*/:
      break;
    case 'em' /*case 'EM'*/:
      break;
    case 'h2' /*case 'H2'*/:
      break;
    case 'h3' /*case 'H3'*/:
      break;
    case 'sub' /*case 'Sub'*/:
      break;
    case 'sup' /*case 'Sup'*/:
      break;
    case 'span' /*case 'Span'*/:
      break;
    case 'alignment' /*case 'Alignment'*/:
      break;
    case 'borders' /*case 'Borders'*/:
      break;
    case 'border' /*case 'Border'*/:
      break;
    case 'font' /*case 'Font'*/:
      if (Rn[0].slice(-2) === "/>") break;else if (Rn[1] === "/") ss += str.slice(fidx, Rn.index);else fidx = Rn.index + Rn[0].length;
      break;
    case 'interior' /*case 'Interior'*/:
      if (!opts.cellStyles) break;
      stag.Interior = xlml_parsexmltag(Rn[0]);
      break;
    case 'protection' /*case 'Protection'*/:
      break;
    case 'author' /*case 'Author'*/:
    case 'title' /*case 'Title'*/:
    case 'description' /*case 'Description'*/:
    case 'created' /*case 'Created'*/:
    case 'keywords' /*case 'Keywords'*/:
    case 'subject' /*case 'Subject'*/:
    case 'category' /*case 'Category'*/:
    case 'company' /*case 'Company'*/:
    case 'lastauthor' /*case 'LastAuthor'*/:
    case 'lastsaved' /*case 'LastSaved'*/:
    case 'lastprinted' /*case 'LastPrinted'*/:
    case 'version' /*case 'Version'*/:
    case 'revision' /*case 'Revision'*/:
    case 'totaltime' /*case 'TotalTime'*/:
    case 'hyperlinkbase' /*case 'HyperlinkBase'*/:
    case 'manager' /*case 'Manager'*/:
    case 'contentstatus' /*case 'ContentStatus'*/:
    case 'identifier' /*case 'Identifier'*/:
    case 'language' /*case 'Language'*/:
    case 'appname' /*case 'AppName'*/:
      if (Rn[0].slice(-2) === "/>") break;else if (Rn[1] === "/") xlml_set_prop(Props, raw_Rn3, str.slice(pidx, Rn.index));else pidx = Rn.index + Rn[0].length;
      break;
    case 'paragraphs' /*case 'Paragraphs'*/:
      break;
    case 'styles' /*case 'Styles'*/:
    case 'workbook' /*case 'Workbook'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
      } else state.push([Rn[3], false]);
      break;
    case 'comment' /*case 'Comment'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
        xlml_clean_comment(comment);
        comments.push(comment);
      } else {
        state.push([Rn[3], false]);
        tmp = xlml_parsexmltag(Rn[0]);
        comment = {
          a: tmp.Author
        } /*:any*/;
      }
      break;
    case 'autofilter' /*case 'AutoFilter'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') {
        var AutoFilter = xlml_parsexmltag(Rn[0]);
        cursheet['!autofilter'] = {
          ref: rc_to_a1(AutoFilter.Range).replace(/\$/g, "")
        };
        state.push([Rn[3], true]);
      }
      break;
    case 'name' /*case 'Name'*/:
      break;
    case 'datavalidation' /*case 'DataValidation'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
      } else {
        if (Rn[0].charAt(Rn[0].length - 2) !== '/') state.push([Rn[3], true]);
      }
      break;
    case 'pixelsperinch' /*case 'PixelsPerInch'*/:
      break;
    case 'componentoptions' /*case 'ComponentOptions'*/:
    case 'documentproperties' /*case 'DocumentProperties'*/:
    case 'customdocumentproperties' /*case 'CustomDocumentProperties'*/:
    case 'officedocumentsettings' /*case 'OfficeDocumentSettings'*/:
    case 'pivottable' /*case 'PivotTable'*/:
    case 'pivotcache' /*case 'PivotCache'*/:
    case 'names' /*case 'Names'*/:
    case 'mapinfo' /*case 'MapInfo'*/:
    case 'pagebreaks' /*case 'PageBreaks'*/:
    case 'querytable' /*case 'QueryTable'*/:
    case 'sorting' /*case 'Sorting'*/:
    case 'schema' /*case 'Schema'*/: //case 'data' /*case 'data'*/:
    case 'conditionalformatting' /*case 'ConditionalFormatting'*/:
    case 'smarttagtype' /*case 'SmartTagType'*/:
    case 'smarttags' /*case 'SmartTags'*/:
    case 'excelworkbook' /*case 'ExcelWorkbook'*/:
    case 'workbookoptions' /*case 'WorkbookOptions'*/:
    case 'worksheetoptions' /*case 'WorksheetOptions'*/:
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw new Error("Bad state: " + tmp.join("|"));
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') state.push([Rn[3], true]);
      break;
    case 'null' /*case 'Null'*/:
      break;
    default:
      /* FODS file root is <office:document> */
      if (state.length == 0 && Rn[3] == "document") return parse_fods(str, opts);
      /* UOS file root is <uof:UOF> */
      if (state.length == 0 && Rn[3] == "uof" /*"UOF"*/) return parse_fods(str, opts);
      var seen = true;
      switch (state[state.length - 1][0]) {
        /* OfficeDocumentSettings */
        case 'officedocumentsettings' /*case 'OfficeDocumentSettings'*/:
          switch (Rn[3]) {
            case 'allowpng' /*case 'AllowPNG'*/:
              break;
            case 'removepersonalinformation' /*case 'RemovePersonalInformation'*/:
              break;
            case 'downloadcomponents' /*case 'DownloadComponents'*/:
              break;
            case 'locationofcomponents' /*case 'LocationOfComponents'*/:
              break;
            case 'colors' /*case 'Colors'*/:
              break;
            case 'color' /*case 'Color'*/:
              break;
            case 'index' /*case 'Index'*/:
              break;
            case 'rgb' /*case 'RGB'*/:
              break;
            case 'targetscreensize' /*case 'TargetScreenSize'*/:
              break;
            case 'readonlyrecommended' /*case 'ReadOnlyRecommended'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* ComponentOptions */
        case 'componentoptions' /*case 'ComponentOptions'*/:
          switch (Rn[3]) {
            case 'toolbar' /*case 'Toolbar'*/:
              break;
            case 'hideofficelogo' /*case 'HideOfficeLogo'*/:
              break;
            case 'spreadsheetautofit' /*case 'SpreadsheetAutoFit'*/:
              break;
            case 'label' /*case 'Label'*/:
              break;
            case 'caption' /*case 'Caption'*/:
              break;
            case 'maxheight' /*case 'MaxHeight'*/:
              break;
            case 'maxwidth' /*case 'MaxWidth'*/:
              break;
            case 'nextsheetnumber' /*case 'NextSheetNumber'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* ExcelWorkbook */
        case 'excelworkbook' /*case 'ExcelWorkbook'*/:
          switch (Rn[3]) {
            case 'date1904' /*case 'Date1904'*/:
              /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
              Workbook.WBProps.date1904 = true;
              break;
            case 'windowheight' /*case 'WindowHeight'*/:
              break;
            case 'windowwidth' /*case 'WindowWidth'*/:
              break;
            case 'windowtopx' /*case 'WindowTopX'*/:
              break;
            case 'windowtopy' /*case 'WindowTopY'*/:
              break;
            case 'tabratio' /*case 'TabRatio'*/:
              break;
            case 'protectstructure' /*case 'ProtectStructure'*/:
              break;
            case 'protectwindow' /*case 'ProtectWindow'*/:
              break;
            case 'protectwindows' /*case 'ProtectWindows'*/:
              break;
            case 'activesheet' /*case 'ActiveSheet'*/:
              break;
            case 'displayinknotes' /*case 'DisplayInkNotes'*/:
              break;
            case 'firstvisiblesheet' /*case 'FirstVisibleSheet'*/:
              break;
            case 'supbook' /*case 'SupBook'*/:
              break;
            case 'sheetname' /*case 'SheetName'*/:
              break;
            case 'sheetindex' /*case 'SheetIndex'*/:
              break;
            case 'sheetindexfirst' /*case 'SheetIndexFirst'*/:
              break;
            case 'sheetindexlast' /*case 'SheetIndexLast'*/:
              break;
            case 'dll' /*case 'Dll'*/:
              break;
            case 'acceptlabelsinformulas' /*case 'AcceptLabelsInFormulas'*/:
              break;
            case 'donotsavelinkvalues' /*case 'DoNotSaveLinkValues'*/:
              break;
            case 'iteration' /*case 'Iteration'*/:
              break;
            case 'maxiterations' /*case 'MaxIterations'*/:
              break;
            case 'maxchange' /*case 'MaxChange'*/:
              break;
            case 'path' /*case 'Path'*/:
              break;
            case 'xct' /*case 'Xct'*/:
              break;
            case 'count' /*case 'Count'*/:
              break;
            case 'selectedsheets' /*case 'SelectedSheets'*/:
              break;
            case 'calculation' /*case 'Calculation'*/:
              break;
            case 'uncalced' /*case 'Uncalced'*/:
              break;
            case 'startupprompt' /*case 'StartupPrompt'*/:
              break;
            case 'crn' /*case 'Crn'*/:
              break;
            case 'externname' /*case 'ExternName'*/:
              break;
            case 'formula' /*case 'Formula'*/:
              break;
            case 'colfirst' /*case 'ColFirst'*/:
              break;
            case 'collast' /*case 'ColLast'*/:
              break;
            case 'wantadvise' /*case 'WantAdvise'*/:
              break;
            case 'boolean' /*case 'Boolean'*/:
              break;
            case 'error' /*case 'Error'*/:
              break;
            case 'text' /*case 'Text'*/:
              break;
            case 'ole' /*case 'OLE'*/:
              break;
            case 'noautorecover' /*case 'NoAutoRecover'*/:
              break;
            case 'publishobjects' /*case 'PublishObjects'*/:
              break;
            case 'donotcalculatebeforesave' /*case 'DoNotCalculateBeforeSave'*/:
              break;
            case 'number' /*case 'Number'*/:
              break;
            case 'refmoder1c1' /*case 'RefModeR1C1'*/:
              break;
            case 'embedsavesmarttags' /*case 'EmbedSaveSmartTags'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* WorkbookOptions */
        case 'workbookoptions' /*case 'WorkbookOptions'*/:
          switch (Rn[3]) {
            case 'owcversion' /*case 'OWCVersion'*/:
              break;
            case 'height' /*case 'Height'*/:
              break;
            case 'width' /*case 'Width'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* WorksheetOptions */
        case 'worksheetoptions' /*case 'WorksheetOptions'*/:
          switch (Rn[3]) {
            case 'visible' /*case 'Visible'*/:
              if (Rn[0].slice(-2) === "/>") {/* empty */} else if (Rn[1] === "/") switch (str.slice(pidx, Rn.index)) {
                case "SheetHidden":
                  wsprops.Hidden = 1;
                  break;
                case "SheetVeryHidden":
                  wsprops.Hidden = 2;
                  break;
              } else pidx = Rn.index + Rn[0].length;
              break;
            case 'header' /*case 'Header'*/:
              if (!cursheet['!margins']) default_margins(cursheet['!margins'] = {}, 'xlml');
              if (!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].header = +parsexmltag(Rn[0]).Margin;
              break;
            case 'footer' /*case 'Footer'*/:
              if (!cursheet['!margins']) default_margins(cursheet['!margins'] = {}, 'xlml');
              if (!isNaN(+parsexmltag(Rn[0]).Margin)) cursheet['!margins'].footer = +parsexmltag(Rn[0]).Margin;
              break;
            case 'pagemargins' /*case 'PageMargins'*/:
              var pagemargins = parsexmltag(Rn[0]);
              if (!cursheet['!margins']) default_margins(cursheet['!margins'] = {}, 'xlml');
              if (!isNaN(+pagemargins.Top)) cursheet['!margins'].top = +pagemargins.Top;
              if (!isNaN(+pagemargins.Left)) cursheet['!margins'].left = +pagemargins.Left;
              if (!isNaN(+pagemargins.Right)) cursheet['!margins'].right = +pagemargins.Right;
              if (!isNaN(+pagemargins.Bottom)) cursheet['!margins'].bottom = +pagemargins.Bottom;
              break;
            case 'displayrighttoleft' /*case 'DisplayRightToLeft'*/:
              if (!Workbook.Views) Workbook.Views = [];
              if (!Workbook.Views[0]) Workbook.Views[0] = {};
              Workbook.Views[0].RTL = true;
              break;
            case 'freezepanes' /*case 'FreezePanes'*/:
              break;
            case 'frozennosplit' /*case 'FrozenNoSplit'*/:
              break;
            case 'splithorizontal' /*case 'SplitHorizontal'*/:
            case 'splitvertical' /*case 'SplitVertical'*/:
              break;
            case 'donotdisplaygridlines' /*case 'DoNotDisplayGridlines'*/:
              break;
            case 'activerow' /*case 'ActiveRow'*/:
              break;
            case 'activecol' /*case 'ActiveCol'*/:
              break;
            case 'toprowbottompane' /*case 'TopRowBottomPane'*/:
              break;
            case 'leftcolumnrightpane' /*case 'LeftColumnRightPane'*/:
              break;
            case 'unsynced' /*case 'Unsynced'*/:
              break;
            case 'print' /*case 'Print'*/:
              break;
            case 'printerrors' /*case 'PrintErrors'*/:
              break;
            case 'panes' /*case 'Panes'*/:
              break;
            case 'scale' /*case 'Scale'*/:
              break;
            case 'pane' /*case 'Pane'*/:
              break;
            case 'number' /*case 'Number'*/:
              break;
            case 'layout' /*case 'Layout'*/:
              break;
            case 'pagesetup' /*case 'PageSetup'*/:
              break;
            case 'selected' /*case 'Selected'*/:
              break;
            case 'protectobjects' /*case 'ProtectObjects'*/:
              break;
            case 'enableselection' /*case 'EnableSelection'*/:
              break;
            case 'protectscenarios' /*case 'ProtectScenarios'*/:
              break;
            case 'validprinterinfo' /*case 'ValidPrinterInfo'*/:
              break;
            case 'horizontalresolution' /*case 'HorizontalResolution'*/:
              break;
            case 'verticalresolution' /*case 'VerticalResolution'*/:
              break;
            case 'numberofcopies' /*case 'NumberofCopies'*/:
              break;
            case 'activepane' /*case 'ActivePane'*/:
              break;
            case 'toprowvisible' /*case 'TopRowVisible'*/:
              break;
            case 'leftcolumnvisible' /*case 'LeftColumnVisible'*/:
              break;
            case 'fittopage' /*case 'FitToPage'*/:
              break;
            case 'rangeselection' /*case 'RangeSelection'*/:
              break;
            case 'papersizeindex' /*case 'PaperSizeIndex'*/:
              break;
            case 'pagelayoutzoom' /*case 'PageLayoutZoom'*/:
              break;
            case 'pagebreakzoom' /*case 'PageBreakZoom'*/:
              break;
            case 'filteron' /*case 'FilterOn'*/:
              break;
            case 'fitwidth' /*case 'FitWidth'*/:
              break;
            case 'fitheight' /*case 'FitHeight'*/:
              break;
            case 'commentslayout' /*case 'CommentsLayout'*/:
              break;
            case 'zoom' /*case 'Zoom'*/:
              break;
            case 'lefttoright' /*case 'LeftToRight'*/:
              break;
            case 'gridlines' /*case 'Gridlines'*/:
              break;
            case 'allowsort' /*case 'AllowSort'*/:
              break;
            case 'allowfilter' /*case 'AllowFilter'*/:
              break;
            case 'allowinsertrows' /*case 'AllowInsertRows'*/:
              break;
            case 'allowdeleterows' /*case 'AllowDeleteRows'*/:
              break;
            case 'allowinsertcols' /*case 'AllowInsertCols'*/:
              break;
            case 'allowdeletecols' /*case 'AllowDeleteCols'*/:
              break;
            case 'allowinserthyperlinks' /*case 'AllowInsertHyperlinks'*/:
              break;
            case 'allowformatcells' /*case 'AllowFormatCells'*/:
              break;
            case 'allowsizecols' /*case 'AllowSizeCols'*/:
              break;
            case 'allowsizerows' /*case 'AllowSizeRows'*/:
              break;
            case 'nosummaryrowsbelowdetail' /*case 'NoSummaryRowsBelowDetail'*/:
              if (!cursheet["!outline"]) cursheet["!outline"] = {};
              cursheet["!outline"].above = true;
              break;
            case 'tabcolorindex' /*case 'TabColorIndex'*/:
              break;
            case 'donotdisplayheadings' /*case 'DoNotDisplayHeadings'*/:
              break;
            case 'showpagelayoutzoom' /*case 'ShowPageLayoutZoom'*/:
              break;
            case 'nosummarycolumnsrightdetail' /*case 'NoSummaryColumnsRightDetail'*/:
              if (!cursheet["!outline"]) cursheet["!outline"] = {};
              cursheet["!outline"].left = true;
              break;
            case 'blackandwhite' /*case 'BlackAndWhite'*/:
              break;
            case 'donotdisplayzeros' /*case 'DoNotDisplayZeros'*/:
              break;
            case 'displaypagebreak' /*case 'DisplayPageBreak'*/:
              break;
            case 'rowcolheadings' /*case 'RowColHeadings'*/:
              break;
            case 'donotdisplayoutline' /*case 'DoNotDisplayOutline'*/:
              break;
            case 'noorientation' /*case 'NoOrientation'*/:
              break;
            case 'allowusepivottables' /*case 'AllowUsePivotTables'*/:
              break;
            case 'zeroheight' /*case 'ZeroHeight'*/:
              break;
            case 'viewablerange' /*case 'ViewableRange'*/:
              break;
            case 'selection' /*case 'Selection'*/:
              break;
            case 'protectcontents' /*case 'ProtectContents'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* PivotTable */
        case 'pivottable' /*case 'PivotTable'*/:
        case 'pivotcache' /*case 'PivotCache'*/:
          switch (Rn[3]) {
            case 'immediateitemsondrop' /*case 'ImmediateItemsOnDrop'*/:
              break;
            case 'showpagemultipleitemlabel' /*case 'ShowPageMultipleItemLabel'*/:
              break;
            case 'compactrowindent' /*case 'CompactRowIndent'*/:
              break;
            case 'location' /*case 'Location'*/:
              break;
            case 'pivotfield' /*case 'PivotField'*/:
              break;
            case 'orientation' /*case 'Orientation'*/:
              break;
            case 'layoutform' /*case 'LayoutForm'*/:
              break;
            case 'layoutsubtotallocation' /*case 'LayoutSubtotalLocation'*/:
              break;
            case 'layoutcompactrow' /*case 'LayoutCompactRow'*/:
              break;
            case 'position' /*case 'Position'*/:
              break;
            case 'pivotitem' /*case 'PivotItem'*/:
              break;
            case 'datatype' /*case 'DataType'*/:
              break;
            case 'datafield' /*case 'DataField'*/:
              break;
            case 'sourcename' /*case 'SourceName'*/:
              break;
            case 'parentfield' /*case 'ParentField'*/:
              break;
            case 'ptlineitems' /*case 'PTLineItems'*/:
              break;
            case 'ptlineitem' /*case 'PTLineItem'*/:
              break;
            case 'countofsameitems' /*case 'CountOfSameItems'*/:
              break;
            case 'item' /*case 'Item'*/:
              break;
            case 'itemtype' /*case 'ItemType'*/:
              break;
            case 'ptsource' /*case 'PTSource'*/:
              break;
            case 'cacheindex' /*case 'CacheIndex'*/:
              break;
            case 'consolidationreference' /*case 'ConsolidationReference'*/:
              break;
            case 'filename' /*case 'FileName'*/:
              break;
            case 'reference' /*case 'Reference'*/:
              break;
            case 'nocolumngrand' /*case 'NoColumnGrand'*/:
              break;
            case 'norowgrand' /*case 'NoRowGrand'*/:
              break;
            case 'blanklineafteritems' /*case 'BlankLineAfterItems'*/:
              break;
            case 'hidden' /*case 'Hidden'*/:
              break;
            case 'subtotal' /*case 'Subtotal'*/:
              break;
            case 'basefield' /*case 'BaseField'*/:
              break;
            case 'mapchilditems' /*case 'MapChildItems'*/:
              break;
            case 'function' /*case 'Function'*/:
              break;
            case 'refreshonfileopen' /*case 'RefreshOnFileOpen'*/:
              break;
            case 'printsettitles' /*case 'PrintSetTitles'*/:
              break;
            case 'mergelabels' /*case 'MergeLabels'*/:
              break;
            case 'defaultversion' /*case 'DefaultVersion'*/:
              break;
            case 'refreshname' /*case 'RefreshName'*/:
              break;
            case 'refreshdate' /*case 'RefreshDate'*/:
              break;
            case 'refreshdatecopy' /*case 'RefreshDateCopy'*/:
              break;
            case 'versionlastrefresh' /*case 'VersionLastRefresh'*/:
              break;
            case 'versionlastupdate' /*case 'VersionLastUpdate'*/:
              break;
            case 'versionupdateablemin' /*case 'VersionUpdateableMin'*/:
              break;
            case 'versionrefreshablemin' /*case 'VersionRefreshableMin'*/:
              break;
            case 'calculation' /*case 'Calculation'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* PageBreaks */
        case 'pagebreaks' /*case 'PageBreaks'*/:
          switch (Rn[3]) {
            case 'colbreaks' /*case 'ColBreaks'*/:
              break;
            case 'colbreak' /*case 'ColBreak'*/:
              break;
            case 'rowbreaks' /*case 'RowBreaks'*/:
              break;
            case 'rowbreak' /*case 'RowBreak'*/:
              break;
            case 'colstart' /*case 'ColStart'*/:
              break;
            case 'colend' /*case 'ColEnd'*/:
              break;
            case 'rowend' /*case 'RowEnd'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* AutoFilter */
        case 'autofilter' /*case 'AutoFilter'*/:
          switch (Rn[3]) {
            case 'autofiltercolumn' /*case 'AutoFilterColumn'*/:
              break;
            case 'autofiltercondition' /*case 'AutoFilterCondition'*/:
              break;
            case 'autofilterand' /*case 'AutoFilterAnd'*/:
              break;
            case 'autofilteror' /*case 'AutoFilterOr'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* QueryTable */
        case 'querytable' /*case 'QueryTable'*/:
          switch (Rn[3]) {
            case 'id' /*case 'Id'*/:
              break;
            case 'autoformatfont' /*case 'AutoFormatFont'*/:
              break;
            case 'autoformatpattern' /*case 'AutoFormatPattern'*/:
              break;
            case 'querysource' /*case 'QuerySource'*/:
              break;
            case 'querytype' /*case 'QueryType'*/:
              break;
            case 'enableredirections' /*case 'EnableRedirections'*/:
              break;
            case 'refreshedinxl9' /*case 'RefreshedInXl9'*/:
              break;
            case 'urlstring' /*case 'URLString'*/:
              break;
            case 'htmltables' /*case 'HTMLTables'*/:
              break;
            case 'connection' /*case 'Connection'*/:
              break;
            case 'commandtext' /*case 'CommandText'*/:
              break;
            case 'refreshinfo' /*case 'RefreshInfo'*/:
              break;
            case 'notitles' /*case 'NoTitles'*/:
              break;
            case 'nextid' /*case 'NextId'*/:
              break;
            case 'columninfo' /*case 'ColumnInfo'*/:
              break;
            case 'overwritecells' /*case 'OverwriteCells'*/:
              break;
            case 'donotpromptforfile' /*case 'DoNotPromptForFile'*/:
              break;
            case 'textwizardsettings' /*case 'TextWizardSettings'*/:
              break;
            case 'source' /*case 'Source'*/:
              break;
            case 'number' /*case 'Number'*/:
              break;
            case 'decimal' /*case 'Decimal'*/:
              break;
            case 'thousandseparator' /*case 'ThousandSeparator'*/:
              break;
            case 'trailingminusnumbers' /*case 'TrailingMinusNumbers'*/:
              break;
            case 'formatsettings' /*case 'FormatSettings'*/:
              break;
            case 'fieldtype' /*case 'FieldType'*/:
              break;
            case 'delimiters' /*case 'Delimiters'*/:
              break;
            case 'tab' /*case 'Tab'*/:
              break;
            case 'comma' /*case 'Comma'*/:
              break;
            case 'autoformatname' /*case 'AutoFormatName'*/:
              break;
            case 'versionlastedit' /*case 'VersionLastEdit'*/:
              break;
            case 'versionlastrefresh' /*case 'VersionLastRefresh'*/:
              break;
            default:
              seen = false;
          }
          break;
        case 'datavalidation' /*case 'DataValidation'*/:
          switch (Rn[3]) {
            case 'range' /*case 'Range'*/:
              break;
            case 'type' /*case 'Type'*/:
              break;
            case 'min' /*case 'Min'*/:
              break;
            case 'max' /*case 'Max'*/:
              break;
            case 'sort' /*case 'Sort'*/:
              break;
            case 'descending' /*case 'Descending'*/:
              break;
            case 'order' /*case 'Order'*/:
              break;
            case 'casesensitive' /*case 'CaseSensitive'*/:
              break;
            case 'value' /*case 'Value'*/:
              break;
            case 'errorstyle' /*case 'ErrorStyle'*/:
              break;
            case 'errormessage' /*case 'ErrorMessage'*/:
              break;
            case 'errortitle' /*case 'ErrorTitle'*/:
              break;
            case 'inputmessage' /*case 'InputMessage'*/:
              break;
            case 'inputtitle' /*case 'InputTitle'*/:
              break;
            case 'combohide' /*case 'ComboHide'*/:
              break;
            case 'inputhide' /*case 'InputHide'*/:
              break;
            case 'condition' /*case 'Condition'*/:
              break;
            case 'qualifier' /*case 'Qualifier'*/:
              break;
            case 'useblank' /*case 'UseBlank'*/:
              break;
            case 'value1' /*case 'Value1'*/:
              break;
            case 'value2' /*case 'Value2'*/:
              break;
            case 'format' /*case 'Format'*/:
              break;
            case 'cellrangelist' /*case 'CellRangeList'*/:
              break;
            default:
              seen = false;
          }
          break;
        case 'sorting' /*case 'Sorting'*/:
        case 'conditionalformatting' /*case 'ConditionalFormatting'*/:
          switch (Rn[3]) {
            case 'range' /*case 'Range'*/:
              break;
            case 'type' /*case 'Type'*/:
              break;
            case 'min' /*case 'Min'*/:
              break;
            case 'max' /*case 'Max'*/:
              break;
            case 'sort' /*case 'Sort'*/:
              break;
            case 'descending' /*case 'Descending'*/:
              break;
            case 'order' /*case 'Order'*/:
              break;
            case 'casesensitive' /*case 'CaseSensitive'*/:
              break;
            case 'value' /*case 'Value'*/:
              break;
            case 'errorstyle' /*case 'ErrorStyle'*/:
              break;
            case 'errormessage' /*case 'ErrorMessage'*/:
              break;
            case 'errortitle' /*case 'ErrorTitle'*/:
              break;
            case 'cellrangelist' /*case 'CellRangeList'*/:
              break;
            case 'inputmessage' /*case 'InputMessage'*/:
              break;
            case 'inputtitle' /*case 'InputTitle'*/:
              break;
            case 'combohide' /*case 'ComboHide'*/:
              break;
            case 'inputhide' /*case 'InputHide'*/:
              break;
            case 'condition' /*case 'Condition'*/:
              break;
            case 'qualifier' /*case 'Qualifier'*/:
              break;
            case 'useblank' /*case 'UseBlank'*/:
              break;
            case 'value1' /*case 'Value1'*/:
              break;
            case 'value2' /*case 'Value2'*/:
              break;
            case 'format' /*case 'Format'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* MapInfo (schema) */
        case 'mapinfo' /*case 'MapInfo'*/:
        case 'schema' /*case 'Schema'*/:
        case 'data' /*case 'data'*/:
          switch (Rn[3]) {
            case 'map' /*case 'Map'*/:
              break;
            case 'entry' /*case 'Entry'*/:
              break;
            case 'range' /*case 'Range'*/:
              break;
            case 'xpath' /*case 'XPath'*/:
              break;
            case 'field' /*case 'Field'*/:
              break;
            case 'xsdtype' /*case 'XSDType'*/:
              break;
            case 'filteron' /*case 'FilterOn'*/:
              break;
            case 'aggregate' /*case 'Aggregate'*/:
              break;
            case 'elementtype' /*case 'ElementType'*/:
              break;
            case 'attributetype' /*case 'AttributeType'*/:
              break;
            /* These are from xsd (XML Schema Definition) */
            case 'schema' /*case 'schema'*/:
            case 'element' /*case 'element'*/:
            case 'complextype' /*case 'complexType'*/:
            case 'datatype' /*case 'datatype'*/:
            case 'all' /*case 'all'*/:
            case 'attribute' /*case 'attribute'*/:
            case 'extends' /*case 'extends'*/:
              break;
            case 'row' /*case 'row'*/:
              break;
            default:
              seen = false;
          }
          break;

        /* SmartTags (can be anything) */
        case 'smarttags' /*case 'SmartTags'*/:
          break;
        default:
          seen = false;
          break;
      }
      if (seen) break;
      /* CustomDocumentProperties */
      if (Rn[3].match(/!\[CDATA/)) break;
      if (!state[state.length - 1][1]) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
      if (state[state.length - 1][0] === /*'CustomDocumentProperties'*/'customdocumentproperties') {
        if (Rn[0].slice(-2) === "/>") break;else if (Rn[1] === "/") xlml_set_custprop(Custprops, raw_Rn3, cp, str.slice(pidx, Rn.index));else {
          cp = Rn;
          pidx = Rn.index + Rn[0].length;
        }
        break;
      }
      if (opts.WTF) throw 'Unrecognized tag: ' + Rn[3] + "|" + state.join("|");
  }
  var out = {} /*:any*/;
  if (!opts.bookSheets && !opts.bookProps) out.Sheets = sheets;
  out.SheetNames = sheetnames;
  out.Workbook = Workbook;
  out.SSF = dup(table_fmt);
  out.Props = Props;
  out.Custprops = Custprops;
  return out;
}
function parse_xlml(data /*:RawBytes|string*/, opts) /*:Workbook*/{
  fix_read_opts(opts = opts || {});
  switch (opts.type || "base64") {
    case "base64":
      return parse_xlml_xml(Base64_decode(data), opts);
    case "binary":
    case "buffer":
    case "file":
      return parse_xlml_xml(data, opts);
    case "array":
      return parse_xlml_xml(a2s(data), opts);
  }
  /*:: throw new Error("unsupported type " + opts.type); */
}

/* TODO */
function write_props_xlml(wb /*:Workbook*/, opts) /*:string*/{
  var o /*:Array<string>*/ = [];
  /* DocumentProperties */
  if (wb.Props) o.push(xlml_write_docprops(wb.Props, opts));
  /* CustomDocumentProperties */
  if (wb.Custprops) o.push(xlml_write_custprops(wb.Props, wb.Custprops, opts));
  return o.join("");
}
/* TODO */
function write_wb_xlml(/*::wb, opts*/
) /*:string*/{
  /* OfficeDocumentSettings */
  /* ExcelWorkbook */
  return "";
}
/* TODO */
function write_sty_xlml(wb, opts) /*:string*/{
  /* Styles */
  var styles /*:Array<string>*/ = ['<Style ss:ID="Default" ss:Name="Normal"><NumberFormat/></Style>'];
  opts.cellXfs.forEach(function (xf, id) {
    var payload /*:Array<string>*/ = [];
    payload.push(writextag('NumberFormat', null, {
      "ss:Format": escapexml(table_fmt[xf.numFmtId])
    }));
    var o = /*::(*/{
      "ss:ID": "s" + (21 + id)
    } /*:: :any)*/;
    styles.push(writextag('Style', payload.join(""), o));
  });
  return writextag("Styles", styles.join(""));
}
function write_name_xlml(n) {
  return writextag("NamedRange", null, {
    "ss:Name": n.Name,
    "ss:RefersTo": "=" + a1_to_rc(n.Ref, {
      r: 0,
      c: 0
    })
  });
}
function write_names_xlml(wb /*::, opts*/) /*:string*/{
  if (!((wb || {}).Workbook || {}).Names) return "";
  /*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
  var names /*:Array<any>*/ = wb.Workbook.Names;
  var out /*:Array<string>*/ = [];
  for (var i = 0; i < names.length; ++i) {
    var n = names[i];
    if (n.Sheet != null) continue;
    if (n.Name.match(/^_xlfn\./)) continue;
    out.push(write_name_xlml(n));
  }
  return writextag("Names", out.join(""));
}
function write_ws_xlml_names(ws /*:Worksheet*/, opts, idx /*:number*/, wb /*:Workbook*/) /*:string*/{
  if (!ws) return "";
  if (!((wb || {}).Workbook || {}).Names) return "";
  /*:: if(!wb || !wb.Workbook || !wb.Workbook.Names) throw new Error("unreachable"); */
  var names /*:Array<any>*/ = wb.Workbook.Names;
  var out /*:Array<string>*/ = [];
  for (var i = 0; i < names.length; ++i) {
    var n = names[i];
    if (n.Sheet != idx) continue;
    /*switch(n.Name) {
    	case "_": continue;
    }*/
    if (n.Name.match(/^_xlfn\./)) continue;
    out.push(write_name_xlml(n));
  }
  return out.join("");
}
/* WorksheetOptions */
function write_ws_xlml_wsopts(ws /*:Worksheet*/, opts, idx /*:number*/, wb /*:Workbook*/) /*:string*/{
  if (!ws) return "";
  var o /*:Array<string>*/ = [];
  /* NOTE: spec technically allows any order, but stick with implied order */

  /* FitToPage */
  /* DoNotDisplayColHeaders */
  /* DoNotDisplayRowHeaders */
  /* ViewableRange */
  /* Selection */
  /* GridlineColor */
  /* Name */
  /* ExcelWorksheetType */
  /* IntlMacro */
  /* Unsynced */
  /* Selected */
  /* CodeName */

  if (ws['!margins']) {
    o.push("<PageSetup>");
    if (ws['!margins'].header) o.push(writextag("Header", null, {
      'x:Margin': ws['!margins'].header
    }));
    if (ws['!margins'].footer) o.push(writextag("Footer", null, {
      'x:Margin': ws['!margins'].footer
    }));
    o.push(writextag("PageMargins", null, {
      'x:Bottom': ws['!margins'].bottom || "0.75",
      'x:Left': ws['!margins'].left || "0.7",
      'x:Right': ws['!margins'].right || "0.7",
      'x:Top': ws['!margins'].top || "0.75"
    }));
    o.push("</PageSetup>");
  }

  /* PageSetup */
  /* DisplayPageBreak */
  /* TransitionExpressionEvaluation */
  /* TransitionFormulaEntry */
  /* Print */
  /* Zoom */
  /* PageLayoutZoom */
  /* PageBreakZoom */
  /* ShowPageBreakZoom */
  /* DefaultRowHeight */
  /* DefaultColumnWidth */
  /* StandardWidth */

  if (wb && wb.Workbook && wb.Workbook.Sheets && wb.Workbook.Sheets[idx]) {
    /* Visible */
    if (wb.Workbook.Sheets[idx].Hidden) o.push(writextag("Visible", wb.Workbook.Sheets[idx].Hidden == 1 ? "SheetHidden" : "SheetVeryHidden", {}));else {
      /* Selected */
      for (var i = 0; i < idx; ++i) if (wb.Workbook.Sheets[i] && !wb.Workbook.Sheets[i].Hidden) break;
      if (i == idx) o.push("<Selected/>");
    }
  }

  /* LeftColumnVisible */

  if (((((wb || {}).Workbook || {}).Views || [])[0] || {}).RTL) o.push("<DisplayRightToLeft/>");

  /* GridlineColorIndex */
  /* DisplayFormulas */
  /* DoNotDisplayGridlines */
  /* DoNotDisplayHeadings */
  /* DoNotDisplayOutline */
  /* ApplyAutomaticOutlineStyles */
  /* NoSummaryRowsBelowDetail */
  /* NoSummaryColumnsRightDetail */
  /* DoNotDisplayZeros */
  /* ActiveRow */
  /* ActiveColumn */
  /* FilterOn */
  /* RangeSelection */
  /* TopRowVisible */
  /* TopRowBottomPane */
  /* LeftColumnRightPane */
  /* ActivePane */
  /* SplitHorizontal */
  /* SplitVertical */
  /* FreezePanes */
  /* FrozenNoSplit */
  /* TabColorIndex */
  /* Panes */

  /* NOTE: Password not supported in XLML Format */
  if (ws['!protect']) {
    o.push(writetag("ProtectContents", "True"));
    if (ws['!protect'].objects) o.push(writetag("ProtectObjects", "True"));
    if (ws['!protect'].scenarios) o.push(writetag("ProtectScenarios", "True"));
    if (ws['!protect'].selectLockedCells != null && !ws['!protect'].selectLockedCells) o.push(writetag("EnableSelection", "NoSelection"));else if (ws['!protect'].selectUnlockedCells != null && !ws['!protect'].selectUnlockedCells) o.push(writetag("EnableSelection", "UnlockedCells"));
    [["formatCells", "AllowFormatCells"], ["formatColumns", "AllowSizeCols"], ["formatRows", "AllowSizeRows"], ["insertColumns", "AllowInsertCols"], ["insertRows", "AllowInsertRows"], ["insertHyperlinks", "AllowInsertHyperlinks"], ["deleteColumns", "AllowDeleteCols"], ["deleteRows", "AllowDeleteRows"], ["sort", "AllowSort"], ["autoFilter", "AllowFilter"], ["pivotTables", "AllowUsePivotTables"]].forEach(function (x) {
      if (ws['!protect'][x[0]]) o.push("<" + x[1] + "/>");
    });
  }
  if (o.length == 0) return "";
  return writextag("WorksheetOptions", o.join(""), {
    xmlns: XLMLNS.x
  });
}
function write_ws_xlml_comment(comments /*:Array<any>*/) /*:string*/{
  return comments.map(function (c) {
    // TODO: formatted text
    var t = xlml_unfixstr(c.t || "");
    var d = writextag("ss:Data", t, {
      "xmlns": "http://www.w3.org/TR/REC-html40"
    });
    return writextag("Comment", d, {
      "ss:Author": c.a
    });
  }).join("");
}
function write_ws_xlml_cell(cell, ref /*:string*/, ws, opts, idx /*:number*/, wb, addr) /*:string*/{
  if (!cell || cell.v == undefined && cell.f == undefined) return "";
  var attr = {};
  if (cell.f) attr["ss:Formula"] = "=" + escapexml(a1_to_rc(cell.f, addr));
  if (cell.F && cell.F.slice(0, ref.length) == ref) {
    var end = decode_cell(cell.F.slice(ref.length + 1));
    attr["ss:ArrayRange"] = "RC:R" + (end.r == addr.r ? "" : "[" + (end.r - addr.r) + "]") + "C" + (end.c == addr.c ? "" : "[" + (end.c - addr.c) + "]");
  }
  if (cell.l && cell.l.Target) {
    attr["ss:HRef"] = escapexml(cell.l.Target);
    if (cell.l.Tooltip) attr["x:HRefScreenTip"] = escapexml(cell.l.Tooltip);
  }
  if (ws['!merges']) {
    var marr = ws['!merges'];
    for (var mi = 0; mi != marr.length; ++mi) {
      if (marr[mi].s.c != addr.c || marr[mi].s.r != addr.r) continue;
      if (marr[mi].e.c > marr[mi].s.c) attr['ss:MergeAcross'] = marr[mi].e.c - marr[mi].s.c;
      if (marr[mi].e.r > marr[mi].s.r) attr['ss:MergeDown'] = marr[mi].e.r - marr[mi].s.r;
    }
  }
  var t = "",
    p = "";
  switch (cell.t) {
    case 'z':
      if (!opts.sheetStubs) return "";
      break;
    case 'n':
      t = 'Number';
      p = String(cell.v);
      break;
    case 'b':
      t = 'Boolean';
      p = cell.v ? "1" : "0";
      break;
    case 'e':
      t = 'Error';
      p = BErr[cell.v];
      break;
    case 'd':
      t = 'DateTime';
      p = new Date(cell.v).toISOString();
      if (cell.z == null) cell.z = cell.z || table_fmt[14];
      break;
    case 's':
      t = 'String';
      p = escapexlml(cell.v || "");
      break;
  }
  /* TODO: cell style */
  var os = get_cell_style(opts.cellXfs, cell, opts);
  attr["ss:StyleID"] = "s" + (21 + os);
  attr["ss:Index"] = addr.c + 1;
  var _v = cell.v != null ? p : "";
  var m = cell.t == 'z' ? "" : '<Data ss:Type="' + t + '">' + _v + '</Data>';
  if ((cell.c || []).length > 0) m += write_ws_xlml_comment(cell.c);
  return writextag("Cell", m, attr);
}
function write_ws_xlml_row(R /*:number*/, row) /*:string*/{
  var o = '<Row ss:Index="' + (R + 1) + '"';
  if (row) {
    if (row.hpt && !row.hpx) row.hpx = pt2px(row.hpt);
    if (row.hpx) o += ' ss:AutoFitHeight="0" ss:Height="' + row.hpx + '"';
    if (row.hidden) o += ' ss:Hidden="1"';
  }
  return o + '>';
}
/* TODO */
function write_ws_xlml_table(ws /*:Worksheet*/, opts, idx /*:number*/, wb /*:Workbook*/) /*:string*/{
  if (!ws['!ref']) return "";
  var range /*:Range*/ = safe_decode_range(ws['!ref']);
  var marr /*:Array<Range>*/ = ws['!merges'] || [],
    mi = 0;
  var o /*:Array<string>*/ = [];
  if (ws['!cols']) ws['!cols'].forEach(function (n, i) {
    process_col(n);
    var w = !!n.width;
    var p = col_obj_w(i, n);
    var k /*:any*/ = {
      "ss:Index": i + 1
    };
    if (w) k['ss:Width'] = width2px(p.width);
    if (n.hidden) k['ss:Hidden'] = "1";
    o.push(writextag("Column", null, k));
  });
  var dense = Array.isArray(ws);
  for (var R = range.s.r; R <= range.e.r; ++R) {
    var row = [write_ws_xlml_row(R, (ws['!rows'] || [])[R])];
    for (var C = range.s.c; C <= range.e.c; ++C) {
      var skip = false;
      for (mi = 0; mi != marr.length; ++mi) {
        if (marr[mi].s.c > C) continue;
        if (marr[mi].s.r > R) continue;
        if (marr[mi].e.c < C) continue;
        if (marr[mi].e.r < R) continue;
        if (marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
        break;
      }
      if (skip) continue;
      var addr = {
        r: R,
        c: C
      };
      var ref = encode_cell(addr),
        cell = dense ? (ws[R] || [])[C] : ws[ref];
      row.push(write_ws_xlml_cell(cell, ref, ws, opts, idx, wb, addr));
    }
    row.push("</Row>");
    if (row.length > 2) o.push(row.join(""));
  }
  return o.join("");
}
function write_ws_xlml(idx /*:number*/, opts, wb /*:Workbook*/) /*:string*/{
  var o /*:Array<string>*/ = [];
  var s = wb.SheetNames[idx];
  var ws = wb.Sheets[s];
  var t /*:string*/ = ws ? write_ws_xlml_names(ws, opts, idx, wb) : "";
  if (t.length > 0) o.push("<Names>" + t + "</Names>");

  /* Table */
  t = ws ? write_ws_xlml_table(ws, opts, idx, wb) : "";
  if (t.length > 0) o.push("<Table>" + t + "</Table>");

  /* WorksheetOptions */
  o.push(write_ws_xlml_wsopts(ws, opts, idx, wb));
  return o.join("");
}
function write_xlml(wb, opts) /*:string*/{
  if (!opts) opts = {};
  if (!wb.SSF) wb.SSF = dup(table_fmt);
  if (wb.SSF) {
    make_ssf();
    SSF_load_table(wb.SSF);
    // $FlowIgnore
    opts.revssf = evert_num(wb.SSF);
    opts.revssf[wb.SSF[65535]] = 0;
    opts.ssf = wb.SSF;
    opts.cellXfs = [];
    get_cell_style(opts.cellXfs, {}, {
      revssf: {
        "General": 0
      }
    });
  }
  var d /*:Array<string>*/ = [];
  d.push(write_props_xlml(wb, opts));
  d.push(write_wb_xlml(wb, opts));
  d.push("");
  d.push("");
  for (var i = 0; i < wb.SheetNames.length; ++i) d.push(writextag("Worksheet", write_ws_xlml(i, opts, wb), {
    "ss:Name": escapexml(wb.SheetNames[i])
  }));
  d[2] = write_sty_xlml(wb, opts);
  d[3] = write_names_xlml(wb, opts);
  return XML_HEADER + writextag("Workbook", d.join(""), {
    'xmlns': XLMLNS.ss,
    'xmlns:o': XLMLNS.o,
    'xmlns:x': XLMLNS.x,
    'xmlns:ss': XLMLNS.ss,
    'xmlns:dt': XLMLNS.dt,
    'xmlns:html': XLMLNS.html
  });
}
/* [MS-OLEDS] 2.3.8 CompObjStream */
function parse_compobj(obj /*:CFBEntry*/) {
  var v = {};
  var o = obj.content;
  /*:: if(o == null) return; */

  /* [MS-OLEDS] 2.3.7 CompObjHeader -- All fields MUST be ignored */
  o.l = 28;
  v.AnsiUserType = o.read_shift(0, "lpstr-ansi");
  v.AnsiClipboardFormat = parse_ClipboardFormatOrAnsiString(o);
  if (o.length - o.l <= 4) return v;
  var m /*:number*/ = o.read_shift(4);
  if (m == 0 || m > 40) return v;
  o.l -= 4;
  v.Reserved1 = o.read_shift(0, "lpstr-ansi");
  if (o.length - o.l <= 4) return v;
  m = o.read_shift(4);
  if (m !== 0x71b239f4) return v;
  v.UnicodeClipboardFormat = parse_ClipboardFormatOrUnicodeString(o);
  m = o.read_shift(4);
  if (m == 0 || m > 40) return v;
  o.l -= 4;
  v.Reserved2 = o.read_shift(0, "lpwstr");
}

/*
	Continue logic for:
	- 2.4.58 Continue          0x003c
	- 2.4.59 ContinueBigName   0x043c
	- 2.4.60 ContinueFrt       0x0812
	- 2.4.61 ContinueFrt11     0x0875
	- 2.4.62 ContinueFrt12     0x087f
*/
var CONTINUE_RT = [0x003c, 0x043c, 0x0812, 0x0875, 0x087f];
function slurp(RecordType, R, blob, length /*:number*/, opts) /*:any*/{
  var l = length;
  var bufs = [];
  var d = blob.slice(blob.l, blob.l + l);
  if (opts && opts.enc && opts.enc.insitu && d.length > 0) switch (RecordType) {
    case 0x0009:
    case 0x0209:
    case 0x0409:
    case 0x0809 /* BOF */:
    case 0x002f /* FilePass */:
    case 0x0195 /* FileLock */:
    case 0x00e1 /* InterfaceHdr */:
    case 0x0196 /* RRDInfo */:
    case 0x0138 /* RRDHead */:
    case 0x0194 /* UsrExcl */:
    case 0x000a /* EOF */:
      break;
    case 0x0085 /* BoundSheet8 */:
      break;
    default:
      opts.enc.insitu(d);
  }
  bufs.push(d);
  blob.l += l;
  var nextrt = __readUInt16LE(blob, blob.l),
    next = XLSRecordEnum[nextrt];
  var start = 0;
  while (next != null && CONTINUE_RT.indexOf(nextrt) > -1) {
    l = __readUInt16LE(blob, blob.l + 2);
    start = blob.l + 4;
    if (nextrt == 0x0812 /* ContinueFrt */) start += 4;else if (nextrt == 0x0875 || nextrt == 0x087f) {
      start += 12;
    }
    d = blob.slice(start, blob.l + 4 + l);
    bufs.push(d);
    blob.l += 4 + l;
    next = XLSRecordEnum[nextrt = __readUInt16LE(blob, blob.l)];
  }
  var b = bconcat(bufs) /*:any*/;
  prep_blob(b, 0);
  var ll = 0;
  b.lens = [];
  for (var j = 0; j < bufs.length; ++j) {
    b.lens.push(ll);
    ll += bufs[j].length;
  }
  if (b.length < length) throw "XLS Record 0x" + RecordType.toString(16) + " Truncated: " + b.length + " < " + length;
  return R.f(b, b.length, opts);
}
function safe_format_xf(p /*:any*/, opts /*:ParseOpts*/, date1904 /*:?boolean*/) {
  if (p.t === 'z') return;
  if (!p.XF) return;
  var fmtid = 0;
  try {
    fmtid = p.z || p.XF.numFmtId || 0;
    if (opts.cellNF) p.z = table_fmt[fmtid];
  } catch (e) {
    if (opts.WTF) throw e;
  }
  if (!opts || opts.cellText !== false) try {
    if (p.t === 'e') {
      p.w = p.w || BErr[p.v];
    } else if (fmtid === 0 || fmtid == "General") {
      if (p.t === 'n') {
        if ((p.v | 0) === p.v) p.w = p.v.toString(10);else p.w = SSF_general_num(p.v);
      } else p.w = SSF_general(p.v);
    } else p.w = SSF_format(fmtid, p.v, {
      date1904: !!date1904,
      dateNF: opts && opts.dateNF
    });
  } catch (e) {
    if (opts.WTF) throw e;
  }
  if (opts.cellDates && fmtid && p.t == 'n' && fmt_is_date(table_fmt[fmtid] || String(fmtid))) {
    var _d = SSF_parse_date_code(p.v);
    if (_d) {
      p.t = 'd';
      p.v = new Date(_d.y, _d.m - 1, _d.d, _d.H, _d.M, _d.S, _d.u);
    }
  }
}
function make_cell(val, ixfe, t) /*:Cell*/{
  return {
    v: val,
    ixfe: ixfe,
    t: t
  } /*:any*/;
}

// 2.3.2
function parse_workbook(blob, options /*:ParseOpts*/) /*:Workbook*/{
  var wb = {
    opts: {}
  } /*:any*/;
  var Sheets = {};
  if (DENSE != null && options.dense == null) options.dense = DENSE;
  var out /*:Worksheet*/ = options.dense ? [] : {} /*:any*/;
  var Directory = {};
  var range /*:Range*/ = {} /*:any*/;
  var last_formula = null;
  var sst /*:SST*/ = [] /*:any*/;
  var cur_sheet = "";
  var Preamble = {};
  var lastcell,
    last_cell = "",
    cc /*:Cell*/,
    cmnt,
    rngC,
    rngR;
  var sharedf = {};
  var arrayf /*:Array<[Range, string]>*/ = [];
  var temp_val /*:Cell*/;
  var country;
  var XFs = []; /* XF records */
  var palette /*:Array<[number, number, number]>*/ = [];
  var Workbook /*:WBWBProps*/ = {
      Sheets: [],
      WBProps: {
        date1904: false
      },
      Views: [{}]
    } /*:any*/,
    wsprops = {};
  var get_rgb = function getrgb(icv /*:number*/) /*:[number, number, number]*/{
    if (icv < 8) return XLSIcv[icv];
    if (icv < 64) return palette[icv - 8] || XLSIcv[icv];
    return XLSIcv[icv];
  };
  var process_cell_style = function pcs(cell, line /*:any*/, options) {
    var xfd = line.XF.data;
    if (!xfd || !xfd.patternType || !options || !options.cellStyles) return;
    line.s = {} /*:any*/;
    line.s.patternType = xfd.patternType;
    var t;
    if (t = rgb2Hex(get_rgb(xfd.icvFore))) {
      line.s.fgColor = {
        rgb: t
      };
    }
    if (t = rgb2Hex(get_rgb(xfd.icvBack))) {
      line.s.bgColor = {
        rgb: t
      };
    }
  };
  var addcell = function addcell(cell /*:any*/, line /*:any*/, options /*:any*/) {
    if (file_depth > 1) return;
    if (options.sheetRows && cell.r >= options.sheetRows) return;
    if (options.cellStyles && line.XF && line.XF.data) process_cell_style(cell, line, options);
    delete line.ixfe;
    delete line.XF;
    lastcell = cell;
    last_cell = encode_cell(cell);
    if (!range || !range.s || !range.e) range = {
      s: {
        r: 0,
        c: 0
      },
      e: {
        r: 0,
        c: 0
      }
    };
    if (cell.r < range.s.r) range.s.r = cell.r;
    if (cell.c < range.s.c) range.s.c = cell.c;
    if (cell.r + 1 > range.e.r) range.e.r = cell.r + 1;
    if (cell.c + 1 > range.e.c) range.e.c = cell.c + 1;
    if (options.cellFormula && line.f) {
      for (var afi = 0; afi < arrayf.length; ++afi) {
        if (arrayf[afi][0].s.c > cell.c || arrayf[afi][0].s.r > cell.r) continue;
        if (arrayf[afi][0].e.c < cell.c || arrayf[afi][0].e.r < cell.r) continue;
        line.F = encode_range(arrayf[afi][0]);
        if (arrayf[afi][0].s.c != cell.c || arrayf[afi][0].s.r != cell.r) delete line.f;
        if (line.f) line.f = "" + stringify_formula(arrayf[afi][1], range, cell, supbooks, opts);
        break;
      }
    }
    {
      if (options.dense) {
        if (!out[cell.r]) out[cell.r] = [];
        out[cell.r][cell.c] = line;
      } else out[last_cell] = line;
    }
  };
  var opts = {
    enc: false,
    // encrypted
    sbcch: 0,
    // cch in the preceding SupBook
    snames: [],
    // sheetnames
    sharedf: sharedf,
    // shared formulae by address
    arrayf: arrayf,
    // array formulae array
    rrtabid: [],
    // RRTabId
    lastuser: "",
    // Last User from WriteAccess
    biff: 8,
    // BIFF version
    codepage: 0,
    // CP from CodePage record
    winlocked: 0,
    // fLockWn from WinProtect
    cellStyles: !!options && !!options.cellStyles,
    WTF: !!options && !!options.wtf
  } /*:any*/;
  if (options.password) opts.password = options.password;
  var themes;
  var merges /*:Array<Range>*/ = [];
  var objects = [];
  var colinfo /*:Array<ColInfo>*/ = [],
    rowinfo /*:Array<RowInfo>*/ = [];
  var seencol = false;
  var supbooks = [] /*:any*/; // 1-indexed, will hold extern names
  supbooks.SheetNames = opts.snames;
  supbooks.sharedf = opts.sharedf;
  supbooks.arrayf = opts.arrayf;
  supbooks.names = [];
  supbooks.XTI = [];
  var last_RT = 0;
  var file_depth = 0; /* TODO: make a real stack */
  var BIFF2Fmt = 0,
    BIFF2FmtTable /*:Array<string>*/ = [];
  var FilterDatabases = []; /* TODO: sort out supbooks and process elsewhere */
  var last_lbl /*:?DefinedName*/;

  /* explicit override for some broken writers */
  opts.codepage = 1200;
  set_cp(1200);
  var seen_codepage = false;
  while (blob.l < blob.length - 1) {
    var s = blob.l;
    var RecordType = blob.read_shift(2);
    if (RecordType === 0 && last_RT === 0x000a /* EOF */) break;
    var length = blob.l === blob.length ? 0 : blob.read_shift(2);
    var R = XLSRecordEnum[RecordType];
    //console.log(RecordType.toString(16), RecordType, R, blob.l, length, blob.length);
    //if(!R) console.log(blob.slice(blob.l, blob.l + length));
    if (R && R.f) {
      if (options.bookSheets) {
        if (last_RT === 0x0085 /* BoundSheet8 */ && RecordType !== 0x0085 /* R.n !== 'BoundSheet8' */) break;
      }
      last_RT = RecordType;
      if (R.r === 2 || R.r == 12) {
        var rt = blob.read_shift(2);
        length -= 2;
        if (!opts.enc && rt !== RecordType && ((rt & 0xFF) << 8 | rt >> 8) !== RecordType) throw new Error("rt mismatch: " + rt + "!=" + RecordType);
        if (R.r == 12) {
          blob.l += 10;
          length -= 10;
        } // skip FRT
      }
      //console.error(R,blob.l,length,blob.length);
      var val /*:any*/ = {} /*:any*/;
      if (RecordType === 0x000a /* EOF */) val = /*::(*/R.f(blob, length, opts) /*:: :any)*/;else val = /*::(*/slurp(RecordType, R, blob, length, opts) /*:: :any)*/;
      /*:: val = (val:any); */
      if (file_depth == 0 && [0x0009, 0x0209, 0x0409, 0x0809].indexOf(last_RT) === -1 /* 'BOF' */) continue;
      switch (RecordType) {
        case 0x0022 /* Date1904 */:
          /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
          wb.opts.Date1904 = Workbook.WBProps.date1904 = val;
          break;
        case 0x0086 /* WriteProtect */:
          wb.opts.WriteProtect = true;
          break;
        case 0x002f /* FilePass */:
          if (!opts.enc) blob.l = 0;
          opts.enc = val;
          if (!options.password) throw new Error("File is password-protected");
          if (val.valid == null) throw new Error("Encryption scheme unsupported");
          if (!val.valid) throw new Error("Password is incorrect");
          break;
        case 0x005c /* WriteAccess */:
          opts.lastuser = val;
          break;
        case 0x0042 /* CodePage */:
          var cpval = Number(val);
          /* overrides based on test cases */
          switch (cpval) {
            case 0x5212:
              cpval = 1200;
              break;
            case 0x8000:
              cpval = 10000;
              break;
            case 0x8001:
              cpval = 1252;
              break;
          }
          set_cp(opts.codepage = cpval);
          seen_codepage = true;
          break;
        case 0x013d /* RRTabId */:
          opts.rrtabid = val;
          break;
        case 0x0019 /* WinProtect */:
          opts.winlocked = val;
          break;
        case 0x01b7 /* RefreshAll */:
          wb.opts["RefreshAll"] = val;
          break;
        case 0x000c /* CalcCount */:
          wb.opts["CalcCount"] = val;
          break;
        case 0x0010 /* CalcDelta */:
          wb.opts["CalcDelta"] = val;
          break;
        case 0x0011 /* CalcIter */:
          wb.opts["CalcIter"] = val;
          break;
        case 0x000d /* CalcMode */:
          wb.opts["CalcMode"] = val;
          break;
        case 0x000e /* CalcPrecision */:
          wb.opts["CalcPrecision"] = val;
          break;
        case 0x005f /* CalcSaveRecalc */:
          wb.opts["CalcSaveRecalc"] = val;
          break;
        case 0x000f /* CalcRefMode */:
          opts.CalcRefMode = val;
          break;
        // TODO: implement R1C1
        case 0x08a3 /* ForceFullCalculation */:
          wb.opts.FullCalc = val;
          break;
        case 0x0081 /* WsBool */:
          if (val.fDialog) out["!type"] = "dialog";
          if (!val.fBelow) (out["!outline"] || (out["!outline"] = {})).above = true;
          if (!val.fRight) (out["!outline"] || (out["!outline"] = {})).left = true;
          break;
        // TODO
        case 0x00e0 /* XF */:
          XFs.push(val);
          break;
        case 0x01ae /* SupBook */:
          supbooks.push([val]);
          supbooks[supbooks.length - 1].XTI = [];
          break;
        case 0x0023:
        case 0x0223 /* ExternName */:
          supbooks[supbooks.length - 1].push(val);
          break;
        case 0x0018:
        case 0x0218 /* Lbl */:
          last_lbl = {
            Name: val.Name,
            Ref: stringify_formula(val.rgce, range, null, supbooks, opts)
          } /*:DefinedName*/;
          if (val.itab > 0) last_lbl.Sheet = val.itab - 1;
          supbooks.names.push(last_lbl);
          if (!supbooks[0]) {
            supbooks[0] = [];
            supbooks[0].XTI = [];
          }
          supbooks[supbooks.length - 1].push(val);
          if (val.Name == "_xlnm._FilterDatabase" && val.itab > 0) if (val.rgce && val.rgce[0] && val.rgce[0][0] && val.rgce[0][0][0] == 'PtgArea3d') FilterDatabases[val.itab - 1] = {
            ref: encode_range(val.rgce[0][0][1][2])
          };
          break;
        case 0x0016 /* ExternCount */:
          opts.ExternCount = val;
          break;
        case 0x0017 /* ExternSheet */:
          if (supbooks.length == 0) {
            supbooks[0] = [];
            supbooks[0].XTI = [];
          }
          supbooks[supbooks.length - 1].XTI = supbooks[supbooks.length - 1].XTI.concat(val);
          supbooks.XTI = supbooks.XTI.concat(val);
          break;
        case 0x0894 /* NameCmt */:
          /* TODO: search for correct name */
          if (opts.biff < 8) break;
          if (last_lbl != null) last_lbl.Comment = val[1];
          break;
        case 0x0012 /* Protect */:
          out["!protect"] = val;
          break;
        /* for sheet or book */
        case 0x0013 /* Password */:
          if (val !== 0 && opts.WTF) console.error("Password verifier: " + val);
          break;
        case 0x0085 /* BoundSheet8 */:
          {
            Directory[val.pos] = val;
            opts.snames.push(val.name);
          }
          break;
        case 0x000a /* EOF */:
          {
            if (--file_depth) break;
            if (range.e) {
              if (range.e.r > 0 && range.e.c > 0) {
                range.e.r--;
                range.e.c--;
                out["!ref"] = encode_range(range);
                if (options.sheetRows && options.sheetRows <= range.e.r) {
                  var tmpri = range.e.r;
                  range.e.r = options.sheetRows - 1;
                  out["!fullref"] = out["!ref"];
                  out["!ref"] = encode_range(range);
                  range.e.r = tmpri;
                }
                range.e.r++;
                range.e.c++;
              }
              if (merges.length > 0) out["!merges"] = merges;
              if (objects.length > 0) out["!objects"] = objects;
              if (colinfo.length > 0) out["!cols"] = colinfo;
              if (rowinfo.length > 0) out["!rows"] = rowinfo;
              Workbook.Sheets.push(wsprops);
            }
            if (cur_sheet === "") Preamble = out;else Sheets[cur_sheet] = out;
            out = options.dense ? [] : {} /*:any*/;
          }
          break;
        case 0x0009:
        case 0x0209:
        case 0x0409:
        case 0x0809 /* BOF */:
          {
            if (opts.biff === 8) opts.biff = {
              /*::[*/0x0009 /*::]*/: 2,
              /*::[*/0x0209 /*::]*/: 3,
              /*::[*/0x0409 /*::]*/: 4
            }[RecordType] || {
              /*::[*/0x0200 /*::]*/: 2,
              /*::[*/0x0300 /*::]*/: 3,
              /*::[*/0x0400 /*::]*/: 4,
              /*::[*/0x0500 /*::]*/: 5,
              /*::[*/0x0600 /*::]*/: 8,
              /*::[*/0x0002 /*::]*/: 2,
              /*::[*/0x0007 /*::]*/: 2
            }[val.BIFFVer] || 8;
            opts.biffguess = val.BIFFVer == 0;
            if (val.BIFFVer == 0 && val.dt == 0x1000) {
              opts.biff = 5;
              seen_codepage = true;
              set_cp(opts.codepage = 28591);
            }
            if (opts.biff == 8 && val.BIFFVer == 0 && val.dt == 16) opts.biff = 2;
            if (file_depth++) break;
            out = options.dense ? [] : {} /*:any*/;
            if (opts.biff < 8 && !seen_codepage) {
              seen_codepage = true;
              set_cp(opts.codepage = options.codepage || 1252);
            }
            if (opts.biff < 5 || val.BIFFVer == 0 && val.dt == 0x1000) {
              if (cur_sheet === "") cur_sheet = "Sheet1";
              range = {
                s: {
                  r: 0,
                  c: 0
                },
                e: {
                  r: 0,
                  c: 0
                }
              };
              /* fake BoundSheet8 */
              var fakebs8 = {
                pos: blob.l - length,
                name: cur_sheet
              };
              Directory[fakebs8.pos] = fakebs8;
              opts.snames.push(cur_sheet);
            } else cur_sheet = (Directory[s] || {
              name: ""
            }).name;
            if (val.dt == 0x20) out["!type"] = "chart";
            if (val.dt == 0x40) out["!type"] = "macro";
            merges = [];
            objects = [];
            opts.arrayf = arrayf = [];
            colinfo = [];
            rowinfo = [];
            seencol = false;
            wsprops = {
              Hidden: (Directory[s] || {
                hs: 0
              }).hs,
              name: cur_sheet
            };
          }
          break;
        case 0x0203 /* Number */:
        case 0x0003 /* BIFF2NUM */:
        case 0x0002 /* BIFF2INT */:
          {
            if (out["!type"] == "chart") if (options.dense ? (out[val.r] || [])[val.c] : out[encode_cell({
              c: val.c,
              r: val.r
            })]) ++val.c;
            temp_val = {
              ixfe: val.ixfe,
              XF: XFs[val.ixfe] || {},
              v: val.val,
              t: 'n'
            } /*:any*/;
            if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
            safe_format_xf(temp_val, options, wb.opts.Date1904);
            addcell({
              c: val.c,
              r: val.r
            }, temp_val, options);
          }
          break;
        case 0x0005:
        case 0x0205 /* BoolErr */:
          {
            temp_val = {
              ixfe: val.ixfe,
              XF: XFs[val.ixfe],
              v: val.val,
              t: val.t
            } /*:any*/;
            if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
            safe_format_xf(temp_val, options, wb.opts.Date1904);
            addcell({
              c: val.c,
              r: val.r
            }, temp_val, options);
          }
          break;
        case 0x027e /* RK */:
          {
            temp_val = {
              ixfe: val.ixfe,
              XF: XFs[val.ixfe],
              v: val.rknum,
              t: 'n'
            } /*:any*/;
            if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
            safe_format_xf(temp_val, options, wb.opts.Date1904);
            addcell({
              c: val.c,
              r: val.r
            }, temp_val, options);
          }
          break;
        case 0x00bd /* MulRk */:
          {
            for (var j = val.c; j <= val.C; ++j) {
              var ixfe = val.rkrec[j - val.c][0];
              temp_val = {
                ixfe: ixfe,
                XF: XFs[ixfe],
                v: val.rkrec[j - val.c][1],
                t: 'n'
              } /*:any*/;
              if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
              safe_format_xf(temp_val, options, wb.opts.Date1904);
              addcell({
                c: j,
                r: val.r
              }, temp_val, options);
            }
          }
          break;
        case 0x0006:
        case 0x0206:
        case 0x0406 /* Formula */:
          {
            if (val.val == 'String') {
              last_formula = val;
              break;
            }
            temp_val = make_cell(val.val, val.cell.ixfe, val.tt);
            temp_val.XF = XFs[temp_val.ixfe];
            if (options.cellFormula) {
              var _f = val.formula;
              if (_f && _f[0] && _f[0][0] && _f[0][0][0] == 'PtgExp') {
                var _fr = _f[0][0][1][0],
                  _fc = _f[0][0][1][1];
                var _fe = encode_cell({
                  r: _fr,
                  c: _fc
                });
                if (sharedf[_fe]) temp_val.f = "" + stringify_formula(val.formula, range, val.cell, supbooks, opts);else temp_val.F = ((options.dense ? (out[_fr] || [])[_fc] : out[_fe]) || {}).F;
              } else temp_val.f = "" + stringify_formula(val.formula, range, val.cell, supbooks, opts);
            }
            if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
            safe_format_xf(temp_val, options, wb.opts.Date1904);
            addcell(val.cell, temp_val, options);
            last_formula = val;
          }
          break;
        case 0x0007:
        case 0x0207 /* String */:
          {
            if (last_formula) {
              /* technically always true */
              last_formula.val = val;
              temp_val = make_cell(val, last_formula.cell.ixfe, 's');
              temp_val.XF = XFs[temp_val.ixfe];
              if (options.cellFormula) {
                temp_val.f = "" + stringify_formula(last_formula.formula, range, last_formula.cell, supbooks, opts);
              }
              if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
              safe_format_xf(temp_val, options, wb.opts.Date1904);
              addcell(last_formula.cell, temp_val, options);
              last_formula = null;
            } else throw new Error("String record expects Formula");
          }
          break;
        case 0x0021:
        case 0x0221 /* Array */:
          {
            arrayf.push(val);
            var _arraystart = encode_cell(val[0].s);
            cc = options.dense ? (out[val[0].s.r] || [])[val[0].s.c] : out[_arraystart];
            if (options.cellFormula && cc) {
              if (!last_formula) break; /* technically unreachable */
              if (!_arraystart || !cc) break;
              cc.f = "" + stringify_formula(val[1], range, val[0], supbooks, opts);
              cc.F = encode_range(val[0]);
            }
          }
          break;
        case 0x04bc /* ShrFmla */:
          {
            if (!options.cellFormula) break;
            if (last_cell) {
              /* TODO: capture range */
              if (!last_formula) break; /* technically unreachable */
              sharedf[encode_cell(last_formula.cell)] = val[0];
              cc = options.dense ? (out[last_formula.cell.r] || [])[last_formula.cell.c] : out[encode_cell(last_formula.cell)];
              (cc || {}).f = "" + stringify_formula(val[0], range, lastcell, supbooks, opts);
            }
          }
          break;
        case 0x00fd /* LabelSst */:
          temp_val = make_cell(sst[val.isst].t, val.ixfe, 's');
          if (sst[val.isst].h) temp_val.h = sst[val.isst].h;
          temp_val.XF = XFs[temp_val.ixfe];
          if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
          safe_format_xf(temp_val, options, wb.opts.Date1904);
          addcell({
            c: val.c,
            r: val.r
          }, temp_val, options);
          break;
        case 0x0201 /* Blank */:
          if (options.sheetStubs) {
            temp_val = {
              ixfe: val.ixfe,
              XF: XFs[val.ixfe],
              t: 'z'
            } /*:any*/;
            if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
            safe_format_xf(temp_val, options, wb.opts.Date1904);
            addcell({
              c: val.c,
              r: val.r
            }, temp_val, options);
          }
          break;
        case 0x00be /* MulBlank */:
          if (options.sheetStubs) {
            for (var _j = val.c; _j <= val.C; ++_j) {
              var _ixfe = val.ixfe[_j - val.c];
              temp_val = {
                ixfe: _ixfe,
                XF: XFs[_ixfe],
                t: 'z'
              } /*:any*/;
              if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
              safe_format_xf(temp_val, options, wb.opts.Date1904);
              addcell({
                c: _j,
                r: val.r
              }, temp_val, options);
            }
          }
          break;
        case 0x00d6 /* RString */:
        case 0x0204 /* Label */:
        case 0x0004 /* BIFF2STR */:
          temp_val = make_cell(val.val, val.ixfe, 's');
          temp_val.XF = XFs[temp_val.ixfe];
          if (BIFF2Fmt > 0) temp_val.z = BIFF2FmtTable[temp_val.ixfe >> 8 & 0x3F];
          safe_format_xf(temp_val, options, wb.opts.Date1904);
          addcell({
            c: val.c,
            r: val.r
          }, temp_val, options);
          break;
        case 0x0000:
        case 0x0200 /* Dimensions */:
          {
            if (file_depth === 1) range = val; /* TODO: stack */
          }
          break;
        case 0x00fc /* SST */:
          {
            sst = val;
          }
          break;
        case 0x041e /* Format */:
          {
            /* val = [id, fmt] */
            if (opts.biff == 4) {
              BIFF2FmtTable[BIFF2Fmt++] = val[1];
              for (var b4idx = 0; b4idx < BIFF2Fmt + 163; ++b4idx) if (table_fmt[b4idx] == val[1]) break;
              if (b4idx >= 163) SSF_load(val[1], BIFF2Fmt + 163);
            } else SSF_load(val[1], val[0]);
          }
          break;
        case 0x001e /* BIFF2FORMAT */:
          {
            BIFF2FmtTable[BIFF2Fmt++] = val;
            for (var b2idx = 0; b2idx < BIFF2Fmt + 163; ++b2idx) if (table_fmt[b2idx] == val) break;
            if (b2idx >= 163) SSF_load(val, BIFF2Fmt + 163);
          }
          break;
        case 0x00e5 /* MergeCells */:
          merges = merges.concat(val);
          break;
        case 0x005d /* Obj */:
          objects[val.cmo[0]] = opts.lastobj = val;
          break;
        case 0x01b6 /* TxO */:
          opts.lastobj.TxO = val;
          break;
        case 0x007f /* ImData */:
          opts.lastobj.ImData = val;
          break;
        case 0x01b8 /* HLink */:
          {
            for (rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) for (rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
              cc = options.dense ? (out[rngR] || [])[rngC] : out[encode_cell({
                c: rngC,
                r: rngR
              })];
              if (cc) cc.l = val[1];
            }
          }
          break;
        case 0x0800 /* HLinkTooltip */:
          {
            for (rngR = val[0].s.r; rngR <= val[0].e.r; ++rngR) for (rngC = val[0].s.c; rngC <= val[0].e.c; ++rngC) {
              cc = options.dense ? (out[rngR] || [])[rngC] : out[encode_cell({
                c: rngC,
                r: rngR
              })];
              if (cc && cc.l) cc.l.Tooltip = val[1];
            }
          }
          break;
        case 0x001c /* Note */:
          {
            if (opts.biff <= 5 && opts.biff >= 2) break; /* TODO: BIFF5 */
            cc = options.dense ? (out[val[0].r] || [])[val[0].c] : out[encode_cell(val[0])];
            var noteobj = objects[val[2]];
            if (!cc) {
              if (options.dense) {
                if (!out[val[0].r]) out[val[0].r] = [];
                cc = out[val[0].r][val[0].c] = {
                  t: "z"
                } /*:any*/;
              } else {
                cc = out[encode_cell(val[0])] = {
                  t: "z"
                } /*:any*/;
              }
              range.e.r = Math.max(range.e.r, val[0].r);
              range.s.r = Math.min(range.s.r, val[0].r);
              range.e.c = Math.max(range.e.c, val[0].c);
              range.s.c = Math.min(range.s.c, val[0].c);
            }
            if (!cc.c) cc.c = [];
            cmnt = {
              a: val[1],
              t: noteobj.TxO.t
            };
            cc.c.push(cmnt);
          }
          break;
        case 0x087d /* XFExt */:
          update_xfext(XFs[val.ixfe], val.ext);
          break;
        case 0x007d /* ColInfo */:
          {
            if (!opts.cellStyles) break;
            while (val.e >= val.s) {
              colinfo[val.e--] = {
                width: val.w / 256,
                level: val.level || 0,
                hidden: !!(val.flags & 1)
              };
              if (!seencol) {
                seencol = true;
                find_mdw_colw(val.w / 256);
              }
              process_col(colinfo[val.e + 1]);
            }
          }
          break;
        case 0x0208 /* Row */:
          {
            var rowobj = {};
            if (val.level != null) {
              rowinfo[val.r] = rowobj;
              rowobj.level = val.level;
            }
            if (val.hidden) {
              rowinfo[val.r] = rowobj;
              rowobj.hidden = true;
            }
            if (val.hpt) {
              rowinfo[val.r] = rowobj;
              rowobj.hpt = val.hpt;
              rowobj.hpx = pt2px(val.hpt);
            }
          }
          break;
        case 0x0026 /* LeftMargin */:
        case 0x0027 /* RightMargin */:
        case 0x0028 /* TopMargin */:
        case 0x0029 /* BottomMargin */:
          if (!out['!margins']) default_margins(out['!margins'] = {});
          out['!margins'][{
            0x26: "left",
            0x27: "right",
            0x28: "top",
            0x29: "bottom"
          }[RecordType]] = val;
          break;
        case 0x00a1 /* Setup */:
          // TODO
          if (!out['!margins']) default_margins(out['!margins'] = {});
          out['!margins'].header = val.header;
          out['!margins'].footer = val.footer;
          break;
        case 0x023e /* Window2 */:
          // TODO
          // $FlowIgnore
          if (val.RTL) Workbook.Views[0].RTL = true;
          break;
        case 0x0092 /* Palette */:
          palette = val;
          break;
        case 0x0896 /* Theme */:
          themes = val;
          break;
        case 0x008c /* Country */:
          country = val;
          break;
        case 0x01ba /* CodeName */:
          {
            /*:: if(!Workbook.WBProps) Workbook.WBProps = {}; */
            if (!cur_sheet) Workbook.WBProps.CodeName = val || "ThisWorkbook";else wsprops.CodeName = val || wsprops.name;
          }
          break;
      }
    } else {
      if (!R) console.error("Missing Info for XLS Record 0x" + RecordType.toString(16));
      blob.l += length;
    }
  }
  wb.SheetNames = keys(Directory).sort(function (a, b) {
    return Number(a) - Number(b);
  }).map(function (x) {
    return Directory[x].name;
  });
  if (!options.bookSheets) wb.Sheets = Sheets;
  if (!wb.SheetNames.length && Preamble["!ref"]) {
    wb.SheetNames.push("Sheet1");
    /*jshint -W069 */
    if (wb.Sheets) wb.Sheets["Sheet1"] = Preamble;
    /*jshint +W069 */
  } else wb.Preamble = Preamble;
  if (wb.Sheets) FilterDatabases.forEach(function (r, i) {
    wb.Sheets[wb.SheetNames[i]]['!autofilter'] = r;
  });
  wb.Strings = sst;
  wb.SSF = dup(table_fmt);
  if (opts.enc) wb.Encryption = opts.enc;
  if (themes) wb.Themes = themes;
  wb.Metadata = {};
  if (country !== undefined) wb.Metadata.Country = country;
  if (supbooks.names.length > 0) Workbook.Names = supbooks.names;
  wb.Workbook = Workbook;
  return wb;
}

/* TODO: split props*/
var PSCLSID = {
  SI: "e0859ff2f94f6810ab9108002b27b3d9",
  DSI: "02d5cdd59c2e1b10939708002b2cf9ae",
  UDI: "05d5cdd59c2e1b10939708002b2cf9ae"
};
function parse_xls_props(cfb /*:CFBContainer*/, props, o) {
  /* [MS-OSHARED] 2.3.3.2.2 Document Summary Information Property Set */
  var DSI = CFB.find(cfb, '/!DocumentSummaryInformation');
  if (DSI && DSI.size > 0) try {
    var DocSummary = parse_PropertySetStream(DSI, DocSummaryPIDDSI, PSCLSID.DSI);
    for (var d in DocSummary) props[d] = DocSummary[d];
  } catch (e) {
    if (o.WTF) throw e; /* empty */
  }

  /* [MS-OSHARED] 2.3.3.2.1 Summary Information Property Set*/
  var SI = CFB.find(cfb, '/!SummaryInformation');
  if (SI && SI.size > 0) try {
    var Summary = parse_PropertySetStream(SI, SummaryPIDSI, PSCLSID.SI);
    for (var s in Summary) if (props[s] == null) props[s] = Summary[s];
  } catch (e) {
    if (o.WTF) throw e; /* empty */
  }
  if (props.HeadingPairs && props.TitlesOfParts) {
    load_props_pairs(props.HeadingPairs, props.TitlesOfParts, props, o);
    delete props.HeadingPairs;
    delete props.TitlesOfParts;
  }
}
function write_xls_props(wb /*:Workbook*/, cfb /*:CFBContainer*/) {
  var DSEntries = [],
    SEntries = [],
    CEntries = [];
  var i = 0,
    Keys;
  var DocSummaryRE /*:{[key:string]:string}*/ = evert_key(DocSummaryPIDDSI, "n");
  var SummaryRE /*:{[key:string]:string}*/ = evert_key(SummaryPIDSI, "n");
  if (wb.Props) {
    Keys = keys(wb.Props);
    // $FlowIgnore
    for (i = 0; i < Keys.length; ++i) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Props[Keys[i]]]);
  }
  if (wb.Custprops) {
    Keys = keys(wb.Custprops);
    // $FlowIgnore
    for (i = 0; i < Keys.length; ++i) if (!Object.prototype.hasOwnProperty.call(wb.Props || {}, Keys[i])) (Object.prototype.hasOwnProperty.call(DocSummaryRE, Keys[i]) ? DSEntries : Object.prototype.hasOwnProperty.call(SummaryRE, Keys[i]) ? SEntries : CEntries).push([Keys[i], wb.Custprops[Keys[i]]]);
  }
  var CEntries2 = [];
  for (i = 0; i < CEntries.length; ++i) {
    if (XLSPSSkip.indexOf(CEntries[i][0]) > -1 || PseudoPropsPairs.indexOf(CEntries[i][0]) > -1) continue;
    if (CEntries[i][1] == null) continue;
    CEntries2.push(CEntries[i]);
  }
  if (SEntries.length) CFB.utils.cfb_add(cfb, "/\u0005SummaryInformation", write_PropertySetStream(SEntries, PSCLSID.SI, SummaryRE, SummaryPIDSI));
  if (DSEntries.length || CEntries2.length) CFB.utils.cfb_add(cfb, "/\u0005DocumentSummaryInformation", write_PropertySetStream(DSEntries, PSCLSID.DSI, DocSummaryRE, DocSummaryPIDDSI, CEntries2.length ? CEntries2 : null, PSCLSID.UDI));
}
function parse_xlscfb(cfb /*:any*/, options /*:?ParseOpts*/) /*:Workbook*/{
  if (!options) options = {};
  fix_read_opts(options);
  reset_cp();
  if (options.codepage) set_ansi(options.codepage);
  var CompObj /*:?CFBEntry*/, WB /*:?any*/;
  if (cfb.FullPaths) {
    if (CFB.find(cfb, '/encryption')) throw new Error("File is password-protected");
    CompObj = CFB.find(cfb, '!CompObj');
    WB = CFB.find(cfb, '/Workbook') || CFB.find(cfb, '/Book');
  } else {
    switch (options.type) {
      case 'base64':
        cfb = s2a(Base64_decode(cfb));
        break;
      case 'binary':
        cfb = s2a(cfb);
        break;
      case 'buffer':
        break;
      case 'array':
        if (!Array.isArray(cfb)) cfb = Array.prototype.slice.call(cfb);
        break;
    }
    prep_blob(cfb, 0);
    WB = {
      content: cfb
    } /*:any*/;
  }
  var /*::CompObjP, */WorkbookP /*:: :Workbook = XLSX.utils.book_new(); */;
  var _data /*:?any*/;
  if (CompObj) /*::CompObjP = */parse_compobj(CompObj);
  if (options.bookProps && !options.bookSheets) WorkbookP = {} /*:any*/;else /*:: if(cfb instanceof CFBContainer) */{
      var T = has_buf ? 'buffer' : 'array';
      if (WB && WB.content) WorkbookP = parse_workbook(WB.content, options);
      /* Quattro Pro 7-8 */else if ((_data = CFB.find(cfb, 'PerfectOffice_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
      /* Quattro Pro 9 */else if ((_data = CFB.find(cfb, 'NativeContent_MAIN')) && _data.content) WorkbookP = WK_.to_workbook(_data.content, (options.type = T, options));
      /* Works 4 for Mac */else if ((_data = CFB.find(cfb, 'MN0')) && _data.content) throw new Error("Unsupported Works 4 for Mac file");else throw new Error("Cannot find Workbook stream");
      if (options.bookVBA && cfb.FullPaths && CFB.find(cfb, '/_VBA_PROJECT_CUR/VBA/dir')) WorkbookP.vbaraw = make_vba_xls(cfb);
    }
  var props = {};
  if (cfb.FullPaths) parse_xls_props(/*::((*/cfb /*:: :any):CFBContainer)*/, props, options);
  WorkbookP.Props = WorkbookP.Custprops = props; /* TODO: split up properties */
  if (options.bookFiles) WorkbookP.cfb = cfb;
  /*WorkbookP.CompObjP = CompObjP; // TODO: storage? */
  return WorkbookP;
}
function write_xlscfb(wb /*:Workbook*/, opts /*:WriteOpts*/) /*:CFBContainer*/{
  var o = opts || {};
  var cfb = CFB.utils.cfb_new({
    root: "R"
  });
  var wbpath = "/Workbook";
  switch (o.bookType || "xls") {
    case "xls":
      o.bookType = "biff8";
    /* falls through */
    case "xla":
      if (!o.bookType) o.bookType = "xla";
    /* falls through */
    case "biff8":
      wbpath = "/Workbook";
      o.biff = 8;
      break;
    case "biff5":
      wbpath = "/Book";
      o.biff = 5;
      break;
    default:
      throw new Error("invalid type " + o.bookType + " for XLS CFB");
  }
  CFB.utils.cfb_add(cfb, wbpath, write_biff_buf(wb, o));
  if (o.biff == 8 && (wb.Props || wb.Custprops)) write_xls_props(wb, cfb);
  // TODO: SI, DSI, CO
  if (o.biff == 8 && wb.vbaraw) fill_vba_xls(cfb, CFB.read(wb.vbaraw, {
    type: typeof wb.vbaraw == "string" ? "binary" : "buffer"
  }));
  return cfb;
}
/* [MS-XLSB] 2.3 Record Enumeration */
var XLSBRecordEnum = {
  /*::[*/0x0000 /*::]*/: {
    /* n:"BrtRowHdr", */f: parse_BrtRowHdr
  },
  /*::[*/0x0001 /*::]*/: {
    /* n:"BrtCellBlank", */f: parse_BrtCellBlank
  },
  /*::[*/0x0002 /*::]*/: {
    /* n:"BrtCellRk", */f: parse_BrtCellRk
  },
  /*::[*/0x0003 /*::]*/: {
    /* n:"BrtCellError", */f: parse_BrtCellError
  },
  /*::[*/0x0004 /*::]*/: {
    /* n:"BrtCellBool", */f: parse_BrtCellBool
  },
  /*::[*/0x0005 /*::]*/: {
    /* n:"BrtCellReal", */f: parse_BrtCellReal
  },
  /*::[*/0x0006 /*::]*/: {
    /* n:"BrtCellSt", */f: parse_BrtCellSt
  },
  /*::[*/0x0007 /*::]*/: {
    /* n:"BrtCellIsst", */f: parse_BrtCellIsst
  },
  /*::[*/0x0008 /*::]*/: {
    /* n:"BrtFmlaString", */f: parse_BrtFmlaString
  },
  /*::[*/0x0009 /*::]*/: {
    /* n:"BrtFmlaNum", */f: parse_BrtFmlaNum
  },
  /*::[*/0x000A /*::]*/: {
    /* n:"BrtFmlaBool", */f: parse_BrtFmlaBool
  },
  /*::[*/0x000B /*::]*/: {
    /* n:"BrtFmlaError", */f: parse_BrtFmlaError
  },
  /*::[*/0x000C /*::]*/: {
    /* n:"BrtShortBlank", */f: parse_BrtShortBlank
  },
  /*::[*/0x000D /*::]*/: {
    /* n:"BrtShortRk", */f: parse_BrtShortRk
  },
  /*::[*/0x000E /*::]*/: {
    /* n:"BrtShortError", */f: parse_BrtShortError
  },
  /*::[*/0x000F /*::]*/: {
    /* n:"BrtShortBool", */f: parse_BrtShortBool
  },
  /*::[*/0x0010 /*::]*/: {
    /* n:"BrtShortReal", */f: parse_BrtShortReal
  },
  /*::[*/0x0011 /*::]*/: {
    /* n:"BrtShortSt", */f: parse_BrtShortSt
  },
  /*::[*/0x0012 /*::]*/: {
    /* n:"BrtShortIsst", */f: parse_BrtShortIsst
  },
  /*::[*/0x0013 /*::]*/: {
    /* n:"BrtSSTItem", */f: parse_RichStr
  },
  /*::[*/0x0014 /*::]*/: {/* n:"BrtPCDIMissing" */},
  /*::[*/0x0015 /*::]*/: {/* n:"BrtPCDINumber" */},
  /*::[*/0x0016 /*::]*/: {/* n:"BrtPCDIBoolean" */},
  /*::[*/0x0017 /*::]*/: {/* n:"BrtPCDIError" */},
  /*::[*/0x0018 /*::]*/: {/* n:"BrtPCDIString" */},
  /*::[*/0x0019 /*::]*/: {/* n:"BrtPCDIDatetime" */},
  /*::[*/0x001A /*::]*/: {/* n:"BrtPCDIIndex" */},
  /*::[*/0x001B /*::]*/: {/* n:"BrtPCDIAMissing" */},
  /*::[*/0x001C /*::]*/: {/* n:"BrtPCDIANumber" */},
  /*::[*/0x001D /*::]*/: {/* n:"BrtPCDIABoolean" */},
  /*::[*/0x001E /*::]*/: {/* n:"BrtPCDIAError" */},
  /*::[*/0x001F /*::]*/: {/* n:"BrtPCDIAString" */},
  /*::[*/0x0020 /*::]*/: {/* n:"BrtPCDIADatetime" */},
  /*::[*/0x0021 /*::]*/: {/* n:"BrtPCRRecord" */},
  /*::[*/0x0022 /*::]*/: {/* n:"BrtPCRRecordDt" */},
  /*::[*/0x0023 /*::]*/: {
    /* n:"BrtFRTBegin", */T: 1
  },
  /*::[*/0x0024 /*::]*/: {
    /* n:"BrtFRTEnd", */T: -1
  },
  /*::[*/0x0025 /*::]*/: {
    /* n:"BrtACBegin", */T: 1
  },
  /*::[*/0x0026 /*::]*/: {
    /* n:"BrtACEnd", */T: -1
  },
  /*::[*/0x0027 /*::]*/: {
    /* n:"BrtName", */f: parse_BrtName
  },
  /*::[*/0x0028 /*::]*/: {/* n:"BrtIndexRowBlock" */},
  /*::[*/0x002A /*::]*/: {/* n:"BrtIndexBlock" */},
  /*::[*/0x002B /*::]*/: {
    /* n:"BrtFont", */f: parse_BrtFont
  },
  /*::[*/0x002C /*::]*/: {
    /* n:"BrtFmt", */f: parse_BrtFmt
  },
  /*::[*/0x002D /*::]*/: {
    /* n:"BrtFill", */f: parse_BrtFill
  },
  /*::[*/0x002E /*::]*/: {
    /* n:"BrtBorder", */f: parse_BrtBorder
  },
  /*::[*/0x002F /*::]*/: {
    /* n:"BrtXF", */f: parse_BrtXF
  },
  /*::[*/0x0030 /*::]*/: {/* n:"BrtStyle" */},
  /*::[*/0x0031 /*::]*/: {
    /* n:"BrtCellMeta", */f: parse_Int32LE
  },
  /*::[*/0x0032 /*::]*/: {/* n:"BrtValueMeta" */},
  /*::[*/0x0033 /*::]*/: {
    /* n:"BrtMdb" */f: parse_BrtMdb
  },
  /*::[*/0x0034 /*::]*/: {
    /* n:"BrtBeginFmd", */T: 1
  },
  /*::[*/0x0035 /*::]*/: {
    /* n:"BrtEndFmd", */T: -1
  },
  /*::[*/0x0036 /*::]*/: {
    /* n:"BrtBeginMdx", */T: 1
  },
  /*::[*/0x0037 /*::]*/: {
    /* n:"BrtEndMdx", */T: -1
  },
  /*::[*/0x0038 /*::]*/: {
    /* n:"BrtBeginMdxTuple", */T: 1
  },
  /*::[*/0x0039 /*::]*/: {
    /* n:"BrtEndMdxTuple", */T: -1
  },
  /*::[*/0x003A /*::]*/: {/* n:"BrtMdxMbrIstr" */},
  /*::[*/0x003B /*::]*/: {/* n:"BrtStr" */},
  /*::[*/0x003C /*::]*/: {
    /* n:"BrtColInfo", */f: parse_ColInfo
  },
  /*::[*/0x003E /*::]*/: {
    /* n:"BrtCellRString", */f: parse_BrtCellRString
  },
  /*::[*/0x003F /*::]*/: {
    /* n:"BrtCalcChainItem$", */f: parse_BrtCalcChainItem$
  },
  /*::[*/0x0040 /*::]*/: {
    /* n:"BrtDVal", */f: parse_BrtDVal
  },
  /*::[*/0x0041 /*::]*/: {/* n:"BrtSxvcellNum" */},
  /*::[*/0x0042 /*::]*/: {/* n:"BrtSxvcellStr" */},
  /*::[*/0x0043 /*::]*/: {/* n:"BrtSxvcellBool" */},
  /*::[*/0x0044 /*::]*/: {/* n:"BrtSxvcellErr" */},
  /*::[*/0x0045 /*::]*/: {/* n:"BrtSxvcellDate" */},
  /*::[*/0x0046 /*::]*/: {/* n:"BrtSxvcellNil" */},
  /*::[*/0x0080 /*::]*/: {/* n:"BrtFileVersion" */},
  /*::[*/0x0081 /*::]*/: {
    /* n:"BrtBeginSheet", */T: 1
  },
  /*::[*/0x0082 /*::]*/: {
    /* n:"BrtEndSheet", */T: -1
  },
  /*::[*/0x0083 /*::]*/: {
    /* n:"BrtBeginBook", */T: 1,
    f: parsenoop,
    p: 0
  },
  /*::[*/0x0084 /*::]*/: {
    /* n:"BrtEndBook", */T: -1
  },
  /*::[*/0x0085 /*::]*/: {
    /* n:"BrtBeginWsViews", */T: 1
  },
  /*::[*/0x0086 /*::]*/: {
    /* n:"BrtEndWsViews", */T: -1
  },
  /*::[*/0x0087 /*::]*/: {
    /* n:"BrtBeginBookViews", */T: 1
  },
  /*::[*/0x0088 /*::]*/: {
    /* n:"BrtEndBookViews", */T: -1
  },
  /*::[*/0x0089 /*::]*/: {
    /* n:"BrtBeginWsView", */T: 1,
    f: parse_BrtBeginWsView
  },
  /*::[*/0x008A /*::]*/: {
    /* n:"BrtEndWsView", */T: -1
  },
  /*::[*/0x008B /*::]*/: {
    /* n:"BrtBeginCsViews", */T: 1
  },
  /*::[*/0x008C /*::]*/: {
    /* n:"BrtEndCsViews", */T: -1
  },
  /*::[*/0x008D /*::]*/: {
    /* n:"BrtBeginCsView", */T: 1
  },
  /*::[*/0x008E /*::]*/: {
    /* n:"BrtEndCsView", */T: -1
  },
  /*::[*/0x008F /*::]*/: {
    /* n:"BrtBeginBundleShs", */T: 1
  },
  /*::[*/0x0090 /*::]*/: {
    /* n:"BrtEndBundleShs", */T: -1
  },
  /*::[*/0x0091 /*::]*/: {
    /* n:"BrtBeginSheetData", */T: 1
  },
  /*::[*/0x0092 /*::]*/: {
    /* n:"BrtEndSheetData", */T: -1
  },
  /*::[*/0x0093 /*::]*/: {
    /* n:"BrtWsProp", */f: parse_BrtWsProp
  },
  /*::[*/0x0094 /*::]*/: {
    /* n:"BrtWsDim", */f: parse_BrtWsDim,
    p: 16
  },
  /*::[*/0x0097 /*::]*/: {
    /* n:"BrtPane", */f: parse_BrtPane
  },
  /*::[*/0x0098 /*::]*/: {/* n:"BrtSel" */},
  /*::[*/0x0099 /*::]*/: {
    /* n:"BrtWbProp", */f: parse_BrtWbProp
  },
  /*::[*/0x009A /*::]*/: {/* n:"BrtWbFactoid" */},
  /*::[*/0x009B /*::]*/: {/* n:"BrtFileRecover" */},
  /*::[*/0x009C /*::]*/: {
    /* n:"BrtBundleSh", */f: parse_BrtBundleSh
  },
  /*::[*/0x009D /*::]*/: {/* n:"BrtCalcProp" */},
  /*::[*/0x009E /*::]*/: {/* n:"BrtBookView" */},
  /*::[*/0x009F /*::]*/: {
    /* n:"BrtBeginSst", */T: 1,
    f: parse_BrtBeginSst
  },
  /*::[*/0x00A0 /*::]*/: {
    /* n:"BrtEndSst", */T: -1
  },
  /*::[*/0x00A1 /*::]*/: {
    /* n:"BrtBeginAFilter", */T: 1,
    f: parse_UncheckedRfX
  },
  /*::[*/0x00A2 /*::]*/: {
    /* n:"BrtEndAFilter", */T: -1
  },
  /*::[*/0x00A3 /*::]*/: {
    /* n:"BrtBeginFilterColumn", */T: 1
  },
  /*::[*/0x00A4 /*::]*/: {
    /* n:"BrtEndFilterColumn", */T: -1
  },
  /*::[*/0x00A5 /*::]*/: {
    /* n:"BrtBeginFilters", */T: 1
  },
  /*::[*/0x00A6 /*::]*/: {
    /* n:"BrtEndFilters", */T: -1
  },
  /*::[*/0x00A7 /*::]*/: {/* n:"BrtFilter" */},
  /*::[*/0x00A8 /*::]*/: {/* n:"BrtColorFilter" */},
  /*::[*/0x00A9 /*::]*/: {/* n:"BrtIconFilter" */},
  /*::[*/0x00AA /*::]*/: {/* n:"BrtTop10Filter" */},
  /*::[*/0x00AB /*::]*/: {/* n:"BrtDynamicFilter" */},
  /*::[*/0x00AC /*::]*/: {
    /* n:"BrtBeginCustomFilters", */T: 1
  },
  /*::[*/0x00AD /*::]*/: {
    /* n:"BrtEndCustomFilters", */T: -1
  },
  /*::[*/0x00AE /*::]*/: {/* n:"BrtCustomFilter" */},
  /*::[*/0x00AF /*::]*/: {/* n:"BrtAFilterDateGroupItem" */},
  /*::[*/0x00B0 /*::]*/: {
    /* n:"BrtMergeCell", */f: parse_BrtMergeCell
  },
  /*::[*/0x00B1 /*::]*/: {
    /* n:"BrtBeginMergeCells", */T: 1
  },
  /*::[*/0x00B2 /*::]*/: {
    /* n:"BrtEndMergeCells", */T: -1
  },
  /*::[*/0x00B3 /*::]*/: {
    /* n:"BrtBeginPivotCacheDef", */T: 1
  },
  /*::[*/0x00B4 /*::]*/: {
    /* n:"BrtEndPivotCacheDef", */T: -1
  },
  /*::[*/0x00B5 /*::]*/: {
    /* n:"BrtBeginPCDFields", */T: 1
  },
  /*::[*/0x00B6 /*::]*/: {
    /* n:"BrtEndPCDFields", */T: -1
  },
  /*::[*/0x00B7 /*::]*/: {
    /* n:"BrtBeginPCDField", */T: 1
  },
  /*::[*/0x00B8 /*::]*/: {
    /* n:"BrtEndPCDField", */T: -1
  },
  /*::[*/0x00B9 /*::]*/: {
    /* n:"BrtBeginPCDSource", */T: 1
  },
  /*::[*/0x00BA /*::]*/: {
    /* n:"BrtEndPCDSource", */T: -1
  },
  /*::[*/0x00BB /*::]*/: {
    /* n:"BrtBeginPCDSRange", */T: 1
  },
  /*::[*/0x00BC /*::]*/: {
    /* n:"BrtEndPCDSRange", */T: -1
  },
  /*::[*/0x00BD /*::]*/: {
    /* n:"BrtBeginPCDFAtbl", */T: 1
  },
  /*::[*/0x00BE /*::]*/: {
    /* n:"BrtEndPCDFAtbl", */T: -1
  },
  /*::[*/0x00BF /*::]*/: {
    /* n:"BrtBeginPCDIRun", */T: 1
  },
  /*::[*/0x00C0 /*::]*/: {
    /* n:"BrtEndPCDIRun", */T: -1
  },
  /*::[*/0x00C1 /*::]*/: {
    /* n:"BrtBeginPivotCacheRecords", */T: 1
  },
  /*::[*/0x00C2 /*::]*/: {
    /* n:"BrtEndPivotCacheRecords", */T: -1
  },
  /*::[*/0x00C3 /*::]*/: {
    /* n:"BrtBeginPCDHierarchies", */T: 1
  },
  /*::[*/0x00C4 /*::]*/: {
    /* n:"BrtEndPCDHierarchies", */T: -1
  },
  /*::[*/0x00C5 /*::]*/: {
    /* n:"BrtBeginPCDHierarchy", */T: 1
  },
  /*::[*/0x00C6 /*::]*/: {
    /* n:"BrtEndPCDHierarchy", */T: -1
  },
  /*::[*/0x00C7 /*::]*/: {
    /* n:"BrtBeginPCDHFieldsUsage", */T: 1
  },
  /*::[*/0x00C8 /*::]*/: {
    /* n:"BrtEndPCDHFieldsUsage", */T: -1
  },
  /*::[*/0x00C9 /*::]*/: {
    /* n:"BrtBeginExtConnection", */T: 1
  },
  /*::[*/0x00CA /*::]*/: {
    /* n:"BrtEndExtConnection", */T: -1
  },
  /*::[*/0x00CB /*::]*/: {
    /* n:"BrtBeginECDbProps", */T: 1
  },
  /*::[*/0x00CC /*::]*/: {
    /* n:"BrtEndECDbProps", */T: -1
  },
  /*::[*/0x00CD /*::]*/: {
    /* n:"BrtBeginECOlapProps", */T: 1
  },
  /*::[*/0x00CE /*::]*/: {
    /* n:"BrtEndECOlapProps", */T: -1
  },
  /*::[*/0x00CF /*::]*/: {
    /* n:"BrtBeginPCDSConsol", */T: 1
  },
  /*::[*/0x00D0 /*::]*/: {
    /* n:"BrtEndPCDSConsol", */T: -1
  },
  /*::[*/0x00D1 /*::]*/: {
    /* n:"BrtBeginPCDSCPages", */T: 1
  },
  /*::[*/0x00D2 /*::]*/: {
    /* n:"BrtEndPCDSCPages", */T: -1
  },
  /*::[*/0x00D3 /*::]*/: {
    /* n:"BrtBeginPCDSCPage", */T: 1
  },
  /*::[*/0x00D4 /*::]*/: {
    /* n:"BrtEndPCDSCPage", */T: -1
  },
  /*::[*/0x00D5 /*::]*/: {
    /* n:"BrtBeginPCDSCPItem", */T: 1
  },
  /*::[*/0x00D6 /*::]*/: {
    /* n:"BrtEndPCDSCPItem", */T: -1
  },
  /*::[*/0x00D7 /*::]*/: {
    /* n:"BrtBeginPCDSCSets", */T: 1
  },
  /*::[*/0x00D8 /*::]*/: {
    /* n:"BrtEndPCDSCSets", */T: -1
  },
  /*::[*/0x00D9 /*::]*/: {
    /* n:"BrtBeginPCDSCSet", */T: 1
  },
  /*::[*/0x00DA /*::]*/: {
    /* n:"BrtEndPCDSCSet", */T: -1
  },
  /*::[*/0x00DB /*::]*/: {
    /* n:"BrtBeginPCDFGroup", */T: 1
  },
  /*::[*/0x00DC /*::]*/: {
    /* n:"BrtEndPCDFGroup", */T: -1
  },
  /*::[*/0x00DD /*::]*/: {
    /* n:"BrtBeginPCDFGItems", */T: 1
  },
  /*::[*/0x00DE /*::]*/: {
    /* n:"BrtEndPCDFGItems", */T: -1
  },
  /*::[*/0x00DF /*::]*/: {
    /* n:"BrtBeginPCDFGRange", */T: 1
  },
  /*::[*/0x00E0 /*::]*/: {
    /* n:"BrtEndPCDFGRange", */T: -1
  },
  /*::[*/0x00E1 /*::]*/: {
    /* n:"BrtBeginPCDFGDiscrete", */T: 1
  },
  /*::[*/0x00E2 /*::]*/: {
    /* n:"BrtEndPCDFGDiscrete", */T: -1
  },
  /*::[*/0x00E3 /*::]*/: {
    /* n:"BrtBeginPCDSDTupleCache", */T: 1
  },
  /*::[*/0x00E4 /*::]*/: {
    /* n:"BrtEndPCDSDTupleCache", */T: -1
  },
  /*::[*/0x00E5 /*::]*/: {
    /* n:"BrtBeginPCDSDTCEntries", */T: 1
  },
  /*::[*/0x00E6 /*::]*/: {
    /* n:"BrtEndPCDSDTCEntries", */T: -1
  },
  /*::[*/0x00E7 /*::]*/: {
    /* n:"BrtBeginPCDSDTCEMembers", */T: 1
  },
  /*::[*/0x00E8 /*::]*/: {
    /* n:"BrtEndPCDSDTCEMembers", */T: -1
  },
  /*::[*/0x00E9 /*::]*/: {
    /* n:"BrtBeginPCDSDTCEMember", */T: 1
  },
  /*::[*/0x00EA /*::]*/: {
    /* n:"BrtEndPCDSDTCEMember", */T: -1
  },
  /*::[*/0x00EB /*::]*/: {
    /* n:"BrtBeginPCDSDTCQueries", */T: 1
  },
  /*::[*/0x00EC /*::]*/: {
    /* n:"BrtEndPCDSDTCQueries", */T: -1
  },
  /*::[*/0x00ED /*::]*/: {
    /* n:"BrtBeginPCDSDTCQuery", */T: 1
  },
  /*::[*/0x00EE /*::]*/: {
    /* n:"BrtEndPCDSDTCQuery", */T: -1
  },
  /*::[*/0x00EF /*::]*/: {
    /* n:"BrtBeginPCDSDTCSets", */T: 1
  },
  /*::[*/0x00F0 /*::]*/: {
    /* n:"BrtEndPCDSDTCSets", */T: -1
  },
  /*::[*/0x00F1 /*::]*/: {
    /* n:"BrtBeginPCDSDTCSet", */T: 1
  },
  /*::[*/0x00F2 /*::]*/: {
    /* n:"BrtEndPCDSDTCSet", */T: -1
  },
  /*::[*/0x00F3 /*::]*/: {
    /* n:"BrtBeginPCDCalcItems", */T: 1
  },
  /*::[*/0x00F4 /*::]*/: {
    /* n:"BrtEndPCDCalcItems", */T: -1
  },
  /*::[*/0x00F5 /*::]*/: {
    /* n:"BrtBeginPCDCalcItem", */T: 1
  },
  /*::[*/0x00F6 /*::]*/: {
    /* n:"BrtEndPCDCalcItem", */T: -1
  },
  /*::[*/0x00F7 /*::]*/: {
    /* n:"BrtBeginPRule", */T: 1
  },
  /*::[*/0x00F8 /*::]*/: {
    /* n:"BrtEndPRule", */T: -1
  },
  /*::[*/0x00F9 /*::]*/: {
    /* n:"BrtBeginPRFilters", */T: 1
  },
  /*::[*/0x00FA /*::]*/: {
    /* n:"BrtEndPRFilters", */T: -1
  },
  /*::[*/0x00FB /*::]*/: {
    /* n:"BrtBeginPRFilter", */T: 1
  },
  /*::[*/0x00FC /*::]*/: {
    /* n:"BrtEndPRFilter", */T: -1
  },
  /*::[*/0x00FD /*::]*/: {
    /* n:"BrtBeginPNames", */T: 1
  },
  /*::[*/0x00FE /*::]*/: {
    /* n:"BrtEndPNames", */T: -1
  },
  /*::[*/0x00FF /*::]*/: {
    /* n:"BrtBeginPName", */T: 1
  },
  /*::[*/0x0100 /*::]*/: {
    /* n:"BrtEndPName", */T: -1
  },
  /*::[*/0x0101 /*::]*/: {
    /* n:"BrtBeginPNPairs", */T: 1
  },
  /*::[*/0x0102 /*::]*/: {
    /* n:"BrtEndPNPairs", */T: -1
  },
  /*::[*/0x0103 /*::]*/: {
    /* n:"BrtBeginPNPair", */T: 1
  },
  /*::[*/0x0104 /*::]*/: {
    /* n:"BrtEndPNPair", */T: -1
  },
  /*::[*/0x0105 /*::]*/: {
    /* n:"BrtBeginECWebProps", */T: 1
  },
  /*::[*/0x0106 /*::]*/: {
    /* n:"BrtEndECWebProps", */T: -1
  },
  /*::[*/0x0107 /*::]*/: {
    /* n:"BrtBeginEcWpTables", */T: 1
  },
  /*::[*/0x0108 /*::]*/: {
    /* n:"BrtEndECWPTables", */T: -1
  },
  /*::[*/0x0109 /*::]*/: {
    /* n:"BrtBeginECParams", */T: 1
  },
  /*::[*/0x010A /*::]*/: {
    /* n:"BrtEndECParams", */T: -1
  },
  /*::[*/0x010B /*::]*/: {
    /* n:"BrtBeginECParam", */T: 1
  },
  /*::[*/0x010C /*::]*/: {
    /* n:"BrtEndECParam", */T: -1
  },
  /*::[*/0x010D /*::]*/: {
    /* n:"BrtBeginPCDKPIs", */T: 1
  },
  /*::[*/0x010E /*::]*/: {
    /* n:"BrtEndPCDKPIs", */T: -1
  },
  /*::[*/0x010F /*::]*/: {
    /* n:"BrtBeginPCDKPI", */T: 1
  },
  /*::[*/0x0110 /*::]*/: {
    /* n:"BrtEndPCDKPI", */T: -1
  },
  /*::[*/0x0111 /*::]*/: {
    /* n:"BrtBeginDims", */T: 1
  },
  /*::[*/0x0112 /*::]*/: {
    /* n:"BrtEndDims", */T: -1
  },
  /*::[*/0x0113 /*::]*/: {
    /* n:"BrtBeginDim", */T: 1
  },
  /*::[*/0x0114 /*::]*/: {
    /* n:"BrtEndDim", */T: -1
  },
  /*::[*/0x0115 /*::]*/: {/* n:"BrtIndexPartEnd" */},
  /*::[*/0x0116 /*::]*/: {
    /* n:"BrtBeginStyleSheet", */T: 1
  },
  /*::[*/0x0117 /*::]*/: {
    /* n:"BrtEndStyleSheet", */T: -1
  },
  /*::[*/0x0118 /*::]*/: {
    /* n:"BrtBeginSXView", */T: 1
  },
  /*::[*/0x0119 /*::]*/: {
    /* n:"BrtEndSXVI", */T: -1
  },
  /*::[*/0x011A /*::]*/: {
    /* n:"BrtBeginSXVI", */T: 1
  },
  /*::[*/0x011B /*::]*/: {
    /* n:"BrtBeginSXVIs", */T: 1
  },
  /*::[*/0x011C /*::]*/: {
    /* n:"BrtEndSXVIs", */T: -1
  },
  /*::[*/0x011D /*::]*/: {
    /* n:"BrtBeginSXVD", */T: 1
  },
  /*::[*/0x011E /*::]*/: {
    /* n:"BrtEndSXVD", */T: -1
  },
  /*::[*/0x011F /*::]*/: {
    /* n:"BrtBeginSXVDs", */T: 1
  },
  /*::[*/0x0120 /*::]*/: {
    /* n:"BrtEndSXVDs", */T: -1
  },
  /*::[*/0x0121 /*::]*/: {
    /* n:"BrtBeginSXPI", */T: 1
  },
  /*::[*/0x0122 /*::]*/: {
    /* n:"BrtEndSXPI", */T: -1
  },
  /*::[*/0x0123 /*::]*/: {
    /* n:"BrtBeginSXPIs", */T: 1
  },
  /*::[*/0x0124 /*::]*/: {
    /* n:"BrtEndSXPIs", */T: -1
  },
  /*::[*/0x0125 /*::]*/: {
    /* n:"BrtBeginSXDI", */T: 1
  },
  /*::[*/0x0126 /*::]*/: {
    /* n:"BrtEndSXDI", */T: -1
  },
  /*::[*/0x0127 /*::]*/: {
    /* n:"BrtBeginSXDIs", */T: 1
  },
  /*::[*/0x0128 /*::]*/: {
    /* n:"BrtEndSXDIs", */T: -1
  },
  /*::[*/0x0129 /*::]*/: {
    /* n:"BrtBeginSXLI", */T: 1
  },
  /*::[*/0x012A /*::]*/: {
    /* n:"BrtEndSXLI", */T: -1
  },
  /*::[*/0x012B /*::]*/: {
    /* n:"BrtBeginSXLIRws", */T: 1
  },
  /*::[*/0x012C /*::]*/: {
    /* n:"BrtEndSXLIRws", */T: -1
  },
  /*::[*/0x012D /*::]*/: {
    /* n:"BrtBeginSXLICols", */T: 1
  },
  /*::[*/0x012E /*::]*/: {
    /* n:"BrtEndSXLICols", */T: -1
  },
  /*::[*/0x012F /*::]*/: {
    /* n:"BrtBeginSXFormat", */T: 1
  },
  /*::[*/0x0130 /*::]*/: {
    /* n:"BrtEndSXFormat", */T: -1
  },
  /*::[*/0x0131 /*::]*/: {
    /* n:"BrtBeginSXFormats", */T: 1
  },
  /*::[*/0x0132 /*::]*/: {
    /* n:"BrtEndSxFormats", */T: -1
  },
  /*::[*/0x0133 /*::]*/: {
    /* n:"BrtBeginSxSelect", */T: 1
  },
  /*::[*/0x0134 /*::]*/: {
    /* n:"BrtEndSxSelect", */T: -1
  },
  /*::[*/0x0135 /*::]*/: {
    /* n:"BrtBeginISXVDRws", */T: 1
  },
  /*::[*/0x0136 /*::]*/: {
    /* n:"BrtEndISXVDRws", */T: -1
  },
  /*::[*/0x0137 /*::]*/: {
    /* n:"BrtBeginISXVDCols", */T: 1
  },
  /*::[*/0x0138 /*::]*/: {
    /* n:"BrtEndISXVDCols", */T: -1
  },
  /*::[*/0x0139 /*::]*/: {
    /* n:"BrtEndSXLocation", */T: -1
  },
  /*::[*/0x013A /*::]*/: {
    /* n:"BrtBeginSXLocation", */T: 1
  },
  /*::[*/0x013B /*::]*/: {
    /* n:"BrtEndSXView", */T: -1
  },
  /*::[*/0x013C /*::]*/: {
    /* n:"BrtBeginSXTHs", */T: 1
  },
  /*::[*/0x013D /*::]*/: {
    /* n:"BrtEndSXTHs", */T: -1
  },
  /*::[*/0x013E /*::]*/: {
    /* n:"BrtBeginSXTH", */T: 1
  },
  /*::[*/0x013F /*::]*/: {
    /* n:"BrtEndSXTH", */T: -1
  },
  /*::[*/0x0140 /*::]*/: {
    /* n:"BrtBeginISXTHRws", */T: 1
  },
  /*::[*/0x0141 /*::]*/: {
    /* n:"BrtEndISXTHRws", */T: -1
  },
  /*::[*/0x0142 /*::]*/: {
    /* n:"BrtBeginISXTHCols", */T: 1
  },
  /*::[*/0x0143 /*::]*/: {
    /* n:"BrtEndISXTHCols", */T: -1
  },
  /*::[*/0x0144 /*::]*/: {
    /* n:"BrtBeginSXTDMPS", */T: 1
  },
  /*::[*/0x0145 /*::]*/: {
    /* n:"BrtEndSXTDMPs", */T: -1
  },
  /*::[*/0x0146 /*::]*/: {
    /* n:"BrtBeginSXTDMP", */T: 1
  },
  /*::[*/0x0147 /*::]*/: {
    /* n:"BrtEndSXTDMP", */T: -1
  },
  /*::[*/0x0148 /*::]*/: {
    /* n:"BrtBeginSXTHItems", */T: 1
  },
  /*::[*/0x0149 /*::]*/: {
    /* n:"BrtEndSXTHItems", */T: -1
  },
  /*::[*/0x014A /*::]*/: {
    /* n:"BrtBeginSXTHItem", */T: 1
  },
  /*::[*/0x014B /*::]*/: {
    /* n:"BrtEndSXTHItem", */T: -1
  },
  /*::[*/0x014C /*::]*/: {
    /* n:"BrtBeginMetadata", */T: 1
  },
  /*::[*/0x014D /*::]*/: {
    /* n:"BrtEndMetadata", */T: -1
  },
  /*::[*/0x014E /*::]*/: {
    /* n:"BrtBeginEsmdtinfo", */T: 1
  },
  /*::[*/0x014F /*::]*/: {
    /* n:"BrtMdtinfo", */f: parse_BrtMdtinfo
  },
  /*::[*/0x0150 /*::]*/: {
    /* n:"BrtEndEsmdtinfo", */T: -1
  },
  /*::[*/0x0151 /*::]*/: {
    /* n:"BrtBeginEsmdb", */f: parse_BrtBeginEsmdb,
    T: 1
  },
  /*::[*/0x0152 /*::]*/: {
    /* n:"BrtEndEsmdb", */T: -1
  },
  /*::[*/0x0153 /*::]*/: {
    /* n:"BrtBeginEsfmd", */T: 1
  },
  /*::[*/0x0154 /*::]*/: {
    /* n:"BrtEndEsfmd", */T: -1
  },
  /*::[*/0x0155 /*::]*/: {
    /* n:"BrtBeginSingleCells", */T: 1
  },
  /*::[*/0x0156 /*::]*/: {
    /* n:"BrtEndSingleCells", */T: -1
  },
  /*::[*/0x0157 /*::]*/: {
    /* n:"BrtBeginList", */T: 1
  },
  /*::[*/0x0158 /*::]*/: {
    /* n:"BrtEndList", */T: -1
  },
  /*::[*/0x0159 /*::]*/: {
    /* n:"BrtBeginListCols", */T: 1
  },
  /*::[*/0x015A /*::]*/: {
    /* n:"BrtEndListCols", */T: -1
  },
  /*::[*/0x015B /*::]*/: {
    /* n:"BrtBeginListCol", */T: 1
  },
  /*::[*/0x015C /*::]*/: {
    /* n:"BrtEndListCol", */T: -1
  },
  /*::[*/0x015D /*::]*/: {
    /* n:"BrtBeginListXmlCPr", */T: 1
  },
  /*::[*/0x015E /*::]*/: {
    /* n:"BrtEndListXmlCPr", */T: -1
  },
  /*::[*/0x015F /*::]*/: {/* n:"BrtListCCFmla" */},
  /*::[*/0x0160 /*::]*/: {/* n:"BrtListTrFmla" */},
  /*::[*/0x0161 /*::]*/: {
    /* n:"BrtBeginExternals", */T: 1
  },
  /*::[*/0x0162 /*::]*/: {
    /* n:"BrtEndExternals", */T: -1
  },
  /*::[*/0x0163 /*::]*/: {
    /* n:"BrtSupBookSrc", */f: parse_RelID
  },
  /*::[*/0x0165 /*::]*/: {/* n:"BrtSupSelf" */},
  /*::[*/0x0166 /*::]*/: {/* n:"BrtSupSame" */},
  /*::[*/0x0167 /*::]*/: {/* n:"BrtSupTabs" */},
  /*::[*/0x0168 /*::]*/: {
    /* n:"BrtBeginSupBook", */T: 1
  },
  /*::[*/0x0169 /*::]*/: {/* n:"BrtPlaceholderName" */},
  /*::[*/0x016A /*::]*/: {
    /* n:"BrtExternSheet", */f: parse_ExternSheet
  },
  /*::[*/0x016B /*::]*/: {/* n:"BrtExternTableStart" */},
  /*::[*/0x016C /*::]*/: {/* n:"BrtExternTableEnd" */},
  /*::[*/0x016E /*::]*/: {/* n:"BrtExternRowHdr" */},
  /*::[*/0x016F /*::]*/: {/* n:"BrtExternCellBlank" */},
  /*::[*/0x0170 /*::]*/: {/* n:"BrtExternCellReal" */},
  /*::[*/0x0171 /*::]*/: {/* n:"BrtExternCellBool" */},
  /*::[*/0x0172 /*::]*/: {/* n:"BrtExternCellError" */},
  /*::[*/0x0173 /*::]*/: {/* n:"BrtExternCellString" */},
  /*::[*/0x0174 /*::]*/: {
    /* n:"BrtBeginEsmdx", */T: 1
  },
  /*::[*/0x0175 /*::]*/: {
    /* n:"BrtEndEsmdx", */T: -1
  },
  /*::[*/0x0176 /*::]*/: {
    /* n:"BrtBeginMdxSet", */T: 1
  },
  /*::[*/0x0177 /*::]*/: {
    /* n:"BrtEndMdxSet", */T: -1
  },
  /*::[*/0x0178 /*::]*/: {
    /* n:"BrtBeginMdxMbrProp", */T: 1
  },
  /*::[*/0x0179 /*::]*/: {
    /* n:"BrtEndMdxMbrProp", */T: -1
  },
  /*::[*/0x017A /*::]*/: {
    /* n:"BrtBeginMdxKPI", */T: 1
  },
  /*::[*/0x017B /*::]*/: {
    /* n:"BrtEndMdxKPI", */T: -1
  },
  /*::[*/0x017C /*::]*/: {
    /* n:"BrtBeginEsstr", */T: 1
  },
  /*::[*/0x017D /*::]*/: {
    /* n:"BrtEndEsstr", */T: -1
  },
  /*::[*/0x017E /*::]*/: {
    /* n:"BrtBeginPRFItem", */T: 1
  },
  /*::[*/0x017F /*::]*/: {
    /* n:"BrtEndPRFItem", */T: -1
  },
  /*::[*/0x0180 /*::]*/: {
    /* n:"BrtBeginPivotCacheIDs", */T: 1
  },
  /*::[*/0x0181 /*::]*/: {
    /* n:"BrtEndPivotCacheIDs", */T: -1
  },
  /*::[*/0x0182 /*::]*/: {
    /* n:"BrtBeginPivotCacheID", */T: 1
  },
  /*::[*/0x0183 /*::]*/: {
    /* n:"BrtEndPivotCacheID", */T: -1
  },
  /*::[*/0x0184 /*::]*/: {
    /* n:"BrtBeginISXVIs", */T: 1
  },
  /*::[*/0x0185 /*::]*/: {
    /* n:"BrtEndISXVIs", */T: -1
  },
  /*::[*/0x0186 /*::]*/: {
    /* n:"BrtBeginColInfos", */T: 1
  },
  /*::[*/0x0187 /*::]*/: {
    /* n:"BrtEndColInfos", */T: -1
  },
  /*::[*/0x0188 /*::]*/: {
    /* n:"BrtBeginRwBrk", */T: 1
  },
  /*::[*/0x0189 /*::]*/: {
    /* n:"BrtEndRwBrk", */T: -1
  },
  /*::[*/0x018A /*::]*/: {
    /* n:"BrtBeginColBrk", */T: 1
  },
  /*::[*/0x018B /*::]*/: {
    /* n:"BrtEndColBrk", */T: -1
  },
  /*::[*/0x018C /*::]*/: {/* n:"BrtBrk" */},
  /*::[*/0x018D /*::]*/: {/* n:"BrtUserBookView" */},
  /*::[*/0x018E /*::]*/: {/* n:"BrtInfo" */},
  /*::[*/0x018F /*::]*/: {/* n:"BrtCUsr" */},
  /*::[*/0x0190 /*::]*/: {/* n:"BrtUsr" */},
  /*::[*/0x0191 /*::]*/: {
    /* n:"BrtBeginUsers", */T: 1
  },
  /*::[*/0x0193 /*::]*/: {/* n:"BrtEOF" */},
  /*::[*/0x0194 /*::]*/: {/* n:"BrtUCR" */},
  /*::[*/0x0195 /*::]*/: {/* n:"BrtRRInsDel" */},
  /*::[*/0x0196 /*::]*/: {/* n:"BrtRREndInsDel" */},
  /*::[*/0x0197 /*::]*/: {/* n:"BrtRRMove" */},
  /*::[*/0x0198 /*::]*/: {/* n:"BrtRREndMove" */},
  /*::[*/0x0199 /*::]*/: {/* n:"BrtRRChgCell" */},
  /*::[*/0x019A /*::]*/: {/* n:"BrtRREndChgCell" */},
  /*::[*/0x019B /*::]*/: {/* n:"BrtRRHeader" */},
  /*::[*/0x019C /*::]*/: {/* n:"BrtRRUserView" */},
  /*::[*/0x019D /*::]*/: {/* n:"BrtRRRenSheet" */},
  /*::[*/0x019E /*::]*/: {/* n:"BrtRRInsertSh" */},
  /*::[*/0x019F /*::]*/: {/* n:"BrtRRDefName" */},
  /*::[*/0x01A0 /*::]*/: {/* n:"BrtRRNote" */},
  /*::[*/0x01A1 /*::]*/: {/* n:"BrtRRConflict" */},
  /*::[*/0x01A2 /*::]*/: {/* n:"BrtRRTQSIF" */},
  /*::[*/0x01A3 /*::]*/: {/* n:"BrtRRFormat" */},
  /*::[*/0x01A4 /*::]*/: {/* n:"BrtRREndFormat" */},
  /*::[*/0x01A5 /*::]*/: {/* n:"BrtRRAutoFmt" */},
  /*::[*/0x01A6 /*::]*/: {
    /* n:"BrtBeginUserShViews", */T: 1
  },
  /*::[*/0x01A7 /*::]*/: {
    /* n:"BrtBeginUserShView", */T: 1
  },
  /*::[*/0x01A8 /*::]*/: {
    /* n:"BrtEndUserShView", */T: -1
  },
  /*::[*/0x01A9 /*::]*/: {
    /* n:"BrtEndUserShViews", */T: -1
  },
  /*::[*/0x01AA /*::]*/: {
    /* n:"BrtArrFmla", */f: parse_BrtArrFmla
  },
  /*::[*/0x01AB /*::]*/: {
    /* n:"BrtShrFmla", */f: parse_BrtShrFmla
  },
  /*::[*/0x01AC /*::]*/: {/* n:"BrtTable" */},
  /*::[*/0x01AD /*::]*/: {
    /* n:"BrtBeginExtConnections", */T: 1
  },
  /*::[*/0x01AE /*::]*/: {
    /* n:"BrtEndExtConnections", */T: -1
  },
  /*::[*/0x01AF /*::]*/: {
    /* n:"BrtBeginPCDCalcMems", */T: 1
  },
  /*::[*/0x01B0 /*::]*/: {
    /* n:"BrtEndPCDCalcMems", */T: -1
  },
  /*::[*/0x01B1 /*::]*/: {
    /* n:"BrtBeginPCDCalcMem", */T: 1
  },
  /*::[*/0x01B2 /*::]*/: {
    /* n:"BrtEndPCDCalcMem", */T: -1
  },
  /*::[*/0x01B3 /*::]*/: {
    /* n:"BrtBeginPCDHGLevels", */T: 1
  },
  /*::[*/0x01B4 /*::]*/: {
    /* n:"BrtEndPCDHGLevels", */T: -1
  },
  /*::[*/0x01B5 /*::]*/: {
    /* n:"BrtBeginPCDHGLevel", */T: 1
  },
  /*::[*/0x01B6 /*::]*/: {
    /* n:"BrtEndPCDHGLevel", */T: -1
  },
  /*::[*/0x01B7 /*::]*/: {
    /* n:"BrtBeginPCDHGLGroups", */T: 1
  },
  /*::[*/0x01B8 /*::]*/: {
    /* n:"BrtEndPCDHGLGroups", */T: -1
  },
  /*::[*/0x01B9 /*::]*/: {
    /* n:"BrtBeginPCDHGLGroup", */T: 1
  },
  /*::[*/0x01BA /*::]*/: {
    /* n:"BrtEndPCDHGLGroup", */T: -1
  },
  /*::[*/0x01BB /*::]*/: {
    /* n:"BrtBeginPCDHGLGMembers", */T: 1
  },
  /*::[*/0x01BC /*::]*/: {
    /* n:"BrtEndPCDHGLGMembers", */T: -1
  },
  /*::[*/0x01BD /*::]*/: {
    /* n:"BrtBeginPCDHGLGMember", */T: 1
  },
  /*::[*/0x01BE /*::]*/: {
    /* n:"BrtEndPCDHGLGMember", */T: -1
  },
  /*::[*/0x01BF /*::]*/: {
    /* n:"BrtBeginQSI", */T: 1
  },
  /*::[*/0x01C0 /*::]*/: {
    /* n:"BrtEndQSI", */T: -1
  },
  /*::[*/0x01C1 /*::]*/: {
    /* n:"BrtBeginQSIR", */T: 1
  },
  /*::[*/0x01C2 /*::]*/: {
    /* n:"BrtEndQSIR", */T: -1
  },
  /*::[*/0x01C3 /*::]*/: {
    /* n:"BrtBeginDeletedNames", */T: 1
  },
  /*::[*/0x01C4 /*::]*/: {
    /* n:"BrtEndDeletedNames", */T: -1
  },
  /*::[*/0x01C5 /*::]*/: {
    /* n:"BrtBeginDeletedName", */T: 1
  },
  /*::[*/0x01C6 /*::]*/: {
    /* n:"BrtEndDeletedName", */T: -1
  },
  /*::[*/0x01C7 /*::]*/: {
    /* n:"BrtBeginQSIFs", */T: 1
  },
  /*::[*/0x01C8 /*::]*/: {
    /* n:"BrtEndQSIFs", */T: -1
  },
  /*::[*/0x01C9 /*::]*/: {
    /* n:"BrtBeginQSIF", */T: 1
  },
  /*::[*/0x01CA /*::]*/: {
    /* n:"BrtEndQSIF", */T: -1
  },
  /*::[*/0x01CB /*::]*/: {
    /* n:"BrtBeginAutoSortScope", */T: 1
  },
  /*::[*/0x01CC /*::]*/: {
    /* n:"BrtEndAutoSortScope", */T: -1
  },
  /*::[*/0x01CD /*::]*/: {
    /* n:"BrtBeginConditionalFormatting", */T: 1
  },
  /*::[*/0x01CE /*::]*/: {
    /* n:"BrtEndConditionalFormatting", */T: -1
  },
  /*::[*/0x01CF /*::]*/: {
    /* n:"BrtBeginCFRule", */T: 1
  },
  /*::[*/0x01D0 /*::]*/: {
    /* n:"BrtEndCFRule", */T: -1
  },
  /*::[*/0x01D1 /*::]*/: {
    /* n:"BrtBeginIconSet", */T: 1
  },
  /*::[*/0x01D2 /*::]*/: {
    /* n:"BrtEndIconSet", */T: -1
  },
  /*::[*/0x01D3 /*::]*/: {
    /* n:"BrtBeginDatabar", */T: 1
  },
  /*::[*/0x01D4 /*::]*/: {
    /* n:"BrtEndDatabar", */T: -1
  },
  /*::[*/0x01D5 /*::]*/: {
    /* n:"BrtBeginColorScale", */T: 1
  },
  /*::[*/0x01D6 /*::]*/: {
    /* n:"BrtEndColorScale", */T: -1
  },
  /*::[*/0x01D7 /*::]*/: {/* n:"BrtCFVO" */},
  /*::[*/0x01D8 /*::]*/: {/* n:"BrtExternValueMeta" */},
  /*::[*/0x01D9 /*::]*/: {
    /* n:"BrtBeginColorPalette", */T: 1
  },
  /*::[*/0x01DA /*::]*/: {
    /* n:"BrtEndColorPalette", */T: -1
  },
  /*::[*/0x01DB /*::]*/: {/* n:"BrtIndexedColor" */},
  /*::[*/0x01DC /*::]*/: {
    /* n:"BrtMargins", */f: parse_BrtMargins
  },
  /*::[*/0x01DD /*::]*/: {/* n:"BrtPrintOptions" */},
  /*::[*/0x01DE /*::]*/: {/* n:"BrtPageSetup" */},
  /*::[*/0x01DF /*::]*/: {
    /* n:"BrtBeginHeaderFooter", */T: 1
  },
  /*::[*/0x01E0 /*::]*/: {
    /* n:"BrtEndHeaderFooter", */T: -1
  },
  /*::[*/0x01E1 /*::]*/: {
    /* n:"BrtBeginSXCrtFormat", */T: 1
  },
  /*::[*/0x01E2 /*::]*/: {
    /* n:"BrtEndSXCrtFormat", */T: -1
  },
  /*::[*/0x01E3 /*::]*/: {
    /* n:"BrtBeginSXCrtFormats", */T: 1
  },
  /*::[*/0x01E4 /*::]*/: {
    /* n:"BrtEndSXCrtFormats", */T: -1
  },
  /*::[*/0x01E5 /*::]*/: {
    /* n:"BrtWsFmtInfo", */f: parse_BrtWsFmtInfo
  },
  /*::[*/0x01E6 /*::]*/: {
    /* n:"BrtBeginMgs", */T: 1
  },
  /*::[*/0x01E7 /*::]*/: {
    /* n:"BrtEndMGs", */T: -1
  },
  /*::[*/0x01E8 /*::]*/: {
    /* n:"BrtBeginMGMaps", */T: 1
  },
  /*::[*/0x01E9 /*::]*/: {
    /* n:"BrtEndMGMaps", */T: -1
  },
  /*::[*/0x01EA /*::]*/: {
    /* n:"BrtBeginMG", */T: 1
  },
  /*::[*/0x01EB /*::]*/: {
    /* n:"BrtEndMG", */T: -1
  },
  /*::[*/0x01EC /*::]*/: {
    /* n:"BrtBeginMap", */T: 1
  },
  /*::[*/0x01ED /*::]*/: {
    /* n:"BrtEndMap", */T: -1
  },
  /*::[*/0x01EE /*::]*/: {
    /* n:"BrtHLink", */f: parse_BrtHLink
  },
  /*::[*/0x01EF /*::]*/: {
    /* n:"BrtBeginDCon", */T: 1
  },
  /*::[*/0x01F0 /*::]*/: {
    /* n:"BrtEndDCon", */T: -1
  },
  /*::[*/0x01F1 /*::]*/: {
    /* n:"BrtBeginDRefs", */T: 1
  },
  /*::[*/0x01F2 /*::]*/: {
    /* n:"BrtEndDRefs", */T: -1
  },
  /*::[*/0x01F3 /*::]*/: {/* n:"BrtDRef" */},
  /*::[*/0x01F4 /*::]*/: {
    /* n:"BrtBeginScenMan", */T: 1
  },
  /*::[*/0x01F5 /*::]*/: {
    /* n:"BrtEndScenMan", */T: -1
  },
  /*::[*/0x01F6 /*::]*/: {
    /* n:"BrtBeginSct", */T: 1
  },
  /*::[*/0x01F7 /*::]*/: {
    /* n:"BrtEndSct", */T: -1
  },
  /*::[*/0x01F8 /*::]*/: {/* n:"BrtSlc" */},
  /*::[*/0x01F9 /*::]*/: {
    /* n:"BrtBeginDXFs", */T: 1
  },
  /*::[*/0x01FA /*::]*/: {
    /* n:"BrtEndDXFs", */T: -1
  },
  /*::[*/0x01FB /*::]*/: {/* n:"BrtDXF" */},
  /*::[*/0x01FC /*::]*/: {
    /* n:"BrtBeginTableStyles", */T: 1
  },
  /*::[*/0x01FD /*::]*/: {
    /* n:"BrtEndTableStyles", */T: -1
  },
  /*::[*/0x01FE /*::]*/: {
    /* n:"BrtBeginTableStyle", */T: 1
  },
  /*::[*/0x01FF /*::]*/: {
    /* n:"BrtEndTableStyle", */T: -1
  },
  /*::[*/0x0200 /*::]*/: {/* n:"BrtTableStyleElement" */},
  /*::[*/0x0201 /*::]*/: {/* n:"BrtTableStyleClient" */},
  /*::[*/0x0202 /*::]*/: {
    /* n:"BrtBeginVolDeps", */T: 1
  },
  /*::[*/0x0203 /*::]*/: {
    /* n:"BrtEndVolDeps", */T: -1
  },
  /*::[*/0x0204 /*::]*/: {
    /* n:"BrtBeginVolType", */T: 1
  },
  /*::[*/0x0205 /*::]*/: {
    /* n:"BrtEndVolType", */T: -1
  },
  /*::[*/0x0206 /*::]*/: {
    /* n:"BrtBeginVolMain", */T: 1
  },
  /*::[*/0x0207 /*::]*/: {
    /* n:"BrtEndVolMain", */T: -1
  },
  /*::[*/0x0208 /*::]*/: {
    /* n:"BrtBeginVolTopic", */T: 1
  },
  /*::[*/0x0209 /*::]*/: {
    /* n:"BrtEndVolTopic", */T: -1
  },
  /*::[*/0x020A /*::]*/: {/* n:"BrtVolSubtopic" */},
  /*::[*/0x020B /*::]*/: {/* n:"BrtVolRef" */},
  /*::[*/0x020C /*::]*/: {/* n:"BrtVolNum" */},
  /*::[*/0x020D /*::]*/: {/* n:"BrtVolErr" */},
  /*::[*/0x020E /*::]*/: {/* n:"BrtVolStr" */},
  /*::[*/0x020F /*::]*/: {/* n:"BrtVolBool" */},
  /*::[*/0x0210 /*::]*/: {
    /* n:"BrtBeginCalcChain$", */T: 1
  },
  /*::[*/0x0211 /*::]*/: {
    /* n:"BrtEndCalcChain$", */T: -1
  },
  /*::[*/0x0212 /*::]*/: {
    /* n:"BrtBeginSortState", */T: 1
  },
  /*::[*/0x0213 /*::]*/: {
    /* n:"BrtEndSortState", */T: -1
  },
  /*::[*/0x0214 /*::]*/: {
    /* n:"BrtBeginSortCond", */T: 1
  },
  /*::[*/0x0215 /*::]*/: {
    /* n:"BrtEndSortCond", */T: -1
  },
  /*::[*/0x0216 /*::]*/: {/* n:"BrtBookProtection" */},
  /*::[*/0x0217 /*::]*/: {/* n:"BrtSheetProtection" */},
  /*::[*/0x0218 /*::]*/: {/* n:"BrtRangeProtection" */},
  /*::[*/0x0219 /*::]*/: {/* n:"BrtPhoneticInfo" */},
  /*::[*/0x021A /*::]*/: {
    /* n:"BrtBeginECTxtWiz", */T: 1
  },
  /*::[*/0x021B /*::]*/: {
    /* n:"BrtEndECTxtWiz", */T: -1
  },
  /*::[*/0x021C /*::]*/: {
    /* n:"BrtBeginECTWFldInfoLst", */T: 1
  },
  /*::[*/0x021D /*::]*/: {
    /* n:"BrtEndECTWFldInfoLst", */T: -1
  },
  /*::[*/0x021E /*::]*/: {
    /* n:"BrtBeginECTwFldInfo", */T: 1
  },
  /*::[*/0x0224 /*::]*/: {/* n:"BrtFileSharing" */},
  /*::[*/0x0225 /*::]*/: {/* n:"BrtOleSize" */},
  /*::[*/0x0226 /*::]*/: {
    /* n:"BrtDrawing", */f: parse_RelID
  },
  /*::[*/0x0227 /*::]*/: {/* n:"BrtLegacyDrawing" */},
  /*::[*/0x0228 /*::]*/: {/* n:"BrtLegacyDrawingHF" */},
  /*::[*/0x0229 /*::]*/: {/* n:"BrtWebOpt" */},
  /*::[*/0x022A /*::]*/: {
    /* n:"BrtBeginWebPubItems", */T: 1
  },
  /*::[*/0x022B /*::]*/: {
    /* n:"BrtEndWebPubItems", */T: -1
  },
  /*::[*/0x022C /*::]*/: {
    /* n:"BrtBeginWebPubItem", */T: 1
  },
  /*::[*/0x022D /*::]*/: {
    /* n:"BrtEndWebPubItem", */T: -1
  },
  /*::[*/0x022E /*::]*/: {
    /* n:"BrtBeginSXCondFmt", */T: 1
  },
  /*::[*/0x022F /*::]*/: {
    /* n:"BrtEndSXCondFmt", */T: -1
  },
  /*::[*/0x0230 /*::]*/: {
    /* n:"BrtBeginSXCondFmts", */T: 1
  },
  /*::[*/0x0231 /*::]*/: {
    /* n:"BrtEndSXCondFmts", */T: -1
  },
  /*::[*/0x0232 /*::]*/: {/* n:"BrtBkHim" */},
  /*::[*/0x0234 /*::]*/: {/* n:"BrtColor" */},
  /*::[*/0x0235 /*::]*/: {
    /* n:"BrtBeginIndexedColors", */T: 1
  },
  /*::[*/0x0236 /*::]*/: {
    /* n:"BrtEndIndexedColors", */T: -1
  },
  /*::[*/0x0239 /*::]*/: {
    /* n:"BrtBeginMRUColors", */T: 1
  },
  /*::[*/0x023A /*::]*/: {
    /* n:"BrtEndMRUColors", */T: -1
  },
  /*::[*/0x023C /*::]*/: {/* n:"BrtMRUColor" */},
  /*::[*/0x023D /*::]*/: {
    /* n:"BrtBeginDVals", */T: 1
  },
  /*::[*/0x023E /*::]*/: {
    /* n:"BrtEndDVals", */T: -1
  },
  /*::[*/0x0241 /*::]*/: {/* n:"BrtSupNameStart" */},
  /*::[*/0x0242 /*::]*/: {/* n:"BrtSupNameValueStart" */},
  /*::[*/0x0243 /*::]*/: {/* n:"BrtSupNameValueEnd" */},
  /*::[*/0x0244 /*::]*/: {/* n:"BrtSupNameNum" */},
  /*::[*/0x0245 /*::]*/: {/* n:"BrtSupNameErr" */},
  /*::[*/0x0246 /*::]*/: {/* n:"BrtSupNameSt" */},
  /*::[*/0x0247 /*::]*/: {/* n:"BrtSupNameNil" */},
  /*::[*/0x0248 /*::]*/: {/* n:"BrtSupNameBool" */},
  /*::[*/0x0249 /*::]*/: {/* n:"BrtSupNameFmla" */},
  /*::[*/0x024A /*::]*/: {/* n:"BrtSupNameBits" */},
  /*::[*/0x024B /*::]*/: {/* n:"BrtSupNameEnd" */},
  /*::[*/0x024C /*::]*/: {
    /* n:"BrtEndSupBook", */T: -1
  },
  /*::[*/0x024D /*::]*/: {/* n:"BrtCellSmartTagProperty" */},
  /*::[*/0x024E /*::]*/: {
    /* n:"BrtBeginCellSmartTag", */T: 1
  },
  /*::[*/0x024F /*::]*/: {
    /* n:"BrtEndCellSmartTag", */T: -1
  },
  /*::[*/0x0250 /*::]*/: {
    /* n:"BrtBeginCellSmartTags", */T: 1
  },
  /*::[*/0x0251 /*::]*/: {
    /* n:"BrtEndCellSmartTags", */T: -1
  },
  /*::[*/0x0252 /*::]*/: {
    /* n:"BrtBeginSmartTags", */T: 1
  },
  /*::[*/0x0253 /*::]*/: {
    /* n:"BrtEndSmartTags", */T: -1
  },
  /*::[*/0x0254 /*::]*/: {/* n:"BrtSmartTagType" */},
  /*::[*/0x0255 /*::]*/: {
    /* n:"BrtBeginSmartTagTypes", */T: 1
  },
  /*::[*/0x0256 /*::]*/: {
    /* n:"BrtEndSmartTagTypes", */T: -1
  },
  /*::[*/0x0257 /*::]*/: {
    /* n:"BrtBeginSXFilters", */T: 1
  },
  /*::[*/0x0258 /*::]*/: {
    /* n:"BrtEndSXFilters", */T: -1
  },
  /*::[*/0x0259 /*::]*/: {
    /* n:"BrtBeginSXFILTER", */T: 1
  },
  /*::[*/0x025A /*::]*/: {
    /* n:"BrtEndSXFilter", */T: -1
  },
  /*::[*/0x025B /*::]*/: {
    /* n:"BrtBeginFills", */T: 1
  },
  /*::[*/0x025C /*::]*/: {
    /* n:"BrtEndFills", */T: -1
  },
  /*::[*/0x025D /*::]*/: {
    /* n:"BrtBeginCellWatches", */T: 1
  },
  /*::[*/0x025E /*::]*/: {
    /* n:"BrtEndCellWatches", */T: -1
  },
  /*::[*/0x025F /*::]*/: {/* n:"BrtCellWatch" */},
  /*::[*/0x0260 /*::]*/: {
    /* n:"BrtBeginCRErrs", */T: 1
  },
  /*::[*/0x0261 /*::]*/: {
    /* n:"BrtEndCRErrs", */T: -1
  },
  /*::[*/0x0262 /*::]*/: {/* n:"BrtCrashRecErr" */},
  /*::[*/0x0263 /*::]*/: {
    /* n:"BrtBeginFonts", */T: 1
  },
  /*::[*/0x0264 /*::]*/: {
    /* n:"BrtEndFonts", */T: -1
  },
  /*::[*/0x0265 /*::]*/: {
    /* n:"BrtBeginBorders", */T: 1
  },
  /*::[*/0x0266 /*::]*/: {
    /* n:"BrtEndBorders", */T: -1
  },
  /*::[*/0x0267 /*::]*/: {
    /* n:"BrtBeginFmts", */T: 1
  },
  /*::[*/0x0268 /*::]*/: {
    /* n:"BrtEndFmts", */T: -1
  },
  /*::[*/0x0269 /*::]*/: {
    /* n:"BrtBeginCellXFs", */T: 1
  },
  /*::[*/0x026A /*::]*/: {
    /* n:"BrtEndCellXFs", */T: -1
  },
  /*::[*/0x026B /*::]*/: {
    /* n:"BrtBeginStyles", */T: 1
  },
  /*::[*/0x026C /*::]*/: {
    /* n:"BrtEndStyles", */T: -1
  },
  /*::[*/0x0271 /*::]*/: {/* n:"BrtBigName" */},
  /*::[*/0x0272 /*::]*/: {
    /* n:"BrtBeginCellStyleXFs", */T: 1
  },
  /*::[*/0x0273 /*::]*/: {
    /* n:"BrtEndCellStyleXFs", */T: -1
  },
  /*::[*/0x0274 /*::]*/: {
    /* n:"BrtBeginComments", */T: 1
  },
  /*::[*/0x0275 /*::]*/: {
    /* n:"BrtEndComments", */T: -1
  },
  /*::[*/0x0276 /*::]*/: {
    /* n:"BrtBeginCommentAuthors", */T: 1
  },
  /*::[*/0x0277 /*::]*/: {
    /* n:"BrtEndCommentAuthors", */T: -1
  },
  /*::[*/0x0278 /*::]*/: {
    /* n:"BrtCommentAuthor", */f: parse_BrtCommentAuthor
  },
  /*::[*/0x0279 /*::]*/: {
    /* n:"BrtBeginCommentList", */T: 1
  },
  /*::[*/0x027A /*::]*/: {
    /* n:"BrtEndCommentList", */T: -1
  },
  /*::[*/0x027B /*::]*/: {
    /* n:"BrtBeginComment", */T: 1,
    f: parse_BrtBeginComment
  },
  /*::[*/0x027C /*::]*/: {
    /* n:"BrtEndComment", */T: -1
  },
  /*::[*/0x027D /*::]*/: {
    /* n:"BrtCommentText", */f: parse_BrtCommentText
  },
  /*::[*/0x027E /*::]*/: {
    /* n:"BrtBeginOleObjects", */T: 1
  },
  /*::[*/0x027F /*::]*/: {/* n:"BrtOleObject" */},
  /*::[*/0x0280 /*::]*/: {
    /* n:"BrtEndOleObjects", */T: -1
  },
  /*::[*/0x0281 /*::]*/: {
    /* n:"BrtBeginSxrules", */T: 1
  },
  /*::[*/0x0282 /*::]*/: {
    /* n:"BrtEndSxRules", */T: -1
  },
  /*::[*/0x0283 /*::]*/: {
    /* n:"BrtBeginActiveXControls", */T: 1
  },
  /*::[*/0x0284 /*::]*/: {/* n:"BrtActiveX" */},
  /*::[*/0x0285 /*::]*/: {
    /* n:"BrtEndActiveXControls", */T: -1
  },
  /*::[*/0x0286 /*::]*/: {
    /* n:"BrtBeginPCDSDTCEMembersSortBy", */T: 1
  },
  /*::[*/0x0288 /*::]*/: {
    /* n:"BrtBeginCellIgnoreECs", */T: 1
  },
  /*::[*/0x0289 /*::]*/: {/* n:"BrtCellIgnoreEC" */},
  /*::[*/0x028A /*::]*/: {
    /* n:"BrtEndCellIgnoreECs", */T: -1
  },
  /*::[*/0x028B /*::]*/: {
    /* n:"BrtCsProp", */f: parse_BrtCsProp
  },
  /*::[*/0x028C /*::]*/: {/* n:"BrtCsPageSetup" */},
  /*::[*/0x028D /*::]*/: {
    /* n:"BrtBeginUserCsViews", */T: 1
  },
  /*::[*/0x028E /*::]*/: {
    /* n:"BrtEndUserCsViews", */T: -1
  },
  /*::[*/0x028F /*::]*/: {
    /* n:"BrtBeginUserCsView", */T: 1
  },
  /*::[*/0x0290 /*::]*/: {
    /* n:"BrtEndUserCsView", */T: -1
  },
  /*::[*/0x0291 /*::]*/: {
    /* n:"BrtBeginPcdSFCIEntries", */T: 1
  },
  /*::[*/0x0292 /*::]*/: {
    /* n:"BrtEndPCDSFCIEntries", */T: -1
  },
  /*::[*/0x0293 /*::]*/: {/* n:"BrtPCDSFCIEntry" */},
  /*::[*/0x0294 /*::]*/: {
    /* n:"BrtBeginListParts", */T: 1
  },
  /*::[*/0x0295 /*::]*/: {/* n:"BrtListPart" */},
  /*::[*/0x0296 /*::]*/: {
    /* n:"BrtEndListParts", */T: -1
  },
  /*::[*/0x0297 /*::]*/: {/* n:"BrtSheetCalcProp" */},
  /*::[*/0x0298 /*::]*/: {
    /* n:"BrtBeginFnGroup", */T: 1
  },
  /*::[*/0x0299 /*::]*/: {/* n:"BrtFnGroup" */},
  /*::[*/0x029A /*::]*/: {
    /* n:"BrtEndFnGroup", */T: -1
  },
  /*::[*/0x029B /*::]*/: {/* n:"BrtSupAddin" */},
  /*::[*/0x029C /*::]*/: {/* n:"BrtSXTDMPOrder" */},
  /*::[*/0x029D /*::]*/: {/* n:"BrtCsProtection" */},
  /*::[*/0x029F /*::]*/: {
    /* n:"BrtBeginWsSortMap", */T: 1
  },
  /*::[*/0x02A0 /*::]*/: {
    /* n:"BrtEndWsSortMap", */T: -1
  },
  /*::[*/0x02A1 /*::]*/: {
    /* n:"BrtBeginRRSort", */T: 1
  },
  /*::[*/0x02A2 /*::]*/: {
    /* n:"BrtEndRRSort", */T: -1
  },
  /*::[*/0x02A3 /*::]*/: {/* n:"BrtRRSortItem" */},
  /*::[*/0x02A4 /*::]*/: {/* n:"BrtFileSharingIso" */},
  /*::[*/0x02A5 /*::]*/: {/* n:"BrtBookProtectionIso" */},
  /*::[*/0x02A6 /*::]*/: {/* n:"BrtSheetProtectionIso" */},
  /*::[*/0x02A7 /*::]*/: {/* n:"BrtCsProtectionIso" */},
  /*::[*/0x02A8 /*::]*/: {/* n:"BrtRangeProtectionIso" */},
  /*::[*/0x02A9 /*::]*/: {/* n:"BrtDValList" */},
  /*::[*/0x0400 /*::]*/: {/* n:"BrtRwDescent" */},
  /*::[*/0x0401 /*::]*/: {/* n:"BrtKnownFonts" */},
  /*::[*/0x0402 /*::]*/: {
    /* n:"BrtBeginSXTupleSet", */T: 1
  },
  /*::[*/0x0403 /*::]*/: {
    /* n:"BrtEndSXTupleSet", */T: -1
  },
  /*::[*/0x0404 /*::]*/: {
    /* n:"BrtBeginSXTupleSetHeader", */T: 1
  },
  /*::[*/0x0405 /*::]*/: {
    /* n:"BrtEndSXTupleSetHeader", */T: -1
  },
  /*::[*/0x0406 /*::]*/: {/* n:"BrtSXTupleSetHeaderItem" */},
  /*::[*/0x0407 /*::]*/: {
    /* n:"BrtBeginSXTupleSetData", */T: 1
  },
  /*::[*/0x0408 /*::]*/: {
    /* n:"BrtEndSXTupleSetData", */T: -1
  },
  /*::[*/0x0409 /*::]*/: {
    /* n:"BrtBeginSXTupleSetRow", */T: 1
  },
  /*::[*/0x040A /*::]*/: {
    /* n:"BrtEndSXTupleSetRow", */T: -1
  },
  /*::[*/0x040B /*::]*/: {/* n:"BrtSXTupleSetRowItem" */},
  /*::[*/0x040C /*::]*/: {/* n:"BrtNameExt" */},
  /*::[*/0x040D /*::]*/: {/* n:"BrtPCDH14" */},
  /*::[*/0x040E /*::]*/: {
    /* n:"BrtBeginPCDCalcMem14", */T: 1
  },
  /*::[*/0x040F /*::]*/: {
    /* n:"BrtEndPCDCalcMem14", */T: -1
  },
  /*::[*/0x0410 /*::]*/: {/* n:"BrtSXTH14" */},
  /*::[*/0x0411 /*::]*/: {
    /* n:"BrtBeginSparklineGroup", */T: 1
  },
  /*::[*/0x0412 /*::]*/: {
    /* n:"BrtEndSparklineGroup", */T: -1
  },
  /*::[*/0x0413 /*::]*/: {/* n:"BrtSparkline" */},
  /*::[*/0x0414 /*::]*/: {/* n:"BrtSXDI14" */},
  /*::[*/0x0415 /*::]*/: {/* n:"BrtWsFmtInfoEx14" */},
  /*::[*/0x0416 /*::]*/: {
    /* n:"BrtBeginConditionalFormatting14", */T: 1
  },
  /*::[*/0x0417 /*::]*/: {
    /* n:"BrtEndConditionalFormatting14", */T: -1
  },
  /*::[*/0x0418 /*::]*/: {
    /* n:"BrtBeginCFRule14", */T: 1
  },
  /*::[*/0x0419 /*::]*/: {
    /* n:"BrtEndCFRule14", */T: -1
  },
  /*::[*/0x041A /*::]*/: {/* n:"BrtCFVO14" */},
  /*::[*/0x041B /*::]*/: {
    /* n:"BrtBeginDatabar14", */T: 1
  },
  /*::[*/0x041C /*::]*/: {
    /* n:"BrtBeginIconSet14", */T: 1
  },
  /*::[*/0x041D /*::]*/: {
    /* n:"BrtDVal14", */f: parse_BrtDVal14
  },
  /*::[*/0x041E /*::]*/: {
    /* n:"BrtBeginDVals14", */T: 1
  },
  /*::[*/0x041F /*::]*/: {/* n:"BrtColor14" */},
  /*::[*/0x0420 /*::]*/: {
    /* n:"BrtBeginSparklines", */T: 1
  },
  /*::[*/0x0421 /*::]*/: {
    /* n:"BrtEndSparklines", */T: -1
  },
  /*::[*/0x0422 /*::]*/: {
    /* n:"BrtBeginSparklineGroups", */T: 1
  },
  /*::[*/0x0423 /*::]*/: {
    /* n:"BrtEndSparklineGroups", */T: -1
  },
  /*::[*/0x0425 /*::]*/: {/* n:"BrtSXVD14" */},
  /*::[*/0x0426 /*::]*/: {
    /* n:"BrtBeginSXView14", */T: 1
  },
  /*::[*/0x0427 /*::]*/: {
    /* n:"BrtEndSXView14", */T: -1
  },
  /*::[*/0x0428 /*::]*/: {
    /* n:"BrtBeginSXView16", */T: 1
  },
  /*::[*/0x0429 /*::]*/: {
    /* n:"BrtEndSXView16", */T: -1
  },
  /*::[*/0x042A /*::]*/: {
    /* n:"BrtBeginPCD14", */T: 1
  },
  /*::[*/0x042B /*::]*/: {
    /* n:"BrtEndPCD14", */T: -1
  },
  /*::[*/0x042C /*::]*/: {
    /* n:"BrtBeginExtConn14", */T: 1
  },
  /*::[*/0x042D /*::]*/: {
    /* n:"BrtEndExtConn14", */T: -1
  },
  /*::[*/0x042E /*::]*/: {
    /* n:"BrtBeginSlicerCacheIDs", */T: 1
  },
  /*::[*/0x042F /*::]*/: {
    /* n:"BrtEndSlicerCacheIDs", */T: -1
  },
  /*::[*/0x0430 /*::]*/: {
    /* n:"BrtBeginSlicerCacheID", */T: 1
  },
  /*::[*/0x0431 /*::]*/: {
    /* n:"BrtEndSlicerCacheID", */T: -1
  },
  /*::[*/0x0433 /*::]*/: {
    /* n:"BrtBeginSlicerCache", */T: 1
  },
  /*::[*/0x0434 /*::]*/: {
    /* n:"BrtEndSlicerCache", */T: -1
  },
  /*::[*/0x0435 /*::]*/: {
    /* n:"BrtBeginSlicerCacheDef", */T: 1
  },
  /*::[*/0x0436 /*::]*/: {
    /* n:"BrtEndSlicerCacheDef", */T: -1
  },
  /*::[*/0x0437 /*::]*/: {
    /* n:"BrtBeginSlicersEx", */T: 1
  },
  /*::[*/0x0438 /*::]*/: {
    /* n:"BrtEndSlicersEx", */T: -1
  },
  /*::[*/0x0439 /*::]*/: {
    /* n:"BrtBeginSlicerEx", */T: 1
  },
  /*::[*/0x043A /*::]*/: {
    /* n:"BrtEndSlicerEx", */T: -1
  },
  /*::[*/0x043B /*::]*/: {
    /* n:"BrtBeginSlicer", */T: 1
  },
  /*::[*/0x043C /*::]*/: {
    /* n:"BrtEndSlicer", */T: -1
  },
  /*::[*/0x043D /*::]*/: {/* n:"BrtSlicerCachePivotTables" */},
  /*::[*/0x043E /*::]*/: {
    /* n:"BrtBeginSlicerCacheOlapImpl", */T: 1
  },
  /*::[*/0x043F /*::]*/: {
    /* n:"BrtEndSlicerCacheOlapImpl", */T: -1
  },
  /*::[*/0x0440 /*::]*/: {
    /* n:"BrtBeginSlicerCacheLevelsData", */T: 1
  },
  /*::[*/0x0441 /*::]*/: {
    /* n:"BrtEndSlicerCacheLevelsData", */T: -1
  },
  /*::[*/0x0442 /*::]*/: {
    /* n:"BrtBeginSlicerCacheLevelData", */T: 1
  },
  /*::[*/0x0443 /*::]*/: {
    /* n:"BrtEndSlicerCacheLevelData", */T: -1
  },
  /*::[*/0x0444 /*::]*/: {
    /* n:"BrtBeginSlicerCacheSiRanges", */T: 1
  },
  /*::[*/0x0445 /*::]*/: {
    /* n:"BrtEndSlicerCacheSiRanges", */T: -1
  },
  /*::[*/0x0446 /*::]*/: {
    /* n:"BrtBeginSlicerCacheSiRange", */T: 1
  },
  /*::[*/0x0447 /*::]*/: {
    /* n:"BrtEndSlicerCacheSiRange", */T: -1
  },
  /*::[*/0x0448 /*::]*/: {/* n:"BrtSlicerCacheOlapItem" */},
  /*::[*/0x0449 /*::]*/: {
    /* n:"BrtBeginSlicerCacheSelections", */T: 1
  },
  /*::[*/0x044A /*::]*/: {/* n:"BrtSlicerCacheSelection" */},
  /*::[*/0x044B /*::]*/: {
    /* n:"BrtEndSlicerCacheSelections", */T: -1
  },
  /*::[*/0x044C /*::]*/: {
    /* n:"BrtBeginSlicerCacheNative", */T: 1
  },
  /*::[*/0x044D /*::]*/: {
    /* n:"BrtEndSlicerCacheNative", */T: -1
  },
  /*::[*/0x044E /*::]*/: {/* n:"BrtSlicerCacheNativeItem" */},
  /*::[*/0x044F /*::]*/: {/* n:"BrtRangeProtection14" */},
  /*::[*/0x0450 /*::]*/: {/* n:"BrtRangeProtectionIso14" */},
  /*::[*/0x0451 /*::]*/: {/* n:"BrtCellIgnoreEC14" */},
  /*::[*/0x0457 /*::]*/: {/* n:"BrtList14" */},
  /*::[*/0x0458 /*::]*/: {/* n:"BrtCFIcon" */},
  /*::[*/0x0459 /*::]*/: {
    /* n:"BrtBeginSlicerCachesPivotCacheIDs", */T: 1
  },
  /*::[*/0x045A /*::]*/: {
    /* n:"BrtEndSlicerCachesPivotCacheIDs", */T: -1
  },
  /*::[*/0x045B /*::]*/: {
    /* n:"BrtBeginSlicers", */T: 1
  },
  /*::[*/0x045C /*::]*/: {
    /* n:"BrtEndSlicers", */T: -1
  },
  /*::[*/0x045D /*::]*/: {/* n:"BrtWbProp14" */},
  /*::[*/0x045E /*::]*/: {
    /* n:"BrtBeginSXEdit", */T: 1
  },
  /*::[*/0x045F /*::]*/: {
    /* n:"BrtEndSXEdit", */T: -1
  },
  /*::[*/0x0460 /*::]*/: {
    /* n:"BrtBeginSXEdits", */T: 1
  },
  /*::[*/0x0461 /*::]*/: {
    /* n:"BrtEndSXEdits", */T: -1
  },
  /*::[*/0x0462 /*::]*/: {
    /* n:"BrtBeginSXChange", */T: 1
  },
  /*::[*/0x0463 /*::]*/: {
    /* n:"BrtEndSXChange", */T: -1
  },
  /*::[*/0x0464 /*::]*/: {
    /* n:"BrtBeginSXChanges", */T: 1
  },
  /*::[*/0x0465 /*::]*/: {
    /* n:"BrtEndSXChanges", */T: -1
  },
  /*::[*/0x0466 /*::]*/: {/* n:"BrtSXTupleItems" */},
  /*::[*/0x0468 /*::]*/: {
    /* n:"BrtBeginSlicerStyle", */T: 1
  },
  /*::[*/0x0469 /*::]*/: {
    /* n:"BrtEndSlicerStyle", */T: -1
  },
  /*::[*/0x046A /*::]*/: {/* n:"BrtSlicerStyleElement" */},
  /*::[*/0x046B /*::]*/: {
    /* n:"BrtBeginStyleSheetExt14", */T: 1
  },
  /*::[*/0x046C /*::]*/: {
    /* n:"BrtEndStyleSheetExt14", */T: -1
  },
  /*::[*/0x046D /*::]*/: {
    /* n:"BrtBeginSlicerCachesPivotCacheID", */T: 1
  },
  /*::[*/0x046E /*::]*/: {
    /* n:"BrtEndSlicerCachesPivotCacheID", */T: -1
  },
  /*::[*/0x046F /*::]*/: {
    /* n:"BrtBeginConditionalFormattings", */T: 1
  },
  /*::[*/0x0470 /*::]*/: {
    /* n:"BrtEndConditionalFormattings", */T: -1
  },
  /*::[*/0x0471 /*::]*/: {
    /* n:"BrtBeginPCDCalcMemExt", */T: 1
  },
  /*::[*/0x0472 /*::]*/: {
    /* n:"BrtEndPCDCalcMemExt", */T: -1
  },
  /*::[*/0x0473 /*::]*/: {
    /* n:"BrtBeginPCDCalcMemsExt", */T: 1
  },
  /*::[*/0x0474 /*::]*/: {
    /* n:"BrtEndPCDCalcMemsExt", */T: -1
  },
  /*::[*/0x0475 /*::]*/: {/* n:"BrtPCDField14" */},
  /*::[*/0x0476 /*::]*/: {
    /* n:"BrtBeginSlicerStyles", */T: 1
  },
  /*::[*/0x0477 /*::]*/: {
    /* n:"BrtEndSlicerStyles", */T: -1
  },
  /*::[*/0x0478 /*::]*/: {
    /* n:"BrtBeginSlicerStyleElements", */T: 1
  },
  /*::[*/0x0479 /*::]*/: {
    /* n:"BrtEndSlicerStyleElements", */T: -1
  },
  /*::[*/0x047A /*::]*/: {/* n:"BrtCFRuleExt" */},
  /*::[*/0x047B /*::]*/: {
    /* n:"BrtBeginSXCondFmt14", */T: 1
  },
  /*::[*/0x047C /*::]*/: {
    /* n:"BrtEndSXCondFmt14", */T: -1
  },
  /*::[*/0x047D /*::]*/: {
    /* n:"BrtBeginSXCondFmts14", */T: 1
  },
  /*::[*/0x047E /*::]*/: {
    /* n:"BrtEndSXCondFmts14", */T: -1
  },
  /*::[*/0x0480 /*::]*/: {
    /* n:"BrtBeginSortCond14", */T: 1
  },
  /*::[*/0x0481 /*::]*/: {
    /* n:"BrtEndSortCond14", */T: -1
  },
  /*::[*/0x0482 /*::]*/: {
    /* n:"BrtEndDVals14", */T: -1
  },
  /*::[*/0x0483 /*::]*/: {
    /* n:"BrtEndIconSet14", */T: -1
  },
  /*::[*/0x0484 /*::]*/: {
    /* n:"BrtEndDatabar14", */T: -1
  },
  /*::[*/0x0485 /*::]*/: {
    /* n:"BrtBeginColorScale14", */T: 1
  },
  /*::[*/0x0486 /*::]*/: {
    /* n:"BrtEndColorScale14", */T: -1
  },
  /*::[*/0x0487 /*::]*/: {
    /* n:"BrtBeginSxrules14", */T: 1
  },
  /*::[*/0x0488 /*::]*/: {
    /* n:"BrtEndSxrules14", */T: -1
  },
  /*::[*/0x0489 /*::]*/: {
    /* n:"BrtBeginPRule14", */T: 1
  },
  /*::[*/0x048A /*::]*/: {
    /* n:"BrtEndPRule14", */T: -1
  },
  /*::[*/0x048B /*::]*/: {
    /* n:"BrtBeginPRFilters14", */T: 1
  },
  /*::[*/0x048C /*::]*/: {
    /* n:"BrtEndPRFilters14", */T: -1
  },
  /*::[*/0x048D /*::]*/: {
    /* n:"BrtBeginPRFilter14", */T: 1
  },
  /*::[*/0x048E /*::]*/: {
    /* n:"BrtEndPRFilter14", */T: -1
  },
  /*::[*/0x048F /*::]*/: {
    /* n:"BrtBeginPRFItem14", */T: 1
  },
  /*::[*/0x0490 /*::]*/: {
    /* n:"BrtEndPRFItem14", */T: -1
  },
  /*::[*/0x0491 /*::]*/: {
    /* n:"BrtBeginCellIgnoreECs14", */T: 1
  },
  /*::[*/0x0492 /*::]*/: {
    /* n:"BrtEndCellIgnoreECs14", */T: -1
  },
  /*::[*/0x0493 /*::]*/: {/* n:"BrtDxf14" */},
  /*::[*/0x0494 /*::]*/: {
    /* n:"BrtBeginDxF14s", */T: 1
  },
  /*::[*/0x0495 /*::]*/: {
    /* n:"BrtEndDxf14s", */T: -1
  },
  /*::[*/0x0499 /*::]*/: {/* n:"BrtFilter14" */},
  /*::[*/0x049A /*::]*/: {
    /* n:"BrtBeginCustomFilters14", */T: 1
  },
  /*::[*/0x049C /*::]*/: {/* n:"BrtCustomFilter14" */},
  /*::[*/0x049D /*::]*/: {/* n:"BrtIconFilter14" */},
  /*::[*/0x049E /*::]*/: {/* n:"BrtPivotCacheConnectionName" */},
  /*::[*/0x0800 /*::]*/: {
    /* n:"BrtBeginDecoupledPivotCacheIDs", */T: 1
  },
  /*::[*/0x0801 /*::]*/: {
    /* n:"BrtEndDecoupledPivotCacheIDs", */T: -1
  },
  /*::[*/0x0802 /*::]*/: {/* n:"BrtDecoupledPivotCacheID" */},
  /*::[*/0x0803 /*::]*/: {
    /* n:"BrtBeginPivotTableRefs", */T: 1
  },
  /*::[*/0x0804 /*::]*/: {
    /* n:"BrtEndPivotTableRefs", */T: -1
  },
  /*::[*/0x0805 /*::]*/: {/* n:"BrtPivotTableRef" */},
  /*::[*/0x0806 /*::]*/: {/* n:"BrtSlicerCacheBookPivotTables" */},
  /*::[*/0x0807 /*::]*/: {
    /* n:"BrtBeginSxvcells", */T: 1
  },
  /*::[*/0x0808 /*::]*/: {
    /* n:"BrtEndSxvcells", */T: -1
  },
  /*::[*/0x0809 /*::]*/: {
    /* n:"BrtBeginSxRow", */T: 1
  },
  /*::[*/0x080A /*::]*/: {
    /* n:"BrtEndSxRow", */T: -1
  },
  /*::[*/0x080C /*::]*/: {/* n:"BrtPcdCalcMem15" */},
  /*::[*/0x0813 /*::]*/: {/* n:"BrtQsi15" */},
  /*::[*/0x0814 /*::]*/: {
    /* n:"BrtBeginWebExtensions", */T: 1
  },
  /*::[*/0x0815 /*::]*/: {
    /* n:"BrtEndWebExtensions", */T: -1
  },
  /*::[*/0x0816 /*::]*/: {/* n:"BrtWebExtension" */},
  /*::[*/0x0817 /*::]*/: {/* n:"BrtAbsPath15" */},
  /*::[*/0x0818 /*::]*/: {
    /* n:"BrtBeginPivotTableUISettings", */T: 1
  },
  /*::[*/0x0819 /*::]*/: {
    /* n:"BrtEndPivotTableUISettings", */T: -1
  },
  /*::[*/0x081B /*::]*/: {/* n:"BrtTableSlicerCacheIDs" */},
  /*::[*/0x081C /*::]*/: {/* n:"BrtTableSlicerCacheID" */},
  /*::[*/0x081D /*::]*/: {
    /* n:"BrtBeginTableSlicerCache", */T: 1
  },
  /*::[*/0x081E /*::]*/: {
    /* n:"BrtEndTableSlicerCache", */T: -1
  },
  /*::[*/0x081F /*::]*/: {/* n:"BrtSxFilter15" */},
  /*::[*/0x0820 /*::]*/: {
    /* n:"BrtBeginTimelineCachePivotCacheIDs", */T: 1
  },
  /*::[*/0x0821 /*::]*/: {
    /* n:"BrtEndTimelineCachePivotCacheIDs", */T: -1
  },
  /*::[*/0x0822 /*::]*/: {/* n:"BrtTimelineCachePivotCacheID" */},
  /*::[*/0x0823 /*::]*/: {
    /* n:"BrtBeginTimelineCacheIDs", */T: 1
  },
  /*::[*/0x0824 /*::]*/: {
    /* n:"BrtEndTimelineCacheIDs", */T: -1
  },
  /*::[*/0x0825 /*::]*/: {
    /* n:"BrtBeginTimelineCacheID", */T: 1
  },
  /*::[*/0x0826 /*::]*/: {
    /* n:"BrtEndTimelineCacheID", */T: -1
  },
  /*::[*/0x0827 /*::]*/: {
    /* n:"BrtBeginTimelinesEx", */T: 1
  },
  /*::[*/0x0828 /*::]*/: {
    /* n:"BrtEndTimelinesEx", */T: -1
  },
  /*::[*/0x0829 /*::]*/: {
    /* n:"BrtBeginTimelineEx", */T: 1
  },
  /*::[*/0x082A /*::]*/: {
    /* n:"BrtEndTimelineEx", */T: -1
  },
  /*::[*/0x082B /*::]*/: {/* n:"BrtWorkBookPr15" */},
  /*::[*/0x082C /*::]*/: {/* n:"BrtPCDH15" */},
  /*::[*/0x082D /*::]*/: {
    /* n:"BrtBeginTimelineStyle", */T: 1
  },
  /*::[*/0x082E /*::]*/: {
    /* n:"BrtEndTimelineStyle", */T: -1
  },
  /*::[*/0x082F /*::]*/: {/* n:"BrtTimelineStyleElement" */},
  /*::[*/0x0830 /*::]*/: {
    /* n:"BrtBeginTimelineStylesheetExt15", */T: 1
  },
  /*::[*/0x0831 /*::]*/: {
    /* n:"BrtEndTimelineStylesheetExt15", */T: -1
  },
  /*::[*/0x0832 /*::]*/: {
    /* n:"BrtBeginTimelineStyles", */T: 1
  },
  /*::[*/0x0833 /*::]*/: {
    /* n:"BrtEndTimelineStyles", */T: -1
  },
  /*::[*/0x0834 /*::]*/: {
    /* n:"BrtBeginTimelineStyleElements", */T: 1
  },
  /*::[*/0x0835 /*::]*/: {
    /* n:"BrtEndTimelineStyleElements", */T: -1
  },
  /*::[*/0x0836 /*::]*/: {/* n:"BrtDxf15" */},
  /*::[*/0x0837 /*::]*/: {
    /* n:"BrtBeginDxfs15", */T: 1
  },
  /*::[*/0x0838 /*::]*/: {
    /* n:"BrtEndDxfs15", */T: -1
  },
  /*::[*/0x0839 /*::]*/: {/* n:"BrtSlicerCacheHideItemsWithNoData" */},
  /*::[*/0x083A /*::]*/: {
    /* n:"BrtBeginItemUniqueNames", */T: 1
  },
  /*::[*/0x083B /*::]*/: {
    /* n:"BrtEndItemUniqueNames", */T: -1
  },
  /*::[*/0x083C /*::]*/: {/* n:"BrtItemUniqueName" */},
  /*::[*/0x083D /*::]*/: {
    /* n:"BrtBeginExtConn15", */T: 1
  },
  /*::[*/0x083E /*::]*/: {
    /* n:"BrtEndExtConn15", */T: -1
  },
  /*::[*/0x083F /*::]*/: {
    /* n:"BrtBeginOledbPr15", */T: 1
  },
  /*::[*/0x0840 /*::]*/: {
    /* n:"BrtEndOledbPr15", */T: -1
  },
  /*::[*/0x0841 /*::]*/: {
    /* n:"BrtBeginDataFeedPr15", */T: 1
  },
  /*::[*/0x0842 /*::]*/: {
    /* n:"BrtEndDataFeedPr15", */T: -1
  },
  /*::[*/0x0843 /*::]*/: {/* n:"BrtTextPr15" */},
  /*::[*/0x0844 /*::]*/: {/* n:"BrtRangePr15" */},
  /*::[*/0x0845 /*::]*/: {/* n:"BrtDbCommand15" */},
  /*::[*/0x0846 /*::]*/: {
    /* n:"BrtBeginDbTables15", */T: 1
  },
  /*::[*/0x0847 /*::]*/: {
    /* n:"BrtEndDbTables15", */T: -1
  },
  /*::[*/0x0848 /*::]*/: {/* n:"BrtDbTable15" */},
  /*::[*/0x0849 /*::]*/: {
    /* n:"BrtBeginDataModel", */T: 1
  },
  /*::[*/0x084A /*::]*/: {
    /* n:"BrtEndDataModel", */T: -1
  },
  /*::[*/0x084B /*::]*/: {
    /* n:"BrtBeginModelTables", */T: 1
  },
  /*::[*/0x084C /*::]*/: {
    /* n:"BrtEndModelTables", */T: -1
  },
  /*::[*/0x084D /*::]*/: {/* n:"BrtModelTable" */},
  /*::[*/0x084E /*::]*/: {
    /* n:"BrtBeginModelRelationships", */T: 1
  },
  /*::[*/0x084F /*::]*/: {
    /* n:"BrtEndModelRelationships", */T: -1
  },
  /*::[*/0x0850 /*::]*/: {/* n:"BrtModelRelationship" */},
  /*::[*/0x0851 /*::]*/: {
    /* n:"BrtBeginECTxtWiz15", */T: 1
  },
  /*::[*/0x0852 /*::]*/: {
    /* n:"BrtEndECTxtWiz15", */T: -1
  },
  /*::[*/0x0853 /*::]*/: {
    /* n:"BrtBeginECTWFldInfoLst15", */T: 1
  },
  /*::[*/0x0854 /*::]*/: {
    /* n:"BrtEndECTWFldInfoLst15", */T: -1
  },
  /*::[*/0x0855 /*::]*/: {
    /* n:"BrtBeginECTWFldInfo15", */T: 1
  },
  /*::[*/0x0856 /*::]*/: {/* n:"BrtFieldListActiveItem" */},
  /*::[*/0x0857 /*::]*/: {/* n:"BrtPivotCacheIdVersion" */},
  /*::[*/0x0858 /*::]*/: {/* n:"BrtSXDI15" */},
  /*::[*/0x0859 /*::]*/: {
    /* n:"BrtBeginModelTimeGroupings", */T: 1
  },
  /*::[*/0x085A /*::]*/: {
    /* n:"BrtEndModelTimeGroupings", */T: -1
  },
  /*::[*/0x085B /*::]*/: {
    /* n:"BrtBeginModelTimeGrouping", */T: 1
  },
  /*::[*/0x085C /*::]*/: {
    /* n:"BrtEndModelTimeGrouping", */T: -1
  },
  /*::[*/0x085D /*::]*/: {/* n:"BrtModelTimeGroupingCalcCol" */},
  /*::[*/0x0C00 /*::]*/: {/* n:"BrtUid" */},
  /*::[*/0x0C01 /*::]*/: {/* n:"BrtRevisionPtr" */},
  /*::[*/0x1000 /*::]*/: {
    /* n:"BrtBeginDynamicArrayPr", */T: 1
  },
  /*::[*/0x1001 /*::]*/: {
    /* n:"BrtEndDynamicArrayPr", */T: -1
  },
  /*::[*/0x138A /*::]*/: {
    /* n:"BrtBeginRichValueBlock", */T: 1
  },
  /*::[*/0x138B /*::]*/: {
    /* n:"BrtEndRichValueBlock", */T: -1
  },
  /*::[*/0x13D9 /*::]*/: {
    /* n:"BrtBeginRichFilters", */T: 1
  },
  /*::[*/0x13DA /*::]*/: {
    /* n:"BrtEndRichFilters", */T: -1
  },
  /*::[*/0x13DB /*::]*/: {/* n:"BrtRichFilter" */},
  /*::[*/0x13DC /*::]*/: {
    /* n:"BrtBeginRichFilterColumn", */T: 1
  },
  /*::[*/0x13DD /*::]*/: {
    /* n:"BrtEndRichFilterColumn", */T: -1
  },
  /*::[*/0x13DE /*::]*/: {
    /* n:"BrtBeginCustomRichFilters", */T: 1
  },
  /*::[*/0x13DF /*::]*/: {
    /* n:"BrtEndCustomRichFilters", */T: -1
  },
  /*::[*/0x13E0 /*::]*/: {/* n:"BrtCustomRichFilter" */},
  /*::[*/0x13E1 /*::]*/: {/* n:"BrtTop10RichFilter" */},
  /*::[*/0x13E2 /*::]*/: {/* n:"BrtDynamicRichFilter" */},
  /*::[*/0x13E4 /*::]*/: {
    /* n:"BrtBeginRichSortCondition", */T: 1
  },
  /*::[*/0x13E5 /*::]*/: {
    /* n:"BrtEndRichSortCondition", */T: -1
  },
  /*::[*/0x13E6 /*::]*/: {/* n:"BrtRichFilterDateGroupItem" */},
  /*::[*/0x13E7 /*::]*/: {
    /* n:"BrtBeginCalcFeatures", */T: 1
  },
  /*::[*/0x13E8 /*::]*/: {
    /* n:"BrtEndCalcFeatures", */T: -1
  },
  /*::[*/0x13E9 /*::]*/: {/* n:"BrtCalcFeature" */},
  /*::[*/0x13EB /*::]*/: {/* n:"BrtExternalLinksPr" */},
  /*::[*/0xFFFF /*::]*/: {
    n: ""
  }
};

/* [MS-XLS] 2.3 Record Enumeration (and other sources) */
var XLSRecordEnum = {
  /* [MS-XLS] 2.3 Record Enumeration 2021-08-17 */
  /*::[*/0x0006 /*::]*/: {
    /* n:"Formula", */f: parse_Formula
  },
  /*::[*/0x000a /*::]*/: {
    /* n:"EOF", */f: parsenoop2
  },
  /*::[*/0x000c /*::]*/: {
    /* n:"CalcCount", */f: parseuint16
  },
  //
  /*::[*/
  0x000d /*::]*/: {
    /* n:"CalcMode", */f: parseuint16
  },
  //
  /*::[*/
  0x000e /*::]*/: {
    /* n:"CalcPrecision", */f: parsebool
  },
  //
  /*::[*/
  0x000f /*::]*/: {
    /* n:"CalcRefMode", */f: parsebool
  },
  //
  /*::[*/
  0x0010 /*::]*/: {
    /* n:"CalcDelta", */f: parse_Xnum
  },
  //
  /*::[*/
  0x0011 /*::]*/: {
    /* n:"CalcIter", */f: parsebool
  },
  //
  /*::[*/
  0x0012 /*::]*/: {
    /* n:"Protect", */f: parsebool
  },
  /*::[*/0x0013 /*::]*/: {
    /* n:"Password", */f: parseuint16
  },
  /*::[*/0x0014 /*::]*/: {
    /* n:"Header", */f: parse_XLHeaderFooter
  },
  /*::[*/0x0015 /*::]*/: {
    /* n:"Footer", */f: parse_XLHeaderFooter
  },
  /*::[*/0x0017 /*::]*/: {
    /* n:"ExternSheet", */f: parse_ExternSheet
  },
  /*::[*/0x0018 /*::]*/: {
    /* n:"Lbl", */f: parse_Lbl
  },
  /*::[*/0x0019 /*::]*/: {
    /* n:"WinProtect", */f: parsebool
  },
  /*::[*/0x001a /*::]*/: {/* n:"VerticalPageBreaks", */},
  /*::[*/0x001b /*::]*/: {/* n:"HorizontalPageBreaks", */},
  /*::[*/0x001c /*::]*/: {
    /* n:"Note", */f: parse_Note
  },
  /*::[*/0x001d /*::]*/: {/* n:"Selection", */},
  /*::[*/0x0022 /*::]*/: {
    /* n:"Date1904", */f: parsebool
  },
  /*::[*/0x0023 /*::]*/: {
    /* n:"ExternName", */f: parse_ExternName
  },
  /*::[*/0x0026 /*::]*/: {
    /* n:"LeftMargin", */f: parse_Xnum
  },
  // *
  /*::[*/
  0x0027 /*::]*/: {
    /* n:"RightMargin", */f: parse_Xnum
  },
  // *
  /*::[*/
  0x0028 /*::]*/: {
    /* n:"TopMargin", */f: parse_Xnum
  },
  // *
  /*::[*/
  0x0029 /*::]*/: {
    /* n:"BottomMargin", */f: parse_Xnum
  },
  // *
  /*::[*/
  0x002a /*::]*/: {
    /* n:"PrintRowCol", */f: parsebool
  },
  /*::[*/0x002b /*::]*/: {
    /* n:"PrintGrid", */f: parsebool
  },
  /*::[*/0x002f /*::]*/: {
    /* n:"FilePass", */f: parse_FilePass
  },
  /*::[*/0x0031 /*::]*/: {
    /* n:"Font", */f: parse_Font
  },
  /*::[*/0x0033 /*::]*/: {
    /* n:"PrintSize", */f: parseuint16
  },
  /*::[*/0x003c /*::]*/: {/* n:"Continue", */},
  /*::[*/0x003d /*::]*/: {
    /* n:"Window1", */f: parse_Window1
  },
  /*::[*/0x0040 /*::]*/: {
    /* n:"Backup", */f: parsebool
  },
  /*::[*/0x0041 /*::]*/: {
    /* n:"Pane", */f: parse_Pane
  },
  /*::[*/0x0042 /*::]*/: {
    /* n:"CodePage", */f: parseuint16
  },
  /*::[*/0x004d /*::]*/: {/* n:"Pls", */},
  /*::[*/0x0050 /*::]*/: {/* n:"DCon", */},
  /*::[*/0x0051 /*::]*/: {/* n:"DConRef", */},
  /*::[*/0x0052 /*::]*/: {/* n:"DConName", */},
  /*::[*/0x0055 /*::]*/: {
    /* n:"DefColWidth", */f: parseuint16
  },
  /*::[*/0x0059 /*::]*/: {/* n:"XCT", */},
  /*::[*/0x005a /*::]*/: {/* n:"CRN", */},
  /*::[*/0x005b /*::]*/: {/* n:"FileSharing", */},
  /*::[*/0x005c /*::]*/: {
    /* n:"WriteAccess", */f: parse_WriteAccess
  },
  /*::[*/0x005d /*::]*/: {
    /* n:"Obj", */f: parse_Obj
  },
  /*::[*/0x005e /*::]*/: {/* n:"Uncalced", */},
  /*::[*/0x005f /*::]*/: {
    /* n:"CalcSaveRecalc", */f: parsebool
  },
  //
  /*::[*/
  0x0060 /*::]*/: {/* n:"Template", */},
  /*::[*/0x0061 /*::]*/: {/* n:"Intl", */},
  /*::[*/0x0063 /*::]*/: {
    /* n:"ObjProtect", */f: parsebool
  },
  /*::[*/0x007d /*::]*/: {
    /* n:"ColInfo", */f: parse_ColInfo
  },
  /*::[*/0x0080 /*::]*/: {
    /* n:"Guts", */f: parse_Guts
  },
  /*::[*/0x0081 /*::]*/: {
    /* n:"WsBool", */f: parse_WsBool
  },
  /*::[*/0x0082 /*::]*/: {
    /* n:"GridSet", */f: parseuint16
  },
  /*::[*/0x0083 /*::]*/: {
    /* n:"HCenter", */f: parsebool
  },
  /*::[*/0x0084 /*::]*/: {
    /* n:"VCenter", */f: parsebool
  },
  /*::[*/0x0085 /*::]*/: {
    /* n:"BoundSheet8", */f: parse_BoundSheet8
  },
  /*::[*/0x0086 /*::]*/: {/* n:"WriteProtect", */},
  /*::[*/0x008c /*::]*/: {
    /* n:"Country", */f: parse_Country
  },
  /*::[*/0x008d /*::]*/: {
    /* n:"HideObj", */f: parseuint16
  },
  /*::[*/0x0090 /*::]*/: {/* n:"Sort", */},
  /*::[*/0x0092 /*::]*/: {
    /* n:"Palette", */f: parse_Palette
  },
  /*::[*/0x0097 /*::]*/: {/* n:"Sync", */},
  /*::[*/0x0098 /*::]*/: {/* n:"LPr", */},
  /*::[*/0x0099 /*::]*/: {/* n:"DxGCol", */},
  /*::[*/0x009a /*::]*/: {/* n:"FnGroupName", */},
  /*::[*/0x009b /*::]*/: {/* n:"FilterMode", */},
  /*::[*/0x009c /*::]*/: {
    /* n:"BuiltInFnGroupCount", */f: parseuint16
  },
  /*::[*/0x009d /*::]*/: {/* n:"AutoFilterInfo", */},
  /*::[*/0x009e /*::]*/: {/* n:"AutoFilter", */},
  /*::[*/0x00a0 /*::]*/: {
    /* n:"Scl", */f: parse_Scl
  },
  /*::[*/0x00a1 /*::]*/: {
    /* n:"Setup", */f: parse_Setup
  },
  /*::[*/0x00ae /*::]*/: {/* n:"ScenMan", */},
  /*::[*/0x00af /*::]*/: {/* n:"SCENARIO", */},
  /*::[*/0x00b0 /*::]*/: {/* n:"SxView", */},
  /*::[*/0x00b1 /*::]*/: {/* n:"Sxvd", */},
  /*::[*/0x00b2 /*::]*/: {/* n:"SXVI", */},
  /*::[*/0x00b4 /*::]*/: {/* n:"SxIvd", */},
  /*::[*/0x00b5 /*::]*/: {/* n:"SXLI", */},
  /*::[*/0x00b6 /*::]*/: {/* n:"SXPI", */},
  /*::[*/0x00b8 /*::]*/: {/* n:"DocRoute", */},
  /*::[*/0x00b9 /*::]*/: {/* n:"RecipName", */},
  /*::[*/0x00bd /*::]*/: {
    /* n:"MulRk", */f: parse_MulRk
  },
  /*::[*/0x00be /*::]*/: {
    /* n:"MulBlank", */f: parse_MulBlank
  },
  /*::[*/0x00c1 /*::]*/: {
    /* n:"Mms", */f: parsenoop2
  },
  /*::[*/0x00c5 /*::]*/: {/* n:"SXDI", */},
  /*::[*/0x00c6 /*::]*/: {/* n:"SXDB", */},
  /*::[*/0x00c7 /*::]*/: {/* n:"SXFDB", */},
  /*::[*/0x00c8 /*::]*/: {/* n:"SXDBB", */},
  /*::[*/0x00c9 /*::]*/: {/* n:"SXNum", */},
  /*::[*/0x00ca /*::]*/: {
    /* n:"SxBool", */f: parsebool
  },
  /*::[*/0x00cb /*::]*/: {/* n:"SxErr", */},
  /*::[*/0x00cc /*::]*/: {/* n:"SXInt", */},
  /*::[*/0x00cd /*::]*/: {/* n:"SXString", */},
  /*::[*/0x00ce /*::]*/: {/* n:"SXDtr", */},
  /*::[*/0x00cf /*::]*/: {/* n:"SxNil", */},
  /*::[*/0x00d0 /*::]*/: {/* n:"SXTbl", */},
  /*::[*/0x00d1 /*::]*/: {/* n:"SXTBRGIITM", */},
  /*::[*/0x00d2 /*::]*/: {/* n:"SxTbpg", */},
  /*::[*/0x00d3 /*::]*/: {/* n:"ObProj", */},
  /*::[*/0x00d5 /*::]*/: {/* n:"SXStreamID", */},
  /*::[*/0x00d7 /*::]*/: {/* n:"DBCell", */},
  /*::[*/0x00d8 /*::]*/: {/* n:"SXRng", */},
  /*::[*/0x00d9 /*::]*/: {/* n:"SxIsxoper", */},
  /*::[*/0x00da /*::]*/: {
    /* n:"BookBool", */f: parseuint16
  },
  /*::[*/0x00dc /*::]*/: {/* n:"DbOrParamQry", */},
  /*::[*/0x00dd /*::]*/: {
    /* n:"ScenarioProtect", */f: parsebool
  },
  /*::[*/0x00de /*::]*/: {/* n:"OleObjectSize", */},
  /*::[*/0x00e0 /*::]*/: {
    /* n:"XF", */f: parse_XF
  },
  /*::[*/0x00e1 /*::]*/: {
    /* n:"InterfaceHdr", */f: parse_InterfaceHdr
  },
  /*::[*/0x00e2 /*::]*/: {
    /* n:"InterfaceEnd", */f: parsenoop2
  },
  /*::[*/0x00e3 /*::]*/: {/* n:"SXVS", */},
  /*::[*/0x00e5 /*::]*/: {
    /* n:"MergeCells", */f: parse_MergeCells
  },
  /*::[*/0x00e9 /*::]*/: {/* n:"BkHim", */},
  /*::[*/0x00eb /*::]*/: {/* n:"MsoDrawingGroup", */},
  /*::[*/0x00ec /*::]*/: {/* n:"MsoDrawing", */},
  /*::[*/0x00ed /*::]*/: {/* n:"MsoDrawingSelection", */},
  /*::[*/0x00ef /*::]*/: {/* n:"PhoneticInfo", */},
  /*::[*/0x00f0 /*::]*/: {/* n:"SxRule", */},
  /*::[*/0x00f1 /*::]*/: {/* n:"SXEx", */},
  /*::[*/0x00f2 /*::]*/: {/* n:"SxFilt", */},
  /*::[*/0x00f4 /*::]*/: {/* n:"SxDXF", */},
  /*::[*/0x00f5 /*::]*/: {/* n:"SxItm", */},
  /*::[*/0x00f6 /*::]*/: {/* n:"SxName", */},
  /*::[*/0x00f7 /*::]*/: {/* n:"SxSelect", */},
  /*::[*/0x00f8 /*::]*/: {/* n:"SXPair", */},
  /*::[*/0x00f9 /*::]*/: {/* n:"SxFmla", */},
  /*::[*/0x00fb /*::]*/: {/* n:"SxFormat", */},
  /*::[*/0x00fc /*::]*/: {
    /* n:"SST", */f: parse_SST
  },
  /*::[*/0x00fd /*::]*/: {
    /* n:"LabelSst", */f: parse_LabelSst
  },
  /*::[*/0x00ff /*::]*/: {
    /* n:"ExtSST", */f: parse_ExtSST
  },
  /*::[*/0x0100 /*::]*/: {/* n:"SXVDEx", */},
  /*::[*/0x0103 /*::]*/: {/* n:"SXFormula", */},
  /*::[*/0x0122 /*::]*/: {/* n:"SXDBEx", */},
  /*::[*/0x0137 /*::]*/: {/* n:"RRDInsDel", */},
  /*::[*/0x0138 /*::]*/: {/* n:"RRDHead", */},
  /*::[*/0x013b /*::]*/: {/* n:"RRDChgCell", */},
  /*::[*/0x013d /*::]*/: {
    /* n:"RRTabId", */f: parseuint16a
  },
  /*::[*/0x013e /*::]*/: {/* n:"RRDRenSheet", */},
  /*::[*/0x013f /*::]*/: {/* n:"RRSort", */},
  /*::[*/0x0140 /*::]*/: {/* n:"RRDMove", */},
  /*::[*/0x014a /*::]*/: {/* n:"RRFormat", */},
  /*::[*/0x014b /*::]*/: {/* n:"RRAutoFmt", */},
  /*::[*/0x014d /*::]*/: {/* n:"RRInsertSh", */},
  /*::[*/0x014e /*::]*/: {/* n:"RRDMoveBegin", */},
  /*::[*/0x014f /*::]*/: {/* n:"RRDMoveEnd", */},
  /*::[*/0x0150 /*::]*/: {/* n:"RRDInsDelBegin", */},
  /*::[*/0x0151 /*::]*/: {/* n:"RRDInsDelEnd", */},
  /*::[*/0x0152 /*::]*/: {/* n:"RRDConflict", */},
  /*::[*/0x0153 /*::]*/: {/* n:"RRDDefName", */},
  /*::[*/0x0154 /*::]*/: {/* n:"RRDRstEtxp", */},
  /*::[*/0x015f /*::]*/: {/* n:"LRng", */},
  /*::[*/0x0160 /*::]*/: {
    /* n:"UsesELFs", */f: parsebool
  },
  /*::[*/0x0161 /*::]*/: {
    /* n:"DSF", */f: parsenoop2
  },
  /*::[*/0x0191 /*::]*/: {/* n:"CUsr", */},
  /*::[*/0x0192 /*::]*/: {/* n:"CbUsr", */},
  /*::[*/0x0193 /*::]*/: {/* n:"UsrInfo", */},
  /*::[*/0x0194 /*::]*/: {/* n:"UsrExcl", */},
  /*::[*/0x0195 /*::]*/: {/* n:"FileLock", */},
  /*::[*/0x0196 /*::]*/: {/* n:"RRDInfo", */},
  /*::[*/0x0197 /*::]*/: {/* n:"BCUsrs", */},
  /*::[*/0x0198 /*::]*/: {/* n:"UsrChk", */},
  /*::[*/0x01a9 /*::]*/: {/* n:"UserBView", */},
  /*::[*/0x01aa /*::]*/: {/* n:"UserSViewBegin", */},
  /*::[*/0x01ab /*::]*/: {/* n:"UserSViewEnd", */},
  /*::[*/0x01ac /*::]*/: {/* n:"RRDUserView", */},
  /*::[*/0x01ad /*::]*/: {/* n:"Qsi", */},
  /*::[*/0x01ae /*::]*/: {
    /* n:"SupBook", */f: parse_SupBook
  },
  /*::[*/0x01af /*::]*/: {
    /* n:"Prot4Rev", */f: parsebool
  },
  /*::[*/0x01b0 /*::]*/: {/* n:"CondFmt", */},
  /*::[*/0x01b1 /*::]*/: {/* n:"CF", */},
  /*::[*/0x01b2 /*::]*/: {/* n:"DVal", */},
  /*::[*/0x01b5 /*::]*/: {/* n:"DConBin", */},
  /*::[*/0x01b6 /*::]*/: {
    /* n:"TxO", */f: parse_TxO
  },
  /*::[*/0x01b7 /*::]*/: {
    /* n:"RefreshAll", */f: parsebool
  },
  //
  /*::[*/
  0x01b8 /*::]*/: {
    /* n:"HLink", */f: parse_HLink
  },
  /*::[*/0x01b9 /*::]*/: {/* n:"Lel", */},
  /*::[*/0x01ba /*::]*/: {
    /* n:"CodeName", */f: parse_XLUnicodeString
  },
  /*::[*/0x01bb /*::]*/: {/* n:"SXFDBType", */},
  /*::[*/0x01bc /*::]*/: {
    /* n:"Prot4RevPass", */f: parseuint16
  },
  /*::[*/0x01bd /*::]*/: {/* n:"ObNoMacros", */},
  /*::[*/0x01be /*::]*/: {/* n:"Dv", */},
  /*::[*/0x01c0 /*::]*/: {
    /* n:"Excel9File", */f: parsenoop2
  },
  /*::[*/0x01c1 /*::]*/: {
    /* n:"RecalcId", */f: parse_RecalcId,
    r: 2
  },
  /*::[*/0x01c2 /*::]*/: {
    /* n:"EntExU2", */f: parsenoop2
  },
  /*::[*/0x0200 /*::]*/: {
    /* n:"Dimensions", */f: parse_Dimensions
  },
  /*::[*/0x0201 /*::]*/: {
    /* n:"Blank", */f: parse_Blank
  },
  /*::[*/0x0203 /*::]*/: {
    /* n:"Number", */f: parse_Number
  },
  /*::[*/0x0204 /*::]*/: {
    /* n:"Label", */f: parse_Label
  },
  /*::[*/0x0205 /*::]*/: {
    /* n:"BoolErr", */f: parse_BoolErr
  },
  /*::[*/0x0207 /*::]*/: {
    /* n:"String", */f: parse_String
  },
  /*::[*/0x0208 /*::]*/: {
    /* n:"Row", */f: parse_Row
  },
  /*::[*/0x020b /*::]*/: {/* n:"Index", */},
  /*::[*/0x0221 /*::]*/: {
    /* n:"Array", */f: parse_Array
  },
  /*::[*/0x0225 /*::]*/: {
    /* n:"DefaultRowHeight", */f: parse_DefaultRowHeight
  },
  /*::[*/0x0236 /*::]*/: {/* n:"Table", */},
  /*::[*/0x023e /*::]*/: {
    /* n:"Window2", */f: parse_Window2
  },
  /*::[*/0x027e /*::]*/: {
    /* n:"RK", */f: parse_RK
  },
  /*::[*/0x0293 /*::]*/: {/* n:"Style", */},
  /*::[*/0x0418 /*::]*/: {/* n:"BigName", */},
  /*::[*/0x041e /*::]*/: {
    /* n:"Format", */f: parse_Format
  },
  /*::[*/0x043c /*::]*/: {/* n:"ContinueBigName", */},
  /*::[*/0x04bc /*::]*/: {
    /* n:"ShrFmla", */f: parse_ShrFmla
  },
  /*::[*/0x0800 /*::]*/: {
    /* n:"HLinkTooltip", */f: parse_HLinkTooltip
  },
  /*::[*/0x0801 /*::]*/: {/* n:"WebPub", */},
  /*::[*/0x0802 /*::]*/: {/* n:"QsiSXTag", */},
  /*::[*/0x0803 /*::]*/: {/* n:"DBQueryExt", */},
  /*::[*/0x0804 /*::]*/: {/* n:"ExtString", */},
  /*::[*/0x0805 /*::]*/: {/* n:"TxtQry", */},
  /*::[*/0x0806 /*::]*/: {/* n:"Qsir", */},
  /*::[*/0x0807 /*::]*/: {/* n:"Qsif", */},
  /*::[*/0x0808 /*::]*/: {/* n:"RRDTQSIF", */},
  /*::[*/0x0809 /*::]*/: {
    /* n:"BOF", */f: parse_BOF
  },
  /*::[*/0x080a /*::]*/: {/* n:"OleDbConn", */},
  /*::[*/0x080b /*::]*/: {/* n:"WOpt", */},
  /*::[*/0x080c /*::]*/: {/* n:"SXViewEx", */},
  /*::[*/0x080d /*::]*/: {/* n:"SXTH", */},
  /*::[*/0x080e /*::]*/: {/* n:"SXPIEx", */},
  /*::[*/0x080f /*::]*/: {/* n:"SXVDTEx", */},
  /*::[*/0x0810 /*::]*/: {/* n:"SXViewEx9", */},
  /*::[*/0x0812 /*::]*/: {/* n:"ContinueFrt", */},
  /*::[*/0x0813 /*::]*/: {/* n:"RealTimeData", */},
  /*::[*/0x0850 /*::]*/: {/* n:"ChartFrtInfo", */},
  /*::[*/0x0851 /*::]*/: {/* n:"FrtWrapper", */},
  /*::[*/0x0852 /*::]*/: {/* n:"StartBlock", */},
  /*::[*/0x0853 /*::]*/: {/* n:"EndBlock", */},
  /*::[*/0x0854 /*::]*/: {/* n:"StartObject", */},
  /*::[*/0x0855 /*::]*/: {/* n:"EndObject", */},
  /*::[*/0x0856 /*::]*/: {/* n:"CatLab", */},
  /*::[*/0x0857 /*::]*/: {/* n:"YMult", */},
  /*::[*/0x0858 /*::]*/: {/* n:"SXViewLink", */},
  /*::[*/0x0859 /*::]*/: {/* n:"PivotChartBits", */},
  /*::[*/0x085a /*::]*/: {/* n:"FrtFontList", */},
  /*::[*/0x0862 /*::]*/: {/* n:"SheetExt", */},
  /*::[*/0x0863 /*::]*/: {
    /* n:"BookExt", */r: 12
  },
  /*::[*/0x0864 /*::]*/: {/* n:"SXAddl", */},
  /*::[*/0x0865 /*::]*/: {/* n:"CrErr", */},
  /*::[*/0x0866 /*::]*/: {/* n:"HFPicture", */},
  /*::[*/0x0867 /*::]*/: {
    /* n:"FeatHdr", */f: parsenoop2
  },
  /*::[*/0x0868 /*::]*/: {/* n:"Feat", */},
  /*::[*/0x086a /*::]*/: {/* n:"DataLabExt", */},
  /*::[*/0x086b /*::]*/: {/* n:"DataLabExtContents", */},
  /*::[*/0x086c /*::]*/: {/* n:"CellWatch", */},
  /*::[*/0x0871 /*::]*/: {/* n:"FeatHdr11", */},
  /*::[*/0x0872 /*::]*/: {/* n:"Feature11", */},
  /*::[*/0x0874 /*::]*/: {/* n:"DropDownObjIds", */},
  /*::[*/0x0875 /*::]*/: {/* n:"ContinueFrt11", */},
  /*::[*/0x0876 /*::]*/: {/* n:"DConn", */},
  /*::[*/0x0877 /*::]*/: {/* n:"List12", */},
  /*::[*/0x0878 /*::]*/: {/* n:"Feature12", */},
  /*::[*/0x0879 /*::]*/: {/* n:"CondFmt12", */},
  /*::[*/0x087a /*::]*/: {/* n:"CF12", */},
  /*::[*/0x087b /*::]*/: {/* n:"CFEx", */},
  /*::[*/0x087c /*::]*/: {
    /* n:"XFCRC", */f: parse_XFCRC,
    r: 12
  },
  /*::[*/0x087d /*::]*/: {
    /* n:"XFExt", */f: parse_XFExt,
    r: 12
  },
  /*::[*/0x087e /*::]*/: {/* n:"AutoFilter12", */},
  /*::[*/0x087f /*::]*/: {/* n:"ContinueFrt12", */},
  /*::[*/0x0884 /*::]*/: {/* n:"MDTInfo", */},
  /*::[*/0x0885 /*::]*/: {/* n:"MDXStr", */},
  /*::[*/0x0886 /*::]*/: {/* n:"MDXTuple", */},
  /*::[*/0x0887 /*::]*/: {/* n:"MDXSet", */},
  /*::[*/0x0888 /*::]*/: {/* n:"MDXProp", */},
  /*::[*/0x0889 /*::]*/: {/* n:"MDXKPI", */},
  /*::[*/0x088a /*::]*/: {/* n:"MDB", */},
  /*::[*/0x088b /*::]*/: {/* n:"PLV", */},
  /*::[*/0x088c /*::]*/: {
    /* n:"Compat12", */f: parsebool,
    r: 12
  },
  /*::[*/0x088d /*::]*/: {/* n:"DXF", */},
  /*::[*/0x088e /*::]*/: {
    /* n:"TableStyles", */r: 12
  },
  /*::[*/0x088f /*::]*/: {/* n:"TableStyle", */},
  /*::[*/0x0890 /*::]*/: {/* n:"TableStyleElement", */},
  /*::[*/0x0892 /*::]*/: {/* n:"StyleExt", */},
  /*::[*/0x0893 /*::]*/: {/* n:"NamePublish", */},
  /*::[*/0x0894 /*::]*/: {
    /* n:"NameCmt", */f: parse_NameCmt,
    r: 12
  },
  /*::[*/0x0895 /*::]*/: {/* n:"SortData", */},
  /*::[*/0x0896 /*::]*/: {
    /* n:"Theme", */f: parse_Theme,
    r: 12
  },
  /*::[*/0x0897 /*::]*/: {/* n:"GUIDTypeLib", */},
  /*::[*/0x0898 /*::]*/: {/* n:"FnGrp12", */},
  /*::[*/0x0899 /*::]*/: {/* n:"NameFnGrp12", */},
  /*::[*/0x089a /*::]*/: {
    /* n:"MTRSettings", */f: parse_MTRSettings,
    r: 12
  },
  /*::[*/0x089b /*::]*/: {
    /* n:"CompressPictures", */f: parsenoop2
  },
  /*::[*/0x089c /*::]*/: {/* n:"HeaderFooter", */},
  /*::[*/0x089d /*::]*/: {/* n:"CrtLayout12", */},
  /*::[*/0x089e /*::]*/: {/* n:"CrtMlFrt", */},
  /*::[*/0x089f /*::]*/: {/* n:"CrtMlFrtContinue", */},
  /*::[*/0x08a3 /*::]*/: {
    /* n:"ForceFullCalculation", */f: parse_ForceFullCalculation
  },
  /*::[*/0x08a4 /*::]*/: {/* n:"ShapePropsStream", */},
  /*::[*/0x08a5 /*::]*/: {/* n:"TextPropsStream", */},
  /*::[*/0x08a6 /*::]*/: {/* n:"RichTextStream", */},
  /*::[*/0x08a7 /*::]*/: {/* n:"CrtLayout12A", */},
  /*::[*/0x1001 /*::]*/: {/* n:"Units", */},
  /*::[*/0x1002 /*::]*/: {/* n:"Chart", */},
  /*::[*/0x1003 /*::]*/: {/* n:"Series", */},
  /*::[*/0x1006 /*::]*/: {/* n:"DataFormat", */},
  /*::[*/0x1007 /*::]*/: {/* n:"LineFormat", */},
  /*::[*/0x1009 /*::]*/: {/* n:"MarkerFormat", */},
  /*::[*/0x100a /*::]*/: {/* n:"AreaFormat", */},
  /*::[*/0x100b /*::]*/: {/* n:"PieFormat", */},
  /*::[*/0x100c /*::]*/: {/* n:"AttachedLabel", */},
  /*::[*/0x100d /*::]*/: {/* n:"SeriesText", */},
  /*::[*/0x1014 /*::]*/: {/* n:"ChartFormat", */},
  /*::[*/0x1015 /*::]*/: {/* n:"Legend", */},
  /*::[*/0x1016 /*::]*/: {/* n:"SeriesList", */},
  /*::[*/0x1017 /*::]*/: {/* n:"Bar", */},
  /*::[*/0x1018 /*::]*/: {/* n:"Line", */},
  /*::[*/0x1019 /*::]*/: {/* n:"Pie", */},
  /*::[*/0x101a /*::]*/: {/* n:"Area", */},
  /*::[*/0x101b /*::]*/: {/* n:"Scatter", */},
  /*::[*/0x101c /*::]*/: {/* n:"CrtLine", */},
  /*::[*/0x101d /*::]*/: {/* n:"Axis", */},
  /*::[*/0x101e /*::]*/: {/* n:"Tick", */},
  /*::[*/0x101f /*::]*/: {/* n:"ValueRange", */},
  /*::[*/0x1020 /*::]*/: {/* n:"CatSerRange", */},
  /*::[*/0x1021 /*::]*/: {/* n:"AxisLine", */},
  /*::[*/0x1022 /*::]*/: {/* n:"CrtLink", */},
  /*::[*/0x1024 /*::]*/: {/* n:"DefaultText", */},
  /*::[*/0x1025 /*::]*/: {/* n:"Text", */},
  /*::[*/0x1026 /*::]*/: {
    /* n:"FontX", */f: parseuint16
  },
  /*::[*/0x1027 /*::]*/: {/* n:"ObjectLink", */},
  /*::[*/0x1032 /*::]*/: {/* n:"Frame", */},
  /*::[*/0x1033 /*::]*/: {/* n:"Begin", */},
  /*::[*/0x1034 /*::]*/: {/* n:"End", */},
  /*::[*/0x1035 /*::]*/: {/* n:"PlotArea", */},
  /*::[*/0x103a /*::]*/: {/* n:"Chart3d", */},
  /*::[*/0x103c /*::]*/: {/* n:"PicF", */},
  /*::[*/0x103d /*::]*/: {/* n:"DropBar", */},
  /*::[*/0x103e /*::]*/: {/* n:"Radar", */},
  /*::[*/0x103f /*::]*/: {/* n:"Surf", */},
  /*::[*/0x1040 /*::]*/: {/* n:"RadarArea", */},
  /*::[*/0x1041 /*::]*/: {/* n:"AxisParent", */},
  /*::[*/0x1043 /*::]*/: {/* n:"LegendException", */},
  /*::[*/0x1044 /*::]*/: {
    /* n:"ShtProps", */f: parse_ShtProps
  },
  /*::[*/0x1045 /*::]*/: {/* n:"SerToCrt", */},
  /*::[*/0x1046 /*::]*/: {/* n:"AxesUsed", */},
  /*::[*/0x1048 /*::]*/: {/* n:"SBaseRef", */},
  /*::[*/0x104a /*::]*/: {/* n:"SerParent", */},
  /*::[*/0x104b /*::]*/: {/* n:"SerAuxTrend", */},
  /*::[*/0x104e /*::]*/: {/* n:"IFmtRecord", */},
  /*::[*/0x104f /*::]*/: {/* n:"Pos", */},
  /*::[*/0x1050 /*::]*/: {/* n:"AlRuns", */},
  /*::[*/0x1051 /*::]*/: {/* n:"BRAI", */},
  /*::[*/0x105b /*::]*/: {/* n:"SerAuxErrBar", */},
  /*::[*/0x105c /*::]*/: {
    /* n:"ClrtClient", */f: parse_ClrtClient
  },
  /*::[*/0x105d /*::]*/: {/* n:"SerFmt", */},
  /*::[*/0x105f /*::]*/: {/* n:"Chart3DBarShape", */},
  /*::[*/0x1060 /*::]*/: {/* n:"Fbi", */},
  /*::[*/0x1061 /*::]*/: {/* n:"BopPop", */},
  /*::[*/0x1062 /*::]*/: {/* n:"AxcExt", */},
  /*::[*/0x1063 /*::]*/: {/* n:"Dat", */},
  /*::[*/0x1064 /*::]*/: {/* n:"PlotGrowth", */},
  /*::[*/0x1065 /*::]*/: {/* n:"SIIndex", */},
  /*::[*/0x1066 /*::]*/: {/* n:"GelFrame", */},
  /*::[*/0x1067 /*::]*/: {/* n:"BopPopCustom", */},
  /*::[*/0x1068 /*::]*/: {/* n:"Fbi2", */},
  /*::[*/0x0000 /*::]*/: {
    /* n:"Dimensions", */f: parse_Dimensions
  },
  /*::[*/0x0001 /*::]*/: {/* n:"BIFF2BLANK", */},
  /*::[*/0x0002 /*::]*/: {
    /* n:"BIFF2INT", */f: parse_BIFF2INT
  },
  /*::[*/0x0003 /*::]*/: {
    /* n:"BIFF2NUM", */f: parse_BIFF2NUM
  },
  /*::[*/0x0004 /*::]*/: {
    /* n:"BIFF2STR", */f: parse_BIFF2STR
  },
  /*::[*/0x0005 /*::]*/: {
    /* n:"BoolErr", */f: parse_BoolErr
  },
  /*::[*/0x0007 /*::]*/: {
    /* n:"String", */f: parse_BIFF2STRING
  },
  /*::[*/0x0008 /*::]*/: {/* n:"BIFF2ROW", */},
  /*::[*/0x0009 /*::]*/: {
    /* n:"BOF", */f: parse_BOF
  },
  /*::[*/0x000b /*::]*/: {/* n:"Index", */},
  /*::[*/0x0016 /*::]*/: {
    /* n:"ExternCount", */f: parseuint16
  },
  /*::[*/0x001e /*::]*/: {
    /* n:"BIFF2FORMAT", */f: parse_BIFF2Format
  },
  /*::[*/0x001f /*::]*/: {/* n:"BIFF2FMTCNT", */},
  /* 16-bit cnt of BIFF2FORMAT records */
  /*::[*/0x0020 /*::]*/: {/* n:"BIFF2COLINFO", */},
  /*::[*/0x0021 /*::]*/: {
    /* n:"Array", */f: parse_Array
  },
  /*::[*/0x0024 /*::]*/: {/* n:"COLWIDTH", */},
  /*::[*/0x0025 /*::]*/: {
    /* n:"DefaultRowHeight", */f: parse_DefaultRowHeight
  },
  // 0x2c ??
  // 0x2d ??
  // 0x2e ??
  // 0x30 FONTCOUNT: number of fonts
  /*::[*/
  0x0032 /*::]*/: {
    /* n:"BIFF2FONTXTRA", */f: parse_BIFF2FONTXTRA
  },
  // 0x35: INFOOPTS
  // 0x36: TABLE (BIFF2 only)
  // 0x37: TABLE2 (BIFF2 only)
  // 0x38: WNDESK
  // 0x39 ??
  // 0x3a: BEGINPREF
  // 0x3b: ENDPREF
  /*::[*/
  0x003e /*::]*/: {/* n:"BIFF2WINDOW2", */},
  // 0x3f ??
  // 0x46: SHOWSCROLL
  // 0x47: SHOWFORMULA
  // 0x48: STATUSBAR
  // 0x49: SHORTMENUS
  // 0x4A:
  // 0x4B:
  // 0x4C:
  // 0x4E:
  // 0x4F:
  // 0x58: TOOLBAR (BIFF3)

  /* - - - */
  /*::[*/
  0x0034 /*::]*/: {/* n:"DDEObjName", */},
  /*::[*/0x0043 /*::]*/: {/* n:"BIFF2XF", */},
  /*::[*/0x0044 /*::]*/: {
    /* n:"BIFF2XFINDEX", */f: parseuint16
  },
  /*::[*/0x0045 /*::]*/: {/* n:"BIFF2FONTCLR", */},
  /*::[*/0x0056 /*::]*/: {/* n:"BIFF4FMTCNT", */},
  /* 16-bit cnt, similar to BIFF2 */
  /*::[*/0x007e /*::]*/: {/* n:"RK", */},
  /* Not necessarily same as 0x027e */
  /*::[*/0x007f /*::]*/: {
    /* n:"ImData", */f: parse_ImData
  },
  /*::[*/0x0087 /*::]*/: {/* n:"Addin", */},
  /*::[*/0x0088 /*::]*/: {/* n:"Edg", */},
  /*::[*/0x0089 /*::]*/: {/* n:"Pub", */},
  // 0x8A
  // 0x8B LH: alternate menu key flag (BIFF3/4)
  // 0x8E
  // 0x8F
  /*::[*/
  0x0091 /*::]*/: {/* n:"Sub", */},
  // 0x93 STYLE
  /*::[*/
  0x0094 /*::]*/: {/* n:"LHRecord", */},
  /*::[*/0x0095 /*::]*/: {/* n:"LHNGraph", */},
  /*::[*/0x0096 /*::]*/: {/* n:"Sound", */},
  // 0xA2 FNPROTO: function prototypes (BIFF4)
  // 0xA3
  // 0xA8
  /*::[*/
  0x00a9 /*::]*/: {/* n:"CoordList", */},
  /*::[*/0x00ab /*::]*/: {/* n:"GCW", */},
  /*::[*/0x00bc /*::]*/: {/* n:"ShrFmla", */},
  /* Not necessarily same as 0x04bc */
  /*::[*/0x00bf /*::]*/: {/* n:"ToolbarHdr", */},
  /*::[*/0x00c0 /*::]*/: {/* n:"ToolbarEnd", */},
  /*::[*/0x00c2 /*::]*/: {/* n:"AddMenu", */},
  /*::[*/0x00c3 /*::]*/: {/* n:"DelMenu", */},
  /*::[*/0x00d6 /*::]*/: {
    /* n:"RString", */f: parse_RString
  },
  /*::[*/0x00df /*::]*/: {/* n:"UDDesc", */},
  /*::[*/0x00ea /*::]*/: {/* n:"TabIdConf", */},
  /*::[*/0x0162 /*::]*/: {/* n:"XL5Modify", */},
  /*::[*/0x01a5 /*::]*/: {/* n:"FileSharing2", */},
  /*::[*/0x0206 /*::]*/: {
    /* n:"Formula", */f: parse_Formula
  },
  /*::[*/0x0209 /*::]*/: {
    /* n:"BOF", */f: parse_BOF
  },
  /*::[*/0x0218 /*::]*/: {
    /* n:"Lbl", */f: parse_Lbl
  },
  /*::[*/0x0223 /*::]*/: {
    /* n:"ExternName", */f: parse_ExternName
  },
  /*::[*/0x0231 /*::]*/: {/* n:"Font", */},
  /*::[*/0x0243 /*::]*/: {/* n:"BIFF3XF", */},
  /*::[*/0x0406 /*::]*/: {
    /* n:"Formula", */f: parse_Formula
  },
  /*::[*/0x0409 /*::]*/: {
    /* n:"BOF", */f: parse_BOF
  },
  /*::[*/0x0443 /*::]*/: {/* n:"BIFF4XF", */},
  /*::[*/0x086d /*::]*/: {/* n:"FeatInfo", */},
  /*::[*/0x0873 /*::]*/: {/* n:"FeatInfo11", */},
  /*::[*/0x0881 /*::]*/: {/* n:"SXAddl12", */},
  /*::[*/0x08c0 /*::]*/: {/* n:"AutoWebPub", */},
  /*::[*/0x08c1 /*::]*/: {/* n:"ListObj", */},
  /*::[*/0x08c2 /*::]*/: {/* n:"ListField", */},
  /*::[*/0x08c3 /*::]*/: {/* n:"ListDV", */},
  /*::[*/0x08c4 /*::]*/: {/* n:"ListCondFmt", */},
  /*::[*/0x08c5 /*::]*/: {/* n:"ListCF", */},
  /*::[*/0x08c6 /*::]*/: {/* n:"FMQry", */},
  /*::[*/0x08c7 /*::]*/: {/* n:"FMSQry", */},
  /*::[*/0x08c8 /*::]*/: {/* n:"PLV", */},
  /*::[*/0x08c9 /*::]*/: {/* n:"LnExt", */},
  /*::[*/0x08ca /*::]*/: {/* n:"MkrExt", */},
  /*::[*/0x08cb /*::]*/: {/* n:"CrtCoopt", */},
  /*::[*/0x08d6 /*::]*/: {
    /* n:"FRTArchId$", */r: 12
  },
  /*::[*/0x7262 /*::]*/: {}
};
function write_biff_rec(ba /*:BufArray*/, type /*:number*/, payload, length /*:?number*/) /*:void*/{
  var t /*:number*/ = type;
  if (isNaN(t)) return;
  var len = length || (payload || []).length || 0;
  var o = ba.next(4);
  o.write_shift(2, t);
  o.write_shift(2, len);
  if (/*:: len != null &&*/len > 0 && is_buf(payload)) ba.push(payload);
}
function write_biff_continue(ba /*:BufArray*/, type /*:number*/, payload, length /*:?number*/) /*:void*/{
  var len = length || (payload || []).length || 0;
  if (len <= 8224) return write_biff_rec(ba, type, payload, len);
  var t = type;
  if (isNaN(t)) return;
  var parts = payload.parts || [],
    sidx = 0;
  var i = 0,
    w = 0;
  while (w + (parts[sidx] || 8224) <= 8224) {
    w += parts[sidx] || 8224;
    sidx++;
  }
  var o = ba.next(4);
  o.write_shift(2, t);
  o.write_shift(2, w);
  ba.push(payload.slice(i, i + w));
  i += w;
  while (i < len) {
    o = ba.next(4);
    o.write_shift(2, 0x3c); // TODO: figure out correct continue type
    w = 0;
    while (w + (parts[sidx] || 8224) <= 8224) {
      w += parts[sidx] || 8224;
      sidx++;
    }
    o.write_shift(2, w);
    ba.push(payload.slice(i, i + w));
    i += w;
  }
}
function write_BIFF2Cell(out, r /*:number*/, c /*:number*/) {
  if (!out) out = new_buf(7);
  out.write_shift(2, r);
  out.write_shift(2, c);
  out.write_shift(2, 0);
  out.write_shift(1, 0);
  return out;
}
function write_BIFF2BERR(r /*:number*/, c /*:number*/, val, t /*:?string*/) {
  var out = new_buf(9);
  write_BIFF2Cell(out, r, c);
  write_Bes(val, t || 'b', out);
  return out;
}

/* TODO: codepage, large strings */
function write_BIFF2LABEL(r /*:number*/, c /*:number*/, val) {
  var out = new_buf(8 + 2 * val.length);
  write_BIFF2Cell(out, r, c);
  out.write_shift(1, val.length);
  out.write_shift(val.length, val, 'sbcs');
  return out.l < out.length ? out.slice(0, out.l) : out;
}
function write_ws_biff2_cell(ba /*:BufArray*/, cell /*:Cell*/, R /*:number*/, C /*:number*/ /*::, opts*/) {
  if (cell.v != null) switch (cell.t) {
    case 'd':
    case 'n':
      var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
      if (v == (v | 0) && v >= 0 && v < 65536) write_biff_rec(ba, 0x0002, write_BIFF2INT(R, C, v));else write_biff_rec(ba, 0x0003, write_BIFF2NUM(R, C, v));
      return;
    case 'b':
    case 'e':
      write_biff_rec(ba, 0x0005, write_BIFF2BERR(R, C, cell.v, cell.t));
      return;
    /* TODO: codepage, sst */
    case 's':
    case 'str':
      write_biff_rec(ba, 0x0004, write_BIFF2LABEL(R, C, (cell.v || "").slice(0, 255)));
      return;
  }
  write_biff_rec(ba, 0x0001, write_BIFF2Cell(null, R, C));
}
function write_ws_biff2(ba /*:BufArray*/, ws /*:Worksheet*/, idx /*:number*/, opts /*::, wb:Workbook*/) {
  var dense = Array.isArray(ws);
  var range = safe_decode_range(ws['!ref'] || "A1"),
    ref /*:string*/,
    rr = "",
    cols /*:Array<string>*/ = [];
  if (range.e.c > 0xFF || range.e.r > 0x3FFF) {
    if (opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
    range.e.c = Math.min(range.e.c, 0xFF);
    range.e.r = Math.min(range.e.c, 0x3FFF);
    ref = encode_range(range);
  }
  for (var R = range.s.r; R <= range.e.r; ++R) {
    rr = encode_row(R);
    for (var C = range.s.c; C <= range.e.c; ++C) {
      if (R === range.s.r) cols[C] = encode_col(C);
      ref = cols[C] + rr;
      var cell = dense ? (ws[R] || [])[C] : ws[ref];
      if (!cell) continue;
      /* write cell */
      write_ws_biff2_cell(ba, cell, R, C, opts);
    }
  }
}

/* Based on test files */
function write_biff2_buf(wb /*:Workbook*/, opts /*:WriteOpts*/) {
  var o = opts || {};
  if (DENSE != null && o.dense == null) o.dense = DENSE;
  var ba = buf_array();
  var idx = 0;
  for (var i = 0; i < wb.SheetNames.length; ++i) if (wb.SheetNames[i] == o.sheet) idx = i;
  if (idx == 0 && !!o.sheet && wb.SheetNames[0] != o.sheet) throw new Error("Sheet not found: " + o.sheet);
  write_biff_rec(ba, o.biff == 4 ? 0x0409 : o.biff == 3 ? 0x0209 : 0x0009, write_BOF(wb, 0x10, o));
  /* ... */
  write_ws_biff2(ba, wb.Sheets[wb.SheetNames[idx]], idx, o, wb);
  /* ... */
  write_biff_rec(ba, 0x000A);
  return ba.end();
}
function write_FONTS_biff8(ba, data, opts) {
  write_biff_rec(ba, 0x0031 /* Font */, write_Font({
    sz: 12,
    color: {
      theme: 1
    },
    name: "Arial",
    family: 2,
    scheme: "minor"
  }, opts));
}
function write_FMTS_biff8(ba, NF /*:?SSFTable*/, opts) {
  if (!NF) return;
  [[5, 8], [23, 26], [41, 44], [/*63*/50, /*66],[164,*/392]].forEach(function (r) {
    /*:: if(!NF) return; */
    for (var i = r[0]; i <= r[1]; ++i) if (NF[i] != null) write_biff_rec(ba, 0x041E /* Format */, write_Format(i, NF[i], opts));
  });
}
function write_FEAT(ba, ws) {
  /* [MS-XLS] 2.4.112 */
  var o = new_buf(19);
  o.write_shift(4, 0x867);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  o.write_shift(2, 3);
  o.write_shift(1, 1);
  o.write_shift(4, 0);
  write_biff_rec(ba, 0x0867 /* FeatHdr */, o);
  /* [MS-XLS] 2.4.111 */
  o = new_buf(39);
  o.write_shift(4, 0x868);
  o.write_shift(4, 0);
  o.write_shift(4, 0);
  o.write_shift(2, 3);
  o.write_shift(1, 0);
  o.write_shift(4, 0);
  o.write_shift(2, 1);
  o.write_shift(4, 4);
  o.write_shift(2, 0);
  write_Ref8U(safe_decode_range(ws['!ref'] || "A1"), o);
  o.write_shift(4, 4);
  write_biff_rec(ba, 0x0868 /* Feat */, o);
}
function write_CELLXFS_biff8(ba, opts) {
  for (var i = 0; i < 16; ++i) write_biff_rec(ba, 0x00e0 /* XF */, write_XF({
    numFmtId: 0,
    style: true
  }, 0, opts));
  opts.cellXfs.forEach(function (c) {
    write_biff_rec(ba, 0x00e0 /* XF */, write_XF(c, 0, opts));
  });
}
function write_ws_biff8_hlinks(ba /*:BufArray*/, ws) {
  for (var R = 0; R < ws['!links'].length; ++R) {
    var HL = ws['!links'][R];
    write_biff_rec(ba, 0x01b8 /* HLink */, write_HLink(HL));
    if (HL[1].Tooltip) write_biff_rec(ba, 0x0800 /* HLinkTooltip */, write_HLinkTooltip(HL));
  }
  delete ws['!links'];
}
function write_ws_cols_biff8(ba, cols) {
  if (!cols) return;
  var cnt = 0;
  cols.forEach(function (col, idx) {
    if (++cnt <= 256 && col) {
      write_biff_rec(ba, 0x007d /* ColInfo */, write_ColInfo(col_obj_w(idx, col), idx));
    }
  });
}
function write_ws_biff8_cell(ba /*:BufArray*/, cell /*:Cell*/, R /*:number*/, C /*:number*/, opts) {
  var os = 16 + get_cell_style(opts.cellXfs, cell, opts);
  if (cell.v == null && !cell.bf) {
    write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
    return;
  }
  if (cell.bf) write_biff_rec(ba, 0x0006 /* Formula */, write_Formula(cell, R, C, opts, os));else switch (cell.t) {
    case 'd':
    case 'n':
      var v = cell.t == 'd' ? datenum(parseDate(cell.v)) : cell.v;
      /* TODO: emit RK as appropriate */
      write_biff_rec(ba, 0x0203 /* Number */, write_Number(R, C, v, os, opts));
      break;
    case 'b':
    case 'e':
      write_biff_rec(ba, 0x0205 /* BoolErr */, write_BoolErr(R, C, cell.v, os, opts, cell.t));
      break;
    /* TODO: codepage, sst */
    case 's':
    case 'str':
      if (opts.bookSST) {
        var isst = get_sst_id(opts.Strings, cell.v, opts.revStrings);
        write_biff_rec(ba, 0x00fd /* LabelSst */, write_LabelSst(R, C, isst, os, opts));
      } else write_biff_rec(ba, 0x0204 /* Label */, write_Label(R, C, (cell.v || "").slice(0, 255), os, opts));
      break;
    default:
      write_biff_rec(ba, 0x0201 /* Blank */, write_XLSCell(R, C, os));
  }
}

/* [MS-XLS] 2.1.7.20.5 */
function write_ws_biff8(idx /*:number*/, opts, wb /*:Workbook*/) {
  var ba = buf_array();
  var s = wb.SheetNames[idx],
    ws = wb.Sheets[s] || {};
  var _WB /*:WBWBProps*/ = (wb || {}).Workbook || {} /*:any*/;
  var _sheet /*:WBWSProp*/ = (_WB.Sheets || [])[idx] || {} /*:any*/;
  var dense = Array.isArray(ws);
  var b8 = opts.biff == 8;
  var ref /*:string*/,
    rr = "",
    cols /*:Array<string>*/ = [];
  var range = safe_decode_range(ws['!ref'] || "A1");
  var MAX_ROWS = b8 ? 65536 : 16384;
  if (range.e.c > 0xFF || range.e.r >= MAX_ROWS) {
    if (opts.WTF) throw new Error("Range " + (ws['!ref'] || "A1") + " exceeds format limit A1:IV16384");
    range.e.c = Math.min(range.e.c, 0xFF);
    range.e.r = Math.min(range.e.c, MAX_ROWS - 1);
  }
  write_biff_rec(ba, 0x0809, write_BOF(wb, 0x10, opts));
  /* [Uncalced] Index */
  write_biff_rec(ba, 0x000d /* CalcMode */, writeuint16(1));
  write_biff_rec(ba, 0x000c /* CalcCount */, writeuint16(100));
  write_biff_rec(ba, 0x000f /* CalcRefMode */, writebool(true));
  write_biff_rec(ba, 0x0011 /* CalcIter */, writebool(false));
  write_biff_rec(ba, 0x0010 /* CalcDelta */, write_Xnum(0.001));
  write_biff_rec(ba, 0x005f /* CalcSaveRecalc */, writebool(true));
  write_biff_rec(ba, 0x002a /* PrintRowCol */, writebool(false));
  write_biff_rec(ba, 0x002b /* PrintGrid */, writebool(false));
  write_biff_rec(ba, 0x0082 /* GridSet */, writeuint16(1));
  write_biff_rec(ba, 0x0080 /* Guts */, write_Guts([0, 0]));
  /* DefaultRowHeight WsBool [Sync] [LPr] [HorizontalPageBreaks] [VerticalPageBreaks] */
  /* Header (string) */
  /* Footer (string) */
  write_biff_rec(ba, 0x0083 /* HCenter */, writebool(false));
  write_biff_rec(ba, 0x0084 /* VCenter */, writebool(false));
  /* ... */
  if (b8) write_ws_cols_biff8(ba, ws["!cols"]);
  /* ... */
  write_biff_rec(ba, 0x200, write_Dimensions(range, opts));
  /* ... */

  if (b8) ws['!links'] = [];
  for (var R = range.s.r; R <= range.e.r; ++R) {
    rr = encode_row(R);
    for (var C = range.s.c; C <= range.e.c; ++C) {
      if (R === range.s.r) cols[C] = encode_col(C);
      ref = cols[C] + rr;
      var cell = dense ? (ws[R] || [])[C] : ws[ref];
      if (!cell) continue;
      /* write cell */
      write_ws_biff8_cell(ba, cell, R, C, opts);
      if (b8 && cell.l) ws['!links'].push([ref, cell.l]);
    }
  }
  var cname /*:string*/ = _sheet.CodeName || _sheet.name || s;
  /* ... */
  if (b8) write_biff_rec(ba, 0x023e /* Window2 */, write_Window2((_WB.Views || [])[0]));
  /* ... */
  if (b8 && (ws['!merges'] || []).length) write_biff_rec(ba, 0x00e5 /* MergeCells */, write_MergeCells(ws['!merges']));
  /* [LRng] *QUERYTABLE [PHONETICINFO] CONDFMTS */
  if (b8) write_ws_biff8_hlinks(ba, ws);
  /* [DVAL] */
  write_biff_rec(ba, 0x01ba /* CodeName */, write_XLUnicodeString(cname, opts));
  /* *WebPub *CellWatch [SheetExt] */
  if (b8) write_FEAT(ba, ws);
  /* *FEAT11 *RECORD12 */
  write_biff_rec(ba, 0x000a /* EOF */);
  return ba.end();
}

/* [MS-XLS] 2.1.7.20.3 */
function write_biff8_global(wb /*:Workbook*/, bufs, opts /*:WriteOpts*/) {
  var A = buf_array();
  var _WB /*:WBWBProps*/ = (wb || {}).Workbook || {} /*:any*/;
  var _sheets /*:Array<WBWSProp>*/ = _WB.Sheets || [];
  var _wb /*:WBProps*/ = /*::((*/_WB.WBProps || {/*::CodeName:"ThisWorkbook"*/} /*:: ):any)*/;
  var b8 = opts.biff == 8,
    b5 = opts.biff == 5;
  write_biff_rec(A, 0x0809, write_BOF(wb, 0x05, opts));
  if (opts.bookType == "xla") write_biff_rec(A, 0x0087 /* Addin */);
  write_biff_rec(A, 0x00e1 /* InterfaceHdr */, b8 ? writeuint16(0x04b0) : null);
  write_biff_rec(A, 0x00c1 /* Mms */, writezeroes(2));
  if (b5) write_biff_rec(A, 0x00bf /* ToolbarHdr */);
  if (b5) write_biff_rec(A, 0x00c0 /* ToolbarEnd */);
  write_biff_rec(A, 0x00e2 /* InterfaceEnd */);
  write_biff_rec(A, 0x005c /* WriteAccess */, write_WriteAccess("SheetJS", opts));
  /* [FileSharing] */
  write_biff_rec(A, 0x0042 /* CodePage */, writeuint16(b8 ? 0x04b0 : 0x04E4));
  /* *2047 Lel */
  if (b8) write_biff_rec(A, 0x0161 /* DSF */, writeuint16(0));
  if (b8) write_biff_rec(A, 0x01c0 /* Excel9File */);
  write_biff_rec(A, 0x013d /* RRTabId */, write_RRTabId(wb.SheetNames.length));
  if (b8 && wb.vbaraw) write_biff_rec(A, 0x00d3 /* ObProj */);
  /* [ObNoMacros] */
  if (b8 && wb.vbaraw) {
    var cname /*:string*/ = _wb.CodeName || "ThisWorkbook";
    write_biff_rec(A, 0x01ba /* CodeName */, write_XLUnicodeString(cname, opts));
  }
  write_biff_rec(A, 0x009c /* BuiltInFnGroupCount */, writeuint16(0x11));
  /* *FnGroupName *FnGrp12 */
  /* *Lbl */
  /* [OleObjectSize] */
  write_biff_rec(A, 0x0019 /* WinProtect */, writebool(false));
  write_biff_rec(A, 0x0012 /* Protect */, writebool(false));
  write_biff_rec(A, 0x0013 /* Password */, writeuint16(0));
  if (b8) write_biff_rec(A, 0x01af /* Prot4Rev */, writebool(false));
  if (b8) write_biff_rec(A, 0x01bc /* Prot4RevPass */, writeuint16(0));
  write_biff_rec(A, 0x003d /* Window1 */, write_Window1(opts));
  write_biff_rec(A, 0x0040 /* Backup */, writebool(false));
  write_biff_rec(A, 0x008d /* HideObj */, writeuint16(0));
  write_biff_rec(A, 0x0022 /* Date1904 */, writebool(safe1904(wb) == "true"));
  write_biff_rec(A, 0x000e /* CalcPrecision */, writebool(true));
  if (b8) write_biff_rec(A, 0x01b7 /* RefreshAll */, writebool(false));
  write_biff_rec(A, 0x00DA /* BookBool */, writeuint16(0));
  /* ... */
  write_FONTS_biff8(A, wb, opts);
  write_FMTS_biff8(A, wb.SSF, opts);
  write_CELLXFS_biff8(A, opts);
  /* ... */
  if (b8) write_biff_rec(A, 0x0160 /* UsesELFs */, writebool(false));
  var a = A.end();
  var C = buf_array();
  /* METADATA [MTRSettings] [ForceFullCalculation] */
  if (b8) write_biff_rec(C, 0x008C, write_Country());
  /* *SUPBOOK *LBL *RTD [RecalcId] *HFPicture *MSODRAWINGGROUP */

  /* BIFF8: [SST *Continue] ExtSST */
  if (b8 && opts.Strings) write_biff_continue(C, 0x00FC, write_SST(opts.Strings, opts));

  /* *WebPub [WOpt] [CrErr] [BookExt] *FeatHdr *DConn [THEME] [CompressPictures] [Compat12] [GUIDTypeLib] */
  write_biff_rec(C, 0x000A /* EOF */);
  var c = C.end();
  var B = buf_array();
  var blen = 0,
    j = 0;
  for (j = 0; j < wb.SheetNames.length; ++j) blen += (b8 ? 12 : 11) + (b8 ? 2 : 1) * wb.SheetNames[j].length;
  var start = a.length + blen + c.length;
  for (j = 0; j < wb.SheetNames.length; ++j) {
    var _sheet /*:WBWSProp*/ = _sheets[j] || {} /*:any*/;
    write_biff_rec(B, 0x0085 /* BoundSheet8 */, write_BoundSheet8({
      pos: start,
      hs: _sheet.Hidden || 0,
      dt: 0,
      name: wb.SheetNames[j]
    }, opts));
    start += bufs[j].length;
  }
  /* 1*BoundSheet8 */
  var b = B.end();
  if (blen != b.length) throw new Error("BS8 " + blen + " != " + b.length);
  var out = [];
  if (a.length) out.push(a);
  if (b.length) out.push(b);
  if (c.length) out.push(c);
  return bconcat(out);
}

/* [MS-XLS] 2.1.7.20 Workbook Stream */
function write_biff8_buf(wb /*:Workbook*/, opts /*:WriteOpts*/) {
  var o = opts || {};
  var bufs = [];
  if (wb && !wb.SSF) {
    wb.SSF = dup(table_fmt);
  }
  if (wb && wb.SSF) {
    make_ssf();
    SSF_load_table(wb.SSF);
    // $FlowIgnore
    o.revssf = evert_num(wb.SSF);
    o.revssf[wb.SSF[65535]] = 0;
    o.ssf = wb.SSF;
  }
  o.Strings = /*::((*/[] /*:: :any):SST)*/;
  o.Strings.Count = 0;
  o.Strings.Unique = 0;
  fix_write_opts(o);
  o.cellXfs = [];
  get_cell_style(o.cellXfs, {}, {
    revssf: {
      "General": 0
    }
  });
  if (!wb.Props) wb.Props = {};
  for (var i = 0; i < wb.SheetNames.length; ++i) bufs[bufs.length] = write_ws_biff8(i, o, wb);
  bufs.unshift(write_biff8_global(wb, bufs, o));
  return bconcat(bufs);
}
function write_biff_buf(wb /*:Workbook*/, opts /*:WriteOpts*/) {
  for (var i = 0; i <= wb.SheetNames.length; ++i) {
    var ws = wb.Sheets[wb.SheetNames[i]];
    if (!ws || !ws["!ref"]) continue;
    var range = decode_range(ws["!ref"]);
    if (range.e.c > 255) {
      // note: 255 is IV
      if (typeof console != "undefined" && console.error) console.error("Worksheet '" + wb.SheetNames[i] + "' extends beyond column IV (255).  Data may be lost.");
    }
  }
  var o = opts || {};
  switch (o.biff || 2) {
    case 8:
    case 5:
      return write_biff8_buf(wb, opts);
    case 4:
    case 3:
    case 2:
      return write_biff2_buf(wb, opts);
  }
  throw new Error("invalid type " + o.bookType + " for BIFF");
}
/* note: browser DOM element cannot see mso- style attrs, must parse */
function html_to_sheet(str /*:string*/, _opts) /*:Workbook*/{
  var opts = _opts || {};
  if (DENSE != null && opts.dense == null) opts.dense = DENSE;
  var ws /*:Worksheet*/ = opts.dense ? [] /*:any*/ : {} /*:any*/;
  str = str.replace(/<!--.*?-->/g, "");
  var mtch /*:any*/ = str.match(/<table/i);
  if (!mtch) throw new Error("Invalid HTML: could not find <table>");
  var mtch2 /*:any*/ = str.match(/<\/table/i);
  var i /*:number*/ = mtch.index,
    j /*:number*/ = mtch2 && mtch2.index || str.length;
  var rows = split_regex(str.slice(i, j), /(:?<tr[^>]*>)/i, "<tr>");
  var R = -1,
    C = 0,
    RS = 0,
    CS = 0;
  var range /*:Range*/ = {
    s: {
      r: 10000000,
      c: 10000000
    },
    e: {
      r: 0,
      c: 0
    }
  };
  var merges /*:Array<Range>*/ = [];
  for (i = 0; i < rows.length; ++i) {
    var row = rows[i].trim();
    var hd = row.slice(0, 3).toLowerCase();
    if (hd == "<tr") {
      ++R;
      if (opts.sheetRows && opts.sheetRows <= R) {
        --R;
        break;
      }
      C = 0;
      continue;
    }
    if (hd != "<td" && hd != "<th") continue;
    var cells = row.split(/<\/t[dh]>/i);
    for (j = 0; j < cells.length; ++j) {
      var cell = cells[j].trim();
      if (!cell.match(/<t[dh]/i)) continue;
      var m = cell,
        cc = 0;
      /* TODO: parse styles etc */
      while (m.charAt(0) == "<" && (cc = m.indexOf(">")) > -1) m = m.slice(cc + 1);
      for (var midx = 0; midx < merges.length; ++midx) {
        var _merge /*:Range*/ = merges[midx];
        if (_merge.s.c == C && _merge.s.r < R && R <= _merge.e.r) {
          C = _merge.e.c + 1;
          midx = -1;
        }
      }
      var tag = parsexmltag(cell.slice(0, cell.indexOf(">")));
      CS = tag.colspan ? +tag.colspan : 1;
      if ((RS = +tag.rowspan) > 1 || CS > 1) merges.push({
        s: {
          r: R,
          c: C
        },
        e: {
          r: R + (RS || 1) - 1,
          c: C + CS - 1
        }
      });
      var _t /*:string*/ = tag.t || tag["data-t"] || "";
      /* TODO: generate stub cells */
      if (!m.length) {
        C += CS;
        continue;
      }
      m = htmldecode(m);
      if (range.s.r > R) range.s.r = R;
      if (range.e.r < R) range.e.r = R;
      if (range.s.c > C) range.s.c = C;
      if (range.e.c < C) range.e.c = C;
      if (!m.length) {
        C += CS;
        continue;
      }
      var o /*:Cell*/ = {
        t: 's',
        v: m
      };
      if (opts.raw || !m.trim().length || _t == 's') {} else if (m === 'TRUE') o = {
        t: 'b',
        v: true
      };else if (m === 'FALSE') o = {
        t: 'b',
        v: false
      };else if (!isNaN(fuzzynum(m))) o = {
        t: 'n',
        v: fuzzynum(m)
      };else if (!isNaN(fuzzydate(m).getDate())) {
        o = {
          t: 'd',
          v: parseDate(m)
        } /*:any*/;
        if (!opts.cellDates) o = {
          t: 'n',
          v: datenum(o.v)
        } /*:any*/;
        o.z = opts.dateNF || table_fmt[14];
      }
      if (opts.dense) {
        if (!ws[R]) ws[R] = [];
        ws[R][C] = o;
      } else ws[encode_cell({
        r: R,
        c: C
      })] = o;
      C += CS;
    }
  }
  ws['!ref'] = encode_range(range);
  if (merges.length) ws["!merges"] = merges;
  return ws;
}
function make_html_row(ws /*:Worksheet*/, r /*:Range*/, R /*:number*/, o /*:Sheet2HTMLOpts*/) /*:string*/{
  var M /*:Array<Range>*/ = ws['!merges'] || [];
  var oo /*:Array<string>*/ = [];
  for (var C = r.s.c; C <= r.e.c; ++C) {
    var RS = 0,
      CS = 0;
    for (var j = 0; j < M.length; ++j) {
      if (M[j].s.r > R || M[j].s.c > C) continue;
      if (M[j].e.r < R || M[j].e.c < C) continue;
      if (M[j].s.r < R || M[j].s.c < C) {
        RS = -1;
        break;
      }
      RS = M[j].e.r - M[j].s.r + 1;
      CS = M[j].e.c - M[j].s.c + 1;
      break;
    }
    if (RS < 0) continue;
    var coord = encode_cell({
      r: R,
      c: C
    });
    var cell = o.dense ? (ws[R] || [])[C] : ws[coord];
    /* TODO: html entities */
    var w = cell && cell.v != null && (cell.h || escapehtml(cell.w || (format_cell(cell), cell.w) || "")) || "";
    var sp = {} /*:any*/;
    if (RS > 1) sp.rowspan = RS;
    if (CS > 1) sp.colspan = CS;
    if (o.editable) w = '<span contenteditable="true">' + w + '</span>';else if (cell) {
      sp["data-t"] = cell && cell.t || 'z';
      if (cell.v != null) sp["data-v"] = cell.v;
      if (cell.z != null) sp["data-z"] = cell.z;
      if (cell.l && (cell.l.Target || "#").charAt(0) != "#") w = '<a href="' + cell.l.Target + '">' + w + '</a>';
    }
    sp.id = (o.id || "sjs") + "-" + coord;
    oo.push(writextag('td', w, sp));
  }
  var preamble = "<tr>";
  return preamble + oo.join("") + "</tr>";
}
var HTML_BEGIN = '<html><head><meta charset="utf-8"/><title>SheetJS Table Export</title></head><body>';
var HTML_END = '</body></html>';
function html_to_workbook(str /*:string*/, opts) /*:Workbook*/{
  var mtch = str.match(/<table[\s\S]*?>[\s\S]*?<\/table>/gi);
  if (!mtch || mtch.length == 0) throw new Error("Invalid HTML: could not find <table>");
  if (mtch.length == 1) return sheet_to_workbook(html_to_sheet(mtch[0], opts), opts);
  var wb = book_new();
  mtch.forEach(function (s, idx) {
    book_append_sheet(wb, html_to_sheet(s, opts), "Sheet" + (idx + 1));
  });
  return wb;
}
function make_html_preamble(ws /*:Worksheet*/, R /*:Range*/, o /*:Sheet2HTMLOpts*/) /*:string*/{
  var out /*:Array<string>*/ = [];
  return out.join("") + '<table' + (o && o.id ? ' id="' + o.id + '"' : "") + '>';
}
function sheet_to_html(ws /*:Worksheet*/, opts /*:?Sheet2HTMLOpts*/ /*, wb:?Workbook*/) /*:string*/{
  var o = opts || {};
  var header = o.header != null ? o.header : HTML_BEGIN;
  var footer = o.footer != null ? o.footer : HTML_END;
  var out /*:Array<string>*/ = [header];
  var r = decode_range(ws['!ref']);
  o.dense = Array.isArray(ws);
  out.push(make_html_preamble(ws, r, o));
  for (var R = r.s.r; R <= r.e.r; ++R) out.push(make_html_row(ws, r, R, o));
  out.push("</table>" + footer);
  return out.join("");
}
function sheet_add_dom(ws /*:Worksheet*/, table /*:HTMLElement*/, _opts /*:?any*/) /*:Worksheet*/{
  var opts = _opts || {};
  if (DENSE != null) opts.dense = DENSE;
  var or_R = 0,
    or_C = 0;
  if (opts.origin != null) {
    if (typeof opts.origin == 'number') or_R = opts.origin;else {
      var _origin /*:CellAddress*/ = typeof opts.origin == "string" ? decode_cell(opts.origin) : opts.origin;
      or_R = _origin.r;
      or_C = _origin.c;
    }
  }
  var rows /*:HTMLCollection<HTMLTableRowElement>*/ = table.getElementsByTagName('tr');
  var sheetRows = Math.min(opts.sheetRows || 10000000, rows.length);
  var range /*:Range*/ = {
    s: {
      r: 0,
      c: 0
    },
    e: {
      r: or_R,
      c: or_C
    }
  };
  if (ws["!ref"]) {
    var _range /*:Range*/ = decode_range(ws["!ref"]);
    range.s.r = Math.min(range.s.r, _range.s.r);
    range.s.c = Math.min(range.s.c, _range.s.c);
    range.e.r = Math.max(range.e.r, _range.e.r);
    range.e.c = Math.max(range.e.c, _range.e.c);
    if (or_R == -1) range.e.r = or_R = _range.e.r + 1;
  }
  var merges /*:Array<Range>*/ = [],
    midx = 0;
  var rowinfo /*:Array<RowInfo>*/ = ws["!rows"] || (ws["!rows"] = []);
  var _R = 0,
    R = 0,
    _C = 0,
    C = 0,
    RS = 0,
    CS = 0;
  if (!ws["!cols"]) ws['!cols'] = [];
  for (; _R < rows.length && R < sheetRows; ++_R) {
    var row /*:HTMLTableRowElement*/ = rows[_R];
    if (is_dom_element_hidden(row)) {
      if (opts.display) continue;
      rowinfo[R] = {
        hidden: true
      };
    }
    var elts /*:HTMLCollection<HTMLTableCellElement>*/ = row.children /*:any*/;
    for (_C = C = 0; _C < elts.length; ++_C) {
      var elt /*:HTMLTableCellElement*/ = elts[_C];
      if (opts.display && is_dom_element_hidden(elt)) continue;
      var v /*:?string*/ = elt.hasAttribute('data-v') ? elt.getAttribute('data-v') : elt.hasAttribute('v') ? elt.getAttribute('v') : htmldecode(elt.innerHTML);
      var z /*:?string*/ = elt.getAttribute('data-z') || elt.getAttribute('z');
      for (midx = 0; midx < merges.length; ++midx) {
        var m /*:Range*/ = merges[midx];
        if (m.s.c == C + or_C && m.s.r < R + or_R && R + or_R <= m.e.r) {
          C = m.e.c + 1 - or_C;
          midx = -1;
        }
      }
      /* TODO: figure out how to extract nonstandard mso- style */
      CS = +elt.getAttribute("colspan") || 1;
      if ((RS = +elt.getAttribute("rowspan") || 1) > 1 || CS > 1) merges.push({
        s: {
          r: R + or_R,
          c: C + or_C
        },
        e: {
          r: R + or_R + (RS || 1) - 1,
          c: C + or_C + (CS || 1) - 1
        }
      });
      var o /*:Cell*/ = {
        t: 's',
        v: v
      };
      var _t /*:string*/ = elt.getAttribute("data-t") || elt.getAttribute("t") || "";
      if (v != null) {
        if (v.length == 0) o.t = _t || 'z';else if (opts.raw || v.trim().length == 0 || _t == "s") {} else if (v === 'TRUE') o = {
          t: 'b',
          v: true
        };else if (v === 'FALSE') o = {
          t: 'b',
          v: false
        };else if (!isNaN(fuzzynum(v))) o = {
          t: 'n',
          v: fuzzynum(v)
        };else if (!isNaN(fuzzydate(v).getDate())) {
          o = {
            t: 'd',
            v: parseDate(v)
          } /*:any*/;
          if (!opts.cellDates) o = {
            t: 'n',
            v: datenum(o.v)
          } /*:any*/;
          o.z = opts.dateNF || table_fmt[14];
        }
      }
      if (o.z === undefined && z != null) o.z = z;
      /* The first link is used.  Links are assumed to be fully specified.
       * TODO: The right way to process relative links is to make a new <a> */
      var l = "",
        Aelts = elt.getElementsByTagName("A");
      if (Aelts && Aelts.length) for (var Aelti = 0; Aelti < Aelts.length; ++Aelti) if (Aelts[Aelti].hasAttribute("href")) {
        l = Aelts[Aelti].getAttribute("href");
        if (l.charAt(0) != "#") break;
      }
      if (l && l.charAt(0) != "#") o.l = {
        Target: l
      };
      if (opts.dense) {
        if (!ws[R + or_R]) ws[R + or_R] = [];
        ws[R + or_R][C + or_C] = o;
      } else ws[encode_cell({
        c: C + or_C,
        r: R + or_R
      })] = o;
      if (range.e.c < C + or_C) range.e.c = C + or_C;
      C += CS;
    }
    ++R;
  }
  if (merges.length) ws['!merges'] = (ws["!merges"] || []).concat(merges);
  range.e.r = Math.max(range.e.r, R - 1 + or_R);
  ws['!ref'] = encode_range(range);
  if (R >= sheetRows) ws['!fullref'] = encode_range((range.e.r = rows.length - _R + R - 1 + or_R, range)); // We can count the real number of rows to parse but we don't to improve the performance
  return ws;
}
function parse_dom_table(table /*:HTMLElement*/, _opts /*:?any*/) /*:Worksheet*/{
  var opts = _opts || {};
  var ws /*:Worksheet*/ = opts.dense ? [] /*:any*/ : {} /*:any*/;
  return sheet_add_dom(ws, table, _opts);
}
function table_to_book(table /*:HTMLElement*/, opts /*:?any*/) /*:Workbook*/{
  return sheet_to_workbook(parse_dom_table(table, opts), opts);
}
function is_dom_element_hidden(element /*:HTMLElement*/) /*:boolean*/{
  var display /*:string*/ = '';
  var get_computed_style /*:?function*/ = get_get_computed_style_function(element);
  if (get_computed_style) display = get_computed_style(element).getPropertyValue('display');
  if (!display) display = element.style && element.style.display;
  return display === 'none';
}

/* global getComputedStyle */
function get_get_computed_style_function(element /*:HTMLElement*/) /*:?function*/{
  // The proper getComputedStyle implementation is the one defined in the element window
  if (element.ownerDocument.defaultView && typeof element.ownerDocument.defaultView.getComputedStyle === 'function') return element.ownerDocument.defaultView.getComputedStyle;
  // If it is not available, try to get one from the global namespace
  if (typeof getComputedStyle === 'function') return getComputedStyle;
  return null;
}
/* OpenDocument */
function parse_text_p(text /*:string*/ /*::, tag*/) /*:Array<any>*/{
  /* 6.1.2 White Space Characters */
  var fixed = text.replace(/[\t\r\n]/g, " ").trim().replace(/ +/g, " ").replace(/<text:s\/>/g, " ").replace(/<text:s text:c="(\d+)"\/>/g, function ($$, $1) {
    return Array(parseInt($1, 10) + 1).join(" ");
  }).replace(/<text:tab[^>]*\/>/g, "\t").replace(/<text:line-break\/>/g, "\n");
  var v = unescapexml(fixed.replace(/<[^>]*>/g, ""));
  return [v];
}
var number_formats_ods = {
  /* ods name: [short ssf fmt, long ssf fmt] */
  day: ["d", "dd"],
  month: ["m", "mm"],
  year: ["y", "yy"],
  hours: ["h", "hh"],
  minutes: ["m", "mm"],
  seconds: ["s", "ss"],
  "am-pm": ["A/P", "AM/PM"],
  "day-of-week": ["ddd", "dddd"],
  era: ["e", "ee"],
  /* there is no native representation of LO "Q" format */
  quarter: ["\\Qm", "m\\\"th quarter\""]
};
function parse_content_xml(d /*:string*/, _opts) /*:Workbook*/{
  var opts = _opts || {};
  if (DENSE != null && opts.dense == null) opts.dense = DENSE;
  var str = xlml_normalize(d);
  var state /*:Array<any>*/ = [],
    tmp;
  var tag /*:: = {}*/;
  var NFtag = {
      name: ""
    },
    NF = "",
    pidx = 0;
  var sheetag /*:: = {name:"", '名称':""}*/;
  var rowtag /*:: = {'行号':""}*/;
  var Sheets = {},
    SheetNames /*:Array<string>*/ = [];
  var ws = opts.dense ? [] /*:any*/ : {} /*:any*/;
  var Rn, q /*:: :any = ({t:"", v:null, z:null, w:"",c:[],}:any)*/;
  var ctag = {
    value: ""
  } /*:any*/;
  var textp = "",
    textpidx = 0,
    textptag /*:: = {}*/;
  var textR = [];
  var R = -1,
    C = -1,
    range = {
      s: {
        r: 1000000,
        c: 10000000
      },
      e: {
        r: 0,
        c: 0
      }
    };
  var row_ol = 0;
  var number_format_map = {};
  var merges /*:Array<Range>*/ = [],
    mrange = {},
    mR = 0,
    mC = 0;
  var rowinfo /*:Array<RowInfo>*/ = [],
    rowpeat = 1,
    colpeat = 1;
  var arrayf /*:Array<[Range, string]>*/ = [];
  var WB = {
    Names: []
  };
  var atag = {} /*:any*/;
  var _Ref /*:[string, string]*/ = ["", ""];
  var comments /*:Array<Comment>*/ = [],
    comment /*:Comment*/ = {} /*:any*/;
  var creator = "",
    creatoridx = 0;
  var isstub = false,
    intable = false;
  var i = 0;
  xlmlregex.lastIndex = 0;
  str = str.replace(/<!--([\s\S]*?)-->/mg, "").replace(/<!DOCTYPE[^\[]*\[[^\]]*\]>/gm, "");
  while (Rn = xlmlregex.exec(str)) switch (Rn[3] = Rn[3].replace(/_.*$/, "")) {
    case 'table':
    case '工作表':
      // 9.1.2 <table:table>
      if (Rn[1] === '/') {
        if (range.e.c >= range.s.c && range.e.r >= range.s.r) ws['!ref'] = encode_range(range);else ws['!ref'] = "A1:A1";
        if (opts.sheetRows > 0 && opts.sheetRows <= range.e.r) {
          ws['!fullref'] = ws['!ref'];
          range.e.r = opts.sheetRows - 1;
          ws['!ref'] = encode_range(range);
        }
        if (merges.length) ws['!merges'] = merges;
        if (rowinfo.length) ws["!rows"] = rowinfo;
        sheetag.name = sheetag['名称'] || sheetag.name;
        if (typeof JSON !== 'undefined') JSON.stringify(sheetag);
        SheetNames.push(sheetag.name);
        Sheets[sheetag.name] = ws;
        intable = false;
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') {
        sheetag = parsexmltag(Rn[0], false);
        R = C = -1;
        range.s.r = range.s.c = 10000000;
        range.e.r = range.e.c = 0;
        ws = opts.dense ? [] /*:any*/ : {} /*:any*/;
        merges = [];
        rowinfo = [];
        intable = true;
      }
      break;
    case 'table-row-group':
      // 9.1.9 <table:table-row-group>
      if (Rn[1] === "/") --row_ol;else ++row_ol;
      break;
    case 'table-row':
    case '行':
      // 9.1.3 <table:table-row>
      if (Rn[1] === '/') {
        R += rowpeat;
        rowpeat = 1;
        break;
      }
      rowtag = parsexmltag(Rn[0], false);
      if (rowtag['行号']) R = rowtag['行号'] - 1;else if (R == -1) R = 0;
      rowpeat = +rowtag['number-rows-repeated'] || 1;
      /* TODO: remove magic */
      if (rowpeat < 10) for (i = 0; i < rowpeat; ++i) if (row_ol > 0) rowinfo[R + i] = {
        level: row_ol
      };
      C = -1;
      break;
    case 'covered-table-cell':
      // 9.1.5 <table:covered-table-cell>
      if (Rn[1] !== '/') ++C;
      if (opts.sheetStubs) {
        if (opts.dense) {
          if (!ws[R]) ws[R] = [];
          ws[R][C] = {
            t: 'z'
          };
        } else ws[encode_cell({
          r: R,
          c: C
        })] = {
          t: 'z'
        };
      }
      textp = "";
      textR = [];
      break;
    /* stub */
    case 'table-cell':
    case '数据':
      if (Rn[0].charAt(Rn[0].length - 2) === '/') {
        ++C;
        ctag = parsexmltag(Rn[0], false);
        colpeat = parseInt(ctag['number-columns-repeated'] || "1", 10);
        q = {
          t: 'z',
          v: null /*:: , z:null, w:"",c:[]*/
        } /*:any*/;
        if (ctag.formula && opts.cellFormula != false) q.f = ods_to_csf_formula(unescapexml(ctag.formula));
        if ((ctag['数据类型'] || ctag['value-type']) == "string") {
          q.t = "s";
          q.v = unescapexml(ctag['string-value'] || "");
          if (opts.dense) {
            if (!ws[R]) ws[R] = [];
            ws[R][C] = q;
          } else {
            ws[encode_cell({
              r: R,
              c: C
            })] = q;
          }
        }
        C += colpeat - 1;
      } else if (Rn[1] !== '/') {
        ++C;
        textp = "";
        textpidx = 0;
        textR = [];
        colpeat = 1;
        var rptR = rowpeat ? R + rowpeat - 1 : R;
        if (C > range.e.c) range.e.c = C;
        if (C < range.s.c) range.s.c = C;
        if (R < range.s.r) range.s.r = R;
        if (rptR > range.e.r) range.e.r = rptR;
        ctag = parsexmltag(Rn[0], false);
        comments = [];
        comment = {} /*:any*/;
        q = {
          t: ctag['数据类型'] || ctag['value-type'],
          v: null /*:: , z:null, w:"",c:[]*/
        } /*:any*/;
        if (opts.cellFormula) {
          if (ctag.formula) ctag.formula = unescapexml(ctag.formula);
          if (ctag['number-matrix-columns-spanned'] && ctag['number-matrix-rows-spanned']) {
            mR = parseInt(ctag['number-matrix-rows-spanned'], 10) || 0;
            mC = parseInt(ctag['number-matrix-columns-spanned'], 10) || 0;
            mrange = {
              s: {
                r: R,
                c: C
              },
              e: {
                r: R + mR - 1,
                c: C + mC - 1
              }
            };
            q.F = encode_range(mrange);
            arrayf.push([mrange, q.F]);
          }
          if (ctag.formula) q.f = ods_to_csf_formula(ctag.formula);else for (i = 0; i < arrayf.length; ++i) if (R >= arrayf[i][0].s.r && R <= arrayf[i][0].e.r) if (C >= arrayf[i][0].s.c && C <= arrayf[i][0].e.c) q.F = arrayf[i][1];
        }
        if (ctag['number-columns-spanned'] || ctag['number-rows-spanned']) {
          mR = parseInt(ctag['number-rows-spanned'], 10) || 0;
          mC = parseInt(ctag['number-columns-spanned'], 10) || 0;
          mrange = {
            s: {
              r: R,
              c: C
            },
            e: {
              r: R + mR - 1,
              c: C + mC - 1
            }
          };
          merges.push(mrange);
        }

        /* 19.675.2 table:number-columns-repeated */
        if (ctag['number-columns-repeated']) colpeat = parseInt(ctag['number-columns-repeated'], 10);

        /* 19.385 office:value-type */
        switch (q.t) {
          case 'boolean':
            q.t = 'b';
            q.v = parsexmlbool(ctag['boolean-value']);
            break;
          case 'float':
            q.t = 'n';
            q.v = parseFloat(ctag.value);
            break;
          case 'percentage':
            q.t = 'n';
            q.v = parseFloat(ctag.value);
            break;
          case 'currency':
            q.t = 'n';
            q.v = parseFloat(ctag.value);
            break;
          case 'date':
            q.t = 'd';
            q.v = parseDate(ctag['date-value']);
            if (!opts.cellDates) {
              q.t = 'n';
              q.v = datenum(q.v);
            }
            q.z = 'm/d/yy';
            break;
          case 'time':
            q.t = 'n';
            q.v = parse_isodur(ctag['time-value']) / 86400;
            if (opts.cellDates) {
              q.t = 'd';
              q.v = numdate(q.v);
            }
            q.z = 'HH:MM:SS';
            break;
          case 'number':
            q.t = 'n';
            q.v = parseFloat(ctag['数据数值']);
            break;
          default:
            if (q.t === 'string' || q.t === 'text' || !q.t) {
              q.t = 's';
              if (ctag['string-value'] != null) {
                textp = unescapexml(ctag['string-value']);
                textR = [];
              }
            } else throw new Error('Unsupported value type ' + q.t);
        }
      } else {
        isstub = false;
        if (q.t === 's') {
          q.v = textp || '';
          if (textR.length) q.R = textR;
          isstub = textpidx == 0;
        }
        if (atag.Target) q.l = atag;
        if (comments.length > 0) {
          q.c = comments;
          comments = [];
        }
        if (textp && opts.cellText !== false) q.w = textp;
        if (isstub) {
          q.t = "z";
          delete q.v;
        }
        if (!isstub || opts.sheetStubs) {
          if (!(opts.sheetRows && opts.sheetRows <= R)) {
            for (var rpt = 0; rpt < rowpeat; ++rpt) {
              colpeat = parseInt(ctag['number-columns-repeated'] || "1", 10);
              if (opts.dense) {
                if (!ws[R + rpt]) ws[R + rpt] = [];
                ws[R + rpt][C] = rpt == 0 ? q : dup(q);
                while (--colpeat > 0) ws[R + rpt][C + colpeat] = dup(q);
              } else {
                ws[encode_cell({
                  r: R + rpt,
                  c: C
                })] = q;
                while (--colpeat > 0) ws[encode_cell({
                  r: R + rpt,
                  c: C + colpeat
                })] = dup(q);
              }
              if (range.e.c <= C) range.e.c = C;
            }
          }
        }
        colpeat = parseInt(ctag['number-columns-repeated'] || "1", 10);
        C += colpeat - 1;
        colpeat = 0;
        q = {/*:: t:"", v:null, z:null, w:"",c:[]*/};
        textp = "";
        textR = [];
      }
      atag = {} /*:any*/;
      break;
    // 9.1.4 <table:table-cell>

    /* pure state */
    case 'document': // TODO: <office:document> is the root for FODS
    case 'document-content':
    case '电子表格文档': // 3.1.3.2 <office:document-content>
    case 'spreadsheet':
    case '主体': // 3.7 <office:spreadsheet>
    case 'scripts': // 3.12 <office:scripts>
    case 'styles': // TODO <office:styles>
    case 'font-face-decls': // 3.14 <office:font-face-decls>
    case 'master-styles':
      // 3.15.4 <office:master-styles> -- relevant for FODS
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw "Bad state: " + tmp;
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') state.push([Rn[3], true]);
      break;
    case 'annotation':
      // 14.1 <office:annotation>
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw "Bad state: " + tmp;
        comment.t = textp;
        if (textR.length) /*::(*/comment /*:: :any)*/.R = textR;
        comment.a = creator;
        comments.push(comment);
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') {
        state.push([Rn[3], false]);
      }
      creator = "";
      creatoridx = 0;
      textp = "";
      textpidx = 0;
      textR = [];
      break;
    case 'creator':
      // 4.3.2.7 <dc:creator>
      if (Rn[1] === '/') {
        creator = str.slice(creatoridx, Rn.index);
      } else creatoridx = Rn.index + Rn[0].length;
      break;

    /* ignore state */
    case 'meta':
    case '元数据': // TODO: <office:meta> <uof:元数据> FODS/UOF
    case 'settings': // TODO: <office:settings>
    case 'config-item-set': // TODO: <office:config-item-set>
    case 'config-item-map-indexed': // TODO: <office:config-item-map-indexed>
    case 'config-item-map-entry': // TODO: <office:config-item-map-entry>
    case 'config-item-map-named': // TODO: <office:config-item-map-entry>
    case 'shapes': // 9.2.8 <table:shapes>
    case 'frame': // 10.4.2 <draw:frame>
    case 'text-box': // 10.4.3 <draw:text-box>
    case 'image': // 10.4.4 <draw:image>
    case 'data-pilot-tables': // 9.6.2 <table:data-pilot-tables>
    case 'list-style': // 16.30 <text:list-style>
    case 'form': // 13.13 <form:form>
    case 'dde-links': // 9.8 <table:dde-links>
    case 'event-listeners': // TODO
    case 'chart':
      // TODO
      if (Rn[1] === '/') {
        if ((tmp = state.pop())[0] !== Rn[3]) throw "Bad state: " + tmp;
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') state.push([Rn[3], false]);
      textp = "";
      textpidx = 0;
      textR = [];
      break;
    case 'scientific-number':
      // TODO: <number:scientific-number>
      break;
    case 'currency-symbol':
      // TODO: <number:currency-symbol>
      break;
    case 'currency-style':
      // TODO: <number:currency-style>
      break;
    case 'number-style': // 16.27.2 <number:number-style>
    case 'percentage-style': // 16.27.9 <number:percentage-style>
    case 'date-style': // 16.27.10 <number:date-style>
    case 'time-style':
      // 16.27.18 <number:time-style>
      if (Rn[1] === '/') {
        number_format_map[NFtag.name] = NF;
        if ((tmp = state.pop())[0] !== Rn[3]) throw "Bad state: " + tmp;
      } else if (Rn[0].charAt(Rn[0].length - 2) !== '/') {
        NF = "";
        NFtag = parsexmltag(Rn[0], false);
        state.push([Rn[3], true]);
      }
      break;
    case 'script':
      break;
    // 3.13 <office:script>
    case 'libraries':
      break;
    // TODO: <ooo:libraries>
    case 'automatic-styles':
      break;
    // 3.15.3 <office:automatic-styles>

    case 'default-style': // TODO: <style:default-style>
    case 'page-layout':
      break;
    // TODO: <style:page-layout>
    case 'style':
      // 16.2 <style:style>
      break;
    case 'map':
      break;
    // 16.3 <style:map>
    case 'font-face':
      break;
    // 16.21 <style:font-face>

    case 'paragraph-properties':
      break;
    // 17.6 <style:paragraph-properties>
    case 'table-properties':
      break;
    // 17.15 <style:table-properties>
    case 'table-column-properties':
      break;
    // 17.16 <style:table-column-properties>
    case 'table-row-properties':
      break;
    // 17.17 <style:table-row-properties>
    case 'table-cell-properties':
      break;
    // 17.18 <style:table-cell-properties>

    case 'number':
      // 16.27.3 <number:number>
      switch (state[state.length - 1][0]) {
        case 'time-style':
        case 'date-style':
          tag = parsexmltag(Rn[0], false);
          NF += number_formats_ods[Rn[3]][tag.style === 'long' ? 1 : 0];
          break;
      }
      break;
    case 'fraction':
      break;
    // TODO 16.27.6 <number:fraction>

    case 'day': // 16.27.11 <number:day>
    case 'month': // 16.27.12 <number:month>
    case 'year': // 16.27.13 <number:year>
    case 'era': // 16.27.14 <number:era>
    case 'day-of-week': // 16.27.15 <number:day-of-week>
    case 'week-of-year': // 16.27.16 <number:week-of-year>
    case 'quarter': // 16.27.17 <number:quarter>
    case 'hours': // 16.27.19 <number:hours>
    case 'minutes': // 16.27.20 <number:minutes>
    case 'seconds': // 16.27.21 <number:seconds>
    case 'am-pm':
      // 16.27.22 <number:am-pm>
      switch (state[state.length - 1][0]) {
        case 'time-style':
        case 'date-style':
          tag = parsexmltag(Rn[0], false);
          NF += number_formats_ods[Rn[3]][tag.style === 'long' ? 1 : 0];
          break;
      }
      break;
    case 'boolean-style':
      break;
    // 16.27.23 <number:boolean-style>
    case 'boolean':
      break;
    // 16.27.24 <number:boolean>
    case 'text-style':
      break;
    // 16.27.25 <number:text-style>
    case 'text':
      // 16.27.26 <number:text>
      if (Rn[0].slice(-2) === "/>") break;else if (Rn[1] === "/") switch (state[state.length - 1][0]) {
        case 'number-style':
        case 'date-style':
        case 'time-style':
          NF += str.slice(pidx, Rn.index);
          break;
      } else pidx = Rn.index + Rn[0].length;
      break;
    case 'named-range':
      // 9.4.12 <table:named-range>
      tag = parsexmltag(Rn[0], false);
      _Ref = ods_to_csf_3D(tag['cell-range-address']);
      var nrange = {
        Name: tag.name,
        Ref: _Ref[0] + '!' + _Ref[1]
      } /*:any*/;
      if (intable) nrange.Sheet = SheetNames.length;
      WB.Names.push(nrange);
      break;
    case 'text-content':
      break;
    // 16.27.27 <number:text-content>
    case 'text-properties':
      break;
    // 16.27.27 <style:text-properties>
    case 'embedded-text':
      break;
    // 16.27.4 <number:embedded-text>

    case 'body':
    case '电子表格':
      break;
    // 3.3 16.9.6 19.726.3

    case 'forms':
      break;
    // 12.25.2 13.2
    case 'table-column':
      break;
    // 9.1.6 <table:table-column>
    case 'table-header-rows':
      break;
    // 9.1.7 <table:table-header-rows>
    case 'table-rows':
      break;
    // 9.1.12 <table:table-rows>
    /* TODO: outline levels */
    case 'table-column-group':
      break;
    // 9.1.10 <table:table-column-group>
    case 'table-header-columns':
      break;
    // 9.1.11 <table:table-header-columns>
    case 'table-columns':
      break;
    // 9.1.12 <table:table-columns>

    case 'null-date':
      break;
    // 9.4.2 <table:null-date> TODO: date1904

    case 'graphic-properties':
      break;
    // 17.21 <style:graphic-properties>
    case 'calculation-settings':
      break;
    // 9.4.1 <table:calculation-settings>
    case 'named-expressions':
      break;
    // 9.4.11 <table:named-expressions>
    case 'label-range':
      break;
    // 9.4.9 <table:label-range>
    case 'label-ranges':
      break;
    // 9.4.10 <table:label-ranges>
    case 'named-expression':
      break;
    // 9.4.13 <table:named-expression>
    case 'sort':
      break;
    // 9.4.19 <table:sort>
    case 'sort-by':
      break;
    // 9.4.20 <table:sort-by>
    case 'sort-groups':
      break;
    // 9.4.22 <table:sort-groups>

    case 'tab':
      break;
    // 6.1.4 <text:tab>
    case 'line-break':
      break;
    // 6.1.5 <text:line-break>
    case 'span':
      break;
    // 6.1.7 <text:span>
    case 'p':
    case '文本串':
      // 5.1.3 <text:p>
      if (['master-styles'].indexOf(state[state.length - 1][0]) > -1) break;
      if (Rn[1] === '/' && (!ctag || !ctag['string-value'])) {
        var ptp = parse_text_p(str.slice(textpidx, Rn.index), textptag);
        textp = (textp.length > 0 ? textp + "\n" : "") + ptp[0];
      } else {
        textptag = parsexmltag(Rn[0], false);
        textpidx = Rn.index + Rn[0].length;
      }
      break;
    // <text:p>
    case 's':
      break;
    // <text:s>

    case 'database-range':
      // 9.4.15 <table:database-range>
      if (Rn[1] === '/') break;
      try {
        _Ref = ods_to_csf_3D(parsexmltag(Rn[0])['target-range-address']);
        Sheets[_Ref[0]]['!autofilter'] = {
          ref: _Ref[1]
        };
      } catch (e) {/* empty */}
      break;
    case 'date':
      break;
    // <*:date>

    case 'object':
      break;
    // 10.4.6.2 <draw:object>
    case 'title':
    case '标题':
      break;
    // <*:title> OR <uof:标题>
    case 'desc':
      break;
    // <*:desc>
    case 'binary-data':
      break;
    // 10.4.5 TODO: b64 blob

    /* 9.2 Advanced Tables */
    case 'table-source':
      break;
    // 9.2.6
    case 'scenario':
      break;
    // 9.2.6

    case 'iteration':
      break;
    // 9.4.3 <table:iteration>
    case 'content-validations':
      break;
    // 9.4.4 <table:
    case 'content-validation':
      break;
    // 9.4.5 <table:
    case 'help-message':
      break;
    // 9.4.6 <table:
    case 'error-message':
      break;
    // 9.4.7 <table:
    case 'database-ranges':
      break;
    // 9.4.14 <table:database-ranges>
    case 'filter':
      break;
    // 9.5.2 <table:filter>
    case 'filter-and':
      break;
    // 9.5.3 <table:filter-and>
    case 'filter-or':
      break;
    // 9.5.4 <table:filter-or>
    case 'filter-condition':
      break;
    // 9.5.5 <table:filter-condition>

    case 'list-level-style-bullet':
      break;
    // 16.31 <text:
    case 'list-level-style-number':
      break;
    // 16.32 <text:
    case 'list-level-properties':
      break;
    // 17.19 <style:

    /* 7.3 Document Fields */
    case 'sender-firstname': // 7.3.6.2
    case 'sender-lastname': // 7.3.6.3
    case 'sender-initials': // 7.3.6.4
    case 'sender-title': // 7.3.6.5
    case 'sender-position': // 7.3.6.6
    case 'sender-email': // 7.3.6.7
    case 'sender-phone-private': // 7.3.6.8
    case 'sender-fax': // 7.3.6.9
    case 'sender-company': // 7.3.6.10
    case 'sender-phone-work': // 7.3.6.11
    case 'sender-street': // 7.3.6.12
    case 'sender-city': // 7.3.6.13
    case 'sender-postal-code': // 7.3.6.14
    case 'sender-country': // 7.3.6.15
    case 'sender-state-or-province': // 7.3.6.16
    case 'author-name': // 7.3.7.1
    case 'author-initials': // 7.3.7.2
    case 'chapter': // 7.3.8
    case 'file-name': // 7.3.9
    case 'template-name': // 7.3.9
    case 'sheet-name':
      // 7.3.9
      break;
    case 'event-listener':
      break;
    /* TODO: FODS Properties */
    case 'initial-creator':
    case 'creation-date':
    case 'print-date':
    case 'generator':
    case 'document-statistic':
    case 'user-defined':
    case 'editing-duration':
    case 'editing-cycles':
      break;

    /* TODO: FODS Config */
    case 'config-item':
      break;

    /* TODO: style tokens */
    case 'page-number':
      break;
    // TODO <text:page-number>
    case 'page-count':
      break;
    // TODO <text:page-count>
    case 'time':
      break;
    // TODO <text:time>

    /* 9.3 Advanced Table Cells */
    case 'cell-range-source':
      break;
    // 9.3.1 <table:
    case 'detective':
      break;
    // 9.3.2 <table:
    case 'operation':
      break;
    // 9.3.3 <table:
    case 'highlighted-range':
      break;
    // 9.3.4 <table:

    /* 9.6 Data Pilot Tables <table: */
    case 'data-pilot-table': // 9.6.3
    case 'source-cell-range': // 9.6.5
    case 'source-service': // 9.6.6
    case 'data-pilot-field': // 9.6.7
    case 'data-pilot-level': // 9.6.8
    case 'data-pilot-subtotals': // 9.6.9
    case 'data-pilot-subtotal': // 9.6.10
    case 'data-pilot-members': // 9.6.11
    case 'data-pilot-member': // 9.6.12
    case 'data-pilot-display-info': // 9.6.13
    case 'data-pilot-sort-info': // 9.6.14
    case 'data-pilot-layout-info': // 9.6.15
    case 'data-pilot-field-reference': // 9.6.16
    case 'data-pilot-groups': // 9.6.17
    case 'data-pilot-group': // 9.6.18
    case 'data-pilot-group-member':
      // 9.6.19
      break;

    /* 10.3 Drawing Shapes */
    case 'rect':
      // 10.3.2
      break;

    /* 14.6 DDE Connections */
    case 'dde-connection-decls': // 14.6.2 <text:
    case 'dde-connection-decl': // 14.6.3 <text:
    case 'dde-link': // 14.6.4 <table:
    case 'dde-source':
      // 14.6.5 <office:
      break;
    case 'properties':
      break;
    // 13.7 <form:properties>
    case 'property':
      break;
    // 13.8 <form:property>

    case 'a':
      // 6.1.8 hyperlink
      if (Rn[1] !== '/') {
        atag = parsexmltag(Rn[0], false);
        if (!atag.href) break;
        atag.Target = unescapexml(atag.href);
        delete atag.href;
        if (atag.Target.charAt(0) == "#" && atag.Target.indexOf(".") > -1) {
          _Ref = ods_to_csf_3D(atag.Target.slice(1));
          atag.Target = "#" + _Ref[0] + "!" + _Ref[1];
        } else if (atag.Target.match(/^\.\.[\\\/]/)) atag.Target = atag.Target.slice(3);
      }
      break;

    /* non-standard */
    case 'table-protection':
      break;
    case 'data-pilot-grand-total':
      break;
    // <table:
    case 'office-document-common-attrs':
      break;
    // bare
    default:
      switch (Rn[2]) {
        case 'dc:': // TODO: properties
        case 'calcext:': // ignore undocumented extensions
        case 'loext:': // ignore undocumented extensions
        case 'ooo:': // ignore undocumented extensions
        case 'chartooo:': // ignore undocumented extensions
        case 'draw:': // TODO: drawing
        case 'style:': // TODO: styles
        case 'chart:': // TODO: charts
        case 'form:': // TODO: forms
        case 'uof:': // TODO: uof
        case '表:': // TODO: uof
        case '字:':
          // TODO: uof
          break;
        default:
          if (opts.WTF) throw new Error(Rn);
      }
  }
  var out /*:Workbook*/ = {
    Sheets: Sheets,
    SheetNames: SheetNames,
    Workbook: WB
  } /*:any*/;
  if (opts.bookSheets) delete /*::(*/out /*:: :any)*/.Sheets;
  return out;
}
function parse_ods(zip /*:ZIPFile*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  opts = opts || {} /*:any*/;
  if (safegetzipfile(zip, 'META-INF/manifest.xml')) parse_manifest(getzipdata(zip, 'META-INF/manifest.xml'), opts);
  var content = getzipstr(zip, 'content.xml');
  if (!content) throw new Error("Missing content.xml in ODS / UOF file");
  var wb = parse_content_xml(utf8read(content), opts);
  if (safegetzipfile(zip, 'meta.xml')) wb.Props = parse_core_props(getzipdata(zip, 'meta.xml'));
  return wb;
}
function parse_fods(data /*:string*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  return parse_content_xml(data, opts);
}

/* OpenDocument */
var write_styles_ods /*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */function () {
  var master_styles = ['<office:master-styles>', '<style:master-page style:name="mp1" style:page-layout-name="mp1">', '<style:header/>', '<style:header-left style:display="false"/>', '<style:footer/>', '<style:footer-left style:display="false"/>', '</style:master-page>', '</office:master-styles>'].join("");
  var payload = '<office:document-styles ' + wxt_helper({
    'xmlns:office': "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
    'xmlns:table': "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
    'xmlns:style': "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
    'xmlns:text': "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
    'xmlns:draw': "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
    'xmlns:fo': "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
    'xmlns:xlink': "http://www.w3.org/1999/xlink",
    'xmlns:dc': "http://purl.org/dc/elements/1.1/",
    'xmlns:number': "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
    'xmlns:svg': "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
    'xmlns:of': "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
    'office:version': "1.2"
  }) + '>' + master_styles + '</office:document-styles>';
  return function wso(/*::wb, opts*/
  ) {
    return XML_HEADER + payload;
  };
}();
var write_content_ods /*:{(wb:any, opts:any):string}*/ = /* @__PURE__ */function () {
  /* 6.1.2 White Space Characters */
  var write_text_p = function (text /*:string*/) /*:string*/{
    return escapexml(text).replace(/  +/g, function ($$) {
      return '<text:s text:c="' + $$.length + '"/>';
    }).replace(/\t/g, "<text:tab/>").replace(/\n/g, "</text:p><text:p>").replace(/^ /, "<text:s/>").replace(/ $/, "<text:s/>");
  };
  var null_cell_xml = '          <table:table-cell />\n';
  var covered_cell_xml = '          <table:covered-table-cell/>\n';
  var write_ws = function (ws, wb /*:Workbook*/, i /*:number*/ /*::, opts*/) /*:string*/{
    /* Section 9 Tables */
    var o /*:Array<string>*/ = [];
    o.push('      <table:table table:name="' + escapexml(wb.SheetNames[i]) + '" table:style-name="ta1">\n');
    var R = 0,
      C = 0,
      range = decode_range(ws['!ref'] || "A1");
    var marr /*:Array<Range>*/ = ws['!merges'] || [],
      mi = 0;
    var dense = Array.isArray(ws);
    if (ws["!cols"]) {
      for (C = 0; C <= range.e.c; ++C) o.push('        <table:table-column' + (ws["!cols"][C] ? ' table:style-name="co' + ws["!cols"][C].ods + '"' : '') + '></table:table-column>\n');
    }
    var H = "",
      ROWS = ws["!rows"] || [];
    for (R = 0; R < range.s.r; ++R) {
      H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
      o.push('        <table:table-row' + H + '></table:table-row>\n');
    }
    for (; R <= range.e.r; ++R) {
      H = ROWS[R] ? ' table:style-name="ro' + ROWS[R].ods + '"' : "";
      o.push('        <table:table-row' + H + '>\n');
      for (C = 0; C < range.s.c; ++C) o.push(null_cell_xml);
      for (; C <= range.e.c; ++C) {
        var skip = false,
          ct = {},
          textp = "";
        for (mi = 0; mi != marr.length; ++mi) {
          if (marr[mi].s.c > C) continue;
          if (marr[mi].s.r > R) continue;
          if (marr[mi].e.c < C) continue;
          if (marr[mi].e.r < R) continue;
          if (marr[mi].s.c != C || marr[mi].s.r != R) skip = true;
          ct['table:number-columns-spanned'] = marr[mi].e.c - marr[mi].s.c + 1;
          ct['table:number-rows-spanned'] = marr[mi].e.r - marr[mi].s.r + 1;
          break;
        }
        if (skip) {
          o.push(covered_cell_xml);
          continue;
        }
        var ref = encode_cell({
            r: R,
            c: C
          }),
          cell = dense ? (ws[R] || [])[C] : ws[ref];
        if (cell && cell.f) {
          ct['table:formula'] = escapexml(csf_to_ods_formula(cell.f));
          if (cell.F) {
            if (cell.F.slice(0, ref.length) == ref) {
              var _Fref = decode_range(cell.F);
              ct['table:number-matrix-columns-spanned'] = _Fref.e.c - _Fref.s.c + 1;
              ct['table:number-matrix-rows-spanned'] = _Fref.e.r - _Fref.s.r + 1;
            }
          }
        }
        if (!cell) {
          o.push(null_cell_xml);
          continue;
        }
        switch (cell.t) {
          case 'b':
            textp = cell.v ? 'TRUE' : 'FALSE';
            ct['office:value-type'] = "boolean";
            ct['office:boolean-value'] = cell.v ? 'true' : 'false';
            break;
          case 'n':
            textp = cell.w || String(cell.v || 0);
            ct['office:value-type'] = "float";
            ct['office:value'] = cell.v || 0;
            break;
          case 's':
          case 'str':
            textp = cell.v == null ? "" : cell.v;
            ct['office:value-type'] = "string";
            break;
          case 'd':
            textp = cell.w || parseDate(cell.v).toISOString();
            ct['office:value-type'] = "date";
            ct['office:date-value'] = parseDate(cell.v).toISOString();
            ct['table:style-name'] = "ce1";
            break;
          //case 'e':
          default:
            o.push(null_cell_xml);
            continue;
        }
        var text_p = write_text_p(textp);
        if (cell.l && cell.l.Target) {
          var _tgt = cell.l.Target;
          _tgt = _tgt.charAt(0) == "#" ? "#" + csf_to_ods_3D(_tgt.slice(1)) : _tgt;
          // TODO: choose correct parent path format based on link delimiters
          if (_tgt.charAt(0) != "#" && !_tgt.match(/^\w+:/)) _tgt = '../' + _tgt;
          text_p = writextag('text:a', text_p, {
            'xlink:href': _tgt.replace(/&/g, "&amp;")
          });
        }
        o.push('          ' + writextag('table:table-cell', writextag('text:p', text_p, {}), ct) + '\n');
      }
      o.push('        </table:table-row>\n');
    }
    o.push('      </table:table>\n');
    return o.join("");
  };
  var write_automatic_styles_ods = function (o /*:Array<string>*/, wb) {
    o.push(' <office:automatic-styles>\n');
    o.push('  <number:date-style style:name="N37" number:automatic-order="true">\n');
    o.push('   <number:month number:style="long"/>\n');
    o.push('   <number:text>/</number:text>\n');
    o.push('   <number:day number:style="long"/>\n');
    o.push('   <number:text>/</number:text>\n');
    o.push('   <number:year/>\n');
    o.push('  </number:date-style>\n');

    /* column styles */
    var cidx = 0;
    wb.SheetNames.map(function (n) {
      return wb.Sheets[n];
    }).forEach(function (ws) {
      if (!ws) return;
      if (ws["!cols"]) {
        for (var C = 0; C < ws["!cols"].length; ++C) if (ws["!cols"][C]) {
          var colobj = ws["!cols"][C];
          if (colobj.width == null && colobj.wpx == null && colobj.wch == null) continue;
          process_col(colobj);
          colobj.ods = cidx;
          var w = ws["!cols"][C].wpx + "px";
          o.push('  <style:style style:name="co' + cidx + '" style:family="table-column">\n');
          o.push('   <style:table-column-properties fo:break-before="auto" style:column-width="' + w + '"/>\n');
          o.push('  </style:style>\n');
          ++cidx;
        }
      }
    });

    /* row styles */
    var ridx = 0;
    wb.SheetNames.map(function (n) {
      return wb.Sheets[n];
    }).forEach(function (ws) {
      if (!ws) return;
      if (ws["!rows"]) {
        for (var R = 0; R < ws["!rows"].length; ++R) if (ws["!rows"][R]) {
          ws["!rows"][R].ods = ridx;
          var h = ws["!rows"][R].hpx + "px";
          o.push('  <style:style style:name="ro' + ridx + '" style:family="table-row">\n');
          o.push('   <style:table-row-properties fo:break-before="auto" style:row-height="' + h + '"/>\n');
          o.push('  </style:style>\n');
          ++ridx;
        }
      }
    });

    /* table */
    o.push('  <style:style style:name="ta1" style:family="table" style:master-page-name="mp1">\n');
    o.push('   <style:table-properties table:display="true" style:writing-mode="lr-tb"/>\n');
    o.push('  </style:style>\n');

    /* table cells, text */
    o.push('  <style:style style:name="ce1" style:family="table-cell" style:parent-style-name="Default" style:data-style-name="N37"/>\n');

    /* page-layout */

    o.push(' </office:automatic-styles>\n');
  };
  return function wcx(wb, opts) {
    var o = [XML_HEADER];
    /* 3.1.3.2 */
    var attr = wxt_helper({
      'xmlns:office': "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
      'xmlns:table': "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
      'xmlns:style': "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
      'xmlns:text': "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
      'xmlns:draw': "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0",
      'xmlns:fo': "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0",
      'xmlns:xlink': "http://www.w3.org/1999/xlink",
      'xmlns:dc': "http://purl.org/dc/elements/1.1/",
      'xmlns:meta': "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
      'xmlns:number': "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
      'xmlns:presentation': "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0",
      'xmlns:svg': "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0",
      'xmlns:chart': "urn:oasis:names:tc:opendocument:xmlns:chart:1.0",
      'xmlns:dr3d': "urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0",
      'xmlns:math': "http://www.w3.org/1998/Math/MathML",
      'xmlns:form': "urn:oasis:names:tc:opendocument:xmlns:form:1.0",
      'xmlns:script': "urn:oasis:names:tc:opendocument:xmlns:script:1.0",
      'xmlns:ooo': "http://openoffice.org/2004/office",
      'xmlns:ooow': "http://openoffice.org/2004/writer",
      'xmlns:oooc': "http://openoffice.org/2004/calc",
      'xmlns:dom': "http://www.w3.org/2001/xml-events",
      'xmlns:xforms': "http://www.w3.org/2002/xforms",
      'xmlns:xsd': "http://www.w3.org/2001/XMLSchema",
      'xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance",
      'xmlns:sheet': "urn:oasis:names:tc:opendocument:sh33tjs:1.0",
      'xmlns:rpt': "http://openoffice.org/2005/report",
      'xmlns:of': "urn:oasis:names:tc:opendocument:xmlns:of:1.2",
      'xmlns:xhtml': "http://www.w3.org/1999/xhtml",
      'xmlns:grddl': "http://www.w3.org/2003/g/data-view#",
      'xmlns:tableooo': "http://openoffice.org/2009/table",
      'xmlns:drawooo': "http://openoffice.org/2010/draw",
      'xmlns:calcext': "urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0",
      'xmlns:loext': "urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.0",
      'xmlns:field': "urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0",
      'xmlns:formx': "urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0",
      'xmlns:css3t': "http://www.w3.org/TR/css3-text/",
      'office:version': "1.2"
    });
    var fods = wxt_helper({
      'xmlns:config': "urn:oasis:names:tc:opendocument:xmlns:config:1.0",
      'office:mimetype': "application/vnd.oasis.opendocument.spreadsheet"
    });
    if (opts.bookType == "fods") {
      o.push('<office:document' + attr + fods + '>\n');
      o.push(write_meta_ods().replace(/office:document-meta/g, "office:meta"));
      // TODO: settings (equiv of settings.xml for ODS)
    } else o.push('<office:document-content' + attr + '>\n');
    // o.push('  <office:scripts/>\n');
    write_automatic_styles_ods(o, wb);
    o.push('  <office:body>\n');
    o.push('    <office:spreadsheet>\n');
    for (var i = 0; i != wb.SheetNames.length; ++i) o.push(write_ws(wb.Sheets[wb.SheetNames[i]], wb, i, opts));
    o.push('    </office:spreadsheet>\n');
    o.push('  </office:body>\n');
    if (opts.bookType == "fods") o.push('</office:document>');else o.push('</office:document-content>');
    return o.join("");
  };
}();
function write_ods(wb /*:any*/, opts /*:any*/) {
  if (opts.bookType == "fods") return write_content_ods(wb, opts);
  var zip = zip_new();
  var f = "";
  var manifest /*:Array<Array<string> >*/ = [];
  var rdf /*:Array<[string, string]>*/ = [];

  /* Part 3 Section 3.3 MIME Media Type */
  f = "mimetype";
  zip_add_file(zip, f, "application/vnd.oasis.opendocument.spreadsheet");

  /* Part 1 Section 2.2 Documents */
  f = "content.xml";
  zip_add_file(zip, f, write_content_ods(wb, opts));
  manifest.push([f, "text/xml"]);
  rdf.push([f, "ContentFile"]);

  /* TODO: these are hard-coded styles to satiate excel */
  f = "styles.xml";
  zip_add_file(zip, f, write_styles_ods(wb, opts));
  manifest.push([f, "text/xml"]);
  rdf.push([f, "StylesFile"]);

  /* TODO: this is hard-coded to satiate excel */
  f = "meta.xml";
  zip_add_file(zip, f, XML_HEADER + write_meta_ods(/*::wb, opts*/));
  manifest.push([f, "text/xml"]);
  rdf.push([f, "MetadataFile"]);

  /* Part 3 Section 6 Metadata Manifest File */
  f = "manifest.rdf";
  zip_add_file(zip, f, write_rdf(rdf /*, opts*/));
  manifest.push([f, "application/rdf+xml"]);

  /* Part 3 Section 4 Manifest File */
  f = "META-INF/manifest.xml";
  zip_add_file(zip, f, write_manifest(manifest /*, opts*/));
  return zip;
}

/*! sheetjs (C) 2013-present SheetJS -- http://sheetjs.com */
function u8_to_dataview(array) {
  return new DataView(array.buffer, array.byteOffset, array.byteLength);
}
function u8str(u8) {
  return typeof TextDecoder != "undefined" ? new TextDecoder().decode(u8) : utf8read(a2s(u8));
}
function stru8(str) {
  return typeof TextEncoder != "undefined" ? new TextEncoder().encode(str) : s2a(utf8write(str));
}
function u8contains(body, search) {
  outer: for (var L = 0; L <= body.length - search.length; ++L) {
    for (var j = 0; j < search.length; ++j) if (body[L + j] != search[j]) continue outer;
    return true;
  }
  return false;
}
function u8concat(u8a) {
  var len = u8a.reduce(function (acc, x) {
    return acc + x.length;
  }, 0);
  var out = new Uint8Array(len);
  var off = 0;
  u8a.forEach(function (u8) {
    out.set(u8, off);
    off += u8.length;
  });
  return out;
}
function popcnt(x) {
  x -= x >> 1 & 1431655765;
  x = (x & 858993459) + (x >> 2 & 858993459);
  return (x + (x >> 4) & 252645135) * 16843009 >>> 24;
}
function readDecimal128LE(buf, offset) {
  var exp = (buf[offset + 15] & 127) << 7 | buf[offset + 14] >> 1;
  var mantissa = buf[offset + 14] & 1;
  for (var j = offset + 13; j >= offset; --j) mantissa = mantissa * 256 + buf[j];
  return (buf[offset + 15] & 128 ? -mantissa : mantissa) * Math.pow(10, exp - 6176);
}
function writeDecimal128LE(buf, offset, value) {
  var exp = Math.floor(value == 0 ? 0 : Math.LOG10E * Math.log(Math.abs(value))) + 6176 - 20;
  var mantissa = value / Math.pow(10, exp - 6176);
  buf[offset + 15] |= exp >> 7;
  buf[offset + 14] |= (exp & 127) << 1;
  for (var i = 0; mantissa >= 1; ++i, mantissa /= 256) buf[offset + i] = mantissa & 255;
  buf[offset + 15] |= value >= 0 ? 0 : 128;
}
function parse_varint49(buf, ptr) {
  var l = ptr ? ptr[0] : 0;
  var usz = buf[l] & 127;
  varint: if (buf[l++] >= 128) {
    usz |= (buf[l] & 127) << 7;
    if (buf[l++] < 128) break varint;
    usz |= (buf[l] & 127) << 14;
    if (buf[l++] < 128) break varint;
    usz |= (buf[l] & 127) << 21;
    if (buf[l++] < 128) break varint;
    usz += (buf[l] & 127) * Math.pow(2, 28);
    ++l;
    if (buf[l++] < 128) break varint;
    usz += (buf[l] & 127) * Math.pow(2, 35);
    ++l;
    if (buf[l++] < 128) break varint;
    usz += (buf[l] & 127) * Math.pow(2, 42);
    ++l;
    if (buf[l++] < 128) break varint;
  }
  if (ptr) ptr[0] = l;
  return usz;
}
function write_varint49(v) {
  var usz = new Uint8Array(7);
  usz[0] = v & 127;
  var L = 1;
  sz: if (v > 127) {
    usz[L - 1] |= 128;
    usz[L] = v >> 7 & 127;
    ++L;
    if (v <= 16383) break sz;
    usz[L - 1] |= 128;
    usz[L] = v >> 14 & 127;
    ++L;
    if (v <= 2097151) break sz;
    usz[L - 1] |= 128;
    usz[L] = v >> 21 & 127;
    ++L;
    if (v <= 268435455) break sz;
    usz[L - 1] |= 128;
    usz[L] = v / 256 >>> 21 & 127;
    ++L;
    if (v <= 34359738367) break sz;
    usz[L - 1] |= 128;
    usz[L] = v / 65536 >>> 21 & 127;
    ++L;
    if (v <= 4398046511103) break sz;
    usz[L - 1] |= 128;
    usz[L] = v / 16777216 >>> 21 & 127;
    ++L;
  }
  return usz.slice(0, L);
}
function varint_to_i32(buf) {
  var l = 0,
    i32 = buf[l] & 127;
  varint: if (buf[l++] >= 128) {
    i32 |= (buf[l] & 127) << 7;
    if (buf[l++] < 128) break varint;
    i32 |= (buf[l] & 127) << 14;
    if (buf[l++] < 128) break varint;
    i32 |= (buf[l] & 127) << 21;
    if (buf[l++] < 128) break varint;
    i32 |= (buf[l] & 127) << 28;
  }
  return i32;
}
function parse_shallow(buf) {
  var out = [],
    ptr = [0];
  while (ptr[0] < buf.length) {
    var off = ptr[0];
    var num = parse_varint49(buf, ptr);
    var type = num & 7;
    num = Math.floor(num / 8);
    var len = 0;
    var res;
    if (num == 0) break;
    switch (type) {
      case 0:
        {
          var l = ptr[0];
          while (buf[ptr[0]++] >= 128);
          res = buf.slice(l, ptr[0]);
        }
        break;
      case 5:
        len = 4;
        res = buf.slice(ptr[0], ptr[0] + len);
        ptr[0] += len;
        break;
      case 1:
        len = 8;
        res = buf.slice(ptr[0], ptr[0] + len);
        ptr[0] += len;
        break;
      case 2:
        len = parse_varint49(buf, ptr);
        res = buf.slice(ptr[0], ptr[0] + len);
        ptr[0] += len;
        break;
      case 3:
      case 4:
      default:
        throw new Error("PB Type ".concat(type, " for Field ").concat(num, " at offset ").concat(off));
    }
    var v = {
      data: res,
      type: type
    };
    if (out[num] == null) out[num] = [v];else out[num].push(v);
  }
  return out;
}
function write_shallow(proto) {
  var out = [];
  proto.forEach(function (field, idx) {
    field.forEach(function (item) {
      if (!item.data) return;
      out.push(write_varint49(idx * 8 + item.type));
      if (item.type == 2) out.push(write_varint49(item.data.length));
      out.push(item.data);
    });
  });
  return u8concat(out);
}
function mappa(data, cb) {
  return (data == null ? void 0 : data.map(function (d) {
    return cb(d.data);
  })) || [];
}
function parse_iwa_file(buf) {
  var _a;
  var out = [],
    ptr = [0];
  while (ptr[0] < buf.length) {
    var len = parse_varint49(buf, ptr);
    var ai = parse_shallow(buf.slice(ptr[0], ptr[0] + len));
    ptr[0] += len;
    var res = {
      id: varint_to_i32(ai[1][0].data),
      messages: []
    };
    ai[2].forEach(function (b) {
      var mi = parse_shallow(b.data);
      var fl = varint_to_i32(mi[3][0].data);
      res.messages.push({
        meta: mi,
        data: buf.slice(ptr[0], ptr[0] + fl)
      });
      ptr[0] += fl;
    });
    if ((_a = ai[3]) == null ? void 0 : _a[0]) res.merge = varint_to_i32(ai[3][0].data) >>> 0 > 0;
    out.push(res);
  }
  return out;
}
function write_iwa_file(ias) {
  var bufs = [];
  ias.forEach(function (ia) {
    var ai = [];
    ai[1] = [{
      data: write_varint49(ia.id),
      type: 0
    }];
    ai[2] = [];
    if (ia.merge != null) ai[3] = [{
      data: write_varint49(+!!ia.merge),
      type: 0
    }];
    var midata = [];
    ia.messages.forEach(function (mi) {
      midata.push(mi.data);
      mi.meta[3] = [{
        type: 0,
        data: write_varint49(mi.data.length)
      }];
      ai[2].push({
        data: write_shallow(mi.meta),
        type: 2
      });
    });
    var aipayload = write_shallow(ai);
    bufs.push(write_varint49(aipayload.length));
    bufs.push(aipayload);
    midata.forEach(function (mid) {
      return bufs.push(mid);
    });
  });
  return u8concat(bufs);
}
function parse_snappy_chunk(type, buf) {
  if (type != 0) throw new Error("Unexpected Snappy chunk type ".concat(type));
  var ptr = [0];
  var usz = parse_varint49(buf, ptr);
  var chunks = [];
  while (ptr[0] < buf.length) {
    var tag = buf[ptr[0]] & 3;
    if (tag == 0) {
      var len = buf[ptr[0]++] >> 2;
      if (len < 60) ++len;else {
        var c = len - 59;
        len = buf[ptr[0]];
        if (c > 1) len |= buf[ptr[0] + 1] << 8;
        if (c > 2) len |= buf[ptr[0] + 2] << 16;
        if (c > 3) len |= buf[ptr[0] + 3] << 24;
        len >>>= 0;
        len++;
        ptr[0] += c;
      }
      chunks.push(buf.slice(ptr[0], ptr[0] + len));
      ptr[0] += len;
      continue;
    } else {
      var offset = 0,
        length = 0;
      if (tag == 1) {
        length = (buf[ptr[0]] >> 2 & 7) + 4;
        offset = (buf[ptr[0]++] & 224) << 3;
        offset |= buf[ptr[0]++];
      } else {
        length = (buf[ptr[0]++] >> 2) + 1;
        if (tag == 2) {
          offset = buf[ptr[0]] | buf[ptr[0] + 1] << 8;
          ptr[0] += 2;
        } else {
          offset = (buf[ptr[0]] | buf[ptr[0] + 1] << 8 | buf[ptr[0] + 2] << 16 | buf[ptr[0] + 3] << 24) >>> 0;
          ptr[0] += 4;
        }
      }
      chunks = [u8concat(chunks)];
      if (offset == 0) throw new Error("Invalid offset 0");
      if (offset > chunks[0].length) throw new Error("Invalid offset beyond length");
      if (length >= offset) {
        chunks.push(chunks[0].slice(-offset));
        length -= offset;
        while (length >= chunks[chunks.length - 1].length) {
          chunks.push(chunks[chunks.length - 1]);
          length -= chunks[chunks.length - 1].length;
        }
      }
      chunks.push(chunks[0].slice(-offset, -offset + length));
    }
  }
  var o = u8concat(chunks);
  if (o.length != usz) throw new Error("Unexpected length: ".concat(o.length, " != ").concat(usz));
  return o;
}
function decompress_iwa_file(buf) {
  var out = [];
  var l = 0;
  while (l < buf.length) {
    var t = buf[l++];
    var len = buf[l] | buf[l + 1] << 8 | buf[l + 2] << 16;
    l += 3;
    out.push(parse_snappy_chunk(t, buf.slice(l, l + len)));
    l += len;
  }
  if (l !== buf.length) throw new Error("data is not a valid framed stream!");
  return u8concat(out);
}
function compress_iwa_file(buf) {
  var out = [];
  var l = 0;
  while (l < buf.length) {
    var c = Math.min(buf.length - l, 268435455);
    var frame = new Uint8Array(4);
    out.push(frame);
    var usz = write_varint49(c);
    var L = usz.length;
    out.push(usz);
    if (c <= 60) {
      L++;
      out.push(new Uint8Array([c - 1 << 2]));
    } else if (c <= 256) {
      L += 2;
      out.push(new Uint8Array([240, c - 1 & 255]));
    } else if (c <= 65536) {
      L += 3;
      out.push(new Uint8Array([244, c - 1 & 255, c - 1 >> 8 & 255]));
    } else if (c <= 16777216) {
      L += 4;
      out.push(new Uint8Array([248, c - 1 & 255, c - 1 >> 8 & 255, c - 1 >> 16 & 255]));
    } else if (c <= 4294967296) {
      L += 5;
      out.push(new Uint8Array([252, c - 1 & 255, c - 1 >> 8 & 255, c - 1 >> 16 & 255, c - 1 >>> 24 & 255]));
    }
    out.push(buf.slice(l, l + c));
    L += c;
    frame[0] = 0;
    frame[1] = L & 255;
    frame[2] = L >> 8 & 255;
    frame[3] = L >> 16 & 255;
    l += c;
  }
  return u8concat(out);
}
function parse_old_storage(buf, sst, rsst, v) {
  var dv = u8_to_dataview(buf);
  var flags = dv.getUint32(4, true);
  var data_offset = (v > 1 ? 12 : 8) + popcnt(flags & (v > 1 ? 3470 : 398)) * 4;
  var ridx = -1,
    sidx = -1,
    ieee = NaN,
    dt = new Date(2001, 0, 1);
  if (flags & 512) {
    ridx = dv.getUint32(data_offset, true);
    data_offset += 4;
  }
  data_offset += popcnt(flags & (v > 1 ? 12288 : 4096)) * 4;
  if (flags & 16) {
    sidx = dv.getUint32(data_offset, true);
    data_offset += 4;
  }
  if (flags & 32) {
    ieee = dv.getFloat64(data_offset, true);
    data_offset += 8;
  }
  if (flags & 64) {
    dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
    data_offset += 8;
  }
  var ret;
  switch (buf[2]) {
    case 0:
      break;
    case 2:
      ret = {
        t: "n",
        v: ieee
      };
      break;
    case 3:
      ret = {
        t: "s",
        v: sst[sidx]
      };
      break;
    case 5:
      ret = {
        t: "d",
        v: dt
      };
      break;
    case 6:
      ret = {
        t: "b",
        v: ieee > 0
      };
      break;
    case 7:
      ret = {
        t: "n",
        v: ieee / 86400
      };
      break;
    case 8:
      ret = {
        t: "e",
        v: 0
      };
      break;
    case 9:
      {
        if (ridx > -1) ret = {
          t: "s",
          v: rsst[ridx]
        };else if (sidx > -1) ret = {
          t: "s",
          v: sst[sidx]
        };else if (!isNaN(ieee)) ret = {
          t: "n",
          v: ieee
        };else throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
      }
      break;
    default:
      throw new Error("Unsupported cell type ".concat(buf.slice(0, 4)));
  }
  return ret;
}
function parse_new_storage(buf, sst, rsst) {
  var dv = u8_to_dataview(buf);
  var flags = dv.getUint32(8, true);
  var data_offset = 12;
  var ridx = -1,
    sidx = -1,
    d128 = NaN,
    ieee = NaN,
    dt = new Date(2001, 0, 1);
  if (flags & 1) {
    d128 = readDecimal128LE(buf, data_offset);
    data_offset += 16;
  }
  if (flags & 2) {
    ieee = dv.getFloat64(data_offset, true);
    data_offset += 8;
  }
  if (flags & 4) {
    dt.setTime(dt.getTime() + dv.getFloat64(data_offset, true) * 1e3);
    data_offset += 8;
  }
  if (flags & 8) {
    sidx = dv.getUint32(data_offset, true);
    data_offset += 4;
  }
  if (flags & 16) {
    ridx = dv.getUint32(data_offset, true);
    data_offset += 4;
  }
  var ret;
  switch (buf[1]) {
    case 0:
      break;
    case 2:
      ret = {
        t: "n",
        v: d128
      };
      break;
    case 3:
      ret = {
        t: "s",
        v: sst[sidx]
      };
      break;
    case 5:
      ret = {
        t: "d",
        v: dt
      };
      break;
    case 6:
      ret = {
        t: "b",
        v: ieee > 0
      };
      break;
    case 7:
      ret = {
        t: "n",
        v: ieee / 86400
      };
      break;
    case 8:
      ret = {
        t: "e",
        v: 0
      };
      break;
    case 9:
      {
        if (ridx > -1) ret = {
          t: "s",
          v: rsst[ridx]
        };else throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf.slice(0, 4)));
      }
      break;
    case 10:
      ret = {
        t: "n",
        v: d128
      };
      break;
    default:
      throw new Error("Unsupported cell type ".concat(buf[1], " : ").concat(flags & 31, " : ").concat(buf.slice(0, 4)));
  }
  return ret;
}
function write_new_storage(cell, sst) {
  var out = new Uint8Array(32),
    dv = u8_to_dataview(out),
    l = 12,
    flags = 0;
  out[0] = 5;
  switch (cell.t) {
    case "n":
      out[1] = 2;
      writeDecimal128LE(out, l, cell.v);
      flags |= 1;
      l += 16;
      break;
    case "b":
      out[1] = 6;
      dv.setFloat64(l, cell.v ? 1 : 0, true);
      flags |= 2;
      l += 8;
      break;
    case "s":
      if (sst.indexOf(cell.v) == -1) throw new Error("Value ".concat(cell.v, " missing from SST!"));
      out[1] = 3;
      dv.setUint32(l, sst.indexOf(cell.v), true);
      flags |= 8;
      l += 4;
      break;
    default:
      throw "unsupported cell type " + cell.t;
  }
  dv.setUint32(8, flags, true);
  return out.slice(0, l);
}
function write_old_storage(cell, sst) {
  var out = new Uint8Array(32),
    dv = u8_to_dataview(out),
    l = 12,
    flags = 0;
  out[0] = 3;
  switch (cell.t) {
    case "n":
      out[2] = 2;
      dv.setFloat64(l, cell.v, true);
      flags |= 32;
      l += 8;
      break;
    case "b":
      out[2] = 6;
      dv.setFloat64(l, cell.v ? 1 : 0, true);
      flags |= 32;
      l += 8;
      break;
    case "s":
      if (sst.indexOf(cell.v) == -1) throw new Error("Value ".concat(cell.v, " missing from SST!"));
      out[2] = 3;
      dv.setUint32(l, sst.indexOf(cell.v), true);
      flags |= 16;
      l += 4;
      break;
    default:
      throw "unsupported cell type " + cell.t;
  }
  dv.setUint32(4, flags, true);
  return out.slice(0, l);
}
function parse_cell_storage(buf, sst, rsst) {
  switch (buf[0]) {
    case 0:
    case 1:
    case 2:
    case 3:
      return parse_old_storage(buf, sst, rsst, buf[0]);
    case 5:
      return parse_new_storage(buf, sst, rsst);
    default:
      throw new Error("Unsupported payload version ".concat(buf[0]));
  }
}
function parse_TSP_Reference(buf) {
  var pb = parse_shallow(buf);
  return parse_varint49(pb[1][0].data);
}
function write_TSP_Reference(idx) {
  var out = [];
  out[1] = [{
    type: 0,
    data: write_varint49(idx)
  }];
  return write_shallow(out);
}
function parse_TST_TableDataList(M, root) {
  var pb = parse_shallow(root.data);
  var type = varint_to_i32(pb[1][0].data);
  var entries = pb[3];
  var data = [];
  (entries || []).forEach(function (entry) {
    var le = parse_shallow(entry.data);
    var key = varint_to_i32(le[1][0].data) >>> 0;
    switch (type) {
      case 1:
        data[key] = u8str(le[3][0].data);
        break;
      case 8:
        {
          var rt = M[parse_TSP_Reference(le[9][0].data)][0];
          var rtp = parse_shallow(rt.data);
          var rtpref = M[parse_TSP_Reference(rtp[1][0].data)][0];
          var mtype = varint_to_i32(rtpref.meta[1][0].data);
          if (mtype != 2001) throw new Error("2000 unexpected reference to ".concat(mtype));
          var tswpsa = parse_shallow(rtpref.data);
          data[key] = tswpsa[3].map(function (x) {
            return u8str(x.data);
          }).join("");
        }
        break;
    }
  });
  return data;
}
function parse_TST_TileRowInfo(u8, type) {
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
  var pb = parse_shallow(u8);
  var R = varint_to_i32(pb[1][0].data) >>> 0;
  var cnt = varint_to_i32(pb[2][0].data) >>> 0;
  var wide_offsets = ((_b = (_a = pb[8]) == null ? void 0 : _a[0]) == null ? void 0 : _b.data) && varint_to_i32(pb[8][0].data) > 0 || false;
  var used_storage_u8, used_storage;
  if (((_d = (_c = pb[7]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && type != 0) {
    used_storage_u8 = (_f = (_e = pb[7]) == null ? void 0 : _e[0]) == null ? void 0 : _f.data;
    used_storage = (_h = (_g = pb[6]) == null ? void 0 : _g[0]) == null ? void 0 : _h.data;
  } else if (((_j = (_i = pb[4]) == null ? void 0 : _i[0]) == null ? void 0 : _j.data) && type != 1) {
    used_storage_u8 = (_l = (_k = pb[4]) == null ? void 0 : _k[0]) == null ? void 0 : _l.data;
    used_storage = (_n = (_m = pb[3]) == null ? void 0 : _m[0]) == null ? void 0 : _n.data;
  } else throw "NUMBERS Tile missing ".concat(type, " cell storage");
  var width = wide_offsets ? 4 : 1;
  var used_storage_offsets = u8_to_dataview(used_storage_u8);
  var offsets = [];
  for (var C = 0; C < used_storage_u8.length / 2; ++C) {
    var off = used_storage_offsets.getUint16(C * 2, true);
    if (off < 65535) offsets.push([C, off]);
  }
  if (offsets.length != cnt) throw "Expected ".concat(cnt, " cells, found ").concat(offsets.length);
  var cells = [];
  for (C = 0; C < offsets.length - 1; ++C) cells[offsets[C][0]] = used_storage.subarray(offsets[C][1] * width, offsets[C + 1][1] * width);
  if (offsets.length >= 1) cells[offsets[offsets.length - 1][0]] = used_storage.subarray(offsets[offsets.length - 1][1] * width);
  return {
    R: R,
    cells: cells
  };
}
function parse_TST_Tile(M, root) {
  var _a;
  var pb = parse_shallow(root.data);
  var storage = ((_a = pb == null ? void 0 : pb[7]) == null ? void 0 : _a[0]) ? varint_to_i32(pb[7][0].data) >>> 0 > 0 ? 1 : 0 : -1;
  var ri = mappa(pb[5], function (u8) {
    return parse_TST_TileRowInfo(u8, storage);
  });
  return {
    nrows: varint_to_i32(pb[4][0].data) >>> 0,
    data: ri.reduce(function (acc, x) {
      if (!acc[x.R]) acc[x.R] = [];
      x.cells.forEach(function (cell, C) {
        if (acc[x.R][C]) throw new Error("Duplicate cell r=".concat(x.R, " c=").concat(C));
        acc[x.R][C] = cell;
      });
      return acc;
    }, [])
  };
}
function parse_TST_TableModelArchive(M, root, ws) {
  var _a;
  var pb = parse_shallow(root.data);
  var range = {
    s: {
      r: 0,
      c: 0
    },
    e: {
      r: 0,
      c: 0
    }
  };
  range.e.r = (varint_to_i32(pb[6][0].data) >>> 0) - 1;
  if (range.e.r < 0) throw new Error("Invalid row varint ".concat(pb[6][0].data));
  range.e.c = (varint_to_i32(pb[7][0].data) >>> 0) - 1;
  if (range.e.c < 0) throw new Error("Invalid col varint ".concat(pb[7][0].data));
  ws["!ref"] = encode_range(range);
  var store = parse_shallow(pb[4][0].data);
  var sst = parse_TST_TableDataList(M, M[parse_TSP_Reference(store[4][0].data)][0]);
  var rsst = ((_a = store[17]) == null ? void 0 : _a[0]) ? parse_TST_TableDataList(M, M[parse_TSP_Reference(store[17][0].data)][0]) : [];
  var tile = parse_shallow(store[3][0].data);
  var _R = 0;
  tile[1].forEach(function (t) {
    var tl = parse_shallow(t.data);
    var ref = M[parse_TSP_Reference(tl[2][0].data)][0];
    var mtype = varint_to_i32(ref.meta[1][0].data);
    if (mtype != 6002) throw new Error("6001 unexpected reference to ".concat(mtype));
    var _tile = parse_TST_Tile(M, ref);
    _tile.data.forEach(function (row, R) {
      row.forEach(function (buf, C) {
        var addr = encode_cell({
          r: _R + R,
          c: C
        });
        var res = parse_cell_storage(buf, sst, rsst);
        if (res) ws[addr] = res;
      });
    });
    _R += _tile.nrows;
  });
}
function parse_TST_TableInfoArchive(M, root) {
  var pb = parse_shallow(root.data);
  var out = {
    "!ref": "A1"
  };
  var tableref = M[parse_TSP_Reference(pb[2][0].data)];
  var mtype = varint_to_i32(tableref[0].meta[1][0].data);
  if (mtype != 6001) throw new Error("6000 unexpected reference to ".concat(mtype));
  parse_TST_TableModelArchive(M, tableref[0], out);
  return out;
}
function parse_TN_SheetArchive(M, root) {
  var _a;
  var pb = parse_shallow(root.data);
  var out = {
    name: ((_a = pb[1]) == null ? void 0 : _a[0]) ? u8str(pb[1][0].data) : "",
    sheets: []
  };
  var shapeoffs = mappa(pb[2], parse_TSP_Reference);
  shapeoffs.forEach(function (off) {
    M[off].forEach(function (m) {
      var mtype = varint_to_i32(m.meta[1][0].data);
      if (mtype == 6e3) out.sheets.push(parse_TST_TableInfoArchive(M, m));
    });
  });
  return out;
}
function parse_TN_DocumentArchive(M, root) {
  var out = book_new();
  var pb = parse_shallow(root.data);
  var sheetoffs = mappa(pb[1], parse_TSP_Reference);
  sheetoffs.forEach(function (off) {
    M[off].forEach(function (m) {
      var mtype = varint_to_i32(m.meta[1][0].data);
      if (mtype == 2) {
        var root2 = parse_TN_SheetArchive(M, m);
        root2.sheets.forEach(function (sheet, idx) {
          book_append_sheet(out, sheet, idx == 0 ? root2.name : root2.name + "_" + idx, true);
        });
      }
    });
  });
  if (out.SheetNames.length == 0) throw new Error("Empty NUMBERS file");
  return out;
}
function parse_numbers_iwa(cfb) {
  var _a, _b, _c, _d;
  var M = {},
    indices = [];
  cfb.FullPaths.forEach(function (p) {
    if (p.match(/\.iwpv2/)) throw new Error("Unsupported password protection");
  });
  cfb.FileIndex.forEach(function (s) {
    if (!s.name.match(/\.iwa$/)) return;
    var o;
    try {
      o = decompress_iwa_file(s.content);
    } catch (e) {
      return console.log("?? " + s.content.length + " " + (e.message || e));
    }
    var packets;
    try {
      packets = parse_iwa_file(o);
    } catch (e) {
      return console.log("## " + (e.message || e));
    }
    packets.forEach(function (packet) {
      M[packet.id] = packet.messages;
      indices.push(packet.id);
    });
  });
  if (!indices.length) throw new Error("File has no messages");
  var docroot = ((_d = (_c = (_b = (_a = M == null ? void 0 : M[1]) == null ? void 0 : _a[0]) == null ? void 0 : _b.meta) == null ? void 0 : _c[1]) == null ? void 0 : _d[0].data) && varint_to_i32(M[1][0].meta[1][0].data) == 1 && M[1][0];
  if (!docroot) indices.forEach(function (idx) {
    M[idx].forEach(function (iwam) {
      var mtype = varint_to_i32(iwam.meta[1][0].data) >>> 0;
      if (mtype == 1) {
        if (!docroot) docroot = iwam;else throw new Error("Document has multiple roots");
      }
    });
  });
  if (!docroot) throw new Error("Cannot find Document root");
  return parse_TN_DocumentArchive(M, docroot);
}
function write_tile_row(tri, data, SST) {
  var _a, _b, _c, _d;
  if (!((_a = tri[6]) == null ? void 0 : _a[0]) || !((_b = tri[7]) == null ? void 0 : _b[0])) throw "Mutation only works on post-BNC storages!";
  var wide_offsets = ((_d = (_c = tri[8]) == null ? void 0 : _c[0]) == null ? void 0 : _d.data) && varint_to_i32(tri[8][0].data) > 0 || false;
  if (wide_offsets) throw "Math only works with normal offsets";
  var cnt = 0;
  var dv = u8_to_dataview(tri[7][0].data),
    last_offset = 0,
    cell_storage = [];
  var _dv = u8_to_dataview(tri[4][0].data),
    _last_offset = 0,
    _cell_storage = [];
  for (var C = 0; C < data.length; ++C) {
    if (data[C] == null) {
      dv.setUint16(C * 2, 65535, true);
      _dv.setUint16(C * 2, 65535);
      continue;
    }
    dv.setUint16(C * 2, last_offset, true);
    _dv.setUint16(C * 2, _last_offset, true);
    var celload, _celload;
    switch (typeof data[C]) {
      case "string":
        celload = write_new_storage({
          t: "s",
          v: data[C]
        }, SST);
        _celload = write_old_storage({
          t: "s",
          v: data[C]
        }, SST);
        break;
      case "number":
        celload = write_new_storage({
          t: "n",
          v: data[C]
        }, SST);
        _celload = write_old_storage({
          t: "n",
          v: data[C]
        }, SST);
        break;
      case "boolean":
        celload = write_new_storage({
          t: "b",
          v: data[C]
        }, SST);
        _celload = write_old_storage({
          t: "b",
          v: data[C]
        }, SST);
        break;
      default:
        throw new Error("Unsupported value " + data[C]);
    }
    cell_storage.push(celload);
    last_offset += celload.length;
    _cell_storage.push(_celload);
    _last_offset += _celload.length;
    ++cnt;
  }
  tri[2][0].data = write_varint49(cnt);
  for (; C < tri[7][0].data.length / 2; ++C) {
    dv.setUint16(C * 2, 65535, true);
    _dv.setUint16(C * 2, 65535, true);
  }
  tri[6][0].data = u8concat(cell_storage);
  tri[3][0].data = u8concat(_cell_storage);
  return cnt;
}
function write_numbers_iwa(wb, opts) {
  if (!opts || !opts.numbers) throw new Error("Must pass a `numbers` option -- check the README");
  var ws = wb.Sheets[wb.SheetNames[0]];
  if (wb.SheetNames.length > 1) console.error("The Numbers writer currently writes only the first table");
  var range = decode_range(ws["!ref"]);
  range.s.r = range.s.c = 0;
  var trunc = false;
  if (range.e.c > 9) {
    trunc = true;
    range.e.c = 9;
  }
  if (range.e.r > 49) {
    trunc = true;
    range.e.r = 49;
  }
  if (trunc) console.error("The Numbers writer is currently limited to ".concat(encode_range(range)));
  var data = sheet_to_json(ws, {
    range: range,
    header: 1
  });
  var SST = ["~Sh33tJ5~"];
  data.forEach(function (row) {
    return row.forEach(function (cell) {
      if (typeof cell == "string") SST.push(cell);
    });
  });
  var dependents = {};
  var indices = [];
  var cfb = CFB.read(opts.numbers, {
    type: "base64"
  });
  cfb.FileIndex.map(function (fi, idx) {
    return [fi, cfb.FullPaths[idx]];
  }).forEach(function (row) {
    var fi = row[0],
      fp = row[1];
    if (fi.type != 2) return;
    if (!fi.name.match(/\.iwa/)) return;
    var old_content = fi.content;
    var raw1 = decompress_iwa_file(old_content);
    var x2 = parse_iwa_file(raw1);
    x2.forEach(function (packet2) {
      indices.push(packet2.id);
      dependents[packet2.id] = {
        deps: [],
        location: fp,
        type: varint_to_i32(packet2.messages[0].meta[1][0].data)
      };
    });
  });
  indices.sort(function (x2, y2) {
    return x2 - y2;
  });
  var indices_varint = indices.filter(function (x2) {
    return x2 > 1;
  }).map(function (x2) {
    return [x2, write_varint49(x2)];
  });
  cfb.FileIndex.map(function (fi, idx) {
    return [fi, cfb.FullPaths[idx]];
  }).forEach(function (row) {
    var fi = row[0],
      fp = row[1];
    if (!fi.name.match(/\.iwa/)) return;
    var x2 = parse_iwa_file(decompress_iwa_file(fi.content));
    x2.forEach(function (ia) {
      ia.messages.forEach(function (m) {
        indices_varint.forEach(function (ivi) {
          if (ia.messages.some(function (mess) {
            return varint_to_i32(mess.meta[1][0].data) != 11006 && u8contains(mess.data, ivi[1]);
          })) {
            dependents[ivi[0]].deps.push(ia.id);
          }
        });
      });
    });
  });
  function get_unique_msgid() {
    for (var i = 927262; i < 2e6; ++i) if (!dependents[i]) return i;
    throw new Error("Too many messages");
  }
  var entry = CFB.find(cfb, dependents[1].location);
  var x = parse_iwa_file(decompress_iwa_file(entry.content));
  var docroot;
  for (var xi = 0; xi < x.length; ++xi) {
    var packet = x[xi];
    if (packet.id == 1) docroot = packet;
  }
  var sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[1][0].data);
  entry = CFB.find(cfb, dependents[sheetrootref].location);
  x = parse_iwa_file(decompress_iwa_file(entry.content));
  for (xi = 0; xi < x.length; ++xi) {
    packet = x[xi];
    if (packet.id == sheetrootref) docroot = packet;
  }
  sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
  entry = CFB.find(cfb, dependents[sheetrootref].location);
  x = parse_iwa_file(decompress_iwa_file(entry.content));
  for (xi = 0; xi < x.length; ++xi) {
    packet = x[xi];
    if (packet.id == sheetrootref) docroot = packet;
  }
  sheetrootref = parse_TSP_Reference(parse_shallow(docroot.messages[0].data)[2][0].data);
  entry = CFB.find(cfb, dependents[sheetrootref].location);
  x = parse_iwa_file(decompress_iwa_file(entry.content));
  for (xi = 0; xi < x.length; ++xi) {
    packet = x[xi];
    if (packet.id == sheetrootref) docroot = packet;
  }
  var pb = parse_shallow(docroot.messages[0].data);
  {
    pb[6][0].data = write_varint49(range.e.r + 1);
    pb[7][0].data = write_varint49(range.e.c + 1);
    var cruidsref = parse_TSP_Reference(pb[46][0].data);
    var oldbucket = CFB.find(cfb, dependents[cruidsref].location);
    var _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
    {
      for (var j = 0; j < _x.length; ++j) {
        if (_x[j].id == cruidsref) break;
      }
      if (_x[j].id != cruidsref) throw "Bad ColumnRowUIDMapArchive";
      var cruids = parse_shallow(_x[j].messages[0].data);
      cruids[1] = [];
      cruids[2] = [], cruids[3] = [];
      for (var C = 0; C <= range.e.c; ++C) {
        var uuid = [];
        uuid[1] = uuid[2] = [{
          type: 0,
          data: write_varint49(C + 420690)
        }];
        cruids[1].push({
          type: 2,
          data: write_shallow(uuid)
        });
        cruids[2].push({
          type: 0,
          data: write_varint49(C)
        });
        cruids[3].push({
          type: 0,
          data: write_varint49(C)
        });
      }
      cruids[4] = [];
      cruids[5] = [], cruids[6] = [];
      for (var R = 0; R <= range.e.r; ++R) {
        uuid = [];
        uuid[1] = uuid[2] = [{
          type: 0,
          data: write_varint49(R + 726270)
        }];
        cruids[4].push({
          type: 2,
          data: write_shallow(uuid)
        });
        cruids[5].push({
          type: 0,
          data: write_varint49(R)
        });
        cruids[6].push({
          type: 0,
          data: write_varint49(R)
        });
      }
      _x[j].messages[0].data = write_shallow(cruids);
    }
    oldbucket.content = compress_iwa_file(write_iwa_file(_x));
    oldbucket.size = oldbucket.content.length;
    delete pb[46];
    var store = parse_shallow(pb[4][0].data);
    {
      store[7][0].data = write_varint49(range.e.r + 1);
      var row_headers = parse_shallow(store[1][0].data);
      var row_header_ref = parse_TSP_Reference(row_headers[2][0].data);
      oldbucket = CFB.find(cfb, dependents[row_header_ref].location);
      _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
      {
        if (_x[0].id != row_header_ref) throw "Bad HeaderStorageBucket";
        var base_bucket = parse_shallow(_x[0].messages[0].data);
        for (R = 0; R < data.length; ++R) {
          var _bucket = parse_shallow(base_bucket[2][0].data);
          _bucket[1][0].data = write_varint49(R);
          _bucket[4][0].data = write_varint49(data[R].length);
          base_bucket[2][R] = {
            type: base_bucket[2][0].type,
            data: write_shallow(_bucket)
          };
        }
        _x[0].messages[0].data = write_shallow(base_bucket);
      }
      oldbucket.content = compress_iwa_file(write_iwa_file(_x));
      oldbucket.size = oldbucket.content.length;
      var col_header_ref = parse_TSP_Reference(store[2][0].data);
      oldbucket = CFB.find(cfb, dependents[col_header_ref].location);
      _x = parse_iwa_file(decompress_iwa_file(oldbucket.content));
      {
        if (_x[0].id != col_header_ref) throw "Bad HeaderStorageBucket";
        base_bucket = parse_shallow(_x[0].messages[0].data);
        for (C = 0; C <= range.e.c; ++C) {
          _bucket = parse_shallow(base_bucket[2][0].data);
          _bucket[1][0].data = write_varint49(C);
          _bucket[4][0].data = write_varint49(range.e.r + 1);
          base_bucket[2][C] = {
            type: base_bucket[2][0].type,
            data: write_shallow(_bucket)
          };
        }
        _x[0].messages[0].data = write_shallow(base_bucket);
      }
      oldbucket.content = compress_iwa_file(write_iwa_file(_x));
      oldbucket.size = oldbucket.content.length;
      var sstref = parse_TSP_Reference(store[4][0].data);
      (function () {
        var sentry = CFB.find(cfb, dependents[sstref].location);
        var sx = parse_iwa_file(decompress_iwa_file(sentry.content));
        var sstroot;
        for (var sxi = 0; sxi < sx.length; ++sxi) {
          var packet2 = sx[sxi];
          if (packet2.id == sstref) sstroot = packet2;
        }
        var sstdata = parse_shallow(sstroot.messages[0].data);
        {
          sstdata[3] = [];
          var newsst = [];
          SST.forEach(function (str, i) {
            newsst[1] = [{
              type: 0,
              data: write_varint49(i)
            }];
            newsst[2] = [{
              type: 0,
              data: write_varint49(1)
            }];
            newsst[3] = [{
              type: 2,
              data: stru8(str)
            }];
            sstdata[3].push({
              type: 2,
              data: write_shallow(newsst)
            });
          });
        }
        sstroot.messages[0].data = write_shallow(sstdata);
        var sy = write_iwa_file(sx);
        var raw32 = compress_iwa_file(sy);
        sentry.content = raw32;
        sentry.size = sentry.content.length;
      })();
      var tile = parse_shallow(store[3][0].data);
      {
        var t = tile[1][0];
        delete tile[2];
        var tl = parse_shallow(t.data);
        {
          var tileref = parse_TSP_Reference(tl[2][0].data);
          (function () {
            var tentry = CFB.find(cfb, dependents[tileref].location);
            var tx = parse_iwa_file(decompress_iwa_file(tentry.content));
            var tileroot;
            for (var sxi = 0; sxi < tx.length; ++sxi) {
              var packet2 = tx[sxi];
              if (packet2.id == tileref) tileroot = packet2;
            }
            var tiledata = parse_shallow(tileroot.messages[0].data);
            {
              delete tiledata[6];
              delete tile[7];
              var rowload = new Uint8Array(tiledata[5][0].data);
              tiledata[5] = [];
              var cnt = 0;
              for (var R2 = 0; R2 <= range.e.r; ++R2) {
                var tilerow = parse_shallow(rowload);
                cnt += write_tile_row(tilerow, data[R2], SST);
                tilerow[1][0].data = write_varint49(R2);
                tiledata[5].push({
                  data: write_shallow(tilerow),
                  type: 2
                });
              }
              tiledata[1] = [{
                type: 0,
                data: write_varint49(range.e.c + 1)
              }];
              tiledata[2] = [{
                type: 0,
                data: write_varint49(range.e.r + 1)
              }];
              tiledata[3] = [{
                type: 0,
                data: write_varint49(cnt)
              }];
              tiledata[4] = [{
                type: 0,
                data: write_varint49(range.e.r + 1)
              }];
            }
            tileroot.messages[0].data = write_shallow(tiledata);
            var ty = write_iwa_file(tx);
            var raw32 = compress_iwa_file(ty);
            tentry.content = raw32;
            tentry.size = tentry.content.length;
          })();
        }
        t.data = write_shallow(tl);
      }
      store[3][0].data = write_shallow(tile);
    }
    pb[4][0].data = write_shallow(store);
  }
  docroot.messages[0].data = write_shallow(pb);
  var y = write_iwa_file(x);
  var raw3 = compress_iwa_file(y);
  entry.content = raw3;
  entry.size = entry.content.length;
  return cfb;
}
function fix_opts_func(defaults /*:Array<Array<any> >*/) /*:{(o:any):void}*/{
  return function fix_opts(opts) {
    for (var i = 0; i != defaults.length; ++i) {
      var d = defaults[i];
      if (opts[d[0]] === undefined) opts[d[0]] = d[1];
      if (d[2] === 'n') opts[d[0]] = Number(opts[d[0]]);
    }
  };
}
function fix_read_opts(opts) {
  fix_opts_func([['cellNF', false], /* emit cell number format string as .z */
  ['cellHTML', true], /* emit html string as .h */
  ['cellFormula', true], /* emit formulae as .f */
  ['cellStyles', false], /* emits style/theme as .s */
  ['cellText', true], /* emit formatted text as .w */
  ['cellDates', false], /* emit date cells with type `d` */

  ['sheetStubs', false], /* emit empty cells */
  ['sheetRows', 0, 'n'], /* read n rows (0 = read all rows) */

  ['bookDeps', false], /* parse calculation chains */
  ['bookSheets', false], /* only try to get sheet names (no Sheets) */
  ['bookProps', false], /* only try to get properties (no Sheets) */
  ['bookFiles', false], /* include raw file structure (keys, files, cfb) */
  ['bookVBA', false], /* include vba raw data (vbaraw) */

  ['password', ''], /* password */
  ['WTF', false] /* WTF mode (throws errors) */])(opts);
}
function fix_write_opts(opts) {
  fix_opts_func([['cellDates', false], /* write date cells with type `d` */

  ['bookSST', false], /* Generate Shared String Table */

  ['bookType', 'xlsx'], /* Type of workbook (xlsx/m/b) */

  ['compression', false], /* Use file compression */

  ['WTF', false] /* WTF mode (throws errors) */])(opts);
}
function get_sheet_type(n /*:string*/) /*:string*/{
  if (RELS.WS.indexOf(n) > -1) return "sheet";
  if (RELS.CS && n == RELS.CS) return "chart";
  if (RELS.DS && n == RELS.DS) return "dialog";
  if (RELS.MS && n == RELS.MS) return "macro";
  return n && n.length ? n : "sheet";
}
function safe_parse_wbrels(wbrels, sheets) {
  if (!wbrels) return 0;
  try {
    wbrels = sheets.map(function pwbr(w) {
      if (!w.id) w.id = w.strRelID;
      return [w.name, wbrels['!id'][w.id].Target, get_sheet_type(wbrels['!id'][w.id].Type)];
    });
  } catch (e) {
    return null;
  }
  return !wbrels || wbrels.length === 0 ? null : wbrels;
}
function safe_parse_sheet(zip, path /*:string*/, relsPath /*:string*/, sheet, idx /*:number*/, sheetRels, sheets, stype /*:string*/, opts, wb, themes, styles) {
  try {
    sheetRels[sheet] = parse_rels(getzipstr(zip, relsPath, true), path);
    var data = getzipdata(zip, path);
    var _ws;
    switch (stype) {
      case 'sheet':
        _ws = parse_ws(data, path, idx, opts, sheetRels[sheet], wb, themes, styles);
        break;
      case 'chart':
        _ws = parse_cs(data, path, idx, opts, sheetRels[sheet], wb, themes, styles);
        if (!_ws || !_ws['!drawel']) break;
        var dfile = resolve_path(_ws['!drawel'].Target, path);
        var drelsp = get_rels_path(dfile);
        var draw = parse_drawing(getzipstr(zip, dfile, true), parse_rels(getzipstr(zip, drelsp, true), dfile));
        var chartp = resolve_path(draw, dfile);
        var crelsp = get_rels_path(chartp);
        _ws = parse_chart(getzipstr(zip, chartp, true), chartp, opts, parse_rels(getzipstr(zip, crelsp, true), chartp), wb, _ws);
        break;
      case 'macro':
        _ws = parse_ms(data, path, idx, opts, sheetRels[sheet], wb, themes, styles);
        break;
      case 'dialog':
        _ws = parse_ds(data, path, idx, opts, sheetRels[sheet], wb, themes, styles);
        break;
      default:
        throw new Error("Unrecognized sheet type " + stype);
    }
    sheets[sheet] = _ws;

    /* scan rels for comments and threaded comments */
    var tcomments = [];
    if (sheetRels && sheetRels[sheet]) keys(sheetRels[sheet]).forEach(function (n) {
      var dfile = "";
      if (sheetRels[sheet][n].Type == RELS.CMNT) {
        dfile = resolve_path(sheetRels[sheet][n].Target, path);
        var comments = parse_cmnt(getzipdata(zip, dfile, true), dfile, opts);
        if (!comments || !comments.length) return;
        sheet_insert_comments(_ws, comments, false);
      }
      if (sheetRels[sheet][n].Type == RELS.TCMNT) {
        dfile = resolve_path(sheetRels[sheet][n].Target, path);
        tcomments = tcomments.concat(parse_tcmnt_xml(getzipdata(zip, dfile, true), opts));
      }
    });
    if (tcomments && tcomments.length) sheet_insert_comments(_ws, tcomments, true, opts.people || []);
  } catch (e) {
    if (opts.WTF) throw e;
  }
}
function strip_front_slash(x /*:string*/) /*:string*/{
  return x.charAt(0) == '/' ? x.slice(1) : x;
}
function parse_zip(zip /*:ZIP*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  make_ssf();
  opts = opts || {};
  fix_read_opts(opts);

  /* OpenDocument Part 3 Section 2.2.1 OpenDocument Package */
  if (safegetzipfile(zip, 'META-INF/manifest.xml')) return parse_ods(zip, opts);
  /* UOC */
  if (safegetzipfile(zip, 'objectdata.xml')) return parse_ods(zip, opts);
  /* Numbers */
  if (safegetzipfile(zip, 'Index/Document.iwa')) {
    if (typeof Uint8Array == "undefined") throw new Error('NUMBERS file parsing requires Uint8Array support');
    if (typeof parse_numbers_iwa != "undefined") {
      if (zip.FileIndex) return parse_numbers_iwa(zip);
      var _zip = CFB.utils.cfb_new();
      zipentries(zip).forEach(function (e) {
        zip_add_file(_zip, e, getzipbin(zip, e));
      });
      return parse_numbers_iwa(_zip);
    }
    throw new Error('Unsupported NUMBERS file');
  }
  if (!safegetzipfile(zip, '[Content_Types].xml')) {
    if (safegetzipfile(zip, 'index.xml.gz')) throw new Error('Unsupported NUMBERS 08 file');
    if (safegetzipfile(zip, 'index.xml')) throw new Error('Unsupported NUMBERS 09 file');
    throw new Error('Unsupported ZIP file');
  }
  var entries = zipentries(zip);
  var dir = parse_ct(getzipstr(zip, '[Content_Types].xml') /*:?any*/);
  var xlsb = false;
  var sheets, binname;
  if (dir.workbooks.length === 0) {
    binname = "xl/workbook.xml";
    if (getzipdata(zip, binname, true)) dir.workbooks.push(binname);
  }
  if (dir.workbooks.length === 0) {
    binname = "xl/workbook.bin";
    if (!getzipdata(zip, binname, true)) throw new Error("Could not find workbook");
    dir.workbooks.push(binname);
    xlsb = true;
  }
  if (dir.workbooks[0].slice(-3) == "bin") xlsb = true;
  var themes = {} /*:any*/;
  var styles = {} /*:any*/;
  if (!opts.bookSheets && !opts.bookProps) {
    strs = [];
    if (dir.sst) try {
      strs = parse_sst(getzipdata(zip, strip_front_slash(dir.sst)), dir.sst, opts);
    } catch (e) {
      if (opts.WTF) throw e;
    }
    if (opts.cellStyles && dir.themes.length) themes = parse_theme(getzipstr(zip, dir.themes[0].replace(/^\//, ''), true) || "", dir.themes[0], opts);
    if (dir.style) styles = parse_sty(getzipdata(zip, strip_front_slash(dir.style)), dir.style, themes, opts);
  }

  /*var externbooks = */
  dir.links.map(function (link) {
    try {
      var rels = parse_rels(getzipstr(zip, get_rels_path(strip_front_slash(link))), link);
      return parse_xlink(getzipdata(zip, strip_front_slash(link)), rels, link, opts);
    } catch (e) {}
  });
  var wb = parse_wb(getzipdata(zip, strip_front_slash(dir.workbooks[0])), dir.workbooks[0], opts);
  var props = {},
    propdata = "";
  if (dir.coreprops.length) {
    propdata = getzipdata(zip, strip_front_slash(dir.coreprops[0]), true);
    if (propdata) props = parse_core_props(propdata);
    if (dir.extprops.length !== 0) {
      propdata = getzipdata(zip, strip_front_slash(dir.extprops[0]), true);
      if (propdata) parse_ext_props(propdata, props, opts);
    }
  }
  var custprops = {};
  if (!opts.bookSheets || opts.bookProps) {
    if (dir.custprops.length !== 0) {
      propdata = getzipstr(zip, strip_front_slash(dir.custprops[0]), true);
      if (propdata) custprops = parse_cust_props(propdata, opts);
    }
  }
  var out = {} /*:any*/;
  if (opts.bookSheets || opts.bookProps) {
    if (wb.Sheets) sheets = wb.Sheets.map(function pluck(x) {
      return x.name;
    });else if (props.Worksheets && props.SheetNames.length > 0) sheets = props.SheetNames;
    if (opts.bookProps) {
      out.Props = props;
      out.Custprops = custprops;
    }
    if (opts.bookSheets && typeof sheets !== 'undefined') out.SheetNames = sheets;
    if (opts.bookSheets ? out.SheetNames : opts.bookProps) return out;
  }
  sheets = {};
  var deps = {};
  if (opts.bookDeps && dir.calcchain) deps = parse_cc(getzipdata(zip, strip_front_slash(dir.calcchain)), dir.calcchain, opts);
  var i = 0;
  var sheetRels = {} /*:any*/;
  var path, relsPath;
  {
    var wbsheets = wb.Sheets;
    props.Worksheets = wbsheets.length;
    props.SheetNames = [];
    for (var j = 0; j != wbsheets.length; ++j) {
      props.SheetNames[j] = wbsheets[j].name;
    }
  }
  var wbext = xlsb ? "bin" : "xml";
  var wbrelsi = dir.workbooks[0].lastIndexOf("/");
  var wbrelsfile = (dir.workbooks[0].slice(0, wbrelsi + 1) + "_rels/" + dir.workbooks[0].slice(wbrelsi + 1) + ".rels").replace(/^\//, "");
  if (!safegetzipfile(zip, wbrelsfile)) wbrelsfile = 'xl/_rels/workbook.' + wbext + '.rels';
  var wbrels = parse_rels(getzipstr(zip, wbrelsfile, true), wbrelsfile.replace(/_rels.*/, "s5s"));
  if ((dir.metadata || []).length >= 1) {
    /* TODO: MDX and other types of metadata */
    opts.xlmeta = parse_xlmeta(getzipdata(zip, strip_front_slash(dir.metadata[0])), dir.metadata[0], opts);
  }
  if ((dir.people || []).length >= 1) {
    opts.people = parse_people_xml(getzipdata(zip, strip_front_slash(dir.people[0])), opts);
  }
  if (wbrels) wbrels = safe_parse_wbrels(wbrels, wb.Sheets);

  /* Numbers iOS hack */
  var nmode = getzipdata(zip, "xl/worksheets/sheet.xml", true) ? 1 : 0;
  wsloop: for (i = 0; i != props.Worksheets; ++i) {
    var stype = "sheet";
    if (wbrels && wbrels[i]) {
      path = 'xl/' + wbrels[i][1].replace(/[\/]?xl\//, "");
      if (!safegetzipfile(zip, path)) path = wbrels[i][1];
      if (!safegetzipfile(zip, path)) path = wbrelsfile.replace(/_rels\/.*$/, "") + wbrels[i][1];
      stype = wbrels[i][2];
    } else {
      path = 'xl/worksheets/sheet' + (i + 1 - nmode) + "." + wbext;
      path = path.replace(/sheet0\./, "sheet.");
    }
    relsPath = path.replace(/^(.*)(\/)([^\/]*)$/, "$1/_rels/$3.rels");
    if (opts && opts.sheets != null) switch (typeof opts.sheets) {
      case "number":
        if (i != opts.sheets) continue wsloop;
        break;
      case "string":
        if (props.SheetNames[i].toLowerCase() != opts.sheets.toLowerCase()) continue wsloop;
        break;
      default:
        if (Array.isArray && Array.isArray(opts.sheets)) {
          var snjseen = false;
          for (var snj = 0; snj != opts.sheets.length; ++snj) {
            if (typeof opts.sheets[snj] == "number" && opts.sheets[snj] == i) snjseen = 1;
            if (typeof opts.sheets[snj] == "string" && opts.sheets[snj].toLowerCase() == props.SheetNames[i].toLowerCase()) snjseen = 1;
          }
          if (!snjseen) continue wsloop;
        }
    }
    safe_parse_sheet(zip, path, relsPath, props.SheetNames[i], i, sheetRels, sheets, stype, opts, wb, themes, styles);
  }
  out = {
    Directory: dir,
    Workbook: wb,
    Props: props,
    Custprops: custprops,
    Deps: deps,
    Sheets: sheets,
    SheetNames: props.SheetNames,
    Strings: strs,
    Styles: styles,
    Themes: themes,
    SSF: dup(table_fmt)
  } /*:any*/;
  if (opts && opts.bookFiles) {
    if (zip.files) {
      out.keys = entries;
      out.files = zip.files;
    } else {
      out.keys = [];
      out.files = {};
      zip.FullPaths.forEach(function (p, idx) {
        p = p.replace(/^Root Entry[\/]/, "");
        out.keys.push(p);
        out.files[p] = zip.FileIndex[idx];
      });
    }
  }
  if (opts && opts.bookVBA) {
    if (dir.vba.length > 0) out.vbaraw = getzipdata(zip, strip_front_slash(dir.vba[0]), true);else if (dir.defaults && dir.defaults.bin === CT_VBA) out.vbaraw = getzipdata(zip, 'xl/vbaProject.bin', true);
  }
  return out;
}

/* [MS-OFFCRYPTO] 2.1.1 */
function parse_xlsxcfb(cfb, _opts /*:?ParseOpts*/) /*:Workbook*/{
  var opts = _opts || {};
  var f = 'Workbook',
    data = CFB.find(cfb, f);
  try {
    f = '/!DataSpaces/Version';
    data = CFB.find(cfb, f);
    if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
    /*var version = */
    parse_DataSpaceVersionInfo(data.content);

    /* 2.3.4.1 */
    f = '/!DataSpaces/DataSpaceMap';
    data = CFB.find(cfb, f);
    if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
    var dsm = parse_DataSpaceMap(data.content);
    if (dsm.length !== 1 || dsm[0].comps.length !== 1 || dsm[0].comps[0].t !== 0 || dsm[0].name !== "StrongEncryptionDataSpace" || dsm[0].comps[0].v !== "EncryptedPackage") throw new Error("ECMA-376 Encrypted file bad " + f);

    /* 2.3.4.2 */
    f = '/!DataSpaces/DataSpaceInfo/StrongEncryptionDataSpace';
    data = CFB.find(cfb, f);
    if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
    var seds = parse_DataSpaceDefinition(data.content);
    if (seds.length != 1 || seds[0] != "StrongEncryptionTransform") throw new Error("ECMA-376 Encrypted file bad " + f);

    /* 2.3.4.3 */
    f = '/!DataSpaces/TransformInfo/StrongEncryptionTransform/!Primary';
    data = CFB.find(cfb, f);
    if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
    /*var hdr = */
    parse_Primary(data.content);
  } catch (e) {}
  f = '/EncryptionInfo';
  data = CFB.find(cfb, f);
  if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);
  var einfo = parse_EncryptionInfo(data.content);

  /* 2.3.4.4 */
  f = '/EncryptedPackage';
  data = CFB.find(cfb, f);
  if (!data || !data.content) throw new Error("ECMA-376 Encrypted file missing " + f);

  /*global decrypt_agile */
  /*:: declare var decrypt_agile:any; */
  if (einfo[0] == 0x04 && typeof decrypt_agile !== 'undefined') return decrypt_agile(einfo[1], data.content, opts.password || "", opts);
  /*global decrypt_std76 */
  /*:: declare var decrypt_std76:any; */
  if (einfo[0] == 0x02 && typeof decrypt_std76 !== 'undefined') return decrypt_std76(einfo[1], data.content, opts.password || "", opts);
  throw new Error("File is password-protected");
}
function write_zip(wb /*:Workbook*/, opts /*:WriteOpts*/) /*:ZIP*/{
  if (opts.bookType == "ods") return write_ods(wb, opts);
  if (opts.bookType == "numbers") return write_numbers_iwa(wb, opts);
  if (opts.bookType == "xlsb") return write_zip_xlsxb(wb, opts);
  return write_zip_xlsx(wb, opts);
}

/* XLSX and XLSB writing are very similar.  Originally they were unified in one
   export function.  This is horrible for tree shaking in the common case (most
   applications need to export files in one format) so this function supports
   both formats while write_zip_xlsx only handles XLSX */
function write_zip_xlsxb(wb /*:Workbook*/, opts /*:WriteOpts*/) /*:ZIP*/{
  _shapeid = 1024;
  if (wb && !wb.SSF) {
    wb.SSF = dup(table_fmt);
  }
  if (wb && wb.SSF) {
    make_ssf();
    SSF_load_table(wb.SSF);
    // $FlowIgnore
    opts.revssf = evert_num(wb.SSF);
    opts.revssf[wb.SSF[65535]] = 0;
    opts.ssf = wb.SSF;
  }
  opts.rels = {};
  opts.wbrels = {};
  opts.Strings = /*::((*/[] /*:: :any):SST)*/;
  opts.Strings.Count = 0;
  opts.Strings.Unique = 0;
  if (browser_has_Map) opts.revStrings = new Map();else {
    opts.revStrings = {};
    opts.revStrings.foo = [];
    delete opts.revStrings.foo;
  }
  var wbext = opts.bookType == "xlsb" ? "bin" : "xml";
  var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
  var ct = new_ct();
  fix_write_opts(opts = opts || {});
  var zip = zip_new();
  var f = "",
    rId = 0;
  opts.cellXfs = [];
  get_cell_style(opts.cellXfs, {}, {
    revssf: {
      "General": 0
    }
  });
  if (!wb.Props) wb.Props = {};
  f = "docProps/core.xml";
  zip_add_file(zip, f, write_core_props(wb.Props, opts));
  ct.coreprops.push(f);
  add_rels(opts.rels, 2, f, RELS.CORE_PROPS);

  /*::if(!wb.Props) throw "unreachable"; */
  f = "docProps/app.xml";
  if (wb.Props && wb.Props.SheetNames) {/* empty */} else if (!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;else {
    var _sn = [];
    for (var _i = 0; _i < wb.SheetNames.length; ++_i) if ((wb.Workbook.Sheets[_i] || {}).Hidden != 2) _sn.push(wb.SheetNames[_i]);
    wb.Props.SheetNames = _sn;
  }
  wb.Props.Worksheets = wb.Props.SheetNames.length;
  zip_add_file(zip, f, write_ext_props(wb.Props, opts));
  ct.extprops.push(f);
  add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
  if (wb.Custprops !== wb.Props && keys(wb.Custprops || {}).length > 0) {
    f = "docProps/custom.xml";
    zip_add_file(zip, f, write_cust_props(wb.Custprops, opts));
    ct.custprops.push(f);
    add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
  }
  for (rId = 1; rId <= wb.SheetNames.length; ++rId) {
    var wsrels = {
      '!id': {}
    };
    var ws = wb.Sheets[wb.SheetNames[rId - 1]];
    var _type = (ws || {})["!type"] || "sheet";
    switch (_type) {
      case "chart":
      /* falls through */
      default:
        f = "xl/worksheets/sheet" + rId + "." + wbext;
        zip_add_file(zip, f, write_ws(rId - 1, f, opts, wb, wsrels));
        ct.sheets.push(f);
        add_rels(opts.wbrels, -1, "worksheets/sheet" + rId + "." + wbext, RELS.WS[0]);
    }
    if (ws) {
      var comments = ws['!comments'];
      var need_vml = false;
      var cf = "";
      if (comments && comments.length > 0) {
        cf = "xl/comments" + rId + "." + wbext;
        zip_add_file(zip, cf, write_cmnt(comments, cf, opts));
        ct.comments.push(cf);
        add_rels(wsrels, -1, "../comments" + rId + "." + wbext, RELS.CMNT);
        need_vml = true;
      }
      if (ws['!legacy']) {
        if (need_vml) zip_add_file(zip, "xl/drawings/vmlDrawing" + rId + ".vml", write_comments_vml(rId, ws['!comments']));
      }
      delete ws['!comments'];
      delete ws['!legacy'];
    }
    if (wsrels['!id'].rId1) zip_add_file(zip, get_rels_path(f), write_rels(wsrels));
  }
  if (opts.Strings != null && opts.Strings.length > 0) {
    f = "xl/sharedStrings." + wbext;
    zip_add_file(zip, f, write_sst(opts.Strings, f, opts));
    ct.strs.push(f);
    add_rels(opts.wbrels, -1, "sharedStrings." + wbext, RELS.SST);
  }
  f = "xl/workbook." + wbext;
  zip_add_file(zip, f, write_wb(wb, f, opts));
  ct.workbooks.push(f);
  add_rels(opts.rels, 1, f, RELS.WB);

  /* TODO: something more intelligent with themes */

  f = "xl/theme/theme1.xml";
  zip_add_file(zip, f, write_theme(wb.Themes, opts));
  ct.themes.push(f);
  add_rels(opts.wbrels, -1, "theme/theme1.xml", RELS.THEME);

  /* TODO: something more intelligent with styles */

  f = "xl/styles." + wbext;
  zip_add_file(zip, f, write_sty(wb, f, opts));
  ct.styles.push(f);
  add_rels(opts.wbrels, -1, "styles." + wbext, RELS.STY);
  if (wb.vbaraw && vbafmt) {
    f = "xl/vbaProject.bin";
    zip_add_file(zip, f, wb.vbaraw);
    ct.vba.push(f);
    add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
  }
  f = "xl/metadata." + wbext;
  zip_add_file(zip, f, write_xlmeta(f));
  ct.metadata.push(f);
  add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
  zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
  zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
  zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
  delete opts.revssf;
  delete opts.ssf;
  return zip;
}
function write_zip_xlsx(wb /*:Workbook*/, opts /*:WriteOpts*/) /*:ZIP*/{
  _shapeid = 1024;
  if (wb && !wb.SSF) {
    wb.SSF = dup(table_fmt);
  }
  if (wb && wb.SSF) {
    make_ssf();
    SSF_load_table(wb.SSF);
    // $FlowIgnore
    opts.revssf = evert_num(wb.SSF);
    opts.revssf[wb.SSF[65535]] = 0;
    opts.ssf = wb.SSF;
  }
  opts.rels = {};
  opts.wbrels = {};
  opts.Strings = /*::((*/[] /*:: :any):SST)*/;
  opts.Strings.Count = 0;
  opts.Strings.Unique = 0;
  if (browser_has_Map) opts.revStrings = new Map();else {
    opts.revStrings = {};
    opts.revStrings.foo = [];
    delete opts.revStrings.foo;
  }
  var wbext = "xml";
  var vbafmt = VBAFMTS.indexOf(opts.bookType) > -1;
  var ct = new_ct();
  fix_write_opts(opts = opts || {});
  var zip = zip_new();
  var f = "",
    rId = 0;
  opts.cellXfs = [];
  get_cell_style(opts.cellXfs, {}, {
    revssf: {
      "General": 0
    }
  });
  if (!wb.Props) wb.Props = {};
  f = "docProps/core.xml";
  zip_add_file(zip, f, write_core_props(wb.Props, opts));
  ct.coreprops.push(f);
  add_rels(opts.rels, 2, f, RELS.CORE_PROPS);

  /*::if(!wb.Props) throw "unreachable"; */
  f = "docProps/app.xml";
  if (wb.Props && wb.Props.SheetNames) {/* empty */} else if (!wb.Workbook || !wb.Workbook.Sheets) wb.Props.SheetNames = wb.SheetNames;else {
    var _sn = [];
    for (var _i = 0; _i < wb.SheetNames.length; ++_i) if ((wb.Workbook.Sheets[_i] || {}).Hidden != 2) _sn.push(wb.SheetNames[_i]);
    wb.Props.SheetNames = _sn;
  }
  wb.Props.Worksheets = wb.Props.SheetNames.length;
  zip_add_file(zip, f, write_ext_props(wb.Props, opts));
  ct.extprops.push(f);
  add_rels(opts.rels, 3, f, RELS.EXT_PROPS);
  if (wb.Custprops !== wb.Props && keys(wb.Custprops || {}).length > 0) {
    f = "docProps/custom.xml";
    zip_add_file(zip, f, write_cust_props(wb.Custprops, opts));
    ct.custprops.push(f);
    add_rels(opts.rels, 4, f, RELS.CUST_PROPS);
  }
  var people = ["SheetJ5"];
  opts.tcid = 0;
  for (rId = 1; rId <= wb.SheetNames.length; ++rId) {
    var wsrels = {
      '!id': {}
    };
    var ws = wb.Sheets[wb.SheetNames[rId - 1]];
    var _type = (ws || {})["!type"] || "sheet";
    switch (_type) {
      case "chart":
      /* falls through */
      default:
        f = "xl/worksheets/sheet" + rId + "." + wbext;
        zip_add_file(zip, f, write_ws_xml(rId - 1, opts, wb, wsrels));
        ct.sheets.push(f);
        add_rels(opts.wbrels, -1, "worksheets/sheet" + rId + "." + wbext, RELS.WS[0]);
    }
    if (ws) {
      var comments = ws['!comments'];
      var need_vml = false;
      var cf = "";
      if (comments && comments.length > 0) {
        var needtc = false;
        comments.forEach(function (carr) {
          carr[1].forEach(function (c) {
            if (c.T == true) needtc = true;
          });
        });
        if (needtc) {
          cf = "xl/threadedComments/threadedComment" + rId + "." + wbext;
          zip_add_file(zip, cf, write_tcmnt_xml(comments, people, opts));
          ct.threadedcomments.push(cf);
          add_rels(wsrels, -1, "../threadedComments/threadedComment" + rId + "." + wbext, RELS.TCMNT);
        }
        cf = "xl/comments" + rId + "." + wbext;
        zip_add_file(zip, cf, write_comments_xml(comments, opts));
        ct.comments.push(cf);
        add_rels(wsrels, -1, "../comments" + rId + "." + wbext, RELS.CMNT);
        need_vml = true;
      }
      if (ws['!legacy']) {
        if (need_vml) zip_add_file(zip, "xl/drawings/vmlDrawing" + rId + ".vml", write_comments_vml(rId, ws['!comments']));
      }
      delete ws['!comments'];
      delete ws['!legacy'];
    }
    if (wsrels['!id'].rId1) zip_add_file(zip, get_rels_path(f), write_rels(wsrels));
  }
  if (opts.Strings != null && opts.Strings.length > 0) {
    f = "xl/sharedStrings." + wbext;
    zip_add_file(zip, f, write_sst_xml(opts.Strings, opts));
    ct.strs.push(f);
    add_rels(opts.wbrels, -1, "sharedStrings." + wbext, RELS.SST);
  }
  f = "xl/workbook." + wbext;
  zip_add_file(zip, f, write_wb_xml(wb, opts));
  ct.workbooks.push(f);
  add_rels(opts.rels, 1, f, RELS.WB);

  /* TODO: something more intelligent with themes */

  f = "xl/theme/theme1.xml";
  zip_add_file(zip, f, write_theme(wb.Themes, opts));
  ct.themes.push(f);
  add_rels(opts.wbrels, -1, "theme/theme1.xml", RELS.THEME);

  /* TODO: something more intelligent with styles */

  f = "xl/styles." + wbext;
  zip_add_file(zip, f, write_sty_xml(wb, opts));
  ct.styles.push(f);
  add_rels(opts.wbrels, -1, "styles." + wbext, RELS.STY);
  if (wb.vbaraw && vbafmt) {
    f = "xl/vbaProject.bin";
    zip_add_file(zip, f, wb.vbaraw);
    ct.vba.push(f);
    add_rels(opts.wbrels, -1, "vbaProject.bin", RELS.VBA);
  }
  f = "xl/metadata." + wbext;
  zip_add_file(zip, f, write_xlmeta_xml());
  ct.metadata.push(f);
  add_rels(opts.wbrels, -1, "metadata." + wbext, RELS.XLMETA);
  if (people.length > 1) {
    f = "xl/persons/person.xml";
    zip_add_file(zip, f, write_people_xml(people, opts));
    ct.people.push(f);
    add_rels(opts.wbrels, -1, "persons/person.xml", RELS.PEOPLE);
  }
  zip_add_file(zip, "[Content_Types].xml", write_ct(ct, opts));
  zip_add_file(zip, '_rels/.rels', write_rels(opts.rels));
  zip_add_file(zip, 'xl/_rels/workbook.' + wbext + '.rels', write_rels(opts.wbrels));
  delete opts.revssf;
  delete opts.ssf;
  return zip;
}
function firstbyte(f /*:RawData*/, o /*:?TypeOpts*/) /*:Array<number>*/{
  var x = "";
  switch ((o || {}).type || "base64") {
    case 'buffer':
      return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
    case 'base64':
      x = Base64_decode(f.slice(0, 12));
      break;
    case 'binary':
      x = f;
      break;
    case 'array':
      return [f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7]];
    default:
      throw new Error("Unrecognized type " + (o && o.type || "undefined"));
  }
  return [x.charCodeAt(0), x.charCodeAt(1), x.charCodeAt(2), x.charCodeAt(3), x.charCodeAt(4), x.charCodeAt(5), x.charCodeAt(6), x.charCodeAt(7)];
}
function read_cfb(cfb /*:CFBContainer*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  if (CFB.find(cfb, "EncryptedPackage")) return parse_xlsxcfb(cfb, opts);
  return parse_xlscfb(cfb, opts);
}
function read_zip(data /*:RawData*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  var zip,
    d = data;
  var o = opts || {};
  if (!o.type) o.type = has_buf && Buffer.isBuffer(data) ? "buffer" : "base64";
  zip = zip_read(d, o);
  return parse_zip(zip, o);
}
function read_plaintext(data /*:string*/, o /*:ParseOpts*/) /*:Workbook*/{
  var i = 0;
  main: while (i < data.length) switch (data.charCodeAt(i)) {
    case 0x0A:
    case 0x0D:
    case 0x20:
      ++i;
      break;
    case 0x3C:
      return parse_xlml(data.slice(i), o);
    default:
      break main;
  }
  return PRN.to_workbook(data, o);
}
function read_plaintext_raw(data /*:RawData*/, o /*:ParseOpts*/) /*:Workbook*/{
  var str = "",
    bytes = firstbyte(data, o);
  switch (o.type) {
    case 'base64':
      str = Base64_decode(data);
      break;
    case 'binary':
      str = data;
      break;
    case 'buffer':
      str = data.toString('binary');
      break;
    case 'array':
      str = cc2str(data);
      break;
    default:
      throw new Error("Unrecognized type " + o.type);
  }
  if (bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF) str = utf8read(str);
  o.type = "binary";
  return read_plaintext(str, o);
}
function read_utf16(data /*:RawData*/, o /*:ParseOpts*/) /*:Workbook*/{
  var d = data;
  if (o.type == 'base64') d = Base64_decode(d);
  d = $cptable.utils.decode(1200, d.slice(2), 'str');
  o.type = "binary";
  return read_plaintext(d, o);
}
function bstrify(data /*:string*/) /*:string*/{
  return !data.match(/[^\x00-\x7F]/) ? data : utf8write(data);
}
function read_prn(data, d, o, str) {
  if (str) {
    o.type = "string";
    return PRN.to_workbook(data, o);
  }
  return PRN.to_workbook(d, o);
}
function readSync(data /*:RawData*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  reset_cp();
  var o = opts || {};
  if (typeof ArrayBuffer !== 'undefined' && data instanceof ArrayBuffer) return readSync(new Uint8Array(data), (o = dup(o), o.type = "array", o));
  if (typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && !o.type) o.type = typeof Deno !== "undefined" ? "buffer" : "array";
  var d = data,
    n = [0, 0, 0, 0],
    str = false;
  if (o.cellStyles) {
    o.cellNF = true;
    o.sheetStubs = true;
  }
  _ssfopts = {};
  if (o.dateNF) _ssfopts.dateNF = o.dateNF;
  if (!o.type) o.type = has_buf && Buffer.isBuffer(data) ? "buffer" : "base64";
  if (o.type == "file") {
    o.type = has_buf ? "buffer" : "binary";
    d = read_binary(data);
    if (typeof Uint8Array !== 'undefined' && !has_buf) o.type = "array";
  }
  if (o.type == "string") {
    str = true;
    o.type = "binary";
    o.codepage = 65001;
    d = bstrify(data);
  }
  if (o.type == 'array' && typeof Uint8Array !== 'undefined' && data instanceof Uint8Array && typeof ArrayBuffer !== 'undefined') {
    // $FlowIgnore
    var ab = new ArrayBuffer(3),
      vu = new Uint8Array(ab);
    vu.foo = "bar";
    // $FlowIgnore
    if (!vu.foo) {
      o = dup(o);
      o.type = 'array';
      return readSync(ab2a(d), o);
    }
  }
  switch ((n = firstbyte(d, o))[0]) {
    case 0xD0:
      if (n[1] === 0xCF && n[2] === 0x11 && n[3] === 0xE0 && n[4] === 0xA1 && n[5] === 0xB1 && n[6] === 0x1A && n[7] === 0xE1) return read_cfb(CFB.read(d, o), o);
      break;
    case 0x09:
      if (n[1] <= 0x08) return parse_xlscfb(d, o);
      break;
    case 0x3C:
      return parse_xlml(d, o);
    case 0x49:
      if (n[1] === 0x49 && n[2] === 0x2a && n[3] === 0x00) throw new Error("TIFF Image File is not a spreadsheet");
      if (n[1] === 0x44) return read_wb_ID(d, o);
      break;
    case 0x54:
      if (n[1] === 0x41 && n[2] === 0x42 && n[3] === 0x4C) return DIF.to_workbook(d, o);
      break;
    case 0x50:
      return n[1] === 0x4B && n[2] < 0x09 && n[3] < 0x09 ? read_zip(d, o) : read_prn(data, d, o, str);
    case 0xEF:
      return n[3] === 0x3C ? parse_xlml(d, o) : read_prn(data, d, o, str);
    case 0xFF:
      if (n[1] === 0xFE) {
        return read_utf16(d, o);
      } else if (n[1] === 0x00 && n[2] === 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
      break;
    case 0x00:
      if (n[1] === 0x00) {
        if (n[2] >= 0x02 && n[3] === 0x00) return WK_.to_workbook(d, o);
        if (n[2] === 0x00 && (n[3] === 0x08 || n[3] === 0x09)) return WK_.to_workbook(d, o);
      }
      break;
    case 0x03:
    case 0x83:
    case 0x8B:
    case 0x8C:
      return DBF.to_workbook(d, o);
    case 0x7B:
      if (n[1] === 0x5C && n[2] === 0x72 && n[3] === 0x74) return RTF.to_workbook(d, o);
      break;
    case 0x0A:
    case 0x0D:
    case 0x20:
      return read_plaintext_raw(d, o);
    case 0x89:
      if (n[1] === 0x50 && n[2] === 0x4E && n[3] === 0x47) throw new Error("PNG Image File is not a spreadsheet");
      break;
  }
  if (DBF_SUPPORTED_VERSIONS.indexOf(n[0]) > -1 && n[2] <= 12 && n[3] <= 31) return DBF.to_workbook(d, o);
  return read_prn(data, d, o, str);
}
function readFileSync(filename /*:string*/, opts /*:?ParseOpts*/) /*:Workbook*/{
  var o = opts || {};
  o.type = 'file';
  return readSync(filename, o);
}
function write_cfb_ctr(cfb /*:CFBContainer*/, o /*:WriteOpts*/) /*:any*/{
  switch (o.type) {
    case "base64":
    case "binary":
      break;
    case "buffer":
    case "array":
      o.type = "";
      break;
    case "file":
      return write_dl(o.file, CFB.write(cfb, {
        type: has_buf ? 'buffer' : ""
      }));
    case "string":
      throw new Error("'string' output type invalid for '" + o.bookType + "' files");
    default:
      throw new Error("Unrecognized type " + o.type);
  }
  return CFB.write(cfb, o);
}

/*:: declare var encrypt_agile:any; */
function write_zip_type(wb /*:Workbook*/, opts /*:?WriteOpts*/) /*:any*/{
  var o = dup(opts || {});
  var z = write_zip(wb, o);
  return write_zip_denouement(z, o);
}
function write_zip_typeXLSX(wb /*:Workbook*/, opts /*:?WriteOpts*/) /*:any*/{
  var o = dup(opts || {});
  var z = write_zip_xlsx(wb, o);
  return write_zip_denouement(z, o);
}
function write_zip_denouement(z /*:any*/, o /*:?WriteOpts*/) /*:any*/{
  var oopts = {};
  var ftype = has_buf ? "nodebuffer" : typeof Uint8Array !== "undefined" ? "array" : "string";
  if (o.compression) oopts.compression = 'DEFLATE';
  if (o.password) oopts.type = ftype;else switch (o.type) {
    case "base64":
      oopts.type = "base64";
      break;
    case "binary":
      oopts.type = "string";
      break;
    case "string":
      throw new Error("'string' output type invalid for '" + o.bookType + "' files");
    case "buffer":
    case "file":
      oopts.type = ftype;
      break;
    default:
      throw new Error("Unrecognized type " + o.type);
  }
  var out = z.FullPaths ? CFB.write(z, {
    fileType: "zip",
    type: /*::(*/{
      "nodebuffer": "buffer",
      "string": "binary"
    } /*:: :any)*/[oopts.type] || oopts.type,
    compression: !!o.compression
  }) : z.generate(oopts);
  if (typeof Deno !== "undefined") {
    if (typeof out == "string") {
      if (o.type == "binary" || o.type == "base64") return out;
      out = new Uint8Array(s2ab(out));
    }
  }
  /*jshint -W083 */
  if (o.password && typeof encrypt_agile !== 'undefined') return write_cfb_ctr(encrypt_agile(out, o.password), o); // eslint-disable-line no-undef
  /*jshint +W083 */
  if (o.type === "file") return write_dl(o.file, out);
  return o.type == "string" ? utf8read(/*::(*/out /*:: :any)*/) : out;
}
function write_cfb_type(wb /*:Workbook*/, opts /*:?WriteOpts*/) /*:any*/{
  var o = opts || {};
  var cfb /*:CFBContainer*/ = write_xlscfb(wb, o);
  return write_cfb_ctr(cfb, o);
}
function write_string_type(out /*:string*/, opts /*:WriteOpts*/, bom /*:?string*/) /*:any*/{
  if (!bom) bom = "";
  var o = bom + out;
  switch (opts.type) {
    case "base64":
      return Base64_encode(utf8write(o));
    case "binary":
      return utf8write(o);
    case "string":
      return out;
    case "file":
      return write_dl(opts.file, o, 'utf8');
    case "buffer":
      {
        if (has_buf) return Buffer_from(o, 'utf8');else if (typeof TextEncoder !== "undefined") return new TextEncoder().encode(o);else return write_string_type(o, {
          type: 'binary'
        }).split("").map(function (c) {
          return c.charCodeAt(0);
        });
      }
  }
  throw new Error("Unrecognized type " + opts.type);
}
function write_stxt_type(out /*:string*/, opts /*:WriteOpts*/) /*:any*/{
  switch (opts.type) {
    case "base64":
      return Base64_encode(out);
    case "binary":
      return out;
    case "string":
      return out;
    /* override in sheet_to_txt */
    case "file":
      return write_dl(opts.file, out, 'binary');
    case "buffer":
      {
        if (has_buf) return Buffer_from(out, 'binary');else return out.split("").map(function (c) {
          return c.charCodeAt(0);
        });
      }
  }
  throw new Error("Unrecognized type " + opts.type);
}

/* TODO: test consistency */
function write_binary_type(out, opts /*:WriteOpts*/) /*:any*/{
  switch (opts.type) {
    case "string":
    case "base64":
    case "binary":
      var bstr = "";
      // $FlowIgnore
      for (var i = 0; i < out.length; ++i) bstr += String.fromCharCode(out[i]);
      return opts.type == 'base64' ? Base64_encode(bstr) : opts.type == 'string' ? utf8read(bstr) : bstr;
    case "file":
      return write_dl(opts.file, out);
    case "buffer":
      return out;
    default:
      throw new Error("Unrecognized type " + opts.type);
  }
}
function writeSyncXLSX(wb /*:Workbook*/, opts /*:?WriteOpts*/) {
  reset_cp();
  check_wb(wb);
  var o = dup(opts || {});
  if (o.cellStyles) {
    o.cellNF = true;
    o.sheetStubs = true;
  }
  if (o.type == "array") {
    o.type = "binary";
    var out /*:string*/ = writeSyncXLSX(wb, o) /*:any*/;
    o.type = "array";
    return s2ab(out);
  }
  return write_zip_typeXLSX(wb, o);
}
function writeSync(wb /*:Workbook*/, opts /*:?WriteOpts*/) {
  reset_cp();
  check_wb(wb);
  var o = dup(opts || {});
  if (o.cellStyles) {
    o.cellNF = true;
    o.sheetStubs = true;
  }
  if (o.type == "array") {
    o.type = "binary";
    var out /*:string*/ = writeSync(wb, o) /*:any*/;
    o.type = "array";
    return s2ab(out);
  }
  var idx = 0;
  if (o.sheet) {
    if (typeof o.sheet == "number") idx = o.sheet;else idx = wb.SheetNames.indexOf(o.sheet);
    if (!wb.SheetNames[idx]) throw new Error("Sheet not found: " + o.sheet + " : " + typeof o.sheet);
  }
  switch (o.bookType || 'xlsb') {
    case 'xml':
    case 'xlml':
      return write_string_type(write_xlml(wb, o), o);
    case 'slk':
    case 'sylk':
      return write_string_type(SYLK.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'htm':
    case 'html':
      return write_string_type(sheet_to_html(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'txt':
      return write_stxt_type(sheet_to_txt(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'csv':
      return write_string_type(sheet_to_csv(wb.Sheets[wb.SheetNames[idx]], o), o, "\ufeff");
    case 'dif':
      return write_string_type(DIF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'dbf':
      return write_binary_type(DBF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'prn':
      return write_string_type(PRN.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'rtf':
      return write_string_type(RTF.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'eth':
      return write_string_type(ETH.from_sheet(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'fods':
      return write_string_type(write_ods(wb, o), o);
    case 'wk1':
      return write_binary_type(WK_.sheet_to_wk1(wb.Sheets[wb.SheetNames[idx]], o), o);
    case 'wk3':
      return write_binary_type(WK_.book_to_wk3(wb, o), o);
    case 'biff2':
      if (!o.biff) o.biff = 2;
    /* falls through */
    case 'biff3':
      if (!o.biff) o.biff = 3;
    /* falls through */
    case 'biff4':
      if (!o.biff) o.biff = 4;
      return write_binary_type(write_biff_buf(wb, o), o);
    case 'biff5':
      if (!o.biff) o.biff = 5;
    /* falls through */
    case 'biff8':
    case 'xla':
    case 'xls':
      if (!o.biff) o.biff = 8;
      return write_cfb_type(wb, o);
    case 'xlsx':
    case 'xlsm':
    case 'xlam':
    case 'xlsb':
    case 'numbers':
    case 'ods':
      return write_zip_type(wb, o);
    default:
      throw new Error("Unrecognized bookType |" + o.bookType + "|");
  }
}
function resolve_book_type(o /*:WriteFileOpts*/) {
  if (o.bookType) return;
  var _BT = {
    "xls": "biff8",
    "htm": "html",
    "slk": "sylk",
    "socialcalc": "eth",
    "Sh33tJS": "WTF"
  };
  var ext = o.file.slice(o.file.lastIndexOf(".")).toLowerCase();
  if (ext.match(/^\.[a-z]+$/)) o.bookType = ext.slice(1);
  o.bookType = _BT[o.bookType] || o.bookType;
}
function writeFileSync(wb /*:Workbook*/, filename /*:string*/, opts /*:?WriteFileOpts*/) {
  var o = opts || {};
  o.type = 'file';
  o.file = filename;
  resolve_book_type(o);
  return writeSync(wb, o);
}
function writeFileSyncXLSX(wb /*:Workbook*/, filename /*:string*/, opts /*:?WriteFileOpts*/) {
  var o = opts || {};
  o.type = 'file';
  o.file = filename;
  resolve_book_type(o);
  return writeSyncXLSX(wb, o);
}
function writeFileAsync(filename /*:string*/, wb /*:Workbook*/, opts /*:?WriteFileOpts*/, cb /*:?(e?:ErrnoError)=>void*/) {
  var o = opts || {};
  o.type = 'file';
  o.file = filename;
  resolve_book_type(o);
  o.type = 'buffer';
  var _cb = cb;
  if (!(_cb instanceof Function)) _cb = opts /*:any*/;
  return _fs.writeFile(filename, writeSync(wb, o), _cb);
}
/*::
type MJRObject = {
	row: any;
	isempty: boolean;
};
*/
function make_json_row(sheet /*:Worksheet*/, r /*:Range*/, R /*:number*/, cols /*:Array<string>*/, header /*:number*/, hdr /*:Array<any>*/, dense /*:boolean*/, o /*:Sheet2JSONOpts*/) /*:MJRObject*/{
  var rr = encode_row(R);
  var defval = o.defval,
    raw = o.raw || !Object.prototype.hasOwnProperty.call(o, "raw");
  var isempty = true;
  var row /*:any*/ = header === 1 ? [] : {};
  if (header !== 1) {
    if (Object.defineProperty) try {
      Object.defineProperty(row, '__rowNum__', {
        value: R,
        enumerable: false
      });
    } catch (e) {
      row.__rowNum__ = R;
    } else row.__rowNum__ = R;
  }
  if (!dense || sheet[R]) for (var C = r.s.c; C <= r.e.c; ++C) {
    var val = dense ? sheet[R][C] : sheet[cols[C] + rr];
    if (val === undefined || val.t === undefined) {
      if (defval === undefined) continue;
      if (hdr[C] != null) {
        row[hdr[C]] = defval;
      }
      continue;
    }
    var v = val.v;
    switch (val.t) {
      case 'z':
        if (v == null) break;
        continue;
      case 'e':
        v = v == 0 ? null : void 0;
        break;
      case 's':
      case 'd':
      case 'b':
      case 'n':
        break;
      default:
        throw new Error('unrecognized type ' + val.t);
    }
    if (hdr[C] != null) {
      if (v == null) {
        if (val.t == "e" && v === null) row[hdr[C]] = null;else if (defval !== undefined) row[hdr[C]] = defval;else if (raw && v === null) row[hdr[C]] = null;else continue;
      } else {
        row[hdr[C]] = raw && (val.t !== "n" || val.t === "n" && o.rawNumbers !== false) ? v : format_cell(val, v, o);
      }
      if (v != null) isempty = false;
    }
  }
  return {
    row: row,
    isempty: isempty
  };
}
function sheet_to_json(sheet /*:Worksheet*/, opts /*:?Sheet2JSONOpts*/) {
  if (sheet == null || sheet["!ref"] == null) return [];
  var val = {
      t: 'n',
      v: 0
    },
    header = 0,
    offset = 1,
    hdr /*:Array<any>*/ = [],
    v = 0,
    vv = "";
  var r = {
    s: {
      r: 0,
      c: 0
    },
    e: {
      r: 0,
      c: 0
    }
  };
  var o = opts || {};
  var range = o.range != null ? o.range : sheet["!ref"];
  if (o.header === 1) header = 1;else if (o.header === "A") header = 2;else if (Array.isArray(o.header)) header = 3;else if (o.header == null) header = 0;
  switch (typeof range) {
    case 'string':
      r = safe_decode_range(range);
      break;
    case 'number':
      r = safe_decode_range(sheet["!ref"]);
      r.s.r = range;
      break;
    default:
      r = range;
  }
  if (header > 0) offset = 0;
  var rr = encode_row(r.s.r);
  var cols /*:Array<string>*/ = [];
  var out /*:Array<any>*/ = [];
  var outi = 0,
    counter = 0;
  var dense = Array.isArray(sheet);
  var R = r.s.r,
    C = 0;
  var header_cnt = {};
  if (dense && !sheet[R]) sheet[R] = [];
  var colinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
  var rowinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!rows"] || [];
  for (C = r.s.c; C <= r.e.c; ++C) {
    if ((colinfo[C] || {}).hidden) continue;
    cols[C] = encode_col(C);
    val = dense ? sheet[R][C] : sheet[cols[C] + rr];
    switch (header) {
      case 1:
        hdr[C] = C - r.s.c;
        break;
      case 2:
        hdr[C] = cols[C];
        break;
      case 3:
        hdr[C] = o.header[C - r.s.c];
        break;
      default:
        if (val == null) val = {
          w: "__EMPTY",
          t: "s"
        };
        vv = v = format_cell(val, null, o);
        counter = header_cnt[v] || 0;
        if (!counter) header_cnt[v] = 1;else {
          do {
            vv = v + "_" + counter++;
          } while (header_cnt[vv]);
          header_cnt[v] = counter;
          header_cnt[vv] = 1;
        }
        hdr[C] = vv;
    }
  }
  for (R = r.s.r + offset; R <= r.e.r; ++R) {
    if ((rowinfo[R] || {}).hidden) continue;
    var row = make_json_row(sheet, r, R, cols, header, hdr, dense, o);
    if (row.isempty === false || (header === 1 ? o.blankrows !== false : !!o.blankrows)) out[outi++] = row.row;
  }
  out.length = outi;
  return out;
}
var qreg = /"/g;
function make_csv_row(sheet /*:Worksheet*/, r /*:Range*/, R /*:number*/, cols /*:Array<string>*/, fs /*:number*/, rs /*:number*/, FS /*:string*/, o /*:Sheet2CSVOpts*/) /*:?string*/{
  var isempty = true;
  var row /*:Array<string>*/ = [],
    txt = "",
    rr = encode_row(R);
  for (var C = r.s.c; C <= r.e.c; ++C) {
    if (!cols[C]) continue;
    var val = o.dense ? (sheet[R] || [])[C] : sheet[cols[C] + rr];
    if (val == null) txt = "";else if (val.v != null) {
      isempty = false;
      txt = '' + (o.rawNumbers && val.t == "n" ? val.v : format_cell(val, null, o));
      for (var i = 0, cc = 0; i !== txt.length; ++i) if ((cc = txt.charCodeAt(i)) === fs || cc === rs || cc === 34 || o.forceQuotes) {
        txt = "\"" + txt.replace(qreg, '""') + "\"";
        break;
      }
      if (txt == "ID") txt = '"ID"';
    } else if (val.f != null && !val.F) {
      isempty = false;
      txt = '=' + val.f;
      if (txt.indexOf(",") >= 0) txt = '"' + txt.replace(qreg, '""') + '"';
    } else txt = "";
    /* NOTE: Excel CSV does not support array formulae */
    row.push(txt);
  }
  if (o.blankrows === false && isempty) return null;
  return row.join(FS);
}
function sheet_to_csv(sheet /*:Worksheet*/, opts /*:?Sheet2CSVOpts*/) /*:string*/{
  var out /*:Array<string>*/ = [];
  var o = opts == null ? {} : opts;
  if (sheet == null || sheet["!ref"] == null) return "";
  var r = safe_decode_range(sheet["!ref"]);
  var FS = o.FS !== undefined ? o.FS : ",",
    fs = FS.charCodeAt(0);
  var RS = o.RS !== undefined ? o.RS : "\n",
    rs = RS.charCodeAt(0);
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
  var row = "",
    cols /*:Array<string>*/ = [];
  o.dense = Array.isArray(sheet);
  var colinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
  var rowinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!rows"] || [];
  for (var C = r.s.c; C <= r.e.c; ++C) if (!(colinfo[C] || {}).hidden) cols[C] = encode_col(C);
  var w = 0;
  for (var R = r.s.r; R <= r.e.r; ++R) {
    if ((rowinfo[R] || {}).hidden) continue;
    row = make_csv_row(sheet, r, R, cols, fs, rs, FS, o);
    if (row == null) {
      continue;
    }
    if (o.strip) row = row.replace(endregex, "");
    if (row || o.blankrows !== false) out.push((w++ ? RS : "") + row);
  }
  delete o.dense;
  return out.join("");
}
function sheet_to_txt(sheet /*:Worksheet*/, opts /*:?Sheet2CSVOpts*/) {
  if (!opts) opts = {};
  opts.FS = "\t";
  opts.RS = "\n";
  var s = sheet_to_csv(sheet, opts);
  if (typeof $cptable == 'undefined' || opts.type == 'string') return s;
  var o = $cptable.utils.encode(1200, s, 'str');
  return String.fromCharCode(255) + String.fromCharCode(254) + o;
}
function sheet_to_formulae(sheet /*:Worksheet*/) /*:Array<string>*/{
  var y = "",
    x,
    val = "";
  if (sheet == null || sheet["!ref"] == null) return [];
  var r = safe_decode_range(sheet['!ref']),
    rr = "",
    cols /*:Array<string>*/ = [],
    C;
  var cmds /*:Array<string>*/ = [];
  var dense = Array.isArray(sheet);
  for (C = r.s.c; C <= r.e.c; ++C) cols[C] = encode_col(C);
  for (var R = r.s.r; R <= r.e.r; ++R) {
    rr = encode_row(R);
    for (C = r.s.c; C <= r.e.c; ++C) {
      y = cols[C] + rr;
      x = dense ? (sheet[R] || [])[C] : sheet[y];
      val = "";
      if (x === undefined) continue;else if (x.F != null) {
        y = x.F;
        if (!x.f) continue;
        val = x.f;
        if (y.indexOf(":") == -1) y = y + ":" + y;
      }
      if (x.f != null) val = x.f;else if (x.t == 'z') continue;else if (x.t == 'n' && x.v != null) val = "" + x.v;else if (x.t == 'b') val = x.v ? "TRUE" : "FALSE";else if (x.w !== undefined) val = "'" + x.w;else if (x.v === undefined) continue;else if (x.t == 's') val = "'" + x.v;else val = "" + x.v;
      cmds[cmds.length] = y + "=" + val;
    }
  }
  return cmds;
}
function sheet_add_json(_ws /*:?Worksheet*/, js /*:Array<any>*/, opts) /*:Worksheet*/{
  var o = opts || {};
  var offset = +!o.skipHeader;
  var ws /*:Worksheet*/ = _ws || {} /*:any*/;
  var _R = 0,
    _C = 0;
  if (ws && o.origin != null) {
    if (typeof o.origin == 'number') _R = o.origin;else {
      var _origin /*:CellAddress*/ = typeof o.origin == "string" ? decode_cell(o.origin) : o.origin;
      _R = _origin.r;
      _C = _origin.c;
    }
  }
  var cell /*:Cell*/;
  var range /*:Range*/ = {
    s: {
      c: 0,
      r: 0
    },
    e: {
      c: _C,
      r: _R + js.length - 1 + offset
    }
  } /*:any*/;
  if (ws['!ref']) {
    var _range = safe_decode_range(ws['!ref']);
    range.e.c = Math.max(range.e.c, _range.e.c);
    range.e.r = Math.max(range.e.r, _range.e.r);
    if (_R == -1) {
      _R = _range.e.r + 1;
      range.e.r = _R + js.length - 1 + offset;
    }
  } else {
    if (_R == -1) {
      _R = 0;
      range.e.r = js.length - 1 + offset;
    }
  }
  var hdr /*:Array<string>*/ = o.header || [],
    C = 0;
  js.forEach(function (JS, R /*:number*/) {
    keys(JS).forEach(function (k) {
      if ((C = hdr.indexOf(k)) == -1) hdr[C = hdr.length] = k;
      var v = JS[k];
      var t = 'z';
      var z = "";
      var ref = encode_cell({
        c: _C + C,
        r: _R + R + offset
      });
      cell = ws_get_cell_stub(ws, ref);
      if (v && typeof v === 'object' && !(v instanceof Date)) {
        ws[ref] = v;
      } else {
        if (typeof v == 'number') t = 'n';else if (typeof v == 'boolean') t = 'b';else if (typeof v == 'string') t = 's';else if (v instanceof Date) {
          t = 'd';
          if (!o.cellDates) {
            t = 'n';
            v = datenum(v);
          }
          z = o.dateNF || table_fmt[14];
        } else if (v === null && o.nullError) {
          t = 'e';
          v = 0;
        }
        if (!cell) ws[ref] = cell = {
          t: t,
          v: v
        } /*:any*/;else {
          cell.t = t;
          cell.v = v;
          delete cell.w;
          delete cell.R;
          if (z) cell.z = z;
        }
        if (z) cell.z = z;
      }
    });
  });
  range.e.c = Math.max(range.e.c, _C + hdr.length - 1);
  var __R = encode_row(_R);
  if (offset) for (C = 0; C < hdr.length; ++C) ws[encode_col(C + _C) + __R] = {
    t: 's',
    v: hdr[C]
  };
  ws['!ref'] = encode_range(range);
  return ws;
}
function json_to_sheet(js /*:Array<any>*/, opts) /*:Worksheet*/{
  return sheet_add_json(null, js, opts);
}

/* get cell, creating a stub if necessary */
function ws_get_cell_stub(ws /*:Worksheet*/, R, C /*:?number*/) /*:Cell*/{
  /* A1 cell address */
  if (typeof R == "string") {
    /* dense */
    if (Array.isArray(ws)) {
      var RC = decode_cell(R);
      if (!ws[RC.r]) ws[RC.r] = [];
      return ws[RC.r][RC.c] || (ws[RC.r][RC.c] = {
        t: 'z'
      });
    }
    return ws[R] || (ws[R] = {
      t: 'z'
    });
  }
  /* cell address object */
  if (typeof R != "number") return ws_get_cell_stub(ws, encode_cell(R));
  /* R and C are 0-based indices */
  return ws_get_cell_stub(ws, encode_cell({
    r: R,
    c: C || 0
  }));
}

/* find sheet index for given name / validate index */
function wb_sheet_idx(wb /*:Workbook*/, sh /*:number|string*/) {
  if (typeof sh == "number") {
    if (sh >= 0 && wb.SheetNames.length > sh) return sh;
    throw new Error("Cannot find sheet # " + sh);
  } else if (typeof sh == "string") {
    var idx = wb.SheetNames.indexOf(sh);
    if (idx > -1) return idx;
    throw new Error("Cannot find sheet name |" + sh + "|");
  } else throw new Error("Cannot find sheet |" + sh + "|");
}

/* simple blank workbook object */
function book_new() /*:Workbook*/{
  return {
    SheetNames: [],
    Sheets: {}
  };
}

/* add a worksheet to the end of a given workbook */
function book_append_sheet(wb /*:Workbook*/, ws /*:Worksheet*/, name /*:?string*/, roll /*:?boolean*/) /*:string*/{
  var i = 1;
  if (!name) for (; i <= 0xFFFF; ++i, name = undefined) if (wb.SheetNames.indexOf(name = "Sheet" + i) == -1) break;
  if (!name || wb.SheetNames.length >= 0xFFFF) throw new Error("Too many worksheets");
  if (roll && wb.SheetNames.indexOf(name) >= 0) {
    var m = name.match(/(^.*?)(\d+)$/);
    i = m && +m[2] || 0;
    var root = m && m[1] || name;
    for (++i; i <= 0xFFFF; ++i) if (wb.SheetNames.indexOf(name = root + i) == -1) break;
  }
  check_ws_name(name);
  if (wb.SheetNames.indexOf(name) >= 0) throw new Error("Worksheet with name |" + name + "| already exists!");
  wb.SheetNames.push(name);
  wb.Sheets[name] = ws;
  return name;
}

/* set sheet visibility (visible/hidden/very hidden) */
function book_set_sheet_visibility(wb /*:Workbook*/, sh /*:number|string*/, vis /*:number*/) {
  if (!wb.Workbook) wb.Workbook = {};
  if (!wb.Workbook.Sheets) wb.Workbook.Sheets = [];
  var idx = wb_sheet_idx(wb, sh);
  // $FlowIgnore
  if (!wb.Workbook.Sheets[idx]) wb.Workbook.Sheets[idx] = {};
  switch (vis) {
    case 0:
    case 1:
    case 2:
      break;
    default:
      throw new Error("Bad sheet visibility setting " + vis);
  }
  // $FlowIgnore
  wb.Workbook.Sheets[idx].Hidden = vis;
}

/* set number format */
function cell_set_number_format(cell /*:Cell*/, fmt /*:string|number*/) {
  cell.z = fmt;
  return cell;
}

/* set cell hyperlink */
function cell_set_hyperlink(cell /*:Cell*/, target /*:string*/, tooltip /*:?string*/) {
  if (!target) {
    delete cell.l;
  } else {
    cell.l = {
      Target: target
    } /*:Hyperlink*/;
    if (tooltip) cell.l.Tooltip = tooltip;
  }
  return cell;
}
function cell_set_internal_link(cell /*:Cell*/, range /*:string*/, tooltip /*:?string*/) {
  return cell_set_hyperlink(cell, "#" + range, tooltip);
}

/* add to cell comments */
function cell_add_comment(cell /*:Cell*/, text /*:string*/, author /*:?string*/) {
  if (!cell.c) cell.c = [];
  cell.c.push({
    t: text,
    a: author || "SheetJS"
  });
}

/* set array formula and flush related cells */
function sheet_set_array_formula(ws /*:Worksheet*/, range, formula /*:string*/, dynamic /*:boolean*/) {
  var rng = typeof range != "string" ? range : safe_decode_range(range);
  var rngstr = typeof range == "string" ? range : encode_range(range);
  for (var R = rng.s.r; R <= rng.e.r; ++R) for (var C = rng.s.c; C <= rng.e.c; ++C) {
    var cell = ws_get_cell_stub(ws, R, C);
    cell.t = 'n';
    cell.F = rngstr;
    delete cell.v;
    if (R == rng.s.r && C == rng.s.c) {
      cell.f = formula;
      if (dynamic) cell.D = true;
    }
  }
  return ws;
}
var utils /*:any*/ = {
  encode_col: encode_col,
  encode_row: encode_row,
  encode_cell: encode_cell,
  encode_range: encode_range,
  decode_col: decode_col,
  decode_row: decode_row,
  split_cell: split_cell,
  decode_cell: decode_cell,
  decode_range: decode_range,
  format_cell: format_cell,
  sheet_add_aoa: sheet_add_aoa,
  sheet_add_json: sheet_add_json,
  sheet_add_dom: sheet_add_dom,
  aoa_to_sheet: aoa_to_sheet,
  json_to_sheet: json_to_sheet,
  table_to_sheet: parse_dom_table,
  table_to_book: table_to_book,
  sheet_to_csv: sheet_to_csv,
  sheet_to_txt: sheet_to_txt,
  sheet_to_json: sheet_to_json,
  sheet_to_html: sheet_to_html,
  sheet_to_formulae: sheet_to_formulae,
  sheet_to_row_object_array: sheet_to_json,
  sheet_get_cell: ws_get_cell_stub,
  book_new: book_new,
  book_append_sheet: book_append_sheet,
  book_set_sheet_visibility: book_set_sheet_visibility,
  cell_set_number_format: cell_set_number_format,
  cell_set_hyperlink: cell_set_hyperlink,
  cell_set_internal_link: cell_set_internal_link,
  cell_add_comment: cell_add_comment,
  sheet_set_array_formula: sheet_set_array_formula,
  consts: {
    SHEET_VISIBLE: 0,
    SHEET_HIDDEN: 1,
    SHEET_VERY_HIDDEN: 2
  }
};
var _Readable;
function set_readable(R) {
  _Readable = R;
}
function write_csv_stream(sheet /*:Worksheet*/, opts /*:?Sheet2CSVOpts*/) {
  var stream = _Readable();
  var o = opts == null ? {} : opts;
  if (sheet == null || sheet["!ref"] == null) {
    stream.push(null);
    return stream;
  }
  var r = safe_decode_range(sheet["!ref"]);
  var FS = o.FS !== undefined ? o.FS : ",",
    fs = FS.charCodeAt(0);
  var RS = o.RS !== undefined ? o.RS : "\n",
    rs = RS.charCodeAt(0);
  var endregex = new RegExp((FS == "|" ? "\\|" : FS) + "+$");
  var row /*:?string*/ = "",
    cols /*:Array<string>*/ = [];
  o.dense = Array.isArray(sheet);
  var colinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
  var rowinfo /*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
  for (var C = r.s.c; C <= r.e.c; ++C) if (!(colinfo[C] || {}).hidden) cols[C] = encode_col(C);
  var R = r.s.r;
  var BOM = false,
    w = 0;
  stream._read = function () {
    if (!BOM) {
      BOM = true;
      return stream.push("\uFEFF");
    }
    while (R <= r.e.r) {
      ++R;
      if ((rowinfo[R - 1] || {}).hidden) continue;
      row = make_csv_row(sheet, r, R - 1, cols, fs, rs, FS, o);
      if (row != null) {
        if (o.strip) row = row.replace(endregex, "");
        if (row || o.blankrows !== false) return stream.push((w++ ? RS : "") + row);
      }
    }
    return stream.push(null);
  };
  return stream;
}
function write_html_stream(ws /*:Worksheet*/, opts /*:?Sheet2HTMLOpts*/) {
  var stream = _Readable();
  var o = opts || {};
  var header = o.header != null ? o.header : HTML_BEGIN;
  var footer = o.footer != null ? o.footer : HTML_END;
  stream.push(header);
  var r = decode_range(ws['!ref']);
  o.dense = Array.isArray(ws);
  stream.push(make_html_preamble(ws, r, o));
  var R = r.s.r;
  var end = false;
  stream._read = function () {
    if (R > r.e.r) {
      if (!end) {
        end = true;
        stream.push("</table>" + footer);
      }
      return stream.push(null);
    }
    while (R <= r.e.r) {
      stream.push(make_html_row(ws, r, R, o));
      ++R;
      break;
    }
  };
  return stream;
}
function write_json_stream(sheet /*:Worksheet*/, opts /*:?Sheet2CSVOpts*/) {
  var stream = _Readable({
    objectMode: true
  });
  if (sheet == null || sheet["!ref"] == null) {
    stream.push(null);
    return stream;
  }
  var val = {
      t: 'n',
      v: 0
    },
    header = 0,
    offset = 1,
    hdr /*:Array<any>*/ = [],
    v = 0,
    vv = "";
  var r = {
    s: {
      r: 0,
      c: 0
    },
    e: {
      r: 0,
      c: 0
    }
  };
  var o = opts || {};
  var range = o.range != null ? o.range : sheet["!ref"];
  if (o.header === 1) header = 1;else if (o.header === "A") header = 2;else if (Array.isArray(o.header)) header = 3;
  switch (typeof range) {
    case 'string':
      r = safe_decode_range(range);
      break;
    case 'number':
      r = safe_decode_range(sheet["!ref"]);
      r.s.r = range;
      break;
    default:
      r = range;
  }
  if (header > 0) offset = 0;
  var rr = encode_row(r.s.r);
  var cols /*:Array<string>*/ = [];
  var counter = 0;
  var dense = Array.isArray(sheet);
  var R = r.s.r,
    C = 0;
  var header_cnt = {};
  if (dense && !sheet[R]) sheet[R] = [];
  var colinfo /*:Array<ColInfo>*/ = o.skipHidden && sheet["!cols"] || [];
  var rowinfo /*:Array<RowInfo>*/ = o.skipHidden && sheet["!rows"] || [];
  for (C = r.s.c; C <= r.e.c; ++C) {
    if ((colinfo[C] || {}).hidden) continue;
    cols[C] = encode_col(C);
    val = dense ? sheet[R][C] : sheet[cols[C] + rr];
    switch (header) {
      case 1:
        hdr[C] = C - r.s.c;
        break;
      case 2:
        hdr[C] = cols[C];
        break;
      case 3:
        hdr[C] = o.header[C - r.s.c];
        break;
      default:
        if (val == null) val = {
          w: "__EMPTY",
          t: "s"
        };
        vv = v = format_cell(val, null, o);
        counter = header_cnt[v] || 0;
        if (!counter) header_cnt[v] = 1;else {
          do {
            vv = v + "_" + counter++;
          } while (header_cnt[vv]);
          header_cnt[v] = counter;
          header_cnt[vv] = 1;
        }
        hdr[C] = vv;
    }
  }
  R = r.s.r + offset;
  stream._read = function () {
    while (R <= r.e.r) {
      if ((rowinfo[R - 1] || {}).hidden) continue;
      var row = make_json_row(sheet, r, R, cols, header, hdr, dense, o);
      ++R;
      if (row.isempty === false || (header === 1 ? o.blankrows !== false : !!o.blankrows)) {
        stream.push(row.row);
        return;
      }
    }
    return stream.push(null);
  };
  return stream;
}
var __stream = {
  to_json: write_json_stream,
  to_html: write_html_stream,
  to_csv: write_csv_stream,
  set_readable: set_readable
};
const version = XLSX.version;


/***/ }),

/***/ 89204:
/*!*********************************************************************!*\
  !*** ./node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js ***!
  \*********************************************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "default": () => (/* binding */ _asyncToGenerator)
/* harmony export */ });
function asyncGeneratorStep(n, t, e, r, o, a, c) {
  try {
    var i = n[a](c),
      u = i.value;
  } catch (n) {
    return void e(n);
  }
  i.done ? t(u) : Promise.resolve(u).then(r, o);
}
function _asyncToGenerator(n) {
  return function () {
    var t = this,
      e = arguments;
    return new Promise(function (r, o) {
      var a = n.apply(t, e);
      function _next(n) {
        asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
      }
      function _throw(n) {
        asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
      }
      _next(void 0);
    });
  };
}


/***/ }),

/***/ 24398:
/*!******************************************!*\
  !*** ./node_modules/tslib/tslib.es6.mjs ***!
  \******************************************/
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   __addDisposableResource: () => (/* binding */ __addDisposableResource),
/* harmony export */   __assign: () => (/* binding */ __assign),
/* harmony export */   __asyncDelegator: () => (/* binding */ __asyncDelegator),
/* harmony export */   __asyncGenerator: () => (/* binding */ __asyncGenerator),
/* harmony export */   __asyncValues: () => (/* binding */ __asyncValues),
/* harmony export */   __await: () => (/* binding */ __await),
/* harmony export */   __awaiter: () => (/* binding */ __awaiter),
/* harmony export */   __classPrivateFieldGet: () => (/* binding */ __classPrivateFieldGet),
/* harmony export */   __classPrivateFieldIn: () => (/* binding */ __classPrivateFieldIn),
/* harmony export */   __classPrivateFieldSet: () => (/* binding */ __classPrivateFieldSet),
/* harmony export */   __createBinding: () => (/* binding */ __createBinding),
/* harmony export */   __decorate: () => (/* binding */ __decorate),
/* harmony export */   __disposeResources: () => (/* binding */ __disposeResources),
/* harmony export */   __esDecorate: () => (/* binding */ __esDecorate),
/* harmony export */   __exportStar: () => (/* binding */ __exportStar),
/* harmony export */   __extends: () => (/* binding */ __extends),
/* harmony export */   __generator: () => (/* binding */ __generator),
/* harmony export */   __importDefault: () => (/* binding */ __importDefault),
/* harmony export */   __importStar: () => (/* binding */ __importStar),
/* harmony export */   __makeTemplateObject: () => (/* binding */ __makeTemplateObject),
/* harmony export */   __metadata: () => (/* binding */ __metadata),
/* harmony export */   __param: () => (/* binding */ __param),
/* harmony export */   __propKey: () => (/* binding */ __propKey),
/* harmony export */   __read: () => (/* binding */ __read),
/* harmony export */   __rest: () => (/* binding */ __rest),
/* harmony export */   __rewriteRelativeImportExtension: () => (/* binding */ __rewriteRelativeImportExtension),
/* harmony export */   __runInitializers: () => (/* binding */ __runInitializers),
/* harmony export */   __setFunctionName: () => (/* binding */ __setFunctionName),
/* harmony export */   __spread: () => (/* binding */ __spread),
/* harmony export */   __spreadArray: () => (/* binding */ __spreadArray),
/* harmony export */   __spreadArrays: () => (/* binding */ __spreadArrays),
/* harmony export */   __values: () => (/* binding */ __values),
/* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */

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 (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
  return extendStatics(d, b);
};

function __extends(d, b) {
  if (typeof b !== "function" && b !== null)
      throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
  extendStatics(d, b);
  function __() { this.constructor = d; }
  d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}

var __assign = function() {
  __assign = Object.assign || function __assign(t) {
      for (var s, i = 1, n = arguments.length; i < n; i++) {
          s = arguments[i];
          for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
      }
      return t;
  }
  return __assign.apply(this, arguments);
}

function __rest(s, e) {
  var t = {};
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
      t[p] = s[p];
  if (s != null && typeof Object.getOwnPropertySymbols === "function")
      for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
          if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
              t[p[i]] = s[p[i]];
      }
  return t;
}

function __decorate(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
}

function __param(paramIndex, decorator) {
  return function (target, key) { decorator(target, key, paramIndex); }
}

function __esDecorate(ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
  function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
  var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
  var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
  var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
  var _, done = false;
  for (var i = decorators.length - 1; i >= 0; i--) {
      var context = {};
      for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
      for (var p in contextIn.access) context.access[p] = contextIn.access[p];
      context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
      var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
      if (kind === "accessor") {
          if (result === void 0) continue;
          if (result === null || typeof result !== "object") throw new TypeError("Object expected");
          if (_ = accept(result.get)) descriptor.get = _;
          if (_ = accept(result.set)) descriptor.set = _;
          if (_ = accept(result.init)) initializers.unshift(_);
      }
      else if (_ = accept(result)) {
          if (kind === "field") initializers.unshift(_);
          else descriptor[key] = _;
      }
  }
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
  done = true;
};

function __runInitializers(thisArg, initializers, value) {
  var useValue = arguments.length > 2;
  for (var i = 0; i < initializers.length; i++) {
      value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
  }
  return useValue ? value : void 0;
};

function __propKey(x) {
  return typeof x === "symbol" ? x : "".concat(x);
};

function __setFunctionName(f, name, prefix) {
  if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
  return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
};

function __metadata(metadataKey, metadataValue) {
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
}

function __awaiter(thisArg, _arguments, P, generator) {
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  return new (P || (P = Promise))(function (resolve, reject) {
      function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
      function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
      function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
      step((generator = generator.apply(thisArg, _arguments || [])).next());
  });
}

function __generator(thisArg, body) {
  var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
  return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  function verb(n) { return function (v) { return step([n, v]); }; }
  function step(op) {
      if (f) throw new TypeError("Generator is already executing.");
      while (g && (g = 0, op[0] && (_ = 0)), _) try {
          if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
          if (y = 0, t) op = [op[0] & 2, t.value];
          switch (op[0]) {
              case 0: case 1: t = op; break;
              case 4: _.label++; return { value: op[1], done: false };
              case 5: _.label++; y = op[1]; op = [0]; continue;
              case 7: op = _.ops.pop(); _.trys.pop(); continue;
              default:
                  if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                  if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                  if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                  if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                  if (t[2]) _.ops.pop();
                  _.trys.pop(); continue;
          }
          op = body.call(thisArg, _);
      } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
      if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  }
}

var __createBinding = Object.create ? (function(o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  var desc = Object.getOwnPropertyDescriptor(m, k);
  if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
  }
  Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
  if (k2 === undefined) k2 = k;
  o[k2] = m[k];
});

function __exportStar(m, o) {
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
}

function __values(o) {
  var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
  if (m) return m.call(o);
  if (o && typeof o.length === "number") return {
      next: function () {
          if (o && i >= o.length) o = void 0;
          return { value: o && o[i++], done: !o };
      }
  };
  throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}

function __read(o, n) {
  var m = typeof Symbol === "function" && o[Symbol.iterator];
  if (!m) return o;
  var i = m.call(o), r, ar = [], e;
  try {
      while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
  }
  catch (error) { e = { error: error }; }
  finally {
      try {
          if (r && !r.done && (m = i["return"])) m.call(i);
      }
      finally { if (e) throw e.error; }
  }
  return ar;
}

/** @deprecated */
function __spread() {
  for (var ar = [], i = 0; i < arguments.length; i++)
      ar = ar.concat(__read(arguments[i]));
  return ar;
}

/** @deprecated */
function __spreadArrays() {
  for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
  for (var r = Array(s), k = 0, i = 0; i < il; i++)
      for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
          r[k] = a[j];
  return r;
}

function __spreadArray(to, from, pack) {
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
      if (ar || !(i in from)) {
          if (!ar) ar = Array.prototype.slice.call(from, 0, i);
          ar[i] = from[i];
      }
  }
  return to.concat(ar || Array.prototype.slice.call(from));
}

function __await(v) {
  return this instanceof __await ? (this.v = v, this) : new __await(v);
}

function __asyncGenerator(thisArg, _arguments, generator) {
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
  var g = generator.apply(thisArg, _arguments || []), i, q = [];
  return i = Object.create((typeof AsyncIterator === "function" ? AsyncIterator : Object).prototype), verb("next"), verb("throw"), verb("return", awaitReturn), i[Symbol.asyncIterator] = function () { return this; }, i;
  function awaitReturn(f) { return function (v) { return Promise.resolve(v).then(f, reject); }; }
  function verb(n, f) { if (g[n]) { i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; if (f) i[n] = f(i[n]); } }
  function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }
  function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
  function fulfill(value) { resume("next", value); }
  function reject(value) { resume("throw", value); }
  function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }
}

function __asyncDelegator(o) {
  var i, p;
  return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
  function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: false } : f ? f(v) : v; } : f; }
}

function __asyncValues(o) {
  if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
  var m = o[Symbol.asyncIterator], i;
  return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
  function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
  function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
}

function __makeTemplateObject(cooked, raw) {
  if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
  return cooked;
};

var __setModuleDefault = Object.create ? (function(o, v) {
  Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
  o["default"] = v;
};

var ownKeys = function(o) {
  ownKeys = Object.getOwnPropertyNames || function (o) {
    var ar = [];
    for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
    return ar;
  };
  return ownKeys(o);
};

function __importStar(mod) {
  if (mod && mod.__esModule) return mod;
  var result = {};
  if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
  __setModuleDefault(result, mod);
  return result;
}

function __importDefault(mod) {
  return (mod && mod.__esModule) ? mod : { default: mod };
}

function __classPrivateFieldGet(receiver, state, kind, f) {
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}

function __classPrivateFieldSet(receiver, state, value, kind, f) {
  if (kind === "m") throw new TypeError("Private method is not writable");
  if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}

function __classPrivateFieldIn(state, receiver) {
  if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function")) throw new TypeError("Cannot use 'in' operator on non-object");
  return typeof state === "function" ? receiver === state : state.has(receiver);
}

function __addDisposableResource(env, value, async) {
  if (value !== null && value !== void 0) {
    if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
    var dispose, inner;
    if (async) {
      if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
      dispose = value[Symbol.asyncDispose];
    }
    if (dispose === void 0) {
      if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
      dispose = value[Symbol.dispose];
      if (async) inner = dispose;
    }
    if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
    if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
    env.stack.push({ value: value, dispose: dispose, async: async });
  }
  else if (async) {
    env.stack.push({ async: true });
  }
  return value;
}

var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
  var e = new Error(message);
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};

function __disposeResources(env) {
  function fail(e) {
    env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
    env.hasError = true;
  }
  var r, s = 0;
  function next() {
    while (r = env.stack.pop()) {
      try {
        if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
        if (r.dispose) {
          var result = r.dispose.call(r.value);
          if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
        }
        else s |= 1;
      }
      catch (e) {
        fail(e);
      }
    }
    if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
    if (env.hasError) throw env.error;
  }
  return next();
}

function __rewriteRelativeImportExtension(path, preserveJsx) {
  if (typeof path === "string" && /^\.\.?\//.test(path)) {
      return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
          return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
      });
  }
  return path;
}

/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
  __extends,
  __assign,
  __rest,
  __decorate,
  __param,
  __esDecorate,
  __runInitializers,
  __propKey,
  __setFunctionName,
  __metadata,
  __awaiter,
  __generator,
  __createBinding,
  __exportStar,
  __values,
  __read,
  __spread,
  __spreadArrays,
  __spreadArray,
  __await,
  __asyncGenerator,
  __asyncDelegator,
  __asyncValues,
  __makeTemplateObject,
  __importStar,
  __importDefault,
  __classPrivateFieldGet,
  __classPrivateFieldSet,
  __classPrivateFieldIn,
  __addDisposableResource,
  __disposeResources,
  __rewriteRelativeImportExtension,
});


/***/ })

}]);
//# sourceMappingURL=vendor.js.map

Youez - 2016 - github.com/yon3zu
LinuXploit